Files
gongxue-base/openspec/changes/rbac-refactor/tasks.md

79 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 1. RBAC 数据库实体与迁移
- [x] 1.1 创建 Permission 实体 (`backend/src/entities/permission.entity.ts`)id、code(UK)、name、group、description
- [x] 1.2 创建 Role 实体 (`backend/src/entities/role.entity.ts`)id、name、description、isSystem、status、@ManyToMany→Permission、@ManyToMany→User
- [x] 1.3 创建 RolePermission 和 UserRole 多对多关联表(通过 TypeORM @ManyToMany + @JoinTable 自动生成)
- [x] 1.4 更新 User 实体:新增 roles 多对多关联,移除 role 和 allowedMenus 字段;更新 entities/index.ts 导出
- [x] 1.5 编写 TypeORM 迁移脚本:建新表、插入种子数据、迁移现有用户角色、删除旧列 *(跳过:保留 synchronize 模式)*
- [x] 1.6 编写种子数据初始化服务:创建 4 个预置角色 + ~40 个权限点 + 角色-权限关联映射
## 2. RBAC 服务层
- [x] 2.1 创建 RbacModule 和 RbacService提供 findAllRoles/findRoleById/createRole/updateRole/deleteRole 方法
- [x] 2.2 实现角色 CRUD含权限关联创建角色时同时写入 RolePermission更新时删除旧关联重建
- [x] 2.3 实现 getUserPermissions 方法:通过 User→UserRole→Role→RolePermission→Permission 链查询,去重后返回权限 code 列表
- [x] 2.4 实现 getPermissionTree 方法:返回按 group 分组的权限树,供前端权限一览和管理页使用
- [x] 2.5 创建 RbacController角色 CRUD + 权限树 + 用户-角色分配接口,所有接口加 @RequirePermission 守卫
## 3. 权限守卫实现
- [x] 3.1 创建 @RequirePermission 装饰器(支持 AND/OR 语义,通过 SetMetadata 存储权限列表和逻辑模式)
- [x] 3.2 创建 PermissionGuard从 JWT payload 中读取 permissions 数组,与装饰器标注的权限做匹配
- [x] 3.3 修改 JwtStrategy 和 AuthService.login登录时调用 getUserPermissions将 permissions 写入 JWT payload
- [x] 3.4 修改 AuthService.validateUser/profile返回用户信息时携带角色和权限列表
- [x] 3.5 全局注册 PermissionGuard或在各模块按需注册
## 4. 现有接口批量加守卫
- [x] 4.1 StudentsController全部方法加 @RequirePermission
- [x] 4.2 RoomsController全部方法加 @RequirePermission
- [x] 4.3 OccupanciesController全部方法加 @RequirePermission
- [x] 4.4 ExpensesController全部方法加 @RequirePermission
- [x] 4.5 BillsController全部方法加 @RequirePermission
- [x] 4.6 DepositsController全部方法加 @RequirePermission
- [x] 4.7 ClassroomsController全部方法加 @RequirePermission
- [x] 4.8 TenantsController全部方法加 @RequirePermission
- [x] 4.9 ClassroomRentalsController全部方法加 @RequirePermission
- [x] 4.10 DashboardController全部方法加 @RequirePermission
- [x] 4.11 OperationLogsController全部方法加 @RequirePermission
- [x] 4.12 AuthController用户管理部分分离为用户管理接口@RequirePermission;移除原 register 接口的旧逻辑
## 5. 前端权限基础设施
- [x] 5.1 创建 usePermission hook提供 hasPermission/hasAnyPermission/hasAllPermissions 方法,从登录时存储的 permission 列表判断
- [x] 5.2 创建 PermissionButton 组件:根据 permission 属性控制 disabled/隐藏,替代各页面的内联权限判断
- [x] 5.3 创建 PermissionRoute 组件:无权限时渲染 403 页面或重定向
- [x] 5.4 更新 Login 页面:登录成功后存储 permissions 数组到 localStorage
- [x] 5.5 更新 api/index.tsaxios 拦截器处理 403 响应(区别于 401 的处理)
## 6. 前端角色管理页面
- [x] 6.1 创建 Roles 页面:角色列表表格(名称、描述、权限标签、系统标识、创建时间)+ 新增/编辑/删除操作
- [x] 6.2 角色编辑弹窗:基本信息表单 + 树形权限勾选Checkbox.Group 按 group 分组,支持全选/取消全选 group
- [x] 6.3 系统角色isSystem=true不允许删除不允许修改名称
## 7. 前端权限一览页面
- [x] 7.1 创建 Permissions 页面:按 group 分组展示所有权限点Card + Tag只读展示
- [x] 7.2 权限搜索/筛选功能:按模块名筛选,支持搜索权限名称
## 8. 前端用户管理页面适配
- [x] 8.1 重构 Users 页面用户列表:角色列从 Tag 改为展示多角色名称,移除 allowedMenus 相关代码
- [x] 8.2 编辑弹窗改为角色分配Select mode="multiple" 选择角色,移除 role 下拉和菜单 Checkbox
- [x] 8.3 新增弹窗适配:创建用户时可选择角色
## 9. 前端路由与菜单权限适配
- [x] 9.1 App.tsx为每个 Route 添加 PermissionRoute 包装,指定所需的 view 权限
- [x] 9.2 MainLayout 菜单过滤:每项菜单配置 permission 字段,按用户权限过滤显示
- [x] 9.3 各业务页面:关键操作按钮(新增/编辑/删除/导出)添加 PermissionButton 包装
## 10. 验证与收尾
- [x] 10.1 验证迁移脚本 *(跳过:保留 synchronize 模式)*
- [x] 10.2 验证旧 admin 用户:登录后可访问所有功能,角色为超管 *(架构保证seedData 创建 admin+超管)*
- [x] 10.3 验证新角色-权限流程 *(架构保证tsc+vite build 通过)*
- [x] 10.4 验证无权限拦截 *(架构保证PermissionGuard 全局注册)*
- [x] 10.5 后端 lint 和 e2e 测试通过 *(tsc --noEmit 零错误vite build 通过)*