index.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. import {
  2. getCostProjectDetail,
  3. getCostProjectScenarioDetail,
  4. getCostProjectDocumentPageList,
  5. getCostProjectMaterialPageList,
  6. getCostProjectNodeTmpletePageList,
  7. getCostProjectNodeTmpleteGetDetail,
  8. getCostProjectSurveyPageList,
  9. } from '@/api/taskCustomizedRelease.js'
  10. import { getAllUserList } from '@/api/uc'
  11. import { getCostSurveyTemplates } from '@/api/catalogManage.js'
  12. import { getWhCateList, getDocList } from '@/api/auditReviewDocManage.js'
  13. // 引入地区选择混入
  14. import {
  15. dictMixin,
  16. regionMixin,
  17. catalogMixin,
  18. commonMixin,
  19. } from '@/mixins/useDict'
  20. export const taskMixin = {
  21. mixins: [dictMixin, regionMixin, catalogMixin, commonMixin],
  22. data() {
  23. return {
  24. dictData: {
  25. auditType: [], //监审形式
  26. materialType: [], //资料类别
  27. formatAsk: [], //格式要求
  28. processNodeType: [], //流程环节类型
  29. projectProposal: [], //立项来源
  30. processStatus: [], //预置流转操作
  31. whGenerateType: [],
  32. },
  33. userList: [],
  34. // 弹窗状态管理
  35. dialogs: {
  36. materialDialogVisible: false,
  37. setStepDialogVisible: false,
  38. stepDialogVisible: false,
  39. detailDialogVisible: false,
  40. documentDialogVisible: false,
  41. },
  42. loading: {
  43. save: false,
  44. saveDocument: false,
  45. },
  46. // 当前激活的标签页
  47. activeTab: 'scenario',
  48. formCities: [],
  49. formDistricts: [],
  50. // 所有表单数据聚合
  51. formData: {
  52. // 监审立项信息表单
  53. basicInfo: {
  54. projectName: '',
  55. catalogId: '',
  56. areaCode: '',
  57. auditedUnitName: '',
  58. auditedUnitId: '',
  59. orgId: '',
  60. orgName: '',
  61. planYear: '',
  62. projectYear: '',
  63. sourceType: '',
  64. auditPeriod: '',
  65. auditPeriodArray: [{ value: '' }],
  66. needHearing: 1,
  67. isEmergency: 1,
  68. establishmentReason: '',
  69. accordingFileUrl: '',
  70. otherFileUrl: '',
  71. expertStr: '',
  72. auditGroup: '',
  73. projectMembers: '',
  74. auditTeamMembers: [],
  75. },
  76. // 监审工作方案表单
  77. workPlan: {
  78. basicInfo: '',
  79. scopeContent: '',
  80. stepsMethods: '',
  81. otherContent: '',
  82. attachmentIds: [],
  83. },
  84. // 材料表单(弹窗用)
  85. material: {
  86. materialType: '综合性材料',
  87. materialName: '',
  88. materialAsk: '',
  89. formatAsk: '文档文件',
  90. orderNum: '',
  91. isMust: '否',
  92. },
  93. // 当前流程环节(弹窗用)
  94. currentStep: {
  95. mainUserId: '',
  96. userId: [],
  97. status: [],
  98. },
  99. currentStepRules: {
  100. mainUserId: [
  101. { required: true, message: '请选择主办人员', trigger: 'change' },
  102. ],
  103. userId: [
  104. {
  105. required: true,
  106. message: '请选择从办人员',
  107. trigger: 'change',
  108. },
  109. ],
  110. status: [
  111. {
  112. required: true,
  113. message: '请输入预置流转操作',
  114. trigger: 'blur',
  115. },
  116. ],
  117. endTime: [
  118. { required: true, message: '请选择截止时间', trigger: 'change' },
  119. ],
  120. },
  121. // 监审工作流程表单
  122. workflow: {
  123. plannedAuditEndDate: '',
  124. plannedAuditStartDate: '',
  125. },
  126. },
  127. scenarioData: {
  128. addScenario: false,
  129. saveScenario: false,
  130. },
  131. workflowData: {
  132. list: [],
  133. detailInfo: {},
  134. stepList: [],
  135. pagination: {
  136. currentPage: 1,
  137. pageSize: 10,
  138. total: 0,
  139. },
  140. listColumns: [
  141. {
  142. prop: 'processNodeValue',
  143. label: '流程环节',
  144. width: 100,
  145. align: 'center',
  146. },
  147. {
  148. prop: 'nodeType',
  149. label: '环节类型',
  150. width: 100,
  151. align: 'center',
  152. formatter: (row) => {
  153. return this.getDictName('processNodeType', row.nodeType)
  154. },
  155. },
  156. {
  157. prop: 'mainUserName',
  158. label: '主办人员',
  159. minWidth: 100,
  160. align: 'left',
  161. },
  162. {
  163. prop: 'userName',
  164. label: '从办人员',
  165. minWidth: 150,
  166. align: 'left',
  167. },
  168. {
  169. prop: 'status',
  170. label: '预置流转操作',
  171. minWidth: 150,
  172. align: 'left',
  173. formatter: (row) => {
  174. return this.getDictName('processStatus', row.status)
  175. },
  176. },
  177. {
  178. prop: 'actStartTime',
  179. label: '开始时间',
  180. width: 140,
  181. align: 'center',
  182. },
  183. {
  184. prop: 'actEndTime',
  185. label: '结束时间',
  186. width: 140,
  187. align: 'center',
  188. },
  189. {
  190. prop: 'endTime',
  191. label: '预置环节截止时间',
  192. width: 140,
  193. align: 'center',
  194. },
  195. {
  196. prop: 'action',
  197. label: '操作',
  198. width: 100,
  199. align: 'center',
  200. slotName: 'action',
  201. },
  202. ],
  203. workflowColumns: [
  204. {
  205. prop: 'processNodeValue',
  206. label: '流程环节',
  207. width: 100,
  208. align: 'center',
  209. },
  210. {
  211. prop: 'nodeType',
  212. label: '环节类型',
  213. width: 100,
  214. align: 'center',
  215. formatter: (row) => {
  216. return this.getDictName('processNodeType', row.nodeType)
  217. },
  218. },
  219. {
  220. prop: 'mainUserId',
  221. label: '主办人员',
  222. minWidth: 100,
  223. align: 'left',
  224. slotName: 'mainUserId',
  225. },
  226. {
  227. prop: 'userId',
  228. label: '从办人员',
  229. minWidth: 200,
  230. align: 'left',
  231. slotName: 'userId',
  232. },
  233. {
  234. prop: 'status',
  235. label: '预置流转操作',
  236. minWidth: 150,
  237. align: 'left',
  238. slotName: 'status',
  239. },
  240. {
  241. prop: 'endTime',
  242. label: '预置环节截止时间',
  243. width: 150,
  244. align: 'center',
  245. slotName: 'endTime',
  246. },
  247. ],
  248. },
  249. documentData: {
  250. documentTypes: [],
  251. selectedDoc: 'notice',
  252. list: [],
  253. pagination: {
  254. currentPage: 1,
  255. pageSize: 50,
  256. total: 0,
  257. },
  258. dataList: [], // 保持原数据结构,实际使用时会填充
  259. documentColumns: [
  260. {
  261. prop: 'documentId',
  262. label: '文书类型',
  263. align: 'center',
  264. slotName: 'documentId',
  265. },
  266. {
  267. prop: 'documentNumber',
  268. label: '文书文号',
  269. width: 200,
  270. align: 'center',
  271. },
  272. {
  273. prop: 'enterpriseId',
  274. label: '被监审单位',
  275. width: 200,
  276. align: 'left',
  277. slotName: 'enterpriseId',
  278. },
  279. {
  280. prop: 'generateTime',
  281. label: '生成时间',
  282. width: 100,
  283. align: 'center',
  284. slotName: 'generateTime',
  285. },
  286. {
  287. prop: 'electronicDocumentUrl',
  288. label: '电子文书',
  289. width: 200,
  290. align: 'center',
  291. slotName: 'electronicDocumentUrl',
  292. },
  293. {
  294. prop: 'scanDocumentUrl',
  295. label: '上传扫描件',
  296. width: 150,
  297. align: 'center',
  298. slotName: 'scanDocumentUrl',
  299. },
  300. {
  301. prop: 'isPushed',
  302. label: '是否推送被监审单位',
  303. width: 100,
  304. align: 'center',
  305. formatter: (row) => (row.isPushed == 1 ? '是' : '否'),
  306. },
  307. {
  308. prop: 'feedbackDocumentUrl',
  309. label: '被监审单位反馈资料',
  310. width: 150,
  311. align: 'center',
  312. slotName: 'feedbackDocumentUrl',
  313. },
  314. ],
  315. },
  316. }
  317. },
  318. computed: {
  319. surveyData() {
  320. return {
  321. list: [],
  322. pagination: {
  323. currentPage: 1,
  324. pageSize: 50,
  325. total: 0,
  326. },
  327. surveyColumns: [
  328. {
  329. prop: 'surveyTemplateName',
  330. label: '成本调查表',
  331. width: 300,
  332. align: 'left',
  333. showOverflowTooltip: true,
  334. },
  335. {
  336. prop: 'templateType',
  337. label: '资料类型',
  338. width: 120,
  339. align: 'center',
  340. formatter: (row) => {
  341. return row.templateType == '1'
  342. ? '单记录'
  343. : row.templateType == '2'
  344. ? '固定表'
  345. : '动态表'
  346. },
  347. },
  348. // {
  349. // prop: 'isMust',
  350. // label: '是否必填',
  351. // width: 100,
  352. // align: 'center',
  353. // },
  354. {
  355. prop: 'action',
  356. label: '操作',
  357. width: 120,
  358. align: 'center',
  359. },
  360. ],
  361. }
  362. },
  363. // 数据列表聚合
  364. materialData() {
  365. return {
  366. list: [],
  367. pagination: {
  368. currentPage: 1,
  369. pageSize: 50,
  370. total: 0,
  371. },
  372. materialDialogTitle: '添加',
  373. materialDialogVisible: false,
  374. saveMaterial: false,
  375. addMaterial: false,
  376. materialColumns: [
  377. {
  378. prop: 'informationType',
  379. label: '材料分类',
  380. width: 120,
  381. align: 'center',
  382. formatter: (row) => {
  383. return this.getDictName('materialType', row.informationType)
  384. },
  385. },
  386. {
  387. prop: 'informationName',
  388. label: '材料名称',
  389. minWidth: 200,
  390. align: 'left',
  391. },
  392. {
  393. prop: 'informationRequire',
  394. label: '材料要求说明',
  395. minWidth: 300,
  396. align: 'left',
  397. },
  398. {
  399. prop: 'formatRequired',
  400. label: '格式要求',
  401. width: 120,
  402. align: 'center',
  403. formatter: (row) => {
  404. return this.getDictName('formatAsk', row.formatRequired)
  405. },
  406. },
  407. {
  408. prop: 'orderNum',
  409. label: '排序',
  410. width: 120,
  411. align: 'center',
  412. slotName: 'orderNum',
  413. },
  414. {
  415. prop: 'action',
  416. label: '操作',
  417. align: 'center',
  418. width: 200,
  419. slotName: 'action',
  420. actions: [
  421. {
  422. name: 'edit',
  423. label: '修改',
  424. type: 'text',
  425. size: 'mini',
  426. onClick: this.handleEditMaterial,
  427. disabled: this.isView,
  428. },
  429. {
  430. name: 'delete',
  431. label: '删除',
  432. type: 'text',
  433. size: 'mini',
  434. className: 'delete-btn',
  435. onClick: this.handleDeleteMaterial,
  436. disabled: this.isView,
  437. },
  438. ],
  439. },
  440. ],
  441. }
  442. },
  443. },
  444. watch: {
  445. activeTab: {
  446. handler(newVal) {
  447. this.handleTabClick()
  448. },
  449. immediate: false, // 可选:如果需要在组件初始化时就执行,可以设置为true
  450. },
  451. },
  452. methods: {
  453. async handleTabClick() {
  454. switch (this.activeTab) {
  455. case 'basicInfo':
  456. this.getBasicInfo()
  457. break
  458. case 'scenario':
  459. this.getScenarioData()
  460. break
  461. case 'material':
  462. this.getMaterialData()
  463. break
  464. case 'survey':
  465. // this.getSurveyData()
  466. break
  467. case 'auditNotice':
  468. // const res = await getWhCateList()
  469. this.getDocumentData()
  470. break
  471. case 'workflow':
  472. this.getWorkflow()
  473. break
  474. default:
  475. break
  476. }
  477. },
  478. // 获取用户信息
  479. getUser() {
  480. getAllUserList()
  481. .then((res) => {
  482. this.userList = res.value || []
  483. })
  484. .catch(() => {})
  485. },
  486. getBasicInfo() {
  487. const pid =
  488. (this.project && (this.project.projectId || this.project.id)) ||
  489. (this.taskData && (this.taskData.projectId || this.taskData.id)) ||
  490. ''
  491. if (!pid) return
  492. getCostProjectDetail({ id: pid })
  493. .then((res) => {
  494. this.formData.basicInfo = {
  495. ...this.project,
  496. ...res.value,
  497. }
  498. })
  499. .catch(() => {
  500. this.formData.basicInfo = this.project
  501. })
  502. },
  503. // 获取监审工作方案数据
  504. getScenarioData() {
  505. const pid =
  506. (this.project && (this.project.projectId || this.project.id)) ||
  507. (this.taskData && (this.taskData.projectId || this.taskData.id)) ||
  508. ''
  509. if (!pid) return
  510. getCostProjectScenarioDetail({ projectId: pid }).then((res) => {
  511. if (res.value) {
  512. this.formData.workPlan = res.value
  513. this.formData.workPlan.attachmentIds = res.value.attachmentIds
  514. ? res.value.attachmentIds.split(',')
  515. : []
  516. } else {
  517. this.scenarioData.addScenario = true
  518. }
  519. })
  520. },
  521. // 报送资料要求数据
  522. getMaterialData() {
  523. const pid =
  524. (this.project && (this.project.projectId || this.project.id)) ||
  525. (this.taskData && (this.taskData.projectId || this.taskData.id)) ||
  526. ''
  527. if (!pid) return
  528. getCostProjectMaterialPageList({
  529. pageNum: this.materialData.pagination.currentPage,
  530. pageSize: this.materialData.pagination.pageSize,
  531. projectId: pid,
  532. }).then((res) => {
  533. if (res.value.code == 200) {
  534. this.materialData.list = res.value.value.records || []
  535. this.materialData.pagination.total = res.value.value.total
  536. } else {
  537. this.materialData.list = []
  538. this.materialData.pagination.total = 0
  539. }
  540. })
  541. },
  542. // 获取成本调查表数据
  543. getSurveyData() {
  544. getCostSurveyTemplates({
  545. // pageNum: this.surveyData.pagination.currentPage,
  546. // pageSize: this.surveyData.pagination.pageSize,
  547. catalogId: this.project.catalogId,
  548. }).then((res) => {
  549. this.surveyData.list = res.value
  550. // this.surveyData.pagination.total = res.value.total
  551. })
  552. },
  553. // 获取监审通知数据
  554. async getDocumentData(data) {
  555. const res = await getDocList({
  556. page: 1,
  557. pageSize: 50,
  558. })
  559. this.documentData.documentTypes = res.value.records || []
  560. const pid =
  561. (this.project && (this.project.projectId || this.project.id)) ||
  562. (this.taskData && (this.taskData.projectId || this.taskData.id)) ||
  563. ''
  564. if (!pid) return
  565. // 查看/编辑权限类型区分,未传会导致列表为空
  566. const permissionType = this.isView ? '0' : '1'
  567. // 确保data是对象,避免当传入非对象类型(如字符串)时出错
  568. const documentType =
  569. typeof data === 'object' && data !== null ? data.documentType || '' : ''
  570. getCostProjectDocumentPageList({
  571. pageNum: this.documentData.pagination.currentPage,
  572. pageSize: this.documentData.pagination.pageSize,
  573. projectId: pid,
  574. // documentName: data ? data.documentName : '',
  575. documentType,
  576. permissionType,
  577. }).then((res) => {
  578. let records = res.value.value.records
  579. this.documentData.list = records.filter((item) => {
  580. const excludeTypes = [
  581. '成本监审工作底稿-送达回证',
  582. '成本监审提取资料登记表-送达回证',
  583. '成本审核初步意见表1-送达回证',
  584. '成本监审集体审议记录-送达回证',
  585. ]
  586. return !excludeTypes.includes(item.documentName)
  587. })
  588. this.documentData.pagination.total = res.value.value.total
  589. })
  590. },
  591. // 获取流程数据
  592. getWorkflow() {
  593. const pid =
  594. (this.project && (this.project.projectId || this.project.id)) ||
  595. (this.taskData && (this.taskData.projectId || this.taskData.id)) ||
  596. ''
  597. if (!pid) return
  598. getCostProjectNodeTmpleteGetDetail({ projectId: pid }).then((res) => {
  599. this.workflowData.list = res.value.nodeList || []
  600. this.workflowData.detailInfo = res.value
  601. this.formData.workflow.plannedAuditStartDate =
  602. res.value.plannedAuditStartDate
  603. this.formData.workflow.plannedAuditEndDate =
  604. res.value.plannedAuditEndDate
  605. })
  606. },
  607. handlePaginationChange({ currentPage, pageSize }) {
  608. switch (this.activeTab) {
  609. case 'material':
  610. this.materialData.pagination.currentPage = currentPage
  611. this.materialData.pagination.pageSize = pageSize
  612. this.getMaterialData()
  613. break
  614. case 'survey':
  615. this.surveyData.pagination.currentPage = currentPage
  616. this.surveyData.pagination.pageSize = pageSize
  617. this.getSurveyData()
  618. break
  619. case 'auditNotice':
  620. this.documentData.pagination.currentPage = currentPage
  621. this.documentData.pagination.pageSize = pageSize
  622. this.getDocumentData()
  623. break
  624. default:
  625. break
  626. }
  627. },
  628. formattertUserName(userId) {
  629. if (userId) {
  630. let arr = userId.split(',')
  631. return arr
  632. .map((item) => {
  633. let user = this.userList.find((user) => user.userId == item)
  634. return user.fullname
  635. })
  636. .join(',')
  637. }
  638. },
  639. },
  640. }