task-review.vue 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391
  1. <template>
  2. <hc-new-dialog
  3. v-model="isShow"
  4. is-table
  5. widths="96%"
  6. title="任务审核"
  7. @close="cancelClick"
  8. >
  9. <template #header="{ titleId, titleClass }">
  10. <div class="hc-card-header flex items-center">
  11. <div :id="titleId" :class="titleClass">
  12. 任务审核 【已开启电签】
  13. </div>
  14. </div>
  15. </template>
  16. <div v-loading="isLoading" class="relative h-full">
  17. <div class="hc-task-name relative">
  18. {{ rowInfo.taskName }} 审批信息
  19. </div>
  20. <div class="hc-task-body relative flex">
  21. <div class="hc-task-time">
  22. <hc-body class="hc-task-body-card" padding="10px" scrollbar>
  23. <el-timeline
  24. v-if="rowInfo.fixedFlowId == null"
  25. class="hc-time-line"
  26. >
  27. <template
  28. v-for="(item, index) in flowList"
  29. :key="index"
  30. >
  31. <el-timeline-item
  32. :class="
  33. item.status === '2'
  34. ? 'success'
  35. : 'primary'
  36. "
  37. size="large"
  38. >
  39. <div class="timeline-item-icon">
  40. <hc-icon
  41. v-if="item.status === '2'"
  42. class="check-icon"
  43. name="check"
  44. />
  45. </div>
  46. <div class="reply-name">
  47. {{ item.name }}
  48. </div>
  49. <div class="reply-time">
  50. {{ item.date }}
  51. </div>
  52. <div
  53. class="reply-content"
  54. v-html="item.flowValue"
  55. />
  56. </el-timeline-item>
  57. </template>
  58. </el-timeline>
  59. <el-timeline v-else class="hc-time-line">
  60. <template
  61. v-for="(item, index) in flowListTask"
  62. :key="index"
  63. >
  64. <el-timeline-item
  65. :class="
  66. item.status == '2'
  67. ? 'success'
  68. : 'primary'
  69. "
  70. size="large"
  71. >
  72. <div class="timeline-item-icon">
  73. <hc-icon
  74. v-if="item.status == '2'"
  75. class="check-icon"
  76. name="check"
  77. />
  78. </div>
  79. <div v-if="!item.isTask" class="reply-name">
  80. {{ item.name }}
  81. </div>
  82. <div v-if="item.isTask">
  83. <div class="reply-name">
  84. {{ item.name }}
  85. <hc-icon
  86. v-if="item.type == 2"
  87. name="links"
  88. class="ml-2"
  89. />
  90. <hc-icon
  91. v-if="item.type == 1"
  92. name="exchange-2"
  93. class="ml-2"
  94. />
  95. <br>
  96. <el-tooltip
  97. placement="right"
  98. effect="light"
  99. :visible="
  100. item.taskDetailvisible
  101. "
  102. >
  103. <template #content>
  104. <el-timeline
  105. class="hc-time-line"
  106. >
  107. <template
  108. v-for="(
  109. item1, index1
  110. ) in item.userList"
  111. :key="index1"
  112. >
  113. <el-timeline-item
  114. :class="
  115. item1.status
  116. === '2'
  117. ? 'success'
  118. : 'primary'
  119. "
  120. size="large"
  121. >
  122. <div
  123. class="timeline-item-icon"
  124. >
  125. <hc-icon
  126. v-if="
  127. item1.status
  128. === '2'
  129. "
  130. class="check-icon"
  131. name="check"
  132. />
  133. </div>
  134. <div
  135. class="reply-name"
  136. >
  137. {{
  138. item1.name
  139. }}
  140. </div>
  141. <div
  142. class="reply-time"
  143. >
  144. {{
  145. item1.date
  146. }}
  147. </div>
  148. <div
  149. class="reply-content"
  150. v-html="
  151. item1.flowValue
  152. "
  153. />
  154. </el-timeline-item>
  155. </template>
  156. </el-timeline>
  157. </template>
  158. <el-link
  159. @mouseenter="
  160. item.taskDetailvisible = true
  161. "
  162. @mouseleave="
  163. item.taskDetailvisible = false
  164. "
  165. >
  166. 点击查看详情
  167. </el-link>
  168. </el-tooltip>
  169. </div>
  170. </div>
  171. <div class="reply-time">
  172. {{ item.date }}
  173. </div>
  174. <div
  175. class="reply-content"
  176. v-html="item.flowValue"
  177. />
  178. </el-timeline-item>
  179. </template>
  180. </el-timeline>
  181. </hc-body>
  182. </div>
  183. <div :id="`hc_task_table_${uuid}`" class="hc-task-table">
  184. <hc-body class="hc-task-body-card" padding="10px">
  185. <div class="hc-task-body-table">
  186. <hc-tab-card
  187. :tabs="tabsData"
  188. :tab-key="tabKey"
  189. @change="tabsChange"
  190. >
  191. <hc-table
  192. v-if="tabKey === '1'"
  193. ref="tableRef"
  194. :column="tableColumn"
  195. :datas="tableData"
  196. :is-stripe="false"
  197. is-new
  198. :index-style="{ width: 60 }"
  199. is-current-row
  200. @row-click="tableRowClick"
  201. >
  202. <template #action="{ row }">
  203. <div
  204. class="hc-task-table-action"
  205. :class="
  206. row.isComment === 1
  207. ? 'is-cur'
  208. : ''
  209. "
  210. @click="rowRemarkClick(row)"
  211. >
  212. <i class="i-iconoir-star-solid" />
  213. </div>
  214. </template>
  215. <template #state="{ row }">
  216. <div class="hc-task-table-state">
  217. <i
  218. v-if="row.status === 1"
  219. class="is-success i-iconoir-check-circle-solid"
  220. />
  221. <i
  222. v-else-if="row.status === 2"
  223. class="is-danger i-iconoir-xmark-circle-solid"
  224. />
  225. <span v-else-if="row.status === 3">审批结束</span>
  226. <i
  227. v-else
  228. class="i-iconoir-help-circle-solid"
  229. />
  230. </div>
  231. </template>
  232. </hc-table>
  233. <div
  234. v-if="tabKey === '2'"
  235. class="hc-task-body-table-form"
  236. >
  237. <template
  238. v-if="
  239. rowInfo.meterType === 1
  240. || rowInfo.meterType === 3
  241. "
  242. >
  243. <div class="title-box">
  244. <div
  245. v-if="
  246. meterApproveOpinion1.projectName
  247. "
  248. class="title"
  249. >
  250. {{
  251. meterApproveOpinion1.projectName
  252. }}
  253. </div>
  254. <div class="text">审批意见</div>
  255. </div>
  256. <div class="name">
  257. 总监理工程师意见:
  258. </div>
  259. <div class="hc-bt-0 input">
  260. <el-input
  261. v-model="
  262. meterApproveOpinion1.chiefSupervisor
  263. "
  264. :autosize="{
  265. minRows: 2,
  266. maxRows: 4,
  267. }"
  268. type="textarea"
  269. />
  270. <div
  271. v-if="
  272. meterApproveOpinion1.chiefSupervisorUserName
  273. "
  274. class="sign-name"
  275. >
  276. <div class="user-name">
  277. {{
  278. meterApproveOpinion1.chiefSupervisorUserName
  279. }}
  280. </div>
  281. <div class="user-time">
  282. {{
  283. meterApproveOpinion1.chiefSupervisorTime
  284. }}
  285. </div>
  286. </div>
  287. </div>
  288. <template
  289. v-if="rowInfo.meterType === 3"
  290. >
  291. <div class="name hc-bt-0">
  292. 监理审核意见:
  293. </div>
  294. <div class="input hc-bt-0 textarea-container">
  295. <el-input
  296. v-model="
  297. meterApproveOpinion1.supervisorAudit
  298. "
  299. :autosize="{
  300. minRows: 2,
  301. maxRows: 4,
  302. }"
  303. type="textarea"
  304. />
  305. <div
  306. v-if="
  307. meterApproveOpinion1.supervisorAuditUserName
  308. "
  309. class="sign-name"
  310. >
  311. <div class="user-name">
  312. {{
  313. meterApproveOpinion1.supervisorAuditUserName
  314. }}
  315. </div>
  316. <div class="user-time">
  317. {{
  318. meterApproveOpinion1.supervisorAuditTime
  319. }}
  320. </div>
  321. </div>
  322. <div v-if="!meterApproveOpinion1.supervisorAudit" class="suffix-icon">
  323. <span>(不填写默认为拟同意)</span>
  324. </div>
  325. </div>
  326. </template>
  327. <div class="input-box">
  328. <div class="box">
  329. <div class="name hc-bt-0">
  330. 工程建设部意见:
  331. </div>
  332. <div
  333. class="input hc-bt-0 textarea-container"
  334. >
  335. <el-input
  336. v-model="
  337. meterApproveOpinion1.projectBuild
  338. "
  339. :autosize="{
  340. minRows: 2,
  341. maxRows: 4,
  342. }"
  343. type="textarea"
  344. />
  345. <div
  346. v-if="
  347. meterApproveOpinion1.projectBuildUserName
  348. "
  349. class="sign-name"
  350. >
  351. <div class="user-name">
  352. {{
  353. meterApproveOpinion1.projectBuildUserName
  354. }}
  355. </div>
  356. <div class="user-time">
  357. {{
  358. meterApproveOpinion1.projectBuildTime
  359. }}
  360. </div>
  361. </div>
  362. <div v-if="!meterApproveOpinion1.projectBuild" class="suffix-icon">
  363. <span>(不填写默认为拟同意)</span>
  364. </div>
  365. </div>
  366. </div>
  367. <div class="box">
  368. <div class="name hc-bt-0 no-b">
  369. 分管领导意见:
  370. </div>
  371. <div
  372. class="input no-b hc-bt-0 textarea-container"
  373. >
  374. <el-input
  375. v-model="
  376. meterApproveOpinion1.projectBuildLeader
  377. "
  378. :autosize="{
  379. minRows: 2,
  380. maxRows: 4,
  381. }"
  382. type="textarea"
  383. />
  384. <div
  385. v-if="
  386. meterApproveOpinion1.projectBuildLeaderUserName
  387. "
  388. class="sign-name"
  389. >
  390. <div class="user-name">
  391. {{
  392. meterApproveOpinion1.projectBuildLeaderUserName
  393. }}
  394. </div>
  395. <div class="user-time">
  396. {{
  397. meterApproveOpinion1.projectBuildLeaderTime
  398. }}
  399. </div>
  400. </div>
  401. <div v-if="!meterApproveOpinion1.projectBuildLeader" class="suffix-icon">
  402. <span>(不填写默认为拟同意)</span>
  403. </div>
  404. </div>
  405. </div>
  406. </div>
  407. <div
  408. v-if="rowInfo.meterType === 1"
  409. class="input-box"
  410. >
  411. <div class="box">
  412. <div class="name hc-bt-0">
  413. 安全管理部意见:
  414. </div>
  415. <div
  416. class="input hc-bt-0 textarea-container"
  417. >
  418. <el-input
  419. v-model="
  420. meterApproveOpinion1.safetyManager
  421. "
  422. :autosize="{
  423. minRows: 2,
  424. maxRows: 4,
  425. }"
  426. type="textarea"
  427. />
  428. <div
  429. v-if="
  430. meterApproveOpinion1.safetyManagerUserName
  431. "
  432. class="sign-name"
  433. >
  434. <div class="user-name">
  435. {{
  436. meterApproveOpinion1.safetyManagerUserName
  437. }}
  438. </div>
  439. <div class="user-time">
  440. {{
  441. meterApproveOpinion1.safetyManagerTime
  442. }}
  443. </div>
  444. </div>
  445. <div v-if="!meterApproveOpinion1.safetyManager" class="suffix-icon">
  446. <span>(不填写默认为拟同意)</span>
  447. </div>
  448. </div>
  449. </div>
  450. <div class="box">
  451. <div class="name no-b hc-bt-0">
  452. 分管领导意见:
  453. </div>
  454. <div
  455. class="input no-b hc-bt-0 textarea-container"
  456. >
  457. <el-input
  458. v-model="
  459. meterApproveOpinion1.safetyManagerLeader
  460. "
  461. :autosize="{
  462. minRows: 2,
  463. maxRows: 4,
  464. }"
  465. type="textarea"
  466. />
  467. <div
  468. v-if="
  469. meterApproveOpinion1.safetyManagerLeaderUserName
  470. "
  471. class="sign-name"
  472. >
  473. <div class="user-name">
  474. {{
  475. meterApproveOpinion1.safetyManagerLeaderUserName
  476. }}
  477. </div>
  478. <div class="user-time">
  479. {{
  480. meterApproveOpinion1.safetyManagerLeaderTime
  481. }}
  482. </div>
  483. </div>
  484. <div v-if="!meterApproveOpinion1.safetyManagerLeader" class="suffix-icon">
  485. <span>(不填写默认为拟同意)</span>
  486. </div>
  487. </div>
  488. </div>
  489. </div>
  490. <div class="input-box">
  491. <div class="box">
  492. <div class="name hc-bt-0">
  493. 合同部意见:
  494. </div>
  495. <div
  496. class="input hc-bt-0 textarea-container"
  497. >
  498. <el-input
  499. v-model="
  500. meterApproveOpinion1.contractDept
  501. "
  502. :autosize="{
  503. minRows: 2,
  504. maxRows: 4,
  505. }"
  506. type="textarea"
  507. />
  508. <div
  509. v-if="
  510. meterApproveOpinion1.contractDeptUserName
  511. "
  512. class="sign-name"
  513. >
  514. <div class="user-name">
  515. {{
  516. meterApproveOpinion1.contractDeptUserName
  517. }}
  518. </div>
  519. <div class="user-time">
  520. {{
  521. meterApproveOpinion1.contractDeptTime
  522. }}
  523. </div>
  524. </div>
  525. <div v-if="!meterApproveOpinion1.contractDept" class="suffix-icon">
  526. <span>(不填写默认为拟同意)</span>
  527. </div>
  528. </div>
  529. </div>
  530. <div class="box">
  531. <div class="name no-b hc-bt-0">
  532. 分管领导意见:
  533. </div>
  534. <div
  535. class="input no-b hc-bt-0 textarea-container"
  536. >
  537. <el-input
  538. v-model="
  539. meterApproveOpinion1.contractDeptLeader
  540. "
  541. :autosize="{
  542. minRows: 2,
  543. maxRows: 4,
  544. }"
  545. type="textarea"
  546. />
  547. <div
  548. v-if="
  549. meterApproveOpinion1.contractDeptLeaderUserName
  550. "
  551. class="sign-name"
  552. >
  553. <div class="user-name">
  554. {{
  555. meterApproveOpinion1.contractDeptLeaderUserName
  556. }}
  557. </div>
  558. <div class="user-time">
  559. {{
  560. meterApproveOpinion1.contractDeptLeaderTime
  561. }}
  562. </div>
  563. </div>
  564. <div v-if="!meterApproveOpinion1.contractDeptLeader" class="suffix-icon">
  565. <span>(不填写默认为拟同意)</span>
  566. </div>
  567. </div>
  568. </div>
  569. </div>
  570. <div class="name hc-bt-0">
  571. 总经理意见:
  572. </div>
  573. <div class="input hc-bt-0 textarea-container">
  574. <el-input
  575. v-model="
  576. meterApproveOpinion1.generalManager
  577. "
  578. :autosize="{
  579. minRows: 2,
  580. maxRows: 4,
  581. }"
  582. type="textarea"
  583. />
  584. <div
  585. v-if="
  586. meterApproveOpinion1.generalManagerUserName
  587. "
  588. class="sign-name"
  589. >
  590. <div class="user-name">
  591. {{
  592. meterApproveOpinion1.generalManagerUserName
  593. }}
  594. </div>
  595. <div class="user-time">
  596. {{
  597. meterApproveOpinion1.generalManagerTime
  598. }}
  599. </div>
  600. </div>
  601. <div v-if="!meterApproveOpinion1.generalManager" class="suffix-icon">
  602. <span>(不填写默认为拟同意)</span>
  603. </div>
  604. </div>
  605. <div class="name no-b hc-bt-0">
  606. 董事长意见:
  607. </div>
  608. <div class="input no-b hc-bt-0 textarea-container">
  609. <el-input
  610. v-model="
  611. meterApproveOpinion1.chiefExecutive
  612. "
  613. :autosize="{
  614. minRows: 2,
  615. maxRows: 4,
  616. }"
  617. type="textarea"
  618. />
  619. <div
  620. v-if="
  621. meterApproveOpinion1.chiefExecutiveUserName
  622. "
  623. class="sign-name"
  624. >
  625. <div class="user-name">
  626. {{
  627. meterApproveOpinion1.chiefExecutiveUserName
  628. }}
  629. </div>
  630. <div class="user-time">
  631. {{
  632. meterApproveOpinion1.chiefExecutiveTime
  633. }}
  634. </div>
  635. </div>
  636. <div v-if="!meterApproveOpinion1.chiefExecutive" class="suffix-icon">
  637. <span>(不填写默认为同意)</span>
  638. </div>
  639. </div>
  640. </template>
  641. <template v-else>
  642. <hc-empty />
  643. </template>
  644. </div>
  645. </hc-tab-card>
  646. </div>
  647. <div
  648. v-if="!isNullES(detailInfo.opinionType)"
  649. class="hc-task-body-tip hc-flex h-30px"
  650. >
  651. <span class="mr-14px">实际支付总金额:{{ reportAllMoney }}元</span>
  652. <span v-if="detailInfo.opinionType != 4">本期审计审核进度款:{{ progressMoney }}元</span>
  653. </div>
  654. </hc-body>
  655. </div>
  656. <div
  657. :id="`hc_task_form_${uuid}`"
  658. class="hc-task-form"
  659. :class="`is-tab-${taskTabsKey}`"
  660. >
  661. <hc-body class="hc-task-body-card" padding="10px" scrollbar>
  662. <HcTaskForm
  663. ref="htmlFormRef"
  664. :table="tableInfo"
  665. :info="rowInfo"
  666. :detail="detailInfo"
  667. :is-edit="tabsKey === 1"
  668. @finish="taskFormFinish"
  669. @tab-tap="taskTabsClick"
  670. />
  671. </hc-body>
  672. </div>
  673. </div>
  674. </div>
  675. <template #footer>
  676. <div class="hc-task-dialog-footer">
  677. <el-button :disabled="tabsKey !== 1" @click="rejectionClick">
  678. 驳回审批
  679. </el-button>
  680. <el-button
  681. v-if="rowInfo.meterType > 0 && rowInfo.meterType <= 3"
  682. type="warning"
  683. :loading="rowViewLoading"
  684. @click="rowViewPdf"
  685. >
  686. 查看报表
  687. </el-button>
  688. <el-button
  689. type="primary"
  690. :loading="confirmLoading"
  691. :disabled="tabsKey !== 1"
  692. @click="confirmClick"
  693. >
  694. 同意审批
  695. </el-button>
  696. </div>
  697. </template>
  698. </hc-new-dialog>
  699. <!-- 批注 -->
  700. <HcTaskNotes
  701. v-model="isNotesShow"
  702. :table="tableNoteInfo"
  703. :info="rowInfo"
  704. :is-edit="tabsKey === 1"
  705. @finish="taskNotesFinish"
  706. />
  707. <!-- 驳回 -->
  708. <HcRepealForm
  709. v-model="isRepealShow"
  710. :info="rowInfo"
  711. @finish="taskRepealFinish"
  712. />
  713. <!-- 短信认证 -->
  714. <HcSmsAuth
  715. :loading="SMSAuthLoading"
  716. :show="SMSAuthShow"
  717. @cancel="SMSAuthCancel"
  718. @confirm="SMSAuthConfirm"
  719. />
  720. </template>
  721. <script setup>
  722. import { nextTick, ref, watch } from 'vue'
  723. import { useAppStore } from '~src/store'
  724. import { toPdfPage } from '~uti/btn-auth'
  725. import HcTaskForm from './task-form.vue'
  726. import HcTaskNotes from './task-notes.vue'
  727. import HcRepealForm from './repeal-form.vue'
  728. import {
  729. arrUnion,
  730. deepClone,
  731. getArrValue,
  732. getObjValue,
  733. getRandom,
  734. isNullES,
  735. } from 'js-fast-way'
  736. import mainApi from '~api/tasks/hc-data'
  737. import dayjs from 'dayjs'
  738. const props = defineProps({
  739. tabs: {
  740. type: [String, Number],
  741. default: '',
  742. },
  743. row: {
  744. type: Object,
  745. default: () => ({}),
  746. },
  747. })
  748. //事件
  749. const emit = defineEmits(['finish', 'close'])
  750. const uuid = getRandom(4)
  751. const useAppState = useAppStore()
  752. const projectId = ref(useAppState.getProjectId || '')
  753. const contractId = ref(useAppState.getContractId || '')
  754. //双向绑定
  755. // eslint-disable-next-line no-undef
  756. const isShow = defineModel('modelValue', {
  757. default: false,
  758. })
  759. //监听
  760. const tableRef = ref(null)
  761. const tabsKey = ref(Number(props.tabs))
  762. const rowInfo = ref(props.row)
  763. const isOverTask = ref(false)//是否结束任务
  764. watch(
  765. () => [props.tabs, props.row],
  766. ([key, row]) => {
  767. tabsKey.value = Number(key)
  768. rowInfo.value = row
  769. const { taskStatusName } = rowInfo.value
  770. isOverTask.value = taskStatusName === '已审批'
  771. },
  772. {
  773. immediate: true,
  774. deep: true,
  775. },
  776. )
  777. //监听显示
  778. watch(isShow, (val) => {
  779. if (val) {
  780. checkSmsCode()
  781. setTaskInfo()
  782. setSplitRef()
  783. }
  784. })
  785. //初始化设置拖动分割线
  786. const setSplitRef = () => {
  787. //配置参考: https://split.js.org/#/?direction=vertical&snapOffset=0
  788. nextTick(() => {
  789. window.$split(['#hc_task_table_' + uuid, '#hc_task_form_' + uuid], {
  790. sizes: [50, 50],
  791. snapOffset: 0,
  792. minSize: [50, 500],
  793. })
  794. })
  795. }
  796. //设置任务信息
  797. const setTaskInfo = () => {
  798. //meterType:1中间,2材料,3开工,4变更令
  799. const { meterType } = rowInfo.value
  800. if (meterType === 1) {
  801. tableColumn.value = middlepayTableColumn.value
  802. } else if (meterType === 2) {
  803. tableColumn.value = materialTableColumn.value
  804. } else if (meterType === 3) {
  805. tableColumn.value = startWorkTableColumn.value
  806. } else if (meterType === 4) {
  807. tableColumn.value = alterTableColumn.value
  808. } else {
  809. tableColumn.value = []
  810. }
  811. getTableDetail()
  812. }
  813. //获取数据详情
  814. const detailInfo = ref({})
  815. const reportAllMoney = ref('0')
  816. const progressMoney = ref('0')
  817. const meterApproveOpinion1 = ref({})
  818. const meterApproveOpinion2 = ref({})
  819. const isLoading = ref(false)
  820. const getTableDetail = async () => {
  821. isLoading.value = true
  822. confirmLoading.value = true
  823. //获取数据
  824. const { data } = await mainApi.getDetail(rowInfo.value.id)
  825. const infoData = getObjValue(data)
  826. const { taskProcessInfo, taskCenterDataInfo } = infoData
  827. tableData.value = getArrValue(taskCenterDataInfo)
  828. flowList.value = getArrValue(taskProcessInfo)
  829. reportAllMoney.value = infoData.reportAllMoney
  830. progressMoney.value = infoData.progressMoney
  831. detailInfo.value = infoData
  832. if (rowInfo.value?.fixedFlowId) {
  833. const list = [...flowList.value]
  834. let firstarr = list.slice(0, 1)
  835. let taskList = list.slice(1, list.length)
  836. taskList.forEach((ele) => {
  837. ele.name = ele.taskBranchName
  838. ele.status = ele.taskBranchStatus
  839. ele.type = ele.taskBranchType
  840. ele.isTask = true
  841. })
  842. flowListTask.value = arrUnion(firstarr, taskList)
  843. }
  844. //意见信息
  845. const meterRes = getObjValue(data.meterApproveOpinion)
  846. meterApproveOpinion2.value = deepClone(meterRes)
  847. meterApproveOpinion1.value = meterRes
  848. if (isOverTask.value) {
  849. //设置默认值
  850. setDefaultOpinion()
  851. }
  852. //默认选中第一行
  853. let info = {}
  854. if (tableData.value.length > 0) {
  855. info = tableData.value[0]
  856. }
  857. await nextTick(() => {
  858. tableInfo.value = info
  859. tableRef.value?.tableRef?.setCurrentRow(info)
  860. })
  861. //关闭加载状态
  862. isLoading.value = false
  863. confirmLoading.value = false
  864. }
  865. const setDefaultValue = (field, defaultOpinion) => {
  866. if (isNullES(meterApproveOpinion1.value[field])) {
  867. //meterApproveOpinion2.value[field] = defaultOpinion
  868. meterApproveOpinion1.value[field] = defaultOpinion
  869. meterApproveOpinion1.value[`${field}Default`] = true
  870. } else if (meterApproveOpinion1.value[field] === defaultOpinion) {
  871. meterApproveOpinion1.value[`${field}Default`] = true
  872. } else {
  873. meterApproveOpinion1.value[`${field}Default`] = false
  874. }
  875. }
  876. const setDefaultOpinion = () => {
  877. const defaultOpinion = '拟同意'
  878. //setDefaultValue('chiefSupervisor', defaultOpinion)
  879. setDefaultValue('supervisorAudit', defaultOpinion)
  880. setDefaultValue('projectBuild', defaultOpinion)
  881. setDefaultValue('projectBuildLeader', defaultOpinion)
  882. setDefaultValue('safetyManager', defaultOpinion)
  883. setDefaultValue('safetyManagerLeader', defaultOpinion)
  884. setDefaultValue('contractDept', defaultOpinion)
  885. setDefaultValue('contractDeptLeader', defaultOpinion)
  886. setDefaultValue('generalManager', defaultOpinion)
  887. // 注意:这里修改为了与其他默认意见一致
  888. setDefaultValue('chiefExecutive', '同意')
  889. }
  890. //流程信息,1待审批,2已审批
  891. const flowList = ref([])
  892. //type为1流程审批,type为2是平行审批
  893. const flowListTask = ref([
  894. {
  895. name: 'PCT',
  896. date: '2024-03-01 09:27:17',
  897. status: '2',
  898. flowValue: '上报',
  899. isTask: false,
  900. },
  901. {
  902. name: '"222"',
  903. date: '',
  904. status: '2',
  905. flowValue: '',
  906. type: 1,
  907. isTask: true,
  908. },
  909. {
  910. name: '"111"',
  911. date: '',
  912. status: '1',
  913. flowValue: '',
  914. type: 2,
  915. isTask: true,
  916. },
  917. ])
  918. const taskDetailList = ref([])
  919. //中间计量单的表格数据
  920. const middlepayTableColumn = ref([
  921. { key: 'action', name: '批注', width: 45, align: 'center' },
  922. { key: 'meterNumber', name: '计量单编号' },
  923. { key: 'meterMoney', name: '计量金额', width: 100 },
  924. { key: 'engineerDivide', name: '工程划分' },
  925. {
  926. key: 'state',
  927. name: '审批状态',
  928. fixed: 'right',
  929. width: 70,
  930. align: 'center',
  931. },
  932. ])
  933. //开工预付款计量单的表格数据
  934. const startWorkTableColumn = ref([
  935. { key: 'action', name: '批注', width: 45, align: 'center' },
  936. { key: 'periodName', name: '计量期', minWidth: 100, align: 'center' },
  937. { key: 'businessDate', name: '业务日期', width: 160, align: 'center' },
  938. { key: 'meterMoney', name: '计量金额', width: 100, align: 'center' },
  939. {
  940. key: 'state',
  941. name: '审批状态',
  942. fixed: 'right',
  943. width: 70,
  944. align: 'center',
  945. },
  946. ])
  947. //变更令的表格数据
  948. const alterTableColumn = ref([
  949. { key: 'action', name: '批注', width: 45, align: 'center' },
  950. { key: 'changeNumber', name: '变更编号', minWidth: 120, align: 'center' },
  951. { key: 'changeName', name: '变更名称', minWidth: 120, align: 'center' },
  952. { key: 'changeMoney', name: '变更金额', width: 100, align: 'center' },
  953. {
  954. key: 'changeApprovalDate',
  955. name: '变更批复日期',
  956. width: 160,
  957. align: 'center',
  958. },
  959. {
  960. key: 'state',
  961. name: '审批状态',
  962. fixed: 'right',
  963. width: 70,
  964. align: 'center',
  965. },
  966. ])
  967. //材料计量单的表格数据
  968. const materialTableColumn = ref([
  969. { key: 'action', name: '批注', width: 45, align: 'center' },
  970. { key: 'periodName', name: '计量期', minWidth: 100, align: 'center' },
  971. {
  972. key: 'contractMaterialName',
  973. name: '合同材料',
  974. minWidth: 120,
  975. align: 'center',
  976. },
  977. {
  978. key: 'materialArriveNumber',
  979. name: '材料到场编号',
  980. width: 120,
  981. align: 'center',
  982. },
  983. { key: 'meterMoney', name: '计量金额', width: 100, align: 'center' },
  984. {
  985. key: 'state',
  986. name: '审批状态',
  987. fixed: 'right',
  988. width: 70,
  989. align: 'center',
  990. },
  991. ])
  992. //表格数据
  993. const tableColumn = ref([])
  994. const tableData = ref([])
  995. //表格行被点击
  996. const tableInfo = ref({})
  997. const tableRowClick = ({ row }) => {
  998. tableInfo.value = row
  999. }
  1000. //批注, isComment 是否已批注,1=是,0=否
  1001. const isNotesShow = ref(false)
  1002. const tableNoteInfo = ref({})
  1003. const rowRemarkClick = (row) => {
  1004. tableNoteInfo.value = row
  1005. nextTick(() => {
  1006. isNotesShow.value = true
  1007. })
  1008. }
  1009. //批注完成
  1010. const taskNotesFinish = () => {
  1011. getTableDetail()
  1012. }
  1013. //单条审批
  1014. const taskFormFinish = () => {
  1015. getTableDetail()
  1016. }
  1017. //确认审批
  1018. const confirmLoading = ref(false)
  1019. const confirmClick = () => {
  1020. const ShowAuth = isCheckSmsCodeTime()
  1021. SMSAuthShow.value = ShowAuth
  1022. //免短信验证
  1023. if (!ShowAuth) SMSAuthConfirm()
  1024. }
  1025. //驳回审批
  1026. const isRepealShow = ref(false)
  1027. const rejectionClick = async () => {
  1028. isRepealShow.value = true
  1029. }
  1030. //驳回完成
  1031. const taskRepealFinish = () => {
  1032. emit('finish')
  1033. cancelClick()
  1034. }
  1035. //取消审批
  1036. const cancelClick = () => {
  1037. isShow.value = false
  1038. isLoading.value = false
  1039. confirmLoading.value = false
  1040. tableColumn.value = []
  1041. tableData.value = []
  1042. tableInfo.value = {}
  1043. emit('close')
  1044. }
  1045. //短信验证有效期
  1046. const smsCodeTime = ref('')
  1047. const checkSmsCode = async () => {
  1048. const { data } = await mainApi.checkSmsCode()
  1049. smsCodeTime.value = data ? data : ''
  1050. }
  1051. //验证短信有效期
  1052. const isCheckSmsCodeTime = () => {
  1053. const smsTime = smsCodeTime.value
  1054. if (isNullES(smsTime)) {
  1055. return true
  1056. } else {
  1057. const toDayTime = dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss')
  1058. return dayjs(smsTime).isBefore(toDayTime)
  1059. }
  1060. }
  1061. //短信验证
  1062. const SMSAuthLoading = ref(false)
  1063. const SMSAuthShow = ref(false)
  1064. const htmlFormRef = ref(null)
  1065. const SMSAuthConfirm = async () => {
  1066. confirmLoading.value = true
  1067. const tableData = htmlFormRef.value?.getTableForm()
  1068. const { error, code, msg } = await mainApi.taskApprove({
  1069. tableData: tableData,
  1070. taskId: rowInfo.value.id,
  1071. projectId: projectId.value,
  1072. contractId: contractId.value,
  1073. meterApproveOpinion: meterApproveOpinion2.value,
  1074. })
  1075. if (!error && code === 200) {
  1076. window.$message.success('审批成功')
  1077. await checkSmsCode()
  1078. confirmLoading.value = false
  1079. emit('finish')
  1080. SMSAuthCancel()
  1081. cancelClick()
  1082. } else {
  1083. confirmLoading.value = false
  1084. window.$message.error(msg ?? '审批失败')
  1085. }
  1086. }
  1087. const SMSAuthCancel = () => {
  1088. SMSAuthShow.value = false
  1089. }
  1090. //选项卡被切换
  1091. const taskTabsKey = ref('key1')
  1092. const taskTabsClick = (key) => {
  1093. taskTabsKey.value = key
  1094. }
  1095. //查看报表
  1096. const rowViewLoading = ref(false)
  1097. const rowViewPdf = async () => {
  1098. const { type, reportId } = detailInfo.value
  1099. if (isNullES(reportId)) {
  1100. window.$message.warning('参数异常')
  1101. return
  1102. }
  1103. rowViewLoading.value = true
  1104. const { code, msg, data } = await mainApi.taskMeterPdfInfo({
  1105. reportId: reportId,
  1106. type: type,
  1107. taskType: 10,
  1108. taskId: rowInfo.value.id,
  1109. })
  1110. rowViewLoading.value = false
  1111. if (code === 200 && !isNullES(data)) {
  1112. window.$message.success('操作成功')
  1113. toPdfPage(data)
  1114. } else {
  1115. window.$message.error(msg ?? '操作失败')
  1116. }
  1117. }
  1118. //选项卡
  1119. const tabKey = ref('1')
  1120. const tabsData = [
  1121. { key: '2', name: '意见信息' },
  1122. { key: '1', name: '计量单信息' },
  1123. ]
  1124. const tabsChange = ({ key }) => {
  1125. tabKey.value = key
  1126. }
  1127. </script>
  1128. <style lang="scss" scoped>
  1129. .textarea-container {
  1130. position: relative;
  1131. }
  1132. .suffix-icon {
  1133. position: absolute;
  1134. bottom: 8px;
  1135. right: 10px;
  1136. font-size: 14px;
  1137. color: #888;
  1138. }
  1139. .hc-task-name {
  1140. font-weight: bold;
  1141. color: #1a1a1a;
  1142. padding-bottom: 10px;
  1143. border-bottom: 1px solid #f5f5f5;
  1144. }
  1145. .hc-task-body {
  1146. height: calc(100% - 27px);
  1147. .hc-task-time {
  1148. position: relative;
  1149. height: 100%;
  1150. flex-shrink: 0;
  1151. width: 170px;
  1152. }
  1153. .hc-task-table,
  1154. .hc-task-form {
  1155. position: relative;
  1156. height: 100%;
  1157. flex: 1;
  1158. flex-basis: auto;
  1159. }
  1160. .hc-task-table {
  1161. border-left: 1px solid #e5e5e5;
  1162. }
  1163. }
  1164. //表格图标
  1165. .hc-task-table-action,
  1166. .hc-task-table-state {
  1167. position: relative;
  1168. display: flex;
  1169. justify-content: center;
  1170. align-items: center;
  1171. cursor: pointer;
  1172. font-size: 20px;
  1173. color: #929293;
  1174. i {
  1175. display: inline-flex;
  1176. }
  1177. }
  1178. //表格批注
  1179. .hc-task-table-action.is-cur {
  1180. color: #f2b90b;
  1181. }
  1182. //表格状态
  1183. .hc-task-table-state {
  1184. .is-success {
  1185. color: #25a62d;
  1186. }
  1187. .is-danger {
  1188. color: #f5221d;
  1189. }
  1190. span {
  1191. color: #1a1a1a;
  1192. }
  1193. }
  1194. //弹窗底部
  1195. .hc-task-dialog-footer {
  1196. position: relative;
  1197. text-align: center;
  1198. }
  1199. </style>
  1200. <style lang="scss">
  1201. .hc-task-body-card {
  1202. background: #f7f7f7;
  1203. .el-scrollbar__bar.is-vertical {
  1204. right: -8px;
  1205. }
  1206. .hc-task-body-table {
  1207. position: relative;
  1208. height: calc(100% - 30px);
  1209. .hc-task-body-table-form {
  1210. position: relative;
  1211. height: 100%;
  1212. overflow: auto;
  1213. .title-box {
  1214. position: relative;
  1215. text-align: center;
  1216. margin-bottom: 10px;
  1217. .title {
  1218. font-size: 18px;
  1219. margin-bottom: 20px;
  1220. }
  1221. .text {
  1222. font-size: 15px;
  1223. }
  1224. }
  1225. .text-box {
  1226. position: relative;
  1227. border: 1px solid #4b4b4b;
  1228. padding: 8px 3px;
  1229. display: flex;
  1230. align-items: center;
  1231. font-size: 12px;
  1232. .content {
  1233. position: relative;
  1234. flex: 1;
  1235. padding-right: 20px;
  1236. }
  1237. .sign-name {
  1238. position: relative;
  1239. .user-time {
  1240. margin-top: 10px;
  1241. }
  1242. }
  1243. }
  1244. .name {
  1245. position: relative;
  1246. display: flex;
  1247. align-items: center;
  1248. font-size: 13px;
  1249. border: 1px solid #4b4b4b;
  1250. background: #eef3f7;
  1251. padding: 8px 3px;
  1252. }
  1253. .input {
  1254. position: relative;
  1255. border: 1px solid #4b4b4b;
  1256. padding: 2px;
  1257. }
  1258. .input-box {
  1259. position: relative;
  1260. display: flex;
  1261. .box {
  1262. position: relative;
  1263. flex: 1;
  1264. display: flex;
  1265. flex-direction: column;
  1266. .name {
  1267. flex-shrink: 0;
  1268. }
  1269. .text-box {
  1270. flex: 1;
  1271. flex-basis: auto;
  1272. }
  1273. }
  1274. .no-b {
  1275. border-left: 0;
  1276. }
  1277. }
  1278. .hc-bt-0 {
  1279. border-top: 0;
  1280. }
  1281. .hc-bb-0 {
  1282. border-bottom: 0;
  1283. }
  1284. }
  1285. }
  1286. .hc-task-body-tip {
  1287. color: red;
  1288. }
  1289. }
  1290. .input{
  1291. .sign-name{
  1292. position: absolute;
  1293. top:15px;
  1294. right: 10px;
  1295. font-size: smaller;
  1296. }
  1297. }
  1298. //html表单模式
  1299. .hc-task-body .hc-task-form.is-tab-key3 .hc-task-body-card {
  1300. .el-scrollbar__view {
  1301. height: 100%;
  1302. }
  1303. .hc-task-form-body {
  1304. height: 100%;
  1305. .el-tabs {
  1306. height: 100%;
  1307. .el-tabs__content {
  1308. height: calc(100% - 39px);
  1309. #pane-key3 {
  1310. height: 100%;
  1311. }
  1312. }
  1313. }
  1314. }
  1315. .hc-task-html-form-body {
  1316. height: 100%;
  1317. .hc-table-form-data-item .el-scrollbar__view {
  1318. height: auto;
  1319. }
  1320. }
  1321. }
  1322. </style>