5.6 KiB
5.6 KiB
title, description, pageClass
| title | description | pageClass |
|---|---|---|
| 附件 | 文件上传(本地 / OSS 直传)、记录落库、删除与静态访问 | g3-api |
附件
文件接口,前缀 /file/**。有两种存储模式,由 erp.file.storage-type 决定(local / aliyun-oss)。
| 模式 | 上传链路 |
|---|---|
local |
前端直接 POST 文件 → 后端写盘 + 落库 |
aliyun-oss |
取凭证 → 前端直传 OSS → 回调后端落库 |
第一步先问模式:调
/file/config拿到当前模式,再决定走哪条链路。前端组件不要写死。
POST /file/config
返回当前存储模式。
{
"code": 0,
"message": "操作成功",
"data": { "storageType": "local" }
}
POST /file/upload
本地上传(storage-type=local 时使用)。支持多文件,是 multipart/form-data,不是 JSON。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
files |
file[] | 是 | 文件,key 固定为 files,可重复 |
father |
string | 是 | 宿主业务主键(存宿主 b_id) |
moduleId |
string | 是 | 模块编码 |
cateId |
string | 分类 ID |
curl -X POST http://localhost:8088/api/file/upload \
-H 'Authorization: Bearer <token>' \
-F 'files=@report.pdf' \
-F 'father=1234567890' \
-F 'moduleId=v_b_othercompany' \
-F 'cateId=987654321'
{
"code": 0,
"message": "操作成功",
"data": [
{
"subid": "1234567890123",
"mx_filename": "report.pdf",
"mx_filesize": "20480",
"mx_fileext": "pdf",
"mx_mapfilename": "/api/file/static/G3HD/2026/10/13/abc.pdf",
"father": "1234567890",
"mx_moduleid": "v_b_othercompany",
"mx_cate_id": "987654321"
}
]
}
mx_mapfilename就是访问地址,预览 / 下载直接用它。subid是雪花 ID,本地模式由后端自己取号后写入bf_files(前端不用管)。
POST /file/upload-credential
取 OSS 直传凭证(storage-type=aliyun-oss 时使用)。无请求字段。
后端转发到 g3oss,bucket 即当前机构码。
{
"code": 0,
"message": "操作成功",
"data": {
"accessid": "LTAI...",
"policy": "eyJleHBpcmF0aW9uIjoi...",
"signature": "abc123==",
"dir": "G3HD/",
"host": "https://g3soft.oss-cn-hangzhou.aliyuncs.com",
"expire": 1700000000
}
}
字段以 g3oss 实际返回为准:后端只做
readValue(...).Map的原样透传,不加工也不改名。 上面是 OSS 直传的常见字段形状,接入时请以实际返回为准;凭证有有效期,取到后应尽快直传。
POST /file/save-record
OSS 直传完成后回调落库(storage-type=aliyun-oss 时使用)。本地模式不需要单独调它。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
subid |
number | 是 | 上传前取的雪花 ID |
father |
string | 是 | 宿主业务主键 |
mx_moduleid |
string | 是 | 模块编码 |
mx_cate_id |
string | 分类 ID | |
mx_filename |
string | 是 | 原始文件名 |
mx_filesize |
string | 是 | 文件大小(字节) |
mx_fileext |
string | 是 | 扩展名 |
mx_mapfilename |
string | 是 | OSS 返回的完整 URL |
{
"code": 0,
"message": "操作成功",
"data": { "subid": "1234567890123", "message": "记录已保存" }
}
subid在 OSS 链路必须由前端在上传前取号(调/data/nextid),因为凭证直传时后端不在链路上,无法代为取号。 本地链路则相反:后端自己取号,前端不用传。两条链路都不能依赖数据库自增。
POST /file/delete
删除文件:先删存储、后删 DB 行。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
subid |
string | 是 | 文件记录 ID |
{ "code": 0, "message": "操作成功", "data": null }
外部对象操作不属于数据库事务:
- 删存储失败 → 不删数据库行(保持可重试)。
- 数据库删除失败 → 保留可重试的清理记录。
记录不存在时静默返回成功(幂等)。
GET /file/static/{fileName}
本地模式下的文件访问入口。不是 JSON 接口,直接返回文件流。
GET /api/file/static/G3HD/2026/10/13/abc.pdf
- 路径形如
{orgId}/{yyyy}/{MM}/{dd}/{file},与mx_mapfilename去掉前缀后的部分对应。 - 带路径穿越防护:解析后必须仍在存储根目录内,否则 404。
- 响应头带
Content-Disposition: inline,浏览器可直接预览。
相关数据表
| 表 | 说明 |
|---|---|
bf_files |
文件记录(主键 subid 雪花 ID,father 存宿主主键) |
bf_files_category |
文件分类(b_module_id 为空表示跨模块通用分类) |
常见错误
| 场景 | 表现 |
|---|---|
本地上传时缺少 files |
1000 参数错误 |
| 文件静态访问越界或不存在 | HTTP 404(这条路径不走统一响应格式) |
| OSS 凭证获取失败 | 1000「获取 OSS 上传凭证失败: {状态码}」 |
| 存储模式不匹配 | 例如 local 模式下调 /file/save-record 会落库成功但文件并不存在——要先查 /file/config |