MarkParamStructure.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. <template>
  2. <div class="mark-param-structure">
  3. <div class="part-box part-box-pad box-justify">
  4. <el-breadcrumb separator="|">
  5. <el-breadcrumb-item
  6. >本试卷大题:{{ paperStat.mainQuestionCount }}道</el-breadcrumb-item
  7. >
  8. <el-breadcrumb-item
  9. >小题:{{ paperStat.questionCount }}道</el-breadcrumb-item
  10. >
  11. <el-breadcrumb-item
  12. >客观题:{{ paperStat.objectiveQuestionCount }}道</el-breadcrumb-item
  13. >
  14. <el-breadcrumb-item
  15. >主观题:{{ paperStat.subjectiveQuestionCount }}道</el-breadcrumb-item
  16. >
  17. <el-breadcrumb-item
  18. >总分:<span class="color-danger mlr-1">{{
  19. paperStat.paperTotalScore
  20. }}</span>
  21. </el-breadcrumb-item>
  22. </el-breadcrumb>
  23. <div>
  24. <el-button type="primary" @click="toNext(1)">下一步</el-button>
  25. </div>
  26. </div>
  27. <div class="part-box part-box-pad structure-body">
  28. <div class="box-justify mb-2">
  29. <div>
  30. <el-button v-if="editOpen" type="primary" @click="toAddMain"
  31. >新增大题</el-button
  32. >
  33. </div>
  34. <div v-if="checkPrivilege('link', 'EditPaperStruct', 'MarkSetting')">
  35. <el-switch v-model="editOpen" active-text="开启编辑"></el-switch>
  36. </div>
  37. </div>
  38. <el-table
  39. ref="TableList"
  40. :data="tableData"
  41. border
  42. :row-class-name="getRowClassName"
  43. :key="tableKey"
  44. :height="tableHeight"
  45. >
  46. <el-table-column width="50" align="center">
  47. <template slot-scope="scope" v-if="scope.row.mainFirstSub">
  48. <div
  49. :class="[
  50. 'expand-btn',
  51. { 'expand-btn-unexpand': !scope.row.expandSub },
  52. ]"
  53. @click="switchExpandSub(scope.row)"
  54. >
  55. <i
  56. :class="scope.row.expandSub ? 'el-icon-minus' : 'el-icon-plus'"
  57. ></i>
  58. </div>
  59. </template>
  60. </el-table-column>
  61. <template v-if="editOpen">
  62. <el-table-column prop="mainTitle" label="大题名称">
  63. <span slot-scope="scope" v-if="scope.row.mainFirstSub">
  64. <el-input
  65. v-model.trim="scope.row.mainTitle"
  66. size="small"
  67. :maxlength="32"
  68. clearable
  69. @change="mainTitleChange(scope.row)"
  70. ></el-input>
  71. </span>
  72. </el-table-column>
  73. <el-table-column prop="questionType" label="题型" width="120">
  74. <template slot-scope="scope" v-if="scope.row.mainFirstSub">
  75. <el-select
  76. v-model="scope.row.questionType"
  77. placeholder="请选择"
  78. class="width-full"
  79. :disabled="checkMainQuestionHasMarker(scope.row.mainId)"
  80. @visible-change="(val) => qTypeVisibleChange(val, scope.row)"
  81. @change="qTypeChange(scope.row)"
  82. >
  83. <el-option
  84. v-for="item in QUESTION_TYPE_LIST"
  85. :key="item.code"
  86. :value="item.code"
  87. :label="item.name"
  88. >
  89. </el-option>
  90. </el-select>
  91. </template>
  92. </el-table-column>
  93. <el-table-column label="选项个数" width="100">
  94. <template
  95. slot-scope="scope"
  96. v-if="scope.row.questionType <= 2 && scope.row.mainFirstSub"
  97. >
  98. <el-input-number
  99. v-model="scope.row.optionCount"
  100. class="width-full"
  101. size="small"
  102. :min="2"
  103. :max="26"
  104. :step="1"
  105. step-strictly
  106. :controls="false"
  107. @change="optionCountChange(scope.row)"
  108. ></el-input-number>
  109. </template>
  110. </el-table-column>
  111. </template>
  112. <template v-else>
  113. <el-table-column prop="mainTitle" label="大题名称">
  114. <span slot-scope="scope" v-if="scope.row.mainFirstSub">
  115. {{ scope.row.mainTitle }}
  116. </span>
  117. </el-table-column>
  118. <el-table-column label="题型" width="120">
  119. <template slot-scope="scope" v-if="scope.row.mainFirstSub">
  120. {{ questionTypeDict[scope.row.questionType] }}
  121. </template>
  122. </el-table-column>
  123. </template>
  124. <el-table-column prop="mainNumber" label="大题号" width="80">
  125. <template slot-scope="scope" v-if="scope.row.mainFirstSub">
  126. <span>{{ scope.row.mainNumber }}</span>
  127. </template>
  128. </el-table-column>
  129. <el-table-column
  130. prop="subNumber"
  131. label="小题号"
  132. width="80"
  133. ></el-table-column>
  134. <el-table-column label="每题分值" width="120">
  135. <template slot="header">
  136. <span>每题分值</span>
  137. <el-tooltip effect="dark" placement="top">
  138. <div slot="content" class="tooltip-area">
  139. <p>每题分值,属于批量设置</p>
  140. <p>
  141. 输入每题分值后,比如2按回车键或鼠标点击输入框外其他地方,系统会自动设置该大题下每个小题的分值为2。
  142. </p>
  143. </div>
  144. <i class="el-icon-info ml-1 tooltip-info-icon"></i>
  145. </el-tooltip>
  146. </template>
  147. <template slot-scope="scope" v-if="scope.row.mainFirstSub">
  148. <el-input-number
  149. v-model="scoresPerTopic[scope.row.mainId]"
  150. class="width-full"
  151. size="small"
  152. :min="0"
  153. :max="500"
  154. :step="0.1"
  155. step-strictly
  156. :controls="false"
  157. placeholder="每题分值"
  158. @change="(val) => scorePerTopicChange(val, scope.row)"
  159. ></el-input-number>
  160. </template>
  161. </el-table-column>
  162. <el-table-column prop="totalScore" label="小题满分" width="120">
  163. <template slot-scope="scope">
  164. <el-input-number
  165. v-model="scope.row.totalScore"
  166. class="width-full"
  167. size="small"
  168. :min="0"
  169. :max="500"
  170. :step="0.1"
  171. step-strictly
  172. :controls="false"
  173. placeholder="小题分值"
  174. @change="totalScoreChange(scope.row)"
  175. ></el-input-number>
  176. </template>
  177. </el-table-column>
  178. <el-table-column label="每题最小分" width="120">
  179. <template
  180. slot-scope="scope"
  181. v-if="scope.row.mainFirstSub && !scope.row.objective"
  182. >
  183. <el-input-number
  184. v-model="intervalScorePerTopic[scope.row.mainId]"
  185. class="width-full"
  186. size="small"
  187. :min="0.1"
  188. :max="500"
  189. :step="0.1"
  190. step-strictly
  191. :controls="false"
  192. placeholder="每题最小分"
  193. @change="(val) => intervalScorePerTopicChange(val, scope.row)"
  194. ></el-input-number>
  195. </template>
  196. </el-table-column>
  197. <el-table-column prop="intervalScore" label="最小分" width="120">
  198. <template slot="header">
  199. <span>最小分</span>
  200. <el-tooltip effect="dark" placement="top">
  201. <div slot="content" class="tooltip-area">
  202. <p>最小分是评卷中每题最小给分间隔,详见样例。</p>
  203. <p>
  204. 如小题总分为5分的题目,最小分设置为1,则可以给0,1,2,3,4,5分。
  205. </p>
  206. <p>
  207. 如最小分设置为0.5分,则可以给0.5,1,1.5,2,2.5,3,3.5,4,4.5,5分。
  208. </p>
  209. <p>如果最小分设置为5分,则只能给0分和5分。</p>
  210. <p>每题最小分是只用设置1次,系统会自动设置每个小题的最小分</p>
  211. </div>
  212. <i class="el-icon-info ml-1 tooltip-info-icon"></i>
  213. </el-tooltip>
  214. </template>
  215. <template slot-scope="scope" v-if="!scope.row.objective">
  216. <el-input-number
  217. v-model="scope.row.intervalScore"
  218. class="width-full"
  219. size="small"
  220. :min="0.1"
  221. :max="scope.row.totalScore"
  222. :step="0.1"
  223. step-strictly
  224. :controls="false"
  225. placeholder="最小分"
  226. ></el-input-number>
  227. </template>
  228. </el-table-column>
  229. <el-table-column
  230. v-if="editOpen"
  231. class-name="action-column"
  232. label="操作"
  233. width="140px"
  234. >
  235. <template slot-scope="scope">
  236. <el-button
  237. class="btn-primary"
  238. type="text"
  239. @click="toAddSub(scope.row)"
  240. >新增小题</el-button
  241. >
  242. <el-button
  243. :disabled="
  244. tableData.length <= 1 || checkSubQuestionHasMarker(scope.row)
  245. "
  246. class="btn-danger"
  247. type="text"
  248. @click="toDeleteSub(scope.row)"
  249. >删除</el-button
  250. >
  251. </template>
  252. </el-table-column>
  253. </el-table>
  254. <!-- tips -->
  255. <div class="mt-2">
  256. <p class="tips-info">
  257. 1.请确认展示的试卷结构与提交的试卷、答题卡是否一致?
  258. </p>
  259. <p class="tips-info">
  260. 2.请补充所有题目的小题分值,并确认试卷总分。主观题设置间隔分,间隔分的具体说明见列表帮助提示。
  261. </p>
  262. <p class="tips-info tips-error">
  263. 3.开始阅卷后不允许修改试卷结构,请确认清楚后再提交!
  264. </p>
  265. </div>
  266. </div>
  267. </div>
  268. </template>
  269. <script>
  270. import { calcSum, maxNum, toPrecision } from "@/plugins/utils";
  271. import { QUESTION_TYPE_LIST } from "@/constants/enumerate";
  272. import { mapState, mapMutations } from "vuex";
  273. import { markStructureSave } from "../../api";
  274. import { omit } from "lodash";
  275. import { MD5 } from "@/plugins/md5";
  276. export default {
  277. name: "mark-paper-structure",
  278. data() {
  279. return {
  280. tableData: [],
  281. curRow: {},
  282. cacheDataMd5: "",
  283. QUESTION_TYPE_LIST,
  284. questionTypeDict: {},
  285. scoresPerTopic: {},
  286. intervalScorePerTopic: {},
  287. loading: false,
  288. editOpen: false,
  289. tableKey: "",
  290. hasMarkerQuestions: [],
  291. tableHeight: 200,
  292. };
  293. },
  294. computed: {
  295. ...mapState("markParam", [
  296. "basicInfo",
  297. "paperStructureInfo",
  298. "subjectiveTaskList",
  299. ]),
  300. paperStat() {
  301. const questionCount = this.tableData.length;
  302. const mainQuestionCount = this.tableData.filter(
  303. (item) => item.mainFirstSub
  304. ).length;
  305. const subjectiveQuestionCount = this.tableData.filter(
  306. (item) => !item.objective
  307. ).length;
  308. const paperTotalScore = toPrecision(
  309. calcSum(this.tableData.map((item) => item.totalScore || 0)),
  310. 1
  311. );
  312. return {
  313. questionCount,
  314. mainQuestionCount,
  315. paperTotalScore,
  316. subjectiveQuestionCount,
  317. objectiveQuestionCount: questionCount - subjectiveQuestionCount,
  318. };
  319. },
  320. },
  321. watch: {
  322. editOpen() {
  323. this.tableKey = this.$randomCode();
  324. this.updateTableHeight();
  325. },
  326. },
  327. mounted() {
  328. this.initData();
  329. this.registResize();
  330. },
  331. methods: {
  332. ...mapMutations("markParam", ["setPaperStructureInfo"]),
  333. initData() {
  334. this.tableKey = this.$randomCode();
  335. this.hasMarkerQuestions = this.subjectiveTaskList
  336. .filter((item) => item.markers.length)
  337. .map((item) => `${item.mainNumber}-${item.subNumber}`);
  338. let questionTypeDict = {};
  339. QUESTION_TYPE_LIST.forEach((item) => {
  340. questionTypeDict[item.code] = item.name;
  341. });
  342. this.questionTypeDict = questionTypeDict;
  343. let curMainNumber = null;
  344. let curMainId = null;
  345. let scoresPerTopic = {},
  346. intervalScorePerTopic = {};
  347. this.tableData = this.paperStructureInfo.map((item) => {
  348. let nitem = {
  349. ...item,
  350. key: this.$randomCode(),
  351. mainFirstSub: false,
  352. expandSub: true,
  353. };
  354. if (curMainNumber !== item.mainNumber) {
  355. curMainNumber = item.mainNumber;
  356. curMainId = this.$randomCode();
  357. scoresPerTopic[curMainNumber] = undefined;
  358. intervalScorePerTopic[curMainNumber] = undefined;
  359. nitem.mainFirstSub = true;
  360. }
  361. nitem.totalScore =
  362. nitem.totalScore || nitem.totalScore === 0
  363. ? nitem.totalScore
  364. : undefined;
  365. nitem.intervalScore = nitem.intervalScore || undefined;
  366. nitem.mainId = curMainId;
  367. return nitem;
  368. });
  369. this.scoresPerTopic = scoresPerTopic;
  370. this.intervalScorePerTopic = intervalScorePerTopic;
  371. if (!this.tableData.length && this.editOpen) {
  372. this.createMain();
  373. }
  374. this.cacheDataMd5 = this.getSubmitDataMd5();
  375. this.updateTableHeight();
  376. },
  377. getSubmitDataMd5() {
  378. return MD5(JSON.stringify(this.getData()));
  379. },
  380. getNewRow(val) {
  381. return this.$objAssign(
  382. {
  383. id: null,
  384. key: this.$randomCode(),
  385. mainId: this.$randomCode(),
  386. objective: true,
  387. mainNumber: 1,
  388. subNumber: 1,
  389. mainTitle: "",
  390. answer: "",
  391. totalScore: undefined,
  392. intervalScore: undefined,
  393. objectivePolicy: null,
  394. questionType: null,
  395. optionCount: undefined,
  396. mainFirstSub: true,
  397. expandSub: true,
  398. },
  399. val
  400. );
  401. },
  402. createMain() {
  403. this.tableData.push(this.getNewRow({}));
  404. },
  405. getRowClassName({ row }) {
  406. let classNames = [];
  407. if (row.mainFirstSub) {
  408. classNames.push("row-main-first-sub");
  409. }
  410. if (!row.mainFirstSub && !row.expandSub) {
  411. classNames.push("row-unexpand-sub");
  412. }
  413. return classNames.join(" ");
  414. },
  415. getNextMainStartPos(startPos, curMainId) {
  416. let nextMainStartPos = null;
  417. for (let i = startPos, len = this.tableData.length; i < len; i++) {
  418. const element = this.tableData[i];
  419. if (element.mainId !== curMainId) {
  420. nextMainStartPos = i;
  421. return nextMainStartPos;
  422. }
  423. }
  424. if (nextMainStartPos === null) return this.tableData.length;
  425. },
  426. getNewMainNumber() {
  427. return maxNum(this.tableData.map((item) => item.mainNumber)) + 1;
  428. },
  429. toAddMain() {
  430. const newMainData = this.getNewRow({
  431. mainId: this.$randomCode(),
  432. mainNumber: this.getNewMainNumber(),
  433. totalScore: undefined,
  434. questionType: null,
  435. objective: true,
  436. });
  437. this.tableData.push(newMainData);
  438. this.$set(this.intervalScorePerTopic, newMainData.mainId, undefined);
  439. },
  440. updateMainData() {
  441. let curMainNumber = 0,
  442. curMainId = null;
  443. this.tableData.forEach((item) => {
  444. if (item.mainId !== curMainId) {
  445. curMainId = item.mainId;
  446. curMainNumber++;
  447. }
  448. item.mainNumber = curMainNumber;
  449. });
  450. },
  451. toAddSub(row) {
  452. const subPos = this.tableData.findIndex((item) => item.key === row.key);
  453. this.tableData.splice(
  454. subPos + 1,
  455. 0,
  456. this.getNewRow({
  457. ...row,
  458. mainFirstSub: false,
  459. answer: "",
  460. key: this.$randomCode(),
  461. })
  462. );
  463. this.updateSubData(row.mainId);
  464. },
  465. updateSubData(mainId) {
  466. this.tableData
  467. .filter((item) => item.mainId === mainId)
  468. .forEach((item, index) => {
  469. item.subNumber = index + 1;
  470. });
  471. },
  472. async toDeleteSub(row) {
  473. if (!row.objective && this.checkSubQuestionHasMarker(row)) {
  474. this.$message.error("当前小题已设置评卷员,不可删除!");
  475. return;
  476. }
  477. const confirm = await this.$confirm(`确定要删除小题吗?`, "提示", {
  478. type: "warning",
  479. }).catch(() => {});
  480. if (confirm !== "confirm") return;
  481. const subPos = this.tableData.findIndex((item) => item.key === row.key);
  482. this.tableData.splice(subPos, 1);
  483. this.tableData
  484. .filter((item) => item.mainId === row.mainId)
  485. .forEach((item, index) => {
  486. item.mainFirstSub = !index;
  487. });
  488. this.updateSubData(row.mainId);
  489. },
  490. switchExpandSub(row) {
  491. row.expandSub = !row.expandSub;
  492. this.tableData
  493. .filter((item) => item.mainId === row.mainId && !item.mainFirstSub)
  494. .forEach((item) => (item.expandSub = row.expandSub));
  495. },
  496. mainTitleChange(row) {
  497. this.tableData
  498. .filter((item) => item.mainId === row.mainId && !item.mainFirstSub)
  499. .forEach((item) => (item.mainTitle = row.mainTitle));
  500. },
  501. qTypeVisibleChange(val, row) {
  502. if (!val) return;
  503. this.curRow = { ...row };
  504. },
  505. checkMainQuestionHasMarker(mainId) {
  506. return this.tableData
  507. .filter((item) => item.mainId === mainId)
  508. .some((item) => this.checkSubQuestionHasMarker(item));
  509. },
  510. checkSubQuestionHasMarker(item) {
  511. return this.hasMarkerQuestions.includes(
  512. `${item.mainNumber}-${item.subNumber}`
  513. );
  514. },
  515. async qTypeChange(row) {
  516. if (row.objective) {
  517. const confirm = await this.$confirm(`确定要更改题型吗?`, "提示", {
  518. type: "warning",
  519. }).catch(() => {});
  520. if (confirm !== "confirm") {
  521. row.questionType = this.curRow.questionType;
  522. return;
  523. }
  524. } else {
  525. if (this.checkMainQuestionHasMarker(row.mainId)) {
  526. row.questionType = this.curRow.questionType;
  527. this.$message.error("当前大题已设置评卷员,不可更改");
  528. return;
  529. }
  530. }
  531. const curQt = this.QUESTION_TYPE_LIST.find(
  532. (item) => item.code === row.questionType
  533. );
  534. if (!curQt) return;
  535. this.tableData
  536. .filter((item) => item.mainId === row.mainId)
  537. .forEach((item) => {
  538. item.questionType = curQt.code;
  539. item.objective = curQt.qType === "objective";
  540. item.optionCount = curQt.optionCount;
  541. if (item.objective) {
  542. item.intervalScore = undefined;
  543. this.intervalScorePerTopic[row.mainId] = undefined;
  544. }
  545. });
  546. },
  547. optionCountChange(row) {
  548. if (!row.optionCount) return;
  549. this.tableData
  550. .filter((item) => item.mainId === row.mainId && !item.mainFirstSub)
  551. .forEach((item) => {
  552. item.optionCount = row.optionCount;
  553. });
  554. },
  555. scorePerTopicChange(val, row) {
  556. if (!val && val !== 0) return;
  557. this.tableData
  558. .filter((item) => item.mainId === row.mainId)
  559. .forEach((item) => {
  560. item.totalScore = val;
  561. item.intervalScore = Math.min(item.totalScore, item.intervalScore);
  562. });
  563. },
  564. intervalScorePerTopicChange(val, row) {
  565. if (!val) return;
  566. this.tableData
  567. .filter((item) => item.mainId === row.mainId)
  568. .forEach((item) => {
  569. item.intervalScore = Math.min(item.totalScore, val);
  570. });
  571. },
  572. totalScoreChange(row) {
  573. const isInit = (num) => !(num % 1);
  574. if (!row.intervalScore) {
  575. row.intervalScore = isInit(row.totalScore) ? 1 : 0.5;
  576. return;
  577. }
  578. if (
  579. (isInit(row.totalScore) && !isInit(row.intervalScore)) ||
  580. (!isInit(row.totalScore) && isInit(row.intervalScore))
  581. ) {
  582. row.intervalScore = isInit(row.totalScore) ? 1 : 0.5;
  583. return;
  584. }
  585. row.intervalScore = Math.min(row.totalScore, row.intervalScore);
  586. },
  587. checkData() {
  588. let errorMessages = [];
  589. this.tableData.forEach((item) => {
  590. let errorMsg = ``;
  591. if (item.mainFirstSub) {
  592. let errorFields = [];
  593. if (!item.mainTitle) {
  594. errorFields.push("大题名称");
  595. }
  596. if (!item.questionType) {
  597. errorFields.push("题型");
  598. }
  599. if (!item.mainNumber) {
  600. errorFields.push("大题号");
  601. }
  602. if (!item.optionCount && item.questionType <= 2) {
  603. errorFields.push("选项个数");
  604. }
  605. if (errorFields.length) {
  606. errorMsg += `${errorFields.join("、")}不能为空,`;
  607. }
  608. }
  609. let errorFields = [];
  610. if (!item.subNumber) {
  611. errorFields.push("小题号");
  612. }
  613. if (!item.totalScore && item.totalScore !== 0) {
  614. errorFields.push("小题满分");
  615. }
  616. if (!item.intervalScore && !item.objective) {
  617. errorFields.push("评卷最小分");
  618. }
  619. if (errorFields.length) {
  620. errorMsg += `第${item.subNumber}小题,${errorFields.join(
  621. "、"
  622. )}不能为空,`;
  623. }
  624. if (errorMsg) {
  625. errorMsg = `第${item.mainNumber}大题,${errorMsg}`;
  626. errorMessages.push(errorMsg);
  627. }
  628. });
  629. if (errorMessages.length) {
  630. this.$message.error(errorMessages.join("。"));
  631. return;
  632. }
  633. return true;
  634. },
  635. getData() {
  636. return this.tableData.map((item) => {
  637. return omit(item, ["key", "mainId", "expandSub"]);
  638. });
  639. },
  640. async submit() {
  641. if (this.loading) return;
  642. if (!this.checkData()) return;
  643. this.loading = true;
  644. const questions = this.getData();
  645. const res = await markStructureSave({
  646. examId: this.basicInfo.examId,
  647. paperNumber: this.basicInfo.paperNumber,
  648. questions,
  649. }).catch(() => {});
  650. this.loading = false;
  651. if (!res) return;
  652. this.$message.success("保存成功!");
  653. this.setPaperStructureInfo(questions);
  654. return true;
  655. },
  656. async toNext(step = 1) {
  657. if (!this.checkData()) return;
  658. // 如果试卷结构有变动,先保存
  659. if (this.cacheDataMd5 !== this.getSubmitDataMd5()) {
  660. const res = await this.submit();
  661. if (!res) return;
  662. }
  663. this.$emit("next", step);
  664. },
  665. // table height
  666. updateTableHeight() {
  667. this.$nextTick(() => {
  668. if (!this.$refs.TableList) return;
  669. const tableOffsetTop = this.$refs.TableList.$el.offsetTop;
  670. this.tableHeight = window.innerHeight - tableOffsetTop - 115;
  671. // console.log(this.tableHeight);
  672. });
  673. },
  674. registResize() {
  675. window.addEventListener("resize", this.updateTableHeight);
  676. },
  677. },
  678. beforeDestroy() {
  679. window.removeEventListener("resize", this.updateTableHeight);
  680. },
  681. };
  682. </script>