PrintTaskManage.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. <template>
  2. <div class="print-task-manage">
  3. <div class="part-box part-box-filter">
  4. <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
  5. <template v-if="checkPrivilege('condition', 'condition')">
  6. <el-form-item label="学期:">
  7. <semester-select
  8. v-model.trim="filter.semesterId"
  9. placeholder="学期"
  10. default-select
  11. ></semester-select>
  12. </el-form-item>
  13. <el-form-item label="考试:">
  14. <exam-select
  15. v-model="filter.examId"
  16. :semester-id="filter.semesterId"
  17. default-select
  18. @default-selected="search"
  19. ></exam-select>
  20. </el-form-item>
  21. <el-form-item label="印刷计划:">
  22. <print-plan-select
  23. v-model.trim="filter.printPlanId"
  24. placeholder="印刷计划"
  25. clearable
  26. :semester-id="filter.semesterId"
  27. :exam-id="filter.examId"
  28. @change="printPlanChange"
  29. ></print-plan-select>
  30. </el-form-item>
  31. <el-form-item label="课程(代码):" label-width="110px">
  32. <course-select
  33. v-model.trim="filter.courseCode"
  34. :semester-id="filter.semesterId"
  35. :exam-id="filter.examId"
  36. :print-plan-id="filter.printPlanId"
  37. placeholder="课程(代码)"
  38. clearable
  39. ></course-select>
  40. </el-form-item>
  41. <el-form-item label="试卷编号:">
  42. <paper-number-select
  43. ref="PaperNumberSelect"
  44. v-model="filter.paperNumber"
  45. :semester-id="filter.semesterId"
  46. :exam-id="filter.examId"
  47. :print-plan-id="filter.printPlanId"
  48. :course-code="filter.courseCode"
  49. placeholder="试卷编号"
  50. clearable
  51. ></paper-number-select>
  52. </el-form-item>
  53. <el-form-item label="印刷室:">
  54. <print-room-select
  55. v-model.trim="filter.printHouseId"
  56. placeholder="印刷室"
  57. clearable
  58. ></print-room-select>
  59. </el-form-item>
  60. <el-form-item label="印刷状态:">
  61. <status-select
  62. v-model="filter.status"
  63. type="EXAM_DETAIL_STATUS_ENUM"
  64. placeholder="印刷状态"
  65. style="width: 120px"
  66. clearable
  67. >
  68. </status-select>
  69. </el-form-item>
  70. <el-form-item label="考点:" label-width="55px">
  71. <place-select
  72. v-model.trim="filter.examPlace"
  73. :print-plan-id="filter.printPlanId"
  74. placeholder="考点"
  75. clearable
  76. ></place-select>
  77. </el-form-item>
  78. <el-form-item label="考场:" label-width="55px">
  79. <room-select
  80. v-model.trim="filter.examRoom"
  81. :print-plan-id="filter.printPlanId"
  82. placeholder="考场"
  83. clearable
  84. ></room-select>
  85. </el-form-item>
  86. <el-form-item label="考试日期:">
  87. <el-date-picker
  88. v-model="createTime"
  89. type="daterange"
  90. :picker-options="pickerOptions"
  91. range-separator="至"
  92. start-placeholder="考试开始日期"
  93. end-placeholder="考试结束日期"
  94. value-format="timestamp"
  95. align="right"
  96. unlink-panels
  97. >
  98. </el-date-picker>
  99. </el-form-item>
  100. <el-form-item label="打印时间:">
  101. <el-date-picker
  102. v-model="printTime"
  103. type="datetimerange"
  104. :picker-options="pickerOptions"
  105. range-separator="至"
  106. start-placeholder="打印开始时间"
  107. end-placeholder="打印结束时间"
  108. value-format="timestamp"
  109. align="right"
  110. unlink-panels
  111. >
  112. </el-date-picker>
  113. </el-form-item>
  114. </template>
  115. <el-form-item label-width="0px">
  116. <el-button
  117. v-if="checkPrivilege('button', 'select')"
  118. type="primary"
  119. @click="search"
  120. >查询</el-button
  121. >
  122. </el-form-item>
  123. </el-form>
  124. <div class="box-justify">
  125. <div></div>
  126. <div>
  127. <el-button
  128. v-if="checkPrivilege('button', 'BatchEnd')"
  129. icon="el-icon-download"
  130. type="danger"
  131. @click="toBatchCancel"
  132. >
  133. 批量撤回
  134. </el-button>
  135. <el-button
  136. v-if="checkPrivilege('button', 'BatchDownload')"
  137. icon="el-icon-download"
  138. type="primary"
  139. :disabled="loading"
  140. @click="toExport"
  141. >
  142. 批量下载PDF
  143. </el-button>
  144. <el-button
  145. v-if="checkPrivilege('button', 'BatchDownload')"
  146. type="primary"
  147. icon="el-icon-s-order"
  148. @click="toDataTask"
  149. >下载结果查询</el-button
  150. >
  151. </div>
  152. </div>
  153. </div>
  154. <div class="part-box part-box-pad box-justify">
  155. <p>
  156. <span class="mr-4"
  157. >科次总计:<i class="color-primary">{{ totalInfo.totalSubjects }}</i>
  158. 科次</span
  159. >
  160. <span class="mr-4"
  161. >试卷总计:<i class="color-primary">{{ totalInfo.paperCount }}</i>
  162. 套</span
  163. >
  164. <span class="mr-4"
  165. >卷袋总计:<i class="color-primary">{{ totalInfo.packageCount }}</i>
  166. 个</span
  167. >
  168. <span
  169. >总印量:<i class="color-primary">{{
  170. totalInfo.paperPages + totalInfo.cardPages
  171. }}</i>
  172. 张</span
  173. >
  174. <span
  175. >(试卷:<i class="color-primary">{{ totalInfo.paperPages }}</i>
  176. 张,</span
  177. >
  178. <span
  179. >题卡:<i class="color-primary">{{ totalInfo.cardPages }}</i>
  180. 张)</span
  181. >
  182. </p>
  183. <p>
  184. <span
  185. >剩余印量:<i class="color-danger">{{
  186. totalInfo.paperPagesLeft + totalInfo.cardPagesLeft
  187. }}</i>
  188. 张</span
  189. >
  190. <span
  191. >(试卷:<i class="color-danger">{{ totalInfo.paperPagesLeft }}</i>
  192. 张,</span
  193. >
  194. <span
  195. >题卡:<i class="color-danger">{{ totalInfo.cardPagesLeft }}</i>
  196. 张)</span
  197. >
  198. </p>
  199. </div>
  200. <div class="part-box part-box-pad">
  201. <el-table
  202. ref="TableList"
  203. :data="dataList"
  204. @selection-change="handleSelectionChange"
  205. >
  206. <el-table-column
  207. type="selection"
  208. width="55"
  209. align="center"
  210. ></el-table-column>
  211. <el-table-column
  212. type="index"
  213. label="序号"
  214. width="60"
  215. :index="indexMethod"
  216. ></el-table-column>
  217. <el-table-column
  218. prop="semesterName"
  219. label="学期"
  220. min-width="200"
  221. ></el-table-column>
  222. <el-table-column
  223. prop="examName"
  224. label="考试"
  225. min-width="160"
  226. ></el-table-column>
  227. <el-table-column
  228. prop="packageCode"
  229. label="卷袋编号"
  230. min-width="160"
  231. ></el-table-column>
  232. <el-table-column
  233. prop="printPlanName"
  234. label="印刷计划"
  235. min-width="200"
  236. ></el-table-column>
  237. <el-table-column
  238. prop="printHouseName"
  239. label="印刷室"
  240. min-width="160"
  241. ></el-table-column>
  242. <el-table-column
  243. prop="examDate"
  244. label="考试日期"
  245. width="100"
  246. ></el-table-column>
  247. <el-table-column
  248. prop="examTime"
  249. label="考试时间"
  250. width="100"
  251. ></el-table-column>
  252. <el-table-column
  253. prop="courseNameCode"
  254. label="课程(代码)"
  255. min-width="200"
  256. >
  257. </el-table-column>
  258. <el-table-column
  259. prop="paperNumber"
  260. label="试卷编号"
  261. min-width="160"
  262. ></el-table-column>
  263. <el-table-column
  264. prop="examPlace"
  265. label="考点"
  266. min-width="160"
  267. ></el-table-column>
  268. <el-table-column
  269. prop="examRoom"
  270. label="考场"
  271. min-width="160"
  272. ></el-table-column>
  273. <!-- <el-table-column
  274. prop="singlePagesA3"
  275. label="单科次准印量A3(页)"
  276. width="80"
  277. ></el-table-column> -->
  278. <el-table-column
  279. prop="totalSubjects"
  280. label="科次"
  281. width="80"
  282. ></el-table-column>
  283. <!-- <el-table-column
  284. prop="pagesA3"
  285. label="A3准印量小计(页)"
  286. width="80"
  287. ></el-table-column>
  288. <el-table-column
  289. prop="pagesA4"
  290. label="A4准印量小计(页)"
  291. width="80"
  292. ></el-table-column> -->
  293. <el-table-column prop="statusDisplay" label="印刷状态" width="80">
  294. </el-table-column>
  295. <el-table-column prop="validate" label="是否校验" width="80">
  296. <span slot-scope="scope">{{ scope.row.validate ? "是" : "否" }}</span>
  297. </el-table-column>
  298. <el-table-column prop="printStartTime" label="打印开始时间" width="170">
  299. <span slot-scope="scope">{{
  300. scope.row.printStartTime | timestampFilter
  301. }}</span>
  302. </el-table-column>
  303. <el-table-column prop="printEndTime" label="打印完成时间" width="170">
  304. <span slot-scope="scope">{{
  305. scope.row.printEndTime | timestampFilter
  306. }}</span>
  307. </el-table-column>
  308. <el-table-column prop="normal" label="任务状态" width="80">
  309. <span slot-scope="scope">{{
  310. scope.row.normal ? "正常" : "作废"
  311. }}</span>
  312. </el-table-column>
  313. <el-table-column
  314. class-name="action-column"
  315. label="操作"
  316. width="160"
  317. fixed="right"
  318. >
  319. <template slot-scope="scope">
  320. <el-button
  321. v-if="
  322. checkPrivilege('link', 'download') &&
  323. (scope.row.status === 'READY' ||
  324. scope.row.status === 'WAITING' ||
  325. scope.row.status === 'PRINTING' ||
  326. scope.row.status === 'FINISH' ||
  327. scope.row.status === 'CANCEL')
  328. "
  329. class="btn-primary"
  330. type="text"
  331. @click="toActionPdf(scope.row, 'view')"
  332. >查看pdf</el-button
  333. >
  334. <el-button
  335. v-if="
  336. scope.row.taskId &&
  337. checkPrivilege('link', 'createpdf') &&
  338. (scope.row.status === 'READY' ||
  339. scope.row.status === 'CANCEL' ||
  340. !scope.row.normal)
  341. "
  342. class="btn-primary"
  343. type="text"
  344. @click="toActionPdf(scope.row, 'build')"
  345. >重新生成pdf</el-button
  346. >
  347. <el-button
  348. v-if="
  349. scope.row.status === 'READY' && checkPrivilege('link', 'submit')
  350. "
  351. class="btn-primary"
  352. type="text"
  353. @click="toSubmit(scope.row)"
  354. >提交印刷</el-button
  355. >
  356. <!-- <el-button
  357. v-if="scope.row.status === 'PRINTING'"
  358. class="btn-primary"
  359. type="text"
  360. @click="toResubmit(scope.row)"
  361. >重新提交</el-button> -->
  362. <el-button
  363. v-if="
  364. scope.row.status === 'WAITING' && checkPrivilege('link', 'end')
  365. "
  366. class="btn-danger"
  367. type="text"
  368. @click="toCancel(scope.row)"
  369. >撤回提交</el-button
  370. >
  371. <el-button
  372. v-if="
  373. (scope.row.status === 'END' || scope.row.status === 'FINISH') &&
  374. checkPrivilege('link', 'normal')
  375. "
  376. :class="scope.row.normal ? 'btn-danger' : 'btn-primary'"
  377. type="text"
  378. @click="toNormal(scope.row)"
  379. >{{ scope.row.normal ? "作废" : "恢复" }}</el-button
  380. >
  381. <!-- <el-button
  382. class="btn-primary"
  383. type="text"
  384. @click="toPreview(scope.row)"
  385. >查看印品模板</el-button> -->
  386. </template>
  387. </el-table-column>
  388. </el-table>
  389. <div class="part-page">
  390. <el-pagination
  391. background
  392. layout="total, sizes, prev, pager, next, jumper"
  393. :pager-count="5"
  394. :current-page="current"
  395. :total="total"
  396. :page-size="size"
  397. @current-change="toPage"
  398. @size-change="pageSizeChange"
  399. >
  400. </el-pagination>
  401. </div>
  402. </div>
  403. <!-- PreviewPrintTaskTemplate-->
  404. <preview-print-task-template
  405. :instance="curTask"
  406. ref="PreviewPrintTaskTemplate"
  407. ></preview-print-task-template>
  408. <!-- pdf-view -->
  409. <el-dialog
  410. class="pdf-view-dialog"
  411. :visible.sync="padViewDialogVisible"
  412. title="请选择PDF类型"
  413. top="10vh"
  414. width="600px"
  415. :close-on-click-modal="false"
  416. :close-on-press-escape="false"
  417. append-to-body
  418. >
  419. <div class="text-center">
  420. <el-button
  421. v-if="actionType === 'build'"
  422. size="large"
  423. @click="actionPdf({ type: undefined })"
  424. >全部</el-button
  425. >
  426. <el-button
  427. v-for="item in pdfList"
  428. :key="item.name"
  429. type="primary"
  430. size="large"
  431. @click="actionPdf(item)"
  432. >{{ item.type | printPdfTypeFilter }}</el-button
  433. >
  434. </div>
  435. <div slot="footer"></div>
  436. </el-dialog>
  437. <!-- data-task-dialog -->
  438. <data-task-dialog
  439. v-if="checkPrivilege('button', 'BatchDownload')"
  440. ref="DataTaskDialog"
  441. task-type="PRINT_PDF_DOWNLOAD"
  442. ></data-task-dialog>
  443. </div>
  444. </template>
  445. <script>
  446. import {
  447. printTaskListPage,
  448. submitPrintTask,
  449. resubmitPrintTask,
  450. cancelPrintTask,
  451. batchCancelPrintTask,
  452. printTaskTotalInfo,
  453. getPrintTaskPdf,
  454. downloadPrintTaskPdf,
  455. rebuildPrintTaskPdf,
  456. printTaskNormal,
  457. } from "../api";
  458. import { PRINT_TASK_STATUS } from "@/constants/enumerate";
  459. import pickerOptions from "@/constants/datePickerOptions";
  460. import { parseTimeRangeDateAndTime } from "@/plugins/utils";
  461. import PreviewPrintTaskTemplate from "../components/PreviewPrintTaskTemplate";
  462. export default {
  463. name: "print-task-manage",
  464. components: { PreviewPrintTaskTemplate },
  465. data() {
  466. return {
  467. filter: {
  468. semesterId: "",
  469. examId: "",
  470. printPlanId: "",
  471. printHouseId: "",
  472. status: "",
  473. courseCode: "",
  474. paperNumber: "",
  475. examPlace: "",
  476. examRoom: "",
  477. examStartTime: "",
  478. examEndTime: "",
  479. printStartTime: "",
  480. printEndTime: "",
  481. },
  482. current: 1,
  483. size: this.GLOBAL.pageSize,
  484. total: 0,
  485. totalInfo: {},
  486. dataList: [],
  487. curRow: {},
  488. multipleSelection: [],
  489. PRINT_TASK_STATUS,
  490. loading: false,
  491. // view-pdf
  492. padViewDialogVisible: false,
  493. pdfList: [],
  494. actionType: "view",
  495. // view-template
  496. curTask: {},
  497. // date-picker
  498. createTime: [],
  499. printTime: [],
  500. pickerOptions,
  501. };
  502. },
  503. mounted() {
  504. // this.search();
  505. },
  506. methods: {
  507. async getList() {
  508. if (!this.checkPrivilege("list", "list")) return;
  509. const datas = {
  510. ...this.filter,
  511. pageNumber: this.current,
  512. pageSize: this.size,
  513. };
  514. if (this.createTime) {
  515. datas.examStartTime = this.createTime[0];
  516. datas.examEndTime = this.createTime[1];
  517. }
  518. if (this.printTime) {
  519. datas.printStartTime = this.printTime[0];
  520. datas.printEndTime = this.printTime[1];
  521. }
  522. const data = await printTaskListPage(datas);
  523. this.dataList = data.records.map((item) => {
  524. const { date, time } = parseTimeRangeDateAndTime(
  525. item.examStartTime,
  526. item.examEndTime
  527. );
  528. item.examDate = date || "--";
  529. item.examTime = time || "--";
  530. return item;
  531. });
  532. this.total = data.total;
  533. },
  534. toPage(page) {
  535. this.current = page;
  536. this.getList();
  537. this.multipleSelection = [];
  538. },
  539. search() {
  540. this.toPage(1);
  541. this.getTotalInfo();
  542. },
  543. printPlanChange() {
  544. this.filter.paperNumber = "";
  545. this.filter.courseCode = "";
  546. this.filter.examRoom = "";
  547. this.filter.examPlace = "";
  548. },
  549. async getTotalInfo() {
  550. const datas = {
  551. ...this.filter,
  552. pageNumber: this.current,
  553. pageSize: this.size,
  554. };
  555. if (this.createTime) {
  556. datas.examStartTime = this.createTime[0];
  557. datas.examEndTime = this.createTime[1];
  558. }
  559. const data = await printTaskTotalInfo(datas);
  560. this.totalInfo = data || {};
  561. },
  562. handleSelectionChange(val) {
  563. this.multipleSelection = val.map((item) => item.examDetailId);
  564. },
  565. toPreview(row) {
  566. this.curTask = row;
  567. this.$refs.PreviewPrintTaskTemplate.open();
  568. },
  569. toSubmit(row) {
  570. this.$confirm("确定提交该印刷任务吗?", "提示", {
  571. type: "warning",
  572. })
  573. .then(async () => {
  574. const data = await submitPrintTask(row.examDetailId);
  575. if (!data) return;
  576. this.$message.success("提交成功!");
  577. this.getList();
  578. })
  579. .catch(() => {});
  580. },
  581. toResubmit(row) {
  582. this.$confirm("确定重新提交该印刷任务吗?", "提示", {
  583. type: "warning",
  584. })
  585. .then(async () => {
  586. const data = await resubmitPrintTask({
  587. id: row.examDetailId,
  588. printPlanId: row.printPlanId,
  589. });
  590. if (!data) return;
  591. this.$message.success("提交成功!");
  592. this.getList();
  593. })
  594. .catch(() => {});
  595. },
  596. toCancel(row) {
  597. this.$confirm("确定撤回该印刷任务的提交吗?", "提示", {
  598. type: "warning",
  599. })
  600. .then(async () => {
  601. const data = await cancelPrintTask(row.examDetailId);
  602. if (!data) return;
  603. this.$message.success("撤回成功!");
  604. this.getList();
  605. })
  606. .catch(() => {});
  607. },
  608. toBatchCancel() {
  609. if (!this.multipleSelection.length) {
  610. this.$message.error("请选择要撤回的记录!");
  611. return;
  612. }
  613. this.$confirm("确定撤回选中的印刷任务的提交吗?", "提示", {
  614. type: "warning",
  615. })
  616. .then(async () => {
  617. const data = await batchCancelPrintTask(
  618. this.multipleSelection.join()
  619. );
  620. if (!data) return;
  621. this.$message.success("撤回成功!");
  622. this.getList();
  623. })
  624. .catch(() => {});
  625. },
  626. async toActionPdf(row, actionType) {
  627. this.curTask = row;
  628. this.actionType = actionType;
  629. this.pdfList = [];
  630. let result = true;
  631. const data = await getPrintTaskPdf(row.examDetailId).catch(() => {
  632. result = false;
  633. });
  634. if (!result) return;
  635. if (!data || !data.length) {
  636. this.$message.error("当前任务pdf还未生成好,请稍后再试!");
  637. return;
  638. }
  639. if (data.length === 1) {
  640. this.actionPdf(data[0]);
  641. } else {
  642. this.pdfList = data;
  643. this.padViewDialogVisible = true;
  644. }
  645. },
  646. actionPdf(item) {
  647. if (this.actionType === "view") {
  648. this.viewPdf(item);
  649. } else {
  650. this.rebuildPdf(item);
  651. }
  652. },
  653. async rebuildPdf(item) {
  654. const action = await this.$confirm(
  655. `确定要重新生成该印刷任务PDF吗?`,
  656. "提示",
  657. {
  658. type: "warning",
  659. }
  660. ).catch(() => {});
  661. if (action !== "confirm") return;
  662. const res = await rebuildPrintTaskPdf(this.curTask.taskId, item.type);
  663. if (!res) return;
  664. this.$message.success("操作成功!");
  665. },
  666. viewPdf(item) {
  667. window.open(item.url);
  668. // this.padViewDialogVisible = false;
  669. },
  670. async toExport() {
  671. if (this.loading) return;
  672. if (!this.multipleSelection.length) {
  673. this.$message.error("请选择要下载的记录!");
  674. return;
  675. }
  676. this.loading = true;
  677. const data = await downloadPrintTaskPdf(this.multipleSelection).catch(
  678. () => {}
  679. );
  680. this.loading = false;
  681. if (!data) return;
  682. this.$message.success("文件下载任务提交成功!");
  683. },
  684. toDataTask() {
  685. this.$refs.DataTaskDialog.open();
  686. },
  687. async toNormal(row) {
  688. const typeName = row.normal ? "作废" : "恢复";
  689. const action = await this.$confirm(
  690. `确定${typeName}该印刷任务吗?`,
  691. "提示",
  692. {
  693. type: "warning",
  694. }
  695. ).catch(() => {});
  696. if (action !== "confirm") return;
  697. const data = await printTaskNormal({
  698. id: row.examDetailId,
  699. normal: !row.normal,
  700. });
  701. if (!data) return;
  702. row.normal = !row.normal;
  703. this.$message.success("撤回成功!");
  704. },
  705. },
  706. };
  707. </script>