TaskOrderDetailDialog.vue 99 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941
  1. <template>
  2. <!-- 主内容区域 -->
  3. <div :class="{ 'app-container': inPageMode }">
  4. <!-- 页面模式下的操作按钮 -->
  5. <div v-if="inPageMode" class="mb-4">
  6. <div class="flex justify-between items-center">
  7. <div v-if="taskOrderDetail">
  8. <el-button
  9. type="primary"
  10. @click="openModifyTimeDialog"
  11. :disabled="canNotModify"
  12. >修改检验时间</el-button
  13. >
  14. <el-button
  15. type="primary"
  16. @click="handleModifyTaskOrder"
  17. :disabled="canNotModify"
  18. >修改任务单</el-button
  19. >
  20. <el-button
  21. type="danger"
  22. @click="openVoidTaskDialog"
  23. :disabled="canNotModify"
  24. >作废任务单</el-button
  25. >
  26. <el-button
  27. type="success"
  28. @click="openCheckerSelectionDialog"
  29. :disabled="isTaskCancelled || isTaskCompleted"
  30. v-if="checkRole(['Pipeline Director','admin'])"
  31. >修改检验人员</el-button
  32. >
  33. <!-- <el-button v-if="props.type !== 'checker'" type="success" @click="openCheckerSelectionDialog" :disabled="isTaskCancelled">修改检验人员</el-button>-->
  34. <el-button
  35. type="success"
  36. @click="handleModifyManager"
  37. :disabled="isTaskCancelled || isTaskCompleted"
  38. v-if="checkRole(['Pipeline Director','admin'])"
  39. >修改项目负责人</el-button
  40. >
  41. <el-button
  42. type="primary"
  43. plain
  44. @click="handleAddSafetyRecord"
  45. :disabled="isTaskCancelled || isTaskCompleted"
  46. >添加安全记录检查</el-button
  47. >
  48. <el-button
  49. type="primary"
  50. plain
  51. @click="() => handleServiceOrder(100)"
  52. :disabled="isTaskCancelled"
  53. >服务单/受理单</el-button
  54. >
  55. <el-button
  56. type="primary"
  57. plain
  58. @click="() => handleInspectionStatusAddReport(1000)"
  59. :disabled="isTaskCancelled"
  60. >检验情况告知</el-button
  61. >
  62. <el-button type="danger" @click="handlePushSettlementSystem"
  63. :disabled="canPushSettlementSystem">推送结算系统</el-button>
  64. </div>
  65. </div>
  66. </div>
  67. <!-- 任务单详情、异常信息、审核、设备清单 -->
  68. <div v-if="!taskOrderDetail" class="loading-text">
  69. 无法加载任务详情。
  70. </div>
  71. <div v-else>
  72. <ContentWrap class="mb-4" title="任务单详情">
  73. <div class="tip custom-block">单位信息</div>
  74. <el-descriptions :column="3" border>
  75. <el-descriptions-item label="任务单号">
  76. {{ taskOrderDetail.orderNo }}
  77. </el-descriptions-item>
  78. <el-descriptions-item label="检验类别">
  79. {{ PressurePipeCheckTypeMap[taskOrderDetail.checkType] || '-' }}
  80. </el-descriptions-item>
  81. <el-descriptions-item label="检验设备数量">
  82. {{ taskOrderDetail.equipNum || '-' }}
  83. </el-descriptions-item>
  84. <el-descriptions-item label="申请单位名称">
  85. {{ taskOrderDetail.unitName || '-' }}
  86. </el-descriptions-item>
  87. <el-descriptions-item label="使用单位名称">
  88. {{ taskOrderDetail.useUnitName || '-' }}
  89. </el-descriptions-item>
  90. <el-descriptions-item label="检验日期">
  91. {{ Array.isArray(taskOrderDetail.checkDate) ? formatArrayDate(taskOrderDetail.checkDate) : taskOrderDetail.checkDate || '-' }}
  92. </el-descriptions-item>
  93. <el-descriptions-item label="申请单位地址">
  94. {{ taskOrderDetail.unitAddress || '-' }}
  95. </el-descriptions-item>
  96. <el-descriptions-item label="使用单位地址">
  97. {{ taskOrderDetail.useUnitAddress || '-' }}
  98. </el-descriptions-item>
  99. <el-descriptions-item label="收费性质">
  100. {{ PressureFeeNatureMap[taskOrderDetail.feeNature] || '-' }}
  101. </el-descriptions-item>
  102. <el-descriptions-item label="收费形式">
  103. {{ PressureFeeTypeMap[taskOrderDetail.feeType] || '-' }}
  104. </el-descriptions-item>
  105. <!-- <el-descriptions-item label="收费金额">
  106. {{ taskOrderDetail.payAmount || '-' }}
  107. </el-descriptions-item> -->
  108. <el-descriptions-item label="收费金额">
  109. {{ taskOrderDetail.payAmount || '-' }}
  110. </el-descriptions-item>
  111. <el-descriptions-item label="应收法定金额">
  112. {{ taskOrderDetail.shouldAmount || 0 }}
  113. </el-descriptions-item>
  114. <el-descriptions-item label="服务收费金额">
  115. {{ taskOrderDetail.serviceAmount || 0 }}
  116. </el-descriptions-item>
  117. <el-descriptions-item label="免征费用">
  118. {{ taskOrderDetail.reduceFee || 0 }}
  119. </el-descriptions-item>
  120. <!-- <el-descriptions-item label="是否已交费">-->
  121. <!-- {{ taskOrderDetail.isPay === 1?'是':'否' }}-->
  122. <!-- </el-descriptions-item>-->
  123. <!-- <el-descriptions-item label="业务受理人">-->
  124. <!-- <el-tag v-if="taskOrderDetail.acceptUser" effect="light" :closable="false">-->
  125. <!-- {{-->
  126. <!-- taskOrderDetail.acceptUser-->
  127. <!-- ? `${taskOrderDetail.acceptUser.nickname} (${taskOrderDetail.acceptUser.employeeNo})`-->
  128. <!-- : '-'-->
  129. <!-- }}-->
  130. <!-- </el-tag>-->
  131. <!-- <span v-else>-</span>-->
  132. <!-- </el-descriptions-item>-->
  133. <el-descriptions-item label="主检员">
  134. <div v-if="taskOrderDetail.manager">
  135. <el-tag type="primary">
  136. {{ taskOrderDetail.manager ? `${taskOrderDetail.manager.nickname} (${taskOrderDetail.manager.employeeNo})` : '-' }}
  137. </el-tag>
  138. </div>
  139. <span v-else>-</span>
  140. </el-descriptions-item>
  141. <el-descriptions-item label="检验人员">
  142. <div
  143. v-if="taskOrderDetail.teamItemList && taskOrderDetail.teamItemList.length > 0">
  144. <div
  145. v-for="(team, teamIndex) in taskOrderDetail.teamItemList"
  146. :key="team.groupTeamId || 'team-' + teamIndex"
  147. style="margin-bottom: 8px">
  148. <div
  149. v-if="taskOrderDetail.teamItemList.length > 1"
  150. style="font-weight: bold; margin-bottom: 4px">
  151. 团队 {{ teamIndex + 1 }}:
  152. </div>
  153. <div
  154. style="display: flex; flex-wrap: wrap; align-items: center; gap: 6px">
  155. <template
  156. v-for="(leader, leaderIdx) in team.leaders"
  157. :key="
  158. leader.id
  159. ? 'leader-' + leader.id
  160. : 'leader-idx-' + leaderIdx + '-' + teamIndex
  161. ">
  162. <el-tag
  163. effect="light"
  164. :closable="false">
  165. <span class="leader-tag">组</span>
  166. {{ leader.nickname }}
  167. </el-tag>
  168. </template>
  169. <template
  170. v-for="(member, memberIdx) in team.members"
  171. :key="
  172. member.id
  173. ? 'member-' + member.id
  174. : 'member-idx-' + memberIdx + '-' + teamIndex
  175. ">
  176. <el-tag effect="light" :closable="false"
  177. >{{ member.nickname
  178. }}({{ member.employeeNo }})</el-tag
  179. >
  180. </template>
  181. <span
  182. v-if="
  183. (!team.leaders || team.leaders.length === 0) &&
  184. (!team.members || team.members.length === 0)
  185. "
  186. style="margin-left: 4px"
  187. >-</span
  188. >
  189. </div>
  190. </div>
  191. </div>
  192. <span v-else>-</span>
  193. </el-descriptions-item>
  194. <!-- <el-descriptions-item label="计划编制人">-->
  195. <!-- <el-tag v-if="taskOrderDetail.scheduleUser" effect="light" :closable="false">-->
  196. <!-- {{-->
  197. <!-- taskOrderDetail.scheduleUser-->
  198. <!-- ? `${taskOrderDetail.scheduleUser.nickname} (${taskOrderDetail.scheduleUser.employeeNo})`-->
  199. <!-- : '-'-->
  200. <!-- }}-->
  201. <!-- </el-tag>-->
  202. <!-- <span v-else>-</span>-->
  203. <!-- </el-descriptions-item>-->
  204. <!-- <el-descriptions-item label="中止检验">-->
  205. <!-- {{ taskOrderDetail.XXX || '-' }}-->
  206. <!-- </el-descriptions-item>-->
  207. <el-descriptions-item label="安全检查记录">
  208. <el-button link type="primary" @click="handleLookSecurityCheck">{{
  209. taskOrderDetail.securityCheckCount
  210. }}</el-button>
  211. </el-descriptions-item>
  212. <el-descriptions-item label="约检联系人">
  213. {{ taskOrderDetail.unitContact || '-' }}
  214. </el-descriptions-item>
  215. <el-descriptions-item label="约检联系人电话">
  216. {{ taskOrderDetail.unitPhone || '-' }}
  217. </el-descriptions-item>
  218. <el-descriptions-item label="备注" :span="2">
  219. {{ taskOrderDetail.remark || '-' }}
  220. </el-descriptions-item>
  221. </el-descriptions>
  222. <!-- <div class="tip custom-block">联系人信息</div>-->
  223. <!-- <el-descriptions :column="3" border>-->
  224. <!-- <el-descriptions-item label="约检联系人">-->
  225. <!-- {{ taskOrderDetail.unitContact || '-' }}-->
  226. <!-- </el-descriptions-item>-->
  227. <!-- <el-descriptions-item label="约检联系人电话">-->
  228. <!-- {{ taskOrderDetail.unitPhone || '-' }}-->
  229. <!-- </el-descriptions-item>-->
  230. <!-- <el-descriptions-item label="约检联系人邮箱">-->
  231. <!-- {{ taskOrderDetail.unitEmail || '-' }}-->
  232. <!-- </el-descriptions-item>-->
  233. <!-- <el-descriptions-item label="电子报告接收人">-->
  234. <!-- {{ taskOrderDetail.recipient || '-' }}-->
  235. <!-- </el-descriptions-item>-->
  236. <!-- <el-descriptions-item label="报告接收人电话">-->
  237. <!-- {{ taskOrderDetail.recipientPhone || '-' }}-->
  238. <!-- </el-descriptions-item>-->
  239. <!-- <el-descriptions-item label="接收人邮箱">-->
  240. <!-- {{ taskOrderDetail.recipientEmail || '-' }}-->
  241. <!-- </el-descriptions-item>-->
  242. <!-- <el-descriptions-item label="缴费联系人">-->
  243. <!-- {{ taskOrderDetail.payerContactName || '-' }}-->
  244. <!-- </el-descriptions-item>-->
  245. <!-- <el-descriptions-item label="缴费人电话">-->
  246. <!-- {{ taskOrderDetail.payerContact || '-' }}-->
  247. <!-- </el-descriptions-item>-->
  248. <!-- <el-descriptions-item label="缴费人邮箱">-->
  249. <!-- {{ taskOrderDetail.payerMail || '-' }}-->
  250. <!-- </el-descriptions-item>-->
  251. <!-- </el-descriptions>-->
  252. </ContentWrap>
  253. <ContentWrap v-if="exceptionInfo.id" title="异常信息">
  254. <el-form
  255. v-if="exceptionInfo.id"
  256. disabled
  257. :model="exceptionInfo"
  258. ref="formRef"
  259. label-width="130px"
  260. class="p-3">
  261. <el-row
  262. v-if="exceptionInfo.id"
  263. class="form-group"
  264. :gutter="24">
  265. <el-col :span="8">
  266. <el-form-item
  267. label="有效日期调整原因"
  268. prop="effectiveDateAdjustReason">
  269. <el-input
  270. v-model="exceptionInfo.effectiveDateAdjustReason"
  271. placeholder="请输入有效日期调整原因" />
  272. </el-form-item>
  273. </el-col>
  274. <el-col :span="8">
  275. <el-form-item
  276. label="受理建议"
  277. prop="acceptSuggeston">
  278. <el-input
  279. v-model="exceptionInfo.acceptSuggeston"
  280. placeholder="请输入受理建议" />
  281. </el-form-item>
  282. </el-col>
  283. <el-col :span="8">
  284. <el-form-item
  285. label="调整有效日期"
  286. prop="adjustEffectiveDate">
  287. <el-date-picker
  288. v-model="exceptionInfo.adjustEffectiveDate"
  289. type="date"
  290. value-format="YYYY-MM-DD"
  291. placeholder="请选择调整有效日期" />
  292. </el-form-item>
  293. </el-col>
  294. <el-col :span="12">
  295. <el-form-item label="情况说明" prop="descrition">
  296. <component
  297. :is="getExceptionItem('descrition', 'descritionAttach')" />
  298. </el-form-item>
  299. </el-col>
  300. <el-col :span="12">
  301. <el-form-item label="重启表" prop="restartTable">
  302. <component
  303. :is="getExceptionItem('restartTable', 'restartTableAttach')" />
  304. </el-form-item>
  305. </el-col>
  306. <el-col :span="12">
  307. <el-form-item label="指令书" prop="instrustionBook">
  308. <component
  309. :is="getExceptionItem('instrustionBook', 'instrustionBookAttach')" />
  310. </el-form-item>
  311. </el-col>
  312. <el-col :span="12">
  313. <el-form-item label="受理回执" prop="acceptReceipt">
  314. <component
  315. :is="getExceptionItem('acceptReceipt', 'acceptReceiptAttach')" />
  316. </el-form-item>
  317. </el-col>
  318. <el-col :span="12">
  319. <el-form-item label="其他" prop="other">
  320. <component
  321. :is="getExceptionItem('other', 'otherAttach')" />
  322. </el-form-item>
  323. </el-col>
  324. <el-col :span="12">
  325. <el-form-item
  326. label="提前检验申请函"
  327. prop="earlyCheckApply">
  328. <component
  329. :is="getExceptionItem('earlyCheckApply', 'earlyCheckApplyAttach')" />
  330. </el-form-item>
  331. </el-col>
  332. </el-row>
  333. </el-form>
  334. </ContentWrap>
  335. <ContentWrap
  336. title="审核"
  337. v-if="supportingDocsAuditDataList.length > 0 && inPageMode">
  338. <SmartTable
  339. v-model:columns="supportingDocsAuditColumns"
  340. :data="supportingDocsAuditDataList"
  341. v-model:page-no="operationReportPageNo"
  342. v-model:page-size="operationReportPageSize"
  343. :total="operationReportTotal"
  344. @on-page-no-change="() => handleGetOperationReportAuditList()"
  345. @on-page-size-change="() => handleGetOperationReportAuditList()"
  346. @refresh="() => handleGetOperationReportAuditList()" />
  347. </ContentWrap>
  348. <ContentWrap title="设备清单">
  349. <div style="margin: 10px 0">
  350. <el-button
  351. type="primary"
  352. :disabled="taskOrder?.taskStatus === PressureTaskOrderTaskStatus['REPORT_END'] || isTaskCancelled"
  353. @click="() => handleAddCheckerItems()"
  354. >批量添加检验项目</el-button
  355. >
  356. <el-button
  357. type="primary"
  358. :disabled="isTaskCancelled"
  359. @click="() => handleMainquestionAddReport(PressureReportType['MAINQUESTION'], 'add')"
  360. >添加重大问题线索</el-button
  361. >
  362. <el-button
  363. type="primary"
  364. :disabled="isTaskCancelled"
  365. @click="handleAddInspectionplanReport">
  366. {{'添加检验方案'}}
  367. </el-button>
  368. <el-button type="primary" @click="() => handleAddReport(PressureReportType['WORKINSTRUCTION'])" :disabled="isTaskCancelled">添加作业指导书</el-button>
  369. <el-button v-if="showViewMainquestionBtn()" type="primary" @click="handleViewMainquestionReport()">查看重大问题线索告知表</el-button>
  370. <el-button
  371. type="primary"
  372. @click="handleBatchConcat"
  373. :disabled="isTaskCancelled"
  374. >批量修改约检联系人</el-button>
  375. <el-button type="danger" @click="handleAbortTask"
  376. :disabled="isTaskCompleted || selectedEquipDetails.length === 0 || taskOrder?.taskStatus === PressureTaskOrderTaskStatus['AUDITING_CANCEL']">移除设备
  377. </el-button>
  378. </div>
  379. <el-table
  380. :data="taskOrderDetail.orderItems"
  381. ref="orderItemsTableRef"
  382. @selection-change="handleEquipSelectionChange"
  383. border
  384. stripe
  385. empty-text="暂无设备信息">
  386. <!-- <el-table-column fixed="left" type="selection" width="40" />-->
  387. <el-table-column type="expand" fixed="left">
  388. <template #default="props">
  389. <PipelineDetailList :row="props.row" @selection-change="handleChildSelectionChange" />
  390. </template>
  391. </el-table-column>
  392. <!-- <el-table-column-->
  393. <!-- label="操作"-->
  394. <!-- fixed="left"-->
  395. <!-- align="center"-->
  396. <!-- width="200px">-->
  397. <!-- <template #default="scope">-->
  398. <!-- <div class="operation-buttons">-->
  399. <!-- <el-button type="primary" link size="small" @click="() => handleAddReport(PressureReportType['WORKINSTRUCTION'], scope.row)" :disabled="isTaskCancelled">添加作业指导书</el-button>-->
  400. <!-- <el-button v-if="showViewMainquestionBtn(scope.row)" type="primary" @click="handleViewMainquestionReport(scope.row)" link size="small">查看重大问题线索告知表</el-button>-->
  401. <!-- <el-button-->
  402. <!-- v-if="scope.row.mainCheckerUser?.id !== taskOrderDetail.manager?.id"-->
  403. <!-- link-->
  404. <!-- type="primary"-->
  405. <!-- size="small"-->
  406. <!-- :disabled="isTaskCancelled"-->
  407. <!-- @click="handleSetMainChecker(scope.row)"-->
  408. <!-- >修改主检人</el-button-->
  409. <!-- >-->
  410. <!-- </div>-->
  411. <!-- </template>-->
  412. <!-- </el-table-column>-->
  413. <el-table-column type="index" label="序号" width="60" align="center" :index="indexMethod" />
  414. <el-table-column
  415. prop="projectNo"
  416. label="工程号"
  417. width="180px"
  418. align="center" />
  419. <el-table-column
  420. prop="checkType"
  421. label="检验性质"
  422. width="150px"
  423. align="center">
  424. <template #default>
  425. {{ typeOptions.find(type => type.value == inspectionNatureTypeList.find(item => item.nature == taskOrderDetail.checkType).type)?.label || '-' }}
  426. </template>
  427. </el-table-column>
  428. <el-table-column
  429. prop="checkType"
  430. label="检验项目"
  431. width="150px"
  432. align="center">
  433. <template #default>
  434. {{ PressurePipeCheckTypeMap[taskOrderDetail.checkType] || '-' }}
  435. </template>
  436. </el-table-column>
  437. <el-table-column
  438. prop="equipDistrictName"
  439. align="center"
  440. label="区域"
  441. width="120px">
  442. <template #default="scope">
  443. <div>{{ scope.row.equipDistrictName }}</div>
  444. <div class="text-gray-400 text-sm">
  445. {{ scope.row.equipStreetName }}
  446. </div>
  447. </template>
  448. </el-table-column>
  449. <!-- <el-table-column-->
  450. <!-- prop="reportRespVOList"-->
  451. <!-- label="检验项目"-->
  452. <!-- width="150px"-->
  453. <!-- align="center">-->
  454. <!-- <template #default="{ row }">-->
  455. <!-- <template-->
  456. <!-- v-if="getRowReportVOList(row).length <= 2">-->
  457. <!-- <el-row-->
  458. <!-- v-for="item in getRowReportVOList(row)"-->
  459. <!-- :key="item?.templateId">-->
  460. <!-- <el-button-->
  461. <!-- :disabled="taskOrder?.taskStatus === PressureTaskOrderTaskStatus['REPORT_END'] || canAddReportItem(row.taskStatus) || isTaskCancelled"-->
  462. <!-- link-->
  463. <!-- type="primary"-->
  464. <!-- class="!whitespace-normal"-->
  465. <!-- @click="() => handleAddCheckerItems(row)"-->
  466. <!-- >{{ item?.reportName }}</el-button-->
  467. <!-- >-->
  468. <!-- <el-button-->
  469. <!-- :disabled="taskOrder?.taskStatus === PressureTaskOrderTaskStatus['REPORT_END']"-->
  470. <!-- link-->
  471. <!-- type="primary"-->
  472. <!-- @click.stop.prevent="() => handleInputCalcField(row.equipId, item)"-->
  473. <!-- >(费用:{{ getCheckItemFeeType(item)-->
  474. <!-- }})</el-button-->
  475. <!-- >-->
  476. <!-- </el-row>-->
  477. <!-- </template>-->
  478. <!-- &lt;!&ndash; 弹窗 &ndash;&gt;-->
  479. <!-- <el-popover-->
  480. <!-- v-else-->
  481. <!-- placement="top-start"-->
  482. <!-- :width="200"-->
  483. <!-- trigger="hover">-->
  484. <!-- &lt;!&ndash; 弹窗内容 &ndash;&gt;-->
  485. <!-- <el-scrollbar max-height="400px">-->
  486. <!-- <el-row-->
  487. <!-- v-for="item in getRowReportVOList(row)"-->
  488. <!-- :key="item?.templateId">-->
  489. <!-- <el-button-->
  490. <!-- :disabled="taskOrder?.taskStatus === PressureTaskOrderTaskStatus['REPORT_END'] || canAddReportItem(row.taskStatus)"-->
  491. <!-- link-->
  492. <!-- type="primary"-->
  493. <!-- class="!whitespace-normal"-->
  494. <!-- @click="() => handleAddCheckerItems(row)"-->
  495. <!-- >{{ item?.reportName }}</el-button-->
  496. <!-- >-->
  497. <!-- <el-button-->
  498. <!-- :disabled="taskOrder?.taskStatus === PressureTaskOrderTaskStatus['REPORT_END']"-->
  499. <!-- link-->
  500. <!-- type="primary"-->
  501. <!-- @click.stop.prevent="() => handleInputCalcField(row.equipId, item)"-->
  502. <!-- >(费用:{{ getCheckItemFeeType(item)-->
  503. <!-- }})</el-button-->
  504. <!-- >-->
  505. <!-- </el-row>-->
  506. <!-- </el-scrollbar>-->
  507. <!-- <template #reference>-->
  508. <!-- <div>-->
  509. <!-- <el-row-->
  510. <!-- v-for="item in getRowReportVOList(row).slice(0, 2)"-->
  511. <!-- :key="item?.templateId">-->
  512. <!-- <el-button-->
  513. <!-- :disabled="taskOrder?.taskStatus === PressureTaskOrderTaskStatus['REPORT_END']"-->
  514. <!-- link-->
  515. <!-- class="!whitespace-normal"-->
  516. <!-- type="primary"-->
  517. <!-- @click="() => handleAddCheckerItems(row)"-->
  518. <!-- >{{ item?.reportName }}</el-button-->
  519. <!-- >-->
  520. <!-- <el-button-->
  521. <!-- :disabled="taskOrder?.taskStatus === PressureTaskOrderTaskStatus['REPORT_END']"-->
  522. <!-- link-->
  523. <!-- type="primary"-->
  524. <!-- @click.stop.prevent="() => handleInputCalcField(row.equipId, item)"-->
  525. <!-- >(费用:{{ getCheckItemFeeType(item)-->
  526. <!-- }})</el-button-->
  527. <!-- >-->
  528. <!-- </el-row>-->
  529. <!-- </div>-->
  530. <!-- </template>-->
  531. <!-- </el-popover>-->
  532. <!-- </template>-->
  533. <!-- </el-table-column>-->
  534. <!-- <el-table-column-->
  535. <!-- prop="reportRespVOList"-->
  536. <!-- label="操作指导书"-->
  537. <!-- width="120px"-->
  538. <!-- align="center">-->
  539. <!-- <template #default="{row}">-->
  540. <!-- <template-->
  541. <!-- v-if="filterReportType(row.reportRespVOList).length">-->
  542. <!-- <div-->
  543. <!-- class="w-full"-->
  544. <!-- v-for="(item,index) in filterReportType(row.reportRespVOList)"-->
  545. <!-- :key="index">-->
  546. <!-- {{ item?.reportName }}-->
  547. <!-- </div>-->
  548. <!-- </template>-->
  549. <!-- <span v-else>-</span>-->
  550. <!-- </template>-->
  551. <!-- </el-table-column>-->
  552. <!-- <el-table-column-->
  553. <!-- prop="fee"-->
  554. <!-- label="收费金额"-->
  555. <!-- width="120px"-->
  556. <!-- align="center" />-->
  557. <!-- <el-table-column-->
  558. <!-- prop="taskStatus"-->
  559. <!-- label="主报告状态"-->
  560. <!-- width="150px"-->
  561. <!-- align="center">-->
  562. <!-- <template #default="scope">-->
  563. <!-- <el-tag :type="getTypeColor(scope.row.taskStatus)">-->
  564. <!-- {{ PressureTaskOrderTaskStatusMap[scope.row.taskStatus] || '-' }}-->
  565. <!-- </el-tag>-->
  566. <!-- </template>-->
  567. <!-- </el-table-column>-->
  568. <el-table-column
  569. prop="projectName"
  570. label="工程名称"
  571. width="280px"
  572. align="center" />
  573. <el-table-column
  574. prop="pipeCategory"
  575. label="管道类别"
  576. width="150px"
  577. align="center">
  578. <template #default="scope">
  579. {{ PipeTypeOptions.find(i => i.value === scope.row.pipeCategory)?.label || '-' }}
  580. </template>
  581. </el-table-column>
  582. <el-table-column
  583. label="下次法定检验"
  584. width="120px"
  585. align="center">
  586. <template #default="scope">
  587. {{ scope.row.nextLegalCheckDate ? dayjs(scope.row.nextLegalCheckDate).format('YYYY-MM-DD') : '-' }}
  588. </template>
  589. </el-table-column>
  590. <el-table-column
  591. label="下次年度检查"
  592. width="120px"
  593. align="center">
  594. <template #default="scope">
  595. {{ scope.row.nextYearCheckDate ? dayjs(scope.row.nextYearCheckDate).format('YYYY-MM-DD') : '-' }}
  596. </template>
  597. </el-table-column>
  598. <el-table-column
  599. label="约检联系人"
  600. width="160px"
  601. align="center">
  602. <template #default="scope">
  603. <div>{{ scope.row.contact || '-' }}</div>
  604. </template>
  605. </el-table-column>
  606. <el-table-column
  607. label="约检联系人电话"
  608. width="160px"
  609. align="center">
  610. <template #default="scope">
  611. <div>{{ scope.row.contactPhone || '-' }}</div>
  612. </template>
  613. </el-table-column>
  614. </el-table>
  615. </ContentWrap>
  616. </div>
  617. <!-- 页面模式下的底部操作按钮 -->
  618. <div
  619. v-if="inPageMode && taskOrderDetail"
  620. class="flex justify-center mt-4">
  621. <!-- <el-button v-if="props.type !== 'checker'" type="success" @click="handlePrintCommitment" :disabled="isTaskCancelled">打印委托书</el-button>-->
  622. <!-- <el-button v-if="props.type !== 'checker'" type="success" @click="handlePrintEquipmentRecord" :disabled="isTaskCancelled">打印设备记录</el-button>-->
  623. <el-button
  624. type="primary"
  625. @click="handleConfirm"
  626. v-if="taskStatus === PressureTaskOrderTaskStatus.WAIT_CONFIRM"
  627. :disabled="isTaskCancelled"
  628. >认领</el-button
  629. >
  630. <el-button
  631. type="primary"
  632. @click="handleCancelConfirm"
  633. v-if="taskStatus === PressureTaskOrderTaskStatus.CONFIRMED"
  634. :disabled="isTaskCancelled || isTaskCompleted || taskOrderDetail.manager?.id !== userStore?.user?.id"
  635. >取消认领</el-button
  636. >
  637. <el-button type="success" v-if="showGenerateReport" @click="() => handleGenerateReportPdf()">
  638. 出具报告PDF</el-button>
  639. <el-button @click="handleClosePage">关闭</el-button>
  640. </div>
  641. </div>
  642. <!-- 内部弹窗:修改检验时间、作废任务单、检验员选择 (仅在页面模式且有权限时出现) -->
  643. <template v-if="inPageMode && taskOrderDetail">
  644. <!-- 修改检验时间对话框 -->
  645. <el-dialog
  646. v-model="modifyTimeDialogVisible"
  647. title="修改检验时间"
  648. width="500px"
  649. draggable
  650. :close-on-click-modal="false"
  651. append-to-body>
  652. <el-form
  653. ref="modifyTimeFormRef"
  654. :model="modifyTimeForm"
  655. label-width="100px">
  656. <el-form-item label="检验日期" prop="newInspectionDate" required>
  657. <el-date-picker
  658. v-model="modifyTimeForm.newInspectionDate"
  659. type="date"
  660. placeholder="选择日期"
  661. value-format="YYYY-MM-DD"
  662. class="!w-full" />
  663. </el-form-item>
  664. <el-form-item label="修改原因" prop="reason" required>
  665. <el-input
  666. v-model="modifyTimeForm.reason"
  667. type="textarea"
  668. :rows="3"
  669. placeholder="请输入修改原因" />
  670. </el-form-item>
  671. </el-form>
  672. <template #footer>
  673. <el-button @click="modifyTimeDialogVisible = false"
  674. >取消</el-button
  675. >
  676. <el-button type="primary" @click="handleSubmitModifyTime"
  677. >确定</el-button
  678. >
  679. </template>
  680. </el-dialog>
  681. <!-- 作废任务单对话框 -->
  682. <el-dialog
  683. v-model="voidTaskDialogVisible"
  684. title="作废任务单"
  685. width="500px"
  686. draggable
  687. :close-on-click-modal="false"
  688. append-to-body>
  689. <el-form
  690. ref="voidTaskFormRef"
  691. :model="voidTaskForm"
  692. :rules="{
  693. reason: [
  694. { required: true, message: '请输入作废原因', trigger: 'blur' },
  695. ],
  696. }"
  697. label-width="100px">
  698. <el-form-item label="作废原因" prop="reason">
  699. <el-input
  700. v-model="voidTaskForm.reason"
  701. type="textarea"
  702. :rows="3"
  703. placeholder="请输入作废原因" />
  704. </el-form-item>
  705. </el-form>
  706. <template #footer>
  707. <el-button @click="voidTaskDialogVisible = false"
  708. >取消</el-button
  709. >
  710. <el-button type="primary" @click="handleSubmitVoidTask"
  711. >确定</el-button
  712. >
  713. </template>
  714. </el-dialog>
  715. <!-- 检验员选择弹窗 -->
  716. <el-dialog
  717. v-model="checkerSelectVisible"
  718. title="选择检验员"
  719. append-to-body
  720. width="800px"
  721. draggable
  722. :close-on-click-modal="false">
  723. <CheckerSelect
  724. ref="checkerSelectRef"
  725. v-model="tempSelectedCheckersInDialog"
  726. :dept-id="taskOrderDetail?.deptId?.toString() || userStore.getUser.deptId?.toString() || '1'"
  727. :disabled="false"
  728. :has-data="true"
  729. empty-text="暂无检验员数据"
  730. :multiple="true"
  731. @change="handleCheckerSelectionChangeInDialog"
  732. />
  733. <template #footer>
  734. <div class="flex justify-end">
  735. <el-button @click="checkerSelectVisible = false"
  736. >取消</el-button
  737. >
  738. <el-button
  739. type="primary"
  740. @click="confirmCheckerSelectionAndSubmit"
  741. >确定</el-button
  742. >
  743. </div>
  744. </template>
  745. </el-dialog>
  746. <UserSelectForm
  747. ref="userSelectFormRef"
  748. @confirm="handleManagerSelected"
  749. :single="true" />
  750. <!-- 出具报告对话框 -->
  751. <GenerateReportDialog
  752. v-model:visible="generateReportDialogVisible"
  753. :equip-id="currentReportEquip?.id || ''"
  754. :equip-name="currentReportEquip?.equipName"
  755. @success="handleGenerateReportSuccess" />
  756. <!-- 出具报告对话框(新版本) -->
  757. <IssueReportDialog
  758. v-model:visible="issueReportDialogVisible"
  759. :task-order-id="currentTaskOrderId"
  760. :report-type="currentReportType"
  761. :default-report-scope="200"
  762. :is-part-report="true"
  763. :default-selected-equipments="currentSelectedEquipment ? [currentSelectedEquipment] : []"
  764. @confirm="handleIssueReportConfirm" />
  765. <!-- 修改主检人对话框 -->
  766. <el-dialog
  767. v-model="mainCheckerDialogVisible"
  768. title="修改主检人"
  769. width="800px"
  770. draggable
  771. :close-on-click-modal="false"
  772. append-to-body>
  773. <div class="mb-4">
  774. <div class="text-sm text-gray-600 mb-2">
  775. 当前设备:{{ currentEquipmentRow?.projectNo }} -
  776. {{ currentEquipmentRow?.projectName }}
  777. </div>
  778. <div class="text-sm text-gray-600 mb-4">
  779. 请选择一个检验员作为主检人(单选)
  780. </div>
  781. </div>
  782. <CheckerSelectBox
  783. v-model="tempSelectedMainChecker"
  784. @change="handleMainCheckerSelectionChange"
  785. :max="1"/>
  786. <template #footer>
  787. <div class="flex justify-end">
  788. <el-button @click="mainCheckerDialogVisible = false"
  789. >取消</el-button
  790. >
  791. <el-button
  792. type="primary"
  793. @click="confirmMainCheckerSelection"
  794. >确定</el-button
  795. >
  796. </div>
  797. </template>
  798. </el-dialog>
  799. </template>
  800. <!-- 安全检查记录弹窗 -->
  801. <SavetyCheckRecordList
  802. v-if="savetyCheckRecordListVsible"
  803. v-model:visible="savetyCheckRecordListVsible"
  804. :checkId="savetyCheck.checkId"
  805. :orderId="savetyCheck.orderId"
  806. :editType="savetyCheck.editType"
  807. @success="handleUpdateSavetyCheckRecordList" />
  808. <CustomDialog
  809. v-if="showSavetyCheckRecordVersions"
  810. v-model="showSavetyCheckRecordVersions"
  811. title="安全检查记录列表"
  812. width="800px"
  813. :showFooter="false"
  814. :z-index="1001">
  815. <SmartTable
  816. ref="smartTableRef"
  817. v-model:pageNo="savetyRecordPageNo"
  818. v-model:pagesize="savetyRecordPageSize"
  819. v-model:total="savetyRecordTotal"
  820. v-model:columns="savetyRecordColumns"
  821. :useBorderLayout="false"
  822. :data="savetyRecordList"
  823. :buttons="[]"
  824. @on-page-no-change="() => fetchSafetyCheckRecordPage()"
  825. @on-page-size-change="() => fetchSafetyCheckRecordPage()"
  826. @refresh="() => fetchSafetyCheckRecordPage()" />
  827. </CustomDialog>
  828. <!-- 批量修改约检联系人 -->
  829. <batchEditForm ref="formRef" @success="handleScheduleSuccess" />
  830. <!-- 添加检验项目弹窗 -->
  831. <AddOrEditCheckItemForEquipment
  832. v-if="showAddCheckItemsDialog"
  833. v-model="showAddCheckItemsDialog"
  834. :orderInfo="taskOrder"
  835. :selectedIds="checkItemIds"
  836. :isBatch="isBatchAdd"
  837. :equipmentIds="selectedEquipmentIds"
  838. :isShowItemPart="false"
  839. @refresh="() => emit('refresh')" />
  840. <!-- 添加检验方案 添加弹窗 -->
  841. <AddInspectionplan
  842. ref="addInspectionplanRef"
  843. @success="handleSuccessInspectionplan" />
  844. <!-- 添加检验方案详情 -->
  845. <AddInspectionplanDetail
  846. v-if="AddInspectionplanDetailVisible"
  847. v-model:visible="AddInspectionplanDetailVisible"
  848. :editInspectionplanParams="editInspectionplanParams"
  849. :inspectionplanDetail="inspectionplanDetail"
  850. :taskOrderDetail="taskOrderDetail"
  851. :isEdit="isEdit"
  852. @success="handleUpdateInspectionplanDetail"
  853. @refresh="handleRefreshInspectionplan"
  854. />
  855. <!-- 服务单/受理单 -->
  856. <OrderDialog
  857. v-if="orderReportVisible"
  858. v-model:visible="orderReportVisible"
  859. :orderId="props.taskOrder.id"
  860. type="pipe"
  861. />
  862. <ServiceRecordList
  863. v-if="serviceRecordListVisible"
  864. v-model:visible="serviceRecordListVisible"
  865. :serverForm="serviceOrderDialogFormData"
  866. :businessType="businessType"
  867. :reportId="mainReportId"
  868. :isAddMainquestion="isAddMainquestion"
  869. :taskOrderDetail="taskOrderDetail"
  870. @success="handleUpdateServiceRecordList"
  871. />
  872. <!-- 作业指导书 添加弹窗 -->
  873. <AddBookAndCheckScheme ref="addBookAndCheckSchemeRef" @success="handleSuccessReport" />
  874. <!-- 作业指导书 编辑弹窗 -->
  875. <EditWorkBookReport
  876. v-if="editWorkBookReportVisible"
  877. v-model:visible="editWorkBookReportVisible"
  878. :title="editOperationReportTypeTitle"
  879. :templateId="editOperationReportParams?.templateId"
  880. :reportId="editOperationReportParams?.reportId"
  881. :orderId="editOperationReportParams?.orderId"
  882. :dataJSON="editOperationReportParams?.prepareJson"
  883. :curReportTypeInfo="curReportTypeInfo"
  884. :isCustomFileUrl="false"
  885. :isEdit="isWorkBookEdit"
  886. @success="handleEditOperationReportList"
  887. />
  888. <!-- 设置主检项目并认领对话框 -->
  889. <el-dialog
  890. v-model="setPipeConfirmDialogVisible"
  891. title="选择主检管道"
  892. width="40%"
  893. :before-close="handleCancelSetPipeInfo"
  894. >
  895. <div class="mb-4">
  896. <el-select
  897. v-model="selectedOrderItemId"
  898. placeholder="请选择主检管道"
  899. clearable
  900. filterable
  901. style="width: 100%"
  902. >
  903. <el-option
  904. v-for="pipe in pipeOrderItemList"
  905. :key="pipe.id"
  906. :label="pipe.projectName"
  907. :value="pipe.id"
  908. />
  909. </el-select>
  910. </div>
  911. <template #footer>
  912. <div class="dialog-footer">
  913. <el-button @click="handleCancelSetPipeInfo">取消</el-button>
  914. <el-button type="primary" @click="handleConfirmSetPipeInfo"> 确认认领 </el-button>
  915. </div>
  916. </template>
  917. </el-dialog>
  918. <calcCheckItemFee
  919. v-if="showCalcCheckItemFeeDialog"
  920. v-model="showCalcCheckItemFeeDialog"
  921. :equipmentId="calcEquipmentId"
  922. :templateInfo="calcTemplateInfo"
  923. @save="handleSaveCalcFee"
  924. />
  925. <Dialog title="客户拒检原因" v-model="dialogVisible" align-center>
  926. <el-form ref="abortFormRef" :model="formData" :rules="rules" label-width="100px" v-loading="formLoading">
  927. <el-form-item label="拒绝原因" prop="reasonDict">
  928. <el-select
  929. v-model="formData.reasonDict"
  930. placeholder="请选择拒绝原因"
  931. prop="reasonDict"
  932. @change=" () => { formData.reason = '' }"
  933. >
  934. <el-option
  935. v-for="dict in getStrDictOptions('refuseInspectedCategory')"
  936. :key="dict.value"
  937. :label="dict.label"
  938. :value="dict.value"
  939. />
  940. </el-select>
  941. </el-form-item>
  942. <el-form-item
  943. v-if="formData.reasonDict == '5'"
  944. label="其他"
  945. prop="reason"
  946. >
  947. <el-input
  948. v-model="formData.reason"
  949. placeholder="请输入其他原因"
  950. maxlength="150"
  951. show-word-limit
  952. :autosize="{ minRows: 5, maxRows: 20 }"
  953. type="textarea"
  954. />
  955. </el-form-item>
  956. </el-form>
  957. <template #footer>
  958. <el-button @click="submitForm" type="primary" :disabled="formLoading">上报市局</el-button>
  959. <el-button @click="submitFormNoReport" :disabled="formLoading" style="background-color: #F56C6C; border-color: #F56C6C; color: #ffffff;">无需上报</el-button>
  960. <el-button @click="dialogVisible = false">取 消</el-button>
  961. </template>
  962. </Dialog>
  963. </template>
  964. <script setup lang="tsx">
  965. import CustomDialog from '@/components/CustomDialog/index.vue'
  966. import SmartTable from '@/components/SmartTable/SmartTable'
  967. import SavetyCheckRecordList from './SavetyCheckRecordList.vue'
  968. import AddOrEditCheckItemForEquipment from './AddOrEditCheckItemForEquipment.vue'
  969. import { ref, watch, defineProps, defineEmits, reactive, computed } from 'vue'
  970. import { PipeTaskOrderApi,PipeTaskOrderItemVO } from '@/api/pressure2/pipetaskorder'
  971. import {
  972. PressureFeeTypeMap,
  973. PressureTaskOrderTaskStatus,
  974. PressureCheckerMyTaskStatus,
  975. PressureFeeNatureMap,
  976. PressurePipeCheckTypeMap,
  977. PressureReportType,
  978. PressureReportTypeMap,
  979. PressureTaskOrderStatus,
  980. PressureTaskOrderStatusMap, PressureCheckerMyTaskStatusMap, PressureTaskOrderTaskStatusMap,
  981. PressureBoilerCheckTypeMap
  982. } from '@/utils/constants'
  983. import { formatArrayDate } from '@/utils/formatTime'
  984. import {
  985. ElMessage,
  986. FormInstance,
  987. ElMessageBox,
  988. dayjs,
  989. type ElForm,
  990. type ElTable,
  991. ElSelect, ElOption, type Action,ElLoading
  992. } from 'element-plus'
  993. import { useRouter, useRoute } from 'vue-router'
  994. import CheckerSelect, { type CheckerItem } from '@/views/pressure2/components/CheckerSelect'
  995. import CheckerSelectBox from '@/views/pressure2/equipboilerscheduling/components/CheckerSelectBox.vue'
  996. import UserSelectForm from '@/components/UserSelectForm/index.vue'
  997. import { useTagsViewStore } from '@/store/modules/tagsView'
  998. import GenerateReportDialog from './GenerateReportDialog.vue'
  999. import IssueReportDialog from './IssueReportDialog.vue'
  1000. import VuePdfEmbed from 'vue-pdf-embed'
  1001. import { Icon } from '@/components/Icon'
  1002. import batchEditForm from '../../pipescheduling/components/batchEditForm.vue'
  1003. import {Message as message} from "@/layout/components/Message";
  1004. import {buildFileUrl} from "@/utils";
  1005. import FileUploadModal from '@/views/pressure2/pipetaskorder/components/ImportFile.vue'
  1006. import {is} from "@/utils/is";
  1007. import {PipeAppointmentConfirmOrderApi} from "@/api/pressure2/pipeappointmentconfirmorder";
  1008. import { getPressureReportTemplateListNoLimit } from '@/api/pressure2/reportTemplate'
  1009. import AddInspectionplan from "@/views/pressure2/pipetaskorder/components/AddInspectionplan.vue";
  1010. import {useUserStore} from "@/store/modules/user";
  1011. import AddInspectionplanDetail from "@/views/pressure2/pipetaskorder/components/AddInspectionplanDetail.vue";
  1012. import ServiceRecordList from "@/views/pressure2/pipetaskorder/components/ServiceRecordList.vue";
  1013. import AddBookAndCheckScheme from "@/views/pressure2/pipetaskorder/components/AddBookAndCheckScheme.vue";
  1014. import EditWorkBookReport from "@/views/pressure2/pipetaskorder/components/EditWorkBookReport.vue";
  1015. import {DICT_TYPE, getStrDictOptions} from "@/utils/dict";
  1016. import PipelineDetailList from "./PipelineDetailList.vue";
  1017. import {EquipPipeSchedulingDetailVO} from "@/api/pressure2/pipescheduling";
  1018. import OrderDialog from "@/views/pressure2/boilertaskorder/components/OrderDialog.vue";
  1019. import calcCheckItemFee from './calcCheckItemFee.vue'
  1020. import {InspectionNatureTypeApi} from "../../../../api/pressure2/inspectionnaturetype";
  1021. import {checkRole} from "@/utils/permission";
  1022. import {BoilerTaskOrderApi} from "@/api/pressure2/boilertaskorder";
  1023. const userStore = useUserStore()
  1024. const userInfo = computed(() => userStore.user)
  1025. const router = useRouter()
  1026. const route = useRoute()
  1027. const tagsViewStore = useTagsViewStore()
  1028. const isWorkBookEdit = ref(false)
  1029. // 异常信息
  1030. const exceptionInfo = ref<Record<string, any>>({})
  1031. const orderDialogRef = ref()
  1032. const orderReportVisible = ref(false)
  1033. const setPipeConfirmDialogVisible = ref(false)
  1034. const pipeOrderItemList = ref([])
  1035. const selectedOrderItemId = ref('')
  1036. // 定义emit事件
  1037. const emit = defineEmits<{
  1038. refresh: []
  1039. }>()
  1040. const props = defineProps({
  1041. taskOrder: {
  1042. type: Object as () => Record<string, any>, // Assuming a generic object, replace with TaskOrderVO or a more specific interface if available
  1043. required: true
  1044. },
  1045. inPageMode: {
  1046. type: Boolean,
  1047. default: false
  1048. },
  1049. type: {
  1050. type: String,
  1051. default: 'taskorder'
  1052. }
  1053. })
  1054. const taskOrderDetail = ref<any>(null) // This will hold the reactive copy of props.taskOrder
  1055. const isTaskCancelled = computed(() => {
  1056. return taskOrderDetail.value?.taskStatus === PressureTaskOrderTaskStatus.CANCELLED;
  1057. });
  1058. const isTaskCompleted = computed(() => {
  1059. const completeStatus = [PressureTaskOrderTaskStatus.REPORT_CONFIRMATION, PressureTaskOrderTaskStatus.REPORT_END];
  1060. return completeStatus.includes(taskOrderDetail.value.taskStatus)
  1061. })
  1062. const canNotModify = computed(() => {
  1063. if (!taskOrderDetail.value) return true;
  1064. if (taskOrderDetail.value.taskStatus === PressureTaskOrderTaskStatus.CANCELLED) {
  1065. return true;
  1066. }
  1067. return taskOrderDetail.value.taskStatus !== PressureTaskOrderTaskStatus.WAIT_CONFIRM;
  1068. });
  1069. const taskStatus = computed(() => {
  1070. return taskOrderDetail.value.taskStatus;
  1071. });
  1072. //管道类型字典选项变量
  1073. const PipeTypeOptions = getStrDictOptions(DICT_TYPE.PIPE_TYPE)
  1074. const modifyTimeDialogVisible = ref(false)
  1075. const modifyTimeFormRef = ref<FormInstance>()
  1076. const modifyTimeForm = reactive({
  1077. newInspectionDate: undefined as string | undefined,
  1078. reason: ''
  1079. })
  1080. const voidTaskDialogVisible = ref(false)
  1081. const voidTaskFormRef = ref<FormInstance>()
  1082. const voidTaskForm = reactive({
  1083. reason: ''
  1084. })
  1085. const showDocPdfDialog = ref(false)
  1086. const checkRowReport = ref()
  1087. const showDesigner = ref(false)
  1088. const checkerSelectVisible = ref(false)
  1089. const currentSelectedCheckerIdsForDialog = ref<string[]>([])
  1090. const tempSelectedCheckersInDialog = ref<CheckerItem[]>([])
  1091. // 检验员组件引用
  1092. const checkerSelectRef = ref()
  1093. const userSelectFormRef = ref<InstanceType<typeof UserSelectForm> | null>(null)
  1094. // 修改主检人相关状态
  1095. const mainCheckerDialogVisible = ref(false)
  1096. const currentEquipmentRow = ref<any>(null)
  1097. const tempSelectedMainChecker = ref<string[]>([])
  1098. const tempSelectedMainCheckerInfo = ref<any[]>([])
  1099. // 出具报告对话框状态
  1100. const generateReportDialogVisible = ref(false)
  1101. const currentReportEquip = ref<any>(null)
  1102. // 出具报告对话框状态(新的IssueReportDialog)
  1103. const issueReportDialogVisible = ref(false)
  1104. const currentTaskOrderId = ref('')
  1105. const currentReportType = ref<100 | 200>(100)
  1106. const currentSelectedEquipment = ref<any>(null)
  1107. const orderItemsTableRef = ref<InstanceType<typeof ElTable>>()
  1108. /** 服务单/受理单 */
  1109. const serviceOrderDialogFormRef = ref<FormInstance>()
  1110. const serviceOrderDialogVisible = ref(false)
  1111. const serviceRecordListVisible = ref(false)
  1112. const businessType = ref<BusinessType>()
  1113. const submitting = ref(false)
  1114. const serviceOrderDialogFormData = ref<Record<string,any>>({
  1115. serviceFormReceiver: '',
  1116. serviceFormReceiverPhone: '',
  1117. confirmStatus: ''
  1118. })
  1119. const typeOptions = [
  1120. {
  1121. value: 1,
  1122. label: '法定'
  1123. },
  1124. {
  1125. value: 2,
  1126. label: '委托'
  1127. }
  1128. ]
  1129. const formRef = ref()
  1130. // 选中的设备
  1131. const selectedEquips = ref<PipeTaskOrderItemVO[]>([])
  1132. const selectedEquipDetails = ref<any[]>([])
  1133. const inspectionNatureTypeList = ref([])
  1134. watch(() => props.taskOrder, (newVal) => {
  1135. if (newVal) {
  1136. taskOrderDetail.value = JSON.parse(JSON.stringify(newVal)); // Use deep copy if modifications are made locally, otherwise direct assignment is fine
  1137. InspectionNatureTypeApi.getInspectionNatureTypePage({
  1138. equip:"300"
  1139. }).then(res=>{
  1140. inspectionNatureTypeList.value = res.list
  1141. })
  1142. // 更新异常单信息
  1143. const orderExceptionRespVO = taskOrderDetail.value.orderExceptionRespVO
  1144. if(orderExceptionRespVO){
  1145. exceptionInfo.value = {
  1146. ...orderExceptionRespVO,
  1147. adjustEffectiveDate: orderExceptionRespVO.adjustEffectiveDate ? dayjs(orderExceptionRespVO.adjustEffectiveDate.join('-')).format('YYYY-MM-DD') : '',
  1148. }
  1149. }
  1150. } else {
  1151. taskOrderDetail.value = null;
  1152. }
  1153. }, { immediate: true, deep: true })
  1154. const openModifyTimeDialog = () => {
  1155. if (!taskOrderDetail.value) return;
  1156. const currentApptDate = taskOrderDetail.value?.checkDate;
  1157. if (currentApptDate) {
  1158. modifyTimeForm.newInspectionDate = Array.isArray(currentApptDate) ? formatArrayDate(currentApptDate) : currentApptDate
  1159. } else {
  1160. modifyTimeForm.newInspectionDate = undefined;
  1161. }
  1162. modifyTimeForm.reason = ''
  1163. if(modifyTimeFormRef.value) {
  1164. modifyTimeFormRef.value.clearValidate()
  1165. }
  1166. modifyTimeDialogVisible.value = true
  1167. }
  1168. const handleModifyTaskOrder = () => {
  1169. if (!taskOrderDetail.value?.id) {
  1170. ElMessage.error('任务单ID不存在,无法修改!');
  1171. return;
  1172. }
  1173. router.push({
  1174. name: 'PipeTaskOrderDetail', // Ensure this route name is correct for editing
  1175. query: {
  1176. id: taskOrderDetail.value.id
  1177. }
  1178. })
  1179. }
  1180. const handleModifyManager = () => {
  1181. if (!userSelectFormRef.value) {
  1182. ElMessage.error('用户选择组件未加载!');
  1183. return;
  1184. }
  1185. if (!taskOrderDetail.value?.id) {
  1186. ElMessage.error('任务ID无效,无法修改项目负责人!');
  1187. return;
  1188. }
  1189. if (!taskOrderDetail.value?.managerId) {
  1190. ElMessage.error('请先认领再修改项目负责人!');
  1191. return;
  1192. }
  1193. userSelectFormRef.value.open(taskOrderDetail.value.id); // ID is now from taskOrderDetail
  1194. }
  1195. const handleManagerSelected = async (emittedId: string, selectedUsers: any[]) => {
  1196. //console.log(emittedId);
  1197. if (!taskOrderDetail.value?.id) {
  1198. ElMessage.error('任务ID不存在,无法修改项目负责人!');
  1199. return;
  1200. }
  1201. if (selectedUsers.length === 0) {
  1202. ElMessage.info('未选择新的项目负责人。');
  1203. return;
  1204. }
  1205. const newManager = selectedUsers[0];
  1206. try {
  1207. const payload = {
  1208. id: taskOrderDetail.value.id, // ID from taskOrderDetail
  1209. managerId: newManager.id
  1210. };
  1211. await PipeTaskOrderApi.updateTaskOrder(payload);
  1212. ElMessage.success('项目负责人更新成功!');
  1213. // 通知父组件刷新数据
  1214. emit('refresh');
  1215. } catch (error) {
  1216. console.error("Failed to update project manager:", error);
  1217. ElMessage.error('项目负责人更新失败!');
  1218. }
  1219. }
  1220. const openVoidTaskDialog = () => {
  1221. if (!taskOrderDetail.value) return;
  1222. voidTaskForm.reason = ''
  1223. if(voidTaskFormRef.value) {
  1224. voidTaskFormRef.value.clearValidate()
  1225. }
  1226. voidTaskDialogVisible.value = true
  1227. }
  1228. const openCheckerSelectionDialog = async () => {
  1229. if (!taskOrderDetail.value) {
  1230. ElMessage.warning('无法加载任务单信息');
  1231. return;
  1232. }
  1233. checkerSelectVisible.value = true;
  1234. // 先获取检验员列表
  1235. await nextTick()
  1236. const deptId = taskOrderDetail.value.deptId?.toString() || userStore.getUser.deptId?.toString() || '1'
  1237. await checkerSelectRef.value?.getCheckerList(deptId)
  1238. // 等待数据加载完成后,再从 teamItemList 中构建检验员列表
  1239. await nextTick()
  1240. // 从 teamItemList 中构建检验员列表
  1241. const checkers: CheckerItem[] = []
  1242. if (taskOrderDetail.value.teamItemList && taskOrderDetail.value.teamItemList.length > 0) {
  1243. taskOrderDetail.value.teamItemList.forEach(team => {
  1244. // 添加组长
  1245. if (team.leaders && team.leaders.length > 0) {
  1246. team.leaders.forEach(leader => {
  1247. checkers.push({
  1248. groupTeamId: team.groupTeamId,
  1249. memberId: leader.id,
  1250. leaderId: leader.id,
  1251. member: leader,
  1252. isLeader: true
  1253. })
  1254. })
  1255. }
  1256. // 添加组员
  1257. if (team.members && team.members.length > 0) {
  1258. team.members.forEach(member => {
  1259. checkers.push({
  1260. groupTeamId: team.groupTeamId,
  1261. memberId: member.id,
  1262. leaderId: team.leaders?.[0]?.id || '',
  1263. member: member,
  1264. isLeader: false
  1265. })
  1266. })
  1267. }
  1268. })
  1269. }
  1270. tempSelectedCheckersInDialog.value = checkers
  1271. // 等待赋值完成后,触发组件内部的状态更新
  1272. await nextTick()
  1273. // 手动触发组件内部的全选状态更新
  1274. checkerSelectRef.value?.processedDeptData?.forEach((dept: any) => {
  1275. dept.teamList?.forEach((team: any) => {
  1276. team.memberList?.forEach((subTeam: any) => {
  1277. const availableMembers = subTeam.memberList || []
  1278. const allSubTeamMembers = availableMembers.map((m: any) => subTeam.id + ':' + m.memberId)
  1279. if (allSubTeamMembers.length === 0) {
  1280. subTeam.checked = false
  1281. return
  1282. }
  1283. const selectedSubTeamMembers = checkers.filter((c: CheckerItem) =>
  1284. allSubTeamMembers.includes(c.groupTeamId + ':' + c.memberId)
  1285. )
  1286. subTeam.checked = selectedSubTeamMembers.length === allSubTeamMembers.length
  1287. })
  1288. })
  1289. })
  1290. }
  1291. /** 处理检验员变化 */
  1292. const handleCheckerSelectionChangeInDialog = (checkers: CheckerItem[]) => {
  1293. tempSelectedCheckersInDialog.value = checkers;
  1294. }
  1295. const confirmCheckerSelectionAndSubmit = async () => {
  1296. if (!taskOrderDetail.value?.id) {
  1297. ElMessage.error('任务ID不存在,无法修改检验员!');
  1298. return;
  1299. }
  1300. try {
  1301. const groupedByTeam: Record<string, { leaderId: string | null; userIds: string[] }> = {};
  1302. tempSelectedCheckersInDialog.value.forEach(checker => {
  1303. if (!checker.groupTeamId) {
  1304. console.warn('Checker missing groupTeamId:', checker);
  1305. return;
  1306. }
  1307. if (!groupedByTeam[checker.groupTeamId]) {
  1308. groupedByTeam[checker.groupTeamId] = { leaderId: null, userIds: [] };
  1309. }
  1310. if (checker.isLeader) {
  1311. groupedByTeam[checker.groupTeamId].leaderId = checker.memberId;
  1312. } else {
  1313. groupedByTeam[checker.groupTeamId].userIds.push(checker.memberId);
  1314. }
  1315. });
  1316. const teamList = Object.keys(groupedByTeam).map(groupTeamId => ({
  1317. groupTeamId: groupTeamId,
  1318. leaderId: groupedByTeam[groupTeamId].leaderId,
  1319. userIds: groupedByTeam[groupTeamId].userIds
  1320. }));
  1321. if (teamList.length < 1){
  1322. ElMessage.error('请选择检验员!');
  1323. return;
  1324. }
  1325. const data = {
  1326. id: taskOrderDetail.value.id, // ID from taskOrderDetail
  1327. teamList: teamList
  1328. };
  1329. await PipeTaskOrderApi.updateCheckers(data);
  1330. ElMessage.success('检验人员更新成功!');
  1331. checkerSelectVisible.value = false;
  1332. // 通知父组件刷新数据
  1333. emit('refresh');
  1334. } catch (error) {
  1335. console.error("Failed to update checkers:", error);
  1336. ElMessage.error('检验人员更新失败!');
  1337. }
  1338. }
  1339. const handleSubmitModifyTime = async () => {
  1340. if (!modifyTimeFormRef.value) return
  1341. if (!taskOrderDetail.value?.id) {
  1342. ElMessage.error('任务ID不存在,无法修改检验时间!')
  1343. return
  1344. }
  1345. await modifyTimeFormRef.value.validate(async (valid) => {
  1346. if (valid) {
  1347. if (!taskOrderDetail.value) {
  1348. ElMessage.error('任务详情为空,无法修改!')
  1349. return
  1350. }
  1351. const taskOrderDetailCopy = JSON.parse(JSON.stringify(taskOrderDetail.value))
  1352. taskOrderDetailCopy.checkDate = modifyTimeForm.newInspectionDate
  1353. const data = {
  1354. id: taskOrderDetail.value.id, // ID from taskOrderDetail
  1355. objId: taskOrderDetail.value.id, // objId from taskOrderDetail
  1356. checkDate: modifyTimeForm.newInspectionDate,
  1357. reason: modifyTimeForm.reason,
  1358. changeType: 100,
  1359. afterJson: JSON.stringify(taskOrderDetailCopy)
  1360. }
  1361. try {
  1362. await PipeTaskOrderApi.createTaskOrderOperationRecord(data)
  1363. ElMessage.success('修改检验时间请求已提交!')
  1364. modifyTimeDialogVisible.value = false
  1365. // 通知父组件刷新数据
  1366. emit('refresh');
  1367. } catch (error) {
  1368. ElMessage.error('提交修改检验时间失败!')
  1369. }
  1370. }
  1371. })
  1372. }
  1373. const handleSubmitVoidTask = async () => {
  1374. if (!voidTaskFormRef.value) return
  1375. if (!taskOrderDetail.value?.id) {
  1376. ElMessage.error('任务ID不存在,无法作废!')
  1377. return
  1378. }
  1379. await voidTaskFormRef.value.validate(async (valid) => {
  1380. if (valid) {
  1381. const data = {
  1382. id: taskOrderDetail.value.id, // ID from taskOrderDetail
  1383. objId: taskOrderDetail.value.id, // objId from taskOrderDetail
  1384. reason: voidTaskForm.reason,
  1385. changeType: 300
  1386. }
  1387. try {
  1388. await PipeTaskOrderApi.createTaskOrderOperationRecord(data)
  1389. ElMessage.success('作废任务单请求已提交!')
  1390. voidTaskDialogVisible.value = false
  1391. // 通知父组件刷新数据
  1392. emit('refresh');
  1393. } catch (error) {
  1394. ElMessage.error('提交作废任务单失败!')
  1395. }
  1396. }
  1397. })
  1398. }
  1399. const handleSetMainChecker = (row: any) => {
  1400. if (!isCanAddFlag(row)){
  1401. return
  1402. }
  1403. currentEquipmentRow.value = row
  1404. // 如果当前有主检人,预选中该主检人
  1405. if (row.mainCheckerUserId) {
  1406. tempSelectedMainChecker.value = [row.mainCheckerUserId]
  1407. } else {
  1408. tempSelectedMainChecker.value = []
  1409. }
  1410. tempSelectedMainCheckerInfo.value = []
  1411. mainCheckerDialogVisible.value = true
  1412. }
  1413. /** 处理主检人选择变化 - 单选逻辑 */
  1414. const handleMainCheckerSelectionChange = (checkers: any[]) => {
  1415. // 实现单选逻辑:如果选择了新的检验员,只保留最后选择的一个
  1416. if (checkers.length > 1) {
  1417. // 获取新选择的检验员(最后一个)
  1418. const newSelected = checkers[checkers.length - 1]
  1419. tempSelectedMainChecker.value = [newSelected]
  1420. tempSelectedMainCheckerInfo.value = [newSelected]
  1421. } else if (checkers.length === 1) {
  1422. tempSelectedMainChecker.value = [checkers[0]]
  1423. tempSelectedMainCheckerInfo.value = [checkers[0]]
  1424. } else {
  1425. tempSelectedMainChecker.value = []
  1426. tempSelectedMainCheckerInfo.value = []
  1427. }
  1428. }
  1429. /** 确认修改主检人 */
  1430. const confirmMainCheckerSelection = async () => {
  1431. if (tempSelectedMainChecker.value.length === 0) {
  1432. ElMessage.warning('请选择一个主检人')
  1433. return
  1434. }
  1435. if (!currentEquipmentRow.value?.id) {
  1436. ElMessage.error('设备信息无效,无法修改主检人')
  1437. return
  1438. }
  1439. try {
  1440. // 调用修改主检人的API
  1441. const data = {
  1442. id: currentEquipmentRow.value.mainID,
  1443. mainCheckerId: tempSelectedMainChecker.value[0].id
  1444. }
  1445. await PipeTaskOrderApi.updateTaskOrderMainChecker(data)
  1446. ElMessage.success('主检人修改成功')
  1447. mainCheckerDialogVisible.value = false
  1448. // 通知父组件刷新数据
  1449. emit('refresh');
  1450. } catch (error) {
  1451. console.error('修改主检人失败:', error)
  1452. ElMessage.error('修改主检人失败')
  1453. }
  1454. }
  1455. /** 实体报告 */
  1456. const handleEntityReport = (row: any) => {
  1457. currentTaskOrderId.value = taskOrderDetail.value?.id || ''
  1458. currentReportType.value = 100
  1459. currentSelectedEquipment.value = row
  1460. issueReportDialogVisible.value = true
  1461. }
  1462. /** 出具报告确认 */
  1463. const handleIssueReportConfirm = (data: any) => {
  1464. console.log('出具报告数据:', data)
  1465. // 刷新数据
  1466. emit('refresh')
  1467. }
  1468. /** 出具报告成功回调 */
  1469. const handleGenerateReportSuccess = () => {
  1470. // 刷新数据或其他处理
  1471. emit('refresh')
  1472. }
  1473. const handleCancelSetPipeInfo = () => {
  1474. setPipeConfirmDialogVisible.value = false
  1475. selectedOrderItemId.value = ''
  1476. }
  1477. const handleConfirmSetPipeInfo = async () => {
  1478. if (!selectedOrderItemId.value) {
  1479. ElMessage.warning('请选择主检管道')
  1480. return
  1481. }
  1482. try {
  1483. const params = {
  1484. id : taskOrderDetail.value.id,
  1485. confirm: true,
  1486. orderItemId: selectedOrderItemId.value
  1487. }
  1488. await PipeTaskOrderApi.confirmTaskOrder(params)
  1489. ElMessage.success('认领成功')
  1490. setPipeConfirmDialogVisible.value = false
  1491. if (props.inPageMode) {
  1492. tagsViewStore.closeSelectedTag(route)
  1493. }
  1494. } catch (error) {
  1495. if (error !== 'cancel') {
  1496. ElMessage.error('认领失败')
  1497. console.error('Confirm error:', error)
  1498. }
  1499. }
  1500. }
  1501. const handleConfirm = async () => {
  1502. // 检查检验日期是否在三天内
  1503. if (taskOrderDetail.value?.checkDate) {
  1504. const checkDate = taskOrderDetail.value.checkDate;
  1505. if (checkDate) {
  1506. const inspectionStartDate = dayjs(checkDate);
  1507. const now = dayjs();
  1508. const daysDiff = now.diff(inspectionStartDate, 'day', true); // 精确计算天数差(包含小数)
  1509. // 如果当前时间不在检验日期开始后的 3 天内,则不允许认领
  1510. if (daysDiff < 0 || daysDiff > 3) {
  1511. ElMessage.warning('只能在检验日期开始后的 3 天内进行认领操作');
  1512. return;
  1513. }
  1514. }
  1515. }
  1516. //taskOrderDetail.value.id
  1517. try {
  1518. await ElMessageBox.confirm('是否认领该任务单?', '认领提示', {
  1519. confirmButtonText: '确定',
  1520. cancelButtonText: '取消',
  1521. type: 'warning'
  1522. })
  1523. await PipeTaskOrderApi.confirmTaskOrder({ id:taskOrderDetail.value.id, "confirm": true })
  1524. ElMessage.success('认领成功')
  1525. if (props.inPageMode) {
  1526. tagsViewStore.closeSelectedTag(route)
  1527. }
  1528. } catch (error) {
  1529. if (error !== 'cancel') {
  1530. ElMessage.error('认领失败')
  1531. console.error('Confirm error:', error)
  1532. }
  1533. }
  1534. // selectedOrderItemId.value = ''
  1535. // //获取管线
  1536. // const params = {
  1537. // orderId: taskOrderDetail.value.id
  1538. // }
  1539. // const response = await PipeTaskOrderApi.getPipeByOrderId(params)
  1540. // pipeOrderItemList.value = response || []
  1541. // setPipeConfirmDialogVisible.value = true
  1542. }
  1543. // 取消认领
  1544. const handleCancelConfirm = async () => {
  1545. try {
  1546. await ElMessageBox.confirm('是否取消认领该任务单?', '取消认领提示', {
  1547. confirmButtonText: '确定',
  1548. cancelButtonText: '取消',
  1549. type: 'warning'
  1550. })
  1551. await PipeTaskOrderApi.confirmTaskOrder({ id:taskOrderDetail.value.id, "confirm": false })
  1552. ElMessage.success('取消认领成功')
  1553. if (props.inPageMode) {
  1554. tagsViewStore.closeSelectedTag(route)
  1555. }
  1556. } catch (error) {
  1557. if (error !== 'cancel') {
  1558. ElMessage.error('取消认领失败')
  1559. console.error('Cancel confirm error:', error)
  1560. }
  1561. }
  1562. }
  1563. const handleClosePage = () => {
  1564. if (props.inPageMode) {
  1565. tagsViewStore.closeSelectedTag(route)
  1566. }
  1567. }
  1568. /**
  1569. * 安全检查记录弹窗
  1570. * @param { visible } 显示状态
  1571. * ***/
  1572. const savetyCheckRecordListVsible = ref(false)
  1573. // 安全检查记录弹窗 携带参数
  1574. const savetyCheck = reactive({
  1575. checkId: '',
  1576. orderId: '',
  1577. editType: '',
  1578. })
  1579. const handleAddSafetyRecord = async () => {
  1580. const confirmed = await ElMessageBox.confirm('是否确定添加安全检查记录?', '添加安全检查记录提示', {
  1581. confirmButtonText: '确定',
  1582. cancelButtonText: '取消',
  1583. type: 'warning'
  1584. }).catch(() => false);
  1585. if (!confirmed) {
  1586. return;
  1587. }
  1588. savetyCheckRecordListVsible.value = true
  1589. savetyCheck.orderId = taskOrderDetail.value.id
  1590. savetyCheck.editType = 'edit'
  1591. }
  1592. watch(() => savetyCheckRecordListVsible.value, (savetyCheckRecordListVsible) => {
  1593. if(savetyCheckRecordListVsible) return
  1594. savetyCheck.checkId = ''
  1595. savetyCheck.orderId = ''
  1596. savetyCheck.editType = ''
  1597. })
  1598. // 安全检查记录列表弹窗
  1599. const showSavetyCheckRecordVersions = ref(false)
  1600. const savetyRecordList = ref([])
  1601. const savetyRecordPageSize = ref(10)
  1602. const savetyRecordPageNo = ref(1)
  1603. const savetyRecordTotal = ref(0)
  1604. const savetyRecordColumns = ref([
  1605. {
  1606. label: '名称',
  1607. prop: 'name',
  1608. },
  1609. {
  1610. label: '日期',
  1611. prop: 'date',
  1612. render: (row, value) => (value ? dayjs(value).format('YYYY-MM-DD') : '-')
  1613. },
  1614. {
  1615. label: '有效期至',
  1616. prop: 'validityDate',
  1617. render: (row, value) => (value ? dayjs(value).format('YYYY-MM-DD') : '-')
  1618. },
  1619. {
  1620. label: '检查结论',
  1621. prop: 'conclusion',
  1622. },
  1623. {
  1624. label: '操作',
  1625. prop: '',
  1626. render: (row) => {
  1627. return <div>
  1628. <el-button link type="primary" onClick={() => handleModifySavetyRecord(row,'view')}>查看</el-button>
  1629. <el-button link type="primary" onClick={() => handleModifySavetyRecord(row,'edit')}>修改</el-button>
  1630. <el-button link type="danger" onClick={() => handleDeleteSavetyRecord(row)}>删除</el-button>
  1631. </div>
  1632. }
  1633. }
  1634. ])
  1635. const fetchSafetyCheckRecordPage = async () => {
  1636. const result = await PipeTaskOrderApi.getSafetyCheckRecordPage({
  1637. pageNo: savetyRecordPageNo.value,
  1638. pageSize: savetyRecordPageSize.value,
  1639. orderId: taskOrderDetail.value.id
  1640. })
  1641. if(result) {
  1642. savetyRecordList.value = result.list
  1643. savetyRecordTotal.value = result.total
  1644. taskOrderDetail.value.securityCheckCount = result.total
  1645. }
  1646. }
  1647. const handleModifySavetyRecord = (row,editType) => {
  1648. // 修改安全检查记录
  1649. savetyCheckRecordListVsible.value = true
  1650. savetyCheck.orderId = taskOrderDetail.value.id
  1651. savetyCheck.checkId = row.id
  1652. savetyCheck.editType = editType
  1653. }
  1654. const handleDeleteSavetyRecord = (row) => {
  1655. ElMessageBox.confirm(`确定要删除【${row.name}】吗?`, '提示', {
  1656. confirmButtonText: '确定',
  1657. cancelButtonText: '取消',
  1658. type: 'warning'
  1659. }).then(async () => {
  1660. // 恢复版本
  1661. // TODO: 这里发起删除请求 --- 缺少删除接口
  1662. const delRes = await PipeTaskOrderApi.deleteSafetyCheckRecord({ id: row.id })
  1663. if(delRes) {
  1664. ElMessage.success('删除成功')
  1665. await fetchSafetyCheckRecordPage()
  1666. }
  1667. }).catch(() => {
  1668. // 取消恢复版本
  1669. })
  1670. }
  1671. const safetyCheckRecordPdfUrl = ref('')
  1672. const savetyCheckRecordPdfLoading = ref(false)
  1673. // 安全检查记录回调方法
  1674. const handleUpdateSavetyCheckRecordList = () => {
  1675. fetchSafetyCheckRecordPage()
  1676. }
  1677. /** 表格选择框变化 */
  1678. const handleEquipSelectionChange = (selection: PipeTaskOrderItemVO[]) => {
  1679. // 实现设备选择逻辑
  1680. selectedEquips.value = selection
  1681. }
  1682. /** 处理批量修改约检联系人 */
  1683. const handleBatchConcat = () => {
  1684. if (!isCanAddFlag()){
  1685. return
  1686. }
  1687. formRef.value.open(taskOrderDetail.value?.orderItems, 'taskOrder')
  1688. }
  1689. /** 修改成功处理 */
  1690. const handleScheduleSuccess = () => {
  1691. selectedEquips.value = []
  1692. //通知父组件刷新数据
  1693. emit('refresh');
  1694. }
  1695. /***** 重大问题线索&检验方案&作业指导书 *****/
  1696. const supportingDocsAuditDataList = ref<Recordable[]>([])
  1697. const supportingDocsAuditColumns = ref([
  1698. // {
  1699. // label: '工程号',
  1700. // prop: 'projectNo',
  1701. // },
  1702. {
  1703. label: '项目名称',
  1704. prop: 'reportName'
  1705. },
  1706. {
  1707. label: '类型',
  1708. prop: 'reportType',
  1709. render: (row, reportType) => {
  1710. return PressureReportTypeMap[reportType] || '-'
  1711. }
  1712. },
  1713. {
  1714. label: '状态',
  1715. prop: 'status',
  1716. render: (row, status) => {
  1717. // 如果 reportType=600 且 tbType=900,显示 -
  1718. if ((row.reportType === 600 && row.tbType === 900) || row.reportType === 500) {
  1719. return '-'
  1720. }
  1721. return !status ? '-' : PressureTaskOrderStatusMap[status]
  1722. }
  1723. },
  1724. {
  1725. label: '当前流程',
  1726. prop: 'currentNode',
  1727. render: (row) => {
  1728. // 如果 reportType=600 且 tbType=900,显示 -
  1729. if ((row.reportType === 600 && row.tbType === 900) || row.reportType === 500) {
  1730. return '-'
  1731. }
  1732. switch(row.status) {
  1733. case PressureTaskOrderStatus['CANCELLED']:
  1734. return '-'
  1735. case PressureTaskOrderStatus['APPROVED']:
  1736. return '审核通过'
  1737. case PressureTaskOrderStatus['AUDITING']:
  1738. return <div>
  1739. <p>当前流程:{row?.currentNode || '-'}</p>
  1740. <p>状态:审核中</p>
  1741. </div>
  1742. case PressureTaskOrderStatus['REJECTED']:
  1743. return <div>
  1744. <p>当前流程:已退回</p>
  1745. <p>状态:{`${row?.currentAuditor?.nickname}(${row?.currentAuditor?.employeeNo})拒绝`}</p>
  1746. </div>
  1747. default:
  1748. return '-'
  1749. }
  1750. }
  1751. },
  1752. {
  1753. label: '退回原因',
  1754. prop: 'returnReason',
  1755. render: (row, returnReason) => {
  1756. return returnReason || '-'
  1757. }
  1758. },
  1759. {
  1760. label: '提交人',
  1761. prop: 'submitUser',
  1762. render: (row, submitUser) => {
  1763. return submitUser?.nickname || '-'
  1764. }
  1765. },
  1766. {
  1767. label: '提交时间',
  1768. prop: 'submitTime',
  1769. render: (row, submitTime) => {
  1770. return !submitTime ? '-' : dayjs(submitTime).format('YYYY-MM-DD')
  1771. }
  1772. },
  1773. {
  1774. label: '操作',
  1775. prop: '',
  1776. render: (row) => {
  1777. switch(row.status) {
  1778. case PressureTaskOrderStatus['AUDITING']:
  1779. case PressureTaskOrderStatus['APPROVED']:
  1780. return <div>
  1781. <el-button link type="primary" onClick={() => newHandleOperationReport(row, 'view')}>查看详情</el-button>
  1782. {row.reportType === PressureReportType.MAINQUESTION && (
  1783. <el-button link type="primary" onClick={() => handleCancelDocs(row)}>作废</el-button>
  1784. )}
  1785. {row.reportType == PressureReportType.WORKINSTRUCTION && row.status == PressureTaskOrderStatus['AUDITING'] && <el-button link type="primary" onClick={() => recycleReportFn(row)}>
  1786. 回收
  1787. </el-button>}
  1788. </div>
  1789. // case PressureTaskOrderStatus['APPROVED']:
  1790. // return <el-button link type="primary" onClick={() => handleAssociateEquipment(row)}>关联设备</el-button>
  1791. case PressureTaskOrderStatus['REJECTED']:
  1792. return <div>
  1793. <el-button link type="primary" onClick={() => handleResubmitDocs(row)}>重新提交</el-button>
  1794. <el-button link type="primary" onClick={() => handleCancelDocs(row)}>作废</el-button>
  1795. </div>
  1796. case 0:
  1797. return <div>
  1798. <el-button link type="primary" onClick={() => newHandleOperationReport(row, 'edit')}>编辑</el-button>
  1799. <el-button link type="primary" onClick={() => handleCancelDocs(row)}>作废</el-button>
  1800. </div>
  1801. default:
  1802. return '-'
  1803. }
  1804. }
  1805. },
  1806. ])
  1807. /***** 异常信息 start *****/
  1808. const getExceptionItem = (field: string, fieldAttr: string)=>{
  1809. const fileUrl = exceptionInfo.value[fieldAttr] && buildFileUrl(exceptionInfo.value[fieldAttr])
  1810. const fileName = exceptionInfo.value[field]
  1811. if(fileUrl) {
  1812. return (
  1813. <>
  1814. <div class="flex items-center w-full p-l-10px p-r-10px hover:bg-gray-100 rounded-6px">
  1815. {/* <el-tooltip content={fileName}> */}
  1816. <span class="flex-1 text-ellipsis overflow-hidden whitespace-nowrap">{fileName}</span>
  1817. {/* </el-tooltip> */}
  1818. <div class="ml-10px">
  1819. <el-link href={fileUrl} underline={false} download target="_blank" type="primary">下载</el-link>
  1820. </div>
  1821. {/* <div class="ml-10px">
  1822. <el-button link type="danger" onClick={()=>handleRemove(field, fieldAttr)}>删除</el-button>
  1823. </div> */}
  1824. </div>
  1825. </>
  1826. )
  1827. } else {
  1828. return (
  1829. <el-button type="primary" onClick={()=>handleOpenFileUploadModal(field, fieldAttr)}>
  1830. <Icon icon="ep:upload-filled" />
  1831. <span>附件上传</span>
  1832. </el-button>
  1833. )
  1834. }
  1835. }
  1836. const handleGetExceptionInfo = (id: string) => {
  1837. PipeAppointmentConfirmOrderApi.getExceptionInfo(id).then((res) => {
  1838. if(res) exceptionInfo.value = {
  1839. ...res,
  1840. adjustEffectiveDate: res.adjustEffectiveDate?.join('-')
  1841. }
  1842. }).catch((error)=>{
  1843. console.log(error, '-----error--->')
  1844. ElMessage.error(error)
  1845. })
  1846. }
  1847. const fileUploadModalRef = ref<InstanceType<typeof FileUploadModal>>();
  1848. const currentUploadMap = reactive({
  1849. field: '',
  1850. fieldAttr: '',
  1851. })
  1852. const handleOpenFileUploadModal = (type: string, attach: string) => {
  1853. currentUploadMap.field = type
  1854. currentUploadMap.fieldAttr = attach
  1855. fileUploadModalRef.value?.open()
  1856. }
  1857. const handleFileUploadSuccess = (fileInfo:{fileName: string, fileUrl: string}) => {
  1858. exceptionInfo.value[currentUploadMap.field] = fileInfo.fileName
  1859. exceptionInfo.value[currentUploadMap.fieldAttr] = fileInfo.fileUrl
  1860. console.log('handleFileUploadSuccess:', exceptionInfo.value)
  1861. }
  1862. /***** 异常信息 end *****/
  1863. // 获取服务单/受理单模板 1000-检验情况告知 400-重大问题线索
  1864. type BusinessType = 100 | 1000 | 400
  1865. const handleServiceOrder = (type: BusinessType) => {
  1866. console.log(type)
  1867. if (type == 100){
  1868. orderReportVisible.value = true
  1869. return
  1870. }
  1871. businessType.value = type
  1872. serviceRecordListVisible.value = true
  1873. // isAddMainquestion.value = 'edit'
  1874. // serviceOrderDialogVisible.value = true
  1875. // const currentBusinessType = getSignFilePath(type)
  1876. // serviceOrderDialogFormData.value.confirmStatus = currentBusinessType.isSignature || '0'
  1877. // downloadSignFilePdf.value = currentBusinessType.signFilePdf
  1878. }
  1879. // 获取审核列表
  1880. const operationReportPageNo = ref(1)
  1881. const operationReportPageSize = ref(10)
  1882. const operationReportTotal = ref(0)
  1883. const handleGetOperationReportAuditList = async () => {
  1884. const auditListResult = await PipeTaskOrderApi.getMajorIssuesAuditList({
  1885. pageNo: operationReportPageNo.value,
  1886. pageSize: operationReportPageSize.value,
  1887. orderId: route.query.id || taskOrderDetail.value?.id,
  1888. // notStatusList: 200,
  1889. })
  1890. supportingDocsAuditDataList.value = auditListResult.list.filter(item => {
  1891. // if([PressureReportType.INSPECTIONPLAN, PressureReportType.WORKINSTRUCTION].includes(item.reportType)){
  1892. // return item.status !== 200
  1893. // } else {
  1894. // return item
  1895. // }
  1896. return item
  1897. })
  1898. operationReportTotal.value = auditListResult.total
  1899. }
  1900. handleGetOperationReportAuditList()
  1901. // 添加重大问题线索 & 检验方案 & 作业指导书
  1902. // reportType:500重大问题线索通知 600 检验方案 700 作业指导书
  1903. const curMainquestionEquipmentRow = ref<Recordable>({})
  1904. const isAddMainquestion = ref<'add' | 'edit' | 'view'>('view')
  1905. const mainOrderItemId = ref('')
  1906. const mainReportId = ref('')
  1907. const editOperationReportVisible = ref(false)
  1908. const editOperationReportTypeTitle = ref('')
  1909. const editOperationReportParams = ref<Record<string, any>>({
  1910. templateId: '',
  1911. reportId: '',
  1912. orderId: '',
  1913. prepareJson: ''
  1914. })
  1915. /***** 添加检验项目 *****/
  1916. const isBatchAdd = ref(false)
  1917. const showAddCheckItemsDialog = ref(false)
  1918. const selectedEquipmentIds = ref<string[]>([])
  1919. const selectedOrderIds = ref<string[]>([])
  1920. const checkItemIds = ref<string[]>([])
  1921. const canAddReportItem = (taskStatus)=>{
  1922. const {REPORT_AUDIT, REPORT_APPROVE, REPORT_END} = PressureCheckerMyTaskStatus
  1923. return [REPORT_AUDIT, REPORT_APPROVE, REPORT_END].includes(taskStatus)
  1924. }
  1925. const isCanAddFlag = (row?:any) =>{
  1926. let selectedItems = [] as any[]
  1927. if(row) {
  1928. isBatchAdd.value = false
  1929. selectedItems.push(row)
  1930. selectedEquipmentIds.value = [row?.equipId]
  1931. selectedOrderIds.value = [row?.mainID]
  1932. checkItemIds.value = (row.reportRespVOList || []).map(item => item.templateId)
  1933. } else {
  1934. isBatchAdd.value = true
  1935. //selectedItems = orderItemsTableRef.value?.getSelectionRows() || []
  1936. selectedItems = taskOrderDetail.value?.orderItems || []
  1937. selectedEquipmentIds.value = selectedItems.map(item => item?.equipId)
  1938. selectedOrderIds.value = selectedItems.map(item => item?.mainID)
  1939. if(selectedItems.length >= 1) {
  1940. checkItemIds.value = (selectedItems[0].reportRespVOList || []).map(item => item.templateId)
  1941. }
  1942. }
  1943. // if(selectedItems.length === 0) {
  1944. // ElMessage.warning('请选择设备单!')
  1945. // return false
  1946. // }
  1947. // 校验选中行的状态是否存在 报告审核/审核/办结
  1948. let canAddFlag = true
  1949. selectedItems.forEach(row=>{
  1950. if(canAddReportItem(row.taskStatus)) {
  1951. ElMessage.warning(`设备:${row.projectNo}的主报告状态为${PressureCheckerMyTaskStatusMap[row.taskStatus]},不能进行调整!`)
  1952. canAddFlag = false
  1953. }
  1954. })
  1955. return canAddFlag
  1956. }
  1957. const handleAddCheckerItems = (row?: any) => {
  1958. if (!isCanAddFlag(row)){
  1959. return
  1960. }
  1961. showAddCheckItemsDialog.value = true
  1962. }
  1963. /***** 添加检验项目 end *****/
  1964. //判断主报告状态
  1965. const checkMainStatus = (row?: any) => {
  1966. // 校验选中行的状态是否存在 报告审核/审核/办结
  1967. let canAddFlag = true
  1968. selectedItems.forEach(row=>{
  1969. if(canAddReportItem(row.taskStatus)) {
  1970. ElMessage.warning(`设备:${row.equipCode}的主报告状态为${PressureCheckerMyTaskStatusMap[row.taskStatus]},不能添加检验项目!`)
  1971. canAddFlag = false
  1972. }
  1973. })
  1974. return canAddFlag;
  1975. }
  1976. const getRowReportVOList = (row)=>{
  1977. return (row.reportRespVOList || []).filter(item=>item.reportType !== PressureReportType['WORKINSTRUCTION'])
  1978. }
  1979. const filterReportType = (list: any[])=>{
  1980. return (list || []).filter(item=>item.reportType === PressureReportType['WORKINSTRUCTION'])
  1981. }
  1982. // 添加检验方案/查看检验方案按钮
  1983. const initEditOperationReportParams = JSON.parse(JSON.stringify(editOperationReportParams.value))
  1984. const addInspectionplanRef = ref<InstanceType<typeof AddInspectionplan>>()
  1985. const isEdit = ref<'add' | 'edit' | 'view'>('view')
  1986. const editInspectionplanParams = ref<Recordable>({
  1987. ...initEditOperationReportParams.value,
  1988. })
  1989. const AddInspectionplanDetailVisible = ref(false)
  1990. const inspectionplanDetail = ref({})
  1991. const handleUpdateInspectionplanDetail = (info) => {
  1992. console.log('handleUpdateInspectionplanDetail-info:', info )
  1993. editInspectionplanParams.value = {
  1994. ...editInspectionplanParams.value,
  1995. ...info
  1996. }
  1997. }
  1998. const handleRefreshInspectionplan= ()=>{
  1999. // 重新获取审核列表数据
  2000. operationReportPageNo.value = 1
  2001. handleGetOperationReportAuditList()
  2002. }
  2003. const handleAddInspectionplanReport = async () => {
  2004. try {
  2005. if (!isCanAddFlag()){
  2006. return
  2007. }
  2008. // 查询检验方案模板数据
  2009. // const options = ref<any[]>([])
  2010. // const params = { type: '6',reportType : 600 }
  2011. // const response = await getPressureReportTemplateListNoLimit({...params, pageNo: 1, pageSize: 100, status: 200})
  2012. // options.value = response?.data?.list || response?.list || response || []
  2013. //
  2014. // const equipType = taskOrderDetail.value.orderItems[0]?.pipeCategoryName;
  2015. // const checkType = PressurePipeCheckTypeMap[taskOrderDetail.value?.checkType] || '-'
  2016. //
  2017. // const newParams = {
  2018. // options: options.value.map(item => ({
  2019. // ...item,
  2020. // label: item.tbName,
  2021. // reportName: equipType + checkType + "-" + item.tbName,
  2022. // value: item.id
  2023. // })),
  2024. // formData: {
  2025. // orderId: taskOrderDetail.value.id,
  2026. // },
  2027. // equipCount: unref(selectedEquips).length
  2028. // }
  2029. const newParams = {
  2030. selectedEquips : selectedEquips.value,
  2031. taskOrderDetail : taskOrderDetail.value,
  2032. }
  2033. // 添加检验方案逻辑
  2034. addInspectionplanRef.value?.open(newParams, '检验方案类型')
  2035. } catch (error) {
  2036. // 处理接口错误
  2037. ElMessage({
  2038. type: 'error',
  2039. message: 'Failed to load options'
  2040. });
  2041. console.error('API error:', error);
  2042. }
  2043. }
  2044. const getCheckItemFeeType = computed(() => {
  2045. return ({isAutoAmount, fee}) => {
  2046. if(is(fee, 'Number')) return fee
  2047. else if(is(fee, 'Null') && isAutoAmount === '1') return '录入计算'
  2048. else return '无'
  2049. }
  2050. })
  2051. const newHandleOperationReport = async (row, type: 'add' | 'edit' | 'view' | '' = '') => {
  2052. if(row.reportType === PressureReportType.MAINQUESTION){
  2053. return handleMainquestionAddReport(row.reportType, type, row)
  2054. }
  2055. // 如果是检验方案走检验方案的逻辑
  2056. if(row.reportType === PressureReportType['INSPECTIONPLAN']) {
  2057. // 检验方案
  2058. editInspectionplanParams.value = {
  2059. ...editInspectionplanParams.value,
  2060. reportId: row.id,
  2061. templateId: row.templateId,
  2062. orderId: taskOrderDetail.value.id,
  2063. isSelfType: row.tbType === 500 && row.pjType === 5,
  2064. }
  2065. inspectionplanDetail.value = row
  2066. if(!row.status){
  2067. // const templateInitJSON = await getPressureReportTemplateMockJSON( {taskOrderNo: props.taskOrder.orderNo,
  2068. // templateId: row.templateId})
  2069. // editInspectionplanParams.value.prepareJson = templateInitJSON
  2070. }
  2071. isEdit.value = type ? type : !row.status ? 'add' : 'edit'
  2072. AddInspectionplanDetailVisible.value = true
  2073. return
  2074. }
  2075. //作业指导书 选择的是模板,则直接通过葡萄城进行查看预览
  2076. if(row.reportType === PressureReportType['WORKINSTRUCTION']) {
  2077. return handleWorkBookDetail(row,type !== 'view')
  2078. }
  2079. // 查看文件详情的pdf
  2080. showDocPdfDialog.value = true
  2081. checkRowReport.value = row
  2082. showDesigner.value = !!row.templateId
  2083. }
  2084. // 作业指导书查看详情/编辑
  2085. const handleWorkBookDetail = (row, isEdit = false)=>{
  2086. //isCustomFileUrl.value = !row.templateId
  2087. editOperationReportTypeTitle.value = PressureReportTypeMap[row.reportType]
  2088. editOperationReportParams.value = {
  2089. ...editOperationReportParams.value,
  2090. reportId: row.id,
  2091. templateId: row.templateId,
  2092. orderId: taskOrderDetail.value.id,
  2093. prepareJson: row.prepareJson
  2094. }
  2095. isWorkBookEdit.value = isEdit
  2096. editWorkBookReportVisible.value = true
  2097. }
  2098. /***** 费用计算 *****/
  2099. const calcEquipmentId = ref('')
  2100. const calcTemplateInfo = ref({})
  2101. const showCalcCheckItemFeeDialog = ref(false)
  2102. const handleInputCalcField = async (equipId, item) => {
  2103. try {
  2104. calcTemplateInfo.value = item
  2105. calcEquipmentId.value = equipId
  2106. showCalcCheckItemFeeDialog.value = true
  2107. } catch (error) {
  2108. ElMessage.error('录入费用出错啦!')
  2109. console.error('录入费用出错啦!', error)
  2110. }
  2111. }
  2112. const handleSaveCalcFee = async (templateInfo) => {
  2113. // 更新检验项目的费用
  2114. const updateRes = await BoilerTaskOrderApi.updateCheckItemFee({id: templateInfo.id, fee: templateInfo.fee, feeCalculateJson: templateInfo.feeCalculateJson })
  2115. if(updateRes) {
  2116. emit('refresh')
  2117. ElMessage.success('费用已更新')
  2118. }
  2119. }
  2120. /***** 费用计算 end *****/
  2121. /*
  2122. * 添加重大问题线索
  2123. * */
  2124. const handleMainquestionAddReport = async (reportType, type: 'add' | 'edit' | 'view', row?: Recordable) => {
  2125. if (!reportType) return ElMessage.error('未知的报告类型')
  2126. // if (!row && unref(selectedEquips).length !== 1) return ElMessage.error('请选择一台设备')
  2127. if (type !== 'view' && !isCanAddFlag(row)){
  2128. return
  2129. }
  2130. isAddMainquestion.value = type
  2131. console.log('isAddMainquestion:log', isAddMainquestion.value)
  2132. mainReportId.value = row ? row.id : ''
  2133. // mainOrderItemId.value = row ? row.orderItemId : unref(selectedEquips)[0].mainID
  2134. curMainquestionEquipmentRow.value = row ? {...row} : unref(selectedEquips)[0]
  2135. // 校验审核列表是否已经存在
  2136. const existingAudit = supportingDocsAuditDataList.value.find(item => item.reportType === reportType)
  2137. if (existingAudit && type == 'add') {
  2138. ElMessage.error('该任务单已存在该类型的报告')
  2139. return
  2140. }
  2141. if (type == 'add'){
  2142. const confirmed = await ElMessageBox.confirm('是否确定添加重大问题线索?', '添加重大问题线索提示', {
  2143. confirmButtonText: '确定',
  2144. cancelButtonText: '取消',
  2145. type: 'warning'
  2146. }).catch(() => false);
  2147. if (!confirmed) {
  2148. return;
  2149. }
  2150. }
  2151. handleServiceOrder(400)
  2152. }
  2153. /*
  2154. * 添加检验情况告知单
  2155. * */
  2156. const handleInspectionStatusAddReport = async (reportType, type: 'add' | 'edit' | 'view') => {
  2157. if (!reportType) return ElMessage.error('未知的报告类型')
  2158. if (taskOrderDetail.value.notificationformReport != null){
  2159. isAddMainquestion.value = 'view'
  2160. mainReportId.value = taskOrderDetail.value.notificationformReport.id
  2161. }else{
  2162. isAddMainquestion.value = 'add'
  2163. }
  2164. // mainOrderItemId.value = row ? row.orderItemId : unref(selectedEquips)[0].mainID
  2165. // 校验审核列表是否已经存在
  2166. // const existingAudit = supportingDocsAuditDataList.value.find(item => item.reportType === reportType && item.orderItemId === curMainquestionEquipmentRow.value.mainID)
  2167. // if (existingAudit) {
  2168. // ElMessage.error('该设备已存在该类型的报告')
  2169. // return
  2170. // }
  2171. if (isAddMainquestion.value == 'add'){
  2172. const confirmed = await ElMessageBox.confirm('是否确定添加检验情况告知单?', '添加检验情况告知单提示', {
  2173. confirmButtonText: '确定',
  2174. cancelButtonText: '取消',
  2175. type: 'warning'
  2176. }).catch(() => false);
  2177. if (!confirmed) {
  2178. return;
  2179. }
  2180. }
  2181. handleServiceOrder(1000)
  2182. }
  2183. const handleSuccessInspectionplan = async (info) => {
  2184. const firstOrderItem = unref(taskOrderDetail).orderItems[0] || {}
  2185. const params: Recordable = {
  2186. taskOrderNo: props.taskOrder.orderNo,
  2187. templateId: info.templateId,
  2188. }
  2189. if (firstOrderItem.equipCode) {
  2190. params.equipCode = firstOrderItem.equipCode
  2191. }
  2192. try {
  2193. // 1.获取选中模板配置信息
  2194. //const templateInitJSON = await getPressureReportTemplateMockJSON(params)
  2195. const templateInitJSON = null;
  2196. const defaultUser: Record<string, any> = {
  2197. prepareName: unref(userInfo)?.nickname,
  2198. prepareDate: dayjs().format('YYYY年MM月DD')
  2199. }
  2200. const prepareJson = templateInitJSON ? {...JSON.parse(templateInitJSON), ...defaultUser} : defaultUser
  2201. // 2.组装参数, 生成新的检验方案记录,
  2202. const addParams = {
  2203. orderId: taskOrderDetail.value.id,
  2204. templateId: info.templateId,
  2205. prepareJson: JSON.stringify(prepareJson),
  2206. prepareId: unref(userInfo)?.id,
  2207. prepareName: unref(userInfo)?.nickname,
  2208. reportName: info.reportName,
  2209. }
  2210. const newReportId = await PipeTaskOrderApi.addMajorIssues(addParams)
  2211. editInspectionplanParams.value = {
  2212. reportId: newReportId,
  2213. templateId: info.templateId,
  2214. orderId: taskOrderDetail.value.id,
  2215. // prepareJson: templateInitJSON ? JSON.parse(templateInitJSON) : ''
  2216. prepareJson: JSON.stringify(prepareJson),
  2217. isSelfType: info.isSelfType,
  2218. }
  2219. isEdit.value = 'add'
  2220. AddInspectionplanDetailVisible.value = true
  2221. } catch (error) {
  2222. ElMessage.error('获取模板失败')
  2223. }
  2224. }
  2225. const handleUpdateServiceRecordList = async ()=>{
  2226. isAddMainquestion.value = 'view'
  2227. await handleGetOperationReportAuditList()
  2228. emit('refresh');
  2229. }
  2230. const showViewMainquestionBtn = (row: Recordable)=>{
  2231. return supportingDocsAuditDataList.value.some(item => item.reportType === PressureReportType.MAINQUESTION)
  2232. }
  2233. const handleViewMainquestionReport = (row: Recordable)=>{
  2234. if(!showViewMainquestionBtn(row)) return ElMessage.error('该设备不存在该类型的报告')
  2235. const checkAuditRow = unref(supportingDocsAuditDataList).find(item => item.reportType === PressureReportType.MAINQUESTION)
  2236. newHandleOperationReport(checkAuditRow, 'view')
  2237. }
  2238. const handleLookSecurityCheck = async () => {
  2239. showSavetyCheckRecordVersions.value = true
  2240. await fetchSafetyCheckRecordPage()
  2241. }
  2242. //添加作业指导书
  2243. // 记录当前的报告类型相关信息
  2244. const addBookAndCheckSchemeRef = ref<InstanceType<typeof AddBookAndCheckScheme>>()
  2245. const curReportType = ref()
  2246. const editWorkBookReportVisible = ref(false)
  2247. const curReportTypeInfo = reactive({
  2248. reportType: '',
  2249. data: {}
  2250. })
  2251. const handleAddReport = async (reportType, row?: Recordable) => {
  2252. if (!isCanAddFlag(row)){
  2253. return
  2254. }
  2255. // 更新记录操作行信息
  2256. curReportTypeInfo.reportType = reportType
  2257. curReportTypeInfo.data = {...row}
  2258. // 创建一个带ElSelect组件的弹窗
  2259. const dialogSelectedValue = ref<string | number>('')
  2260. const createElSelectFormDialog = (options, label) => {
  2261. return defineComponent({
  2262. setup() {
  2263. return () => h('div', [
  2264. h('p', { style: 'margin-bottom: 6px' }, label),
  2265. h(ElSelect, {
  2266. modelValue: dialogSelectedValue.value,
  2267. 'onUpdate:modelValue': (value: string) => {
  2268. dialogSelectedValue.value = value;
  2269. },
  2270. placeholder: '请选择' + label,
  2271. style: 'width: 100%'
  2272. }, options.map(option =>
  2273. h(ElOption, {
  2274. key: option.id,
  2275. label: option.name,
  2276. value: option.id
  2277. })
  2278. ))
  2279. ]);
  2280. }
  2281. });
  2282. }
  2283. try {
  2284. if(!reportType) {
  2285. ElMessage.error('未知的报告类型')
  2286. return
  2287. }
  2288. // 获取下拉选择框的options数据
  2289. const options = ref<any[]>([])
  2290. const params = {}
  2291. switch (reportType) {
  2292. // case PressureReportType['MAINQUESTION']:
  2293. // params['classId'] = 'd799cf8309fa17df5bb87766fc10e00b'
  2294. // break
  2295. // case PressureReportType['INSPECTIONPLAN']:
  2296. // // 检验方案
  2297. // params['type'] = '6'
  2298. // break
  2299. case PressureReportType['WORKINSTRUCTION']:
  2300. // 作业指导书
  2301. params['reportType'] = '700'
  2302. break
  2303. default:
  2304. return
  2305. }
  2306. // 获取指定项目类型的报告
  2307. const response = await getPressureReportTemplateListNoLimit({...params, pageNo: 1, pageSize: 100, status: 200})
  2308. options.value = response?.data?.list || response?.list || response || []
  2309. if([PressureReportType['INSPECTIONPLAN'], PressureReportType['WORKINSTRUCTION']].includes(reportType)) {
  2310. curReportType.value = reportType
  2311. // 检验方案 & 作业指导书 调整修改逻辑其他的保持不变
  2312. const newParams = {
  2313. title: PressureReportTypeMap[reportType],
  2314. options: options.value.map(item => ({
  2315. ...item,
  2316. label: item.tbName,
  2317. value: item.id
  2318. })),
  2319. formData: {
  2320. ...row,
  2321. orderId: taskOrderDetail.value.id,
  2322. // templateId: dialogSelectedValue.value,
  2323. }
  2324. }
  2325. // 添加检验方案逻辑
  2326. // if(reportType === PressureReportType['INSPECTIONPLAN']) {
  2327. // addInspectionplanRef.value?.open(newParams, '添加检验方案')
  2328. // return
  2329. // }
  2330. addBookAndCheckSchemeRef.value?.open(newParams, reportType)
  2331. return
  2332. }
  2333. // 4. 显示自定义弹窗
  2334. ElMessageBox({
  2335. title: '关联项目模板',
  2336. message: h(createElSelectFormDialog(options.value, '项目模板')),
  2337. confirmButtonText: '确定',
  2338. cancelButtonText: '取消',
  2339. showCancelButton: true,
  2340. customClass: 'customPromptStyle',
  2341. beforeClose: (action: Action, instance, done) => {
  2342. if((dialogSelectedValue.value && action === 'confirm') || action === 'cancel') {
  2343. done()
  2344. } else {
  2345. ElMessage.error('请选择项目模板')
  2346. }
  2347. }
  2348. }).then(async () => {
  2349. if(dialogSelectedValue.value) {
  2350. if (params['type'] == '700') {
  2351. // 这里去打开模板
  2352. editOperationReportVisible.value = true
  2353. editOperationReportTypeTitle.value = PressureReportTypeMap[reportType]
  2354. editOperationReportParams.value = {
  2355. ...editOperationReportParams.value,
  2356. templateId: dialogSelectedValue.value,
  2357. orderId: taskOrderDetail.value.id,
  2358. }
  2359. dialogSelectedValue.value = ''
  2360. }
  2361. }
  2362. }).catch((error) => {
  2363. dialogSelectedValue.value = ''
  2364. });
  2365. } catch (error) {
  2366. // 处理接口错误
  2367. ElMessage({
  2368. type: 'error',
  2369. message: 'Failed to load options'
  2370. });
  2371. console.error('API error:', error);
  2372. }
  2373. }
  2374. // 添加作业指导书
  2375. const handleSuccessReport = async (info) => {
  2376. const reportList = filterReportType(info.reportRespVOList);
  2377. const templateIds = (reportList || []).filter(item=>item.templateId === info.templateId)
  2378. if (templateIds.length > 0){
  2379. ElMessage.error('该设备已存在该作业指导书')
  2380. return
  2381. }
  2382. if(!info) return handleEditOperationReportList()
  2383. // 如果选择的是模板,则还是走之前的逻辑,打开葡萄城进行编辑提交
  2384. if(info?.addType === '2'){
  2385. // 这里去打开模板
  2386. editOperationReportTypeTitle.value = PressureReportTypeMap[unref(curReportType)]
  2387. editOperationReportParams.value = {
  2388. ...editOperationReportParams.value,
  2389. templateId: info.templateId,
  2390. orderId: taskOrderDetail.value.id,
  2391. //orderItemId: info.mainID,
  2392. // 操作指导书,初始化编制人和编制时间
  2393. // prepareJson: JSON.stringify({
  2394. // prepareName: unref(userInfo)?.nickname,
  2395. // prepareDate: dayjs().format('YYYY年MM月DD'),
  2396. // })
  2397. }
  2398. isWorkBookEdit.value = true
  2399. //添加操作指导书
  2400. if (!editOperationReportParams.value.reportId) {
  2401. // 初次编辑模板 需要添加报告
  2402. // newReportId 返回的是reportId
  2403. const params: Recordable = {
  2404. orderId: editOperationReportParams.value.orderId,
  2405. templateId: editOperationReportParams.value.templateId,
  2406. prepareId: unref(userInfo)?.id,
  2407. prepareName: unref(userInfo)?.nickname,
  2408. orderItemId: editOperationReportParams.value.orderItemId
  2409. }
  2410. editOperationReportParams.value.reportId = await PipeTaskOrderApi.addMajorIssues(params)
  2411. }
  2412. editWorkBookReportVisible.value = true
  2413. }
  2414. }
  2415. const handleEditOperationReportList = () => {
  2416. // 重新获取列表数据
  2417. // operationReportPageNo.value = 1
  2418. // handleGetOperationReportAuditList()
  2419. // editOperationReportParams.value = initEditOperationReportParams.value
  2420. emit('refresh');
  2421. }
  2422. const getTypeColor = (status: string | number) => {
  2423. const statusMap = {
  2424. [PressureTaskOrderTaskStatus.WAIT_CONFIRM]: 'primary',
  2425. [PressureTaskOrderTaskStatus.CANCELLED]: 'info',
  2426. [PressureTaskOrderTaskStatus.AUDITING_EDIT]: 'warning',
  2427. [PressureTaskOrderTaskStatus.AUDITING_CANCEL]: 'warning',
  2428. [PressureTaskOrderTaskStatus.AUDITING_TIME]: 'warning',
  2429. [PressureTaskOrderTaskStatus.CONFIRMED]: 'success',
  2430. [PressureTaskOrderTaskStatus.RECORD_INPUT]: 'warning',
  2431. [PressureTaskOrderTaskStatus.RECORD_CHECK]: 'warning',
  2432. [PressureTaskOrderTaskStatus.REPORT_INPUT]: 'warning',
  2433. [PressureTaskOrderTaskStatus.REPORT_AUDIT]: 'warning',
  2434. [PressureTaskOrderTaskStatus.REPORT_APPROVE]: 'warning',
  2435. [PressureTaskOrderTaskStatus.REPORT_END]: 'primary'
  2436. };
  2437. return statusMap[status] || 'info';
  2438. }
  2439. const isCustomFileUrl = ref(false)
  2440. const handleResubmitDocs = async (row) => {
  2441. if(row.reportType === PressureReportType.MAINQUESTION){
  2442. return handleMainquestionAddReport(row.reportType, 'edit', row)
  2443. }
  2444. // 如果是检验方案走检验方案的逻辑
  2445. if(row.reportType === PressureReportType['INSPECTIONPLAN']) {
  2446. // 检验方案
  2447. editInspectionplanParams.value = {
  2448. reportId: row.id,
  2449. templateId: row.templateId,
  2450. orderId: taskOrderDetail.value.id,
  2451. prepareJson: row.prepareJson || '',
  2452. isSelfType: row.tbType === 500 && row.pjType === 5,
  2453. }
  2454. inspectionplanDetail.value = row
  2455. isEdit.value = 'edit'
  2456. AddInspectionplanDetailVisible.value = true
  2457. return
  2458. }
  2459. isCustomFileUrl.value = !row.templateId
  2460. // 重新提交
  2461. editOperationReportTypeTitle.value = PressureReportTypeMap[row.reportType]
  2462. editOperationReportParams.value = {
  2463. ...editOperationReportParams.value,
  2464. reportId: row.id,
  2465. templateId: row.templateId,
  2466. orderId: taskOrderDetail.value.id,
  2467. prepareJson: row.prepareJson
  2468. }
  2469. // 作业指导书 重新提交审批
  2470. if(row.reportType === PressureReportType['WORKINSTRUCTION']) {
  2471. return handleWorkBookDetail(row, true)
  2472. }
  2473. editOperationReportVisible.value = true
  2474. }
  2475. const handleCancelDocs = async (item) => {
  2476. // 作废项目
  2477. try {
  2478. const { value: voidReason } = await ElMessageBox.prompt(
  2479. `确定要作废项目 ${item.reportName} 吗?`,
  2480. '作废项目',
  2481. {
  2482. confirmButtonText: '确认作废',
  2483. cancelButtonText: '取消',
  2484. inputPlaceholder: '请输入作废原因',
  2485. inputType: 'textarea',
  2486. inputValidator: (value: string) => {
  2487. if (!value || !value.trim()) {
  2488. return '作废原因不能为空'
  2489. }
  2490. if (value.trim().length < 5) {
  2491. return '作废原因至少需要5个字符'
  2492. }
  2493. if (value.trim().length > 200) {
  2494. return '作废原因不能超过200个字符'
  2495. }
  2496. return true
  2497. },
  2498. inputErrorMessage: '请输入有效的作废原因'
  2499. }
  2500. )
  2501. if (voidReason && voidReason.trim()) {
  2502. const params: Recordable = {
  2503. id: item.id,
  2504. reportType: item.reportType,
  2505. reason: voidReason.trim()
  2506. }
  2507. // 如果类型是检验方案/操作指导书作废,多传递一个isDelete字段
  2508. if([PressureReportType['INSPECTIONPLAN'], PressureReportType['WORKINSTRUCTION'], PressureReportType.MAINQUESTION].includes(item.reportType)) {
  2509. params.isDelete = true
  2510. }
  2511. await PipeTaskOrderApi.cancelReport(params)
  2512. ElMessage.success(`成功作废项目 ${item.reportName}`)
  2513. handleGetOperationReportAuditList()
  2514. }
  2515. } catch (error: any) {
  2516. if (error !== 'cancel') {
  2517. console.error('作废项目失败:', error)
  2518. ElMessage.error('作废项目失败,请稍后重试')
  2519. }
  2520. }
  2521. }
  2522. const handleChildSelectionChange = (selection: any[], parentId: string | number) => {
  2523. selectedEquipDetails.value = selectedEquipDetails.value.filter((item) => item.equipPipeId !== parentId)
  2524. selection.forEach((sel) => {
  2525. selectedEquipDetails.value.push({ ...sel, equipPipeId: parentId })
  2526. })
  2527. }
  2528. const indexMethod = (index: number) => {
  2529. return index + 1
  2530. }
  2531. const showGenerateReport = computed(() => {
  2532. if (taskStatus.value !== PressureTaskOrderTaskStatus.CONFIRMED && taskStatus.value !== PressureTaskOrderTaskStatus.REPORT_CONFIRMATION && taskStatus.value !== PressureTaskOrderTaskStatus.REPORT_END){
  2533. return false;
  2534. }
  2535. const mainReports = taskOrderDetail.value.orderItems.filter((item) => item.taskStatus < PressureCheckerMyTaskStatus.REPORT_INPUT)
  2536. if (mainReports.length < 1) {
  2537. return true
  2538. }else{
  2539. return false
  2540. }
  2541. })
  2542. const handleGenerateReportPdf = async () => {
  2543. ElMessageBox.confirm(`确定要出具报告吗?`, '提示', {
  2544. confirmButtonText: '确定',
  2545. cancelButtonText: '取消',
  2546. type: 'warning'
  2547. }).then( async () => {
  2548. const loadingInstance = ElLoading.service({
  2549. fullscreen: true,
  2550. text: '出具中...'
  2551. })
  2552. try {
  2553. // 获取PDF字节流
  2554. const response = await PipeTaskOrderApi.generateReportPdf({
  2555. orderId: props.taskOrder.id
  2556. }, { responseType: 'blob' }) // 确保以blob格式接收响应
  2557. // 创建Blob对象
  2558. const blob = new Blob([response], { type: 'application/pdf' })
  2559. // 创建下载链接
  2560. const url = window.URL.createObjectURL(blob)
  2561. const link = document.createElement('a')
  2562. link.href = url
  2563. link.download = `检验报告_${props.taskOrder.orderNo}.pdf` // 设置下载文件名
  2564. // 触发下载
  2565. document.body.appendChild(link)
  2566. link.click()
  2567. // 清理
  2568. document.body.removeChild(link)
  2569. window.URL.revokeObjectURL(url)
  2570. ElMessage.success('报告下载成功')
  2571. } catch (error) {
  2572. console.error('下载PDF失败:', error)
  2573. ElMessage.error('报告下载失败')
  2574. } finally {
  2575. // 关闭 Loading
  2576. loadingInstance.close()
  2577. }
  2578. })
  2579. }
  2580. // 推送结算系统
  2581. const handlePushSettlementSystem = () => {
  2582. ElMessageBox.confirm('确认推送结算系统吗?', '提示', {
  2583. confirmButtonText: '确定',
  2584. cancelButtonText: '取消',
  2585. type: 'warning'
  2586. }).then(() => {
  2587. PipeTaskOrderApi.pushSettlementSystem({}, {
  2588. id: props.taskOrder.id
  2589. }).then(() => {
  2590. ElMessage.success('推送结算系统成功')
  2591. }).catch(()=>{
  2592. ElMessage.error('推送结算系统失败')
  2593. })
  2594. })
  2595. }
  2596. const canPushSettlementSystem = computed(() => {
  2597. // 超级管理员角色 | 项目负责人 才能推送结算系统
  2598. return !(taskOrderDetail.value.managerId == unref(userInfo)?.id || userStore.getRoles.includes('super_admin'))
  2599. })
  2600. const recycleReportFn = async (item) => {
  2601. ElMessageBox.confirm(`确定要回收项目 ${item.reportName} 吗?`, '提示', {
  2602. confirmButtonText: '确认回收',
  2603. cancelButtonText: '取 消'
  2604. })
  2605. .then(async () => {
  2606. const res = await PipeTaskOrderApi.majorIssuesRecovery({
  2607. businessType: '0',
  2608. reportId: item.id
  2609. })
  2610. if (res) {
  2611. ElMessage.success('回收成功')
  2612. refreshDetail()
  2613. }
  2614. })
  2615. .catch(() => console.info('操作取消'))
  2616. }
  2617. const refreshDetail = () => {
  2618. console.log('刷新详情')
  2619. emit('refresh')
  2620. }
  2621. /** 处理中止检验 */
  2622. const dialogVisible = ref(false) // 弹窗的是否展示
  2623. const abortFormRef = ref<InstanceType<typeof ElForm>>()
  2624. const formLoading = ref(false)
  2625. const formData = ref<Record<string, any>>({
  2626. reasonDict: '',
  2627. reason: ''
  2628. })
  2629. const rules = reactive({
  2630. reasonDict: [{ required: true, message: '请选择拒绝原因', trigger: 'change' }],
  2631. reason: [{ required: true, message: '请输入其他原因', trigger: 'blur' }]
  2632. })
  2633. const submitForm = async () => {
  2634. abortFormRef.value &&
  2635. abortFormRef.value.validate().then(() => {
  2636. const params: any = {
  2637. ...unref(formData),
  2638. orderItemDetails: selectedEquipDetails.value,
  2639. flag: 1
  2640. }
  2641. if (params.reasonDict != 5) {
  2642. params.reason = ''
  2643. }
  2644. formLoading.value = true
  2645. PipeTaskOrderApi.abortTask(params)
  2646. .then(() => {
  2647. // 刷新数据
  2648. ElMessage.success('检验任务已中止')
  2649. emit('refresh')
  2650. })
  2651. .finally(() => {
  2652. formLoading.value = false
  2653. })
  2654. })
  2655. }
  2656. const submitFormNoReport = async () => {
  2657. const params: any = {
  2658. ...unref(formData),
  2659. orderItemDetails: selectedEquipDetails.value,
  2660. flag: 0
  2661. }
  2662. if (params.reasonDict != 5) {
  2663. params.reason = ''
  2664. }
  2665. console.log('params', params)
  2666. formLoading.value = true
  2667. PipeTaskOrderApi.abortTask(params)
  2668. .then(() => {
  2669. // 刷新数据
  2670. ElMessage.success('无需上报操作成功')
  2671. emit('refresh')
  2672. })
  2673. .finally(() => {
  2674. formLoading.value = false
  2675. })
  2676. }
  2677. const handleAbortTask = () => {
  2678. if (selectedEquipDetails.value.length === 0) {
  2679. ElMessage.warning('请至少选择一条记录')
  2680. return
  2681. }
  2682. // 主报告状态,为报告办结的不能中止
  2683. const hasReportEnd = selectedEquips.value.some((row) => row.taskStatus === 800)
  2684. if (hasReportEnd) {
  2685. ElMessage.warning('主报告状态为报告办结的不能进行客户拒检')
  2686. return
  2687. }
  2688. abortFormRef.value && abortFormRef.value.resetFields()
  2689. dialogVisible.value = true
  2690. }
  2691. </script>
  2692. <style lang="scss" scoped>
  2693. .loading-text {
  2694. text-align: center;
  2695. padding: 20px;
  2696. color: #909399;
  2697. }
  2698. :deep(.el-descriptions__label) {
  2699. width: 10%;
  2700. }
  2701. :deep(.el-descriptions__content) {
  2702. width: 20%;
  2703. }
  2704. .leader-tag {
  2705. display: inline-block;
  2706. width: 16px;
  2707. height: 16px;
  2708. line-height: 14px;
  2709. text-align: center;
  2710. border: 1px solid #4475d6;
  2711. font-size: 12px;
  2712. margin-right: 4px;
  2713. color: #4475d6;
  2714. }
  2715. .app-container {
  2716. padding: 20px;
  2717. position: relative;
  2718. min-height: 100vh;
  2719. }
  2720. // 操作按钮对齐样式
  2721. .operation-buttons {
  2722. display: flex;
  2723. justify-content: center;
  2724. align-items: center;
  2725. gap: 8px;
  2726. flex-wrap: wrap;
  2727. }
  2728. .custom-block.tip {
  2729. padding: 0 6px;
  2730. background-color: var(--block-warning-bg-color);
  2731. border-left: 5px solid var(--el-color-primary);
  2732. margin: 15px 0;
  2733. }
  2734. .el-row {
  2735. margin: 1px;
  2736. }
  2737. </style>