equipTableList.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. <template>
  2. <ContentWrap title="设备清单">
  3. <!-- 锅炉设备展示 -->
  4. <template v-if="equipMainType === 200">
  5. <el-table
  6. ref="orderItemsTableRef"
  7. :data="taskOrderDetail.orderItems"
  8. border
  9. stripe
  10. empty-text="暂无设备信息"
  11. @selection-change="handleEquipSelectionChange"
  12. >
  13. <el-table-column type="selection" width="60" fixed="left" />
  14. <el-table-column label="操作" fixed="left" align="center" width="100">
  15. <template #default="scope">
  16. <div class="operation-buttons">
  17. <el-button
  18. v-if="scope.row.taskStatus === PressureCheckerMyTaskStatus.REPORT_END"
  19. link
  20. type="primary"
  21. size="small"
  22. :disabled="isTaskCancelled"
  23. @click="handlePreviewReport(scope.row)"
  24. >查看报告</el-button>
  25. </div>
  26. </template>
  27. </el-table-column>
  28. <el-table-column label="区域" align="center" min-width="120">
  29. <template #default="scope">
  30. <div>{{ scope.row.equipDistrictName || '-' }}</div>
  31. <div class="text-gray-400 text-sm">{{ scope.row.equipStreetName || '' }}</div>
  32. </template>
  33. </el-table-column>
  34. <el-table-column label="设备注册代码" align="center" min-width="190">
  35. <template #default="scope">
  36. <el-button link type="success" @click="handleEquipCodeFn(scope.row.equipId)">
  37. {{ scope.row.equipCode || '-' }}
  38. </el-button>
  39. <div class="mt-2px mb-2px">
  40. <el-tag v-if="scope.row.productNo" type="success">
  41. {{ scope.row.productNo }}
  42. </el-tag>
  43. </div>
  44. <el-tag v-if="scope.row.editType === 'reject'" type="danger" size="small" class="ml-1"
  45. >拒绝约检</el-tag>
  46. <el-tag v-if="scope.row.editType === 'add'" type="success" size="small" class="ml-1"
  47. >新增设备</el-tag>
  48. </template>
  49. </el-table-column>
  50. <el-table-column label="是否租借" align="center" prop="isRent" min-width="80">
  51. <template #default="scope">
  52. {{ scope.row.isRent ? '是' : '否' }}
  53. </template>
  54. </el-table-column>
  55. <el-table-column label="使用证编号" align="center" prop="useRegisterNo" min-width="120" />
  56. <el-table-column label="出厂编号" align="center" prop="factoryNo" min-width="120" />
  57. <el-table-column label="约检联系人" align="center" prop="contact" min-width="120" />
  58. <el-table-column label="约检联系人电话" align="center" prop="contactPhone" min-width="140" />
  59. <el-table-column label="蒸发量" align="center" prop="maxContinueEvapor" min-width="80" />
  60. <el-table-column label="型号" align="center" prop="boilerModel" min-width="120" />
  61. <el-table-column prop="taskStatus" label="主报告状态" width="100" align="center">
  62. <template #default="scope">
  63. <el-tag :type="getTypeColor(scope.row.taskStatus)">
  64. {{ PressureTaskOrderTaskStatusMap[scope.row.taskStatus] || '-' }}
  65. </el-tag>
  66. </template>
  67. </el-table-column>
  68. <el-table-column label="检验结论" align="center" prop="mainConclusion" min-width="120px">
  69. <template #default="scope">
  70. <div v-if="scope.row.mainConclusion">
  71. <el-tag
  72. v-if="['符合要求', '基本符合要求'].includes(scope.row.mainConclusion)"
  73. type="success"
  74. >{{ scope.row.mainConclusion }}</el-tag>
  75. <el-tag v-else type="danger">{{ scope.row.mainConclusion }}</el-tag>
  76. </div>
  77. <div v-else>-</div>
  78. </template>
  79. </el-table-column>
  80. </el-table>
  81. </template>
  82. <!-- 管道设备展示 -->
  83. <template v-else-if="equipMainType === 300">
  84. <el-table
  85. ref="orderItemsTableRef"
  86. :data="taskOrderDetail.orderItems"
  87. border
  88. stripe
  89. empty-text="暂无设备信息"
  90. row-key="id"
  91. @selection-change="handleEquipSelectionChange"
  92. >
  93. <el-table-column type="selection" width="60" fixed="left" />
  94. <el-table-column label="操作" fixed="left" align="center" width="100">
  95. <template #default="scope">
  96. <div class="operation-buttons">
  97. <el-button
  98. v-if="scope.row.taskStatus === PressureCheckerMyTaskStatus.REPORT_END"
  99. link
  100. type="primary"
  101. size="small"
  102. :disabled="isTaskCancelled"
  103. @click="handlePreviewReport(scope.row)"
  104. >查看报告</el-button>
  105. </div>
  106. </template>
  107. </el-table-column>
  108. <el-table-column type="expand" width="1">
  109. <template #default="scope">
  110. <div class="ml-15px mr-15px">
  111. <el-table :data="scope.row.detailDOS || []" border>
  112. <el-table-column label="注册代码" prop="pipeRegCode" min-width="120" show-overflow-tooltip />
  113. <el-table-column label="管道名称" prop="pipeName" min-width="120" show-overflow-tooltip />
  114. <el-table-column label="管道编号" prop="pipeNo" min-width="120" show-overflow-tooltip />
  115. <el-table-column label="管道级别" prop="pipeLevel" min-width="120" show-overflow-tooltip />
  116. <el-table-column label="管道品种" prop="pipeType" min-width="120" show-overflow-tooltip />
  117. <el-table-column label="长度" prop="pipeLength" min-width="100" show-overflow-tooltip />
  118. <el-table-column label="管道材质" prop="pipeMaterial" min-width="120" show-overflow-tooltip />
  119. <el-table-column label="材料标准" prop="materialStandard" min-width="120" show-overflow-tooltip />
  120. </el-table>
  121. </div>
  122. </template>
  123. </el-table-column>
  124. <el-table-column label="工程号" align="center" prop="projectNo" min-width="120" />
  125. <el-table-column label="使用证编号" align="center" prop="useNo" min-width="120" show-overflow-tooltip />
  126. <el-table-column label="工程名称" align="center" prop="projectName" min-width="120" show-overflow-tooltip />
  127. <el-table-column label="区域/街道" align="center" min-width="120" show-overflow-tooltip>
  128. <template #default="scope">
  129. <span class="text-xs">{{ scope.row.equipStreetName ?? scope.row.equipDistrictName }}</span>
  130. </template>
  131. </el-table-column>
  132. <el-table-column label="约检联系人" align="center" prop="contact" min-width="120" show-overflow-tooltip />
  133. <el-table-column label="约检联系人电话" align="center" prop="contactPhone" min-width="140" />
  134. <el-table-column prop="taskStatus" label="主报告状态" width="100" align="center">
  135. <template #default="scope">
  136. <el-tag :type="getTypeColor(scope.row.taskStatus)">
  137. {{ PressureTaskOrderTaskStatusMap[scope.row.taskStatus] || '-' }}
  138. </el-tag>
  139. </template>
  140. </el-table-column>
  141. <el-table-column label="检验结论" align="center" prop="mainConclusion" min-width="120px">
  142. <template #default="scope">
  143. <div v-if="scope.row.mainConclusion">
  144. <el-tag
  145. v-if="['符合要求', '基本符合要求'].includes(scope.row.mainConclusion)"
  146. type="success"
  147. >{{ scope.row.mainConclusion }}</el-tag>
  148. <el-tag v-else type="danger">{{ scope.row.mainConclusion }}</el-tag>
  149. </div>
  150. <div v-else>-</div>
  151. </template>
  152. </el-table-column>
  153. </el-table>
  154. </template>
  155. <!-- 默认展示 -->
  156. <template v-else>
  157. <el-table
  158. ref="orderItemsTableRef"
  159. :data="taskOrderDetail.orderItems"
  160. border
  161. stripe
  162. empty-text="暂无设备信息"
  163. @selection-change="handleEquipSelectionChange"
  164. >
  165. <el-table-column type="selection" width="60" fixed="left" />
  166. <el-table-column label="操作" fixed="left" align="center" width="100">
  167. <template #default="scope">
  168. <div class="operation-buttons">
  169. <el-button
  170. v-if="scope.row.taskStatus === PressureCheckerMyTaskStatus.REPORT_END"
  171. link
  172. type="primary"
  173. size="small"
  174. :disabled="isTaskCancelled"
  175. @click="handlePreviewReport(scope.row)"
  176. >查看报告</el-button>
  177. </div>
  178. </template>
  179. </el-table-column>
  180. <el-table-column prop="equipName" label="设备名称" width="100" align="center" />
  181. <el-table-column prop="fee" label="收费金额" width="100" align="center" />
  182. <el-table-column prop="equipCode" label="设备注册代码" width="195" align="center">
  183. <template #default="scope">
  184. <el-button link type="success" @click="handleEquipCodeFn(scope.row.equipId)">{{
  185. scope.row.equipCode
  186. }}</el-button>
  187. <div class="mt-2px mb-2px">
  188. <el-tag v-if="scope.row.productNo" type="success">
  189. {{ scope.row.productNo }}
  190. </el-tag>
  191. </div>
  192. <el-tag v-if="scope.row.editType === 'reject'" type="danger" size="small" class="ml-1"
  193. >拒绝约检</el-tag>
  194. <el-tag v-if="scope.row.editType === 'add'" type="success" size="small" class="ml-1"
  195. >新增设备</el-tag>
  196. </template>
  197. </el-table-column>
  198. <el-table-column prop="reportRespVOList" label="记录编号" width="100" align="center">
  199. <template #default="{ row }">
  200. {{ Array.isArray(row.reportRespVOList) ? row.reportRespVOList[0]?.reportNo || '-' : '-' }}
  201. </template>
  202. </el-table-column>
  203. <el-table-column prop="checkType" label="检验性质" width="100" align="center">
  204. <template #default>
  205. {{ PressureCheckTypeMap[taskOrderDetail.checkType] || '-' }}
  206. </template>
  207. </el-table-column>
  208. <el-table-column
  209. prop="reportRespVOList"
  210. label="检验项目"
  211. min-width="550"
  212. header-align="center"
  213. >
  214. <template #default="{ row }">
  215. <span v-for="item in getRowReportVOList(row)" :key="item?.templateId">
  216. <el-button
  217. :disabled="
  218. taskOrder?.taskStatus === PressureTaskOrderTaskStatus['REPORT_END'] ||
  219. canAddReportItem(row.taskStatus) ||
  220. taskOrder?.taskStatus === PressureTaskOrderTaskStatus['AUDITING_CANCEL']
  221. "
  222. link
  223. type="primary"
  224. class="!whitespace-normal !m-[0px]"
  225. >{{ item?.reportName }}</el-button>
  226. <el-button
  227. :disabled="
  228. taskOrder?.taskStatus === PressureTaskOrderTaskStatus['REPORT_END'] ||
  229. taskOrder?.taskStatus === PressureTaskOrderTaskStatus['AUDITING_CANCEL']
  230. "
  231. link
  232. type="primary"
  233. class="!m-[0px]"
  234. >({{ getCheckItemFeeType(item) }})</el-button>
  235. </span>
  236. </template>
  237. </el-table-column>
  238. <el-table-column prop="reportRespVOList" label="操作指导书名称" width="180" align="center">
  239. <template #default="{ row }">
  240. <template
  241. v-if="
  242. filterReportType(row.reportRespVOList, PressureReportType['WORKINSTRUCTION']).length
  243. "
  244. >
  245. <template
  246. v-if="
  247. filterReportType(row.reportRespVOList, PressureReportType['WORKINSTRUCTION'])
  248. .length <= 2
  249. "
  250. >
  251. <el-button
  252. class="!whitespace-normal !m-[0px] w-full"
  253. link
  254. v-for="(item, index) in filterReportType(
  255. row.reportRespVOList,
  256. PressureReportType['WORKINSTRUCTION']
  257. )"
  258. :type="item?.taskStatus != 800 ? 'danger' : 'success'"
  259. :key="index"
  260. @click="handlePreviewDownload(item)"
  261. >{{ item?.reportName ? `${item?.reportName}` : '-' }}</el-button>
  262. </template>
  263. <!-- 弹窗 -->
  264. <el-popover v-else placement="top-start" :width="200" trigger="hover">
  265. <el-button
  266. class="!whitespace-normal !m-[0px] w-full"
  267. link
  268. v-for="(item, index) in filterReportType(
  269. row.reportRespVOList,
  270. PressureReportType['WORKINSTRUCTION']
  271. )"
  272. :type="item?.taskStatus != 800 ? 'danger' : 'success'"
  273. :key="index"
  274. @click="handlePreviewDownload(item)"
  275. >{{ item?.reportName ? `${item?.reportName}` : '-' }}</el-button>
  276. <template #reference>
  277. <div>
  278. <el-button
  279. class="!whitespace-normal !m-[0px] w-full"
  280. link
  281. v-for="(item, index) in filterReportType(
  282. row.reportRespVOList,
  283. PressureReportType['WORKINSTRUCTION']
  284. ).slice(0, 2)"
  285. :type="item?.taskStatus != 800 ? 'danger' : 'success'"
  286. :key="index"
  287. @click="handlePreviewDownload(item)"
  288. >{{ item?.reportName ? `${item?.reportName}` : '-' }}</el-button>
  289. </div>
  290. </template>
  291. </el-popover>
  292. </template>
  293. <span v-else>-</span>
  294. </template>
  295. </el-table-column>
  296. <el-table-column prop="reportRespVOList" label="检验方案" min-width="180" align="center">
  297. <template #default="{ row }">
  298. <template
  299. v-if="
  300. filterReportType(
  301. row.reportRespVOList,
  302. PressureReportType['INSPECTIONPLAN'],
  303. row.majorIssuesList
  304. ).length
  305. "
  306. >
  307. <template
  308. v-if="
  309. filterReportType(
  310. row.reportRespVOList,
  311. PressureReportType['INSPECTIONPLAN'],
  312. row.majorIssuesList
  313. ).length <= 2
  314. "
  315. >
  316. <el-button
  317. class="!whitespace-normal !m-[0px] w-full"
  318. link
  319. v-for="(item, index) in filterReportType(
  320. row.reportRespVOList,
  321. PressureReportType['INSPECTIONPLAN'],
  322. row.majorIssuesList
  323. )"
  324. :type="item?.taskStatus != 800 ? 'danger' : 'success'"
  325. :key="index"
  326. @click="handlePreviewDownload(item)"
  327. >{{
  328. item?.reportName ? `${item?.reportName}(${item.currentIndex})` : '-'
  329. }}</el-button>
  330. </template>
  331. <!-- 弹窗 -->
  332. <el-popover v-else placement="top-start" :width="200" trigger="hover">
  333. <el-button
  334. class="!whitespace-normal !m-[0px] w-full"
  335. link
  336. v-for="(item, index) in filterReportType(
  337. row.reportRespVOList,
  338. PressureReportType['INSPECTIONPLAN'],
  339. row.majorIssuesList
  340. )"
  341. :type="item?.taskStatus != 800 ? 'danger' : 'success'"
  342. :key="index"
  343. @click="handlePreviewDownload(item)"
  344. >{{
  345. item?.reportName ? `${item?.reportName}(${item.currentIndex})` : '-'
  346. }}</el-button>
  347. <template #reference>
  348. <div>
  349. <el-button
  350. class="!whitespace-normal !m-[0px] w-full"
  351. link
  352. v-for="(item, index) in filterReportType(
  353. row.reportRespVOList,
  354. PressureReportType['INSPECTIONPLAN'],
  355. row.majorIssuesList
  356. ).slice(0, 2)"
  357. :type="item?.taskStatus != 800 ? 'danger' : 'success'"
  358. :key="index"
  359. @click="handlePreviewDownload(item)"
  360. >{{
  361. item?.reportName ? `${item?.reportName}(${item.currentIndex})` : '-'
  362. }}</el-button>
  363. </div>
  364. </template>
  365. </el-popover>
  366. </template>
  367. <span v-else>-</span>
  368. </template>
  369. </el-table-column>
  370. <el-table-column prop="taskStatus" label="主报告状态" width="100" align="center">
  371. <template #default="scope">
  372. <el-tag :type="getTypeColor(scope.row.taskStatus)">
  373. {{ PressureTaskOrderTaskStatusMap[scope.row.taskStatus] || '-' }}
  374. </el-tag>
  375. </template>
  376. </el-table-column>
  377. <el-table-column label="检验结论" align="center" prop="mainConclusion" min-width="120px">
  378. <template #default="scope">
  379. <div v-if="scope.row.mainConclusion">
  380. <el-tag
  381. v-if="['符合要求', '基本符合要求'].includes(scope.row.mainConclusion)"
  382. type="success"
  383. >{{ scope.row.mainConclusion }}</el-tag>
  384. <el-tag v-else type="danger">{{ scope.row.mainConclusion }}</el-tag>
  385. </div>
  386. <div v-else>-</div>
  387. </template>
  388. </el-table-column>
  389. <el-table-column prop="equipDistrictName" align="center" label="区域" width="100">
  390. <template #default="scope">
  391. <div>{{ scope.row.equipDistrictName }}</div>
  392. <div class="text-gray-400 text-sm">{{ scope.row.equipStreetName }}</div>
  393. </template>
  394. </el-table-column>
  395. <el-table-column prop="useRegisterNo" label="使用证编号" width="135" align="center" />
  396. <el-table-column prop="equipVolume" label="容积" width="60" align="center" />
  397. <el-table-column label="下次年度检查" width="110" align="center">
  398. <template #default="scope">
  399. {{ !scope.row.nextYearCheckDate ? '-' : formatArrayDate(scope.row.nextYearCheckDate) }}
  400. </template>
  401. </el-table-column>
  402. <el-table-column label="下次定期检验" width="110" align="center">
  403. <template #default="scope">
  404. {{ formatArrayDate(scope.row.nextCheckDate) }}
  405. </template>
  406. </el-table-column>
  407. <el-table-column label="超年限检验" width="110" align="center">
  408. <template #default="scope">
  409. {{
  410. scope.row.nextExpiredCheckDate ? formatArrayDate(scope.row.nextExpiredCheckDate) : '-'
  411. }}
  412. </template>
  413. </el-table-column>
  414. <el-table-column label="超年限时间" width="110" align="center">
  415. <template #default="scope">
  416. {{ scope.row.overdueDate ? formatArrayDate(scope.row.overdueDate) : '-' }}
  417. </template>
  418. </el-table-column>
  419. <el-table-column
  420. label="约检联系人"
  421. prop="contact"
  422. width="110"
  423. align="center"
  424. show-overflow-tooltip
  425. />
  426. <el-table-column label="约检联系人电话" prop="contactPhone" width="135" align="center" />
  427. <el-table-column label="主检人" width="110" align="center">
  428. <template #default="scope">
  429. <div>{{ scope.row.mainCheckerUser?.nickname || '-' }}</div>
  430. <div class="text-gray-400 text-sm">{{ scope.row.mainCheckerUser?.employeeNo || '' }}</div>
  431. </template>
  432. </el-table-column>
  433. </el-table>
  434. </template>
  435. </ContentWrap>
  436. <!-- 打印记录 -->
  437. <Dialog
  438. v-model="nprintRecordDialogVisible"
  439. :dialogAttrs="{
  440. zIndex: 10006
  441. }"
  442. :title="'打印项目'"
  443. >
  444. <SmartTable
  445. ref="nprintRecordTableRef"
  446. v-model:columns="nprintRecordColumns"
  447. :isPagination="false"
  448. :maxHeight="600"
  449. :data="nprintRecordTableList"
  450. :buttons="[]"
  451. :showSettingTools="false"
  452. :showSearch="false"
  453. :showRefresh="false"
  454. :tableProps="{
  455. onRowClick: handleRowClick
  456. }"
  457. />
  458. <template #footer>
  459. <el-button :loading="nprintRecordLoading" type="primary" @click="handlePrintFn"
  460. >打 印</el-button>
  461. <el-button :loading="nprintRecordLoading" type="primary" @click="handlePrintFnDownload"
  462. >下 载</el-button>
  463. <el-button :loading="nprintRecordLoading" @click="nprintRecordDialogVisible = false"
  464. >取 消</el-button>
  465. </template>
  466. </Dialog>
  467. </template>
  468. <script setup lang="tsx">
  469. import {
  470. PressureCheckTypeMap,
  471. PressureTaskOrderTaskStatus,
  472. PressureTaskOrderTaskStatusMap,
  473. PressureCheckerMyTaskStatusMap,
  474. PressureCheckerMyTaskStatus,
  475. PressureReportType
  476. } from '@/utils/constants'
  477. import SmartTable from '@/components/SmartTable/SmartTable'
  478. import { SmartTableColumn } from '@/types/table'
  479. import { is } from '@/utils/is'
  480. import { formatArrayDate } from '@/utils/formatTime'
  481. import { TableInstance } from 'element-plus'
  482. import { TaskOrderApi } from '@/api/pressure/taskorder'
  483. import { BoilerTaskOrderApi } from '@/api/pressure2/boilertaskorder'
  484. import { PipeTaskOrderApi } from '@/api/pressure2/pipetaskorder'
  485. import { buildFileUrl } from '@/utils'
  486. import { getJCP } from '@/utils/jcp/jcp-vue'
  487. const props = defineProps({
  488. taskOrder: {
  489. type: Object as () => Record<string, any>,
  490. required: true
  491. },
  492. taskOrderDetail: {
  493. type: Object as () => Record<string, any>,
  494. required: true
  495. },
  496. supportingDocsAuditDataList: {
  497. type: Array as () => Record<string, any>[],
  498. required: true
  499. }
  500. })
  501. // 设备类型 200-锅炉 300-管道
  502. const equipMainType = computed(() => {
  503. return props.taskOrderDetail?.equipMainType || null
  504. })
  505. // 根据 equipMainType 获取对应的 API
  506. const getCurrentApi = () => {
  507. if (equipMainType.value === 200) {
  508. return BoilerTaskOrderApi
  509. } else if (equipMainType.value === 300) {
  510. return PipeTaskOrderApi
  511. }
  512. return TaskOrderApi // 默认
  513. }
  514. const InformationModificationVisible = ref(false) // 弹窗的是否展示
  515. const formLoading = ref(false)
  516. const formData = ref({
  517. safeManager: '', //安全管理员姓名
  518. safeManagerPhone: '', //安全管理员电话
  519. safeManagerIdNumber: '', //安全管理员证号
  520. operatorIdNumber: '' //操作人证号
  521. })
  522. const formRules = reactive({})
  523. const formRef = ref() // 表单 Ref
  524. const nprintRecordLoading = ref(false)
  525. const nprintRecordTableRef = ref()
  526. const nprintRecordDialogVisible = ref(false)
  527. const nprintRecordTableList = ref<any[]>([])
  528. const nprintRecordColumns = ref<SmartTableColumn[]>([
  529. {
  530. type: 'selection',
  531. width: '50px'
  532. },
  533. {
  534. label: '检验项目',
  535. prop: 'reportName'
  536. },
  537. {
  538. label: '状态',
  539. prop: 'taskStatus',
  540. render: (row) => {
  541. return row.taskStatus ? (
  542. <div>
  543. <el-tag key={row.id} type={getTypeColor2(row.taskStatus)}>
  544. {PressureCheckerMyTaskStatusMap[row.taskStatus]}
  545. </el-tag>
  546. </div>
  547. ) : (
  548. '-'
  549. )
  550. }
  551. }
  552. ])
  553. const emit = defineEmits([
  554. 'refresh-detail',
  555. 'handle-add-checker-items',
  556. 'handle-mainquestion-add-report',
  557. 'handle-add-inspectionplan-report',
  558. 'handle-batch-edit-fn',
  559. 'handle-abort-task',
  560. 'handle-equip-selection-change',
  561. 'handle-equip-code-fn',
  562. 'handle-input-calc-field',
  563. 'handle-preview-download',
  564. 'handle-add-report',
  565. 'handle-view-mainquestion-report',
  566. 'handle-set-main-checker',
  567. 'handle-preview-report',
  568. 'handle-add-finite-space-report'
  569. ])
  570. const rowData = ref<any>({})
  571. const selectedEquips = ref<Array<Record<string, any>>>([])
  572. const handlePrintFnDownload = async () => {
  573. const selectRows = nprintRecordTableRef.value.getTableRef().getSelectionRows()
  574. if (selectRows.length == 0) {
  575. return ElMessage.error('请选择打印项目')
  576. } else {
  577. const params = selectRows.map((item) => item.id)
  578. const currentApi = getCurrentApi()
  579. const result = await currentApi.downloadReport({ ids: params })
  580. const downloadUrl = window.URL.createObjectURL(result)
  581. const a = document.createElement('a')
  582. a.href = downloadUrl
  583. const fileName = `${rowData.value.equipCode}` + '项目'
  584. a.download = fileName
  585. document.body.appendChild(a)
  586. a.click()
  587. // 下载文件
  588. window.URL.revokeObjectURL(downloadUrl)
  589. document.body.removeChild(a)
  590. }
  591. }
  592. const handleRowClick = (row) => {
  593. nprintRecordTableRef.value?.getTableRef()?.toggleRowSelection(row)
  594. }
  595. const handlePrintFn = async () => {
  596. const selectRows = nprintRecordTableRef.value.getTableRef().getSelectionRows()
  597. if (selectRows.length == 0) {
  598. return ElMessage.error('请选择打印项目')
  599. }
  600. const ids = selectRows.map((item) => item.id)
  601. const queryString = ids.map((id) => `ids=${id}`).join('&')
  602. nprintRecordLoading.value = true
  603. try {
  604. const currentApi = getCurrentApi()
  605. const result = await currentApi.getBatchUploadPdfApi(queryString)
  606. if (!result || result.length === 0) {
  607. nprintRecordLoading.value = false
  608. return ElMessage.error('未获取到打印文件')
  609. }
  610. const jcp = getJCP()
  611. // 检测JCP是否可用
  612. if (!jcp) {
  613. nprintRecordLoading.value = false
  614. return ElMessage.error('打印组件未初始化,请安装打印插件')
  615. }
  616. let completedCount = 0
  617. let failedCount = 0
  618. // 循环打印每个PDF
  619. for (let i = 0; i < result.length; i++) {
  620. const url = buildFileUrl(result[i])
  621. const encodedUrl = url
  622. .split('/')
  623. .map((part) => {
  624. return /[\u4e00-\u9fa5]/.test(part) ? encodeURIComponent(part) : part
  625. })
  626. .join('/')
  627. // 为每个打印任务添加超时处理
  628. await new Promise((resolve) => {
  629. let isResolved = false
  630. // 设置10秒超时
  631. const timeout = setTimeout(() => {
  632. if (!isResolved) {
  633. isResolved = true
  634. failedCount++
  635. console.error(`第 ${i + 1} 个文件打印超时(可能用户取消了打印)`)
  636. resolve(false)
  637. }
  638. }, 5000) // 5秒超时,可根据实际情况调整
  639. jcp.printPDF(encodedUrl, {
  640. settings: {
  641. paperName: 'A4',
  642. orientation: 'portrait',
  643. marginTop: 0,
  644. marginBottom: 0,
  645. marginLeft: 0,
  646. marginRight: 0,
  647. shrink: false
  648. },
  649. printer: '',
  650. preview: false,
  651. fileType: 'pdf',
  652. done: function () {
  653. if (!isResolved) {
  654. isResolved = true
  655. clearTimeout(timeout)
  656. completedCount++
  657. console.log(`第 ${i + 1} 个文件打印完成`)
  658. resolve(true)
  659. }
  660. },
  661. fail: function (error) {
  662. if (!isResolved) {
  663. isResolved = true
  664. clearTimeout(timeout)
  665. failedCount++
  666. console.error(`第 ${i + 1} 个文件打印失败:`, error)
  667. resolve(false)
  668. }
  669. }
  670. })
  671. })
  672. }
  673. // 显示最终结果
  674. if (failedCount === 0) {
  675. ElMessage.success(`全部打印完成,共 ${completedCount} 个文件`)
  676. } else if (completedCount === 0) {
  677. ElMessage.error(`打印失败,共 ${failedCount} 个文件未能打印`)
  678. } else {
  679. ElMessage.warning(`打印完成 ${completedCount} 个,失败 ${failedCount} 个`)
  680. }
  681. } catch (error) {
  682. console.error('打印过程出错:', error)
  683. ElMessage.error('打印过程出错: ' + (error.message || '未知错误'))
  684. } finally {
  685. // 确保无论如何都会关闭loading
  686. nprintRecordLoading.value = false
  687. }
  688. }
  689. // 作废报告项
  690. const submitForm = async () => {
  691. if (!formRef) return
  692. const valid = await formRef.value.validate()
  693. if (!valid) return
  694. // 提交请求
  695. formLoading.value = true
  696. try {
  697. const selectRows = getSelectionRows()
  698. const data = {
  699. ...formData.value,
  700. ids: selectRows.map((item) => item.equipId)
  701. }
  702. const logId = await TaskOrderApi.updateEquipJobInfoApi(data)
  703. if (logId) {
  704. ElMessage.success('修改成功')
  705. }
  706. InformationModificationVisible.value = false
  707. } finally {
  708. formLoading.value = false
  709. }
  710. }
  711. const orderItemsTableRef = ref<TableInstance>()
  712. const handleEquipSelectionChange = (selection) => {
  713. // 实现设备选择逻辑
  714. selectedEquips.value = selection
  715. emit('handle-equip-selection-change', selection)
  716. }
  717. const isTaskCancelled = computed(() => {
  718. return props.taskOrderDetail?.taskStatus === PressureTaskOrderTaskStatus.CANCELLED
  719. })
  720. const handlePreviewReport = (row: any) => {
  721. emit('handle-preview-report', row)
  722. }
  723. const handleEquipCodeFn = (id?: string) => {
  724. emit('handle-equip-code-fn', id)
  725. }
  726. const getRowReportVOList = (row) => {
  727. return (row.reportRespVOList || []).filter(
  728. (item) =>
  729. ![PressureReportType['WORKINSTRUCTION'], PressureReportType['INSPECTIONPLAN']].includes(
  730. item.reportType
  731. )
  732. )
  733. }
  734. const canAddReportItem = (taskStatus) => {
  735. const { REPORT_AUDIT, REPORT_APPROVE, REPORT_END } = PressureCheckerMyTaskStatus
  736. return [REPORT_AUDIT, REPORT_APPROVE, REPORT_END].includes(taskStatus)
  737. }
  738. const getCheckItemFeeType = computed(() => {
  739. return ({ isAutoAmount, fee }) => {
  740. if (is(fee, 'Number')) return fee
  741. else if (is(fee, 'Null') && isAutoAmount === '1') return '录入计算'
  742. else return '0'
  743. }
  744. })
  745. const filterReportType = (list: any[], reportType: number, majorIssuesList?: any[]) => {
  746. const reportList = list.filter((item) => item.reportType === reportType)
  747. const majorIssuesListValue = majorIssuesList?.map((item) => item) || []
  748. const newList = [...reportList, ...majorIssuesListValue]
  749. const sortedList = newList.sort((a, b) => {
  750. const timeA = a.createTime || 0
  751. const timeB = b.createTime || 0
  752. return timeB - timeA // 倒序排列
  753. })
  754. const total = sortedList.length
  755. return sortedList.map((item, index) => {
  756. return {
  757. ...item,
  758. currentIndex: total - index // 倒序编号:第一个显示的是最大数字
  759. }
  760. })
  761. }
  762. const handlePreviewDownload = (row) => {
  763. emit('handle-preview-download', row)
  764. }
  765. const getTypeColor = (status: string | number) => {
  766. const statusMap = {
  767. [PressureTaskOrderTaskStatus.WAIT_CONFIRM]: 'primary',
  768. [PressureTaskOrderTaskStatus.CANCELLED]: 'info',
  769. [PressureTaskOrderTaskStatus.AUDITING_EDIT]: 'warning',
  770. [PressureTaskOrderTaskStatus.AUDITING_CANCEL]: 'warning',
  771. [PressureTaskOrderTaskStatus.AUDITING_TIME]: 'warning',
  772. [PressureTaskOrderTaskStatus.CONFIRMED]: 'success',
  773. [PressureTaskOrderTaskStatus.RECORD_INPUT]: 'warning',
  774. [PressureTaskOrderTaskStatus.RECORD_CHECK]: 'warning',
  775. [PressureTaskOrderTaskStatus.REPORT_INPUT]: 'warning',
  776. [PressureTaskOrderTaskStatus.REPORT_AUDIT]: 'warning',
  777. [PressureTaskOrderTaskStatus.REPORT_APPROVE]: 'warning',
  778. [PressureTaskOrderTaskStatus.REPORT_END]: 'primary'
  779. }
  780. return statusMap[status] || 'info'
  781. }
  782. const getTypeColor2 = (status: string | number) => {
  783. const statusMap = {
  784. [PressureTaskOrderTaskStatus.WAIT_CONFIRM]: 'primary',
  785. [PressureTaskOrderTaskStatus.CANCELLED]: 'info',
  786. [PressureTaskOrderTaskStatus.AUDITING_EDIT]: 'warning',
  787. [PressureTaskOrderTaskStatus.AUDITING_CANCEL]: 'warning',
  788. [PressureTaskOrderTaskStatus.AUDITING_TIME]: 'warning',
  789. [PressureTaskOrderTaskStatus.CONFIRMED]: 'success',
  790. [PressureTaskOrderTaskStatus.RECORD_INPUT]: 'warning',
  791. [PressureTaskOrderTaskStatus.RECORD_CHECK]: 'warning',
  792. [PressureTaskOrderTaskStatus.REPORT_INPUT]: 'warning',
  793. [PressureTaskOrderTaskStatus.REPORT_AUDIT]: 'warning',
  794. [PressureTaskOrderTaskStatus.REPORT_APPROVE]: 'warning',
  795. [PressureTaskOrderTaskStatus.REPORT_END]: 'success'
  796. }
  797. return statusMap[status] || 'info'
  798. }
  799. const getSelectionRows = () => {
  800. return orderItemsTableRef.value?.getSelectionRows() || []
  801. }
  802. defineExpose({
  803. getSelectionRows
  804. })
  805. </script>