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

5.3 KiB
Raw Blame History

1. RBAC 数据库实体与迁移

  • 1.1 创建 Permission 实体 (backend/src/entities/permission.entity.ts)id、code(UK)、name、group、description
  • 1.2 创建 Role 实体 (backend/src/entities/role.entity.ts)id、name、description、isSystem、status、@ManyToMany→Permission、@ManyToMany→User
  • 1.3 创建 RolePermission 和 UserRole 多对多关联表(通过 TypeORM @ManyToMany + @JoinTable 自动生成)
  • 1.4 更新 User 实体:新增 roles 多对多关联,移除 role 和 allowedMenus 字段;更新 entities/index.ts 导出
  • 1.5 编写 TypeORM 迁移脚本:建新表、插入种子数据、迁移现有用户角色、删除旧列
  • 1.6 编写种子数据初始化服务:创建 4 个预置角色 + ~40 个权限点 + 角色-权限关联映射

2. RBAC 服务层

  • 2.1 创建 RbacModule 和 RbacService提供 findAllRoles/findRoleById/createRole/updateRole/deleteRole 方法
  • 2.2 实现角色 CRUD含权限关联创建角色时同时写入 RolePermission更新时删除旧关联重建
  • 2.3 实现 getUserPermissions 方法:通过 User→UserRole→Role→RolePermission→Permission 链查询,去重后返回权限 code 列表
  • 2.4 实现 getPermissionTree 方法:返回按 group 分组的权限树,供前端权限一览和管理页使用
  • 2.5 创建 RbacController角色 CRUD + 权限树 + 用户-角色分配接口,所有接口加 @RequirePermission 守卫

3. 权限守卫实现

  • 3.1 创建 @RequirePermission 装饰器(支持 AND/OR 语义,通过 SetMetadata 存储权限列表和逻辑模式)
  • 3.2 创建 PermissionGuard从 JWT payload 中读取 permissions 数组,与装饰器标注的权限做匹配
  • 3.3 修改 JwtStrategy 和 AuthService.login登录时调用 getUserPermissions将 permissions 写入 JWT payload
  • 3.4 修改 AuthService.validateUser/profile返回用户信息时携带角色和权限列表
  • 3.5 全局注册 PermissionGuard或在各模块按需注册

4. 现有接口批量加守卫

  • 4.1 StudentsController全部方法加 @RequirePermission
  • 4.2 RoomsController全部方法加 @RequirePermission
  • 4.3 OccupanciesController全部方法加 @RequirePermission
  • 4.4 ExpensesController全部方法加 @RequirePermission
  • 4.5 BillsController全部方法加 @RequirePermission
  • 4.6 DepositsController全部方法加 @RequirePermission
  • 4.7 ClassroomsController全部方法加 @RequirePermission
  • 4.8 TenantsController全部方法加 @RequirePermission
  • 4.9 ClassroomRentalsController全部方法加 @RequirePermission
  • 4.10 DashboardController全部方法加 @RequirePermission
  • 4.11 OperationLogsController全部方法加 @RequirePermission
  • 4.12 AuthController用户管理部分分离为用户管理接口加 @RequirePermission移除原 register 接口的旧逻辑

5. 前端权限基础设施

  • 5.1 创建 usePermission hook提供 hasPermission/hasAnyPermission/hasAllPermissions 方法,从登录时存储的 permission 列表判断
  • 5.2 创建 PermissionButton 组件:根据 permission 属性控制 disabled/隐藏,替代各页面的内联权限判断
  • 5.3 创建 PermissionRoute 组件:无权限时渲染 403 页面或重定向
  • 5.4 更新 Login 页面:登录成功后存储 permissions 数组到 localStorage
  • 5.5 更新 api/index.tsaxios 拦截器处理 403 响应(区别于 401 的处理)

6. 前端角色管理页面

  • 6.1 创建 Roles 页面:角色列表表格(名称、描述、权限标签、系统标识、创建时间)+ 新增/编辑/删除操作
  • 6.2 角色编辑弹窗:基本信息表单 + 树形权限勾选Checkbox.Group 按 group 分组,支持全选/取消全选 group
  • 6.3 系统角色isSystem=true不允许删除不允许修改名称

7. 前端权限一览页面

  • 7.1 创建 Permissions 页面:按 group 分组展示所有权限点Card + Tag只读展示
  • 7.2 权限搜索/筛选功能:按模块名筛选,支持搜索权限名称

8. 前端用户管理页面适配

  • 8.1 重构 Users 页面用户列表:角色列从 Tag 改为展示多角色名称,移除 allowedMenus 相关代码
  • 8.2 编辑弹窗改为角色分配Select mode="multiple" 选择角色,移除 role 下拉和菜单 Checkbox
  • 8.3 新增弹窗适配:创建用户时可选择角色

9. 前端路由与菜单权限适配

  • 9.1 App.tsx为每个 Route 添加 PermissionRoute 包装,指定所需的 view 权限
  • 9.2 MainLayout 菜单过滤:每项菜单配置 permission 字段,按用户权限过滤显示
  • 9.3 各业务页面:关键操作按钮(新增/编辑/删除/导出)添加 PermissionButton 包装

10. 验证与收尾

  • 10.1 验证迁移脚本:在 SQLite 和 MySQL 环境下分别执行迁移,确认数据正确
  • 10.2 验证旧 admin 用户:登录后可访问所有功能,角色为超管
  • 10.3 验证新角色-权限流程:创建角色→分配权限→给用户分配角色→用户登录→菜单/按钮/API都按权限工作
  • 10.4 验证无权限拦截:直接访问无权限 URL 返回 403直接调 API 返回 403 JSON
  • 10.5 后端 lint 和 e2e 测试通过