本文档分析了项目中购机者照片、证件附件和发票附件这三个文件上传功能的接口和参数。
所有文件上传都使用同一个接口:
/api/attachment/addimg| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | File | 是 | 上传的图片文件 |
| attmodel | String | 是 | "coupon_buyer" (关联模块) |
| attpath | String | 是 | "/coupon_buyer/" (上传路径) |
| token | String | 是 | 用户认证token (在请求头中) |
src/pages/coupon/modify-info.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="用于确认购机者身份"
/>
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | File | 是 | 上传的图片文件 |
| attmodel | String | 是 | "coupon_identity" (关联模块) |
| attpath | String | 是 | "/coupon_identity/" (上传路径) |
| token | String | 是 | 用户认证token (在请求头中) |
src/pages/coupon/modify-info.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="请上传营业执照照片"
/>
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| file | File | 是 | 上传的文件(支持图片和PDF) |
| attmodel | String | 是 | "coupon_invoice" (关联模块) |
| attpath | String | 是 | "/coupon_invoice/" (上传路径) |
| token | String | 是 | 用户认证token (在请求头中) |
src/pages/form/formStep4.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"
/>
/api/attachment/addimgattmodel 和 attpath 参数区分不同类型的文件filesid 参数提交给后端在表单提交时,不同类型的文件ID会被收集到同一个数组中,然后通过逗号连接成一个字符串:
// 示例代码
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。
// 创建自定义上传方法
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 中实现:
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 表中,表结构如下:
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收集起来,在表单提交时统一提交给后端。这种设计简化了文件上传的实现,同时保持了足够的灵活性来处理不同类型的文件上传需求。