文件编辑问题修复,添加文件预览功能

This commit is contained in:
LHD_HY 2025-11-18 14:52:37 +08:00
parent 82bab0ea11
commit df332f8138
12 changed files with 323 additions and 358 deletions

View File

@ -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 + ''
})) }))
}, },

View File

@ -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;

View File

@ -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) {
// businessTypename //
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;

View File

@ -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 + ''
})) }))
}, },

View File

@ -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,

View File

@ -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))
}, },

View File

@ -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 + ''
})) }))
}, },

View File

@ -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)
// responseOCR
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) {

View File

@ -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 + ''
})) }))
} }
} }

View File

@ -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,
// uidUploadFile
}))
: [];
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: []
} }
});
} }
} }
} }

View File

@ -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 + ''
})) }))
} }
} }

View File

@ -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 = {