上线:用户管理页面中加入部门树,根据部门过滤用户,前后端接口数据完成调试

This commit is contained in:
zhangtao
2025-01-11 01:18:27 +08:00
parent 01c3cb1368
commit f5819f91b2
13 changed files with 135 additions and 116 deletions
+2 -2
View File
@@ -74,7 +74,7 @@
:loading="loading"
:dataSource="cacheNames"
:pagination="false"
:scroll="{ y: 600 }"
:scroll="{ y: 500 }"
rowKey="cache_name"
>
<a-table-column key="cache_name" title="缓存名称" align="center" :ellipsis="true">
@@ -149,7 +149,7 @@
<a-form-item label="缓存内容:" name="cache_value">
<a-textarea
v-model:value="cacheForm.cache_value"
:rows="19"
:rows="15"
readonly
/>
</a-form-item>
@@ -44,7 +44,6 @@
:data-source="tableData"
:loading="loading"
:scroll="{ x: 500 }"
:style="{ minHeight: '500px' }"
:pagination="pagination">
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'index'">
+4 -3
View File
@@ -57,15 +57,16 @@
</a-space>
</template>
<a-table
<a-table v-if="dataSource.length"
:defaultExpandAllRows="true"
:rowKey="record => record.id"
:columns="columns"
:data-source="dataSource"
:loading="tableLoading"
:scroll="{ x: 500, y: 'calc(100vh - 500px)' }"
:scroll="{ x: 500, y: 'calc(100vh - 300px)' }"
:row-selection="rowSelection"
:pagination="false"
:style="{ minHeight: '500px' }"
:style="{ minHeight: '300px' }"
>
<template #bodyCell="{ column, record }">
+2 -1
View File
@@ -57,7 +57,8 @@
@change="handleTableChange"
:scroll="{ x: 500 }"
:pagination="pagination"
:style="{ minHeight: '500px' }">
:style="{ minHeight: '300px'}"
>
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'index'">
<span>{{ (pagination.current - 1) * pagination.pageSize + index + 1 }}</span>
+4 -3
View File
@@ -57,15 +57,16 @@
</a-button>
</a-dropdown>
</template>
<a-table
<a-table v-if="dataSource.length"
:defaultExpandAllRows="true"
:rowKey="record => record.id"
:columns="columns"
:data-source="dataSource"
:loading="tableLoading"
:scroll="{ x: 500, y: 'calc(100vh - 500px)' }"
:scroll="{ x: 500, y: 'calc(100vh - 300px)' }"
:row-selection="rowSelection"
:pagination="false"
:style="{ minHeight: '500px' }"
:style="{ minHeight: '300px' }"
>
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'type'">
+2 -1
View File
@@ -68,7 +68,8 @@
@change="handleTableChange"
:scroll="{ x: 500 }"
:pagination="pagination"
:style="{ minHeight: '500px' }">
:style="{ minHeight: '300px' }"
>
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'index'">
<span>{{ (pagination.current - 1) * pagination.pageSize + index + 1 }}</span>
+2 -1
View File
@@ -73,7 +73,8 @@
@change="handleTableChange"
:scroll="{ x: 500 }"
:pagination="pagination"
:style="{ minHeight: '500px' }">
:style="{ minHeight: '300px' }"
>
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'index'">
<span>{{ (pagination.current - 1) * pagination.pageSize + index + 1 }}</span>
@@ -33,7 +33,7 @@
:checkedKeys="permissionState.dept_ids"
:rowKey="record => record.id"
:tree-data="deptTreeData"
:defaultExpandAll="true"
defaultExpandAll=true
:scroll="{ y: 1000 }"
:field-names="{ children: 'children', title: 'name', key: 'id' }"
@check="deptTreeCheck" checkable checkStrictly style="margin-top: 15px;" />
@@ -56,7 +56,9 @@
</div>
<div style="margin-top: 15px;">
<a-table :rowKey="record => record.id"
<a-table v-if="menuTreeData.length"
:rowKey="record => record.id"
:defaultExpandAllRows="true"
:columns="menuColumns"
:data-source="menuTreeData"
:row-selection="menuRowSelection"
+2 -1
View File
@@ -71,7 +71,8 @@
@change="handleTableChange"
:scroll="{ x: 500 }"
:pagination="pagination"
:style="{ minHeight: '500px' }">
:style="{ minHeight: '420px' }"
>
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'index'">
<span>{{ (pagination.current - 1) * pagination.pageSize + index + 1 }}</span>
+110 -101
View File
@@ -39,8 +39,10 @@
<!-- 表格区域 -->
<div class="table-wrapper">
<a-card title="用户列表" :bordered="false" :headStyle="{ borderBottom: 'none', padding: '20px 24px' }"
:bodyStyle="{ padding: '0 24px', minHeight: 'calc(100vh - 400px)' }">
<a-card title="用户管理"
:bordered="false"
:headStyle="{ borderBottom: 'none', padding: '20px 24px' }"
:bodyStyle="{ padding: '10px 24px', minHeight: 'calc(100vh - 400px)' }">
<template #extra>
<a-button type="primary" :icon="h(PlusOutlined)" @click="modalHandle('create')" style="margin-right: 10px;">
新建
@@ -67,52 +69,75 @@
</a-button>
</a-dropdown>
</template>
<a-table :rowKey="record => record.id"
:columns="columns"
:data-source="dataSource"
:row-selection="rowSelection"
:loading="tableLoading"
@change="handleTableChange"
:scroll="{ x: 500 }"
:pagination="pagination"
:style="{ minHeight: '500px' }">
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'index'">
<span>{{ (pagination.current - 1) * pagination.pageSize + index + 1 }}</span>
</template>
<template v-if="column.dataIndex === 'dept'">
<span>{{ record.dept_name }}</span>
</template>
<template v-if="column.dataIndex === 'roles'">
<span>{{ record.roleNames }}</span>
</template>
<template v-if="column.dataIndex === 'positions'">
<span>{{ record.positionNames }}</span>
</template>
<template v-if="column.dataIndex === 'gender'">
<a-tag :color="record.gender === 1 ? 'blue' : 'pink'">{{ record.gender === 1 ? '男' : '女' }}</a-tag>
</template>
<template v-if="column.dataIndex === 'available'">
<span>
<a-badge :status="record.available ? 'processing': 'error'" :text="record.available ? '启用' : '停用'" />
</span>
</template>
<template v-if="column.dataIndex === 'is_superuser'">
<span>
<a-badge :status="record.is_superuser ? 'processing': 'error'" :text="record.is_superuser ? '是' : '否'" />
</span>
</template>
<template v-if="column.dataIndex === 'operation'">
<a-space size="middle">
<a v-on:click="modalHandle('view', index)">查看</a>
<a v-on:click="modalHandle('update', index)">修改</a>
<a-popconfirm title="确定删除吗?" ok-text="确定" cancel-text="取消" @confirm="deleteRow(record)">
<a style="color: red;">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</a-table>
<!-- 使用 a-row a-col 划分左右布局 -->
<a-row :gutter="16">
<!-- 左侧部门树 -->
<a-col :span="4">
<a-tree ref="deptTree" v-if="deptTreeData.length"
:tree-data="deptTreeData"
:show-line="true"
:defaultExpandAll="true"
:field-names="{ children: 'children', title: 'name', key: 'id' }"
:selected-keys="selectedKeys"
@select="onSelectDept">
</a-tree>
</a-col>
<!-- 右侧用户列表 -->
<a-col :span="20">
<a-card title="用户列表" >
<a-table :rowKey="record => record.id"
:columns="columns"
:data-source="dataSource"
:row-selection="rowSelection"
:loading="tableLoading"
@change="handleTableChange"
:scroll="{ x: 300 }"
:pagination="pagination"
:style="{ minHeight: '310px' }">
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'index'">
<span>{{ (pagination.current - 1) * pagination.pageSize + index + 1 }}</span>
</template>
<template v-if="column.dataIndex === 'dept'">
<span>{{ record.dept_name }}</span>
</template>
<template v-if="column.dataIndex === 'roles'">
<span>{{ record.roleNames }}</span>
</template>
<template v-if="column.dataIndex === 'positions'">
<span>{{ record.positionNames }}</span>
</template>
<template v-if="column.dataIndex === 'gender'">
<a-tag :color="record.gender === 1 ? 'blue' : 'pink'">{{ record.gender === 1 ? '男' : '女' }}</a-tag>
</template>
<template v-if="column.dataIndex === 'available'">
<span>
<a-badge :status="record.available ? 'processing' : 'error'"
:text="record.available ? '启用' : '停用'" />
</span>
</template>
<template v-if="column.dataIndex === 'is_superuser'">
<span>
<a-badge :status="record.is_superuser ? 'processing' : 'error'"
:text="record.is_superuser ? '是' : '否'" />
</span>
</template>
<template v-if="column.dataIndex === 'operation'">
<a-space size="middle">
<a v-on:click="modalHandle('view', index)">查看</a>
<a v-on:click="modalHandle('update', index)">修改</a>
<a-popconfirm title="确定删除吗?" ok-text="确定" cancel-text="取消" @confirm="deleteRow(record)">
<a style="color: red;">删除</a>
</a-popconfirm>
</a-space>
</template>
</template>
</a-table>
</a-card>
</a-col>
</a-row>
</a-card>
</div>
@@ -139,10 +164,12 @@
<a-descriptions-item label="邮箱">{{ detailState.email }}</a-descriptions-item>
<a-descriptions-item label="联系电话">{{ detailState.mobile }}</a-descriptions-item>
<a-descriptions-item label="是否超管">
<a-badge :status="detailState.is_superuser ? 'processing': 'error'" :text="detailState.is_superuser ? '是' : '否'" />
<a-badge :status="detailState.is_superuser ? 'processing': 'error'"
:text="detailState.is_superuser ? '是' : '否'" />
</a-descriptions-item>
<a-descriptions-item label="状态">
<a-badge :status="detailState.available ? 'processing': 'error'" :text="detailState.available ? '启用' : '停用'" />
<a-badge :status="detailState.available ? 'processing': 'error'"
:text="detailState.available ? '启用' : '停用'" />
</a-descriptions-item>
<a-descriptions-item label="上次登录时间">{{ detailState.last_login }}</a-descriptions-item>
<a-descriptions-item label="创建人">{{ detailState.creator ? detailState.creator.name : '-'
@@ -283,29 +310,12 @@
</a-modal>
<!-- 导入对话框 -->
<a-modal v-model:open="upload.open"
title="导入用户"
:width="500"
@ok="submitFileForm"
:confirmLoading="upload.isUploading"
:bodyStyle="{ padding: '24px' }">
<a-modal v-model:open="upload.open" title="导入用户" :width="500" @ok="submitFileForm"
:confirmLoading="upload.isUploading" :bodyStyle="{ padding: '24px' }">
<div class="import-container">
<a-alert
message="请先下载模板,按照模板格式填写数据后再导入"
type="info"
show-icon
style="margin-bottom: 16px"
/>
<a-upload
ref="uploadRef"
:accept="'.xlsx, .xls'"
:showUploadList="true"
:beforeUpload="beforeUpload"
:customRequest="customRequest"
:maxCount="1"
:fileList="upload.fileList"
@remove="handleRemove"
>
<a-alert message="请先下载模板,按照模板格式填写数据后再导入" type="info" show-icon style="margin-bottom: 16px" />
<a-upload ref="uploadRef" :accept="'.xlsx, .xls'" :showUploadList="true" :beforeUpload="beforeUpload"
:customRequest="customRequest" :maxCount="1" :fileList="upload.fileList" @remove="handleRemove">
<a-button type="primary">
<upload-outlined></upload-outlined>
选择文件
@@ -315,12 +325,8 @@
<a-typography-text>
{{ file.name }}
</a-typography-text>
<a-progress
v-if="file.status === 'uploading'"
:percent="file.percent"
size="small"
style="width: 100px"
/>
<a-progress v-if="file.status === 'uploading'" :percent="file.percent" size="small"
style="width: 100px" />
</a-space>
</template>
</a-upload>
@@ -354,7 +360,7 @@
import { ref, reactive, computed, unref, onMounted, h } from 'vue';
import { Table, message, Modal } from 'ant-design-vue';
import type { TableColumnsType, MenuProps } from 'ant-design-vue';
import { PlusOutlined, DownOutlined, UploadOutlined, DownloadOutlined, CheckOutlined, StopOutlined, SearchOutlined } from '@ant-design/icons-vue';
import { CarryOutOutlined, SmileTwoTone, PlusOutlined, DownOutlined, UploadOutlined, DownloadOutlined, CheckOutlined, StopOutlined, SearchOutlined } from '@ant-design/icons-vue';
import { isEmpty, listToTree } from '@/utils/util';
import PageHeader from '@/components/PageHeader.vue';
import { getDeptList } from '@/api/system/dept'
@@ -363,6 +369,7 @@ import SelectorModal from './SelectorModal.vue'
import type { searchDataType, tableDataType, deptTreeType, roleSelectorType, positionSelectorType } from './types'
import storage from 'store';
const deptTree = ref(null);
const tableLoading = ref(false);
const openModal = ref(false);
const modalTitle = ref('');
@@ -476,20 +483,6 @@ const columns = reactive<TableColumnsType>([
align: 'center',
width: 100
},
{
title: '邮箱',
dataIndex: 'email',
ellipsis: true,
align: 'center',
width: 160
},
{
title: '联系电话',
dataIndex: 'mobile',
align: 'center',
ellipsis: true,
width: 120
},
{
title: '性别',
dataIndex: 'gender',
@@ -504,13 +497,6 @@ const columns = reactive<TableColumnsType>([
ellipsis: true,
width: 100
},
{
title: '备注',
dataIndex: 'description',
ellipsis: true,
align: 'center',
// width: 200
},
{
title: '操作',
dataIndex: 'operation',
@@ -536,6 +522,8 @@ const rowSelection = computed(() => {
}
});
const selectedKeys = ref<string[]>([]);
// 生命周期钩子
onMounted(() => loadingData());
@@ -559,6 +547,13 @@ const loadingData = () => {
if (queryState.available) {
params['available'] = queryState.available == "true" ? true : false;
}
if (queryState.dept_id) {
params['dept_id'] = queryState.dept_id; // 添加 dept_id 参数
selectedKeys.value = [queryState.dept_id]; // 选中对应的部门节点
} else {
selectedKeys.value = []; // 清除选中状态
}
params['page_no'] = pagination.current
params['page_size'] = pagination.pageSize
@@ -590,7 +585,11 @@ const resetFields = () => {
delete queryState[key];
});
pagination.current = 1;
queryState.available = null
queryState.available = null;
queryState.dept_id = null;
selectedKeys.value = [];
loadingData();
}
@@ -790,6 +789,16 @@ const handleSelectorModalEvent = (
}
}
// 部门选择器事件
const onSelectDept = (selectedKeys: string[], info: any) => {
if (selectedKeys.length > 0) {
queryState.dept_id = selectedKeys[0]; // 获取选中的部门 ID
} else {
queryState.dept_id = null; // 如果没有选中部门,则删除 dept_id 参数
}
loadingData(); // 重新加载用户列表
};
// 上传配置
const token = storage.get('Access-Token');
+1
View File
@@ -2,6 +2,7 @@ export interface searchDataType {
username?: string
name?: string
available?: string
dept_id?: number;
}
export interface searchSelectDataType {