# 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清单 - 补充缩略图相关的错误处理和状态码说明 ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本API参考文档面向前端开发者,系统化梳理认证鉴权、系统管理、文件上传下载等模块的RESTful接口规范。内容覆盖HTTP方法、URL路径、请求参数、响应格式、状态码与错误信息;明确认证方式(JWT)、多部分表单上传流程、权限控制要求;提供完整请求/响应示例、参数校验规则与业务约束,并附带接口测试用例与常见问题解答,帮助快速集成与排障。 ## 项目结构 本项目采用多模块架构: - crm-app:应用启动入口与全局配置 - crm-auth:认证鉴权与系统管理(用户、角色、菜单、部门) - crm-base:通用基础能力(统一响应、异常处理、安全上下文、分页等) - crm-file:文件服务(分片上传、断点续传、预览、下载、缩略图生成) ```mermaid graph TB subgraph "应用层" APP["crm-app
应用启动"] end subgraph "认证与系统管理" AUTH["crm-auth
认证/权限/系统管理"] end subgraph "基础能力" BASE["crm-base
通用组件/异常/结果封装"] end subgraph "文件服务" 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) - [application.yml](file://crm-app/src/main/resources/application.yml) 章节来源 - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) ## 核心组件 - 统一响应体 Result:所有接口返回统一包装,包含状态码、消息与数据体 - 分页 PageResult:标准分页数据结构 - 全局异常 GlobalExceptionHandlerAdvice:统一捕获业务异常、参数校验异常、权限异常等,输出标准化错误 - 安全上下文 LoginUser/AuthLoginUser:当前登录用户信息与权限范围 - TokenService:JWT签发、解析、刷新与黑名单管理 - JwtAuthenticationFilter:请求级JWT校验与上下文注入 - FileApi/FileApiImpl:文件上传下载、分片、预览、清理、缩略图生成等能力抽象与实现 - FileInfoService:文件元数据持久化与查询 - ThumbnailGenerationTask:异步缩略图生成任务 - ThumbnailPlaceholderService:动态生成文件类型占位图 章节来源 - [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) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [AuthLoginUser.java](file://crm-auth/src/main/java/com/crm/auth/security/AuthLoginUser.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) - [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) - [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java) - [ThumbnailPlaceholderService.java](file://crm-file/src/main/java/com/crm/file/service/ThumbnailPlaceholderService.java) ## 架构总览 整体调用链路:客户端通过HTTP访问Controller,Controller调用Service完成业务逻辑,Service通过Mapper访问数据库或调用外部存储(如MinIO)。认证流程由Spring Security过滤器链拦截,基于JWT进行鉴权;权限控制通过注解与数据权限拦截器实现。缩略图功能采用异步生成+同步兜底的策略,确保用户体验。 ```mermaid 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 " 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](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) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/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未登录 - 鉴权机制 - 认证方式:Bearer JWT - 请求头:Authorization: Bearer - 过滤器:JwtAuthenticationFilter负责解析与校验 - 权限模型:基于角色的菜单/按钮权限,支持数据权限范围(部门/个人) - 系统管理接口(需管理员权限) - 用户管理:CRUD /system/user/* - 角色管理:CRUD /system/role/* - 菜单管理:CRUD /system/menu/* - 部门管理:CRUD /system/dept/* - 权限校验:使用注解或拦截器,结合DataScope实现数据隔离 - 统一响应与错误 - 响应体:Result - 错误码:ResultCodeEnum定义 - 异常处理:GlobalExceptionHandlerAdvice统一捕获并返回 ```mermaid 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](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) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.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) 章节来源 - [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) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.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) - [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) - [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) ### 文件服务模块(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不一致 - 文件下载与预览 - 下载:GET /file/download/{fileId} - 响应:二进制流,Content-Disposition含文件名 - 状态码:200成功;404文件不存在;403无权限 - 预览:GET /file/preview/{fileId} - 响应:HTML预览页面或重定向到在线预览地址 - 状态码:200成功;404文件不存在;403无权限 - **新增:缩略图获取** - 缩略图: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 /file/list - 查询参数:page、size、keyword、type、ownerId等 - 响应:PageResult~FileInfoDTO~ - 状态码:200成功;400参数错误 - 删除:DELETE /file/delete/{fileId} - 响应:Result~void~ - 状态码:200成功;404文件不存在;403无权限 ```mermaid flowchart TD Start(["开始"]) --> Init["初始化分片会话
POST /file/upload/init"] Init --> UploadChunk["循环上传分片
POST /file/upload/chunk"] UploadChunk --> Merge["合并分片
POST /file/upload/merge"] Merge --> Success{"合并成功?"} Success --> |是| ReturnInfo["返回FileInfoDTO"] Success --> |否| Error["返回错误码与提示"] ReturnInfo --> End(["结束"]) Error --> End ``` 图表来源 - [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) 章节来源 - [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) - [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java) - [ThumbnailPlaceholderService.java](file://crm-file/src/main/java/com/crm/file/service/ThumbnailPlaceholderService.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) ### 统一响应与异常处理(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](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) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java) - [CommonConstants.java](file://crm-base/src/main/java/com/crm/base/constant/CommonConstants.java) ## 依赖关系分析 - 控制器依赖服务接口,服务实现依赖数据访问与外部存储 - 认证过滤器依赖TokenService进行JWT校验 - 文件服务依赖MinIO配置与属性配置 - 缩略图功能依赖ThumbnailGenerationTask进行异步生成 - 统一异常处理贯穿各模块 ```mermaid 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](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) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.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) - [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) - [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) 章节来源 - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java) - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.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) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/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](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.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) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/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 /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~ - 系统管理接口(需管理员权限) - 用户/角色/菜单/部门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 ### 常见问题解答 - 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