ModifyPrintPlan.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  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. <el-select
  47. v-model.trim="modalForm.semesterId"
  48. placeholder="请选择使用学期"
  49. style="width: 100%"
  50. :disabled="!editable"
  51. >
  52. <el-option
  53. v-for="item in semesters"
  54. :key="item.id"
  55. :value="item.id"
  56. :label="item.name"
  57. ></el-option>
  58. </el-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="!editable"
  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="!editable"
  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="!editable"
  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="!editable"
  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="!editable">
  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="!editable"
  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="!editable"
  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="!editable"
  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="!editable"
  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="!editable"
  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="!editable"
  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 { examSemesterList } from "../../base/api";
  279. const initModalForm = {
  280. id: null,
  281. name: "",
  282. examStartTime: "",
  283. examEndTime: "",
  284. semesterId: "",
  285. printContent: [],
  286. backupMethod: "ROOM",
  287. backupCount: 1,
  288. drawRule: "ONE",
  289. variableContent: [
  290. {
  291. type: "SIGN",
  292. templateId: [],
  293. oldTemplateId: [],
  294. backupMethod: "ROOM",
  295. backupCount: 1
  296. },
  297. {
  298. type: "PACKAGE",
  299. templateId: [],
  300. oldTemplateId: [],
  301. backupMethod: "ROOM",
  302. backupCount: 1
  303. }
  304. ],
  305. ordinaryContent: [
  306. {
  307. type: "CHECK_IN",
  308. templateId: [],
  309. oldTemplateId: [],
  310. backupMethod: "ROOM",
  311. backupCount: 1
  312. }
  313. ]
  314. };
  315. export default {
  316. name: "modify-print-plan",
  317. props: {
  318. instance: {
  319. type: Object,
  320. default() {
  321. return {};
  322. }
  323. },
  324. editType: {
  325. type: String,
  326. default: "ADD",
  327. validator: val => ["ADD", "PREVIEW", "EDIT"].includes(val)
  328. }
  329. },
  330. computed: {
  331. isEdit() {
  332. return !!this.instance.id;
  333. },
  334. title() {
  335. const names = {
  336. ADD: "新增印刷计划",
  337. PREVIEW: "印刷计划详情",
  338. EDIT: "编辑印刷计划"
  339. };
  340. return names[this.editType];
  341. },
  342. editable() {
  343. return this.editType !== "PREVIEW";
  344. },
  345. contentIncludesPaper() {
  346. return this.modalForm.printContent.includes("PAPER");
  347. }
  348. },
  349. data() {
  350. // const printContentValidator = (rule, value, callback) => {
  351. // if (value.includes("PAPER") && !value.includes("CARD")) {
  352. // callback(new Error("选择了试卷,同时必须选择题卡"));
  353. // } else {
  354. // callback();
  355. // }
  356. // };
  357. const backupMethodValidator = (rule, value, callback) => {
  358. if (!this.modalForm.printContent.length) {
  359. return callback();
  360. }
  361. if (!value) {
  362. return callback(new Error("请选择备份方式"));
  363. }
  364. if (!this.modalForm.backupCount) {
  365. return callback(new Error("请输入备份数量"));
  366. }
  367. callback();
  368. };
  369. const selectedPrintValidator = (rule, value, callback) => {
  370. const printInfo = [
  371. ...this.modalForm.variableContent,
  372. ...this.modalForm.ordinaryContent
  373. ];
  374. const hasPrintInfo = printInfo.some(item => item.templateId.length);
  375. if (hasPrintInfo || this.modalForm.printContent.length) {
  376. callback();
  377. } else {
  378. callback(new Error("必须选择一项印品"));
  379. }
  380. };
  381. return {
  382. modalIsShow: false,
  383. isSubmit: false,
  384. modalForm: deepCopy(initModalForm),
  385. createTime: [],
  386. semesters: [],
  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. printContent: [
  421. {
  422. required: false,
  423. // validator: printContentValidator,
  424. trigger: "change"
  425. }
  426. ],
  427. backupMethod: [
  428. {
  429. required: true,
  430. validator: backupMethodValidator,
  431. trigger: "change"
  432. }
  433. ],
  434. drawRule: [
  435. {
  436. required: true,
  437. message: "请选择抽卷规则",
  438. trigger: "change"
  439. }
  440. ],
  441. selectedPrint: [
  442. {
  443. required: false,
  444. validator: selectedPrintValidator,
  445. trigger: "change"
  446. }
  447. ]
  448. }
  449. };
  450. },
  451. mounted() {
  452. this.getTemplates();
  453. this.getSemesters();
  454. },
  455. methods: {
  456. async getTemplates() {
  457. const data = await printPlanTemplateList();
  458. const templateSources = {};
  459. const templates = [...data.variable, ...data.ordinary];
  460. templates.forEach(item => {
  461. templateSources[item.type] = item.template;
  462. });
  463. this.templateSources = templateSources;
  464. },
  465. async getSemesters() {
  466. const res = await examSemesterList({ inUsed: 1 });
  467. this.semesters = res || [];
  468. },
  469. selectAll(selected) {
  470. if (selected) {
  471. this.modalForm.printContent = ["PAPER", "CARD"];
  472. this.modalForm.variableContent.forEach(item => {
  473. if (item.templateId && item.templateId.length) return;
  474. const source = this.templateSources[item.type][0];
  475. item.templateId = source && [source.id];
  476. item.oldTemplateId = source && [source.id];
  477. });
  478. this.modalForm.ordinaryContent.forEach(item => {
  479. if (item.templateId && item.templateId.length) return;
  480. const source = this.templateSources[item.type][0];
  481. item.templateId = source && [source.id];
  482. item.oldTemplateId = source && [source.id];
  483. });
  484. } else {
  485. this.modalForm.printContent = [];
  486. this.modalForm.variableContent.forEach(item => {
  487. item.templateId = [];
  488. item.oldTemplateId = [];
  489. });
  490. this.modalForm.ordinaryContent.forEach(item => {
  491. item.templateId = [];
  492. item.oldTemplateId = [];
  493. });
  494. }
  495. },
  496. checkSelectAll() {
  497. const vNotSelected = this.modalForm.variableContent.some(
  498. item => !item.templateId.length
  499. );
  500. const oNotSelected = this.modalForm.ordinaryContent.some(
  501. item => !item.templateId.length
  502. );
  503. const pNotSelected = this.modalForm.printContent.length < 2;
  504. const selecteds = [vNotSelected, oNotSelected, pNotSelected];
  505. this.allSelected = !selecteds.some(item => item);
  506. },
  507. templateValidator(rule, value, callback) {
  508. const [field, index] = rule.field.split(".");
  509. const val = this.modalForm[field][index];
  510. if (val.templateId.length) {
  511. if (!val.backupMethod) {
  512. return callback(new Error("请选择备份方式"));
  513. }
  514. if (!val.backupCount) {
  515. return callback(new Error("请输入备份数量"));
  516. }
  517. callback();
  518. } else {
  519. callback();
  520. }
  521. },
  522. tempChange(vals, name) {
  523. const [field, index] = name.split(".");
  524. const info = this.modalForm[field][index];
  525. const newVals = vals.filter(item => !info.oldTemplateId.includes(item));
  526. info.templateId = newVals;
  527. info.oldTemplateId = newVals;
  528. this.checkSelectAll();
  529. this.$refs.modalFormComp.validateField("selectedPrint");
  530. },
  531. printContentChange(val) {
  532. const isSelectPaper =
  533. !this.oldPrintContent.includes("PAPER") && val.includes("PAPER");
  534. if (isSelectPaper && !val.includes("CARD")) {
  535. val.push("CARD");
  536. }
  537. this.oldPrintContent = val;
  538. },
  539. initData(val) {
  540. if (val.id) {
  541. this.createTime = [val.examStartTime, val.examEndTime];
  542. this.modalForm = this.$objAssign(deepCopy(initModalForm), val);
  543. const transformInfo = item => {
  544. const templateIds = item.templateId ? [item.templateId] : [];
  545. return {
  546. type: item.type,
  547. templateId: templateIds,
  548. oldTemplateId: templateIds,
  549. backupMethod: item.backupMethod,
  550. backupCount: item.backupCount
  551. };
  552. };
  553. this.modalForm.variableContent = val.variableContent.map(transformInfo);
  554. this.modalForm.ordinaryContent = val.ordinaryContent.map(transformInfo);
  555. this.modalForm.printContent = val.printContent
  556. ? val.printContent.split(",")
  557. : [];
  558. this.checkSelectAll();
  559. } else {
  560. this.allSelected = false;
  561. let modalForm = deepCopy(initModalForm);
  562. modalForm.variableContent = modalForm.variableContent.filter(
  563. item => this.templateSources[item.type]
  564. );
  565. modalForm.ordinaryContent = modalForm.ordinaryContent.filter(
  566. item => this.templateSources[item.type]
  567. );
  568. modalForm.semesterId = this.semesters[0].id || "";
  569. this.modalForm = modalForm;
  570. this.createTime = [];
  571. }
  572. },
  573. visibleChange() {
  574. this.initData(this.instance);
  575. this.$nextTick(() => {
  576. this.$refs.modalFormComp.clearValidate();
  577. });
  578. },
  579. cancel() {
  580. this.modalIsShow = false;
  581. },
  582. open() {
  583. this.modalIsShow = true;
  584. },
  585. dateChange() {
  586. if (this.createTime) {
  587. this.modalForm.examStartTime = this.createTime[0];
  588. this.modalForm.examEndTime = this.createTime[1];
  589. } else {
  590. this.modalForm.examStartTime = "";
  591. this.modalForm.examEndTime = "";
  592. }
  593. },
  594. async submit() {
  595. const valid = await this.$refs.modalFormComp.validate().catch(() => {});
  596. if (!valid) return;
  597. if (this.isSubmit) return;
  598. this.isSubmit = true;
  599. const datas = { ...this.modalForm };
  600. const transformInfo = item => {
  601. const templateId = item.templateId.join();
  602. const template = this.templateSources[item.type].find(
  603. temp => temp.id === templateId
  604. );
  605. return {
  606. type: item.type,
  607. templateId,
  608. attachmentId: template && template.attachmentId,
  609. backupMethod: item.backupMethod,
  610. backupCount: item.backupCount
  611. };
  612. };
  613. datas.variableContent = JSON.stringify(
  614. this.modalForm.variableContent.map(transformInfo)
  615. );
  616. datas.ordinaryContent = JSON.stringify(
  617. this.modalForm.ordinaryContent.map(transformInfo)
  618. );
  619. const data = await updatePrintPlan(datas).catch(() => {});
  620. this.isSubmit = false;
  621. if (!data) return;
  622. this.$message.success("保存成功!");
  623. this.$emit("modified");
  624. this.cancel();
  625. }
  626. }
  627. };
  628. </script>