Commit 533a17d882dd30982aa461954342953c8006daa9

Authored by 梁保满
1 parent 255e2506

备题组卷添加批量设置答案

src/assets/css/index.scss
... ... @@ -104,7 +104,9 @@
104 104 .el-table thead th.el-table__cell {
105 105 background: #f5f7fa;
106 106 }
107   -
  107 +.el-table .el-table__cell.bg{
  108 + background: #f9f9f9;
  109 +}
108 110 .el-menu--popup {
109 111 min-width: 160px;
110 112 }
... ...
src/components/setAnswer.vue
... ... @@ -194,7 +194,7 @@ export default {
194 194 let types = [{}];
195 195 let addndex = 0;
196 196 this.FormQuestionList?.map((sub, index) => {
197   - if (!!sub.questionType) {
  197 + if (!!sub.questionType && sub.questionType!=5) {
198 198 if (sub.questionType == types[addndex].qusType) {
199 199 //同类型批量答案+1
200 200 types[addndex].subNum += 1;
... ... @@ -219,7 +219,7 @@ export default {
219 219 //不同类型时如果原有类型数量大于等于5,保存批量答案
220 220 types[addndex].endIndex =
221 221 this.questionList[index - 1].questionIndex;
222   - types[addndex].index = index;
  222 + types[addndex].index = index-1;
223 223 addndex += 1;
224 224 types[addndex] = {};
225 225 }
... ...
src/router/index.js
... ... @@ -246,22 +246,22 @@ let addrouters = [ //测试用,后续后端获取
246 246 },
247 247 ]
248 248 },
249   - // {
250   - // path: "/card",
251   - // iconCls: "fa fa-id-card", // 图标样式class
252   - // name: "发卡记录",
253   - // component: Layout,
254   - // alone: true,
255   - // children: [
256   - // {
257   - // path: "/card",
258   - // iconCls: "fa fa-id-card", // 图标样式class
259   - // name: "",
260   - // component: Card,
261   - // children: []
262   - // }
263   - // ]
264   - // },
  249 + {
  250 + path: "/card",
  251 + iconCls: "fa fa-id-card", // 图标样式class
  252 + name: "发卡记录",
  253 + component: Layout,
  254 + alone: true,
  255 + children: [
  256 + {
  257 + path: "/card",
  258 + iconCls: "fa fa-id-card", // 图标样式class
  259 + name: "",
  260 + component: Card,
  261 + children: []
  262 + }
  263 + ]
  264 + },
265 265 {
266 266 path: "/device",
267 267 iconCls: "fa fa-dashboard", // 图标样式class
... ...
src/views/analysis/index.vue
... ... @@ -74,14 +74,20 @@
74 74 <el-button type="primary" round @click="_QueryData">筛选</el-button>
75 75 </div>
76 76 </div>
77   - <div class="table-box">
78   - <div class="radio-box" v-if="role == 'ROLE_JITUAN'">
79   - <el-radio-group v-model="type" @change="changeType">
80   - <el-radio-button :label="1">学校使用对比</el-radio-button>
81   - <el-radio-button :label="2">学段使用对比</el-radio-button>
82   - </el-radio-group>
83   - </div>
  77 + <div class="radio-box" v-if="role == 'ROLE_JITUAN'">
  78 + <el-radio-group v-model="type" @change="changeType">
  79 + <el-radio-button :label="1">学校使用对比</el-radio-button>
  80 + <el-radio-button :label="2">学段使用对比</el-radio-button>
  81 + </el-radio-group>
  82 + </div>
  83 + <div class="table-box" v-loading="loading">
  84 + <el-empty
  85 + :image-size="100"
  86 + v-if="!tableData.length && !loading"
  87 + description="没有更多数据"
  88 + ></el-empty>
84 89 <el-table
  90 + v-else
85 91 :data="tableData"
86 92 :border="false"
87 93 style="width: 100%"
... ... @@ -114,7 +120,7 @@
114 120 </el-table-column>
115 121 </el-table>
116 122 <p class="down" v-if="role != 'ROLE_JITUAN'">
117   - <el-button @click="downExc" plain round icon="fa fa-cloud-download"
  123 + <el-button @click="downExc" type="primary" plain round icon="fa fa-cloud-download"
118 124 >导出报表</el-button
119 125 >
120 126 </p>
... ... @@ -124,10 +130,11 @@
124 130 </template>
125 131  
126 132 <script>
127   -import { formatDate,downloadFile } from "@/utils";
  133 +import { formatDate, downloadFile } from "@/utils";
128 134 export default {
129 135 data() {
130 136 return {
  137 + loading: false,
131 138 exportLoading: false,
132 139 role: "",
133 140 date: "", //今天-本周-本月-本季度
... ... @@ -315,7 +322,7 @@ export default {
315 322 dataIdsList.push(items.grade);
316 323 dataList.push(items);
317 324 }
318   - } else{
  325 + } else {
319 326 if (!dataIdsList.includes(items.classId)) {
320 327 dataIdsList.push(items.classId);
321 328 dataList.push(items);
... ... @@ -421,7 +428,7 @@ export default {
421 428 padding: 0 20px;
422 429 }
423 430 .radio-box {
424   - padding-bottom: 12px;
  431 + padding: 0 20px 12px;
425 432 }
426 433 .down {
427 434 padding-top: 20px;
... ...
src/views/ask/analysis.vue
... ... @@ -279,7 +279,7 @@
279 279 <p class="down">
280 280 <el-button
281 281 @click="exportData"
282   - type="info"
  282 + type="primary"
283 283 plain
284 284 round
285 285 icon="fa fa-cloud-download"
... ...
src/views/ask/index.vue
... ... @@ -442,7 +442,7 @@
442 442 <p class="down" v-if="tabIndex == 3 || tabIndex == 2">
443 443 <el-button
444 444 @click="exportData"
445   - type="info"
  445 + type="primary"
446 446 plain
447 447 round
448 448 icon="fa fa-cloud-download"
... ...
src/views/card/index.vue
... ... @@ -5,7 +5,12 @@
5 5 <span>发卡记录</span>
6 6 </template>
7 7 </back-box>
8   - <div class="page-content">
  8 + <el-empty
  9 + :image-size="100"
  10 + v-if="!tableData.length && !loading"
  11 + description="暂无数据"
  12 + ></el-empty>
  13 + <!-- <div class="page-content">
9 14 <div class="answer-header">
10 15 <div class="sel-box">
11 16 <el-cascader size="small"
... ... @@ -85,7 +90,7 @@
85 90 ></el-table-column>
86 91 </el-table>
87 92 </div>
88   - </div>
  93 + </div> -->
89 94 </div>
90 95 </template>
91 96  
... ... @@ -104,7 +109,7 @@ export default {
104 109 };
105 110 },
106 111 created() {
107   - this._QueryGradeList();
  112 + // this._QueryGradeList();
108 113 },
109 114 methods: {
110 115 // 查找班级
... ... @@ -168,7 +173,7 @@ export default {
168 173 </script>
169 174  
170 175 <style lang="scss" scoped>
171   -.table-box{
172   - padding:0 20px;
  176 +.table-box {
  177 + padding: 0 20px;
173 178 }
174 179 </style>
175 180 \ No newline at end of file
... ...
src/views/dataSync/index.vue
... ... @@ -7,9 +7,9 @@
7 7 </back-box>
8 8 <div class="page-content">
9 9 <div class="down-item">
10   - <p class="h-title">从U盘导入</p>
  10 + <p class="h-title">从U盘上传</p>
11 11 <p class="txt">
12   - 本功能帮助无法上网的授课端软件,将本地数据同步到云平台,需要先在数据包放到U盘
  12 + 本功能帮助无法上网的授课端软件,将本地数据同步到云平台
13 13 </p>
14 14 <el-upload
15 15 class="upload-demo"
... ... @@ -32,7 +32,7 @@
32 32 <div class="down-item">
33 33 <p class="h-title">数据导出至U盘</p>
34 34 <p class="txt">
35   - 本功能将云平台的数据导出到U盘。待导出数据包括4套答题卡。
  35 + 本功能将云平台的数据导出到U盘。包括4套答题卡。
36 36 </p>
37 37 <div class="btn-box btn-box2" v-loading="downLoading">
38 38 <i class="fa fa-cloud-download" @click="downloadFile"></i>
... ... @@ -46,7 +46,7 @@
46 46 </template>
47 47  
48 48 <script>
49   -import { downloadFile } from "@/utils";
  49 +import { formatDate } from "@/utils";
50 50 export default {
51 51 data() {
52 52 return {
... ... @@ -68,7 +68,7 @@ export default {
68 68 const url = URL.createObjectURL(blob);
69 69 const link = document.createElement("a");
70 70 document.body.appendChild(link);
71   - link.download = "文件.json";
  71 + link.download = this.$store.getters.info.name+formatDate(new Date,'yyyy_MM_dd_hh_mm_ss')+"文件.json";
72 72 link.href = url;
73 73 link.click();
74 74 document.body.removeChild(link);
... ...
src/views/device/index.vue
... ... @@ -512,7 +512,6 @@ export default {
512 512 props: {
513 513 multiple: true,
514 514 checkStrictly: true,
515   - lazy: true,
516 515 },
517 516 type: 1,
518 517 query: {
... ... @@ -572,6 +571,7 @@ export default {
572 571 });
573 572 this.role = role ? role : this.$store.getters.info.permissions[0].role;
574 573 if (this.role == "ROLE_JITUAN") {
  574 + this.props.lazy = true,
575 575 this.props.lazyLoad = function (node, resolve) {
576 576 const { level } = node;
577 577 if (level == 2) {
... ...
src/views/examinationPaper/add.vue
... ... @@ -186,8 +186,9 @@
186 186 class="number-ipt"
187 187 size="medium"
188 188 :min="1"
189   - :max="200"
  189 + :max="100"
190 190 :precision="2"
  191 + :step="1"
191 192 v-model="subQuestions.score"
192 193 label="单题分值"
193 194 ></el-input-number>
... ... @@ -311,7 +312,7 @@
311 312 :rules="questionFormRules"
312 313 label-width="100px"
313 314 >
314   - <el-form-item label="标题:" prop="questionTitle">
  315 + <el-form-item label="标题:">
315 316 <el-col :span="20">
316 317 <el-input
317 318 v-model.trim="questionForm.questionTitle"
... ... @@ -345,7 +346,7 @@
345 346 <el-form-item
346 347 label="默认选项:"
347 348 v-show="
348   - questionForm.questionType != 4 ||
  349 + questionForm.questionType != 4 &&
349 350 questionForm.questionType != 5
350 351 "
351 352 >
... ... @@ -358,22 +359,28 @@
358 359 label="label"
359 360 ></el-input-number>
360 361 </el-form-item>
361   - <el-form-item
362   - label="默认分数:"
363   - v-show="
364   - questionForm.questionType != 4 ||
365   - questionForm.questionType != 5
366   - "
367   - >
  362 + <el-form-item label="默认分数:">
368 363 <el-input-number
369 364 v-model="questionForm.score"
370 365 :min="1"
371   - :max="100"
372   - :step-strictly="true"
  366 + :precision="2"
373 367 :step="1"
374 368 label="label"
375 369 ></el-input-number>
376 370 </el-form-item>
  371 + <el-form-item
  372 + label="漏选得分:"
  373 + v-if="questionForm.questionType == 3"
  374 + >
  375 + <el-input-number
  376 + v-model="questionForm.partScore"
  377 + :min="0"
  378 + :max="questionForm.score"
  379 + :precision="2"
  380 + :step="0.5"
  381 + label="label"
  382 + ></el-input-number>
  383 + </el-form-item>
377 384 </el-form>
378 385 </div>
379 386 <div class="dialog-footer" slot="footer">
... ... @@ -402,90 +409,186 @@
402 409 <div class="qs-options qs-options2">选项设置</div>
403 410 </li>
404 411 <li
405   - class="sub-questions"
406 412 v-for="(subQuestions, indexs) in question.subQuestions"
407 413 :key="indexs"
408 414 >
409   - <div class="qs-num">{{ setNum(index, indexs) }}</div>
410   - <div class="qs-type">
411   - {{ setSubPro(subQuestions.questionType) }}
412   - </div>
413   - <div class="qs-score">
414   - <el-input-number
415   - class="number-ipt"
416   - size="medium"
417   - :min="1"
418   - :max="200"
419   - :precision="2"
420   - v-model="subQuestions.score"
421   - label="单题分值"
422   - ></el-input-number>
423   - </div>
424   - <div class="qs-partScore">
425   - <p v-if="subQuestions.questionType != 3">--</p>
426   - <el-input-number
427   - class="number-ipt"
428   - v-else
429   - size="medium"
430   - :min="0"
431   - :precision="2"
432   - :max="subQuestions.score"
433   - :step="0.5"
434   - v-model="subQuestions.partScore"
435   - label="漏选得分"
436   - ></el-input-number>
  415 + <p
  416 + class="set-ans-btn"
  417 + v-if="
  418 + subQuestions.qusType &&
  419 + subQuestions.subNum &&
  420 + subQuestions.subNum > 4
  421 + "
  422 + >
  423 + <el-button type="primary" @click="setFormAns(indexs, index)"
  424 + >批量设置答案</el-button
  425 + >
  426 + </p>
  427 + <div v-else class="sub-questions">
  428 + <div class="qs-num">
  429 + {{ setNum(index, indexs, subQuestions) }}
  430 + </div>
  431 + <div class="qs-type">
  432 + {{ setSubPro(subQuestions.questionType) }}
  433 + </div>
  434 + <div class="qs-score">
  435 + <el-input-number
  436 + class="number-ipt"
  437 + size="medium"
  438 + :min="1"
  439 + :max="200"
  440 + :precision="2"
  441 + v-model="subQuestions.score"
  442 + label="单题分值"
  443 + ></el-input-number>
  444 + </div>
  445 + <div class="qs-partScore">
  446 + <p v-if="subQuestions.questionType != 3">--</p>
  447 + <el-input-number
  448 + class="number-ipt"
  449 + v-else
  450 + size="medium"
  451 + :min="0"
  452 + :precision="2"
  453 + :max="subQuestions.score"
  454 + :step="0.5"
  455 + v-model="subQuestions.partScore"
  456 + label="漏选得分"
  457 + ></el-input-number>
  458 + </div>
  459 + <div class="qs-options qs-options2">
  460 + <p v-if="subQuestions.questionType == 5">--</p>
  461 + <p v-if="subQuestions.questionType == 4" class="answer-box">
  462 + <span
  463 + class="answer-s"
  464 + :class="subQuestions.correctAnswer == 1 ? 'active' : ''"
  465 + @click="subQuestions.correctAnswer = 1"
  466 + >✓</span
  467 + >
  468 + <span
  469 + class="answer-s"
  470 + :class="subQuestions.correctAnswer == 2 ? 'active' : ''"
  471 + @click="subQuestions.correctAnswer = 2"
  472 + >✗</span
  473 + >
  474 + </p>
  475 + <p v-if="subQuestions.questionType == 3" class="answer-box">
  476 + <span
  477 + class="answer-s"
  478 + v-for="option in subQuestions.answerOptions.split(',')"
  479 + :class="
  480 + subQuestions.correctAnswer.includes(option)
  481 + ? 'active'
  482 + : ''
  483 + "
  484 + :key="option"
  485 + @click="changAnswer(subQuestions, option)"
  486 + >{{ option }}</span
  487 + >
  488 + </p>
  489 + <p v-if="subQuestions.questionType == 2" class="answer-box">
  490 + <span
  491 + class="answer-s"
  492 + v-for="option in subQuestions.answerOptions.split(',')"
  493 + :class="
  494 + subQuestions.correctAnswer == option ? 'active' : ''
  495 + "
  496 + :key="option"
  497 + @click="subQuestions.correctAnswer = option"
  498 + >{{ option }}</span
  499 + >
  500 + </p>
  501 + </div>
437 502 </div>
438   - <div class="qs-options qs-options2">
439   - <p v-if="subQuestions.questionType == 5">--</p>
440   - <p v-if="subQuestions.questionType == 4" class="answer-box">
  503 + </li>
  504 + </ul>
  505 + <el-dialog
  506 + title="批量设置答案"
  507 + :visible.sync="diaSetAns"
  508 + width="400"
  509 + :modal-append-to-body="false"
  510 + >
  511 + <div class="qs-options">
  512 + <p class="dia-tips">
  513 + 请点击选项按钮设置答案,多选题题目之间用“,”隔开,若添加5道题:“AC,AD,BD,AC,CD”
  514 + </p>
  515 + <p>{{ setSubPro(formAns.qusType) }}:</p>
  516 + <p class="ipt">
  517 + <el-input
  518 + v-model="formAns.answerList"
  519 + @keydown.native="keydownAnswer($event)"
  520 + ></el-input>
  521 + </p>
  522 + <p class="answer-box">
  523 + <template v-if="formAns.qusType == 4">
441 524 <span
442   - class="answer-s"
443   - :class="subQuestions.correctAnswer == 1 ? 'active' : ''"
444   - @click="subQuestions.correctAnswer = 1"
  525 + class="answer-s active"
  526 + @click="
  527 + formAns.answerList.length < formAns.subNum
  528 + ? (formAns.answerList += '✓')
  529 + : ''
  530 + "
445 531 >✓</span
446 532 >
447 533 <span
448   - class="answer-s"
449   - :class="subQuestions.correctAnswer == 2 ? 'active' : ''"
450   - @click="subQuestions.correctAnswer = 2"
  534 + class="answer-s active"
  535 + @click="
  536 + formAns.answerList.length < formAns.subNum
  537 + ? (formAns.answerList += '✗')
  538 + : ''
  539 + "
451 540 >✗</span
452 541 >
453   - </p>
454   - <p v-if="subQuestions.questionType == 3" class="answer-box">
  542 + </template>
  543 + <template v-if="formAns.qusType == 3">
455 544 <span
456   - class="answer-s"
457   - v-for="option in subQuestions.answerOptions.split(',')"
458   - :class="
459   - subQuestions.correctAnswer.includes(option)
460   - ? 'active'
461   - : ''
462   - "
  545 + class="answer-s active"
  546 + v-for="option in formAns.answerOptions.split(',')"
463 547 :key="option"
464   - @click="changAnswer(subQuestions, option)"
  548 + @click="setMultiple(formAns, option)"
465 549 >{{ option }}</span
466 550 >
467   - </p>
468   - <p v-if="subQuestions.questionType == 2" class="answer-box">
469 551 <span
470   - class="answer-s"
471   - v-for="option in subQuestions.answerOptions.split(',')"
472   - :class="
473   - subQuestions.correctAnswer == option ? 'active' : ''
  552 + class="answer-s active"
  553 + @click="
  554 + formAns.answerList.split(',').length < formAns.subNum
  555 + ? (formAns.answerList += ',')
  556 + : ''
474 557 "
  558 + >,</span
  559 + >
  560 + </template>
  561 + <template v-if="formAns.qusType == 2" class="answer-box">
  562 + <span
  563 + class="answer-s active"
  564 + v-for="option in formAns.answerOptions.split(',')"
475 565 :key="option"
476   - @click="subQuestions.correctAnswer = option"
  566 + @click="
  567 + formAns.answerList.length < formAns.subNum
  568 + ? (formAns.answerList += option)
  569 + : ''
  570 + "
477 571 >{{ option }}</span
478 572 >
479   - </p>
480   - </div>
481   - </li>
482   - </ul>
  573 + </template>
  574 + <span
  575 + class="answer-s delButton"
  576 + @click="formAns.answerList = formAns.answerList.slice(0, -1)"
  577 + >x</span
  578 + >
  579 + </p>
  580 + </div>
  581 + <div class="dialog-footer" slot="footer">
  582 + <el-button @click="saveFormAns">确 定</el-button>
  583 + <el-button @click="diaSetAns = false">取 消</el-button>
  584 + </div>
  585 + </el-dialog>
483 586 </div>
484 587 <div class="btn-box">
485 588 <el-button type="danger" plain round @click="linkBack"
486 589 >取消</el-button
487 590 >
488   - <el-button round @click="step = 1">上一步</el-button>
  591 + <el-button round @click="backStep1">上一步</el-button>
489 592 <el-button type="primary" round @click="save">保存</el-button>
490 593 </div>
491 594 </div>
... ... @@ -494,13 +597,14 @@
494 597 </template>
495 598  
496 599 <script>
497   -import { formatDate, deepClone } from "utils";
  600 +import { deepClone, checkAnswer } from "utils";
498 601 const questionForm = {
499 602 questionTitle: "",
500 603 questionType: 2,
501 604 number: 10,
502 605 selectNum: 4,
503 606 score: 1,
  607 + partScore: 0,
504 608 };
505 609 const subQuesOptions = {
506 610 questionType: 2,
... ... @@ -516,7 +620,7 @@ export default {
516 620 let score = 0;
517 621 this.form.questionList.map((item) => {
518 622 score += item.subQuestions.reduce((a, b) => {
519   - return a + Number(b.score);
  623 + return a + Number(b.score ? b.score : 0);
520 624 }, 0);
521 625 }, 0);
522 626 return Number(score).toFixed(2);
... ... @@ -588,6 +692,15 @@ export default {
588 692 { required: true, message: "请设置考试时长", trigger: "blur" },
589 693 ],
590 694 },
  695 + diaSetAns: false,
  696 + formAns: {
  697 + listIndex: 0, //大题位置
  698 + endIndex: 0, //相同题目最后一位题目的questionIndex
  699 + qusType: "", //题目类型
  700 + subNum: 0, //数量
  701 + answerOptions: [], //答案选项
  702 + answerList: "", //答案列表-字符串
  703 + },
591 704 };
592 705 },
593 706 async created() {
... ... @@ -641,12 +754,22 @@ export default {
641 754 }
642 755 return tit;
643 756 },
644   - setNum(index, indexs) {
  757 + setNum(index, indexs, sub) {
645 758 let lengths = 0;
  759 + let subIndex = 0;
646 760 for (let i = 0; i < index; i++) {
647   - lengths += this.form.questionList[i].subQuestions.length;
  761 + let subArr = this.form.questionList[i].subQuestions.filter((item) => {
  762 + return !!item.questionType;
  763 + });
  764 + lengths += subArr.length;
648 765 }
649   - return lengths + indexs + 1;
  766 +
  767 + for (let i = 0; i < indexs; i++) {
  768 + if (!!this.form.questionList[index].subQuestions[i].questionType) {
  769 + subIndex += 1;
  770 + }
  771 + }
  772 + return lengths + subIndex + 1;
650 773 },
651 774 setBigNum(num) {
652 775 let txt = "";
... ... @@ -676,7 +799,91 @@ export default {
676 799  
677 800 return txt;
678 801 },
679   - setAddIndex(index) {},
  802 + setFormAns(indexs, index) {
  803 + //初始化要修改的答案
  804 + this.formAns = { ...this.form.questionList[index].subQuestions[indexs] };
  805 + this.formAns.listIndex = index;
  806 + this.diaSetAns = true;
  807 + },
  808 + setMultiple(obj, answer) {
  809 + //多选答案设置
  810 + obj.answerList += answer;
  811 + let str = obj.answerList;
  812 + let str2 = checkAnswer(
  813 + str,
  814 + 3,
  815 + obj.answerOptions.split(",").length,
  816 + obj.answerList.length
  817 + );
  818 + obj.answerList = str2;
  819 + },
  820 + saveFormAns() {
  821 + //批量修改答案
  822 + let EndIndex;
  823 + let subNum = this.formAns.subNum - 1;
  824 + this.form.questionList[this.formAns.listIndex].subQuestions.some(
  825 + (item, index) => {
  826 + if (this.formAns.endIndex == item.questionIndex) {
  827 + EndIndex = index;
  828 + return;
  829 + }
  830 + }
  831 + );
  832 +
  833 + for (let i = 0; i <= subNum; i++) {
  834 + let correctAnswer = "";
  835 + if (this.formAns.qusType == 2) {
  836 + correctAnswer = this.formAns.answerList[subNum - i];
  837 + } else if (this.formAns.qusType == 3) {
  838 + correctAnswer = this.formAns.answerList.split(",")[subNum - i];
  839 +
  840 + console.log(this.formAns.answerList.split(",")[subNum - i]);
  841 + } else if (this.formAns.qusType == 4) {
  842 + correctAnswer = this.formAns.answerList[subNum - i] == "✓" ? 1 : 2;
  843 + }
  844 + this.form.questionList[this.formAns.listIndex].subQuestions[
  845 + EndIndex - i
  846 + ].correctAnswer = correctAnswer;
  847 + }
  848 + this.diaSetAns = false;
  849 + },
  850 + keydownAnswer(event) {
  851 + //快速答案设置禁止输入
  852 + if (
  853 + event.key == "Meta" ||
  854 + event.key == "CapsLock" ||
  855 + event.key == "Shift" ||
  856 + event.key == "Enter" ||
  857 + event.key == "Alt" ||
  858 + event.key == "Backspace" ||
  859 + event.key == "Delete" ||
  860 + event.key == "ArrowUp" ||
  861 + event.key == "ArrowDown" ||
  862 + event.key == "ArrowLeft" ||
  863 + event.key == "v" ||
  864 + event.key == "V" ||
  865 + event.key == "ArrowRight"
  866 + ) {
  867 + return;
  868 + } else {
  869 + event.returnValue = "";
  870 + }
  871 + },
  872 + setAnswer(type, ans) {
  873 + let txt = "";
  874 + if (type == 2) {
  875 + txt = ans;
  876 + } else if (type == 3) {
  877 + txt = ans + ",";
  878 + } else if (type == 4) {
  879 + txt = ans == 1 ? "✓" : "✗";
  880 + }
  881 + return txt;
  882 + },
  883 + backStep1() {
  884 + this.formatQuestionList();
  885 + this.step = 1;
  886 + },
680 887 setStep1() {
681 888 this.$refs["forms"].validate((valid) => {
682 889 // 验证通过:保存
... ... @@ -693,19 +900,99 @@ export default {
693 900 this.$message.warning("请添加题目!");
694 901 return;
695 902 }
696   - let valid = "";
697   - this.form.questionList.map((item, index) => {
698   - if (!item.questionTitle) {
699   - valid += index + 1 + "、";
700   - }
701   - });
702   - if (!valid) {
  903 + // let valid = "";
  904 + // this.form.questionList.map((item, index) => {
  905 + // if (!item.questionTitle) {
  906 + // valid += index + 1 + "、";
  907 + // }
  908 + // });
  909 + // if (!valid) {
  910 + //添加题目ID、序号
  911 + this.form.questionList.map((item, index) => {
  912 + item.questionType = 0;
  913 + item.subQuestions.map((items, indexs) => {
  914 + items.questionId = this.setNum(index, indexs);
  915 + items.questionIndex = this.setNum(index, indexs);
  916 + });
  917 + });
  918 + //整理问题
  919 + this.form.questionList?.map((item) => {
  920 + let types = [{}];
  921 + let addndex = 0;
  922 + item.subQuestions.map((sub, index) => {
  923 + if (!!sub.questionType && sub.questionType != 5) {
  924 + if (sub.questionType == types[addndex].qusType) {
  925 + //同类型批量答案+1
  926 + types[addndex].subNum += 1;
  927 + if (
  928 + types[addndex].answerOptions.length < sub.answerOptions.length
  929 + ) {
  930 + types[addndex].answerOptions = sub.answerOptions;
  931 + }
  932 + types[addndex].answerList += this.setAnswer(
  933 + sub.questionType,
  934 + sub.correctAnswer
  935 + );
  936 + if (index == item.subQuestions.length - 1) {
  937 + //循环最后类型数量大于等于5,保存批量答案
  938 + if (types[addndex].subNum && types[addndex].subNum >= 5) {
  939 + types[addndex].endIndex = sub.questionIndex;
  940 + types[addndex].index = index;
  941 + }
  942 + }
  943 + } else {
  944 + if (types[addndex].subNum && types[addndex].subNum >= 5) {
  945 + //不同类型时如果原有类型数量大于等于5,保存批量答案
  946 + types[addndex].endIndex =
  947 + item.subQuestions[index - 1].questionIndex;
  948 + types[addndex].index = index - 1;
  949 + addndex += 1;
  950 + types[addndex] = {};
  951 + }
  952 + //不同类型初始化批量答案
  953 + types[addndex].qusType = sub.questionType;
  954 + types[addndex].subNum = 1;
  955 + types[addndex].answerOptions = sub.answerOptions;
  956 + types[addndex].answerList = this.setAnswer(
  957 + sub.questionType,
  958 + sub.correctAnswer
  959 + );
  960 + }
  961 + }
  962 + });
  963 + for (let i = 0; i < types.length; i++) {
  964 + if (types[i].qusType == 3) {
  965 + types[i].answerList = types[i].answerList.slice(0, -1);
  966 + }
  967 + if (types[i].subNum >= 5) {
  968 + item.subQuestions.splice(
  969 + types[i].index + i + 1,
  970 + 0,
  971 + deepClone(types[i])
  972 + );
  973 + }
  974 + }
  975 + console.log(types);
  976 + });
703 977 this.step = 2;
704 978 return;
705   - } else {
706   - this.$message.error(
707   - `大题名称不能为空,请检查第${valid.slice(0, -1)}大题!`
708   - );
  979 + // } else {
  980 + // this.$message.error(
  981 + // `大题名称不能为空,请检查第${valid.slice(0, -1)}大题!`
  982 + // );
  983 + // }
  984 + },
  985 + formatQuestionList() {
  986 + for (let i = 0; i < this.form.questionList.length; i++) {
  987 + for (
  988 + let j = 0;
  989 + j < this.form.questionList[i].subQuestions.length;
  990 + j++
  991 + ) {
  992 + if (this.form.questionList[i].subQuestions[j].qusType) {
  993 + this.form.questionList[i].subQuestions.splice(j, 1);
  994 + }
  995 + }
709 996 }
710 997 },
711 998 openQuestion() {
... ... @@ -718,6 +1005,7 @@ export default {
718 1005 ...subQuesOptions,
719 1006 selectNum: this.questionForm.selectNum,
720 1007 score: this.questionForm.score,
  1008 + partScore: this.questionForm.partScore,
721 1009 questionType:
722 1010 this.questionForm.questionType == 6
723 1011 ? 2
... ... @@ -758,7 +1046,7 @@ export default {
758 1046 },
759 1047 setScore(question) {
760 1048 let score = question.subQuestions.reduce((a, b) => {
761   - return a + b.score;
  1049 + return a + (b.score ? b.score : 0);
762 1050 }, 0);
763 1051 return Number(score).toFixed(2);
764 1052 },
... ... @@ -875,16 +1163,7 @@ export default {
875 1163 async save() {
876 1164 if (this.saveLoading) return;
877 1165 this.saveLoading = true;
878   - //添加题目ID、序号
879   - this.form.questionList.map((item, index) => {
880   - // item.questionId = index + 1;
881   - // item.questionIndex = index + 1;
882   - item.questionType = 0;
883   - item.subQuestions.map((items, indexs) => {
884   - items.questionId = this.setNum(index, indexs);
885   - items.questionIndex = this.setNum(index, indexs);
886   - });
887   - });
  1166 + this.formatQuestionList();
888 1167 const { data, status, info } = await this.$request.addPaper({
889 1168 ...this.form,
890 1169 });
... ... @@ -997,9 +1276,44 @@ export default {
997 1276 .red {
998 1277 color: #f30;
999 1278 }
  1279 +.qs-options {
  1280 + flex: 1;
  1281 + .ipt {
  1282 + margin-bottom: 5px;
  1283 + }
  1284 + .answer-box {
  1285 + .answer-s {
  1286 + cursor: pointer;
  1287 + user-select: none;
  1288 + &:first-of-type {
  1289 + margin-left: 0;
  1290 + }
  1291 + }
  1292 + }
  1293 + .delButton {
  1294 + text-indent: -9999999px;
  1295 + border-color: #ff6868;
  1296 + background: #ff6868 url("../../assets/images/arrow.png") no-repeat center;
  1297 + background-size: 19px;
  1298 + color: transparent;
  1299 + }
  1300 + .ac {
  1301 + border-color: #ff6868;
  1302 + background: #ff6868;
  1303 + color: #fff;
  1304 + }
  1305 +}
  1306 +
1000 1307 .sel2 {
1001 1308 width: 480px;
1002 1309 }
  1310 +.set-ans-btn {
  1311 + width: 100%;
  1312 + padding: 10px 0 10px 630px;
  1313 + box-sizing: border-box;
  1314 + border-right: 1px solid #e2e2e2;
  1315 + border-bottom: 1px solid #e2e2e2;
  1316 +}
1003 1317 .content-box {
1004 1318 width: 100%;
1005 1319 height: 100%;
... ...
src/views/login/index.vue
... ... @@ -101,10 +101,6 @@ export default {
101 101 // password: "712576",
102 102 username: "13247726488",
103 103 password: "726488",
104   - // username: "13319607658",
105   - // password: "Pw607658#",
106   - // username: "18213902650",
107   - // password: "Pw902650#",
108 104 },
109 105 loginRules: {
110 106 username: [
... ...
src/views/test/analysis.vue
... ... @@ -131,7 +131,7 @@
131 131 :label="item.title"
132 132 :prop="'count' + index"
133 133 align="center"
134   - ><template slot-scope="scope">{{
  134 + ><template slot-scope="scope"><p class="present">{{
135 135 scope.row.questionType == "5"
136 136 ? ""
137 137 : scope.row["option" + index]
... ... @@ -139,7 +139,7 @@
139 139 scope.row["present" + index]
140 140 })`
141 141 : ""
142   - }}</template>
  142 + }}</p></template>
143 143 </el-table-column>
144 144 </el-table>
145 145 <div class="hui-box" v-show="type == 1">
... ... @@ -358,7 +358,7 @@
358 358 <div class="down">
359 359 <el-button
360 360 @click="exportData"
361   - type="info"
  361 + type="primary"
362 362 plain
363 363 round
364 364 icon="fa fa-cloud-download"
... ... @@ -640,12 +640,7 @@ export default {
640 640 items["title"] = "未答";
641 641 params["count" + index] = lastOPtion.count;
642 642 params["present" + index] = lastOPtion.present;
643   - params["option" + index] =
644   - lastOPtion.option == 1
645   - ? "✓"
646   - : lastOPtion.option == 2
647   - ? "✗"
648   - : lastOPtion.option;
  643 + params["option" + index] = "?";
649 644 }
650 645 });
651 646 return {
... ... @@ -665,15 +660,15 @@ export default {
665 660 },
666 661 //导出
667 662 async exportData() {
668   - if (this.exportLoading == true) return;
669   - this.exportLoading = true;
670   - const { data, status, info } = await this.$request.exportPeriodReport();
671   - this.exportLoading = false;
672   - if (data) {
673   - downloadFile(this.title + "报表", data);
674   - } else {
675   - this.$message.error(info);
676   - }
  663 + // if (this.exportLoading == true) return;
  664 + // this.exportLoading = true;
  665 + // const { data, status, info } = await this.$request.exportPeriodReport();
  666 + // this.exportLoading = false;
  667 + // if (data) {
  668 + // downloadFile(this.title + "报表", data);
  669 + // } else {
  670 + // this.$message.error(info);
  671 + // }
677 672 },
678 673 },
679 674 };
... ... @@ -711,6 +706,9 @@ div::-webkit-scrollbar-thumb {
711 706 z-index: 10;
712 707 }
713 708 }
  709 +.present{
  710 + white-space: nowrap;
  711 +}
714 712 .error {
715 713 color: #f30;
716 714 }
... ...
src/views/test/editAnswer.vue
... ... @@ -502,7 +502,7 @@ export default {
502 502 let types = [{}];
503 503 let addndex = 0;
504 504 item.subQuestions.map((sub, index) => {
505   - if (!!sub.questionType) {
  505 + if (!!sub.questionType && sub.questionType!=5) {
506 506 if (sub.questionType == types[addndex].qusType) {
507 507 //同类型批量答案+1
508 508 types[addndex].subNum += 1;
... ... @@ -527,7 +527,7 @@ export default {
527 527 //不同类型时如果原有类型数量大于等于5,保存批量答案
528 528 types[addndex].endIndex =
529 529 item.subQuestions[index - 1].questionIndex;
530   - types[addndex].index = index;
  530 + types[addndex].index = index-1;
531 531 addndex += 1;
532 532 types[addndex] = {};
533 533 }
... ... @@ -559,7 +559,7 @@ export default {
559 559 let types = [{}];
560 560 let addndex = 0;
561 561 this.questionList?.map((sub, index) => {
562   - if (!!sub.questionType) {
  562 + if (!!sub.questionType && sub.questionType!=5) {
563 563 if (sub.questionType == types[addndex].qusType) {
564 564 //同类型批量答案+1
565 565 types[addndex].subNum += 1;
... ... @@ -584,7 +584,7 @@ export default {
584 584 //不同类型时如果原有类型数量大于等于5,保存批量答案
585 585 types[addndex].endIndex =
586 586 this.questionList[index - 1].questionIndex;
587   - types[addndex].index = index;
  587 + types[addndex].index = index-1;
588 588 addndex += 1;
589 589 types[addndex] = {};
590 590 }
... ...
src/views/test/index.vue
... ... @@ -7,7 +7,12 @@
7 7 </back-box>
8 8 <div class="answer-header">
9 9 <div class="sel-box">
10   - <el-select class="sel" v-model="query.classId" placeholder="选择班级" @change="changeclass">
  10 + <el-select
  11 + class="sel"
  12 + v-model="query.classId"
  13 + placeholder="选择班级"
  14 + @change="changeclass"
  15 + >
11 16 <el-option
12 17 v-for="item in classList"
13 18 :key="item.value"
... ... @@ -89,10 +94,18 @@
89 94 style="margin-bottom: 20px"
90 95 >
91 96 <el-radio-button :label="1">单卷测练报表</el-radio-button>
92   - <el-radio-button :label="2" v-show="this.query.startDay!=this.query.endDay">阶段测练报表</el-radio-button>
  97 + <el-radio-button
  98 + :label="2"
  99 + v-show="this.query.startDay != this.query.endDay"
  100 + >阶段测练报表</el-radio-button
  101 + >
93 102 </el-radio-group>
94 103 <div v-show="tabIndex == 1" v-loading="loading">
95   - <el-table :data="tableData" :show-header="tableData.length?true:false" border style="width: 100%">
  104 + <el-table
  105 + :data="tableData"
  106 + border
  107 + style="width: 100%"
  108 + >
96 109 <el-table-column
97 110 prop="title"
98 111 label="试卷名称"
... ... @@ -116,7 +129,8 @@
116 129 ></el-table-column>
117 130 <el-table-column prop="avgScore" label="班平均分" align="center"
118 131 ><template slot-scope="scoped">{{
119   - (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.answerNum == 0) &&
  132 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  133 + scoped.row.answerNum == 0) &&
120 134 scoped.row.recordStatus == 0
121 135 ? "-"
122 136 : scoped.row.avgScore
... ... @@ -124,7 +138,8 @@
124 138 >
125 139 <el-table-column prop="highestScore" label="班最高分" align="center"
126 140 ><template slot-scope="scoped">{{
127   - (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.answerNum == 0) &&
  141 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  142 + scoped.row.answerNum == 0) &&
128 143 scoped.row.recordStatus == 0
129 144 ? "-"
130 145 : scoped.row.highestScore
... ... @@ -132,7 +147,8 @@
132 147 >
133 148 <el-table-column prop="lowestScore" label="班最低分" align="center"
134 149 ><template slot-scope="scoped">{{
135   - (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.answerNum == 0) &&
  150 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  151 + scoped.row.answerNum == 0) &&
136 152 scoped.row.recordStatus == 0
137 153 ? "-"
138 154 : scoped.row.lowestScore
... ... @@ -144,11 +160,12 @@
144 160 sortable
145 161 align="center"
146 162 ><template slot-scope="scoped">{{
147   - (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.answerNum == 0) &&
  163 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  164 + scoped.row.answerNum == 0) &&
148 165 scoped.row.recordStatus == 0
149 166 ? "-"
150 167 : scoped.row.excellenNum
151   - ? `${scoped.row.excellenNum}/${scoped.row.excellenRate}%`
  168 + ? `${scoped.row.excellenNum}(${scoped.row.excellenRate}%)`
152 169 : scoped.row.excellenNum
153 170 }}</template></el-table-column
154 171 >
... ... @@ -159,11 +176,12 @@
159 176 align="center"
160 177 ><template slot-scope="scoped"
161 178 >{{
162   - (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.answerNum == 0) &&
  179 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  180 + scoped.row.answerNum == 0) &&
163 181 scoped.row.recordStatus == 0
164 182 ? "-"
165 183 : scoped.row.goodNum
166   - ? `${scoped.row.goodNum}/${scoped.row.goodRate}%`
  184 + ? `${scoped.row.goodNum}(${scoped.row.goodRate}%)`
167 185 : scoped.row.goodNum
168 186 }}
169 187 </template></el-table-column
... ... @@ -175,11 +193,12 @@
175 193 align="center"
176 194 ><template slot-scope="scoped"
177 195 >{{
178   - (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.answerNum == 0) &&
  196 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  197 + scoped.row.answerNum == 0) &&
179 198 scoped.row.recordStatus == 0
180 199 ? "-"
181 200 : scoped.row.passNum
182   - ? `${scoped.row.passNum}/${scoped.row.passRate}%`
  201 + ? `${scoped.row.passNum}(${scoped.row.passRate}%)`
183 202 : scoped.row.passNum
184 203 }}
185 204 </template></el-table-column
... ... @@ -190,18 +209,23 @@
190 209 sortable
191 210 align="center"
192 211 ><template slot-scope="scoped">{{
193   - (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.nswerNum == 0) &&
194   - scoped.row.arecordStatus== 0
  212 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  213 + scoped.row.nswerNum == 0) &&
  214 + scoped.row.arecordStatus == 0
195 215 ? "-"
196 216 : scoped.row.failedNum
197   - ? `${scoped.row.failedNum}/${scoped.row.failedRate}%`
  217 + ? `${scoped.row.failedNum}(${scoped.row.failedRate}%)`
198 218 : scoped.row.failedNum
199 219 }}</template></el-table-column
200 220 >
201 221 <el-table-column label="操作" align="center">
202 222 <template slot-scope="scoped">
203 223 <el-tooltip
204   - v-if="scoped.row.answerNum != 0 || (scoped.row.recordStatus != 0 &&scoped.row.subjectiveScore == scoped.row.examPaperScore)"
  224 + v-if="
  225 + scoped.row.answerNum != 0 ||
  226 + (scoped.row.recordStatus != 0 &&
  227 + scoped.row.subjectiveScore == scoped.row.examPaperScore)
  228 + "
205 229 effect="dark"
206 230 content="详情"
207 231 placement="top"
... ... @@ -215,7 +239,10 @@
215 239 ></el-button>
216 240 </el-tooltip>
217 241 <el-tooltip
218   - v-if="scoped.row.answerNum == 0 && scoped.row.subjectiveScore != scoped.row.examPaperScore"
  242 + v-if="
  243 + scoped.row.answerNum == 0 &&
  244 + scoped.row.subjectiveScore != scoped.row.examPaperScore
  245 + "
219 246 effect="dark"
220 247 content="设置答案"
221 248 placement="top"
... ... @@ -229,7 +256,10 @@
229 256 ></el-button>
230 257 </el-tooltip>
231 258 <el-tooltip
232   - v-if="scoped.row.subjectiveScore == scoped.row.examPaperScore && scoped.row.recordStatus == 0"
  259 + v-if="
  260 + scoped.row.subjectiveScore == scoped.row.examPaperScore &&
  261 + scoped.row.recordStatus == 0
  262 + "
233 263 effect="dark"
234 264 content="导入主观题"
235 265 placement="top"
... ... @@ -263,7 +293,6 @@
263 293 :max-height="tableMaxHeight"
264 294 v-if="role == 'ROLE_JIAOSHI'"
265 295 :data="tableData"
266   - :show-header="tableData.length?true:false"
267 296 border
268 297 style="width: 100%"
269 298 >
... ... @@ -289,19 +318,20 @@
289 318 :prop="'score' + index"
290 319 :label="index == 0 ? '总分' : '成绩'"
291 320 align="center"
  321 + :class-name="index%2==0?'bg':''"
292 322 ></el-table-column>
293 323 <el-table-column
294 324 :prop="'classRank' + index"
295 325 label="班名"
296 326 align="center"
  327 + :class-name="index%2==0?'bg':''"
297 328 ></el-table-column>
298 329 </el-table-column>
299 330 </el-table>
300 331 <el-table
301   - :show-header="tableData.length?true:false"
302   - :max-height="tableMaxHeight"
303 332 v-else
304 333 :data="tableData"
  334 + :max-height="tableMaxHeight"
305 335 border
306 336 style="width: 100%"
307 337 >
... ... @@ -327,33 +357,43 @@
327 357 :prop="'examCount' + item"
328 358 label="测练数"
329 359 align="center"
  360 + :class-name="index%2==0?'bg':''"
330 361 ></el-table-column>
331 362 <el-table-column
332 363 :prop="'participationCount' + item"
333 364 label="参与数"
334 365 align="center"
  366 + :class-name="index%2==0?'bg':''"
335 367 ></el-table-column>
336 368 <el-table-column
337 369 :prop="'score' + item"
338 370 label="总分"
339 371 align="center"
  372 + :class-name="index%2==0?'bg':''"
340 373 ></el-table-column>
341 374 <el-table-column
342 375 :prop="'classRank' + item"
343 376 label="班名"
344 377 align="center"
  378 + :class-name="index%2==0?'bg':''"
345 379 ></el-table-column>
346 380 </el-table-column>
347 381 </el-table>
348 382 </div>
349 383 <p class="down" v-if="tabIndex == 2">
350   - <el-button type="info" plain round icon="fa fa-cloud-download"
  384 + <el-button type="primary" plain round icon="fa fa-cloud-download"
351 385 >导出报表</el-button
352 386 >
353 387 </p>
354 388 </div>
355 389 <el-dialog title="导入主观题分数" :visible.sync="diaUp" width="600">
356   - <up-load :url="url" :examId="examId" @upSuccess="upSuccess" fileName="主观题分数" v-loading="loadingDown">
  390 + <up-load
  391 + :url="url"
  392 + :examId="examId"
  393 + @upSuccess="upSuccess"
  394 + fileName="主观题分数"
  395 + v-loading="loadingDown"
  396 + >
357 397 <template slot="down">
358 398 <p class="down-txt">
359 399 第一步:下载模板并编辑完成学生分数
... ... @@ -389,7 +429,7 @@ export default {
389 429 role: "",
390 430 loading: false,
391 431 diaUp: false,
392   - loadingDown:false,
  432 + loadingDown: false,
393 433 url: "/api_html/teaching/importSubjectiveScore",
394 434 examId: "",
395 435 dialogVisible: false,
... ... @@ -547,21 +587,22 @@ export default {
547 587 this.page = 1;
548 588 this._QueryData();
549 589 },
550   - upSuccess(){//导入成功
551   - this.diaUp = false
  590 + upSuccess() {
  591 + //导入成功
  592 + this.diaUp = false;
552 593 this._QueryData();
553 594 },
554   - async changeclass(){
555   - await this._QuerySubjectList()
556   - this.page = 1
557   - this._QueryData()
  595 + async changeclass() {
  596 + await this._QuerySubjectList();
  597 + this.page = 1;
  598 + this._QueryData();
558 599 },
559 600 async downExcel() {
560   - this.loadingDown = true
  601 + this.loadingDown = true;
561 602 let data = await this.$request.subjectiveScoreTemplate({
562 603 examId: this.examId,
563 604 });
564   - this.loadingDown = false
  605 + this.loadingDown = false;
565 606 if (data && !data.code) {
566 607 let blob = new Blob([data], {
567 608 type: "application/vnd.ms-excel;charset=utf-8",
... ...