From a6fc7b48dc6fcd26aa7b8450e46c988ecb9bcd28 Mon Sep 17 00:00:00 2001 From: dk <1260500659@qq.com> Date: Tue, 14 Apr 2026 16:33:47 +0800 Subject: [PATCH] =?UTF-8?q?feat(user-management-relation):=20=E5=9C=A8?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=E9=9B=86?= =?UTF-8?q?=E6=88=90=E7=94=A8=E6=88=B7=E5=B8=A6=E4=BA=BA=E5=85=B3=E7=B3=BB?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=EF=BC=8C=E5=B9=B6=E4=BF=AE=E5=A4=8D=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=9A=84=E8=AF=B8=E5=A4=9ABUG=E5=92=8C=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/service/api/system-manage.ts | 14 +- src/typings/api/system-manage.d.ts | 23 +-- src/views/system/role/index.vue | 4 + .../system/user-management-relation/index.vue | 138 +++++++++++------- .../modules/relation-operate-dialog.vue | 14 +- .../modules/relation-search.vue | 14 +- src/views/system/user/index.vue | 78 ++++++---- 7 files changed, 187 insertions(+), 98 deletions(-) diff --git a/src/service/api/system-manage.ts b/src/service/api/system-manage.ts index 8d00b9c..6296a39 100644 --- a/src/service/api/system-manage.ts +++ b/src/service/api/system-manage.ts @@ -318,6 +318,15 @@ export function fetchGetUserPage(params?: Api.SystemManage.UserSearchParams) { /** 为兼容旧代码保留原函数名 */ export const fetchGetUserList = fetchGetUserPage; +/** 通过部门id获取用户详情 */ +export function fetchGetUserListByDeptId(deptId: any) { + return request({ + url: `${USER_PREFIX}/list-by-dept-id`, + method: 'get', + params: { deptId } + }); +} + /** 获取用户详情 */ export function fetchGetUser(id: number) { return request({ @@ -487,10 +496,11 @@ export function fetchAssignUserRoles(data: Api.SystemManage.AssignUserRoleParams * - 中间节点:有上级也有下级 * - 叶子节点:基层员工,没有下级 */ -export function fetchGetUserManagementRelationTree() { +export function fetchGetUserManagementRelationTree(query: UserManagementRelationQueryReqVO) { return request({ url: `${USER_MANAGEMENT_RELATION_PREFIX}/tree`, - method: 'get' + method: 'get', + params: query }); } diff --git a/src/typings/api/system-manage.d.ts b/src/typings/api/system-manage.d.ts index 306d04e..ce79f45 100644 --- a/src/typings/api/system-manage.d.ts +++ b/src/typings/api/system-manage.d.ts @@ -40,8 +40,8 @@ declare namespace Api { type RoleSearchParams = CommonType.RecordNullable> & PageParams & { - createTime?: string[]; - }; + createTime?: string[]; + }; type SaveRoleParams = Pick & { remark?: string | null; @@ -143,12 +143,12 @@ declare namespace Api { type UserSearchParams = CommonType.RecordNullable< Pick & - Pick & { - username?: string; - mobile?: string; - deptId?: number; - roleId?: number; - } + Pick & { + username?: string; + mobile?: string; + deptId?: number; + roleId?: number; + } >; type UserList = PageResult; @@ -387,7 +387,12 @@ declare namespace Api { * 对应后端 UserManagementRelationQueryReqVO */ type UserManagementRelationQueryReqVO = CommonType.RecordNullable< - Pick + Pick & { + /** 是否来自带人关系的index组件 */ + fromUserIndex: boolean; + /** 部门ID */ + deptId?: number | null; + } >; /** diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index 2cb9bcf..02f9a3f 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -325,4 +325,8 @@ getMenuTreeData(); :deep(.el-table__row.current-row > td.el-table__cell) { background-color: rgb(64 158 255 / 8%); } + +:deep(.el-row) { + margin: 0 0 -15px 0; +} diff --git a/src/views/system/user-management-relation/index.vue b/src/views/system/user-management-relation/index.vue index bc5f151..89c3c64 100644 --- a/src/views/system/user-management-relation/index.vue +++ b/src/views/system/user-management-relation/index.vue @@ -15,21 +15,33 @@ * - 叶子节点:基层员工,没有下级 */ -import { nextTick, onMounted, reactive, ref } from 'vue'; -import type { ElTree } from 'element-plus'; -import { ElButton, ElPopconfirm, ElTag } from 'element-plus'; -import { useBoolean } from '@sa/hooks'; +import {nextTick, onMounted, reactive, ref} from 'vue'; +import type {ElTree} from 'element-plus'; +import {ElButton, ElPopconfirm, ElTag} from 'element-plus'; +import {useBoolean} from '@sa/hooks'; import { fetchBatchDeleteUserManagementRelation, - fetchDeleteUserManagementRelation, + fetchDeleteUserManagementRelation, fetchGetUserListByDeptId, fetchGetUserManagementRelationQuery, fetchGetUserManagementRelationTree, - fetchGetUserSimpleList } from '@/service/api'; import RelationOperateDialog from './modules/relation-operate-dialog.vue'; import RelationSearch from './modules/relation-search.vue'; -defineOptions({ name: 'UserManagementRelation' }); +defineOptions({name: 'UserManagementRelation'}); + +/** + * 组件 userQuery 定义 + * + * @param fromUserIndex 是否不是从带人关系 index 页面访问(从 user 页面访问时为 true) + */ +interface userQuery { + fromUserIndex?: boolean; + deptId?: number | null; +} + +//从user的index组件访问带人关系,fromUserIndex为true,否则false; dept=100是灿能电力的id +const {fromUserIndex = false, deptId = 100} = defineProps() /** * 初始化搜索参数 @@ -74,7 +86,7 @@ const treeProps: any = { * 获取用户简单列表,供搜索组件和对话框组件共享使用 */ async function loadUserList() { - const { data, error } = await fetchGetUserSimpleList(); + const {data, error} = await fetchGetUserListByDeptId(deptId); if (!error) { userList.value = data || []; } @@ -89,7 +101,12 @@ async function loadTreeData() { loading.value = true; try { - const { data, error } = await fetchGetUserManagementRelationTree(); + // 默认不是来自user的index组件访问且deptId=100,查询灿能电力及其以下所有部门的用户的带人关系 + const query: Api.SystemManage.UserManagementRelationQueryReqVO = { + fromUserIndex: fromUserIndex, + deptId: deptId + }; + const {data, error} = await fetchGetUserManagementRelationTree(query); if (!error) { treeData.value = data || []; @@ -110,7 +127,7 @@ async function loadTreeDataByQuery(query: Api.SystemManage.UserManagementRelatio loading.value = true; try { - const { data, error } = await fetchGetUserManagementRelationQuery(query); + const {data, error} = await fetchGetUserManagementRelationQuery(query); if (!error) { treeData.value = data || []; @@ -143,13 +160,13 @@ async function handleSearch() { // 判断是否有搜索条件 const hasSearchCondition = searchParams.subordinateUserId !== undefined && searchParams.subordinateUserId !== null; - if (hasSearchCondition) { // 有搜索条件,调用查询接口 const query: Api.SystemManage.UserManagementRelationQueryReqVO = { - subordinateUserId: searchParams.subordinateUserId + subordinateUserId: searchParams.subordinateUserId, + fromUserIndex: fromUserIndex, + deptId: deptId }; - console.log('查询参数 query:', query); await loadTreeDataByQuery(query); } else { // 无搜索条件,加载完整树 @@ -171,7 +188,7 @@ function resetSearchParams() { } // 对话框相关状态 -const { bool: operateVisible, setTrue: openOperateModal, setFalse: closeOperateModal } = useBoolean(); +const {bool: operateVisible, setTrue: openOperateModal, setFalse: closeOperateModal} = useBoolean(); const operateType = ref('add'); const editingData = ref(null); @@ -186,14 +203,14 @@ function openAdd(item?: Api.SystemManage.UserManagementRelationTreeRespVO) { // 否则默认管理者为当前登录用户(在对话框组件中处理) editingData.value = item ? { - id: null, - managerUserId: item.userId, - subordinateUserId: null, - effectiveFrom: null, - effectiveUntil: null, - remark: null, - createTime: Date.now() - } + id: null, + managerUserId: item.userId, + subordinateUserId: null, + effectiveFrom: null, + effectiveUntil: null, + remark: null, + createTime: Date.now() + } : null; openOperateModal(); } @@ -208,14 +225,14 @@ function openEdit(item: Api.SystemManage.UserManagementRelationTreeRespVO) { // 构建树节点数据为编辑所需格式 editingData.value = item.id ? { - id: item.id, - managerUserId: item.managerUserId, - subordinateUserId: item.userId, - effectiveFrom: null, - effectiveUntil: null, - remark: null, - createTime: Date.now() - } + id: item.id, + managerUserId: item.managerUserId, + subordinateUserId: item.userId, + effectiveFrom: null, + effectiveUntil: null, + remark: null, + createTime: Date.now() + } : null; openOperateModal(); } @@ -226,7 +243,7 @@ function openEdit(item: Api.SystemManage.UserManagementRelationTreeRespVO) { * @param item 要删除的关系记录 */ async function handleDelete(item: Api.SystemManage.UserManagementRelationTreeRespVO) { - const { error } = await fetchDeleteUserManagementRelation(item.id); + const {error} = await fetchDeleteUserManagementRelation(item.id); if (error) { return; @@ -246,7 +263,7 @@ async function handleBatchDelete() { return; } - const { error } = await fetchBatchDeleteUserManagementRelation(checkedNodeKeys.value); + const {error} = await fetchBatchDeleteUserManagementRelation(checkedNodeKeys.value); if (error) { return; @@ -287,6 +304,25 @@ function hasChildren(node: Api.SystemManage.UserManagementRelationTreeRespVO): b return Boolean(node.children && node.children.length > 0); } +/** + * 计算树形数据中所有节点的数量 + * + * 递归遍历树形结构,统计所有节点总数 + * + * @param nodes 树形数据数组 + * @returns 节点总数 + */ +function countTreeNodes(nodes: Api.SystemManage.UserManagementRelationTreeRespVO[]): number { + let count = 0; + for (const node of nodes) { + count += 1; + if (node.children && node.children.length > 0) { + count += countTreeNodes(node.children); + } + } + return count; +} + onMounted(async () => { await loadUserList(); await reloadTreeData(); @@ -309,28 +345,28 @@ onMounted(async () => {

用户带人关系树

- {{ treeData.length }} + {{ countTreeNodes(treeData) }}
新增 - - - + + + + + + + + + + 刷新 @@ -346,7 +382,6 @@ onMounted(async () => { :data="treeData" :props="treeProps" node-key="userId" - show-checkbox default-expand-all :expand-on-click-node="false" @check="handleNodeCheck" @@ -355,18 +390,18 @@ onMounted(async () => {
{{ node.label }} - 上级:{{ data.managerNickname }} +
新增 编辑 @@ -378,14 +413,13 @@ onMounted(async () => { - 有下级 - 不可删除 +
diff --git a/src/views/system/user-management-relation/modules/relation-operate-dialog.vue b/src/views/system/user-management-relation/modules/relation-operate-dialog.vue index a28b994..eb04f59 100644 --- a/src/views/system/user-management-relation/modules/relation-operate-dialog.vue +++ b/src/views/system/user-management-relation/modules/relation-operate-dialog.vue @@ -281,28 +281,34 @@ watch(visible, value => { + + - + - + + + @@ -313,4 +319,6 @@ watch(visible, value => { - + diff --git a/src/views/system/user-management-relation/modules/relation-search.vue b/src/views/system/user-management-relation/modules/relation-search.vue index 97ae85d..61a924c 100644 --- a/src/views/system/user-management-relation/modules/relation-search.vue +++ b/src/views/system/user-management-relation/modules/relation-search.vue @@ -14,9 +14,9 @@ * - 用户列表通过 props 传入,由父组件统一管理 */ -import { defineEmits, defineModel, defineOptions } from 'vue'; +import {defineEmits, defineModel, defineOptions} from 'vue'; -defineOptions({ name: 'RelationSearch' }); +defineOptions({name: 'RelationSearch'}); /** * 组件 Emits 定义 @@ -43,7 +43,7 @@ defineProps(); /** * 搜索参数模型,支持双向绑定 */ -const model = defineModel('model', { required: true }); +const model = defineModel('model', {required: true}); /** * 重置搜索 @@ -81,9 +81,9 @@ function search() { - + - + @@ -94,4 +94,8 @@ function search() { :deep(.el-form-item__label) { width: 100px !important; } + +:deep(.el-row) { + margin: 0 0 -15px 0; +} diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index ce6710d..ad62320 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -1,10 +1,10 @@