编辑 | blame | 历史 | 原始文档

文件上传功能 - 前端联调方案

涉及页面

  • 文件上传组件(通用,可被任何业务页面引用)
  • 附件列表展示(通用,可被任何业务页面引用)
  • 文件预览/下载(通用)

业务流程与数据带入

  1. 上传文件 → 拿到 blobIdpreviewURLdownloadURL
  2. 保存业务 → 将 blobId 列表随业务表单一起提交,后端自动绑定附件关系
  3. 查看业务详情 → 通过 recordType + recordId 查询附件列表,展示预览/下载链接
  4. 删除业务 → 后端自动清理附件关系和文件

API

方法 路径 说明
POST /admin-api/system/storage-blob/upload 文件上传(token时效控制)
POST /admin-api/system/storage-blob/public-upload 公共文件上传(永久有效,慎用)
GET /admin-api/system/storage-blob/preview/{fileName}?token=xxx 文件预览(免登录)
GET /admin-api/system/storage-blob/preview/{fileName}?publicKey=xxx 公共文件预览(免登录)
GET /admin-api/system/storage-blob/download/{fileName}?token=xxx 文件下载(免登录)
GET /admin-api/system/storage-blob/download/{fileName}?publicKey=xxx 公共文件下载(免登录)
GET /admin-api/system/storage-attachment/list 查询附件列表
POST /admin-api/system/storage-attachment/bind 绑定附件到业务记录
DELETE /admin-api/system/storage-attachment/delete 批量删除附件

文件上传

POST /admin-api/system/storage-blob/upload

请求:multipart/form-data,字段名 files,支持多文件

响应:

{
  "code": 0,
  "data": [
    {
      "id": 1,
      "resourceKey": "a1b2c3d4e5f6",
      "contentType": "image/jpeg",
      "originalFilename": "测试图片.jpg",
      "uidFilename": "550e8400-e29b-41d4-a716-446655440000_测试图片.jpg",
      "byteSize": 102400,
      "path": "2026/0720",
      "previewURL": "http://localhost:48080/admin-api/system/storage-blob/preview/550e8400-e29b-41d4-a716-446655440000_测试图片.jpg?token=eyJhbGciOiJIUzI1NiJ9...",
      "url": "http://localhost:48080/admin-api/system/storage-blob/preview/550e8400-e29b-41d4-a716-446655440000_测试图片.jpg?token=eyJhbGciOiJIUzI1NiJ9...",
      "name": "测试图片.jpg",
      "downloadURL": "http://localhost:48080/admin-api/system/storage-blob/download/550e8400-e29b-41d4-a716-446655440000_测试图片.jpg?token=eyJhbGciOiJIUzI1NiJ9..."
    }
  ]
}

公共文件上传

POST /admin-api/system/storage-blob/public-upload

请求同上,返回的 URL 使用 publicKey 参数,永久有效:

{
  "code": 0,
  "data": [
    {
      "id": 2,
      "resourceKey": "f6e5d4c3b2a1",
      "previewURL": "http://localhost:48080/admin-api/system/storage-blob/preview/xxx_文件.jpg?publicKey=f6e5d4c3b2a1",
      "downloadURL": "http://localhost:48080/admin-api/system/storage-blob/download/xxx_文件.jpg?publicKey=f6e5d4c3b2a1"
    }
  ]
}

附件绑定

POST /admin-api/system/storage-attachment/bind

请求参数:

参数 类型 必填 说明
application String 文件用途(file/image/avatar),不传则从每个 blobItem 中读取
recordType String 业务记录类型(对应 StorageRecordTypeEnum)
recordId Long 业务记录ID
blobItems Array 待绑定的文件列表

blobItems 子项:

参数 类型 必填 说明
blobId Long 上传返回的文件ID
application String 文件用途(可覆盖外层)

请求示例:

{
  "application": "file",
  "recordType": "common_file",
  "recordId": 1001,
  "blobItems": [
    { "blobId": 1, "application": "file" },
    { "blobId": 2, "application": "image" }
  ]
}

