# 权限体系模型 **本文引用的文件** - [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java) - [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java) - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) - [SysUserDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java) - [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) - [MenuTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuTypeEnum.java) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java) - [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) ## 目录 1. [引言](#引言) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 引言 本文件面向权限系统的数据模型设计与实现,围绕RBAC(基于角色的访问控制)模型,系统化阐述角色、菜单、部门及其关联关系的数据结构设计。文档涵盖用户-角色、角色-菜单、用户-部门的关联表设计;说明权限继承机制、数据范围控制与菜单权限过滤的数据库支持;提供实体关系图、外键约束建议与索引优化策略,为权限系统的开发与扩展提供完整参考。 ## 项目结构 权限相关实体、枚举、服务与拦截器主要分布在认证模块与基础模块中: - 认证模块(crm-auth):包含用户、角色、菜单、部门等实体定义,以及权限计算、菜单树构建、数据范围拦截等实现。 - 基础模块(crm-base):提供通用基类、数据可见性上下文、数据范围注解与工具方法、MyBatis-Plus配置与SQL注入器等。 ```mermaid graph TB subgraph "认证模块" A["AuthUser"] --> B["SysUserRole"] C["SysRole"] --> D["SysRoleMenu"] E["SysMenu"] F["SysDept"] --> G["SysUserDept"] H["PermissionServiceImpl"] I["SysMenuServiceImpl"] J["SysDeptServiceImpl"] K["SysRoleServiceImpl"] L["AuthUserServiceImpl"] M["DataScopeInterceptor"] N["DataScopeTables"] end subgraph "基础模块" O["BaseEntity"] P["OwnedEntity"] Q["DataScope"] R["DataScopeHelper"] S["DataScopeLevel"] T["DataVisibilityContext"] U["SecurityUtils"] V["LoginUser"] W["MybatisPlusConfig"] X["CrmSqlInjector"] end A --> O C --> O E --> O F --> O B --> O D --> O G --> O H --> Q I --> E J --> F K --> C L --> A M --> R M --> S M --> T W --> X ``` 图表来源 - [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java) - [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java) - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) - [SysUserDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java) - [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java) - [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) 章节来源 - [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java) - [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java) - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) - [SysUserDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java) - [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) - [MenuTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuTypeEnum.java) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java) - [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) ## 核心组件 - 实体模型 - 用户:AuthUser,承载登录账号、身份标识、状态等基础信息。 - 角色:SysRole,承载角色名称、编码、描述、数据范围等。 - 菜单:SysMenu,承载菜单层级、类型、路径、图标、排序、可见性等。 - 部门:SysDept,承载部门名称、上级部门、排序、状态等。 - 关联表:SysUserRole(用户-角色)、SysRoleMenu(角色-菜单)、SysUserDept(用户-部门)。 - 枚举与常量 - DataScopeEnum:数据范围类型(如全部、本部门、本部门及子部门、仅本人等)。 - MenuTypeEnum:菜单类型(目录、菜单、按钮等),用于前端渲染与权限判断。 - 安全与数据范围 - DataScope注解:标注在查询方法上,声明数据范围级别。 - DataScopeHelper/DataScopeLevel/DataVisibilityContext:数据范围解析与上下文管理。 - SecurityUtils/LoginUser:当前登录用户上下文获取。 - 基础设施 - BaseEntity/OwnedEntity:通用字段(如创建时间、更新人、租户或归属等)。 - MybatisPlusConfig/CrmSqlInjector:分页、自动填充、SQL注入增强。 - DataScopeInterceptor/DataScopeTables:数据范围拦截与表级范围映射。 章节来源 - [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java) - [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java) - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) - [SysUserDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java) - [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) - [MenuTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuTypeEnum.java) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) ## 架构总览 权限体系采用RBAC模型,结合菜单树与部门层级,形成“用户-角色-菜单”和“用户-部门”的双维度权限控制。数据范围通过注解与拦截器在SQL层动态拼接条件,实现细粒度的数据可见性控制。 ```mermaid classDiagram class AuthUser { +id +username +status +... } class SysRole { +id +name +code +data_scope +... } class SysMenu { +id +parent_id +type +path +sort +visible +... } class SysDept { +id +parent_id +name +sort +status +... } class SysUserRole { +user_id +role_id } class SysRoleMenu { +role_id +menu_id } class SysUserDept { +user_id +dept_id } AuthUser --> SysUserRole : "多对多" SysRole --> SysRoleMenu : "多对多" SysMenu --> SysRoleMenu : "多对多" AuthUser --> SysUserDept : "多对多" SysDept --> SysUserDept : "多对多" ``` 图表来源 - [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java) - [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java) - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) - [SysUserDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java) ## 详细组件分析 ### RBAC权限模型与关联表设计 - 用户-角色(SysUserRole) - 作用:将用户与角色建立多对多关系,支撑角色权限继承。 - 关键字段:用户ID、角色ID。 - 索引建议:联合唯一索引(user_id, role_id),查询用户角色时高效。 - 角色-菜单(SysRoleMenu) - 作用:将角色与菜单建立多对多关系,决定角色可访问的菜单与按钮。 - 关键字段:角色ID、菜单ID。 - 索引建议:联合唯一索引(role_id, menu_id),按角色加载菜单树时高效。 - 用户-部门(SysUserDept) - 作用:将用户与部门建立多对多关系,支撑数据范围与组织视图。 - 关键字段:用户ID、部门ID。 - 索引建议:联合唯一索引(user_id, dept_id),按用户加载部门列表时高效。 章节来源 - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) - [SysUserDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java) ### 菜单树结构与类型 - 菜单(SysMenu) - 层级结构:通过父ID(parent_id)自引用形成树形结构,根节点parent_id为空或特定值。 - 类型(MenuTypeEnum):区分目录、菜单、按钮等,用于前端渲染与权限校验。 - 可见性与排序:visible与sort字段控制展示顺序与可见性。 - 菜单权限过滤 - 服务层(SysMenuServiceImpl)负责根据角色与用户权限构建菜单树,过滤无权限节点。 - 权限计算(PermissionServiceImpl)汇总用户角色与角色菜单,生成权限集合。 ```mermaid flowchart TD Start(["开始"]) --> LoadRoles["加载用户角色"] LoadRoles --> LoadMenus["加载角色对应菜单"] LoadMenus --> BuildTree["构建菜单树"] BuildTree --> FilterVisible{"是否可见?"} FilterVisible --> |否| Skip["跳过该节点"] FilterVisible --> |是| Keep["保留该节点"] Skip --> Next["处理下一个节点"] Keep --> Next Next --> Done(["完成"]) ``` 图表来源 - [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java) - [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [MenuTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuTypeEnum.java) 章节来源 - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [MenuTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuTypeEnum.java) - [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java) - [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java) ### 部门层级关系与数据范围 - 部门(SysDept) - 层级结构:通过父ID(parent_id)自引用形成树形结构,便于组织视图与数据范围推导。 - 状态与排序:status与sort字段控制显示与顺序。 - 数据范围(DataScopeEnum) - 类型包括:全部、本部门、本部门及子部门、仅本人等,影响查询时的数据可见性。 - 注解(DataScope)与级别(DataScopeLevel)配合使用,声明方法级的数据范围策略。 - 上下文(DataVisibilityContext)维护当前请求的数据可见范围。 - 辅助(DataScopeHelper)解析范围并生成SQL片段。 - 拦截器(DataScopeInterceptor)在SQL执行前注入WHERE条件。 - 表级映射(DataScopeTables)定义哪些表需要应用数据范围。 ```mermaid sequenceDiagram participant Client as "客户端" participant Controller as "业务控制器" participant Service as "业务服务" participant Interceptor as "数据范围拦截器" participant DB as "数据库" Client->>Controller : 发起查询请求 Controller->>Service : 调用带@DataScope的方法 Service->>Interceptor : 进入拦截器 Interceptor->>Interceptor : 解析DataScopeLevel与上下文 Interceptor->>DB : 注入数据范围WHERE条件 DB-->>Interceptor : 返回受限结果集 Interceptor-->>Service : 返回结果 Service-->>Controller : 返回数据 Controller-->>Client : 响应数据 ``` 图表来源 - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) 章节来源 - [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java) - [DataScopeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/DataScopeEnum.java) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) ### 用户-角色-菜单权限计算流程 - 用户(AuthUser)通过SysUserRole关联多个角色。 - 角色(SysRole)通过SysRoleMenu关联多个菜单。 - 权限计算(PermissionServiceImpl)聚合用户角色与角色菜单,生成权限集合,供前端菜单渲染与后端接口鉴权使用。 - 用户服务(AuthUserServiceImpl)在登录或会话初始化时加载用户权限。 ```mermaid sequenceDiagram participant User as "用户" participant AuthService as "认证服务" participant PermService as "权限服务" participant RoleMapper as "角色映射" participant MenuMapper as "菜单映射" User->>AuthService : 登录 AuthService->>PermService : 计算权限(用户ID) PermService->>RoleMapper : 查询用户角色 RoleMapper-->>PermService : 角色列表 PermService->>MenuMapper : 查询角色菜单 MenuMapper-->>PermService : 菜单列表 PermService-->>AuthService : 权限集合 AuthService-->>User : 返回登录结果与权限 ``` 图表来源 - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java) - [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) 章节来源 - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java) - [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) ### 实体关系图(ERD) ```mermaid erDiagram AUTH_USER { bigint id PK varchar username UK int status datetime created_at datetime updated_at } SYS_ROLE { bigint id PK varchar name varchar code UK int data_scope datetime created_at datetime updated_at } SYS_MENU { bigint id PK bigint parent_id FK enum type varchar path int sort boolean visible datetime created_at datetime updated_at } SYS_DEPT { bigint id PK bigint parent_id FK varchar name int sort int status datetime created_at datetime updated_at } SYS_USER_ROLE { bigint user_id FK bigint role_id FK } SYS_ROLE_MENU { bigint role_id FK bigint menu_id FK } SYS_USER_DEPT { bigint user_id FK bigint dept_id FK } AUTH_USER ||--o{ SYS_USER_ROLE : "拥有" SYS_ROLE ||--o{ SYS_USER_ROLE : "分配给" SYS_ROLE ||--o{ SYS_ROLE_MENU : "包含" SYS_MENU ||--o{ SYS_ROLE_MENU : "被授权" AUTH_USER ||--o{ SYS_USER_DEPT : "属于" SYS_DEPT ||--o{ SYS_USER_DEPT : "包含" ``` 图表来源 - [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java) - [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java) - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) - [SysUserDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java) ## 依赖关系分析 - 实体依赖 - AuthUser、SysRole、SysMenu、SysDept均继承BaseEntity,可能还继承OwnedEntity以支持归属字段。 - 关联表(SysUserRole、SysRoleMenu、SysUserDept)作为中间表,承载多对多关系。 - 服务与拦截器依赖 - PermissionServiceImpl依赖角色与菜单映射,生成权限集合。 - SysMenuServiceImpl依赖菜单实体与权限集合,构建菜单树。 - DataScopeInterceptor依赖DataScopeHelper、DataScopeLevel、DataVisibilityContext与DataScopeTables,在SQL层注入数据范围条件。 - 基础设施依赖 - MybatisPlusConfig与CrmSqlInjector提供分页、自动填充与SQL增强能力。 ```mermaid graph LR AuthUser --> BaseEntity SysRole --> BaseEntity SysMenu --> BaseEntity SysDept --> BaseEntity SysUserRole --> AuthUser SysUserRole --> SysRole SysRoleMenu --> SysRole SysRoleMenu --> SysMenu SysUserDept --> AuthUser SysUserDept --> SysDept PermissionServiceImpl --> SysRole PermissionServiceImpl --> SysMenu SysMenuServiceImpl --> SysMenu DataScopeInterceptor --> DataScopeHelper DataScopeInterceptor --> DataScopeLevel DataScopeInterceptor --> DataVisibilityContext DataScopeInterceptor --> DataScopeTables MybatisPlusConfig --> CrmSqlInjector ``` 图表来源 - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) - [SysUserDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java) - [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java) - [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) 章节来源 - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) - [SysUserDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserDept.java) - [PermissionServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/PermissionServiceImpl.java) - [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) ## 性能考虑 - 索引优化 - 关联表联合唯一索引:(user_id, role_id)、(role_id, menu_id)、(user_id, dept_id),提升多对多查询效率。 - 菜单树查询:为parent_id与type建立复合索引,加速菜单树构建与过滤。 - 数据范围:为涉及部门与用户的字段建立索引,减少全表扫描。 - SQL注入与分页 - 使用MybatisPlusConfig与CrmSqlInjector进行分页与自动填充,避免手写复杂SQL。 - 数据范围拦截器在SQL层注入WHERE条件,避免在应用层过滤大量数据。 - 缓存与预取 - 菜单树与权限集合可在登录后缓存,减少重复计算。 - 部门树可缓存,降低频繁查询开销。 [本节为通用性能指导,不直接分析具体文件] ## 故障排查指南 - 权限缺失 - 检查用户是否分配了角色(SysUserRole)。 - 检查角色是否包含所需菜单(SysRoleMenu)。 - 确认菜单可见性(SysMenu.visible)与类型(MenuTypeEnum)。 - 数据范围异常 - 检查方法是否标注@DataScope,且级别正确(DataScopeLevel)。 - 确认DataVisibilityContext是否正确设置当前用户与部门。 - 检查DataScopeTables是否包含目标表。 - 菜单树构建问题 - 检查parent_id层级是否正确,是否存在孤立节点。 - 确认权限集合是否包含必要菜单项。 章节来源 - [SysUserRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysUserRole.java) - [SysRoleMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRoleMenu.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [MenuTypeEnum.java](file://crm-auth/src/main/java/com/crm/auth/domain/enums/MenuTypeEnum.java) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) ## 结论 本权限体系以RBAC为核心,结合菜单树与部门层级,实现了灵活的权限控制与数据范围管理。通过关联表与枚举、注解与拦截器的协同,系统在数据库层与应用层共同保障权限与数据的准确性与性能。建议在开发中严格遵循索引与SQL注入规范,合理使用缓存,确保系统在高并发场景下的稳定性与可扩展性。 [本节为总结性内容,不直接分析具体文件] ## 附录 - 最佳实践 - 为所有关联表建立联合唯一索引,避免重复数据与低效查询。 - 使用统一的基类(BaseEntity/OwnedEntity)管理公共字段,保证一致性。 - 在方法级使用@DataScope明确数据范围,避免硬编码WHERE条件。 - 菜单树构建与权限计算应在登录后缓存,减少重复计算。 - 定期审计角色与菜单分配,清理无效权限。 [本节为通用指导,不直接分析具体文件]