# 文件上传集成指南 ## 概述 本系统使用 `yudao-module-system` 模块的 **Storage API** 作为统一的文件上传服务,支持多种存储方式(本地、S3/OSS)。 > **重要**:所有业务模块必须使用 system 模块的 Storage API,**禁止使用 infra 模块的 `/infra/file/*` 接口,禁止为每个模块新增上传接口**。 --- ## 一、通用接口 ### 1.1 文件上传 | 方法 | 路径 | 说明 | |------|------|------| | POST | `/system/storage-blob/upload` | 通用文件上传 | **请求参数**:`files`(MultipartFile 数组) **响应**: ```json [ { "id": 123, "resourceKey": "abc123", "contentType": "application/pdf", "originalFilename": "合同.pdf", "uidFilename": "u_abc123.pdf", "byteSize": 102400, "path": "/storage/2024/01/abc123.pdf", "previewURL": "https://xxx.com/preview/u_abc123.pdf", "url": "https://xxx.com/u_abc123.pdf", "name": "合同.pdf", "downloadURL": "https://xxx.com/download/u_abc123.pdf" } ] ``` ### 1.2 附件绑定 | 方法 | 路径 | 说明 | |------|------|------| | POST | `/system/storage-attachment/bind` | 将已上传文件绑定到业务记录 | **请求参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | application | String | 否 | 文件用途,如 `file` | | recordType | String | 是 | 关联记录类型,如 `mes_purchase_order` | | recordId | Long | 是 | 关联记录 ID | | blobItems | List\ | 是 | 待绑定文件列表 | `BlobItem`: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | blobId | Long | 是 | 上传返回的文件 ID | | application | String | 否 | 覆盖外层的文件用途 | ### 1.3 查询附件列表 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/system/storage-attachment/list` | 查询业务记录的附件 | **请求参数**: | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | recordType | String | 是 | 关联记录类型 | | recordId | Long | 是 | 关联记录 ID | | application | String | 否 | 按用途过滤 | ### 1.4 删除附件 | 方法 | 路径 | 说明 | |------|------|------| | DELETE | `/system/storage-attachment/delete` | 批量删除附件 | **请求体**:文件 ID 数组 `[1, 2, 3]` --- ## 二、前端集成 ### 2.1 使用封装好的 API ```typescript import { bindAttachments, listAttachments, uploadFile } from '#/api/system/storage'; // 1. 上传文件 const handleUpload = async (file: File) => { const blobs = await uploadFile([file]); // 获取 blob ID const blobId = blobs[0]!.id; return blobId; }; // 2. 绑定到业务记录 const handleBind = async (blobIds: number[], recordId: number) => { await bindAttachments({ application: 'file', recordType: 'mes_pro_work_order', recordId, blobItems: blobIds.map(id => ({ blobId: id })), }); }; // 3. 查询附件列表 const handleLoad = async (recordId: number) => { const attachments = await listAttachments({ recordType: 'mes_pro_work_order', recordId, }); return attachments; }; ``` ### 2.2 标准流程 1. 用户选择文件 → 调用 `POST /system/storage-blob/upload` 上传 2. 业务记录保存时 → 调用 `POST /system/storage-attachment/bind` 绑定附件到记录 3. 详情/编辑页 → 调用 `GET /system/storage-attachment/list` 加载已有附件 4. 用户删除附件 → 调用 `DELETE /system/storage-attachment/delete` ### 2.3 displayUpload 组件 项目中已有文件上传显示组件,可直接使用系统 Storage API。 --- ## 三、recordType 命名规范 格式:`{模块前缀}_{业务表名}` | 模块 | recordType | 说明 | |------|------------|------| | MES 采购订单 | `mes_purchase_order` | 采购订单附件 | | MES 工单 | `mes_pro_work_order` | 生产工单附件 | | MES 设备 | `mes_dv_machinery` | 设备档案附件 | | MES 文档 | `mes_pd_document` | 项目文档附件 | | CRM 客户 | `crm_customer` | 客户附件 | | ERP 产品 | `erp_product` | 产品附件 | --- ## 四、禁止行为 - ❌ 禁止调用 `/infra/file/upload` 或 `/infra/file/presigned-url` - ❌ 禁止在 MES/CRM/ERP 等业务模块 Controller 新增 `@PostMapping("/upload")` - ❌ 禁止注入 `cn.iocoder.yudao.module.infra.api.file.FileApi` - ❌ 禁止使用旧版 `src/api/infra/file/index.ts` 中的 `uploadFile()` 函数 --- ## 五、前端 API 模块位置 `src/api/system/storage/index.ts` 导出函数:`uploadFile`、`listAttachments`、`bindAttachments`、`deleteAttachments` --- ## 六、注意事项 1. **使用通用接口**:所有上传走 system 模块,通过 `recordType` 区分业务 2. **上传后绑定**:文件上传只是暂存,必须调用 bind 接口关联到业务记录 3. **文件预览**:使用响应中的 `previewURL` 或 `url` 字段 4. **文件下载**:使用 `GET /system/storage-blob/download/{fileName}?token=xxx`