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-item>
|
||||
<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-grid-item>
|
||||
<n-grid-item>
|
||||
<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-grid-item>
|
||||
<n-grid-item>
|
||||
<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-grid-item>
|
||||
<n-grid-item>
|
||||
<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-grid-item>
|
||||
<n-grid-item>
|
||||
<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-grid-item>
|
||||
<n-grid-item>
|
||||
<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-grid-item>
|
||||
<n-grid-item>
|
||||
<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-grid-item>
|
||||
<n-grid-item>
|
||||
<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>
|
||||
</n-input-number>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<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-grid-item>
|
||||
</n-grid>
|
||||
@@ -113,8 +122,9 @@
|
||||
<span>2. 附件文档 (限1份)</span>
|
||||
</div>
|
||||
<div class="section-body">
|
||||
<n-upload :max="1" directory-dnd v-model:file-list="formData.documentFileList"
|
||||
@preview="handlePreview" :custom-request="handleCustomUpload">
|
||||
<n-upload :max="1" directory-dnd v-model:file-list="documentFileListLast"
|
||||
@preview="handlePreview"
|
||||
:custom-request="({ file, onFinish, onError, onProgress }) => handleCustomUpload({ file, onFinish, onError, onProgress }, 'documentFileList')">
|
||||
<n-upload-dragger class="custom-dragger">
|
||||
<div class="dragger-icon">
|
||||
<n-icon size="48" :depth="3">
|
||||
@@ -140,8 +150,8 @@
|
||||
</div>
|
||||
<div class="section-body">
|
||||
<n-upload class="custom-multi-upload" accept="image/*" multiple list-type="image-card"
|
||||
v-model:file-list="formData.paymentFileList" @preview="handlePreview"
|
||||
:custom-request="handleCustomUpload">
|
||||
v-model:file-list="paymentFileListLast" @preview="handlePreview"
|
||||
:custom-request="({ file, onFinish, onError, onProgress }) => handleCustomUpload({ file, onFinish, onError, onProgress }, 'paymentFileList')">
|
||||
<div class="upload-placeholder">
|
||||
<div class="icon-bg">
|
||||
<n-icon size="28" color="#666">
|
||||
@@ -164,8 +174,9 @@
|
||||
</div>
|
||||
<div class="section-body">
|
||||
<n-upload class="signature-upload-container" accept="image/*" :max="1"
|
||||
list-type="image-card" v-model:file-list="formData.signatureFileList"
|
||||
@preview="handlePreview" :custom-request="handleCustomUpload">
|
||||
list-type="image-card" v-model:file-list="signatureFileListLast"
|
||||
@preview="handlePreview"
|
||||
:custom-request="({ file, onFinish, onError, onProgress }) => handleCustomUpload({ file, onFinish, onError, onProgress }, 'signatureFileList')">
|
||||
<div class="upload-placeholder signature-placeholder">
|
||||
<n-icon size="32" depth="3">
|
||||
<CreateOutline />
|
||||
@@ -244,6 +255,11 @@ const formData = reactive({
|
||||
signatureFileList: []
|
||||
})
|
||||
|
||||
// 临时文件列表,用于上传前预览
|
||||
const documentFileListLast = ref([])
|
||||
const paymentFileListLast = ref([])
|
||||
const signatureFileListLast = ref([])
|
||||
|
||||
// 定义校验规则
|
||||
const rules = {
|
||||
analystSupervisor: { required: true, message: '请输入主管姓名', trigger: 'blur' },
|
||||
@@ -255,7 +271,7 @@ const rules = {
|
||||
* 核心:通用文件上传逻辑
|
||||
* 直接把后端返回的数据挂载到文件对象的 rawResponse 字段,完全隔离前端生成的 id/fullPath
|
||||
*/
|
||||
const handleCustomUpload = async ({ file, onFinish, onError, onProgress }) => {
|
||||
const handleCustomUpload = async ({ file, onFinish, onError, onProgress }, type) => {
|
||||
try {
|
||||
const uploadData = new FormData()
|
||||
uploadData.append('file', file.file)
|
||||
@@ -272,8 +288,14 @@ const handleCustomUpload = async ({ file, onFinish, onError, onProgress }) => {
|
||||
// 下面两行是给 UI 看的,保证能回显图片和显示“完成”状态
|
||||
file.url = response.url
|
||||
file.status = 'finished'
|
||||
formData.documentFileList.push(file)
|
||||
console.log('Updated documentFileList:', formData.documentFileList)
|
||||
if (type == 'paymentFileList') {
|
||||
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('上传成功')
|
||||
onFinish()
|
||||
} else {
|
||||
@@ -293,7 +315,7 @@ const initData = async () => {
|
||||
try {
|
||||
const wecomId = route.query.wecom_id || 'wmcr-ECwAAzKclEfIKNcVgOdxD-TcqLg'
|
||||
const res = await http.get('/v1/customer/get_customers_info', { wecom_id: wecomId })
|
||||
|
||||
|
||||
// 1. 回显基础字段
|
||||
formData.analystName = res.analystName
|
||||
formData.parentName = res.customerName
|
||||
@@ -306,7 +328,7 @@ const initData = async () => {
|
||||
|
||||
// 2. 回显付款截图:将已有的 object_name 和 url 封装进 rawResponse
|
||||
if (res.proofOfPayment && res.proofOfPayment_urls) {
|
||||
formData.paymentFileList = res.proofOfPayment.map((objName, index) => ({
|
||||
const paymentFiles = res.proofOfPayment.map((objName, index) => ({
|
||||
id: objName, // UI 需要一个 ID
|
||||
name: `凭证-${index + 1}`,
|
||||
status: 'finished',
|
||||
@@ -318,6 +340,8 @@ const initData = async () => {
|
||||
success: true
|
||||
}
|
||||
}))
|
||||
formData.paymentFileList = paymentFiles
|
||||
paymentFileListLast.value = paymentFiles
|
||||
}
|
||||
message.success('数据加载成功')
|
||||
} catch (error) {
|
||||
@@ -357,10 +381,10 @@ const handleSubmit = () => {
|
||||
// 2. 提取纯净的文件数据(仅包含请求回来的 data 对象)
|
||||
// 单个文件取第 0 项的 rawResponse
|
||||
document: formData.documentFileList[0]?.rawResponse || null,
|
||||
|
||||
|
||||
// 多个文件用 map 提取数组
|
||||
proofOfPayment: formData.paymentFileList.map(f => f.rawResponse).filter(Boolean),
|
||||
|
||||
|
||||
// 签名文件
|
||||
signature: formData.signatureFileList[0]?.rawResponse || null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user