8.4 文件上传接口
概述
上传接口统一 multipart:POST /api/upload/uploadFile(单文件)与 uploadFiles(多文件),字段名 file。返回可预览 URL 与入库形态 Path。两段式协议详见 7.1 文件上传全流程。
接口定义
text
POST /api/upload/uploadFile 权限 sys:upload:file multipart 字段名 file
POST /api/upload/uploadFiles 权限 sys:upload:files 多文件
入参 type=image 时按图片规则校验(扩展名 + 魔数嗅探),否则按普通文件multipart 标签约定:*ghttp.UploadFile + p:"file"。
请求示例
sh
curl -X POST http://127.0.0.1:8000/api/upload/uploadFile \
-H "Authorization: Bearer <access_token>" \
-F "file=@avatar.png" \
-F "type=image"响应结构
json
{
"code": 0, "ok": true, "msg": "操作成功",
"data": {
"originalName": "avatar.png",
"fileExtension": "png",
"fileType": "image/png",
"fileSize": 102400,
"fileName": "a1b2c3....png",
"filePath": "temp/20261018/a1b2c3....png",
"fileUrl": "http://file.example.com/temp/20261018/a1b2c3....png"
}
}| 字段 | 用途 |
|---|---|
| originalName | 原始文件名(前端展示/回显用) |
| fileExtension | 扩展名(小写,无点) |
| fileType | MIME 类型(按文件头内容嗅探,识别不出为 application/octet-stream) |
| fileSize | 文件大小(字节) |
| fileName | 存储文件名(= filePath 的 basename,32位随机.ext) |
| filePath | 相对 uploadDir 路径(入库形态;表单保存时转正) |
| fileUrl | 可直接预览的完整地址(domainUrl 拼接) |
校验失败场景
| 场景 | 响应 |
|---|---|
| 超过 maxSize(默认 10MB) | code=1,msg 提示大小超限 |
| 扩展名不在白名单 | code=1,msg 提示类型不允许 |
| type=image 但魔数非 image/* | code=1,拒绝(防改后缀伪造) |
| 未登录/令牌无效 | code=401 |
| 无权限 | code=403 |
| 触发限流 | code=429 |
两段式协议(对接要点)
text
上传阶段:只落 temp 目录(upload/temp/日期/随机名)
前端持有 url;表单字段存 url 或 path
保存阶段:业务接口(userAdd/articleAdd/...)的 spec.saveTransform
自动 SaveFromTemp 转正到业务目录(user/日期/时间戳_随机.ext)
库存相对路径
读取阶段:Detail/List 的 readTransform 经 GetFileUrl 补域名前端不要在上传后直接把 url 当最终地址持久化到业务表——转正由业务保存触发。
批量上传(uploadFiles)
text
POST /api/upload/uploadFiles
multipart 多个 file 字段 → 逐个 SaveTemp → 返回结果数组
(每项同单文件结构;单项校验失败不影响其他项——对照导入的逐行语义)安全链速查
text
大小限制 → 扩展名白名单 → 图片魔数嗅探 → 随机文件名 → 两段式
→ svg 附件化+nosniff → temp 定期清理(tempExpireDays + 03:30 gcron)公网开放上传时收紧 fileExt(当前含 js/css/sql)——配置见 7.2 上传配置详解。