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.

425 lines
22 KiB

1 month ago
# 文件上传下载
<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)
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.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)
- [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)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java)
- [application.yml](file://crm-app/src/main/resources/application.yml)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录:API 接口规范与示例](#附录api-接口规范与示例)
## 简介
本技术文档围绕文件上传下载能力,系统性阐述单文件上传、分片上传与断点续传的实现机制,覆盖 MultipartFile 处理流程、会话管理、进度跟踪、并发控制、重试与异常恢复策略,以及文件校验规则(大小限制、类型验证等)与安全机制。同时提供完整的 API 接口规范、请求响应示例和错误处理方案,并给出客户端集成建议与最佳实践。
## 项目结构
文件模块位于 crm-file 子模块中,采用分层设计:
- Controller 层:对外暴露 REST 接口,统一返回 Result 包装体
- Service 层:封装业务逻辑,协调存储与元数据服务
- Domain 层:实体与 DTO,承载上传会话、文件信息、下载参数等
- Config 层:MinIO 存储配置、文件大小限制、调度任务开关等
- Task 层:清理孤立分片的定时任务
- Base 模块:统一的异常处理、结果封装、安全工具等
```mermaid
graph TB
Client["客户端"] --> FC["FileController<br/>REST 接口"]
FC --> FA["FileApi<br/>抽象接口"]
FA --> FAI["FileApiImpl<br/>实现类"]
FAI --> FS["IFileInfoService / FileInfoServiceImpl<br/>元数据服务"]
FAI --> MINIO["MinIO 存储<br/>MinioConfig"]
FAI --> TASK["OrphanChunkCleanupTask<br/>分片清理"]
FS --> DB["数据库<br/>FileInfoMapper"]
FC --> RESULT["Result / ResultCodeEnum<br/>统一响应"]
FC --> EXC["GlobalExceptionHandlerAdvice<br/>全局异常处理"]
```
图表来源
- [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)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.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)
- [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)
- [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)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
## 核心组件
- FileController:定义上传、分片上传、断点续传、下载、进度查询等 REST 端点,统一使用 Result 包装响应
- FileApi / FileApiImpl:上传下载的核心业务编排,包含分片初始化、分片合并、元数据持久化、存储对象操作
- IFileInfoService / FileInfoServiceImpl:文件元数据的增删改查,维护 FileInfo 实体与数据库映射
- MinioConfig / FileProperties:MinIO 连接参数、桶名、访问密钥、文件大小限制、分片大小等配置
- OrphanChunkCleanupTask:定时扫描并清理长时间未完成的孤立分片,释放存储空间
- Result / ResultCodeEnum / GlobalExceptionHandlerAdvice:统一响应体、错误码、全局异常捕获与转换
章节来源
- [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)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
## 架构总览
整体采用“控制器-服务-存储”的分层架构,结合 MinIO 作为对象存储,元数据落库,分片上传通过会话管理保证可靠性与可恢复性。
```mermaid
sequenceDiagram
participant C as "客户端"
participant FC as "FileController"
participant FA as "FileApiImpl"
participant FS as "FileInfoServiceImpl"
participant MINIO as "MinIO"
participant DB as "数据库"
C->>FC : "POST /upload/init (分片初始化)"
FC->>FA : "initMultipart(params)"
FA->>MINIO : "创建分片桶/命名空间"
FA-->>C : "返回 uploadId/sessionId"
loop "分片上传"
C->>FC : "POST /upload/chunk (携带分片数据)"
FC->>FA : "uploadChunk(uploadId, chunkIndex, data)"
FA->>MINIO : "PUT Object(分片)"
FA-->>C : "返回分片状态"
end
C->>FC : "POST /upload/complete (完成合并)"
FC->>FA : "completeMultipart(uploadId, chunks)"
FA->>MINIO : "合并分片为完整对象"
FA->>FS : "保存 FileInfo 元数据"
FS->>DB : "INSERT/UPDATE FileInfo"
FA-->>C : "返回文件ID/URL"
C->>FC : "GET /download/{fileId}"
FC->>FA : "download(fileId)"
FA->>FS : "查询 FileInfo"
FS->>DB : "SELECT FileInfo"
FA->>MINIO : "GetObject(流式下载)"
FA-->>C : "返回文件流"
```
图表来源
- [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)
- [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java)
## 详细组件分析
### 单文件上传流程(MultipartFile)
- 入口:FileController 接收 MultipartFile 参数
- 校验:基于 FileProperties 的大小限制与类型白名单进行校验
- 存储:调用 FileApiImpl 将文件写入 MinIO,生成唯一对象键
- 元数据:FileInfoServiceImpl 持久化文件元数据(名称、大小、类型、路径等)
- 响应:统一 Result 包装成功或错误信息
```mermaid
flowchart TD
Start(["开始"]) --> Validate["校验文件大小/类型"]
Validate --> |通过| SaveToMinIO["写入 MinIO"]
Validate --> |失败| Error["返回错误码"]
SaveToMinIO --> PersistMeta["持久化 FileInfo"]
PersistMeta --> Return["返回 Result{fileId,url}"]
Error --> 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)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.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)
- [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java)
### 分片上传与断点续传
- 初始化:客户端调用初始化接口获取 uploadId/sessionId,服务端建立分片会话
- 分片上传:客户端按序或乱序上传分片,服务端记录已上传分片索引
- 断点续传:支持重复上传同一分片,服务端幂等处理;未完成会话可继续补传
- 合并完成:所有分片上传完成后触发合并,生成最终对象并更新元数据
- 进度跟踪:可通过 session 查询各分片上传状态,计算总体进度
```mermaid
classDiagram
class UploadSession {
+string sessionId
+string uploadId
+long fileSize
+int chunkSize
+Set~Integer~ uploadedChunks
+boolean completed
+timestamp createdAt
+timestamp updatedAt
}
class FileInfo {
+string id
+string name
+long size
+string type
+string storageKey
+string url
+timestamp createdAt
+timestamp updatedAt
}
class FileApiImpl {
+initMultipart(params) UploadSession
+uploadChunk(uploadId, index, data) boolean
+completeMultipart(uploadId, chunks) FileInfo
-validateChunk(index, size) boolean
-mergeChunks(uploadId) void
}
class FileInfoServiceImpl {
+saveFileInfo(info) FileInfo
+getFileInfo(id) FileInfo
+updateFileInfo(id, info) FileInfo
}
FileApiImpl --> UploadSession : "创建/维护"
FileApiImpl --> FileInfoServiceImpl : "持久化元数据"
FileInfoServiceImpl --> FileInfo : "CRUD"
```
图表来源
- [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java)
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.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)
章节来源
- [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java)
- [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java)
- [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
### 下载流程
- 入口:FileController 接收 fileId 或下载参数
- 校验:检查权限与文件存在性
- 读取:从 MinIO 流式读取对象内容
- 响应:以流形式返回,设置合适的 Content-Type 与文件名
```mermaid
sequenceDiagram
participant C as "客户端"
participant FC as "FileController"
participant FA as "FileApiImpl"
participant FS as "FileInfoServiceImpl"
participant MINIO as "MinIO"
C->>FC : "GET /download?fileId=xxx"
FC->>FA : "download(fileId)"
FA->>FS : "查询 FileInfo"
FS-->>FA : "返回 FileInfo"
FA->>MINIO : "GetObject(storageKey)"
MINIO-->>FA : "返回输入流"
FA-->>C : "返回文件流"
```
图表来源
- [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)
- [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)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
### 会话管理与进度跟踪
- 会话模型:UploadSession 记录 sessionId、uploadId、分片集合、完成状态、时间戳
- 进度计算:根据已上传分片数量与总分片数计算百分比
- 并发控制:分片上传允许乱序到达,服务端以分片索引去重
- 超时清理:OrphanChunkCleanupTask 定期清理长时间未完成的会话与分片
```mermaid
flowchart TD
Init["初始化会话"] --> Upload["上传分片"]
Upload --> Track{"是否全部上传?"}
Track --> |否| Upload
Track --> |是| Merge["合并分片"]
Merge --> Complete["标记会话完成"]
Complete --> Cleanup["定时清理孤立会话"]
```
图表来源
- [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
章节来源
- [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
### 文件校验与安全机制
- 大小限制:通过 FileProperties 配置最大文件大小,防止超大文件导致内存溢出
- 类型验证:白名单校验 MIME 类型或扩展名,拒绝非法类型
- 权限控制:结合 SecurityUtils 获取当前用户上下文,确保上传/下载权限
- 异常处理:GlobalExceptionHandlerAdvice 统一捕获并转换为标准错误码
章节来源
- [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java)
- [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
### 分片上传的并发控制、重试与异常恢复
- 并发控制:分片上传接口无状态,支持多实例并行上传;服务端以 uploadId+chunkIndex 唯一标识分片
- 重试机制:客户端对失败分片进行指数退避重试,服务端幂等处理重复分片
- 异常恢复:网络中断后重新发起分片上传,已完成分片无需重复上传;会话超时由清理任务回收
章节来源
- [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
## 依赖关系分析
- FileController 依赖 FileApi(抽象),实际由 FileApiImpl 实现
- FileApiImpl 依赖 MinIO 存储与 FileInfoService 元数据服务
- FileInfoServiceImpl 依赖数据库 Mapper 进行持久化
- 统一响应与异常处理由 base 模块提供
```mermaid
graph LR
FC["FileController"] --> FA["FileApi"]
FA --> FAI["FileApiImpl"]
FAI --> MINIO["MinIO"]
FAI --> FS["FileInfoServiceImpl"]
FS --> DB["数据库"]
FC --> RESULT["Result/ResultCodeEnum"]
FC --> EXC["GlobalExceptionHandlerAdvice"]
```
图表来源
- [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)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.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)
- [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
## 性能考量
- 分片大小:合理设置分片大小(如 5MB~50MB)平衡网络开销与合并成本
- 并发度:客户端分片上传并发度建议 3~10,避免服务器资源耗尽
- 流式处理:下载使用流式 IO,避免大文件全量加载到内存
- 缓存策略:热点文件的 URL 或元数据可考虑短期缓存
- 存储优化:MinIO 桶分区与对象键前缀设计提升检索效率
[本节为通用指导,不直接分析具体文件]
## 故障排查指南
- 上传失败:检查文件大小与类型是否符合配置;查看全局异常处理器返回的错误码
- 分片丢失:确认客户端是否正确重试;检查会话是否被清理任务提前回收
- 下载失败:核对 fileId 是否存在;检查 MinIO 对象键与权限
- 进度不更新:确认分片上传接口是否成功返回;检查会话状态是否标记完成
章节来源
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
- [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java)
- [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java)
## 结论
本文件上传下载模块通过分层架构与 MinIO 存储实现了高可靠、可扩展的单文件与分片上传能力,配合会话管理与定时清理保障断点续传与资源回收。统一响应与异常处理提升了可观测性与可维护性。建议在生产环境合理配置分片大小、并发度与超时策略,并结合监控告警保障稳定性。
[本节为总结,不直接分析具体文件]
## 附录:API 接口规范与示例
### 接口总览
- 单文件上传:POST /upload
- 分片初始化:POST /upload/init
- 分片上传:POST /upload/chunk
- 分片完成:POST /upload/complete
- 文件下载:GET /download
- 进度查询:GET /upload/status
### 请求与响应示例
- 单文件上传
- 请求:multipart/form-data,字段 file
- 响应:Result{code,msg,data:{fileId,url}}
- 分片初始化
- 请求:body 包含 fileName、fileSize、chunkSize
- 响应:Result{data:{sessionId,uploadId}}
- 分片上传
- 请求:multipart/form-data,字段 chunkIndex、chunkData
- 响应:Result{data:{uploaded:true}}
- 分片完成
- 请求:body 包含 uploadId、chunks[]
- 响应:Result{data:{fileId,url}}
- 文件下载
- 请求:query fileId
- 响应:二进制流,Content-Disposition 含文件名
- 进度查询
- 请求:query sessionId
- 响应:Result{data:{progress:百分比,uploadedChunks:数量}}
### 错误处理
- 统一错误码:ResultCodeEnum 定义业务错误码
- 全局异常:GlobalExceptionHandlerAdvice 捕获异常并返回标准错误格式
- 常见错误:文件过大、类型不支持、会话不存在、分片缺失、权限不足
章节来源
- [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java)
- [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java)
- [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java)
- [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java)
### 客户端集成建议与最佳实践
- 分片大小:默认 5MB~10MB,根据网络状况调整
- 并发控制:限制并发数为 3~10,避免阻塞线程池
- 重试策略:指数退避 + 最大重试次数,区分可重试与不可重试错误
- 进度反馈:轮询进度接口,展示上传进度条
- 安全性:校验文件类型与大小,服务端二次校验,避免越权访问
- 稳定性:断网恢复后从最后一个成功分片继续上传,避免重复传输
[本节为通用指导,不直接分析具体文件]