|
|
@@ -178,6 +178,7 @@
|
|
|
} from '@/api/costVerifyManage'
|
|
|
import { getDetail } from '@/api/auditInitiation'
|
|
|
import { catalogMixin } from '@/mixins/useDict'
|
|
|
+ import { saveAs } from 'file-saver'
|
|
|
export default {
|
|
|
name: 'CostAudit',
|
|
|
mixins: [catalogMixin],
|
|
|
@@ -240,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: {},
|
|
|
}
|
|
|
},
|
|
|
@@ -371,7 +282,7 @@
|
|
|
this.project = res.value
|
|
|
this.auditForm.catalogId = res.value.catalogId
|
|
|
// this.auditForm.surveyTemplateId = '9368f1cf-77e7-49fe-8502-4a7a2da99668'
|
|
|
- this.loadTemplateDataForEdit()
|
|
|
+ this.loadTemplateData()
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
@@ -468,6 +379,44 @@
|
|
|
: ''
|
|
|
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([
|
|
|
@@ -493,15 +442,6 @@
|
|
|
this.tableHeadersRes = Array.isArray(res.value) ? res.value : []
|
|
|
if (this.tableHeadersRes.length > 0) {
|
|
|
this.auditForm.surveyTemplateId = res.value[0].surveyTemplateId
|
|
|
- if (!this.auditForm.surveyTemplateId) {
|
|
|
- getVerifyTemplateDetail({
|
|
|
- id: this.auditForm.surveyTemplateId,
|
|
|
- }).then((res) => {
|
|
|
- this.auditForm.surveyTemplateName = res.value.surveyTemplateName
|
|
|
- this.auditForm.catalogId = res.value.catalogId
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
// 表头按照orderNum重新排序
|
|
|
this.tableHeadersRes.sort((a, b) => a.orderNum - b.orderNum)
|
|
|
this.costAuditcolumn = [] // 清空现有列配置
|
|
|
@@ -566,7 +506,7 @@
|
|
|
fieldName: item + '年审核调整值',
|
|
|
fieldType: 'integer',
|
|
|
format: '',
|
|
|
- fieldTypelen: '255',
|
|
|
+ fieldTypelen: '9',
|
|
|
fieldTypenointlen: '',
|
|
|
isRequired: 'true',
|
|
|
isAuditPeriod: 'true',
|
|
|
@@ -670,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}年BookValue账面值`] = '' // 账面值
|
|
|
- rowData[`${year}年Audit审核调整值`] = '' // 审核调整值
|
|
|
- rowData[`${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)
|
|
|
@@ -704,7 +644,10 @@
|
|
|
background: 'rgba(0, 0, 0, 0.7)',
|
|
|
})
|
|
|
// 加上遮罩层
|
|
|
- let headersList = this.tableHeadersRes
|
|
|
+ const headersList = this.tableHeadersRes.map((header, index) => ({
|
|
|
+ ...header,
|
|
|
+ orderNum: header.orderNum || index + 1,
|
|
|
+ }))
|
|
|
let splitData = this.splitFixedTableDataForSave(this.costAuditData)
|
|
|
|
|
|
let data = {
|
|
|
@@ -718,6 +661,7 @@
|
|
|
this.$loading().close()
|
|
|
if (type != 'delete') {
|
|
|
this.$message.success('保存成功')
|
|
|
+ this.loadTemplateData()
|
|
|
}
|
|
|
})
|
|
|
.catch((err) => {
|
|
|
@@ -736,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.fieldEname],
|
|
|
+ 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' &&
|
|
|
@@ -797,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,作为新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并标记为已使用
|
|
|
- item.orderNum = nextAvailableOrderNum
|
|
|
- usedOrderNums.add(nextAvailableOrderNum)
|
|
|
+ // 第二次遍历:为子节点分配唯一的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
|
|
|
@@ -888,11 +851,9 @@
|
|
|
|
|
|
// 其他参数作为query参数传递
|
|
|
const queryParams = {
|
|
|
- materialId: '', // 根据API文档,此参数为必填,但当前没有值,保留空字符串
|
|
|
- surveyTemplateId:
|
|
|
- this.auditForm.surveyTemplateId ||
|
|
|
- '62d10551-1576-49b0-9130-622b513f431e',
|
|
|
+ surveyTemplateId: this.auditForm.surveyTemplateId,
|
|
|
taskId: this.selectedProject.taskId,
|
|
|
+ materialId: '', // 根据API文档,此参数为必填,但当前没有值,保留空字符串
|
|
|
periodRecordId: '', // 非必填参数
|
|
|
}
|
|
|
|
|
|
@@ -900,24 +861,12 @@
|
|
|
const uploadRes = await importExcel(formData, queryParams)
|
|
|
|
|
|
// 第四步:检查上传结果
|
|
|
- if (!uploadRes || !uploadRes.value) {
|
|
|
+ if (!uploadRes.state) {
|
|
|
this.$message.error('导入失败!')
|
|
|
return
|
|
|
}
|
|
|
-
|
|
|
- // 第五步:文件上传成功后,再更新数据
|
|
|
- // const fileInfo = uploadRes.value
|
|
|
- // 创建更新数据对象
|
|
|
- // const updateData = {
|
|
|
- // id: row.id,
|
|
|
- // scanDocumentUrl: fileInfo?.savePath, // 更新扫描件URL
|
|
|
- // }
|
|
|
-
|
|
|
- // 第六步:调用更新API
|
|
|
- // await updateScan(updateData)
|
|
|
-
|
|
|
- // 第七步:更新成功,显示提示并刷新
|
|
|
this.$message.success('导入成功')
|
|
|
+ this.loadTemplateData()
|
|
|
// this.$emit('refresh', this.project.projectId) // 通知父组件刷新
|
|
|
} catch (error) {
|
|
|
// 错误处理
|
|
|
@@ -934,81 +883,62 @@
|
|
|
if (this.costAuditData.length === 0) {
|
|
|
return
|
|
|
}
|
|
|
- // this.$message({ type: 'info', message: '导出数据' })
|
|
|
// 显示加载状态
|
|
|
- this.$loading({
|
|
|
+ const loading = this.$loading({
|
|
|
lock: true,
|
|
|
text: '文件下载中...',
|
|
|
spinner: 'el-icon-loading',
|
|
|
background: 'rgba(0, 0, 0, 0.7)',
|
|
|
})
|
|
|
|
|
|
- // 从API中获取文件URL
|
|
|
+ // 调用导出API
|
|
|
exportExcel({
|
|
|
- surveyTemplateId:
|
|
|
- this.costAuditData[0].surveyTemplateId ||
|
|
|
- '62d10551-1576-49b0-9130-622b513f431e',
|
|
|
- versionId: this.costAuditData[0].versionId || '',
|
|
|
+ // 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 = ''
|
|
|
+ // 使用a标签方式下载文件
|
|
|
+ const blobData = new Blob([res.data], {
|
|
|
+ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
|
+ })
|
|
|
|
|
|
- // 从URL中提取文件名
|
|
|
- const urlParts = fileUrl.split('/')
|
|
|
- let urlFileName = urlParts[urlParts.length - 1]
|
|
|
+ // 创建URL对象
|
|
|
+ const url = window.URL.createObjectURL(blobData)
|
|
|
|
|
|
- // 处理URL可能包含查询参数的情况
|
|
|
- if (urlFileName.includes('?')) {
|
|
|
- urlFileName = urlFileName.split('?')[0]
|
|
|
- }
|
|
|
+ // 创建a标签
|
|
|
+ const a = document.createElement('a')
|
|
|
+ a.style.display = 'none'
|
|
|
+ a.href = url
|
|
|
+ a.download = fileName // 设置下载文件名
|
|
|
|
|
|
- // 检查从URL提取的文件名是否有效
|
|
|
- if (urlFileName && /\.[a-zA-Z0-9]+$/.test(urlFileName)) {
|
|
|
- fileName = urlFileName
|
|
|
- } else {
|
|
|
- // URL中无法提取有效文件名时,使用row.documentName作为备选
|
|
|
- fileName =
|
|
|
- row.documentName || `成本核定表审核_${new Date().getTime()}`
|
|
|
-
|
|
|
- // 确保备选文件名有扩展名
|
|
|
- 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)
|
|
|
})
|
|
|
},
|
|
|
|