项目名称: jeeplus cloud
组织: org.jeeplus
版本: 9.0
架构模式: Spring Cloud 微服务 + 多模块 Maven 工程
JDK: 1.8
构建工具: Maven
┌──────────────────────────────────────────────────────────┐
│ Nacos (8848) │
│ 服务注册/发现 + 配置中心 │
└──────────────────────┬───────────────────────────────────┘
│
┌──────────────────────┴───────────────────────────────────┐
│ Sentinel (8858) │
│ 流量控制 + 熔断降级 │
└──────────────────────┬───────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ jeeplus-gateway (:8088) │
│ Spring Cloud Gateway + WebFlux │
│ 路由转发 / JWT鉴权 / Swagger聚合 │
└──────────────────────┬───────────────────────────────────┘
│
┌────────────┼────────────┬──────────────┐
▼ ▼ ▼ ▼
┌──────────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐
│ jeeplus-auth │ │jeeplus- │ │jeeplus- │ │ jeeplus-modules │
│ (:9211) │ │ system │ │ flowable │ │ (assess, finance, │
│ 登录/认证 │ │ │ │ 工作流 │ │ human, ccpm …) │
└──────────────┘ └──────────┘ └──────────┘ └──────────────────┘
│
▼
┌──────────────────┐
│ Spring Boot │
│ Admin (:8989) │
│ 服务监控 │
└──────────────────┘
请求链路:
客户端请求 → Gateway(:8088) → JWTFilter 鉴权 → 路由转发 → 目标微服务
│
Redis (token 校验/刷新)
jeeplus (POM, parent)
├── jeeplus-gateway [网关服务 - Spring Boot]
├── jeeplus-auth [认证服务 - Spring Boot]
├── jeeplus-api (POM) [接口定义聚合]
│ ├── jeeplus-system-api [系统API: IUserApi, ITenantApi, BaseDTO, TreeDTO]
│ ├── jeeplus-public-modules-api [公共模块API: IWorkAttachmentApi]
│ ├── jeeplus-finance-api [财务API: ICwProjectReportApi]
│ └── jeeplus-file-api [文件API: IFileApi]
├── jeeplus-common (POM) [公共组件聚合]
│ ├── jeeplus-common-core [核心: Entity/DTO基类, Redis, Excel, Query, 常量]
│ ├── jeeplus-common-log [日志: AOP切面, @ApiLog注解]
│ ├── jeeplus-common-mybatis-plus [ORM: MyBatis-Plus配置, 分页, 多租户]
│ ├── jeeplus-common-security [安全: JWT, Spring Security, TokenProvider]
│ └── jeeplus-common-swagger [文档: Knife4j/Swagger配置]
└── jeeplus-modules (POM) [业务模块聚合]
├── jeeplus-system [★核心: 用户/角色/菜单/租户/部门/数据权限]
├── jeeplus-flowable [★工作流: Flowable引擎]
├── jeeplus-file [文件存储: MinIO/OSS]
├── jeeplus-finance [财务管理]
├── jeeplus-assess [评估考核]
├── jeeplus-human [人力资源管理]
├── jeeplus-ccpm [项目管理]
├── jeeplus-consult [培训咨询]
├── jeeplus-public-modules [公共功能: 收藏/合同/知识库/会议室/抽奖/物料等]
├── jeeplus-centrecareful [中审管理]
├── jeeplus-psi-management [PSI管理]
├── jeeplus-devtools [开发工具]
├── jeeplus-ureport [报表引擎]
├── jeeplus-wps [WPS集成]
├── jeeplus-xxl-job-admin [XXL-Job调度中心]
├── jeeplus-xxl-job-executor-sample [XXL-Job执行器]
├── jeeplus-admin-server [Spring Boot Admin监控]
└── jeeplus-test [测试模块]
| 组件 | 版本 | 用途 |
|---|---|---|
| Spring Boot | 2.4.4 | 微服务基础框架 |
| Spring Cloud | 2020.0.2 (Ilford) | 微服务治理 |
| Spring Cloud Alibaba | 2021.1 | 阿里云微服务生态 |
| Nacos | 2.0.0 | 服务注册/发现 + 配置中心 |
| Sentinel | 2.2.5.RELEASE | 流量防卫兵(限流/熔断) |
| Spring Cloud Gateway | — | API 网关 |
| MyBatis-Plus | 3.4.2 | ORM 增强框架 |
| Druid | 1.2.8 | 数据库连接池 |
| dynamic-datasource | 3.5.1 | 多数据源 |
| Redis (Spring Data) | — | 分布式缓存(token/字典/菜单) |
| MinIO | 8.0.3 | 对象存储(自建) |
| Aliyun OSS | 3.13.1 | 对象存储(阿里云) |
| Flowable | 6.7.2 | 工作流引擎 |
| Liquibase | 4.3.5 | 数据库版本管理 |
| XXL-Job | 2.3.1 | 分布式定时任务 |
| Knife4j (Swagger) | 2.0.8 | API 文档 |
| MapStruct | 1.4.2 | 对象映射转换 |
| Lombok | 1.18.24 | 代码简化 |
| Hutool | 5.7.13 | Java 工具包 |
| Guava | 29.0-jre | 集合/缓存工具 |
| EasyExcel | 3.1.1 | Excel 读写 |
| Auth0 JWT | 3.4.0 | JWT Token 处理 |
| Spring Boot Admin | 2.5.1 | 服务监控 |
| UReport | 2.2.9 | 报表引擎 |
| CAS Client | 3.5.1 | 单点登录客户端 |
| Easypoi | 4.3.0 | POI 工具 |
端口: 8088
服务名: jeeplus-gateway
技术栈: Spring Cloud Gateway + WebFlux + Spring Security Reactive
jeeplus-gateway/src/main/java/com/jeeplus/gateway/
├── JeeplusGatewayApplication.java # 启动类 (排除DataSource/MyBatisPlus自动配置)
├── config/
│ ├── SecurityConfiguration.java # WebFlux安全配置 (白名单/认证规则)
│ └── SwaggerProvider.java # Swagger资源聚合
├── controller/
│ └── SwaggerResourceController.java # Swagger文档入口
├── filter/
│ └── JWTFilter.java # WebFlux JWT过滤器 (Order=-300)
├── handler/
│ └── GatewayExceptionHandler.java # 统一异常处理 (ErrorWebExceptionHandler)
├── security/
│ └── TokenProvider.java # 网关层Token生成/校验/刷新
├── service/
│ └── ... # 网关业务服务
└── excepiton/
├── JwtAccessDeniedHandler.java
└── JwtAuthenticationEntryPoint.java
SecurityConfiguration 安全规则:
@EnableWebFluxSecurity + @EnableReactiveMethodSecurityignore.whiteList 配置读取白名单 URL/api/** 路径需要认证/management/** (健康检查) 放行JWTFilter (网关层):
user:cache:token 校验 tokenReactiveSecurityContextHolderGatewayExceptionHandler:
NotFoundException, ConnectTimeoutException, AccessDeniedExceptionMethodArgumentNotValidException, BindException依赖:
spring-cloud-starter-gateway # 网关核心
spring-cloud-starter-alibaba-nacos-discovery # Nacos注册
spring-cloud-starter-alibaba-nacos-config # Nacos配置
spring-cloud-starter-alibaba-sentinel # Sentinel
spring-cloud-alibaba-sentinel-gateway # Sentinel网关
spring-boot-starter-security # 安全
spring-boot-starter-actuator # 监控端点
springfox-boot-starter # Swagger
kaptcha # 验证码
hutool-all # 工具
jeeplus-system-api # 系统API(Feign)
端口: 9211
服务名: jeeplus-auth
技术栈: Spring Boot + Spring Security + JWT
jeeplus-auth/src/main/java/com/jeeplus/auth/
├── JeeplusAuthApplication.java # 启动类 (@EnableCaching)
├── config/
│ └── DingTalkProperties.java # 钉钉多租户配置
├── controller/
│ ├── LoginController.java # 登录核心控制器 (694行)
│ └── app/ # 移动端控制器
├── model/
│ └── LoginForm.java # 登录表单
└── service/
└── DingTalkAuthService.java # 钉钉AuthCode授权服务
| 接口 | 路径 | 说明 |
|---|---|---|
| 账号密码登录 | POST /user/login |
标准账号密码 + 验证码 + 单一登录校验 |
| 微信登录 | POST /user/sys/wxLogin |
通过 openId 免密登录 |
| 钉钉免登 | POST /user/sys/ddLogin |
钉钉 ddId 免密登录 |
| 钉钉授权登录 | POST /user/sys/dingtalk/login |
钉钉 authCode OAuth2 登录 |
| 钉钉绑定登录 | POST /user/sys/dingtalk/bindLogin |
首次钉钉用户绑定系统账号 |
| CAS单点登录 | GET /user/casLogin |
CAS ticket 验证 |
| 退出登录 | GET /user/logout |
清除 Redis token + 钉钉解绑 |
| 获取验证码 | GET /user/getCode |
Hutool 图形验证码 |
1. 客户端提交 LoginForm (username/password/code/uuid)
2. 检查 Redis 登录失败次数 (超过5次需要验证码, 超过10次禁止登录)
3. Spring Security AuthenticationManager.authenticate()
4. 调用 IUserApi.getByLoginName() 获取用户信息
5. 单一登录检查: IUserApi.isEnableLogin()
6. 特殊规则: 樊莉↔黄玮 互斥登录
7. 生成 JWT Token → 存入 Redis (user:cache:token)
8. 在线用户列表存入 Redis (user:cache:online:users)
9. 更新用户最后登录信息 (IP/时间)
依赖:
jeeplus-system-api # 系统API(Feign调用User/Tenant)
jeeplus-common-security # 公共安全模块(JWT/SecurityUtils)
jeeplus-common-swagger # Swagger文档
jeeplus-common-log # 日志AOP
spring-boot-starter-web # Web MVC
nacos-discovery/nacos-config # Nacos
sentinel # Sentinel
actuator + admin-client # 监控
cas-client-core # CAS单点登录
所有微服务间的 Feign 调用契约 都定义在此层。每个 API 模块包含:
feign/ — FeignClient 接口factory/ — FallbackFactory 降级工厂domain/ — 共享领域对象service/dto/ — DTO 传输对象| 模块 | 核心 Feign 接口 | 服务提供者 | 主要功能 |
|---|---|---|---|
| jeeplus-system-api | IUserApi, ITenantApi | jeeplus-system | 用户CRUD, 权限查询, 租户 |
| jeeplus-system-api | (flowable工厂) | 各业务模块 | FlowableApi, AssessApi, CcpmApi, FinanceApi, HumanApi, ConsultApi, PsiManagementApi, ZsApi |
| jeeplus-file-api | IFileApi | jeeplus-file | 文件上传下载 |
| jeeplus-finance-api | ICwProjectReportApi | jeeplus-finance | 财务项目报告 |
| jeeplus-public-modules-api | IWorkAttachmentApi | jeeplus-public-modules | 工作附件 |
FeignClient(name = "jeeplus-system", path = "/feign/sys/user")
├── 用户查询: getByLoginName(), getByOpenId(), getByDdId(), getById(), getUserDTOByName()
├── 权限查询: getPermissions(), getDataRuleList()
├── 在线管理: isEnableLogin(), getOnLineUserList()
├── 用户更新: updateUser(), saveOrUpdate(), updateUserById(), updateUserUpPassword()
├── 短信发送: sendRandomCodes(), sendEntryRandomCodes()
├── 文件操作: getFileDir(), delFile()
├── 认证相关: getCertListByUserId(), addDefaultSignatureCount()
└── 批量查询: findListByPostId(), findListByRoleId(), findListByOfficeId(), findListByCompanyId()
FeignClient(name = "jeeplus-system")
└── getCurrentTenantId() → 从请求上下文获取当前租户ID
BaseDTO (jeeplus-system-api):
字段: taskId, procInsId, processDefinitionId (流程相关)
id, createTime, createBy(UserDTO), updateTime, updateBy(UserDTO)
delFlag, tenantDTO(TenantDTO)
TreeDTO extends BaseDTO:
字段: parent(T), children(List<T>), parentIds, name, sort
方法: getParentId(), getParentName(), getRootId()="0"
目录结构:
jeeplus-common-core/src/main/java/com/jeeplus/
├── core/
│ ├── annotation/JeeplusCloudApplication.java # 组合注解(@EnableDiscoveryClient+@EnableFeignClients+@EnableAsync)
│ ├── domain/BaseEntity.java # 实体基类
│ ├── domain/TreeEntity.java # 树形实体基类
│ ├── domain/TreeMapper.java # 树形Mapper基类
│ ├── dto/DragNode.java # 拖拽排序DTO
│ ├── mapstruct/EntityWrapper.java # MapStruct DTO↔Entity映射
│ ├── mapstruct/TreeWrapper.java # 树形映射(含parent转换)
│ ├── query/Query.java # @Query 查询注解
│ ├── query/QueryType.java # 查询类型枚举
│ └── query/QueryWrapperGenerator.java # 动态查询条件构建器
├── common/
│ ├── constant/AppNameConstants.java # 服务名常量
│ ├── constant/CacheNames.java # 缓存Key常量
│ ├── constant/ErrorConstants.java # 错误消息常量
│ ├── constant/CommonConstants.java # 通用常量
│ ├── excel/EasyExcelUtils.java # EasyExcel工具
│ ├── excel/ExcelListener.java # Excel读取监听器
│ ├── excel/annotation/ # Excel注解(@ExcelField等)
│ ├── redis/RedisUtils.java # Redis工具(1439行, 完整API)
│ ├── redis/RedisConfig.java # Redis配置
│ ├── utils/Collections3.java # 集合工具
│ ├── utils/CommonUtils.java # 通用工具
│ ├── utils/RequestUtils.java # 请求工具(token解析)
│ ├── utils/ResponseUtil.java # 响应构建器
│ └── converter/StringToDateConverter.java # 日期转换器
├── config/
│ ├── AppInit.java # 启动信息打印(CommandLineRunner)
│ ├── DomainFeignConfig.java # Feign配置
│ ├── ExceptionHandlingAsyncTaskExecutor.java # 异步任务异常处理
│ └── properties/JeePlusProperties.java # 全局配置(token过期时间/文件路径)
└── aop/demo/ # AOP示例
@JeeplusCloudApplication 组合注解:
@EnableAsync
@EnableDiscoveryClient
@EnableFeignClients({"com.jeeplus.*"})
@SpringBootApplication(scanBasePackages = {"com.jeeplus", "cn.hutool.extra.spring"},
exclude = {SecurityAutoConfiguration.class})
LoggingAspect AOP 切面:
@annotation(com.jeeplus.logging.annotation.ApiLog)@Around: 记录方法执行时间 → AsyncLogService 异步保存日志@AfterThrowing: 记录异常日志LogTypeEnum (LOGIN, ACCESS 等)├── config/ # MyBatis-Plus 分页插件、多租户插件、自动填充
└── database/ # 数据源配置、动态数据源
核心类:
| 类名 | 说明 |
|---|---|
WebSecurityConfig |
Spring Security 配置 (BCrypt编码, 无状态Session, 白名单) |
TokenProvider |
JWT 生成/解析/校验 (Auth0 JWT, HMAC256, SIGN_CODE=@#&#$^JWE@#$F123) |
JWTFilter |
Token 过滤器 (GenericFilterBean) |
JWTConfigurer |
将 JWTFilter 注册到 Security 链 |
SecurityUtils |
安全工具 (获取当前用户/Token/密码加密) |
CustomUserDetailsService |
自定义用户详情服务 |
DaoAuthenticationProvider |
自定义认证提供者 |
JwtAuthenticationEntryPoint |
未认证处理 |
JwtAccessDeniedHandler |
权限不足处理 |
ExceptionTranslator |
异常翻译器 |
WebConfig |
Web 配置 (CORS/拦截器) |
工具类 (utils/):
Encodes.java — 编码工具Exceptions.java — 异常工具SecuritySpringContextHolder.java — Spring上下文持有者StringUtils.java — 字符串工具 (22.9KB)SwaggerConfig.java — Knife4j 配置 (分组/认证头)TypeNameIndexingAdapter.java — 类型命名适配启动类: JeeplusSystemApplication (使用 @JeeplusCloudApplication + @EnableCaching)
分层结构:
jeeplus-system/src/main/java/com/jeeplus/
├── sys/
│ ├── controller/ # REST 控制器
│ │ ├── UserController.java (93KB) # 用户管理
│ │ ├── RoleController.java # 角色管理
│ │ ├── MenuController.java # 菜单管理
│ │ ├── OfficeController.java # 组织机构
│ │ ├── PostController.java # 岗位管理
│ │ ├── AreaController.java # 区域管理
│ │ ├── DictController.java # 字典管理
│ │ ├── TenantController.java # 租户管理
│ │ ├── LogController.java # 日志管理
│ │ ├── DataRuleController.java # 数据权限
│ │ ├── ConfigController.java # 系统配置
│ │ ├── DeskController.java # 桌面配置
│ │ ├── LanguageController.java # 国际化
│ │ └── app/ # 移动端控制器
│ ├── service/ # 业务逻辑
│ │ ├── UserService.java (36KB)
│ │ ├── OfficeService.java (31KB)
│ │ ├── MenuService.java
│ │ ├── RoleService.java
│ │ ├── TenantService.java
│ │ ├── DictTypeService.java
│ │ ├── DataRuleService.java
│ │ ├── AreaService.java
│ │ └── dto/ + mapstruct/
│ ├── domain/ # 实体 (User, Role, Menu, Office, Post, Area, DictType, DictValue, Log...)
│ ├── mapper/ # MyBatis Mapper
│ ├── feign/ # Feign 接口实现 (供其他服务调用)
│ ├── model/ # 页面VO/Model
│ ├── sms/ # 短信服务
│ └── utils/ # 系统专用工具
├── calendar/ # 日历
├── database/ # 数据库管理
├── datav/ # 数据可视化
├── echarts/ # 图表
├── form/ # 表单设计
├── mail/ # 邮件
├── monitor/ # 监控
├── notify/ # 通知
└── tools/ # 工具
jeeplus-flowable/src/main/java/com/jeeplus/
├── flowable/
│ ├── controller/ # 流程控制器 (8个)
│ ├── service/ # 流程服务 (7个)
│ ├── model/ # 流程模型 (11个)
│ ├── mapper/ # 流程Mapper
│ ├── listener/ # 流程监听器
│ ├── utils/ # 流程工具 (13个)
│ ├── vo/ # 视图对象
│ ├── common/ # 公共流程工具
│ └── constant/ # 流程常量
├── centerservice/ # 中心服务
├── extension/ # 扩展
├── modules/ # 模块
└── weChat/ # 微信集成
存储支持: MinIO / 阿里云 OSS
jeeplus-file/src/main/java/com/jeeplus/file/
├── JeeplusFileApplication.java
├── controller/ # 文件上传/下载/预览
├── repository/ # 存储仓库 (5种)
├── config/ # 存储配置
├── model/ # 文件模型
└── utils/ # 文件工具
| 模块 | 包路径 | 功能描述 |
|---|---|---|
| jeeplus-finance | com.jeeplus.finance |
财务管理 (15个子包) |
| jeeplus-assess | com.jeeplus.assess |
评估考核 (10个子包) |
| jeeplus-human | com.jeeplus.human |
人力资源管理 (5个子包) |
| jeeplus-ccpm | com.jeeplus.ccpm |
项目管理 (3个子包) |
| jeeplus-consult | com.jeeplus.consultancy |
培训咨询 (4个子包) |
| jeeplus-public-modules | com.jeeplus.pubmodules |
公共功能: 收藏/合同/知识库/会议室/抽奖/物料/供应商/仓库/采购/序列号/OOS/假期/编辑器/附件 |
| jeeplus-centrecareful | — | 中审管理 |
| jeeplus-psi-management | — | PSI管理 |
| jeeplus-devtools | — | 代码生成等开发工具 |
| jeeplus-ureport | — | UReport 报表引擎 |
| jeeplus-wps | — | WPS 文档在线编辑 |
| jeeplus-xxl-job-admin | — | XXL-Job 调度中心 |
| jeeplus-xxl-job-executor-sample | — | XXL-Job 执行器 |
| jeeplus-admin-server | — | Spring Boot Admin 监控服务 |
| jeeplus-test | — | 测试模块 |
BaseEntity (jeeplus-common-core)
├── id: String @TableId
├── createTime: Date @TableField(fill=INSERT)
├── createById: String @TableField(fill=INSERT)
├── updateTime: Date @TableField(fill=INSERT_UPDATE)
├── updateById: String @TableField(fill=INSERT_UPDATE)
├── delFlag: Integer @TableLogic, @TableField(fill=INSERT)
└── tenantId: String @TableField(fill=INSERT), @Query(type=EQ)
│
└── TreeEntity<T> extends BaseEntity
├── parentId: String
├── parentIds: String # 所有父级ID路径
├── name: String
├── sort: Integer
└── children: List<T> @TableField(exist=false)
BaseDTO<T> (jeeplus-system-api)
├── taskId: String # 流程任务ID
├── procInsId: String # 流程实例ID
├── processDefinitionId: String # 流程定义ID
├── id: String
├── createTime: Date
├── createBy: UserDTO
├── updateTime: Date
├── updateBy: UserDTO
├── delFlag: Integer
└── tenantDTO: TenantDTO
│
└── TreeDTO<T> extends BaseDTO<T>
├── parent: T
├── children: List<T>
├── parentIds: String
├── name: String
└── sort: Integer
EntityWrapper<D, E>
├── toEntity(D dto) → E # @Mapping: tenantDTO.id→tenantId, createBy.id→createById
├── toDTO(E entity) → D # @Mapping: tenantId→tenantDTO.id, createById→createBy.id
├── toEntity(List<D>) → List<E>
├── toDTO(List<E>) → List<D>
├── toEntity(Page<D>) → Page<E>
└── toDTO(Page<E>) → Page<D>
TreeWrapper<D, E> extends EntityWrapper<D, E>
├── toEntity/toDTO (继承 + parent.id↔parentId 映射)
├── copyEntity / copyDTO
└── toEntity(DragNode<D>) → DragNode<E> # 拖拽排序支持
TreeService<D extends TreeMapper<T>, T extends TreeEntity<T>> extends ServiceImpl<D, T>
├── saveOrUpdate(T) # 自动维护 parentIds 路径
├── sortList(DragNode<T>) # 拖拽排序
├── getChildren(T) # 查询子节点
├── removeWithChildrenById() # 级联删除
├── treeData() # 获取完整树
└── formatListToTree() # 列表→树形转换 (Map分组+递归)
位置:
com.jeeplus.common.redis.RedisUtils(1439行)
推荐API (带 cacheName 前缀):
RedisUtils.getInstance().get(cacheName, key) // 读取
RedisUtils.getInstance().set(cacheName, key, value) // 写入
RedisUtils.getInstance().delete(cacheName, key) // 删除
RedisUtils.getInstance().expire(cacheName, key, t) // 过期
RedisUtils.getInstance().keys(cacheName, pattern) // 模糊匹配
@Deprecated 标记的直接操作方法 (不带 cacheName) 不推荐使用,因为会使 @CacheEvict/@Cacheable 注解无效。
ResponseUtil.newInstance()
.add("key", value) // 链式添加响应字段
.ok() // 返回 ResponseEntity (200)
.ok("message") // 返回带消息的 ResponseEntity
RequestUtils.getRequest() // 获取 HttpServletRequest
RequestUtils.getHeader("headerName") // 获取请求头
RequestUtils.resolveToken(request, "token") // 解析token (param > header > cookie)
SecurityUtils.getLoginName() // 当前登录用户名
SecurityUtils.getCurrentUserDTO() // 当前用户完整信息
SecurityUtils.getToken() // 当前Token
SecurityUtils.getAuthentication() // 认证信息
SecurityUtils.login(username, password, authMgr) // 手动登录
SecurityUtils.encryptPassword(password) // BCrypt加密
SecurityUtils.validatePassword(plain, encoded) // 密码验证
基于 @Query 注解动态构建 MyBatis-Plus QueryWrapper:
QueryWrapper<T> qw = QueryWrapperGenerator.buildQueryCondition(searchObj, Entity.class);
支持查询类型: EQ, NE, GT, GE, LT, LE, BETWEEN, NOTBETWEEN, LIKE, NOTLIKE, LIKELEFT, LIKERIGHT
EasyExcel 读写封装,支持自定义 @ExcelField 注解的列转换。
TokenProvider.createAccessToken(username) // 生成JWT
TokenProvider.validateToken(token) // 校验JWT
TokenProvider.getLoginName(token) // 从Token中获取用户名
TokenProvider.getAuthentication(token) // 获取认证对象(含权限)
TokenProvider.resolveToken(request) // 从请求中解析Token
TokenProvider.getCurrentToken() // 获取当前请求的Token
JWT 签名: Algorithm.HMAC256("@#&#$^JWE@#$F123")
Token 中包含: username claim + expiresAt
JeePlusProperties.newInstance().getEXPIRE_TIME() // Token过期时间(秒)
JeePlusProperties.newInstance().getUserfilesBaseDir() // 文件存储根目录
| 服务名 | 端口 | 模块 |
|---|---|---|
jeeplus-gateway |
8088 | 网关 |
jeeplus-auth |
9211 | 认证 |
jeeplus-system |
— | 系统核心 |
jeeplus-flowable |
— | 工作流 |
jeeplus-file |
— | 文件 |
jeeplus-finance |
— | 财务 |
jeeplus-assess |
— | 评估 |
jeeplus-human |
— | 人事 |
jeeplus-ccpm |
— | 项目管理 |
jeeplus-public-modules |
— | 公共模块 |
jeeplus-centrecareful |
— | 中审 |
jeeplus-consultancy |
— | 培训 |
jeeplus-psi-management |
— | PSI |
jeeplus-auth ──Feign──▶ jeeplus-system (IUserApi, ITenantApi)
jeeplus-gateway ──Feign──▶ jeeplus-system (IUserApi)
jeeplus-flowable ──Feign──▶ jeeplus-system
──▶ jeeplus-assess
──▶ jeeplus-finance
──▶ jeeplus-human
──▶ jeeplus-ccpm
──▶ jeeplus-consult
──▶ jeeplus-psi-management
──▶ jeeplus-centrecareful
各业务模块 ──Feign──▶ jeeplus-system (获取用户/权限/租户)
──▶ jeeplus-file (文件存储)
──▶ jeeplus-public-modules (工作附件)
所有 Feign 接口都配置了 fallbackFactory,当服务不可用时返回默认值或空对象:
| API | FallbackFactory |
|---|---|
| IUserApi | UserApiFallbackFactory |
| ITenantApi | TenantApiFallbackFactory |
| IFileApi | FileApiFallbackFactory |
| IWorkAttachmentApi | WorkAttachmentApiFallbackFactory |
| ICwProjectReportApi | CwProjectReportApiFallbackFactory |
| FlowableApi | FlowableApiFallbackFactory |
| AssessApi | AssessApiFallbackFactory |
| 等... |
/模块名/资源名/操作
用户管理: /sys/user/**
角色管理: /sys/role/**
菜单管理: /sys/menu/**
部门管理: /sys/office/**
岗位管理: /sys/post/**
字典管理: /sys/dict/**
租户管理: /sys/tenant/**
流程管理: /flowable/**
文件管理: /file/**
Feign内部调用: /feign/模块名/资源名/**
@Api(tags="xxx") 标注分组@ApiOperation("xxx") 标注说明@ApiModelProperty 标注@IgnoreSwaggerParameter, @ApiModelProperty(hidden=true), @ExcelIgnorehttp://{ip}:{port}/doc.htmlEntityWrapper, TreeWrapper)UserDTO createBy),Entity 中只存 ID (如 String createById)@Mapping 注解声明映射关系使用 MyBatis-Plus IPage<UserDTO> 作为分页返回类型,MapStruct 提供 Page<DTO> ↔ Page<Entity> 自动转换。
{
"token": "xxx",
"oldLoginDate": "2026-01-01 12:00:00",
"oldLoginIp": "192.168.1.1"
}
通过 ResponseUtil 链式构建响应,最终返回 ResponseEntity。
┌─────────────┐
│ 客户端 │
└──────┬──────┘
│ 用户名/密码
▼
┌─────────────────┐
│ jeeplus-auth │
│ LoginController │
└────────┬────────┘
│ SpringSecurity.authenticate()
▼
┌─────────────────┐
│ DaoAuthentication│
│ Provider │
└────────┬────────┘
│ BCrypt密码校验
▼
┌─────────────────┐
│ IUserApi │──▶ jeeplus-system
│ getByLoginName()│ 查询用户
└────────┬────────┘
│
┌────────▼────────┐
│ 生成JWT Token │
│ 存入 Redis │
│ user:cache:token │
└────────┬────────┘
│ 返回 Token
▼
┌─────────────┐
│ 客户端 │ 携带 Token
└──────┬──────┘
│ 每次请求带 Token
▼
┌─────────────────┐
│ jeeplus-gateway │
│ JWTFilter │
└────────┬────────┘
│ 校验Redis中的Token
│ 过期自动刷新
▼
┌─────────────────┐
│ 路由到目标服务 │
└────────┬────────┘
│
┌────────▼────────┐
│ 微服务内部 │
│ WebSecurityConfig │
│ JWTFilter(common) │
└────────┬────────┘
│ @PreAuthorize 方法级权限
▼
┌─────────────────┐
│ 执行业务逻辑 │
└─────────────────┘
用户(User) ──多对多──▶ 角色(Role) ──多对多──▶ 菜单权限(Menu/permission)
│ │
│ └── 数据权限(DataRule)
│
└── 多对一 ──▶ 部门(Office)
└── 多对多 ──▶ 岗位(Post)
└── 多对一 ──▶ 租户(Tenant)
@PreAuthorize)WebSecurityConfig 开启 @EnableGlobalMethodSecurity(prePostEnabled = true),支持:
@PreAuthorize("hasAuthority('sys:user:edit')")
@PreAuthorize("hasRole('admin')")
权限标识通过 IUserApi.getPermissions(loginName) 获取,注入到 Authentication.authorities。
IUserApi.getDataRuleList(userDTO) 获取用户数据权限规则user:cache:dataRuleListBaseEntity.tenantId 自动填充 (@TableField(fill=INSERT))@Query(type=EQ) 默认按租户等值查询ITenantApi.getCurrentTenantId() 从请求上下文获取当前租户登录 → createAccessToken() → Redis.set(token, ttl=EXPIRE_TIME)
→ Redis.set(onlineUsers, ttl=EXPIRE_TIME)
请求 → JWTFilter(Gateway):
1. 从Redis校验token
2. 若accessToken过期 → 自动生成新token → 更新Redis
3. 刷新Redis过期时间
4. 注入SecurityContext
退出 → LoginController.logout():
1. Redis.delete(token)
2. Redis.delete(onlineUsers)
3. 清除Spring Security上下文
4. 同用户名所有设备下线
5. 钉钉解绑
ignore.whiteList)通过 Nacos 配置动态管理,支持通配符路径。示例中允许:
/** (全局)/*/public-modules-server/luckyDraw/events/** (抽奖活动)/doc.html, /swagger-ui.html, /webjars/**)/management/**)| 常量 | 值 |
|---|---|
| APP_AUTH_SERVICE | jeeplus-auth |
| APP_SYSTEM_SERVICE | jeeplus-system |
| APP_FILE_SERVICE | jeeplus-file |
| APP_FLOWABLE_SERVICE | jeeplus-flowable |
| APP_PUBLIC_MODULES | jeeplus-public-modules |
| APP_ASSESS_MODULES | jeeplus-assess |
| APP_FINANCE_MODULES | jeeplus-finance |
| APP_HUMAN_MODULES | jeeplus-human |
| APP_CCPM_MODULES | jeeplus-ccpm |
| APP_CENTRECAREFUL_MODULES | jeeplus-centrecareful |
| APP_CONSULT_MODULES | jeeplus-consultancy |
| APP_PSI_MANAGEMENT_MODULES | jeeplus-psi-management |
sys:cache:code # 验证码
sys:cache:config # 系统配置
sys:cache:areaList # 区域列表
sys:cache:dictMap # 字典映射
sys:cache:tenant # 租户信息
sys:cache:menu # 菜单
sys:cache:languageMap # 语言国际化
user:cache:topMenu # 用户顶部菜单
user:cache:menuList # 用户左侧菜单
user:cache:dataRuleList # 用户数据权限规则
user:cache:roleList # 用户角色列表
user:cache:userId # 用户ID→用户信息
user:cache:loginName # 登录名→用户信息
user:cache:token # Token存储
user:cache:online:users # 在线用户列表
user:cache:user:all:info # 所有用户信息
user:assess:cache:code:loginName # 登录失败次数
ccpm:is:connect # CCPM系统连接状态
user:cache:dataRuleExists # 数据权限存在标记
LOGIN_ERROR_NOT_LOGIN_IN "您尚未登录,请登录后操作!"
LOGIN_ERROR_FORBIDDEN "该帐号已经被禁止登录!"
LOGIN_ERROR_INCORRECT "用户名或者密码错误!"
LOGIN_ERROR_NOTFOUND "用户名不存在!"
LOGIN_ERROR_EXPIRED "您的登录已过期,请重新登录!"
LOGIN_ERROR_FORBID_LOGGED_IN_ELSEWHERE "您的账号已在其它地方登录,您被禁止登录!"
LOGIN_ERROR__KICK_OUT_LOGGED_IN_ELSEWHERE "您的账号在另一台设备上登录..."
LOGIN_ERROR_ERROR_VALIDATE_CODE "您输入的验证码不正确,请重新输入!"
LOGIN_CODE "请输入验证码进行登录!"
LOGIN_MAX_COUNT "今天登录次数已达最大,请明天再登录!"
LOGIN_ERROR "您目前无法登录!"
spring.cloud.nacos:
discovery.server-addr: 127.0.0.1:8848
discovery.namespace: ${spring.profiles.active}
config.server-addr: 127.0.0.1:8848
config.file-extension: yml
config.shared-configs: [application.yml]
sentinel.transport.dashboard: 127.0.0.1:8858
ribbon.ReadTimeout: 600000
ribbon.ConnectTimeout: 600000
hystrix.command.default.execution.isolation.thread.timeoutInMillisecond: 60000
jwt.accessToken.expireTime: (在Nacos中配置, 单位秒)
userfiles.basedir: (文件存储根目录)
生成时间: 2026-06-01
索引范围: xg_total_process_master_cloud 全部模块 (5个顶层模块, 27个子模块)
Java源文件: 覆盖 jeeplus-gateway, jeeplus-auth, jeeplus-api, jeeplus-common, jeeplus-modules 五大模块