ModifyMarkParams.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <template>
  2. <el-dialog
  3. class="modify-mark-params"
  4. :visible.sync="modalIsShow"
  5. top="0"
  6. :close-on-click-modal="false"
  7. :close-on-press-escape="false"
  8. append-to-body
  9. fullscreen
  10. :before-close="beforeClose"
  11. @open="initData"
  12. >
  13. <div slot="title">
  14. <h2 class="el-dialog__title">评卷参数设置</h2>
  15. <span
  16. >课程名称:{{ instance.courseName }}({{ instance.courseCode }})</span
  17. >
  18. </div>
  19. <div class="mb-4 tab-btns">
  20. <el-button
  21. v-for="tab in tabs"
  22. :key="tab.val"
  23. size="medium"
  24. :type="curTab == tab.val ? 'primary' : 'default'"
  25. @click="selectMenu(tab.val)"
  26. >{{ tab.name }}
  27. </el-button>
  28. </div>
  29. <div v-if="dataReady">
  30. <component
  31. :is="currentComponent"
  32. def="MarkParamRef"
  33. @cancel="cancel"
  34. @confirm="confirm"
  35. ></component>
  36. </div>
  37. <div slot="footer"></div>
  38. </el-dialog>
  39. </template>
  40. <script>
  41. import { mapMutations } from "vuex";
  42. import MarkParamStructure from "./MarkParamStructure.vue";
  43. import MarkParamMarker from "./MarkParamMarker.vue";
  44. import MarkParamMarkerLeader from "./MarkParamMarkerLeader.vue";
  45. import MarkParamObjectiveAnswer from "./MarkParamObjectiveAnswer.vue";
  46. import MarkParamUploadAnswer from "./MarkParamUploadAnswer.vue";
  47. import { cardDetail } from "../../../card/api";
  48. import { examStructureStatus } from "../../api";
  49. export default {
  50. name: "modify-mark-params",
  51. components: {
  52. MarkParamStructure,
  53. MarkParamMarker,
  54. MarkParamMarkerLeader,
  55. MarkParamObjectiveAnswer,
  56. MarkParamUploadAnswer,
  57. },
  58. props: {
  59. instance: {
  60. type: Object,
  61. default() {
  62. return {};
  63. },
  64. },
  65. },
  66. data() {
  67. return {
  68. modalIsShow: false,
  69. dataReady: false,
  70. // step
  71. curTab: "structure",
  72. tabs: [
  73. {
  74. name: "评卷参数设置",
  75. val: "structure",
  76. },
  77. {
  78. name: "科组长设置",
  79. val: "marker-leader",
  80. },
  81. {
  82. name: "评卷员管理",
  83. val: "marker",
  84. },
  85. {
  86. name: "客观题标答设置",
  87. val: "objective-answer",
  88. },
  89. {
  90. name: "主观题标答设置",
  91. val: "upload-answer",
  92. },
  93. ],
  94. current: 0,
  95. };
  96. },
  97. computed: {
  98. currentComponent() {
  99. return `mark-param-${this.curTab}`;
  100. },
  101. isFirstStep() {
  102. return this.current === 0;
  103. },
  104. isLastStep() {
  105. return this.current === this.lastStep;
  106. },
  107. lastStep() {
  108. return this.tabs.length - 1;
  109. },
  110. },
  111. watch: {
  112. curTab() {
  113. this.updateMarkStatus();
  114. },
  115. },
  116. methods: {
  117. ...mapMutations("markParam", [
  118. "setMarkParamInfos",
  119. "setObjectiveStructure",
  120. "setMarkStatus",
  121. "setMarkLeader",
  122. "initStore",
  123. ]),
  124. async initData() {
  125. this.initStore();
  126. if (this.instance.paperInfoJson) {
  127. const { paperStructureInfo, groupInfo, classInfo, structureCanEdit } =
  128. JSON.parse(this.instance.paperInfoJson);
  129. const infos = {
  130. structureCanEdit,
  131. paperStructureInfo: [
  132. ...paperStructureInfo.objectiveQuestionList,
  133. ...paperStructureInfo.subjectiveQuestionList,
  134. ],
  135. groupInfo: groupInfo || [],
  136. classInfo: classInfo || [],
  137. basicPaperInfo: this.instance,
  138. };
  139. this.setMarkParamInfos(infos);
  140. } else {
  141. const detData = await cardDetail(this.instance.cardId);
  142. const cardContent = JSON.parse(detData.content);
  143. let infos = {};
  144. if (
  145. (detData.type === "GENERIC" && detData.createMethod === "STANDARD") ||
  146. detData.type === "CUSTOM"
  147. ) {
  148. infos.structureCanEdit = false;
  149. infos.paperStructureInfo = this.parsePaperStructureFromCard(
  150. cardContent.pages
  151. );
  152. }
  153. this.setMarkParamInfos(infos);
  154. }
  155. if (this.instance.status) {
  156. const data = JSON.parse(this.instance.status);
  157. this.setMarkStatus(data);
  158. }
  159. if (this.instance.markLeader) {
  160. const data = JSON.parse(this.instance.markLeader);
  161. this.setMarkLeader(data);
  162. }
  163. const objectiveStructure = JSON.parse(
  164. this.instance.objectiveStructure || "[]"
  165. );
  166. this.setObjectiveStructure(objectiveStructure);
  167. this.dataReady = true;
  168. },
  169. async updateMarkStatus() {
  170. const res = await examStructureStatus(this.instance.id).catch(() => {});
  171. if (!res) return;
  172. const data = JSON.parse(res);
  173. this.setMarkStatus(data);
  174. },
  175. parsePaperStructureFromCard(pages) {
  176. let structData = [];
  177. let curTopicId = 0;
  178. pages.forEach((page) => {
  179. page.columns.forEach((column) => {
  180. column.elements.forEach((topic) => {
  181. if (!topic.parent) return;
  182. if (curTopicId === topic.parent.id) return;
  183. curTopicId = topic.parent.id;
  184. let questionsCount = 1,
  185. startNumber = 1;
  186. if (topic.type === "COMPOSITION") {
  187. // 相同大题号的作文题合并处理
  188. const compositionData = structData.find(
  189. (struct) =>
  190. struct.cardTopicType === "COMPOSITION" &&
  191. struct.mainNumber === topic.parent.topicNo * 1
  192. );
  193. if (compositionData) return;
  194. } else {
  195. questionsCount = topic.parent.questionsCount;
  196. startNumber = topic.parent.startNumber || 1;
  197. }
  198. const typeInfo = this.getQuestionType(topic);
  199. if (!typeInfo) return;
  200. let data = {
  201. mainNumber: topic.parent.topicNo * 1,
  202. mainTitle: topic.parent.topicName,
  203. questionsCount,
  204. startNumber,
  205. cardTopicType: topic.type,
  206. ...typeInfo,
  207. };
  208. if (topic.type === "FILL_QUESTION") {
  209. data.optionCount = topic.optionCount;
  210. }
  211. structData.push(data);
  212. });
  213. });
  214. });
  215. // console.log(structData);
  216. let structure = [];
  217. let mainIds = {};
  218. structData.forEach((struct) => {
  219. const { startNumber, questionsCount, qType, mainNumber, mainTitle } =
  220. struct;
  221. if (!mainIds[mainNumber]) {
  222. mainIds[mainNumber] = this.$randomCode();
  223. }
  224. for (let i = 0; i < questionsCount; i++) {
  225. structure.push({
  226. id: this.$randomCode(),
  227. qType,
  228. mainId: mainIds[mainNumber],
  229. mainTitle,
  230. mainNumber,
  231. subNumber: startNumber + i,
  232. type: struct.type,
  233. typeName: struct.typeName,
  234. optionCount: struct.optionCount || null,
  235. totalScore: undefined,
  236. mainFirstSub: false,
  237. expandSub: true,
  238. });
  239. }
  240. });
  241. structure.sort(
  242. (a, b) => a.mainNumber - b.mainNumber || a.subNumber - b.subNumber
  243. );
  244. let curMainId = null;
  245. structure.forEach((item) => {
  246. if (curMainId !== item.mainId) {
  247. curMainId = item.mainId;
  248. item.mainFirstSub = true;
  249. }
  250. });
  251. return structure;
  252. },
  253. selectMenu(val) {
  254. this.curTab = val;
  255. this.current = this.tabs.findIndex((item) => item.val === val);
  256. },
  257. async cancel() {
  258. const res = await this.$confirm("确定要退出阅卷参数编辑吗?", "提示", {
  259. type: "warning",
  260. }).catch(() => {});
  261. if (res !== "confirm") return;
  262. this.modalIsShow = false;
  263. },
  264. open() {
  265. this.modalIsShow = true;
  266. },
  267. async beforeClose(done) {
  268. const res = await this.$confirm("确定要退出阅卷参数编辑吗?", "提示", {
  269. type: "warning",
  270. }).catch(() => {});
  271. if (res !== "confirm") return;
  272. this.dataReady = false;
  273. done();
  274. },
  275. confirm() {
  276. if (this.isLastStep) return;
  277. this.selectMenu(this.tabs[this.current + 1].val);
  278. },
  279. },
  280. };
  281. </script>