文件编辑问题修复,添加文件预览功能
This commit is contained in:
parent
82bab0ea11
commit
df332f8138
|
|
@ -105,7 +105,8 @@ export default {
|
||||||
name: item.fileName || '未知文件',
|
name: item.fileName || '未知文件',
|
||||||
filePath: item.filePath || '',
|
filePath: item.filePath || '',
|
||||||
lsFilePath: item.lsFilePath || '', // 预览路径
|
lsFilePath: item.lsFilePath || '', // 预览路径
|
||||||
fileType: item.fileType || '2' // 文件类型(默认文档)
|
fileType: item.fileType || '2', // 文件类型(默认文档)
|
||||||
|
id: item.sourceId + ''
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- 模板部分保持不变 -->
|
|
||||||
<div>
|
<div>
|
||||||
<div class="basic-info-title">
|
<div class="basic-info-title">
|
||||||
<img src="@/assets/enterpriseLibrary/basic-info.png" alt="财务报告">
|
<img src="@/assets/enterpriseLibrary/basic-info.png" alt="财务报告">
|
||||||
|
|
@ -13,12 +12,11 @@
|
||||||
label-width="110px"
|
label-width="110px"
|
||||||
label-position="top"
|
label-position="top"
|
||||||
>
|
>
|
||||||
<!-- 财务报告上传 -->
|
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="财务报告附件" prop="fileList">
|
<el-form-item label="财务报告附件" prop="fileList">
|
||||||
<UploadFile
|
<UploadFile
|
||||||
:fileList="formatFileList()"
|
:fileList="formData.fileList"
|
||||||
:fileUploadRule="financeReportUploadRule"
|
:fileUploadRule="financeReportUploadRule"
|
||||||
@file-change="(files, type) => handleFileChange(files, type)"
|
@file-change="(files, type) => handleFileChange(files, type)"
|
||||||
@del-file="handleDelFile"
|
@del-file="handleDelFile"
|
||||||
|
|
@ -32,7 +30,6 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 文件名 -->
|
|
||||||
<el-row :gutter="24" class="info-row">
|
<el-row :gutter="24" class="info-row">
|
||||||
<el-col :span="8" class="info-col">
|
<el-col :span="8" class="info-col">
|
||||||
<el-form-item label="文件名" prop="fileName">
|
<el-form-item label="文件名" prop="fileName">
|
||||||
|
|
@ -46,7 +43,6 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<!-- 报告年份 -->
|
|
||||||
<el-col :span="8" class="info-col">
|
<el-col :span="8" class="info-col">
|
||||||
<el-form-item label="报告年份" prop="reportYear">
|
<el-form-item label="报告年份" prop="reportYear">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
|
|
@ -81,10 +77,10 @@ export default {
|
||||||
"报告年份": "reportYear"
|
"报告年份": "reportYear"
|
||||||
},
|
},
|
||||||
formData: {
|
formData: {
|
||||||
fileList: [], // 存储原始文件数据
|
fileList: [],
|
||||||
fileName: '',
|
fileName: '',
|
||||||
reportYear: '', // 存储年份字符串(如"2023")
|
reportYear: '',
|
||||||
delFileList: [] // 记录删除的文件路径
|
delFileList: []
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
fileList: [
|
fileList: [
|
||||||
|
|
@ -96,7 +92,8 @@ export default {
|
||||||
reportYear: [
|
reportYear: [
|
||||||
{ required: true, message: '请选择报告年份', trigger: 'change' }
|
{ required: true, message: '请选择报告年份', trigger: 'change' }
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
isReplacingFile: false // 新增:标记是否正在替换文件
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -115,51 +112,33 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 接收父组件数据并回显
|
|
||||||
setFormData(data) {
|
setFormData(data) {
|
||||||
|
// 财务报告文件:不手动生成uid
|
||||||
const financeFiles = Array.isArray(data.fileList)
|
const financeFiles = Array.isArray(data.fileList)
|
||||||
? data.fileList.filter(file => file && file.businessType === 'finance_report')
|
? data.fileList.filter(file => file && file.businessType === 'finance_report')
|
||||||
: []
|
.map(file => ({
|
||||||
|
name: file.name || file.fileName || '未知文件',
|
||||||
|
filePath: file.filePath,
|
||||||
|
lsFilePath: file.lsFilePath,
|
||||||
|
fileType: file.fileType || '2',
|
||||||
|
businessType: 'finance_report'
|
||||||
|
}))
|
||||||
|
: [];
|
||||||
|
|
||||||
this.formData = {
|
this.formData = {
|
||||||
...data,
|
...(data || {}),
|
||||||
fileList: financeFiles,
|
fileList: financeFiles,
|
||||||
fileName: financeFiles.length > 0 ? this.getFileName(financeFiles[0]) : '',
|
fileName: financeFiles.length > 0 ? this.getFileName(financeFiles[0]) : '',
|
||||||
delFileList: []
|
delFileList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 格式化文件列表,适配UploadFile组件
|
|
||||||
formatFileList() {
|
|
||||||
return this.formData.fileList.map((file, index) => {
|
|
||||||
const fileExt = this.getFileExt(file)
|
|
||||||
return {
|
|
||||||
...file,
|
|
||||||
uid: file.uid || file.filePath || `${Date.now()}-${index}`,
|
|
||||||
name: this.getFileName(file), // 这里会使用去掉后缀的文件名
|
|
||||||
status: file.status || 'success',
|
|
||||||
percentage: file.percentage || 100,
|
|
||||||
fileType: file.fileType || '2'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 核心修改:提取文件名并去掉后缀
|
|
||||||
getFileName(file) {
|
getFileName(file) {
|
||||||
// 先获取原始文件名(包含后缀)
|
const fullName = file.name || file.fileName || '未知文件'
|
||||||
const fullName = file.name || file.fileName || `未命名文件.${this.getFileExt(file)}`
|
|
||||||
|
|
||||||
// 查找最后一个点的位置,用于分割文件名和后缀
|
|
||||||
const lastDotIndex = fullName.lastIndexOf('.')
|
const lastDotIndex = fullName.lastIndexOf('.')
|
||||||
|
return lastDotIndex > 0 ? fullName.substring(0, lastDotIndex) : fullName
|
||||||
// 如果存在后缀(且点不是文件名的第一个字符),则去掉后缀;否则返回原文件名
|
|
||||||
if (lastDotIndex > 0) {
|
|
||||||
return fullName.substring(0, lastDotIndex)
|
|
||||||
}
|
|
||||||
return fullName
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 提取文件后缀(保持不变)
|
|
||||||
getFileExt(file) {
|
getFileExt(file) {
|
||||||
if (!file) return ''
|
if (!file) return ''
|
||||||
const fileName = file.name || file.fileName || ''
|
const fileName = file.name || file.fileName || ''
|
||||||
|
|
@ -167,37 +146,53 @@ export default {
|
||||||
return extMatch ? extMatch[1].toLowerCase() : ''
|
return extMatch ? extMatch[1].toLowerCase() : ''
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理文件变更(保持不变)
|
|
||||||
handleFileChange(files, type) {
|
handleFileChange(files, type) {
|
||||||
if (type === 'finance_report') {
|
if (type === 'finance_report' && files instanceof Array) {
|
||||||
|
// 处理文件替换逻辑
|
||||||
|
if (files.length > 0 && files[0].response) { // 验证上传成功
|
||||||
|
// 标记为已完成替换
|
||||||
|
this.isReplacingFile = false;
|
||||||
|
|
||||||
|
// 处理旧文件删除
|
||||||
|
if (this.formData.fileList.length > 0) {
|
||||||
|
const oldFile = this.formData.fileList[0];
|
||||||
|
const delPath = oldFile?.response?.fileRes?.filePath || oldFile?.filePath || null;
|
||||||
|
if (delPath && !this.formData.delFileList.includes(delPath)) {
|
||||||
|
this.formData.delFileList.push(delPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const markedFiles = files.map(file => ({
|
const markedFiles = files.map(file => ({
|
||||||
...file,
|
...file,
|
||||||
businessType: 'finance_report',
|
businessType: 'finance_report'
|
||||||
name: file.name || file.fileName || '未知文件'
|
})).slice(-1);
|
||||||
}))
|
|
||||||
this.formData.fileList = markedFiles
|
|
||||||
|
|
||||||
|
this.formData.fileList = markedFiles;
|
||||||
|
|
||||||
|
// 提取文件名逻辑不变
|
||||||
if (markedFiles.length > 0) {
|
if (markedFiles.length > 0) {
|
||||||
const originalFileName = this.getFileName(markedFiles[0]) // 这里会使用去掉后缀的文件名
|
const originalFileName = this.getFileName(markedFiles[0])
|
||||||
const safeFileName = originalFileName.replace(/--+/g, '-')
|
const safeFileName = originalFileName.replace(/--+/g, '-')
|
||||||
this.formData.fileName = safeFileName
|
this.formData.fileName = safeFileName
|
||||||
this.$refs.financeReportForm.validateField('fileName')
|
this.$refs.financeReportForm.validateField('fileName')
|
||||||
this.$message.success(`文件名已自动提取:${safeFileName}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handleOcrResult(markedFiles)
|
this.handleOcrResult(markedFiles)
|
||||||
|
} else if (!this.isReplacingFile) {
|
||||||
|
// 只有非替换操作才清空文件列表
|
||||||
|
this.formData.fileList = [];
|
||||||
|
this.formData.fileName = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 其他方法保持不变
|
|
||||||
handleDelFile(file) {
|
handleDelFile(file) {
|
||||||
const filePath = file.filePath || file.response?.fileRes?.uploadPath
|
// 标记为替换操作,保留文件列表结构等待新文件
|
||||||
if (filePath && !this.formData.delFileList.includes(filePath)) {
|
this.isReplacingFile = true;
|
||||||
this.formData.delFileList.push(filePath)
|
|
||||||
|
const delPath = file?.response?.fileRes?.filePath || file?.filePath || null;
|
||||||
|
if (delPath && !this.formData.delFileList.includes(delPath)) {
|
||||||
|
this.formData.delFileList.push(delPath);
|
||||||
}
|
}
|
||||||
this.formData.fileList = []
|
|
||||||
this.formData.fileName = ''
|
|
||||||
this.formData.reportYear = ''
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleOcrResult(files) {
|
handleOcrResult(files) {
|
||||||
|
|
@ -264,6 +259,7 @@ export default {
|
||||||
reportYear: '',
|
reportYear: '',
|
||||||
delFileList: []
|
delFileList: []
|
||||||
}
|
}
|
||||||
|
this.isReplacingFile = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
addOcrRule() {
|
addOcrRule() {
|
||||||
|
|
@ -292,7 +288,6 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
/* 样式部分保持不变 */
|
|
||||||
.basic-info-title {
|
.basic-info-title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,11 @@
|
||||||
label-width="110px"
|
label-width="110px"
|
||||||
label-position="top"
|
label-position="top"
|
||||||
>
|
>
|
||||||
<!-- 财务报表上传 -->
|
|
||||||
<el-row :gutter="24" class="data-row">
|
<el-row :gutter="24" class="data-row">
|
||||||
<el-col :span="8" class="data-col">
|
<el-col :span="8" class="data-col">
|
||||||
<el-form-item label="财务报表附件" prop="fileList" class="data-item">
|
<el-form-item label="财务报表附件" prop="fileList" class="data-item">
|
||||||
<UploadFile
|
<UploadFile
|
||||||
:fileList="formatFileList()"
|
:fileList="formData.fileList"
|
||||||
:fileUploadRule="financialStatementUploadRule"
|
:fileUploadRule="financialStatementUploadRule"
|
||||||
@file-change="(files, type) => handleFileChange(files, type)"
|
@file-change="(files, type) => handleFileChange(files, type)"
|
||||||
@del-file="handleDelFile"
|
@del-file="handleDelFile"
|
||||||
|
|
@ -31,7 +30,6 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 财务数据字段(三列布局) -->
|
|
||||||
<el-row :gutter="24" class="data-row">
|
<el-row :gutter="24" class="data-row">
|
||||||
<el-col :span="8" class="data-col">
|
<el-col :span="8" class="data-col">
|
||||||
<el-form-item label="营业收入" prop="operatingIncome" class="data-item">
|
<el-form-item label="营业收入" prop="operatingIncome" class="data-item">
|
||||||
|
|
@ -163,7 +161,7 @@ export default {
|
||||||
"资产负债率": "assetLiabilityRatio"
|
"资产负债率": "assetLiabilityRatio"
|
||||||
},
|
},
|
||||||
formData: {
|
formData: {
|
||||||
fileList: [], // 存储原始文件数据
|
fileList: [],
|
||||||
operatingIncome: '',
|
operatingIncome: '',
|
||||||
currentAssets: '',
|
currentAssets: '',
|
||||||
currentLiabilities: '',
|
currentLiabilities: '',
|
||||||
|
|
@ -174,7 +172,7 @@ export default {
|
||||||
totalLiabilities: '',
|
totalLiabilities: '',
|
||||||
totalAssets: '',
|
totalAssets: '',
|
||||||
assetLiabilityRatio: '',
|
assetLiabilityRatio: '',
|
||||||
delFileList: [] // 记录删除的文件路径
|
delFileList: []
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
fileList: [
|
fileList: [
|
||||||
|
|
@ -213,7 +211,8 @@ export default {
|
||||||
{ required: true, message: '资产负债率为必填项', trigger: 'blur' },
|
{ required: true, message: '资产负债率为必填项', trigger: 'blur' },
|
||||||
{ pattern: /^\d+(\.\d+)?%?$/, message: '请输入有效的资产负债率(如1或1%)', trigger: 'blur' }
|
{ pattern: /^\d+(\.\d+)?%?$/, message: '请输入有效的资产负债率(如1或1%)', trigger: 'blur' }
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
isReplacingFile: false // 新增:标记是否正在替换文件
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -232,43 +231,30 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 接收父组件数据并回显(适配编辑场景)
|
|
||||||
setFormData(data) {
|
setFormData(data) {
|
||||||
// 筛选出财务报表类型的文件(businessType=financial_statement)
|
// 财务报表文件:不手动生成uid
|
||||||
const financialFiles = Array.isArray(data.fileList)
|
const financialFiles = Array.isArray(data.fileList)
|
||||||
? data.fileList.filter(file => file && file.businessType === 'financial_statement')
|
? data.fileList.filter(file => file && file.businessType === 'financial_statement')
|
||||||
: []
|
.map(file => ({
|
||||||
|
name: file.name || file.fileName || '未知文件',
|
||||||
|
filePath: file.filePath,
|
||||||
|
lsFilePath: file.lsFilePath,
|
||||||
|
fileType: file.fileType || '2',
|
||||||
|
businessType: 'financial_statement'
|
||||||
|
}))
|
||||||
|
: [];
|
||||||
|
|
||||||
this.formData = {
|
this.formData = {
|
||||||
...data,
|
...(data || {}),
|
||||||
fileList: financialFiles, // 存储原始文件列表
|
fileList: financialFiles,
|
||||||
delFileList: [] // 清空删除记录
|
delFileList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 核心:格式化文件列表,适配UploadFile组件
|
|
||||||
formatFileList() {
|
|
||||||
return this.formData.fileList.map((file, index) => {
|
|
||||||
// 提取文件后缀
|
|
||||||
const fileExt = this.getFileExt(file)
|
|
||||||
return {
|
|
||||||
...file,
|
|
||||||
// 补充组件所需核心字段
|
|
||||||
uid: file.uid || file.filePath || `${Date.now()}-${index}`, // 唯一标识
|
|
||||||
name: this.getFileName(file), // 显示文件名
|
|
||||||
status: file.status || 'success', // 默认为已上传状态
|
|
||||||
percentage: file.percentage || 100, // 进度100%
|
|
||||||
fileType: file.fileType || '2' // 默认为文档类型
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 提取文件名(兼容不同数据结构)
|
|
||||||
getFileName(file) {
|
getFileName(file) {
|
||||||
return file.name || file.fileName || `未命名文件.${this.getFileExt(file)}`
|
return file.name || file.fileName || '未知文件'
|
||||||
},
|
},
|
||||||
|
|
||||||
// 提取文件后缀
|
|
||||||
getFileExt(file) {
|
getFileExt(file) {
|
||||||
if (!file) return ''
|
if (!file) return ''
|
||||||
const fileName = file.name || file.fileName || ''
|
const fileName = file.name || file.fileName || ''
|
||||||
|
|
@ -276,25 +262,39 @@ export default {
|
||||||
return extMatch ? extMatch[1].toLowerCase() : ''
|
return extMatch ? extMatch[1].toLowerCase() : ''
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理文件变更
|
|
||||||
handleFileChange(files, type) {
|
handleFileChange(files, type) {
|
||||||
if (type === 'financial_statement') {
|
if (type === 'financial_statement' && files instanceof Array) {
|
||||||
// 为新上传文件添加businessType标记,并补充name字段
|
// 处理文件替换逻辑
|
||||||
|
if (files.length > 0 && files[0].response) { // 验证上传成功
|
||||||
|
// 标记为已完成替换
|
||||||
|
this.isReplacingFile = false;
|
||||||
|
|
||||||
|
// 处理旧文件删除
|
||||||
|
if (this.formData.fileList.length > 0) {
|
||||||
|
const oldFile = this.formData.fileList[0];
|
||||||
|
const delPath = oldFile?.response?.fileRes?.filePath || oldFile?.filePath || null;
|
||||||
|
if (delPath && !this.formData.delFileList.includes(delPath)) {
|
||||||
|
this.formData.delFileList.push(delPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const markedFiles = files.map(file => ({
|
const markedFiles = files.map(file => ({
|
||||||
...file,
|
...file,
|
||||||
businessType: 'financial_statement',
|
businessType: 'financial_statement'
|
||||||
name: file.name || file.fileName || '未知文件' // 确保name存在
|
})).slice(-1);
|
||||||
}))
|
|
||||||
this.formData.fileList = markedFiles // 更新原始文件列表
|
this.formData.fileList = markedFiles;
|
||||||
this.handleOcrResult(markedFiles)
|
this.handleOcrResult(markedFiles)
|
||||||
|
} else if (!this.isReplacingFile) {
|
||||||
|
// 只有非替换操作才清空文件列表
|
||||||
|
this.formData.fileList = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理OCR识别结果
|
|
||||||
handleOcrResult(files) {
|
handleOcrResult(files) {
|
||||||
if (!files || !Array.isArray(files) || files.length === 0) return
|
if (!files || !Array.isArray(files) || files.length === 0) return
|
||||||
|
|
||||||
// 触发全局上传动画
|
|
||||||
this.$bus.$emit('startUpload', '正在识别财务数据')
|
this.$bus.$emit('startUpload', '正在识别财务数据')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -307,7 +307,6 @@ export default {
|
||||||
Object.keys(chat_res).forEach(key => {
|
Object.keys(chat_res).forEach(key => {
|
||||||
const formField = this.ocrResultParams[key]
|
const formField = this.ocrResultParams[key]
|
||||||
if (formField && chat_res[key]) {
|
if (formField && chat_res[key]) {
|
||||||
// 处理数字类型字段,移除非数字字符
|
|
||||||
if (['operatingIncome', 'currentAssets', 'currentLiabilities', 'currentRatio',
|
if (['operatingIncome', 'currentAssets', 'currentLiabilities', 'currentRatio',
|
||||||
'netProfit', 'shareholdersEquity', 'returnOnNetAssets', 'totalLiabilities',
|
'netProfit', 'shareholdersEquity', 'returnOnNetAssets', 'totalLiabilities',
|
||||||
'totalAssets', 'assetLiabilityRatio'].includes(formField)) {
|
'totalAssets', 'assetLiabilityRatio'].includes(formField)) {
|
||||||
|
|
@ -327,23 +326,20 @@ export default {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$message.error(`处理识别结果失败: ${error.message}`)
|
this.$message.error(`处理识别结果失败: ${error.message}`)
|
||||||
} finally {
|
} finally {
|
||||||
// 结束全局上传动画
|
|
||||||
this.$bus.$emit('endUpload')
|
this.$bus.$emit('endUpload')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理文件删除
|
|
||||||
handleDelFile(file) {
|
handleDelFile(file) {
|
||||||
// 记录删除的文件路径
|
// 标记为替换操作,保留文件列表结构等待新文件
|
||||||
const filePath = file.filePath || file.response?.fileRes?.uploadPath
|
this.isReplacingFile = true;
|
||||||
if (filePath && !this.formData.delFileList.includes(filePath)) {
|
|
||||||
this.formData.delFileList.push(filePath)
|
const delPath = file?.response?.fileRes?.filePath || file?.filePath || null;
|
||||||
|
if (delPath && !this.formData.delFileList.includes(delPath)) {
|
||||||
|
this.formData.delFileList.push(delPath);
|
||||||
}
|
}
|
||||||
// 清空文件列表(允许重新上传)
|
|
||||||
this.formData.fileList = []
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 表单验证
|
|
||||||
validate() {
|
validate() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this.$refs.financialStatementForm) {
|
if (!this.$refs.financialStatementForm) {
|
||||||
|
|
@ -361,7 +357,6 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 重置表单
|
|
||||||
resetForm() {
|
resetForm() {
|
||||||
if (this.$refs.financialStatementForm) {
|
if (this.$refs.financialStatementForm) {
|
||||||
this.$refs.financialStatementForm.resetFields()
|
this.$refs.financialStatementForm.resetFields()
|
||||||
|
|
@ -380,16 +375,15 @@ export default {
|
||||||
assetLiabilityRatio: '',
|
assetLiabilityRatio: '',
|
||||||
delFileList: []
|
delFileList: []
|
||||||
}
|
}
|
||||||
|
this.isReplacingFile = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 初始化OCR识别规则
|
|
||||||
addOcrRule() {
|
addOcrRule() {
|
||||||
this.ocrRuleList.forEach(item => {
|
this.ocrRuleList.forEach(item => {
|
||||||
this.ocrRule(item)
|
this.ocrRule(item)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取OCR识别规则
|
|
||||||
ocrRule(type) {
|
ocrRule(type) {
|
||||||
const foundItem = this.dict.type.identification_tag?.find(item => item.value === type)
|
const foundItem = this.dict.type.identification_tag?.find(item => item.value === type)
|
||||||
if (!foundItem) {
|
if (!foundItem) {
|
||||||
|
|
@ -468,7 +462,6 @@ export default {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 优化上传组件样式,确保文件列表正确显示 */
|
|
||||||
::v-deep .upload-container {
|
::v-deep .upload-container {
|
||||||
::v-deep .el-upload-dragger {
|
::v-deep .el-upload-dragger {
|
||||||
height: 180px;
|
height: 180px;
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,8 @@ export default {
|
||||||
name: item.fileName || '未知文件',
|
name: item.fileName || '未知文件',
|
||||||
filePath: item.filePath || '',
|
filePath: item.filePath || '',
|
||||||
lsFilePath: item.lsFilePath || '', // 预览路径
|
lsFilePath: item.lsFilePath || '', // 预览路径
|
||||||
fileType: item.fileType || '2' // 文件类型(默认文档)
|
fileType: item.fileType || '2', // 文件类型(默认文档)
|
||||||
|
id: item.sourceId + ''
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,18 +139,6 @@ export default {
|
||||||
this.$refs.otherInfo.validate()
|
this.$refs.otherInfo.validate()
|
||||||
])
|
])
|
||||||
|
|
||||||
// 2. 项目名称唯一性校验
|
|
||||||
if (this.type === 'add' || (this.type === 'edit' && contractData.proName !== this.originalProName)) {
|
|
||||||
const isUnique = await checkProNameUnique({
|
|
||||||
proName: contractData.proName,
|
|
||||||
enterpriseId: this.enterpriseId,
|
|
||||||
performanceId: this.id || null
|
|
||||||
})
|
|
||||||
if (!isUnique) {
|
|
||||||
throw new Error('同一企业下项目名称已存在,请更换')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 初始化提交数据
|
// 3. 初始化提交数据
|
||||||
const formData = {
|
const formData = {
|
||||||
...contractData,
|
...contractData,
|
||||||
|
|
@ -193,15 +181,15 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. 处理团队业绩证明附件
|
// 7. 处理团队业绩证明附件
|
||||||
// if (otherData.performanceFileList && otherData.performanceFileList.length) {
|
if (otherData.performanceFileList && otherData.performanceFileList.length) {
|
||||||
// const performanceFiles = otherData.performanceFileList.map(file =>
|
const performanceFiles = otherData.performanceFileList.map(file =>
|
||||||
// file.response?.fileRes ? { ...file.response.fileRes, businessType: 'team_performance' } : null
|
file.response?.fileRes ? { ...file.response.fileRes, businessType: 'team_performance' } : null
|
||||||
// ).filter(Boolean)
|
).filter(Boolean)
|
||||||
// formData.files.push(...performanceFiles)
|
formData.files.push(...performanceFiles)
|
||||||
// }
|
}
|
||||||
// if (otherData.delFileList && otherData.delFileList.length) {
|
if (otherData.delFileList && otherData.delFileList.length) {
|
||||||
// formData.delFiles.push(...otherData.delFileList)
|
formData.delFiles.push(...otherData.delFileList)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// 8. 删除临时文件字段
|
// 8. 删除临时文件字段
|
||||||
['fileList', 'completionReportFileList', 'bidNoticeFileList', 'performanceFileList', 'delFileList'].forEach(key => {
|
['fileList', 'completionReportFileList', 'bidNoticeFileList', 'performanceFileList', 'delFileList'].forEach(key => {
|
||||||
|
|
@ -242,6 +230,7 @@ export default {
|
||||||
const bidFiles = fileList.filter(f => f.businessType === 'bid_notice')
|
const bidFiles = fileList.filter(f => f.businessType === 'bid_notice')
|
||||||
const teamFiles = fileList.filter(f => f.businessType === 'team_performance')
|
const teamFiles = fileList.filter(f => f.businessType === 'team_performance')
|
||||||
|
|
||||||
|
|
||||||
// 传递数据给子组件
|
// 传递数据给子组件
|
||||||
this.$refs.contractInfo.setFormData({
|
this.$refs.contractInfo.setFormData({
|
||||||
...performanceData,
|
...performanceData,
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,11 @@
|
||||||
label-width="110px"
|
label-width="110px"
|
||||||
label-position="top"
|
label-position="top"
|
||||||
>
|
>
|
||||||
<!-- 竣工报告 -->
|
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="竣工报告附件" prop="completionReportFileList">
|
<el-form-item label="竣工报告附件" prop="completionReportFileList">
|
||||||
<UploadFile
|
<UploadFile
|
||||||
:fileList="formatFileList('completionReportFileList')"
|
:fileList="formData.completionReportFileList"
|
||||||
:fileUploadRule="completionReportUploadRule"
|
:fileUploadRule="completionReportUploadRule"
|
||||||
@file-change="(files, type) => handleFileChange('completionReportFileList', files, type)"
|
@file-change="(files, type) => handleFileChange('completionReportFileList', files, type)"
|
||||||
@del-file="(file) => handleDelFile('completionReportFileList', file)"
|
@del-file="(file) => handleDelFile('completionReportFileList', file)"
|
||||||
|
|
@ -30,11 +29,10 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<!-- 中标通知书 -->
|
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="中标通知书附件" prop="bidNoticeFileList">
|
<el-form-item label="中标通知书附件" prop="bidNoticeFileList">
|
||||||
<UploadFile
|
<UploadFile
|
||||||
:fileList="formatFileList('bidNoticeFileList')"
|
:fileList="formData.bidNoticeFileList"
|
||||||
:fileUploadRule="bidNoticeUploadRule"
|
:fileUploadRule="bidNoticeUploadRule"
|
||||||
@file-change="(files, type) => handleFileChange('bidNoticeFileList', files, type)"
|
@file-change="(files, type) => handleFileChange('bidNoticeFileList', files, type)"
|
||||||
@del-file="(file) => handleDelFile('bidNoticeFileList', file)"
|
@del-file="(file) => handleDelFile('bidNoticeFileList', file)"
|
||||||
|
|
@ -48,7 +46,6 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 时间信息 -->
|
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="开工时间" prop="startTime">
|
<el-form-item label="开工时间" prop="startTime">
|
||||||
|
|
@ -119,6 +116,10 @@ export default {
|
||||||
bidNoticeFileList: [
|
bidNoticeFileList: [
|
||||||
{ required: true, message: '请上传中标通知书附件', trigger: 'change' }
|
{ required: true, message: '请上传中标通知书附件', trigger: 'change' }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
replacingFiles: {
|
||||||
|
completionReportFileList: false,
|
||||||
|
bidNoticeFileList: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -142,48 +143,43 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 接收父组件数据并按业务类型回显
|
|
||||||
setFormData(data) {
|
setFormData(data) {
|
||||||
const completionFiles = Array.isArray(data.completionReportFileList)
|
// 竣工报告文件:不手动生成uid
|
||||||
? data.completionReportFileList.filter(file => file && file.businessType === 'completion_report')
|
const completionFiles = Array.isArray(data.fileList)
|
||||||
: []
|
? data.fileList.filter(file => file && file.businessType === 'completion_report')
|
||||||
const bidFiles = Array.isArray(data.bidNoticeFileList)
|
.map(file => ({
|
||||||
? data.bidNoticeFileList.filter(file => file && file.businessType === 'bid_notice')
|
name: file.name || file.fileName || '未知文件',
|
||||||
: []
|
filePath: file.filePath,
|
||||||
|
lsFilePath: file.lsFilePath,
|
||||||
|
fileType: file.fileType || '2',
|
||||||
|
businessType: 'completion_report'
|
||||||
|
}))
|
||||||
|
: [];
|
||||||
|
|
||||||
|
// 中标通知书文件:不手动生成uid
|
||||||
|
const bidFiles = Array.isArray(data.fileList)
|
||||||
|
? data.fileList.filter(file => file && file.businessType === 'bid_notice')
|
||||||
|
.map(file => ({
|
||||||
|
name: file.name || file.fileName || '未知文件',
|
||||||
|
filePath: file.filePath,
|
||||||
|
lsFilePath: file.lsFilePath,
|
||||||
|
fileType: file.fileType || '2',
|
||||||
|
businessType: 'bid_notice'
|
||||||
|
}))
|
||||||
|
: [];
|
||||||
|
|
||||||
this.formData = {
|
this.formData = {
|
||||||
...data,
|
...(data || {}),
|
||||||
completionReportFileList: completionFiles,
|
completionReportFileList: completionFiles,
|
||||||
bidNoticeFileList: bidFiles,
|
bidNoticeFileList: bidFiles,
|
||||||
delFileList: []
|
delFileList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 格式化文件列表
|
|
||||||
formatFileList(field) {
|
|
||||||
return this.formData[field].map((file, index) => {
|
|
||||||
const fileExt = this.getFileExt(file)
|
|
||||||
const businessType = field === 'completionReportFileList' ? 'completion_report' : 'bid_notice'
|
|
||||||
return {
|
|
||||||
...file,
|
|
||||||
uid: file.uid || file.filePath || `${Date.now()}-${index}-${field}`,
|
|
||||||
name: this.getFileName(file),
|
|
||||||
status: file.status || 'success',
|
|
||||||
percentage: file.percentage || 100,
|
|
||||||
fileType: file.fileType || '2',
|
|
||||||
businessType
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取文件名(去除后缀)
|
|
||||||
getFileName(file) {
|
getFileName(file) {
|
||||||
const fullName = file.name || file.fileName || `未命名文件.${this.getFileExt(file)}`
|
return file.name || file.fileName || '未知文件'
|
||||||
const lastDotIndex = fullName.lastIndexOf('.')
|
|
||||||
return lastDotIndex > 0 ? fullName.substring(0, lastDotIndex) : fullName
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取文件后缀
|
|
||||||
getFileExt(file) {
|
getFileExt(file) {
|
||||||
if (!file) return ''
|
if (!file) return ''
|
||||||
const fileName = file.name || file.fileName || ''
|
const fileName = file.name || file.fileName || ''
|
||||||
|
|
@ -191,22 +187,43 @@ export default {
|
||||||
return extMatch ? extMatch[1].toLowerCase() : ''
|
return extMatch ? extMatch[1].toLowerCase() : ''
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理文件变更
|
|
||||||
handleFileChange(field, files, type) {
|
handleFileChange(field, files, type) {
|
||||||
const markedFiles = files.map(file => ({
|
if (files instanceof Array) {
|
||||||
...file,
|
// 处理新文件上传
|
||||||
businessType: type,
|
if (files.length > 0) {
|
||||||
name: file.name || file.fileName || '未知文件'
|
// 标记为已完成替换
|
||||||
}))
|
this.replacingFiles[field] = false;
|
||||||
this.formData[field] = markedFiles
|
|
||||||
|
|
||||||
// 处理竣工报告的OCR识别
|
const markedFiles = files
|
||||||
if (field === 'completionReportFileList' && type === 'completion_report') {
|
.map(file => ({
|
||||||
|
...file,
|
||||||
|
businessType: type
|
||||||
|
}))
|
||||||
|
.slice(-1); // 限制1个文件
|
||||||
|
|
||||||
|
// 处理旧文件删除
|
||||||
|
if (this.formData[field].length > 0) {
|
||||||
|
const oldFile = this.formData[field][0];
|
||||||
|
const delPath = oldFile?.response?.fileRes?.filePath || oldFile?.filePath || null;
|
||||||
|
if (delPath && !this.formData.delFileList.includes(delPath)) {
|
||||||
|
this.formData.delFileList.push(delPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新为新文件
|
||||||
|
this.formData[field] = markedFiles;
|
||||||
|
|
||||||
|
// 处理OCR识别(仅竣工报告)
|
||||||
|
if (field === 'completionReportFileList' && type === 'completion_report' && markedFiles[0].response) {
|
||||||
this.handleOcrResult(markedFiles)
|
this.handleOcrResult(markedFiles)
|
||||||
}
|
}
|
||||||
|
} else if (!this.replacingFiles[field]) {
|
||||||
|
// 只有非替换操作才清空文件列表
|
||||||
|
this.formData[field] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理OCR结果
|
|
||||||
handleOcrResult(files) {
|
handleOcrResult(files) {
|
||||||
if (!files?.length) return
|
if (!files?.length) return
|
||||||
|
|
||||||
|
|
@ -235,17 +252,16 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理文件删除
|
|
||||||
handleDelFile(field, file) {
|
handleDelFile(field, file) {
|
||||||
const filePath = file.filePath || file.response?.fileRes?.uploadPath
|
// 标记为替换操作,保留文件列表结构
|
||||||
if (filePath && !this.formData.delFileList.includes(filePath)) {
|
this.replacingFiles[field] = true;
|
||||||
this.formData.delFileList.push(filePath)
|
|
||||||
|
const delPath = file?.response?.fileRes?.filePath || file?.filePath || null;
|
||||||
|
if (delPath && !this.formData.delFileList.includes(delPath)) {
|
||||||
|
this.formData.delFileList.push(delPath);
|
||||||
}
|
}
|
||||||
// 只清空当前字段的文件列表
|
|
||||||
this.formData[field] = []
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 日期验证
|
|
||||||
disabledFutureDate(date) {
|
disabledFutureDate(date) {
|
||||||
return date > new Date()
|
return date > new Date()
|
||||||
},
|
},
|
||||||
|
|
@ -265,7 +281,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 表单验证
|
|
||||||
validate() {
|
validate() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this.$refs.completionForm) {
|
if (!this.$refs.completionForm) {
|
||||||
|
|
@ -288,7 +303,6 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 重置表单
|
|
||||||
resetForm() {
|
resetForm() {
|
||||||
if (this.$refs.completionForm) {
|
if (this.$refs.completionForm) {
|
||||||
this.$refs.completionForm.resetFields()
|
this.$refs.completionForm.resetFields()
|
||||||
|
|
@ -300,9 +314,12 @@ export default {
|
||||||
completionTime: '',
|
completionTime: '',
|
||||||
delFileList: []
|
delFileList: []
|
||||||
}
|
}
|
||||||
|
this.replacingFiles = {
|
||||||
|
completionReportFileList: false,
|
||||||
|
bidNoticeFileList: false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 初始化OCR规则
|
|
||||||
addOcrRule() {
|
addOcrRule() {
|
||||||
this.ocrRuleList.forEach(item => this.ocrRule(item))
|
this.ocrRuleList.forEach(item => this.ocrRule(item))
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,8 @@ export default {
|
||||||
name: item.fileName || '未知文件',
|
name: item.fileName || '未知文件',
|
||||||
filePath: item.filePath || '',
|
filePath: item.filePath || '',
|
||||||
lsFilePath: item.lsFilePath || '',
|
lsFilePath: item.lsFilePath || '',
|
||||||
fileType: item.fileType || '2'
|
fileType: item.fileType || '2',
|
||||||
|
id: item.sourceId + ''
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="合同附件" prop="fileList">
|
<el-form-item label="合同附件" prop="fileList">
|
||||||
<UploadFile
|
<UploadFile
|
||||||
:fileList="formatFileList()"
|
:fileList="formData.fileList"
|
||||||
:fileUploadRule="contractUploadRule"
|
:fileUploadRule="contractUploadRule"
|
||||||
@file-change="(files, type) => handleFileChange(files, type)"
|
@file-change="(files, type) => handleFileChange(files, type)"
|
||||||
@del-file="handleDelFile"
|
@del-file="handleDelFile"
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
:maxFileTips="maxFileTips"
|
:maxFileTips="maxFileTips"
|
||||||
type="contract"
|
type="contract"
|
||||||
:show-file-list="true"
|
:show-file-list="true"
|
||||||
|
:limitUploadNum="1"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -42,7 +43,6 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<!-- 合同签订时间 -->
|
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="合同签订时间" prop="contractSigningTime">
|
<el-form-item label="合同签订时间" prop="contractSigningTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
|
|
@ -56,7 +56,6 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<!-- 合同金额 -->
|
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="合同金额" prop="contractAmount">
|
<el-form-item label="合同金额" prop="contractAmount">
|
||||||
<el-input
|
<el-input
|
||||||
|
|
@ -72,7 +71,6 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 建设地点 -->
|
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="建设地点" prop="constructionSite">
|
<el-form-item label="建设地点" prop="constructionSite">
|
||||||
|
|
@ -81,12 +79,11 @@
|
||||||
placeholder="请输入建设地点"
|
placeholder="请输入建设地点"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
maxlength="32"
|
maxlength="100"
|
||||||
></el-input>
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<!-- 建设单位 -->
|
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="建设单位" prop="constructionUnit">
|
<el-form-item label="建设单位" prop="constructionUnit">
|
||||||
<el-input
|
<el-input
|
||||||
|
|
@ -94,12 +91,11 @@
|
||||||
placeholder="请输入建设单位"
|
placeholder="请输入建设单位"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
maxlength="32"
|
maxlength="100"
|
||||||
></el-input>
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<!-- 建设单位联系方式 -->
|
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="建设单位联系方式" prop="constructionPhone">
|
<el-form-item label="建设单位联系方式" prop="constructionPhone">
|
||||||
<el-input
|
<el-input
|
||||||
|
|
@ -137,14 +133,14 @@ export default {
|
||||||
"建设单位联系方式": "constructionPhone"
|
"建设单位联系方式": "constructionPhone"
|
||||||
},
|
},
|
||||||
formData: {
|
formData: {
|
||||||
fileList: [], // 存储合同附件列表
|
fileList: [],
|
||||||
proName: '',
|
proName: '',
|
||||||
contractSigningTime: '',
|
contractSigningTime: '',
|
||||||
contractAmount: '',
|
contractAmount: '',
|
||||||
constructionSite: '',
|
constructionSite: '',
|
||||||
constructionUnit: '',
|
constructionUnit: '',
|
||||||
constructionPhone: '',
|
constructionPhone: '',
|
||||||
delFileList: [] // 记录删除的文件路径
|
delFileList: []
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
proName: [
|
proName: [
|
||||||
|
|
@ -169,7 +165,8 @@ export default {
|
||||||
{ required: true, message: '请输入建设单位联系方式', trigger: 'blur' },
|
{ required: true, message: '请输入建设单位联系方式', trigger: 'blur' },
|
||||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入有效的手机号码', trigger: 'blur' }
|
{ pattern: /^1[3-9]\d{9}$/, message: '请输入有效的手机号码', trigger: 'blur' }
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
isReplacingFile: false // 标记是否正在替换文件
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|
@ -188,43 +185,30 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 接收父组件数据并回显
|
|
||||||
setFormData(data) {
|
setFormData(data) {
|
||||||
|
// 回显文件:不手动生成uid,仅传递基础字段
|
||||||
const contractFiles = Array.isArray(data.fileList)
|
const contractFiles = Array.isArray(data.fileList)
|
||||||
? data.fileList.filter(file => file && file.businessType === 'contract')
|
? data.fileList.filter(file => file && file.businessType === 'contract')
|
||||||
: []
|
.map(file => ({
|
||||||
|
name: file.name || file.fileName || '未知文件',
|
||||||
|
filePath: file.filePath,
|
||||||
|
lsFilePath: file.lsFilePath,
|
||||||
|
fileType: file.fileType || '2',
|
||||||
|
businessType: 'contract'
|
||||||
|
}))
|
||||||
|
: [];
|
||||||
|
|
||||||
this.formData = {
|
this.formData = {
|
||||||
...data,
|
...(data || {}),
|
||||||
fileList: contractFiles,
|
fileList: contractFiles,
|
||||||
delFileList: []
|
delFileList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 格式化文件列表
|
|
||||||
formatFileList() {
|
|
||||||
return this.formData.fileList.map((file, index) => {
|
|
||||||
const fileExt = this.getFileExt(file)
|
|
||||||
return {
|
|
||||||
...file,
|
|
||||||
uid: file.uid || file.filePath || `${Date.now()}-${index}`,
|
|
||||||
name: this.getFileName(file),
|
|
||||||
status: file.status || 'success',
|
|
||||||
percentage: file.percentage || 100,
|
|
||||||
fileType: file.fileType || '2',
|
|
||||||
businessType: 'contract'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取文件名(去除后缀)
|
|
||||||
getFileName(file) {
|
getFileName(file) {
|
||||||
const fullName = file.name || file.fileName || `未命名文件.${this.getFileExt(file)}`
|
return file.name || file.fileName || '未知文件'
|
||||||
const lastDotIndex = fullName.lastIndexOf('.')
|
|
||||||
return lastDotIndex > 0 ? fullName.substring(0, lastDotIndex) : fullName
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取文件后缀
|
|
||||||
getFileExt(file) {
|
getFileExt(file) {
|
||||||
if (!file) return ''
|
if (!file) return ''
|
||||||
const fileName = file.name || file.fileName || ''
|
const fileName = file.name || file.fileName || ''
|
||||||
|
|
@ -232,20 +216,31 @@ export default {
|
||||||
return extMatch ? extMatch[1].toLowerCase() : ''
|
return extMatch ? extMatch[1].toLowerCase() : ''
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理文件变更
|
|
||||||
handleFileChange(files, type) {
|
handleFileChange(files, type) {
|
||||||
if (type === 'contract') {
|
if (type === 'contract' && files instanceof Array) {
|
||||||
|
// 处理文件替换逻辑
|
||||||
|
if (files.length > 0) {
|
||||||
|
// 标记为已完成替换
|
||||||
|
this.isReplacingFile = false;
|
||||||
|
|
||||||
const markedFiles = files.map(file => ({
|
const markedFiles = files.map(file => ({
|
||||||
...file,
|
...file,
|
||||||
businessType: 'contract',
|
businessType: 'contract'
|
||||||
name: file.name || file.fileName || '未知文件'
|
})).slice(-1); // 限制1个文件
|
||||||
}))
|
|
||||||
this.formData.fileList = markedFiles
|
this.formData.fileList = markedFiles;
|
||||||
this.handleOcrResult(markedFiles)
|
|
||||||
|
// 只有当文件有response时才进行OCR识别
|
||||||
|
if (markedFiles.length > 0 && markedFiles[0].response) {
|
||||||
|
this.handleOcrResult(markedFiles);
|
||||||
|
}
|
||||||
|
} else if (!this.isReplacingFile) {
|
||||||
|
// 只有非替换操作才清空文件列表
|
||||||
|
this.formData.fileList = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理OCR识别结果
|
|
||||||
handleOcrResult(files) {
|
handleOcrResult(files) {
|
||||||
if (!files || !Array.isArray(files) || files.length === 0) return
|
if (!files || !Array.isArray(files) || files.length === 0) return
|
||||||
|
|
||||||
|
|
@ -259,7 +254,6 @@ export default {
|
||||||
const formField = this.ocrResultParams[key]
|
const formField = this.ocrResultParams[key]
|
||||||
if (formField && chatRes[key]) {
|
if (formField && chatRes[key]) {
|
||||||
let value = chatRes[key]
|
let value = chatRes[key]
|
||||||
// 清洗合同金额中的非数字字符
|
|
||||||
if (formField === 'contractAmount') {
|
if (formField === 'contractAmount') {
|
||||||
value = value.replace(/[^\d.]/g, '')
|
value = value.replace(/[^\d.]/g, '')
|
||||||
}
|
}
|
||||||
|
|
@ -279,21 +273,20 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理文件删除
|
|
||||||
handleDelFile(file) {
|
handleDelFile(file) {
|
||||||
const filePath = file.filePath || file.response?.fileRes?.uploadPath
|
// 标记为替换操作,保留文件列表结构等待新文件
|
||||||
if (filePath && !this.formData.delFileList.includes(filePath)) {
|
this.isReplacingFile = true;
|
||||||
this.formData.delFileList.push(filePath)
|
|
||||||
|
const delPath = file?.response?.fileRes?.filePath || file?.filePath || null;
|
||||||
|
if (delPath && !this.formData.delFileList.includes(delPath)) {
|
||||||
|
this.formData.delFileList.push(delPath);
|
||||||
}
|
}
|
||||||
this.formData.fileList = []
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 禁止选择未来日期
|
|
||||||
disabledFutureDate(date) {
|
disabledFutureDate(date) {
|
||||||
return date > new Date()
|
return date > new Date()
|
||||||
},
|
},
|
||||||
|
|
||||||
// 表单验证
|
|
||||||
validate() {
|
validate() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this.$refs.contractForm) {
|
if (!this.$refs.contractForm) {
|
||||||
|
|
@ -311,7 +304,6 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 重置表单
|
|
||||||
resetForm() {
|
resetForm() {
|
||||||
if (this.$refs.contractForm) {
|
if (this.$refs.contractForm) {
|
||||||
this.$refs.contractForm.resetFields()
|
this.$refs.contractForm.resetFields()
|
||||||
|
|
@ -326,16 +318,15 @@ export default {
|
||||||
constructionPhone: '',
|
constructionPhone: '',
|
||||||
delFileList: []
|
delFileList: []
|
||||||
}
|
}
|
||||||
|
this.isReplacingFile = false
|
||||||
},
|
},
|
||||||
|
|
||||||
// 初始化OCR识别规则
|
|
||||||
addOcrRule() {
|
addOcrRule() {
|
||||||
this.ocrRuleList.forEach(item => {
|
this.ocrRuleList.forEach(item => {
|
||||||
this.ocrRule(item)
|
this.ocrRule(item)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取OCR识别规则
|
|
||||||
ocrRule(type) {
|
ocrRule(type) {
|
||||||
const foundItem = this.dict.type.identification_tag?.find(item => item.value === type)
|
const foundItem = this.dict.type.identification_tag?.find(item => item.value === type)
|
||||||
if (!foundItem) {
|
if (!foundItem) {
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,8 @@ export default {
|
||||||
name: item.fileName || '未知文件',
|
name: item.fileName || '未知文件',
|
||||||
filePath: item.filePath || '', // 文件实际路径
|
filePath: item.filePath || '', // 文件实际路径
|
||||||
lsFilePath: item.lsFilePath || '', // 文件预览路径
|
lsFilePath: item.lsFilePath || '', // 文件预览路径
|
||||||
fileType: item.fileType || '2' // 2表示文档类型
|
fileType: item.fileType || '2', // 2表示文档类型
|
||||||
|
id: item.sourceId + ''
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,22 +13,22 @@
|
||||||
label-position="top"
|
label-position="top"
|
||||||
>
|
>
|
||||||
<!-- 团队业绩证明 -->
|
<!-- 团队业绩证明 -->
|
||||||
<!-- <el-row :gutter="24">-->
|
<el-row :gutter="24">
|
||||||
<!-- <el-col :span="8">-->
|
<el-col :span="8">
|
||||||
<!-- <el-form-item label="团队业绩证明" prop="performanceFileList">-->
|
<el-form-item label="团队业绩证明" prop="performanceFileList">
|
||||||
<!-- <UploadFile-->
|
<UploadFile
|
||||||
<!-- :fileList="formatFileList()"-->
|
ref="uploadFileComp"
|
||||||
<!-- @file-change="(files, type) => handleFileChange(files, type)"-->
|
:fileList="formData.performanceFileList"
|
||||||
<!-- @del-file="handleDelFile"-->
|
@file-change="handleFileChange"
|
||||||
<!-- :uploadType="uploadType"-->
|
@del-file="handleDelFile"
|
||||||
<!-- :maxFileTips="maxFileTips"-->
|
:uploadType="uploadType"
|
||||||
<!-- :limitUploadNum="3"-->
|
:maxFileTips="maxFileTips"
|
||||||
<!-- type="team_performance"-->
|
:limitUploadNum="1"
|
||||||
<!-- :show-file-list="true"-->
|
type="team_performance"
|
||||||
<!-- />-->
|
/>
|
||||||
<!-- </el-form-item>-->
|
</el-form-item>
|
||||||
<!-- </el-col>-->
|
</el-col>
|
||||||
<!-- </el-row>-->
|
</el-row>
|
||||||
|
|
||||||
<!-- 项目信息 -->
|
<!-- 项目信息 -->
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
|
|
@ -107,6 +107,9 @@
|
||||||
<script>
|
<script>
|
||||||
import UploadFile from '@/views/common/UploadFile.vue'
|
import UploadFile from '@/views/common/UploadFile.vue'
|
||||||
|
|
||||||
|
// 工具函数:安全获取数组
|
||||||
|
const safeGetArray = (value) => Array.isArray(value) ? value : []
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'OtherInfo',
|
name: 'OtherInfo',
|
||||||
components: { UploadFile },
|
components: { UploadFile },
|
||||||
|
|
@ -125,8 +128,8 @@ export default {
|
||||||
proType: '',
|
proType: '',
|
||||||
voltageLevel: '',
|
voltageLevel: '',
|
||||||
projectOverview: '',
|
projectOverview: '',
|
||||||
performanceFileList: [], // 存储原始文件数据
|
performanceFileList: [], // 完全同步UploadFile的文件列表
|
||||||
delFileList: [] // 记录删除的文件路径
|
delFileList: [] // 记录删除/替换的文件路径
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
projectManager: [
|
projectManager: [
|
||||||
|
|
@ -143,7 +146,7 @@ export default {
|
||||||
{ max: 500, message: '项目概况不能超过500个字符', trigger: 'blur' }
|
{ max: 500, message: '项目概况不能超过500个字符', trigger: 'blur' }
|
||||||
],
|
],
|
||||||
performanceFileList: [
|
performanceFileList: [
|
||||||
{ required: true, message: '请上传团队业绩证明', trigger: 'change' }
|
{ required: true, message: '请上传团队业绩证明', trigger: ['change', 'blur'] }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
proTypeOptions: [],
|
proTypeOptions: [],
|
||||||
|
|
@ -155,48 +158,24 @@ export default {
|
||||||
this.loadProjcetTypeDict()
|
this.loadProjcetTypeDict()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 接收父组件数据并回显(按业务类型筛选文件)
|
// 接收父组件数据并回显(完全对齐正常组件的getFileList逻辑)
|
||||||
setFormData(data) {
|
setFormData(data) {
|
||||||
const teamFiles = Array.isArray(data.performanceFileList)
|
const teamFiles = Array.isArray(data.fileList)
|
||||||
? data.performanceFileList.filter(file => file && file.businessType === 'team_performance')
|
? data.fileList.filter(file => file && file.businessType === 'team_performance')
|
||||||
: []
|
.map(file => ({
|
||||||
|
name: file.fileName,
|
||||||
|
filePath: file.filePath,
|
||||||
|
lsFilePath: file.lsFilePath,
|
||||||
|
fileType: file.fileType,
|
||||||
|
// 不手动生成uid,由UploadFile处理
|
||||||
|
}))
|
||||||
|
: [];
|
||||||
|
|
||||||
this.formData = {
|
this.formData = {
|
||||||
...data,
|
...data,
|
||||||
performanceFileList: teamFiles,
|
performanceFileList: teamFiles,
|
||||||
delFileList: []
|
delFileList: []
|
||||||
}
|
};
|
||||||
},
|
|
||||||
|
|
||||||
// 格式化文件列表,适配UploadFile组件
|
|
||||||
formatFileList() {
|
|
||||||
return this.formData.performanceFileList.map((file, index) => {
|
|
||||||
const fileExt = this.getFileExt(file)
|
|
||||||
return {
|
|
||||||
...file,
|
|
||||||
uid: file.uid || file.filePath || `${Date.now()}-${index}`,
|
|
||||||
name: this.getFileName(file), // 去除后缀的文件名
|
|
||||||
status: file.status || 'success',
|
|
||||||
percentage: file.percentage || 100,
|
|
||||||
fileType: file.fileType || '2',
|
|
||||||
businessType: 'team_performance'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 提取文件名并去掉后缀
|
|
||||||
getFileName(file) {
|
|
||||||
const fullName = file.name || file.fileName || `未命名文件.${this.getFileExt(file)}`
|
|
||||||
const lastDotIndex = fullName.lastIndexOf('.')
|
|
||||||
return lastDotIndex > 0 ? fullName.substring(0, lastDotIndex) : fullName
|
|
||||||
},
|
|
||||||
|
|
||||||
// 提取文件后缀
|
|
||||||
getFileExt(file) {
|
|
||||||
if (!file) return ''
|
|
||||||
const fileName = file.name || file.fileName || ''
|
|
||||||
const extMatch = fileName.match(/\.([a-zA-Z0-9]+)$/)
|
|
||||||
return extMatch ? extMatch[1].toLowerCase() : ''
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 加载字典数据
|
// 加载字典数据
|
||||||
|
|
@ -222,32 +201,22 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理文件变更
|
// 关键修改:仅在文件上传成功(有response)后更新列表
|
||||||
handleFileChange(files, type) {
|
handleFileChange(files, type) {
|
||||||
if (type === 'team_performance') {
|
if (type === 'team_performance' && files instanceof Array) {
|
||||||
const markedFiles = files.map(file => ({
|
// 仅在文件上传成功后才更新(对齐正常组件逻辑)
|
||||||
...file,
|
if (files.length > 0 && files[0].response) {
|
||||||
businessType: 'team_performance',
|
this.formData.performanceFileList = files;
|
||||||
name: file.name || file.fileName || '未知文件'
|
|
||||||
}))
|
|
||||||
this.formData.performanceFileList = markedFiles
|
|
||||||
|
|
||||||
if (markedFiles.length > 0) {
|
|
||||||
this.$message.success(`成功上传${markedFiles.length}个团队业绩证明文件`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 处理文件删除
|
// 处理文件删除(与正常组件逻辑一致)
|
||||||
handleDelFile(file) {
|
handleDelFile(file) {
|
||||||
const filePath = file.filePath || file.response?.fileRes?.uploadPath
|
const delPath = file?.response?.fileRes?.filePath || file?.filePath || null;
|
||||||
if (filePath && !this.formData.delFileList.includes(filePath)) {
|
if (delPath) {
|
||||||
this.formData.delFileList.push(filePath)
|
this.formData.delFileList.push(delPath);
|
||||||
}
|
}
|
||||||
// 保留其他文件,只删除当前文件
|
|
||||||
this.formData.performanceFileList = this.formData.performanceFileList.filter(
|
|
||||||
item => item.uid !== file.uid
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 表单验证
|
// 表单验证
|
||||||
|
|
@ -270,6 +239,10 @@ export default {
|
||||||
|
|
||||||
// 重置表单
|
// 重置表单
|
||||||
resetForm() {
|
resetForm() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.uploadFileComp) {
|
||||||
|
this.$refs.uploadFileComp.clearFiles();
|
||||||
|
}
|
||||||
if (this.$refs.otherForm) {
|
if (this.$refs.otherForm) {
|
||||||
this.$refs.otherForm.resetFields()
|
this.$refs.otherForm.resetFields()
|
||||||
}
|
}
|
||||||
|
|
@ -281,6 +254,7 @@ export default {
|
||||||
performanceFileList: [],
|
performanceFileList: [],
|
||||||
delFileList: []
|
delFileList: []
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,18 +11,18 @@
|
||||||
class="detail-form"
|
class="detail-form"
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- <el-row :gutter="24">-->
|
<el-row :gutter="24">
|
||||||
<!-- <el-col :span="12">-->
|
<el-col :span="8">
|
||||||
<!-- <el-form-item label="团队业绩证明" class="form-item">-->
|
<el-form-item label="团队业绩证明" class="form-item">
|
||||||
<!-- <FileOrImageDisplay-->
|
<FileOrImageDisplay
|
||||||
<!-- :label="''"-->
|
:label="''"
|
||||||
<!-- :file="form.fileList[0]"-->
|
:file="form.fileList[0]"
|
||||||
<!-- :image-url="form.url"-->
|
:image-url="form.url"
|
||||||
<!-- />-->
|
/>
|
||||||
<!-- <span v-if="form.fileList.length === 0" class="no-file-tip">无附件</span>-->
|
<span v-if="form.fileList.length === 0" class="no-file-tip">无附件</span>
|
||||||
<!-- </el-form-item>-->
|
</el-form-item>
|
||||||
<!-- </el-col>-->
|
</el-col>
|
||||||
<!-- </el-row>-->
|
</el-row>
|
||||||
|
|
||||||
<!-- 项目经理 + 项目类型:使用输入框(禁用) -->
|
<!-- 项目经理 + 项目类型:使用输入框(禁用) -->
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
|
|
@ -126,14 +126,15 @@ export default {
|
||||||
getFileList() {
|
getFileList() {
|
||||||
// 从detailData中筛选业绩证明类型的文件
|
// 从detailData中筛选业绩证明类型的文件
|
||||||
const rawFileList = Array.isArray(this.detailData.fileList) ? this.detailData.fileList : []
|
const rawFileList = Array.isArray(this.detailData.fileList) ? this.detailData.fileList : []
|
||||||
const performanceFiles = rawFileList.filter(file => file && file.businessType === 'performance')
|
const performanceFiles = rawFileList.filter(file => file && file.businessType === 'team_performance')
|
||||||
|
|
||||||
// 格式化文件数据
|
// 格式化文件数据
|
||||||
return performanceFiles.map(item => ({
|
return performanceFiles.map(item => ({
|
||||||
name: item.fileName || '未知文件',
|
name: item.fileName || '未知文件',
|
||||||
filePath: item.filePath || '', // 文件实际路径
|
filePath: item.filePath || '', // 文件实际路径
|
||||||
lsFilePath: item.lsFilePath || '', // 文件预览路径
|
lsFilePath: item.lsFilePath || '', // 文件预览路径
|
||||||
fileType: item.fileType || '2' // 2表示文档类型
|
fileType: item.fileType || '2', // 2表示文档类型
|
||||||
|
id: item.sourceId + ''
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,8 @@ export default {
|
||||||
name: item.fileName || item.name || '未知文件',
|
name: item.fileName || item.name || '未知文件',
|
||||||
filePath: item.filePath || '',
|
filePath: item.filePath || '',
|
||||||
lsFilePath: item.lsFilePath || item.fileUrl || '',
|
lsFilePath: item.lsFilePath || item.fileUrl || '',
|
||||||
fileType: item.fileType || '2'
|
fileType: item.fileType || '2',
|
||||||
|
id: item.sourceId + ''
|
||||||
}))
|
}))
|
||||||
|
|
||||||
this.form = {
|
this.form = {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue