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.
655 lines
30 KiB
655 lines
30 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)
|
||
|
|
- [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)
|
||
|
|
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java)
|
||
|
|
</cite>
|
||
|
|
|
||
|
|
## 目录
|
||
|
|
1. [简介](#简介)
|
||
|
|
2. [项目结构](#项目结构)
|
||
|
|
3. [核心组件](#核心组件)
|
||
|
|
4. [架构总览](#架构总览)
|
||
|
|
5. [详细组件分析](#详细组件分析)
|
||
|
|
6. [依赖关系分析](#依赖关系分析)
|
||
|
|
7. [性能考虑](#性能考虑)
|
||
|
|
8. [故障排查指南](#故障排查指南)
|
||
|
|
9. [结论](#结论)
|
||
|
|
10. [附录:接口清单与规范](#附录接口清单与规范)
|
||
|
|
|
||
|
|
## 简介
|
||
|
|
本文件管理模块提供统一的文件上传、下载、预览、删除等能力,支持分片上传、断点续传与并发上传;集成 MinIO 对象存储与 KkFileView 在线预览服务;提供缩略图生成、临时访问链接、权限控制与批量操作。文档面向开发者与集成方,覆盖 HTTP 接口、数据模型、存储策略、安全校验、错误处理与优化建议。
|
||
|
|
|
||
|
|
## 项目结构
|
||
|
|
文件模块位于 crm-file 子模块,采用分层组织:
|
||
|
|
- controller:HTTP 接口层
|
||
|
|
- api:对外 API 抽象
|
||
|
|
- service:业务逻辑与外部服务客户端(MinIO、KkFileView)
|
||
|
|
- domain:实体、DTO、枚举与常量
|
||
|
|
- config:配置类(MinIO、调度任务、文件属性)
|
||
|
|
- task:定时清理任务(分片残留清理)
|
||
|
|
- 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"]
|
||
|
|
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)
|
||
|
|
- [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.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)
|
||
|
|
- [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:调用第三方预览服务,生成预览链接或缩略图。
|
||
|
|
- OrphanChunkCleanupTask:定时清理未完成的分片文件,释放空间。
|
||
|
|
- FileInfo 实体与 Mapper:文件元信息表结构与数据访问。
|
||
|
|
|
||
|
|
**章节来源**
|
||
|
|
- [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)
|
||
|
|
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.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)
|
||
|
|
|
||
|
|
## 架构总览
|
||
|
|
整体采用“控制器-服务-存储/外部服务”的分层架构:
|
||
|
|
- 控制器负责参数校验、鉴权与响应封装。
|
||
|
|
- 服务层编排上传、下载、预览、删除等业务流程,协调 MinIO 与 KkFileView。
|
||
|
|
- 配置层集中管理 MinIO、文件属性与调度任务。
|
||
|
|
- 数据层通过 MyBatis-Plus 维护文件元信息。
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
sequenceDiagram
|
||
|
|
participant Client as "客户端"
|
||
|
|
participant Controller as "FileController"
|
||
|
|
participant Api as "FileApiImpl"
|
||
|
|
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 : "写入文件元信息"
|
||
|
|
Api-->>Controller : "文件信息"
|
||
|
|
Controller-->>Client : "文件URL/预览链接"
|
||
|
|
Client->>Controller : "GET /api/file/download/{id}"
|
||
|
|
Controller->>Api : "下载文件"
|
||
|
|
Api->>MinIO : "GetObject"
|
||
|
|
Api-->>Controller : "流式响应"
|
||
|
|
Controller-->>Client : "文件流"
|
||
|
|
Client->>Controller : "GET /api/file/preview/{id}"
|
||
|
|
Controller->>Api : "获取预览链接"
|
||
|
|
Api->>Preview : "生成预览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)
|
||
|
|
- [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["持久化文件元信息"]
|
||
|
|
SaveMeta --> Return["返回文件信息"]
|
||
|
|
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)
|
||
|
|
|
||
|
|
### 缩略图生成
|
||
|
|
- 触发时机:上传成功后异步生成缩略图(图片类型)
|
||
|
|
- 存储位置:MinIO 同桶下 thumbnail 目录
|
||
|
|
- 接口:GET /api/file/thumbnail/{id}
|
||
|
|
- 策略:若缩略图不存在则实时生成并缓存;支持尺寸参数
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
Start(["缩略图请求"]) --> CheckCache["检查缩略图是否存在"]
|
||
|
|
CheckCache --> |存在| ReturnThumb["返回缩略图"]
|
||
|
|
CheckCache --> |不存在| GenThumb["生成缩略图"]
|
||
|
|
GenThumb --> SaveThumb["保存至 MinIO"]
|
||
|
|
SaveThumb --> ReturnThumb
|
||
|
|
```
|
||
|
|
|
||
|
|
**图表来源**
|
||
|
|
- [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)
|
||
|
|
|
||
|
|
**章节来源**
|
||
|
|
- [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)
|
||
|
|
|
||
|
|
### 批量操作接口
|
||
|
|
- 批量删除: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 进行清理。
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
classDiagram
|
||
|
|
class FileController {
|
||
|
|
+upload()
|
||
|
|
+download()
|
||
|
|
+preview()
|
||
|
|
+delete()
|
||
|
|
+batchDelete()
|
||
|
|
+presignedUrl()
|
||
|
|
}
|
||
|
|
class FileApiImpl {
|
||
|
|
+initMultipart()
|
||
|
|
+uploadChunk()
|
||
|
|
+completeMultipart()
|
||
|
|
+download()
|
||
|
|
+preview()
|
||
|
|
+thumbnail()
|
||
|
|
+delete()
|
||
|
|
+presignedUrl()
|
||
|
|
}
|
||
|
|
class MinioConfig {
|
||
|
|
+client
|
||
|
|
+bucket
|
||
|
|
}
|
||
|
|
class FileProperties {
|
||
|
|
+maxFileSize
|
||
|
|
+allowedTypes
|
||
|
|
+pathRules
|
||
|
|
}
|
||
|
|
class KkFileViewClient {
|
||
|
|
+generatePreviewUrl()
|
||
|
|
}
|
||
|
|
class FileInfoServiceImpl {
|
||
|
|
+save()
|
||
|
|
+query()
|
||
|
|
+updateStatus()
|
||
|
|
}
|
||
|
|
class FileInfo {
|
||
|
|
+id
|
||
|
|
+name
|
||
|
|
+size
|
||
|
|
+url
|
||
|
|
+status
|
||
|
|
}
|
||
|
|
class FileInfoMapper
|
||
|
|
FileController --> FileApiImpl : "调用"
|
||
|
|
FileApiImpl --> MinioConfig : "使用"
|
||
|
|
FileApiImpl --> FileProperties : "读取配置"
|
||
|
|
FileApiImpl --> KkFileViewClient : "调用预览"
|
||
|
|
FileApiImpl --> FileInfoServiceImpl : "元数据操作"
|
||
|
|
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)
|
||
|
|
- [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)
|
||
|
|
- [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 断点续传。
|
||
|
|
- 缩略图:异步生成与缓存,命中缓存直接返回。
|
||
|
|
- 预览服务:KkFileView 集群部署与缓存加速,避免单点瓶颈。
|
||
|
|
- 连接池:MinIO 客户端连接池与超时参数调优。
|
||
|
|
- 压缩与缓存:对静态资源启用 GZIP 与浏览器缓存。
|
||
|
|
- 限流与熔断:对上传/下载接口实施限流,异常时快速失败。
|
||
|
|
|
||
|
|
[本节为通用指导,不直接分析具体文件]
|
||
|
|
|
||
|
|
## 故障排查指南
|
||
|
|
- 上传失败:检查文件类型与大小限制、网络超时、MinIO 连通性。
|
||
|
|
- 分片丢失:核对 uploadId 与分片索引,查看分片状态记录。
|
||
|
|
- 预览失败:确认 KkFileView 服务可用性与文件格式支持。
|
||
|
|
- 下载慢:检查带宽、MinIO 延迟、是否命中预签名 URL。
|
||
|
|
- 权限问题:校验登录态、角色与数据范围。
|
||
|
|
- 清理任务:查看调度配置与日志,确认清理阈值合理。
|
||
|
|
|
||
|
|
**章节来源**
|
||
|
|
- [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)
|
||
|
|
- [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)
|
||
|
|
|
||
|
|
## 结论
|
||
|
|
文件模块以清晰的分层架构与完善的流程设计,提供了稳定高效的文件管理能力。通过分片上传、断点续传、并发上传与预览集成,满足企业级场景需求。配合 MinIO 与权限控制,确保数据安全与访问可控。建议在大规模使用时关注连接池、缓存与限流等性能优化点。
|
||
|
|
|
||
|
|
[本节为总结,不直接分析具体文件]
|
||
|
|
|
||
|
|
## 附录:接口清单与规范
|
||
|
|
|
||
|
|
### 接口清单
|
||
|
|
- 普通上传: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}
|
||
|
|
- 缩略图:GET /api/file/thumbnail/{id}
|
||
|
|
- 删除文件: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(可选)
|
||
|
|
- 删除参数:id、ids(批量)
|
||
|
|
- 响应格式:统一 Result 包装,包含 code、message、data
|
||
|
|
|
||
|
|
### 存储策略
|
||
|
|
- MinIO 桶命名:按业务域划分(如 file-prod、file-dev)
|
||
|
|
- 路径规则:/tenant/user/date/originalName
|
||
|
|
- 缩略图路径:/thumbnail/...
|
||
|
|
- 分片路径:/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 加速
|
||
|
|
|
||
|
|
### 错误处理机制
|
||
|
|
- 统一异常处理:BusinessErrorException、ResourceNotExistException
|
||
|
|
- 错误码:ResultCodeEnum 定义
|
||
|
|
- 重试策略:网络重试与指数退避
|
||
|
|
|
||
|
|
### 重试策略
|
||
|
|
- 上传分片:失败重试 3 次,间隔递增
|
||
|
|
- 下载:超时重试 1 次
|
||
|
|
- 预览:失败降级为原始文件下载
|
||
|
|
|
||
|
|
### 性能优化建议
|
||
|
|
- 分片大小与并发度调优
|
||
|
|
- 缩略图异步生成与缓存
|
||
|
|
- 预览服务集群与缓存
|
||
|
|
- 连接池与超时参数优化
|
||
|
|
- 限流与熔断保护
|
||
|
|
|
||
|
|
**章节来源**
|
||
|
|
- [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)
|
||
|
|
- [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)
|
||
|
|
- [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java)
|