7 changed files with 2027 additions and 1 deletions
-
9src/api/statistics/statistics.js
-
2src/router/index.js
-
5src/router/routers.js
-
274src/views/archivesStatistics/Da3Report-checkbox.vue
-
272src/views/archivesStatistics/Da3Report.vue
-
376src/views/archivesStatistics/annualReport/index.vue
-
1090src/views/archivesStatistics/da3-model.js
@ -0,0 +1,274 @@ |
|||
<script> |
|||
import embeddedModel from './da3-model.js' |
|||
|
|||
export default { |
|||
name: 'Da3Report', |
|||
props: { |
|||
// 后台聚合返回的数据模型(template/units/body/footer);不传则用内置 demo 数据 |
|||
model: { type: Object, default: null } |
|||
}, |
|||
data() { |
|||
return { |
|||
form: {}, |
|||
orgCheck: [] |
|||
} |
|||
}, |
|||
computed: { |
|||
data() { |
|||
return this.model || embeddedModel |
|||
}, |
|||
leftUnits() { |
|||
return this.data.units.filter(u => u.card === 1) // 01-05 |
|||
}, |
|||
rightUnits() { |
|||
return this.data.units.filter(u => u.card === 2) // 06-07 |
|||
}, |
|||
metaTop() { |
|||
return [ |
|||
{ label: '表号', value: this.data.template.form_no }, |
|||
{ label: '制定机关', value: this.data.template.issuing_org }, |
|||
{ label: '批准机关', value: this.data.template.approving_org } |
|||
// { label: '批准文号', value: this.data.template.approve_doc_no }, |
|||
// { label: '有效期至', value: this.data.template.valid_to } |
|||
] |
|||
} |
|||
}, |
|||
watch: { |
|||
data: { |
|||
handler(d) { |
|||
this.initForm(d) |
|||
}, |
|||
immediate: true |
|||
} |
|||
}, |
|||
methods: { |
|||
initForm(d) { |
|||
const form = {} |
|||
d.units.forEach(u => { form['u_' + u.code] = '' }) |
|||
d.body.forEach(it => { |
|||
if (it.type === 'indicator' || it.type === 'continuation') { |
|||
form[it.code + '_c'] = '' // 本年 |
|||
form[it.code + '_p'] = '' // 上年 |
|||
} |
|||
}) |
|||
this.form = form |
|||
}, |
|||
fillDemo() { |
|||
const DEMO = { |
|||
u_01: '91420100MA4KXXXXXX', u_02: '阅行客(武汉)科技有限公司', u_03: '130', |
|||
u_04: '430000', u_05: '武汉市xx区xx路1号', u_06: '027-88888888', u_07: '独立档案室', |
|||
'08_c': '12', '08_p': '10', '09_c': '8', '09_p': '7', '10_c': '2', |
|||
'11_c': '5', '12_c': '5', '34_c': '1200', '35_c': '35000', '36_c': '42.5', |
|||
'37_c': '800', '38_c': '600', '39_c': '120', '82_c': '5', '95_c': '是', |
|||
'96_c': '否', '97_c': '否', '109_c': '1' |
|||
} |
|||
Object.assign(this.form, DEMO) |
|||
}, |
|||
clearAll() { |
|||
Object.keys(this.form).forEach(k => { this.form[k] = '' }) |
|||
}, |
|||
buildPayload() { |
|||
const units = {}; const reportData = {} |
|||
this.data.units.forEach(u => { units[u.code] = this.form['u_' + u.code] || '' }) |
|||
// 07 机构情况:勾选项同步 |
|||
if (this.orgCheck.length > 0) { |
|||
const labels = [] |
|||
if (this.orgCheck.includes('1')) labels.push('1.档案馆') |
|||
if (this.orgCheck.includes('2')) labels.push('2.档案方如馆等') |
|||
units['07'] = labels.join('、') |
|||
} |
|||
this.data.body.forEach(it => { |
|||
if (it.type === 'indicator' || it.type === 'continuation') { |
|||
reportData[it.code] = { cur: this.form[it.code + '_c'] || '', prev: this.form[it.code + '_p'] || '' } |
|||
} |
|||
}) |
|||
return { units, data: reportData } |
|||
}, |
|||
exportJSON() { |
|||
const payload = this.buildPayload() |
|||
console.log(JSON.stringify(payload, null, 2)) |
|||
this.$emit('export', payload) |
|||
alert('已导出到控制台(F12),并通过 emit("export") 回传父组件') |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<template> |
|||
<div class="da3"> |
|||
<!-- <div class="toolbar"> |
|||
<button @click="fillDemo">填入示例数据</button> |
|||
<button @click="clearAll">清空</button> |
|||
<button @click="exportJSON">导出当前填报 JSON</button> |
|||
<span class="hint">数据驱动渲染 · 来自 template_item 等表</span> |
|||
</div> --> |
|||
|
|||
<table class="form"> |
|||
<!-- 附件2 + 题名 --> |
|||
<tr><td class="attach" colspan="9">{{ data.template.attach }}</td></tr> |
|||
<tr><td class="title" colspan="9">{{ data.template.title }}</td></tr> |
|||
|
|||
<!-- 元信息(表号/制定机关/批准机关) --> |
|||
<tr v-for="(m, i) in metaTop" :key="'mt' + i" class="meta-row"> |
|||
<td colspan="9" class="meta"> |
|||
<div class="meta-flex"> |
|||
<!-- <i class="colon">:</i> --> |
|||
<span class="meta-label">{{ m.label }}</span> |
|||
<i class="colon">:</i> |
|||
<span class="meta-value">{{ m.value }}</span> |
|||
</div> |
|||
</td> |
|||
</tr> |
|||
|
|||
<!-- 单位信息卡 01-07(左列 01-05 + 右列 06-07 + 批准文号/有效期) --> |
|||
<tr v-for="(u, i) in leftUnits" :key="'lu' + i" :class="['unit-row', { 'unit-row-bordered': i >= 2 }]"> |
|||
<td class="ucode">{{ u.code }}</td> |
|||
<td class="ulabel" colspan="4">{{ u.label }}:<input v-model="form['u_' + u.code]" type="text"></td> |
|||
|
|||
<template v-if="i === 0"> |
|||
<td class="meta" colspan="4"> |
|||
<div class="meta-flex"> |
|||
<span class="meta-label">批准文号</span> |
|||
<i class="colon">:</i> |
|||
<span class="meta-value">{{ data.template.approve_doc_no }}</span> |
|||
</div> |
|||
</td></template> |
|||
<template v-else-if="i === 1"> |
|||
<td class="meta" colspan="4"> |
|||
<div class="meta-flex"> |
|||
<span class="meta-label">有效期至</span> |
|||
<i class="colon">:</i> |
|||
<span class="meta-value" style="text-align: right !important; text-align-last: right !important;">{{ data.template.valid_to }}</span> |
|||
</div> |
|||
</td> |
|||
</template> |
|||
<template v-if="i === 2 && rightUnits[0]"> |
|||
<td class="ucode">{{ rightUnits[0].code }}</td> |
|||
<td class="ulabel" colspan="3">{{ rightUnits[0].label }}:<input v-model="form['u_' + rightUnits[0].code]" type="text"></td> |
|||
</template> |
|||
<template v-else-if="i === 3 && rightUnits[1]"> |
|||
<td class="ucode ucell" rowspan="2">{{ rightUnits[1].code }}</td> |
|||
<td class="ulabel ucell" rowspan="2">{{ rightUnits[1].label }}:</td> |
|||
<td class="ucell check-cell" colspan="2" rowspan="2"> |
|||
<label class="check-line"><input v-model="orgCheck" type="checkbox" value="1"> 1.档案馆</label> |
|||
<label class="check-line"><input v-model="orgCheck" type="checkbox" value="2"> 2.档案方如馆等</label> |
|||
</td> |
|||
</template> |
|||
<template v-else-if="i === 4" /> |
|||
<template v-else> |
|||
<td colspan="4" /> |
|||
</template> |
|||
</tr> |
|||
|
|||
<!-- 列头 --> |
|||
<tr> |
|||
<th class="colname" colspan="5">指标名称</th> |
|||
<th class="colname">计量单位</th> |
|||
<th class="colname">代码</th> |
|||
<th class="colname">数量({{ data.template.cur_year }}年)</th> |
|||
<th class="colname">上年度数据({{ data.template.prev_year }}年)</th> |
|||
</tr> |
|||
<tr> |
|||
<th class="colsub" colspan="5">甲</th> |
|||
<th class="colsub">乙</th> |
|||
<th class="colsub">丙</th> |
|||
<th class="colsub">1</th> |
|||
<th class="colsub" /> |
|||
</tr> |
|||
|
|||
<!-- 主体 --> |
|||
<template v-for="(it, idx) in data.body"> |
|||
<!-- 章节 / 分组 --> |
|||
<tr v-if="it.type === 'section' || it.type === 'group'" :key="'s' + idx" :class="it.type + ' body-row'"> |
|||
<td class="nm" colspan="5" :style="{ paddingLeft: (it.level * 1.6) + 'em' }">{{ it.name }}</td> |
|||
<td class="dash">{{ it.unit || '—' }}</td> |
|||
<td class="dash">—</td> |
|||
<td class="dash">—</td> |
|||
<td class="dash" /> |
|||
</tr> |
|||
<!-- 指标 / 续行 --> |
|||
<tr v-if="it.type !== 'section' && it.type !== 'group'" :key="'i' + idx" class="body-row"> |
|||
<td class="nm" colspan="5" :style="{ paddingLeft: (it.level * 1.6) + 'em' }">{{ it.name }}</td> |
|||
<td class="unit">{{ it.unit }}</td> |
|||
<td class="code">{{ it.code }}</td> |
|||
<td class="data"> |
|||
<select v-if="it.input === 'yesno'" v-model="form[it.code + '_c']"> |
|||
<option value="" /><option value="是">是</option><option value="否">否</option> |
|||
</select> |
|||
<input v-else v-model="form[it.code + '_c']" type="text" inputmode="decimal"> |
|||
</td> |
|||
<td class="data"> |
|||
<select v-if="it.input === 'yesno'" v-model="form[it.code + '_p']"> |
|||
<option value="" /><option value="是">是</option><option value="否">否</option> |
|||
</select> |
|||
<input v-else v-model="form[it.code + '_p']" type="text" inputmode="decimal"> |
|||
</td> |
|||
</tr> |
|||
</template> |
|||
|
|||
<!-- 页脚签章 --> |
|||
<tr class="footer-row"> |
|||
<td v-for="(f, fi) in data.footer" :key="'f' + fi" :colspan="fi < data.footer.length - 1 ? data.footer[fi + 1].col - f.col : (10 - f.col)">{{ f.label }}</td> |
|||
</tr> |
|||
</table> |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped> |
|||
* { box-sizing: border-box; } |
|||
.da3 { font-family: "SimSun", "宋体", serif; color: #000; background: #fff; padding: 20px; } |
|||
.toolbar { max-width: 1040px; margin: 0 auto 12px; font-size: 13px; color: #444; } |
|||
.toolbar button { font-family: inherit; padding: 4px 10px; margin-right: 8px; cursor: pointer; } |
|||
.toolbar .hint { color: #888; } |
|||
table.form { |
|||
width: 1000px; margin: 0 auto; border-collapse: collapse; |
|||
background: #fff; border: hidden; |
|||
} |
|||
/* 标题、附件、元信息区无边框 */ |
|||
table.form .attach, table.form .title, |
|||
table.form .meta-row td { |
|||
border: none; |
|||
} |
|||
/* 01-02 无边框 */ |
|||
table.form .unit-row td { |
|||
border: none; |
|||
} |
|||
/* 03-07 有边框 */ |
|||
table.form .unit-row-bordered td { |
|||
border: 1px solid #000; |
|||
} |
|||
/* 列头 + 数据区有边框 */ |
|||
table.form .colname, table.form .colsub, |
|||
table.form .body-row td { |
|||
border-right: 1px solid #000; |
|||
} |
|||
table.form .colname:last-child, |
|||
table.form .colsub:last-child, |
|||
table.form .body-row td:last-child { |
|||
border-right: none; |
|||
} |
|||
table.form td, table.form th { padding: 2px 6px; vertical-align: middle; font-size: 13px; line-height: 1.6; } |
|||
.attach { font-size: 12px; text-align: left; } |
|||
table.form td.title { font-size: 30px !important; font-weight: bold; text-align: center; letter-spacing: 6px; padding: 12px 0; font-family: "SimHei", "黑体", sans-serif; } |
|||
.meta { font-size: 12px; white-space: nowrap; } |
|||
.meta-flex { display: flex; justify-content: flex-end; align-items: baseline; width: 210px; margin-left: auto; } |
|||
.meta-label { display: block; width: 60px; text-align: justify; text-align-last: justify; } |
|||
.meta-flex .colon { font-style: normal; } |
|||
.meta-value { display: block; flex: 1; margin-left: 5px; text-align: justify; text-align-last: justify; word-break: break-all; } |
|||
.ucode { text-align: center; width: 30px; font-weight: bold; white-space: nowrap; } |
|||
.ulabel { font-size: 13px; white-space: nowrap; border-right: none !important; } |
|||
.ulabel input { width: auto; min-width: 200px; border: none; border: 1px solid #ccc ; font-family: inherit; font-size: 13px; padding: 2px; outline: none; } |
|||
.check-line { text-align: left; font-size: 13px; line-height: 1.8; } |
|||
.check-cell { white-space: nowrap; border-right: none !important; } |
|||
.colname { font-weight: bold; text-align: center; background: #fff; border-top: 1px solid #000; border-bottom: 1px solid #000; white-space: nowrap; } |
|||
.colsub { text-align: center; font-size: 12px; color: #000; font-weight: normal; border-bottom: 1px solid #000; white-space: nowrap; } |
|||
.section td { font-weight: bold; } |
|||
.nm { white-space: pre; } |
|||
.unit { text-align: center; width: 60px; white-space: nowrap; } |
|||
.code { text-align: center; width: 42px; white-space: nowrap; } |
|||
.data { width: 160px; text-align: center; white-space: nowrap; } |
|||
.data input, .data select { width: 96%; border: none; border: 1px solid #ccc; padding: 4px 0; font-family: inherit; font-size: 13px; text-align: center; outline: none; } |
|||
.dash { text-align: center; } |
|||
.footer-row td { border: none; border-top: 1px solid #000; white-space: nowrap; padding: 8px 6px; } |
|||
.footer-note td { border: none; padding: 8px 6px; font-size: 12px; } |
|||
</style> |
|||
@ -0,0 +1,272 @@ |
|||
<script> |
|||
import embeddedModel from './da3-model.js' |
|||
|
|||
export default { |
|||
name: 'Da3Report', |
|||
props: { |
|||
// 后台聚合返回的数据模型(template/units/body/footer);不传则用内置 demo 数据 |
|||
model: { type: Object, default: null } |
|||
}, |
|||
data() { |
|||
return { |
|||
form: {} |
|||
} |
|||
}, |
|||
computed: { |
|||
data() { |
|||
return this.model || embeddedModel |
|||
}, |
|||
// 查看模式(不可输入)还是编辑模式(可输入),默认查看 |
|||
isView() { |
|||
return this.$route.query.mode !== 'edit' |
|||
}, |
|||
leftUnits() { |
|||
return this.data.units.filter(u => u.card === 1) // 01-05 |
|||
}, |
|||
rightUnits() { |
|||
return this.data.units.filter(u => u.card === 2) // 06-07 |
|||
}, |
|||
metaTop() { |
|||
return [ |
|||
{ label: '表号', value: this.data.template.form_no }, |
|||
{ label: '制定机关', value: this.data.template.issuing_org }, |
|||
{ label: '批准机关', value: this.data.template.approving_org } |
|||
// { label: '批准文号', value: this.data.template.approve_doc_no }, |
|||
// { label: '有效期至', value: this.data.template.valid_to } |
|||
] |
|||
} |
|||
}, |
|||
watch: { |
|||
data: { |
|||
handler(d) { |
|||
this.initForm(d) |
|||
// TODO: 接口就绪后,改为按路由参数(id)请求真实填报数据后回显 |
|||
this.fillDemo() |
|||
}, |
|||
immediate: true |
|||
} |
|||
}, |
|||
methods: { |
|||
initForm(d) { |
|||
const form = {} |
|||
d.units.forEach(u => { form['u_' + u.code] = '' }) |
|||
d.body.forEach(it => { |
|||
if (it.type === 'indicator' || it.type === 'continuation') { |
|||
form[it.code + '_c'] = '' // 本年 |
|||
form[it.code + '_p'] = '' // 上年 |
|||
} |
|||
}) |
|||
this.form = form |
|||
}, |
|||
fillDemo() { |
|||
const DEMO = { |
|||
u_01: '91420100MA4KXXXXXX', u_02: '阅行客(武汉)科技有限公司', u_03: '130', |
|||
u_04: '430000', u_05: '武汉市xx区xx路1号', u_06: '027-88888888', u_07: '独立档案室', |
|||
'08_c': '12', '08_p': '10', '09_c': '8', '09_p': '7', '10_c': '2', |
|||
'11_c': '5', '12_c': '5', '34_c': '1200', '35_c': '35000', '36_c': '42.5', |
|||
'37_c': '800', '38_c': '600', '39_c': '120', '82_c': '5', '95_c': '是', |
|||
'96_c': '否', '97_c': '否', '109_c': '1' |
|||
} |
|||
Object.assign(this.form, DEMO) |
|||
}, |
|||
clearAll() { |
|||
Object.keys(this.form).forEach(k => { this.form[k] = '' }) |
|||
}, |
|||
buildPayload() { |
|||
const units = {}; const reportData = {} |
|||
this.data.units.forEach(u => { units[u.code] = this.form['u_' + u.code] || '' }) |
|||
this.data.body.forEach(it => { |
|||
if (it.type === 'indicator' || it.type === 'continuation') { |
|||
reportData[it.code] = { cur: this.form[it.code + '_c'] || '', prev: this.form[it.code + '_p'] || '' } |
|||
} |
|||
}) |
|||
return { units, data: reportData } |
|||
}, |
|||
exportJSON() { |
|||
const payload = this.buildPayload() |
|||
console.log(JSON.stringify(payload, null, 2)) |
|||
this.$emit('export', payload) |
|||
alert('已导出到控制台(F12),并通过 emit("export") 回传父组件') |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<template> |
|||
<div class="da3"> |
|||
<!-- <div class="toolbar"> |
|||
<button @click="fillDemo">填入示例数据</button> |
|||
<button @click="clearAll">清空</button> |
|||
<button @click="exportJSON">导出当前填报 JSON</button> |
|||
<span class="hint">数据驱动渲染 · 来自 template_item 等表</span> |
|||
</div> --> |
|||
|
|||
<table class="form"> |
|||
<!-- 附件2 + 题名 --> |
|||
<tr><td class="attach" colspan="9">{{ data.template.attach }}</td></tr> |
|||
<tr><td class="title" colspan="9">{{ data.template.title }}</td></tr> |
|||
|
|||
<!-- 元信息(表号/制定机关/批准机关) --> |
|||
<tr v-for="(m, i) in metaTop" :key="'mt' + i" class="meta-row"> |
|||
<td colspan="9" class="meta"> |
|||
<div class="meta-flex"> |
|||
<!-- <i class="colon">:</i> --> |
|||
<span class="meta-label">{{ m.label }}</span> |
|||
<i class="colon">:</i> |
|||
<span class="meta-value">{{ m.value }}</span> |
|||
</div> |
|||
</td> |
|||
</tr> |
|||
|
|||
<!-- 单位信息卡 01-07(左列 01-05 + 右列 06-07 + 批准文号/有效期) --> |
|||
<tr v-for="(u, i) in leftUnits" :key="'lu' + i" :class="['unit-row', { 'unit-row-bordered': i >= 2 }]"> |
|||
<td class="ucode">{{ u.code }}</td> |
|||
<td class="ulabel" colspan="4">{{ u.label }}:<span v-if="isView" class="plain">{{ form['u_' + u.code] }}</span><input v-else v-model="form['u_' + u.code]" type="text"></td> |
|||
|
|||
<template v-if="i === 0"> |
|||
<td class="meta" colspan="4"> |
|||
<div class="meta-flex"> |
|||
<span class="meta-label">批准文号</span> |
|||
<i class="colon">:</i> |
|||
<span class="meta-value">{{ data.template.approve_doc_no }}</span> |
|||
</div> |
|||
</td></template> |
|||
<template v-else-if="i === 1"> |
|||
<td class="meta" colspan="4"> |
|||
<div class="meta-flex"> |
|||
<span class="meta-label">有效期至</span> |
|||
<i class="colon">:</i> |
|||
<span class="meta-value" style="text-align: right !important; text-align-last: right !important;">{{ data.template.valid_to }}</span> |
|||
</div> |
|||
</td> |
|||
</template> |
|||
<template v-if="i === 2 && rightUnits[0]"> |
|||
<td class="ucode">{{ rightUnits[0].code }}</td> |
|||
<td class="ulabel" colspan="3">{{ rightUnits[0].label }}:<span v-if="isView" class="plain">{{ form['u_' + rightUnits[0].code] }}</span><input v-else v-model="form['u_' + rightUnits[0].code]" type="text"></td> |
|||
</template> |
|||
<template v-else-if="i === 3 && rightUnits[1]"> |
|||
<td class="ucode ucell" rowspan="2">{{ rightUnits[1].code }}</td> |
|||
<td class="ulabel ucell" colspan="3" rowspan="2">{{ rightUnits[1].label }}:<span v-if="isView" class="plain">{{ form['u_' + rightUnits[1].code] }}</span><input v-else v-model="form['u_' + rightUnits[1].code]" type="text"></td> |
|||
</template> |
|||
<template v-else-if="i === 4" /> |
|||
<template v-else> |
|||
<td colspan="4" /> |
|||
</template> |
|||
</tr> |
|||
|
|||
<!-- 列头 --> |
|||
<tr> |
|||
<th class="colname" colspan="5">指标名称</th> |
|||
<th class="colname">计量单位</th> |
|||
<th class="colname">代码</th> |
|||
<th class="colname">数量({{ data.template.cur_year }}年)</th> |
|||
<th class="colname">上年度数据({{ data.template.prev_year }}年)</th> |
|||
</tr> |
|||
<tr> |
|||
<th class="colsub" colspan="5">甲</th> |
|||
<th class="colsub">乙</th> |
|||
<th class="colsub">丙</th> |
|||
<th class="colsub">1</th> |
|||
<th class="colsub" /> |
|||
</tr> |
|||
|
|||
<!-- 主体 --> |
|||
<template v-for="(it, idx) in data.body"> |
|||
<!-- 章节 / 分组 --> |
|||
<tr v-if="it.type === 'section' || it.type === 'group'" :key="'s' + idx" :class="it.type + ' body-row'"> |
|||
<td class="nm" colspan="5" :style="{ paddingLeft: (it.level * 1.6) + 'em' }">{{ it.name }}</td> |
|||
<td class="dash">{{ it.unit || '—' }}</td> |
|||
<td class="dash">—</td> |
|||
<td class="dash">—</td> |
|||
<td class="dash" /> |
|||
</tr> |
|||
<!-- 指标 / 续行 --> |
|||
<tr v-if="it.type !== 'section' && it.type !== 'group'" :key="'i' + idx" class="body-row"> |
|||
<td class="nm" colspan="5" :style="{ paddingLeft: (it.level * 1.6) + 'em' }">{{ it.name }}</td> |
|||
<td class="unit">{{ it.unit }}</td> |
|||
<td class="code">{{ it.code }}</td> |
|||
<td class="data"> |
|||
<span v-if="isView" class="plain">{{ form[it.code + '_c'] }}</span> |
|||
<select v-else-if="it.input === 'yesno'" v-model="form[it.code + '_c']"> |
|||
<option value="" /><option value="是">是</option><option value="否">否</option> |
|||
</select> |
|||
<input v-else v-model="form[it.code + '_c']" type="text" inputmode="decimal"> |
|||
</td> |
|||
<td class="data"> |
|||
<span v-if="isView" class="plain">{{ form[it.code + '_p'] }}</span> |
|||
<select v-else-if="it.input === 'yesno'" v-model="form[it.code + '_p']"> |
|||
<option value="" /><option value="是">是</option><option value="否">否</option> |
|||
</select> |
|||
<input v-else v-model="form[it.code + '_p']" type="text" inputmode="decimal"> |
|||
</td> |
|||
</tr> |
|||
</template> |
|||
|
|||
<!-- 页脚签章 --> |
|||
<tr class="footer-row"> |
|||
<td v-for="(f, fi) in data.footer" :key="'f' + fi" :colspan="fi < data.footer.length - 1 ? data.footer[fi + 1].col - f.col : (10 - f.col)">{{ f.label }}</td> |
|||
</tr> |
|||
</table> |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped> |
|||
* { box-sizing: border-box; } |
|||
.da3 { font-family: "SimSun", "宋体", serif; color: #000; background: #fff; padding: 20px; } |
|||
.toolbar { max-width: 1040px; margin: 0 auto 12px; font-size: 13px; color: #444; } |
|||
.toolbar button { font-family: inherit; padding: 4px 10px; margin-right: 8px; cursor: pointer; } |
|||
.toolbar .hint { color: #888; } |
|||
table.form { |
|||
width: 1000px; margin: 0 auto; border-collapse: collapse; |
|||
background: #fff; border: hidden; |
|||
} |
|||
/* 标题、附件、元信息区无边框 */ |
|||
table.form .attach, table.form .title, |
|||
table.form .meta-row td { |
|||
border: none; |
|||
} |
|||
/* 01-02 无边框 */ |
|||
table.form .unit-row td { |
|||
border: none; |
|||
} |
|||
/* 03-07 有边框 */ |
|||
table.form .unit-row-bordered td { |
|||
border: 1px solid #000; |
|||
} |
|||
/* 列头 + 数据区有边框 */ |
|||
table.form .colname, table.form .colsub, |
|||
table.form .body-row td { |
|||
border-right: 1px solid #000; |
|||
} |
|||
table.form .colname:last-child, |
|||
table.form .colsub:last-child, |
|||
table.form .body-row td:last-child { |
|||
border-right: none; |
|||
} |
|||
table.form td, table.form th { padding: 2px 6px; vertical-align: middle; font-size: 13px; line-height: 1.6; } |
|||
.attach { font-size: 12px; text-align: left; } |
|||
table.form td.title { font-size: 30px !important; font-weight: bold; text-align: center; letter-spacing: 6px; padding: 12px 0; font-family: "SimHei", "黑体", sans-serif; } |
|||
.meta { font-size: 12px; white-space: nowrap; } |
|||
.meta-flex { display: flex; justify-content: flex-end; align-items: baseline; width: 210px; margin-left: auto; } |
|||
.meta-label { display: block; width: 60px; text-align: justify; text-align-last: justify; } |
|||
.meta-flex .colon { font-style: normal; } |
|||
.meta-value { display: block; flex: 1; margin-left: 5px; text-align: justify; text-align-last: justify; word-break: break-all; } |
|||
.ucode { text-align: center; width: 30px; font-weight: bold; white-space: nowrap; } |
|||
.ulabel { font-size: 13px; white-space: nowrap; border-right: none !important; } |
|||
.ulabel input { width: auto; min-width: 200px; border: none; border: 1px solid #ccc ; font-family: inherit; font-size: 13px; padding: 2px; outline: none; } |
|||
.check-line { text-align: left; font-size: 13px; line-height: 1.8; } |
|||
.check-cell { white-space: nowrap; border-right: none !important; } |
|||
.colname { font-weight: bold; text-align: center; background: #fff; border-top: 1px solid #000; border-bottom: 1px solid #000; white-space: nowrap; } |
|||
.colsub { text-align: center; font-size: 12px; color: #000; font-weight: normal; border-bottom: 1px solid #000; white-space: nowrap; } |
|||
.section td { font-weight: bold; } |
|||
.nm { white-space: pre; } |
|||
.unit { text-align: center; width: 60px; white-space: nowrap; } |
|||
.code { text-align: center; width: 42px; white-space: nowrap; } |
|||
.data { width: 160px; text-align: center; white-space: nowrap; } |
|||
.data input, .data select { width: 96%; border: none; border: 1px solid #ccc; padding: 4px 0; font-family: inherit; font-size: 13px; text-align: center; outline: none; } |
|||
/* 查看模式纯文本展示 */ |
|||
.plain { display: inline-block; min-width: 60px; min-height: 1em; } |
|||
.dash { text-align: center; } |
|||
.footer-row td { border: none; border-top: 1px solid #000; white-space: nowrap; padding: 8px 6px; } |
|||
.footer-note td { border: none; padding: 8px 6px; font-size: 12px; } |
|||
</style> |
|||
@ -0,0 +1,376 @@ |
|||
<template> |
|||
<div class="app-container row-container"> |
|||
<div class="connection-header collect-header" style="padding: 0; border-top: none; height: auto; margin-bottom: 20px;"> |
|||
<div class="head-search" style="margin-bottom: 0;"> |
|||
<el-select |
|||
v-model="fondsIds" |
|||
multiple |
|||
collapse-tags |
|||
placeholder="请选择所属全宗" |
|||
style="width: 320px;" |
|||
> |
|||
<el-option |
|||
v-for="item in fondsOptions" |
|||
:key="item.id" |
|||
:label="item.fondsName" |
|||
:value="item.id" |
|||
/> |
|||
</el-select> |
|||
<el-select |
|||
v-model="years" |
|||
multiple |
|||
collapse-tags |
|||
placeholder="请选择年份" |
|||
style="width: 150px;" |
|||
> |
|||
<el-option |
|||
v-for="item in yearsOptions" |
|||
:key="item.id" |
|||
:label="item.name" |
|||
:value="item.id" |
|||
/> |
|||
</el-select> |
|||
<el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" @click="getTotalStatistics">查询</el-button> |
|||
<el-button class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery">重置</el-button> |
|||
</div> |
|||
<el-button size="mini" :loading="addLoading" @click="toAdd"> |
|||
<i class="iconfont icon-xinzeng" /> |
|||
新增 |
|||
</el-button> |
|||
</div> |
|||
<el-table v-loading="loading" class="archives-table" :data="allData" style="width: 100%;"> |
|||
<el-table-column prop="year" label="年度" align="center" /> |
|||
<el-table-column prop="archivesCount" label="填报单位" /> |
|||
<el-table-column prop="username" label="创建人" align="center" /> |
|||
<el-table-column prop="createTime" label="创建时间" align="center"> |
|||
<template slot-scope="scope"> |
|||
<div>{{ scope.row.createTime | parseTime }}</div> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column prop="modelName" label="统计模板" /> |
|||
<el-table-column prop="handle" label="操作"> |
|||
<template slot-scope="scope"> |
|||
<el-button size="mini" @click="handleDetail(scope.row)">查看详情</el-button> |
|||
<el-button size="mini" @click="handleEdit(scope.row)">编辑</el-button> |
|||
<el-button size="mini" @click="handleDelete(scope.row)">删除</el-button> |
|||
<!-- <el-button :loading="btnLoading" class="packing-handle-btn iconfont" @click="handleCartoning(scope.row)"><svg-icon icon-class="zhuanghe" class="svg-arc-style" />装盒</el-button> --> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
<el-pagination |
|||
v-if="allData.length !== 0" |
|||
:current-page="page.page" |
|||
:total="page.total" |
|||
:page-size="page.size" |
|||
:pager-count="5" |
|||
layout="total, prev, pager, next, sizes" |
|||
@size-change="handleSizeChange" |
|||
@current-change="handleCurrentPage" |
|||
/> |
|||
<!-- 年报新增/编辑弹框 --> |
|||
<el-dialog class="dialog-middle" :modal-append-to-body="false" :close-on-click-modal="false" :before-close="closeFormDialog" :visible="formVisible" :title="dialogTitle" width="560px"> |
|||
<span class="dialog-right-top" /> |
|||
<span class="dialog-left-bottom" /> |
|||
<div class="setting-dialog"> |
|||
<el-form ref="form" :model="form" :rules="formRules" label-width="90px"> |
|||
<el-form-item label="全宗" prop="fondsId"> |
|||
<el-select v-model="form.fondsId" :disabled="isEdit" placeholder="请选择全宗" style="width: 100%;"> |
|||
<el-option |
|||
v-for="item in fondsOptions" |
|||
:key="item.id" |
|||
:label="item.fondsName" |
|||
:value="item.id" |
|||
/> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="年度" prop="year"> |
|||
<el-date-picker v-model="form.year" type="year" value-format="yyyy" :disabled="isEdit" placeholder="请选择年度" style="width: 100%;" /> |
|||
</el-form-item> |
|||
<el-form-item label="统计模板" prop="modelId"> |
|||
<el-select v-model="form.modelId" :disabled="isEdit" placeholder="请选择统计模板" style="width: 100%;"> |
|||
<el-option |
|||
v-for="item in modelOptions" |
|||
:key="item.id" |
|||
:label="item.name" |
|||
:value="item.id" |
|||
/> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="备注" prop="remarks"> |
|||
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" /> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
<div slot="footer" class="dialog-footer"> |
|||
<el-button v-if="isEdit" type="primary" @click="handleEditDetail">编辑详情</el-button> |
|||
<el-button type="text" @click="closeFormDialog">取消</el-button> |
|||
<el-button :loading="submitLoading" type="primary" @click="handleSubmit">确定</el-button> |
|||
</div> |
|||
</el-dialog> |
|||
<!-- 年报详情弹框 --> |
|||
<el-dialog class="dialog-middle" :modal-append-to-body="false" :close-on-click-modal="false" :before-close="closeDetailDialog" :visible="detailVisible" title="年报详情" width="600px"> |
|||
<span class="dialog-right-top" /> |
|||
<span class="dialog-left-bottom" /> |
|||
<div class="setting-dialog detail-content"> |
|||
<div class="detail-item"><span class="detail-label">统计年度:</span>{{ detailData.year }}</div> |
|||
<div class="detail-item"><span class="detail-label">填报单位:</span>{{ detailData.archivesCount }}</div> |
|||
<div class="detail-item"><span class="detail-label">填报人:</span>{{ detailData.username }}</div> |
|||
<div class="detail-item"><span class="detail-label">填报时间:</span>{{ detailData.createTime | parseTime }}</div> |
|||
<div class="detail-item"><span class="detail-label">备注:</span>{{ detailData.remarks || '-' }}</div> |
|||
<div class="detail-item"><span class="detail-label">统计模板:</span>{{ detailData.modelName }}</div> |
|||
</div> |
|||
<div slot="footer" class="dialog-footer"> |
|||
<el-button type="primary" @click="handleReportDetail">报表详情</el-button> |
|||
<el-button type="primary" @click="closeDetailDialog">确定</el-button> |
|||
</div> |
|||
</el-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { FetchFondsAll } from '@/api/system/fonds' |
|||
import { FetchTotalStatistics, FetchArchivedAllYear } from '@/api/statistics/statistics' |
|||
import { mapGetters } from 'vuex' |
|||
|
|||
export default { |
|||
name: 'AnnualReport', |
|||
data() { |
|||
return { |
|||
allData: [], |
|||
fondsOptions: [], |
|||
fondsIds: [], |
|||
yearsOptions: [], |
|||
years: [], |
|||
loading: false, |
|||
// 新增/编辑共用弹框 |
|||
formVisible: false, |
|||
dialogMode: 'add', // 'add' | 'edit' |
|||
submitLoading: false, |
|||
form: { |
|||
id: null, |
|||
fondsId: null, |
|||
year: String(new Date().getFullYear()), |
|||
modelId: null, |
|||
remarks: null |
|||
}, |
|||
formRules: { |
|||
fondsId: [{ required: true, message: '请选择全宗', trigger: 'change' }], |
|||
year: [{ required: true, message: '请选择年度', trigger: 'change' }], |
|||
modelId: [{ required: true, message: '请选择统计模板', trigger: 'change' }] |
|||
}, |
|||
addLoading: false, |
|||
// 详情弹框 |
|||
detailVisible: false, |
|||
detailData: {}, |
|||
// 统计模板 mock 数据 |
|||
modelOptions: [ |
|||
{ id: 1, name: '《档案室基本情况表》(2025版)' } |
|||
], |
|||
page: { |
|||
page: 1, |
|||
total: 0, |
|||
size: 10 |
|||
} |
|||
} |
|||
}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'baseApi', |
|||
'user' |
|||
]), |
|||
isEdit() { |
|||
return this.dialogMode === 'edit' |
|||
}, |
|||
dialogTitle() { |
|||
return this.isEdit ? '年报编辑' : '年报新增' |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.getFondsDatas() |
|||
this.getArchivedAllYearDatas() |
|||
this.getTotalStatistics() |
|||
}, |
|||
methods: { |
|||
toAdd() { |
|||
this.dialogMode = 'add' |
|||
this.form = { |
|||
id: null, |
|||
fondsId: null, |
|||
year: String(new Date().getFullYear()), |
|||
modelId: null, |
|||
remarks: null |
|||
} |
|||
this.formVisible = true |
|||
}, |
|||
handleEdit(row) { |
|||
this.dialogMode = 'edit' |
|||
const modelItem = this.modelOptions.find(m => m.name === row.modelName) |
|||
const fondsItem = this.fondsOptions.find(f => f.fondsName === row.archivesCount) |
|||
this.form = { |
|||
id: row.id, |
|||
fondsId: fondsItem ? fondsItem.id : null, |
|||
year: row.year, |
|||
modelId: modelItem ? modelItem.id : null, |
|||
remarks: row.remarks |
|||
} |
|||
this.formVisible = true |
|||
}, |
|||
closeFormDialog() { |
|||
this.formVisible = false |
|||
this.$refs.form.resetFields() |
|||
}, |
|||
handleSubmit() { |
|||
this.$refs.form.validate((valid) => { |
|||
if (valid) { |
|||
this.submitLoading = true |
|||
if (this.isEdit) { |
|||
// TODO: 替换为实际编辑接口 |
|||
const index = this.allData.findIndex(item => item.id === this.form.id) |
|||
if (index !== -1) { |
|||
this.allData[index].remarks = this.form.remarks |
|||
} |
|||
this.$message({ message: '编辑成功', type: 'success', offset: 8 }) |
|||
} else { |
|||
// TODO: 替换为实际新增接口 |
|||
const modelName = this.modelOptions.find(item => item.id === this.form.modelId)?.name |
|||
const fondsName = this.fondsOptions.find(item => item.id === this.form.fondsId)?.fondsName |
|||
const newRow = { |
|||
id: Date.now(), |
|||
year: this.form.year, |
|||
archivesCount: fondsName, |
|||
username: this.user?.username || '', |
|||
createTime: new Date().getTime(), |
|||
modelName: modelName, |
|||
remarks: this.form.remarks |
|||
} |
|||
this.allData.unshift(newRow) |
|||
this.$message({ message: '新增成功', type: 'success', offset: 8 }) |
|||
} |
|||
this.submitLoading = false |
|||
this.closeFormDialog() |
|||
} |
|||
}) |
|||
}, |
|||
handleEditDetail() { |
|||
const route = this.$router.resolve({ path: '/da3Report', query: { mode: 'edit' }}) |
|||
window.open(route.href, '_blank') |
|||
}, |
|||
handleSizeChange(val) { |
|||
this.page.size = val |
|||
this.getTotalStatistics() |
|||
}, |
|||
handleCurrentPage(val) { |
|||
this.page.page = val |
|||
this.getTotalStatistics() |
|||
}, |
|||
handleDetail(row) { |
|||
this.detailData = { ...row } |
|||
this.detailVisible = true |
|||
}, |
|||
closeDetailDialog() { |
|||
this.detailVisible = false |
|||
this.detailData = {} |
|||
}, |
|||
handleReportDetail() { |
|||
const route = this.$router.resolve({ path: '/da3Report', query: { mode: 'view' }}) |
|||
window.open(route.href, '_blank') |
|||
}, |
|||
handleDelete() { |
|||
this.$confirm('此操作将删除当前数据' + '<span>你是否还要继续?</span>', '提示', { |
|||
confirmButtonText: '继续', |
|||
cancelButtonText: '取消', |
|||
type: 'warning', |
|||
dangerouslyUseHTMLString: true |
|||
}).then(() => { |
|||
console.log('确认删除') |
|||
}).catch(() => { |
|||
console.log('取消') |
|||
}) |
|||
}, |
|||
resetQuery() { |
|||
this.fondsIds = [] |
|||
this.years = [] |
|||
this.getTotalStatistics() |
|||
}, |
|||
getFondsDatas() { |
|||
FetchFondsAll().then(res => { |
|||
this.fondsOptions = res |
|||
// 默认全选所有档案库 |
|||
// this.fondsIds = res.map(item => item.id) |
|||
// this.checkAndQuery() |
|||
}) |
|||
}, |
|||
getArchivedAllYearDatas() { |
|||
FetchArchivedAllYear().then(res => { |
|||
this.yearsOptions = res.map(item => ({ |
|||
id: item, |
|||
name: item |
|||
})) |
|||
// 默认全选所有年份 |
|||
// this.years = res.map(item => item) |
|||
// this.checkAndQuery() |
|||
}) |
|||
}, |
|||
checkAndQuery() { |
|||
// 当两个数据都加载完成后才执行查询 |
|||
if (this.fondsOptions.length > 0 && this.yearsOptions.length > 0) { |
|||
this.getTotalStatistics() |
|||
} |
|||
}, |
|||
getTotalStatistics() { |
|||
this.loading = true |
|||
FetchTotalStatistics({ |
|||
fondsIds: this.fondsIds, |
|||
years: this.years |
|||
}).then(res => { |
|||
this.allData = res |
|||
this.loading = false |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.app-container { |
|||
height: calc(100vh - 140px); |
|||
.head-search{ |
|||
.el-select, |
|||
.el-button{ |
|||
margin-right: 10px; |
|||
} |
|||
} |
|||
::v-deep .el-table__footer{ |
|||
font-size: 14px; |
|||
} |
|||
::v-deep .el-table__empty-block{ |
|||
border-bottom: 1px solid #e4e7ed; |
|||
} |
|||
::v-deep .summary-row { |
|||
background-color: #f5f7fa !important; |
|||
td{ |
|||
border-top: 1px solid #dfe6ec !important; |
|||
border-bottom: 1px solid #dfe6ec !important; |
|||
} |
|||
} |
|||
.detail-content { |
|||
padding: 10px 20px; |
|||
.detail-item { |
|||
margin-bottom: 16px; |
|||
font-size: 14px; |
|||
line-height: 1.6; |
|||
color: #545B65; |
|||
.detail-label { |
|||
display: inline-block; |
|||
color: #0C0E1E; |
|||
font-weight: 500; |
|||
width: 70px; |
|||
text-align: right; |
|||
} |
|||
} |
|||
} |
|||
::v-deep .el-dialog__footer{ |
|||
padding: 20px 0; |
|||
} |
|||
} |
|||
</style> |
|||
1090
src/views/archivesStatistics/da3-model.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue