37 KiB
认证授权域功能详细设计文档(反推自代码)
文档类型: 反推设计文档 数据来源: module-auth 实际代码 生成日期: 2026-04-23 对照文档: 05-AUTH.md(原需求设计)
一、领域概述
1.1 领域职责
认证授权域(module-auth)负责 Ether 平台的身份认证与授权管理,核心职责包括:
- 身份认证:用户登录/登出、JWT Token 生成与验证、登录失败锁定
- 用户管理:多类型用户(企业员工、项目员工、住户)的 CRUD 与扩展信息管理
- RBAC 权限模型:角色-权限-用户三层关联,支持项目级角色隔离
- 数据权限:四级数据范围(ALL/PROJECT/DEPARTMENT/SELF)
- 项目隔离:用户-项目多对多关联,项目成员管理与角色分配
- 部门管理:树形组织架构,支持多种部门类型
- 审计日志:操作日志自动记录,异步持久化,30天查询窗口
- 系统配置:键值对形式的系统参数管理
1.2 核心概念
| 概念 | 说明 | 对应实体 |
|---|---|---|
| 用户 | 系统登录账户,支持四种用户类型 | User |
| 企业员工 | 企业类型用户的扩展信息 | EnterpriseUser |
| 项目员工 | 项目类型员工的扩展信息,含班次、岗位状态 | ProjectStaff |
| 住户 | 业主/家属/租户,含认证流程 | Resident |
| 角色 | 权限集合,支持系统级/项目级/部门级 | Role |
| 权限 | 功能访问控制点,支持菜单/按钮/API三种类型 | Permission |
| 部门 | 组织架构节点,支持树形结构 | Dept |
| 用户-项目关联 | 用户参与项目的多对多关系 | UserProject |
| 项目员工角色 | 项目员工在项目中的角色分配 | ProjectStaffRole |
| 数据访问授权 | 细粒度数据访问控制记录 | DataAccess |
| 审计日志 | 操作审计记录 | AuditLog |
| 房屋空间 | 项目下的房屋/空间信息 | Space |
| 住户-房屋关联 | 住户与房屋的绑定关系 | ResidentSpace |
| 系统配置 | 键值对形式的系统参数 | SysConfig |
1.3 用户类型体系
User (基础用户)
├── EnterpriseUser (企业员工) — 共享主键一对一
│ └── 员工工号、部门、职位、入职日期、员工类别
├── ProjectStaff (项目员工) — 独立主键一对一
│ └── 所属项目、员工类型、班次、班组长、在岗状态
│ └── ProjectStaffRole (项目员工角色) — 一对多
└── Resident (住户) — 共享主键一对一
└── 身份证、住户类型、认证状态
└── ResidentSpace (住户-房屋关联) — 一对多
二、数据结构设计
2.1 User(用户)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | UUID | PK, 自动生成 | 用户唯一标识符 |
| username | VARCHAR(50) | NOT NULL, UNIQUE | 登录用户名,仅字母数字下划线,3-50位 |
| password | VARCHAR(255) | NOT NULL, JSON忽略 | BCrypt加密密码 |
| salt | VARCHAR | JSON忽略 | 密码盐值(BCrypt模式下冗余) |
| realName | VARCHAR(50) | 真实姓名 | |
| phone | VARCHAR(20) | 正则^1[3-9]\d{9}$ |
手机号码 |
| VARCHAR(100) | 电子邮箱 | ||
| avatar | VARCHAR | 头像URL | |
| status | VARCHAR(20) | NOT NULL, 默认ACTIVE | 用户状态枚举 |
| userType | VARCHAR(20) | NOT NULL | 用户类型:ENTERPRISE/PROJECT_STAFF/RESIDENT/CUSTOMER |
| deptId | UUID | 所属部门ID | |
| lastLoginTime | LocalDateTime | 最后登录时间 | |
| lastLoginIp | VARCHAR | 最后登录IP | |
| roles | List<Role> | M2M, LAZY | 关联角色列表(通过auth_user_role表) |
| createdAt | LocalDateTime | NOT NULL, 自动填充 | 创建时间 |
| updatedAt | LocalDateTime | NOT NULL, 自动填充 | 更新时间 |
| createdBy | UUID | 创建人ID |
枚举:UserStatus
| 值 | 描述 |
|---|---|
| ACTIVE | 正常 |
| LOCKED | 锁定 |
| DISABLED | 禁用 |
关联表:auth_user_role
| 字段 | 类型 | 说明 |
|---|---|---|
| user_id | UUID | FK → auth_user |
| role_id | UUID | FK → auth_role |
2.2 Role(角色)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | UUID | PK, 自动生成 | 角色唯一标识符 |
| code | VARCHAR(50) | NOT NULL, UNIQUE | 角色代码,仅字母数字下划线,2-50位 |
| name | VARCHAR(50) | NOT NULL | 角色名称 |
| description | VARCHAR(200) | 角色描述 | |
| type | VARCHAR(20) | NOT NULL | 角色类型枚举 |
| dataScope | VARCHAR(20) | 默认SELF | 数据范围枚举 |
| projectId | UUID | 所属项目ID(NULL=系统级) | |
| status | VARCHAR(20) | NOT NULL, 默认ENABLED | 角色状态枚举 |
| permissions | List<Permission> | M2M, LAZY | 关联权限列表(通过auth_role_permission表) |
| createdAt | LocalDateTime | NOT NULL, 自动填充 | 创建时间 |
| updatedAt | LocalDateTime | NOT NULL, 自动填充 | 更新时间 |
枚举:RoleType
| 值 | 描述 |
|---|---|
| SYSTEM | 系统级 |
| PROJECT | 项目级 |
| DEPARTMENT | 部门级 |
枚举:DataScope
| 值 | 描述 |
|---|---|
| ALL | 全部数据 |
| PROJECT | 本项目数据 |
| DEPARTMENT | 本部门数据 |
| SELF | 仅本人数据 |
枚举:RoleStatus
| 值 | 描述 |
|---|---|
| ENABLED | 启用 |
| DISABLED | 禁用 |
关联表:auth_role_permission
| 字段 | 类型 | 说明 |
|---|---|---|
| role_id | UUID | FK → auth_role |
| permission_id | UUID | FK → auth_permission |
2.3 Permission(权限)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | UUID | PK, 自动生成 | 权限唯一标识符 |
| code | VARCHAR(100) | NOT NULL, UNIQUE | 权限代码,格式module:resource:action,仅字母数字冒号下划线 |
| name | VARCHAR(100) | NOT NULL | 权限名称 |
| type | VARCHAR(20) | 权限类型:MENU/BUTTON/API | |
| resource | VARCHAR(50) | 资源路径(API类型) | |
| method | VARCHAR(50) | HTTP方法(API类型) | |
| description | VARCHAR(200) | 权限描述 | |
| parentCode | VARCHAR(50) | 父权限代码(树形结构) | |
| sortOrder | Integer | 排序序号 | |
| roles | List<Role> | M2M, LAZY | 关联角色列表 |
| createdAt | LocalDateTime | 自动填充 | 创建时间 |
| updatedAt | LocalDateTime | 自动填充 | 更新时间 |
2.4 Dept(部门)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | UUID | PK, 自动生成 | 部门唯一标识符 |
| parentId | UUID | 上级部门ID(NULL=顶级) | |
| deptName | VARCHAR(100) | NOT NULL | 部门名称 |
| deptType | VARCHAR(20) | 默认ADMIN | 部门类型 |
| leaderId | UUID | 部门负责人ID | |
| sortOrder | Integer | 排序序号 | |
| status | VARCHAR(20) | 默认ACTIVE | 状态:ACTIVE/DISABLED |
| createdAt | LocalDateTime | 自动填充 | 创建时间 |
| updatedAt | LocalDateTime | 自动填充 | 更新时间 |
| createdBy | UUID | 创建人ID | |
| updatedBy | UUID | 更新人ID |
枚举:DeptType
| 值 | 描述 |
|---|---|
| ADMIN | 行政管理 |
| ENGINEERING | 工程部 |
| SECURITY | 安保部 |
| CS | 客服部 |
| CLEANING | 保洁部 |
2.5 EnterpriseUser(企业员工)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| userId | UUID | PK, FK → auth_user | 用户ID(共享主键) |
| employeeNo | VARCHAR(50) | 员工工号 | |
| deptId | UUID | 部门ID | |
| position | VARCHAR(50) | 职位 | |
| entryDate | LocalDate | 入职日期 | |
| userCategory | VARCHAR(50) | 员工类别:ENTERPRISE/MANAGEMENT | |
| user | User | @OneToOne @MapsId | 关联User实体 |
2.6 ProjectStaff(项目员工)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | UUID | PK, 自动生成 | 主键ID |
| userId | UUID | FK → auth_user | 用户ID |
| projectId | UUID | 所属项目ID | |
| deptId | UUID | 所属部门ID | |
| staffType | VARCHAR(50) | 员工类型 | |
| shiftType | VARCHAR(20) | 班次类型:DAY/NIGHT/ROTATION | |
| leaderId | UUID | 班组长ID | |
| assignmentStatus | VARCHAR(20) | 在岗状态:ASSIGNED/ON_LEAVE/TRANSFERRED | |
| staffRoles | List<ProjectStaffRole> | @OneToMany, 级联删除 | 员工角色列表 |
| createdAt | LocalDateTime | 创建时间 | |
| updatedAt | LocalDateTime | 更新时间 | |
| user | User | @OneToOne | 关联User实体 |
StaffType 枚举值:SECURITY / CLEANING / GARDEN / MAINTENANCE / CUSTOMER_SERVICE / GENERAL
2.7 ProjectStaffRole(项目员工角色)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | UUID | PK, 自动生成 | 主键ID |
| staff | ProjectStaff | @ManyToOne, LAZY, NOT NULL | 关联项目员工 |
| role | Role | @ManyToOne, EAGER, NOT NULL | 关联角色 |
| createdAt | LocalDateTime | 自动填充 | 创建时间 |
2.8 Resident(住户)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| userId | UUID | PK, FK → auth_user | 用户ID(共享主键) |
| idCard | VARCHAR(18) | JSON忽略 | 身份证号码 |
| residentType | VARCHAR(20) | 住户类型:OWNER/FAMILY/TENANT | |
| verificationStatus | VARCHAR(20) | 认证状态:UNVERIFIED/PENDING/VERIFIED/REJECTED | |
| verifiedAt | LocalDateTime | 认证时间 | |
| verifiedBy | UUID | 认证人ID | |
| user | User | @OneToOne @MapsId | 关联User实体 |
| createdAt | LocalDateTime | NOT NULL | 创建时间 |
| updatedAt | LocalDateTime | NOT NULL | 更新时间 |
| createdBy | UUID | 创建人ID | |
| updatedBy | UUID | 更新人ID |
2.9 ResidentSpace(住户-房屋关联)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | UUID | PK, 自动生成 | 关联记录ID |
| userId | UUID | NOT NULL | 用户ID |
| spaceId | UUID | NOT NULL | 房屋ID |
| relationType | VARCHAR(20) | 关系类型:OWNER/FAMILY/TENANT | |
| bindingStatus | VARCHAR(20) | 绑定状态:PENDING/ACTIVE/EXPIRED/CANCELLED | |
| startDate | LocalDate | 生效日期 | |
| endDate | LocalDate | 失效日期(NULL=永久) |
2.10 Space(房屋空间)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | UUID | PK, 自动生成 | 空间ID |
| projectId | UUID | 所属项目ID | |
| building | VARCHAR(50) | 楼栋 | |
| unit | VARCHAR(50) | 单元 | |
| roomNo | VARCHAR(50) | 房号 | |
| spaceType | VARCHAR(20) | 房屋类型:RESIDENTIAL/COMMERCIAL | |
| floor | Integer | 楼层 | |
| unitArea | BigDecimal | 建筑面积(㎡) | |
| status | VARCHAR(20) | 状态 |
2.11 UserProject(用户-项目关联)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | UUID | PK, 自动生成 | 关联记录ID |
| userId | UUID | NOT NULL | 用户ID |
| projectId | UUID | NOT NULL | 项目ID |
| roleInProject | VARCHAR | NOT NULL, 默认"member" | 项目中角色:leader/member/viewer |
| joinedAt | LocalDateTime | NOT NULL, 默认当前时间 | 加入时间 |
2.12 DataAccess(数据访问授权)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | UUID | PK, 自动生成 | 授权记录ID |
| dataType | VARCHAR | NOT NULL | 数据类型 |
| dataId | UUID | NOT NULL | 数据ID |
| accessType | VARCHAR | NOT NULL | 访问者类型 |
| accessId | UUID | NOT NULL | 访问者ID |
| accessLevel | VARCHAR | NOT NULL, 默认"read" | 访问级别 |
| grantedBy | UUID | 授权人ID | |
| grantedAt | LocalDateTime | NOT NULL, 默认当前时间 | 授权时间 |
2.13 AuditLog(审计日志)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | UUID | PK, 自动生成 | 日志ID |
| userId | UUID | 操作用户ID | |
| username | VARCHAR(64) | NOT NULL | 操作用户名 |
| operation | VARCHAR(128) | NOT NULL | 操作描述 |
| module | VARCHAR(64) | NOT NULL | 模块标识 |
| action | VARCHAR(64) | NOT NULL | 操作类型枚举 |
| targetType | VARCHAR(64) | 目标类型 | |
| targetId | VARCHAR(64) | 目标ID | |
| content | VARCHAR(2000) | 操作内容 | |
| params | LONGVARCHAR(5000) | 请求参数 | |
| result | LONGVARCHAR(5000) | 操作结果 | |
| ipAddress | VARCHAR(64) | IP地址 | |
| userAgent | VARCHAR(512) | 用户代理 | |
| requestUrl | VARCHAR(512) | 请求URL | |
| requestMethod | VARCHAR(16) | 请求方法 | |
| executionTimeMs | Integer | 执行耗时(ms) | |
| status | VARCHAR(16) | 默认SUCCESS | 状态枚举 |
| errorMsg | VARCHAR(2000) | 错误信息 | |
| createdAt | LocalDateTime | NOT NULL, 自动填充 | 创建时间 |
| tenantId | UUID | 租户ID |
索引:
idx_audit_log_created_at→ createdAtidx_audit_log_user_id→ userIdidx_audit_log_module→ moduleidx_audit_log_action→ actionidx_al_user_createdat→ userId, createdAt DESC
枚举:ActionType
| 值 | 描述 |
|---|---|
| CREATE | 创建 |
| UPDATE | 修改 |
| DELETE | 删除 |
| QUERY | 查询 |
| VIEW | 查看 |
| LOGIN | 登录 |
| LOGOUT | 登出 |
| EXPORT | 导出 |
| IMPORT | 导入 |
| ASSIGN | 分配 |
| REVOKE | 撤销 |
枚举:Status
| 值 | 描述 |
|---|---|
| SUCCESS | 成功 |
| FAIL | 失败 |
2.14 SysConfig(系统配置)
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | UUID | PK, 自动生成 | 配置项ID |
| configKey | VARCHAR(128) | NOT NULL, UNIQUE | 配置键 |
| configValue | VARCHAR(5000) | 配置值 | |
| description | VARCHAR(256) | 配置描述 | |
| createdAt | LocalDateTime | NOT NULL, 自动填充 | 创建时间 |
| updatedAt | LocalDateTime | NOT NULL, 自动填充 | 更新时间 |
2.15 实体关系图
┌──────────┐ M2M ┌──────────┐ M2M ┌────────────┐
│ User │◄────────────►│ Role │◄────────────►│ Permission │
└────┬─────┘ auth_user └────┬─────┘ auth_role └────────────┘
│ _role │ _permission
│ 1:1 │
▼ ▼
┌──────────────┐ ┌──────────────────┐
│EnterpriseUser│ │ ProjectStaff │
│ (共享主键) │ │ (独立主键) │
└──────────────┘ └───────┬──────────┘
│ 1:N
▼
┌──────────────────┐
│ProjectStaffRole │──────► Role
└──────────────────┘
┌──────────┐ 1:1 ┌──────────┐
│ User │◄───────────►│ Resident │
└──────────┘ └────┬─────┘
│ 1:N
▼
┌───────────────┐ N:1 ┌───────┐
│ResidentSpace │◄────────────►│ Space │
└───────────────┘ └───────┘
┌──────────┐ N:N ┌──────────┐
│ User │◄───────────►│ Project │ (通过 UserProject)
└──────────┘ └──────────┘
┌──────────┐
│ Dept │ 树形结构(parentId → 自引用)
└──────────┘
┌──────────┐
│DataAccess│ 通用数据访问授权
└──────────┘
┌──────────┐
│ AuditLog │ 操作审计日志
└──────────┘
┌──────────┐
│ SysConfig│ 系统键值对配置
└──────────┘
三、API接口设计
3.1 AuthController — 认证管理
基础路径: /api/auth
| 方法 | 路径 | 说明 | 请求体 | 响应 |
|---|---|---|---|---|
| POST | /login |
用户登录 | {username, password} |
{token, userId, username, realName, roles} |
| POST | /logout |
用户登出 | Header: Authorization | void |
| GET | /me |
获取当前用户 | Header: Authorization | {username} |
| POST | /refresh |
刷新Token | Header: Authorization | {token} |
登录流程:
- 检查登录失败锁定(Redis,5次失败锁定10分钟)
- 查询用户(含角色)
- 验证密码(BCrypt)
- 检查用户状态(LOCKED/DISABLED拒绝)
- 收集所有角色(用户直接角色 + 项目员工角色)
- 生成JWT Token(含userId、username、roles claims)
- 返回Token和用户基本信息
3.2 UserController — 用户管理
基础路径: /api/auth/users
| 方法 | 路径 | 说明 | 审计日志 |
|---|---|---|---|
| GET | / |
分页查询用户列表 | - |
| GET | /{id} |
根据ID获取用户 | - |
| POST | / |
创建用户 | CREATE |
| PUT | /{id} |
更新用户 | UPDATE |
| DELETE | /{id} |
删除用户 | DELETE |
| PUT | /{id}/password |
修改密码 | UPDATE |
| POST | /{id}/roles |
分配角色 | ASSIGN |
| GET | /{id}/projects |
获取用户项目列表 | - |
| POST | /{id}/projects |
添加用户到项目 | - |
| DELETE | /{id}/projects/{projectId} |
从项目移除用户 | - |
| GET | /enterprise |
获取企业员工列表 | - |
密码修改规则:
- 需验证原密码
- 新密码需通过强度校验(8-20位,大小写+数字+特殊字符)
- 弱密码检测(黑名单:password、123456、admin等)
3.3 RoleController — 角色管理
基础路径: /api/auth/roles
| 方法 | 路径 | 说明 | 审计日志 |
|---|---|---|---|
| GET | / |
分页查询角色列表 | - |
| GET | /{id} |
根据ID获取角色 | - |
| GET | /project/{projectId} |
根据项目ID查询角色 | - |
| POST | / |
创建角色 | CREATE |
| PUT | /{id} |
更新角色 | UPDATE |
| DELETE | /{id} |
删除角色 | DELETE |
| POST | /{id}/permissions |
为角色分配权限 | ASSIGN |
| GET | /{id}/permissions |
获取角色权限列表 | - |
| GET | /{id}/users |
获取拥有某角色的用户 | - |
3.4 PermissionController — 权限管理
基础路径: /api/auth/permissions
| 方法 | 路径 | 说明 | 审计日志 |
|---|---|---|---|
| GET | / |
分页查询权限列表 | - |
| GET | /{id} |
根据ID获取权限 | - |
| GET | /type/{type} |
根据类型查询权限 | - |
| GET | /menus |
查询所有菜单权限 | - |
| POST | / |
创建权限 | - |
| PUT | /{id} |
更新权限 | - |
| DELETE | /{id} |
删除权限 | - |
3.5 DeptController — 部门管理
基础路径: /api/auth/depts
| 方法 | 路径 | 说明 | 审计日志 |
|---|---|---|---|
| GET | /tree |
获取部门树 | - |
| GET | / |
获取所有启用部门 | - |
| GET | /{id} |
根据ID获取部门 | - |
| POST | / |
创建部门 | CREATE |
| PUT | /{id} |
更新部门 | UPDATE |
| DELETE | /{id} |
删除部门 | DELETE |
| GET | /{deptId}/members |
获取部门成员 | - |
| GET | /by-type/{deptType} |
根据类型查询部门 | - |
部门树构建:后端返回扁平列表,Controller层递归构建树形结构(DeptVO含children字段)
3.6 ProjectMemberController — 项目成员管理
基础路径: /api/auth/projects
| 方法 | 路径 | 说明 | 审计日志 |
|---|---|---|---|
| GET | /{projectId}/members |
查询项目成员列表(分页) | - |
| GET | /{projectId}/available-members |
获取可添加成员(企业员工) | - |
| POST | /{projectId}/members |
添加项目成员 | CREATE |
| DELETE | /{projectId}/members/{userId} |
移除项目成员 | DELETE |
添加项目成员流程:
- 创建/更新 ProjectStaff 记录(设定员工类型、分配状态)
- 覆盖模式更新角色:先删除旧角色,再添加新角色
- 支持 search 参数模糊搜索可用成员(用户名/姓名)
3.7 DataAccessController — 数据访问授权
基础路径: /api/data-access
| 方法 | 路径 | 说明 | 请求体 |
|---|---|---|---|
| POST | / |
授予数据访问权限 | {dataType, dataId, accessType, accessId, accessLevel} |
| DELETE | /{id} |
撤销数据访问权限 | - |
| GET | / |
查询数据访问记录 | 参数: dataType, dataId |
授权逻辑:若已存在相同 dataType+dataId+accessType+accessId 的记录,则更新 accessLevel;否则新建。
3.8 AuditLogController — 审计日志
基础路径: /api/audit-logs
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | / |
分页查询审计日志(支持module/action/username/日期范围筛选) |
| GET | /modules |
获取模块列表(用于筛选下拉) |
| GET | /actions |
获取操作类型列表(用于筛选下拉) |
| GET | /stats |
获取最近30天日志统计 |
查询约束:强制限制查询范围不超过30天,防止大量数据查询。
模块列表:USER / ROLE / PERMISSION / PROJECT / AUTH
3.9 SysConfigController — 系统配置
基础路径: /api/config
| 方法 | 路径 | 说明 | 审计日志 |
|---|---|---|---|
| GET | / |
获取所有配置项 | - |
| GET | /{configKey} |
根据键获取配置 | - |
| PUT | /{configKey} |
更新单个配置 | UPDATE |
| PUT | / |
批量更新配置 | UPDATE |
四、业务规则
4.1 RBAC 权限模型
模型结构:User ←M2M→ Role ←M2M→ Permission
双层角色分配:
- 用户直接角色:通过
auth_user_role表关联,用户创建时或通过 UserController.assignRoles 分配 - 项目员工角色:通过
ProjectStaffRole关联,项目成员管理时分配
登录时角色收集:
用户所有角色 = 用户直接角色 ∪ 项目员工角色
角色类型与数据范围:
| 角色类型 | 说明 | 数据范围 |
|---|---|---|
| SYSTEM | 系统级角色,跨项目 | ALL |
| PROJECT | 项目级角色,绑定特定项目 | PROJECT |
| DEPARTMENT | 部门级角色 | DEPARTMENT |
4.2 四级数据范围
| 数据范围 | 编码 | 说明 | 实际效果 |
|---|---|---|---|
| 全部 | ALL | 可查看所有数据 | 不做数据过滤 |
| 项目 | PROJECT | 仅可查看所属项目数据 | 过滤 project_id |
| 部门 | DEPARTMENT | 仅可查看本部门数据 | 过滤 project_id + dept_id |
| 本人 | SELF | 仅可查看本人数据 | 过滤 assigned_to/creator |
DataScopeService 实现:
canAccessAllData(): 检查角色集中是否有 ALL 范围isSelfScopeOnly(): 检查是否所有角色都是 SELF 范围getPermittedProjectIds(): 获取用户可访问的项目ID列表
4.3 JWT 认证流程
Token 生成:
- 算法:HMAC-SHA256
- Claims:userId(subject)、username、roles 列表
- 过期时间:可配置(默认86400000ms = 24小时)
认证流程:
1. 客户端 POST /api/auth/login {username, password}
2. 检查登录锁定(Redis: login:attempt:{username})
3. 查询用户 + 验证密码(BCrypt)
4. 检查用户状态
5. 收集角色(直接角色 + 项目员工角色)
6. 生成 JWT Token
7. 返回 {token, userId, username, realName, roles}
后续请求:
1. 客户端 Header: Authorization: Bearer {token}
2. JwtTokenProvider.validateToken() 验证签名和过期
3. 解析 userId / username / roles
Token 刷新:
- POST /api/auth/refresh,需携带有效Token
- 生成新Token返回
4.4 登录失败锁定机制
实现:LoginAttemptService(基于Redis)
| 参数 | 默认值 | 说明 |
|---|---|---|
| maxAttempts | 5 | 最大失败次数 |
| lockoutDurationMinutes | 10 | 锁定时长(分钟) |
| Key格式 | login:attempt:{username} |
Redis Key |
流程:
- 每次失败:increment计数,首次设置TTL
- 达到上限:isLockedOut返回true,拒绝登录
- 登录成功:清除计数
- 手动解锁:unlock方法清除Key
4.5 项目隔离机制
双层隔离:
- UserProject 关联:用户-项目多对多,记录用户参与的项目
- ProjectStaff 扩展:项目员工在特定项目中的详细角色和状态
项目上下文传递:
- 请求头
X-Project-ID携带当前项目ID - ProjectContextInterceptor 拦截器设置 ThreadLocal
- 业务层通过 DataScopeService 过滤数据
项目成员管理:
- 添加成员:创建 ProjectStaff + 分配 ProjectStaffRole
- 移除成员:删除 ProjectStaff(级联删除角色关联)
- 角色分配:覆盖模式(先删后加)
4.6 审计日志
记录方式:@OperationLog 注解 + AOP切面
@OperationLog(operation = "创建用户", module = "USER", action = AuditLog.ActionType.CREATE)
异步持久化:通过 auditLogExecutor 线程池异步保存,避免影响业务性能
查询窗口:强制限制30天,超过30天的查询自动截断起始时间
归档策略:90天以上日志归档(当前实现为直接删除,TODO: 导出至对象存储)
记录模块:USER / ROLE / PERMISSION / PROJECT / AUTH / DEPT / PROJECT_MEMBER / SYSTEM
4.7 密码加密与强度校验
加密算法:BCrypt(Spring Security PasswordEncoder)
强度校验规则(可配置,前缀 password.*):
| 规则 | 默认值 | 说明 |
|---|---|---|
| minLength | 8 | 最小长度 |
| maxLength | 20 | 最大长度 |
| requireUppercase | true | 需要大写字母 |
| requireLowercase | true | 需要小写字母 |
| requireDigit | true | 需要数字 |
| requireSpecial | true | 需要特殊字符 |
弱密码检测:黑名单包含 password、123456、admin、qwerty、letmein、welcome、monkey、dragon
旧密码兼容:检测非BCrypt格式密码(MD5/SHA-1),强制返回false要求重置
五、前端操作流程
5.1 登录
页面:/auth/Login.vue
流程:
- 输入用户名 + 密码
- 调用
POST /api/auth/login - 存储 Token 到本地
- 跳转至主页
前端API:auth.ts → login(), logout(), getCurrentUser(), refreshToken()
5.2 项目选择
流程:
- 登录后获取用户项目列表
GET /api/auth/users/{id}/projects - 用户选择项目
- 后续请求携带
X-Project-IDHeader
5.3 用户管理
页面:/system/Users.vue, /system/UserDetail.vue
操作:
- 用户列表(分页、搜索、状态筛选)
- 创建用户(用户名、密码、真实姓名、手机号、邮箱、用户类型、部门)
- 编辑用户信息
- 删除用户
- 修改密码(需原密码)
- 分配角色(多选,覆盖模式)
- 查看用户参与的项目
前端API:user.ts → getUsers(), createUser(), updateUser(), deleteUser(), updatePassword(), assignRoles(), getUserProjects()
5.4 角色管理
页面:/system/Roles.vue
操作:
- 角色列表(分页、搜索)
- 创建角色(代码、名称、描述、类型、数据范围、所属项目、状态)
- 编辑角色
- 删除角色
- 为角色分配权限(多选,覆盖模式)
- 查看角色关联的用户
前端API:role.ts → getRoles(), createRole(), updateRole(), deleteRole(), assignPermissions(), getRolePermissions(), getRoleUsers(), getRolesByProject()
5.5 权限管理
页面:/system/Permissions.vue
操作:
- 权限列表(分页、搜索)
- 创建权限(代码、名称、类型、资源路径、HTTP方法、描述、父权限、排序)
- 编辑权限
- 删除权限
- 按类型筛选(MENU/BUTTON/API)
- 查看菜单权限
前端API:permission.ts → getPermissions(), createPermission(), updatePermission(), deletePermission(), getPermissionsByModule()
5.6 部门管理
页面:/system/Depts.vue
操作:
- 部门树展示
- 创建部门(名称、上级部门、类型、负责人、排序)
- 编辑部门
- 删除部门(需先删除子部门)
- 查看部门成员
- 按类型筛选部门
前端API:dept.ts → getDeptTree(), getAllDepts(), createDept(), updateDept(), deleteDept(), getDeptMembers(), getDeptsByType()
5.7 审计日志
页面:/system/Audit.vue
操作:
- 日志列表(分页、模块/操作类型/用户名/日期范围筛选)
- 查看日志统计(最近30天总量)
- 模块和操作类型下拉选项
前端API:audit.ts → getAuditLogs(), getAuditModules(), getAuditActions(), getAuditStats()
5.8 系统设置
页面:/system/Settings.vue
操作:
- 查看所有配置项(键值对)
- 单个/批量更新配置值
前端API:system.ts → getConfig(), updateConfig()
六、与原需求文档 05-AUTH.md 的差异对比
6.1 实体差异
| 对比项 | 原需求 05-AUTH.md | 实际代码实现 | 差异说明 |
|---|---|---|---|
| Role.type | SYSTEM / CUSTOM | SYSTEM / PROJECT / DEPARTMENT | 实际代码使用三级分类(系统/项目/部门),而非预设/自定义 |
| Role 业务属性 | 有 businessType、terminalType、isFrontline 字段 | 无这些字段 | 实际代码未实现角色业务属性扩展 |
| Role.status | enabled (Boolean) | status (RoleStatus枚举: ENABLED/DISABLED) | 实际代码使用枚举而非布尔值 |
| Permission 结构 | 有 projectId、module、resource、action、path、component、icon、parentId(UUID)、level、apiMethod、apiPath、enabled | 无 projectId/module/resource/action/path/component/icon/parentId(UUID)/level/apiMethod/apiPath/enabled,有 parentCode(String)、resource、method | 实际代码简化了权限结构,用 parentCode 替代 parentId,缺少菜单路由属性 |
| Permission.type | PermissionType 枚举 (MENU/BUTTON/API) | String 类型 | 实际代码用字符串而非枚举 |
| UserRole 关联 | 独立实体 UserRole(含 projectId、isDefault) | JPA自动管理的 M2M 中间表 auth_user_role(无额外字段) | 实际代码简化了关联,去掉了项目隔离和默认角色标记 |
| OperationLog | auth_operation_log 表,含 projectId、realName、description、requestBody、responseBody、responseStatus、hasError | sys_audit_log 表,含 content、params、result、targetType、targetId、executionTimeMs、status、errorMsg、tenantId | 实际代码使用了不同的表名和字段结构,增加了目标追踪和租户ID |
| VisitorCredential | 完整实体(auth_visitor_credential) | 不存在于 module-auth | 访客凭证未在认证模块实现 |
| EnterpriseUser | 未提及 | 存在,共享主键一对一 | 实际代码增加了企业员工扩展实体 |
| ProjectStaff | 未提及 | 存在,独立主键一对一 | 实际代码增加了项目员工扩展实体 |
| ProjectStaffRole | 未提及 | 存在,项目员工-角色关联 | 实际代码增加了项目级角色分配机制 |
| Resident | 未提及 | 存在,含认证流程 | 实际代码增加了住户实体 |
| ResidentSpace | 未提及 | 存在,住户-房屋关联 | 实际代码增加了住户房屋绑定 |
| Space | 未提及 | 存在,房屋空间 | 实际代码增加了房屋空间实体 |
| UserProject | 未提及 | 存在,用户-项目关联 | 实际代码增加了用户项目多对多 |
| DataAccess | 未提及 | 存在,细粒度数据访问控制 | 实际代码增加了数据访问授权机制 |
| Dept | 未提及 | 存在,树形部门结构 | 实际代码增加了部门管理 |
| SysConfig | 未提及 | 存在,键值对配置 | 实际代码增加了系统配置 |
| User.userType | 未提及 | 存在,ENTERPRISE/PROJECT_STAFF/RESIDENT/CUSTOMER | 实际代码增加了用户类型区分 |
| User.deptId | 未提及 | 存在 | 实际代码增加了部门关联 |
6.2 API 差异
| 对比项 | 原需求 05-AUTH.md | 实际代码实现 | 差异说明 |
|---|---|---|---|
| API路径前缀 | /api/v1/auth |
/api/auth |
实际代码去掉了版本号 v1 |
| 认证接口 | login/logout/refreshToken/currentUser/changePassword/userPermissions | login/logout/refresh/me | 实际代码缺少 changePassword 和 userPermissions 独立端点,/me 替代 currentUser |
| 用户状态修改 | POST /{id}/status 独立端点 |
通过 PUT /{id} 更新status字段 |
实际代码合并到通用更新接口 |
| 权限树 | GET /permissions/tree |
未实现 | 实际代码缺少权限树端点 |
| 权限校验 | POST /check |
未实现 | 实际代码缺少权限校验端点 |
| 用户菜单 | GET /users/{id}/menus |
未实现 | 实际代码缺少用户菜单端点 |
| 用户权限查询 | GET /users/{id}/permissions |
未实现 | 实际代码缺少用户权限查询端点 |
| 部门管理 | 未提及 | 完整CRUD + 树 + 成员查询 | 实际代码新增了部门管理 |
| 项目成员管理 | 未提及 | 完整CRUD + 可用成员查询 | 实际代码新增了项目成员管理 |
| 数据访问授权 | 未提及 | grant/revoke/query | 实际代码新增了数据访问授权 |
| 审计日志 | 未提及 | 完整查询 + 统计 + 筛选选项 | 实际代码新增了审计日志管理 |
| 系统配置 | 未提及 | 完整CRUD + 批量更新 | 实际代码新增了系统配置管理 |
| 企业员工 | 未提及 | GET /users/enterprise |
实际代码新增了企业员工列表 |
| 用户项目关联 | 未提及 | 完整CRUD | 实际代码新增了用户项目关联 |
6.3 业务规则差异
| 对比项 | 原需求 05-AUTH.md | 实际代码实现 | 差异说明 |
|---|---|---|---|
| 角色体系 | 13个预定义角色(SUPER_ADMIN到OWNER) | 角色通过数据库动态管理,无硬编码预定义 | 实际代码采用灵活的角色管理,未绑定固定角色列表 |
| 数据权限SQL生成 | DataScopeHelper 工具类生成SQL片段 | DataScopeService 提供判断方法 | 实际代码未实现SQL自动注入,仅提供判断接口 |
| 项目上下文 | ProjectContextHolder + 拦截器 | 同样实现,通过 X-Project-ID Header | 基本一致 |
| 状态驱动权限 | 工单状态→操作映射设计 | 未在认证模块实现 | 实际代码未实现状态驱动权限(应在业务模块) |
| 访客凭证 | 完整的二维码生成/验证流程 | 不存在于 module-auth | 实际代码未实现访客凭证 |
| 登录失败锁定 | 未提及 | Redis实现,5次失败锁10分钟 | 实际代码新增了登录安全机制 |
| 密码强度校验 | 未提及 | 完整的强度规则 + 弱密码检测 | 实际代码新增了密码安全策略 |
| 旧密码兼容 | 未提及 | 检测非BCrypt格式,强制重置 | 实际代码新增了密码迁移策略 |
| 审计日志 | AOP切面 + 同步保存 | AOP切面 + 异步保存 + 30天查询限制 + 90天归档 | 实际代码增强了审计日志管理 |
| 项目成员角色 | 未提及 | 双层角色(用户直接角色 + 项目员工角色) | 实际代码新增了项目级角色分配 |
| 部门类型 | 未提及 | 5种部门类型(行政/工程/安保/客服/保洁) | 实际代码新增了部门分类 |
| 住户认证 | 未提及 | 4种认证状态(未认证/待审核/已认证/已拒绝) | 实际代码新增了住户认证流程 |
| 数据访问授权 | 未提及 | 通用数据访问控制(dataType/dataId/accessType/accessId/accessLevel) | 实际代码新增了细粒度数据授权 |
6.4 差异总结
实际代码相比原需求增加的功能:
- 多类型用户扩展(EnterpriseUser / ProjectStaff / Resident)
- 项目成员管理(ProjectStaff + ProjectStaffRole)
- 部门管理(树形结构 + 5种类型)
- 住户与房屋关联(ResidentSpace + Space)
- 数据访问授权(DataAccess)
- 系统配置管理(SysConfig)
- 登录失败锁定(Redis)
- 密码强度校验 + 弱密码检测
- 审计日志增强(异步保存、30天窗口、90天归档)
- 用户-项目多对多关联(UserProject)
原需求中未实现的功能:
- 角色业务属性(businessType / terminalType / isFrontline)
- 权限树端点(GET /permissions/tree)
- 权限校验端点(POST /check)
- 用户菜单端点(GET /users/{id}/menus)
- 用户权限查询端点(GET /users/{id}/permissions)
- 访客凭证管理(VisitorCredential)
- 状态驱动权限(工单状态→操作映射)
- Permission 的菜单路由属性(path / component / icon)
- Permission 的模块/资源/操作拆分字段(module / resource / action)
- UserRole 关联的项目隔离和默认角色标记