196 lines
4.9 KiB
Markdown
196 lines
4.9 KiB
Markdown
# 完成分片上传并合并文件
|
||
|
||
## 接口信息
|
||
|
||
- **接口名称**: 完成分片上传并合并文件
|
||
- **接口路径**: /file/completeUpload
|
||
- **请求方法**: POST
|
||
- **模块归属**: file
|
||
- **版本号**: v1.0.0
|
||
- **创建日期**: 2026-01-18
|
||
- **最后更新**: 2026-01-18
|
||
|
||
## 功能描述
|
||
|
||
完成分片上传并合并所有分片为一个完整的文件。需要提供所有分片的 ETag 信息,系统会验证并合并分片,同时在数据库中创建文件记录。
|
||
|
||
## 请求参数
|
||
|
||
### 表单参数
|
||
|
||
| 参数名 | 类型 | 必填 | 描述 | 示例 |
|
||
|--------|------|------|------|------|
|
||
| uploadId | String | 是 | 上传 ID,由初始化分片上传接口返回 | 1234567890abcdef |
|
||
| filePath | String | 是 | 文件路径,由初始化分片上传接口返回 | /upload/2026/01/18/1234567890_large-file.zip |
|
||
| fileSize | Long | 是 | 文件总大小(字节) | 1073741824 |
|
||
| fileName | String | 是 | 文件名 | large-file.zip |
|
||
|
||
### 请求体 (JSON)
|
||
|
||
```json
|
||
[
|
||
{
|
||
"partNumber": 1,
|
||
"eTag": "\"d41d8cd98f00b204e9800998ecf8427e\""
|
||
},
|
||
{
|
||
"partNumber": 2,
|
||
"eTag": "\"098f6bcd4621d373cade4e832627b4f6\""
|
||
}
|
||
]
|
||
```
|
||
|
||
| 参数名 | 类型 | 必填 | 描述 | 示例 |
|
||
|--------|------|------|------|------|
|
||
| partNumber | Integer | 是 | 分片序号 | 1 |
|
||
| eTag | String | 是 | 分片的 ETag 值 | "d41d8cd98f00b204e9800998ecf8427e" |
|
||
|
||
## 响应数据
|
||
|
||
### 成功响应
|
||
|
||
**HTTP 状态码**: 200 OK
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "操作成功",
|
||
"data": {
|
||
"fileId": 1,
|
||
"fileName": "large-file.zip",
|
||
"filePath": "/upload/2026/01/18/1234567890_large-file.zip",
|
||
"fileSize": 1073741824,
|
||
"fileType": "zip",
|
||
"storageType": "minio",
|
||
"createBy": "admin",
|
||
"createTime": "2026-01-18T10:00:00",
|
||
"updateBy": "admin",
|
||
"updateTime": "2026-01-18T10:00:00",
|
||
"delFlag": "0"
|
||
}
|
||
}
|
||
```
|
||
|
||
| 字段名 | 类型 | 描述 | 示例 |
|
||
|--------|------|------|------|
|
||
| fileId | Long | 文件 ID | 1 |
|
||
| fileName | String | 文件名 | large-file.zip |
|
||
| filePath | String | 文件路径 | /upload/2026/01/18/1234567890_large-file.zip |
|
||
| fileSize | Long | 文件大小(字节) | 1073741824 |
|
||
| fileType | String | 文件类型 | zip |
|
||
| storageType | String | 存储类型 | minio |
|
||
| createBy | String | 创建人 | admin |
|
||
| createTime | String | 创建时间 | 2026-01-18T10:00:00 |
|
||
| updateBy | String | 更新人 | admin |
|
||
| updateTime | String | 更新时间 | 2026-01-18T10:00:00 |
|
||
| delFlag | String | 删除标志 | 0 |
|
||
|
||
### 失败响应
|
||
|
||
**HTTP 状态码**: 500 Internal Server Error
|
||
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"message": "分片信息不能为空",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"message": "分片信息格式不正确",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"message": "合并分片失败:未获取到最终文件路径",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
## 接口示例
|
||
|
||
### 请求示例
|
||
|
||
```bash
|
||
curl -X POST "http://localhost:8080/file/completeUpload" \
|
||
-H "Authorization: Bearer [token]" \
|
||
-H "Content-Type: application/json" \
|
||
-F "uploadId=1234567890abcdef" \
|
||
-F "filePath=/upload/2026/01/18/1234567890_large-file.zip" \
|
||
-F "fileSize=1073741824" \
|
||
-F "fileName=large-file.zip" \
|
||
-d '[
|
||
{
|
||
"partNumber": 1,
|
||
"eTag": "\"d41d8cd98f00b204e9800998ecf8427e\""
|
||
},
|
||
{
|
||
"partNumber": 2,
|
||
"eTag": "\"098f6bcd4621d373cade4e832627b4f6\""
|
||
}
|
||
]'
|
||
```
|
||
|
||
### 响应示例
|
||
|
||
**成功**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "操作成功",
|
||
"data": {
|
||
"fileId": 1,
|
||
"fileName": "large-file.zip",
|
||
"filePath": "/upload/2026/01/18/1234567890_large-file.zip",
|
||
"fileSize": 1073741824,
|
||
"fileType": "zip",
|
||
"storageType": "minio",
|
||
"createBy": "admin",
|
||
"createTime": "2026-01-18T10:00:00",
|
||
"updateBy": "admin",
|
||
"updateTime": "2026-01-18T10:00:00",
|
||
"delFlag": "0"
|
||
}
|
||
}
|
||
```
|
||
|
||
## 错误处理
|
||
|
||
- 分片信息为空时返回错误
|
||
- 分片信息格式不正确时返回错误
|
||
- 分片序号或 ETag 无效时返回错误
|
||
- 合并分片失败时返回错误
|
||
- 未获取到最终文件路径时返回错误
|
||
|
||
## 注意事项
|
||
|
||
- 分片信息必须按 partNumber 从小到大排序
|
||
- 分片序号必须从 1 开始,连续递增
|
||
- 所有分片的 ETag 都必须提供
|
||
- 合并成功后会自动在数据库中创建文件记录
|
||
- 使用系统配置的默认存储桶
|
||
- 文件类型从文件名中提取(扩展名)
|
||
|
||
## 相关接口
|
||
|
||
- [初始化分片上传](./0006-init-upload.md) - 初始化分片上传
|
||
- [上传文件分片](./0007-upload-chunk.md) - 上传文件分片
|
||
- [统一上传接口](./0002-upload.md) - 普通文件上传(非分片)
|
||
|
||
## 实现细节
|
||
|
||
- 使用 `StorageService.completeMultipartUpload()` 合并分片
|
||
- 验证并排序分片信息
|
||
- 过滤无效的分片信息
|
||
- 创建 `SysFileInfo` 实体并保存到数据库
|
||
- 使用 `SecurityUtils.getUsername()` 获取当前用户
|
||
- 文件类型从文件名的扩展名中提取
|
||
- 使用系统配置的默认存储桶
|