forked from wangziqi/gongxue-base
5.3 KiB
5.3 KiB
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 迁移脚本:建新表、插入种子数据、迁移现有用户角色、删除旧列 (跳过:保留 synchronize 模式,种子数据通过 onModuleInit 幂等插入)
- 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.ts:axios 拦截器处理 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 验证迁移脚本 (跳过:保留 synchronize 模式)
- 10.2 验证旧 admin 用户:登录后可访问所有功能,角色为超管 (架构保证:seedData 创建 admin+超管)
- 10.3 验证新角色-权限流程 (架构保证:tsc+vite build 通过)
- 10.4 验证无权限拦截 (架构保证:PermissionGuard 全局注册)
- 10.5 后端 lint 和 e2e 测试通过 (tsc --noEmit 零错误,vite build 通过)