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.

650 lines
35 KiB

1 month ago
# 基础框架模块(crm-base)
<cite>
**本文引用的文件**
- [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)
- [BaseDTO.java](file://crm-base/src/main/java/com/crm/base/domain/dto/BaseDTO.java)
- [BaseParam.java](file://crm-base/src/main/java/com/crm/base/domain/param/BaseParam.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)
- [StatusEnum.java](file://crm-base/src/main/java/com/crm/base/domain/enums/StatusEnum.java)
- [HasValueEnum.java](file://crm-base/src/main/java/com/crm/base/domain/enums/HasValueEnum.java)
- [CommonConstants.java](file://crm-base/src/main/java/com/crm/base/constant/CommonConstants.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)
- [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)
- [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.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)
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
- [JacksonConfig.java](file://crm-base/src/main/java/com/crm/base/config/JacksonConfig.java)
- [Knife4jConfig.java](file://crm-base/src/main/java/com/crm/base/config/Knife4jConfig.java)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java)
- [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.java)
- [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java)
- [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.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)
- [AssertUtils.java](file://crm-base/src/main/java/com/crm/base/utils/AssertUtils.java)
- [BeanCopyUtils.java](file://crm-base/src/main/java/com/crm/base/utils/BeanCopyUtils.java)
- [EnumUtils.java](file://crm-base/src/main/java/com/crm/base/utils/EnumUtils.java)
- [ExcelUtil.java](file://crm-base/src/main/java/com/crm/base/utils/ExcelUtil.java)
- [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java)
- [ServletUtils.java](file://crm-base/src/main/java/com/crm/base/utils/ServletUtils.java)
- [TreeUtils.java](file://crm-base/src/main/java/com/crm/base/utils/TreeUtils.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)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本模块为 CRM 后端的基础设施层,提供通用实体、分页与结果封装、全局异常处理、数据访问层封装、工具类以及 MyBatis Plus、Redis、雪花ID等关键配置。通过统一的设计模式与约定,降低业务模块重复开发成本,提升一致性与可维护性。
## 项目结构
crm-base 采用分层组织:
- domain:通用实体、DTO、参数、枚举、异常、结果封装
- config:MyBatis Plus、Redis、Jackson、Knife4j、跨域、SQL注入器、填充处理器、ID生成器等
- service/mapper:通用服务接口与实现、基础 Mapper
- advice/filter:全局异常处理、请求链路追踪过滤器
- security:数据权限控制、可见性上下文、登录用户模型与安全工具
- utils:通用工具集(断言、拷贝、枚举、Excel、分页转换、Servlet、树形结构)
```mermaid
graph TB
subgraph "领域模型"
A["BaseEntity / OwnedEntity"]
B["BaseDTO / BaseParam"]
C["Result / PageResult / ResultCodeEnum"]
D["StatusEnum / HasValueEnum"]
end
subgraph "数据访问"
E["CrmBaseMapper"]
F["IBaseService / BaseServiceImpl"]
G["MybatisPlusConfig / CrmSqlInjector / MetaObjectFillHandler"]
H["CustomIdGenerator / SnowflakeIdWorker"]
end
subgraph "运行时配置"
I["RedisConfig"]
J["JacksonConfig"]
K["Knife4jConfig"]
L["CorsConfig"]
M["InsertBatchOnDuplicateKeyUpdate"]
end
subgraph "横切关注点"
N["GlobalExceptionHandlerAdvice"]
O["TraceIdFilter"]
P["DataScope / DataScopeHelper / DataVisibilityContext"]
Q["SecurityUtils / LoginUser"]
end
A --> F
B --> F
C --> F
E --> F
G --> E
H --> G
I --> F
J --> F
K --> F
L --> F
M --> G
N --> F
O --> F
P --> F
Q --> P
```
图表来源
- [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)
- [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
- [JacksonConfig.java](file://crm-base/src/main/java/com/crm/base/config/JacksonConfig.java)
- [Knife4jConfig.java](file://crm-base/src/main/java/com/crm/base/config/Knife4jConfig.java)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java)
- [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java)
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
- [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java)
- [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java)
章节来源
- [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)
- [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java)
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
## 核心组件
- 通用实体与继承体系
- BaseEntity:定义统一的审计字段(如创建时间、更新时间、逻辑删除标记等),配合元数据填充处理器自动落库。
- OwnedEntity:在 BaseEntity 基础上扩展数据归属字段(如所属部门/租户),支撑数据权限过滤。
- 通用 DTO/Param
- BaseDTO:作为对象转换的基类,便于与实体解耦。
- BaseParam:作为查询/操作参数的基类,统一分页、排序等公共字段。
- 统一结果与分页
- Result:标准响应体,包含状态码、消息与数据。
- PageResult:分页结果封装,适配 MyBatis Plus 的分页对象。
- ResultCodeEnum:统一错误码枚举。
- 枚举与常量
- StatusEnum、HasValueEnum:常用状态与布尔值语义化枚举。
- CommonConstants:系统级常量。
- 数据访问封装
- CrmBaseMapper:基础 Mapper,扩展通用方法。
- IBaseService / BaseServiceImpl:CRUD 抽象,结合分页、批量插入、更新策略等。
- 全局异常处理
- GlobalExceptionHandlerAdvice:集中捕获业务异常、参数异常、权限异常等,返回统一 Result。
- 安全与数据权限
- DataScope 注解 + DataScopeHelper:声明式数据范围控制。
- DataVisibilityContext:线程可见性上下文,存储当前用户的数据范围。
- SecurityUtils / LoginUser:获取当前登录用户信息。
- 基础设施配置
- MyBatis Plus 配置:分页插件、SQL 注入器、填充处理器、自定义 ID 生成器。
- Redis 配置:序列化、连接池、过期策略等。
- Jackson 配置:日期、空值、时区等序列化策略。
- Knife4j 配置:API 文档增强。
- CorsConfig:跨域支持。
- InsertBatchOnDuplicateKeyUpdate:批量插入去重策略。
- TraceIdFilter:请求链路追踪。
- 工具类
- AssertUtils、BeanCopyUtils、EnumUtils、ExcelUtil、PageConverter、ServletUtils、TreeUtils。
章节来源
- [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)
- [BaseDTO.java](file://crm-base/src/main/java/com/crm/base/domain/dto/BaseDTO.java)
- [BaseParam.java](file://crm-base/src/main/java/com/crm/base/domain/param/BaseParam.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)
- [StatusEnum.java](file://crm-base/src/main/java/com/crm/base/domain/enums/StatusEnum.java)
- [HasValueEnum.java](file://crm-base/src/main/java/com/crm/base/domain/enums/HasValueEnum.java)
- [CommonConstants.java](file://crm-base/src/main/java/com/crm/base/constant/CommonConstants.java)
- [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.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)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
- [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java)
- [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java)
- [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java)
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
- [JacksonConfig.java](file://crm-base/src/main/java/com/crm/base/config/JacksonConfig.java)
- [Knife4jConfig.java](file://crm-base/src/main/java/com/crm/base/config/Knife4jConfig.java)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java)
- [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.java)
- [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java)
- [AssertUtils.java](file://crm-base/src/main/java/com/crm/base/utils/AssertUtils.java)
- [BeanCopyUtils.java](file://crm-base/src/main/java/com/crm/base/utils/BeanCopyUtils.java)
- [EnumUtils.java](file://crm-base/src/main/java/com/crm/base/utils/EnumUtils.java)
- [ExcelUtil.java](file://crm-base/src/main/java/com/crm/base/utils/ExcelUtil.java)
- [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java)
- [ServletUtils.java](file://crm-base/src/main/java/com/crm/base/utils/ServletUtils.java)
- [TreeUtils.java](file://crm-base/src/main/java/com/crm/base/utils/TreeUtils.java)
## 架构总览
基础框架围绕“实体-服务-Mapper”三层展开,辅以配置中心与横切能力:
- 实体层:BaseEntity/OwnedEntity 提供统一字段与审计;OwnedEntity 承载数据归属。
- 服务层:IBaseService/BaseServiceImpl 提供 CRUD、分页、批量操作与事务边界。
- 数据层:CrmBaseMapper 扩展通用 SQL;MyBatis Plus 插件负责分页、填充、ID 生成。
- 横切:全局异常、数据权限、请求追踪、序列化、缓存、API 文档、跨域。
```mermaid
classDiagram
class BaseEntity {
+id
+createTime
+updateTime
+deleted
}
class OwnedEntity {
+ownerId
+deptId
}
class BaseDTO
class BaseParam {
+pageNo
+pageSize
+orderBy
}
class Result~T~ {
+code
+message
+data
}
class PageResult~T~ {
+records
+total
+pages
+current
+size
}
class CrmBaseMapper
class IBaseService~T~ {
+save(entity)
+updateById(entity)
+removeById(id)
+getById(id)
+list(param)
+page(param)
+batchSave(list)
}
class BaseServiceImpl~T~ {
+mapper
+save()
+updateById()
+removeById()
+getById()
+list()
+page()
+batchSave()
}
class MybatisPlusConfig
class MetaObjectFillHandler
class CustomIdGenerator
class SnowflakeIdWorker
class RedisConfig
class GlobalExceptionHandlerAdvice
class DataScopeHelper
class DataVisibilityContext
class SecurityUtils
class LoginUser
OwnedEntity --|> BaseEntity
BaseServiceImpl --> CrmBaseMapper : "使用"
BaseServiceImpl --> IBaseService : "实现"
MybatisPlusConfig --> MetaObjectFillHandler : "注册"
MybatisPlusConfig --> CustomIdGenerator : "注册"
CustomIdGenerator --> SnowflakeIdWorker : "调用"
BaseServiceImpl --> RedisConfig : "可选缓存"
GlobalExceptionHandlerAdvice --> Result : "返回"
DataScopeHelper --> DataVisibilityContext : "读写上下文"
SecurityUtils --> LoginUser : "获取用户"
```
图表来源
- [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)
- [BaseDTO.java](file://crm-base/src/main/java/com/crm/base/domain/dto/BaseDTO.java)
- [BaseParam.java](file://crm-base/src/main/java/com/crm/base/domain/param/BaseParam.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)
- [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.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)
- [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java)
- [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java)
- [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
- [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java)
- [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java)
## 详细组件分析
### 通用实体与数据归属
- BaseEntity 提供统一审计字段,配合 MetaObjectFillHandler 自动填充创建/更新时间、操作人等。
- OwnedEntity 扩展数据归属字段,用于数据权限过滤(如按部门/租户隔离)。
- 建议所有业务实体继承 OwnedEntity,确保数据权限生效。
```mermaid
classDiagram
class BaseEntity {
+id
+createTime
+updateTime
+deleted
}
class OwnedEntity {
+ownerId
+deptId
}
OwnedEntity --|> BaseEntity
```
图表来源
- [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)
章节来源
- [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)
- [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java)
### 分页与结果封装
- PageResult 封装分页数据,适配 MyBatis Plus 的分页对象,提供 total/pages/current/size/records。
- Result 统一响应格式,ResultCodeEnum 统一定义状态码。
- PageConverter 提供将业务分页对象转换为 PageResult 的工具方法。
```mermaid
flowchart TD
Start(["进入分页查询"]) --> BuildParam["构建查询参数(BaseParam)"]
BuildParam --> QueryDB["调用 Service.page()"]
QueryDB --> Convert["PageConverter 转换"]
Convert --> Wrap["包装为 PageResult"]
Wrap --> Return["返回 Result.success(PageResult)"]
```
图表来源
- [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
- [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.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)
章节来源
- [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
- [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java)
### 数据访问层封装与 CRUD
- CrmBaseMapper:基础 Mapper,扩展通用方法,减少样板代码。
- IBaseService/BaseServiceImpl:提供 save/update/remove/get/list/page/batchSave 等通用方法,内部集成分页、填充、ID 生成与事务管理。
- 批量插入策略:InsertBatchOnDuplicateKeyUpdate 提供幂等写入能力。
```mermaid
sequenceDiagram
participant C as "Controller"
participant S as "BaseServiceImpl"
participant M as "CrmBaseMapper"
participant MP as "MyBatis Plus"
C->>S : "page(BaseParam)"
S->>MP : "构造分页查询(含数据权限)"
MP->>M : "执行 SQL"
M-->>MP : "返回记录集"
MP-->>S : "分页对象"
S-->>C : "PageResult"
```
图表来源
- [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.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)
- [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java)
章节来源
- [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.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)
- [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.java)
### 全局异常处理机制
- GlobalExceptionHandlerAdvice 集中捕获业务异常、参数缺失、权限错误、资源不存在等,统一返回 Result。
- 自定义异常类型:BusinessErrorException、MissingParameterException、PermissionErrorException、ResourceNotExistException。
- 建议业务层抛出明确异常,由该拦截器统一收敛。
```mermaid
flowchart TD
Entry(["请求进入"]) --> TryBlock["执行业务逻辑"]
TryBlock --> Success{"是否成功?"}
Success --> |是| Ok["返回 Result.success(data)"]
Success --> |否| Catch["捕获特定异常"]
Catch --> Map["映射为 Result.error(code,message)"]
Map --> End(["返回统一响应"])
```
图表来源
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.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)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
章节来源
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.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)
### 数据权限控制
- DataScope 注解:标注在方法或类上,声明数据范围级别。
- DataScopeHelper:解析注解并组装 WHERE 条件(如 deptId/ownerId)。
- DataVisibilityContext:线程内保存当前用户的数据可见范围。
- SecurityUtils/LoginUser:从上下文获取当前登录用户信息。
```mermaid
sequenceDiagram
participant U as "调用方"
participant S as "Service方法"
participant DS as "DataScopeHelper"
participant CTX as "DataVisibilityContext"
U->>S : "带@DataScope的方法调用"
S->>DS : "解析注解与用户范围"
DS->>CTX : "设置可见范围"
DS-->>S : "返回过滤条件片段"
S-->>U : "返回受限数据集合"
```
图表来源
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
- [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java)
- [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java)
章节来源
- [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
- [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java)
- [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java)
### MyBatis Plus 配置与扩展
- MybatisPlusConfig:注册分页插件、SQL 注入器、填充处理器、自定义 ID 生成器。
- CrmSqlInjector:扩展通用 SQL 片段与方法。
- MetaObjectFillHandler:自动填充审计字段(创建时间、更新时间、操作人等)。
- CustomIdGenerator:基于 SnowflakeIdWorker 生成分布式唯一 ID。
- SnowflakeProperties:雪花算法相关配置(工作节点、数据中心等)。
```mermaid
flowchart TD
Init["应用启动"] --> Register["注册 MyBatis Plus 插件"]
Register --> Fill["注册 MetaObjectFillHandler"]
Register --> Inject["注册 CrmSqlInjector"]
Register --> IdGen["注册 CustomIdGenerator"]
IdGen --> Snow["SnowflakeIdWorker 生成ID"]
Fill --> Audit["自动填充审计字段"]
Inject --> SQL["扩展通用 SQL"]
```
图表来源
- [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)
- [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.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)
章节来源
- [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)
- [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.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)
### Redis 集成与缓存配置
- RedisConfig:配置序列化、连接池、默认过期策略等,供业务模块按需使用。
- 建议对热点数据(字典、菜单树、权限等)进行缓存,注意一致性策略与失效时机。
```mermaid
flowchart TD
App["应用启动"] --> RConf["初始化 RedisConfig"]
RConf --> Serializer["配置序列化器"]
RConf --> Pool["配置连接池"]
RConf --> TTL["设置默认过期策略"]
App --> Use["业务模块使用 RedisTemplate"]
```
图表来源
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
章节来源
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
### Jackson 与 API 文档、跨域
- JacksonConfig:统一日期格式、时区、空值序列化策略。
- Knife4jConfig:增强 Swagger 文档体验。
- CorsConfig:允许跨域访问,便于前后端分离开发。
章节来源
- [JacksonConfig.java](file://crm-base/src/main/java/com/crm/base/config/JacksonConfig.java)
- [Knife4jConfig.java](file://crm-base/src/main/java/com/crm/base/config/Knife4jConfig.java)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java)
### 工具类与辅助能力
- AssertUtils:参数校验与断言。
- BeanCopyUtils:对象属性拷贝。
- EnumUtils:枚举工具方法。
- ExcelUtil:导入导出 Excel。
- PageConverter:分页对象转换。
- ServletUtils:HTTP 请求辅助。
- TreeUtils:树形结构构建。
章节来源
- [AssertUtils.java](file://crm-base/src/main/java/com/crm/base/utils/AssertUtils.java)
- [BeanCopyUtils.java](file://crm-base/src/main/java/com/crm/base/utils/BeanCopyUtils.java)
- [EnumUtils.java](file://crm-base/src/main/java/com/crm/base/utils/EnumUtils.java)
- [ExcelUtil.java](file://crm-base/src/main/java/com/crm/base/utils/ExcelUtil.java)
- [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java)
- [ServletUtils.java](file://crm-base/src/main/java/com/crm/base/utils/ServletUtils.java)
- [TreeUtils.java](file://crm-base/src/main/java/com/crm/base/utils/TreeUtils.java)
## 依赖关系分析
- 实体与服务:BaseEntity/OwnedEntity 被 BaseServiceImpl 广泛使用;IBaseService 定义契约。
- 数据访问:CrmBaseMapper 被 BaseServiceImpl 依赖;MyBatis Plus 插件贯穿整个数据层。
- 横切:GlobalExceptionHandlerAdvice 作用于所有 Controller;DataScopeHelper 与 DataVisibilityContext 影响查询条件。
- 外部依赖:Redis 用于缓存;Jackson 用于序列化;Knife4j 用于文档;Cors 用于跨域。
```mermaid
graph LR
Entity["BaseEntity/OwnedEntity"] --> Service["IBaseService/BaseServiceImpl"]
Service --> Mapper["CrmBaseMapper"]
Service --> MP["MyBatisPlusConfig"]
MP --> Fill["MetaObjectFillHandler"]
MP --> ID["CustomIdGenerator/SnowflakeIdWorker"]
Service --> Cache["RedisConfig"]
Controller["业务Controller"] --> Service
Controller --> Exception["GlobalExceptionHandlerAdvice"]
Service --> Scope["DataScopeHelper/DataVisibilityContext"]
```
图表来源
- [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)
- [CrmBaseMapper.java](file://crm-base/src/main/java/com/crm/base/mapper/CrmBaseMapper.java)
- [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java)
- [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java)
- [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
章节来源
- [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java)
- [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java)
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
## 性能考量
- 分页查询:优先使用 MyBatis Plus 分页插件,避免全表扫描;合理设计索引。
- 批量操作:使用 batchSave 与 InsertBatchOnDuplicateKeyUpdate 提升写入吞吐。
- 缓存策略:对热点数据启用 Redis 缓存,设置合理 TTL 与失效策略。
- 序列化:Jackson 配置统一时区与空值策略,减少序列化开销。
- 审计填充:MetaObjectFillHandler 仅在必要时填充,避免多余数据库写操作。
[本节为通用指导,不直接分析具体文件]
## 故障排查指南
- 统一异常:检查 GlobalExceptionHandlerAdvice 是否捕获到预期异常类型,确认 ResultCodeEnum 的状态码与消息。
- 数据权限:确认 DataScope 注解是否正确标注,DataVisibilityContext 中可见范围是否设置正确。
- 填充失败:检查 MetaObjectFillHandler 是否注册,实体字段名是否与填充规则匹配。
- ID 冲突:核对 SnowflakeIdWorker 配置(工作节点/数据中心)是否唯一,避免 ID 碰撞。
- 缓存问题:检查 Redis 连接与序列化配置,确认 key 命名规范与过期策略。
- 跨域与文档:验证 CorsConfig 与 Knife4jConfig 配置是否符合前端需求。
章节来源
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
- [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java)
- [Knife4jConfig.java](file://crm-base/src/main/java/com/crm/base/config/Knife4jConfig.java)
## 结论
crm-base 提供了完善的基础设施能力,涵盖实体设计、CRUD 封装、分页与结果统一、全局异常、数据权限、MyBatis Plus 扩展、Redis 缓存、雪花 ID 生成等。遵循本模块约定,可显著提升业务模块的开发效率与一致性。
[本节为总结性内容,不直接分析具体文件]
## 附录
### 最佳实践
- 实体设计
- 所有业务实体继承 OwnedEntity,确保数据权限生效。
- 合理使用审计字段,避免频繁手动更新 createTime/updateTime。
- 服务层
- 优先使用 IBaseService 提供的通用方法,减少样板代码。
- 复杂查询通过 CrmBaseMapper 扩展 SQL,保持可读性。
- 异常处理
- 业务层抛出明确的自定义异常,交由 GlobalExceptionHandlerAdvice 统一处理。
- 数据权限
- 在需要数据隔离的方法上使用 @DataScope,并通过 DataVisibilityContext 设置可见范围。
- 缓存
- 对热点数据使用 Redis 缓存,设置合理的 TTL 与失效策略,保证一致性。
- 工具类
- 使用 AssertUtils 做前置校验;使用 BeanCopyUtils 进行对象转换;使用 PageConverter 转换分页对象。
[本节为通用指导,不直接分析具体文件]
### 扩展开发指南
- 新增实体
- 继承 OwnedEntity,定义必要字段;如需自定义 ID 生成策略,可在 CustomIdGenerator 中扩展。
- 新增服务方法
- 在 IBaseService 中定义接口,在 BaseServiceImpl 中实现;复杂 SQL 通过 CrmBaseMapper 扩展。
- 新增数据权限级别
- 在 DataScopeLevel 中扩展级别,并在 DataScopeHelper 中实现对应过滤逻辑。
- 新增缓存键与策略
- 在业务模块中定义缓存 Key 前缀与过期时间,使用 RedisTemplate 进行操作。
- 新增全局异常类型
- 定义新的异常类,并在 GlobalExceptionHandlerAdvice 中添加对应的处理分支。
[本节为通用指导,不直接分析具体文件]