|
|
|
@ -141,6 +141,12 @@ |
|
|
|
</table> |
|
|
|
|
|
|
|
<!-- 编辑模式:底部固定保存栏 --> |
|
|
|
<!-- 查看模式工具栏 --> |
|
|
|
<div v-if="isView" class="save-bar"> |
|
|
|
<el-button @click="exportExcel">导出Excel</el-button> |
|
|
|
<el-button @click="handleCancel">关闭</el-button> |
|
|
|
</div> |
|
|
|
<!-- 编辑模式工具栏 --> |
|
|
|
<div v-if="!isView" class="save-bar"> |
|
|
|
<el-button class="saveetch-btn" type="primary" :loading="refetchLoading" @click="handleRefetch">重新获取统计数据</el-button> |
|
|
|
<el-button @click="exportExcel">导出Excel</el-button> |
|
|
|
@ -151,7 +157,7 @@ |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
import { FetchInitStatisticsTemplate, SaveStatisticsTemplate } from '@/api/statistics/statistics' |
|
|
|
import { FetchInitStatisticsTemplate, FetchRecalculateArchivesDoReport, FetchEditArchivesReportDetails } from '@/api/statistics/statistics' |
|
|
|
import ExcelJS from 'exceljs' |
|
|
|
import { saveAs } from 'file-saver' |
|
|
|
import { mapGetters } from 'vuex' |
|
|
|
@ -225,26 +231,12 @@ export default { |
|
|
|
created() { |
|
|
|
this.fetchReport() |
|
|
|
}, |
|
|
|
beforeDestroy() { |
|
|
|
sessionStorage.removeItem('da3_fondsName') |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
fetchReport() { |
|
|
|
const { reportingYear, unitId, templateId } = this.$route.query |
|
|
|
// 尝试读缓存(annualReport 预检时写入) |
|
|
|
const cacheKey = 'da3_report_cache_' + reportingYear + '_' + unitId |
|
|
|
let cached = null |
|
|
|
try { |
|
|
|
const raw = sessionStorage.getItem(cacheKey) |
|
|
|
if (raw) cached = JSON.parse(raw) |
|
|
|
} catch (e) { /* 解析失败忽略 */ } |
|
|
|
|
|
|
|
if (cached) { |
|
|
|
console.log('[Da3Report] 使用缓存数据', cached) |
|
|
|
this.rawReport = cached |
|
|
|
const model = this.normalizeModel(cached) |
|
|
|
if (model) this.remoteModel = model |
|
|
|
// 缓存用一次后清掉,避免脏数据 |
|
|
|
sessionStorage.removeItem(cacheKey) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
this.loading = true |
|
|
|
FetchInitStatisticsTemplate({ |
|
|
|
@ -302,14 +294,29 @@ export default { |
|
|
|
const body = [] |
|
|
|
const formData = { units: {}, data: {}} |
|
|
|
const leftCards = ['01', '02', '03', '04', '05'] |
|
|
|
// 填报值:inputType 为 'code'/'number' 时用 valCurNum,'text' 时用 valCurText |
|
|
|
// 填报值:优先按 inputType 取对应字段,没有则取另一个字段,都没有则为空 |
|
|
|
const pickVal = (r, which) => { |
|
|
|
const t = r.inputType |
|
|
|
if (which === 'cur') { |
|
|
|
// 本年:code/number 优先 valCurNum,text 优先 valCurText |
|
|
|
if (t === 'code' || t === 'number') { |
|
|
|
return which === 'cur' ? (r.valCurNum != null ? r.valCurNum : '') : (r.valPrevNum != null ? r.valPrevNum : '') |
|
|
|
if (r.valCurNum != null) return r.valCurNum |
|
|
|
if (r.valCurText != null) return r.valCurText |
|
|
|
} else { |
|
|
|
if (r.valCurText != null) return r.valCurText |
|
|
|
if (r.valCurNum != null) return r.valCurNum |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 上年:code/number 优先 valPrevNum,text 优先 valPrevText |
|
|
|
if (t === 'code' || t === 'number') { |
|
|
|
if (r.valPrevNum != null) return r.valPrevNum |
|
|
|
if (r.valPrevText != null) return r.valPrevText |
|
|
|
} else { |
|
|
|
if (r.valPrevText != null) return r.valPrevText |
|
|
|
if (r.valPrevNum != null) return r.valPrevNum |
|
|
|
} |
|
|
|
// text 或其他类型用 valCurText / valPrevText |
|
|
|
return which === 'cur' ? (r.valCurText != null ? r.valCurText : '') : (r.valPrevText != null ? r.valPrevText : '') |
|
|
|
} |
|
|
|
return '' |
|
|
|
} |
|
|
|
|
|
|
|
flat.forEach(r => { |
|
|
|
@ -326,7 +333,8 @@ export default { |
|
|
|
card: leftCards.indexOf(r.code) !== -1 ? 1 : 2, |
|
|
|
kind: r.inputType === 'code' ? 'code' : 'text' |
|
|
|
}) |
|
|
|
formData.units[r.code] = unitValues[r.code] != null ? unitValues[r.code] : (r.valCurText || '') |
|
|
|
const curVal = pickVal(r, 'cur') |
|
|
|
formData.units[r.code] = unitValues[r.code] != null ? unitValues[r.code] : (curVal != null && curVal !== '' ? curVal : (r.valCurText || r.valCurNum || '')) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
@ -379,10 +387,6 @@ export default { |
|
|
|
filler: res.filler || '', |
|
|
|
submitTime: res.submitTime || '' |
|
|
|
} |
|
|
|
// 填表人默认取当前登录用户名(接口无值时) |
|
|
|
if (!footerFormData.filler && this.user && this.user.username) { |
|
|
|
footerFormData.filler = this.user.username |
|
|
|
} |
|
|
|
const footer = [ |
|
|
|
{ col: 1, label: '单位负责人:' + footerFormData.unitHead }, |
|
|
|
{ col: 5, label: '统计负责人:' + footerFormData.statsHead }, |
|
|
|
@ -408,7 +412,7 @@ export default { |
|
|
|
this.$set(this.form, code + '_p', item.prev) |
|
|
|
}) |
|
|
|
} |
|
|
|
// 回填页脚签章 |
|
|
|
// 回填页脚签章(formData.footer 或 d.footerForm 都会走到这里) |
|
|
|
if (formData.footer) { |
|
|
|
Object.keys(this.footerForm).forEach(k => { |
|
|
|
if (formData.footer[k] != null) this.footerForm[k] = formData.footer[k] |
|
|
|
@ -572,6 +576,10 @@ export default { |
|
|
|
ws.getCell('I6').alignment = { horizontal: 'right', vertical: 'middle' } |
|
|
|
ws.getCell('I7').value = `有效期至:${this.data.template.valid_to}` |
|
|
|
ws.getCell('I7').font = { size: 10 } |
|
|
|
// 第7行 06 上方加当前年报年份 |
|
|
|
ws.getCell('G7').value = `${this.data.template.cur_year}年` |
|
|
|
ws.getCell('G7').font = { size: 10 } |
|
|
|
ws.getCell('G7').alignment = { horizontal: 'center', vertical: 'middle' } |
|
|
|
ws.getCell('I7').alignment = { horizontal: 'right', vertical: 'middle' } |
|
|
|
|
|
|
|
// ===== 第11行:表头(指标名称合并A-E) ===== |
|
|
|
@ -688,7 +696,8 @@ export default { |
|
|
|
|
|
|
|
// 生成并下载 |
|
|
|
const buffer = await wb.xlsx.writeBuffer() |
|
|
|
const fileName = `${this.data.template.title}_${this.data.template.cur_year}年.xlsx` |
|
|
|
const fondsName = sessionStorage.getItem('da3_fondsName') || (this.rawReport && this.rawReport.fondsName) || this.form.u_02 || '' |
|
|
|
const fileName = `${this.data.template.title}_${this.data.template.cur_year}年_${fondsName}.xlsx` |
|
|
|
saveAs(new Blob([buffer]), fileName) |
|
|
|
}, |
|
|
|
// 保存:基于接口原始结构回填用户输入(数值也写入 text 字段,与回显口径一致) |
|
|
|
@ -717,6 +726,21 @@ export default { |
|
|
|
// 指标行回填:inputType 为 'code'/'number' 写 valCurNum/valPrevNum,'text' 写 valCurText/valPrevText |
|
|
|
const walk = list => { |
|
|
|
(list || []).forEach(r => { |
|
|
|
// 单位信息行(01-07)回填到 rows 对应节点 |
|
|
|
if (r.itemType === 'unit' && r.code) { |
|
|
|
const v = this.form['u_' + r.code] |
|
|
|
const val = v === '' || v == null ? null : v |
|
|
|
if (r.inputType === 'code' || r.inputType === 'number') { |
|
|
|
const num = Number(val) |
|
|
|
if (val != null && !isNaN(num)) { |
|
|
|
r.valCurNum = num |
|
|
|
} else { |
|
|
|
r.valCurText = val != null ? String(val) : null |
|
|
|
} |
|
|
|
} else { |
|
|
|
r.valCurText = val != null ? String(val) : null |
|
|
|
} |
|
|
|
} |
|
|
|
if (r.itemType === 'indicator' && r.isLeaf && r.code) { |
|
|
|
const cur = this.form[r.code + '_c'] |
|
|
|
const prev = this.form[r.code + '_p'] |
|
|
|
@ -735,26 +759,91 @@ export default { |
|
|
|
} |
|
|
|
walk(payload.rows) |
|
|
|
|
|
|
|
// 页脚签章回填到顶层字段 |
|
|
|
payload.unitHead = this.footerForm.unitHead || null |
|
|
|
payload.statsHead = this.footerForm.statsHead || null |
|
|
|
payload.filler = this.footerForm.filler || null |
|
|
|
payload.submitTime = this.footerForm.submitTime || null |
|
|
|
// 拍平 rows,只保留接口需要的字段 |
|
|
|
const flatList = [] |
|
|
|
const flatten = list => { |
|
|
|
(list || []).forEach(r => { |
|
|
|
if (r.code) { |
|
|
|
flatList.push({ |
|
|
|
indicatorCode: r.code, |
|
|
|
reportId: payload.reportId != null ? payload.reportId : null, |
|
|
|
valCurNum: r.valCurNum != null ? r.valCurNum : null, |
|
|
|
valCurText: r.valCurText != null ? r.valCurText : null, |
|
|
|
valPrevNum: r.valPrevNum != null ? r.valPrevNum : null, |
|
|
|
valPrevText: r.valPrevText != null ? r.valPrevText : null |
|
|
|
}) |
|
|
|
} |
|
|
|
if (r.children && r.children.length) flatten(r.children) |
|
|
|
}) |
|
|
|
} |
|
|
|
flatten(payload.rows) |
|
|
|
|
|
|
|
// 组装最终传参 |
|
|
|
const savePayload = { |
|
|
|
reportId: payload.reportId != null ? payload.reportId : null, |
|
|
|
unitCreditCode: this.form.u_01 || null, |
|
|
|
unitName: this.form.u_02 || null, |
|
|
|
unitCategoryCode: this.form.u_03 || null, |
|
|
|
postalCode: this.form.u_04 || null, |
|
|
|
unitAddress: this.form.u_05 || null, |
|
|
|
telephone: this.form.u_06 || null, |
|
|
|
orgSituation: this.form.u_07 || null, |
|
|
|
unitHead: this.footerForm.unitHead || null, |
|
|
|
statsHead: this.footerForm.statsHead || null, |
|
|
|
filler: this.footerForm.filler || null, |
|
|
|
submitTime: this.footerForm.submitTime || null, |
|
|
|
reportDataList: flatList |
|
|
|
} |
|
|
|
|
|
|
|
this.saving = true |
|
|
|
SaveStatisticsTemplate(payload).then(() => { |
|
|
|
this.$message({ message: '保存成功', type: 'success', offset: 80 }) |
|
|
|
console.log('payload', savePayload) |
|
|
|
FetchEditArchivesReportDetails(savePayload).then((res) => { |
|
|
|
console.log('保存成功', res) |
|
|
|
if (res.code !== 500) { |
|
|
|
this.$message({ message: res, type: 'success', offset: 80 }) |
|
|
|
this.fetchReport() |
|
|
|
} else { |
|
|
|
this.$message({ message: res.message || '保存失败', type: 'error', offset: 80 }) |
|
|
|
} |
|
|
|
}).catch(() => { |
|
|
|
this.$message({ message: '保存失败', type: 'error', offset: 80 }) |
|
|
|
}).finally(() => { |
|
|
|
this.saving = false |
|
|
|
}) |
|
|
|
}, |
|
|
|
// 重新获取统计数据:点击后调用 fetchReport 重新获取接口数据 |
|
|
|
// 重新获取统计数据 |
|
|
|
handleRefetch() { |
|
|
|
this.refetchLoading = true |
|
|
|
this.fetchReport() |
|
|
|
FetchRecalculateArchivesDoReport(this.rawReport.reportId).then((res) => { |
|
|
|
console.log('重新计算成功', res) |
|
|
|
if (res.code !== 500) { |
|
|
|
// 根据 value{code}_{1|2} 回填表单:1=本年,2=上年 |
|
|
|
if (res && typeof res === 'object') { |
|
|
|
Object.keys(res).forEach(key => { |
|
|
|
const m = key.match(/^value(\d+)_(1|2)$/) |
|
|
|
if (m) { |
|
|
|
const code = m[1] |
|
|
|
const type = m[2] // 1=本年 2=上年 |
|
|
|
const val = res[key] |
|
|
|
if (type === '1') { |
|
|
|
this.$set(this.form, code + '_c', val) |
|
|
|
} else { |
|
|
|
this.$set(this.form, code + '_p', val) |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
this.$message({ message: '重新计算成功', type: 'success', offset: 80 }) |
|
|
|
} else { |
|
|
|
this.$message({ message: res.message || '重新计算失败', type: 'error', offset: 80 }) |
|
|
|
} |
|
|
|
}).finally(() => { |
|
|
|
this.refetchLoading = false |
|
|
|
}) |
|
|
|
}, |
|
|
|
// 取消:点击后关闭当前路由 |
|
|
|
handleCancel() { |
|
|
|
sessionStorage.removeItem('da3_fondsName') |
|
|
|
window.close() |
|
|
|
} |
|
|
|
} |
|
|
|
|