# 认证授权域功能详细设计文档(反推自代码) **文档类型**: 反推设计文档 **数据来源**: 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}$` | 手机号码 | | email | VARCHAR(100) | @Email | 电子邮箱 | | 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\ | 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\ | 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\ | 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\ | @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` → createdAt - `idx_audit_log_user_id` → userId - `idx_audit_log_module` → module - `idx_audit_log_action` → action - `idx_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}` | **登录流程**: 1. 检查登录失败锁定(Redis,5次失败锁定10分钟) 2. 查询用户(含角色) 3. 验证密码(BCrypt) 4. 检查用户状态(LOCKED/DISABLED拒绝) 5. 收集所有角色(用户直接角色 + 项目员工角色) 6. 生成JWT Token(含userId、username、roles claims) 7. 返回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 | **添加项目成员流程**: 1. 创建/更新 ProjectStaff 记录(设定员工类型、分配状态) 2. 覆盖模式更新角色:先删除旧角色,再添加新角色 3. 支持 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 **双层角色分配**: 1. **用户直接角色**:通过 `auth_user_role` 表关联,用户创建时或通过 UserController.assignRoles 分配 2. **项目员工角色**:通过 `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 项目隔离机制 **双层隔离**: 1. **UserProject 关联**:用户-项目多对多,记录用户参与的项目 2. **ProjectStaff 扩展**:项目员工在特定项目中的详细角色和状态 **项目上下文传递**: - 请求头 `X-Project-ID` 携带当前项目ID - ProjectContextInterceptor 拦截器设置 ThreadLocal - 业务层通过 DataScopeService 过滤数据 **项目成员管理**: - 添加成员:创建 ProjectStaff + 分配 ProjectStaffRole - 移除成员:删除 ProjectStaff(级联删除角色关联) - 角色分配:覆盖模式(先删后加) ### 4.6 审计日志 **记录方式**:`@OperationLog` 注解 + AOP切面 ```java @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` **流程**: 1. 输入用户名 + 密码 2. 调用 `POST /api/auth/login` 3. 存储 Token 到本地 4. 跳转至主页 **前端API**:`auth.ts` → `login()`, `logout()`, `getCurrentUser()`, `refreshToken()` ### 5.2 项目选择 **流程**: 1. 登录后获取用户项目列表 `GET /api/auth/users/{id}/projects` 2. 用户选择项目 3. 后续请求携带 `X-Project-ID` Header ### 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 差异总结 **实际代码相比原需求增加的功能**: 1. 多类型用户扩展(EnterpriseUser / ProjectStaff / Resident) 2. 项目成员管理(ProjectStaff + ProjectStaffRole) 3. 部门管理(树形结构 + 5种类型) 4. 住户与房屋关联(ResidentSpace + Space) 5. 数据访问授权(DataAccess) 6. 系统配置管理(SysConfig) 7. 登录失败锁定(Redis) 8. 密码强度校验 + 弱密码检测 9. 审计日志增强(异步保存、30天窗口、90天归档) 10. 用户-项目多对多关联(UserProject) **原需求中未实现的功能**: 1. 角色业务属性(businessType / terminalType / isFrontline) 2. 权限树端点(GET /permissions/tree) 3. 权限校验端点(POST /check) 4. 用户菜单端点(GET /users/{id}/menus) 5. 用户权限查询端点(GET /users/{id}/permissions) 6. 访客凭证管理(VisitorCredential) 7. 状态驱动权限(工单状态→操作映射) 8. Permission 的菜单路由属性(path / component / icon) 9. Permission 的模块/资源/操作拆分字段(module / resource / action) 10. UserRole 关联的项目隔离和默认角色标记