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.
 
 
 
 
 
 

28 KiB

基础框架

**本文引用的文件** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [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) - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) - [BeanCopyUtils.java](file://crm-base/src/main/java/com/crm/base/utils/BeanCopyUtils.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) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) - [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java) - [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java) - [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java) - [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java) - [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [MissingParameterException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/MissingParameterException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) - [ResourceNotExistException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/ResourceNotExistException.java) - [DataOwnership.java](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.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) - [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java) - [SystemController.java](file://crm-auth/src/main/java/com/crm/auth/controller/SystemController.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.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) - [AuthService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本技术文档面向“基础框架”模块,系统性梳理通用实体、基础服务接口与实现、全局异常处理、分页工具、Bean转换工具等核心能力;并深入说明自定义注解、拦截器、AOP切面、数据可见性控制等高级特性。同时覆盖数据库配置、Redis缓存、雪花算法ID生成、MyBatis Plus扩展等基础设施的用法与配置,提供扩展点与自定义化指导,帮助开发者基于此框架快速构建业务模块。

项目结构

本项目采用多模块组织:

  • crm-app:应用启动入口与全局配置
  • crm-base:基础能力(实体基类、通用服务、异常、工具、安全上下文、MyBatis/Redis/雪花ID等)
  • crm-auth:认证授权与安全相关能力(JWT、权限、数据范围)
  • crm-file:文件上传下载与预览集成
graph TB
subgraph "应用层"
APP["crm-app<br/>启动与配置"]
end
subgraph "基础能力"
BASE["crm-base<br/>实体/服务/异常/工具/安全/配置"]
end
subgraph "认证授权"
AUTH["crm-auth<br/>认证/鉴权/数据范围"]
end
subgraph "文件服务"
FILE["crm-file<br/>文件上传/下载/预览"]
end
APP --> BASE
APP --> AUTH
APP --> FILE
AUTH --> BASE
FILE --> BASE

图表来源

  • CrmAppApplication.java
  • application.yml

章节来源

  • CrmAppApplication.java
  • application.yml

核心组件

  • 通用实体
    • BaseEntity:统一主键、创建/更新时间等公共字段
    • OwnedEntity:在BaseEntity基础上增加数据归属字段,支撑数据可见性与范围控制
  • 基础服务
    • IBaseService:定义CRUD、分页、批量操作等通用接口
    • BaseServiceImpl:基于MyBatis Plus封装通用实现,减少样板代码
  • 全局异常处理
    • GlobalExceptionHandlerAdvice:集中捕获业务异常、参数异常、权限异常等,返回统一结果
  • 分页与转换
    • PageConverter:将查询对象转换为分页请求/响应
    • BeanCopyUtils:对象属性拷贝与转换
  • 安全与数据可见性
    • DataOwnership、DataScope、DataScopeLevel、DataScopeHelper、DataVisibilityContext、LoginUser、SecurityUtils
  • 基础设施配置
    • MybatisPlusConfig、CrmSqlInjector、MetaObjectFillHandler、InsertBatchOnDuplicateKeyUpdate
    • RedisConfig
    • SnowflakeIdWorker、SnowflakeProperties、CustomIdGenerator
  • 横切能力
    • TraceIdFilter:链路追踪ID注入

章节来源

  • BaseEntity.java
  • OwnedEntity.java
  • IBaseService.java
  • BaseServiceImpl.java
  • GlobalExceptionHandlerAdvice.java
  • PageConverter.java
  • BeanCopyUtils.java
  • DataOwnership.java
  • DataScope.java
  • DataScopeLevel.java
  • DataScopeHelper.java
  • DataVisibilityContext.java
  • LoginUser.java
  • SecurityUtils.java
  • MybatisPlusConfig.java
  • CrmSqlInjector.java
  • MetaObjectFillHandler.java
  • InsertBatchOnDuplicateKeyUpdate.java
  • RedisConfig.java
  • SnowflakeIdWorker.java
  • SnowflakeProperties.java
  • CustomIdGenerator.java
  • TraceIdFilter.java

架构总览

整体分层清晰:控制器层调用服务层,服务层通过MyBatis Plus访问数据库;安全与数据范围通过过滤器、拦截器与AOP切面贯穿;统一结果与异常由全局处理器收敛;Redis用于缓存与分布式场景;雪花算法提供分布式唯一ID。

graph TB
Client["客户端"]
API["控制器层<br/>AuthController/SystemController"]
SVC["服务层<br/>IBaseService + 业务Service"]
MP["MyBatis Plus<br/>Mapper/SQL注入"]
DB["数据库"]
SEC["安全与数据范围<br/>JWT/拦截器/AOP/上下文"]
REDIS["Redis缓存"]
IDG["雪花ID生成器"]
EXC["全局异常处理"]
FILT["TraceId过滤器"]
Client --> API
API --> SVC
SVC --> MP
MP --> DB
API --> SEC
SVC --> SEC
SEC --> REDIS
MP --> IDG
API --> EXC
Client --> FILT --> API

图表来源

  • AuthController.java
  • SystemController.java
  • IBaseService.java
  • BaseServiceImpl.java
  • MybatisPlusConfig.java
  • CrmSqlInjector.java
  • RedisConfig.java
  • SnowflakeIdWorker.java
  • GlobalExceptionHandlerAdvice.java
  • TraceIdFilter.java

详细组件分析

通用实体与数据模型

  • BaseEntity:提供统一的标识与审计字段,便于所有实体共享公共行为
  • OwnedEntity:继承BaseEntity并扩展数据归属字段,配合数据可见性上下文实现行级数据隔离
classDiagram
class BaseEntity {
+id
+createTime
+updateTime
}
class OwnedEntity {
+ownerId
+dataScope
}
OwnedEntity --|> BaseEntity : "继承"

图表来源

  • BaseEntity.java
  • OwnedEntity.java

章节来源

  • BaseEntity.java
  • OwnedEntity.java

基础服务接口与实现

  • IBaseService:定义标准CRUD、分页、批量插入/更新等接口
  • BaseServiceImpl:基于MyBatis Plus封装通用逻辑,减少重复代码,提升一致性
classDiagram
class IBaseService {
+getById(id)
+list(page, query)
+save(entity)
+update(entity)
+deleteById(id)
+batchSave(list)
}
class BaseServiceImpl {
+getById(id)
+list(page, query)
+save(entity)
+update(entity)
+deleteById(id)
+batchSave(list)
}
BaseServiceImpl ..|> IBaseService : "实现"

图表来源

  • IBaseService.java
  • BaseServiceImpl.java

章节来源

  • IBaseService.java
  • BaseServiceImpl.java

全局异常处理与统一结果

  • GlobalExceptionHandlerAdvice:集中捕获业务异常、参数缺失、权限错误、资源不存在等,统一返回Result
  • Result/PageResult/ResultCodeEnum:统一响应结构与状态码
flowchart TD
Start(["请求进入"]) --> Try["执行业务逻辑"]
Try --> Success{"是否成功?"}
Success --> |是| ReturnOK["返回Result.success()"]
Success --> |否| Catch["捕获异常类型"]
Catch --> Map["映射为ResultCodeEnum"]
Map --> Build["构造Result/PageResult"]
Build --> ReturnErr["返回统一错误响应"]
ReturnOK --> End(["结束"])
ReturnErr --> End

图表来源

  • GlobalExceptionHandlerAdvice.java
  • Result.java
  • PageResult.java
  • ResultCodeEnum.java
  • BusinessErrorException.java
  • MissingParameterException.java
  • PermissionErrorException.java
  • ResourceNotExistException.java

章节来源

  • GlobalExceptionHandlerAdvice.java
  • Result.java
  • PageResult.java
  • ResultCodeEnum.java
  • BusinessErrorException.java
  • MissingParameterException.java
  • PermissionErrorException.java
  • ResourceNotExistException.java

分页工具与Bean转换

  • PageConverter:封装分页参数到查询对象,支持排序、过滤条件
  • BeanCopyUtils:简化对象间属性复制与转换,避免手写getter/setter
sequenceDiagram
participant C as "控制器"
participant PC as "PageConverter"
participant S as "服务层"
participant M as "Mapper"
C->>PC : "构建分页查询对象"
PC-->>C : "返回标准化分页参数"
C->>S : "调用分页查询"
S->>M : "执行分页SQL"
M-->>S : "返回分页数据"
S-->>C : "返回PageResult"

图表来源

  • PageConverter.java
  • BeanCopyUtils.java

章节来源

  • PageConverter.java
  • BeanCopyUtils.java

自定义注解、拦截器与AOP切面

  • DataScope注解:标注方法或类,声明数据范围策略
  • DataScopeInterceptor:拦截器解析数据范围,注入到查询上下文
  • DataScopeHelper/DataScopeLevel:辅助计算与级别管理
  • DataVisibilityContext:线程级数据可见性上下文,保证跨层传递
sequenceDiagram
participant C as "控制器"
participant INT as "DataScopeInterceptor"
participant AOP as "AOP切面(DataScope)"
participant CTX as "DataVisibilityContext"
participant S as "服务层"
C->>INT : "请求进入"
INT->>AOP : "解析@DataScope"
AOP->>CTX : "设置数据范围"
AOP-->>INT : "完成上下文设置"
INT-->>C : "放行请求"
C->>S : "执行业务"
S->>CTX : "读取数据范围"
CTX-->>S : "返回范围条件"

图表来源

  • DataScope.java
  • DataScopeInterceptor.java
  • DataScopeHelper.java
  • DataScopeLevel.java
  • DataVisibilityContext.java

章节来源

  • DataScope.java
  • DataScopeInterceptor.java
  • DataScopeHelper.java
  • DataScopeLevel.java
  • DataVisibilityContext.java

安全上下文与登录用户

  • LoginUser:承载当前登录用户信息
  • SecurityUtils:便捷获取当前用户与权限信息
  • DataOwnership:数据所有权标记,结合数据范围实现细粒度控制
classDiagram
class LoginUser {
+userId
+username
+roles
+permissions
}
class SecurityUtils {
+getCurrentUser()
+hasRole(role)
+hasPermission(permission)
}
class DataOwnership {
+ownerId
+scopeLevel
}
SecurityUtils --> LoginUser : "持有"
DataOwnership --> LoginUser : "关联"

图表来源

  • LoginUser.java
  • SecurityUtils.java
  • DataOwnership.java

章节来源

  • LoginUser.java
  • SecurityUtils.java
  • DataOwnership.java

数据库配置与MyBatis Plus扩展

  • MybatisPlusConfig:注册插件、分页、乐观锁等扩展
  • CrmSqlInjector:自定义SQL注入器,增强查询能力
  • MetaObjectFillHandler:自动填充审计字段(如创建时间、更新时间)
  • InsertBatchOnDuplicateKeyUpdate:批量插入去重更新策略
flowchart TD
Start(["应用启动"]) --> LoadCfg["加载MybatisPlusConfig"]
LoadCfg --> RegisterPlugins["注册插件(分页/乐观锁)"]
RegisterCfg --> Injector["注册CrmSqlInjector"]
InjectCfg --> FillHandler["注册MetaObjectFillHandler"]
FillHandler --> BatchUpdate["启用批量插入去重更新"]
BatchUpdate --> Ready(["准备就绪"])

图表来源

  • MybatisPlusConfig.java
  • CrmSqlInjector.java
  • MetaObjectFillHandler.java
  • InsertBatchOnDuplicateKeyUpdate.java

章节来源

  • MybatisPlusConfig.java
  • CrmSqlInjector.java
  • MetaObjectFillHandler.java
  • InsertBatchOnDuplicateKeyUpdate.java

Redis缓存配置

  • RedisConfig:序列化、连接池、过期策略等配置项
classDiagram
class RedisConfig {
+redisTemplate
+cacheManager
+setSerializer()
+setExpiration()
}

图表来源

  • RedisConfig.java

章节来源

  • RedisConfig.java

雪花算法ID生成

  • SnowflakeIdWorker:分布式唯一ID生成器
  • SnowflakeProperties:工作节点ID等配置
  • CustomIdGenerator:与MyBatis Plus集成,作为实体ID生成策略
sequenceDiagram
participant App as "应用"
participant Gen as "CustomIdGenerator"
participant SW as "SnowflakeIdWorker"
App->>Gen : "请求生成ID"
Gen->>SW : "调用雪花算法"
SW-->>Gen : "返回唯一ID"
Gen-->>App : "返回ID"

图表来源

  • SnowflakeIdWorker.java
  • SnowflakeProperties.java
  • CustomIdGenerator.java

章节来源

  • SnowflakeIdWorker.java
  • SnowflakeProperties.java
  • CustomIdGenerator.java

认证与授权流程(JWT)

  • JwtAuthenticationFilter:解析JWT并设置安全上下文
  • TokenService:令牌签发与校验
  • SecurityConfig:安全配置与路径白名单
sequenceDiagram
participant Client as "客户端"
participant Filter as "JwtAuthenticationFilter"
participant Token as "TokenService"
participant Sec as "SecurityConfig"
Client->>Filter : "携带Authorization头"
Filter->>Token : "解析并验证Token"
Token-->>Filter : "返回用户信息"
Filter->>Sec : "设置SecurityContext"
Sec-->>Client : "放行至控制器"

图表来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • SecurityConfig.java

章节来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • SecurityConfig.java

文件服务集成(示例)

  • FileApiImpl:文件API实现,对接存储与预览服务
  • FileInfoServiceImpl:文件元数据管理与持久化
  • MinioConfig:MinIO客户端配置
classDiagram
class FileApiImpl {
+upload(file)
+download(fileId)
+preview(fileId)
}
class FileInfoServiceImpl {
+save(info)
+getById(id)
+deleteById(id)
}
class MinioConfig {
+endpoint
+accessKey
+secretKey
+bucketName
}
FileApiImpl --> FileInfoServiceImpl : "使用"
FileApiImpl --> MinioConfig : "配置"

图表来源

  • FileApiImpl.java
  • FileInfoServiceImpl.java
  • MinioConfig.java

章节来源

  • FileApiImpl.java
  • FileInfoServiceImpl.java
  • MinioConfig.java

依赖关系分析

  • 模块依赖
    • crm-app依赖crm-base、crm-auth、crm-file
    • crm-auth依赖crm-base(安全上下文、异常、工具)
    • crm-file依赖crm-base(通用实体、工具、配置)
  • 内部依赖
    • 服务层依赖MyBatis Plus与Redis
    • 安全层依赖JWT与上下文
    • 基础设施层提供ID生成、序列化、填充策略
graph LR
APP["crm-app"] --> BASE["crm-base"]
APP --> AUTH["crm-auth"]
APP --> FILE["crm-file"]
AUTH --> BASE
FILE --> BASE
BASE --> DB["数据库"]
BASE --> REDIS["Redis"]

图表来源

  • CrmAppApplication.java
  • application.yml

章节来源

  • CrmAppApplication.java
  • application.yml

性能考虑

  • 分页查询:合理设置页大小,避免大结果集一次性加载
  • 批量操作:使用批量插入/更新减少往返次数
  • 缓存策略:热点数据使用Redis缓存,注意过期与一致性
  • ID生成:雪花算法无锁且有序,适合高并发场景
  • SQL优化:借助CrmSqlInjector与MyBatis Plus插件,避免N+1问题

[本节为通用建议,不直接分析具体文件]

故障排查指南

  • 统一异常分类:业务异常、参数缺失、权限错误、资源不存在
  • 日志与追踪:TraceIdFilter注入链路ID,便于定位问题
  • 常见错误
    • 权限不足:检查SecurityContext与角色/权限配置
    • 数据范围异常:确认@DataScope与上下文是否正确设置
    • 缓存异常:检查Redis连接与序列化配置
    • ID冲突:确认雪花工作节点ID配置唯一

章节来源

  • GlobalExceptionHandlerAdvice.java
  • TraceIdFilter.java
  • RedisConfig.java
  • SnowflakeProperties.java

结论

本基础框架以清晰的模块化设计、统一的实体与服务抽象、完善的安全与数据范围控制、强大的基础设施配置为核心,提供了开箱即用的开发体验。通过扩展点与自定义化指导,开发者可快速搭建稳定、高性能的业务模块。

[本节为总结性内容,不直接分析具体文件]

附录

  • 扩展点建议
    • 自定义数据范围策略:扩展DataScopeHelper与DataScopeLevel
    • 新增异常类型:在GlobalExceptionHandlerAdvice中统一处理
    • 扩展MyBatis插件:在MybatisPlusConfig中注册
    • 自定义ID生成:替换CustomIdGenerator实现
  • 常用配置项
    • 数据库连接、Redis连接、雪花工作节点ID、MinIO端点等

[本节为补充信息,不直接分析具体文件]