You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

495 lines
26 KiB

1 month ago
# 架构设计
<cite>
**本文引用的文件**
- [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)
1 month ago
- [ThirdPartyUserInfo.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyUserInfo.java)
1 month ago
- [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 month ago
- [0009-sso-reuses-scan-login-endpoint.md](file://docs/adr/0009-sso-reuses-scan-login-endpoint.md)
1 month ago
</cite>
1 month ago
## 更新摘要
**所做更改**
- 更新了第三方集成模式章节,详细说明单点登录端点复用决策
- 新增了SSO架构设计说明,解释钉钉免登与扫码登录的统一处理机制
- 更新了认证流程图,展示两种登录方式的统一处理路径
- 增强了扩展性设计说明,包含未来JS-SDK支持的规划
1 month ago
## 目录
1. [引言](#引言)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 引言
本架构设计文档面向架构师与高级开发者,围绕CRM系统的微服务划分、分层设计原则、组件交互关系与数据流向展开。重点阐述安全架构(认证授权、数据权限)、数据访问层(MyBatis-Plus、分布式ID)、缓存策略(Redis、部门树缓存)、文件存储方案(分片上传、对象存储、在线预览)等关键技术决策。同时给出系统边界定义、第三方集成模式与扩展点设计,并提供架构图表以说明模块间的依赖关系与通信机制。
1 month ago
**更新** 本次更新重点阐述了单点登录(SSO)的架构决策,特别是钉钉免登录场景下复用现有扫码登录端点的设计模式,消除了冗余代码的同时支持多种登录方式。
1 month ago
## 项目结构
本项目采用多模块Maven工程,按领域与服务进行拆分:
- crm-app:应用启动入口与全局配置聚合
- crm-base:公共基础能力(统一异常、通用实体、安全工具、MyBatis-Plus与Redis配置、分布式ID生成等)
- crm-auth:认证授权与系统管理域(用户、角色、菜单、部门、数据权限、第三方登录)
- crm-file:文件服务(分片上传、断点续传、对象存储、在线预览、清理任务)
```mermaid
graph TB
subgraph "应用层"
APP["crm-app<br/>应用启动"]
end
subgraph "基础能力"
BASE["crm-base<br/>通用配置/安全/工具"]
end
subgraph "业务服务"
AUTH["crm-auth<br/>认证与系统管理"]
FILE["crm-file<br/>文件服务"]
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:雪花算法实现
- 文件服务:分片上传、断点续传、对象存储、在线预览、定时清理
1 month ago
- 第三方认证:工厂模式抽象、统一用户信息模型、组织准入校验
1 month ago
章节来源
- [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)
1 month ago
- [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java)
- [ThirdPartyUserInfo.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyUserInfo.java)
1 month ago
## 架构总览
1 month ago
系统采用"网关/应用聚合 + 领域微服务"的分层与解耦模式:
1 month ago
- 应用层:统一入口与跨服务编排
- 领域服务:认证授权、文件服务等独立部署
- 基础能力:被各服务复用,保证一致性与可维护性
```mermaid
graph TB
Client["客户端"] --> API["API层<br/>控制器"]
API --> SVC["服务层<br/>业务编排"]
SVC --> SEC["安全层<br/>鉴权/数据权限"]
SVC --> DB["数据访问层<br/>MyBatis-Plus"]
SVC --> CACHE["缓存层<br/>Redis"]
SVC --> EXT["外部集成<br/>第三方登录/文件预览"]
DB --> DS["数据库"]
CACHE --> RC["Redis集群"]
EXT --> OSS["对象存储"]
EXT --> VIEW["在线预览服务"]
1 month ago
EXT --> THIRD["第三方平台<br/>钉钉OAuth"]
1 month ago
```
图表来源
- [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注入器动态拼接数据可见性条件
- 第三方登录:通过工厂模式扩展不同平台(如钉钉),统一抽象为第三方认证客户端
1 month ago
**更新** 单点登录(SSO)采用端点复用策略,钉钉免登录与扫码登录共用同一接口,简化了架构设计。
1 month ago
```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标准化第三方用户信息
- 可扩展:新增平台只需实现客户端接口并注册到工厂
1 month ago
- **单点登录优化**:钉钉免登录复用现有扫码登录端点,消除冗余代码
**更新** 单点登录(SSO)架构采用了端点复用策略,钉钉免登录与扫码登录共用 `POST /api/auth/login/dingtalk` 接口。这种设计避免了为免登录场景创建独立的SSO端点,因为两种场景的authCode都通过钉钉 `oauth2/userAccessToken` API换取用户级accessToken,后端处理逻辑完全一致。
```mermaid
sequenceDiagram
participant Browser as "浏览器"
participant DingTalk as "钉钉平台"
participant CRM as "CRM后端"
participant Auth as "认证服务"
participant Client as "钉钉客户端"
Note over Browser,DingTalk : 扫码登录流程
Browser->>DingTalk : "打开扫码页面"
DingTalk-->>Browser : "返回二维码"
Browser->>DingTalk : "用户扫码确认"
DingTalk-->>Browser : "返回authCode"
Browser->>CRM : "POST /api/auth/login/dingtalk?authCode=xxx"
CRM->>Auth : "调用登录服务"
Auth->>Client : "getUserInfo(authCode)"
Client->>DingTalk : "换取accessToken"
DingTalk-->>Client : "返回accessToken"
Client->>DingTalk : "查询用户信息"
DingTalk-->>Client : "返回用户信息"
Client-->>Auth : "返回ThirdPartyUserInfo"
Auth->>Auth : "用户匹配/注册/绑定身份"
Auth-->>CRM : "返回登录结果"
CRM-->>Browser : "返回JWT Token"
Note over Browser,DingTalk : 免登录流程复用同一端点
Browser->>DingTalk : "已登录态访问CRM"
DingTalk-->>Browser : "自动重定向带authCode"
Browser->>CRM : "POST /api/auth/login/dingtalk?authCode=xxx"
Note over CRM : "处理逻辑与扫码登录完全相同"
```
图表来源
- [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.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)
- [0009-sso-reuses-scan-login-endpoint.md](file://docs/adr/0009-sso-reuses-scan-login-endpoint.md)
章节来源
- [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)
- [ThirdPartyUserInfo.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyUserInfo.java)
- [0009-sso-reuses-scan-login-endpoint.md](file://docs/adr/0009-sso-reuses-scan-login-endpoint.md)
### 单点登录架构设计
**新增** 基于ADR-0009的决策,系统采用了统一的第三方认证架构:
- **端点复用策略**:钉钉免登录与扫码登录共用 `POST /api/auth/login/dingtalk` 接口
- **统一处理逻辑**:两种场景的authCode都通过相同的钉钉API换取用户级accessToken
- **零后端改动**:前端自行管理OAuth重定向URL和clientId,后端无需区分登录来源
- **扩展性考虑**:未来如需支持钉钉桌面客户端内H5免登(JS-SDK),需新增签名端点
1 month ago
```mermaid
classDiagram
1 month ago
class ThirdPartyAuthClient {
<<interface>>
+getType() IdentityTypeEnum
+getUserInfo(authCode) ThirdPartyUserInfo
+isOrgMember(user) boolean
1 month ago
}
class DingTalkAuthClient {
1 month ago
+fetchUserAccessToken(code) String
+fetchUserInfo(token) ThirdPartyUserInfo
+getCorpAccessToken() String
+requestTokenApi(code) String
+requestUserInfoApi(token) String
+requestCorpTokenApi() String
+requestGetByUnionIdApi(token, unionId) String
1 month ago
}
1 month ago
class ThirdPartyAuthClientFactory {
+getClient(type) ThirdPartyAuthClient
}
class AuthServiceImpl {
+login(type, authCode) LoginResultDTO
+doLoginInTx(type, thirdUser) AuthUser
+preCheckOrgMembership(type, user, client) void
1 month ago
}
1 month ago
ThirdPartyAuthClient <|.. DingTalkAuthClient
ThirdPartyAuthClientFactory --> ThirdPartyAuthClient
AuthServiceImpl --> ThirdPartyAuthClientFactory
1 month ago
```
图表来源
- [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthClient.java)
1 month ago
- [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java)
- [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java)
1 month ago
章节来源
- [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthClient.java)
1 month ago
- [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java)
- [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java)
- [0009-sso-reuses-scan-login-endpoint.md](file://docs/adr/0009-sso-reuses-scan-login-endpoint.md)
1 month ago
## 依赖关系分析
- 模块耦合: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无状态减少会话存储压力;敏感操作加限流与幂等保护
1 month ago
- **第三方调用优化**:钉钉企业级token缓存、组织准入校验事务外执行,避免长时间占用数据库连接
1 month ago
[本节为通用指导,不直接分析具体文件]
## 故障排查指南
- 统一异常处理:GlobalExceptionHandlerAdvice集中捕获业务与系统异常,返回标准错误码与消息
- 常见错误定位:检查日志中的TraceId;核对Redis连接与对象存储配置;确认JWT签名与过期时间
- 数据权限问题:核查@DataScope注解与上下文是否正确设置;检查SQL注入器是否生效
- 文件上传失败:查看分片完整性与合并任务;确认对象存储桶权限与网络连通性
1 month ago
- **第三方登录问题**:检查钉钉配置(client-id/secret)、网络连通性、token缓存状态、组织准入校验结果
1 month ago
章节来源
- [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)
## 结论
1 month ago
本架构以清晰的模块边界与分层设计为基础,通过安全、数据访问、缓存与文件服务的专项设计,满足CRM系统在认证授权、数据权限、高可用与可扩展方面的需求。**特别地,单点登录架构通过端点复用策略实现了简洁高效的第三方认证处理**。未来可在网关层引入更细粒度的路由与限流,在服务间引入事件总线以提升异步处理能力,并持续完善监控与可观测性体系。
1 month ago
[本节为总结性内容,不直接分析具体文件]
## 附录
- 系统边界定义:认证与系统管理(crm-auth)、文件服务(crm-file)、基础能力(crm-base)、应用聚合(crm-app)
- 扩展点设计:第三方登录客户端工厂、数据权限注解、文件上传处理器、缓存项命名规范
- 配置要点:跨域、Jackson序列化、Knife4j文档、定时任务属性、雪花ID参数
1 month ago
- **SSO设计决策**:钉钉免登录复用扫码登录端点,消除冗余代码,支持未来JS-SDK扩展
1 month ago
[本节为补充信息,不直接分析具体文件]