|
|
|
@ -46,8 +46,30 @@ |
|
|
|
- [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) |
|
|
|
- [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) |
|
|
|
</cite> |
|
|
|
|
|
|
|
## 更新摘要 |
|
|
|
**变更内容** |
|
|
|
- 更新了数据字典模块的VO设计架构,DictGroupVO和DictItemVO现在使用独立字段定义而非继承实体类 |
|
|
|
- 增强了API设计的清晰度和安全性,通过明确的字段暴露控制敏感信息 |
|
|
|
- 优化了服务层实现以适配新的VO结构,提升了数据转换效率 |
|
|
|
- 完善了VO设计模式的最佳实践说明 |
|
|
|
|
|
|
|
## 目录 |
|
|
|
1. [简介](#简介) |
|
|
|
2. [项目结构](#项目结构) |
|
|
|
@ -63,6 +85,8 @@ |
|
|
|
## 简介 |
|
|
|
本模块为 CRM 后端的基础设施层,提供通用实体、分页与结果封装、全局异常处理、数据访问层封装、工具类以及 MyBatis Plus、Redis、雪花ID等关键配置。通过统一的设计模式与约定,降低业务模块重复开发成本,提升一致性与可维护性。 |
|
|
|
|
|
|
|
**更新** 新增 crm-dict 数据字典模块,作为独立的服务模块提供平台级键值字典管理能力,支持分组管理、字典项管理、引用计数和权限集成等功能。该模块采用了先进的VO设计模式,通过独立的视图对象定义提升了API的安全性和清晰度。 |
|
|
|
|
|
|
|
## 项目结构 |
|
|
|
crm-base 采用分层组织: |
|
|
|
- domain:通用实体、DTO、参数、枚举、异常、结果封装 |
|
|
|
@ -72,72 +96,60 @@ crm-base 采用分层组织: |
|
|
|
- security:数据权限控制、可见性上下文、登录用户模型与安全工具 |
|
|
|
- utils:通用工具集(断言、拷贝、枚举、Excel、分页转换、Servlet、树形结构) |
|
|
|
|
|
|
|
**更新** crm-dict 模块结构: |
|
|
|
- controller:字典分组和字典项的管理接口 |
|
|
|
- service:字典查询、引用计数、分组和字典项的业务逻辑 |
|
|
|
- domain:字典实体、DTO、参数定义,采用独立VO设计模式 |
|
|
|
- config:内置数据初始化、权限种子化配置 |
|
|
|
- constant:字典模块常量定义 |
|
|
|
|
|
|
|
```mermaid |
|
|
|
graph TB |
|
|
|
subgraph "领域模型" |
|
|
|
subgraph "基础框架 (crm-base)" |
|
|
|
A["BaseEntity / OwnedEntity"] |
|
|
|
B["BaseDTO / BaseParam"] |
|
|
|
C["Result / PageResult / ResultCodeEnum"] |
|
|
|
D["StatusEnum / HasValueEnum"] |
|
|
|
E["MybatisPlusConfig / CrmSqlInjector"] |
|
|
|
F["RedisConfig / JacksonConfig"] |
|
|
|
G["GlobalExceptionHandlerAdvice"] |
|
|
|
H["DataScope / SecurityUtils"] |
|
|
|
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"] |
|
|
|
subgraph "数据字典 (crm-dict)" |
|
|
|
I["DictGroup / DictItem"] |
|
|
|
J["DictGroupVO / DictItemVO"] |
|
|
|
K["DictGroupController / DictItemController"] |
|
|
|
L["IDictGroupService / IDictItemService"] |
|
|
|
M["DictDataInitializer / DictPermissionInitializer"] |
|
|
|
N["DictConstants"] |
|
|
|
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 |
|
|
|
A --> L |
|
|
|
B --> L |
|
|
|
C --> K |
|
|
|
E --> L |
|
|
|
F --> M |
|
|
|
G --> K |
|
|
|
H --> K |
|
|
|
I --> J |
|
|
|
J --> K |
|
|
|
L --> E |
|
|
|
M --> I |
|
|
|
N --> L |
|
|
|
``` |
|
|
|
|
|
|
|
图表来源 |
|
|
|
- [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) |
|
|
|
- [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) |
|
|
|
- [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) |
|
|
|
|
|
|
|
@ -175,7 +187,15 @@ Q --> P |
|
|
|
- 工具类 |
|
|
|
- AssertUtils、BeanCopyUtils、EnumUtils、ExcelUtil、PageConverter、ServletUtils、TreeUtils。 |
|
|
|
|
|
|
|
章节来源 |
|
|
|
**更新** 数据字典核心组件: |
|
|
|
- 字典实体:DictGroup(分组)、DictItem(字典项)、DictGroupDefault(默认项)、DictRefCount(引用计数) |
|
|
|
- **VO设计模式**:DictGroupVO和DictItemVO采用独立字段定义,不继承实体类,提供更清晰的API契约 |
|
|
|
- 控制器:DictGroupController、DictItemController 提供 RESTful API |
|
|
|
- 服务层:IDictGroupService、IDictItemService 定义业务接口 |
|
|
|
- 初始化器:DictDataInitializer(内置数据)、DictPermissionInitializer(权限种子) |
|
|
|
- 常量定义:DictConstants 包含状态码、权限码、缓存配置等 |
|
|
|
|
|
|
|
**章节来源** |
|
|
|
- [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) |
|
|
|
@ -209,14 +229,37 @@ Q --> P |
|
|
|
- [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) |
|
|
|
- [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) |
|
|
|
|
|
|
|
## 架构总览 |
|
|
|
基础框架围绕“实体-服务-Mapper”三层展开,辅以配置中心与横切能力: |
|
|
|
基础框架围绕"实体-服务-Mapper"三层展开,辅以配置中心与横切能力: |
|
|
|
- 实体层:BaseEntity/OwnedEntity 提供统一字段与审计;OwnedEntity 承载数据归属。 |
|
|
|
- 服务层:IBaseService/BaseServiceImpl 提供 CRUD、分页、批量操作与事务边界。 |
|
|
|
- 数据层:CrmBaseMapper 扩展通用 SQL;MyBatis Plus 插件负责分页、填充、ID 生成。 |
|
|
|
- 横切:全局异常、数据权限、请求追踪、序列化、缓存、API 文档、跨域。 |
|
|
|
|
|
|
|
**更新** 新增 crm-dict 模块架构: |
|
|
|
- 独立服务模块:基于 crm-base 构建,不依赖 crm-auth 具体实现 |
|
|
|
- 两级字典结构:分组 → 字典项,支持内置和用户字典分离 |
|
|
|
- **VO设计模式**:采用独立的视图对象(DictGroupVO、DictItemVO)替代实体继承,提升API安全性和清晰度 |
|
|
|
- 引用计数机制:跟踪字典项使用情况,防止误删 |
|
|
|
- 权限集成:通过权限码契约与 crm-auth 解耦集成 |
|
|
|
- 本地缓存:使用 Caffeine 提供高性能字典查询缓存 |
|
|
|
|
|
|
|
```mermaid |
|
|
|
classDiagram |
|
|
|
class BaseEntity { |
|
|
|
@ -229,25 +272,58 @@ class OwnedEntity { |
|
|
|
+ownerId |
|
|
|
+deptId |
|
|
|
} |
|
|
|
class BaseDTO |
|
|
|
class BaseParam { |
|
|
|
+pageNo |
|
|
|
+pageSize |
|
|
|
+orderBy |
|
|
|
class DictGroup { |
|
|
|
+code |
|
|
|
+name |
|
|
|
+status |
|
|
|
+builtin |
|
|
|
+deleteKey |
|
|
|
} |
|
|
|
class Result~T~ { |
|
|
|
class DictItem { |
|
|
|
+groupId |
|
|
|
+code |
|
|
|
+message |
|
|
|
+data |
|
|
|
+name |
|
|
|
+value |
|
|
|
+status |
|
|
|
+builtin |
|
|
|
+deleteKey |
|
|
|
} |
|
|
|
class PageResult~T~ { |
|
|
|
+records |
|
|
|
+total |
|
|
|
+pages |
|
|
|
+current |
|
|
|
+size |
|
|
|
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 |
|
|
|
} |
|
|
|
class CrmBaseMapper |
|
|
|
class IBaseService~T~ { |
|
|
|
+save(entity) |
|
|
|
+updateById(entity) |
|
|
|
@ -257,58 +333,47 @@ class IBaseService~T~ { |
|
|
|
+page(param) |
|
|
|
+batchSave(list) |
|
|
|
} |
|
|
|
class BaseServiceImpl~T~ { |
|
|
|
+mapper |
|
|
|
+save() |
|
|
|
+updateById() |
|
|
|
+removeById() |
|
|
|
+getById() |
|
|
|
+list() |
|
|
|
+page() |
|
|
|
+batchSave() |
|
|
|
class IDictGroupService { |
|
|
|
+pageGroups(param) |
|
|
|
+saveGroup(group) |
|
|
|
+deleteGroup(id) |
|
|
|
+updateGroupStatus(id, status) |
|
|
|
+listEnabled() |
|
|
|
} |
|
|
|
class MybatisPlusConfig |
|
|
|
class MetaObjectFillHandler |
|
|
|
class CustomIdGenerator |
|
|
|
class SnowflakeIdWorker |
|
|
|
class RedisConfig |
|
|
|
class GlobalExceptionHandlerAdvice |
|
|
|
class DataScopeHelper |
|
|
|
class DataVisibilityContext |
|
|
|
class SecurityUtils |
|
|
|
class LoginUser |
|
|
|
class IDictItemService { |
|
|
|
+pageItems(param) |
|
|
|
+saveItem(item) |
|
|
|
+deleteItem(id) |
|
|
|
+forceDeleteItem(id) |
|
|
|
+updateItemStatus(id, status) |
|
|
|
+setDefault(groupId, itemId) |
|
|
|
} |
|
|
|
class DictDataInitializer |
|
|
|
class DictPermissionInitializer |
|
|
|
OwnedEntity --|> BaseEntity |
|
|
|
BaseServiceImpl --> CrmBaseMapper : "使用" |
|
|
|
BaseServiceImpl --> IBaseService : "实现" |
|
|
|
MybatisPlusConfig --> MetaObjectFillHandler : "注册" |
|
|
|
MybatisPlusConfig --> CustomIdGenerator : "注册" |
|
|
|
CustomIdGenerator --> SnowflakeIdWorker : "调用" |
|
|
|
BaseServiceImpl --> RedisConfig : "可选缓存" |
|
|
|
GlobalExceptionHandlerAdvice --> Result : "返回" |
|
|
|
DataScopeHelper --> DataVisibilityContext : "读写上下文" |
|
|
|
SecurityUtils --> LoginUser : "获取用户" |
|
|
|
DictGroup --> DictGroupDefault : "一对多" |
|
|
|
DictItem --> DictRefCount : "引用计数" |
|
|
|
IDictGroupService --> IBaseService : "继承" |
|
|
|
IDictItemService --> IBaseService : "继承" |
|
|
|
DictDataInitializer --> DictGroup : "初始化" |
|
|
|
DictDataInitializer --> DictItem : "初始化" |
|
|
|
DictPermissionInitializer --> DictGroup : "权限绑定" |
|
|
|
``` |
|
|
|
|
|
|
|
图表来源 |
|
|
|
**图表来源** |
|
|
|
- [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) |
|
|
|
- [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) |
|
|
|
- [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) |
|
|
|
- [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) |
|
|
|
|
|
|
|
## 详细组件分析 |
|
|
|
|
|
|
|
@ -332,11 +397,11 @@ class OwnedEntity { |
|
|
|
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) |
|
|
|
@ -355,7 +420,7 @@ 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) |
|
|
|
@ -363,7 +428,7 @@ Wrap --> Return["返回 Result.success(PageResult)"] |
|
|
|
- [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) |
|
|
|
@ -388,13 +453,13 @@ 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) |
|
|
|
@ -415,7 +480,7 @@ 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) |
|
|
|
@ -423,7 +488,7 @@ Map --> End(["返回统一响应"]) |
|
|
|
- [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) |
|
|
|
@ -449,14 +514,14 @@ 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) |
|
|
|
@ -481,7 +546,7 @@ 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) |
|
|
|
@ -489,7 +554,7 @@ Inject --> SQL["扩展通用 SQL"] |
|
|
|
- [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) |
|
|
|
@ -510,10 +575,10 @@ 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 文档、跨域 |
|
|
|
@ -521,7 +586,7 @@ App --> Use["业务模块使用 RedisTemplate"] |
|
|
|
- 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) |
|
|
|
@ -535,7 +600,7 @@ App --> Use["业务模块使用 RedisTemplate"] |
|
|
|
- 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) |
|
|
|
@ -544,12 +609,203 @@ App --> Use["业务模块使用 RedisTemplate"] |
|
|
|
- [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) |
|
|
|
|
|
|
|
### 数据字典模块详解 |
|
|
|
|
|
|
|
#### 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) |
|
|
|
|
|
|
|
## 依赖关系分析 |
|
|
|
- 实体与服务:BaseEntity/OwnedEntity 被 BaseServiceImpl 广泛使用;IBaseService 定义契约。 |
|
|
|
- 数据访问:CrmBaseMapper 被 BaseServiceImpl 依赖;MyBatis Plus 插件贯穿整个数据层。 |
|
|
|
- 横切:GlobalExceptionHandlerAdvice 作用于所有 Controller;DataScopeHelper 与 DataVisibilityContext 影响查询条件。 |
|
|
|
- 外部依赖:Redis 用于缓存;Jackson 用于序列化;Knife4j 用于文档;Cors 用于跨域。 |
|
|
|
|
|
|
|
**更新** 新增 crm-dict 模块依赖关系: |
|
|
|
- crm-dict 仅依赖 crm-base,不直接依赖 crm-auth,通过权限码契约解耦 |
|
|
|
- 使用 Caffeine 本地缓存提升字典查询性能 |
|
|
|
- 通过 CommandLineRunner 实现启动时初始化 |
|
|
|
- 与 crm-auth 通过权限资源树间接集成 |
|
|
|
- **VO设计模式**:通过独立的视图对象减少了实体与API的直接耦合 |
|
|
|
|
|
|
|
```mermaid |
|
|
|
graph LR |
|
|
|
Entity["BaseEntity/OwnedEntity"] --> Service["IBaseService/BaseServiceImpl"] |
|
|
|
@ -561,9 +817,15 @@ Service --> Cache["RedisConfig"] |
|
|
|
Controller["业务Controller"] --> Service |
|
|
|
Controller --> Exception["GlobalExceptionHandlerAdvice"] |
|
|
|
Service --> Scope["DataScopeHelper/DataVisibilityContext"] |
|
|
|
DictModule["crm-dict 模块"] --> BaseModule["crm-base 模块"] |
|
|
|
DictModule --> Caffeine["Caffeine 缓存"] |
|
|
|
DictModule --> AuthContract["权限码契约"] |
|
|
|
AuthContract --> AuthModule["crm-auth 模块"] |
|
|
|
DictModule --> VOPattern["VO设计模式"] |
|
|
|
VOPattern --> APIClear["清晰的API契约"] |
|
|
|
``` |
|
|
|
|
|
|
|
图表来源 |
|
|
|
**图表来源** |
|
|
|
- [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) |
|
|
|
@ -577,12 +839,14 @@ Service --> Scope["DataScopeHelper/DataVisibilityContext"] |
|
|
|
- [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) |
|
|
|
- [pom.xml](file://crm-dict/pom.xml) |
|
|
|
|
|
|
|
章节来源 |
|
|
|
**章节来源** |
|
|
|
- [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) |
|
|
|
- [pom.xml](file://crm-dict/pom.xml) |
|
|
|
|
|
|
|
## 性能考量 |
|
|
|
- 分页查询:优先使用 MyBatis Plus 分页插件,避免全表扫描;合理设计索引。 |
|
|
|
@ -591,6 +855,14 @@ Service --> Scope["DataScopeHelper/DataVisibilityContext"] |
|
|
|
- 序列化:Jackson 配置统一时区与空值策略,减少序列化开销。 |
|
|
|
- 审计填充:MetaObjectFillHandler 仅在必要时填充,避免多余数据库写操作。 |
|
|
|
|
|
|
|
**更新** 数据字典性能优化: |
|
|
|
- 使用 Caffeine 本地缓存提供 10s TTL 的字典查询缓存 |
|
|
|
- 空结果缓存 2s 防穿透,避免缓存击穿 |
|
|
|
- 引用计数表不缓存,保证数据一致性 |
|
|
|
- 聚合查询优化:分组分页时一次性查询字典项数量 |
|
|
|
- 默认排序优化:sort_no IS NULL, sort_no ASC, create_time ASC |
|
|
|
- **VO设计优化**:通过独立的VO对象减少数据传输量,提升网络传输效率 |
|
|
|
|
|
|
|
[本节为通用指导,不直接分析具体文件] |
|
|
|
|
|
|
|
## 故障排查指南 |
|
|
|
@ -601,7 +873,15 @@ Service --> Scope["DataScopeHelper/DataVisibilityContext"] |
|
|
|
- 缓存问题:检查 Redis 连接与序列化配置,确认 key 命名规范与过期策略。 |
|
|
|
- 跨域与文档:验证 CorsConfig 与 Knife4jConfig 配置是否符合前端需求。 |
|
|
|
|
|
|
|
章节来源 |
|
|
|
**更新** 数据字典故障排查: |
|
|
|
- 初始化失败:检查 DictDataInitializer 的种子数据合法性,确认 fail-fast 机制 |
|
|
|
- 权限问题:验证 DictPermissionInitializer 是否正确创建菜单和权限点 |
|
|
|
- 缓存不一致:检查 Caffeine 缓存配置,确认 TTL 设置合理 |
|
|
|
- 引用计数异常:监控 DictRefCount 表的计数准确性,必要时使用强制删除功能 |
|
|
|
- 内置字典保护:确认 builtin=true 的字典项无法被删除或修改关键字段 |
|
|
|
- **VO设计问题**:检查DictGroupVO和DictItemVO的字段映射是否正确,确保toDTO方法正常工作 |
|
|
|
|
|
|
|
**章节来源** |
|
|
|
- [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) |
|
|
|
@ -609,10 +889,14 @@ Service --> Scope["DataScopeHelper/DataVisibilityContext"] |
|
|
|
- [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) |
|
|
|
- [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) |
|
|
|
|
|
|
|
## 结论 |
|
|
|
crm-base 提供了完善的基础设施能力,涵盖实体设计、CRUD 封装、分页与结果统一、全局异常、数据权限、MyBatis Plus 扩展、Redis 缓存、雪花 ID 生成等。遵循本模块约定,可显著提升业务模块的开发效率与一致性。 |
|
|
|
|
|
|
|
**更新** 新增 crm-dict 数据字典模块作为独立的基础设施服务,提供平台级的键值字典管理能力。该模块通过先进的VO设计模式重构,实现了更清晰的API契约和更高的安全性,同时通过解耦设计与权限码契约,实现了与认证模块的松耦合集成。VO设计模式的采用使得数据展示更加灵活可控,有效避免了敏感信息的泄露风险。 |
|
|
|
|
|
|
|
[本节为总结性内容,不直接分析具体文件] |
|
|
|
|
|
|
|
## 附录 |
|
|
|
@ -633,6 +917,14 @@ crm-base 提供了完善的基础设施能力,涵盖实体设计、CRUD 封装 |
|
|
|
- 工具类 |
|
|
|
- 使用 AssertUtils 做前置校验;使用 BeanCopyUtils 进行对象转换;使用 PageConverter 转换分页对象。 |
|
|
|
|
|
|
|
**更新** 数据字典最佳实践: |
|
|
|
- 字典设计:优先使用内置字典,用户字典用于个性化需求 |
|
|
|
- 编码规范:字典编码使用有意义的英文标识,避免使用数字 ID |
|
|
|
- 引用管理:业务代码中正确使用引用计数增减,避免内存泄漏 |
|
|
|
- 缓存策略:利用 Caffeine 本地缓存提升查询性能,注意缓存失效时机 |
|
|
|
- 权限控制:通过权限码进行细粒度控制,避免硬编码权限判断 |
|
|
|
- **VO设计模式**:采用独立的视图对象定义API契约,避免直接暴露实体字段,提升安全性和灵活性 |
|
|
|
|
|
|
|
[本节为通用指导,不直接分析具体文件] |
|
|
|
|
|
|
|
### 扩展开发指南 |
|
|
|
@ -647,4 +939,12 @@ crm-base 提供了完善的基础设施能力,涵盖实体设计、CRUD 封装 |
|
|
|
- 新增全局异常类型 |
|
|
|
- 定义新的异常类,并在 GlobalExceptionHandlerAdvice 中添加对应的处理分支。 |
|
|
|
|
|
|
|
**更新** 数据字典扩展指南: |
|
|
|
- 新增字典分组:通过 DictGroupController 的 saveOrUpdate 接口创建新分组 |
|
|
|
- 新增字典项:使用 DictItemController 的 saveOrUpdate 接口添加字典项 |
|
|
|
- 扩展内置数据:修改 DictDataInitializer 中的 SEED_GROUPS 列表 |
|
|
|
- 新增权限点:在 DictPermissionInitializer 中添加新的权限点种子 |
|
|
|
- 自定义缓存策略:扩展 DictConstants 中的缓存配置参数 |
|
|
|
- **VO扩展**:如需新增展示字段,应在DictGroupVO和DictItemVO中定义独立字段,而非修改实体类 |
|
|
|
|
|
|
|
[本节为通用指导,不直接分析具体文件] |