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.

950 lines
50 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)
1 month ago
- [DictGroup.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroup.java)
- [DictItem.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictItem.java)
- [DictGroupDefault.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroupDefault.java)
- [DictRefCount.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictRefCount.java)
- [DictGroupVO.java](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictGroupVO.java)
- [DictItemVO.java](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictItemVO.java)
- [DictGroupController.java](file://crm-dict/src/main/java/com/crm/dict/controller/DictGroupController.java)
- [DictItemController.java](file://crm-dict/src/main/java/com/crm/dict/controller/DictItemController.java)
- [IDictGroupService.java](file://crm-dict/src/main/java/com/crm/dict/service/IDictGroupService.java)
- [IDictItemService.java](file://crm-dict/src/main/java/com/crm/dict/service/IDictItemService.java)
- [DictGroupServiceImpl.java](file://crm-dict/src/main/java/com/crm/dict/service/impl/DictGroupServiceImpl.java)
- [DictItemServiceImpl.java](file://crm-dict/src/main/java/com/crm/dict/service/impl/DictItemServiceImpl.java)
- [DictDataInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictDataInitializer.java)
- [DictPermissionInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictPermissionInitializer.java)
- [DictConstants.java](file://crm-dict/src/main/java/com/crm/dict/constant/DictConstants.java)
1 month ago
</cite>
1 month ago
## 更新摘要
**变更内容**
- 更新了数据字典模块的VO设计架构,DictGroupVO和DictItemVO现在使用独立字段定义而非继承实体类
- 增强了API设计的清晰度和安全性,通过明确的字段暴露控制敏感信息
- 优化了服务层实现以适配新的VO结构,提升了数据转换效率
- 完善了VO设计模式的最佳实践说明
1 month ago
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本模块为 CRM 后端的基础设施层,提供通用实体、分页与结果封装、全局异常处理、数据访问层封装、工具类以及 MyBatis Plus、Redis、雪花ID等关键配置。通过统一的设计模式与约定,降低业务模块重复开发成本,提升一致性与可维护性。
1 month ago
**更新** 新增 crm-dict 数据字典模块,作为独立的服务模块提供平台级键值字典管理能力,支持分组管理、字典项管理、引用计数和权限集成等功能。该模块采用了先进的VO设计模式,通过独立的视图对象定义提升了API的安全性和清晰度。
1 month ago
## 项目结构
crm-base 采用分层组织:
- domain:通用实体、DTO、参数、枚举、异常、结果封装
- config:MyBatis Plus、Redis、Jackson、Knife4j、跨域、SQL注入器、填充处理器、ID生成器等
- service/mapper:通用服务接口与实现、基础 Mapper
- advice/filter:全局异常处理、请求链路追踪过滤器
- security:数据权限控制、可见性上下文、登录用户模型与安全工具
- utils:通用工具集(断言、拷贝、枚举、Excel、分页转换、Servlet、树形结构)
1 month ago
**更新** crm-dict 模块结构:
- controller:字典分组和字典项的管理接口
- service:字典查询、引用计数、分组和字典项的业务逻辑
- domain:字典实体、DTO、参数定义,采用独立VO设计模式
- config:内置数据初始化、权限种子化配置
- constant:字典模块常量定义
1 month ago
```mermaid
graph TB
1 month ago
subgraph "基础框架 (crm-base)"
1 month ago
A["BaseEntity / OwnedEntity"]
B["BaseDTO / BaseParam"]
C["Result / PageResult / ResultCodeEnum"]
D["StatusEnum / HasValueEnum"]
1 month ago
E["MybatisPlusConfig / CrmSqlInjector"]
F["RedisConfig / JacksonConfig"]
G["GlobalExceptionHandlerAdvice"]
H["DataScope / SecurityUtils"]
1 month ago
end
1 month ago
subgraph "数据字典 (crm-dict)"
I["DictGroup / DictItem"]
J["DictGroupVO / DictItemVO"]
K["DictGroupController / DictItemController"]
L["IDictGroupService / IDictItemService"]
M["DictDataInitializer / DictPermissionInitializer"]
N["DictConstants"]
1 month ago
end
1 month ago
A --> L
B --> L
C --> K
E --> L
F --> M
G --> K
H --> K
I --> J
J --> K
L --> E
M --> I
N --> L
1 month ago
```
1 month ago
**图表来源**
1 month ago
- [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java)
1 month ago
- [DictGroup.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroup.java)
- [DictItem.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictItem.java)
- [DictGroupVO.java](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictGroupVO.java)
- [DictItemVO.java](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictItemVO.java)
- [DictGroupController.java](file://crm-dict/src/main/java/com/crm/dict/controller/DictGroupController.java)
- [IDictGroupService.java](file://crm-dict/src/main/java/com/crm/dict/service/IDictGroupService.java)
- [DictDataInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictDataInitializer.java)
**章节来源**
- [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java)
- [DictGroup.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroup.java)
1 month ago
- [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。
1 month ago
**更新** 数据字典核心组件:
- 字典实体:DictGroup(分组)、DictItem(字典项)、DictGroupDefault(默认项)、DictRefCount(引用计数)
- **VO设计模式**:DictGroupVO和DictItemVO采用独立字段定义,不继承实体类,提供更清晰的API契约
- 控制器:DictGroupController、DictItemController 提供 RESTful API
- 服务层:IDictGroupService、IDictItemService 定义业务接口
- 初始化器:DictDataInitializer(内置数据)、DictPermissionInitializer(权限种子)
- 常量定义:DictConstants 包含状态码、权限码、缓存配置等
**章节来源**
1 month ago
- [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)
1 month ago
- [DictGroup.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroup.java)
- [DictItem.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictItem.java)
- [DictGroupDefault.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroupDefault.java)
- [DictRefCount.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictRefCount.java)
- [DictGroupVO.java](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictGroupVO.java)
- [DictItemVO.java](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictItemVO.java)
- [DictGroupController.java](file://crm-dict/src/main/java/com/crm/dict/controller/DictGroupController.java)
- [DictItemController.java](file://crm-dict/src/main/java/com/crm/dict/controller/DictItemController.java)
- [IDictGroupService.java](file://crm-dict/src/main/java/com/crm/dict/service/IDictGroupService.java)
- [IDictItemService.java](file://crm-dict/src/main/java/com/crm/dict/service/IDictItemService.java)
- [DictGroupServiceImpl.java](file://crm-dict/src/main/java/com/crm/dict/service/impl/DictGroupServiceImpl.java)
- [DictItemServiceImpl.java](file://crm-dict/src/main/java/com/crm/dict/service/impl/DictItemServiceImpl.java)
- [DictDataInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictDataInitializer.java)
- [DictPermissionInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictPermissionInitializer.java)
- [DictConstants.java](file://crm-dict/src/main/java/com/crm/dict/constant/DictConstants.java)
1 month ago
## 架构总览
1 month ago
基础框架围绕"实体-服务-Mapper"三层展开,辅以配置中心与横切能力:
1 month ago
- 实体层:BaseEntity/OwnedEntity 提供统一字段与审计;OwnedEntity 承载数据归属。
- 服务层:IBaseService/BaseServiceImpl 提供 CRUD、分页、批量操作与事务边界。
- 数据层:CrmBaseMapper 扩展通用 SQL;MyBatis Plus 插件负责分页、填充、ID 生成。
- 横切:全局异常、数据权限、请求追踪、序列化、缓存、API 文档、跨域。
1 month ago
**更新** 新增 crm-dict 模块架构:
- 独立服务模块:基于 crm-base 构建,不依赖 crm-auth 具体实现
- 两级字典结构:分组 → 字典项,支持内置和用户字典分离
- **VO设计模式**:采用独立的视图对象(DictGroupVO、DictItemVO)替代实体继承,提升API安全性和清晰度
- 引用计数机制:跟踪字典项使用情况,防止误删
- 权限集成:通过权限码契约与 crm-auth 解耦集成
- 本地缓存:使用 Caffeine 提供高性能字典查询缓存
1 month ago
```mermaid
classDiagram
class BaseEntity {
+id
+createTime
+updateTime
+deleted
}
class OwnedEntity {
+ownerId
+deptId
}
1 month ago
class DictGroup {
+code
+name
+status
+builtin
+deleteKey
1 month ago
}
1 month ago
class DictItem {
+groupId
1 month ago
+code
1 month ago
+name
+value
+status
+builtin
+deleteKey
1 month ago
}
1 month ago
class DictGroupVO {
+id
+name
+code
+sortNo
+status
+description
+builtin
+createTime
+itemCount
}
class DictItemVO {
+id
+groupId
+name
+code
+value
+sortNo
+status
+description
+builtin
+createTime
+groupName
+isDefault
+referenced
+effectiveSelectable
}
class DictGroupDefault {
+groupId
+itemId
}
class DictRefCount {
+groupCode
+itemCode
+refCount
1 month ago
}
class IBaseService~T~ {
+save(entity)
+updateById(entity)
+removeById(id)
+getById(id)
+list(param)
+page(param)
+batchSave(list)
}
1 month ago
class IDictGroupService {
+pageGroups(param)
+saveGroup(group)
+deleteGroup(id)
+updateGroupStatus(id, status)
+listEnabled()
1 month ago
}
1 month ago
class IDictItemService {
+pageItems(param)
+saveItem(item)
+deleteItem(id)
+forceDeleteItem(id)
+updateItemStatus(id, status)
+setDefault(groupId, itemId)
}
class DictDataInitializer
class DictPermissionInitializer
1 month ago
OwnedEntity --|> BaseEntity
1 month ago
DictGroup --> DictGroupDefault : "一对多"
DictItem --> DictRefCount : "引用计数"
IDictGroupService --> IBaseService : "继承"
IDictItemService --> IBaseService : "继承"
DictDataInitializer --> DictGroup : "初始化"
DictDataInitializer --> DictItem : "初始化"
DictPermissionInitializer --> DictGroup : "权限绑定"
1 month ago
```
1 month ago
**图表来源**
1 month ago
- [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)
1 month ago
- [DictGroup.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroup.java)
- [DictItem.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictItem.java)
- [DictGroupVO.java](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictGroupVO.java)
- [DictItemVO.java](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictItemVO.java)
- [DictGroupDefault.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroupDefault.java)
- [DictRefCount.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictRefCount.java)
1 month ago
- [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java)
1 month ago
- [IDictGroupService.java](file://crm-dict/src/main/java/com/crm/dict/service/IDictGroupService.java)
- [IDictItemService.java](file://crm-dict/src/main/java/com/crm/dict/service/IDictItemService.java)
- [DictDataInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictDataInitializer.java)
- [DictPermissionInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictPermissionInitializer.java)
1 month ago
## 详细组件分析
### 通用实体与数据归属
- BaseEntity 提供统一审计字段,配合 MetaObjectFillHandler 自动填充创建/更新时间、操作人等。
- OwnedEntity 扩展数据归属字段,用于数据权限过滤(如按部门/租户隔离)。
- 建议所有业务实体继承 OwnedEntity,确保数据权限生效。
```mermaid
classDiagram
class BaseEntity {
+id
+createTime
+updateTime
+deleted
}
class OwnedEntity {
+ownerId
+deptId
}
OwnedEntity --|> BaseEntity
```
1 month ago
**图表来源**
1 month ago
- [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)
1 month ago
**章节来源**
1 month ago
- [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)"]
```
1 month ago
**图表来源**
1 month ago
- [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)
1 month ago
**章节来源**
1 month ago
- [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"
```
1 month ago
**图表来源**
1 month ago
- [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)
1 month ago
**章节来源**
1 month ago
- [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(["返回统一响应"])
```
1 month ago
**图表来源**
1 month ago
- [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)
1 month ago
**章节来源**
1 month ago
- [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 : "返回受限数据集合"
```
1 month ago
**图表来源**
1 month ago
- [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)
1 month ago
**章节来源**
1 month ago
- [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"]
```
1 month ago
**图表来源**
1 month ago
- [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)
1 month ago
**章节来源**
1 month ago
- [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"]
```
1 month ago
**图表来源**
1 month ago
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
1 month ago
**章节来源**
1 month ago
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
### Jackson 与 API 文档、跨域
- JacksonConfig:统一日期格式、时区、空值序列化策略。
- Knife4jConfig:增强 Swagger 文档体验。
- CorsConfig:允许跨域访问,便于前后端分离开发。
1 month ago
**章节来源**
1 month ago
- [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:树形结构构建。
1 month ago
**章节来源**
1 month ago
- [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)
1 month ago
### 数据字典模块详解
#### VO设计模式重构
**更新** 数据字典模块采用了先进的VO设计模式,DictGroupVO和DictItemVO现在使用独立的字段定义而非继承实体类,显著提升了API设计的清晰度和安全性。
- **DictGroupVO**:专门用于分页列表展示的视图对象,只暴露前端需要的业务字段(id、name、code、sortNo、status、description、builtin、createTime、itemCount),排除了敏感的审计字段(creatorId/updaterId/updateTime/deleted)和软删内部字段(deleteKey)。
- **DictItemVO**:字典项视图对象,包含丰富的展示字段(groupName、isDefault、referenced、effectiveSelectable),其中referenced字段实时读取引用计数,绝不进缓存,确保数据准确性。
```mermaid
classDiagram
class BaseEntity {
+id
+createTime
+updateTime
+deleted
}
class DictGroup {
+code
+name
+status
+builtin
+deleteKey
}
class DictItem {
+groupId
+code
+name
+value
+status
+builtin
+deleteKey
}
class DictGroupVO {
+id
+name
+code
+sortNo
+status
+description
+builtin
+createTime
+itemCount
}
class DictItemVO {
+id
+groupId
+name
+code
+value
+sortNo
+status
+description
+builtin
+createTime
+groupName
+isDefault
+referenced
+effectiveSelectable
}
DictGroup --> DictGroupVO : "toDTO()"
DictItem --> DictItemVO : "toDTO()"
```
**图表来源**
- [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java)
- [DictGroup.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroup.java)
- [DictItem.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictItem.java)
- [DictGroupVO.java](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictGroupVO.java)
- [DictItemVO.java](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictItemVO.java)
#### 核心实体设计
- **DictGroup(字典分组)**:字典的第一级容器,具有全局唯一编码,创建后不可修改。支持内置标记区分平台内置和用户自定义字典。
- **DictItem(字典项)**:字典的第二级键值条目,身份由{分组ID, 编码}确定,创建后不可修改。支持字典值同组唯一约束。
- **DictGroupDefault(分组默认项)**:通过主键约束保证每组最多一个默认项,独立表存储避免污染字典项实体。
- **DictRefCount(引用计数)**:跟踪字典项被业务数据引用的次数,防止误删已使用的字典项。
```mermaid
classDiagram
class DictGroup {
+Long id
+String code
+String name
+Integer sortNo
+Integer status
+Boolean builtin
+Long deleteKey
}
class DictItem {
+Long id
+Long groupId
+String code
+String name
+String value
+Integer sortNo
+Integer status
+Boolean builtin
+Long deleteKey
}
class DictGroupDefault {
+Long groupId
+Long itemId
}
class DictRefCount {
+String groupCode
+String itemCode
+Integer refCount
}
DictGroup "1" --> "0..*" DictItem : "拥有"
DictGroup "1" --> "0..1" DictGroupDefault : "默认项"
DictItem "1" --> "0..1" DictRefCount : "引用计数"
```
**图表来源**
- [DictGroup.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroup.java)
- [DictItem.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictItem.java)
- [DictGroupDefault.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroupDefault.java)
- [DictRefCount.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictRefCount.java)
#### 控制器与服务层
- **DictGroupController**:提供分组管理的 RESTful API,包括分页查询、新建编辑、删除、启停等操作。
- **DictItemController**:提供字典项管理的 RESTful API,支持分页查询、CRUD、默认项设置、强制删除等功能。
- **IDictGroupService/IDictItemService**:定义业务接口,继承 IBaseService 获得通用 CRUD 能力。
- **DictGroupServiceImpl**:实现分组业务逻辑,包含数据验证、权限检查、事务管理等。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Controller as "DictGroupController"
participant Service as "IDictGroupService"
participant DB as "数据库"
Client->>Controller : POST /api/dict/group/saveOrUpdate
Controller->>Service : saveGroup(DictGroup)
Service->>Service : 数据验证与权限检查
Service->>DB : INSERT/UPDATE dict_group
DB-->>Service : 操作结果
Service-->>Controller : 业务结果
Controller-->>Client : Result.success()
```
**图表来源**
- [DictGroupController.java](file://crm-dict/src/main/java/com/crm/dict/controller/DictGroupController.java)
- [IDictGroupService.java](file://crm-dict/src/main/java/com/crm/dict/service/IDictGroupService.java)
- [DictGroupServiceImpl.java](file://crm-dict/src/main/java/com/crm/dict/service/impl/DictGroupServiceImpl.java)
#### 初始化与权限集成
- **DictDataInitializer**:应用启动时执行内置字典的幂等初始化,支持 Excel 替换口,保护用户字典不被覆盖。
- **DictPermissionInitializer**:权限种子化,将 10 个 dict:* 权限点注入到权限资源树,并与管理员角色绑定。
- **DictConstants**:集中定义状态码、权限码、缓存配置、错误码等常量。
```mermaid
flowchart TD
Startup["应用启动"] --> DataInit["DictDataInitializer.run()"]
Startup --> PermInit["DictPermissionInitializer.run()"]
DataInit --> Validate["校验种子数据"]
Validate --> UpsertGroup["upsertGroup()"]
UpsertGroup --> UpsertItem["upsertItem()"]
UpsertItem --> SetDefault["setDefaultIfAbsent()"]
PermInit --> CreateMenu["创建菜单节点"]
CreateMenu --> CreateButtons["创建权限按钮"]
CreateButtons --> BindRole["绑定管理员角色"]
```
**图表来源**
- [DictDataInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictDataInitializer.java)
- [DictPermissionInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictPermissionInitializer.java)
- [DictConstants.java](file://crm-dict/src/main/java/com/crm/dict/constant/DictConstants.java)
**章节来源**
- [DictGroup.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroup.java)
- [DictItem.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictItem.java)
- [DictGroupDefault.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroupDefault.java)
- [DictRefCount.java](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictRefCount.java)
- [DictGroupVO.java](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictGroupVO.java)
- [DictItemVO.java](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictItemVO.java)
- [DictGroupController.java](file://crm-dict/src/main/java/com/crm/dict/controller/DictGroupController.java)
- [DictItemController.java](file://crm-dict/src/main/java/com/crm/dict/controller/DictItemController.java)
- [IDictGroupService.java](file://crm-dict/src/main/java/com/crm/dict/service/IDictGroupService.java)
- [IDictItemService.java](file://crm-dict/src/main/java/com/crm/dict/service/IDictItemService.java)
- [DictGroupServiceImpl.java](file://crm-dict/src/main/java/com/crm/dict/service/impl/DictGroupServiceImpl.java)
- [DictItemServiceImpl.java](file://crm-dict/src/main/java/com/crm/dict/service/impl/DictItemServiceImpl.java)
- [DictDataInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictDataInitializer.java)
- [DictPermissionInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictPermissionInitializer.java)
- [DictConstants.java](file://crm-dict/src/main/java/com/crm/dict/constant/DictConstants.java)
1 month ago
## 依赖关系分析
- 实体与服务:BaseEntity/OwnedEntity 被 BaseServiceImpl 广泛使用;IBaseService 定义契约。
- 数据访问:CrmBaseMapper 被 BaseServiceImpl 依赖;MyBatis Plus 插件贯穿整个数据层。
- 横切:GlobalExceptionHandlerAdvice 作用于所有 Controller;DataScopeHelper 与 DataVisibilityContext 影响查询条件。
- 外部依赖:Redis 用于缓存;Jackson 用于序列化;Knife4j 用于文档;Cors 用于跨域。
1 month ago
**更新** 新增 crm-dict 模块依赖关系:
- crm-dict 仅依赖 crm-base,不直接依赖 crm-auth,通过权限码契约解耦
- 使用 Caffeine 本地缓存提升字典查询性能
- 通过 CommandLineRunner 实现启动时初始化
- 与 crm-auth 通过权限资源树间接集成
- **VO设计模式**:通过独立的视图对象减少了实体与API的直接耦合
1 month ago
```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"]
1 month ago
DictModule["crm-dict 模块"] --> BaseModule["crm-base 模块"]
DictModule --> Caffeine["Caffeine 缓存"]
DictModule --> AuthContract["权限码契约"]
AuthContract --> AuthModule["crm-auth 模块"]
DictModule --> VOPattern["VO设计模式"]
VOPattern --> APIClear["清晰的API契约"]
1 month ago
```
1 month ago
**图表来源**
1 month ago
- [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)
1 month ago
- [pom.xml](file://crm-dict/pom.xml)
1 month ago
1 month ago
**章节来源**
1 month ago
- [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)
1 month ago
- [pom.xml](file://crm-dict/pom.xml)
1 month ago
## 性能考量
- 分页查询:优先使用 MyBatis Plus 分页插件,避免全表扫描;合理设计索引。
- 批量操作:使用 batchSave 与 InsertBatchOnDuplicateKeyUpdate 提升写入吞吐。
- 缓存策略:对热点数据启用 Redis 缓存,设置合理 TTL 与失效策略。
- 序列化:Jackson 配置统一时区与空值策略,减少序列化开销。
- 审计填充:MetaObjectFillHandler 仅在必要时填充,避免多余数据库写操作。
1 month ago
**更新** 数据字典性能优化:
- 使用 Caffeine 本地缓存提供 10s TTL 的字典查询缓存
- 空结果缓存 2s 防穿透,避免缓存击穿
- 引用计数表不缓存,保证数据一致性
- 聚合查询优化:分组分页时一次性查询字典项数量
- 默认排序优化:sort_no IS NULL, sort_no ASC, create_time ASC
- **VO设计优化**:通过独立的VO对象减少数据传输量,提升网络传输效率
1 month ago
[本节为通用指导,不直接分析具体文件]
## 故障排查指南
- 统一异常:检查 GlobalExceptionHandlerAdvice 是否捕获到预期异常类型,确认 ResultCodeEnum 的状态码与消息。
- 数据权限:确认 DataScope 注解是否正确标注,DataVisibilityContext 中可见范围是否设置正确。
- 填充失败:检查 MetaObjectFillHandler 是否注册,实体字段名是否与填充规则匹配。
- ID 冲突:核对 SnowflakeIdWorker 配置(工作节点/数据中心)是否唯一,避免 ID 碰撞。
- 缓存问题:检查 Redis 连接与序列化配置,确认 key 命名规范与过期策略。
- 跨域与文档:验证 CorsConfig 与 Knife4jConfig 配置是否符合前端需求。
1 month ago
**更新** 数据字典故障排查:
- 初始化失败:检查 DictDataInitializer 的种子数据合法性,确认 fail-fast 机制
- 权限问题:验证 DictPermissionInitializer 是否正确创建菜单和权限点
- 缓存不一致:检查 Caffeine 缓存配置,确认 TTL 设置合理
- 引用计数异常:监控 DictRefCount 表的计数准确性,必要时使用强制删除功能
- 内置字典保护:确认 builtin=true 的字典项无法被删除或修改关键字段
- **VO设计问题**:检查DictGroupVO和DictItemVO的字段映射是否正确,确保toDTO方法正常工作
**章节来源**
1 month ago
- [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)
1 month ago
- [DictDataInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictDataInitializer.java)
- [DictPermissionInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictPermissionInitializer.java)
1 month ago
## 结论
crm-base 提供了完善的基础设施能力,涵盖实体设计、CRUD 封装、分页与结果统一、全局异常、数据权限、MyBatis Plus 扩展、Redis 缓存、雪花 ID 生成等。遵循本模块约定,可显著提升业务模块的开发效率与一致性。
1 month ago
**更新** 新增 crm-dict 数据字典模块作为独立的基础设施服务,提供平台级的键值字典管理能力。该模块通过先进的VO设计模式重构,实现了更清晰的API契约和更高的安全性,同时通过解耦设计与权限码契约,实现了与认证模块的松耦合集成。VO设计模式的采用使得数据展示更加灵活可控,有效避免了敏感信息的泄露风险。
1 month ago
[本节为总结性内容,不直接分析具体文件]
## 附录
### 最佳实践
- 实体设计
- 所有业务实体继承 OwnedEntity,确保数据权限生效。
- 合理使用审计字段,避免频繁手动更新 createTime/updateTime。
- 服务层
- 优先使用 IBaseService 提供的通用方法,减少样板代码。
- 复杂查询通过 CrmBaseMapper 扩展 SQL,保持可读性。
- 异常处理
- 业务层抛出明确的自定义异常,交由 GlobalExceptionHandlerAdvice 统一处理。
- 数据权限
- 在需要数据隔离的方法上使用 @DataScope,并通过 DataVisibilityContext 设置可见范围。
- 缓存
- 对热点数据使用 Redis 缓存,设置合理的 TTL 与失效策略,保证一致性。
- 工具类
- 使用 AssertUtils 做前置校验;使用 BeanCopyUtils 进行对象转换;使用 PageConverter 转换分页对象。
1 month ago
**更新** 数据字典最佳实践:
- 字典设计:优先使用内置字典,用户字典用于个性化需求
- 编码规范:字典编码使用有意义的英文标识,避免使用数字 ID
- 引用管理:业务代码中正确使用引用计数增减,避免内存泄漏
- 缓存策略:利用 Caffeine 本地缓存提升查询性能,注意缓存失效时机
- 权限控制:通过权限码进行细粒度控制,避免硬编码权限判断
- **VO设计模式**:采用独立的视图对象定义API契约,避免直接暴露实体字段,提升安全性和灵活性
1 month ago
[本节为通用指导,不直接分析具体文件]
### 扩展开发指南
- 新增实体
- 继承 OwnedEntity,定义必要字段;如需自定义 ID 生成策略,可在 CustomIdGenerator 中扩展。
- 新增服务方法
- 在 IBaseService 中定义接口,在 BaseServiceImpl 中实现;复杂 SQL 通过 CrmBaseMapper 扩展。
- 新增数据权限级别
- 在 DataScopeLevel 中扩展级别,并在 DataScopeHelper 中实现对应过滤逻辑。
- 新增缓存键与策略
- 在业务模块中定义缓存 Key 前缀与过期时间,使用 RedisTemplate 进行操作。
- 新增全局异常类型
- 定义新的异常类,并在 GlobalExceptionHandlerAdvice 中添加对应的处理分支。
1 month ago
**更新** 数据字典扩展指南:
- 新增字典分组:通过 DictGroupController 的 saveOrUpdate 接口创建新分组
- 新增字典项:使用 DictItemController 的 saveOrUpdate 接口添加字典项
- 扩展内置数据:修改 DictDataInitializer 中的 SEED_GROUPS 列表
- 新增权限点:在 DictPermissionInitializer 中添加新的权限点种子
- 自定义缓存策略:扩展 DictConstants 中的缓存配置参数
- **VO扩展**:如需新增展示字段,应在DictGroupVO和DictItemVO中定义独立字段,而非修改实体类
1 month ago
[本节为通用指导,不直接分析具体文件]