# 用户管理接口适配设计规范 **工单**: #2 - 用户管理接口变更通知 **日期**: 2026-06-07 **方案**: 方案 B(完整适配) --- ## 1. 背景 后端已完成用户管理模块接口重构(提交 `dbd04d8`),支持部门、角色联表查询和聚合信息返回。前端需要适配以: - 减少请求次数(从 3 个请求合并为 1 个) - 支持部门/角色筛选 - 在列表和详情中展示部门、角色信息 ## 2. 后端变更摘要 ### 2.1 用户实体扩展字段 ```json { "id": 1, "username": "admin", "phone": "13800138000", "depts": [ { "deptId": 1, "deptCode": "TECH", "deptName": "技术部", "main": true } ], "roles": [ { "roleId": 1, "roleCode": "admin", "roleName": "管理员", "dataScope": 1 } ] } ``` ### 2.2 新增接口 - `GET /user/admin/user/{id}/aggregate` - 聚合查询(基础信息 + 部门列表 + 角色列表) ### 2.3 增强接口 - `GET /user/admin/user/page` - 自动返回 `depts` 和 `roles` - `GET /user/admin/user/list` - 自动返回 `depts` 和 `roles` - 支持筛选参数:`deptId`、`roleId` ## 3. 前端适配范围 ### 3.1 用户列表页 (`views/user/info/Index.vue`) **新增列:** - 部门列:显示用户所属部门名称(多个部门用逗号分隔,主部门加粗) - 角色列:显示用户角色名称(多个角色用标签展示) **新增筛选条件:** - 部门筛选:树形选择器(`el-tree-select`),支持多选 - 角色筛选:树形选择器(`el-tree-select`),支持多选 **数据流:** - 列表接口自动返回 `depts` 和 `roles`,无需额外请求 - 筛选参数通过 `queryParams` 传递给 `userService.page()` ### 3.2 用户详情弹窗 (`views/user/info/UserDetailDialog.vue`) **改造:** - 使用新的聚合接口 `GET /user/admin/user/{id}/aggregate` - 展示部门列表(部门名称 + 是否主部门标记) - 展示角色列表(角色名称 + 数据范围) **数据流:** ``` 打开弹窗 → 调用 aggregate 接口 → 展示完整信息 ``` ### 3.3 用户表单 (`views/user/info/UserFormDialog.vue`) **优化:** - 编辑时从 `row.depts` 解析 `deptIds`(替代调用 `userDeptService.listDeptIdsByUserId`) - 编辑时从 `row.roles` 解析 `roleIds`(替代调用 `userService.getRoles`) - 保留 `userDeptService.assignDepts` 和 `userPostService.assignPosts` 用于保存 ### 3.4 Service 层扩展 (`service/user/userService.ts`) **新增方法:** - `aggregate(userId)` - 调用聚合查询接口 ## 4. 组件设计 ### 4.1 部门/角色展示组件 无需新增组件,直接在表格列中使用 `slot` 渲染: ```vue ``` ### 4.2 筛选区域 ```vue ``` ## 5. 数据类型定义 ```typescript // 部门信息(嵌套在用户中) interface UserDept { deptId: number deptCode: string deptName: string main: boolean } // 角色信息(嵌套在用户中) interface UserRole { roleId: number roleCode: string roleName: string dataScope: number } // 扩展用户类型 interface User { id: number username: string // ... 其他字段 depts?: UserDept[] roles?: UserRole[] } ``` ## 6. 接口调用变更 ### 6.1 列表页 **变更前:** - 调用 `userService.page(params)` - 仅返回基础信息 **变更后:** - 调用 `userService.page(params)` - 自动包含 `depts` 和 `roles` - 支持 `deptId` 和 `roleId` 筛选参数 ### 6.2 详情弹窗 **变更前:** - 直接使用 `props.row` 数据 **变更后:** - 打开时调用 `userService.aggregate(props.row.id)` - 使用返回的完整数据渲染 ### 6.3 编辑表单 **变更前:** ```typescript // 需要额外请求获取部门和角色 const deptIds = await userDeptService.listDeptIdsByUserId(userId) const roleIds = await userService.getRoles(userId) ``` **变更后:** ```typescript // 直接从 row 中解析 const deptIds = props.row.depts?.map((d: any) => d.deptId) || [] const roleIds = props.row.roles?.map((r: any) => r.roleId) || [] ``` ## 7. 错误处理 - 聚合接口失败时,回退到使用 `props.row` 基础信息 - 部门/角色数据缺失时,显示 "-" 或空标签 - 筛选条件不影响现有查询逻辑 ## 8. 兼容性 - 原有接口保持不变 - 新增字段通过 `@TableField(exist = false)` 添加,不影响旧逻辑 - 保留 `userDeptService` 和 `userPostService` 用于分配功能 ## 9. 测试要点 1. 列表页是否正确显示部门和角色信息 2. 部门/角色筛选是否生效 3. 详情弹窗是否正确展示聚合数据 4. 编辑表单是否正确解析已选部门/角色 5. 保存后数据是否正确刷新 ## 10. 文件变更清单 | 文件 | 变更类型 | 说明 | |------|---------|------| | `views/user/info/Index.vue` | 修改 | 添加部门/角色列和筛选条件 | | `views/user/info/UserDetailDialog.vue` | 修改 | 使用聚合接口,展示部门/角色详情 | | `views/user/info/UserFormDialog.vue` | 修改 | 从 row 解析 deptIds/roleIds | | `service/user/userService.ts` | 修改 | 添加 aggregate 方法 | --- **设计评审状态**: 待评审 **下一步**: 用户评审通过后,编写实施计划