Browse Source

feat: 添加文件上传分析文档,详细说明购机者照片、证件附件和发票附件的上传接口及参数

laiqi 5 months ago
parent
commit
4bc3733b0b
1 changed files with 279 additions and 0 deletions
  1. 279 0
      doc/文件上传分析文档.md

+ 279 - 0
doc/文件上传分析文档.md

@@ -0,0 +1,279 @@
+# 文件上传分析文档
+
+## 概述
+
+本文档分析了项目中购机者照片、证件附件和发票附件这三个文件上传功能的接口和参数。
+
+## 文件上传接口
+
+所有文件上传都使用同一个接口:
+
+- **接口地址**: `/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
+<UploadComponent
+  v-model="formData.buyerPhoto"
+  v-model:fileIds="formData.buyerPhotoIds"
+  :limit="1"
+  :required="false"
+  attmodel="coupon_buyer"
+  attpath="/coupon_buyer/"
+  modelStats="buyerPhotoIds"
+  message="请上传购机者照片"
+  tips="用于确认购机者身份"
+/>
+```
+
+## 2. 证件附件上传
+
+### 接口参数
+
+| 参数名   | 类型   | 必填 | 说明                           |
+| -------- | ------ | ---- | ------------------------------ |
+| file     | File   | 是   | 上传的图片文件                 |
+| attmodel | String | 是   | "coupon_identity" (关联模块)   |
+| attpath  | String | 是   | "/coupon_identity/" (上传路径) |
+| token    | String | 是   | 用户认证token (在请求头中)     |
+
+### 使用场景
+
+- **页面位置**: `src/pages/coupon/modify-info.vue`
+- **是否必填**: 是
+- **用途**: 根据用户类型上传不同的证件
+  - 个人用户:上传身份证照片
+  - 企业用户:上传营业执照照片
+- **限制**: 最多上传1张图片
+
+### 代码示例
+
+```vue
+<!-- 个人身份证上传 -->
+<UploadComponent
+  v-model="formData.idCardFiles"
+  v-model:fileIds="formData.idCardIds"
+  :limit="1"
+  attmodel="coupon_identity"
+  attpath="/coupon_identity/"
+  modelStats="idCardIds"
+  message="请上传身份证照片"
+  tips="请上传身份证正面照片"
+/>
+
+<!-- 企业营业执照上传 -->
+<UploadComponent
+  v-model="formData.businessLicenseFiles"
+  v-model:fileIds="formData.businessLicenseIds"
+  :limit="1"
+  attmodel="coupon_identity"
+  attpath="/coupon_identity/"
+  modelStats="businessLicenseIds"
+  message="请上传营业执照照片"
+/>
+```
+
+## 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
+<UploadComponent
+  v-model="formData.invoiceFiles"
+  v-model:fileIds="formData.invoiceFileIds"
+  :limit="1"
+  :required="true"
+  accept="all"
+  :extension="['.jpg', '.jpeg', '.png', '.pdf']"
+  attmodel="coupon_invoice"
+  attpath="/coupon_invoice/"
+  modelStats="invoiceFileIds"
+  message="请上传发票照片或PDF文件"
+  tips="支持图片格式(JPG、PNG)和PDF文件,文件大小不超过10MB"
+/>
+```
+
+## 文件上传流程
+
+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<T>({ 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收集起来,在表单提交时统一提交给后端。这种设计简化了文件上传的实现,同时保持了足够的灵活性来处理不同类型的文件上传需求。