# 文件上传分析文档 ## 概述 本文档分析了项目中购机者照片、证件附件和发票附件这三个文件上传功能的接口和参数。 ## 文件上传接口 所有文件上传都使用同一个接口: - **接口地址**: `/api/attachment/addimg` - **请求方法**: POST - **请求类型**: multipart/form-data - **认证方式**: 通过请求头中的 token 参数进行用户认证 ## 1. 购机者照片上传 ### 接口参数 | 参数名 | 类型 | 必填 | 说明 | | -------- | ------ | ---- | --------------------------- | | file | File | 是 | 上传的图片文件 | | attmodel | String | 是 | "coupon_buyer" (关联模块) | | attpath | String | 是 | "/coupon_buyer/" (上传路径) | | token | String | 是 | 用户认证token (在请求头中) | ### 使用场景 - **页面位置**: `src/pages/coupon/modify-info.vue` - **是否必填**: 否 - **用途**: 用于确认购机者身份 - **限制**: 最多上传1张图片 ### 代码示例 ```vue ``` ## 2. 证件附件上传 ### 接口参数 | 参数名 | 类型 | 必填 | 说明 | | -------- | ------ | ---- | ------------------------------ | | file | File | 是 | 上传的图片文件 | | attmodel | String | 是 | "coupon_identity" (关联模块) | | attpath | String | 是 | "/coupon_identity/" (上传路径) | | token | String | 是 | 用户认证token (在请求头中) | ### 使用场景 - **页面位置**: `src/pages/coupon/modify-info.vue` - **是否必填**: 是 - **用途**: 根据用户类型上传不同的证件 - 个人用户:上传身份证照片 - 企业用户:上传营业执照照片 - **限制**: 最多上传1张图片 ### 代码示例 ```vue ``` ## 3. 发票附件上传 ### 接口参数 | 参数名 | 类型 | 必填 | 说明 | | -------- | ------ | ---- | ----------------------------- | | file | File | 是 | 上传的文件(支持图片和PDF) | | attmodel | String | 是 | "coupon_invoice" (关联模块) | | attpath | String | 是 | "/coupon_invoice/" (上传路径) | | token | String | 是 | 用户认证token (在请求头中) | ### 使用场景 - **页面位置**: `src/pages/form/formStep4.vue` - **是否必填**: 是 - **用途**: 上传购买发票 - **限制**: - 最多上传1个文件 - 支持格式:JPG、PNG、PDF - 文件大小:不超过10MB ### 代码示例 ```vue ``` ## 文件上传流程 1. 所有文件上传都使用同一个接口 `/api/attachment/addimg` 2. 通过 `attmodel` 和 `attpath` 参数区分不同类型的文件 3. 上传成功后,服务器返回文件ID,前端将文件ID保存到相应的数组中 4. 提交表单时,将所有文件ID通过逗号连接成一个字符串,通过 `filesid` 参数提交给后端 ## 文件ID处理 在表单提交时,不同类型的文件ID会被收集到同一个数组中,然后通过逗号连接成一个字符串: ```javascript // 示例代码 const fileIds = [ ...idCardIds.map((item) => item.id), // 证件照片ID ...buyerPhotoIds.map((item) => item.id), // 购机者照片ID ...invoiceFileIds.map((item) => item.id), // 发票文件ID ]; const fileIdsString = fileIds.join(','); // 提交参数 const submitParams = { // ...其他参数 filesid: fileIdsString, // 文件ID字符串 }; ``` ## 上传组件实现 文件上传功能通过 `UploadComponent` 组件实现,该组件位于 `src/components/UploadComponent.vue`。 ### 主要功能 1. 文件选择和预览 2. 文件上传前的验证 3. 自定义上传方法 4. 文件ID管理 5. 文件删除功能 ### 核心方法 ```javascript // 创建自定义上传方法 function createCustomUpload({ attmodel, attpath, modelStats }) { return async function (file, formData, options) { const requestFromData = { attmodel, attpath, }; if (props.attlsh) { requestFromData.attlsh = props.attlsh; } await uploadFile({ tempFilePath: file.url, formData: requestFromData, data, error, loading, }); if (!error.value) { options.onSuccess('', file, formData); // 处理返回的文件ID let dataObject = data.value; if (typeof data.value === 'string') { dataObject = JSON.parse(data.value); } const newFileIds = [...props.fileIds]; newFileIds.push({ url: file.url, id: dataObject.Data, }); emit('update:fileIds', newFileIds); } }; } ``` ## 上传钩子实现 文件上传的核心逻辑在 `src/hooks/useUpload.ts` 中实现: ```javascript export function uploadFile({ tempFilePath, formData, data, error, loading }) { return new Promise((resolve, reject) => { const appStore = useAppStore() uni.uploadFile({ url: VITE_UPLOAD_BASEURL + '/api/attachment/addimg', filePath: tempFilePath, name: 'file', formData, header: { token: `${appStore.appInfo.token}`, // 请求token }, success: (uploadFileRes) => { const decryptedRes = decryptResponse(uploadFileRes) data.value = decryptedRes.data as T resolve(data.value) }, fail: (err) => { console.error('uni.uploadFile err->', err) error.value = true reject(err) }, complete: () => { loading.value = false }, }) }) } ``` ## 数据库表结构 文件上传相关的数据存储在 `attachment` 表中,表结构如下: ```sql CREATE TABLE `attachment` ( `attid` varchar(32) NOT NULL COMMENT '附件ID(查询条件)', `attname` varchar(32) NOT NULL COMMENT '文件名', `attpath` varchar(200) NOT NULL COMMENT '路径', `atttype` varchar(10) NOT NULL COMMENT '扩展名', `attsize` varchar(20) NOT NULL COMMENT '文件大小', `attmodel` varchar(20) NOT NULL COMMENT '关联模块(查询条件)', `attlsh` varchar(32) DEFAULT NULL COMMENT '关联表单流水号(查询条件)', `attcreate` datetime NOT NULL COMMENT '创建时间#不可编辑(禁止前端编辑)(查询条件)', `attcreateuser` varchar(30) DEFAULT NULL COMMENT '上传者#不可编辑(禁止前端编辑)', `attdelcode` tinyint(4) DEFAULT NULL COMMENT '删除标记(禁止前端编辑)(禁止插入)', `attother1` varchar(50) DEFAULT NULL COMMENT '附加参数1', `attother2` varchar(50) DEFAULT NULL COMMENT '附加参数2', `attother3` varchar(50) DEFAULT NULL COMMENT '附加参数3', `attorginname` varchar(255) DEFAULT NULL COMMENT '文件原始名称', `attfileSHA1` varchar(100) DEFAULT NULL COMMENT '文件SHA1值', `attfileSHA256` varchar(100) DEFAULT NULL COMMENT '文件SHA256值', `attfileMD5` varchar(100) DEFAULT NULL COMMENT '文件MD5值', PRIMARY KEY (`attid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='附件'; ``` ## 总结 项目中的文件上传功能采用了统一的上传接口,通过不同的参数来区分不同类型的文件。上传成功后,服务器返回文件ID,前端将这些ID收集起来,在表单提交时统一提交给后端。这种设计简化了文件上传的实现,同时保持了足够的灵活性来处理不同类型的文件上传需求。