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.
 
 
 
 
 
 

30 KiB

文件API

**本文引用的文件** - [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)

目录

  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:数据库映射(文件元信息)
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
  • FileApi.java
  • FileApiImpl.java
  • IFileInfoService.java
  • FileInfoServiceImpl.java
  • MinioConfig.java
  • FileProperties.java
  • KkFileViewClient.java
  • FileInfo.java
  • FileInfoMapper.java
  • OrphanChunkCleanupTask.java

章节来源

  • FileController.java
  • FileApi.java
  • FileApiImpl.java
  • IFileInfoService.java
  • FileInfoServiceImpl.java
  • MinioConfig.java
  • FileProperties.java
  • KkFileViewClient.java
  • FileInfo.java
  • FileInfoMapper.java
  • OrphanChunkCleanupTask.java

核心组件

  • FileController:暴露 REST 接口,统一接收请求并委派给 FileApi。
  • FileApi / FileApiImpl:定义并实现文件上传、下载、预览、删除、分片、续传、缩略图等核心流程。
  • IFileInfoService / FileInfoServiceImpl:文件元数据持久化、查询、状态管理与事务边界。
  • MinioConfig:MinIO 客户端配置与桶策略。
  • FileProperties:文件大小限制、允许类型、路径规则等配置项。
  • KkFileViewClient:调用第三方预览服务,生成预览链接或缩略图。
  • OrphanChunkCleanupTask:定时清理未完成的分片文件,释放空间。
  • FileInfo 实体与 Mapper:文件元信息表结构与数据访问。

章节来源

  • FileController.java
  • FileApi.java
  • FileApiImpl.java
  • IFileInfoService.java
  • FileInfoServiceImpl.java
  • MinioConfig.java
  • FileProperties.java
  • KkFileViewClient.java
  • OrphanChunkCleanupTask.java
  • FileInfo.java
  • FileInfoMapper.java

架构总览

整体采用“控制器-服务-存储/外部服务”的分层架构:

  • 控制器负责参数校验、鉴权与响应封装。
  • 服务层编排上传、下载、预览、删除等业务流程,协调 MinIO 与 KkFileView。
  • 配置层集中管理 MinIO、文件属性与调度任务。
  • 数据层通过 MyBatis-Plus 维护文件元信息。
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
  • FileApiImpl.java
  • MinioConfig.java
  • KkFileViewClient.java
  • FileInfoServiceImpl.java
  • FileInfo.java

详细组件分析

文件上传接口(普通上传)

  • 方法:POST
  • 路径:/api/file/upload
  • 请求体:multipart/form-data,字段 file(二进制文件)
  • 响应:文件基本信息(ID、名称、大小、URL、预览链接)
  • 校验:文件名白名单、大小限制、MIME 类型校验、重复检测
  • 存储:MinIO 直传,按日期/用户维度组织桶路径
  • 安全:鉴权拦截器校验登录态与权限
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
  • FileApiImpl.java
  • FileProperties.java
  • MinioConfig.java
  • FileInfoServiceImpl.java

章节来源

  • FileController.java
  • FileApiImpl.java
  • FileProperties.java
  • MinioConfig.java
  • 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 与分片索引去重,未上传分片可重试
  • 并发上传:客户端并行上传分片,服务端保证幂等与顺序无关
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
  • FileApiImpl.java
  • MultipartInitDTO.java
  • UploadSession.java
  • FileInfoServiceImpl.java
  • MinioConfig.java

章节来源

  • FileController.java
  • FileApiImpl.java
  • MultipartInitDTO.java
  • UploadSession.java
  • FileInfoServiceImpl.java
  • MinioConfig.java

文件下载接口

  • 方法:GET
  • 路径:/api/file/download/{id}
  • 参数:id(文件ID)、可选签名参数(如过期时间)
  • 响应:文件流(Content-Disposition 设置下载名)
  • 权限:需具备文件读取权限;支持私有桶访问(预签名 URL)
  • 缓存:浏览器缓存控制头由服务端设置
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
  • FileApiImpl.java
  • MinioConfig.java

章节来源

  • FileController.java
  • FileApiImpl.java
  • MinioConfig.java

文件预览接口

  • 方法:GET
  • 路径:/api/file/preview/{id}
  • 功能:根据文件类型调用 KkFileView 生成预览链接或直接返回预览页面
  • 参数:id(文件ID)、可选格式参数(pdf/html/img)
  • 响应:预览页面或跳转链接
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
  • FileApiImpl.java
  • KkFileViewClient.java

章节来源

  • FileController.java
  • FileApiImpl.java
  • KkFileViewClient.java

文件删除接口

  • 方法:DELETE
  • 路径:/api/file/delete/{id}
  • 权限:仅文件所有者或管理员可删除
  • 行为:删除 MinIO 对象与数据库元信息;软删除标记可选
flowchart TD
Start(["进入删除接口"]) --> Auth["鉴权与所有权校验"]
Auth --> Exists{"文件存在?"}
Exists --> |否| NotFound["返回资源不存在"]
Exists --> |是| DeleteMinIO["删除 MinIO 对象"]
DeleteMinIO --> DeleteDB["删除/标记文件元信息"]
DeleteDB --> Ok["返回删除成功"]
NotFound --> End(["结束"])
Ok --> End

