# 文件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:数据库映射(文件元信息) ```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)