diff --git a/docs/后台管理系统-Bug清单.md b/docs/后台管理系统-Bug清单.md new file mode 100644 index 00000000..bca99ea5 --- /dev/null +++ b/docs/后台管理系统-Bug清单.md @@ -0,0 +1,274 @@ +# 后台管理系统 Bug 清单 + +> 更新时间:2026-01-05 +> 涉及模块:角色管理、部门管理、管理员管理 + +--- + +## 一、后端 API 缺失问题 + +### BUG-001:部门菜单获取接口缺失 +- **严重程度**:🔴 高 +- **模块**:部门管理 +- **问题描述**:前端调用 `GET /api/admin/departments/{id}/menus` 获取部门已分配的菜单,但后端没有实现该接口 +- **影响**:部门管理页面点击"分配菜单"按钮后,无法加载该部门已有的菜单勾选状态 +- **前端代码位置**:`admin-web/src/api/department.ts` - `getDepartmentMenus()` +- **后端缺失**:`DepartmentController.cs` 缺少 `GET /{id}/menus` 接口 +- **修复方案**: + 1. 在 `IDepartmentService` 添加 `GetMenuIdsAsync(long departmentId)` 方法 + 2. 在 `DepartmentService` 实现该方法 + 3. 在 `DepartmentController` 添加 `[HttpGet("{id:long}/menus")]` 接口 + +--- + +## 二、前后端字段不匹配问题 + +### BUG-002:管理员查询参数不匹配 +- **严重程度**:🔴 高 +- **模块**:管理员管理 +- **问题描述**:前端使用 `keyword` 字段进行模糊搜索,后端期望 `Username`、`RealName`、`Phone` 分开的字段 +- **影响**:管理员列表页面的搜索功能完全失效 +- **前端参数**: + ```typescript + interface AdminUserQuery { + keyword?: string // 前端传这个 + departmentId?: number + status?: number + } + ``` +- **后端参数**: + ```csharp + public class AdminUserQueryRequest { + public string? Username { get; set; } // 后端期望这些 + public string? RealName { get; set; } + public string? Phone { get; set; } + } + ``` +- **修复方案**:后端添加 `Keyword` 字段,在 Service 中实现对用户名、姓名、手机号的模糊搜索,移除其它字段。 + +### BUG-003:管理员列表角色字段格式不匹配 +- **严重程度**:🔴 高 +- **模块**:管理员管理 +- **问题描述**:前端期望 `roles` 是对象数组,后端返回的是两个独立数组 +- **影响**:管理员列表页面无法正确显示用户的角色标签 +- **前端期望**: + ```typescript + roles: { id: number; name: string }[] + ``` +- **后端返回**: + ```csharp + RoleIds: List + RoleNames: List + ``` +- **修复方案**: + - 方案A(推荐):后端修改 `AdminUserDto`,添加 `Roles` 属性返回对象数组 + - 方案B:前端修改类型定义,适配后端返回格式 + +### BUG-004:管理员列表时间字段名不匹配 +- **严重程度**:🟡 中 +- **模块**:管理员管理 +- **问题描述**:前端期望 `lastLoginAt`,后端返回 `LastLoginTime` +- **影响**:最后登录时间列显示为空 +- **前端期望**:`lastLoginAt` +- **后端返回**:`LastLoginTime`(JSON 序列化后为 `lastLoginTime`) +- **修复方案**:前端修改字段名为 `lastLoginTime` + +--- + +## 三、功能逻辑问题 + +### BUG-005:权限编码不匹配导致按钮不显示 +- **严重程度**:🔴 高 +- **模块**:角色管理、部门管理、管理员管理 +- **问题描述**:多个页面的操作按钮因权限编码不匹配而不显示 +- **根本原因**:前端权限指令中使用连字符 `-`,后端初始化使用下划线 `_` + +#### 权限编码对照表 + +| 页面 | 前端使用(连字符) | 后端定义(下划线) | 影响按钮 | +|------|-------------------|-------------------|----------| +| 角色管理 | `role:assign-menu` | `role:assign_menu` | 分配菜单 | +| 角色管理 | `role:assign-permission` | `role:assign_permission` | 分配权限 | +| 部门管理 | `department:assign-menu` | `department:assign_menu` | 分配菜单 | +| 管理员管理 | `user:assign-role` | `user:assign_role` | 分配角色 | +| 管理员管理 | `user:assign-department` | `user:assign_department` | 分配部门 | +| 管理员管理 | `user:assign-menu` | ❌ 未定义 | 专属菜单 | +| 管理员管理 | `user:reset-password` | `user:reset_password` | 重置密码 | + +- **影响**: + 1. 角色管理页面看不到"分配菜单"、"分配权限"按钮 + 2. 部门管理页面看不到"分配菜单"按钮 + 3. 管理员管理页面看不到"分配角色"、"分配部门"、"专属菜单"、"重置密码"按钮 +- **修复方案**: + - 方案A(推荐):前端统一改为下划线格式,与后端保持一致 + - 方案B:后端修改权限编码为连字符格式 + - 注意:`user:assign-menu`(专属菜单)后端完全没有定义,需要补充 + +### BUG-006:管理员专属菜单权限未定义 +- **严重程度**:🟡 中 +- **模块**:管理员管理 +- **问题描述**:前端使用 `user:assign-menu` 权限控制"专属菜单"按钮,但后端 DataSeeder 中没有初始化该权限 +- **影响**:即使修复了权限编码格式问题,该按钮仍然不会显示 +- **修复方案**:在 DataSeeder.cs 中添加权限: + ```csharp + new() { Name = "分配专属菜单", Code = "user:assign_menu", Module = "管理员管理", CreatedAt = DateTime.Now }, + ``` + +### BUG-007:部门管理 - 分配菜单功能异常 +- **严重程度**:🔴 高 +- **模块**:部门管理 +- **问题描述**:同 BUG-001,由于后端接口缺失,无法获取部门已分配的菜单 +- **修复方案**:见 BUG-001 + +### BUG-008:管理员管理 - 无法查看用户详情 +- **严重程度**:🟡 中 +- **模块**:管理员管理 +- **问题描述**:列表页面无法直观看到用户的角色、部门、专属菜单信息 +- **影响**: + 1. 角色列显示异常(BUG-003 导致) + 2. 部门名称可能显示为空 + 3. 没有入口查看用户的专属菜单 +- **修复方案**: + 1. 修复 BUG-003 + 2. 确保后端正确返回 `departmentName` + 3. 考虑添加"查看详情"功能或在分配菜单弹窗中显示当前菜单 + +--- + +## 四、数据展示问题 + +### BUG-009:管理员列表 - 角色标签不显示 +- **严重程度**:🔴 高 +- **模块**:管理员管理 +- **问题描述**:角色列的 `el-tag` 无法正确渲染 +- **前端代码**: + ```vue + + {{ role.name }} + + ``` +- **原因**:`row.roles` 不存在,后端返回的是 `roleIds` 和 `roleNames` +- **修复方案**:见 BUG-003 + +### BUG-010:管理员列表 - 部门名称可能为空 +- **严重程度**:🟡 中 +- **模块**:管理员管理 +- **问题描述**:部门列可能显示为空 +- **原因**:需要确认后端 `AdminUserDto.DepartmentName` 是否正确填充 +- **修复方案**:检查后端 Service 中的查询是否正确 Include 了 Department + +### BUG-011:管理员列表 - 表头与数据列错位 +- **严重程度**:🔴 高 +- **模块**:管理员管理 +- **问题描述**:表格表头和实际内容对应不上,例如"姓名"列显示的是其他字段的数据 +- **现象**:姓名列可能显示"超级管理员"等不正确的内容 +- **可能原因**: + 1. 后端返回的字段顺序或字段名与前端期望不一致 + 2. 角色列因为 `row.roles` 不存在导致渲染异常,影响后续列的显示 + 3. JSON 序列化时字段名大小写问题(后端 `RealName` vs 前端期望 `realName`) +- **前端表格列定义**: + ``` + username → 用户名 + realName → 姓名 + departmentName → 部门 + phone → 手机号 + roles → 角色(对象数组,但后端返回 roleIds/roleNames) + status → 状态 + lastLoginAt → 最后登录(后端是 lastLoginTime) + ``` +- **修复方案**: + 1. 修复 BUG-003(角色字段格式) + 2. 修复 BUG-004(时间字段名) + 3. 确认后端 JSON 序列化配置使用 camelCase + +### BUG-012:管理员表单 - 邮箱不应该是必填项 +- **严重程度**:🟢 低 +- **模块**:管理员管理 +- **问题描述**:新增/编辑管理员时,邮箱字段不应该是必填的 +- **当前状态**:需要确认前端表单验证规则是否将邮箱设为必填 +- **修复方案**:检查 `formRules` 中 `email` 字段的验证规则,移除 `required: true` + +### BUG-013:部门表单 - 新增时残留上次数据 +- **严重程度**:🟡 中 +- **模块**:部门管理 +- **问题描述**:点击"新增部门"按钮时,表单中会显示上一次新增/编辑的数据,而不是空白表单 +- **原因**:`resetForm()` 方法可能没有正确清空表单数据,或者 `el-dialog` 关闭时没有触发重置 +- **前端代码位置**:`admin-web/src/views/system/department/index.vue` - `handleAdd()` 和 `resetForm()` +- **修复方案**: + 1. 确保 `handleAdd()` 调用 `resetForm()` 清空数据 + 2. 检查 `el-dialog` 的 `@close` 事件是否正确绑定 `resetForm` + 3. 使用 `formRef.value?.resetFields()` 重置表单验证状态 + +--- + +## 五、修复优先级 + +| 优先级 | Bug编号 | 问题 | 修复工作量 | +|--------|---------|------|------------| +| P0 | BUG-005 | 权限编码不匹配(连字符vs下划线) | 前端 10分钟 | +| P0 | BUG-001 | 部门菜单获取接口缺失 | 后端 30分钟 | +| P0 | BUG-002 | 管理员查询参数不匹配 | 后端 20分钟 | +| P0 | BUG-003 | 角色字段格式不匹配 | 后端 20分钟 或 前端 10分钟 | +| P0 | BUG-011 | 管理员列表表头与数据错位 | 依赖 BUG-003/004 | +| P1 | BUG-006 | 管理员专属菜单权限未定义 | 后端 5分钟 | +| P1 | BUG-004 | 时间字段名不匹配 | 前端 5分钟 | +| P1 | BUG-007 | 部门分配菜单异常 | 依赖 BUG-001 | +| P2 | BUG-008 | 无法查看用户详情 | 依赖其他Bug | +| P2 | BUG-009 | 角色标签不显示 | 依赖 BUG-003 | +| P2 | BUG-010 | 部门名称为空 | 需排查 | +| P3 | BUG-012 | 邮箱不应该是必填项 | 前端 2分钟 | +| P2 | BUG-013 | 部门新增时残留上次数据 | 前端 5分钟 | + +--- + +## 六、修复清单 + +### 后端修改 + +1. **DepartmentController.cs** - 添加获取部门菜单接口 `GET /{id}/menus` +2. **IDepartmentService.cs** - 添加 `GetMenuIdsAsync` 方法声明 +3. **DepartmentService.cs** - 实现 `GetMenuIdsAsync` 方法 +4. **AdminUserQueryRequest.cs** - 添加 `Keyword` 字段 +5. **AdminUserService.cs** - 修改查询逻辑支持 `Keyword` 模糊搜索 +6. **AdminUserDto.cs** - 添加 `Roles` 属性(对象数组格式) +7. **AdminUserService.cs** - 修改映射逻辑填充 `Roles` +8. **DataSeeder.cs** - 添加 `user:assign_menu` 权限 + +### 前端修改 + +1. **role/index.vue** - 权限编码改为下划线格式: + - `role:assign-menu` → `role:assign_menu` + - `role:assign-permission` → `role:assign_permission` +2. **department/index.vue** - 权限编码改为下划线格式: + - `department:assign-menu` → `department:assign_menu` +3. **user/index.vue** - 权限编码改为下划线格式: + - `user:assign-role` → `user:assign_role` + - `user:assign-department` → `user:assign_department` + - `user:assign-menu` → `user:assign_menu` + - `user:reset-password` → `user:reset_password` +4. **adminUser.ts** - 修改 `AdminUser` 接口,`lastLoginAt` → `lastLoginTime` +5. **user/index.vue** - 修改表格列绑定字段名 `lastLoginAt` → `lastLoginTime` +6. **user/index.vue** - 根据后端修改调整角色显示逻辑(使用 `roleNames` 或等待后端返回 `roles`) +7. **user/index.vue** - 移除邮箱字段的必填验证(如果有的话) +8. **department/index.vue** - 修复新增部门时表单数据残留问题 + +--- + +## 七、测试验证 + +修复完成后需要验证: + +- [ ] 角色管理 - 分配菜单能正确加载已勾选项 +- [ ] 角色管理 - 分配菜单能正确保存 +- [ ] 角色管理 - 分配权限能正确加载和保存 +- [ ] 部门管理 - 分配菜单能正确加载已勾选项 +- [ ] 部门管理 - 分配菜单能正确保存 +- [ ] 管理员管理 - 列表搜索功能正常 +- [ ] 管理员管理 - 角色列正确显示 +- [ ] 管理员管理 - 部门列正确显示 +- [ ] 管理员管理 - 最后登录时间正确显示 +- [ ] 管理员管理 - 分配角色能正确加载和保存 +- [ ] 管理员管理 - 分配部门能正确加载和保存 +- [ ] 管理员管理 - 分配专属菜单能正确加载和保存 +- [ ] 新增管理员功能正常 +- [ ] 编辑管理员功能正常 diff --git a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/system/department/index.vue b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/system/department/index.vue index 1105959a..e2ce6126 100644 --- a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/system/department/index.vue +++ b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/system/department/index.vue @@ -133,7 +133,7 @@ const formRules: FormRules = { name: [{ required: true, message: '请输入部门名称', trigger: 'blur' }], code: [ { required: true, message: '请输入部门编码', trigger: 'blur' }, - { pattern: /^[a-z_]+$/, message: '只能包含小写字母和下划线', trigger: 'blur' } + { pattern: /^[a-z0-9_]+$/, message: '只能包含小写字母、数字和下划线', trigger: 'blur' } ] }