ModifyPrintPlan.vue 22 KB

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