图表来源

  • FileController.java
  • FileApiImpl.java
  • FileInfoServiceImpl.java

章节来源

  • FileController.java
  • FileApiImpl.java
  • FileInfoServiceImpl.java

缩略图生成

  • 触发时机:上传成功后异步生成缩略图(图片类型)
  • 存储位置:MinIO 同桶下 thumbnail 目录
  • 接口:GET /api/file/thumbnail/{id}
  • 策略:若缩略图不存在则实时生成并缓存;支持尺寸参数
flowchart TD
Start(["缩略图请求"]) --> CheckCache["检查缩略图是否存在"]
CheckCache --> |存在| ReturnThumb["返回缩略图"]
CheckCache --> |不存在| GenThumb["生成缩略图"]
GenThumb --> SaveThumb["保存至 MinIO"]
SaveThumb --> ReturnThumb

图表来源

  • FileApiImpl.java
  • MinioConfig.java

章节来源

  • FileApiImpl.java
  • MinioConfig.java

批量操作接口

  • 批量删除:POST /api/file/batch/delete
    • 参数:ids(数组)
    • 行为:逐个校验权限后执行删除
  • 批量下载:POST /api/file/batch/download
    • 参数:ids(数组)
    • 行为:打包为 ZIP 流返回(大文件建议分页或异步任务)
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
  • FileApiImpl.java

章节来源

  • FileController.java
  • FileApiImpl.java

临时链接生成

  • 场景:私有桶访问、外链分享
  • 接口:GET /api/file/presigned-url?fileId=xxx&expires=秒数
  • 行为:生成 MinIO 预签名 URL,带过期时间与访问权限
  • 安全:结合鉴权与访问控制策略
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
  • FileApiImpl.java
  • MinioConfig.java

章节来源

  • FileController.java
  • FileApiImpl.java
  • MinioConfig.java

分片残留清理任务

  • 任务:定时扫描未完成上传的会话与分片,清理无效数据
  • 策略:超过保留时间的会话自动清理,避免磁盘膨胀
  • 配置:调度周期与保留时长在配置中管理
flowchart TD
Start(["定时任务启动"]) --> Scan["扫描未完成会话"]
Scan --> Filter{"是否超期?"}
Filter --> |否| Next["跳过"]
Filter --> |是| Cleanup["清理分片与会话"]
Cleanup --> Log["记录清理日志"]
Log --> End(["结束"])
Next --> End

图表来源

  • OrphanChunkCleanupTask.java
  • SchedulingConfig.java

章节来源

  • OrphanChunkCleanupTask.java
  • SchedulingConfig.java

依赖关系分析

  • FileController 依赖 FileApi,解耦 HTTP 与业务逻辑。
  • FileApiImpl 依赖 MinioConfig(MinIO 客户端)、FileProperties(配置)、KkFileViewClient(预览)。
  • FileInfoServiceImpl 依赖 FileInfo 实体与 FileInfoMapper(MyBatis-Plus)。
  • OrphanChunkCleanupTask 依赖 MinIO 与 FileInfoService 进行清理。
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
  • FileApiImpl.java
  • MinioConfig.java
  • FileProperties.java
  • KkFileViewClient.java
  • FileInfoServiceImpl.java
  • FileInfo.java
  • FileInfoMapper.java

章节来源

  • FileController.java
  • FileApiImpl.java
  • MinioConfig.java
  • FileProperties.java
  • KkFileViewClient.java
  • FileInfoServiceImpl.java
  • FileInfo.java
  • FileInfoMapper.java

性能考虑

  • 分片上传:合理设置分片大小(建议 5~10MB),提升大文件上传稳定性与并发度。
  • 并发上传:客户端并行上传分片,服务端幂等处理,避免重复写入。
  • 流式下载:使用流式响应减少内存占用,支持 Range 断点续传。
  • 缩略图:异步生成与缓存,命中缓存直接返回。
  • 预览服务:KkFileView 集群部署与缓存加速,避免单点瓶颈。
  • 连接池:MinIO 客户端连接池与超时参数调优。
  • 压缩与缓存:对静态资源启用 GZIP 与浏览器缓存。
  • 限流与熔断:对上传/下载接口实施限流,异常时快速失败。

[本节为通用指导,不直接分析具体文件]

故障排查指南

  • 上传失败:检查文件类型与大小限制、网络超时、MinIO 连通性。
  • 分片丢失:核对 uploadId 与分片索引,查看分片状态记录。
  • 预览失败:确认 KkFileView 服务可用性与文件格式支持。
  • 下载慢:检查带宽、MinIO 延迟、是否命中预签名 URL。
  • 权限问题:校验登录态、角色与数据范围。
  • 清理任务:查看调度配置与日志,确认清理阈值合理。

章节来源

  • FileApiImpl.java
  • KkFileViewClient.java
  • MinioConfig.java
  • 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
  • FileApiImpl.java
  • FileProperties.java
  • MinioConfig.java
  • KkFileViewClient.java
  • FileInfoServiceImpl.java
  • FileConstants.java