# 分片上传 大文件分片上传:客户端把文件切成固定大小的分片逐个上传,服务端按索引合并并做 SHA256 校验。 支持**断点续传**(相同 `file_hash` + 大小 + 文件名的未完成会话自动续传)。 需站点开启 `enableChunk`(公共配置 `enableChunk` 返回 `true`)。 分片会话保留 24 小时。全部端点经审计中间件落库(action=upload)。 ## 上传流程 ```text POST /chunk/upload/init → upload_id, total_chunks POST /chunk/upload/{id}/{index} → 逐片上传(0 起,可并发) GET /chunk/upload/status/{id} → 断点续传时查进度 POST /chunk/upload/complete/{id} → 合并 + SHA256 → 取件码 DELETE /chunk/upload/{id} → 取消(可选) ``` ## 初始化:POST /chunk/upload/init **请求体**(JSON,亦兼容表单): | 参数 | 类型 | 必需 | 默认 | 说明 | |---|---|---|---|---| | `file_name` | string | ✅ | - | 文件名(会做清理与白名单校验) | | `file_size` | int | ✅ | - | 文件总字节数(>0;服务端按分片数校验上限) | | `chunk_size` | int | ❌ | `5242880`(5MB) | 每片大小(字节),硬上限 32MiB(超出 400「chunk_size 过大」) | | `file_hash` | string | ❌ | - | 整文件 SHA256(断点续传的匹配键) | **curl 示例**: ```bash curl -s -X POST http://localhost:8466/chunk/upload/init \ -H 'Content-Type: application/json' \ -d '{"file_name":"movie.mp4","file_size":15728640,"chunk_size":5242880,"file_hash":""}' ``` **成功响应**(200,新建会话): ```json { "code": 200, "msg": "ok", "data": { "existed": false, "upload_id": "3f6b8c2a4d5e6f708192a3b4c5d6e7f8", "chunk_size": 5242880, "total_chunks": 3, "uploaded_chunks": [] } } ``` **断点续传响应**(200,命中未完成会话):返回既有会话,`uploaded_chunks` 为已传分片索引列表, 客户端只需补传缺失分片(注意:`existed` 字段恒为 `false`,是否续传以 `upload_id` 复用且 `uploaded_chunks` 非空为准): ```json { "code": 200, "msg": "ok", "data": { "existed": false, "upload_id": "3f6b8c2a4d5e6f708192a3b4c5d6e7f8", "chunk_size": 5242880, "total_chunks": 3, "uploaded_chunks": [0, 1] } } ``` **错误响应**: ```json { "code": 400, "msg": "file_size 必须大于 0" } ``` ```json { "code": 403, "msg": "大小超过限制,最大为10.00 MB" } ``` ```json { "code": 403, "msg": "分片上传未启用" } ``` ## 上传分片:POST /chunk/upload/{uploadID}/{chunkIndex} 主路径(与参考实现语义一致)。`chunkIndex` 从 `0` 起。 **multipart 字段**:`chunk`(必需,该分片的二进制数据)。 **curl 示例**: ```bash split -b 5242880 movie.mp4 part- # 本地分片 curl -s -X POST http://localhost:8466/chunk/upload/3f6b8c2a4d5e6f708192a3b4c5d6e7f8/0 \ -F 'chunk=@./part-aa' ``` **成功响应**(200): ```json { "code": 200, "msg": "ok", "data": { "chunk_hash": "9af1…", "chunk_index": 0 } } ``` 重复上传已完成的分片(幂等跳过): ```json { "code": 200, "msg": "ok", "data": { "chunk_hash": "9af1…", "chunk_index": 0, "skipped": true } } ``` **错误响应**: ```json { "code": 404, "msg": "上传会话不存在" } ``` ```json { "code": 400, "msg": "无效的分片索引" } ``` ```json { "code": 400, "msg": "分片大小超过声明值: 最大 5242880, 实际 5300000" } ``` ```json { "code": 400, "msg": "缺少分片文件字段 chunk" } ``` ```json { "code": 403, "msg": "大小超过限制,最大为10.00 MB" } ``` > 约束:单分片 ≤ `chunk_size`(init 声明值)且 ≤ **32MiB 硬上限**(init 时 `chunk_size>33554432` 直接 400「chunk_size 过大」); > 总大小(init 按分片数上限、上传/合并按累计)受**动态策略上限**约束——`max_file_size>0` 时为其, > 否则回落 `uploadSize`(26.9 需求 ④⑩,管理端改后立即生效,超限清理会话);首个分片做 magic bytes > 防伪校验(403「文件内容校验失败:…」)。分片哈希由服务端计算;合并时与分片记录交叉校验,不一致报 400。 > > **enableChunk 开关**:管理端关闭分片上传后,`/chunk/upload/*` 全部端点返回 403「分片上传未启用」(后端强制,前端仅隐藏入口)。 ## 查询进度:GET /chunk/upload/status/{uploadID} ```bash curl -s http://localhost:8466/chunk/upload/status/3f6b8c2a4d5e6f708192a3b4c5d6e7f8 ``` **成功响应**(200): ```json { "code": 200, "msg": "ok", "data": { "upload_id": "3f6b8c2a4d5e6f708192a3b4c5d6e7f8", "file_name": "movie.mp4", "file_size": 15728640, "chunk_size": 5242880, "total_chunks": 3, "uploaded_chunks": [0, 1], "progress": 66.66666666666667 } } ``` ## 完成合并:POST /chunk/upload/complete/{uploadID} 全部分片到齐后调用。服务端按索引有序合并 + SHA256 校验,成功后创建分享并清理分片。 **请求体**(JSON,亦兼容表单): | 参数 | 类型 | 必需 | 默认 | 说明 | |---|---|---|---|---| | `expire_value` | int | ❌ | `1` | 过期值 | | `expire_style` | string | ❌ | `day` | 过期方式(同文件分享) | ```bash curl -s -X POST http://localhost:8466/chunk/upload/complete/3f6b8c2a4d5e6f708192a3b4c5d6e7f8 \ -H 'Content-Type: application/json' \ -d '{"expire_value":1,"expire_style":"day"}' ``` **成功响应**(200): ```json { "code": 200, "msg": "ok", "data": { "code": "R7T2K", "name": "movie.mp4" } } ``` **错误响应**: ```json { "code": 400, "msg": "分片不完整" } ``` ```json { "code": 400, "msg": "分片哈希校验失败,请重新上传" } ``` ```json { "code": 403, "msg": "大小超过限制,最大为10.00 MB" } ``` ## 取消上传:DELETE /chunk/upload/{uploadID} 清理分片文件与上传记录,释放容量预留。 ```bash curl -s -X DELETE http://localhost:8466/chunk/upload/3f6b8c2a4d5e6f708192a3b4c5d6e7f8 ``` ```json { "code": 200, "msg": "ok", "data": { "message": "上传已取消" } } ``` ```json { "code": 404, "msg": "上传会话不存在" } ```