index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. <template>
  2. <div class="cost-audit-management">
  3. <!-- 成本审核项目列表页面 -->
  4. <div class="audit-list-container">
  5. <div class="search-section">
  6. <el-input
  7. v-model="searchQuery"
  8. placeholder="监审项目名称"
  9. style="width: 300px; margin-right: 10px"
  10. clearable
  11. />
  12. <el-button type="primary" @click="handleSearch">查询</el-button>
  13. </div>
  14. <el-table
  15. v-loading="loading"
  16. class="mb10"
  17. :data="auditProjectList"
  18. style="width: 100%"
  19. border
  20. default-expand-all
  21. row-key="id"
  22. :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
  23. >
  24. <el-table-column
  25. type="index"
  26. label="序号"
  27. width="80"
  28. header-align="center"
  29. align="center"
  30. >
  31. <template slot-scope="scope">
  32. <!-- 只显示父节点的序号 -->
  33. <span v-if="scope.row.children">
  34. {{ getParentNodeIndex(scope.row) }}
  35. </span>
  36. <span v-else></span>
  37. </template>
  38. </el-table-column>
  39. <el-table-column
  40. prop="projectName"
  41. label="成本监审项目名称"
  42. show-overflow-tooltip
  43. header-align="center"
  44. align="left"
  45. />
  46. <el-table-column
  47. prop="auditObject"
  48. label="监审对象"
  49. header-align="center"
  50. align="left"
  51. />
  52. <el-table-column
  53. prop="auditPeriod"
  54. label="监审期间"
  55. header-align="center"
  56. align="center"
  57. width="120"
  58. />
  59. <el-table-column
  60. prop="source"
  61. label="立项来源"
  62. header-align="center"
  63. align="center"
  64. width="100"
  65. />
  66. <el-table-column
  67. prop="form"
  68. label="监审形式"
  69. header-align="center"
  70. align="center"
  71. width="100"
  72. />
  73. <el-table-column
  74. prop="currentNodeName"
  75. label="状态"
  76. align="center"
  77. width="80"
  78. >
  79. <template slot-scope="scope">
  80. <span v-if="!scope.row.isSubTask">
  81. {{ scope.row.currentNodeName }}
  82. </span>
  83. <span v-else>{{ scope.row.status }}</span>
  84. </template>
  85. </el-table-column>
  86. <el-table-column label="操作" align="center" width="260">
  87. <template slot-scope="scope">
  88. <span v-if="!scope.row.isSubTask" class="action-buttons">
  89. <el-button type="text" @click="handleViewTaskDetail(scope.row)">
  90. 任务详情
  91. </el-button>
  92. <el-button type="text" @click="handleOpenMainDetails(scope.row)">
  93. 任务办理
  94. </el-button>
  95. <el-button type="text" @click="handleCheckRecord(scope.row)">
  96. 备忘录
  97. </el-button>
  98. </span>
  99. <span v-if="scope.row.isSubTask" class="action-buttons">
  100. <el-button
  101. v-if="
  102. scope.row.currentNode === 'clcs' &&
  103. (scope.row.status === '审核中' ||
  104. scope.row.status === '补充材料')
  105. "
  106. type="text"
  107. @click="handleOpenDetails(scope.row)"
  108. >
  109. 资料初审
  110. </el-button>
  111. <el-button
  112. v-if="
  113. (scope.row.currentNode === 'sdsh' ||
  114. scope.row.currentNode === 'yjfk') &&
  115. scope.row.status === '审核中'
  116. "
  117. type="text"
  118. @click="handleOpenDetails(scope.row)"
  119. >
  120. 成本审核
  121. </el-button>
  122. <el-button
  123. v-if="
  124. scope.row.currentNode === 'yjgz' &&
  125. scope.row.status === '审核中'
  126. "
  127. type="text"
  128. @click="handleOpenDetails(scope.row)"
  129. >
  130. 意见告知
  131. </el-button>
  132. <el-button
  133. v-if="
  134. scope.row.currentNode === 'yjfk' &&
  135. scope.row.status === '已反馈'
  136. "
  137. type="text"
  138. @click="handleOpenDetails(scope.row)"
  139. >
  140. 审核
  141. </el-button>
  142. <el-button
  143. v-if="scope.row.status === '中止'"
  144. type="text"
  145. @click="handleHf(scope.row)"
  146. >
  147. 恢复
  148. </el-button>
  149. <el-button
  150. type="text"
  151. @click="handleMessage(scope.row, 'chengben')"
  152. >
  153. 查看
  154. </el-button>
  155. </span>
  156. </template>
  157. </el-table-column>
  158. </el-table>
  159. <el-pagination
  160. background
  161. layout="total, sizes, prev, pager, next"
  162. :current-page="currentPage"
  163. :page-sizes="[10, 20, 30, 40]"
  164. :page-size="pageSize"
  165. :total="total"
  166. @current-change="handleCurrentChange"
  167. @size-change="handleSizeChange"
  168. />
  169. </div>
  170. <!-- 详情弹窗组件 -->
  171. <details-dialog
  172. :id="selectedProject && selectedProject.id"
  173. ref="detailsRef"
  174. :visible.sync="detailsVisible"
  175. :current-node="selectedProject && selectedProject.currentNode"
  176. :current-status="selectedProject && selectedProject.status"
  177. @close="handleDetailsClose"
  178. @refresh="handleRefresh"
  179. />
  180. <!-- 主详情弹窗组件 -->
  181. <mainDetailsDialog
  182. :id="selectedProject && selectedProject.id"
  183. ref="mainDetailsRef"
  184. :visible.sync="mainDetailsVisible"
  185. :current-node="selectedProject && selectedProject.currentNode"
  186. :current-status="selectedProject && selectedProject.status"
  187. @close="handleMainDetailsClose"
  188. @refresh="handleMainRefresh"
  189. />
  190. <taskInfo ref="taskInfo" />
  191. <!-- 成本监审信息弹窗 -->
  192. <cbjs-info
  193. :id="cbjsInfoData && cbjsInfoData.id"
  194. :visible.sync="cbjsInfoVisible"
  195. :current-node="cbjsInfoData && cbjsInfoData.currentNode"
  196. :current-status="cbjsInfoData && cbjsInfoData.status"
  197. />
  198. <taskDetail ref="taskDetail" />
  199. </div>
  200. </template>
  201. <script>
  202. import { doProcessBtn } from '@/api/dataPreliminaryReview'
  203. import detailsDialog from './details.vue'
  204. import mainDetailsDialog from './mainDetails.vue'
  205. // 成本监审任务列表API
  206. import { getReviewTaskList } from '@/api/audit/auditIndex'
  207. import taskInfo from '@/components/task/taskInfo.vue'
  208. import cbjsInfo from '@/components/task/cbjsInfo.vue'
  209. import taskDetail from '@/components/task/taskDetail.vue'
  210. export default {
  211. name: 'CostAuditManagement',
  212. components: {
  213. detailsDialog,
  214. taskInfo,
  215. cbjsInfo,
  216. mainDetailsDialog,
  217. taskDetail,
  218. },
  219. data() {
  220. return {
  221. // 分页相关
  222. currentPage: 1,
  223. pageSize: 10,
  224. total: 0,
  225. // 搜索相关
  226. searchQuery: '',
  227. // 列表数据
  228. auditProjectList: [],
  229. // 加载状态
  230. loading: false,
  231. // 详情弹窗相关
  232. detailsVisible: false,
  233. selectedProject: null,
  234. // cbjsInfo弹窗相关
  235. cbjsInfoVisible: false,
  236. cbjsInfoData: null,
  237. mainDetailsVisible: false,
  238. }
  239. },
  240. created() {
  241. this.loadAuditProjectList()
  242. },
  243. methods: {
  244. // 获取父节点的连续序号
  245. getParentNodeIndex(row) {
  246. // 过滤出所有父节点
  247. const parentNodes = this.auditProjectList.filter(
  248. (item) => item.children && item.children.length > 0
  249. )
  250. // 找到当前行在父节点数组中的索引
  251. const index = parentNodes.findIndex((item) => item.id === row.id)
  252. // 返回序号(索引+1)
  253. return index + 1
  254. },
  255. // 加载审核项目列表
  256. async loadAuditProjectList() {
  257. try {
  258. this.loading = true
  259. // 调用API获取数据
  260. const params = {
  261. currentPage: this.currentPage,
  262. pageSize: this.pageSize,
  263. projectName: this.searchQuery,
  264. }
  265. const response = await getReviewTaskList(params)
  266. // 根据API返回格式处理数据
  267. if (response.state && response.value) {
  268. // 获取记录列表
  269. const records = response.value.records || []
  270. // 转换数据格式,将childTasks转换为children以适应表格组件
  271. this.auditProjectList = records.map((record) => {
  272. return {
  273. id: record.id,
  274. projectName: record.projectName,
  275. auditObject: record.auditedUnitName,
  276. auditPeriod: record.auditPeriod,
  277. source: this.getSourceTypeText(record.sourceType),
  278. form: this.getAuditTypeText(record.auditType),
  279. status: this.getStatusText(record.status),
  280. isSubTask: record.pid !== '0',
  281. currentNodeName: record.currentNodeName,
  282. currentNode: record.currentNode,
  283. projectId: record.projectId,
  284. auditedUnitId: record.auditedUnitId,
  285. children: record.childTasks
  286. ? record.childTasks.map((child) => ({
  287. id: child.id,
  288. projectName: child.projectName,
  289. auditObject: child.auditedUnitName,
  290. auditPeriod: record.auditPeriod, // 子任务可能使用父任务的审核期间
  291. source: '',
  292. form: '',
  293. currentNode: child.currentNode,
  294. status: child.status,
  295. isSubTask: true,
  296. projectId: child.projectId,
  297. auditedUnitId: child.auditedUnitId,
  298. taskId: child.id,
  299. }))
  300. : [],
  301. }
  302. })
  303. // 设置总数
  304. this.total = response.value.total || 0
  305. } else {
  306. this.auditProjectList = []
  307. this.total = 0
  308. this.$message.warning('未获取到审核项目数据')
  309. }
  310. } catch (error) {
  311. this.$message.error('加载审核项目列表失败')
  312. console.error('加载审核项目列表失败:', error)
  313. } finally {
  314. this.loading = false
  315. }
  316. },
  317. // 获取来源类型文本
  318. getSourceTypeText(type) {
  319. const typeMap = {
  320. 1: '年度计划内',
  321. 2: '年度计划外',
  322. // 可根据实际需求补充其他类型
  323. }
  324. return typeMap[type] || type
  325. },
  326. // 获取审核类型文本
  327. getAuditTypeText(type) {
  328. const typeMap = {
  329. 1: '定期监审',
  330. 2: '定调价监审',
  331. // 可根据实际需求补充其他类型
  332. }
  333. return typeMap[type] || type
  334. },
  335. // 获取状态文本
  336. getStatusText(status) {
  337. const statusMap = {
  338. ccls: '资料初审',
  339. 200: '审核通过',
  340. clcs: '审核中', // 添加clcs状态映射为审核中
  341. // 可根据实际需求补充其他状态
  342. }
  343. return statusMap[status] || status
  344. },
  345. // 搜索
  346. handleSearch() {
  347. // 搜索逻辑
  348. this.loadAuditProjectList()
  349. },
  350. // 查看任务详情
  351. handleViewTaskDetail(row) {
  352. // this.selectedTask = row
  353. // this.activeTab = 'detail'
  354. // this.showTaskDetail = true
  355. this.$refs.taskDetail.open(row, 'chengben')
  356. },
  357. // 打开详情弹窗
  358. handleOpenDetails(project) {
  359. console.log('project', project)
  360. this.selectedProject = project
  361. this.detailsVisible = true
  362. },
  363. handleOpenMainDetails(project) {
  364. console.log('project', project)
  365. this.selectedProject = project
  366. this.mainDetailsVisible = true
  367. },
  368. // 详情弹窗关闭处理
  369. handleDetailsClose() {
  370. this.selectedProject = null
  371. this.detailsVisible = false
  372. // 可以在这里添加刷新列表的逻辑
  373. },
  374. // 刷新表格数据
  375. handleRefresh() {
  376. // 刷新列表数据
  377. this.loadAuditProjectList()
  378. },
  379. // 主详情弹窗关闭处理
  380. handleMainDetailsClose() {
  381. this.selectedProject = null
  382. this.mainDetailsVisible = false
  383. },
  384. // 主详情刷新处理
  385. handleMainRefresh() {
  386. // 刷新列表数据
  387. this.loadAuditProjectList()
  388. },
  389. // 查记录
  390. handleCheckRecord(project) {
  391. // memoManage
  392. this.$router.push({
  393. name: 'memoManage',
  394. // params: { projectId: project.id }
  395. })
  396. },
  397. // 恢复任务
  398. async handleHf(row) {
  399. if (!row || !row.id) {
  400. this.$message.error('缺少任务ID')
  401. return
  402. }
  403. // 弹出确认对话框
  404. this.$confirm('确定要恢复此任务吗?', '恢复任务', {
  405. confirmButtonText: '确定',
  406. cancelButtonText: '取消',
  407. type: 'warning',
  408. })
  409. .then(async () => {
  410. try {
  411. const params = {
  412. taskId: row.id,
  413. key: 2,
  414. status: 200,
  415. processNodeKey: row.currentNode,
  416. }
  417. const response = await doProcessBtn(params)
  418. if (response && response.code === 200) {
  419. this.$message.success('恢复任务成功')
  420. // 刷新列表
  421. this.loadAuditProjectList()
  422. } else {
  423. this.$message.error(response?.message || '恢复任务失败')
  424. }
  425. } catch (error) {
  426. this.$message.error('恢复任务失败')
  427. console.error('恢复任务失败:', error)
  428. }
  429. })
  430. .catch(() => {
  431. // 用户取消操作
  432. this.$message.info('已取消恢复任务')
  433. })
  434. },
  435. // 分页处理
  436. handleSizeChange(size) {
  437. this.pageSize = size
  438. this.loadAuditProjectList()
  439. },
  440. handleCurrentChange(current) {
  441. this.currentPage = current
  442. this.loadAuditProjectList()
  443. },
  444. // 查看 - 修改为打开cbjsInfo弹窗
  445. handleMessage(row, type) {
  446. if (type === 'chengben') {
  447. this.cbjsInfoData = row
  448. this.cbjsInfoVisible = true
  449. } else {
  450. this.$refs.taskInfo.open(row, type)
  451. }
  452. },
  453. },
  454. }
  455. </script>
  456. <style scoped>
  457. .cost-audit-management {
  458. padding: 20px;
  459. }
  460. /* 列表页面样式 */
  461. .search-section {
  462. margin-bottom: 20px;
  463. }
  464. .action-buttons {
  465. font-size: 12px;
  466. }
  467. .action-buttons a {
  468. color: #409eff;
  469. text-decoration: none;
  470. }
  471. .separator {
  472. margin: 0 5px;
  473. color: #999;
  474. }
  475. .note-section {
  476. margin-top: 20px;
  477. }
  478. .note-text {
  479. color: #f56c6c;
  480. font-size: 12px;
  481. margin: 5px 0;
  482. }
  483. /* 详情页面样式 */
  484. .audit-detail-container {
  485. margin-top: 20px;
  486. }
  487. .detail-form {
  488. margin-top: 20px;
  489. }
  490. .tab-content {
  491. padding: 20px;
  492. background-color: #f9f9f9;
  493. min-height: 200px;
  494. }
  495. /* 办理页面样式 */
  496. .audit-process-container {
  497. margin-top: 20px;
  498. }
  499. .process-actions {
  500. margin-bottom: 20px;
  501. }
  502. .process-actions .el-button {
  503. margin-right: 10px;
  504. }
  505. /* 响应式设计 */
  506. @media (max-width: 768px) {
  507. .process-steps {
  508. flex-direction: column;
  509. }
  510. .step-line {
  511. width: 2px;
  512. height: 20px;
  513. margin: 5px 0;
  514. }
  515. .documents-layout {
  516. flex-direction: column;
  517. }
  518. .documents-type-list {
  519. width: 100%;
  520. margin-right: 0;
  521. margin-bottom: 20px;
  522. }
  523. .meeting-form .el-row {
  524. flex-direction: column;
  525. }
  526. .meeting-form .el-col {
  527. width: 100%;
  528. }
  529. }
  530. </style>