|
|
@@ -1,7 +1,12 @@
|
|
|
<template>
|
|
|
<div class="app-container">
|
|
|
<div class="audit-controls">
|
|
|
- <el-form ref="auditForm" :model="auditForm" :rules="rules">
|
|
|
+ <el-form
|
|
|
+ ref="auditForm"
|
|
|
+ :model="auditForm"
|
|
|
+ :rules="rules"
|
|
|
+ :disabled="auditForm.surveyTemplateId !== ''"
|
|
|
+ >
|
|
|
<el-row>
|
|
|
<el-col :span="6">
|
|
|
<el-form-item label="" prop="catalogId">
|
|
|
@@ -87,7 +92,12 @@
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
</el-form>
|
|
|
- <el-button type="primary" size="small" @click="handleGenerateTemplate">
|
|
|
+ <el-button
|
|
|
+ v-if="!auditForm.surveyTemplateId"
|
|
|
+ type="primary"
|
|
|
+ size="small"
|
|
|
+ @click="handleGenerateTemplate"
|
|
|
+ >
|
|
|
生成核定表
|
|
|
</el-button>
|
|
|
<el-button type="primary" size="small" @click="handleSaveTemplate">
|
|
|
@@ -162,15 +172,13 @@
|
|
|
} from '@/api/costFormManage'
|
|
|
import {
|
|
|
getlistBySurveyTemplateId,
|
|
|
- batchDeleteCostVerifyForm,
|
|
|
- getlistBySurveyTemplateIdcurrentversion,
|
|
|
- batchSave,
|
|
|
- enable,
|
|
|
- getListFixedEnabled,
|
|
|
- listByVerifyTemplateId,
|
|
|
+ getVerifyTemplateDetail,
|
|
|
+ importExcel,
|
|
|
+ exportExcel,
|
|
|
} from '@/api/costVerifyManage'
|
|
|
import { getDetail } from '@/api/auditInitiation'
|
|
|
import { catalogMixin } from '@/mixins/useDict'
|
|
|
+ import { saveAs } from 'file-saver'
|
|
|
export default {
|
|
|
name: 'CostAudit',
|
|
|
mixins: [catalogMixin],
|
|
|
@@ -233,99 +241,9 @@
|
|
|
tableHeadersRes: [],
|
|
|
tableDataRes: [],
|
|
|
// 成本审核表格列配置
|
|
|
- costAuditcolumn: [
|
|
|
- // {
|
|
|
- // prop: 'id',
|
|
|
- // label: '序号',
|
|
|
- // width: 80,
|
|
|
- // align: 'center',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // prop: 'itemName',
|
|
|
- // label: '项目',
|
|
|
- // width: 180,
|
|
|
- // },
|
|
|
- // {
|
|
|
- // prop: 'unit',
|
|
|
- // label: '单位',
|
|
|
- // width: 100,
|
|
|
- // align: 'center',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // prop: 'year2022BookValue',
|
|
|
- // label: '2022年账面值',
|
|
|
- // width: 120,
|
|
|
- // align: 'right',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // prop: 'year2022Audit',
|
|
|
- // label: '2022年审核',
|
|
|
- // width: 120,
|
|
|
- // align: 'center',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // prop: 'year2022ApprovedValue',
|
|
|
- // label: '2022年核定值',
|
|
|
- // width: 120,
|
|
|
- // align: 'right',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // prop: 'year2023BookValue',
|
|
|
- // label: '2023年账面值',
|
|
|
- // width: 120,
|
|
|
- // align: 'right',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // prop: 'year2023Audit',
|
|
|
- // label: '2023年审核',
|
|
|
- // width: 120,
|
|
|
- // align: 'center',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // prop: 'year2023ApprovedValue',
|
|
|
- // label: '2023年核定值',
|
|
|
- // width: 120,
|
|
|
- // align: 'right',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // prop: 'year2024BookValue',
|
|
|
- // label: '2024年账面值',
|
|
|
- // width: 120,
|
|
|
- // align: 'right',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // prop: 'year2024Audit',
|
|
|
- // label: '2024年审核',
|
|
|
- // width: 120,
|
|
|
- // align: 'center',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // prop: 'year2024ApprovedValue',
|
|
|
- // label: '2024年核定值',
|
|
|
- // width: 120,
|
|
|
- // align: 'right',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // prop: 'action',
|
|
|
- // label: '操作',
|
|
|
- // width: 150,
|
|
|
- // align: 'center',
|
|
|
- // fixed: 'right',
|
|
|
- // },
|
|
|
- ],
|
|
|
+ costAuditcolumn: [],
|
|
|
// 成本审核数据
|
|
|
- costAuditData: [
|
|
|
- // {
|
|
|
- // id: '一',
|
|
|
- // itemName: '人员费用小计',
|
|
|
- // unit: '元',
|
|
|
- // },
|
|
|
- // {
|
|
|
- // id: 1,
|
|
|
- // itemName: '基本工资',
|
|
|
- // unit: '元',
|
|
|
- // },
|
|
|
- ],
|
|
|
+ costAuditData: [],
|
|
|
project: {},
|
|
|
}
|
|
|
},
|
|
|
@@ -342,12 +260,7 @@
|
|
|
if (newVal) {
|
|
|
this.$nextTick(() => {
|
|
|
// 获取项目的详情数据
|
|
|
- getDetail({ id: newVal.projectId }).then((res) => {
|
|
|
- if (res.code === 200) {
|
|
|
- this.project = res.value
|
|
|
- this.auditForm.catalogId = res.value.catalogId
|
|
|
- }
|
|
|
- })
|
|
|
+ this.getDetail()
|
|
|
})
|
|
|
}
|
|
|
},
|
|
|
@@ -355,19 +268,24 @@
|
|
|
created() {
|
|
|
if (this.selectedProject && this.selectedProject.projectId) {
|
|
|
// 获取项目的详情数据
|
|
|
- getDetail({ id: this.selectedProject.projectId }).then((res) => {
|
|
|
- if (res.code === 200) {
|
|
|
- this.project = res.value
|
|
|
- this.auditForm.catalogId = res.value.catalogId
|
|
|
- this.loadTemplateDataForEdit()
|
|
|
- }
|
|
|
- })
|
|
|
+ this.getDetail()
|
|
|
}
|
|
|
this.getActiveCostVerifyFormListByType()
|
|
|
this.getActiveCostVerifyFormList()
|
|
|
// this.handleGenerateTemplate1()
|
|
|
},
|
|
|
methods: {
|
|
|
+ getDetail() {
|
|
|
+ // 获取项目的详情数据
|
|
|
+ getDetail({ id: this.selectedProject.projectId }).then((res) => {
|
|
|
+ if (res.code === 200) {
|
|
|
+ this.project = res.value
|
|
|
+ this.auditForm.catalogId = res.value.catalogId
|
|
|
+ // this.auditForm.surveyTemplateId = '9368f1cf-77e7-49fe-8502-4a7a2da99668'
|
|
|
+ this.loadTemplateData()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
// 获取所有模板类型为固定表的所有启用成本调查表数据
|
|
|
getActiveCostVerifyFormListByType() {
|
|
|
getActiveCostVerifyFormListByType().then((res) => {
|
|
|
@@ -461,16 +379,54 @@
|
|
|
: ''
|
|
|
this.loadTemplateDataForEdit(this.auditForm.surveyTemplateId)
|
|
|
},
|
|
|
+
|
|
|
+ // 回显数据用
|
|
|
+ async loadTemplateData(surveyTemplateId) {
|
|
|
+ // 先获取表格数据
|
|
|
+ const tableDataRes = await getCostFormVersionsByTemplateId({
|
|
|
+ taskId: this.selectedProject.taskId,
|
|
|
+ // surveyTemplateId: '',
|
|
|
+ })
|
|
|
+
|
|
|
+ // 处理表格数据
|
|
|
+ if (tableDataRes.code == 200) {
|
|
|
+ this.auditForm.surveyTemplateId =
|
|
|
+ tableDataRes.value.itemlist[0].surveyTemplateId
|
|
|
+ // 有数据后再获取表头数据
|
|
|
+ const tableHeadersRes = await getlistBySurveyTemplateId({
|
|
|
+ // taskId: this.selectedProject.taskId,
|
|
|
+ surveyTemplateId: this.auditForm.surveyTemplateId,
|
|
|
+ })
|
|
|
+ getVerifyTemplateDetail({
|
|
|
+ id: this.auditForm.surveyTemplateId,
|
|
|
+ }).then((res) => {
|
|
|
+ this.auditForm.surveyTemplateName = res.value.surveyTemplateName
|
|
|
+ this.auditForm.catalogId = res.value.catalogId
|
|
|
+ this.auditForm.templateType = res.value.createmode
|
|
|
+ if (res.value.createmode == '1') {
|
|
|
+ this.auditForm.dataTable = res.value.createtemplateid
|
|
|
+ } else if (res.value.createmode == '2') {
|
|
|
+ this.auditForm.historyTemplate = res.value.createtemplateid
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 处理表头数据
|
|
|
+ if (tableHeadersRes.code == 200) {
|
|
|
+ this.parseAndDisplayTableHeaders(tableHeadersRes)
|
|
|
+ this.parseAndDisplayTableData(tableDataRes)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
async loadTemplateDataForEdit(surveyTemplateId) {
|
|
|
// 并行获取表头和表格数据
|
|
|
const [tableHeadersRes, tableDataRes] = await Promise.all([
|
|
|
getlistBySurveyTemplateId({
|
|
|
- surveyTemplateId: this.auditForm.surveyTemplateId,
|
|
|
taskId: this.selectedProject.taskId,
|
|
|
+ surveyTemplateId: this.auditForm.surveyTemplateId,
|
|
|
}),
|
|
|
getCostFormVersionsByTemplateId({
|
|
|
- surveyTemplateId: this.auditForm.surveyTemplateId,
|
|
|
taskId: this.selectedProject.taskId,
|
|
|
+ surveyTemplateId: '',
|
|
|
}),
|
|
|
])
|
|
|
// 处理表头数据
|
|
|
@@ -485,6 +441,7 @@
|
|
|
parseAndDisplayTableHeaders(res) {
|
|
|
this.tableHeadersRes = Array.isArray(res.value) ? res.value : []
|
|
|
if (this.tableHeadersRes.length > 0) {
|
|
|
+ this.auditForm.surveyTemplateId = res.value[0].surveyTemplateId
|
|
|
// 表头按照orderNum重新排序
|
|
|
this.tableHeadersRes.sort((a, b) => a.orderNum - b.orderNum)
|
|
|
this.costAuditcolumn = [] // 清空现有列配置
|
|
|
@@ -503,7 +460,10 @@
|
|
|
label: '单位',
|
|
|
width: '80px',
|
|
|
})
|
|
|
- if (this.selectedProject.auditPeriod) {
|
|
|
+ // 检查tableHeadersRes数组是否包含年账面值
|
|
|
+ const hasBookValueColumn = this.checkHasBookValueColumn()
|
|
|
+
|
|
|
+ if (!hasBookValueColumn && this.selectedProject.auditPeriod) {
|
|
|
// 获取审计期间并按年份排序
|
|
|
let auditPeriod = this.selectedProject.auditPeriod
|
|
|
.split(',')
|
|
|
@@ -520,10 +480,11 @@
|
|
|
width: '120px',
|
|
|
align: 'right',
|
|
|
fieldName: item + '年账面值',
|
|
|
- fieldType: 'string',
|
|
|
- format: '255',
|
|
|
- fieldTypelen: '',
|
|
|
+ fieldType: 'integer',
|
|
|
+ format: '',
|
|
|
+ fieldTypelen: '255',
|
|
|
fieldTypenointlen: '',
|
|
|
+ isAuditPeriod: 'true',
|
|
|
isRequired: 'true',
|
|
|
showVisible: '1',
|
|
|
isDict: 'false',
|
|
|
@@ -532,9 +493,10 @@
|
|
|
tabtype: this.tableHeadersRes[0].tabtype,
|
|
|
surveyTemplateId: this.tableHeadersRes[0].surveyTemplateId,
|
|
|
versionId: this.tableHeadersRes[0].versionId,
|
|
|
- orderNum: num + 1,
|
|
|
+ orderNum: this.getMaxOrderNum() + 1,
|
|
|
}
|
|
|
-
|
|
|
+ this.costAuditcolumn.push(bookValueColumn)
|
|
|
+ this.tableHeadersRes.push(bookValueColumn)
|
|
|
// 审核字段
|
|
|
let auditColumn = {
|
|
|
prop: 'year' + item + 'Audit',
|
|
|
@@ -542,11 +504,12 @@
|
|
|
width: '150px',
|
|
|
align: 'center',
|
|
|
fieldName: item + '年审核调整值',
|
|
|
- fieldType: 'string',
|
|
|
- format: '255',
|
|
|
- fieldTypelen: '',
|
|
|
+ fieldType: 'integer',
|
|
|
+ format: '',
|
|
|
+ fieldTypelen: '9',
|
|
|
fieldTypenointlen: '',
|
|
|
isRequired: 'true',
|
|
|
+ isAuditPeriod: 'true',
|
|
|
showVisible: '1',
|
|
|
isDict: 'false',
|
|
|
dictid: '',
|
|
|
@@ -554,9 +517,10 @@
|
|
|
tabtype: this.tableHeadersRes[0].tabtype,
|
|
|
surveyTemplateId: this.tableHeadersRes[0].surveyTemplateId,
|
|
|
versionId: this.tableHeadersRes[0].versionId,
|
|
|
- orderNum: num + 2,
|
|
|
+ orderNum: this.getMaxOrderNum() + num + 1,
|
|
|
}
|
|
|
-
|
|
|
+ this.costAuditcolumn.push(auditColumn)
|
|
|
+ this.tableHeadersRes.push(auditColumn)
|
|
|
// 核定值字段
|
|
|
let approvedValueColumn = {
|
|
|
prop: 'year' + item + 'ApprovedValue',
|
|
|
@@ -564,11 +528,12 @@
|
|
|
width: '120px',
|
|
|
align: 'right',
|
|
|
fieldName: item + '年核定值',
|
|
|
- fieldType: 'string',
|
|
|
- format: '255',
|
|
|
- fieldTypelen: '',
|
|
|
+ fieldType: 'integer',
|
|
|
+ format: '',
|
|
|
+ fieldTypelen: '255',
|
|
|
fieldTypenointlen: '',
|
|
|
isRequired: 'true',
|
|
|
+ isAuditPeriod: 'true',
|
|
|
showVisible: '1',
|
|
|
isDict: 'false',
|
|
|
dictid: '',
|
|
|
@@ -576,20 +541,36 @@
|
|
|
tabtype: this.tableHeadersRes[0].tabtype,
|
|
|
surveyTemplateId: this.tableHeadersRes[0].surveyTemplateId,
|
|
|
versionId: this.tableHeadersRes[0].versionId,
|
|
|
- orderNum: num + 3,
|
|
|
+ orderNum: this.getMaxOrderNum() + num + 1,
|
|
|
}
|
|
|
-
|
|
|
- // 依次添加三个字段到列配置
|
|
|
- this.costAuditcolumn.push(bookValueColumn)
|
|
|
- this.costAuditcolumn.push(auditColumn)
|
|
|
this.costAuditcolumn.push(approvedValueColumn)
|
|
|
- this.tableHeadersRes.push(bookValueColumn)
|
|
|
- this.tableHeadersRes.push(auditColumn)
|
|
|
this.tableHeadersRes.push(approvedValueColumn)
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
+ getMaxOrderNum() {
|
|
|
+ if (!this.tableHeadersRes || this.tableHeadersRes.length === 0) {
|
|
|
+ return 0
|
|
|
+ }
|
|
|
+ const maxOrderNum = Math.max(
|
|
|
+ ...this.tableHeadersRes.map((item) => item.orderNum || 0)
|
|
|
+ )
|
|
|
+ return maxOrderNum
|
|
|
+ },
|
|
|
+ // 检查tableHeadersRes数组是否包含年账面值列
|
|
|
+ checkHasBookValueColumn() {
|
|
|
+ if (!this.tableHeadersRes || this.tableHeadersRes.length === 0) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ // 检查是否有列的label或fieldName包含'年账面值'字样
|
|
|
+ return this.tableHeadersRes.some((item) => {
|
|
|
+ return (
|
|
|
+ (item.label && item.label.includes('年账面值')) ||
|
|
|
+ (item.fieldName && item.fieldName.includes('年账面值'))
|
|
|
+ )
|
|
|
+ })
|
|
|
+ },
|
|
|
parseAndDisplayTableData(res) {
|
|
|
// 清空现有数据
|
|
|
this.costAuditData = []
|
|
|
@@ -629,22 +610,22 @@
|
|
|
}
|
|
|
})
|
|
|
|
|
|
- // 为审计期间的三个字段添加初始值
|
|
|
- if (this.selectedProject && this.selectedProject.auditPeriod) {
|
|
|
- // 获取审计期间并按年份排序
|
|
|
- let auditPeriod = this.selectedProject.auditPeriod
|
|
|
- .split(',')
|
|
|
- .map((year) => parseInt(year))
|
|
|
- .sort((a, b) => a - b)
|
|
|
- .map((year) => year.toString())
|
|
|
-
|
|
|
- // 为每个年份添加三个字段的初始值
|
|
|
- auditPeriod.forEach((year) => {
|
|
|
- rowData[`year${year}BookValue`] = '' // 账面价值
|
|
|
- rowData[`year${year}Audit`] = '' // 审核调整值
|
|
|
- rowData[`year${year}ApprovedValue`] = '' // 核定值
|
|
|
- })
|
|
|
- }
|
|
|
+ // if (this.selectedProject && this.selectedProject.auditPeriod) {
|
|
|
+ // // 为审计期间的三个字段添加初始值
|
|
|
+ // // 获取审计期间并按年份排序
|
|
|
+ // let auditPeriod = this.selectedProject.auditPeriod
|
|
|
+ // .split(',')
|
|
|
+ // .map((year) => parseInt(year))
|
|
|
+ // .sort((a, b) => a - b)
|
|
|
+ // .map((year) => year.toString())
|
|
|
+
|
|
|
+ // // 为每个年份添加三个字段的初始值,使用与表头定义一致的属性名
|
|
|
+ // auditPeriod.forEach((year) => {
|
|
|
+ // rowData[`year${year}BookValue`] = '' // 账面值
|
|
|
+ // rowData[`year${year}Audit`] = '' // 审核调整值
|
|
|
+ // rowData[`year${year}ApprovedValue`] = '' // 核定值
|
|
|
+ // })
|
|
|
+ // }
|
|
|
|
|
|
// 添加完整的行数据到表格数据中
|
|
|
this.costAuditData.push(rowData)
|
|
|
@@ -655,7 +636,18 @@
|
|
|
}
|
|
|
},
|
|
|
handleSaveTemplate(type) {
|
|
|
- let headersList = this.tableHeadersRes
|
|
|
+ // 显示加载状态
|
|
|
+ this.$loading({
|
|
|
+ lock: true,
|
|
|
+ text: '保存数据中...',
|
|
|
+ spinner: 'el-icon-loading',
|
|
|
+ background: 'rgba(0, 0, 0, 0.7)',
|
|
|
+ })
|
|
|
+ // 加上遮罩层
|
|
|
+ const headersList = this.tableHeadersRes.map((header, index) => ({
|
|
|
+ ...header,
|
|
|
+ orderNum: header.orderNum || index + 1,
|
|
|
+ }))
|
|
|
let splitData = this.splitFixedTableDataForSave(this.costAuditData)
|
|
|
|
|
|
let data = {
|
|
|
@@ -665,11 +657,16 @@
|
|
|
}
|
|
|
batchSaveOrUpdate(data)
|
|
|
.then((data) => {
|
|
|
+ // 关闭加载状态
|
|
|
+ this.$loading().close()
|
|
|
if (type != 'delete') {
|
|
|
this.$message.success('保存成功')
|
|
|
+ this.loadTemplateData()
|
|
|
}
|
|
|
})
|
|
|
.catch((err) => {
|
|
|
+ // 关闭加载状态
|
|
|
+ this.$loading().close()
|
|
|
console.log(err)
|
|
|
})
|
|
|
// this.$message({ type: 'success', message: '保存成功' })
|
|
|
@@ -683,54 +680,70 @@
|
|
|
}))
|
|
|
},
|
|
|
splitFixedTableDataForSave() {
|
|
|
- let headersList = this.tableHeadersRes
|
|
|
+ let fixedHeaders = this.tableHeadersRes
|
|
|
let fixedTables = this.costAuditData
|
|
|
- let fixedFields = headersList
|
|
|
+ let fixedFields = fixedHeaders
|
|
|
.map((header) => header.fieldName)
|
|
|
.join(',')
|
|
|
let fixedTitles = this.stringToObjects(fixedFields || '')
|
|
|
// 结果数组
|
|
|
const result = []
|
|
|
- // 为每个固定列创建一条记录
|
|
|
- fixedTables.forEach((row) => {
|
|
|
- fixedTitles.forEach((item) => {
|
|
|
+ const processNode = (node, parentRowIndex = 0) => {
|
|
|
+ // 确保node和fixedValues存在
|
|
|
+ if (!node) {
|
|
|
+ console.warn('遇到空节点,跳过处理')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保fixedValues属性存在,如果不存在则初始化为空对象
|
|
|
+ if (!node.fixedValues) {
|
|
|
+ node.fixedValues = {}
|
|
|
+ }
|
|
|
+
|
|
|
+ // 为每个固定列创建一条记录
|
|
|
+ fixedTitles.forEach((title) => {
|
|
|
// 找到对应的表头信息
|
|
|
- const correspondingHeader = headersList.find(
|
|
|
- (header) => header.fieldName === item.rkey
|
|
|
+ const correspondingHeader = fixedHeaders.find(
|
|
|
+ (header) => header.fieldName === title.rkey
|
|
|
)
|
|
|
const newItem = {
|
|
|
- id: row.itemId || null,
|
|
|
- rkey: correspondingHeader.fieldName,
|
|
|
- rvalue: row[correspondingHeader.fieldName],
|
|
|
+ rkey: title.rkey,
|
|
|
+ rvalue: node[correspondingHeader.fieldEname] || '',
|
|
|
+ [correspondingHeader.fieldName]:
|
|
|
+ node[correspondingHeader.fieldEname] || '',
|
|
|
surveyTemplateId:
|
|
|
- row.surveyTemplateId || correspondingHeader.surveyTemplateId,
|
|
|
- versionId: row.versionId || correspondingHeader.versionId,
|
|
|
- tabtype: row.tabtype || correspondingHeader.tabtype,
|
|
|
+ node.surveyTemplateId || correspondingHeader.surveyTemplateId,
|
|
|
+ versionId: node.versionId || correspondingHeader.versionId,
|
|
|
+ tabtype: node.tabtype || correspondingHeader.templateType,
|
|
|
// 添加 headersId 字段(表头的id)
|
|
|
headersId: correspondingHeader ? correspondingHeader.id : null,
|
|
|
// 添加记录的id(itemlist中每条记录的id)
|
|
|
- id: row.itemId || null,
|
|
|
+ id: node.id || null,
|
|
|
// 添加父子关系字段
|
|
|
- parentid: row.parentid || -1, // 父项ID,默认为-1表示无父项
|
|
|
- isChild: row.isChild || false, // 是否为子项
|
|
|
+ parentid: node.parentid || -1, // 父项ID,默认为-1表示无父项
|
|
|
+ isChild: node.isChild || false, // 是否为子项
|
|
|
// 添加 rowid 字段
|
|
|
- rowid: row.rowid || null,
|
|
|
+ rowid: node.rowid || null,
|
|
|
// 添加计算公式相关字段
|
|
|
- calculationFormula: row.calculationFormula || null,
|
|
|
- jsonstr: row.jsonstr || null,
|
|
|
+ calculationFormula: node.calculationFormula || null,
|
|
|
+ jsonstr: node.jsonstr || null,
|
|
|
orderNum:
|
|
|
- typeof row.orderNum === 'number'
|
|
|
- ? row.orderNum
|
|
|
- : parseInt(row.orderNum, 10) || 0,
|
|
|
+ typeof node.orderNum === 'number'
|
|
|
+ ? node.orderNum
|
|
|
+ : parseInt(node.orderNum, 10) || 0,
|
|
|
+ // 添加用户需要的其他字段
|
|
|
+ orderText: node.orderText || '',
|
|
|
+ percentage: node.percentage || '',
|
|
|
+ unit: node.unit || '',
|
|
|
}
|
|
|
// 添加其他固定表特有的字段
|
|
|
- if (!row.isSubItem) {
|
|
|
- newItem.cellCode = row.cellCode || ''
|
|
|
- newItem.unit = row.unit || ''
|
|
|
+ if (!node.isSubItem) {
|
|
|
+ newItem.cellCode = node.cellCode || ''
|
|
|
+ newItem.unit = node.unit || ''
|
|
|
}
|
|
|
|
|
|
// 添加其他可能需要的字段,但排除特定字段
|
|
|
- Object.keys(row).forEach((key) => {
|
|
|
+ Object.keys(node).forEach((key) => {
|
|
|
if (
|
|
|
!(key in newItem) &&
|
|
|
key !== 'fixedValues' &&
|
|
|
@@ -744,51 +757,54 @@
|
|
|
key !== 'calculationFormula' &&
|
|
|
key !== 'children' // 排除children字段
|
|
|
) {
|
|
|
- newItem[key] = row[key]
|
|
|
+ newItem[key] = node[key]
|
|
|
}
|
|
|
})
|
|
|
|
|
|
result.push(newItem)
|
|
|
})
|
|
|
+ }
|
|
|
+ fixedTables.forEach((row) => {
|
|
|
+ processNode(row)
|
|
|
+ })
|
|
|
|
|
|
- // 首先收集所有父节点的orderNum,确保不与子节点冲突
|
|
|
- const parentOrderNums = new Set()
|
|
|
-
|
|
|
- // 第一次遍历:识别父节点并收集它们的orderNum
|
|
|
- result.forEach((item) => {
|
|
|
- // 假设isChild为false或parentid为-1的是父节点
|
|
|
- if (!item.isChild || item.parentid === -1) {
|
|
|
- parentOrderNums.add(item.orderNum)
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- // 创建映射来跟踪已使用的orderNum
|
|
|
- const usedOrderNums = new Set([...parentOrderNums])
|
|
|
- let nextAvailableOrderNum = 1
|
|
|
+ // 首先收集所有父节点的orderNum,确保不与子节点冲突
|
|
|
+ const parentOrderNums = new Set()
|
|
|
|
|
|
- // 找到当前最大的orderNum,作为新orderNum的起点
|
|
|
- const allOrderNums = result
|
|
|
- .map((item) => item.orderNum)
|
|
|
- .filter((num) => typeof num === 'number' && !isNaN(num))
|
|
|
- if (allOrderNums.length > 0) {
|
|
|
- nextAvailableOrderNum = Math.max(...allOrderNums) + 1
|
|
|
+ // 第一次遍历:识别父节点并收集它们的orderNum
|
|
|
+ result.forEach((item) => {
|
|
|
+ // 假设isChild为false或parentid为-1的是父节点
|
|
|
+ if (!item.isChild || item.parentid === -1) {
|
|
|
+ parentOrderNums.add(item.orderNum)
|
|
|
}
|
|
|
+ })
|
|
|
|
|
|
- // 第二次遍历:为子节点分配唯一的orderNum
|
|
|
- result.forEach((item) => {
|
|
|
- // 只为子节点重新分配orderNum
|
|
|
- if (item.isChild && item.parentid !== -1) {
|
|
|
- // 找到下一个未使用的orderNum
|
|
|
- while (usedOrderNums.has(nextAvailableOrderNum)) {
|
|
|
- nextAvailableOrderNum++
|
|
|
- }
|
|
|
+ // 创建映射来跟踪已使用的orderNum
|
|
|
+ const usedOrderNums = new Set([...parentOrderNums])
|
|
|
+ let nextAvailableOrderNum = 1
|
|
|
|
|
|
- // 分配新的orderNum并标记为已使用
|
|
|
- item.orderNum = nextAvailableOrderNum
|
|
|
- usedOrderNums.add(nextAvailableOrderNum)
|
|
|
+ // 找到当前最大的orderNum,作为新orderNum的起点
|
|
|
+ const allOrderNums = result
|
|
|
+ .map((item) => item.orderNum)
|
|
|
+ .filter((num) => typeof num === 'number' && !isNaN(num))
|
|
|
+ if (allOrderNums.length > 0) {
|
|
|
+ nextAvailableOrderNum = Math.max(...allOrderNums) + 1
|
|
|
+ }
|
|
|
+
|
|
|
+ // 第二次遍历:为子节点分配唯一的orderNum
|
|
|
+ result.forEach((item) => {
|
|
|
+ // 只为子节点重新分配orderNum
|
|
|
+ if (item.isChild && item.parentid !== -1) {
|
|
|
+ // 找到下一个未使用的orderNum
|
|
|
+ while (usedOrderNums.has(nextAvailableOrderNum)) {
|
|
|
nextAvailableOrderNum++
|
|
|
}
|
|
|
- })
|
|
|
+
|
|
|
+ // 分配新的orderNum并标记为已使用
|
|
|
+ item.orderNum = nextAvailableOrderNum
|
|
|
+ usedOrderNums.add(nextAvailableOrderNum)
|
|
|
+ nextAvailableOrderNum++
|
|
|
+ }
|
|
|
})
|
|
|
|
|
|
return result
|
|
|
@@ -796,7 +812,6 @@
|
|
|
|
|
|
//
|
|
|
handleImportData() {
|
|
|
- return
|
|
|
let loading = null
|
|
|
// 第一步:创建文件选择器
|
|
|
const input = document.createElement('input')
|
|
|
@@ -834,28 +849,24 @@
|
|
|
const formData = new FormData()
|
|
|
formData.append('file', file)
|
|
|
|
|
|
- // 先调用上传API
|
|
|
- // const uploadRes = await uploadFile('/api/file/v1/upload', formData)
|
|
|
-
|
|
|
- // 第四步:检查上传结果
|
|
|
- // if (!uploadRes || !uploadRes.value) {
|
|
|
- // // this.$message.error('文件上传失败!');
|
|
|
- // return
|
|
|
- // }
|
|
|
-
|
|
|
- // 第五步:文件上传成功后,再更新数据
|
|
|
- const fileInfo = uploadRes.value
|
|
|
- // 创建更新数据对象
|
|
|
- // const updateData = {
|
|
|
- // id: row.id,
|
|
|
- // scanDocumentUrl: fileInfo?.savePath, // 更新扫描件URL
|
|
|
- // }
|
|
|
+ // 其他参数作为query参数传递
|
|
|
+ const queryParams = {
|
|
|
+ surveyTemplateId: this.auditForm.surveyTemplateId,
|
|
|
+ taskId: this.selectedProject.taskId,
|
|
|
+ materialId: '', // 根据API文档,此参数为必填,但当前没有值,保留空字符串
|
|
|
+ periodRecordId: '', // 非必填参数
|
|
|
+ }
|
|
|
|
|
|
- // 第六步:调用更新API
|
|
|
- // await updateScan(updateData)
|
|
|
+ // 先调用上传API,将参数作为query传递
|
|
|
+ const uploadRes = await importExcel(formData, queryParams)
|
|
|
|
|
|
- // 第七步:更新成功,显示提示并刷新
|
|
|
- // this.$message.success('文件上传成功并更新数据!')
|
|
|
+ // 第四步:检查上传结果
|
|
|
+ if (!uploadRes.state) {
|
|
|
+ this.$message.error('导入失败!')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.$message.success('导入成功')
|
|
|
+ this.loadTemplateData()
|
|
|
// this.$emit('refresh', this.project.projectId) // 通知父组件刷新
|
|
|
} catch (error) {
|
|
|
// 错误处理
|
|
|
@@ -869,80 +880,65 @@
|
|
|
input.click()
|
|
|
},
|
|
|
handleExportTemplate() {
|
|
|
- return
|
|
|
-
|
|
|
- // this.$message({ type: 'info', message: '导出数据' })
|
|
|
+ if (this.costAuditData.length === 0) {
|
|
|
+ return
|
|
|
+ }
|
|
|
// 显示加载状态
|
|
|
- this.$loading({
|
|
|
+ const loading = this.$loading({
|
|
|
lock: true,
|
|
|
text: '文件下载中...',
|
|
|
spinner: 'el-icon-loading',
|
|
|
background: 'rgba(0, 0, 0, 0.7)',
|
|
|
})
|
|
|
|
|
|
- // 从API中获取文件URL
|
|
|
- downDocument({
|
|
|
- id: row.id,
|
|
|
+ // 调用导出API
|
|
|
+ exportExcel({
|
|
|
+ // surveyTemplateId: '1985224388517109760', // 测试用 1989165590455066624
|
|
|
+ surveyTemplateId: this.auditForm.surveyTemplateId,
|
|
|
+ versionId: this.tableHeadersRes[0].versionId || '',
|
|
|
})
|
|
|
.then((res) => {
|
|
|
- // 关闭加载状态
|
|
|
- this.$loading().close()
|
|
|
-
|
|
|
- // 检查返回结果是否成功
|
|
|
- if (!res || !res.state) {
|
|
|
- this.$message.error(
|
|
|
- `下载失败:${res?.message || '未获取到文件数据'}`
|
|
|
- )
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // 获取文件URL
|
|
|
- const fileUrl = res.value
|
|
|
- if (!fileUrl) {
|
|
|
- this.$message.error('下载失败:未获取到文件URL')
|
|
|
- return
|
|
|
+ // 从响应头获取文件名(如果有)
|
|
|
+ let fileName = `成本审核模板_${new Date()
|
|
|
+ .toLocaleString()
|
|
|
+ .replace(/[:\s]/g, '_')}.xlsx`
|
|
|
+ if (res.headers && res.headers['content-disposition']) {
|
|
|
+ const contentDisposition = res.headers['content-disposition']
|
|
|
+ const match = contentDisposition.match(/filename=([^;]+)/i)
|
|
|
+ if (match && match[1]) {
|
|
|
+ fileName = decodeURIComponent(match[1].replace(/['"]/g, ''))
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- // 优先从URL中提取文件名
|
|
|
- let fileName = ''
|
|
|
-
|
|
|
- // 从URL中提取文件名
|
|
|
- const urlParts = fileUrl.split('/')
|
|
|
- let urlFileName = urlParts[urlParts.length - 1]
|
|
|
+ // 使用a标签方式下载文件
|
|
|
+ const blobData = new Blob([res.data], {
|
|
|
+ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
|
+ })
|
|
|
|
|
|
- // 处理URL可能包含查询参数的情况
|
|
|
- if (urlFileName.includes('?')) {
|
|
|
- urlFileName = urlFileName.split('?')[0]
|
|
|
- }
|
|
|
+ // 创建URL对象
|
|
|
+ const url = window.URL.createObjectURL(blobData)
|
|
|
|
|
|
- // 检查从URL提取的文件名是否有效
|
|
|
- if (urlFileName && /\.[a-zA-Z0-9]+$/.test(urlFileName)) {
|
|
|
- fileName = urlFileName
|
|
|
- } else {
|
|
|
- // URL中无法提取有效文件名时,使用row.documentName作为备选
|
|
|
- fileName =
|
|
|
- row.documentName || `成本核定表审核_${new Date().getTime()}`
|
|
|
+ // 创建a标签
|
|
|
+ const a = document.createElement('a')
|
|
|
+ a.style.display = 'none'
|
|
|
+ a.href = url
|
|
|
+ a.download = fileName // 设置下载文件名
|
|
|
|
|
|
- // 确保备选文件名有扩展名
|
|
|
- if (!/\.[a-zA-Z0-9]+$/.test(fileName)) {
|
|
|
- fileName += '.pdf'
|
|
|
- }
|
|
|
- }
|
|
|
- // 创建隐藏的a标签进行下载
|
|
|
- const link = document.createElement('a')
|
|
|
- link.style.display = 'none'
|
|
|
- link.href = fileUrl
|
|
|
- // link.href = window.context.form + row.electronicDocumentUrl
|
|
|
- // 设置下载文件名
|
|
|
- link.download = fileName
|
|
|
- document.body.appendChild(link)
|
|
|
- link.click()
|
|
|
- document.body.removeChild(link)
|
|
|
+ // 添加到DOM并触发点击
|
|
|
+ document.body.appendChild(a)
|
|
|
+ a.click()
|
|
|
+ // 关闭加载状态
|
|
|
+ loading.close()
|
|
|
+ // 清理
|
|
|
+ setTimeout(() => {
|
|
|
+ document.body.removeChild(a)
|
|
|
+ window.URL.revokeObjectURL(url) // 释放URL对象,避免内存泄漏
|
|
|
+ }, 100)
|
|
|
})
|
|
|
.catch((error) => {
|
|
|
// 关闭加载状态
|
|
|
- this.$loading().close()
|
|
|
- console.error('获取文件URL失败:', error)
|
|
|
+ loading.close()
|
|
|
+ console.error('文件下载失败:', error)
|
|
|
})
|
|
|
},
|
|
|
|