refactor(UserHome): 优化文件上传逻辑并分离预览数据
将文件上传逻辑与预览数据分离,使用临时变量存储上传前的文件列表 修改handleCustomUpload方法以支持不同类型文件的上传 修复初始化时支付凭证文件回显的问题
This commit is contained in:
@@ -48,49 +48,58 @@
|
|||||||
<n-grid :x-gap="24" :y-gap="8" cols="1 s:2 m:3" responsive="screen">
|
<n-grid :x-gap="24" :y-gap="8" cols="1 s:2 m:3" responsive="screen">
|
||||||
<n-grid-item>
|
<n-grid-item>
|
||||||
<n-form-item label="分析师主管" path="analystSupervisor">
|
<n-form-item label="分析师主管" path="analystSupervisor">
|
||||||
<n-input v-model:value="formData.analystSupervisor" placeholder="请输入主管姓名" clearable />
|
<n-input v-model:value="formData.analystSupervisor" placeholder="请输入主管姓名"
|
||||||
|
clearable />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-grid-item>
|
</n-grid-item>
|
||||||
<n-grid-item>
|
<n-grid-item>
|
||||||
<n-form-item label="分析师部门" path="analystDepartment">
|
<n-form-item label="分析师部门" path="analystDepartment">
|
||||||
<n-input v-model:value="formData.analystDepartment" placeholder="例如: 市场一部" clearable />
|
<n-input v-model:value="formData.analystDepartment" placeholder="例如: 市场一部"
|
||||||
|
clearable />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-grid-item>
|
</n-grid-item>
|
||||||
<n-grid-item>
|
<n-grid-item>
|
||||||
<n-form-item label="分析师姓名" path="analystName">
|
<n-form-item label="分析师姓名" path="analystName">
|
||||||
<n-input v-model:value="formData.analystName" placeholder="请输入分析师姓名" clearable />
|
<n-input v-model:value="formData.analystName" placeholder="请输入分析师姓名"
|
||||||
|
clearable />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-grid-item>
|
</n-grid-item>
|
||||||
<n-grid-item>
|
<n-grid-item>
|
||||||
<n-form-item label="家长姓名" path="parentName">
|
<n-form-item label="家长姓名" path="parentName">
|
||||||
<n-input v-model:value="formData.parentName" placeholder="请输入家长姓名" clearable />
|
<n-input v-model:value="formData.parentName" placeholder="请输入家长姓名"
|
||||||
|
clearable />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-grid-item>
|
</n-grid-item>
|
||||||
<n-grid-item>
|
<n-grid-item>
|
||||||
<n-form-item label="家长电话" path="parentPhone">
|
<n-form-item label="家长电话" path="parentPhone">
|
||||||
<n-input v-model:value="formData.parentPhone" placeholder="请输入联系电话" clearable />
|
<n-input v-model:value="formData.parentPhone" placeholder="请输入联系电话"
|
||||||
|
clearable />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-grid-item>
|
</n-grid-item>
|
||||||
<n-grid-item>
|
<n-grid-item>
|
||||||
<n-form-item label="家长身份证号码" path="parentIdCard">
|
<n-form-item label="家长身份证号码" path="parentIdCard">
|
||||||
<n-input v-model:value="formData.parentIdCard" placeholder="请输入18位身份证号" clearable />
|
<n-input v-model:value="formData.parentIdCard" placeholder="请输入18位身份证号"
|
||||||
|
clearable />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-grid-item>
|
</n-grid-item>
|
||||||
<n-grid-item>
|
<n-grid-item>
|
||||||
<n-form-item label="成交日期" path="transactionDate">
|
<n-form-item label="成交日期" path="transactionDate">
|
||||||
<n-date-picker v-model:value="formData.transactionDate" type="date" clearable style="width: 100%" />
|
<n-date-picker v-model:value="formData.transactionDate" type="date"
|
||||||
|
clearable style="width: 100%" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-grid-item>
|
</n-grid-item>
|
||||||
<n-grid-item>
|
<n-grid-item>
|
||||||
<n-form-item label="成交金额" path="transactionAmount">
|
<n-form-item label="成交金额" path="transactionAmount">
|
||||||
<n-input-number v-model:value="formData.transactionAmount" placeholder="0.00" clearable style="width: 100%">
|
<n-input-number v-model:value="formData.transactionAmount"
|
||||||
|
placeholder="0.00" clearable style="width: 100%">
|
||||||
<template #prefix>¥</template>
|
<template #prefix>¥</template>
|
||||||
</n-input-number>
|
</n-input-number>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-grid-item>
|
</n-grid-item>
|
||||||
<n-grid-item>
|
<n-grid-item>
|
||||||
<n-form-item label="指导周期" path="guidancePeriod">
|
<n-form-item label="指导周期" path="guidancePeriod">
|
||||||
<n-input v-model:value="formData.guidancePeriod" placeholder="例如: 3个月" clearable />
|
<n-input v-model:value="formData.guidancePeriod" placeholder="例如: 3个月"
|
||||||
|
clearable />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-grid-item>
|
</n-grid-item>
|
||||||
</n-grid>
|
</n-grid>
|
||||||
@@ -113,8 +122,9 @@
|
|||||||
<span>2. 附件文档 (限1份)</span>
|
<span>2. 附件文档 (限1份)</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="section-body">
|
<div class="section-body">
|
||||||
<n-upload :max="1" directory-dnd v-model:file-list="formData.documentFileList"
|
<n-upload :max="1" directory-dnd v-model:file-list="documentFileListLast"
|
||||||
@preview="handlePreview" :custom-request="handleCustomUpload">
|
@preview="handlePreview"
|
||||||
|
:custom-request="({ file, onFinish, onError, onProgress }) => handleCustomUpload({ file, onFinish, onError, onProgress }, 'documentFileList')">
|
||||||
<n-upload-dragger class="custom-dragger">
|
<n-upload-dragger class="custom-dragger">
|
||||||
<div class="dragger-icon">
|
<div class="dragger-icon">
|
||||||
<n-icon size="48" :depth="3">
|
<n-icon size="48" :depth="3">
|
||||||
@@ -140,8 +150,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="section-body">
|
<div class="section-body">
|
||||||
<n-upload class="custom-multi-upload" accept="image/*" multiple list-type="image-card"
|
<n-upload class="custom-multi-upload" accept="image/*" multiple list-type="image-card"
|
||||||
v-model:file-list="formData.paymentFileList" @preview="handlePreview"
|
v-model:file-list="paymentFileListLast" @preview="handlePreview"
|
||||||
:custom-request="handleCustomUpload">
|
:custom-request="({ file, onFinish, onError, onProgress }) => handleCustomUpload({ file, onFinish, onError, onProgress }, 'paymentFileList')">
|
||||||
<div class="upload-placeholder">
|
<div class="upload-placeholder">
|
||||||
<div class="icon-bg">
|
<div class="icon-bg">
|
||||||
<n-icon size="28" color="#666">
|
<n-icon size="28" color="#666">
|
||||||
@@ -164,8 +174,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="section-body">
|
<div class="section-body">
|
||||||
<n-upload class="signature-upload-container" accept="image/*" :max="1"
|
<n-upload class="signature-upload-container" accept="image/*" :max="1"
|
||||||
list-type="image-card" v-model:file-list="formData.signatureFileList"
|
list-type="image-card" v-model:file-list="signatureFileListLast"
|
||||||
@preview="handlePreview" :custom-request="handleCustomUpload">
|
@preview="handlePreview"
|
||||||
|
:custom-request="({ file, onFinish, onError, onProgress }) => handleCustomUpload({ file, onFinish, onError, onProgress }, 'signatureFileList')">
|
||||||
<div class="upload-placeholder signature-placeholder">
|
<div class="upload-placeholder signature-placeholder">
|
||||||
<n-icon size="32" depth="3">
|
<n-icon size="32" depth="3">
|
||||||
<CreateOutline />
|
<CreateOutline />
|
||||||
@@ -244,6 +255,11 @@ const formData = reactive({
|
|||||||
signatureFileList: []
|
signatureFileList: []
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 临时文件列表,用于上传前预览
|
||||||
|
const documentFileListLast = ref([])
|
||||||
|
const paymentFileListLast = ref([])
|
||||||
|
const signatureFileListLast = ref([])
|
||||||
|
|
||||||
// 定义校验规则
|
// 定义校验规则
|
||||||
const rules = {
|
const rules = {
|
||||||
analystSupervisor: { required: true, message: '请输入主管姓名', trigger: 'blur' },
|
analystSupervisor: { required: true, message: '请输入主管姓名', trigger: 'blur' },
|
||||||
@@ -255,7 +271,7 @@ const rules = {
|
|||||||
* 核心:通用文件上传逻辑
|
* 核心:通用文件上传逻辑
|
||||||
* 直接把后端返回的数据挂载到文件对象的 rawResponse 字段,完全隔离前端生成的 id/fullPath
|
* 直接把后端返回的数据挂载到文件对象的 rawResponse 字段,完全隔离前端生成的 id/fullPath
|
||||||
*/
|
*/
|
||||||
const handleCustomUpload = async ({ file, onFinish, onError, onProgress }) => {
|
const handleCustomUpload = async ({ file, onFinish, onError, onProgress }, type) => {
|
||||||
try {
|
try {
|
||||||
const uploadData = new FormData()
|
const uploadData = new FormData()
|
||||||
uploadData.append('file', file.file)
|
uploadData.append('file', file.file)
|
||||||
@@ -272,8 +288,14 @@ const handleCustomUpload = async ({ file, onFinish, onError, onProgress }) => {
|
|||||||
// 下面两行是给 UI 看的,保证能回显图片和显示“完成”状态
|
// 下面两行是给 UI 看的,保证能回显图片和显示“完成”状态
|
||||||
file.url = response.url
|
file.url = response.url
|
||||||
file.status = 'finished'
|
file.status = 'finished'
|
||||||
formData.documentFileList.push(file)
|
if (type == 'paymentFileList') {
|
||||||
console.log('Updated documentFileList:', formData.documentFileList)
|
formData.paymentFileList.push(file)
|
||||||
|
} else if (type == 'documentFileList') {
|
||||||
|
formData.documentFileList.push(file)
|
||||||
|
} else if (type == 'signatureFileList') {
|
||||||
|
formData.signatureFileList.push(file)
|
||||||
|
}
|
||||||
|
console.log('Updated documentFileList:', formData)
|
||||||
message.success('上传成功')
|
message.success('上传成功')
|
||||||
onFinish()
|
onFinish()
|
||||||
} else {
|
} else {
|
||||||
@@ -306,7 +328,7 @@ const initData = async () => {
|
|||||||
|
|
||||||
// 2. 回显付款截图:将已有的 object_name 和 url 封装进 rawResponse
|
// 2. 回显付款截图:将已有的 object_name 和 url 封装进 rawResponse
|
||||||
if (res.proofOfPayment && res.proofOfPayment_urls) {
|
if (res.proofOfPayment && res.proofOfPayment_urls) {
|
||||||
formData.paymentFileList = res.proofOfPayment.map((objName, index) => ({
|
const paymentFiles = res.proofOfPayment.map((objName, index) => ({
|
||||||
id: objName, // UI 需要一个 ID
|
id: objName, // UI 需要一个 ID
|
||||||
name: `凭证-${index + 1}`,
|
name: `凭证-${index + 1}`,
|
||||||
status: 'finished',
|
status: 'finished',
|
||||||
@@ -318,6 +340,8 @@ const initData = async () => {
|
|||||||
success: true
|
success: true
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
formData.paymentFileList = paymentFiles
|
||||||
|
paymentFileListLast.value = paymentFiles
|
||||||
}
|
}
|
||||||
message.success('数据加载成功')
|
message.success('数据加载成功')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user