UploadPaperAnswerDialog.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <template>
  2. <el-dialog
  3. class="upload-paper-answer-dialog"
  4. :visible.sync="modalIsShow"
  5. title="上传试卷结构文档/标答PDF文档"
  6. top="10vh"
  7. width="740px"
  8. :close-on-click-modal="false"
  9. :close-on-press-escape="false"
  10. append-to-body
  11. destroy-on-close
  12. @open="visibleChange"
  13. >
  14. <el-form ref="modalFormComp" :model="infos" label-width="130px">
  15. <div v-for="paperType in paperTypes" :key="paperType" class="part-box">
  16. <h3 class="mb-2">卷型{{ paperType }}</h3>
  17. <el-form-item
  18. v-for="(val, key) in fileTypes"
  19. :key="key"
  20. :prop="`${paperType}.${key}`"
  21. :label="`${val.name}:`"
  22. >
  23. <select-file
  24. :format="val.format"
  25. :disabled="isSubmit"
  26. @file-change="data => fileChange(paperType, key, data)"
  27. ></select-file>
  28. <el-button
  29. v-if="val.downloadUrl"
  30. type="success"
  31. icon="el-icon-download"
  32. >
  33. <a :href="val.downloadUrl" :download="val.downloadName">模板下载</a>
  34. </el-button>
  35. </el-form-item>
  36. </div>
  37. </el-form>
  38. <div slot="footer">
  39. <el-button type="primary" :disabled="isSubmit" @click="submit"
  40. >确认</el-button
  41. >
  42. <el-button @click="cancel">取消</el-button>
  43. </div>
  44. </el-dialog>
  45. </template>
  46. <script>
  47. import { examStructureUpload } from "../api";
  48. import SelectFile from "./SelectFile.vue";
  49. export default {
  50. name: "upload-paper-answer-dialog",
  51. components: { SelectFile },
  52. props: {
  53. instance: {
  54. type: Object,
  55. default() {
  56. return {};
  57. }
  58. }
  59. },
  60. data() {
  61. return {
  62. modalIsShow: false,
  63. isSubmit: false,
  64. infos: {},
  65. paperTypes: [],
  66. fileTypes: {
  67. objectiveQuestion: {
  68. name: "客观题试卷结构",
  69. downloadUrl: "/temps/objectiveQuestionTemplate.xlsx",
  70. downloadName: "客观题导入模板.xlsx",
  71. format: ["xlsx", "xls"]
  72. },
  73. subjectiveQuestion: {
  74. name: "主观题试卷结构",
  75. downloadUrl: "/temps/subjectiveQuestionTemplate.xlsx",
  76. downloadName: "主观题导入模板.xlsx",
  77. format: ["xlsx", "xls"]
  78. },
  79. standardAnswer: {
  80. name: "标答",
  81. format: ["pdf"]
  82. }
  83. },
  84. fileTypeSerial: [
  85. "objectiveQuestion",
  86. "subjectiveQuestion",
  87. "standardAnswer"
  88. ]
  89. };
  90. },
  91. methods: {
  92. initData() {
  93. this.paperTypes = this.instance.paperType.split(",");
  94. let infos = {};
  95. this.paperTypes.forEach(paperType => {
  96. let item = {};
  97. Object.keys(this.fileTypes).map(typeKey => {
  98. item[typeKey] = {
  99. file: null,
  100. md5: null,
  101. errorMsg: null
  102. };
  103. });
  104. infos[paperType] = item;
  105. });
  106. this.infos = infos;
  107. },
  108. visibleChange() {
  109. this.initData();
  110. },
  111. cancel() {
  112. this.modalIsShow = false;
  113. },
  114. open() {
  115. this.modalIsShow = true;
  116. },
  117. fileChange(paperType, typeKey, data) {
  118. if (data.errorMsg) {
  119. this.infos[paperType][typeKey].file = null;
  120. this.infos[paperType][typeKey].md5 = null;
  121. this.infos[paperType][typeKey].errorMsg = data.errorMsg;
  122. } else {
  123. this.infos[paperType][typeKey].file = data.file;
  124. this.infos[paperType][typeKey].md5 = data.md5;
  125. this.infos[paperType][typeKey].errorMsg = null;
  126. }
  127. // this.$refs.modalFormComp.validateField(`${paperType}.${typeKey}`);
  128. },
  129. fileValidator(rule, value, callback) {
  130. // const [paperType, typeKey] = rule.field.split(".");
  131. // const val = this.infos[paperType][typeKey];
  132. // if (val.errorMsg) {
  133. // return callback(new Error(val.errorMsg));
  134. // } else {
  135. // if (!val.file) {
  136. // return callback(new Error("请选择文件"));
  137. // }
  138. // }
  139. const [paperType] = rule.field.split(".");
  140. const paperTypeVals = this.infos[paperType];
  141. const kvs = Object.vals(paperTypeVals);
  142. const valid = kvs.some(val => !!val.file);
  143. if (!valid) {
  144. return callback(new Error(`卷型${paperType}至少要上传一种文件`));
  145. }
  146. callback();
  147. },
  148. async submit() {
  149. const valid = await this.$refs.modalFormComp.validate().catch(() => {});
  150. if (!valid) return;
  151. if (this.isSubmit) return;
  152. this.isSubmit = true;
  153. let formData = new FormData();
  154. formData.append("examPaperStructure", JSON.stringify(this.instance));
  155. let md5s = [];
  156. let keys = [];
  157. Object.entries(this.infos).forEach(([paperType, vals]) => {
  158. this.fileTypeSerial.forEach(typeKey => {
  159. if (!vals[typeKey].file) return;
  160. formData.append(`files`, vals[typeKey].file);
  161. md5s.push(vals[typeKey].md5);
  162. keys.push(`${paperType}-${typeKey}`);
  163. });
  164. });
  165. formData.append(`md5`, md5s.join());
  166. formData.append(`keys`, keys.join());
  167. // Object.entries(this.infos).forEach(([paperType, vals], index) => {
  168. // const indexName = `files[${index}]`;
  169. // formData.append(`${indexName}.paperType`, paperType);
  170. // this.fileTypeSerial.forEach(typeKey => {
  171. // formData.append(`${indexName}.${typeKey}File`, vals[typeKey].file);
  172. // formData.append(`${indexName}.${typeKey}Md5`, vals[typeKey].md5);
  173. // });
  174. // });
  175. const data = await examStructureUpload(formData).catch(() => {});
  176. this.isSubmit = false;
  177. if (!data) return;
  178. this.$message.success("上传成功!");
  179. this.$emit("modified");
  180. this.cancel();
  181. }
  182. }
  183. };
  184. </script>