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.

733 lines
34 KiB

1 month ago
# 文件API
<cite>
**本文引用的文件**
- [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)
- [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.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)
1 month ago
- [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)
1 month ago
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.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)
- [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)
1 month ago
- [ThumbnailDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/ThumbnailDTO.java)
1 month ago
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java)
</cite>
1 month ago
## 更新摘要
**变更内容**
- 新增缩略图API端点 `/api/file/thumbnail`,支持二进制图片数据和JSON信封响应
- 增强FileApiImpl中的缩略图生命周期管理,实现状态跟踪(PENDING, READY, FAILED, UNSUPPORTED)
- 添加同步回退机制,在异步任务未完成时提供即时响应
- 完善缩略图生成、缓存策略和错误处理流程
1 month ago
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录:接口清单与规范](#附录接口清单与规范)
## 简介
本文件管理模块提供统一的文件上传、下载、预览、删除等能力,支持分片上传、断点续传与并发上传;集成 MinIO 对象存储与 KkFileView 在线预览服务;提供缩略图生成、临时访问链接、权限控制与批量操作。文档面向开发者与集成方,覆盖 HTTP 接口、数据模型、存储策略、安全校验、错误处理与优化建议。
1 month ago
**更新** 新增缩略图API端点,支持智能状态管理和同步回退机制,提供更健壮的缩略图获取体验。
1 month ago
## 项目结构
文件模块位于 crm-file 子模块,采用分层组织:
- controller:HTTP 接口层
- api:对外 API 抽象
- service:业务逻辑与外部服务客户端(MinIO、KkFileView)
- domain:实体、DTO、枚举与常量
- config:配置类(MinIO、调度任务、文件属性)
1 month ago
- task:定时清理任务(分片残留清理、缩略图生成)
1 month ago
- mapper:数据库映射(文件元信息)
```mermaid
graph TB
subgraph "crm-file"
C["controller.FileController"] --> A["api.FileApi"]
A --> S1["service.impl.FileApiImpl"]
S1 --> S2["service.IFileInfoService"]
S2 --> S3["service.impl.FileInfoServiceImpl"]
S1 --> M["config.MinioConfig"]
S1 --> P["config.FileProperties"]
S1 --> K["service.KkFileViewClient"]
1 month ago
S1 --> TGT["task.ThumbnailGenerationTask"]
S1 --> TPS["service.ThumbnailPlaceholderService"]
1 month ago
S3 --> E["domain.entity.FileInfo"]
S3 --> MAP["mapper.FileInfoMapper"]
T["task.OrphanChunkCleanupTask"] --> M
T --> S2
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)
- [IFileInfoService.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)
- [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)
- [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java)
1 month ago
- [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)
1 month ago
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
## 核心组件
- FileController:暴露 REST 接口,统一接收请求并委派给 FileApi。
- FileApi / FileApiImpl:定义并实现文件上传、下载、预览、删除、分片、续传、缩略图等核心流程。
- IFileInfoService / FileInfoServiceImpl:文件元数据持久化、查询、状态管理与事务边界。
- MinioConfig:MinIO 客户端配置与桶策略。
- FileProperties:文件大小限制、允许类型、路径规则等配置项。
- KkFileViewClient:调用第三方预览服务,生成预览链接或缩略图。
1 month ago
- ThumbnailGenerationTask:异步缩略图生成任务,支持分布式锁和重试机制。
- ThumbnailPlaceholderService:动态生成文件类型占位图。
1 month ago
- OrphanChunkCleanupTask:定时清理未完成的分片文件,释放空间。
- FileInfo 实体与 Mapper:文件元信息表结构与数据访问。
1 month ago
**更新** 新增缩略图相关组件,提供完整的缩略图生命周期管理能力。
1 month ago
## 架构总览
1 month ago
整体采用"控制器-服务-存储/外部服务"的分层架构:
1 month ago
- 控制器负责参数校验、鉴权与响应封装。
- 服务层编排上传、下载、预览、删除等业务流程,协调 MinIO 与 KkFileView。
- 配置层集中管理 MinIO、文件属性与调度任务。
- 数据层通过 MyBatis-Plus 维护文件元信息。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Controller as "FileController"
participant Api as "FileApiImpl"
1 month ago
participant Task as "ThumbnailGenerationTask"
1 month ago
participant MinIO as "MinIO 存储"
participant Preview as "KkFileView 预览服务"
participant DB as "数据库(FileInfo)"
Client->>Controller : "POST /api/file/upload/init"
Controller->>Api : "初始化分片会话"
Api->>DB : "创建上传会话/记录"
Api-->>Controller : "返回会话ID/分片大小"
Controller-->>Client : "会话信息"
loop "分片上传"
Client->>Controller : "POST /api/file/upload/chunk"
Controller->>Api : "上传分片"
Api->>MinIO : "PutObject(分片)"
Api->>DB : "记录分片状态"
Api-->>Controller : "分片上传结果"
Controller-->>Client : "分片成功/失败"
end
Client->>Controller : "POST /api/file/upload/complete"
Controller->>Api : "合并分片/完成上传"
Api->>MinIO : "CompleteMultipartUpload"
Api->>DB : "写入文件元信息"
1 month ago
Api->>Task : "触发异步缩略图生成"
1 month ago
Api-->>Controller : "文件信息"
Controller-->>Client : "文件URL/预览链接"
1 month ago
Client->>Controller : "GET /api/file/thumbnail/{id}"
Controller->>Api : "获取缩略图"
Api->>Task : "尝试同步生成"
Task-->>Api : "生成结果"
Api->>MinIO : "读取缩略图"
Api-->>Controller : "缩略图数据"
Controller-->>Client : "二进制图片流"
1 month ago
```
**图表来源**
- [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)
1 month ago
- [ThumbnailGenerationTask.java](file://crm-file/src/main/java/com/crm/file/task/ThumbnailGenerationTask.java)
1 month ago
- [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)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java)
## 详细组件分析
### 文件上传接口(普通上传)
- 方法:POST
- 路径:/api/file/upload
- 请求体:multipart/form-data,字段 file(二进制文件)
- 响应:文件基本信息(ID、名称、大小、URL、预览链接)
- 校验:文件名白名单、大小限制、MIME 类型校验、重复检测
- 存储:MinIO 直传,按日期/用户维度组织桶路径
- 安全:鉴权拦截器校验登录态与权限
```mermaid
flowchart TD
Start(["进入上传接口"]) --> Validate["校验请求参数与权限"]
Validate --> CheckType{"文件类型允许?"}
CheckType --> |否| ErrType["返回类型不允许错误"]
CheckType --> |是| CheckSize{"文件大小合规?"}
CheckSize --> |否| ErrSize["返回大小超限错误"]
CheckSize --> |是| Upload["调用 MinIO 上传"]
Upload --> SaveMeta["持久化文件元信息"]
1 month ago
SaveMeta --> GenThumb["触发缩略图生成"]
GenThumb --> Return["返回文件信息"]
1 month ago
ErrType --> End(["结束"])
ErrSize --> End
Return --> End
```
**图表来源**
- [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)
- [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.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)
**章节来源**
- [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)
- [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.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)
### 分片上传(含断点续传与并发)
- 初始化会话:POST /api/file/upload/init
- 参数:fileName、fileSize、chunkSize、uploadId
- 响应:uploadId、分片大小、已存在分片列表
- 上传分片:POST /api/file/upload/chunk
- 参数:uploadId、chunkIndex、chunkData
- 行为:幂等上传,支持并发;记录分片状态
- 完成上传:POST /api/file/upload/complete
- 参数:uploadId、fileName、fileSize、checksum
- 行为:合并分片、落盘、写元信息、生成访问链接
- 断点续传:基于 uploadId 与分片索引去重,未上传分片可重试
- 并发上传:客户端并行上传分片,服务端保证幂等与顺序无关
```mermaid
sequenceDiagram
participant C as "客户端"
participant Ctrl as "FileController"
participant Api as "FileApiImpl"
participant MinIO as "MinIO"
participant DB as "FileInfoService"
C->>Ctrl : "init(uploadId, fileName, fileSize, chunkSize)"
Ctrl->>Api : "初始化会话"
Api->>DB : "创建会话/查询已上传分片"
Api-->>Ctrl : "返回分片策略"
Ctrl-->>C : "分片策略"
par "并发上传分片"
C->>Ctrl : "chunk(uploadId, index, data)"
Ctrl->>Api : "上传分片"
Api->>MinIO : "分片PutObject"
Api->>DB : "记录分片状态"
Api-->>Ctrl : "分片成功"
Ctrl-->>C : "分片成功"
end
C->>Ctrl : "complete(uploadId, checksum)"
Ctrl->>Api : "合并分片"
Api->>MinIO : "CompleteMultipartUpload"
Api->>DB : "写入文件元信息"
Api-->>Ctrl : "文件信息"
Ctrl-->>C : "文件URL/预览链接"
```
**图表来源**
- [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)
- [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)
- [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)
**章节来源**
- [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)
- [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)
- [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)
### 文件下载接口
- 方法:GET
- 路径:/api/file/download/{id}
- 参数:id(文件ID)、可选签名参数(如过期时间)
- 响应:文件流(Content-Disposition 设置下载名)
- 权限:需具备文件读取权限;支持私有桶访问(预签名 URL)
- 缓存:浏览器缓存控制头由服务端设置
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Controller as "FileController"
participant Api as "FileApiImpl"
participant MinIO as "MinIO"
Client->>Controller : "GET /api/file/download/{id}"
Controller->>Api : "校验权限/构建下载参数"
Api->>MinIO : "GetObject(或预签名URL)"
MinIO-->>Api : "文件流/URL"
Api-->>Controller : "流/URL"
Controller-->>Client : "文件流/重定向"
```
**图表来源**
- [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)
- [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.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)
- [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java)
### 文件预览接口
- 方法:GET
- 路径:/api/file/preview/{id}
- 功能:根据文件类型调用 KkFileView 生成预览链接或直接返回预览页面
- 参数:id(文件ID)、可选格式参数(pdf/html/img)
- 响应:预览页面或跳转链接
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Controller as "FileController"
participant Api as "FileApiImpl"
participant Preview as "KkFileViewClient"
Client->>Controller : "GET /api/file/preview/{id}"
Controller->>Api : "解析文件类型/构造预览参数"
Api->>Preview : "生成预览URL"
Preview-->>Api : "预览URL"
Api-->>Controller : "预览URL"
Controller-->>Client : "跳转/嵌入预览"
```
**图表来源**
- [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)
- [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.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)
- [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java)
### 文件删除接口
- 方法:DELETE
- 路径:/api/file/delete/{id}
- 权限:仅文件所有者或管理员可删除
- 行为:删除 MinIO 对象与数据库元信息;软删除标记可选
```mermaid
flowchart TD
Start(["进入删除接口"]) --> Auth["鉴权与所有权校验"]
Auth --> Exists{"文件存在?"}
Exists --> |否| NotFound["返回资源不存在"]
Exists --> |是| DeleteMinIO["删除 MinIO 对象"]
DeleteMinIO --> DeleteDB["删除/标记文件元信息"]
DeleteDB --> Ok["返回删除成功"]
NotFound --> End(["结束"])
Ok --> End
```
**图表来源**
- [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)
**章节来源**
- [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)
1 month ago
### 缩略图API端点(新增)
- 方法:GET
- 路径:/api/file/thumbnail/{id}
- 功能:获取文件缩略图,支持智能状态管理和同步回退
- 参数:id(文件ID)
- 响应:二进制图片数据(image/jpeg)或占位图(image/png)
- 状态码:200(正常)、202(缩略图生成中,稍后重试)
**更新** 新增缩略图API端点,提供 sophisticated 的响应处理和状态管理。
1 month ago
```mermaid
1 month ago
sequenceDiagram
participant Client as "客户端"
participant Controller as "FileController"
participant Api as "FileApiImpl"
participant Task as "ThumbnailGenerationTask"
participant MinIO as "MinIO"
Client->>Controller : "GET /api/file/thumbnail/{id}"
Controller->>Api : "获取缩略图"
Api->>Api : "检查缩略图状态"
alt 状态为READY
Api->>MinIO : "读取缩略图"
MinIO-->>Api : "缩略图数据"
Api-->>Controller : "缩略图数据"
else 状态为PENDING
Api->>Task : "尝试同步生成"
Task-->>Api : "生成结果"
Api->>MinIO : "读取缩略图"
MinIO-->>Api : "缩略图数据"
Api-->>Controller : "缩略图数据"
else 其他状态
Api->>Api : "生成占位图"
Api-->>Controller : "占位图数据"
end
Controller-->>Client : "二进制图片流"
1 month ago
```
**图表来源**
1 month ago
- [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java)
1 month ago
- [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java)
1 month ago
- [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)
1 month ago
**章节来源**
1 month ago
- [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java)
1 month ago
- [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java)
1 month ago
- [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)
### 缩略图生命周期管理(新增)
- 状态机:PENDING → READY / FAILED / UNSUPPORTED
- 初始状态:上传时根据文件类型判断(支持的类型设为PENDING,不支持的设为UNSUPPORTED)
- 异步生成:上传完成后触发异步缩略图生成任务
- 同步回退:首次请求时若异步任务未完成,尝试同步生成
- 轮询等待:同步生成失败时轮询状态,超时返回202状态码
- 降级处理:生成失败或超时时返回占位图
```mermaid
stateDiagram-v2
[*] --> PENDING : 上传成功支持类型
[*] --> UNSUPPORTED : 上传成功不支持类型
PENDING --> READY : 缩略图生成成功
PENDING --> FAILED : 缩略图生成失败重试耗尽
PENDING --> PENDING : 缩略图生成失败继续重试
READY --> [*]
FAILED --> [*]
UNSUPPORTED --> [*]
```
**图表来源**
- [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)
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.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)
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java)
1 month ago
### 批量操作接口
- 批量删除:POST /api/file/batch/delete
- 参数:ids(数组)
- 行为:逐个校验权限后执行删除
- 批量下载:POST /api/file/batch/download
- 参数:ids(数组)
- 行为:打包为 ZIP 流返回(大文件建议分页或异步任务)
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Controller as "FileController"
participant Api as "FileApiImpl"
Client->>Controller : "POST /api/file/batch/delete {ids}"
Controller->>Api : "遍历校验与删除"
Api-->>Controller : "结果汇总"
Controller-->>Client : "批量结果"
```
**图表来源**
- [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)
**章节来源**
- [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)
### 临时链接生成
- 场景:私有桶访问、外链分享
- 接口:GET /api/file/presigned-url?fileId=xxx&expires=秒数
- 行为:生成 MinIO 预签名 URL,带过期时间与访问权限
- 安全:结合鉴权与访问控制策略
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Controller as "FileController"
participant Api as "FileApiImpl"
participant MinIO as "MinIO"
Client->>Controller : "GET /api/file/presigned-url"
Controller->>Api : "校验权限/计算过期时间"
Api->>MinIO : "GeneratePresignedUrl"
MinIO-->>Api : "预签名URL"
Api-->>Controller : "URL"
Controller-->>Client : "临时链接"
```
**图表来源**
- [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)
- [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.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)
- [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java)
### 分片残留清理任务
- 任务:定时扫描未完成上传的会话与分片,清理无效数据
- 策略:超过保留时间的会话自动清理,避免磁盘膨胀
- 配置:调度周期与保留时长在配置中管理
```mermaid
flowchart TD
Start(["定时任务启动"]) --> Scan["扫描未完成会话"]
Scan --> Filter{"是否超期?"}
Filter --> |否| Next["跳过"]
Filter --> |是| Cleanup["清理分片与会话"]
Cleanup --> Log["记录清理日志"]
Log --> End(["结束"])
Next --> End
```
**图表来源**
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.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)
- [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java)
## 依赖关系分析
- FileController 依赖 FileApi,解耦 HTTP 与业务逻辑。
- FileApiImpl 依赖 MinioConfig(MinIO 客户端)、FileProperties(配置)、KkFileViewClient(预览)。
- FileInfoServiceImpl 依赖 FileInfo 实体与 FileInfoMapper(MyBatis-Plus)。
- OrphanChunkCleanupTask 依赖 MinIO 与 FileInfoService 进行清理。
1 month ago
- **更新** FileApiImpl 新增对 ThumbnailGenerationTask 和 ThumbnailPlaceholderService 的依赖。
1 month ago
```mermaid
classDiagram
class FileController {
+upload()
+download()
+preview()
+delete()
+batchDelete()
+presignedUrl()
1 month ago
+thumbnail()
1 month ago
}
class FileApiImpl {
+initMultipart()
+uploadChunk()
+completeMultipart()
+download()
+preview()
+thumbnail()
+delete()
+presignedUrl()
}
1 month ago
class ThumbnailGenerationTask {
+isSupported()
+assignInitialStatus()
+generate()
+tryGenerateSync()
}
class ThumbnailPlaceholderService {
+getPlaceholder()
}
1 month ago
class MinioConfig {
+client
+bucket
}
class FileProperties {
+maxFileSize
+allowedTypes
+pathRules
}
class KkFileViewClient {
+generatePreviewUrl()
}
class FileInfoServiceImpl {
+save()
+query()
+updateStatus()
}
class FileInfo {
+id
+name
+size
+url
+status
1 month ago
+thumbnailStatus
1 month ago
}
class FileInfoMapper
FileController --> FileApiImpl : "调用"
FileApiImpl --> MinioConfig : "使用"
FileApiImpl --> FileProperties : "读取配置"
FileApiImpl --> KkFileViewClient : "调用预览"
FileApiImpl --> FileInfoServiceImpl : "元数据操作"
1 month ago
FileApiImpl --> ThumbnailGenerationTask : "缩略图生成"
FileApiImpl --> ThumbnailPlaceholderService : "占位图生成"
1 month ago
FileInfoServiceImpl --> FileInfo : "实体"
FileInfoServiceImpl --> FileInfoMapper : "数据访问"
```
**图表来源**
- [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)
1 month ago
- [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)
1 month ago
- [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)
- [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.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)
1 month ago
- [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)
1 month ago
- [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)
- [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java)
- [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java)
## 性能考虑
- 分片上传:合理设置分片大小(建议 5~10MB),提升大文件上传稳定性与并发度。
- 并发上传:客户端并行上传分片,服务端幂等处理,避免重复写入。
- 流式下载:使用流式响应减少内存占用,支持 Range 断点续传。
1 month ago
- **更新** 缩略图:异步生成与缓存,命中缓存直接返回;同步回退机制避免阻塞。
1 month ago
- 预览服务:KkFileView 集群部署与缓存加速,避免单点瓶颈。
- 连接池:MinIO 客户端连接池与超时参数调优。
- 压缩与缓存:对静态资源启用 GZIP 与浏览器缓存。
- 限流与熔断:对上传/下载接口实施限流,异常时快速失败。
1 month ago
**更新** 缩略图性能优化包括异步生成、分布式锁、缓存策略和同步回退机制。
1 month ago
## 故障排查指南
- 上传失败:检查文件类型与大小限制、网络超时、MinIO 连通性。
- 分片丢失:核对 uploadId 与分片索引,查看分片状态记录。
- 预览失败:确认 KkFileView 服务可用性与文件格式支持。
- 下载慢:检查带宽、MinIO 延迟、是否命中预签名 URL。
- 权限问题:校验登录态、角色与数据范围。
- 清理任务:查看调度配置与日志,确认清理阈值合理。
1 month ago
- **更新** 缩略图问题:检查缩略图状态、生成任务执行情况、Redis锁状态、MinIO缩略图存储。
1 month ago
1 month ago
**更新** 新增缩略图故障排查指南,包括状态检查、任务监控和缓存验证。
1 month ago
## 结论
1 month ago
文件模块以清晰的分层架构与完善的流程设计,提供了稳定高效的文件管理能力。通过分片上传、断点续传、并发上传与预览集成,满足企业级场景需求。配合 MinIO 与权限控制,确保数据安全与访问可控。**更新** 新增的缩略图功能提供了完整的生命周期管理和智能状态处理,进一步提升了用户体验。建议在大规模使用时关注连接池、缓存与限流等性能优化点。
1 month ago
## 附录:接口清单与规范
### 接口清单
- 普通上传:POST /api/file/upload
- 分片初始化:POST /api/file/upload/init
- 分片上传:POST /api/file/upload/chunk
- 分片完成:POST /api/file/upload/complete
- 文件下载:GET /api/file/download/{id}
- 文件预览:GET /api/file/preview/{id}
1 month ago
- **更新** 缩略图:GET /api/file/thumbnail/{id}
1 month ago
- 删除文件:DELETE /api/file/delete/{id}
- 批量删除:POST /api/file/batch/delete
- 批量下载:POST /api/file/batch/download
- 临时链接:GET /api/file/presigned-url
### 请求参数与响应格式
- 上传参数:file(二进制)、fileName、fileSize、chunkSize、uploadId、chunkIndex、checksum
- 下载参数:id、可选签名参数
- 预览参数:id、format(可选)
1 month ago
- **更新** 缩略图参数:id(文件ID)
1 month ago
- 删除参数:id、ids(批量)
1 month ago
- 响应格式:统一 Result 包装,包含 code、message、data;缩略图接口例外返回二进制数据
1 month ago
### 存储策略
- MinIO 桶命名:按业务域划分(如 file-prod、file-dev)
- 路径规则:/tenant/user/date/originalName
1 month ago
- **更新** 缩略图路径:/thumbnails/{fileId}.jpg
1 month ago
- 分片路径:/chunks/{uploadId}/...
### 支持的文件格式与大小限制
- 允许类型:image/*、application/pdf、application/msword、application/vnd.openxmlformats-officedocument.*、text/*
- 大小限制:默认 100MB,可通过配置调整
- 安全检查:MIME 类型校验、扩展名校验、内容扫描(可选)
### 安全校验规则
- 鉴权:JWT 登录态校验
- 权限:基于角色与数据范围的访问控制
- 输入校验:白名单类型、大小限制、文件名清洗
- 输出控制:下载与预览链接有效期控制
### MinIO 存储配置
- 端点、AccessKey、SecretKey、Bucket、Region
- 连接池大小、超时时间、重试次数
- 桶策略:读写权限、匿名访问开关
### 文件访问权限控制
- 私有桶:通过预签名 URL 访问
- 公开桶:受限域名与 Referer 白名单
- 租户隔离:路径前缀区分租户
### 临时链接生成
- 过期时间:秒级精度,默认 1 小时
- 权限继承:继承原文件的访问策略
- 防滥用:频率限制与 IP 白名单
### 文件预览服务集成
- KkFileView 地址、超时、重试
- 支持的格式与渲染选项
- 缓存策略:本地缓存与 CDN 加速
1 month ago
### 缩略图服务集成(新增)
- **更新** 缩略图生成:异步任务 + 同步回退机制
- 状态管理:PENDING、READY、FAILED、UNSUPPORTED
- 缓存策略:cacheable=true时设置max-age=86400,false时no-cache
- 占位图:动态生成文件类型图标(PNG格式)
- 重试机制:支持多次重试,耗尽后标记FAILED
1 month ago
### 错误处理机制
- 统一异常处理:BusinessErrorException、ResourceNotExistException
- 错误码:ResultCodeEnum 定义
- 重试策略:网络重试与指数退避
1 month ago
- **更新** 缩略图错误:生成失败降级为占位图,超时返回202状态码
1 month ago
### 重试策略
- 上传分片:失败重试 3 次,间隔递增
- 下载:超时重试 1 次
- 预览:失败降级为原始文件下载
1 month ago
- **更新** 缩略图:异步任务支持多次重试,同步回退超时返回202
1 month ago
### 性能优化建议
- 分片大小与并发度调优
- 缩略图异步生成与缓存
- 预览服务集群与缓存
- 连接池与超时参数优化
- 限流与熔断保护
1 month ago
- **更新** 缩略图分布式锁避免重复生成,Redis缓存提升访问性能
1 month ago
**章节来源**
- [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)
1 month ago
- [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)
1 month ago
- [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.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)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
1 month ago
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java)
- [ThumbnailDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/ThumbnailDTO.java)