You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

580 lines
30 KiB

1 month ago
# 权限体系模型
<cite>
**本文引用的文件**
- [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)
</cite>
## 目录
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条件。
- 菜单树构建与权限计算应在登录后缓存,减少重复计算。
- 定期审计角色与菜单分配,清理无效权限。
[本节为通用指导,不直接分析具体文件]