响应: { "code": 0, "data": true }

查询附件列表

GET /admin-api/system/storage-attachment/list

参数 类型 必填 说明
recordType String 业务记录类型
recordId Long 业务记录ID
application String 文件用途(不传则查全部用途)

响应:

{
  "code": 0,
  "data": [
    {
      "id": 1,
      "resourceKey": "a1b2c3d4e5f6",
      "contentType": "image/jpeg",
      "originalFilename": "测试图片.jpg",
      "uidFilename": "550e8400_测试图片.jpg",
      "byteSize": 102400,
      "path": "2026/0720",
      "previewURL": "http://localhost:48080/admin-api/system/storage-blob/preview/xxx?token=eyJ...",
      "url": "http://localhost:48080/admin-api/system/storage-blob/preview/xxx?token=eyJ...",
      "name": "测试图片.jpg",
      "downloadURL": "http://localhost:48080/admin-api/system/storage-blob/download/xxx?token=eyJ...",
      "storageAttachmentId": 10,
      "application": "file"
    }
  ]
}

批量删除附件

DELETE /admin-api/system/storage-attachment/delete

请求体:[1, 2, 3](storage_attachment 的 ID 列表)

响应: { "code": 0, "data": true }

字段展示规则

字段 展示位置 说明
originalFilename / name 文件列表 原始文件名,用于展示
previewURL / url 图片缩略图、文件预览 点击可预览,浏览器直接打开
downloadURL 下载按钮 点击触发下载
byteSize 文件列表 文件大小,建议格式化显示(KB/MB)
contentType 文件列表 可根据类型显示不同图标
application 文件列表分组 区分同一记录下不同用途的文件

业务记录类型枚举(recordType)

枚举值 说明
common_file 通用文件
production_order 生产工单
quality_inspect 质检
device_maintenance 设备维护
notice 通知公告
avatar 头像

后续业务模块如需新增 recordType,需在后端 StorageRecordTypeEnum 中添加枚举值。

文件用途枚举(application)

枚举值 说明
file 通用文件
image 图片
avatar 头像

业务接入示例

1. 上传 + 保存业务(两阶段模式)

步骤1:用户选择文件 → 调用 /storage-blob/upload → 拿到 blobId 列表
步骤2:用户填写业务表单 → 提交时将 blobId 列表一起传给后端
步骤3:后端保存业务数据 + 调用 /storage-attachment/bind 绑定附件

2. 查看业务详情 + 展示附件

步骤1:加载业务详情
步骤2:调用 /storage-attachment/list?recordType=xxx&recordId=xxx → 获取附件列表
步骤3:展示附件列表(图片用 previewURL 预览,文件用 downloadURL 下载)

3. 删除业务 + 清理附件

后端自动处理:删除业务数据时,同时删除关联的附件记录和磁盘文件
前端无需额外调用删除附件接口

注意事项

  • 预览/下载接口免登录:preview 和 download 接口使用 @PermitAll,通过 URL 中的 token 或 publicKey 鉴权,前端直接用 <img src="previewURL">window.open(downloadURL) 即可
  • token 时效:普通上传的预览/下载链接默认 120 分钟有效,且限制使用 10 次。如需永久链接,使用 /public-upload 接口
  • 图片压缩:后端自动对超过 10MB 的 jpg/jpeg/png 图片进行压缩,预览时返回压缩版本,下载时返回原图
  • 多文件上传:upload 接口支持一次上传多个文件,字段名 files
  • 附件绑定是替换模式:调用 bind 接口时,会先删除该记录下同用途的旧附件,再插入新附件
  • 同一记录多组附件:使用 application 字段区分,如同一工单下既有"图片"又有"文件"
  • 权限控制:附件查询需要 system:storage-attachment:query,绑定需要 system:storage-attachment:create,删除需要 system:storage-attachment:delete