Browse Source

创建用户列表页面;对接接口完成;

songjie/feature-20260331101525-后台整改需求
songjie 1 week ago
parent
commit
737d6d5b90
  1. 21
      src/api/userPermissions.js
  2. 18
      src/router/index.js
  3. 459
      src/views/UserPermissions/UserList.vue

21
src/api/userPermissions.js

@ -207,4 +207,23 @@ export function getOriginListApi(params) {
method: "post", method: "post",
data: params, data: params,
}); });
}
}
// 2026.04.01
// 用户列表--获取用户列表
export function userListApi(params) {
return request({
url: base_url + "/admin/user/list/get",
method: "post",
data: params,
});
}
// 用户列表--创建导出
export function exportUserListApi(params) {
return request({
url: base_url + "/admin/user/list/export",
method: "post",
data: params,
});
}
// 2026.04.01

18
src/router/index.js

@ -28,6 +28,12 @@ const routes = [
name: 'userPermissions', name: 'userPermissions',
meta: { title: '用户权限管理', icon: "UserFilled", showSidebar: true, isParentNav: true }, meta: { title: '用户权限管理', icon: "UserFilled", showSidebar: true, isParentNav: true },
children: [ children: [
{
path: 'userList',
name: 'userList',
component: () => import('../views/UserPermissions/UserList.vue'),
meta: { title: '用户列表', showSidebar: true }
},
// { // {
// path: 'market', // path: 'market',
// name: 'market', // name: 'market',
@ -40,12 +46,6 @@ const routes = [
// component: () => import('../views/UserPermissions/Module.vue'), // component: () => import('../views/UserPermissions/Module.vue'),
// meta: { title: '模块期限', showSidebar: true } // meta: { title: '模块期限', showSidebar: true }
// }, // },
{
path: 'invitedLook',
name: 'invitedLook',
component: () => import('../views/UserPermissions/invitedLook.vue'),
meta: { title: '查看被邀请用户', showSidebar: true }
},
// 期限管理子菜单 // 期限管理子菜单
{ {
path: 'limitManagement', path: 'limitManagement',
@ -72,6 +72,12 @@ const routes = [
} }
] ]
}, },
{
path: 'invitedLook',
name: 'invitedLook',
component: () => import('../views/UserPermissions/invitedLook.vue'),
meta: { title: '查看被邀请用户', showSidebar: true }
},
// 深度探索--操作日志 // 深度探索--操作日志
{ {
path: 'logDeepexplore', path: 'logDeepexplore',

459
src/views/UserPermissions/UserList.vue

@ -0,0 +1,459 @@
<template>
<div class="page-container">
<!-- 搜索区域 -->
<div class="search-container">
<div class="search-form">
<div class="search-row">
<div class="search-item">
<span class="form-label">账号</span>
<el-input
v-model="searchForm.dccode"
placeholder="请输入ID"
clearable
style="width: 140px;"
/>
</div>
<div class="search-item">
<span class="form-label">姓名</span>
<el-input
v-model="searchForm.name"
placeholder="请输入姓名"
clearable
style="width: 140px;"
/>
</div>
<div class="search-item">
<span class="form-label">来源</span>
<el-select
v-model="searchForm.origin_id"
placeholder="请选择来源"
clearable
filterable
style="width: 160px;"
:loading="isOriginLoading"
>
<el-option
v-for="origin in originList"
:key="origin.origin_id"
:label="origin.origin_name"
:value="origin.origin_id"
/>
</el-select>
</div>
<div class="search-item">
<span class="form-label">地区</span>
<el-select
v-model="searchForm.country"
placeholder="请选择地区"
clearable
filterable
style="width: 140px;"
:loading="isRegionLoading"
>
<el-option
v-for="region in regionList"
:key="region.ID"
:label="region.Name"
:value="region.Name"
/>
</el-select>
</div>
<div class="search-item">
<span class="form-label">登录</span>
<el-select
v-model="searchForm.is_login"
placeholder="请选择是否登录"
clearable
style="width: 140px;"
>
<el-option label="已登录" :value="1" />
<el-option label="未登录" :value="0" />
</el-select>
</div>
<div class="search-item">
<span class="form-label">注册方式</span>
<el-input
v-model="searchForm.register_type"
placeholder="请输入手机号/邮箱"
clearable
style="width: 180px;"
/>
</div>
</div>
<div class="search-row">
<div class="search-item">
<span class="form-label">注册时间</span>
<el-date-picker
v-model="searchForm.regTimeRange"
type="datetimerange"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 320px;"
/>
</div>
<div class="search-item">
<span class="form-label">登录时间</span>
<el-date-picker
v-model="searchForm.loginTimeRange"
type="datetimerange"
range-separator="至"
start-placeholder="开始时间"
end-placeholder="结束时间"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 320px;"
/>
</div>
</div>
<div class="button-group">
<el-button type="primary" @click="handleSearch">搜索</el-button>
<el-button type="success" @click="handleExport">导出Excel列表</el-button>
<el-button color="#626aef" @click="handleViewExport">查看导出列表</el-button>
<el-button @click="handleReset">重置</el-button>
</div>
</div>
</div>
<!-- 数据表格 -->
<el-table
:data="tableData"
style="width: 100%; margin-top: 20px;"
header-cell-class-name="table-header"
class="table-rounded"
:loading="tableLoading"
:header-cell-style="{background:'#f5f7fa', color:'#606266', fontWeight:'600'}"
>
<el-table-column prop="id" label="序号" align="center" header-align="center" width="60">
<template #default="scope">
{{ (currentPage - 1) * pageSize + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="dccode" label="ID" align="center" header-align="center" width="100"/>
<el-table-column prop="name" label="姓名" align="center" header-align="center" width="120">
<template #default="scope">
<span>{{ scope.row.name || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="country" label="地区" align="center" header-align="center" width="120"/>
<el-table-column prop="origin" label="来源" align="center" header-align="center" width="160">
<template #default="scope">
<span class="ellipsis-text" :title="scope.row.origin">{{ scope.row.origin }}</span>
</template>
</el-table-column>
<el-table-column prop="phone" label="手机号" align="center" header-align="center" width="120">
<template #default="scope">
<span>{{ scope.row.phone || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="emails" label="邮箱" align="center" header-align="center" width="200">
<template #default="scope">
<span class="ellipsis-text" :title="scope.row.emails">{{ scope.row.emails || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="inviter" label="邀请人" align="center" header-align="center" width="100">
<template #default="scope">
<span>{{ scope.row.inviter || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="is_login" label="是否登录" align="center" header-align="center" width="90">
<template #default="scope">
<el-tag v-if="scope.row.is_login == 1" type="success" size="small" effect="light" class="login-tag">登录过</el-tag>
<el-tag v-else type="info" size="small" effect="light">未登录</el-tag>
</template>
</el-table-column>
<el-table-column prop="reg_time" label="注册时间" align="center" header-align="center" width="160">
<template #default="scope">
{{ scope.row.reg_time }}
</template>
</el-table-column>
<el-table-column prop="last_login_time" label="登录时间" align="center" header-align="center" width="160">
<template #default="scope">
{{ scope.row.last_login_time }}
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<div class="demo-pagination-block">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
/>
</div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import router from '../../router';
import {
marketListApi,
getOriginListApi,
userListApi,
exportUserListApi
} from '../../api/userPermissions';
// token
const token = localStorage.getItem('token')
//
const searchForm = reactive({
dccode: '',
name: '',
origin_id: '',
country: '',
is_login: '',
register_type: '',
regTimeRange: [],
loginTimeRange: []
});
//
const regionList = ref([]);
const isRegionLoading = ref(false);
//
const originList = ref([]);
const isOriginLoading = ref(false);
//
const tableData = ref([]);
const tableLoading = ref(false);
const total = ref(0);
//
const currentPage = ref(1);
const pageSize = ref(10);
//
const fetchRegionList = async () => {
try {
isRegionLoading.value = true;
const data = await marketListApi({
token: token,
app_form: "en"
});
regionList.value = data.list || [];
} catch (error) {
console.error('获取地区列表失败:', error);
regionList.value = [];
} finally {
isRegionLoading.value = false;
}
};
//
const fetchOriginList = async () => {
try {
isOriginLoading.value = true;
const data = await getOriginListApi({ token: token });
originList.value = data.list || [];
} catch (error) {
console.error('获取来源列表失败:', error);
originList.value = [];
} finally {
isOriginLoading.value = false;
}
};
//
const fetchTableData = async () => {
try {
tableLoading.value = true;
const requestParams = {
token: token,
page: currentPage.value,
page_size: pageSize.value,
dccode: searchForm.dccode,
name: searchForm.name,
origin_id: searchForm.origin_id,
country: searchForm.country,
is_login: searchForm.is_login,
phone: searchForm.register_type,
is_phone: searchForm.register_type ? 1 : 0,
email: searchForm.register_type,
reg_time_start: searchForm.regTimeRange && searchForm.regTimeRange[0] ? searchForm.regTimeRange[0] : '',
reg_time_end: searchForm.regTimeRange && searchForm.regTimeRange[1] ? searchForm.regTimeRange[1] : '',
list_login_time_start: searchForm.loginTimeRange && searchForm.loginTimeRange[0] ? searchForm.loginTimeRange[0] : '',
list_login_time_end: searchForm.loginTimeRange && searchForm.loginTimeRange[1] ? searchForm.loginTimeRange[1] : '',
reg_time_asc: '',
list_login_time_asc: ''
};
const data = await userListApi(requestParams);
tableData.value = data.list || [];
total.value = data.total || 0;
} catch (error) {
console.error('获取表格数据失败:', error);
tableData.value = [];
total.value = 0;
} finally {
tableLoading.value = false;
}
};
//
const handleSearch = () => {
currentPage.value = 1;
fetchTableData();
};
// Excel
const handleExport = async () => {
try {
const requestParams = {
token: token,
dccode: searchForm.dccode,
name: searchForm.name,
origin_id: searchForm.origin_id,
country: searchForm.country,
is_login: searchForm.is_login,
phone: searchForm.register_type,
is_phone: searchForm.register_type ? 1 : 0,
email: searchForm.register_type,
reg_time_start: searchForm.regTimeRange && searchForm.regTimeRange[0] ? searchForm.regTimeRange[0] : '',
reg_time_end: searchForm.regTimeRange && searchForm.regTimeRange[1] ? searchForm.regTimeRange[1] : '',
list_login_time_start: searchForm.loginTimeRange && searchForm.loginTimeRange[0] ? searchForm.loginTimeRange[0] : '',
list_login_time_end: searchForm.loginTimeRange && searchForm.loginTimeRange[1] ? searchForm.loginTimeRange[1] : ''
};
await exportUserListApi(requestParams);
ElMessage.success('导出任务已创建,请查看导出列表');
} catch (error) {
console.error('导出失败:', error);
ElMessage.error('导出失败,请重试');
}
};
//
const handleViewExport = () => {
router.push({
path: "/userPermissions/export"
});
};
//
const handleReset = () => {
searchForm.dccode = '';
searchForm.name = '';
searchForm.origin_id = '';
searchForm.country = '';
searchForm.is_login = '';
searchForm.register_type = '';
searchForm.regTimeRange = [];
searchForm.loginTimeRange = [];
currentPage.value = 1;
pageSize.value = 10;
fetchTableData();
};
//
const handleSizeChange = (val) => {
pageSize.value = val;
currentPage.value = 1;
fetchTableData();
};
const handleCurrentChange = (val) => {
currentPage.value = val;
fetchTableData();
};
//
onMounted(() => {
fetchRegionList();
fetchOriginList();
fetchTableData();
});
</script>
<style scoped>
/* 页面容器 */
.page-container {
padding: 20px;
background: #fff;
min-height: calc(100vh - 40px);
}
/* 搜索区域 */
.search-container {
background: #fefaf9;
border-radius: 8px;
padding: 20px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
}
.search-form {
display: flex;
flex-direction: column;
gap: 15px;
}
.search-row {
display: flex;
flex-wrap: wrap;
gap: 15px;
align-items: center;
}
.search-item {
display: flex;
align-items: center;
gap: 8px;
}
.form-label {
font-size: 14px;
color: #333;
white-space: nowrap;
font-weight: 500;
}
.button-group {
display: flex;
gap: 10px;
margin-top: 10px;
}
/* 表格样式 */
.table-rounded {
border-radius: 8px;
overflow: hidden;
border: 1px solid #e4e7ed;
}
.table-header {
background-color: #f5f7fa !important;
color: #606266;
font-weight: 600;
}
.ellipsis-text {
display: inline-block;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.login-tag {
background-color: #f0f9eb;
border-color: #e1f3d8;
color: #67c23a;
}
/* 分页 */
.demo-pagination-block {
display: flex;
justify-content: center;
margin-top: 20px;
padding: 10px 0;
}
</style>
Loading…
Cancel
Save