ModifyPrintPlan.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. <template>
  2. <el-dialog
  3. class="modify-print-plan"
  4. :visible.sync="modalIsShow"
  5. :title="title"
  6. top="10px"
  7. width="600px"
  8. :close-on-click-modal="false"
  9. :close-on-press-escape="false"
  10. append-to-body
  11. @open="visibleChange"
  12. >
  13. <el-form
  14. ref="modalFormComp"
  15. label-width="130px"
  16. :rules="rules"
  17. :model="modalForm"
  18. >
  19. <div class="part-box">
  20. <h4 class="part-box-tips">基本信息:</h4>
  21. <el-form-item prop="name" label="印刷计划名称:">
  22. <el-input
  23. v-model.trim="modalForm.name"
  24. clearable
  25. placeholder="请输入"
  26. :disabled="!editable"
  27. ></el-input>
  28. </el-form-item>
  29. <el-form-item prop="examStartTime" label="考试时间:">
  30. <el-date-picker
  31. v-model="createTime"
  32. type="datetimerange"
  33. range-separator="至"
  34. start-placeholder="开始时间"
  35. end-placeholder="结束时间"
  36. value-format="timestamp"
  37. align="right"
  38. unlink-panels
  39. :disabled="!editable"
  40. @change="dateChange"
  41. >
  42. </el-date-picker>
  43. </el-form-item>
  44. <el-form-item prop="semesterId" label="使用学期:">
  45. <semester-select
  46. v-model="modalForm.semesterId"
  47. class="width-full"
  48. :disabled="!editable"
  49. ></semester-select>
  50. </el-form-item>
  51. <el-form-item prop="examId" label="考试:">
  52. <exam-select
  53. v-model="modalForm.examId"
  54. :semester-id="modalForm.semesterId"
  55. class="width-full"
  56. @change="examChange"
  57. ></exam-select>
  58. </el-form-item>
  59. </div>
  60. <div class="part-box">
  61. <h4 class="part-box-tips">
  62. 试卷&题卡印品:
  63. <el-checkbox
  64. v-model="allSelected"
  65. label="全选"
  66. disabled
  67. @change="selectAll"
  68. ></el-checkbox>
  69. </h4>
  70. <el-form-item prop="printContent" label="试卷、题卡:">
  71. <el-checkbox-group
  72. v-model="modalForm.printContent"
  73. disabled
  74. @change="() => checkSelectAll()"
  75. >
  76. <el-checkbox
  77. v-for="(val, key) in PRINT_CONTENT_TYPE"
  78. :key="key"
  79. :label="key"
  80. >{{ val }}</el-checkbox
  81. >
  82. </el-checkbox-group>
  83. </el-form-item>
  84. <el-form-item
  85. v-if="modalForm.printContent.length"
  86. prop="backupMethod"
  87. label="备用数量:"
  88. >
  89. <el-select
  90. v-model="modalForm.backupMethod"
  91. class="mr-2"
  92. size="small"
  93. placeholder="请选择"
  94. disabled
  95. >
  96. <el-option
  97. v-for="(val, key) in PAPER_BACKUP_TYPE"
  98. :key="key"
  99. :value="key"
  100. :label="val"
  101. ></el-option>
  102. </el-select>
  103. <exam-backup-edit
  104. v-model="modalForm.backupCount"
  105. disabled
  106. ></exam-backup-edit>
  107. </el-form-item>
  108. <el-form-item
  109. v-if="contentIncludesPaper"
  110. prop="drawRule"
  111. label="抽卷规则:"
  112. >
  113. <el-radio-group v-model="modalForm.drawRule" disabled>
  114. <el-radio
  115. v-for="(val, key) in DRAW_RULE_TYPE"
  116. :label="key"
  117. :key="key"
  118. >{{ val }}</el-radio
  119. >
  120. </el-radio-group>
  121. <p class="tips-info">
  122. 1.只抽取一次:不同印刷计划下,同一试卷编号下的卷型只能被抽取一次;
  123. </p>
  124. <p class="tips-info">
  125. 2.可反复抽取:不同印刷计划下,同一试卷编号下的卷型可重复抽取,系统默认优先抽取未曝光卷型。
  126. </p>
  127. </el-form-item>
  128. </div>
  129. <div class="part-box">
  130. <h4 class="part-box-tips">其他印品:</h4>
  131. <el-form-item
  132. v-for="(item, index) in modalForm.variableContent"
  133. :key="item.type"
  134. :label="`${TEMPLATE_CLASSIFY[item.type]}:`"
  135. :prop="`variableContent.${index}.templateId`"
  136. :rules="{
  137. required: false,
  138. validator: templateValidator,
  139. trigger: 'change',
  140. }"
  141. :required="!!item.templateId.length"
  142. >
  143. <el-checkbox-group
  144. v-model="item.templateId"
  145. disabled
  146. @change="(vals) => tempChange(vals, `variableContent.${index}`)"
  147. >
  148. <el-checkbox
  149. v-for="temp in templateSources[item.type]"
  150. :label="temp.id"
  151. :key="temp.id"
  152. >{{ temp.name }}</el-checkbox
  153. >
  154. </el-checkbox-group>
  155. <div v-if="item.templateId.length">
  156. <el-select
  157. v-model="item.backupMethod"
  158. class="mr-2"
  159. size="small"
  160. placeholder="请选择"
  161. disabled
  162. >
  163. <el-option
  164. v-for="(val, key) in PRINT_BACKUP_TYPE"
  165. :key="key"
  166. :value="key"
  167. :label="val"
  168. ></el-option>
  169. </el-select>
  170. <exam-backup-edit
  171. v-model="item.backupCount"
  172. disabled
  173. ></exam-backup-edit>
  174. </div>
  175. </el-form-item>
  176. </div>
  177. <div class="part-box">
  178. <!-- <h4 class="part-box-tips">普通印品:</h4> -->
  179. <el-form-item
  180. v-for="(item, index) in modalForm.ordinaryContent"
  181. :key="item.type"
  182. :label="`${TEMPLATE_CLASSIFY[item.type]}:`"
  183. :prop="`ordinaryContent.${index}.templateId`"
  184. :rules="{
  185. required: false,
  186. validator: templateValidator,
  187. trigger: 'change',
  188. }"
  189. :required="!!item.templateId.length"
  190. >
  191. <el-checkbox-group
  192. v-model="item.templateId"
  193. disabled
  194. @change="(vals) => tempChange(vals, `ordinaryContent.${index}`)"
  195. >
  196. <el-checkbox
  197. v-for="temp in templateSources[item.type]"
  198. :label="temp.id"
  199. :key="temp.id"
  200. >{{ temp.name }}</el-checkbox
  201. >
  202. </el-checkbox-group>
  203. <div v-if="item.templateId.length">
  204. <el-select
  205. v-model="item.backupMethod"
  206. class="mr-2"
  207. size="small"
  208. placeholder="请选择"
  209. disabled
  210. >
  211. <el-option
  212. v-for="(val, key) in PRINT_BACKUP_TYPE"
  213. :key="key"
  214. :value="key"
  215. :label="val"
  216. ></el-option>
  217. </el-select>
  218. <exam-backup-edit
  219. v-model="item.backupCount"
  220. disabled
  221. ></exam-backup-edit>
  222. </div>
  223. </el-form-item>
  224. </div>
  225. <el-form-item prop="selectedPrint"></el-form-item>
  226. </el-form>
  227. <div slot="footer">
  228. <el-button
  229. v-if="editable"
  230. type="primary"
  231. :disabled="isSubmit"
  232. @click="submit"
  233. >确认</el-button
  234. >
  235. <el-button @click="cancel">取消</el-button>
  236. </div>
  237. </el-dialog>
  238. </template>
  239. <script>
  240. import {
  241. PRINT_CONTENT_TYPE,
  242. DRAW_RULE_TYPE,
  243. PRINT_BACKUP_TYPE,
  244. PAPER_BACKUP_TYPE,
  245. TEMPLATE_CLASSIFY,
  246. } from "@/constants/enumerate";
  247. import { deepCopy } from "@/plugins/utils";
  248. import { updatePrintPlan, printPlanTemplateList } from "../api";
  249. import { examConfigQuery } from "../../base/api";
  250. import ExamBackupEdit from "../../base/components/ExamBackupEdit.vue";
  251. const initModalForm = {
  252. id: null,
  253. name: "",
  254. examStartTime: "",
  255. examEndTime: "",
  256. semesterId: "",
  257. examId: "",
  258. printContent: [],
  259. backupMethod: "ROOM",
  260. backupCount: 1,
  261. drawRule: "ONE",
  262. variableContent: [
  263. {
  264. type: "SIGN",
  265. templateId: [],
  266. oldTemplateId: [],
  267. backupMethod: "ROOM",
  268. backupCount: 1,
  269. },
  270. {
  271. type: "PACKAGE",
  272. templateId: [],
  273. oldTemplateId: [],
  274. backupMethod: "ROOM",
  275. backupCount: 1,
  276. },
  277. ],
  278. ordinaryContent: [
  279. {
  280. type: "CHECK_IN",
  281. templateId: [],
  282. oldTemplateId: [],
  283. backupMethod: "ROOM",
  284. backupCount: 1,
  285. },
  286. ],
  287. };
  288. export default {
  289. name: "modify-print-plan",
  290. components: { ExamBackupEdit },
  291. props: {
  292. instance: {
  293. type: Object,
  294. default() {
  295. return {};
  296. },
  297. },
  298. editType: {
  299. type: String,
  300. default: "ADD",
  301. validator: (val) => ["ADD", "PREVIEW", "EDIT"].includes(val),
  302. },
  303. },
  304. computed: {
  305. isEdit() {
  306. return !!this.instance.id;
  307. },
  308. title() {
  309. const names = {
  310. ADD: "新增印刷计划",
  311. PREVIEW: "印刷计划详情",
  312. EDIT: "编辑印刷计划",
  313. };
  314. return names[this.editType];
  315. },
  316. editable() {
  317. return this.editType !== "PREVIEW";
  318. },
  319. contentIncludesPaper() {
  320. return this.modalForm.printContent.includes("PAPER");
  321. },
  322. },
  323. data() {
  324. // const printContentValidator = (rule, value, callback) => {
  325. // if (value.includes("PAPER") && !value.includes("CARD")) {
  326. // callback(new Error("选择了试卷,同时必须选择题卡"));
  327. // } else {
  328. // callback();
  329. // }
  330. // };
  331. const backupMethodValidator = (rule, value, callback) => {
  332. if (!this.modalForm.printContent.length) {
  333. return callback();
  334. }
  335. if (!value) {
  336. return callback(new Error("请选择备份方式"));
  337. }
  338. if (!this.modalForm.backupCount) {
  339. return callback(new Error("请输入备份数量"));
  340. }
  341. callback();
  342. };
  343. const selectedPrintValidator = (rule, value, callback) => {
  344. const printInfo = [
  345. ...this.modalForm.variableContent,
  346. ...this.modalForm.ordinaryContent,
  347. ];
  348. const hasPrintInfo = printInfo.some((item) => item.templateId.length);
  349. if (hasPrintInfo || this.modalForm.printContent.length) {
  350. callback();
  351. } else {
  352. callback(new Error("必须选择一项印品"));
  353. }
  354. };
  355. return {
  356. modalIsShow: false,
  357. isSubmit: false,
  358. modalForm: deepCopy(initModalForm),
  359. createTime: [],
  360. PRINT_CONTENT_TYPE,
  361. DRAW_RULE_TYPE,
  362. PRINT_BACKUP_TYPE,
  363. PAPER_BACKUP_TYPE,
  364. TEMPLATE_CLASSIFY,
  365. variableContent: [],
  366. ordinaryContent: [],
  367. templateSources: {},
  368. oldPrintContent: [],
  369. allSelected: false,
  370. rules: {
  371. name: [
  372. {
  373. required: true,
  374. message: "请输入印刷计划名称,长度不要超过50个字符",
  375. max: 50,
  376. trigger: "change",
  377. },
  378. ],
  379. examStartTime: [
  380. {
  381. required: true,
  382. message: "请设置考试时间",
  383. trigger: "change",
  384. },
  385. ],
  386. semesterId: [
  387. {
  388. required: true,
  389. message: "请选择使用学期",
  390. trigger: "change",
  391. },
  392. ],
  393. examId: [
  394. {
  395. required: true,
  396. message: "请选择使用考试",
  397. trigger: "change",
  398. },
  399. ],
  400. printContent: [
  401. {
  402. required: false,
  403. // validator: printContentValidator,
  404. trigger: "change",
  405. },
  406. ],
  407. backupMethod: [
  408. {
  409. required: true,
  410. validator: backupMethodValidator,
  411. trigger: "change",
  412. },
  413. ],
  414. drawRule: [
  415. {
  416. required: true,
  417. message: "请选择抽卷规则",
  418. trigger: "change",
  419. },
  420. ],
  421. selectedPrint: [
  422. {
  423. required: false,
  424. validator: selectedPrintValidator,
  425. trigger: "change",
  426. },
  427. ],
  428. },
  429. };
  430. },
  431. mounted() {
  432. this.getTemplates();
  433. },
  434. methods: {
  435. async getTemplates() {
  436. const data = await printPlanTemplateList();
  437. const templateSources = {};
  438. const templates = [...data.variable, ...data.ordinary];
  439. templates.forEach((item) => {
  440. templateSources[item.type] = item.template;
  441. });
  442. this.templateSources = templateSources;
  443. },
  444. selectAll(selected) {
  445. if (selected) {
  446. this.modalForm.printContent = ["PAPER", "CARD"];
  447. this.modalForm.variableContent.forEach((item) => {
  448. if (item.templateId && item.templateId.length) return;
  449. const source = this.templateSources[item.type][0];
  450. item.templateId = source && [source.id];
  451. item.oldTemplateId = source && [source.id];
  452. });
  453. this.modalForm.ordinaryContent.forEach((item) => {
  454. if (item.templateId && item.templateId.length) return;
  455. const source = this.templateSources[item.type][0];
  456. item.templateId = source && [source.id];
  457. item.oldTemplateId = source && [source.id];
  458. });
  459. } else {
  460. this.modalForm.printContent = [];
  461. this.modalForm.variableContent.forEach((item) => {
  462. item.templateId = [];
  463. item.oldTemplateId = [];
  464. });
  465. this.modalForm.ordinaryContent.forEach((item) => {
  466. item.templateId = [];
  467. item.oldTemplateId = [];
  468. });
  469. }
  470. },
  471. checkSelectAll() {
  472. const vNotSelected = this.modalForm.variableContent.some(
  473. (item) => !item.templateId.length
  474. );
  475. const oNotSelected = this.modalForm.ordinaryContent.some(
  476. (item) => !item.templateId.length
  477. );
  478. const pNotSelected = this.modalForm.printContent.length < 2;
  479. const selecteds = [vNotSelected, oNotSelected, pNotSelected];
  480. this.allSelected = !selecteds.some((item) => item);
  481. },
  482. templateValidator(rule, value, callback) {
  483. const [field, index] = rule.field.split(".");
  484. const val = this.modalForm[field][index];
  485. if (val.templateId.length) {
  486. if (!val.backupMethod) {
  487. return callback(new Error("请选择备份方式"));
  488. }
  489. if (!val.backupCount) {
  490. return callback(new Error("请输入备份数量"));
  491. }
  492. callback();
  493. } else {
  494. callback();
  495. }
  496. },
  497. tempChange(vals, name) {
  498. const [field, index] = name.split(".");
  499. const info = this.modalForm[field][index];
  500. const newVals = vals.filter((item) => !info.oldTemplateId.includes(item));
  501. info.templateId = newVals;
  502. info.oldTemplateId = newVals;
  503. this.checkSelectAll();
  504. this.$refs.modalFormComp.validateField("selectedPrint");
  505. },
  506. printContentChange(val) {
  507. const isSelectPaper =
  508. !this.oldPrintContent.includes("PAPER") && val.includes("PAPER");
  509. if (isSelectPaper && !val.includes("CARD")) {
  510. val.push("CARD");
  511. }
  512. this.oldPrintContent = val;
  513. },
  514. initData(val) {
  515. if (val.id) {
  516. this.createTime = [val.examStartTime, val.examEndTime];
  517. this.modalForm = this.$objAssign(deepCopy(initModalForm), val);
  518. const transformInfo = (item) => {
  519. const templateIds = item.templateId ? [item.templateId] : [];
  520. return {
  521. type: item.type,
  522. templateId: templateIds,
  523. oldTemplateId: templateIds,
  524. backupMethod: item.backupMethod,
  525. backupCount: item.backupCount,
  526. };
  527. };
  528. const initModalFormContent = deepCopy(initModalForm);
  529. const variableContent = val.variableContent;
  530. const variableContentTypes = variableContent.map((item) => item.type);
  531. this.modalForm.variableContent = [];
  532. initModalFormContent.variableContent.forEach((item) => {
  533. if (variableContentTypes.includes(item.type)) {
  534. const vitem = variableContent.find(
  535. (cont) => cont.type === item.type
  536. );
  537. this.modalForm.variableContent.push(transformInfo(vitem));
  538. return;
  539. }
  540. if (this.templateSources[item.type]) {
  541. this.modalForm.variableContent.push(item);
  542. return;
  543. }
  544. });
  545. const ordinaryContent = val.ordinaryContent;
  546. const ordinaryContentTypes = ordinaryContent.map((item) => item.type);
  547. this.modalForm.ordinaryContent = [];
  548. initModalFormContent.ordinaryContent.forEach((item) => {
  549. if (ordinaryContentTypes.includes(item.type)) {
  550. const vitem = ordinaryContent.find(
  551. (cont) => cont.type === item.type
  552. );
  553. this.modalForm.ordinaryContent.push(transformInfo(vitem));
  554. return;
  555. }
  556. if (this.templateSources[item.type]) {
  557. this.modalForm.ordinaryContent.push(item);
  558. return;
  559. }
  560. });
  561. this.modalForm.printContent = val.printContent
  562. ? val.printContent.split(",")
  563. : [];
  564. this.checkSelectAll();
  565. } else {
  566. this.allSelected = false;
  567. let modalForm = deepCopy(initModalForm);
  568. modalForm.variableContent = modalForm.variableContent.filter(
  569. (item) => this.templateSources[item.type]
  570. );
  571. modalForm.ordinaryContent = modalForm.ordinaryContent.filter(
  572. (item) => this.templateSources[item.type]
  573. );
  574. this.modalForm = modalForm;
  575. this.createTime = [];
  576. }
  577. },
  578. visibleChange() {
  579. this.initData(this.instance);
  580. this.$nextTick(() => {
  581. this.$refs.modalFormComp.clearValidate();
  582. });
  583. },
  584. cancel() {
  585. this.modalIsShow = false;
  586. },
  587. open() {
  588. this.modalIsShow = true;
  589. },
  590. async examChange() {
  591. if (!this.modalForm.examId) return;
  592. const data = await examConfigQuery({
  593. examId: this.modalForm.examId,
  594. pageNumber: 1,
  595. pageSize: 10,
  596. });
  597. this.initExamConfig(data.records[0]);
  598. },
  599. initExamConfig(val) {
  600. // console.log(val);
  601. if (!val) return;
  602. const data = this.$objAssign(
  603. {
  604. backupMethod: "ROOM",
  605. backupCount: 1,
  606. drawRule: "ONE",
  607. },
  608. val
  609. );
  610. Object.assign(this.modalForm, data);
  611. const transformInfo = (item) => {
  612. const templateIds = item.templateId ? [item.templateId] : [];
  613. return {
  614. type: item.type,
  615. templateId: templateIds,
  616. oldTemplateId: templateIds,
  617. backupMethod: item.backupMethod,
  618. backupCount: item.backupCount,
  619. };
  620. };
  621. const initModalFormContent = deepCopy(initModalForm);
  622. const variableContent = JSON.parse(val.variableContent);
  623. const variableContentTypes = variableContent.map((item) => item.type);
  624. this.modalForm.variableContent = [];
  625. initModalFormContent.variableContent.forEach((item) => {
  626. if (variableContentTypes.includes(item.type)) {
  627. const vitem = variableContent.find((cont) => cont.type === item.type);
  628. this.modalForm.variableContent.push(transformInfo(vitem));
  629. return;
  630. }
  631. if (this.templateSources[item.type]) {
  632. this.modalForm.variableContent.push(item);
  633. return;
  634. }
  635. });
  636. const ordinaryContent = JSON.parse(val.ordinaryContent);
  637. const ordinaryContentTypes = ordinaryContent.map((item) => item.type);
  638. this.modalForm.ordinaryContent = [];
  639. initModalFormContent.ordinaryContent.forEach((item) => {
  640. if (ordinaryContentTypes.includes(item.type)) {
  641. const vitem = ordinaryContent.find((cont) => cont.type === item.type);
  642. this.modalForm.ordinaryContent.push(transformInfo(vitem));
  643. return;
  644. }
  645. if (this.templateSources[item.type]) {
  646. this.modalForm.ordinaryContent.push(item);
  647. return;
  648. }
  649. });
  650. this.modalForm.printContent = JSON.parse(val.printContent);
  651. this.checkSelectAll();
  652. },
  653. dateChange() {
  654. if (this.createTime) {
  655. this.modalForm.examStartTime = this.createTime[0];
  656. this.modalForm.examEndTime = this.createTime[1];
  657. } else {
  658. this.modalForm.examStartTime = "";
  659. this.modalForm.examEndTime = "";
  660. }
  661. },
  662. async submit() {
  663. const valid = await this.$refs.modalFormComp.validate().catch(() => {});
  664. if (!valid) return;
  665. if (this.isSubmit) return;
  666. this.isSubmit = true;
  667. const datas = { ...this.modalForm };
  668. const transformInfo = (item) => {
  669. const templateId = item.templateId.join();
  670. const template = this.templateSources[item.type].find(
  671. (temp) => temp.id === templateId
  672. );
  673. return {
  674. type: item.type,
  675. templateId,
  676. attachmentId: template && template.attachmentId,
  677. backupMethod: item.backupMethod,
  678. backupCount: item.backupCount,
  679. };
  680. };
  681. datas.variableContent = JSON.stringify(
  682. this.modalForm.variableContent.map(transformInfo)
  683. );
  684. datas.ordinaryContent = JSON.stringify(
  685. this.modalForm.ordinaryContent.map(transformInfo)
  686. );
  687. const data = await updatePrintPlan(datas).catch(() => {});
  688. this.isSubmit = false;
  689. if (!data) return;
  690. this.$message.success("保存成功!");
  691. this.$emit("modified");
  692. this.cancel();
  693. },
  694. },
  695. };
  696. </script>