ModifyPrintPlan.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. <template>
  2. <el-dialog
  3. class="modify-print-plan"
  4. :visible.sync="modalIsShow"
  5. :title="title"
  6. top="10px"
  7. width="700px"
  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="110px"
  16. :rules="rules"
  17. :model="modalForm"
  18. >
  19. <div class="part-box part-box-pad part-box-border">
  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. </div>
  45. <div class="part-box part-box-pad part-box-border">
  46. <h4 class="part-box-tips">试卷&题卡印品:</h4>
  47. <el-form-item prop="printContent" label="试卷、题卡:">
  48. <el-checkbox-group
  49. v-model="modalForm.printContent"
  50. :disabled="!editable"
  51. >
  52. <el-checkbox
  53. v-for="(val, key) in PRINT_CONTENT_TYPE"
  54. :key="key"
  55. :label="key"
  56. >{{ val }}</el-checkbox
  57. >
  58. </el-checkbox-group>
  59. </el-form-item>
  60. <el-form-item
  61. prop="backupMethod"
  62. label="试卷备份方式:"
  63. :required="!!modalForm.printContent.length"
  64. >
  65. <el-select
  66. v-model="modalForm.backupMethod"
  67. class="mr-2"
  68. size="small"
  69. placeholder="请选择"
  70. :disabled="!editable"
  71. >
  72. <el-option
  73. v-for="(val, key) in PAPER_BACKUP_TYPE"
  74. :key="key"
  75. :value="key"
  76. :label="val"
  77. ></el-option>
  78. </el-select>
  79. <el-input-number
  80. class="mr-1"
  81. v-model="modalForm.backupCount"
  82. size="small"
  83. :min="1"
  84. :max="200"
  85. :step="1"
  86. step-strictly
  87. :controls="false"
  88. :disabled="!editable"
  89. ></el-input-number>
  90. <span>份</span>
  91. </el-form-item>
  92. <el-form-item
  93. prop="drawRule"
  94. label="抽卷规则:"
  95. :required="!!modalForm.printContent.length"
  96. >
  97. <el-radio-group v-model="modalForm.drawRule" :disabled="!editable">
  98. <el-radio
  99. v-for="(val, key) in DRAW_RULE_TYPE"
  100. :label="key"
  101. :key="key"
  102. >{{ val }}</el-radio
  103. >
  104. </el-radio-group>
  105. <p class="tips-info">
  106. 1.只抽取一次:不同印刷计划下,同一试卷编号下的卷型只能被抽取一次;
  107. </p>
  108. <p class="tips-info">
  109. 2.可反复抽取:不同印刷计划下,同一试卷编号下的卷型可重复抽取,系统默认优先抽取未曝光卷型。
  110. </p>
  111. </el-form-item>
  112. </div>
  113. <div class="part-box part-box-pad part-box-border">
  114. <h4 class="part-box-tips">变量印品:</h4>
  115. <el-form-item
  116. v-for="(item, index) in modalForm.variableContent"
  117. :key="item.type"
  118. :label="`${TEMPLATE_CLASSIFY[item.type]}:`"
  119. :prop="`variableContent.${index}.templateId`"
  120. :rules="{
  121. required: false,
  122. validator: templateValidator,
  123. trigger: 'change'
  124. }"
  125. :required="!!item.templateId.length"
  126. >
  127. <el-checkbox-group
  128. v-model="item.templateId"
  129. :disabled="!editable"
  130. @change="vals => tempChange(vals, `variableContent.${index}`)"
  131. >
  132. <el-checkbox
  133. v-for="temp in templateSources[item.type]"
  134. :label="temp.id"
  135. :key="temp.id"
  136. >{{ temp.name }}</el-checkbox
  137. >
  138. </el-checkbox-group>
  139. <div v-if="item.templateId.length">
  140. <el-select
  141. v-model="item.backupMethod"
  142. class="mr-2"
  143. size="small"
  144. placeholder="请选择"
  145. :disabled="!editable"
  146. >
  147. <el-option
  148. v-for="(val, key) in PRINT_BACKUP_TYPE"
  149. :key="key"
  150. :value="key"
  151. :label="val"
  152. ></el-option>
  153. </el-select>
  154. <el-input-number
  155. v-model="item.backupCount"
  156. class="mr-1"
  157. size="small"
  158. :min="1"
  159. :max="200"
  160. :step="1"
  161. step-strictly
  162. :controls="false"
  163. :disabled="!editable"
  164. ></el-input-number>
  165. <span>份</span>
  166. </div>
  167. </el-form-item>
  168. </div>
  169. <div class="part-box part-box-pad part-box-border">
  170. <h4 class="part-box-tips">普通印品:</h4>
  171. <el-form-item
  172. v-for="(item, index) in modalForm.ordinaryContent"
  173. :key="item.type"
  174. :label="`${TEMPLATE_CLASSIFY[item.type]}:`"
  175. label-width="130px"
  176. :prop="`ordinaryContent.${index}.templateId`"
  177. :rules="{
  178. required: false,
  179. validator: templateValidator,
  180. trigger: 'change'
  181. }"
  182. :required="!!item.templateId.length"
  183. >
  184. <el-checkbox-group
  185. v-model="item.templateId"
  186. :disabled="!editable"
  187. @change="vals => tempChange(vals, `ordinaryContent.${index}`)"
  188. >
  189. <el-checkbox
  190. v-for="temp in templateSources[item.type]"
  191. :label="temp.id"
  192. :key="temp.id"
  193. >{{ temp.name }}</el-checkbox
  194. >
  195. </el-checkbox-group>
  196. <div v-if="item.templateId.length">
  197. <el-select
  198. v-model="item.backupMethod"
  199. class="mr-2"
  200. size="small"
  201. placeholder="请选择"
  202. :disabled="!editable"
  203. >
  204. <el-option
  205. v-for="(val, key) in PRINT_BACKUP_TYPE"
  206. :key="key"
  207. :value="key"
  208. :label="val"
  209. ></el-option>
  210. </el-select>
  211. <el-input-number
  212. v-model="item.backupCount"
  213. class="mr-1"
  214. size="small"
  215. :min="1"
  216. :max="200"
  217. :step="1"
  218. step-strictly
  219. :controls="false"
  220. :disabled="!editable"
  221. ></el-input-number>
  222. <span>份</span>
  223. </div>
  224. </el-form-item>
  225. </div>
  226. <el-form-item prop="selectedPrint"></el-form-item>
  227. </el-form>
  228. <div slot="footer">
  229. <el-button
  230. v-if="editable"
  231. type="primary"
  232. :disabled="isSubmit"
  233. @click="submit"
  234. >确认</el-button
  235. >
  236. <el-button type="danger" @click="cancel" plain>取消</el-button>
  237. </div>
  238. </el-dialog>
  239. </template>
  240. <script>
  241. import {
  242. PRINT_CONTENT_TYPE,
  243. DRAW_RULE_TYPE,
  244. PRINT_BACKUP_TYPE,
  245. PAPER_BACKUP_TYPE,
  246. TEMPLATE_CLASSIFY
  247. } from "@/constants/enumerate";
  248. import { deepCopy } from "@/plugins/utils";
  249. import { updatePrintPlan, printPlanTemplateList } from "../api";
  250. const initModalForm = {
  251. id: null,
  252. name: "",
  253. examStartTime: "",
  254. examEndTime: "",
  255. printContent: [],
  256. backupMethod: "PLACE",
  257. backupCount: 1,
  258. drawRule: "ONE",
  259. variableContent: [
  260. {
  261. type: "SIGN",
  262. templateId: [],
  263. oldTemplateId: [],
  264. backupMethod: "ROOM",
  265. backupCount: 1
  266. },
  267. {
  268. type: "PACKAGE",
  269. templateId: [],
  270. oldTemplateId: [],
  271. backupMethod: "ROOM",
  272. backupCount: 1
  273. }
  274. ],
  275. ordinaryContent: [
  276. {
  277. type: "CHECK_IN",
  278. templateId: [],
  279. oldTemplateId: [],
  280. backupMethod: "ROOM",
  281. backupCount: 1
  282. }
  283. ]
  284. };
  285. export default {
  286. name: "modify-print-plan",
  287. props: {
  288. instance: {
  289. type: Object,
  290. default() {
  291. return {};
  292. }
  293. },
  294. editType: {
  295. type: String,
  296. default: "ADD",
  297. validator: val => ["ADD", "PREVIEW", "EDIT"].includes(val)
  298. }
  299. },
  300. computed: {
  301. isEdit() {
  302. return !!this.instance.id;
  303. },
  304. title() {
  305. const names = {
  306. ADD: "新增印刷计划",
  307. PREVIEW: "印刷计划详情",
  308. EDIT: "编辑印刷计划"
  309. };
  310. return names[this.editType];
  311. },
  312. editable() {
  313. return this.editType !== "PREVIEW";
  314. }
  315. },
  316. data() {
  317. const printContentValidator = (rule, value, callback) => {
  318. if (value.includes("PAPER") && !value.includes("CARD")) {
  319. callback(new Error("选择了试卷,同时必须选择题卡"));
  320. } else {
  321. callback();
  322. }
  323. };
  324. const backupMethodValidator = (rule, value, callback) => {
  325. if (!this.modalForm.printContent.length) {
  326. return callback();
  327. }
  328. if (!value) {
  329. return callback(new Error("请选择备份方式"));
  330. }
  331. if (!this.modalForm.backupCount) {
  332. return callback(new Error("请输入备份数量"));
  333. }
  334. callback();
  335. };
  336. const selectedPrintValidator = (rule, value, callback) => {
  337. const printInfo = [
  338. ...this.modalForm.variableContent,
  339. ...this.modalForm.ordinaryContent
  340. ];
  341. const hasPrintInfo = printInfo.some(item => item.templateId.length);
  342. if (hasPrintInfo || this.modalForm.printContent.length) {
  343. callback();
  344. } else {
  345. callback(new Error("必须选择一项印品"));
  346. }
  347. };
  348. return {
  349. modalIsShow: false,
  350. isSubmit: false,
  351. modalForm: deepCopy(initModalForm),
  352. createTime: [],
  353. PRINT_CONTENT_TYPE,
  354. DRAW_RULE_TYPE,
  355. PRINT_BACKUP_TYPE,
  356. PAPER_BACKUP_TYPE,
  357. TEMPLATE_CLASSIFY,
  358. variableContent: [],
  359. ordinaryContent: [],
  360. templateSources: {},
  361. rules: {
  362. name: [
  363. {
  364. required: true,
  365. message: "请输入印刷计划名称,长度不要超过50个字符",
  366. max: 50,
  367. trigger: "change"
  368. }
  369. ],
  370. examStartTime: [
  371. {
  372. required: true,
  373. message: "请设置考试时间",
  374. trigger: "change"
  375. }
  376. ],
  377. printContent: [
  378. {
  379. required: false,
  380. validator: printContentValidator,
  381. trigger: "change"
  382. }
  383. ],
  384. backupMethod: [
  385. {
  386. required: false,
  387. validator: backupMethodValidator,
  388. trigger: "change"
  389. }
  390. ],
  391. drawRule: [
  392. {
  393. required: false,
  394. message: "请选择抽卷规则",
  395. trigger: "change"
  396. }
  397. ],
  398. selectedPrint: [
  399. {
  400. required: false,
  401. validator: selectedPrintValidator,
  402. trigger: "change"
  403. }
  404. ]
  405. }
  406. };
  407. },
  408. mounted() {
  409. this.getTemplates();
  410. },
  411. methods: {
  412. async getTemplates() {
  413. const data = await printPlanTemplateList();
  414. const templateSources = {};
  415. const templates = [...data.variable, ...data.ordinary];
  416. templates.forEach(item => {
  417. templateSources[item.type] = item.template;
  418. });
  419. this.templateSources = templateSources;
  420. },
  421. templateValidator(rule, value, callback) {
  422. const [field, index] = rule.field.split(".");
  423. const val = this.modalForm[field][index];
  424. if (val.templateId.length) {
  425. if (!val.backupMethod) {
  426. return callback(new Error("请选择备份方式"));
  427. }
  428. if (!val.backupCount) {
  429. return callback(new Error("请输入备份数量"));
  430. }
  431. callback();
  432. } else {
  433. callback();
  434. }
  435. },
  436. tempChange(vals, name) {
  437. const [field, index] = name.split(".");
  438. const info = this.modalForm[field][index];
  439. const newVals = vals.filter(item => !info.oldTemplateId.includes(item));
  440. info.templateId = newVals;
  441. info.oldTemplateId = newVals;
  442. this.$refs.modalFormComp.validateField("selectedPrint");
  443. },
  444. initData(val) {
  445. if (val.id) {
  446. this.createTime = [val.examStartTime, val.examEndTime];
  447. this.modalForm = this.$objAssign(deepCopy(initModalForm), val);
  448. const transformInfo = item => {
  449. const templateIds = item.templateId ? [item.templateId] : [];
  450. return {
  451. type: item.type,
  452. templateId: templateIds,
  453. oldTemplateId: templateIds,
  454. backupMethod: item.backupMethod,
  455. backupCount: item.backupCount
  456. };
  457. };
  458. this.modalForm.variableContent = val.variableContent.map(transformInfo);
  459. this.modalForm.ordinaryContent = val.ordinaryContent.map(transformInfo);
  460. this.modalForm.printContent = val.printContent
  461. ? val.printContent.split(",")
  462. : [];
  463. } else {
  464. let modalForm = deepCopy(initModalForm);
  465. modalForm.variableContent = modalForm.variableContent.filter(
  466. item => this.templateSources[item.type]
  467. );
  468. modalForm.ordinaryContent = modalForm.ordinaryContent.filter(
  469. item => this.templateSources[item.type]
  470. );
  471. this.modalForm = modalForm;
  472. this.createTime = [];
  473. }
  474. },
  475. visibleChange() {
  476. this.initData(this.instance);
  477. this.$nextTick(() => {
  478. this.$refs.modalFormComp.clearValidate();
  479. });
  480. },
  481. cancel() {
  482. this.modalIsShow = false;
  483. },
  484. open() {
  485. this.modalIsShow = true;
  486. },
  487. dateChange() {
  488. if (this.createTime) {
  489. this.modalForm.examStartTime = this.createTime[0];
  490. this.modalForm.examEndTime = this.createTime[1];
  491. } else {
  492. this.modalForm.examStartTime = "";
  493. this.modalForm.examEndTime = "";
  494. }
  495. },
  496. async submit() {
  497. const valid = await this.$refs.modalFormComp.validate().catch(() => {});
  498. if (!valid) return;
  499. if (this.isSubmit) return;
  500. this.isSubmit = true;
  501. const datas = { ...this.modalForm };
  502. const transformInfo = item => {
  503. const templateId = item.templateId.join();
  504. const template = this.templateSources[item.type].find(
  505. temp => temp.id === templateId
  506. );
  507. return {
  508. type: item.type,
  509. templateId,
  510. attachmentId: template && template.attachmentId,
  511. backupMethod: item.backupMethod,
  512. backupCount: item.backupCount
  513. };
  514. };
  515. datas.variableContent = JSON.stringify(
  516. this.modalForm.variableContent.map(transformInfo)
  517. );
  518. datas.ordinaryContent = JSON.stringify(
  519. this.modalForm.ordinaryContent.map(transformInfo)
  520. );
  521. const data = await updatePrintPlan(datas).catch(() => {});
  522. this.isSubmit = false;
  523. if (!data) return;
  524. this.$message.success("保存成功!");
  525. this.$emit("modified");
  526. this.cancel();
  527. }
  528. }
  529. };
  530. </script>