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.
29 KiB
29 KiB
API参考文档
**本文档引用的文件** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [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) - [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) - [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) - [AuthLoginUser.java](file://crm-auth/src/main/java/com/crm/auth/security/AuthLoginUser.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) - [AuthService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [SysMenuServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysMenuServiceImpl.java) - [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) - [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java) - [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java) - [CommonConstants.java](file://crm-base/src/main/java/com/crm/base/constant/CommonConstants.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) - [FileInfoService.java](file://crm-file/src/main/java/com/crm/file/service/IFileInfoService.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.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) - [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java) - [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java) - [ThumbnailDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/ThumbnailDTO.java) - [ThumbnailPlaceholderService.java](file://crm-file/src/main/java/com/crm/file/service/ThumbnailPlaceholderService.java) - [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java)更新摘要
变更内容
- 新增缩略图获取API端点
/api/file/thumbnail的详细文档 - 添加缩略图生成功能的完整说明
- 更新文件服务模块的API清单
- 补充缩略图相关的错误处理和状态码说明
目录
简介
本API参考文档面向前端开发者,系统化梳理认证鉴权、系统管理、文件上传下载等模块的RESTful接口规范。内容覆盖HTTP方法、URL路径、请求参数、响应格式、状态码与错误信息;明确认证方式(JWT)、多部分表单上传流程、权限控制要求;提供完整请求/响应示例、参数校验规则与业务约束,并附带接口测试用例与常见问题解答,帮助快速集成与排障。
项目结构
本项目采用多模块架构:
- crm-app:应用启动入口与全局配置
- crm-auth:认证鉴权与系统管理(用户、角色、菜单、部门)
- crm-base:通用基础能力(统一响应、异常处理、安全上下文、分页等)
- crm-file:文件服务(分片上传、断点续传、预览、下载、缩略图生成)
graph TB
subgraph "应用层"
APP["crm-app<br/>应用启动"]
end
subgraph "认证与系统管理"
AUTH["crm-auth<br/>认证/权限/系统管理"]
end
subgraph "基础能力"
BASE["crm-base<br/>通用组件/异常/结果封装"]
end
subgraph "文件服务"
FILE["crm-file<br/>文件上传/下载/预览/缩略图"]
end
APP --> AUTH
APP --> FILE
AUTH --> BASE
FILE --> BASE
图表来源
- CrmAppApplication.java
- application.yml
章节来源
- CrmAppApplication.java
- application.yml
核心组件
- 统一响应体 Result:所有接口返回统一包装,包含状态码、消息与数据体
- 分页 PageResult:标准分页数据结构
- 全局异常 GlobalExceptionHandlerAdvice:统一捕获业务异常、参数校验异常、权限异常等,输出标准化错误
- 安全上下文 LoginUser/AuthLoginUser:当前登录用户信息与权限范围
- TokenService:JWT签发、解析、刷新与黑名单管理
- JwtAuthenticationFilter:请求级JWT校验与上下文注入
- FileApi/FileApiImpl:文件上传下载、分片、预览、清理、缩略图生成等能力抽象与实现
- FileInfoService:文件元数据持久化与查询
- ThumbnailGenerationTask:异步缩略图生成任务
- ThumbnailPlaceholderService:动态生成文件类型占位图
章节来源
- Result.java
- PageResult.java
- GlobalExceptionHandlerAdvice.java
- AuthLoginUser.java
- TokenService.java
- JwtAuthenticationFilter.java
- FileApi.java
- FileApiImpl.java
- FileInfoService.java
- ThumbnailGenerationTask.java
- ThumbnailPlaceholderService.java
架构总览
整体调用链路:客户端通过HTTP访问Controller,Controller调用Service完成业务逻辑,Service通过Mapper访问数据库或调用外部存储(如MinIO)。认证流程由Spring Security过滤器链拦截,基于JWT进行鉴权;权限控制通过注解与数据权限拦截器实现。缩略图功能采用异步生成+同步兜底的策略,确保用户体验。
sequenceDiagram
participant Client as "客户端"
participant AuthF as "JwtAuthenticationFilter"
participant Controller as "Controller"
participant Service as "Service"
participant Task as "ThumbnailGenerationTask"
participant DB as "数据库/对象存储"
Client->>AuthF : "携带Authorization : Bearer <token>"
AuthF->>AuthF : "校验签名/过期时间"
AuthF-->>Client : "未通过则返回401"
AuthF->>Controller : "通过则注入登录用户上下文"
Controller->>Service : "执行业务方法"
alt 缩略图请求
Service->>Task : "检查缩略图状态"
alt 需要生成
Task->>DB : "异步生成缩略图"
Service-->>Client : "返回占位图或等待"
else 已有缩略图
Service->>DB : "读取缩略图"
Service-->>Client : "返回缩略图"
end
else 其他操作
Service->>DB : "读写数据/文件元信息"
DB-->>Service : "返回结果"
Service-->>Controller : "业务结果"
Controller-->>Client : "统一Result包装响应"
end
图表来源
- JwtAuthenticationFilter.java
- TokenService.java
- GlobalExceptionHandlerAdvice.java
- ThumbnailGenerationTask.java
详细组件分析
认证与鉴权模块(crm-auth)
-
认证接口
- 登录:POST /auth/login
- 请求体:LoginParam(用户名、密码、验证码/第三方授权信息等)
- 响应:LoginResultDTO(access_token、refresh_token、过期时间、用户基本信息)
- 状态码:200成功;400参数校验失败;401账号不存在或密码错误;429频繁请求
- 刷新令牌:POST /auth/refresh
- 请求体:refresh_token
- 响应:新的access_token
- 状态码:200成功;401无效或过期
- 登出:POST /auth/logout
- 行为:将token加入黑名单或失效
- 状态码:200成功;401未登录
- 登录:POST /auth/login
-
鉴权机制
- 认证方式:Bearer JWT
- 请求头:Authorization: Bearer
- 过滤器:JwtAuthenticationFilter负责解析与校验
- 权限模型:基于角色的菜单/按钮权限,支持数据权限范围(部门/个人)
-
系统管理接口(需管理员权限)
- 用户管理:CRUD /system/user/*
- 角色管理:CRUD /system/role/*
- 菜单管理:CRUD /system/menu/*
- 部门管理:CRUD /system/dept/*
- 权限校验:使用注解或拦截器,结合DataScope实现数据隔离
-
统一响应与错误
- 响应体:Result
- 错误码:ResultCodeEnum定义
- 异常处理:GlobalExceptionHandlerAdvice统一捕获并返回
classDiagram
class AuthController {
+login(param) Result~LoginResultDTO~
+refresh(token) Result~LoginResultDTO~
+logout() Result~void~
}
class IAuthService {
+login(param) LoginResultDTO
+refresh(refreshToken) LoginResultDTO
+logout(userId) void
}
class AuthUserServiceImpl {
+login(param) LoginResultDTO
+refresh(refreshToken) LoginResultDTO
+logout(userId) void
}
class TokenService {
+createToken(user) String
+parseToken(token) AuthLoginUser
+isExpired(token) boolean
+addToBlacklist(token) void
}
class JwtAuthenticationFilter {
+doFilter(request, response, chain) void
}
AuthController --> IAuthService : "调用"
IAuthService <|.. AuthUserServiceImpl : "实现"
AuthUserServiceImpl --> TokenService : "使用"
JwtAuthenticationFilter --> TokenService : "校验"
图表来源
- AuthController.java
- IAuthService.java
- AuthUserServiceImpl.java
- TokenService.java
- JwtAuthenticationFilter.java
章节来源
- AuthController.java
- IAuthService.java
- AuthUserServiceImpl.java
- TokenService.java
- JwtAuthenticationFilter.java
- SecurityConfig.java
- PermissionConfig.java
- LoginParam.java
- LoginResultDTO.java
- UserInfoDTO.java
文件服务模块(crm-file)
-
文件上传(分片/断点续传)
- 初始化分片会话:POST /file/upload/init
- 请求体:MultipartInitDTO(文件名、大小、MD5、分片大小等)
- 响应:UploadSession(sessionId、分片策略)
- 状态码:200成功;400参数错误;413文件过大
- 上传分片:POST /file/upload/chunk
- Content-Type:multipart/form-data
- 表单字段:file(二进制)、chunkIndex(分片序号)、totalChunks(总分片数)、sessionId
- 响应:Result~boolean~(是否上传成功)
- 状态码:200成功;400参数缺失;404会话不存在;413单分片过大
- 合并分片:POST /file/upload/merge
- 请求体:{ sessionId, fileName, totalChunks, md5 }
- 响应:FileInfoDTO(文件ID、URL、大小、类型等)
- 状态码:200成功;400参数错误;409MD5不一致
- 初始化分片会话:POST /file/upload/init
-
文件下载与预览
- 下载:GET /file/download/{fileId}
- 响应:二进制流,Content-Disposition含文件名
- 状态码:200成功;404文件不存在;403无权限
- 预览:GET /file/preview/{fileId}
- 响应:HTML预览页面或重定向到在线预览地址
- 状态码:200成功;404文件不存在;403无权限
- 下载:GET /file/download/{fileId}
-
新增:缩略图获取
- 缩略图:GET /api/file/thumbnail
- 请求参数:fileId(必填,文件ID)
- 响应:二进制图片流(image/jpeg或image/png)
- 状态码:200成功(已就绪或占位图);202接受(正在生成中)
- 缓存控制:根据缩略图状态自动设置Cache-Control头
- cacheable=true:max-age=86400(强缓存1天)
- cacheable=false:no-cache(不缓存)
- 功能特性:
- 智能状态检测:READY直接返回缩略图,PENDING触发异步生成
- 同步兜底:首次请求时尝试同步生成,避免长时间等待
- 占位图降级:UNSUPPORTED/FAILED/读取失败时返回动态占位图
- 分布式锁:防止并发重复生成,提高性能
- 缩略图:GET /api/file/thumbnail
-
文件元数据管理
- 列表:GET /file/list
- 查询参数:page、size、keyword、type、ownerId等
- 响应:PageResult~FileInfoDTO~
- 状态码:200成功;400参数错误
- 删除:DELETE /file/delete/{fileId}
- 响应:Result~void~
- 状态码:200成功;404文件不存在;403无权限
- 列表:GET /file/list
flowchart TD
Start(["开始"]) --> Init["初始化分片会话<br/>POST /file/upload/init"]
Init --> UploadChunk["循环上传分片<br/>POST /file/upload/chunk"]
UploadChunk --> Merge["合并分片<br/>POST /file/upload/merge"]
Merge --> Success{"合并成功?"}
Success --> |是| ReturnInfo["返回FileInfoDTO"]
Success --> |否| Error["返回错误码与提示"]
ReturnInfo --> End(["结束"])
Error --> End
图表来源
- FileController.java
- FileApi.java
- FileApiImpl.java
- FileInfoService.java
- FileInfoServiceImpl.java
- MultipartInitDTO.java
- UploadSession.java
- FileInfoDTO.java
- FileDownloadDTO.java
章节来源
- FileController.java
- FileApi.java
- FileApiImpl.java
- FileInfoService.java
- FileInfoServiceImpl.java
- MultipartInitDTO.java
- UploadSession.java
- FileInfoDTO.java
- FileDownloadDTO.java
- ThumbnailDTO.java
- ThumbnailGenerationTask.java
- ThumbnailPlaceholderService.java
- FileConstants.java
- MinioConfig.java
- FileProperties.java
统一响应与异常处理(crm-base)
- 统一响应体 Result
- 字段:code(状态码)、message(提示信息)、data(业务数据)
- 成功示例:{ "code": 200, "message": "操作成功", "data": {...} }
- 分页 PageResult
- 字段:records(列表)、total(总数)、page(页码)、size(每页条数)
- 全局异常处理
- 业务异常:BusinessErrorException -> code=业务码,message=描述
- 参数校验:MissingParameterException -> code=400,message=缺参说明
- 权限异常:PermissionErrorException -> code=403,message=权限不足
- 资源不存在:ResourceNotExistException -> code=404,message=资源不存在
章节来源
- Result.java
- PageResult.java
- GlobalExceptionHandlerAdvice.java
- ResultCodeEnum.java
- CommonConstants.java
依赖关系分析
- 控制器依赖服务接口,服务实现依赖数据访问与外部存储
- 认证过滤器依赖TokenService进行JWT校验
- 文件服务依赖MinIO配置与属性配置
- 缩略图功能依赖ThumbnailGenerationTask进行异步生成
- 统一异常处理贯穿各模块
graph LR
AC["AuthController"] --> ASvc["IAuthService"]
ASvc --> AImpl["AuthUserServiceImpl"]
AImpl --> Tok["TokenService"]
FC["FileController"] --> FApi["FileApi"]
FApi --> FImpl["FileApiImpl"]
FImpl --> FInfoSvc["IFileInfoService"]
FInfoSvc --> FInfoImpl["FileInfoServiceImpl"]
FImpl --> TGT["ThumbnailGenerationTask"]
Tok --> Sec["JwtAuthenticationFilter"]
FImpl --> Minio["MinIO(外部存储)"]
TGT --> Minio
图表来源
- AuthController.java
- IAuthService.java
- AuthUserServiceImpl.java
- TokenService.java
- JwtAuthenticationFilter.java
- FileController.java
- FileApi.java
- FileApiImpl.java
- FileInfoService.java
- FileInfoServiceImpl.java
- ThumbnailGenerationTask.java
- MinioConfig.java
章节来源
- AuthController.java
- FileController.java
- TokenService.java
- JwtAuthenticationFilter.java
- FileApiImpl.java
- ThumbnailGenerationTask.java
- MinioConfig.java
性能考虑
- 文件上传
- 合理设置分片大小(建议1MB~5MB),避免单次传输过大
- 并发上传分片时注意限流与重试退避
- 合并前校验MD5,减少重复计算
- 认证鉴权
- JWT本地校验,避免频繁访问Redis;必要时缓存用户权限
- 刷新令牌策略应限制频率,防止滥用
- 分页查询
- 使用合理的page/size,避免大偏移量查询
- 对常用查询条件建立索引
- 缩略图优化
- 异步生成:上传完成后后台异步生成,不阻塞主流程
- 分布式锁:防止并发重复生成,提高系统稳定性
- 智能缓存:根据状态设置合适的缓存策略,减少重复请求
- 占位图降级:生成失败或类型不支持时快速返回占位图
- 同步兜底:首次请求时尝试同步生成,提升用户体验
故障排查指南
- 401 未认证
- 检查Authorization头是否正确携带Bearer token
- 确认token未过期且未被拉黑
- 403 权限不足
- 检查当前用户角色与菜单权限
- 确认数据权限范围是否包含目标数据
- 404 资源不存在
- 核对文件ID或用户ID是否存在
- 413 文件过大
- 调整服务端最大文件大小配置
- 400 参数校验失败
- 检查必填字段、格式与长度限制
- 缩略图相关问题
- 202 Accepted:缩略图正在生成中,稍后重试即可
- 占位图显示:文件类型不支持或生成失败,属于正常降级
- 缓存问题:检查Cache-Control头设置是否符合预期
- 生成超时:检查缩略图生成任务的执行时间和重试配置
章节来源
- GlobalExceptionHandlerAdvice.java
- ResultCodeEnum.java
- SecurityConfig.java
- PermissionConfig.java
- FileConstants.java
结论
本文档从架构到接口细节全面梳理了CRM后端的认证鉴权、系统管理与文件服务三大模块的API规范。通过统一的响应与异常处理、严格的权限控制与健壮的分片上传机制,为前端提供了稳定可靠的集成基础。新增的缩略图功能进一步增强了文件处理能力,支持多种文件类型的缩略图生成,具备智能缓存控制和完善的降级机制。建议在前端集成时严格遵循参数校验与错误处理规范,并结合测试用例验证关键流程。
附录
接口清单与示例
-
认证接口
- POST /auth/login
- 请求体:LoginParam(用户名、密码等)
- 响应:Result~LoginResultDTO~
- 示例响应:{ "code": 200, "message": "登录成功", "data": { "accessToken": "...", "refreshToken": "...", "expiresIn": 7200, "userInfo": {...} } }
- POST /auth/refresh
- 请求体:{ "refreshToken": "..." }
- 响应:Result~LoginResultDTO~
- POST /auth/logout
- 响应:Result~void~
- POST /auth/login
-
文件接口
- POST /file/upload/init
- 请求体:MultipartInitDTO(fileName、fileSize、md5、chunkSize)
- 响应:Result~UploadSession~
- POST /file/upload/chunk
- Content-Type:multipart/form-data
- 表单字段:file、chunkIndex、totalChunks、sessionId
- 响应:Result~boolean~
- POST /file/upload/merge
- 请求体:{ "sessionId": "...", "fileName": "...", "totalChunks": 10, "md5": "..." }
- 响应:Result~FileInfoDTO~
- GET /file/download/{fileId}
- 响应:二进制流
- GET /file/preview/{fileId}
- 响应:HTML预览或重定向
- GET /api/file/thumbnail?fileId={fileId}
- 请求参数:fileId(必填)
- 响应:二进制图片流(image/jpeg或image/png)
- 状态码:200成功;202接受(生成中)
- 缓存头:Cache-Control根据状态自动设置
- GET /file/list?page=1&size=10&keyword=...
- 响应:Result~PageResult~FileInfoDTO~
- POST /file/upload/init
-
系统管理接口(需管理员权限)
- 用户/角色/菜单/部门CRUD接口,路径以/system/开头
- 权限要求:具备对应菜单与数据权限
参数验证规则与业务约束
- 登录
- 用户名:非空,长度1~50
- 密码:非空,长度6~32
- 验证码:可选,按配置启用
- 文件上传
- 文件名:非空,长度1~255
- 文件大小:不超过配置上限
- MD5:必填,用于完整性校验
- 分片序号:从0开始连续,不得重复
- 分页查询
- page>=1,size<=100(可配置)
- keyword:模糊匹配,长度<=100
- 缩略图请求
- fileId:必填,必须是有效的文件ID
- 支持的文件类型:图片、PDF、Office文档等(取决于渲染器配置)
- 缓存策略:自动生成,无需手动控制
接口测试用例(示例)
- 登录成功
- 输入:{ "username": "admin", "password": "123456" }
- 期望:code=200,data.accessToken存在
- 登录失败(密码错误)
- 输入:{ "username": "admin", "password": "wrong" }
- 期望:code!=200,message提示错误
- 分片上传
- 步骤:init -> 上传N个chunk -> merge
- 期望:merge返回FileInfoDTO,download/preview可用
- 权限不足
- 步骤:使用低权限token访问/system/role/*
- 期望:code=403,message提示权限不足
- 缩略图测试
- 已就绪文件:GET /api/file/thumbnail?fileId={ready_file_id}
- 期望:200状态码,返回image/jpeg缩略图,Cache-Control: max-age=86400
- 生成中文件:GET /api/file/thumbnail?fileId={pending_file_id}
- 期望:可能返回202状态码,Cache-Control: no-cache,稍后重试
- 不支持类型:GET /api/file/thumbnail?fileId={unsupported_file_id}
- 期望:200状态码,返回image/png占位图,Cache-Control: no-cache
- 已就绪文件:GET /api/file/thumbnail?fileId={ready_file_id}
常见问题解答
- Q:如何获取并保存token?
- A:登录成功后从响应data中获取accessToken与refreshToken,保存在本地存储并在后续请求头中携带
- Q:token过期如何处理?
- A:优先使用refreshToken调用刷新接口;若失败则引导重新登录
- Q:分片上传失败如何恢复?
- A:记录已上传的分片序号,合并前校验MD5,缺失分片继续上传
- Q:如何限制文件类型与大小?
- A:在FileProperties中配置允许的类型与大小上限,并在前端做二次校验
- Q:缩略图加载慢怎么办?
- A:首次请求会触发异步生成,后续请求会命中缓存;如果持续慢,检查缩略图生成任务的执行情况和MinIO性能
- Q:为什么有些文件没有缩略图?
- A:可能是文件类型不支持,或者缩略图生成失败;系统会自动返回占位图作为降级处理
- Q:如何优化缩略图的缓存效果?
- A:系统已自动设置合适的Cache-Control头;对于已就绪的缩略图会设置1天的强缓存,对于生成中的文件使用no-cache