# GenesFirstBackend **Repository Path**: whalec3/genes-first-backend ## Basic Information - **Project Name**: GenesFirstBackend - **Description**: 基因重一组数字马力项目git仓库 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-08 - **Last Updated**: 2026-07-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # HumanResourceManageSystem 人力资源管理系统 基于 **模块化单体 (Modular Monolith)** 架构的企业级 HRMS 系统,采用 RBAC 权限模型 + 三层鉴权防线设计。 --- ## 技术栈与版本 ### 运行环境 | 类别 | 技术 | 版本 | 说明 | |------|------|------|------| | 语言 | OpenJDK | **17**(编译目标)/ 21(开发推荐) | ⚠️ JDK 25 不兼容 Lombok 1.18.36 | | 构建 | Maven | 3.8+ | | | 容器 | Docker & Docker Compose | 最新稳定版 | | ### 中间件(docker-compose 部署) | 服务 | 镜像 | 宿主机端口 | 账号/密码 | |------|------|-----------|----------| | MySQL | `mysql:8.0` | 3310 | root / root | | Redis | `redis:7.0-alpine` | 6381 | 无密码 | | MinIO | `minio/minio:latest` | 9001 (API), 9002 (Console) | admin / password123 | | Nacos | `nacos/nacos-server:v2.3.2` | 8848, 9848 | — | ### Maven 依赖(pom.xml) | GroupId | ArtifactId | 版本 | 用途 | |---------|-----------|------|------| | `org.springframework.boot` | `spring-boot-starter-parent` | **3.4.1** | Spring Boot 父 POM | | `org.springframework.boot` | `spring-boot-starter-web` | 3.4.1 | Web 框架 (Spring MVC) | | `org.springframework.boot` | `spring-boot-starter-security` | 3.4.1 | 安全框架 (认证 + 鉴权) | | `org.springframework.boot` | `spring-boot-starter-data-redis` | 3.4.1 | Redis 客户端 (Lettuce) | | `org.springframework.boot` | `spring-boot-starter-mail` | 3.4.1 | 邮件发送 (QQ SMTP) | | `org.springframework.boot` | `spring-boot-starter-validation` | 3.4.1 | Jakarta Bean Validation | | `org.springframework.boot` | `spring-boot-starter-test` | 3.4.1 | 测试框架 (test scope) | | `com.baomidou` | `mybatis-plus-spring-boot3-starter` | **3.5.7** | ORM 框架 (MyBatis Plus) | | `com.mysql` | `mysql-connector-j` | (由 parent 管理) | MySQL 驱动 | | `io.minio` | `minio` | **8.5.13** | 对象存储 SDK | | `io.jsonwebtoken` | `jjwt-api` | **0.12.6** | JWT 签发与校验 | | `io.jsonwebtoken` | `jjwt-impl` | 0.12.6 | JWT 实现 (runtime) | | `io.jsonwebtoken` | `jjwt-jackson` | 0.12.6 | JWT Jackson 序列化 (runtime) | | `cn.hutool` | `hutool-all` | **5.8.34** | 工具库(验证码、字符串等) | | `org.projectlombok` | `lombok` | **1.18.36** | 代码简化 (provided scope) | --- ## 快速开始 ### 1. 环境准备 ```bash # 确认 JDK 版本(必须是 JDK 17 或 21) java -version # 如默认是 JDK 25,需临时切换 export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64 ``` ### 2. 启动中间件 ```bash cd backend docker-compose up -d ``` ### 3. 初始化数据库 ```bash mysql -h 127.0.0.1 -P 3310 -u root -proot < src/main/resources/sql/schema-auth.sql ``` ### 4. 编译与运行 ```bash # 编译 mvn clean compile # 启动应用(端口 8080) mvn spring-boot:run # 打包 mvn clean package -DskipTests ``` ### 5. 验证 ```bash # 获取图形验证码 curl -s http://localhost:8080/api/v1/auth/captcha | python3 -m json.tool ``` ### 测试账号 | 账号 | 密码 | 角色 | 数据范围 | |------|------|------|---------| | admin | 123456 | 系统管理员 | 全平台 | | hr_zhang | 123456 | HR 专员 | 全部员工 | | leader_li | 123456 | 部门主管 | 本部门及下属 | | fin_wang | 123456 | 财务专员 | 财务部 (自定义) | | emp_zhao | 123456 | 普通员工 | 仅本人 | --- ## 登录认证与授权体系 ### 核心文件清单 登录认证涉及 **3 个包、14 个核心文件**,按请求处理流程排列: #### 第一梯队:请求入口(API 层) | 文件 | 路径 | 作用 | |------|------|------| | `AuthController` | `module/system/api/controller/` | 认证 REST 控制器 — 暴露 6 个认证端点:获取验证码、密码登录、发送邮箱验证码、邮箱登录、密码重置、登出 | | `LoginRequest` | `module/system/api/dto/` | 密码登录请求 DTO — 兼容 `account`/`username` 双字段名 | | `EmailLoginRequest` | `module/system/api/dto/` | 邮箱登录请求 DTO | | `EmailCodeRequest` | `module/system/api/dto/` | 发送邮箱验证码请求 DTO(支持 login/reset 类型) | | `ResetPasswordRequest` | `module/system/api/dto/` | 密码重置请求 DTO | #### 第二梯队:认证业务(Application 层) | 文件 | 路径 | 作用 | |------|------|------| | `AuthServiceImpl` | `module/system/application/service/` | **认证核心服务** — 登录校验、防暴力破解封控、Token 签发、登出、密码重置、验证码生成、邮箱验证码发送、登录日志记录 | | `UserDetailsServiceImpl` | `module/system/application/service/` | **权限聚合服务** — 登录时执行 5 步联表查询,一次性聚合用户全部安全凭证(角色、权限标识、数据范围、字段权限)注入 `LoginUser` | #### 第三梯队:安全基础设施(Framework 层) | 文件 | 路径 | 作用 | |------|------|------| | `SecurityConfig` | `framework/security/config/` | **安全总控中心** — 配置白名单路径、禁用 Session、注册 JWT 过滤器、开启 `@PreAuthorize` 方法级鉴权 | | `JwtAuthenticationFilter` | `framework/security/filter/` | **JWT 安检门** — 拦截每个请求,从 Header 提取 Bearer Token → 校验 JWT → 从 Redis 读取 LoginUser → 注入 SecurityContext → 滑动续期 | | `LoginUser` | `framework/security/core/` | **安全载体** — 实现 `UserDetails` 接口,携带 userId、deptId、roles、permissions、dataScopeDeptIds、fieldPermissions | | `SecurityUtils` | `framework/security/util/` | **安全工具箱** — 静态方法随时随地获取当前用户上下文、判断超级管理员、支持"上帝模式"运行定时任务 | | `JwtTokenProvider` | `framework/jwt/` | **JWT 工具** — JWT 签发/校验/解析,Token 中仅存 UUID,用户信息在 Redis | | `RedisService` | `framework/redis/service/` | **Redis 缓存服务** — 封装 String/Set/过期等通用操作,支撑会话存储和滑动续期 | | `CustomAuthEntryPoint` | `framework/security/handler/` | **401 处理器** — Token 缺失/失效时返回 JSON `{"code":401, "msg":"登录已过期"}` | | `CustomAccessDeniedHandler` | `framework/security/handler/` | **403 处理器** — 已登录但权限不足时返回 JSON `{"code":403, "msg":"无权访问该资源"}` | #### 数据层(Infrastructure 层,登录时读取) | 文件 | 路径 | 作用 | |------|------|------| | `SysUser` | `module/system/.../persistence/entity/` | 系统用户实体 — 对应 `sys_user` 表 | | `SysUserMapper` | `module/system/.../persistence/mapper/` | 用户 Mapper — `BaseMapper` + 自定义 `selectByUserId` | | `SysRoleMapper` | `module/system/.../persistence/mapper/` | 角色 Mapper | | `SysUserRoleMapper` | `module/system/.../persistence/mapper/` | 用户-角色关联 Mapper | | `SysRolePermissionMapper` | `module/system/.../persistence/mapper/` | 角色-权限关联 Mapper | | `SysPermissionMapper` | `module/system/.../persistence/mapper/` | 权限资源 Mapper | | `SysDataScopeRuleMapper` | `module/system/.../persistence/mapper/` | 数据范围规则 Mapper | | `SysDataScopeDeptMapper` | `module/system/.../persistence/mapper/` | 自定义部门范围 Mapper | | `SysFieldPermissionMapper` | `module/system/.../persistence/mapper/` | 字段权限 Mapper | | `SysLoginLogMapper` | `module/system/.../persistence/mapper/` | 登录日志 Mapper | | `schema-auth.sql` | `resources/sql/` | 数据库初始化脚本(11 张表 + 测试数据) | ### 登录认证流程图 #### 密码登录流程 ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ 密码登录 (POST /api/v1/auth/login) │ └─────────────────────────────────────────────────────────────────────────┘ 前端 AuthController AuthServiceImpl Redis/DB/Spring Security ──── ────────────── ────────────── ───────────────────── │ │ │ │ │── POST /api/v1/auth/login ──────▶│ │ │ │ {account, password, │ │ │ │ captchaId, captchaCode} │ │ │ │ │── login(username,pwd, │ │ │ │ captchaId,captchaCode)─▶│ │ │ │ │ │ │ │ │── ① 校验图形验证码 ──────────▶│ Redis: auth:captcha:img:{uuid} │ │ │◀─── 正确 / 过期 / 错误 ──────│ │ │ │ │ │ │ │── ② 防刷封控检查 ────────────▶│ Redis: auth:pwd_lock:{username} │ │ │◀─── 是否锁定 ────────────────│ │ │ │ │ │ │ │── ③ 密码校验 ────────────────▶│ Spring Security │ │ │ AuthenticationManager │ AuthenticationManager │ │ │ .authenticate() │ → UserDetailsServiceImpl │ │ │ │ .loadUserByUsername() │ │ │ │ ├─ 查 sys_user │ │ │ │ ├─ 查 sys_user_role + sys_role │ │ │ │ ├─ 查 sys_role_permission + sys_permission │ │ │ │ ├─ 查 sys_data_scope_rule + _dept │ │ │ │ └─ 查 sys_field_permission │ │ │◀── LoginUser (含全部权限) ────│ → 组装 LoginUser │ │ │ │ │ │ ┌─ 密码错误 ──▶ handleLoginFailure() ───▶│ Redis: 错误次数+1 / 5次锁定 │ │ │ ◀── throw BusinessException │ │ │ │ │ │ │ └─ 密码正确 ──▶ clearLoginFailureState()─▶│ Redis: 清除错误计数和锁 │ │ │ │ │ │ │── ④ 签发 Token ──────────────▶│ │ │ │ UUID → JWT │ Redis: │ │ │ LoginUser → Redis │ SET auth:token:{uuid} = LoginUser (TTL 30min) │ │ │ 记录活跃 Token 集合 │ SADD auth:user:{userId}:tokens {uuid} │ │ │ │ │ │ │── ⑤ 记录登录日志 ────────────▶│ DB: INSERT sys_login_log │ │ │ │ │◀── { code:200, data:"Bearer eyJ..." } ─────────────────────│ │ │ │ │ │ ``` #### 请求鉴权流程(三层防线) ``` ┌───────────────────────────────────────────────────────────────────────────────┐ │ 每个业务请求的鉴权流程 (JWT + Redis 会话 + 三层权限) │ └───────────────────────────────────────────────────────────────────────────────┘ 客户端 JwtAuthenticationFilter Spring Security DataScopeInterceptor Jackson序列化 ────── ─────────────────────── ──────────────── ───────────────────── ────────────── │ │ │ │ │ │── GET /api/v1/employee/test-list ──▶│ │ │ │ │ Authorization: Bearer eyJ... │ │ │ │ │ │ │ │ │ │ │── ① 提取 Token ────────────────│ │ │ │ │ 去掉 "Bearer " 前缀 │ │ │ │ │ │ │ │ │ │── ② 校验 JWT 签名 ─────────────│ │ │ │ │ JwtTokenProvider.validate() │ │ │ │ │ │ │ │ │ │── ③ 从 JWT 取 UUID ───────────│ │ │ │ │ getUuidFromToken() │ │ │ │ │ │ │ │ │ │── ④ 从 Redis 读 LoginUser ────▶│ Redis │ │ │ │ GET auth:token:{uuid} │ │ │ │ │◀── LoginUser (JSON) ──────────│ │ │ │ │ │ │ │ │ │── ⑤ 注入 SecurityContext ──────│ │ │ │ │ SecurityContextHolder.set() │ │ │ │ │ │ │ │ │ │── ⑥ 滑动续期 ────────────────▶│ Redis │ │ │ │ EXPIRE auth:token:{uuid} 30min│ │ │ │ │ │ │ │ │ │── doFilter() ─────────────────▶│ │ │ │ │ │ │ │ │ │ ┌─ 白名单路径? ───┤ (放行) │ │ │ │ │ │ │ │ │ │ ├─ 第一层防线 ────┤ │ │ │ │ │ @PreAuthorize │ │ │ │ │ │ hasAuthority │ │ │ │ │ │ ("employee:list")│ │ │ │ │ │ 无权限 → 403 │ │ │ │ │ │ │ │ │ │ │ └─ 通过 ────────▶│ Controller │ │ │ │ │ │ │ │ │ │── employeeMapper ───────▶│ │ │ │ │ .selectList(null) │ │ │ │ │ │ │ │ │ │ ┌─ 第二层防线 ──┤ │ │ │ │ │ DataScope │ │ │ │ │ │ Interceptor │ │ │ │ │ │ 自动推断 │ │ │ │ │ │ resourceType │ │ │ │ │ │ =EMPLOYEE │ │ │ │ │ │ 拼接 WHERE │ │ │ │ │ │ dept_id IN() │ │ │ │ │ │ OR emp_id=? │ │ │ │ │ └──────────────┤ │ │ │ │ SQL 已注入行过滤条件 │ │ │ │◀── List ───────│ │ │ │ │ │ │ │ │ │── return Result ──────────────────────────────▶│ │ │ │ │ │ │ │ │ ┌─ 第三层防线 ───────────────┤ │ │ │ │ FieldPermissionSerializer │ │ │ │ │ Modifier │ │ │ │ │ phone→READONLY 正常输出 │ │ │ │ │ idCard→MASKED→"***" │ │ │ │ │ baseSalary→HIDDEN→移除字段 │ │ │ │ └───────────────────────────│ │ │ │ │ │ │◀── { code:200, data: [...] } JSON (敏感字段已脱敏) ◀───────────────────────────────────────────────────────────────│ │ │ │ │ │ ``` #### 邮箱验证码登录(安全降级通道) ``` ┌──────────────────────────────────────────────────────────────────────────────┐ │ 邮箱验证码登录 (POST /api/v1/auth/login/email) — 封控降级通道 │ └──────────────────────────────────────────────────────────────────────────────┘ 前端 AuthController AuthServiceImpl Redis / DB ──── ────────────── ────────────── ──────────── │ │ │ │ │── ① 获取邮箱验证码 ───────────▶│ │ │ │ POST /auth/email-code │── sendEmailCode() ─────▶│ │ │ {email, type:"login"} │ │── 生成6位数字验证码 ───────────▶│ Redis: SET auth:captcha:mail_login:{email} │ │ │── 发送邮件 ───────────────────▶│ QQ SMTP │◀── { code:200 } ──────────────│ │ │ │ │ │ │ │── ② 邮箱登录 ─────────────────▶│ │ │ │ POST /auth/login/email │── emailLogin() ────────▶│ │ │ {email, code} │ │── 校验 Redis 验证码 ──────────▶│ Redis: GET auth:captcha:mail_login:{email} │ │ │── 根据邮箱查用户 ─────────────▶│ DB: SELECT * FROM sys_user WHERE email=? │ │ │── loadLoginUser() ────────────▶│ UserDetailsServiceImpl (5步联表) │ │ │── 删除已验证码 ───────────────▶│ Redis: DEL captcha key │ │ │── clearLoginFailureState() ───▶│ Redis: 清除密码错误计数 + 封控锁 │ │ │── issueToken() ───────────────▶│ Redis: SET auth:token:{uuid} │ │ │── 记录登录日志 ───────────────▶│ DB: INSERT sys_login_log │◀── { code:200, data:"Bearer eyJ..." } ─────────────────│ │ │ │ │ │ │ ``` ### Redis 会话数据契约 | Key 模式 | 类型 | 内容 | TTL | 用途 | |---------|------|------|-----|------| | `auth:token:{uuid}` | String | `LoginUser` JSON | **30 分钟** | 核心会话,每次请求滑动续期 | | `auth:user:{userId}:tokens` | Set | UUID 集合 | **7 天** | 改密/禁用时全局踢人 | | `auth:pwd_err_count:{username}` | String(Integer) | 错误次数 | **24 小时** | 防暴力破解计数 | | `auth:pwd_lock:{username}` | String | "LOCKED" | **15 分钟** | 封控熔断锁 | | `auth:captcha:img:{uuid}` | String | 验证码答案 | **5 分钟** | 图形验证码 | | `auth:captcha:mail_login:{email}` | String | 6 位数字 | **5 分钟** | 邮箱登录验证码 | | `auth:captcha:mail_reset:{email}` | String | 6 位数字 | **5 分钟** | 密码重置验证码 | ### 封控机制 ``` 密码错误 ──▶ Redis 错误计数 +1 │ ├── 错误 < 5 次 ──▶ 返回 "用户名或密码错误"(40305) │ └── 错误 ≥ 5 次 ──▶ Redis 写入封控锁 (TTL 15min) │ └── 后续密码登录 ──▶ 返回 "账号已锁定,请使用邮箱验证码登录"(40306) │ └── 邮箱验证码登录成功 ──▶ 主动清除错误计数 + 封控锁 ``` --- ## 项目架构 ### 分层架构总览 ``` com.genesfirst.hrms ├── GenesFirstApplication.java # Spring Boot 启动类 ├── common/ # 全局公共层 │ ├── constant/ # 常量 (AuthConstants, HttpStatusCode) │ ├── exception/ # 通用异常 (BusinessException, ForbiddenException) │ ├── response/ # 统一响应体 (Result, PageResult) │ └── util/ # 工具类 (IpUtils, StringUtils) ├── framework/ # 技术基础设施层 │ ├── security/ # Spring Security 配置 + JWT 过滤器 + LoginUser + 安全工具 │ ├── jwt/ # JWT Token 签发/校验 (JwtTokenProvider) │ ├── mybatis/ # MyBatis Plus 配置 + @DataScope 注解 + 数据权限拦截器 │ ├── jackson/ # Jackson 序列化配置 + 字段脱敏修改器 │ ├── redis/ # Redis 配置 + 缓存服务 (RedisService) │ ├── mail/ # 邮件服务 (MailService) │ └── web/ # WebMvc 配置 + 全局异常处理 (GlobalExceptionHandler) ├── sharedkernel/ # 共享业务内核(跨模块接口 + 模型) │ ├── employee/ # Employee 共享模型 + EmployeeQueryService 接口 │ ├── department/ # Department 共享模型 + DepartmentQueryService 接口 │ └── dictionary/ # 字典缓存 (DictionaryCache) └── module/ # 业务模块层 ├── system/ # 系统管理模块 (认证/角色/权限/菜单) │ ├── api/controller/ # AuthController, RoleController, MenuController, PermissionController │ ├── api/dto/ # LoginRequest, EmailCodeRequest 等 │ ├── application/service/ # AuthServiceImpl, UserDetailsServiceImpl, RoleServiceImpl, PermissionServiceImpl │ └── infrastructure/persistence/ # Entity (11张表) + Mapper └── employee/ # 员工管理模块 (三层权限验证测试) ├── api/controller/ # EmployeeController └── infrastructure/persistence/ # Employee Entity + Mapper ``` ### 模块内部三层结构 ``` module/{name}/ ├── api/ │ ├── controller/ # REST 控制器 — 接收请求、参数校验、调用 Application 服务 │ └── dto/ # 请求/响应 DTO ├── application/ │ └── service/ # 应用服务 — 业务逻辑编排,不包含 SQL └── infrastructure/ └── persistence/ ├── entity/ # MyBatis Plus Entity — 对应数据库表 (@TableName) └── mapper/ # MyBatis Plus Mapper — 继承 BaseMapper ``` ### 包依赖规则 ``` ┌─────────────────────────────────────────────┐ │ module │ ← 业务模块层 │ api ──▶ application ──▶ infrastructure │ └─────────────────────────────────────────────┘ │ │ │ ▼ ▼ ▼ sharedkernel framework common (跨模块接口) (技术基础设施) (全局公共) ``` - **common** 不依赖 framework 或 module - **module** 之间禁止横向直接依赖,通过 sharedkernel 接口或 Spring Event 通讯 - 业务模块内部单向:api → application → infrastructure --- ## 项目文件结构 ``` HumanResouceManageSystem/ ├── README.md # 本文件 ├── .gitignore ├── .claude/ # Claude Code 配置 ├── doc/ # 系统设计文档 │ ├── 认证与权限体系系分.md # 认证权限体系详细设计 │ ├── 前端登录与认证模块系分.md # 前端登录模块设计 │ └── 模块间通信.md # 模块间通信方案 ├── frontend/ # 前端项目(待建立) └── backend/ # 后端项目 ├── pom.xml # Maven 配置 ├── docker-compose.yml # 中间件编排 ├── CLAUDE.md # Claude Code 后端指南 └── src/main/ ├── java/com/genesfirst/hrms/ # Java 源码 └── resources/ ├── application.yml # 应用配置 └── sql/ └── schema-auth.sql # 数据库初始化(DDL + 种子数据) ``` --- ## API 接口列表 ### 认证接口(白名单,无需 Token) | 方法 | 路径 | 说明 | |------|------|------| | GET | `/api/v1/auth/captcha` | 获取图形验证码 | | POST | `/api/v1/auth/login` | 密码登录 | | POST | `/api/v1/auth/email-code` | 发送邮箱验证码 | | POST | `/api/v1/auth/login/email` | 邮箱验证码登录 | | POST | `/api/v1/auth/password/reset` | 忘记密码重置 | ### 认证接口(需 Token) | 方法 | 路径 | 说明 | |------|------|------| | POST | `/api/v1/auth/logout` | 登出 | ### 业务接口(需 Token + 权限) | 方法 | 路径 | 所需权限 | 说明 | |------|------|---------|------| | GET | `/api/v1/employee/test-list` | `employee:list` | 员工列表(三层权限测试) | --- ## 相关文档 - [认证与权限体系系分](doc/认证与权限体系系分.md) — 安全设计、数据契约、数据库表结构 - [前端登录与认证模块系分](doc/前端登录与认证模块系分.md) — 前端交互流程 - [模块间通信](doc/模块间通信.md) — 跨模块通讯方案 - [CLAUDE.md](CLAUDE.md) — Claude Code 操作指南 - [CLAUDE.md (backend)](backend/CLAUDE.md) — 后端开发详细指南