阅行客电子档案
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

376 lines
13 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <template>
  2. <div class="app-container row-container">
  3. <div class="connection-header collect-header" style="padding: 0; border-top: none; height: auto; margin-bottom: 20px;">
  4. <div class="head-search" style="margin-bottom: 0;">
  5. <el-select
  6. v-model="fondsIds"
  7. multiple
  8. collapse-tags
  9. placeholder="请选择所属全宗"
  10. style="width: 320px;"
  11. >
  12. <el-option
  13. v-for="item in fondsOptions"
  14. :key="item.id"
  15. :label="item.fondsName"
  16. :value="item.id"
  17. />
  18. </el-select>
  19. <el-select
  20. v-model="years"
  21. multiple
  22. collapse-tags
  23. placeholder="请选择年份"
  24. style="width: 150px;"
  25. >
  26. <el-option
  27. v-for="item in yearsOptions"
  28. :key="item.id"
  29. :label="item.name"
  30. :value="item.id"
  31. />
  32. </el-select>
  33. <el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" @click="getTotalStatistics">查询</el-button>
  34. <el-button class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery">重置</el-button>
  35. </div>
  36. <el-button size="mini" :loading="addLoading" @click="toAdd">
  37. <i class="iconfont icon-xinzeng" />
  38. 新增
  39. </el-button>
  40. </div>
  41. <el-table v-loading="loading" class="archives-table" :data="allData" style="width: 100%;">
  42. <el-table-column prop="year" label="年度" align="center" />
  43. <el-table-column prop="archivesCount" label="填报单位" />
  44. <el-table-column prop="username" label="创建人" align="center" />
  45. <el-table-column prop="createTime" label="创建时间" align="center">
  46. <template slot-scope="scope">
  47. <div>{{ scope.row.createTime | parseTime }}</div>
  48. </template>
  49. </el-table-column>
  50. <el-table-column prop="modelName" label="统计模板" />
  51. <el-table-column prop="handle" label="操作">
  52. <template slot-scope="scope">
  53. <el-button size="mini" @click="handleDetail(scope.row)">查看详情</el-button>
  54. <el-button size="mini" @click="handleEdit(scope.row)">编辑</el-button>
  55. <el-button size="mini" @click="handleDelete(scope.row)">删除</el-button>
  56. <!-- <el-button :loading="btnLoading" class="packing-handle-btn iconfont" @click="handleCartoning(scope.row)"><svg-icon icon-class="zhuanghe" class="svg-arc-style" />装盒</el-button> -->
  57. </template>
  58. </el-table-column>
  59. </el-table>
  60. <el-pagination
  61. v-if="allData.length !== 0"
  62. :current-page="page.page"
  63. :total="page.total"
  64. :page-size="page.size"
  65. :pager-count="5"
  66. layout="total, prev, pager, next, sizes"
  67. @size-change="handleSizeChange"
  68. @current-change="handleCurrentPage"
  69. />
  70. <!-- 年报新增/编辑弹框 -->
  71. <el-dialog class="dialog-middle" :modal-append-to-body="false" :close-on-click-modal="false" :before-close="closeFormDialog" :visible="formVisible" :title="dialogTitle" width="560px">
  72. <span class="dialog-right-top" />
  73. <span class="dialog-left-bottom" />
  74. <div class="setting-dialog">
  75. <el-form ref="form" :model="form" :rules="formRules" label-width="90px">
  76. <el-form-item label="全宗" prop="fondsId">
  77. <el-select v-model="form.fondsId" :disabled="isEdit" placeholder="请选择全宗" style="width: 100%;">
  78. <el-option
  79. v-for="item in fondsOptions"
  80. :key="item.id"
  81. :label="item.fondsName"
  82. :value="item.id"
  83. />
  84. </el-select>
  85. </el-form-item>
  86. <el-form-item label="年度" prop="year">
  87. <el-date-picker v-model="form.year" type="year" value-format="yyyy" :disabled="isEdit" placeholder="请选择年度" style="width: 100%;" />
  88. </el-form-item>
  89. <el-form-item label="统计模板" prop="modelId">
  90. <el-select v-model="form.modelId" :disabled="isEdit" placeholder="请选择统计模板" style="width: 100%;">
  91. <el-option
  92. v-for="item in modelOptions"
  93. :key="item.id"
  94. :label="item.name"
  95. :value="item.id"
  96. />
  97. </el-select>
  98. </el-form-item>
  99. <el-form-item label="备注" prop="remarks">
  100. <el-input v-model="form.remarks" type="textarea" :rows="3" placeholder="请输入备注" />
  101. </el-form-item>
  102. </el-form>
  103. </div>
  104. <div slot="footer" class="dialog-footer">
  105. <el-button v-if="isEdit" type="primary" @click="handleEditDetail">编辑详情</el-button>
  106. <el-button type="text" @click="closeFormDialog">取消</el-button>
  107. <el-button :loading="submitLoading" type="primary" @click="handleSubmit">确定</el-button>
  108. </div>
  109. </el-dialog>
  110. <!-- 年报详情弹框 -->
  111. <el-dialog class="dialog-middle" :modal-append-to-body="false" :close-on-click-modal="false" :before-close="closeDetailDialog" :visible="detailVisible" title="年报详情" width="600px">
  112. <span class="dialog-right-top" />
  113. <span class="dialog-left-bottom" />
  114. <div class="setting-dialog detail-content">
  115. <div class="detail-item"><span class="detail-label">统计年度:</span>{{ detailData.year }}</div>
  116. <div class="detail-item"><span class="detail-label">填报单位:</span>{{ detailData.archivesCount }}</div>
  117. <div class="detail-item"><span class="detail-label">填报人:</span>{{ detailData.username }}</div>
  118. <div class="detail-item"><span class="detail-label">填报时间:</span>{{ detailData.createTime | parseTime }}</div>
  119. <div class="detail-item"><span class="detail-label">备注:</span>{{ detailData.remarks || '-' }}</div>
  120. <div class="detail-item"><span class="detail-label">统计模板:</span>{{ detailData.modelName }}</div>
  121. </div>
  122. <div slot="footer" class="dialog-footer">
  123. <el-button type="primary" @click="handleReportDetail">报表详情</el-button>
  124. <el-button type="primary" @click="closeDetailDialog">确定</el-button>
  125. </div>
  126. </el-dialog>
  127. </div>
  128. </template>
  129. <script>
  130. import { FetchFondsAll } from '@/api/system/fonds'
  131. import { FetchTotalStatistics, FetchArchivedAllYear } from '@/api/statistics/statistics'
  132. import { mapGetters } from 'vuex'
  133. export default {
  134. name: 'AnnualReport',
  135. data() {
  136. return {
  137. allData: [],
  138. fondsOptions: [],
  139. fondsIds: [],
  140. yearsOptions: [],
  141. years: [],
  142. loading: false,
  143. // 新增/编辑共用弹框
  144. formVisible: false,
  145. dialogMode: 'add', // 'add' | 'edit'
  146. submitLoading: false,
  147. form: {
  148. id: null,
  149. fondsId: null,
  150. year: String(new Date().getFullYear()),
  151. modelId: null,
  152. remarks: null
  153. },
  154. formRules: {
  155. fondsId: [{ required: true, message: '请选择全宗', trigger: 'change' }],
  156. year: [{ required: true, message: '请选择年度', trigger: 'change' }],
  157. modelId: [{ required: true, message: '请选择统计模板', trigger: 'change' }]
  158. },
  159. addLoading: false,
  160. // 详情弹框
  161. detailVisible: false,
  162. detailData: {},
  163. // 统计模板 mock 数据
  164. modelOptions: [
  165. { id: 1, name: '《档案室基本情况表》(2025版)' }
  166. ],
  167. page: {
  168. page: 1,
  169. total: 0,
  170. size: 10
  171. }
  172. }
  173. },
  174. computed: {
  175. ...mapGetters([
  176. 'baseApi',
  177. 'user'
  178. ]),
  179. isEdit() {
  180. return this.dialogMode === 'edit'
  181. },
  182. dialogTitle() {
  183. return this.isEdit ? '年报编辑' : '年报新增'
  184. }
  185. },
  186. mounted() {
  187. this.getFondsDatas()
  188. this.getArchivedAllYearDatas()
  189. this.getTotalStatistics()
  190. },
  191. methods: {
  192. toAdd() {
  193. this.dialogMode = 'add'
  194. this.form = {
  195. id: null,
  196. fondsId: null,
  197. year: String(new Date().getFullYear()),
  198. modelId: null,
  199. remarks: null
  200. }
  201. this.formVisible = true
  202. },
  203. handleEdit(row) {
  204. this.dialogMode = 'edit'
  205. const modelItem = this.modelOptions.find(m => m.name === row.modelName)
  206. const fondsItem = this.fondsOptions.find(f => f.fondsName === row.archivesCount)
  207. this.form = {
  208. id: row.id,
  209. fondsId: fondsItem ? fondsItem.id : null,
  210. year: row.year,
  211. modelId: modelItem ? modelItem.id : null,
  212. remarks: row.remarks
  213. }
  214. this.formVisible = true
  215. },
  216. closeFormDialog() {
  217. this.formVisible = false
  218. this.$refs.form.resetFields()
  219. },
  220. handleSubmit() {
  221. this.$refs.form.validate((valid) => {
  222. if (valid) {
  223. this.submitLoading = true
  224. if (this.isEdit) {
  225. // TODO: 替换为实际编辑接口
  226. const index = this.allData.findIndex(item => item.id === this.form.id)
  227. if (index !== -1) {
  228. this.allData[index].remarks = this.form.remarks
  229. }
  230. this.$message({ message: '编辑成功', type: 'success', offset: 8 })
  231. } else {
  232. // TODO: 替换为实际新增接口
  233. const modelName = this.modelOptions.find(item => item.id === this.form.modelId)?.name
  234. const fondsName = this.fondsOptions.find(item => item.id === this.form.fondsId)?.fondsName
  235. const newRow = {
  236. id: Date.now(),
  237. year: this.form.year,
  238. archivesCount: fondsName,
  239. username: this.user?.username || '',
  240. createTime: new Date().getTime(),
  241. modelName: modelName,
  242. remarks: this.form.remarks
  243. }
  244. this.allData.unshift(newRow)
  245. this.$message({ message: '新增成功', type: 'success', offset: 8 })
  246. }
  247. this.submitLoading = false
  248. this.closeFormDialog()
  249. }
  250. })
  251. },
  252. handleEditDetail() {
  253. const route = this.$router.resolve({ path: '/da3Report', query: { mode: 'edit' }})
  254. window.open(route.href, '_blank')
  255. },
  256. handleSizeChange(val) {
  257. this.page.size = val
  258. this.getTotalStatistics()
  259. },
  260. handleCurrentPage(val) {
  261. this.page.page = val
  262. this.getTotalStatistics()
  263. },
  264. handleDetail(row) {
  265. this.detailData = { ...row }
  266. this.detailVisible = true
  267. },
  268. closeDetailDialog() {
  269. this.detailVisible = false
  270. this.detailData = {}
  271. },
  272. handleReportDetail() {
  273. const route = this.$router.resolve({ path: '/da3Report', query: { mode: 'view' }})
  274. window.open(route.href, '_blank')
  275. },
  276. handleDelete() {
  277. this.$confirm('此操作将删除当前数据' + '<span>你是否还要继续?</span>', '提示', {
  278. confirmButtonText: '继续',
  279. cancelButtonText: '取消',
  280. type: 'warning',
  281. dangerouslyUseHTMLString: true
  282. }).then(() => {
  283. console.log('确认删除')
  284. }).catch(() => {
  285. console.log('取消')
  286. })
  287. },
  288. resetQuery() {
  289. this.fondsIds = []
  290. this.years = []
  291. this.getTotalStatistics()
  292. },
  293. getFondsDatas() {
  294. FetchFondsAll().then(res => {
  295. this.fondsOptions = res
  296. // 默认全选所有档案库
  297. // this.fondsIds = res.map(item => item.id)
  298. // this.checkAndQuery()
  299. })
  300. },
  301. getArchivedAllYearDatas() {
  302. FetchArchivedAllYear().then(res => {
  303. this.yearsOptions = res.map(item => ({
  304. id: item,
  305. name: item
  306. }))
  307. // 默认全选所有年份
  308. // this.years = res.map(item => item)
  309. // this.checkAndQuery()
  310. })
  311. },
  312. checkAndQuery() {
  313. // 当两个数据都加载完成后才执行查询
  314. if (this.fondsOptions.length > 0 && this.yearsOptions.length > 0) {
  315. this.getTotalStatistics()
  316. }
  317. },
  318. getTotalStatistics() {
  319. this.loading = true
  320. FetchTotalStatistics({
  321. fondsIds: this.fondsIds,
  322. years: this.years
  323. }).then(res => {
  324. this.allData = res
  325. this.loading = false
  326. })
  327. }
  328. }
  329. }
  330. </script>
  331. <style lang="scss" scoped>
  332. .app-container {
  333. height: calc(100vh - 140px);
  334. .head-search{
  335. .el-select,
  336. .el-button{
  337. margin-right: 10px;
  338. }
  339. }
  340. ::v-deep .el-table__footer{
  341. font-size: 14px;
  342. }
  343. ::v-deep .el-table__empty-block{
  344. border-bottom: 1px solid #e4e7ed;
  345. }
  346. ::v-deep .summary-row {
  347. background-color: #f5f7fa !important;
  348. td{
  349. border-top: 1px solid #dfe6ec !important;
  350. border-bottom: 1px solid #dfe6ec !important;
  351. }
  352. }
  353. .detail-content {
  354. padding: 10px 20px;
  355. .detail-item {
  356. margin-bottom: 16px;
  357. font-size: 14px;
  358. line-height: 1.6;
  359. color: #545B65;
  360. .detail-label {
  361. display: inline-block;
  362. color: #0C0E1E;
  363. font-weight: 500;
  364. width: 70px;
  365. text-align: right;
  366. }
  367. }
  368. }
  369. ::v-deep .el-dialog__footer{
  370. padding: 20px 0;
  371. }
  372. }
  373. </style>