|
@@ -1031,16 +1031,17 @@
|
|
|
// 处理模板下载
|
|
// 处理模板下载
|
|
|
async handleTemplateDownload(row) {
|
|
async handleTemplateDownload(row) {
|
|
|
console.log(row)
|
|
console.log(row)
|
|
|
|
|
+ let loading
|
|
|
try {
|
|
try {
|
|
|
// 显示加载提示
|
|
// 显示加载提示
|
|
|
- const loading = this.$loading({
|
|
|
|
|
|
|
+ loading = this.$loading({
|
|
|
lock: true,
|
|
lock: true,
|
|
|
text: '模板下载中...',
|
|
text: '模板下载中...',
|
|
|
spinner: 'el-icon-loading',
|
|
spinner: 'el-icon-loading',
|
|
|
background: 'rgba(0, 0, 0, 0.7)',
|
|
background: 'rgba(0, 0, 0, 0.7)',
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- // 构建请求参数,根据实际接口需求调整
|
|
|
|
|
|
|
+ // 构建请求参数
|
|
|
const params = { type: 2 }
|
|
const params = { type: 2 }
|
|
|
const surveyTemplateId = this.getSurveyTemplateId(row)
|
|
const surveyTemplateId = this.getSurveyTemplateId(row)
|
|
|
if (surveyTemplateId) {
|
|
if (surveyTemplateId) {
|
|
@@ -1051,49 +1052,96 @@
|
|
|
if (taskId || this.taskId) {
|
|
if (taskId || this.taskId) {
|
|
|
params.taskId = taskId || this.taskId
|
|
params.taskId = taskId || this.taskId
|
|
|
}
|
|
}
|
|
|
- // if (row.materialId) {
|
|
|
|
|
- // params.materialId = row.materialId
|
|
|
|
|
- // }
|
|
|
|
|
- // 如果接口需要其他参数,可以继续添加
|
|
|
|
|
|
|
|
|
|
- // 调用下载接口
|
|
|
|
|
const response = await downloadTemplate(params)
|
|
const response = await downloadTemplate(params)
|
|
|
|
|
|
|
|
- // 关闭加载提示
|
|
|
|
|
- loading.close()
|
|
|
|
|
|
|
+ // 下载接口可能返回两类数据:
|
|
|
|
|
+ // 1) 正常:Blob(xlsx)
|
|
|
|
|
+ // 2) 异常:JSON({code:500,state:false,message:'...'}),但由于 responseType=blob,前端拿到的可能仍是 Blob
|
|
|
|
|
+ const getJsonFromBlobIfPossible = async (blob) => {
|
|
|
|
|
+ if (!(blob instanceof Blob)) return null
|
|
|
|
|
+ try {
|
|
|
|
|
+ const text = await blob.text()
|
|
|
|
|
+ if (!text) return null
|
|
|
|
|
+ return JSON.parse(text)
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let maybeJson = null
|
|
|
|
|
+ if (
|
|
|
|
|
+ response &&
|
|
|
|
|
+ response.data &&
|
|
|
|
|
+ typeof response.data === 'object' &&
|
|
|
|
|
+ !(response.data instanceof Blob)
|
|
|
|
|
+ ) {
|
|
|
|
|
+ maybeJson = response.data
|
|
|
|
|
+ } else if (
|
|
|
|
|
+ response &&
|
|
|
|
|
+ typeof response === 'object' &&
|
|
|
|
|
+ !(response instanceof Blob) &&
|
|
|
|
|
+ !(response.data instanceof Blob)
|
|
|
|
|
+ ) {
|
|
|
|
|
+ maybeJson = response
|
|
|
|
|
+ } else if (response && response.data instanceof Blob) {
|
|
|
|
|
+ maybeJson = await getJsonFromBlobIfPossible(response.data)
|
|
|
|
|
+ } else if (response instanceof Blob) {
|
|
|
|
|
+ maybeJson = await getJsonFromBlobIfPossible(response)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ console.log('下载模板接口返回数据:', maybeJson)
|
|
|
|
|
+
|
|
|
|
|
+ if (
|
|
|
|
|
+ maybeJson &&
|
|
|
|
|
+ (maybeJson.state === false ||
|
|
|
|
|
+ (maybeJson.code !== undefined &&
|
|
|
|
|
+ maybeJson.code !== null &&
|
|
|
|
|
+ ![0, 200].includes(Number(maybeJson.code))))
|
|
|
|
|
+ ) {
|
|
|
|
|
+ const msg =
|
|
|
|
|
+ maybeJson.message ||
|
|
|
|
|
+ maybeJson.msg ||
|
|
|
|
|
+ '导出失败:该表存在跨表引用且部分年份数据缺失,请先完善后再下载'
|
|
|
|
|
+ this.$message && this.$message.warning && this.$message.warning(msg)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// 处理响应数据
|
|
// 处理响应数据
|
|
|
// response 可能是 { data, headers } 格式,也可能是直接的 Blob
|
|
// response 可能是 { data, headers } 格式,也可能是直接的 Blob
|
|
|
- let blob = response.data || response
|
|
|
|
|
- let fileName = ''
|
|
|
|
|
- const headers = response.headers || {}
|
|
|
|
|
|
|
+ const blobData = (response && response.data) || response
|
|
|
|
|
+ const blob =
|
|
|
|
|
+ blobData instanceof Blob ? blobData : new Blob([blobData])
|
|
|
|
|
|
|
|
- // 尝试从响应头中获取文件名
|
|
|
|
|
- if (headers['content-disposition']) {
|
|
|
|
|
- const contentDisposition = headers['content-disposition']
|
|
|
|
|
|
|
+ // 文件名:优先从响应头获取
|
|
|
|
|
+ let fileName = ''
|
|
|
|
|
+ const headers = (response && response.headers) || {}
|
|
|
|
|
+ const contentDisposition =
|
|
|
|
|
+ headers['content-disposition'] || headers['Content-Disposition']
|
|
|
|
|
+ if (contentDisposition) {
|
|
|
const fileNameMatch = contentDisposition.match(
|
|
const fileNameMatch = contentDisposition.match(
|
|
|
/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
|
|
/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
|
|
|
)
|
|
)
|
|
|
if (fileNameMatch && fileNameMatch[1]) {
|
|
if (fileNameMatch && fileNameMatch[1]) {
|
|
|
- fileName = decodeURIComponent(
|
|
|
|
|
- fileNameMatch[1].replace(/['"]/g, '')
|
|
|
|
|
- )
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ fileName = decodeURIComponent(
|
|
|
|
|
+ fileNameMatch[1].replace(/['"]/g, '')
|
|
|
|
|
+ )
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ fileName = fileNameMatch[1].replace(/['"]/g, '')
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 如果响应头中没有文件名,使用默认文件名
|
|
|
|
|
if (!fileName) {
|
|
if (!fileName) {
|
|
|
- const defaultName = row.informationName || row.name || '模板文件'
|
|
|
|
|
|
|
+ const defaultName = row?.informationName || row?.name || '模板文件'
|
|
|
fileName = `${defaultName}_模板.xlsx`
|
|
fileName = `${defaultName}_模板.xlsx`
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // 确保文件名有扩展名
|
|
|
|
|
if (!/\.[a-zA-Z0-9]+$/.test(fileName)) {
|
|
if (!/\.[a-zA-Z0-9]+$/.test(fileName)) {
|
|
|
fileName += '.xlsx'
|
|
fileName += '.xlsx'
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 创建 Blob URL 并触发下载
|
|
|
|
|
- const url = window.URL.createObjectURL(new Blob([blob]))
|
|
|
|
|
|
|
+ const url = window.URL.createObjectURL(blob)
|
|
|
const link = document.createElement('a')
|
|
const link = document.createElement('a')
|
|
|
link.style.display = 'none'
|
|
link.style.display = 'none'
|
|
|
link.href = url
|
|
link.href = url
|
|
@@ -1101,14 +1149,47 @@
|
|
|
document.body.appendChild(link)
|
|
document.body.appendChild(link)
|
|
|
link.click()
|
|
link.click()
|
|
|
document.body.removeChild(link)
|
|
document.body.removeChild(link)
|
|
|
-
|
|
|
|
|
- // 释放 URL 对象
|
|
|
|
|
window.URL.revokeObjectURL(url)
|
|
window.URL.revokeObjectURL(url)
|
|
|
|
|
|
|
|
- this.$message.success('模板下载成功')
|
|
|
|
|
|
|
+ this.$message &&
|
|
|
|
|
+ this.$message.success &&
|
|
|
|
|
+ this.$message.success('开始下载文件')
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
|
|
+ // 兼容:axios 抛错时,错误信息可能在 error.response.data(同样可能是 Blob)
|
|
|
|
|
+ try {
|
|
|
|
|
+ const errRes = error && error.response
|
|
|
|
|
+ const errData = errRes && errRes.data
|
|
|
|
|
+ let errJson = null
|
|
|
|
|
+ if (
|
|
|
|
|
+ errData &&
|
|
|
|
|
+ typeof errData === 'object' &&
|
|
|
|
|
+ !(errData instanceof Blob)
|
|
|
|
|
+ ) {
|
|
|
|
|
+ errJson = errData
|
|
|
|
|
+ } else if (errData instanceof Blob) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const text = await errData.text()
|
|
|
|
|
+ errJson = text ? JSON.parse(text) : null
|
|
|
|
|
+ } catch (_) {
|
|
|
|
|
+ errJson = null
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (errJson && (errJson.message || errJson.msg)) {
|
|
|
|
|
+ this.$message &&
|
|
|
|
|
+ this.$message.warning &&
|
|
|
|
|
+ this.$message.warning(errJson.message || errJson.msg)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (_) {
|
|
|
|
|
+ // ignore
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
console.error('模板下载失败:', error)
|
|
console.error('模板下载失败:', error)
|
|
|
- this.$message.error(error.message || '模板下载失败,请稍后重试')
|
|
|
|
|
|
|
+ this.$message &&
|
|
|
|
|
+ this.$message.error &&
|
|
|
|
|
+ this.$message.error(error.message || '模板下载失败,请稍后重试')
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ if (loading && loading.close) loading.close()
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
// 以下为在线填报所需方法,与 CostSurveyTab 对齐
|
|
// 以下为在线填报所需方法,与 CostSurveyTab 对齐
|