# 架构设计
**本文引用的文件**
- [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)
- [pom.xml](file://pom.xml)
- [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)
- [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.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)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.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)
- [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)
- [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)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java)
- [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java)
- [AuthService.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)
- [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java)
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
- [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java)
- [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthClient.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)
- [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java)
- [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
## 目录
1. [引言](#引言)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 引言
本架构设计文档面向架构师与高级开发者,围绕CRM系统的微服务划分、分层设计原则、组件交互关系与数据流向展开。重点阐述安全架构(认证授权、数据权限)、数据访问层(MyBatis-Plus、分布式ID)、缓存策略(Redis、部门树缓存)、文件存储方案(分片上传、对象存储、在线预览)等关键技术决策。同时给出系统边界定义、第三方集成模式与扩展点设计,并提供架构图表以说明模块间的依赖关系与通信机制。
## 项目结构
本项目采用多模块Maven工程,按领域与服务进行拆分:
- crm-app:应用启动入口与全局配置聚合
- crm-base:公共基础能力(统一异常、通用实体、安全工具、MyBatis-Plus与Redis配置、分布式ID生成等)
- crm-auth:认证授权与系统管理域(用户、角色、菜单、部门、数据权限、第三方登录)
- crm-file:文件服务(分片上传、断点续传、对象存储、在线预览、清理任务)
```mermaid
graph TB
subgraph "应用层"
APP["crm-app
应用启动"]
end
subgraph "基础能力"
BASE["crm-base
通用配置/安全/工具"]
end
subgraph "业务服务"
AUTH["crm-auth
认证与系统管理"]
FILE["crm-file
文件服务"]
end
APP --> AUTH
APP --> FILE
AUTH --> BASE
FILE --> BASE
```
图表来源
- [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)
- [pom.xml](file://pom.xml)
章节来源
- [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)
- [pom.xml](file://pom.xml)
## 核心组件
- 统一响应与分页:Result、PageResult
- 通用实体:BaseEntity、OwnedEntity(支持审计字段与数据归属)
- 安全上下文:LoginUser、SecurityUtils、DataVisibilityContext
- 数据权限:@DataScope注解、DataScopeHelper、拦截器与SQL注入器
- MyBatis-Plus:CRUD增强、自动填充、分页插件
- Redis:缓存与分布式会话支撑
- 分布式ID:雪花算法实现
- 文件服务:分片上传、断点续传、对象存储、在线预览、定时清理
章节来源
- [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)
- [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)
- [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.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)
- [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)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
## 架构总览
系统采用“网关/应用聚合 + 领域微服务”的分层与解耦模式:
- 应用层:统一入口与跨服务编排
- 领域服务:认证授权、文件服务等独立部署
- 基础能力:被各服务复用,保证一致性与可维护性
```mermaid
graph TB
Client["客户端"] --> API["API层
控制器"]
API --> SVC["服务层
业务编排"]
SVC --> SEC["安全层
鉴权/数据权限"]
SVC --> DB["数据访问层
MyBatis-Plus"]
SVC --> CACHE["缓存层
Redis"]
SVC --> EXT["外部集成
第三方登录/文件预览"]
DB --> DS["数据库"]
CACHE --> RC["Redis集群"]
EXT --> OSS["对象存储"]
EXT --> VIEW["在线预览服务"]
```
图表来源
- [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java)
- [AuthService.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)
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
- [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)
- [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java)
## 详细组件分析
### 认证与安全架构
- 认证流程:客户端提交凭证 → 过滤器校验JWT → 构建登录用户上下文 → 控制器调用服务层完成登录逻辑 → 返回令牌与用户信息
- 授权与数据权限:基于角色的菜单权限与基于注解的数据范围控制,结合SQL注入器动态拼接数据可见性条件
- 第三方登录:通过工厂模式扩展不同平台(如钉钉),统一抽象为第三方认证客户端
```mermaid
sequenceDiagram
participant C as "客户端"
participant F as "JwtAuthenticationFilter"
participant A as "AuthController"
participant S as "AuthServiceImpl"
participant T as "TokenService"
participant R as "Redis"
C->>F : "携带JWT请求"
F->>F : "解析并验证Token"
F-->>A : "放行并注入Security上下文"
A->>S : "登录/刷新Token"
S->>T : "生成/更新Token"
T->>R : "写入会话/黑名单"
T-->>S : "返回Token"
S-->>A : "返回结果"
A-->>C : "统一响应Result"
```
图表来源
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
- [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java)
- [AuthService.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)
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
章节来源
- [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java)
- [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java)
- [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java)
- [AuthService.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)
- [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java)
#### 数据权限模型
- 注解驱动:@DataScope标注方法或类,声明数据范围级别
- 执行期处理:DataScopeHelper解析当前用户与范围,动态注入SQL过滤条件
- 上下文隔离:DataVisibilityContext在请求链路中传递可见性参数
```mermaid
classDiagram
class DataScope {
+注解 : 声明数据范围
}
class DataScopeHelper {
+解析范围()
+注入SQL条件()
}
class DataVisibilityContext {
+设置可见性()
+获取可见性()
}
DataScopeHelper --> DataVisibilityContext : "读写上下文"
```
图表来源
- [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)
章节来源
- [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)
### 数据访问层设计
- ORM框架:MyBatis-Plus提供CRUD增强、分页、自动填充、条件构造器
- 分布式ID:SnowflakeIdWorker生成唯一主键,避免冲突
- 通用基类:BaseEntity统一审计字段,OwnedEntity扩展数据归属字段
- 配置:注册MetaObjectFillHandler、分页插件、自定义SQL注入器
```mermaid
flowchart TD
Start(["进入查询"]) --> BuildQuery["构建查询条件"]
BuildQuery --> ApplyScope["应用数据权限条件"]
ApplyScope --> Execute["执行SQL(分页/排序)"]
Execute --> MapEntity["映射到实体(BaseEntity/OwenedEntity)"]
MapEntity --> Return["返回结果集"]
```
图表来源
- [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java)
- [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java)
- [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java)
章节来源
- [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java)
- [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.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)
### 缓存策略
- 部门树缓存:将部门层级结构缓存至Redis,降低频繁查询压力
- 会话与令牌:TokenService使用Redis维护会话状态与黑名单
- 通用缓存:RedisConfig提供连接池、序列化等基础能力
```mermaid
sequenceDiagram
participant S as "服务层"
participant D as "DeptTreeCache"
participant R as "Redis"
S->>D : "获取部门树"
D->>R : "读取缓存"
alt "命中"
R-->>D : "返回缓存数据"
D-->>S : "直接返回"
else "未命中"
D->>D : "查询数据库构建树"
D->>R : "写入缓存"
D-->>S : "返回数据"
end
```
图表来源
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
章节来源
- [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)
- [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java)
### 文件存储方案
- 分片上传:前端分片、服务端合并、断点续传与会话管理
- 对象存储:MinIO作为底层存储,统一文件元数据与下载接口
- 在线预览:KkFileViewClient对接预览服务,返回预览链接
- 清理任务:定时扫描孤儿分片,释放存储空间
```mermaid
sequenceDiagram
participant FE as "前端"
participant FC as "FileController"
participant FA as "FileApiImpl"
participant FS as "FileInfoServiceImpl"
participant OSS as "对象存储"
participant PV as "预览服务"
FE->>FC : "发起分片上传"
FC->>FA : "初始化上传会话"
FA->>FS : "创建/更新分片记录"
loop "分片传输"
FE->>FC : "上传分片"
FC->>FA : "保存分片到OSS"
FA->>FS : "更新分片状态"
end
FE->>FC : "触发合并"
FC->>FA : "合并分片并生成文件信息"
FA->>PV : "生成预览链接"
FA-->>FE : "返回文件信息与预览地址"
```
图表来源
- [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)
- [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.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)
- [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
### 第三方集成模式
- 工厂模式:ThirdPartyAuthClientFactory根据类型选择具体客户端
- 统一抽象:ThirdPartyUserInfo标准化第三方用户信息
- 可扩展:新增平台只需实现客户端接口并注册到工厂
```mermaid
classDiagram
class ThirdPartyAuthClientFactory {
+getClient(type) ThirdPartyAuthClient
}
class DingTalkAuthClient {
+login(code) ThirdPartyUserInfo
}
class ThirdPartyAuthClient {
<>
+login(code) ThirdPartyUserInfo
}
ThirdPartyAuthClientFactory --> ThirdPartyAuthClient : "创建实例"
DingTalkAuthClient ..|> ThirdPartyAuthClient
```
图表来源
- [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.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)
- [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthClient.java)
## 依赖关系分析
- 模块耦合:crm-app仅负责启动与聚合;crm-auth与crm-file均依赖crm-base
- 内部依赖:auth服务内service→mapper→entity的单向依赖;file服务内controller→api→service→mapper
- 外部依赖:Redis、对象存储、第三方登录平台
```mermaid
graph LR
APP["crm-app"] --> AUTH["crm-auth"]
APP --> FILE["crm-file"]
AUTH --> BASE["crm-base"]
FILE --> BASE
AUTH --> REDIS["Redis"]
FILE --> OSS["对象存储"]
AUTH --> THIRD["第三方登录平台"]
```
图表来源
- [pom.xml](file://pom.xml)
- [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)
章节来源
- [pom.xml](file://pom.xml)
- [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)
## 性能考量
- 数据访问优化:合理使用分页、索引与条件构造器,避免全表扫描;利用MyBatis-Plus批量操作减少往返
- 缓存策略:热点数据(如部门树、字典)优先缓存;注意缓存穿透、雪崩与一致性策略
- 分布式ID:雪花算法避免中心节点瓶颈,提升写入吞吐
- 文件上传:分片并发上传与断点续传提升大文件体验;合并后及时清理临时分片
- 安全开销:JWT无状态减少会话存储压力;敏感操作加限流与幂等保护
[本节为通用指导,不直接分析具体文件]
## 故障排查指南
- 统一异常处理:GlobalExceptionHandlerAdvice集中捕获业务与系统异常,返回标准错误码与消息
- 常见错误定位:检查日志中的TraceId;核对Redis连接与对象存储配置;确认JWT签名与过期时间
- 数据权限问题:核查@DataScope注解与上下文是否正确设置;检查SQL注入器是否生效
- 文件上传失败:查看分片完整性与合并任务;确认对象存储桶权限与网络连通性
章节来源
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [application.yml](file://crm-app/src/main/resources/application.yml)
- [application.yml](file://crm-auth/src/main/resources/application.yml)
## 结论
本架构以清晰的模块边界与分层设计为基础,通过安全、数据访问、缓存与文件服务的专项设计,满足CRM系统在认证授权、数据权限、高可用与可扩展方面的需求。未来可在网关层引入更细粒度的路由与限流,在服务间引入事件总线以提升异步处理能力,并持续完善监控与可观测性体系。
[本节为总结性内容,不直接分析具体文件]
## 附录
- 系统边界定义:认证与系统管理(crm-auth)、文件服务(crm-file)、基础能力(crm-base)、应用聚合(crm-app)
- 扩展点设计:第三方登录客户端工厂、数据权限注解、文件上传处理器、缓存项命名规范
- 配置要点:跨域、Jackson序列化、Knife4j文档、定时任务属性、雪花ID参数
[本节为补充信息,不直接分析具体文件]