Commit 079cb4cf3372babc7d21215a01eecb79fef45a2a

Authored by 梁保满
1 parent 86201e49

即时测导出

src/components/charts/lineChart.vue
... ... @@ -9,6 +9,7 @@ export default {
9 9 id: String,
10 10 params: Array,
11 11 xAxis: Array,
  12 + colors: Array
12 13 },
13 14 watch: {
14 15 params: {
... ... @@ -25,7 +26,7 @@ export default {
25 26 chart: null,
26 27 };
27 28 },
28   - created() {},
  29 + created() { },
29 30 mounted() {
30 31 this.initData();
31 32 },
... ... @@ -33,7 +34,7 @@ export default {
33 34 setOption() {
34 35 const that = this;
35 36 const options = {
36   - color: this.colors || ["#4472c4", "#ed7d32", "#a5a5a5"],
  37 + color: this.colors || ["#9772ff", "#79cd91", "#72b8ff"],
37 38 backgroundColor: "#fff",
38 39 tooltip: {
39 40 trigger: "item",
... ... @@ -41,8 +42,10 @@ export default {
41 42 },
42 43 legend: {
43 44 show: true,
44   - bottom: 0,
45   - itemHeight: 2,
  45 + top: 0,
  46 + right: 20,
  47 + itemHeight: 15,
  48 + icon: "circle"
46 49 },
47 50 xAxis: {
48 51 type: "category",
... ... @@ -52,7 +55,7 @@ export default {
52 55 show: false,
53 56 },
54 57 axisLabel: {
55   - color: "#666",
  58 + color: "#333",
56 59 },
57 60 },
58 61 yAxis: {
... ... @@ -63,13 +66,16 @@ export default {
63 66 },
64 67 axisLabel: {
65 68 color: "#666",
  69 + formatter: function (name) {
  70 + return name + "%"
  71 + },
66 72 },
67 73 },
68 74 grid: {
69   - top:28,
70   - left: "10%",
71   - right: "10%",
72   - bottom: 30,
  75 + top: 36,
  76 + left: 20,
  77 + right: 20,
  78 + bottom: 20,
73 79 containLabel: true,
74 80 },
75 81 series: that.params.map((item) => {
... ... @@ -77,9 +83,9 @@ export default {
77 83 name: item.name,
78 84 type: "line",
79 85 symbol: "circle",
80   - symbolSize: "8",
  86 + symbolSize: "6",
81 87 lineStyle: {
82   - width: 3,
  88 + width: 1,
83 89 },
84 90 data: item.value,
85 91 };
... ...
src/components/charts/radarChart.vue
... ... @@ -24,45 +24,62 @@ export default {
24 24 chart: null,
25 25 };
26 26 },
27   - created() {},
  27 + created() { },
28 28 mounted() {
29 29 this.initData();
30 30 },
31 31 methods: {
32 32 setOption() {
  33 + let that = this
33 34 const option = {
34   - color: this.colors || ["#4472c4", "#ed7d32", "#a5a5a5"],
  35 + color: that.colors || ["#4472c4", "#ed7d32", "#a5a5a5"],
35 36 backgroundColor: "#fff",
36 37 tooltip: {
37 38 trigger: "item",
38 39 confine: true,
  40 + formatter: function (param) {
  41 + let marker = param.marker
  42 + let oHtml = `<p>${marker}${param.name}</p>`
  43 + param.value.map((item, index) => {
  44 + oHtml += `<p>${that.params.indicator[index].name}:${item}</p>`
  45 + })
  46 + return oHtml
  47 + }
39 48 },
40 49 legend: {
41   - show:true,
42   - bottom:0,
43   - itemHeight:2
  50 + show: true,
  51 + top: 0,
  52 + right: 20,
  53 + itemHeight: 15,
  54 + icon: "circle"
44 55 },
  56 +
45 57 radar: {
46   - indicator: [...this.params.indicator],
  58 + indicator: [...that.params.indicator],
47 59 splitNumber: 5,
48   - center:['50%', '48%'],
49   - radius:"70%",
  60 + center: ['50%', '48%'],
  61 + radius: "80%",
50 62 shape: "polygon",
51   - nameGap:10,
52   - axisLine:{
53   - show:false
  63 + nameGap: 6,
  64 + axisLine: {
  65 + show: false
54 66 },
55   - splitLine:{
  67 + splitLine: {
56 68 lineStyle: {
57 69 width: 0.5,
58   - color:'#e2e2e2'
  70 + color: '#e2e2e2'
59 71 },
60 72 },
61   - splitArea:{
62   - areaStyle:{
63   - color:['rgba(250,250,250,0)','rgba(200,200,200,0)']
  73 + splitArea: {
  74 + areaStyle: {
  75 + color: ['rgba(250,250,250,0)', 'rgba(200,200,200,0)']
64 76 }
65   - }
  77 + },
  78 + // axisLabel: {
  79 + // show: false,
  80 + // hideOverlap: true,
  81 + // formatter: '{value}%'
  82 + // },
66 83 },
67 84 series: [
68 85 {
... ... @@ -74,7 +91,7 @@ export default {
74 91 areaStyle: {
75 92 color: "transparent",
76 93 },
77   - data: this.params.num,
  94 + data: that.params.seriesData,
78 95 },
79 96 ],
80 97 };
... ...
src/mock/index.js
... ... @@ -35,7 +35,7 @@ Mock.mock(
35 35 "answerOptions": "A,B,C,D",
36 36 "correctAnswer|1": ["A", "B", "C", "D"],
37 37 "screenshot": "./1.html",
38   - "knowledge":"数与式#有理数#正数和负数,数与式#有理数#有理数"
  38 + "knowledge": "数与式#有理数#正数和负数,数与式#有理数#有理数"
39 39 },
40 40 {
41 41 "questionType": 2,
... ... @@ -45,7 +45,7 @@ Mock.mock(
45 45 "answerOptions": "A,B,C,D",
46 46 "correctAnswer|1": ["A", "B", "C", "D"],
47 47 "screenshot": "./1.html",
48   - "knowledge":"数与式#有理数#正数和负数"
  48 + "knowledge": "数与式#有理数#正数和负数"
49 49 },
50 50 {
51 51 "questionType": 2,
... ... @@ -208,4 +208,503 @@ Mock.mock(
208 208 ]
209 209 }
210 210 }
  211 +)
  212 +
  213 +Mock.mock(
  214 + "/api_html/teaching/examReportList", {
  215 + info: "success",
  216 + status: 0,
  217 + data: {
  218 + "list|2": [
  219 + {
  220 + "id": "@id",
  221 + subjectName: '语文',
  222 + className: '2班',
  223 + classId: "3215",
  224 + "title": "@cTitle",
  225 + "score|80-100": 85,
  226 + "answeredNum|45-50": 48,
  227 + classPersonNum: 50,
  228 + "examStartTime": '@date',
  229 + answerNum: 0,
  230 + recordStatus: 2,
  231 + classList: [{
  232 + classId: "@id",
  233 + className: "@cname",
  234 + }, {
  235 + classId: "@id",
  236 + className: "@cname",
  237 + }]
  238 + },
  239 + {
  240 + "id": "@id",
  241 + subjectName: '数学',
  242 + className: '2班',
  243 + classId: "3215",
  244 + "title": "@cTitle",
  245 + "score|80-100": 85,
  246 + "answeredNum|45-50": 48,
  247 + classPersonNum: 50,
  248 + "examStartTime": '@date',
  249 + answerNum: 0,
  250 + recordStatus: 2,
  251 + classList: [{
  252 + classId: "@id",
  253 + className: "@cname",
  254 + }, {
  255 + classId: "@id",
  256 + className: "@cname",
  257 + }]
  258 + },
  259 + {
  260 + "id": "@id",
  261 + subjectName: '英语',
  262 + className: '2班',
  263 + classId: "3215",
  264 + "title": "@cTitle",
  265 + "score|80-100": 85,
  266 + "answeredNum|45-50": 48,
  267 + classPersonNum: 50,
  268 + "examStartTime": '@date',
  269 + answerNum: 0,
  270 + recordStatus: 2,
  271 + classList: [{
  272 + classId: "@id",
  273 + className: "@cname",
  274 + }, {
  275 + classId: "@id",
  276 + className: "@cname",
  277 + }]
  278 + }
  279 + ]
  280 + }
  281 +}
  282 +)
  283 +Mock.mock(
  284 + "/api_html/teaching/phaseExamReport", {
  285 + info: "success",
  286 + status: 0,
  287 + data: {
  288 + "list|5": [
  289 + {
  290 + "studentId": "@id",
  291 + "studentName": '@cname',
  292 + "studentCode": '@id',
  293 + "shortNumber": "@id",
  294 + "title": "@cTitle",
  295 + "examList": [
  296 + {
  297 + "title": "结石分气在织织",
  298 + "score": 80,
  299 + "classRank|+1": 1,
  300 + "participationRate|+1": 80,
  301 + "correctRate|+1": 82,
  302 + "answerCorrectRate|+1": 85,
  303 + },
  304 + {
  305 + "title": "第业适声",
  306 + "score": 81,
  307 + "classRank|+1": 1,
  308 + "participationRate|+1": 81,
  309 + "correctRate|+1": 88,
  310 + "answerCorrectRate|+1": 90,
  311 + },
  312 + {
  313 + "title": "把住六",
  314 + "score": 82,
  315 + "classRank|+1": 1,
  316 + "participationRate|+1": 82,
  317 + "correctRate|+1": 91,
  318 + "answerCorrectRate|+1": 95,
  319 + },
  320 + {
  321 + "title": "取严酸百列县",
  322 + "score": 83,
  323 + "classRank|+1": 1,
  324 + "participationRate|+1": 85,
  325 + "correctRate|+1": 90,
  326 + "answerCorrectRate|+1": 93,
  327 + },
  328 + {
  329 + "title": "三原上光",
  330 + "score": 84,
  331 + "classRank|+1": 1,
  332 + "participationRate|+1": 83,
  333 + "correctRate|+1": 93,
  334 + "answerCorrectRate|+1": 96,
  335 + }
  336 + ]
  337 + }
  338 + ]
  339 + }
  340 +}
  341 +)
  342 +Mock.mock(
  343 + "/api_html/teaching/examMultiClassReport", {
  344 + info: "success",
  345 + status: 0,
  346 + data: {
  347 + "classes": [],
  348 + "students": [],
  349 + }
  350 +}
  351 +)
  352 +Mock.mock(
  353 + "/api_html/teaching/listStudentsAndQuestions", {
  354 + info: "success",
  355 + status: 0,
  356 + data: {
  357 + "students": [{
  358 + "studentId": "@id",
  359 + "studentName": "@cname",
  360 + "questionList": [
  361 + {
  362 + "examQuestionId|+1": 0,
  363 + "questionId|+1": 1,
  364 + "questionTitle": "@cname",
  365 + "questionType|1-4": 1,
  366 + "score|1-2": 1,
  367 + "subQuestions": [
  368 + {
  369 + id: 1,
  370 + "questionType": 2,
  371 + "score": 1,
  372 + },
  373 + {
  374 + id: 2,
  375 + "questionType": 2,
  376 + "score": 2,
  377 + },
  378 + {
  379 + id: 3,
  380 + "questionType": 2,
  381 + "score": 1,
  382 + },
  383 + {
  384 + id: 4,
  385 + "questionType": 2,
  386 + "score": 1,
  387 + },
  388 + {
  389 + id: 5,
  390 + "questionType": 2,
  391 + "score": 1,
  392 + },
  393 + {
  394 + id: 6,
  395 + "questionType": 3,
  396 + "score": 1,
  397 + },
  398 + ]
  399 + },
  400 + {
  401 + "examQuestionId|+1": 0,
  402 + "questionId|+1": 1,
  403 + "questionTitle": "@cname",
  404 + "questionType|1-4": 1,
  405 + "score|1-2": 1,
  406 + "subQuestions": [
  407 + {
  408 + id: 7,
  409 + "questionType": 2,
  410 + "score": 2,
  411 + },
  412 + {
  413 + id: 8,
  414 + "questionType": 2,
  415 + "score": 3,
  416 + },
  417 + {
  418 + id: 9,
  419 + "questionType": 2,
  420 + "score": 1,
  421 + },
  422 + {
  423 + id: 10,
  424 + "questionType": 2,
  425 + "score": 1,
  426 + },
  427 + {
  428 + id: 11,
  429 + "questionType": 2,
  430 + "score": 1,
  431 + },
  432 + {
  433 + id: 12,
  434 + "questionType": 3,
  435 + "score": 1,
  436 + },
  437 + {
  438 + id: 13,
  439 + "questionType": 2,
  440 + "score": 1,
  441 + },
  442 + {
  443 + id: 14,
  444 + "questionType": 2,
  445 + "score": 1,
  446 + },
  447 + {
  448 + id: 15,
  449 + "questionType": 2,
  450 + "score": 1,
  451 + },
  452 + {
  453 + id: 16,
  454 + "questionType": 2,
  455 + "score": 1,
  456 + }
  457 + ]
  458 + },
  459 + ]
  460 + }, {
  461 + "studentId": "@id",
  462 + "studentName": "@cname",
  463 + "questionList": [
  464 + {
  465 + "examQuestionId|+1": 0,
  466 + "questionId|+1": 1,
  467 + "questionTitle": "@cname",
  468 + "questionType|1-4": 1,
  469 + "score|1-2": 1,
  470 + "subQuestions": [
  471 + {
  472 + id: 1,
  473 + "questionType": 2,
  474 + "score": 1,
  475 + },
  476 + {
  477 + id: 2,
  478 + "questionType": 2,
  479 + "score": 2,
  480 + },
  481 + {
  482 + id: 3,
  483 + "questionType": 2,
  484 + "score": 1,
  485 + },
  486 + {
  487 + id: 4,
  488 + "questionType": 2,
  489 + "score": 1,
  490 + },
  491 + {
  492 + id: 5,
  493 + "questionType": 2,
  494 + "score": 1,
  495 + },
  496 + {
  497 + id: 6,
  498 + "questionType": 3,
  499 + "score": 1,
  500 + },
  501 + ]
  502 + },
  503 + {
  504 + "examQuestionId|+1": 0,
  505 + "questionId|+1": 1,
  506 + "questionTitle": "@cname",
  507 + "questionType|1-4": 1,
  508 + "score|1-2": 1,
  509 + "subQuestions": [
  510 + {
  511 + id: 7,
  512 + "questionType": 2,
  513 + "score": 2,
  514 + },
  515 + {
  516 + id: 8,
  517 + "questionType": 2,
  518 + "score": 3,
  519 + },
  520 + {
  521 + id: 9,
  522 + "questionType": 2,
  523 + "score": 1,
  524 + },
  525 + {
  526 + id: 10,
  527 + "questionType": 2,
  528 + "score": 1,
  529 + },
  530 + {
  531 + id: 11,
  532 + "questionType": 2,
  533 + "score": 1,
  534 + },
  535 + {
  536 + id: 12,
  537 + "questionType": 3,
  538 + "score": 1,
  539 + },
  540 + {
  541 + id: 13,
  542 + "questionType": 2,
  543 + "score": 1,
  544 + },
  545 + {
  546 + id: 14,
  547 + "questionType": 2,
  548 + "score": 1,
  549 + },
  550 + {
  551 + id: 15,
  552 + "questionType": 2,
  553 + "score": 1,
  554 + },
  555 + {
  556 + id: 16,
  557 + "questionType": 2,
  558 + "score": 1,
  559 + }
  560 + ]
  561 + },
  562 + ]
  563 + }, {
  564 + "studentId": "@id",
  565 + "studentName": "@cname",
  566 + "questionList": [
  567 + {
  568 + "examQuestionId|+1": 0,
  569 + "questionId|+1": 1,
  570 + "questionTitle": "@cname",
  571 + "questionType|1-4": 1,
  572 + "score|1-2": 1,
  573 + "subQuestions": [
  574 + {
  575 + id: 1,
  576 + "questionType": 2,
  577 + "score": 1,
  578 + },
  579 + {
  580 + id: 2,
  581 + "questionType": 2,
  582 + "score": 2,
  583 + },
  584 + {
  585 + id: 3,
  586 + "questionType": 2,
  587 + "score": 1,
  588 + },
  589 + {
  590 + id: 4,
  591 + "questionType": 2,
  592 + "score": 1,
  593 + },
  594 + {
  595 + id: 5,
  596 + "questionType": 2,
  597 + "score": 1,
  598 + },
  599 + {
  600 + id: 6,
  601 + "questionType": 3,
  602 + "score": 1,
  603 + },
  604 + ]
  605 + },
  606 + {
  607 + "examQuestionId|+1": 0,
  608 + "questionId|+1": 1,
  609 + "questionTitle": "@cname",
  610 + "questionType|1-4": 1,
  611 + "score|1-2": 1,
  612 + "subQuestions": [
  613 + {
  614 + id: 7,
  615 + "questionType": 2,
  616 + "score": 2,
  617 + },
  618 + {
  619 + id: 8,
  620 + "questionType": 2,
  621 + "score": 3,
  622 + },
  623 + {
  624 + id: 9,
  625 + "questionType": 2,
  626 + "score": 1,
  627 + },
  628 + {
  629 + id: 10,
  630 + "questionType": 2,
  631 + "score": 1,
  632 + },
  633 + {
  634 + id: 11,
  635 + "questionType": 2,
  636 + "score": 1,
  637 + },
  638 + {
  639 + id: 12,
  640 + "questionType": 3,
  641 + "score": 1,
  642 + },
  643 + {
  644 + id: 13,
  645 + "questionType": 2,
  646 + "score": 1,
  647 + },
  648 + {
  649 + id: 14,
  650 + "questionType": 2,
  651 + "score": 1,
  652 + },
  653 + {
  654 + id: 15,
  655 + "questionType": 2,
  656 + "score": 1,
  657 + },
  658 + {
  659 + id: 16,
  660 + "questionType": 2,
  661 + "score": 1,
  662 + }
  663 + ]
  664 + },
  665 + ]
  666 + }],
  667 + }
  668 +}
  669 +)
  670 +Mock.mock(
  671 + "/api_html/class/manager/phaseExamReport", {
  672 + info: "success",
  673 + status: 0,
  674 + data: {
  675 + "list": [{
  676 + "studentId": "@id",
  677 + "studentName": "@cname",
  678 + "dataList": [
  679 + {
  680 + "subjectName": "数学",
  681 + "examCount": '5',
  682 + "participationCount": '5',
  683 + "classRank": '1',
  684 + "score": '100',
  685 + "participationRate":'88',
  686 + "correctRate":'90',
  687 + },
  688 + {
  689 + "subjectName": "英语",
  690 + "examCount": '5',
  691 + "participationCount": '5',
  692 + "classRank": '2',
  693 + "score": '100',
  694 + "participationRate":'70',
  695 + "correctRate":'76',
  696 + },
  697 + {
  698 + "subjectName": "语文",
  699 + "examCount": '5',
  700 + "participationCount": '5',
  701 + "classRank": '2',
  702 + "score": '100',
  703 + "participationRate":'99',
  704 + "correctRate":'100',
  705 + },
  706 + ]
  707 + }],
  708 + }
  709 +}
211 710 )
212 711 \ No newline at end of file
... ...
src/router/index.js
... ... @@ -22,6 +22,7 @@ const AskList = () =&gt; import(&quot;@/views/basic/ask/list&quot;)
22 22 const AskAnalysis = () => import("@/views/basic/ask/analysis")
23 23 const AskArchiving = () => import("@/views/basic/ask/archiving")
24 24 const Test = () => import("@/views/basic/test/index")
  25 +const TestList = () => import("@/views/basic/test/list")
25 26 const TestAnalysis = () => import("@/views/basic/test/analysis")
26 27 const TestArchiving = () => import("@/views/basic/test/archiving")
27 28 const DataSync = () => import("@/views/basic/dataSync/index")
... ... @@ -214,9 +215,6 @@ let addrouters = [
214 215 iconCls: "fa fa-bar-chart", // 图标样式class
215 216 name: "随堂问报表",
216 217 component: Ask,
217   - meta: {
218   - keepAlive: true,
219   - },
220 218 children: []
221 219  
222 220 },
... ... @@ -260,18 +258,23 @@ let addrouters = [
260 258 iconCls: "fa fa-pie-chart", // 图标样式class
261 259 name: "",
262 260 component: Test,
263   - meta: {
264   - keepAlive: true,
265   - },
266 261 children: []
267 262 },
268 263 {
269   - path: "/testAnalysis",
270   - iconCls: "", // 图标样式class
271   - name: "即时测报表分析",
272   - component: TestAnalysis,
273   - parent: "test",
274   - children: []
  264 + path: "/testList",
  265 + name: "",
  266 + component: TestList,
  267 +
  268 + children: [
  269 + {
  270 + path: "/testAnalysis",
  271 + iconCls: "", // 图标样式class
  272 + name: "即时测报表分析",
  273 + component: TestAnalysis,
  274 + parent: "test",
  275 + children: []
  276 + },
  277 + ]
275 278 },
276 279 {
277 280 path: "/testArchiving",
... ...
src/views/basic/ask/index.vue
... ... @@ -97,8 +97,8 @@ export default {
97 97  
98 98 methods: {
99 99 handleCheckAllChange(val) {
  100 + this.isIndeterminate = false;
100 101 this.query.subjectNames = val ? this.subjectList : [];
101   - this.allSubject = false;
102 102 },
103 103 handleChecked(value) {
104 104 console.log(value)
... ...
src/views/basic/test/analysis.vue
... ... @@ -2,1013 +2,85 @@
2 2 <div ref="main" class="page-container">
3 3 <back-box>
4 4 <template slot="title">
5   - <span>单卷分析</span>
  5 + <span>{{ type == 1 ? '单卷测练报表' : type == 2 ? subject + "汇总报表" : type == 3 ? "多科汇总报表" :
  6 + `多班_${subjectName}_${title}_测练成绩对比分析` }}</span>
6 7 </template>
7 8 </back-box>
8   - <div class="tips" v-if="paperModifyLog.modifiedTime && !status">
9   - <p class="tips-p">
10   - <i class="fa fa-bell-o"></i>
11   - {{
12   - `${paperModifyLog.modifiedTime} ${paperModifyLog.realName}`
13   - }}修改了答案,是否重新记分?
14   - </p>
15   - <div class="btn-box">
16   - <el-button type="danger" round @click="_ReScore" size="mini"
17   - >重新计分</el-button
18   - >
19   - <el-button
20   - type="danger"
21   - round
22   - plain
23   - size="mini"
24   - @click="paperModifyLog.modifiedTime = ''"
25   - >暂时不计</el-button
26   - >
27   - </div>
28   - </div>
29   - <div class="page-content">
30   - <div class="content-header">
31   - <div class="tab-box">
32   - <span
33   - v-for="(item, index) in tabList"
34   - :key="item"
35   - class="tab-item"
36   - :class="type == index ? 'active' : ''"
37   - @click="setType(index)"
38   - >{{ item }}</span
39   - >
40   - </div>
41   - <el-button
42   - v-if="!status"
43   - class="setMinScore"
44   - @click="diaMinScore = true"
45   - round
46   - size="small"
47   - >设置低分值</el-button
48   - >
49   - </div>
50   - <div id="print-content" class="table-box" v-loading="loading">
51   - <el-table
52   - :max-height="tableMaxHeight"
53   - v-show="type == 0"
54   - :data="tableData"
55   - border
56   - style="width: 100%"
57   - >
58   - <el-table-column
59   - prop="questionIndex"
60   - label="题号"
61   - align="center"
62   - fixed
63   - width="60"
64   - ></el-table-column>
65   - <el-table-column
66   - prop="questionType"
67   - label="题型"
68   - align="center"
69   - fixed
70   - width="100"
71   - ><template slot-scope="scope">{{
72   - setSubPro(scope.row.questionType)
73   - }}</template></el-table-column
74   - >
75   - <el-table-column
76   - prop="score"
77   - width="100"
78   - label="满分值"
79   - sortable
80   - align="center"
81   - ></el-table-column>
82   - <el-table-column
83   - width="110"
84   - prop="highestScore"
85   - label="班最高分"
86   - sortable
87   - align="center"
88   - ></el-table-column>
89   - <el-table-column
90   - width="110"
91   - prop="lowestScore"
92   - label="班最低分"
93   - sortable
94   - align="center"
95   - ></el-table-column>
96   - <el-table-column
97   - width="110"
98   - prop="avgScore"
99   - label="班平均分"
100   - sortable
101   - align="center"
102   - ></el-table-column>
103   - <el-table-column
104   - prop="classScoringRate"
105   - width="120"
106   - sortable
107   - label="班级得分率"
108   - align="center"
109   - ><template slot-scope="scoped"
110   - >{{ scoped.row.classScoringRate }}%</template
111   - ></el-table-column
112   - >
113   - <el-table-column prop="correctAnswer" label="答案" align="center"
114   - ><template slot-scope="scoped">{{
115   - scoped.row.correctAnswer == 1
116   - ? "✓"
117   - : scoped.row.correctAnswer == 2
118   - ? "✗"
119   - : scoped.row.correctAnswer
120   - }}</template>
121   - </el-table-column>
122   - <el-table-column
123   - v-for="(item, index) in optionsList"
124   - :key="index"
125   - :label="item.title"
126   - :prop="'count' + index"
127   - align="center"
128   - width="120"
129   - ><template slot-scope="scope"
130   - ><p class="persent">
131   - {{
132   - scope.row.questionType == "5"
133   - ? ""
134   - : scope.row["option" + index]
135   - ? `${scope.row["option" + index]}(${
136   - scope.row["persent" + index]
137   - })`
138   - : ""
139   - }}
140   - </p></template
141   - >
142   - </el-table-column>
143   - </el-table>
144   - <div id="print-table">
145   - <table class="hide">
146   - <thead>
147   - <tr>
148   - <th>题号</th>
149   - <th>题型</th>
150   - <th>满分值</th>
151   - <th>班最高分</th>
152   - <th>班最低分</th>
153   - <th>班平均分</th>
154   - <th>班级得分率</th>
155   - <th>答案</th>
156   - <th>选项1</th>
157   - <th>选项2</th>
158   - <th>选项3</th>
159   - <th>选项4</th>
160   - <th>未答</th>
161   - </tr>
162   - </thead>
163   - <tbody>
164   - <tr v-for="(tr, index) in tableData">
165   - <td width="60">{{ index + 1 }}</td>
166   - <td width="100">{{ setSubPro(tr.questionType) }}</td>
167   - <td width="100">{{ tr.sortable }}</td>
168   - <td width="110">{{ tr.highestScore }}</td>
169   - <td width="110">{{ tr.lowestScore }}</td>
170   - <td width="110">{{ tr.avgScore }}</td>
171   - <td width="120">{{ tr.classScoringRate }}%</td>
172   - <td>
173   - {{
174   - tr.correctAnswer == 1
175   - ? "✓"
176   - : tr.correctAnswer == 2
177   - ? "✗"
178   - : tr.correctAnswer
179   - }}
180   - </td>
181   - <td
182   - v-for="(item, index) in optionsList"
183   - :key="index"
184   - width="120"
185   - >
186   - <p class="persent">
187   - {{
188   - tr.questionType == "5"
189   - ? ""
190   - : tr["option" + index]
191   - ? `${tr["option" + index]}(${tr["persent" + index]})`
192   - : ""
193   - }}
194   - </p>
195   - </td>
196   - </tr>
197   - </tbody>
198   - </table>
199   - <div class="hui-box" v-show="type == 0">
200   - <span class="s-txt">汇总</span>
201   - <ul class="hui-ul">
202   - <li class="hui-li">
203   - <span class="hui-s s1">主观题</span>
204   - <span class="hui-s s1">{{ examReport.subjectiveScore }}</span>
205   - <span class="hui-s s2">{{
206   - examReport.subjectiveHighestScore
207   - }}</span>
208   - <span class="hui-s s2">{{
209   - examReport.subjectiveLowestScore
210   - }}</span>
211   - <span class="hui-s s2">{{
212   - examReport.subjectiveAvgScore
213   - }}</span>
214   - <span class="hui-s s3"
215   - >{{ examReport.subjectiveClassScoringRate }}%</span
216   - >
217   - </li>
218   - <li class="hui-li">
219   - <span class="hui-s s1">客观题</span>
220   - <span class="hui-s s1">{{ examReport.objectiveScore }}</span>
221   - <span class="hui-s s2">{{
222   - examReport.objectiveHighestScore
223   - }}</span>
224   - <span class="hui-s s2">{{
225   - examReport.objectiveLowestScore
226   - }}</span>
227   - <span class="hui-s s2">{{ examReport.objectiveAvgScore }}</span>
228   - <span class="hui-s s3"
229   - >{{ examReport.objectiveClassScoringRate }}%</span
230   - >
231   - </li>
232   - <li class="hui-li">
233   - <span class="hui-s s1">整卷</span>
234   - <span class="hui-s s1">{{ examReport.examPaperScore }}</span>
235   - <span class="hui-s s2">{{ examReport.highestScore }}</span>
236   - <span class="hui-s s2">{{ examReport.lowestScore }}</span>
237   - <span class="hui-s s2">{{ examReport.avgScore }}</span>
238   - <span class="hui-s s3">{{ examReport.classScoringRate }}%</span>
239   - </li>
240   - </ul>
241   - </div>
242   - </div>
243   - <el-table
244   - v-show="type == 1"
245   - :max-height="tableMaxHeight"
246   - :data="tableData2"
247   - border
248   - style="width: 100%"
249   - :default-sort="{ prop: 'dadui', order: 'descending' }"
250   - >
251   - <el-table-column
252   - prop="studentCode"
253   - label="学号"
254   - align="center"
255   - fixed
256   - ></el-table-column>
257   - <el-table-column
258   - prop="studentName"
259   - label="姓名"
260   - fixed
261   - align="center"
262   - ></el-table-column>
263   - <el-table-column
264   - prop="examScore"
265   - label="总分"
266   - sortable
267   - align="center"
268   - ></el-table-column>
269   - <el-table-column
270   - prop="scoringRate"
271   - label="得分率"
272   - sortable
273   - align="center"
274   - ><template slot-scope="scope"
275   - >{{ scope.row.scoringRate }}%</template
276   - ></el-table-column
277   - >
278   - <el-table-column
279   - prop="classRank"
280   - label="班名"
281   - sortable
282   - align="center"
283   - ></el-table-column>
284   - <el-table-column label="客观题" align="center">
285   - <el-table-column
286   - prop="objectiveExamScore"
287   - label="得分"
288   - align="center"
289   - ></el-table-column>
290   - <el-table-column
291   - prop="objectiveScoringRate"
292   - label="得分率"
293   - align="center"
294   - ><template slot-scope="scope"
295   - >{{ scope.row.objectiveScoringRate }}%</template
296   - ></el-table-column
297   - >
298   - </el-table-column>
299   - <el-table-column label="主观题" align="center">
300   - <el-table-column
301   - prop="subjectiveExamScore"
302   - label="得分"
303   - align="center"
304   - ></el-table-column>
305   - <el-table-column
306   - prop="subjectiveScoringRate"
307   - label="得分率"
308   - align="center"
309   - ><template slot-scope="scope"
310   - >{{ scope.row.subjectiveScoringRate }}%</template
311   - ></el-table-column
312   - >
313   - </el-table-column>
314   - </el-table>
315   - <el-table
316   - v-show="type == 2"
317   - :max-height="tableMaxHeight"
318   - :data="tableData2"
319   - border
320   - style="width: 100%"
321   - :default-sort="{ prop: '', order: 'descending' }"
322   - >
323   - <el-table-column
324   - prop="studentCode"
325   - label="学号"
326   - fixed
327   - align="center"
328   - width="120"
329   - ></el-table-column>
330   - <el-table-column
331   - prop="studentName"
332   - label="姓名"
333   - fixed
334   - align="center"
335   - ></el-table-column>
336   - <el-table-column
337   - prop="examScore"
338   - label="总分"
339   - sortable
340   - align="center"
341   - ></el-table-column>
342   - <el-table-column label="分数组成" align="center">
343   - <el-table-column
344   - prop="objectiveExamScore"
345   - label="客观题分"
346   - align="center"
347   - ></el-table-column>
348   - <el-table-column
349   - prop="subjectiveExamScore"
350   - label="主观题分"
351   - align="center"
352   - ></el-table-column>
353   - </el-table-column>
354   - <el-table-column
355   - align="center"
356   - v-for="(item, index) in questionList"
357   - :key="index"
358   - :label="'Q' + item.id"
359   - :prop="'score' + item.id"
360   - >
361   - </el-table-column>
362   - </el-table>
363   - <el-table
364   - :max-height="tableMaxHeight"
365   - v-show="type == 3"
366   - :data="tableData2"
367   - border
368   - style="width: 100%"
369   - :default-sort="{ prop: '', order: 'descending' }"
370   - >
371   - <el-table-column
372   - prop="studentCode"
373   - label="学号"
374   - fixed
375   - align="center"
376   - ></el-table-column>
377   - <el-table-column
378   - prop="studentName"
379   - label="姓名"
380   - fixed
381   - align="center"
382   - ></el-table-column>
383   - <el-table-column
384   - prop="className"
385   - label="班级"
386   - align="center"
387   - ></el-table-column>
388   - <el-table-column
389   - prop="examScore"
390   - label="总分"
391   - sortable
392   - align="center"
393   - ></el-table-column>
394   - <el-table-column
395   - align="center"
396   - v-for="(item, index) in questionList"
397   - :key="index"
398   - :label="'Q' + item.id"
399   - >
400   - <template slot-scope="scope">
401   - <span v-if="tableData[index]?.questionType == 5">*</span>
402   - <span
403   - v-else-if="scope.row['answer' + item.id]"
404   - :class="scope.row['isRight' + item.id] ? '' : 'error'"
405   - >
406   - {{ scope.row["answer" + item.id] }}
407   - </span>
408   - <span
409   - v-else
410   - :class="scope.row['questionType' + item.id] == 5 ? '' : 'error'"
411   - >-</span
412   - >
413   - </template>
414   - </el-table-column>
415   - </el-table>
416   - </div>
417   - <div class="down">
418   - <div>
419   - <el-button
420   - @click="exportData"
421   - type="primary"
422   - plain
423   - round
424   - icon="fa fa-cloud-download"
425   - >导出报表</el-button
426   - >
427   - <el-button
428   - v-if="!this.$store.getters.code"
429   - @click="print"
430   - type="primary"
431   - plain
432   - round
433   - icon="el-icon-printer"
434   - >打印</el-button
435   - >
436   - </div>
437   - <div v-if="!status">
438   - <el-button
439   - v-if="examReport.subjectiveScore != 0"
440   - @click="diaUp = true"
441   - type="primary"
442   - round
443   - v-loading="exportLoading"
444   - >导入主观题分数</el-button
445   - >
446   - <template v-if="role == 'ROLE_JIAOSHI'">
447   - <el-button
448   - @click="edit"
449   - type="primary"
450   - v-if="examReport.subjectiveScore != examReport.examPaperScore"
451   - round
452   - >查看题目</el-button
453   - ></template
454   - >
455   - </div>
456   - </div>
457   - <el-dialog
458   - :close-on-click-modal="false"
459   - title="导入主观题分数"
460   - :visible.sync="diaUp"
461   - width="600"
462   - >
463   - <upload :url="url" :examId="id" @upSuccess="upSuccess">
464   - <template slot="down">
465   - <p class="down-txt">
466   - 第一步:下载模板并编辑完成学生分数
467   - <el-link type="danger" @click="downExcel">模板下载</el-link> 。
468   - </p>
469   - <p class="down-txt">第二步:上传完成编辑的模板文件并导入。</p>
470   - </template>
471   - </upload>
472   - <div class="dialog-footer" slot="footer">
473   - <el-button @click="diaUp = false">取 消</el-button>
474   - </div>
475   - </el-dialog>
476   - <el-dialog
477   - :close-on-click-modal="false"
478   - title="低分区间设置"
479   - :visible.sync="diaMinScore"
480   - width="480px"
481   - @closed="closeDiaMinScore"
482   - >
483   - <el-form>
484   - <el-form-item label="低分设置模式:">
485   - <el-select v-model="lowRange.type" @change="changeScore">
486   - <el-option label="按分数设置" :value="0"></el-option>
487   - <el-option label="按已考人数比例" :value="1"></el-option>
488   - <el-option label="按分数比例设置(按题目)" :value="2"></el-option>
489   - </el-select>
490   - </el-form-item>
491   - <el-form-item label="低分区间:">
492   - <el-input
493   - class="score-ipt"
494   - type="number"
495   - v-model="lowRange.range[0]"
496   - :min="0"
497   - :max="100"
498   - @input="lowRange.range[1] > 100 ? (lowRange.range[1] = 100) : ''"
499   - @keydown.native="keydownRange($event)"
500   - ></el-input
501   - >{{ lowRange.type != 0 ? "%" : "分" }}(含)
502   - <el-input
503   - class="score-ipt"
504   - type="number"
505   - v-model="lowRange.range[1]"
506   - :min="0"
507   - :max="100"
508   - @input="lowRange.range[1] > 100 ? (lowRange.range[1] = 100) : ''"
509   - @keydown.native="keydownRange($event)"
510   - ></el-input
511   - >{{ lowRange.type != 0 ? "%" : "分" }}(含)
512   - </el-form-item>
513   - </el-form>
514   -
515   - <div
516   - class="dialog-footer"
517   - slot="footer"
518   - align="center"
519   - v-loading="loadingTange"
520   - >
521   - <el-button type="danger" @click="_SavelowRange">保存</el-button>
522   - <el-button @click="diaMinScore = false">取 消</el-button>
523   - </div>
524   - </el-dialog>
525   - </div>
  9 + <Test v-if="type == 1" :role="role" :id="id" :classId="classId" :subjectName="subjectName" :title="title" />
  10 + <MultipleTest v-else-if="type == 2" :role="role" :ids="ids" :classId="classId" :subjectName="subjectName" />
  11 + <MultipleSubTest v-else-if="type == 3" :role="role" :ids="ids" :classId="classId" :subjectName="subjectName" />
  12 + <Contrast v-else-if="type == 4" :role="role" :ids="ids" :subjectName="subjectName" :title="title" />
526 13 </div>
527 14 </template>
528 15  
529 16 <script>
530   -import { downloadFile, tablePrint } from "@/utils";
  17 +import Test from "./components/test.vue"
  18 +import MultipleTest from "./components/multipleTest.vue"
  19 +import MultipleSubTest from "./components/multipleSubTest.vue"
  20 +import Contrast from "./components/contrast.vue"
531 21 export default {
  22 + components: {
  23 + Test,
  24 + MultipleTest,
  25 + MultipleSubTest,
  26 + Contrast
  27 + },
532 28 data() {
533 29 return {
534 30 role: "",
535   - status: 0,// 1:已归档试卷
536   - tableMaxHeight: 600,
537   - loading: false,
538   - exportLoading: false,
539   - diaUp: false,
540   - url: "/api_html/teaching/importSubjectiveScore",
541 31 id: "",
542   - classId: "",
543   - subjectName: "",
544   - title: "",
545   - score: "",
546   - tabList: ["试题分析", "成绩排名", "小题分报表", "作答明细表"],
  32 + ids: [],
547 33 type: 0,
548   - paperModifyLog: { //修改信息
549   - realName: "",
550   - modifiedTime: "",
551   - },
552   - examReport: {
553   - subjectiveScore: 0,
554   - subjectiveHighestScore: "",
555   - subjectiveLowestScore: "",
556   - subjectiveAvgScore: "",
557   - subjectiveClassScoringRate: "",
558   - objectiveScore: "",
559   - objectiveHighestScore: "",
560   - objectiveLowestScore: "",
561   - objectiveAvgScore: "",
562   - objectiveClassScoringRate: "",
563   - examPaperScore: "",
564   - highestScore: "",
565   - lowestScore: "",
566   - avgScore: "",
567   - classScoringRate: "",
568   - },
569   - tableData: [],
570   - optionsList: [],
571   - tableData2: [],
572   - questionList: [],
573   - page: 1,
574   - size: 20,
575   - total: 0,
576   - // 设置低分值
577   - loadingTange: false,
578   - diaMinScore: false,
579   - lowRange: {
580   - type: 0,
581   - range: [60, 0],
582   - },
583   - defaultLowRange: {
584   - type: 0,
585   - range: [],
586   - },
  34 + classId: "",
  35 + subjectName: '',
  36 + title: ''
587 37 };
588 38 },
589 39 created() {
590 40 this.role =
591 41 this.$store.getters.info.showRole ||
592 42 this.$store.getters.info.permissions[0].role;
593   - this.id = this.$route.query.id;
594   - this.status = this.$route.query.status ? this.$route.query.status : 0;
595   - this.title = this.$route.query.title || "";
  43 + this.id = this.$route.query.id || "";
  44 + this.ids = this.$route.query.ids && this.$route.query.ids.split() || "";
  45 + this.type = this.$route.query.type
596 46 this.classId = this.$route.query.classId || "";
597   - this.subjectName = this.$route.query.subjectName || "";
598   - this._QueryData();
  47 + this.subjectName = this.$route.query.subjectName || ""
  48 + this.title = this.$route.query.title || ""
599 49 },
600 50 methods: {
601   - print() {
602   - if (this.type == 0) {
603   - tablePrint("print-table", this.title + this.tabList[this.type], true);
604   - } else {
605   - tablePrint("print-content", this.title + this.tabList[this.type]);
606   - }
607   - },
608   - upSuccess(res) {
609   - //导入成功
610   - this.$message.success("导入成功");
611   - this.diaUp = false;
612   - this._QueryData();
613   - },
614   - setType(type) {
615   - console.log(this.$refs.main.offsetHeight - 50);
616   - this.tableMaxHeight = this.$refs.main.offsetHeight;
617   - this.type = type;
618   - },
619   - setSubPro(type) {
620   - let tit;
621   - switch (type) {
622   - case 2:
623   - tit = "单选题";
624   - break;
625   - case 3:
626   - tit = "多选题";
627   - break;
628   - case 4:
629   - tit = "判断题";
630   - break;
631   - case 5:
632   - tit = "主观题";
633   - break;
634   - }
635   - return tit;
636   - },
637   - edit() {
638   - this.$router.push({
639   - path: "/examinationPaperEdit",
640   - query: {
641   - paperId: this.id,
642   - title: this.title,
643   - type: 2,
644   - },
645   - });
646   - },
647   - changePage(page) {
648   - this.page = page;
649   - this.examQuestionReport();
650   - },
651   - // 切换低分设置类型设置默认分值
652   - changeScore() {
653   - this.lowRange.range = [...this.defaultLowRange.range];
654   - },
655   - // 禁止输入负数
656   - keydownRange(event) {
657   - if (event.key == "-" || event.key == "e") {
658   - event.returnValue = "";
659   - }
660   - },
661   - // 关闭低分设置
662   - closeDiaMinScore() {
663   - this.lowRange.type = this.defaultLowRange.type;
664   - this.lowRange.range = [...this.defaultLowRange.range];
665   - },
666   - // 保存低分设置
667   - async _SavelowRange() {
668   - if(this.lowRange.range[0].trim() == "" || this.lowRange.range[1].trim() == ""){
669   - this.$message.warning("请补全低分设置!");
670   - return
671   - }
672   - this.loadingTange = true;
673   - let { data, status, info } = await this.$request.setLowRange({
674   - classId: this.classId,
675   - subjectName: this.subjectName,
676   - ...this.lowRange,
677   - });
678   - this.loadingTange = false;
679   - if (status === 0) {
680   - this.$message.success(info);
681   - this.diaMinScore = false;
682   - this.examDetail();
683   - } else {
684   - this.$message.error(info);
685   - }
686   - },
687   - async _QueryData() {
688   - this.examDetail();
689   - this.examStudentReport();
690   - this.examQuestionReport();
691   - },
692   - async examDetail() {
693   - //详情
694   - this.loading = true;
695   - let { data, info, status } = await this.$request.examDetail({
696   - examId: this.id,
697   - });
698   - this.loading = false;
699   - if (status === 0) {
700   - if (data.paperModifyLog) {
701   - this.paperModifyLog = { ...data?.paperModifyLog };
702   - }
703   - this.examReport = { ...data?.examReport };
704   - this.defaultLowRange = data.lowRange || {
705   - type: 1,
706   - range: [60, 0],
707   - };
708   - this.lowRange.type = this.defaultLowRange.type;
709   - this.lowRange.range = [...this.defaultLowRange.range];
710   - } else {
711   - this.$message.error(info);
712   - }
713   - },
714   - async _ReScore() {
715   - //重新记分
716   - this.loading = true;
717   - let { data, info, status } = await this.$request.reScore({
718   - examId: this.id,
719   - });
720   - this.loading = false;
721   - if (status === 0) {
722   - this.$message.success(info);
723   - this._QueryData();
724   - this.paperModifyLog.modifiedTime = "";
725   - this.paperModifyLog.realName = "";
726   - } else {
727   - this.$message.error(info);
728   - }
729   - },
730   - async examStudentReport() {
731   - //成绩排名-小题分-作答明细
732   - this.loading = true;
733   - let { data, info, status } = await this.$request.examStudentReport({
734   - examId: this.id,
735   - });
736   - this.loading = false;
737   - if (status === 0) {
738   - let optionsList = [];
739   - this.tableData2 = data?.list.map((item) => {
740   - let params = {};
741   -
742   - const detail = JSON.parse(item.detail);
743   - if (detail.length > optionsList.length) {
744   - optionsList = [...detail];
745   - }
746   - detail.map((items, index) => {
747   - params["que" + items.id] = items.id;
748   - params["score" + items.id] = String(items.score).includes(".")
749   - ? Number(items.score)
750   - : items.score;
751   - params["answer" + items.id] =
752   - items.answer == 1 ? "✓" : items.answer == 2 ? "✗" : items.answer;
753   - params["isRight" + items.id] = items.isRight;
754   - params["questionType" + items.id] = items.questionType;
755   - });
756   - return {
757   - ...item,
758   - ...params,
759   - };
760   - });
761   - console.log();
762   - this.questionList = optionsList.sort((a, b) => {
763   - return a.id - b.id;
764   - });
765   - } else {
766   - this.$message.error(info);
767   - }
768   - },
769   - async examQuestionReport() {
770   - //试题分析
771   - this.loading = true;
772   - let { data, info, status } = await this.$request.examQuestionReport({
773   - examId: this.id,
774   - page: this.page,
775   - // size: this.size,
776   - size: 9999,
777   - });
778   - this.loading = false;
779   - if (status === 0) {
780   - let optionsList = [{}, {}, {}, {}, {}];
781   - let tableData = data?.list.map((item) => {
782   - let params = {};
783   - const detail = JSON.parse(item.detail);
784   - let lastOPtion = detail?.find((item) => {
785   - return item.option == "未答";
786   - });
787   - let defaultArr = detail?.filter((item) => {
788   - return item.option != "未答";
789   - });
790 51  
791   - optionsList.map((items, index) => {
792   - if (index != 4) {
793   - params["count" + index] =
794   - defaultArr[index]?.option != "未答"
795   - ? defaultArr[index]?.count
796   - : "";
797   - params["persent" + index] =
798   - defaultArr[index]?.option != "未答"
799   - ? defaultArr[index]?.persent
800   - : "";
801   - params["option" + index] =
802   - defaultArr[index]?.option != "未答"
803   - ? defaultArr[index]?.option == 1
804   - ? "✓"
805   - : defaultArr[index]?.option == 2
806   - ? "✗"
807   - : defaultArr[index]?.option
808   - : "";
809   - items["title"] = "选项" + (index + 1);
810   - } else {
811   - items["title"] = "未答";
812   - params["count" + index] = lastOPtion.count;
813   - params["persent" + index] = lastOPtion.persent;
814   - params["option" + index] = "?";
815   - }
816   - });
817   - return {
818   - ...item,
819   - ...params,
820   - };
821   - });
822   - this.tableData = tableData.sort((a, b) => {
823   - return a.questionIndex - b.questionIndex;
824   - });
825   - this.optionsList = [...optionsList];
826   - this.total = data.count;
827   - this.setType(0);
828   - } else {
829   - this.$message.error(info);
830   - }
831   - },
832   - //导出
833   - async exportData() {
834   - if (this.exportLoading == true) return;
835   - this.exportLoading = true;
836   - const data = await this.$request.exportExamReport({
837   - examId: this.id,
838   - });
839   - this.exportLoading = false;
840   - if (data) {
841   - let blob = new Blob([data], {
842   - type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
843   - });
844   - downloadFile(
845   - this.status
846   - ? "即时测-已归档单卷测练报表.xlsx"
847   - : "即时测-单卷测练报表.xlsx",
848   - blob
849   - );
850   - } else {
851   - this.$message.error("下载失败");
852   - }
853   - },
854   - async downExcel() {
855   - let data = await this.$request.subjectiveScoreTemplate({
856   - examId: this.id,
857   - });
858   - if (data && !data.code) {
859   - let blob = new Blob([data], {
860   - type: "application/vnd.ms-excel;charset=utf-8",
861   - });
862   - downloadFile(`主观题模版.xlsx`, blob);
863   - } else {
864   - this.$message.error(data.info);
865   - }
866   - },
867   - },
  52 + }
868 53 };
869 54 </script>
870   -<style>
871   -div::-webkit-scrollbar {
872   - width: 3px;
873   - height: 10px;
874   -}
875   -div::-webkit-scrollbar-thumb {
876   - border-radius: 10px;
877   - background-color: #ccc;
878   -}
879   -</style>
880 55 <style lang="scss" scoped>
881   -.hide {
882   - display: none;
883   -}
884 56 .page-container {
885 57 position: relative;
886 58 height: 100%;
  59 +
887 60 .table-box {
888 61 min-height: 100%;
889 62 }
  63 +
890 64 &.active {
891 65 overflow: hidden;
892 66 }
893   - .edit-dia {
894   - position: absolute;
895   - left: 0;
896   - top: 0;
897   - right: 0;
898   - bottom: 0;
899   - width: 100%;
900   - height: calc(100vh - 70px);
901   - background: #fff;
902   - overflow-y: auto;
903   - z-index: 10;
904   - }
905   -}
906   -.persent {
907   - white-space: nowrap;
  67 +
  68 +
908 69 }
  70 +
909 71 .error {
910 72 color: #f30;
911 73 }
  74 +
912 75 .page-content {
913 76 padding: 20px 20px 0;
914 77 }
915   -.tips {
916   - height: 48px;
917   - box-sizing: border-box;
918   - line-height: 48px;
919   - padding: 0 16px;
920   - border: 1px solid #fac7cc;
921   - border-radius: 5px;
922   - background-color: #ffebec;
923   - font-size: 14px;
924   - color: #fd9795;
925   - margin: 10px 20px 0 20px;
926   - display: flex;
927   - &-p {
928   - flex: 1;
929   - }
930   - .fa-bell-o {
931   - font-size: 18px;
932   - margin-right: 5px;
933   - }
934   -}
935   -.tab-box {
936   - width: 800px;
937   - margin: 0 auto 12px;
938   - background: #f8f8f8;
939   - border-radius: 20px;
940   - display: flex;
941   - user-select: none;
942   - .tab-item {
943   - flex: 1;
944   - height: 40px;
945   - line-height: 40px;
946   - text-align: center;
947   - font-size: 16px;
948   - color: #666;
949   - font-weight: 500;
950   - background: transparent;
951   - border-radius: 20px;
952   - cursor: pointer;
953   - &.active {
954   - background: #667ffd;
955   - color: #fff;
956   - }
957   - }
958   -}
  78 +
  79 +
959 80 .down {
960 81 padding-top: 20px;
961 82 width: 100%;
962 83 display: flex;
963 84 justify-content: space-between;
964 85 }
965   -.hui-box {
966   - display: flex;
967   - text-align: center;
968   - .s-txt {
969   - width: 61px;
970   - line-height: 144px;
971   - background: #e2e2e2;
972   - font-size: 16px;
973   - color: #fff;
974   - font-weight: 700;
975   - }
976   - .hui-ul {
977   - border-top: 1px solid #e2e2e2;
978   - }
979   - .hui-li {
980   - display: flex;
981   - .hui-s {
982   - height: 48px;
983   - line-height: 48px;
984   - border-right: 1px solid #e2e2e2;
985   - border-bottom: 1px solid #e2e2e2;
986   - box-sizing: border-box;
987   - }
988   - .s1 {
989   - width: 100px;
990   - }
991   - .s2 {
992   - width: 110px;
993   - }
994   - .s3 {
995   - width: 120px;
996   - }
997   - }
998   -}
999   -
1000   -// 设置低分值
1001   -.content-header {
1002   - width: 100%;
1003   - position: relative;
1004   - .setMinScore {
1005   - position: absolute;
1006   - bottom: 0;
1007   - right: 0px;
1008   - }
1009   -}
1010   -.score-ipt {
1011   - width: 80px;
1012   - margin: 0 5px;
1013   -}
1014 86 </style>
1015 87 \ No newline at end of file
... ...
src/views/basic/test/components/test.vue
... ... @@ -308,7 +308,11 @@ export default {
308 308 range: [],
309 309 },
310 310 //答题录分
311   - diaScoreSet: false
  311 + diaScoreSet: false,
  312 +
  313 + exportType: 1,
  314 + exportStudent: [],
  315 + multipleSelection: [],
312 316 };
313 317 },
314 318 created() {
... ... @@ -563,8 +567,29 @@ export default {
563 567 async exportData() {
564 568 if (this.exportLoading == true) return;
565 569 this.exportLoading = true;
566   - const data = await this.$request.exportExamReport({
  570 + let studentIds = []
  571 + if (length) {
  572 + studentIds = this.exportStudent.slice(0, 10).map(item => {
  573 + return item.studentId
  574 + })
  575 + } else {
  576 + studentIds = this.multipleSelection.map(item => {
  577 + return item.studentId
  578 + })
  579 + }
  580 + let query = {};
  581 + if (studentIds.length == this.exportStudent.length) {
  582 + query.studentIds = []
  583 + } else if (studentIds.length > 0) {
  584 + query.studentIds = studentIds
  585 + }
  586 + const exportExamReport = this.role == "ROLE_PERSONAL" ?
  587 + this.$request.pExportExamReport
  588 + : this.$request.exportExamReport;
  589 +
  590 + const data = await exportExamReport({
567 591 examId: this.id,
  592 + ...query
568 593 });
569 594 this.exportLoading = false;
570 595 if (data) {
... ...
src/views/basic/test/contrast.vue deleted
1   -<template>
2   - <div ref="main" class="page-container">
3   - <back-box>
4   - <template slot="title">
5   - <span>多班_{{ subjectNames }}_{{ title }}_测练成绩对比分析</span>
6   - </template>
7   - </back-box>
8   - <div class="page-content">
9   - <div class="content-header">
10   - <div class="tab-box">
11   - <span
12   - v-for="(item, index) in tabList"
13   - :key="item"
14   - class="tab-item"
15   - :class="type == index ? 'active' : ''"
16   - @click="setType(index)"
17   - >{{ item }}</span
18   - >
19   - </div>
20   - <el-button class="setMinScore" @click="openDia" round size="small"
21   - >对比成绩等级设置</el-button
22   - >
23   - </div>
24   - <div id="print-content" class="table-box" v-loading="loading">
25   - <el-table
26   - :max-height="tableMaxHeight"
27   - v-show="type == 0"
28   - :data="tableData"
29   - border
30   - style="width: 100%"
31   - >
32   - <el-table-column
33   - type="index"
34   - label="序号"
35   - fixed
36   - align="center"
37   - width="60"
38   - ></el-table-column>
39   - <el-table-column
40   - prop="className"
41   - label="班级"
42   - align="center"
43   - fixed
44   - ></el-table-column>
45   - <el-table-column label="测验人数/班级人数" align="center" width="84">
46   - <template slot-scope="scope">
47   - <p v-for="(item, index) in scope.row.count.split('/')">
48   - {{ item }}{{ index == 0 ? "/" : "" }}
49   - </p>
50   - </template>
51   - </el-table-column>
52   - <el-table-column
53   - prop="percent"
54   - label="参与度"
55   - align="center"
56   - ></el-table-column>
57   - <el-table-column
58   - prop="avg"
59   - label="班平均分"
60   - align="center"
61   - ></el-table-column>
62   - <el-table-column
63   - prop="max"
64   - label="班最高分"
65   - sortable
66   - align="center"
67   - ></el-table-column>
68   - <el-table-column
69   - prop="min"
70   - label="班最低分"
71   - sortable
72   - align="center"
73   - ></el-table-column>
74   -
75   - <el-table-column
76   - v-for="(item, index) in defaultLevels.levels"
77   - :label="item[0] + '数(率)'"
78   - align="center"
79   - ><template slot-scope="scoped">
80   - <p class="p1">{{ scoped.row.levels[index].people }}</p>
81   - <p class="p1">({{ scoped.row.levels[index].percent }})</p>
82   - </template></el-table-column
83   - >
84   - </el-table>
85   - <el-table
86   - v-show="type == 1"
87   - :max-height="tableMaxHeight"
88   - :data="tableData2"
89   - border
90   - style="width: 100%"
91   - >
92   - <el-table-column
93   - prop="rank"
94   - label="排名"
95   - sortable
96   - align="center"
97   - ></el-table-column>
98   - <el-table-column
99   - prop="name"
100   - label="姓名"
101   - align="center"
102   - ></el-table-column>
103   - <el-table-column
104   - prop="className"
105   - label="班级"
106   - align="center"
107   - ></el-table-column>
108   - <el-table-column
109   - prop="score"
110   - label="总分"
111   - sortable
112   - align="center"
113   - ></el-table-column>
114   - <el-table-column
115   - prop="levelName"
116   - label="成绩等级"
117   - align="center"
118   - ></el-table-column>
119   - </el-table>
120   - </div>
121   - <div class="down">
122   - <div>
123   - <el-button
124   - v-loading="exportLoading"
125   - @click="exportData"
126   - type="primary"
127   - plain
128   - round
129   - icon="fa fa-cloud-download"
130   - >导出报表</el-button
131   - >
132   - <el-button
133   - v-if="!this.$store.getters.code"
134   - @click="print"
135   - type="primary"
136   - plain
137   - round
138   - icon="el-icon-printer"
139   - >打印</el-button
140   - >
141   - </div>
142   - </div>
143   -
144   - <el-dialog
145   - :close-on-click-modal="false"
146   - title="等级设置"
147   - :visible.sync="diaLogBox"
148   - width="800px"
149   - @closed="closeDia"
150   - >
151   - <el-form class="use-form">
152   - <el-form-item class="use-form-item-box">
153   - <el-form-item label="等级名称:" class="use-form-item">
154   - <el-select
155   - size="small"
156   - v-model="fromData.type"
157   - @change="changeType"
158   - >
159   - <el-option label="优良合格不合格" :value="0"></el-option>
160   - <el-option label="ABCD" :value="1"></el-option>
161   - <el-option label="自定义" :value="2"></el-option>
162   - </el-select>
163   - </el-form-item>
164   - <el-form-item label="等级设置模式:" class="use-form-item">
165   - <el-select size="small" v-model="fromData.levelType">
166   - <el-option label="按分数比例" :value="0"></el-option>
167   - <el-option label="按已考人数比例" :value="1"></el-option>
168   - </el-select>
169   - </el-form-item>
170   - </el-form-item>
171   - <el-form-item>
172   - <div class="dia-tab-box">
173   - <p class="dia-tab-tit">
174   - <span class="item1">编号</span>
175   - <span class="item2"><i>*</i>等级名称</span>
176   - <span class="item3"><i>*</i>等级最高</span>
177   - <span class="item3"><i>*</i>等级最低</span>
178   - <span class="item"></span>
179   - </p>
180   - <div
181   - class="dia-tab-item"
182   - v-for="(item, index) in fromData.levels"
183   - >
184   - <span class="item1">{{ index + 1 }}</span>
185   - <p class="item2">
186   - <el-input
187   - class="score-ipt"
188   - v-model="item[0]"
189   - :maxlength="12"
190   - @keydown.native="keydownRange($event)"
191   - ></el-input>
192   - </p>
193   - <p class="item3">
194   - <el-input
195   - class="score-ipt"
196   - type="number"
197   - v-model="item[1]"
198   - :min="item[2]"
199   - :max="index == 0 ? 100 : fromData.levels[index - 1][2]"
200   - @keydown.native="keydownRange($event)"
201   - ></el-input>
202   - %
203   - <template v-if="fromData.levelType == 0">
204   - ({{ index != 0 ? "不含" : ""
205   - }}{{
206   - Number(((item[1] / 100) * examPaperScore).toFixed(1))
207   - }}分)
208   - </template>
209   - <template v-else>{{ index != 0 ? "不含" : "" }}</template>
210   - </p>
211   - <p>~</p>
212   - <p class="item3">
213   - <el-input
214   - class="score-ipt"
215   - type="number"
216   - v-model="item[2]"
217   - :min="0"
218   - :max="item[1]"
219   - @keydown.native="keydownRange($event)"
220   - ></el-input>
221   - %
222   - <template v-if="fromData.levelType == 0">
223   - ({{
224   - Number(((item[2] / 100) * examPaperScore).toFixed(1))
225   - }}分)
226   - </template>
227   - </p>
228   - <p class="item">
229   - <el-link
230   - type="danger"
231   - :underline="false"
232   - @click="fromData.levels.splice(index, 1)"
233   - >删除</el-link
234   - >
235   - </p>
236   - </div>
237   - <div class="add">
238   - <p @click="fromData.levels.push(['', '', ''])">
239   - <el-button
240   - size="mini"
241   - icon="el-icon-plus"
242   - circle
243   - type="primary"
244   - ></el-button
245   - >添加一行
246   - </p>
247   - </div>
248   - </div>
249   - </el-form-item>
250   - </el-form>
251   -
252   - <div class="dialog-footer" slot="footer" align="center">
253   - <el-button type="danger" @click="savefrom">保存</el-button>
254   - <el-button @click="diaLogBox = false">取 消</el-button>
255   - </div>
256   - </el-dialog>
257   - </div>
258   - </div>
259   -</template>
260   -
261   -<script>
262   -import { downloadFile, tablePrint } from "@/utils";
263   -export default {
264   - data() {
265   - return {
266   - ids: "",
267   - title: "",
268   - subjectNames: "",
269   - tabList: ["班级对比情况", "学生成绩排名"],
270   - type: 0,
271   - loading: false,
272   - exportLoading: false,
273   - diaLogBox: false,
274   - fromData: {
275   - type: 0,
276   - levelType: 0,
277   - levels: [
278   - ["优秀", 100, 90],
279   - ["良好", 89.9, 70],
280   - ["合格", 69.9, 60],
281   - ["不合格", 59.9, 0],
282   - ],
283   - },
284   - defaultLevels: {
285   - levelType: 0,
286   - levels: [],
287   - },
288   - tableMaxHeight: 600,
289   - tableData: [],
290   - tableData2: [],
291   - examPaperScore: 100, //卷面最高分
292   - };
293   - },
294   - async created() {
295   - this.ids = this.$route.query.ids;
296   - await this._QueryData();
297   - await this._QueryDefaultLevels();
298   - },
299   - destroyed() {
300   - sessionStorage.setItem("levelFromData", "");
301   - },
302   - methods: {
303   - // 禁止输入负数
304   - keydownRange(event) {
305   - if (event.key == "-" || event.key == "e") {
306   - event.returnValue = "";
307   - }
308   - },
309   - print() {
310   - tablePrint(
311   - "print-content",
312   - `多班_${this.subjectNames}_${this.title}_测练成绩对比分析`
313   - );
314   - },
315   - setType(type) {
316   - console.log(this.$refs.main.offsetHeight - 50);
317   - this.tableMaxHeight = this.$refs.main.offsetHeight;
318   - this.type = type;
319   - },
320   - openDia() {
321   - this.diaLogBox = true;
322   - },
323   - closeDia() {
324   - let levelFromData = sessionStorage.getItem("levelFromData");
325   - if (levelFromData) {
326   - levelFromData = JSON.parse(levelFromData);
327   - this.fromData.type = levelFromData.type;
328   - this.fromData.levelType = levelFromData.levelType;
329   - this.fromData.levels = [...levelFromData.levels];
330   - } else {
331   - this.fromData.type = 0;
332   - this.fromData.levelType = this.defaultLevels.levelType;
333   - this.fromData.levels = [...this.defaultLevels.levels];
334   - }
335   - },
336   - changeType(val) {
337   - if (val == this.defaultLevels.type) {
338   - this.fromData.levels = [...this.defaultLevels.levels];
339   - } else {
340   - this.fromData.levels = this.fromData.levels.splice(0, 4);
341   - if (val == 0) {
342   - this.fromData.levels = this.fromData.levels.map((item, index) => {
343   - let arrTxt = ["优秀", "良好", "合格", "不合格"];
344   - return [arrTxt[index], item[1], item[2]];
345   - });
346   - } else if (val == 1) {
347   - this.fromData.levels = this.fromData.levels.map((item, index) => {
348   - let arrTxt = ["A", "B", "C", "D"];
349   - return [arrTxt[index], item[1], item[2]];
350   - });
351   - } else {
352   - this.fromData.levels = this.fromData.levels.map((item, index) => {
353   - return ["", item[1], item[2]];
354   - });
355   - }
356   - }
357   - },
358   - savefrom() {
359   - for (let i = 0; i < this.fromData.levels.length; i++) {
360   - if (this.fromData.levels[i].includes("")) {
361   - this.$message.warning("请补全编号" + (i + 1) + "设置信息!");
362   - return;
363   - }
364   - }
365   - if (this.fromData.levels.length == 0) {
366   - this.$message.warning("请添加等级设置!");
367   - return;
368   - }
369   - let nums = [];
370   - let ERR_OK = false;
371   - this.fromData.levels.map((item) => {
372   - nums.push(Number(item[1]));
373   - nums.push(Number(item[2]));
374   - });
375   - for (let i = 0; i < nums.length; i++) {
376   - if (nums[i + 1] && nums[i + 1] > nums[i]) {
377   - ERR_OK = true;
378   - this.$message.warning("高等级比例不能低于低等级比例!请检查");
379   - break;
380   - }
381   - }
382   - if (ERR_OK) return;
383   - this.tableData = [];
384   - this.tableData2 = [];
385   - this.defaultLevels.type = this.fromData.type;
386   - this.defaultLevels.levelType = this.fromData.levelType;
387   - this.defaultLevels.levels = [...this.fromData.levels];
388   - sessionStorage.setItem("levelFromData", JSON.stringify(this.fromData));
389   - this.diaLogBox = false;
390   - this._QueryData({
391   - levelType: this.fromData.levelType,
392   - levels: this.fromData.levels,
393   - });
394   - },
395   -
396   - async _QueryDefaultLevels() {
397   - const { data, info, status } = await this.$request.defaultLevels();
398   - if (status === 0) {
399   - this.defaultLevels = { ...data } || {
400   - levelType: 0,
401   - levels: [
402   - ["优秀", 100, 90],
403   - ["良好", 89.9, 70],
404   - ["合格", 69.9, 60],
405   - ["不合格", 59.9, 0],
406   - ],
407   - };
408   - this.defaultLevels.type = 0
409   - this.fromData.levelType = this.defaultLevels.levelType;
410   - this.fromData.levels = [...this.defaultLevels.levels];
411   - sessionStorage.setItem(
412   - "levelFromData",
413   - JSON.stringify(this.defaultLevels)
414   - );
415   - } else {
416   - this.$message.error(info);
417   - }
418   - },
419   - async _QueryData(params) {
420   - let query = {};
421   - if (params) {
422   - let paramObj = JSON.parse(JSON.stringify(params))
423   - if (paramObj.levelType == 0) {
424   - paramObj.levels = paramObj.levels.map((item) => {
425   - item[1] = ((item[1] / 100) * this.examPaperScore).toFixed(1);
426   - item[2] = ((item[2] / 100) * this.examPaperScore).toFixed(1);
427   - return item;
428   - });
429   - }
430   - query = { ...paramObj };
431   - }
432   - const { data, info, status } = await this.$request.examMultiClassReport({
433   - examIds: this.ids,
434   - ...query,
435   - });
436   - if (status === 0) {
437   - this.title = data.title;
438   - this.examPaperScore = data.examPaperScore || 100;
439   - this.subjectNames = data.subjectName;
440   - this.tableData = data.classes || [];
441   - this.tableData2 =
442   - data.students.map((item) => {
443   - item.score = Number(item.score);
444   - return item;
445   - }) || [];
446   - } else {
447   - this.$message.error(info);
448   - }
449   - },
450   -
451   - //导出
452   - async exportData() {
453   - if (this.exportLoading == true) return;
454   - this.exportLoading = true;
455   - let params = { ...this.fromData };
456   - if (params.levelType == 0) {
457   - params.levels = params.levels.map((item) => {
458   - console.log(item);
459   - item[1] = ((item[1] / 100) * this.examPaperScore).toFixed(1);
460   - item[2] = ((item[2] / 100) * this.examPaperScore).toFixed(1);
461   - return item;
462   - });
463   - }
464   - const data = await this.$request.exportExamMultiReport({
465   - examIds: this.ids,
466   - levels: params.levels,
467   - levelType: params.levelType,
468   - });
469   - this.exportLoading = false;
470   - if (data) {
471   - let blob = new Blob([data], {
472   - type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
473   - });
474   - downloadFile(
475   - `多班_${this.subjectNames}_${this.title}_测练成绩对比分析`,
476   - blob
477   - );
478   - } else {
479   - this.$message.error("下载失败");
480   - }
481   - },
482   - },
483   -};
484   -</script>
485   -
486   -<style lang="scss" scoped>
487   -.page-container {
488   - position: relative;
489   - height: 100%;
490   - .table-box {
491   - min-height: 100%;
492   - }
493   - &.active {
494   - overflow: hidden;
495   - }
496   - .content-header {
497   - width: 100%;
498   - position: relative;
499   - .setMinScore {
500   - position: absolute;
501   - bottom: 0;
502   - right: 0;
503   - }
504   - }
505   - .page-content {
506   - padding: 20px 20px 0;
507   - }
508   -}
509   -.tab-box {
510   - width: 400px;
511   - margin: 0 auto 12px;
512   - background: #f8f8f8;
513   - border-radius: 20px;
514   - display: flex;
515   - user-select: none;
516   - .tab-item {
517   - flex: 1;
518   - height: 40px;
519   - line-height: 40px;
520   - text-align: center;
521   - font-size: 16px;
522   - color: #666;
523   - font-weight: 500;
524   - background: transparent;
525   - border-radius: 20px;
526   - cursor: pointer;
527   - &.active {
528   - background: #667ffd;
529   - color: #fff;
530   - }
531   - }
532   -}
533   -.down {
534   - padding-top: 20px;
535   - width: 100%;
536   - display: flex;
537   - justify-content: space-between;
538   -}
539   -.use-form {
540   - padding: 0 12px;
541   - .use-form-item-box {
542   - :deep(.el-form-item__content) {
543   - display: flex;
544   - }
545   - .use-form-item {
546   - width: 40%;
547   - margin-right: 20px;
548   - }
549   - }
550   -}
551   -.dia-tab-box {
552   - .dia-tab-tit,
553   - .dia-tab-item {
554   - margin-bottom: 10px;
555   - i {
556   - color: #f30;
557   - padding-right: 5px;
558   - }
559   - display: flex;
560   - .item {
561   - width: 40px;
562   - }
563   - .item1 {
564   - padding-left: 10px;
565   - width: 10%;
566   - }
567   - .item2 {
568   - width: 18%;
569   - }
570   - .item3 {
571   - padding-left: 12px;
572   - flex: 1;
573   - }
574   - .score-ipt {
575   - width: 100px;
576   - }
577   - }
578   - .dia-tab-tit {
579   - background: rgba(243, 243, 243, 1);
580   - }
581   - .add {
582   - display: flex;
583   - justify-content: center;
584   - margin: 0 auto;
585   - p {
586   - cursor: pointer;
587   - }
588   - .el-button {
589   - margin-right: 6px;
590   - }
591   - }
592   -}
593   -.p1 {
594   - line-height: 18px;
595   -}
596   -</style>
597 0 \ No newline at end of file
src/views/basic/test/index.vue
1 1 <template>
2   - <div ref="main" class="page-container">
3   - <back-box>
4   - <template slot="title">
5   - <span>即时测-数据报表</span>
6   - </template>
7   - <template slot="btns">
8   - <el-tooltip
9   - v-if="!code && gdClass"
10   - effect="dark"
11   - content="已归档试卷"
12   - placement="bottom"
13   - >
14   - <el-button
15   - type="primary"
16   - icon="fa fa-archive"
17   - size="mini"
18   - plain
19   - circle
20   - @click="toArchiving"
21   - ></el-button>
22   - </el-tooltip>
23   - </template>
24   - </back-box>
25   - <div class="answer-header">
26   - <div class="sel-box">
27   - <el-select
28   - class="sel"
29   - v-model="query.classId"
30   - placeholder="选择班级"
31   - @change="changeclass"
32   - >
33   - <el-option
34   - v-for="item in classList"
35   - :key="item.value"
36   - :label="item.label"
37   - :value="item.value"
38   - >
39   - </el-option>
40   - </el-select>
41   - <el-select
42   - v-if="role == 'ROLE_BANZHUREN'"
43   - class="sel"
44   - multiple
45   - v-model="query.subjectNames"
46   - placeholder="选择科目"
47   - @change="changeSub"
48   - >
49   - <el-option
50   - v-for="item in subjectList"
51   - :key="item.value"
52   - :label="item.label"
53   - :value="item.value"
54   - >
55   - </el-option>
56   - </el-select>
57   - <el-select
58   - v-else
59   - class="sel"
60   - v-model="query.subjectNames"
61   - placeholder="选择科目"
62   - >
63   - <el-option
64   - v-for="item in subjectList"
65   - :key="item.value"
66   - :label="item.label"
67   - :value="item.value"
68   - >
69   - </el-option>
70   - </el-select>
71   - <div class="d1">
72   - <el-date-picker
73   - v-model="query.startDay"
74   - type="date"
75   - @change="handleChangeTimeStart"
76   - placeholder="选择日期时间"
77   - value-format="yyyy-MM-dd"
78   - >
79   - </el-date-picker>
80   - ~
81   - <el-date-picker
82   - v-model="query.endDay"
83   - type="date"
84   - placeholder="选择日期时间"
85   - @change="handleChangeTimeEnd"
86   - value-format="yyyy-MM-dd"
87   - >
88   - </el-date-picker>
  2 + <div class="main" ref="main">
  3 + <div class="sel-dia">
  4 + <p class="tit">
  5 + <span>报表数据配置</span>
  6 + <i class="el-icon-close" @click="goHome"></i>
  7 + </p>
  8 + <div class="select-box">
  9 + <div class="sel-item sel-item2">
  10 + <span class="sel-label">班级:</span>
  11 + <div class="sel-d">
  12 + <p class="p-all">
  13 + <el-checkbox :indeterminate="isIndeterminateClass" v-model="allClass"
  14 + @change="handleCheckAllChangeClass">全选</el-checkbox>
  15 + </p>
  16 + <p class="sel-p">
  17 + <el-checkbox-group v-model="query.classId" @change="changeclass">
  18 + <el-checkbox v-for="item in classList" :label="item.value" :key="item.value">{{ item.label
  19 + }}</el-checkbox>
  20 + </el-checkbox-group>
  21 + </p>
  22 + </div>
89 23 </div>
90   - <p class="p1">
91   - <span @click="setDate(1)" :class="[date == 1 ? 'active' : '', 's1']"
92   - >今天</span
93   - >
94   - <span @click="setDate(2)" :class="[date == 2 ? 'active' : '', 's1']"
95   - >本周</span
96   - >
97   - <span @click="setDate(3)" :class="[date == 3 ? 'active' : '', 's1']"
98   - >本月</span
99   - >
100   - <span @click="setDate(4)" :class="[date == 4 ? 'active' : '', 's1']"
101   - >本季度</span
102   - >
103   - </p>
104   - <el-button type="primary" round @click="_QueryData()">筛选</el-button>
105   - </div>
106   - </div>
107   - <div class="table-box">
108   - <el-radio-group
109   - v-model="tabIndex"
110   - @change="changeTab"
111   - style="margin-bottom: 20px"
112   - >
113   - <template v-for="(item, index) in tabList">
114   - <el-radio-button
115   - v-if="index == 0 || query.startDay != query.endDay"
116   - :key="index"
117   - :label="index + 1"
118   - >{{ item }}</el-radio-button
119   - >
120   - </template>
121   - </el-radio-group>
122   - <div v-show="tabIndex == 1" v-loading="loading">
123   - <el-table :data="tableData" border style="width: 100%">
124   - <el-table-column
125   - prop="title"
126   - label="试卷名称"
127   - fixed
128   - align="center"
129   - ></el-table-column>
130   - <el-table-column
131   - prop="examPaperScore"
132   - label="卷面分"
133   - align="center"
134   - width="68"
135   - ></el-table-column>
136   - <el-table-column prop="answeredNum" label="测验人数" align="center"
137   - ><template slot-scope="scoped">{{
138   - `${scoped.row.answeredNum}/${scoped.row.classPersonNum}`
139   - }}</template></el-table-column
140   - >
141   - <el-table-column
142   - prop="examStartTime"
143   - label="测验时间"
144   - width="100"
145   - align="center"
146   - ></el-table-column>
147   - <el-table-column prop="avgScore" label="班平均分" align="center"
148   - ><template slot-scope="scoped">{{
149   - (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
150   - scoped.row.answerNum == 0) &&
151   - scoped.row.recordStatus == 0
152   - ? "-"
153   - : scoped.row.avgScore
154   - }}</template></el-table-column
155   - >
156   - <el-table-column prop="highestScore" label="班最高分" align="center"
157   - ><template slot-scope="scoped">{{
158   - (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
159   - scoped.row.answerNum == 0) &&
160   - scoped.row.recordStatus == 0
161   - ? "-"
162   - : scoped.row.highestScore
163   - }}</template></el-table-column
164   - >
165   - <el-table-column prop="lowestScore" label="班最低分" align="center"
166   - ><template slot-scope="scoped">{{
167   - (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
168   - scoped.row.answerNum == 0) &&
169   - scoped.row.recordStatus == 0
170   - ? "-"
171   - : scoped.row.lowestScore
172   - }}</template></el-table-column
173   - >
174   - <el-table-column
175   - prop="excellenRate"
176   - label="优秀数(率)"
177   - sortable
178   - align="center"
179   - width="110"
180   - class-name="p0"
181   - ><template slot-scope="scoped">
182   - <p
183   - v-if="
184   - (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
185   - scoped.row.answerNum == 0) &&
186   - scoped.row.arecordStatus == 0
187   - "
188   - >
189   - "-"
190   - </p>
191   - <template v-else>
192   - <p>{{ scoped.row.excellenNum }}</p>
193   - <p v-if="scoped.row.excellenNum">
194   - {{ `(${scoped.row.excellenRate}%)` }}
195   - </p>
196   - </template>
197   - </template></el-table-column
198   - >
199   - <el-table-column
200   - prop="goodRate"
201   - label="良好数(率)"
202   - sortable
203   - align="center"
204   - width="110"
205   - class-name="p0"
206   - ><template slot-scope="scoped">
207   - <p
208   - v-if="
209   - (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
210   - scoped.row.answerNum == 0) &&
211   - scoped.row.arecordStatus == 0
212   - "
213   - >
214   - "-"
215   - </p>
216   - <template v-else>
217   - <p>{{ scoped.row.goodNum }}</p>
218   - <p v-if="scoped.row.goodNum">
219   - {{ `(${scoped.row.goodRate}%)` }}
220   - </p>
221   - </template>
222   - </template></el-table-column
223   - >
224   - <el-table-column
225   - prop="passRate"
226   - label="及格数(率)"
227   - sortable
228   - align="center"
229   - width="110"
230   - class-name="p0"
231   - ><template slot-scope="scoped">
232   - <p
233   - v-if="
234   - (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
235   - scoped.row.answerNum == 0) &&
236   - scoped.row.arecordStatus == 0
237   - "
238   - >
239   - "-"
240   - </p>
241   - <template v-else>
242   - <p>{{ scoped.row.passNum }}</p>
243   - <p v-if="scoped.row.passNum">
244   - {{ `(${scoped.row.passRate}%)` }}
245   - </p>
246   - </template>
247   - </template></el-table-column
248   - >
249   - <el-table-column
250   - prop="failedRate"
251   - label="不及格数(率)"
252   - sortable
253   - align="center"
254   - width="130"
255   - class-name="p0"
256   - ><template slot-scope="scoped">
257   - <p
258   - v-if="
259   - (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
260   - scoped.row.answerNum == 0) &&
261   - scoped.row.arecordStatus == 0
262   - "
263   - >
264   - "-"
265   - </p>
266   - <template v-else>
267   - <p>{{ scoped.row.failedNum }}</p>
268   - <p v-if="scoped.row.failedNum">
269   - {{ `(${scoped.row.failedRate}%)` }}
270   - </p>
271   - </template>
272   - </template></el-table-column
273   - >
274   - <el-table-column label="操作" align="center">
275   - <template slot-scope="scoped">
276   - <el-tooltip
277   - v-if="
278   - scoped.row.answerNum != 0 ||
279   - (scoped.row.recordStatus != 0 &&
280   - scoped.row.subjectiveScore == scoped.row.examPaperScore)
281   - "
282   - effect="dark"
283   - content="详情"
284   - placement="top"
285   - >
286   - <el-button
287   - type="primary"
288   - circle
289   - size="mini"
290   - icon="fa fa-arrow-right"
291   - @click="linkTo(scoped.row)"
292   - ></el-button>
293   - </el-tooltip>
294   - <template
295   - v-if="
296   - scoped.row.answerNum == 0 &&
297   - scoped.row.subjectiveScore != scoped.row.examPaperScore
298   - "
299   - >
300   - <el-tooltip
301   - v-if="role == 'ROLE_JIAOSHI'"
302   - effect="dark"
303   - content="设置答案"
304   - placement="top"
305   - >
306   - <el-button
307   - type="primary"
308   - circle
309   - size="mini"
310   - icon="fa fa-file-text"
311   - @click="edit(scoped.row)"
312   - ></el-button>
313   - </el-tooltip>
314   - <template v-else>未设置答案</template>
315   - </template>
316   - <el-tooltip
317   - v-if="
318   - scoped.row.subjectiveScore == scoped.row.examPaperScore &&
319   - scoped.row.recordStatus == 0
320   - "
321   - effect="dark"
322   - content="导入主观题"
323   - placement="top"
324   - >
325   - <el-button
326   - type="primary"
327   - circle
328   - size="mini"
329   - icon="fa fa-cloud"
330   - @click="uploadSJ(scoped.row)"
331   - ></el-button>
332   - </el-tooltip>
333   - </template>
334   - </el-table-column>
335   - </el-table>
336   - <div class="pagination-box">
337   - <el-pagination
338   - small=""
339   - layout="total,prev, pager, next"
340   - :hide-on-single-page="true"
341   - :total="total"
342   - @current-change="changePage"
343   - :current-page="page"
344   - :page-size="size"
345   - >
346   - </el-pagination>
  24 + <div class="sel-item sel-item2">
  25 + <span class="sel-label">科目:</span>
  26 + <div class="sel-d">
  27 + <p class="p-all">
  28 + <el-checkbox :indeterminate="isIndeterminateSub" v-model="allSubject"
  29 + @change="handleCheckAllChangeSub">全选</el-checkbox>
  30 + </p>
  31 + <p class="sel-p">
  32 + <el-checkbox-group v-model="query.subjectNames" @change="CheckedSub">
  33 + <el-checkbox v-for="item in subjectList" :label="item" :key="item">{{ item
  34 + }}</el-checkbox>
  35 + </el-checkbox-group>
  36 + </p>
  37 + </div>
347 38 </div>
348   - </div>
349   - <div v-show="tabIndex == 2" v-loading="loading">
350   - <el-empty
351   - :image-size="100"
352   - v-if="!tableData.length && loading == false"
353   - description="没有更多数据"
354   - ></el-empty>
355   - <template v-if="tableData.length && loading == false">
356   - <div id="print-content">
357   - <el-table
358   - :max-height="tableMaxHeight"
359   - v-if="role == 'ROLE_JIAOSHI'"
360   - :data="tableData"
361   - border
362   - style="width: 100%"
363   - >
364   - <el-table-column
365   - prop="studentCode"
366   - label="学号"
367   - align="center"
368   - fixed
369   - ></el-table-column>
370   - <el-table-column
371   - prop="studentName"
372   - label="姓名"
373   - fixed
374   - align="center"
375   - >
376   - <template slot-scope="scoped"
377   - ><span class="click-b" @click="toPortrait(scoped.row)">
378   - {{ scoped.row.studentName }}
379   - </span></template
380   - ></el-table-column
381   - >
382   - <el-table-column
383   - align="center"
384   - v-for="(item, index) in answerList"
385   - :key="index"
386   - :label="item.title"
387   - >
388   - <el-table-column
389   - :prop="'score' + index"
390   - :label="index == 0 ? '总分' : '成绩'"
391   - align="center"
392   - :class-name="index % 2 == 0 ? 'bg' : ''"
393   - ></el-table-column>
394   - <el-table-column
395   - :prop="'classRank' + index"
396   - label="班名"
397   - align="center"
398   - :class-name="index % 2 == 0 ? 'bg' : ''"
399   - ></el-table-column>
400   - </el-table-column>
401   - </el-table>
402   - <el-table
403   - v-else
404   - :data="tableData"
405   - :max-height="tableMaxHeight"
406   - border
407   - style="width: 100%"
408   - >
409   - <el-table-column
410   - prop="studentCode"
411   - label="学号"
412   - align="center"
413   - fixed
414   - ></el-table-column>
415   -
416   - <el-table-column
417   - prop="studentName"
418   - label="姓名"
419   - fixed
420   - align="center"
421   - >
422   - <template slot-scope="scoped"
423   - ><span class="click-b" @click="toPortrait(scoped.row)">
424   - {{ scoped.row.studentName }}
425   - </span></template
426   - >
427   - </el-table-column>
428   - <el-table-column
429   - align="center"
430   - v-for="(item, index) in answerList"
431   - :key="index"
432   - :label="item"
433   - >
434   - <el-table-column
435   - :prop="'examCount' + item"
436   - label="测练数"
437   - align="center"
438   - :class-name="index % 2 == 0 ? 'bg' : ''"
439   - ></el-table-column>
440   - <el-table-column
441   - :prop="'participationCount' + item"
442   - label="参与数"
443   - align="center"
444   - :class-name="index % 2 == 0 ? 'bg' : ''"
445   - ></el-table-column>
446   - <el-table-column
447   - :prop="'score' + item"
448   - label="总分"
449   - align="center"
450   - :class-name="index % 2 == 0 ? 'bg' : ''"
451   - ></el-table-column>
452   - <el-table-column
453   - :prop="'classRank' + item"
454   - label="班名"
455   - align="center"
456   - :class-name="index % 2 == 0 ? 'bg' : ''"
457   - ></el-table-column>
458   - </el-table-column>
459   - </el-table>
  39 + <div class="sel-item">
  40 + <span class="sel-label">日期:</span>
  41 + <div class="d1">
  42 + <el-date-picker v-model="query.startDay" type="date" @change="handleChangeTimeStart" placeholder="选择日期时间"
  43 + value-format="yyyy-MM-dd">
  44 + </el-date-picker>
  45 + ~
  46 + <el-date-picker v-model="query.endDay" type="date" placeholder="选择日期时间" @change="handleChangeTimeEnd"
  47 + value-format="yyyy-MM-dd">
  48 + </el-date-picker>
460 49 </div>
461   - </template>
462   - </div>
463   - <p class="down" v-if="tabIndex == 2 && tableData.length">
464   - <el-button
465   - type="primary"
466   - plain
467   - round
468   - icon="fa fa-cloud-download"
469   - @click="downExl"
470   - >导出报表</el-button
471   - >
472   - <el-button
473   - v-if="!this.$store.getters.code"
474   - @click="print"
475   - type="primary"
476   - plain
477   - round
478   - icon="el-icon-printer"
479   - >打印</el-button
480   - >
481   - </p>
482   - </div>
483   - <el-dialog :close-on-click-modal="false" title="导入主观题分数" :visible.sync="diaUp" width="600">
484   - <upload
485   - :url="url"
486   - :examId="examId"
487   - @upSuccess="upSuccess"
488   - fileName="主观题分数"
489   - v-loading="loadingDown"
490   - >
491   - <template slot="down">
492   - <p class="down-txt">
493   - 第一步:下载模板并编辑完成学生分数
494   - <el-link type="danger" @click="downExcel">模板下载</el-link> 。
  50 + <p class="p1">
  51 + <span @click="setDate(1)" :class="[date == 1 ? 'active' : '', 's1']">本周</span>
  52 + <span @click="setDate(2)" :class="[date == 2 ? 'active' : '', 's1']">本月</span>
  53 + <span @click="setDate(3)" :class="[date == 3 ? 'active' : '', 's1']">本季度</span>
495 54 </p>
496   - <p class="down-txt">第二步:上传完成编辑的模板文件并导入。</p>
497   - </template>
498   - </upload>
499   - <div class="dialog-footer" slot="footer">
500   - <el-button @click="diaUp = false">取 消</el-button>
  55 + </div>
  56 + </div>
  57 + <div class="foot-box">
  58 + <el-button type="primary" round @click="goList">确定</el-button>
  59 + <el-button type="danger" round @click="goHome">取消</el-button>
501 60 </div>
502   - </el-dialog>
  61 + </div>
503 62 </div>
504 63 </template>
505 64  
506 65 <script>
507   -import { formatDate, downloadFile, tablePrint } from "utils";
508   -import BusEvent from "@/utils/busEvent";
  66 +import { formatDate } from "utils";
509 67 export default {
510 68 data() {
511 69 return {
512 70 code: "",
513   - gdClass: 0, //已归档班级数量
514   - exportLoading: false,
515   - tableMaxHeight: 300,
516 71 role: "",
517   - loading: false,
518   - diaUp: false,
519   - loadingDown: false,
520   - url: "/api_html/teaching/importSubjectiveScore",
521   - examId: "",
522   - form: {
523   - id: "",
524   - title: "",
525   - examPaperScore: "",
526   - },
527 72 date: "", //今天-昨天-本周
528 73 query: {
529 74 //搜索条件
530   - classId: "",
531   - subjectNames: "",
  75 + classId: [],
  76 + subjectNames: [],
532 77 startDay: "",
533 78 endDay: "",
534   - day: "",
535 79 },
536   - tabList: ["单卷测练报表", "阶段测练报表"],
537 80 classList: [], //班级
538 81 subjectList: [], //科目
539   - tabIndex: 1, //选项卡
540   - tableData: [],
541   - answerList: [], //设置多卷内容供tableStage表格数据用
542   - page: 1,
543   - size: 20,
544   - total: 0,
  82 +
  83 + isIndeterminateClass: true,//全选样式
  84 + allClass: false,//全选状态
  85 + isIndeterminateSub: true,//全选样式
  86 + allSubject: false,//全选状态
545 87 };
546 88 },
547 89 async created() {
... ... @@ -549,7 +91,7 @@ export default {
549 91 this.role =
550 92 this.$store.getters.info.showRole ||
551 93 this.$store.getters.info.permissions[0].role;
552   - this._QueryClassList2();
  94 + this.query.subjectNames = [];
553 95 await this._QueryClassList();
554 96 if (!this.query.classId) {
555 97 return;
... ... @@ -562,115 +104,37 @@ export default {
562 104 this.query.endDay = new Date();
563 105 }
564 106 },
565   - activated() {
566   - const that = this;
567   - BusEvent.$on("keepAlive", async function () {
568   - // if (that.$route.path == "/test") {
569   - that.query.subjectNames = that.role == "ROLE_BANZHUREN" ? [] : "";
570   - that._QueryClassList2();
571   - await that._QueryClassList();
572   - if (!that.query.classId) {
573   - return;
574   - }
575   - await that._QuerySubjectList();
576   - await that.setDate(1);
577   - let startDay = that.query?.startDay;
578   - if (!startDay) {
579   - that.query.startDay = new Date();
580   - that.query.endDay = new Date();
581   - }
582   - // }
583   - });
584   - },
  107 +
585 108 methods: {
586   - print() {
587   - tablePrint("print-content", "即时测-" + this.tabList[this.tabIndex - 1]);
  109 + handleCheckAllChangeClass(val) {
  110 + this.isIndeterminateClass = false
  111 + this.query.classId = val ? this.classList.map(item => item.value) : [];
588 112 },
589   - changeSub(val) {
590   - //科目改变触发事件
591   - let sub;
592   - if (val && val.length) {
593   - let leng = val.length - 1;
594   - sub = val[leng];
595   - }
596   - console.log(val);
597   - this.query.subjectNames = val.filter((item) => {
598   - return sub != "全部" ? item != "全部" : item == "全部";
599   - });
  113 + changeclass(value) {
  114 + console.log(value)
  115 + let checkedCount = value.length;
  116 + this.allClass = checkedCount === this.classList.length;
  117 + this.isIndeterminateClass = checkedCount > 0 && checkedCount < this.classList.length;
600 118 },
601   - toArchiving() {
602   - this.$router.push({
603   - path: "/testArchiving",
604   - });
  119 + handleCheckAllChangeSub(val) {
  120 + this.isIndeterminate = false
  121 + this.query.subjectNames = val ? this.subjectList : [];
605 122 },
606   - linkTo(obj) {
607   - //去详情
608   - this.$router.push({
609   - path: "/testAnalysis",
610   - query: {
611   - id: obj.id,
612   - title: obj.title,
613   - score: obj.examPaperScore,
614   - },
615   - });
616   - },
617   - toPortrait(obj) {
618   - //暂时不上线
619   - return;
620   - if (this.$store.getters.code) {
621   - return;
622   - }
623   - let subjectNames = [];
624   - subjectNames =
625   - this.role == "ROLE_BANZHUREN"
626   - ? [...this.query["subjectNames"]]
627   - : [this.query["subjectNames"]];
628   - if (
629   - this.query["subjectNames"] &&
630   - this.query["subjectNames"]?.length == 1 &&
631   - this.query["subjectNames"][0] == "全部"
632   - ) {
633   - subjectNames = this.subjectList.map((item) => {
634   - return item.value;
635   - });
636   - subjectNames?.shift();
637   - }
638   - //去学生画像
639   - this.$router.push({
640   - path: "/portraitDetail",
641   - query: {
642   - id: obj.studentId,
643   - classId: this.query.classId,
644   - subjectNames: subjectNames.join(","),
645   - studentName: obj.studentName,
646   - studentCode: obj.studentCode,
647   - startDay: this.query.startDay,
648   - endDay: this.query.endDay,
649   - date: this.date,
650   - },
651   - });
652   - },
653   - uploadSJ(obj) {
654   - //导入开关
655   - this.examId = obj.id;
656   - this.diaUp = true;
  123 + CheckedSub(value) {
  124 + console.log(value)
  125 + let checkedCount = value.length;
  126 + this.allSubject = checkedCount === this.subjectList.length;
  127 + this.isIndeterminate = checkedCount > 0 && checkedCount < this.subjectList.length;
657 128 },
658 129 setDate(index) {
659 130 const that = this;
660 131 this.date = index == this.date ? "" : index;
661 132 let aYear = new Date().getFullYear();
662 133 let aMonth = new Date().getMonth() + 1;
663   - that.query.day = "";
664 134 that.query.startDay = "";
665 135 that.query.endDay = "";
666 136 switch (index) {
667 137 case 1:
668   - that.query.day = formatDate(new Date(), "yyyy-MM-dd");
669   - that.query.startDay = that.query.day;
670   - that.query.endDay = that.query.day;
671   - that.tabIndex = 1;
672   - break;
673   - case 2:
674 138 let day = new Date().getDay();
675 139 if (day == 0) {
676 140 //中国式星期天是一周的最后一天
... ... @@ -681,12 +145,12 @@ export default {
681 145 that.query.startDay = formatDate(new Date(aTime), "yyyy-MM-dd");
682 146 that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
683 147 break;
684   - case 3:
  148 + case 2:
685 149 aMonth = aMonth < 10 ? "0" + aMonth : aMonth;
686 150 that.query.startDay = `${aYear}-${aMonth}-01`;
687 151 that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
688 152 break;
689   - case 4:
  153 + case 3:
690 154 if (aMonth > 0 && aMonth < 4) {
691 155 aMonth = "1";
692 156 } else if (aMonth > 3 && aMonth < 7) {
... ... @@ -703,10 +167,8 @@ export default {
703 167 break;
704 168 }
705 169 this.page = 1;
706   - this._QueryData();
707 170 },
708 171 handleChangeTimeStart(val) {
709   - this.query.day = "";
710 172 this.date = "";
711 173 if (this.query.endDay) {
712 174 if (new Date(val).getTime() > new Date(this.query.endDay).getTime()) {
... ... @@ -716,67 +178,21 @@ export default {
716 178 }
717 179 },
718 180 handleChangeTimeEnd(val) {
719   - this.query.day = "";
720 181 this.date = "";
721   - if (this.query.startDay) {
  182 + if (this.query.startDay && val) {
722 183 if (new Date(val).getTime() < new Date(this.query.startDay).getTime()) {
723 184 this.$message.error("任务结束时间不能任务开始时间前面,请重新设置");
724 185 this.query.endDay = "";
725 186 }
726 187 }
727 188 },
728   - changePage(page) {
729   - this.page = page;
730   - this._QueryData();
731   - },
732   - edit(item) {
733   - this.$router.push({
734   - path: "/examinationPaperEdit",
735   - query: {
736   - paperId: item.id,
737   - title: item.title,
738   - type: 2,
739   - },
740   - });
741   - },
742   - changeTab() {
743   - this.tableMaxHeight = this.$refs.main.offsetHeight;
744   - this.page = 1;
745   - this._QueryData();
746   - },
747   - upSuccess(res) {
748   - //导入成功
749   - this.$message.success("导入成功");
750   - this.diaUp = false;
751   - this._QueryData();
752   - },
753   - async changeclass() {
754   - await this._QuerySubjectList();
755   - this.page = 1;
756   - this._QueryData();
757   - },
758   - async changClazz() {
759   - this.page = 1;
760   - await this._QuerySubjectList();
761   - await this._QueryData();
762   - },
763   - async _QueryClassList2() {
764   - const fetchClassList =
765   - this.role == "ROLE_BANZHUREN"
766   - ? this.$request.cTClassList
767   - : this.$request.tClassList;
768   - const { data, status, info } = await fetchClassList({ status: 1 });
769   - if (status === 0) {
770   - this.gdClass = data?.list?.length || 0;
771   - } else {
772   - this.$message.error(info);
773   - }
774   - },
775 189 async _QueryClassList() {
776 190 const fetchClassList =
777 191 this.role == "ROLE_BANZHUREN"
778   - ? this.$request.cTClassList
779   - : this.$request.tClassList;
  192 + ? this.$request.cTClassList :
  193 + this.role == "ROLE_PERSONAL"
  194 + ? this.$request.pClassList
  195 + : this.$request.tClassList;
780 196 const { data, status, info } = await fetchClassList();
781 197 if (status === 0) {
782 198 this.classList = data.list.map((item) => {
... ... @@ -785,7 +201,7 @@ export default {
785 201 label: item.className,
786 202 };
787 203 });
788   - this.query.classId = this.classList[0]?.value;
  204 + this.classList.length ? this.query.classId.push(this.classList[0].value) : "";
789 205 } else {
790 206 this.$message.error(info);
791 207 }
... ... @@ -793,275 +209,191 @@ export default {
793 209 async _QuerySubjectList() {
794 210 const fetchSubjectList =
795 211 this.role == "ROLE_BANZHUREN"
796   - ? this.$request.cTSubjectList
797   - : this.$request.tSubjectList;
  212 + ? this.$request.cTSubjectList :
  213 + this.role == "ROLE_PERSONAL"
  214 + ? this.$request.pSubjectList
  215 + : this.$request.tSubjectList;
798 216  
  217 + const classIds = this.classList.map(item => item.value) || []
799 218 const { data, status, info } = await fetchSubjectList({
800   - classId: this.query.classId,
  219 + classIds: classIds,
801 220 });
802 221 if (status === 0) {
803   - this.subjectList =
804   - data.subjectNames?.map((item) => {
805   - return {
806   - value: item,
807   - label: item,
808   - };
809   - }) || [];
810   - if (this.role == "ROLE_BANZHUREN") {
811   - this.subjectList.unshift({
812   - value: "全部",
813   - label: "全部",
814   - });
815   - this.query.subjectNames.push(this.subjectList[0]?.value);
816   - } else {
817   - this.query.subjectNames = this.subjectList[0]?.value;
818   - }
  222 + this.subjectList = data.subjectNames || [];
  223 + // if (this.role == "ROLE_BANZHUREN") {
  224 + // this.query.subjectNames = this.subjectList
  225 + // } else {
  226 + this.subjectList.length ? this.query.subjectNames.push(this.subjectList[0]) : "";
  227 + // }
819 228 } else {
820 229 this.$message.error(info);
821 230 }
822 231 },
823   - async _QueryData() {
824   - if (!this.query.classId) {
825   - return;
826   - }
827   - this.tableData = [];
828   - if (this.tabIndex == 1) {
829   - this.examReportList();
830   - } else {
831   - this.phaseExamReport();
832   - }
833   - },
834   - //单卷测练
835   - async examReportList() {
836   - this.loading = true;
837   - let query = {};
838   - for (let key in this.query) {
839   - if (this.query[key] != "") {
840   - query[key] = this.query[key];
841   - }
842   - }
843   - if (this.role != "ROLE_BANZHUREN") {
844   - query.subjectNames = [query.subjectNames];
845   - } else {
846   - if (
847   - query["subjectNames"] &&
848   - query["subjectNames"].length == 1 &&
849   - query["subjectNames"][0] == "全部"
850   - ) {
851   - query["subjectNames"] = this.subjectList.map((item) => {
852   - return item.value;
853   - });
854   - query["subjectNames"].shift();
855   - }
856   - if (!query["subjectNames"]) {
857   - this.$message.warning("请选择科目");
858   - return;
859   - }
860   - }
861   - const { data, status, info } = await this.$request.examReportList({
862   - ...query,
863   - page: this.page,
864   - size: this.size,
865   - });
866   - this.loading = false;
867   - if (status === 0) {
868   - this.tableData = (data?.list && [...data?.list]) || [];
869   - this.total = data?.count || 0;
870   - } else {
871   - this.$message.error(info);
872   - }
873   - },
874   - //多卷测练
875   - async phaseExamReport() {
876   - this.loading = true;
877   - let query = {};
878   - for (let key in this.query) {
879   - if (this.query[key] != "") {
880   - if (key == "subjectNames" && this.role != "ROLE_BANZHUREN") {
881   - query["subjectName"] = this.query[key];
882   - } else {
883   - query[key] = this.query[key];
884   - }
885   - }
886   - }
887   - if (this.role == "ROLE_BANZHUREN") {
888   - if (
889   - query["subjectNames"] &&
890   - query["subjectNames"]?.length == 1 &&
891   - query["subjectNames"][0] == "全部"
892   - ) {
893   - query["subjectNames"] = this.subjectList.map((item) => {
894   - return item.value;
895   - });
896   - query["subjectNames"]?.shift();
897   - }
898   - }
899   - const phaseExamReport =
900   - this.role == "ROLE_BANZHUREN"
901   - ? this.$request.cTPhaseExamReport
902   - : this.$request.phaseExamReport;
903   - const { data, status, info } = await phaseExamReport({
904   - ...query,
905   - });
906   - this.loading = false;
907   - if (status === 0) {
908   - this.total = data.count;
909   - if (this.role == "ROLE_BANZHUREN") {
910   - let subjectName = [];
911   - this.tableData = data?.list.map((item) => {
912   - let params = {};
913   - item.dataList.map((items, index) => {
914   - if (!subjectName.includes(items.subjectName)) {
915   - subjectName.push(items.subjectName);
916   - }
917   - params["examCount" + items.subjectName] = items.examCount;
918   - params["participationCount" + items.subjectName] =
919   - items.participationCount;
920   - params["score" + items.subjectName] = items.score;
921   - params["classRank" + items.subjectName] = items.classRank;
922   - });
923   - return {
924   - ...item,
925   - ...params,
926   - };
927   - });
928   - this.answerList = [...subjectName];
929   - } else {
930   - let dataIdsList = [],
931   - dataList = [];
932   - data?.list.map((item) => {
933   - item.examList.map((items) => {
934   - if (!dataIdsList.includes(items.title)) {
935   - dataIdsList.push(items.title);
936   - dataList.push(items);
937   - }
938   - });
939   - });
940   - console.log(dataList);
941   - this.tableData = data?.list.map((item) => {
942   - let params = {};
943   - dataIdsList.map((ids, index) => {
944   - params["score" + index] = "--";
945   - params["classRank" + index] = "--";
946   - item.examList.map((items) => {
947   - if (items.title == ids) {
948   - params["score" + index] = items.score;
949   - params["classRank" + index] = items.classRank;
950   - }
951   - });
952   - });
953   - return {
954   - ...item,
955   - ...params,
956   - };
957   - });
958   - this.answerList = dataList;
959   - }
960   - } else {
961   - this.$message.error(info);
962   - }
  232 +
  233 + //回主页
  234 + goHome() {
  235 + this.$router.push({
  236 + path: '/index'
  237 + })
963 238 },
964   - async downExl() {
965   - //报表到处
966   - if (this.exportLoading == true) return;
967   - let query = {};
968   - for (let key in this.query) {
969   - if (this.query[key] != "") {
970   - if (key == "subjectNames" && this.role != "ROLE_BANZHUREN") {
971   - query["subjectName"] = this.query[key];
972   - } else {
973   - query[key] = this.query[key];
974   - }
975   - }
976   - }
977   - if (this.role == "ROLE_BANZHUREN") {
978   - if (
979   - query["subjectNames"] &&
980   - query["subjectNames"].length == 1 &&
981   - query["subjectNames"][0] == "全部"
982   - ) {
983   - query["subjectNames"] = this.subjectList.map((item) => {
984   - return item.value;
985   - });
986   - query["subjectNames"].shift();
987   - }
988   - if (!query["subjectNames"]) {
989   - this.$message.warning("请选择科目");
990   - return;
  239 + //去列表
  240 + goList() {
  241 + this.$router.push({
  242 + path: '/testList',
  243 + query: {
  244 + params: JSON.stringify(this.query)
991 245 }
992   - }
993   - const exportPhaseExamReport =
994   - this.role == "ROLE_BANZHUREN"
995   - ? this.$request.cTExportPhaseExamReport
996   - : this.$request.exportPhaseExamReport;
997   - this.exportLoading = true;
998   - const data = await exportPhaseExamReport({ ...query });
999   - this.exportLoading = false;
1000   - if (data && !data.code) {
1001   - let blob = new Blob([data], {
1002   - type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
1003   - });
1004   - downloadFile("即时测-阶段测练报表.xlsx", blob);
1005   - } else {
1006   - this.$message.error(data.info);
1007   - }
1008   - },
1009   - async downExcel() {
1010   - //模板下载
1011   - this.loadingDown = true;
1012   - let data = await this.$request.subjectiveScoreTemplate({
1013   - examId: this.examId,
1014   - });
1015   - this.loadingDown = false;
1016   - if (data && !data.code) {
1017   - let blob = new Blob([data], {
1018   - type: "application/vnd.ms-excel;charset=utf-8",
1019   - });
1020   - downloadFile(`主观题模版.xlsx`, blob);
1021   - } else {
1022   - this.$message.error(data.info);
1023   - }
1024   - },
  246 + })
  247 + }
1025 248 },
1026 249 };
1027 250 </script>
1028   -
1029 251 <style>
1030 252 div::-webkit-scrollbar {
1031 253 width: 3px;
1032 254 height: 10px;
1033 255 }
  256 +
1034 257 div::-webkit-scrollbar-thumb {
1035 258 border-radius: 10px;
1036 259 background-color: #ccc;
1037 260 }
1038 261 </style>
1039 262 <style lang="scss" scoped>
1040   -.page-container {
1041   - position: relative;
  263 +.main {
1042 264 height: 100%;
1043   - &.active {
1044   - overflow: hidden;
1045   - }
  265 + background: rgba($color: #000000, $alpha: .3);
  266 + display: flex;
  267 + justify-content: center;
1046 268 }
1047   -.table-box {
1048   - margin: 0 20px;
1049   - padding: 16px;
1050   - background: #f8f8f8;
1051   - border-radius: 5px;
1052   - :deep(.fa-arrow-right) {
1053   - padding-left: 2px;
  269 +
  270 +.sel-dia {
  271 + margin-top: 100px;
  272 + width: 750px;
  273 + background: #fff;
  274 + border-radius: 10px;
  275 + overflow: hidden;
  276 + height: 460px;
  277 + display: flex;
  278 + flex-direction: column;
  279 +
  280 + .tit {
  281 + text-align: center;
  282 + position: relative;
  283 + padding: 20px 0 12px;
  284 + font-size: 18px;
  285 + font-weight: 500;
  286 + flex-shrink: 0;
  287 +
  288 + .el-icon-close {
  289 + position: absolute;
  290 + top: 0;
  291 + right: 0;
  292 + width: 30px;
  293 + height: 30px;
  294 + text-align: center;
  295 + line-height: 28px;
  296 + background: #e2e2e2;
  297 + border-radius: 0 0 0 24px;
  298 + box-sizing: border-box;
  299 + padding-left: 6px;
  300 + font-size: 18px;
  301 + cursor: pointer;
  302 +
  303 + &:hover {
  304 + color: #f30;
  305 + }
  306 + }
1054 307 }
1055   - :deep(.fa-file-text) {
1056   - padding-left: 2px;
  308 +
  309 + .select-box {
  310 + flex: 1;
  311 + overflow-y: auto;
  312 + padding: 0 30px;
  313 +
  314 + .sel-item {
  315 + display: flex;
  316 + align-items: center;
  317 + margin-bottom: 12px;
  318 +
  319 + .sel-label {
  320 + width: 60px;
  321 + margin-right: 10px;
  322 + flex-shrink: 0;
  323 + font-size: 15px;
  324 + font-weight: 500;
  325 + }
  326 +
  327 + :deep(.el-input__inner) {
  328 + height: 36px;
  329 + line-height: 36px;
  330 + border-radius: 18px;
  331 + }
  332 +
  333 + :deep(.el-input__suffix) {
  334 + .el-input__icon {
  335 + line-height: 36px;
  336 + }
  337 + }
  338 +
  339 + :deep(.el-input__inner) {
  340 + height: 36px;
  341 + line-height: 36px;
  342 + border-radius: 18px;
  343 +
  344 + .el-input__icon {
  345 + line-height: 36px;
  346 + }
  347 + }
  348 +
  349 + .el-date-editor.el-input,
  350 + .el-date-editor.el-input__inner {
  351 + width: 160px;
  352 + height: 36px;
  353 + line-height: 36px;
  354 +
  355 + :deep(.el-input__icon) {
  356 + line-height: 36px;
  357 + }
  358 + }
  359 + }
  360 +
  361 + .sel-item2 {
  362 + align-items: flex-start;
  363 + line-height: 20px;
  364 + padding-top: 10px;
  365 +
  366 + .p-all {
  367 + padding-bottom: 6px;
  368 + }
  369 + }
  370 +
  371 + .p1 {
  372 + .s1 {
  373 + margin-left: 20px;
  374 + cursor: pointer;
  375 + color: #7f7f7f;
  376 +
  377 + &:hover {
  378 + color: #409eff;
  379 + }
  380 +
  381 + &.active {
  382 + color: #667ffd;
  383 + }
  384 + }
  385 + }
  386 + }
  387 +
  388 + .foot-box {
  389 + flex-shrink: 0;
  390 + padding: 12px 0 20px;
  391 + display: flex;
  392 + justify-content: center;
  393 +
  394 + .el-button {
  395 + margin: 0 30px;
  396 + }
1057 397 }
1058   -}
1059   -.down {
1060   - padding-top: 16px;
1061   -}
1062   -.click-b {
1063   - cursor: pointer;
1064   - color: #409eff;
1065   - text-decoration: underline;
1066 398 }
1067 399 </style>
1068 400 \ No newline at end of file
... ...
src/views/basic/test/list.vue 0 → 100644
  1 +<template>
  2 + <div ref="main" class="page-container">
  3 + <back-box v-show="!isDetail">
  4 + <template slot="title">
  5 + <span>即时测-数据报表</span>
  6 + </template>
  7 + <template slot="btns">
  8 + <el-tooltip v-if="!code && gdClass" effect="dark" content="已归档试卷" placement="bottom">
  9 + <el-button type="primary" icon="fa fa-archive" size="mini" plain circle @click="toArchiving"></el-button>
  10 + </el-tooltip>
  11 + </template>
  12 + </back-box>
  13 + <div v-show="!isDetail" class="table-box" v-loading="loading">
  14 + <div v-if="!isMultipleClass">
  15 + <p class="btn-box">
  16 + <el-button type="primary" round @click="linkToDetail2">查看汇总报表</el-button>
  17 + </p>
  18 + <el-table :data="tableData" :max-height="tableMaxHeight" border style="width: 100%"
  19 + @selection-change="handleSelectionChange">
  20 + <el-table-column type="selection" width="40"></el-table-column>
  21 + <el-table-column prop="subjectName" label="科目" align="center"></el-table-column>
  22 + <el-table-column prop="className" label="班级" align="center"></el-table-column>
  23 + <el-table-column prop="title" label="试卷名称" align="center"></el-table-column>
  24 + <el-table-column prop="score" label="卷面分" align="center"></el-table-column>
  25 + <el-table-column label="测验人数/班级人数" align="center">
  26 + <template slot-scope="scoped">{{ `${scoped.row.answeredNum}/${scoped.row.classPersonNum}` }}</template>
  27 + </el-table-column>
  28 + <el-table-column prop="examStartTime" label="测验开始时间" align="center"></el-table-column>
  29 + <el-table-column label="操作" align="center">
  30 + <template slot-scope="scoped">
  31 + <el-tooltip v-if="scoped.row.answerNum != 0 || scoped.row.recordStatus != 0
  32 + " effect="dark" content="详情" placement="top">
  33 + <el-button type="primary" circle size="mini" icon="fa fa-arrow-right"
  34 + @click="linkTo(scoped.row)"></el-button>
  35 + </el-tooltip>
  36 + <template v-if="scoped.row.answerNum == 0">
  37 + <el-tooltip v-if="role != 'ROLE_BANZHUREN'" effect="dark" content="设置答案" placement="top">
  38 + <el-button type="primary" circle size="mini" icon="fa fa-file-text"
  39 + @click="edit(scoped.row)"></el-button>
  40 + </el-tooltip>
  41 + <template v-else>未设置答案</template>
  42 + </template>
  43 + <!-- <el-tooltip v-else effect="dark" content="答卷录分" placement="top">
  44 + <el-button type="primary" circle size="mini" @click="openScoreSet(scoped.row)">分</el-button>
  45 + </el-tooltip> -->
  46 + <el-tooltip effect="dark" content="答卷录分" placement="top">
  47 + <el-button type="primary" circle size="mini" @click="openScoreSet(scoped.row)">分</el-button>
  48 + </el-tooltip>
  49 + </template>
  50 + </el-table-column>
  51 + </el-table>
  52 + <div class="pagination-box">
  53 + <el-pagination small="" layout="total,prev, pager, next" :hide-on-single-page="true" :total="total"
  54 + @current-change="changePage" :current-page="page" :page-size="size">
  55 + </el-pagination>
  56 + </div>
  57 + <ScoreSet v-show="diaScoreSet" :role="role" :id="examId" :title="examTitlt" :examScore="examScore"
  58 + @closeScoreSet="closeScoreSet" />
  59 + </div>
  60 + <div v-else>
  61 + <el-table :data="tableData" :max-height="tableMaxHeight" border style="width: 100%">
  62 + <el-table-column prop="subjectName" label="科目" align="center"></el-table-column>
  63 + <el-table-column prop="classList" label="班级" align="center">
  64 + <template slot-scope="scoped"><span v-for="(item, index) in scoped.row.classList">{{
  65 + `${index == 0 ? '' : '/'}` + item.className
  66 + }}</span></template>
  67 + </el-table-column>
  68 + <el-table-column prop="title" label="试卷名称" align="center"></el-table-column>
  69 + <el-table-column prop="score" label="卷面分" align="center"></el-table-column>
  70 + <el-table-column label="操作" align="center">
  71 + <template slot-scope="scoped">
  72 + <el-button type="primary" circle size="mini" icon="el-icon-arrow-right"
  73 + @click="linkContrast(scoped.row)"></el-button>
  74 + </template>
  75 + </el-table-column>
  76 + </el-table>
  77 + <div class="pagination-box">
  78 + <el-pagination small="" layout="total,prev, pager, next" :hide-on-single-page="true" :total="total"
  79 + @current-change="changePage" :current-page="page" :page-size="size">
  80 + </el-pagination>
  81 + </div>
  82 + </div>
  83 + </div>
  84 + <router-view v-show="isDetail"></router-view>
  85 + </div>
  86 +</template>
  87 +
  88 +<script>
  89 +import ScoreSet from "./components/scoreSet.vue"
  90 +export default {
  91 + components: {
  92 + ScoreSet
  93 + },
  94 + data() {
  95 + return {
  96 + code: "",
  97 + gdClass: 0, //已归档班级数量
  98 + tableMaxHeight: null,
  99 + role: "",
  100 + loading: false,
  101 + diaScoreSet: false,
  102 + examId: "",//当前操作试卷
  103 + examTitlt: "",//当前操作试卷名称
  104 + examScore: 0,//当前操作试卷卷面总分
  105 + query: {
  106 + //搜索条件
  107 + classId: [],
  108 + subjectNames: [],
  109 + startDay: "",
  110 + endDay: "",
  111 + },
  112 + multipleSelection: [],
  113 + tableData: [],
  114 + page: 1,
  115 + size: 20,
  116 + total: 0,
  117 + isMultipleClass: false,
  118 + };
  119 + },
  120 + computed: {
  121 + isDetail: function () {
  122 + let bol = (this.$route.name == "即时测报表分析") ? true : false
  123 + return bol
  124 + }
  125 + },
  126 + async created() {
  127 + this.code = localStorage.getItem("csCode") || "";
  128 +
  129 + this.init()
  130 + },
  131 + mounted() {
  132 + this.tableMaxHeight = this.$refs.main.offsetHeight;
  133 + },
  134 + watch: {
  135 + "$route.query.params": function (nVal) {
  136 + let isFromTestDetail = sessionStorage.getItem("isFromTestDetail");
  137 + if (!isFromTestDetail && nVal) {
  138 + this.init()
  139 + }
  140 + }
  141 + },
  142 + methods: {
  143 + //初始化
  144 + init() {
  145 + const queryData = this.$route.query.params
  146 + queryData ? this.query = { ...this.query, ...JSON.parse(queryData) } : ''
  147 + console.log(this.query)
  148 + if (this.query.classId.length > 1) {
  149 + this.isMultipleClass = true
  150 + }
  151 + this.role =
  152 + this.$store.getters.info.showRole ||
  153 + this.$store.getters.info.permissions[0].role;
  154 + if (this.role != "ROLE_PERSONAL") {
  155 + this._QueryGdClass()
  156 + }
  157 + this.page = 1
  158 + this.total = 0
  159 + this.tableData = []
  160 + this._QueryData()
  161 + },
  162 + //归档列表
  163 + toArchiving() {
  164 + this.$router.push({
  165 + path: "/testArchiving",
  166 + });
  167 + },
  168 + //跳转单卷分析
  169 + linkTo(obj) {
  170 + //去详情
  171 + this.$router.push({
  172 + path: "/testAnalysis",
  173 + query: {
  174 + id: obj.id,
  175 + title: obj.title,
  176 + score: obj.examPaperScore || 0,
  177 + type: 1,
  178 + subject: obj.subjectName
  179 + },
  180 + });
  181 + },
  182 + //汇总跳转-多卷
  183 + linkToDetail2() {
  184 + if (this.multipleSelection.length == 0) {
  185 + this.$message.warning("请选择试卷!")
  186 + return
  187 + };
  188 + let subjectArr = []
  189 + const ids = this.multipleSelection.map(item => {
  190 + subjectArr.push(item.subjectName)
  191 + return item.id
  192 + })
  193 + subjectArr = [...new Set(subjectArr)]
  194 + console.log(subjectArr)
  195 + if (ids.length == 1) {
  196 + this.$router.push({
  197 + path: "/testAnalysis",
  198 + query: {
  199 + id: ids[0],
  200 + title: this.multipleSelection[0].title,
  201 + score: this.multipleSelection[0].examPaperScore || 0,
  202 + type: 1,
  203 + subjectName: subjectArr.join()
  204 + },
  205 + });
  206 + } else {
  207 + //去详情
  208 + this.$router.push({
  209 + path: "/testAnalysis",
  210 + query: {
  211 + ids: ids.join(),
  212 + classId: this.query.classId[0],
  213 + type: subjectArr.length == 1 ? 2 : 3,
  214 + subjectName: subjectArr.join()
  215 + },
  216 + });
  217 + }
  218 + },
  219 + // 多班对比
  220 + linkContrast(obj) {
  221 + this.$router.push({
  222 + path: "/testAnalysis",
  223 + query: {
  224 + ids: obj.classList.map(item => item.classId).join(),
  225 + subjectName: obj.subjectName,
  226 + title: obj.title,
  227 + type: 4
  228 + },
  229 + });
  230 + },
  231 + handleSelectionChange(val) {
  232 + this.multipleSelection = val;
  233 + },
  234 + //打开答卷录分
  235 + openScoreSet(obj) {
  236 + this.examId = obj.id;
  237 + this.examTitlt = obj.title;
  238 + this.examScore = obj.examScore;
  239 + this.diaScoreSet = true;
  240 + },
  241 + //关闭设置分数
  242 + closeScoreSet() {
  243 + this.diaScoreSet = false
  244 + },
  245 + //修改答案
  246 + edit(item) {
  247 + this.$router.push({
  248 + path: "/examinationPaperEdit",
  249 + query: {
  250 + paperId: item.id,
  251 + title: item.title,
  252 + type: 2,
  253 + },
  254 + });
  255 + },
  256 +
  257 + async _QueryGdClass() {
  258 + const fetchClassList =
  259 + this.role == "ROLE_BANZHUREN"
  260 + ? this.$request.cTClassList
  261 + : this.$request.tClassList;
  262 + const { data, status, info } = await fetchClassList({ status: 1 });
  263 + if (status === 0) {
  264 + this.gdClass = data?.list?.length || 0;
  265 + } else {
  266 + this.$message.error(info);
  267 + }
  268 + },
  269 + changePage(page) {
  270 + this.page = page;
  271 + this._QueryData();
  272 + },
  273 + async _QueryData() {
  274 + this.loading = true;
  275 + let query = {};
  276 + for (let key in this.query) {
  277 + if (this.query[key] != "") {
  278 + query[key] = this.query[key];
  279 + }
  280 + }
  281 + const examReportList = this.role == "ROLE_PERSONAL" ?
  282 + this.$request.pExamReportList : this.$request.examReportList
  283 + const { data, status, info } = await examReportList({
  284 + ...query,
  285 + page: this.page,
  286 + size: this.size,
  287 + });
  288 + this.loading = false;
  289 + if (status === 0) {
  290 + this.tableData = (data?.list && [...data?.list]) || [];
  291 + this.total = data?.count || 0;
  292 + } else {
  293 + this.$message.error(info);
  294 + }
  295 + },
  296 + },
  297 +};
  298 +</script>
  299 +
  300 +<style>
  301 +div::-webkit-scrollbar {
  302 + width: 3px;
  303 + height: 10px;
  304 +}
  305 +
  306 +div::-webkit-scrollbar-thumb {
  307 + border-radius: 10px;
  308 + background-color: #ccc;
  309 +}
  310 +</style>
  311 +<style lang="scss" scoped>
  312 +.page-container {
  313 + position: relative;
  314 + height: 100%;
  315 +
  316 + &.active {
  317 + overflow: hidden;
  318 + }
  319 +}
  320 +
  321 +.table-box {
  322 + margin: 20px;
  323 + border-radius: 5px;
  324 +
  325 + :deep(.fa-arrow-right) {
  326 + padding-left: 2px;
  327 + }
  328 +
  329 + :deep(.fa-file-text) {
  330 + padding-left: 2px;
  331 + }
  332 +}
  333 +
  334 +.down {
  335 + padding-top: 16px;
  336 +}
  337 +
  338 +.click-b {
  339 + cursor: pointer;
  340 + color: #409eff;
  341 + text-decoration: underline;
  342 +}
  343 +
  344 +.btn-box {
  345 + text-align: right;
  346 + padding: 0 12px 16px;
  347 +}
  348 +</style>
0 349 \ No newline at end of file
... ...