index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. <template>
  2. <div class="task-query-statistics">
  3. <!-- 页面标题 -->
  4. <!-- <h2>成本监审任务查询统计</h2> -->
  5. <div v-if="activeView == 'list'">
  6. <!-- 查询区域 -->
  7. <div class="search-container">
  8. <el-form :inline="true" :model="searchForm" class="demo-form-inline">
  9. <el-form-item label="年度:">
  10. <el-date-picker
  11. v-model="searchForm.year"
  12. type="year"
  13. placeholder="请选择计划年度"
  14. format="yyyy"
  15. value-format="yyyy"
  16. ></el-date-picker>
  17. </el-form-item>
  18. <el-form-item label="地区:">
  19. <el-cascader
  20. v-model="searchForm.areaCode"
  21. :options="districtTree"
  22. :props="districtTreeCascaderProps"
  23. :show-all-levels="false"
  24. clearable
  25. placeholder="请选择地区"
  26. @change="handleAreaChange"
  27. ></el-cascader>
  28. </el-form-item>
  29. <el-form-item label="状态:">
  30. <el-select
  31. v-model="searchForm.currentNode"
  32. placeholder="请选择状态"
  33. >
  34. <el-option label="全部" value=""></el-option>
  35. <el-option label="材料初审" value="clcs"></el-option>
  36. <el-option label="实地审核" value="sdsh"></el-option>
  37. <el-option label="意见告知" value="yjgz"></el-option>
  38. <el-option label="意见反馈" value="yjfk"></el-option>
  39. <el-option label="集体审议" value="jtsy"></el-option>
  40. <el-option label="出具报告" value="cjbg"></el-option>
  41. <el-option label="归档" value="gd"></el-option>
  42. </el-select>
  43. </el-form-item>
  44. <el-form-item label="监审项目名称:">
  45. <el-input
  46. v-model="searchForm.projectName"
  47. placeholder="请输入监审项目名称"
  48. clearable
  49. ></el-input>
  50. </el-form-item>
  51. <el-form-item>
  52. <el-button
  53. icon="el-icon-search"
  54. type="primary"
  55. @click="generateTableData"
  56. >
  57. 搜索
  58. </el-button>
  59. <el-button
  60. plain
  61. type="primary"
  62. icon="el-icon-refresh"
  63. @click="handleReset"
  64. >
  65. 重置
  66. </el-button>
  67. </el-form-item>
  68. </el-form>
  69. </div>
  70. <!-- 统计信息 -->
  71. <div class="statistics-info">
  72. <span>
  73. 在办事项:
  74. <span class="pending-count">{{ statistics.pendingCount }}</span>
  75. </span>
  76. <span>
  77. 已结事项:
  78. <span class="completed-count">{{ statistics.completedCount }}</span>
  79. </span>
  80. </div>
  81. <!-- 数据表格 -->
  82. <cost-audit-table
  83. v-loading="loading"
  84. :table-data="tableData"
  85. :columns="tableColumns"
  86. :border="true"
  87. :row-class-name="getRowClassName"
  88. :show-pagination="false"
  89. :table-props="{
  90. rowKey: 'id',
  91. treeProps: { children: 'children', hasChildren: 'hasChildren' },
  92. defaultExpandAll: true,
  93. }"
  94. >
  95. <!-- 操作列自定义模板 -->
  96. <template #operation="{ row }">
  97. <el-button size="mini" type="text" @click="handleView(row)">
  98. 查看
  99. </el-button>
  100. </template>
  101. </cost-audit-table>
  102. <!-- 分页 -->
  103. <el-pagination
  104. background
  105. layout="total, sizes, prev, pager, next"
  106. :current-page="pageNum"
  107. :page-sizes="[10, 20, 30, 40]"
  108. :page-size="pageSize"
  109. :total="total"
  110. style="margin-top: 20px; text-align: right"
  111. @current-change="handleCurrentChange"
  112. @size-change="handleSizeChange"
  113. />
  114. </div>
  115. <!-- 详情内容 -->
  116. <div v-if="activeView == 'detail'" class="detail-content">
  117. <detail-tabs
  118. :project="project"
  119. :task-data="taskData"
  120. :is-view="true"
  121. @detailClose="handleDetailClose"
  122. ></detail-tabs>
  123. </div>
  124. </div>
  125. </template>
  126. <script>
  127. import { dictMixin, regionMixin } from '@/mixins/useDict'
  128. import detailTabs from '@/views/costAudit/projectInfo/auditTaskManage/taskProgressManage/detailTabs.vue'
  129. import CostAuditTable from '@/components/costAudit/CostAuditTable.vue'
  130. import { getTaskListStatistics, getItemsCount } from '@/api/home'
  131. export default {
  132. components: {
  133. detailTabs,
  134. CostAuditTable,
  135. },
  136. mixins: [dictMixin, regionMixin],
  137. data() {
  138. return {
  139. dictData: {
  140. auditType: [], //监审形式
  141. projectProposal: [], //立项来源
  142. },
  143. activeView: 'list',
  144. loading: false,
  145. isView: true,
  146. searchForm: {
  147. year: '',
  148. areaCode: null,
  149. currentNode: null,
  150. projectName: '',
  151. },
  152. tableData: [],
  153. // 分页相关
  154. pageNum: 1,
  155. pageSize: 10,
  156. total: 0,
  157. // 统计数据
  158. statistics: {
  159. pendingCount: 0,
  160. completedCount: 0,
  161. },
  162. project: {},
  163. taskData: {},
  164. unitList: [],
  165. // 表格列配置
  166. tableColumns: [
  167. {
  168. prop: 'serialNumber',
  169. label: '序号',
  170. width: 60,
  171. align: 'center',
  172. formatter: (row) => {
  173. return row.pid == 0 ? row.parentIndex : ''
  174. },
  175. },
  176. {
  177. prop: 'year',
  178. label: '立项年度',
  179. width: 100,
  180. align: 'center',
  181. formatter: (row) => {
  182. return row.year || ''
  183. },
  184. },
  185. {
  186. prop: 'areaName',
  187. label: '立项地区',
  188. width: 100,
  189. align: 'center',
  190. },
  191. {
  192. prop: 'projectName',
  193. label: '成本监审项目名称',
  194. showOverflowTooltip: true,
  195. },
  196. {
  197. prop: 'auditedUnitName',
  198. label: '被监审单位',
  199. showOverflowTooltip: true,
  200. },
  201. {
  202. prop: 'auditPeriod',
  203. label: '监审期间',
  204. width: 150,
  205. align: 'center',
  206. },
  207. {
  208. prop: 'sourceType',
  209. label: '立项来源',
  210. width: 120,
  211. align: 'center',
  212. formatter: (row) => {
  213. return this.getDictName('projectProposal', row.sourceType)
  214. },
  215. },
  216. {
  217. prop: 'auditType',
  218. label: '监审形式',
  219. width: 120,
  220. align: 'center',
  221. formatter: (row) => {
  222. return this.getDictName('auditType', row.auditType)
  223. },
  224. },
  225. {
  226. prop: 'currentNodeName',
  227. label: '状态',
  228. width: 100,
  229. align: 'center',
  230. },
  231. {
  232. prop: 'operation',
  233. label: '操作',
  234. width: 80,
  235. align: 'center',
  236. slotName: 'operation',
  237. },
  238. ],
  239. }
  240. },
  241. computed: {
  242. pendingCount() {
  243. // 计算在办任务数量(非办结状态)
  244. return this.tableData.filter((item) => item.status !== 400).length
  245. },
  246. completedCount() {
  247. // 计算办结任务数量
  248. return this.tableData.filter((item) => item.status === 400).length
  249. },
  250. },
  251. mounted() {
  252. this.getTaskList()
  253. this.getItemsCount()
  254. },
  255. methods: {
  256. getItemsCount() {
  257. return getItemsCount().then((res) => {
  258. this.statistics = res.value
  259. })
  260. },
  261. getTaskList() {
  262. return getTaskListStatistics({
  263. pageNum: this.pageNum,
  264. pageSize: this.pageSize,
  265. year: this.searchForm.year,
  266. areaCode: this.searchForm.areaCode,
  267. currentNode: this.searchForm.currentNode,
  268. projectName: this.searchForm.projectName,
  269. }).then((res) => {
  270. if (res.state && res.value) {
  271. // 获取记录列表
  272. const records = res.value.records || []
  273. // 转换数据格式,将childTasks转换为children以適应表格组件
  274. this.tableData = records.map((record, index) => {
  275. return {
  276. id: record.id,
  277. projectName: record.projectName,
  278. auditedUnitName: record.auditedUnitName,
  279. auditPeriod: record.auditPeriod,
  280. source: this.getSourceTypeText(record.sourceType),
  281. form: this.getAuditTypeText(record.auditType),
  282. status: record.status,
  283. statusName: record.statusName,
  284. isSubTask: record.pid !== '0' && record.pid !== 0,
  285. currentNodeName: record.currentNodeName,
  286. currentNode: record.currentNode,
  287. projectId: record.projectId,
  288. auditedUnitId: record.auditedUnitId,
  289. parentIndex: index + 1, // 母计数作为parentIndex
  290. year: record.year,
  291. sourceType: record.sourceType,
  292. auditType: record.auditType,
  293. isGd: record.isGd,
  294. areaName: record.areaName,
  295. warningStatus: record.warningStatus,
  296. children:
  297. record.childTasks && record.childTasks.length > 0
  298. ? record.childTasks.map((child) => ({
  299. id: child.id,
  300. projectName: child.projectName,
  301. auditedUnitName: child.auditedUnitName,
  302. auditPeriod: child.auditPeriod || record.auditPeriod,
  303. source: child.sourceType
  304. ? this.getSourceTypeText(child.sourceType)
  305. : '',
  306. form: child.auditType
  307. ? this.getAuditTypeText(child.auditType)
  308. : '',
  309. currentNode: child.currentNode,
  310. status: child.status,
  311. statusName: child.statusName,
  312. isSubTask: true,
  313. currentNodeName: child.statusName,
  314. projectId: child.projectId,
  315. auditedUnitId: child.auditedUnitId,
  316. taskId: child.id,
  317. catalogId: child.catalogId,
  318. year: child.year,
  319. sourceType: child.sourceType,
  320. auditType: child.auditType,
  321. isGd: child.isGd,
  322. warningStatus: child.warningStatus,
  323. }))
  324. : [],
  325. }
  326. })
  327. // 设置总数
  328. this.total = res.value.total || records.length
  329. } else {
  330. this.tableData = []
  331. this.total = 0
  332. }
  333. })
  334. },
  335. // 获取来源类型文本
  336. getSourceTypeText(type) {
  337. const typeMap = {
  338. 1: '年度计划内',
  339. 2: '年度计划外',
  340. }
  341. return typeMap[type] || type
  342. },
  343. // 获取审核类型文本
  344. getAuditTypeText(type) {
  345. const typeMap = {
  346. 1: '定期监审',
  347. 2: '定调价监审',
  348. }
  349. return typeMap[type] || type
  350. },
  351. handleReset() {
  352. this.searchForm = {
  353. year: '',
  354. areaCode: null,
  355. currentNode: null,
  356. projectName: '',
  357. }
  358. this.pageNum = 1
  359. this.getTaskList()
  360. },
  361. generateTableData() {
  362. // 查询时重置为第一页
  363. this.pageNum = 1
  364. this.getTaskList()
  365. },
  366. getRowClassName({ row }) {
  367. if (row.isSubTask) {
  368. return 'sub-task-row'
  369. }
  370. return ''
  371. },
  372. handleView(row) {
  373. this.taskData = row
  374. this.getProject()
  375. this.activeView = 'detail'
  376. },
  377. handleDetailClose() {
  378. this.activeView = 'list'
  379. },
  380. // 分页处理
  381. handleSizeChange(size) {
  382. this.pageSize = size
  383. this.pageNum = 1
  384. this.getTaskList()
  385. },
  386. handleCurrentChange(current) {
  387. this.pageNum = current
  388. this.getTaskList()
  389. },
  390. // 地区选择处理 - 只按上佊中最后一级值
  391. handleAreaChange(value) {
  392. if (Array.isArray(value) && value.length > 0) {
  393. // 只保留最后一级的值
  394. this.searchForm.areaCode = value[value.length - 1]
  395. } else {
  396. // 清空时设为null
  397. this.searchForm.areaCode = null
  398. }
  399. },
  400. },
  401. }
  402. </script>
  403. <style scoped>
  404. .task-query-statistics {
  405. padding: 20px;
  406. }
  407. h2 {
  408. margin-bottom: 20px;
  409. font-size: 18px;
  410. color: #303133;
  411. }
  412. .demo-form-inline {
  413. display: flex;
  414. align-items: center;
  415. flex-wrap: wrap;
  416. }
  417. .statistics-info {
  418. text-align: right;
  419. margin-bottom: 20px;
  420. }
  421. .statistics-info span {
  422. margin-right: 30px;
  423. }
  424. .pending-count,
  425. .completed-count {
  426. font-weight: bold;
  427. color: #1890ff;
  428. }
  429. .description {
  430. margin-top: 15px;
  431. padding: 15px;
  432. background-color: #fff7e6;
  433. border: 1px solid #ffe7ba;
  434. border-radius: 4px;
  435. }
  436. .description p {
  437. margin: 0;
  438. line-height: 1.6;
  439. }
  440. /* 子任务样式 */
  441. .el-table .sub-task-row {
  442. background-color: #fafafa !important;
  443. }
  444. /* 响应式布局 */
  445. @media (max-width: 1200px) {
  446. .demo-form-inline {
  447. flex-direction: column;
  448. align-items: flex-start;
  449. }
  450. .demo-form-inline .el-form-item {
  451. margin-right: 0;
  452. margin-bottom: 15px;
  453. }
  454. }
  455. </style>