题库批量(文件)导入接口文档(补充)
接上一回 补充接回,
------->《题库批量(文件)导入的全链路优化实践》
------->《题库批量(文件)导入的具体代码实现》
补充一下接口文档,这样子可以跟好得理清楚逻辑
接口概述
用于支持大文件(如 Excel 题库)的分片上传、异步解析及批量入库,包含分片初始化、分片上传、合并分片、任务状态查询 4 个核心接口。
1. 初始化分片上传
接口说明
前端选择文件后,先调用此接口获取分片上传凭证(uploadId)和分片总数,用于后续分片切割和上传。
- 请求 URL:
/api/question/import/multipart/init
- 请求方式:
POST
- Content-Type:
application/json
请求参数(Request Body)
将参数表格转换为Markdown语法如下:
参数表格
参数名 | 类型 | 是否必填 | 说明 |
---|---|---|---|
fileName | String | 是 | 文件名(含后缀),如 “高中数学题库.xlsx” |
fileMd5 | String | 是 | 文件 MD5 值(前端计算,用于唯一标识文件,支持断点续传) |
fileSize | Long | 是 | 文件总大小(单位:字节),用于计算分片总数(分片大小固定为 5MB) |
表格内容严格遵循Markdown语法规则,层级清晰,无多余包装符号。
响应参数(Response Body)
统一响应格式为Result<InitMultipartResponse>
,结构如下:
以下是转换后的后的 Markdown 表格格式组织的内容:
一级字段
字段名 | 类型 | 说明 |
---|---|---|
code | Int | 响应码(0:成功,1:失败) |
msg | String | 响应消息 |
data | Object | 响应数据(见下表) |
data 字段详情
以下是符合Markdown语法规范的表格形式:
参数表格
参数名 | 类型 | 说明 |
---|---|---|
uploadId | String | -suppression 分片上传唯一标识(OSS 返回,后续上传分片和合并需使用) |
partCount | Int | 分片总数(前端需按此数量切割文件,如 100MB 文件→20 片,每片 5 MB) |
示例
请求示例:
{"fileName": "高中数学题库.xlsx","fileMd5": "a1b2c3d4e5f67890abcdef1234567890","fileSize": 104857600 // 100MB(100*1024*1024)
}
响应示例:
{"code": 0,"msg": "操作成功","data": {"uploadId": "7F26866A168A4B9A8F6A7D8F7A6B5C4D","partCount": 20}
}
2. 上传单个分片
接口说明
前端将文件按partCount切割为多个分片后,循环调用此接口上传每个分片(从 1 到partCount)。
- 请求 URL:
/api/question/import/multipart/upload
- 请求方式:
POST
- Content-Type:
application/octet-stream
(二进制流)
请求参数(Request Param + Body)
参数位置 | 参数名 | 类型 | 是否必填 | 说明 |
---|---|---|---|---|
Query | uploadId | String | 是 | 分片上传标识(从初始化接口获取) |
Query | partNumber | Int | 是 | 分分片序号(从 1 开始,如 1、2、…、20) |
Query | fileMd5 | String | 是 | 文件 MD5 值(与初始化时一致) |
Query | fileName | String | 是 | 文件名(与初始化时一致) |
Body | partData | Byte[] | 是 | parte binario 数据(每片大小≤5MB,最后一片可小于 5MB) |
响应参数(Response Body)
统一响应格式为Result<Void>
,结构如下:
字段名 | 类型 | 说明 |
---|---|---|
code | Int | 响应码(0:成功,1:失败) |
msg | String | 响应消息(如“分片上传成功 environ) |
示例
请求示例:
Query 参数:uploadId=7F26866A168A4B9A8F6A7D8F7A6B5C4D&partNumber=1&fileMd5=a1b2c3d4e5f67890abcdef1234567890&fileName=高中数学题库.xlsx
Body:第 1 片的二进制数据(5MB)
响应示例:
{"code": 0,"msg": "操作成功","data": null
}
3. 合并分片并创建导入任务
接口说明
所有分片上传完成后,调用此接口通知后端合并分片为完整文件,并创建异步导入任务(返回任务 ID 供查询进度)。
- 请求 URL:
/api/question/import/multipart/complete
- 请求方式:
POST
- Content-Type:
application/x-www-form-urlencoded
请求参数(Request Param)
玩法烹饪 | 参数名 | 类型 | 是否必填 | 说明 |
---|---|---|---|---|
uploadId | String | 是 | 分片上传标识(与初始化时一致) | |
fileMd5 | String | 是 | 文件 MD5 值(与初始化时一致) | |
fileName | String | 是 | 文件名(与初始化时一致) |
响应参数(Response Body)
统一响应格式为Result<String>
,结构如下:
字段名 | 类型 | 说明 |
---|---|---|
code | Int | 响应码(0:成功,1:失败) |
msg | String | 响应消息 |
data | String | 任务 ID(用于查询导入进度) |
示例
请求示例:
Query 参数:uploadId=7F26866A168A4B9A8F6A7D8F7A6B5C4D&fileMd5=a1b2c3d4e5f67890abcdef1234567890&fileName=高中数学题库.xlsx
响应示例:
{"code": 0,"msg": "操作成功","data": "9f8e7d6c5b4a3b2c1d0e9f8e7d6c5b4a" // 任务ID
}
4. 查询任务状态
接口说明
前端通过任务 ID 轮询调用此接口,获取导入任务的实时状态(处理中 / 成功 / 失败)及结果。
- 请求 URL:
/api/question/import/task/status/{taskId}
- 请求方式:
GET
- 请求参数(Path Param)
参数名 | 类型 | 是否必填 | 说明 |
---|---|---|---|
taskId | String | 是 | 任务 ID(从合并接口获取) |
响应参数(Response Body)
统一响应格式为Result<TaskStatusDTO>
,结构如下:
一级字段 | 类型 | 说明 |
---|---|---|
code | Int | 响应码(0:成功,1:失败) |
msg | String | 响应消息 |
data | Object | 任务状态详情(见下表) |
data字段详情:
参数名 | 类型 | 说明 |
---|---|---|
taskId | String | 任务 ID(与请求一致) |
status | String | 任务状态:processing (处理中)、success (成功)、failed (失败)、not_found (任务不存在) |
total | Int | 成功导入的试题总数(仅 status=success 时返回) |
errorMsg | String | 错误信息(仅 status=failed 时返回,如解析失败原因) |
示例
请求示例:
URL:/api/question/import/task/status/9f8e7d6c5b4a3b2c1d0e9f8e7d6c5b4a
响应示例(处理中):
{"code": 0,"msg": "操作成功","data": {"taskId": "9f8e7d6c5b4a3b2c1d0e9f8e7d6c5b4a","status": "processing"}
}
响应示例(成功):
{"code": 0,"msg": "操作成功","data": {"taskId": "9f8e7d6c5b4a3b2c1d0e9f8e7d6c5b4a","status": "success","total": 5000 // 成功导入5000条试题}
}
响应示例(失败):
{"code": 0,"msg": "操作成功","data": {"taskId": "9f8e7d6c5b4a3b2c1d0e9f8e7d6c5b4a","status": "failed","errorMsg": "Excel格式错误:第10行缺少答案字段"}
}
接口调用流程
- 前端计算文件 MD5、获取文件大小,调用「初始化分片上传」接口,得到uploadId和partCount;
- 按partCount切割文件为分片(每片 5MB),循环调用「上传单个分片」接口,确保所有分片上传成功;
- 调用「合并分片并创建导入任务」接口,得到
taskId
; - 轮询调用「查询任务状态」接口,直到
status
为success或failed
,展示结果给用户。
异常处理说明
- 若分片上传失败(如网络中断),前端可重新调用「上传单个分片」接口,仅重传失败的分片(基于partNumber);
- 若任务状态为failed,可通过errorMsg提示用户修正文件后重新上传;
- 接口返回code=1时,msg字段会说明具体错误原因(如 “文件 MD5 不匹配”“分片序号超出范围”)。