# 模块说明 **本文引用的文件** - [pom.xml](file://pom.xml) - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) - [application.yml](file://crm-auth/src/main/resources/application.yml) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java) - [DataInitializer.java](file://crm-auth/src/main/java/com/crm/auth/config/DataInitializer.java) - [AuthProperties.java](file://crm-auth/src/main/java/com/crm/auth/config/AuthProperties.java) - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java) - [SystemController.java](file://crm-auth/src/main/java/com/crm/auth/controller/SystemController.java) - [IAuthService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java) - [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java) - [IAuthUserService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthUserService.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [ISysRoleService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysRoleService.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [ISysMenuService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysMenuService.java) - [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java) - [ISysDeptService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysDeptService.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java) - [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java) - [ThirdPartyAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClient.java) - [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthClient.java) - [ThirdPartyUserInfo.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyUserInfo.java) - [AuthIdentity.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthIdentity.java) - [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java) - [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java) - [LoginParam.java](file://crm-auth/src/main/java/com/crm/auth/domain/param/LoginParam.java) - [LoginResultDTO.java](file://crm-auth/src/main/java/com/crm/auth/domain/dto/LoginResultDTO.java) - [UserInfoDTO.java](file://crm-auth/src/main/java/com/crm/auth/domain/dto/UserInfoDTO.java) - [AuthConstants.java](file://crm-auth/src/main/java/com/crm/auth/constant/AuthConstants.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.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) - [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) - [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [CommonConstants.java](file://crm-base/src/main/java/com/crm/base/constant/CommonConstants.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) - [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) - [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) - [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) - [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) - [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) - [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) - [FileApi.java](file://crm-file/src/main/java/com/crm/file/api/FileApi.java) - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [IFileInfoService.java](file://crm-file/src/main/java/com/crm/file/service/IFileInfoService.java) - [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java) - [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java) - [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java) - [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java) - [DictApplication.java](file://crm-dict/src/main/java/com/crm/dict/DictApplication.java) - [pom.xml](file://crm-dict/pom.xml) - [CONTEXT.md](file://crm-dict/CONTEXT.md) - [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) - [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) - [DictQueryService.java](file://crm-dict/src/main/java/com/crm/dict/service/DictQueryService.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) - [DictDataInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictDataInitializer.java) - [DictConstants.java](file://crm-dict/src/main/java/com/crm/dict/constant/DictConstants.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) ## 更新摘要 **变更内容** - 更新了数据字典模块的VO设计说明,强调内部实体模型与外部API契约的明确分离 - 增强了分层架构设计的描述,体现更好的领域边界划分 - 补充了VO类的设计理念和字段暴露策略 - 更新了数据字典组件分析章节,包含VO设计优化的详细说明 ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心模块](#核心模块) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录:配置与扩展点](#附录配置与扩展点) ## 简介 本仓库为CRM后端多模块工程,采用分层与模块化设计,包含以下核心模块: - crm-auth(认证服务):负责用户认证、权限管理、第三方登录集成。 - crm-base(基础框架):提供通用能力,如分页、异常处理、数据权限、统一结果封装、工具类等。 - crm-file(文件服务):提供文件上传、下载、预览及分片断点续传等能力。 - crm-dict(数据字典):提供两级平铺字典管理(分组→字典项),支持缓存、引用计数和内置字典初始化。 - crm-app(应用入口):作为统一启动入口,聚合各模块并加载配置。 文档将从模块职责、包结构、核心类与接口、依赖关系、通信方式、配置项、扩展点与自定义开发等方面进行全面说明,帮助开发者快速上手并进行深度定制。 ## 项目结构 整体采用Maven多模块组织,顶层pom.xml定义聚合与依赖版本管理;各子模块独立构建,通过Spring Boot启动。 ```mermaid graph TB subgraph "应用层" APP["crm-app
统一启动入口"] end subgraph "业务模块" AUTH["crm-auth
认证与权限"] FILE["crm-file
文件服务"] DICT["crm-dict
数据字典"] end subgraph "基础模块" BASE["crm-base
通用能力"] end APP --> AUTH APP --> FILE APP --> DICT AUTH --> BASE FILE --> BASE DICT --> BASE ``` **图表来源** - [pom.xml:21-28](file://pom.xml#L21-L28) - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) - [DictApplication.java](file://crm-dict/src/main/java/com/crm/dict/DictApplication.java) **章节来源** - [pom.xml:21-28](file://pom.xml#L21-L28) - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) ## 核心模块 - crm-auth(认证服务) - 职责:用户认证、角色/菜单/部门权限模型、JWT鉴权、数据权限控制、第三方登录(如钉钉)。 - 关键包:config、controller、domain、mapper、security、service、constant。 - 典型流程:登录校验→签发/校验JWT→基于注解的数据权限过滤→资源访问。 - crm-base(基础框架) - 职责:全局异常处理、统一响应体、分页、MyBatis-Plus增强、Redis、Jackson、Knife4j、雪花ID、审计字段填充、数据可见性上下文等。 - 关键包:advice、annotation、config、constant、domain、filter、mapper、security、service、utils。 - crm-file(文件服务) - 职责:文件上传(含分片)、下载、预览(对接kkFileView)、元信息持久化、定时清理孤儿分片。 - 关键包:api、config、constant、controller、domain、mapper、service、task。 - crm-dict(数据字典) - 职责:两级平铺字典管理(分组→字典项)、内置字典幂等初始化、本地缓存、引用计数、权限控制。 - 关键包:config、constant、controller、domain、mapper、service。 - 核心特性:Caffeine本地缓存(10s TTL)、软删除复用键、内置字典保护、引用计数机制。 - **VO设计优化**:明确区分内部实体模型(Entity)和外部API契约(VO),提供更好的分层架构设计。 - crm-app(应用入口) - 职责:聚合模块、加载应用配置、启动Spring Boot应用。 **章节来源** - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [DictApplication.java](file://crm-dict/src/main/java/com/crm/dict/DictApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) ## 架构总览 下图展示模块间依赖与请求流转:应用入口聚合认证、文件和字典模块,各业务模块依赖基础框架的通用能力。 ```mermaid graph TB Client["客户端"] --> App["crm-app
CrmAppApplication"] App --> Auth["crm-auth
认证服务"] App --> File["crm-file
文件服务"] App --> Dict["crm-dict
数据字典"] Auth --> Base["crm-base
基础框架"] File --> Base Dict --> Base Auth --> DB["数据库"] File --> MinIO["对象存储"] File --> KK["kkFileView
预览服务"] Dict --> Cache["Caffeine
本地缓存"] ``` **图表来源** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) - [DictApplication.java](file://crm-dict/src/main/java/com/crm/dict/DictApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) ## 详细组件分析 ### 认证服务(crm-auth) - 包结构与职责 - config:安全配置、权限配置、数据初始化、属性注入。 - controller:登录、系统相关接口。 - domain:实体、DTO、枚举、参数。 - mapper:数据访问映射。 - security:JWT过滤器、令牌服务、数据权限拦截器、异常处理器。 - service:认证、用户、角色、菜单、部门等服务接口与实现;第三方登录客户端工厂与实现。 - 核心流程(登录与鉴权) ```mermaid sequenceDiagram participant C as "客户端" participant AC as "AuthController" participant AS as "IAuthService" participant TS as "TokenService" participant SEC as "JwtAuthenticationFilter" participant DS as "DataScopeInterceptor" C->>AC : "POST /auth/login" AC->>AS : "校验用户名密码" AS-->>AC : "返回用户信息" AC->>TS : "生成JWT" TS-->>AC : "返回token" AC-->>C : "返回{token, user}" C->>SEC : "携带Authorization头访问受保护接口" SEC->>SEC : "解析并校验JWT" SEC-->>C : "设置当前登录用户上下文" C->>DS : "触发数据权限拦截" DS-->>C : "根据数据范围过滤查询" ``` **图表来源** - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java) - [IAuthService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java) - [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - 第三方登录扩展 - 通过工厂模式注册不同平台客户端,新增平台只需实现接口并注册到工厂。 ```mermaid classDiagram class ThirdPartyAuthClient { + "获取第三方用户信息()" } class DingTalkAuthClient { + "获取第三方用户信息()" } class ThirdPartyAuthClientFactory { + "获取客户端(平台)" } ThirdPartyAuthClient <|-- DingTalkAuthClient ThirdPartyAuthClientFactory --> ThirdPartyAuthClient : "创建/获取" ``` **图表来源** - [ThirdPartyAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClient.java) - [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthClient.java) - [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java) - 数据权限与可见性 - 使用注解+拦截器实现数据范围控制,结合基础框架的数据可见性上下文。 ```mermaid flowchart TD Start(["进入方法"]) --> CheckAnno["检查@DataScope注解"] CheckAnno --> HasAnno{"存在注解?"} HasAnno --> |否| Proceed["直接执行"] HasAnno --> |是| BuildScope["构建数据范围SQL片段"] BuildScope --> Inject["注入到查询条件"] Inject --> Proceed Proceed --> End(["返回结果"]) ``` **图表来源** - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [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) - 领域模型与权限模型 ```mermaid classDiagram class AuthUser { + "用户基本信息" } class SysRole { + "角色信息" } class SysMenu { + "菜单信息" } class SysDept { + "部门信息" } class AuthIdentity { + "第三方身份绑定" } AuthUser --> SysRole : "多对多" SysRole --> SysMenu : "多对多" AuthUser --> SysDept : "多对多" AuthUser --> AuthIdentity : "一对多" ``` **图表来源** - [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java) - [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java) - [AuthIdentity.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthIdentity.java) **章节来源** - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java) - [SystemController.java](file://crm-auth/src/main/java/com/crm/auth/controller/SystemController.java) - [IAuthService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java) - [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java) - [IAuthUserService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthUserService.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [ISysRoleService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysRoleService.java) - [SysRoleServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysRoleServiceImpl.java) - [ISysMenuService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysMenuService.java) - [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java) - [ISysDeptService.java](file://crm-auth/src/main/java/com/crm/auth/service/ISysDeptService.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java) - [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java) - [ThirdPartyAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClient.java) - [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthClient.java) - [ThirdPartyUserInfo.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyUserInfo.java) - [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java) - [SysRole.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysRole.java) - [SysMenu.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysMenu.java) - [SysDept.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/SysDept.java) - [AuthIdentity.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthIdentity.java) - [LoginParam.java](file://crm-auth/src/main/java/com/crm/auth/domain/param/LoginParam.java) - [LoginResultDTO.java](file://crm-auth/src/main/java/com/crm/auth/domain/dto/LoginResultDTO.java) - [UserInfoDTO.java](file://crm-auth/src/main/java/com/crm/auth/domain/dto/UserInfoDTO.java) - [AuthConstants.java](file://crm-auth/src/main/java/com/crm/auth/constant/AuthConstants.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java) - [DataInitializer.java](file://crm-auth/src/main/java/com/crm/auth/config/DataInitializer.java) - [AuthProperties.java](file://crm-auth/src/main/java/com/crm/auth/config/AuthProperties.java) ### 基础框架(crm-base) - 职责概览 - 统一异常处理与错误码、统一响应体、分页封装。 - MyBatis-Plus增强(自动填充、批量插入更新、SQL注入器)。 - Redis、Jackson、Knife4j配置。 - 雪花ID生成与属性配置。 - 数据权限注解与辅助工具、登录用户上下文与安全工具。 - 通用实体基类、DTO/Param基类、工具类集合。 - 关键类与关系 ```mermaid classDiagram class GlobalExceptionHandlerAdvice { + "统一异常处理" } class Result~T~ { + "统一响应体" } class PageResult~T~ { + "分页结果" } class BaseEntity { + "公共字段" } class OwnedEntity { + "数据归属字段" } class DataScope { + "数据范围注解" } class DataScopeHelper { + "构建数据范围SQL" } class DataVisibilityContext { + "数据可见性上下文" } class LoginUser { + "登录用户信息" } class SecurityUtils { + "安全工具方法" } class BaseServiceImpl { + "基础CRUD服务实现" } class IBaseService { + "基础服务接口" } GlobalExceptionHandlerAdvice --> Result : "封装响应" BaseServiceImpl --> IBaseService : "实现" OwnedEntity --|> BaseEntity : "继承" DataScopeHelper --> DataVisibilityContext : "使用" SecurityUtils --> LoginUser : "获取上下文" ``` **图表来源** - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.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) - [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) - [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) - [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) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) **章节来源** - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.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) - [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) - [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [CommonConstants.java](file://crm-base/src/main/java/com/crm/base/constant/CommonConstants.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) - [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) - [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) - [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) - [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) - [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) - [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) ### 文件服务(crm-file) - 包结构与职责 - api:对外API抽象。 - config:MinIO、调度任务、文件属性配置。 - controller:文件上传、下载、预览接口。 - domain:文件元信息实体、DTO、上传会话。 - mapper:文件元信息持久化。 - service:文件API实现、文件信息服务、kkFileView客户端。 - task:定时清理孤儿分片。 - 上传流程(分片) ```mermaid sequenceDiagram participant C as "客户端" participant FC as "FileController" participant FA as "FileApi" participant FS as "FileInfoServiceImpl" participant MINIO as "MinIO" participant KK as "kkFileView" C->>FC : "发起分片上传初始化" FC->>FA : "创建上传会话" FA->>FS : "记录会话/分片索引" FS-->>FA : "返回会话ID" FA-->>C : "返回会话ID" loop "分片上传" C->>FC : "上传分片(chunk)" FC->>FS : "保存分片到临时目录/MinIO" FS-->>FC : "确认分片完成" end C->>FC : "合并分片" FC->>FS : "合并并生成文件元信息" FS->>MINIO : "最终文件落盘" FS-->>FC : "返回文件信息" C->>KK : "请求预览链接" KK-->>C : "返回预览地址" ``` **图表来源** - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java) - [FileApi.java](file://crm-file/src/main/java/com/crm/file/api/FileApi.java) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [IFileInfoService.java](file://crm-file/src/main/java/com/crm/file/service/IFileInfoService.java) - [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) **章节来源** - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java) - [FileApi.java](file://crm-file/src/main/java/com/crm/file/api/FileApi.java) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [IFileInfoService.java](file://crm-file/src/main/java/com/crm/file/service/IFileInfoService.java) - [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java) - [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java) - [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java) - [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java) ### 数据字典(crm-dict) - 包结构与职责 - config:内置字典初始化、权限初始化。 - constant:常量定义、权限码、错误码。 - controller:分组和字典项的管理接口。 - domain:实体(分组、字典项、默认项、引用计数)、DTO、参数。 - mapper:数据访问映射。 - service:分组服务、字典项服务、查询服务、引用服务。 - 核心特性 - 两级平铺结构:分组(第一级)→ 字典项(第二级) - 内置字典保护:builtin=true的字典不可删除,支持幂等初始化 - 引用计数机制:跟踪字典项被业务数据引用的次数 - 本地缓存:Caffeine缓存,10秒TTL,空结果2秒防穿透 - 软删除复用键:delete_key=id,支持编码复用 - **VO设计优化**:明确区分内部实体模型和外部API契约,体现更好的分层架构设计 - **DictGroupVO**:分页列表展示专用视图对象,仅暴露前端需要的业务字段 + createTime,排除审计字段和软删内部字段 - **DictItemVO**:分页列表展示专用视图对象,包含实时引用计数(referenced)和有效可选标记(effectiveSelectable) - **设计原则**:VO独立字段(不继承实体),只暴露必要的业务字段,避免泄露内部实现细节 - 数据模型关系 ```mermaid classDiagram class DictGroup { + "分组名称" + "分组编码(全局唯一)" + "状态" + "排序号" + "内置标记" + "描述" } class DictItem { + "所属分组ID" + "字典名称" + "字典编码(组内唯一)" + "字典值(同组唯一)" + "状态" + "排序号" + "内置标记" + "描述" } class DictGroupDefault { + "分组ID" + "字典项ID" } class DictRefCount { + "分组编码" + "字典编码" + "引用计数" } class DictGroupVO { + "分组业务字段" + "createTime" + "itemCount" } class DictItemVO { + "字典项业务字段" + "groupName" + "isDefault" + "referenced" + "effectiveSelectable" } DictGroup --> DictItem : "一对多" DictGroup --> DictGroupDefault : "一对一" DictItem --> DictGroupDefault : "一对一" DictItem --> DictRefCount : "一对一" DictGroup --> DictGroupVO : "转换" DictItem --> DictItemVO : "转换" ``` **图表来源** - [DictGroup.java:17-51](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictGroup.java#L17-L51) - [DictItem.java:17-61](file://crm-dict/src/main/java/com/crm/dict/domain/entity/DictItem.java#L17-L61) - [DictGroupVO.java:14-34](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictGroupVO.java#L14-L34) - [DictItemVO.java:16-49](file://crm-dict/src/main/java/com/crm/dict/domain/dto/DictItemVO.java#L16-L49) - 内置字典初始化流程 ```mermaid sequenceDiagram participant INIT as "DictDataInitializer" participant GROUP as "DictGroupMapper" participant ITEM as "DictItemMapper" participant DEFAULT as "DictGroupDefaultMapper" INIT->>INIT : "验证种子数据合法性" loop "遍历种子分组" INIT->>GROUP : "upsert分组(仅内置)" GROUP-->>INIT : "返回或创建分组" loop "遍历分组下的字典项" INIT->>ITEM : "upsert字典项(仅内置)" ITEM-->>INIT : "返回或创建字典项" INIT->>DEFAULT : "设置默认项(仅当无默认时)" DEFAULT-->>INIT : "完成默认设置" end end INIT-->>INIT : "初始化完成" ``` **图表来源** - [DictDataInitializer.java:70-94](file://crm-dict/src/main/java/com/crm/dict/config/DictDataInitializer.java#L70-L94) - [DictDataInitializer.java:141-236](file://crm-dict/src/main/java/com/crm/dict/config/DictDataInitializer.java#L141-L236) - 字典查询缓存机制 ```mermaid flowchart TD A["查询请求"] --> B{"缓存命中?"} B --> |是| C["返回缓存数据"] B --> |否| D["查询数据库"] D --> E{"有结果?"} E --> |是| F["写入缓存(10s TTL)"] F --> G["返回数据"] E --> |否| H["写入空缓存(2s TTL)"] H --> I["返回null"] ``` **图表来源** - [DictQueryService.java:7-31](file://crm-dict/src/main/java/com/crm/dict/service/DictQueryService.java#L7-L31) - [DictConstants.java:24-30](file://crm-dict/src/main/java/com/crm/dict/constant/DictConstants.java#L24-L30) **章节来源** - [DictApplication.java](file://crm-dict/src/main/java/com/crm/dict/DictApplication.java) - [pom.xml](file://crm-dict/pom.xml) - [CONTEXT.md](file://crm-dict/CONTEXT.md) - [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) - [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) - [DictQueryService.java](file://crm-dict/src/main/java/com/crm/dict/service/DictQueryService.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) - [DictDataInitializer.java](file://crm-dict/src/main/java/com/crm/dict/config/DictDataInitializer.java) - [DictConstants.java](file://crm-dict/src/main/java/com/crm/dict/constant/DictConstants.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) ### 应用入口(crm-app) - 职责:聚合模块、加载配置文件、启动Spring Boot应用。 - 关键点:确保扫描到各模块的包路径,正确引入依赖。 **章节来源** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) ## 依赖关系分析 - 模块依赖 - crm-app 依赖 crm-auth、crm-file、crm-dict。 - crm-auth、crm-file、crm-dict 均依赖 crm-base。 - crm-dict 仅依赖 crm-base,不依赖 crm-auth(通过权限码字符串契约解耦)。 - 运行时依赖 - crm-auth 依赖数据库(MyBatis-Plus)、Redis(可选用于缓存)、JWT库。 - crm-file 依赖对象存储(MinIO)、外部预览服务(kkFileView)。 - crm-dict 依赖数据库(MyBatis-Plus)、Caffeine本地缓存。 - 内部通信 - 通过REST API暴露接口,模块间通过Spring Bean注入协作。 - 认证模块通过安全上下文传递登录用户信息,供其他模块读取。 - 数据字典模块通过权限码字符串与认证模块解耦耦合。 ```mermaid graph LR APP["crm-app"] --> AUTH["crm-auth"] APP --> FILE["crm-file"] APP --> DICT["crm-dict"] AUTH --> BASE["crm-base"] FILE --> BASE DICT --> BASE AUTH --> DB["数据库"] FILE --> MINIO["MinIO"] FILE --> KK["kkFileView"] DICT --> CACHE["Caffeine缓存"] ``` **图表来源** - [pom.xml:21-28](file://pom.xml#L21-L28) - [pom.xml:48-74](file://pom.xml#L48-L74) - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) - [DictApplication.java](file://crm-dict/src/main/java/com/crm/dict/DictApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) **章节来源** - [pom.xml:21-28](file://pom.xml#L21-L28) - [pom.xml:48-74](file://pom.xml#L48-L74) - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) - [DictApplication.java](file://crm-dict/src/main/java/com/crm/dict/DictApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) ## 性能考虑 - 认证模块 - JWT无状态校验,减少服务端状态压力;合理设置过期时间。 - 数据权限SQL片段在拦截器中动态注入,避免全表扫描;建议为常用查询字段建立索引。 - 基础框架 - 分页使用PageResult封装,避免一次性拉取大量数据。 - 批量插入更新使用InsertBatchOnDuplicateKeyUpdate提升写入性能。 - 雪花ID分布式唯一,降低热点冲突。 - 文件服务 - 分片上传提升大文件稳定性与并发;合并后落盘MinIO,减轻本地磁盘压力。 - 定时清理孤儿分片,防止存储空间泄漏。 - 预览通过kkFileView异步或直链方式,避免阻塞主线程。 - 数据字典模块 - Caffeine本地缓存:10秒正结果缓存 + 2秒空结果防穿透,大幅降低数据库压力。 - 软删除复用键:支持编码无限次删除重建,避免主键冲突。 - 引用计数机制:O(1)复杂度判断是否可删除,避免复杂关联查询。 - 内置字典幂等初始化:部署时快速完成种子数据导入,支持Excel替换。 - **VO设计优化**:通过独立的VO对象减少数据传输冗余,提高序列化性能,避免泄露内部实现细节。 ## 故障排查指南 - 认证相关问题 - 登录失败:检查用户名密码、账号状态、第三方回调配置。 - 权限不足:检查角色-菜单授权、数据范围注解是否生效。 - JWT失效:检查TokenService配置、过期策略、客户端是否正确携带Authorization头。 - 文件相关问题 - 上传失败:检查MinIO连接、分片大小限制、临时目录权限。 - 预览失败:检查kkFileView服务可达性与配置。 - 空间占用异常:检查OrphanChunkCleanupTask是否正常运行。 - 数据字典相关问题 - 内置字典无法修改:检查builtin标记,内置字典只允许改名、改描述、调排序、启停用。 - 字典项无法删除:检查引用计数是否为0,或被引用后字典值是否被修改。 - 缓存不一致:等待10秒TTL过期,或重启服务刷新缓存。 - 初始化失败:检查种子数据合法性,查看控制台日志中的fail-fast错误信息。 - VO数据不完整:检查服务层的toDTO转换逻辑,确保必要字段已正确映射。 - 基础框架问题 - 统一异常未捕获:检查GlobalExceptionHandlerAdvice是否生效。 - 分页异常:检查PageConverter与前端分页参数一致性。 - 审计字段缺失:检查MetaObjectFillHandler是否启用。 **章节来源** - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) - [DictDataInitializer.java:96-137](file://crm-dict/src/main/java/com/crm/dict/config/DictDataInitializer.java#L96-L137) - [DictItemServiceImpl.java:218-238](file://crm-dict/src/main/java/com/crm/dict/service/impl/DictItemServiceImpl.java#L218-L238) ## 结论 本CRM后端采用清晰的多模块架构,认证、文件、数据字典与基础框架职责边界明确,具备良好的可扩展性与可维护性。通过统一的异常处理、分页、数据权限与工具集,开发者可以快速构建业务功能。新增的数据字典模块提供了稳定的键值管理能力,支持内置字典保护和引用计数机制。**特别是VO设计的优化,通过明确区分内部实体模型和外部API契约,体现了更好的分层架构设计,提高了系统的可维护性和安全性**。建议在新增第三方登录、文件存储或业务字典时,遵循现有扩展点与配置约定,保持模块内聚与低耦合。 ## 附录:配置与扩展点 - 认证模块配置 - 安全配置:SecurityConfig、PermissionConfig。 - 数据初始化:DataInitializer。 - 属性注入:AuthProperties。 - 扩展点:新增第三方登录需实现ThirdPartyAuthClient并注册到ThirdPartyAuthClientFactory。 - 基础框架配置 - MyBatis-Plus:MybatisPlusConfig、CrmSqlInjector、MetaObjectFillHandler、InsertBatchOnDuplicateKeyUpdate。 - 缓存与序列化:RedisConfig、JacksonConfig。 - API文档:Knife4jConfig。 - ID生成:CustomIdGenerator、SnowflakeIdWorker、SnowflakeProperties。 - 数据权限:DataScope注解、DataScopeHelper、DataVisibilityContext。 - 文件服务配置 - 对象存储:MinioConfig。 - 调度任务:SchedulingConfig、OrphanChunkCleanupTask。 - 文件属性:FileProperties。 - 预览服务:KkFileViewClient。 - 数据字典模块配置 - 内置字典初始化:DictDataInitializer,支持Excel替换口。 - 权限初始化:DictPermissionInitializer,将权限点注入权限资源树。 - 缓存配置:Caffeine本地缓存,10秒TTL,空结果2秒防穿透。 - 权限码常量:DictConstants中定义的dict:*权限点。 - 扩展点:新增内置字典可通过SEED_GROUPS列表或Excel文件扩展。 - **VO设计扩展**:新增VO时应遵循独立字段原则,仅暴露必要的业务字段,避免继承实体类。 - 应用入口配置 - 统一启动:CrmAppApplication。 - 应用配置:application.yml。 **章节来源** - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java) - [DataInitializer.java](file://crm-auth/src/main/java/com/crm/auth/config/DataInitializer.java) - [AuthProperties.java](file://crm-auth/src/main/java/com/crm/auth/config/AuthProperties.java) - [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java) - [ThirdPartyAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClient.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) - [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) - [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) - [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) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.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) - [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) - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml)