certificate.vue 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954
  1. <template>
  2. <ContentWrap>
  3. <!-- 搜索工作栏 -->
  4. <el-form
  5. class="-mb-15px"
  6. :model="queryParams"
  7. ref="queryFormRef"
  8. :inline="true"
  9. label-width="100px"
  10. >
  11. <el-form-item label="产品编号" prop="productNo">
  12. <el-input
  13. v-model="queryParams.productNo"
  14. placeholder="请输入产品编号"
  15. clearable
  16. @keyup.enter="handleQuery"
  17. class="!w-240px"
  18. />
  19. </el-form-item>
  20. <el-form-item label="任务单号" prop="orderNo">
  21. <el-input
  22. v-model="queryParams.orderNo"
  23. placeholder="请输入任务单号"
  24. clearable
  25. @keyup.enter="handleQuery"
  26. class="!w-240px"
  27. />
  28. </el-form-item>
  29. <el-form-item label="检验结论" prop="reportConclusion">
  30. <el-select
  31. v-model="queryParams.reportConclusion"
  32. placeholder="请选择检验结论"
  33. clearable
  34. class="!w-240px"
  35. >
  36. <el-option label="符合要求" value="符合要求" />
  37. <el-option label="基本符合要求" value="基本符合要求" />
  38. <el-option label="不符合要求" value="不符合要求" />
  39. </el-select>
  40. </el-form-item>
  41. <el-form-item label="使用单位" prop="useUnitName">
  42. <el-input
  43. v-model="queryParams.useUnitName"
  44. placeholder="请输入使用单位"
  45. clearable
  46. @keyup.enter="handleQuery"
  47. class="!w-240px"
  48. />
  49. </el-form-item>
  50. <el-form-item label="设备注册代码" prop="equipCode">
  51. <el-input
  52. v-model="queryParams.equipCode"
  53. placeholder="请输入设备注册代码"
  54. clearable
  55. @keyup.enter="handleQuery"
  56. class="!w-240px"
  57. />
  58. </el-form-item>
  59. <el-form-item label="使用登记编号" prop="useRegisterNo">
  60. <el-input
  61. v-model="queryParams.useRegisterNo"
  62. placeholder="请输入使用登记编号"
  63. clearable
  64. @keyup.enter="handleQuery"
  65. class="!w-240px"
  66. />
  67. </el-form-item>
  68. <el-form-item label="报告编号" prop="reportNo">
  69. <el-input
  70. v-model="queryParams.reportNo"
  71. placeholder="请输入报告编号"
  72. clearable
  73. @keyup.enter="handleQuery"
  74. class="!w-240px"
  75. />
  76. </el-form-item>
  77. <el-form-item label="检验性质" prop="checkType">
  78. <el-select
  79. v-model="queryParams.checkType"
  80. placeholder="请选择检验性质"
  81. clearable
  82. class="!w-240px"
  83. >
  84. <el-option
  85. v-for="(item, key) in PressurePipeCheckTypeMap"
  86. :key="key"
  87. :label="item"
  88. :value="key"
  89. />
  90. </el-select>
  91. </el-form-item>
  92. <el-form-item label="检验时间" prop="checkDate">
  93. <el-date-picker
  94. v-model="queryParams.checkDate"
  95. value-format="YYYY-MM-DD"
  96. type="daterange"
  97. start-placeholder="开始日期"
  98. end-placeholder="结束日期"
  99. :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
  100. class="!w-240px"
  101. />
  102. </el-form-item>
  103. <el-form-item label="批准时间" prop="ratifyTime">
  104. <el-date-picker
  105. v-model="queryParams.ratifyTime"
  106. value-format="YYYY-MM-DD HH:mm:ss"
  107. type="daterange"
  108. start-placeholder="开始日期"
  109. end-placeholder="结束日期"
  110. :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
  111. class="!w-240px"
  112. />
  113. </el-form-item>
  114. <el-form-item label="缴费情况" prop="paymentStatus">
  115. <el-select
  116. v-model="queryParams.paymentStatus"
  117. placeholder="请选择缴费情况"
  118. clearable
  119. class="!w-240px"
  120. @change="handleQuery"
  121. >
  122. <el-option label="待缴费" :value="0" />
  123. <el-option label="已缴费" :value="1" />
  124. </el-select>
  125. </el-form-item>
  126. <el-form-item label="发放状态" prop="releaseStatus">
  127. <el-select
  128. v-model="queryParams.releaseStatus"
  129. placeholder="请选择发放状态"
  130. clearable
  131. class="!w-240px"
  132. >
  133. <el-option
  134. v-for="(item, key) in PrintIssueStatusMap"
  135. :key="key"
  136. :label="item"
  137. :value="key"
  138. />
  139. </el-select>
  140. </el-form-item>
  141. <el-form-item label="部门" prop="deptName">
  142. <DeptSelect
  143. v-model="queryParams.deptId"
  144. placeholder="请选择部门"
  145. clearable
  146. class="!w-240px"
  147. />
  148. </el-form-item>
  149. <el-form-item>
  150. <el-button @click="handleQuery">
  151. <Icon icon="ep:search" class="mr-0.05rem" /> 搜索
  152. </el-button>
  153. <el-button @click="resetQuery">
  154. <Icon icon="ep:refresh" class="mr-0.05rem" /> 重置
  155. </el-button>
  156. <el-button
  157. :disabled="selectedRows.length === 0"
  158. type="primary"
  159. @click="handlePrintIssuebution"
  160. >
  161. <Icon icon="ep:plus" class="mr-0.05rem" /> 打印发放
  162. </el-button>
  163. <el-button
  164. type="primary"
  165. :disabled="selectedRows.length === 0"
  166. @click="handleElectronicDistribution"
  167. >
  168. <Icon icon="ep:plus" class="mr-0.05rem" /> 电子发放
  169. </el-button>
  170. <el-button
  171. type="primary"
  172. @click="
  173. () => {
  174. handleRoute('PressureIssueReportPipe')
  175. }
  176. "
  177. >
  178. 按任务单发放
  179. </el-button>
  180. </el-form-item>
  181. </el-form>
  182. </ContentWrap>
  183. <!-- 列表 -->
  184. <ContentWrap>
  185. <el-table
  186. ref="tableRef"
  187. v-loading="loading"
  188. :data="list"
  189. :stripe="true"
  190. @selection-change="handleSelectionChange"
  191. >
  192. <el-table-column type="selection" width="40" align="center" fixed="left" />
  193. <!-- 操作 -->
  194. <el-table-column label="操作" align="center" min-width="150px" fixed="left">
  195. <template #default="scope">
  196. <el-button link type="primary" @click="toPreview(scope.row.orderId)"> 预览 </el-button>
  197. <el-button link type="primary" @click="handlePrint(scope.row)"> 打印 </el-button>
  198. <el-button link type="primary" @click="handleDownload2(scope.row)"> 下载 </el-button>
  199. <el-button
  200. link
  201. type="primary"
  202. v-if="signShowFn(scope.row)"
  203. @click="handleSign(scope.row.id, scope.row.equipCode)"
  204. >
  205. 标志
  206. </el-button>
  207. </template>
  208. </el-table-column>
  209. <el-table-column label="打印记录" align="center" prop="printRecordNum" min-width="120px">
  210. <template #default="scope">
  211. <el-button
  212. type="primary"
  213. link
  214. class="decoration-underline"
  215. @click="handleViewPrintRecord(scope.row)"
  216. :disabled="!scope.row.printRecordNum"
  217. >
  218. {{ scope.row.printRecordNum || 0 }}
  219. </el-button>
  220. </template>
  221. </el-table-column>
  222. <el-table-column label="打印状态" align="center" prop="printIssueStatus" min-width="120px">
  223. <template #default="scope">
  224. <el-tag v-if="!!scope.row.printRecordNum" type="primary">已打印</el-tag>
  225. <el-tag v-else type="warning">未打印</el-tag>
  226. </template>
  227. </el-table-column>
  228. <el-table-column label="发放记录" align="center" prop="releaseRecordNum" min-width="120px">
  229. <template #default="scope">
  230. <span
  231. v-if="scope.row.releaseRecordNum"
  232. class="report-count-link"
  233. @click="handleViewReportRecord(scope.row.reportId,scope.row.equipId)"
  234. >
  235. {{ scope.row.releaseRecordNum }}
  236. </span>
  237. <span v-else>-</span>
  238. </template>
  239. </el-table-column>
  240. <el-table-column label="发放状态" align="center" prop="releaseStatus" min-width="120px">
  241. <template #default="scope">
  242. <el-tag v-if="scope.row.releaseRecordNum" type="primary">已发放</el-tag>
  243. <el-tag v-else type="warning">未发放</el-tag>
  244. </template>
  245. </el-table-column>
  246. <el-table-column label="缴费情况" align="center" prop="paymentStatus" min-width="120px">
  247. <template #default="scope">
  248. {{ PrintIssuePaymentStatusMap[scope.row.paymentStatus] }}
  249. </template>
  250. </el-table-column>
  251. <el-table-column label="检验结论" align="center" prop="reportConclusion" min-width="120px">
  252. <template #default="scope">
  253. <el-tag
  254. v-if="['符合要求', '基本符合要求'].includes(scope.row.reportConclusion)"
  255. type="success"
  256. >{{ scope.row.reportConclusion }}</el-tag
  257. >
  258. <el-tag v-else-if="['不符合要求'].includes(scope.row.reportConclusion)" type="danger">{{
  259. scope.row.reportConclusion
  260. }}</el-tag>
  261. <div v-else>{{scope.row.reportConclusion || '-'}}</div>
  262. </template>
  263. </el-table-column>
  264. <el-table-column label="任务单号" align="center" prop="orderNo" min-width="120px" />
  265. <!-- <el-table-column label="产品编号" align="center" prop="productNo" min-width="120px" />-->
  266. <el-table-column
  267. label="使用登记证编号"
  268. align="center"
  269. prop="useRegisterNo"
  270. min-width="120px"
  271. />
  272. <el-table-column label="使用单位" align="center" prop="useUnitName" min-width="120px" show-overflow-tooltip>
  273. <template #default="{row}">
  274. <div style="color: #015293; cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" @click="handleUnitCodeFn(row.useUnitName)">{{row.useUnitName}}</div>
  275. </template>
  276. </el-table-column>
  277. <el-table-column label="报告编号" align="center" prop="reportNo" min-width="120px" />
  278. <el-table-column label="批准时间" align="center" prop="ratifyTime" min-width="120px">
  279. <template #default="scope">
  280. <div v-if="scope.row.ratifyTime">
  281. {{ formatDate(scope.row.ratifyTime) }}
  282. </div>
  283. <span v-else>-</span>
  284. </template>
  285. </el-table-column>
  286. <el-table-column label="工程号" align="center" prop="equipCode" min-width="120px" />
  287. <el-table-column label="检验性质" align="center" prop="checkType" min-width="120px">
  288. <template #default="scope">
  289. {{ PressurePipeCheckTypeMap[scope.row.checkType] }}
  290. </template>
  291. </el-table-column>
  292. <el-table-column label="委托协议" align="center" prop="templateName" min-width="120px">
  293. <template #default="scope">
  294. <div
  295. v-if="scope.row.templateName"
  296. style="color: #409eff; cursor: pointer"
  297. @click="handleConsignmentAgreement(scope.row)"
  298. >
  299. {{ scope.row.templateName }}
  300. </div>
  301. <span v-else>-</span>
  302. </template>
  303. </el-table-column>
  304. <el-table-column label="检验时间" align="center" prop="checkDate" min-width="120px">
  305. <template #default="scope">
  306. {{ formatArrayDate(scope.row.checkDate) }}
  307. </template>
  308. </el-table-column>
  309. <el-table-column label="下次检验日期" align="center" prop="nextCheckDate" min-width="120px">
  310. <template #default="scope">
  311. {{ formatDate(scope.row.nextCheckDate,"YYYY-MM-DD") }}
  312. </template>
  313. </el-table-column>
  314. <el-table-column label="部门" align="center" prop="deptName" min-width="120px" />
  315. <el-table-column label="发放人" align="center" prop="releaseName" min-width="120px">
  316. <template #default="scope">
  317. <div v-if="scope.row.releaseName">
  318. {{ scope.row.releaseName }}
  319. </div>
  320. <span v-else>-</span>
  321. </template>
  322. </el-table-column>
  323. <el-table-column label="发放日期" align="center" prop="releaseTime" min-width="120px">
  324. <template #default="scope">
  325. <div v-if="scope.row.releaseTime">
  326. {{ formatDate(scope.row.releaseTime) }}
  327. </div>
  328. <span v-else>-</span>
  329. </template>
  330. </el-table-column>
  331. </el-table>
  332. <!-- 分页 -->
  333. <Pagination
  334. :total="total"
  335. v-model:page="queryParams.pageNo"
  336. v-model:limit="queryParams.pageSize"
  337. @pagination="getList"
  338. />
  339. </ContentWrap>
  340. <!-- 报告出具记录对话框 -->
  341. <PrintIssueRecordDialog
  342. v-model:visible="reportRecordDialogVisible"
  343. :report-id="currentReportId"
  344. :equip-id="currentEquipId"
  345. />
  346. <!-- 发放报告对话框 -->
  347. <IssuePrintReportDialog
  348. v-model:visible="issueReportDialogVisible"
  349. :task-order-id="currentTaskOrderId"
  350. :report-type="currentReportType"
  351. :list="selectedRows"
  352. @confirm="handleIssueReportConfirm"
  353. />
  354. <!-- 文件预览组件 -->
  355. <FilePreview
  356. v-model="previewVisible"
  357. width="45%"
  358. :url="currentPreviewUrl"
  359. :filename="currentFilename"
  360. :filesize="currentFilesize"
  361. :title="'打印发证-预览'"
  362. :isPdfPage="false"
  363. :is-footer="false"
  364. :is-header="false"
  365. @close="handlePreviewClose"
  366. />
  367. <!-- 服务单/受理单 编辑模板内容 -->
  368. <!-- @update:visible="handleUpdateServiceRecordListVisible" -->
  369. <ServiceRecordList
  370. v-if="serviceRecordListVisible"
  371. v-model:visible="serviceRecordListVisible"
  372. :serverForm="serviceOrderDialogFormData"
  373. :businessType="businessType"
  374. :orderItemId="mainOrderItemId"
  375. :reportId="mainReportId"
  376. :isAddMainquestion="isAddMainquestion"
  377. :taskOrderDetail="taskOrderDetail"
  378. @success="handleUpdateServiceRecordList"
  379. />
  380. <!-- 选择打印机 -->
  381. <el-dialog
  382. v-model="printDialog"
  383. title="打印机列表"
  384. width="30vw"
  385. destroy-on-close
  386. :close-on-click-modal="false"
  387. >
  388. <div>
  389. <el-form :model="printFormData" label-width="auto" :rules="rules" ref="printFormRef">
  390. <!-- <el-form-item label="受理单号">
  391. <div> {{ printFormData.acceptNo || '-' }}</div>
  392. </el-form-item> -->
  393. <!-- <el-form-item label="选择打印机" prop="printer">
  394. <el-select filterable clearable v-model="printFormData.printer" placeholder="选择打印机">
  395. <el-option v-for="item in printList" :label="item" :value="item" :key="item">
  396. {{ item }}
  397. </el-option>
  398. </el-select>
  399. </el-form-item> -->
  400. <el-form-item label="打印原因" prop="reason">
  401. <el-input type="textarea" v-model="printFormData.reason" maxlength="50" show-word-limit :autosize="{minRows: 3, maxRows: 6}"/>
  402. </el-form-item>
  403. </el-form>
  404. </div>
  405. <template #footer>
  406. <div class="dialog-footer">
  407. <el-button @click="printDialog = false">取消</el-button>
  408. <el-button type="primary" @click="confirmPrint(1)" :loading="printLoading">打印</el-button>
  409. <!-- <el-button type="primary" @click="confirmPrint(2)" :loading="printPreLoading">打印预览</el-button> -->
  410. <!-- <el-button type="primary" @click="handleDownload" :loading="printLoading">下载</el-button> -->
  411. </div>
  412. </template>
  413. </el-dialog>
  414. <FilePreviewDialog
  415. v-if="signPreviewVisible"
  416. v-model="signPreviewVisible"
  417. :id="signPreviewId"
  418. :filename="signFileName"
  419. :title="'文件预览'"
  420. @close="handleSignPreviewClose"
  421. />
  422. <CustomTableDialog ref="customTableDialogRef" :showSearch="false" :showFooter="false" />
  423. <unitContainerForm ref="unitContainerFormRef" />
  424. <!-- PDF预览弹窗 -->
  425. <PdfPreviewDialog
  426. v-model="pdfPreviewVisible"
  427. :pdfBlob="currentPdfBlob"
  428. @close="handlePdfPreviewClose"
  429. />
  430. <!-- 服务单/受理单 -->
  431. <OrderDialog
  432. v-if="orderReportVisible"
  433. v-model:visible="orderReportVisible"
  434. :orderId="currentTaskOrderId"
  435. type="pipe"
  436. />
  437. </template>
  438. <script setup lang="ts">
  439. import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
  440. import { ElMessage } from 'element-plus'
  441. import { formatArrayDate, formatDate } from '@/utils/formatTime'
  442. import { PipeTaskOrderApi, PipeTaskOrderVO } from '@/api/pressure2/pipetaskorder'
  443. import ServiceRecordList from './components/ServiceRecordList.vue'
  444. import unitContainerForm from '@/components/unitContainerForm/index.vue'
  445. import { ElTable } from 'element-plus'
  446. import { PrintIssuePaymentStatusMap, PrintIssueStatusMap } from '@/utils/constants'
  447. import IssuePrintReportDialog from './components/IssuePrintReportDialog.vue'
  448. import PrintIssueRecordDialog from './components/PrintIssueRecordDialog.vue'
  449. import FilePreview from '@/views/Functional/components/FilePreview.vue'
  450. import { PressurePipeCheckTypeMap, PressurePipeCheckType } from '@/utils/constants'
  451. import { useRouter } from 'vue-router'
  452. import FilePreviewDialog from './FilePreview.vue'
  453. import CustomTableDialog from '@/components/CustomTableDialog/index.vue'
  454. import { SmartTableColumn } from '@/types/table'
  455. import {getJCP} from '@/utils/jcp/jcp-vue'
  456. import {PipeInputApi} from "@/api/pressure2/pipeInput";
  457. import PdfPreviewDialog from './PdfPreviewDialog.vue'
  458. import 'https://printjs-4de6.kxcdn.com/print.min.js'
  459. import OrderDialog from "@/views/pressure2/boilertaskorder/components/OrderDialog.vue";
  460. const router = useRouter()
  461. /** 出具报告任务单 列表 */
  462. defineOptions({ name: 'PrintIssueCertificatesPipe' })
  463. const signFileName = ref<string>('')
  464. const signPreviewId = ref<string>('')
  465. const signPreviewVisible = ref<boolean>(false)
  466. const unitContainerFormRef = ref<InstanceType<typeof unitContainerForm>>()
  467. const loading = ref(true)
  468. const list = ref<PipeTaskOrderVO[]>([])
  469. const total = ref(0)
  470. // PDF预览相关
  471. const pdfPreviewVisible = ref(false)
  472. const currentPdfBlob = ref<Blob | null>(null)
  473. const queryParams = reactive({
  474. pageNo: 1,
  475. pageSize: 50,
  476. releaseRecordNum: undefined,
  477. releaseStatus: undefined,
  478. paymentStatus: undefined,
  479. orderNo: undefined,
  480. productNo: undefined,
  481. unitName: undefined,
  482. reportNo: undefined,
  483. ratifyTime: undefined,
  484. equipCode: undefined,
  485. templateName: undefined,
  486. deptName: undefined,
  487. useRegisterNo: undefined,
  488. checkType: undefined,
  489. nextCheckDate: undefined,
  490. deptId: undefined,
  491. reportConclusion: undefined,
  492. useUnitName: undefined,
  493. checkDate: undefined
  494. })
  495. const queryFormRef = ref()
  496. const tableRef = ref<InstanceType<typeof ElTable>>()
  497. // 表格选择状态
  498. const selectedRows = ref<PipeTaskOrderVO[]>([])
  499. // 出具报告对话框状态
  500. const issueReportDialogVisible = ref(false)
  501. const currentTaskOrderId = ref('')
  502. const currentReportType = ref<100 | 200>(100)
  503. // 发放报告记录对话框状态
  504. const reportRecordDialogVisible = ref(false)
  505. const currentReportId = ref('')
  506. const currentEquipId = ref('')
  507. // 打印机列表
  508. const printList = ref([])
  509. const printUrl = ref('') // 打印文件地址
  510. const printDialog = ref(false) // 打印机弹窗
  511. const printFormData = ref({}) as any // 打印参数
  512. const printLoading = ref(false) // 打印按钮的loading
  513. const printPreLoading = ref(false) // 打印预览 loading
  514. const printFormRef = ref() as any // 打印表单引用
  515. const rules = ref({
  516. reason: [
  517. { required: true, message: '请输入打印原因', trigger: 'blur' },
  518. ]
  519. })// 预览
  520. const previewVisible = ref<boolean>(false)
  521. const currentPreviewUrl = ref<string>('')
  522. const currentFilename = ref<string>('')
  523. const currentFilesize = ref<number>(0)
  524. /** 服务单/受理单 */
  525. const serviceRecordListVisible = ref(false)
  526. const businessType = ref()
  527. const serviceOrderDialogFormData = ref<Record<string, any>>({
  528. serviceFormReceiver: '',
  529. serviceFormReceiverPhone: '',
  530. confirmStatus: ''
  531. })
  532. const mainOrderItemId = ref('')
  533. const mainReportId = ref('')
  534. const isAddMainquestion = ref<'add' | 'edit' | 'view'>('view')
  535. const taskOrderDetail = ref<any>(null)
  536. const handleUpdateServiceRecordList = () => {
  537. isAddMainquestion.value = 'view'
  538. // emit('refresh')
  539. }
  540. /** 查询列表 */
  541. const getList = async () => {
  542. loading.value = true
  543. try {
  544. const params = { ...queryParams }
  545. if (queryParams?.ratifyTime) {
  546. params['ratifyTimeStart'] = queryParams?.ratifyTime[0]
  547. params['ratifyTimeEnd'] = queryParams?.ratifyTime[1]
  548. delete params['ratifyTime']
  549. }
  550. const data = await PipeTaskOrderApi.getIssueReportPrintPage(params)
  551. list.value = data?.list || []
  552. total.value = data?.total || 0
  553. } finally {
  554. loading.value = false
  555. }
  556. }
  557. /** 表格选择变化 */
  558. const handleSelectionChange = (selection: PipeTaskOrderVO[]) => {
  559. selectedRows.value = selection
  560. }
  561. /** 搜索按钮操作 */
  562. const handleQuery = () => {
  563. queryParams.pageNo = 1
  564. getList()
  565. }
  566. const handleSignPreviewClose = () => {
  567. signPreviewId.value = ''
  568. signFileName.value = ''
  569. signPreviewVisible.value = false
  570. }
  571. /** 重置按钮操作 */
  572. const resetQuery = () => {
  573. queryFormRef.value.resetFields()
  574. handleQuery()
  575. }
  576. /** 查看发放报告记录 */
  577. const handleViewReportRecord = (reportId: string,equipId :string) => {
  578. currentReportId.value = reportId
  579. currentEquipId.value = equipId
  580. reportRecordDialogVisible.value = true
  581. }
  582. const printTypeMap = [
  583. {
  584. label: '直接打印',
  585. value: 100
  586. },
  587. {
  588. label: '下载PDF',
  589. value: 200
  590. }
  591. ]
  592. const customTableDialogRef = ref<InstanceType<typeof CustomTableDialog>>()
  593. type ModalParamsConfig = {
  594. modalUrl: string
  595. columns: SmartTableColumn[]
  596. isSingle: boolean
  597. modalParams?: any
  598. keyWord?: string
  599. modalTitle?: string
  600. }
  601. const openModalConfig: ModalParamsConfig = {
  602. modalUrl: '/pressure2/pipe-task-order-item-print/page',
  603. columns: [
  604. {
  605. prop: 'type',
  606. label: '打印类型',
  607. fieldProps: {
  608. align: 'center',
  609. minWidth: 120
  610. },
  611. render: (row, value) => {
  612. return printTypeMap.find((item) => item.value == value)?.label || '-'
  613. }
  614. },
  615. {
  616. prop: 'creatorUser',
  617. label: '打印人',
  618. fieldProps: {
  619. align: 'center',
  620. minWidth: 120
  621. },
  622. render: (row, value) => {
  623. return value
  624. ? `${value?.nickname}${value?.employeeNo ? `(${value?.employeeNo})` : ''}`
  625. : '-'
  626. }
  627. },
  628. {
  629. prop: 'createTime',
  630. label: '打印时间',
  631. fieldProps: {
  632. align: 'center',
  633. minWidth: 120
  634. },
  635. render: (row, value) => {
  636. return formatDate(value)
  637. }
  638. },
  639. {
  640. prop: 'reason',
  641. label: '打印原因',
  642. fieldProps: {
  643. align: 'center',
  644. minWidth: 150
  645. }
  646. }
  647. ],
  648. isSingle: true,
  649. keyWord: 'name',
  650. modalTitle: '打印记录详情'
  651. }
  652. const handleViewPrintRecord = (row) => {
  653. openModalConfig.modalParams = {
  654. itemId: row.id
  655. }
  656. customTableDialogRef.value?.openModal(openModalConfig, false)
  657. }
  658. // 委托协议
  659. const orderReportVisible = ref(false)
  660. const handleConsignmentAgreement = (row) => {
  661. // businessType.value = 100
  662. // serviceRecordListVisible.value = true
  663. // isAddMainquestion.value = 'view'
  664. // taskOrderDetail.value = { ...row, id: row.orderId } //'a08885bd8f4f1607acb3b4e41d99fd11'
  665. // if (row.checkType == PressureBoilerCheckType.IN || row.checkType == PressureBoilerCheckType.OUT) {
  666. // // 内外检验
  667. // } else if (row.checkType == PressureBoilerCheckType.PRESSURE) {
  668. // // 耐压检验
  669. // }
  670. currentTaskOrderId.value = row.orderId
  671. orderReportVisible.value = true
  672. }
  673. /** 电子发放 */
  674. const handleElectronicDistribution = (id) => {
  675. if (selectedRows.value.length === 0) {
  676. ElMessage.warning('请先选择需要出具报告的设备')
  677. return
  678. }
  679. currentTaskOrderId.value = id
  680. currentReportType.value = 200
  681. issueReportDialogVisible.value = true
  682. }
  683. const handleRoute = (routerName, query?: Record<string, any>) => {
  684. router.push({
  685. name: routerName,
  686. query
  687. })
  688. }
  689. /** 打印发放 */
  690. const handlePrintIssuebution = (id) => {
  691. if (selectedRows.value.length === 0) {
  692. ElMessage.warning('请先选择需要出具报告的设备')
  693. return
  694. }
  695. currentTaskOrderId.value = id
  696. currentReportType.value = 100
  697. issueReportDialogVisible.value = true
  698. }
  699. /** 出具报告确认 */
  700. const handleIssueReportConfirm = (data: any) => {
  701. console.log('出具报告数据:', data)
  702. // 这里应该调用API提交数据
  703. // 提交成功后刷新列表
  704. getList()
  705. }
  706. /**
  707. * 确认打印
  708. * @param type 1 打印 2 打印预览
  709. */
  710. const confirmPrint = async (type = 1) => {
  711. const loadingInstance = ElLoading.service({
  712. fullscreen: true,
  713. text: '正在打印...'
  714. })
  715. try {
  716. printLoading.value = false
  717. printDialog.value = false // 打开弹窗
  718. const response = await PipeTaskOrderApi.generateReportPdf({
  719. orderId: printRow.value.orderId
  720. }, { responseType: 'blob' }) // 确保以blob格式接收响应
  721. // 创建Blob对象
  722. const pdfBlob = new Blob([response], { type: 'application/pdf' })
  723. if (pdfBlob) {
  724. // 创建临时 URL
  725. const pdfUrl = URL.createObjectURL(pdfBlob)
  726. // 使用 printJS 打印
  727. printJS({
  728. printable: pdfUrl,
  729. type: 'pdf',
  730. showModal: false,
  731. onPrintDialogClose: () => {
  732. // 打印对话框关闭后释放 URL
  733. URL.revokeObjectURL(pdfUrl)
  734. handleAddPrintRecord(100)
  735. },
  736. })
  737. } else {
  738. ElMessage.error('获取打印文件失败')
  739. }
  740. } catch (error) {
  741. console.error('打印失败:', error)
  742. ElMessage.error('打印失败')
  743. }finally {
  744. loadingInstance.close()
  745. }
  746. }
  747. // 预览
  748. const toPreview = async (id: string) => {
  749. const loadingInstance = ElLoading.service({
  750. fullscreen: true,
  751. text: '正在生成...'
  752. })
  753. try {
  754. loading.value = true
  755. // 获取PDF字节流
  756. const response = await PipeTaskOrderApi.generateReportPdf({
  757. orderId: id
  758. }, { responseType: 'blob' }) // 确保以blob格式接收响应
  759. // 创建Blob对象
  760. const blob = new Blob([response], { type: 'application/pdf' })
  761. // 设置当前PDF blob并显示预览弹窗
  762. currentPdfBlob.value = blob
  763. pdfPreviewVisible.value = true
  764. loading.value = false
  765. } catch (error) {
  766. console.error('预览PDF失败:', error)
  767. ElMessage.error('预览PDF失败')
  768. loading.value = false
  769. } finally {
  770. // 关闭 Loading
  771. loadingInstance.close()
  772. }
  773. }
  774. // PDF预览关闭处理
  775. const handlePdfPreviewClose = () => {
  776. currentPdfBlob.value = null
  777. }
  778. const handleSign = async (id: string, equipCode: string) => {
  779. signPreviewId.value = id
  780. signFileName.value = `${equipCode}使用标志`
  781. signPreviewVisible.value = true
  782. // previewVisible.value = true
  783. // currentPreviewUrl.value = buildFileUrl(url)
  784. }
  785. const signShowFn = (row: any) => {
  786. if (!row.useRegisterNo || row.useRegisterNo.length < 4) {
  787. return false
  788. } else {
  789. return true
  790. }
  791. }
  792. const handlePreviewClose = () => {
  793. currentPreviewUrl.value = ''
  794. previewVisible.value = false
  795. }
  796. // 打印
  797. const printRow = ref<any>({})
  798. const handlePrint = async (row) => {
  799. const { id } = row
  800. if (!id) return ElMessage.error('未找到受理单ID!')
  801. try {
  802. printRow.value = row
  803. printLoading.value = false
  804. printDialog.value = true // 打开弹窗
  805. } catch (error) {
  806. console.error('打印失败:', error)
  807. ElMessage.error('打印失败')
  808. }finally {
  809. }
  810. }
  811. const handleDownload2 = async (row) => {
  812. const { id } = row
  813. if (!id) return ElMessage.error('未找到受理单ID!')
  814. ElMessageBox.confirm('是否确认下载', '提示', {
  815. confirmButtonText: '确 认',
  816. cancelButtonText: '取 消'
  817. })
  818. .then(async () => {
  819. const loadingInstance = ElLoading.service({
  820. fullscreen: true,
  821. text: '正在下载...'
  822. })
  823. try {
  824. loading.value = true
  825. // 获取PDF字节流
  826. const response = await PipeTaskOrderApi.generateReportPdf({
  827. orderId: row.orderId
  828. }, { responseType: 'blob' }) // 确保以blob格式接收响应
  829. // 创建Blob对象
  830. const blob = new Blob([response], { type: 'application/pdf' })
  831. // 创建下载链接
  832. const url = window.URL.createObjectURL(blob)
  833. const link = document.createElement('a')
  834. link.href = url
  835. link.download = `检验报告_${row.reportNo}.pdf` // 设置下载文件名
  836. // 触发下载
  837. document.body.appendChild(link)
  838. link.click()
  839. // 清理
  840. document.body.removeChild(link)
  841. window.URL.revokeObjectURL(url)
  842. ElMessage.success('报告下载成功')
  843. loading.value = false
  844. } catch (error) {
  845. console.error('下载PDF失败:', error)
  846. ElMessage.error('报告下载失败')
  847. loading.value = false
  848. } finally {
  849. // 关闭 Loading
  850. loadingInstance.close()
  851. }
  852. })
  853. .catch(() => console.info('操作取消'))
  854. }
  855. const handleAddPrintRecord = async (type: 100 | 200) => {
  856. const params = {
  857. itemId: printRow.value.id,
  858. reason: printFormData.value.reason,
  859. type
  860. }
  861. try {
  862. printLoading.value = true
  863. await PipeTaskOrderApi.createPrintRecord(params)
  864. ElMessage.success('打印记录添加成功')
  865. getList()
  866. } catch (error) {
  867. ElMessage.error('打印记录添加失败!')
  868. } finally {
  869. printLoading.value = false
  870. }
  871. }
  872. const handleUnitCodeFn = (code) => {
  873. if (!code) {
  874. return ElMessage.warning('该单位信息异常!')
  875. }
  876. unitContainerFormRef.value?.open('', code, true)
  877. }
  878. /** 初始化 **/
  879. onMounted(() => {
  880. getList()
  881. })
  882. </script>
  883. <style lang="scss" scoped>
  884. .report-count-link {
  885. color: #409eff;
  886. text-decoration: underline;
  887. cursor: pointer;
  888. &:hover {
  889. color: #66b1ff;
  890. }
  891. }
  892. .dialog-footer {
  893. display: flex;
  894. padding-top: 0.2rem;
  895. margin-top: 0.2rem;
  896. border-top: 0.01rem solid #dcdfe6;
  897. box-sizing: border-box;
  898. justify-content: flex-end;
  899. align-items: center;
  900. }
  901. </style>