Browse Source

年报管理1008

master
xuhuajiao 3 weeks ago
parent
commit
4febb13938
  1. 50
      src/api/statistics/statistics.js
  2. 78
      src/assets/iconfonts/light/iconfont.css
  3. 2
      src/assets/iconfonts/light/iconfont.js
  4. 126
      src/assets/iconfonts/light/iconfont.json
  5. BIN
      src/assets/iconfonts/light/iconfont.ttf
  6. BIN
      src/assets/iconfonts/light/iconfont.woff
  7. BIN
      src/assets/iconfonts/light/iconfont.woff2
  8. 86
      src/views/archivesStatistics/Da3Report.vue
  9. 288
      src/views/archivesStatistics/annualReport‌/index.vue

50
src/api/statistics/statistics.js

@ -76,11 +76,59 @@ export function SaveStatisticsTemplate(data) {
}) })
} }
// 分页查询年度报表
export function FetchPageReports(params) {
return request({
url: 'api/archives-report/pageReports' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 编辑年度报表
export function FetchSaveArchivesReport(data) {
return request({
url: 'api/archives-report/saveArchivesReport',
method: 'post',
data
})
}
// 查询年度报表详情
export function FetchFindArchivesReportById(params) {
return request({
url: 'api/archives-report/findArchivesReportById',
method: 'post',
params
})
}
// 年度统计模板
export function FetchAnnualStatisticalTemplateAll(params) {
return request({
url: 'api/archives-report/getAnnualStatisticalTemplateAll' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 删除年度报表
export function FetchDeleteArchivesReport(data) {
return request({
url: 'api/archives-report/deleteArchivesReport',
method: 'post',
data
})
}
export default { export default {
FetchTotalStatistics, FetchTotalStatistics,
FetchArchivedAllYear, FetchArchivedAllYear,
FetchRoomCollectionStatistics, FetchRoomCollectionStatistics,
FetchBorrowdStatistics, FetchBorrowdStatistics,
FetchBorrowdCountStatisticsList, FetchBorrowdCountStatisticsList,
FetchBorrowdRegisterStatisticsList
FetchBorrowdRegisterStatisticsList,
FetchPageReports,
FetchSaveArchivesReport,
FetchFindArchivesReportById,
FetchAnnualStatisticalTemplateAll,
FetchDeleteArchivesReport
} }

78
src/assets/iconfonts/light/iconfont.css

@ -1,8 +1,8 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 3966148 */ font-family: "iconfont"; /* Project id 3966148 */
src: url('iconfont.woff2?t=1763358168922') format('woff2'),
url('iconfont.woff?t=1763358168922') format('woff'),
url('iconfont.ttf?t=1763358168922') format('truetype');
src: url('iconfont.woff2?t=1791438838309') format('woff2'),
url('iconfont.woff?t=1791438838309') format('woff'),
url('iconfont.ttf?t=1791438838309') format('truetype');
} }
.iconfont { .iconfont {
@ -13,6 +13,78 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-shanchu-:before {
content: "\e6aa";
}
.icon-huifu1:before {
content: "\e6ab";
}
.icon-tjg:before {
content: "\e6ac";
}
.icon-gb:before {
content: "\e6ad";
}
.icon-Group:before {
content: "\e6ae";
}
.icon-xiajia:before {
content: "\e7aa";
}
.icon-cangku:before {
content: "\e927";
}
.icon-baojingjilu:before {
content: "\e6a8";
}
.icon-yitiji:before {
content: "\e6a2";
}
.icon-kufangguanli:before {
content: "\e6a3";
}
.icon-renlianshibiejiqi:before {
content: "\e759";
}
.icon-wangluoshexiangtou:before {
content: "\e754";
}
.icon-Dkufang:before {
content: "\e6a4";
}
.icon-rfidduxieqi:before {
content: "\e879";
}
.icon-shouchipandianyi:before {
content: "\e6a5";
}
.icon-zhinengyitiji:before {
content: "\e6a6";
}
.icon-a-3D-xidingtanceqi:before {
content: "\e6b7";
}
.icon-saomiao:before {
content: "\e6a7";
}
.icon-mimachakan:before { .icon-mimachakan:before {
content: "\e6a1"; content: "\e6a1";
} }

2
src/assets/iconfonts/light/iconfont.js
File diff suppressed because it is too large
View File

126
src/assets/iconfonts/light/iconfont.json

@ -5,6 +5,132 @@
"css_prefix_text": "icon-", "css_prefix_text": "icon-",
"description": "", "description": "",
"glyphs": [ "glyphs": [
{
"icon_id": "1817720",
"name": "删除-3",
"font_class": "shanchu-",
"unicode": "e6aa",
"unicode_decimal": 59050
},
{
"icon_id": "1817721",
"name": "恢复",
"font_class": "huifu1",
"unicode": "e6ab",
"unicode_decimal": 59051
},
{
"icon_id": "1817730",
"name": "tjg",
"font_class": "tjg",
"unicode": "e6ac",
"unicode_decimal": 59052
},
{
"icon_id": "1817776",
"name": "gb",
"font_class": "gb",
"unicode": "e6ad",
"unicode_decimal": 59053
},
{
"icon_id": "1817794",
"name": "Group 2",
"font_class": "Group",
"unicode": "e6ae",
"unicode_decimal": 59054
},
{
"icon_id": "10599880",
"name": "icon-xiajiashenhe",
"font_class": "xiajia",
"unicode": "e7aa",
"unicode_decimal": 59306
},
{
"icon_id": "44433330",
"name": "仓库",
"font_class": "cangku",
"unicode": "e927",
"unicode_decimal": 59687
},
{
"icon_id": "30256923",
"name": "报警记录",
"font_class": "baojingjilu",
"unicode": "e6a8",
"unicode_decimal": 59048
},
{
"icon_id": "79099",
"name": "一体机",
"font_class": "yitiji",
"unicode": "e6a2",
"unicode_decimal": 59042
},
{
"icon_id": "6296998",
"name": "库房管理",
"font_class": "kufangguanli",
"unicode": "e6a3",
"unicode_decimal": 59043
},
{
"icon_id": "8434614",
"name": "人脸识别机器",
"font_class": "renlianshibiejiqi",
"unicode": "e759",
"unicode_decimal": 59225
},
{
"icon_id": "9437011",
"name": "网络摄像头",
"font_class": "wangluoshexiangtou",
"unicode": "e754",
"unicode_decimal": 59220
},
{
"icon_id": "11661938",
"name": "3D库房",
"font_class": "Dkufang",
"unicode": "e6a4",
"unicode_decimal": 59044
},
{
"icon_id": "19373677",
"name": "rfid读写器",
"font_class": "rfidduxieqi",
"unicode": "e879",
"unicode_decimal": 59513
},
{
"icon_id": "31422233",
"name": "手持盘点仪",
"font_class": "shouchipandianyi",
"unicode": "e6a5",
"unicode_decimal": 59045
},
{
"icon_id": "36973886",
"name": "智能一体机",
"font_class": "zhinengyitiji",
"unicode": "e6a6",
"unicode_decimal": 59046
},
{
"icon_id": "40950858",
"name": "3D-吸顶探测器",
"font_class": "a-3D-xidingtanceqi",
"unicode": "e6b7",
"unicode_decimal": 59063
},
{
"icon_id": "43488473",
"name": "吸顶式盘点设备",
"font_class": "saomiao",
"unicode": "e6a7",
"unicode_decimal": 59047
},
{ {
"icon_id": "26584955", "icon_id": "26584955",
"name": "密码查看", "name": "密码查看",

BIN
src/assets/iconfonts/light/iconfont.ttf

BIN
src/assets/iconfonts/light/iconfont.woff

BIN
src/assets/iconfonts/light/iconfont.woff2

86
src/views/archivesStatistics/Da3Report.vue

@ -1,5 +1,4 @@
<script> <script>
// import embeddedModel from './da3-model.js'
import { FetchInitStatisticsTemplate, SaveStatisticsTemplate } from '@/api/statistics/statistics' import { FetchInitStatisticsTemplate, SaveStatisticsTemplate } from '@/api/statistics/statistics'
export default { export default {
@ -12,7 +11,8 @@ export default {
// 接口返回的原始数据(保存时按同结构回传) // 接口返回的原始数据(保存时按同结构回传)
rawReport: null, rawReport: null,
loading: false, loading: false,
saving: false
saving: false,
refetchLoading: false
} }
}, },
computed: { computed: {
@ -24,12 +24,15 @@ export default {
return this.$route.query.mode !== 'edit' return this.$route.query.mode !== 'edit'
}, },
leftUnits() { leftUnits() {
if (!this.data) return []
return this.data.units.filter(u => u.card === 1) // 01-05 return this.data.units.filter(u => u.card === 1) // 01-05
}, },
rightUnits() { rightUnits() {
if (!this.data) return []
return this.data.units.filter(u => u.card === 2) // 06-07 return this.data.units.filter(u => u.card === 2) // 06-07
}, },
metaTop() { metaTop() {
if (!this.data) return []
return [ return [
{ label: '表号', value: this.data.template.form_no }, { label: '表号', value: this.data.template.form_no },
{ label: '制定机关', value: this.data.template.issuing_org }, { label: '制定机关', value: this.data.template.issuing_org },
@ -42,6 +45,7 @@ export default {
watch: { watch: {
data: { data: {
handler(d) { handler(d) {
if (!d) return
this.initForm(d) this.initForm(d)
// 接口模型自带填报值时回显 // 接口模型自带填报值时回显
if (d.formData) this.fillFormData(d.formData) if (d.formData) this.fillFormData(d.formData)
@ -53,13 +57,26 @@ export default {
this.fetchReport() this.fetchReport()
}, },
methods: { methods: {
// 按路由参数拉取年报详情;无参数(独立预览)时使用 mock 数据
fetchReport() { fetchReport() {
const { reportingYear, unitId, templateId } = this.$route.query const { reportingYear, unitId, templateId } = this.$route.query
// if (!reportingYear || !unitId) {
// this.fillDemo()
// return
// }
// 尝试读缓存(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 this.loading = true
FetchInitStatisticsTemplate({ FetchInitStatisticsTemplate({
reportingYear, reportingYear,
@ -83,6 +100,7 @@ export default {
}).finally(() => { }).finally(() => {
this.loading = false this.loading = false
this.refetchLoading = false
}) })
}, },
// 将接口返回结构归一化为组件内置模型结构:{ template, units, body, footer, formData } // 将接口返回结构归一化为组件内置模型结构:{ template, units, body, footer, formData }
@ -115,8 +133,15 @@ export default {
const body = [] const body = []
const formData = { units: {}, data: {}} const formData = { units: {}, data: {}}
const leftCards = ['01', '02', '03', '04', '05'] const leftCards = ['01', '02', '03', '04', '05']
// 填报值统一以文本字段(valCurText/valPrevText)为准,text 为空时再回退取数值字段
const pickVal = (text, num) => (text != null && text !== '' ? text : (num != null ? num : ''))
// 填报值:inputType 为 'code'/'number' 时用 valCurNum,'text' 时用 valCurText
const pickVal = (r, which) => {
const t = r.inputType
if (t === 'code' || t === 'number') {
return which === 'cur' ? (r.valCurNum != null ? r.valCurNum : '') : (r.valPrevNum != null ? r.valPrevNum : '')
}
// text 或其他类型用 valCurText / valPrevText
return which === 'cur' ? (r.valCurText != null ? r.valCurText : '') : (r.valPrevText != null ? r.valPrevText : '')
}
flat.forEach(r => { flat.forEach(r => {
// 章节(section)或顶级叶子指标(如 82/95/96/97/109)需把中文序号拼到名称前:一、人员情况 / 五、检索工具 // 章节(section)或顶级叶子指标(如 82/95/96/97/109)需把中文序号拼到名称前:一、人员情况 / 五、检索工具
@ -157,9 +182,9 @@ export default {
} }
if (type === 'indicator' || type === 'continuation') { if (type === 'indicator' || type === 'continuation') {
item.input = r.inputType === 'yesno' ? 'yesno' : 'number'
const cur = pickVal(r.valCurText, r.valCurNum)
const prev = pickVal(r.valPrevText, r.valPrevNum)
item.input = r.inputType === 'yesno' ? 'yesno' : (r.inputType || 'number')
const cur = pickVal(r, 'cur')
const prev = pickVal(r, 'prev')
formData.data[r.code] = { cur, prev } formData.data[r.code] = { cur, prev }
} }
body.push(item) body.push(item)
@ -190,6 +215,7 @@ export default {
}, },
// 回填填报值:{ u_01: 'xx', '08_c': '12' } 或 { units: {01:'xx'}, data: {08:{cur:'12'}} } // 回填填报值:{ u_01: 'xx', '08_c': '12' } 或 { units: {01:'xx'}, data: {08:{cur:'12'}} }
fillFormData(formData) { fillFormData(formData) {
console.log('fillFormData', formData)
if (!formData) return if (!formData) return
if (formData.units) { if (formData.units) {
Object.keys(formData.units).forEach(code => { Object.keys(formData.units).forEach(code => {
@ -210,6 +236,10 @@ export default {
}) })
}, },
initForm(d) { initForm(d) {
if (!d || !Array.isArray(d.units) || !Array.isArray(d.body)) {
this.form = {}
return
}
const form = {} const form = {}
d.units.forEach(u => { form['u_' + u.code] = '' }) d.units.forEach(u => { form['u_' + u.code] = '' })
d.body.forEach(it => { d.body.forEach(it => {
@ -273,14 +303,21 @@ export default {
payload[unitFieldMap[code]] = v === '' || v == null ? null : v payload[unitFieldMap[code]] = v === '' || v == null ? null : v
}) })
// 指标行回填 valCurText / valPrevText(递归 children 树形结构)
// 指标行回填:inputType 为 'code'/'number' 写 valCurNum/valPrevNum,'text' 写 valCurText/valPrevText
const walk = list => { const walk = list => {
(list || []).forEach(r => { (list || []).forEach(r => {
if (r.itemType === 'indicator' && r.isLeaf && r.code) { if (r.itemType === 'indicator' && r.isLeaf && r.code) {
const cur = this.form[r.code + '_c'] const cur = this.form[r.code + '_c']
const prev = this.form[r.code + '_p'] const prev = this.form[r.code + '_p']
r.valCurText = cur === '' || cur == null ? null : String(cur)
r.valPrevText = prev === '' || prev == null ? null : String(prev)
const curVal = cur === '' || cur == null ? null : cur
const prevVal = prev === '' || prev == null ? null : prev
if (r.inputType === 'code' || r.inputType === 'number') {
r.valCurNum = curVal != null ? Number(curVal) : null
r.valPrevNum = prevVal != null ? Number(prevVal) : null
} else {
r.valCurText = curVal != null ? String(curVal) : null
r.valPrevText = prevVal != null ? String(prevVal) : null
}
} }
if (r.children && r.children.length) walk(r.children) if (r.children && r.children.length) walk(r.children)
}) })
@ -293,6 +330,15 @@ export default {
}).finally(() => { }).finally(() => {
this.saving = false this.saving = false
}) })
},
// 重新获取统计数据:点击后调用 fetchReport 重新获取接口数据
handleRefetch() {
this.refetchLoading = true
this.fetchReport()
},
// 取消:点击后关闭当前路由
handleCancel() {
window.close()
} }
} }
} }
@ -307,7 +353,7 @@ export default {
<span class="hint">数据驱动渲染 · 来自 template_item 等表</span> <span class="hint">数据驱动渲染 · 来自 template_item 等表</span>
</div> --> </div> -->
<table class="form">
<table v-if="data" class="form">
<!-- 附件2 + 题名 --> <!-- 附件2 + 题名 -->
<tr><td class="attach" colspan="9">{{ data.template.attach }}</td></tr> <tr><td class="attach" colspan="9">{{ data.template.attach }}</td></tr>
<tr><td class="title" colspan="9">{{ data.template.title }}</td></tr> <tr><td class="title" colspan="9">{{ data.template.title }}</td></tr>
@ -396,6 +442,7 @@ export default {
<select v-else-if="it.input === 'yesno'" v-model="form[it.code + '_c']"> <select v-else-if="it.input === 'yesno'" v-model="form[it.code + '_c']">
<option value="" /><option value="是">是</option><option value="否">否</option> <option value="" /><option value="是">是</option><option value="否">否</option>
</select> </select>
<input v-else-if="it.input === 'text'" v-model="form[it.code + '_c']" type="text">
<input v-else v-model="form[it.code + '_c']" type="text" inputmode="decimal"> <input v-else v-model="form[it.code + '_c']" type="text" inputmode="decimal">
</td> </td>
<td class="data"> <td class="data">
@ -403,6 +450,7 @@ export default {
<select v-else-if="it.input === 'yesno'" v-model="form[it.code + '_p']"> <select v-else-if="it.input === 'yesno'" v-model="form[it.code + '_p']">
<option value="" /><option value="是">是</option><option value="否">否</option> <option value="" /><option value="是">是</option><option value="否">否</option>
</select> </select>
<input v-else-if="it.input === 'text'" v-model="form[it.code + '_p']" type="text">
<input v-else v-model="form[it.code + '_p']" type="text" inputmode="decimal"> <input v-else v-model="form[it.code + '_p']" type="text" inputmode="decimal">
</td> </td>
</tr> </tr>
@ -416,7 +464,9 @@ export default {
<!-- 编辑模式:底部固定保存栏 --> <!-- 编辑模式:底部固定保存栏 -->
<div v-if="!isView" class="save-bar"> <div v-if="!isView" class="save-bar">
<el-button type="primary" :loading="saving" @click="handleSave">保存</el-button>
<el-button class="saveetch-btn" type="primary" :loading="refetchLoading" @click="handleRefetch">重新获取统计数据</el-button>
<el-button @click="handleCancel">取消</el-button>
<el-button class="save-btn" type="primary" :loading="saving" @click="handleSave">保存</el-button>
</div> </div>
</div> </div>
</template> </template>
@ -432,7 +482,7 @@ export default {
border-top: 1px solid #e4e7ed; border-top: 1px solid #e4e7ed;
box-shadow: 0 -2px 8px rgba(0, 0, 0, .06); box-shadow: 0 -2px 8px rgba(0, 0, 0, .06);
} }
.save-bar .el-button { min-width: 88px; color: #fff; background-color: #0348f3; border-color: #0348f3; }
.save-bar .el-button.save-btn,.save-bar .el-button.saveetch-btn { min-width: 88px; color: #fff; background-color: #0348f3; border-color: #0348f3; }
.toolbar { max-width: 1040px; margin: 0 auto 12px; font-size: 13px; color: #444; } .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 button { font-family: inherit; padding: 4px 10px; margin-right: 8px; cursor: pointer; }
.toolbar .hint { color: #888; } .toolbar .hint { color: #888; }

288
src/views/archivesStatistics/annualReport‌/index.vue

@ -8,6 +8,7 @@
collapse-tags collapse-tags
placeholder="请选择所属全宗" placeholder="请选择所属全宗"
style="width: 320px;" style="width: 320px;"
@change="getPageReports"
> >
<el-option <el-option
v-for="item in fondsOptions" v-for="item in fondsOptions"
@ -22,6 +23,7 @@
collapse-tags collapse-tags
placeholder="请选择年份" placeholder="请选择年份"
style="width: 150px;" style="width: 150px;"
@change="getPageReports"
> >
<el-option <el-option
v-for="item in yearsOptions" v-for="item in yearsOptions"
@ -30,7 +32,7 @@
:value="item.id" :value="item.id"
/> />
</el-select> </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-search" size="mini" type="success" icon="el-icon-search" @click="getPageReports">查询</el-button>
<el-button class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery">重置</el-button> <el-button class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery">重置</el-button>
</div> </div>
<el-button size="mini" :loading="addLoading" @click="toAdd"> <el-button size="mini" :loading="addLoading" @click="toAdd">
@ -39,21 +41,28 @@
</el-button> </el-button>
</div> </div>
<el-table v-loading="loading" class="archives-table" :data="allData" style="width: 100%;"> <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">
<el-table-column prop="reportingYear" label="年度" align="center" width="100" />
<el-table-column prop="fondsName" label="填报单位" />
<el-table-column prop="createBy" label="创建人" />
<el-table-column prop="createdAt" label="创建时间">
<template slot-scope="scope"> <template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
<div>{{ scope.row.createdAt | parseTime }}</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="modelName" label="统计模板" />
<el-table-column prop="handle" label="操作">
<el-table-column prop="templateName" label="统计模板" />
<el-table-column prop="handle" label="操作" width="200">
<template slot-scope="scope"> <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> -->
<el-tooltip class="item" effect="dark" content="查看详情" placement="top">
<el-button class="hanle-btn" size="mini" :loading="getRowLoading(scope.row, 'detail')" @click="handleDetail(scope.row)">
<i class="iconfont icon-sulan" />
</el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="编辑" placement="top">
<el-button class="hanle-btn" size="mini" :loading="getRowLoading(scope.row, 'edit')" @click="handleEdit(scope.row)"><i class="iconfont icon-Group" /></el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="删除" placement="top">
<el-button class="hanle-btn" size="mini" :loading="getRowLoading(scope.row, 'delete')" @click="handleDelete(scope.row)"><i class="iconfont icon-shanchu-" /></el-button>
</el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -73,9 +82,9 @@
<span class="dialog-left-bottom" /> <span class="dialog-left-bottom" />
<div class="setting-dialog"> <div class="setting-dialog">
<el-form ref="form" :model="form" :rules="formRules" label-width="90px"> <el-form ref="form" :model="form" :rules="formRules" label-width="90px">
<el-form-item label="全宗" prop="fondsId">
<el-form-item label="全宗" prop="unitId">
<!-- :disabled="isEdit" --> <!-- :disabled="isEdit" -->
<el-select v-model="form.fondsId" placeholder="请选择全宗" style="width: 100%;">
<el-select v-model="form.unitId" :disabled="isEdit" placeholder="请选择全宗" style="width: 100%;">
<el-option <el-option
v-for="item in fondsOptions" v-for="item in fondsOptions"
:key="item.id" :key="item.id"
@ -84,22 +93,22 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="年度" prop="year">
<!-- :disabled="isEdit" -->
<el-date-picker v-model="form.year" type="year" value-format="yyyy" placeholder="请选择年度" style="width: 100%;" />
<el-form-item label="年度" prop="reportingYear">
<!-- -->
<el-date-picker v-model="form.reportingYear" :disabled="isEdit" type="year" value-format="yyyy" placeholder="请选择年度" style="width: 100%;" />
</el-form-item> </el-form-item>
<el-form-item label="统计模板" prop="modelId">
<el-select v-model="form.modelId" :disabled="isEdit" placeholder="请选择统计模板" style="width: 100%;">
<el-form-item label="统计模板" prop="templateId">
<el-select v-model="form.templateId" :disabled="isEdit" placeholder="请选择统计模板" style="width: 100%;">
<el-option <el-option
v-for="item in modelOptions" v-for="item in modelOptions"
:key="item.id"
:label="item.name"
:value="item.id"
:key="item.templateId"
:label="item.formTitle"
:value="item.templateId"
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remarks">
<el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" />
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -114,12 +123,12 @@
<span class="dialog-right-top" /> <span class="dialog-right-top" />
<span class="dialog-left-bottom" /> <span class="dialog-left-bottom" />
<div class="setting-dialog detail-content"> <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 class="detail-item"><span class="detail-label">统计年度:</span>{{ detailData.reportingYear }}</div>
<div class="detail-item"><span class="detail-label">填报单位:</span>{{ detailData.fondsName }}</div>
<div class="detail-item"><span class="detail-label">填报人:</span>{{ detailData.createBy }}</div>
<div class="detail-item"><span class="detail-label">填报时间:</span>{{ detailData.createdAt | parseTime }}</div>
<div class="detail-item"><span class="detail-label">备注:</span>{{ detailData.remark || '-' }}</div>
<div class="detail-item"><span class="detail-label">统计模板:</span>{{ detailData.templateName }}</div>
</div> </div>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" :loading="reportDetailLoading" @click="handleReportDetail">报表详情</el-button> <el-button type="primary" :loading="reportDetailLoading" @click="handleReportDetail">报表详情</el-button>
@ -131,7 +140,7 @@
<script> <script>
import { FetchFondsAll } from '@/api/system/fonds' import { FetchFondsAll } from '@/api/system/fonds'
import { FetchTotalStatistics, FetchArchivedAllYear, FetchInitStatisticsTemplate } from '@/api/statistics/statistics'
import { FetchPageReports, FetchArchivedAllYear, FetchInitStatisticsTemplate, FetchSaveArchivesReport, FetchFindArchivesReportById, FetchAnnualStatisticalTemplateAll, FetchDeleteArchivesReport } from '@/api/statistics/statistics'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
export default { export default {
@ -150,17 +159,19 @@ export default {
submitLoading: false, submitLoading: false,
form: { form: {
id: null, id: null,
fondsId: null,
year: String(new Date().getFullYear()),
modelId: null,
remarks: null
unitId: null,
reportingYear: String(new Date().getFullYear()),
templateId: null,
remark: null
}, },
formRules: { formRules: {
fondsId: [{ required: true, message: '请选择全宗', trigger: 'change' }],
year: [{ required: true, message: '请选择年度', trigger: 'change' }],
modelId: [{ required: true, message: '请选择统计模板', trigger: 'change' }]
unitId: [{ required: true, message: '请选择全宗', trigger: 'change' }],
reportingYear: [{ required: true, message: '请选择年度', trigger: 'change' }],
templateId: [{ required: true, message: '请选择统计模板', trigger: 'change' }]
}, },
addLoading: false, addLoading: false,
// 行级按钮 loading:{ [reportId]: { detail, edit, delete } }
rowLoading: {},
// 详情弹框 // 详情弹框
detailVisible: false, detailVisible: false,
detailData: {}, detailData: {},
@ -191,89 +202,145 @@ export default {
} }
}, },
mounted() { mounted() {
this.getAnnualStatisticalTemplateAll()
this.getFondsDatas() this.getFondsDatas()
this.getArchivedAllYearDatas() this.getArchivedAllYearDatas()
this.getTotalStatistics()
this.getPageReports()
}, },
methods: { methods: {
// 读取行级按钮 loading
getRowLoading(row, action) {
const r = this.rowLoading[row.reportId]
return r ? !!r[action] : false
},
// 设置行级按钮 loading
setRowLoading(row, action, val) {
const id = row.reportId
if (!this.rowLoading[id]) {
this.$set(this.rowLoading, id, { detail: false, edit: false, delete: false })
}
this.$set(this.rowLoading[id], action, val)
},
// 分页查询年报数据
async getPageReports() {
this.loading = true
try {
const res = await FetchPageReports({
page: this.page.page - 1,
size: this.page.size,
reportingYearList: this.years, // 查询年份
unitIdList: this.fondsIds // 全宗id
})
if (res.code !== 500) {
this.allData = res.records
this.page.total = res.total
} else {
this.$message.error(res.message)
}
} catch (error) {
this.$message.error(error.message)
} finally {
this.loading = false
}
},
// 年度统计模板
async getAnnualStatisticalTemplateAll() {
try {
const res = await FetchAnnualStatisticalTemplateAll()
if (res.code !== 500) {
this.modelOptions = res
} else {
this.$message.error(res.message)
}
} catch (error) {
this.$message.error(error.message)
}
},
toAdd() { toAdd() {
this.dialogMode = 'add' this.dialogMode = 'add'
this.form = { this.form = {
id: null,
fondsId: null,
year: String(new Date().getFullYear()),
modelId: null,
remarks: null
reportId: null,
unitId: null,
reportingYear: String(new Date().getFullYear()),
templateId: null,
remark: null
} }
this.formVisible = true this.formVisible = true
}, },
handleEdit(row) {
async handleEdit(row) {
this.dialogMode = 'edit' 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
// const modelItem = this.modelOptions.find(m => m.id === row.templateId)
// const fondsItem = this.fondsOptions.find(f => f.id === row.unitId)
// 查询年度报表详情
this.setRowLoading(row, 'edit', true)
try {
const params = {
id: row.reportId
}
const res = await FetchFindArchivesReportById(params)
if (res.code !== 500) {
this.form = { ...res }
this.form.reportingYear = String(res.reportingYear)
this.formVisible = true
} else {
this.$message.error(res.message)
}
} catch (error) {
this.$message.error(error.message)
} finally {
this.setRowLoading(row, 'edit', false)
} }
this.formVisible = true
}, },
closeFormDialog() { closeFormDialog() {
this.formVisible = false this.formVisible = false
this.$refs.form.resetFields() this.$refs.form.resetFields()
}, },
handleSubmit() { handleSubmit() {
this.$refs.form.validate((valid) => {
this.$refs.form.validate(async(valid) => {
if (valid) { if (valid) {
this.submitLoading = true 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
try {
const res = await FetchSaveArchivesReport(this.form)
if (res.code !== 500) {
this.$message({ message: this.isEdit ? '编辑成功' : '新增成功', type: 'success', offset: 8 })
this.closeFormDialog()
this.getPageReports()
} else {
this.$message.error(res.message)
} }
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 })
} catch (error) {
this.$message.error(error.message)
} finally {
this.submitLoading = false
} }
this.submitLoading = false
this.closeFormDialog()
} }
}) })
}, },
handleEditDetail() { handleEditDetail() {
this.checkAndOpenReport('edit', { this.checkAndOpenReport('edit', {
reportingYear: this.form.year,
unitId: this.form.fondsId,
templateId: Number(this.form.modelId) || 1
reportingYear: this.form.reportingYear,
unitId: this.form.unitId,
templateId: Number(this.form.templateId) || 1
}, 'editDetailLoading') }, 'editDetailLoading')
}, },
handleSizeChange(val) { handleSizeChange(val) {
this.page.size = val this.page.size = val
this.getTotalStatistics()
this.getPageReports()
}, },
handleCurrentPage(val) { handleCurrentPage(val) {
this.page.page = val this.page.page = val
this.getTotalStatistics()
this.getPageReports()
}, },
handleDetail(row) { handleDetail(row) {
this.detailData = { ...row }
this.detailVisible = true
this.setRowLoading(row, 'detail', true)
try {
this.detailData = { ...row }
this.detailVisible = true
} finally {
this.setRowLoading(row, 'detail', false)
}
}, },
closeDetailDialog() { closeDetailDialog() {
this.detailVisible = false this.detailVisible = false
@ -281,12 +348,12 @@ export default {
}, },
handleReportDetail() { handleReportDetail() {
// 行数据无全宗 id 时,按填报单位名称匹配 // 行数据无全宗 id 时,按填报单位名称匹配
const fondsItem = this.fondsOptions.find(f => f.fondsName === this.detailData.archivesCount)
const unitId = this.detailData.unitId || this.detailData.fondsId || (fondsItem && fondsItem.id)
// const fondsItem = this.fondsOptions.find(f => f.fondsName === this.detailData.archivesCount)
const unitId = this.detailData.unitId
this.checkAndOpenReport('view', { this.checkAndOpenReport('view', {
reportingYear: this.detailData.year,
reportingYear: this.detailData.reportingYear,
unitId, unitId,
templateId: 1
templateId: Number(this.detailData.templateId) || 1
}, 'reportDetailLoading') }, 'reportDetailLoading')
}, },
// 跳转报表前先调初始化接口预检:有数据才打开新页,否则提示且不跳转 // 跳转报表前先调初始化接口预检:有数据才打开新页,否则提示且不跳转
@ -299,8 +366,13 @@ export default {
const win = window.open('', '_blank') const win = window.open('', '_blank')
this[loadingKey] = true this[loadingKey] = true
FetchInitStatisticsTemplate(params).then(res => { FetchInitStatisticsTemplate(params).then(res => {
console.log('FetchInitStatisticsTemplate', res)
// 接口正常且模板行有数据才放行 // 接口正常且模板行有数据才放行
if (res && Array.isArray(res.rows) && res.rows.length) { if (res && Array.isArray(res.rows) && res.rows.length) {
// 预检结果缓存到 sessionStorage,Da3Report 直接读取避免重复调接口
try {
sessionStorage.setItem('da3_report_cache_' + params.reportingYear + '_' + params.unitId, JSON.stringify(res))
} catch (e) { /* 存储满则忽略 */ }
const route = this.$router.resolve({ const route = this.$router.resolve({
path: '/da3Report', path: '/da3Report',
query: { mode, ...params } query: { mode, ...params }
@ -318,14 +390,24 @@ export default {
this[loadingKey] = false this[loadingKey] = false
}) })
}, },
handleDelete() {
handleDelete(row) {
this.$confirm('此操作将删除当前数据' + '<span>你是否还要继续?</span>', '提示', { this.$confirm('此操作将删除当前数据' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续', confirmButtonText: '继续',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
dangerouslyUseHTMLString: true dangerouslyUseHTMLString: true
}).then(() => { }).then(() => {
console.log('确认删除')
this.setRowLoading(row, 'delete', true)
FetchDeleteArchivesReport(row.reportId).then(res => {
if (res.code !== 500) {
this.$message({ message: '删除成功', type: 'success', offset: 8 })
this.getPageReports()
} else {
this.$message.error(res.message)
}
}).catch(() => {}).finally(() => {
this.setRowLoading(row, 'delete', false)
})
}).catch(() => { }).catch(() => {
console.log('取消') console.log('取消')
}) })
@ -333,7 +415,7 @@ export default {
resetQuery() { resetQuery() {
this.fondsIds = [] this.fondsIds = []
this.years = [] this.years = []
this.getTotalStatistics()
this.getPageReports()
}, },
getFondsDatas() { getFondsDatas() {
FetchFondsAll().then(res => { FetchFondsAll().then(res => {
@ -357,18 +439,8 @@ export default {
checkAndQuery() { checkAndQuery() {
// 当两个数据都加载完成后才执行查询 // 当两个数据都加载完成后才执行查询
if (this.fondsOptions.length > 0 && this.yearsOptions.length > 0) { if (this.fondsOptions.length > 0 && this.yearsOptions.length > 0) {
this.getTotalStatistics()
this.getPageReports()
} }
},
getTotalStatistics() {
this.loading = true
FetchTotalStatistics({
fondsIds: this.fondsIds,
years: this.years
}).then(res => {
this.allData = res
this.loading = false
})
} }
} }
} }
@ -416,4 +488,14 @@ export default {
padding: 20px 0; padding: 20px 0;
} }
} }
::v-deep .hanle-btn{
padding: 7px;
.icon-sulan{
font-size: 18px;
}
.iconfont::before{
margin-right: 0 !important;
}
}
</style> </style>
Loading…
Cancel
Save