Commit 079cb4cf3372babc7d21215a01eecb79fef45a2a
1 parent
86201e49
即时测导出
Showing
10 changed files
with
1225 additions
and
2519 deletions
src/components/charts/lineChart.vue
@@ -9,6 +9,7 @@ export default { | @@ -9,6 +9,7 @@ export default { | ||
9 | id: String, | 9 | id: String, |
10 | params: Array, | 10 | params: Array, |
11 | xAxis: Array, | 11 | xAxis: Array, |
12 | + colors: Array | ||
12 | }, | 13 | }, |
13 | watch: { | 14 | watch: { |
14 | params: { | 15 | params: { |
@@ -25,7 +26,7 @@ export default { | @@ -25,7 +26,7 @@ export default { | ||
25 | chart: null, | 26 | chart: null, |
26 | }; | 27 | }; |
27 | }, | 28 | }, |
28 | - created() {}, | 29 | + created() { }, |
29 | mounted() { | 30 | mounted() { |
30 | this.initData(); | 31 | this.initData(); |
31 | }, | 32 | }, |
@@ -33,7 +34,7 @@ export default { | @@ -33,7 +34,7 @@ export default { | ||
33 | setOption() { | 34 | setOption() { |
34 | const that = this; | 35 | const that = this; |
35 | const options = { | 36 | const options = { |
36 | - color: this.colors || ["#4472c4", "#ed7d32", "#a5a5a5"], | 37 | + color: this.colors || ["#9772ff", "#79cd91", "#72b8ff"], |
37 | backgroundColor: "#fff", | 38 | backgroundColor: "#fff", |
38 | tooltip: { | 39 | tooltip: { |
39 | trigger: "item", | 40 | trigger: "item", |
@@ -41,8 +42,10 @@ export default { | @@ -41,8 +42,10 @@ export default { | ||
41 | }, | 42 | }, |
42 | legend: { | 43 | legend: { |
43 | show: true, | 44 | show: true, |
44 | - bottom: 0, | ||
45 | - itemHeight: 2, | 45 | + top: 0, |
46 | + right: 20, | ||
47 | + itemHeight: 15, | ||
48 | + icon: "circle" | ||
46 | }, | 49 | }, |
47 | xAxis: { | 50 | xAxis: { |
48 | type: "category", | 51 | type: "category", |
@@ -52,7 +55,7 @@ export default { | @@ -52,7 +55,7 @@ export default { | ||
52 | show: false, | 55 | show: false, |
53 | }, | 56 | }, |
54 | axisLabel: { | 57 | axisLabel: { |
55 | - color: "#666", | 58 | + color: "#333", |
56 | }, | 59 | }, |
57 | }, | 60 | }, |
58 | yAxis: { | 61 | yAxis: { |
@@ -63,13 +66,16 @@ export default { | @@ -63,13 +66,16 @@ export default { | ||
63 | }, | 66 | }, |
64 | axisLabel: { | 67 | axisLabel: { |
65 | color: "#666", | 68 | color: "#666", |
69 | + formatter: function (name) { | ||
70 | + return name + "%" | ||
71 | + }, | ||
66 | }, | 72 | }, |
67 | }, | 73 | }, |
68 | grid: { | 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 | containLabel: true, | 79 | containLabel: true, |
74 | }, | 80 | }, |
75 | series: that.params.map((item) => { | 81 | series: that.params.map((item) => { |
@@ -77,9 +83,9 @@ export default { | @@ -77,9 +83,9 @@ export default { | ||
77 | name: item.name, | 83 | name: item.name, |
78 | type: "line", | 84 | type: "line", |
79 | symbol: "circle", | 85 | symbol: "circle", |
80 | - symbolSize: "8", | 86 | + symbolSize: "6", |
81 | lineStyle: { | 87 | lineStyle: { |
82 | - width: 3, | 88 | + width: 1, |
83 | }, | 89 | }, |
84 | data: item.value, | 90 | data: item.value, |
85 | }; | 91 | }; |
src/components/charts/radarChart.vue
@@ -24,45 +24,62 @@ export default { | @@ -24,45 +24,62 @@ export default { | ||
24 | chart: null, | 24 | chart: null, |
25 | }; | 25 | }; |
26 | }, | 26 | }, |
27 | - created() {}, | 27 | + created() { }, |
28 | mounted() { | 28 | mounted() { |
29 | this.initData(); | 29 | this.initData(); |
30 | }, | 30 | }, |
31 | methods: { | 31 | methods: { |
32 | setOption() { | 32 | setOption() { |
33 | + let that = this | ||
33 | const option = { | 34 | const option = { |
34 | - color: this.colors || ["#4472c4", "#ed7d32", "#a5a5a5"], | 35 | + color: that.colors || ["#4472c4", "#ed7d32", "#a5a5a5"], |
35 | backgroundColor: "#fff", | 36 | backgroundColor: "#fff", |
36 | tooltip: { | 37 | tooltip: { |
37 | trigger: "item", | 38 | trigger: "item", |
38 | confine: true, | 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 | legend: { | 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 | radar: { | 57 | radar: { |
46 | - indicator: [...this.params.indicator], | 58 | + indicator: [...that.params.indicator], |
47 | splitNumber: 5, | 59 | splitNumber: 5, |
48 | - center:['50%', '48%'], | ||
49 | - radius:"70%", | 60 | + center: ['50%', '48%'], |
61 | + radius: "80%", | ||
50 | shape: "polygon", | 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 | lineStyle: { | 68 | lineStyle: { |
57 | width: 0.5, | 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 | series: [ | 84 | series: [ |
68 | { | 85 | { |
@@ -74,7 +91,7 @@ export default { | @@ -74,7 +91,7 @@ export default { | ||
74 | areaStyle: { | 91 | areaStyle: { |
75 | color: "transparent", | 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,7 +35,7 @@ Mock.mock( | ||
35 | "answerOptions": "A,B,C,D", | 35 | "answerOptions": "A,B,C,D", |
36 | "correctAnswer|1": ["A", "B", "C", "D"], | 36 | "correctAnswer|1": ["A", "B", "C", "D"], |
37 | "screenshot": "./1.html", | 37 | "screenshot": "./1.html", |
38 | - "knowledge":"数与式#有理数#正数和负数,数与式#有理数#有理数" | 38 | + "knowledge": "数与式#有理数#正数和负数,数与式#有理数#有理数" |
39 | }, | 39 | }, |
40 | { | 40 | { |
41 | "questionType": 2, | 41 | "questionType": 2, |
@@ -45,7 +45,7 @@ Mock.mock( | @@ -45,7 +45,7 @@ Mock.mock( | ||
45 | "answerOptions": "A,B,C,D", | 45 | "answerOptions": "A,B,C,D", |
46 | "correctAnswer|1": ["A", "B", "C", "D"], | 46 | "correctAnswer|1": ["A", "B", "C", "D"], |
47 | "screenshot": "./1.html", | 47 | "screenshot": "./1.html", |
48 | - "knowledge":"数与式#有理数#正数和负数" | 48 | + "knowledge": "数与式#有理数#正数和负数" |
49 | }, | 49 | }, |
50 | { | 50 | { |
51 | "questionType": 2, | 51 | "questionType": 2, |
@@ -208,4 +208,503 @@ Mock.mock( | @@ -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 | \ No newline at end of file | 711 | \ No newline at end of file |
src/router/index.js
@@ -22,6 +22,7 @@ const AskList = () => import("@/views/basic/ask/list") | @@ -22,6 +22,7 @@ const AskList = () => import("@/views/basic/ask/list") | ||
22 | const AskAnalysis = () => import("@/views/basic/ask/analysis") | 22 | const AskAnalysis = () => import("@/views/basic/ask/analysis") |
23 | const AskArchiving = () => import("@/views/basic/ask/archiving") | 23 | const AskArchiving = () => import("@/views/basic/ask/archiving") |
24 | const Test = () => import("@/views/basic/test/index") | 24 | const Test = () => import("@/views/basic/test/index") |
25 | +const TestList = () => import("@/views/basic/test/list") | ||
25 | const TestAnalysis = () => import("@/views/basic/test/analysis") | 26 | const TestAnalysis = () => import("@/views/basic/test/analysis") |
26 | const TestArchiving = () => import("@/views/basic/test/archiving") | 27 | const TestArchiving = () => import("@/views/basic/test/archiving") |
27 | const DataSync = () => import("@/views/basic/dataSync/index") | 28 | const DataSync = () => import("@/views/basic/dataSync/index") |
@@ -214,9 +215,6 @@ let addrouters = [ | @@ -214,9 +215,6 @@ let addrouters = [ | ||
214 | iconCls: "fa fa-bar-chart", // 图标样式class | 215 | iconCls: "fa fa-bar-chart", // 图标样式class |
215 | name: "随堂问报表", | 216 | name: "随堂问报表", |
216 | component: Ask, | 217 | component: Ask, |
217 | - meta: { | ||
218 | - keepAlive: true, | ||
219 | - }, | ||
220 | children: [] | 218 | children: [] |
221 | 219 | ||
222 | }, | 220 | }, |
@@ -260,18 +258,23 @@ let addrouters = [ | @@ -260,18 +258,23 @@ let addrouters = [ | ||
260 | iconCls: "fa fa-pie-chart", // 图标样式class | 258 | iconCls: "fa fa-pie-chart", // 图标样式class |
261 | name: "", | 259 | name: "", |
262 | component: Test, | 260 | component: Test, |
263 | - meta: { | ||
264 | - keepAlive: true, | ||
265 | - }, | ||
266 | children: [] | 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 | path: "/testArchiving", | 280 | path: "/testArchiving", |
src/views/basic/ask/index.vue
@@ -97,8 +97,8 @@ export default { | @@ -97,8 +97,8 @@ export default { | ||
97 | 97 | ||
98 | methods: { | 98 | methods: { |
99 | handleCheckAllChange(val) { | 99 | handleCheckAllChange(val) { |
100 | + this.isIndeterminate = false; | ||
100 | this.query.subjectNames = val ? this.subjectList : []; | 101 | this.query.subjectNames = val ? this.subjectList : []; |
101 | - this.allSubject = false; | ||
102 | }, | 102 | }, |
103 | handleChecked(value) { | 103 | handleChecked(value) { |
104 | console.log(value) | 104 | console.log(value) |
src/views/basic/test/analysis.vue
@@ -2,1013 +2,85 @@ | @@ -2,1013 +2,85 @@ | ||
2 | <div ref="main" class="page-container"> | 2 | <div ref="main" class="page-container"> |
3 | <back-box> | 3 | <back-box> |
4 | <template slot="title"> | 4 | <template slot="title"> |
5 | - <span>单卷分析</span> | 5 | + <span>{{ type == 1 ? '单卷测练报表' : type == 2 ? subject + "汇总报表" : type == 3 ? "多科汇总报表" : |
6 | + `多班_${subjectName}_${title}_测练成绩对比分析` }}</span> | ||
6 | </template> | 7 | </template> |
7 | </back-box> | 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 | </div> | 13 | </div> |
527 | </template> | 14 | </template> |
528 | 15 | ||
529 | <script> | 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 | export default { | 21 | export default { |
22 | + components: { | ||
23 | + Test, | ||
24 | + MultipleTest, | ||
25 | + MultipleSubTest, | ||
26 | + Contrast | ||
27 | + }, | ||
532 | data() { | 28 | data() { |
533 | return { | 29 | return { |
534 | role: "", | 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 | id: "", | 31 | id: "", |
542 | - classId: "", | ||
543 | - subjectName: "", | ||
544 | - title: "", | ||
545 | - score: "", | ||
546 | - tabList: ["试题分析", "成绩排名", "小题分报表", "作答明细表"], | 32 | + ids: [], |
547 | type: 0, | 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 | created() { | 39 | created() { |
590 | this.role = | 40 | this.role = |
591 | this.$store.getters.info.showRole || | 41 | this.$store.getters.info.showRole || |
592 | this.$store.getters.info.permissions[0].role; | 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 | this.classId = this.$route.query.classId || ""; | 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 | methods: { | 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 | </script> | 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 | <style lang="scss" scoped> | 55 | <style lang="scss" scoped> |
881 | -.hide { | ||
882 | - display: none; | ||
883 | -} | ||
884 | .page-container { | 56 | .page-container { |
885 | position: relative; | 57 | position: relative; |
886 | height: 100%; | 58 | height: 100%; |
59 | + | ||
887 | .table-box { | 60 | .table-box { |
888 | min-height: 100%; | 61 | min-height: 100%; |
889 | } | 62 | } |
63 | + | ||
890 | &.active { | 64 | &.active { |
891 | overflow: hidden; | 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 | .error { | 71 | .error { |
910 | color: #f30; | 72 | color: #f30; |
911 | } | 73 | } |
74 | + | ||
912 | .page-content { | 75 | .page-content { |
913 | padding: 20px 20px 0; | 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 | .down { | 80 | .down { |
960 | padding-top: 20px; | 81 | padding-top: 20px; |
961 | width: 100%; | 82 | width: 100%; |
962 | display: flex; | 83 | display: flex; |
963 | justify-content: space-between; | 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 | </style> | 86 | </style> |
1015 | \ No newline at end of file | 87 | \ No newline at end of file |
src/views/basic/test/components/test.vue
@@ -308,7 +308,11 @@ export default { | @@ -308,7 +308,11 @@ export default { | ||
308 | range: [], | 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 | created() { | 318 | created() { |
@@ -563,8 +567,29 @@ export default { | @@ -563,8 +567,29 @@ export default { | ||
563 | async exportData() { | 567 | async exportData() { |
564 | if (this.exportLoading == true) return; | 568 | if (this.exportLoading == true) return; |
565 | this.exportLoading = true; | 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 | examId: this.id, | 591 | examId: this.id, |
592 | + ...query | ||
568 | }); | 593 | }); |
569 | this.exportLoading = false; | 594 | this.exportLoading = false; |
570 | if (data) { | 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 | \ No newline at end of file | 0 | \ No newline at end of file |
src/views/basic/test/index.vue
1 | <template> | 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 | </div> | 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 | </div> | 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 | </div> | 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 | </p> | 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 | </div> | 60 | </div> |
502 | - </el-dialog> | 61 | + </div> |
503 | </div> | 62 | </div> |
504 | </template> | 63 | </template> |
505 | 64 | ||
506 | <script> | 65 | <script> |
507 | -import { formatDate, downloadFile, tablePrint } from "utils"; | ||
508 | -import BusEvent from "@/utils/busEvent"; | 66 | +import { formatDate } from "utils"; |
509 | export default { | 67 | export default { |
510 | data() { | 68 | data() { |
511 | return { | 69 | return { |
512 | code: "", | 70 | code: "", |
513 | - gdClass: 0, //已归档班级数量 | ||
514 | - exportLoading: false, | ||
515 | - tableMaxHeight: 300, | ||
516 | role: "", | 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 | date: "", //今天-昨天-本周 | 72 | date: "", //今天-昨天-本周 |
528 | query: { | 73 | query: { |
529 | //搜索条件 | 74 | //搜索条件 |
530 | - classId: "", | ||
531 | - subjectNames: "", | 75 | + classId: [], |
76 | + subjectNames: [], | ||
532 | startDay: "", | 77 | startDay: "", |
533 | endDay: "", | 78 | endDay: "", |
534 | - day: "", | ||
535 | }, | 79 | }, |
536 | - tabList: ["单卷测练报表", "阶段测练报表"], | ||
537 | classList: [], //班级 | 80 | classList: [], //班级 |
538 | subjectList: [], //科目 | 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 | async created() { | 89 | async created() { |
@@ -549,7 +91,7 @@ export default { | @@ -549,7 +91,7 @@ export default { | ||
549 | this.role = | 91 | this.role = |
550 | this.$store.getters.info.showRole || | 92 | this.$store.getters.info.showRole || |
551 | this.$store.getters.info.permissions[0].role; | 93 | this.$store.getters.info.permissions[0].role; |
552 | - this._QueryClassList2(); | 94 | + this.query.subjectNames = []; |
553 | await this._QueryClassList(); | 95 | await this._QueryClassList(); |
554 | if (!this.query.classId) { | 96 | if (!this.query.classId) { |
555 | return; | 97 | return; |
@@ -562,115 +104,37 @@ export default { | @@ -562,115 +104,37 @@ export default { | ||
562 | this.query.endDay = new Date(); | 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 | methods: { | 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 | setDate(index) { | 129 | setDate(index) { |
659 | const that = this; | 130 | const that = this; |
660 | this.date = index == this.date ? "" : index; | 131 | this.date = index == this.date ? "" : index; |
661 | let aYear = new Date().getFullYear(); | 132 | let aYear = new Date().getFullYear(); |
662 | let aMonth = new Date().getMonth() + 1; | 133 | let aMonth = new Date().getMonth() + 1; |
663 | - that.query.day = ""; | ||
664 | that.query.startDay = ""; | 134 | that.query.startDay = ""; |
665 | that.query.endDay = ""; | 135 | that.query.endDay = ""; |
666 | switch (index) { | 136 | switch (index) { |
667 | case 1: | 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 | let day = new Date().getDay(); | 138 | let day = new Date().getDay(); |
675 | if (day == 0) { | 139 | if (day == 0) { |
676 | //中国式星期天是一周的最后一天 | 140 | //中国式星期天是一周的最后一天 |
@@ -681,12 +145,12 @@ export default { | @@ -681,12 +145,12 @@ export default { | ||
681 | that.query.startDay = formatDate(new Date(aTime), "yyyy-MM-dd"); | 145 | that.query.startDay = formatDate(new Date(aTime), "yyyy-MM-dd"); |
682 | that.query.endDay = formatDate(new Date(), "yyyy-MM-dd"); | 146 | that.query.endDay = formatDate(new Date(), "yyyy-MM-dd"); |
683 | break; | 147 | break; |
684 | - case 3: | 148 | + case 2: |
685 | aMonth = aMonth < 10 ? "0" + aMonth : aMonth; | 149 | aMonth = aMonth < 10 ? "0" + aMonth : aMonth; |
686 | that.query.startDay = `${aYear}-${aMonth}-01`; | 150 | that.query.startDay = `${aYear}-${aMonth}-01`; |
687 | that.query.endDay = formatDate(new Date(), "yyyy-MM-dd"); | 151 | that.query.endDay = formatDate(new Date(), "yyyy-MM-dd"); |
688 | break; | 152 | break; |
689 | - case 4: | 153 | + case 3: |
690 | if (aMonth > 0 && aMonth < 4) { | 154 | if (aMonth > 0 && aMonth < 4) { |
691 | aMonth = "1"; | 155 | aMonth = "1"; |
692 | } else if (aMonth > 3 && aMonth < 7) { | 156 | } else if (aMonth > 3 && aMonth < 7) { |
@@ -703,10 +167,8 @@ export default { | @@ -703,10 +167,8 @@ export default { | ||
703 | break; | 167 | break; |
704 | } | 168 | } |
705 | this.page = 1; | 169 | this.page = 1; |
706 | - this._QueryData(); | ||
707 | }, | 170 | }, |
708 | handleChangeTimeStart(val) { | 171 | handleChangeTimeStart(val) { |
709 | - this.query.day = ""; | ||
710 | this.date = ""; | 172 | this.date = ""; |
711 | if (this.query.endDay) { | 173 | if (this.query.endDay) { |
712 | if (new Date(val).getTime() > new Date(this.query.endDay).getTime()) { | 174 | if (new Date(val).getTime() > new Date(this.query.endDay).getTime()) { |
@@ -716,67 +178,21 @@ export default { | @@ -716,67 +178,21 @@ export default { | ||
716 | } | 178 | } |
717 | }, | 179 | }, |
718 | handleChangeTimeEnd(val) { | 180 | handleChangeTimeEnd(val) { |
719 | - this.query.day = ""; | ||
720 | this.date = ""; | 181 | this.date = ""; |
721 | - if (this.query.startDay) { | 182 | + if (this.query.startDay && val) { |
722 | if (new Date(val).getTime() < new Date(this.query.startDay).getTime()) { | 183 | if (new Date(val).getTime() < new Date(this.query.startDay).getTime()) { |
723 | this.$message.error("任务结束时间不能任务开始时间前面,请重新设置"); | 184 | this.$message.error("任务结束时间不能任务开始时间前面,请重新设置"); |
724 | this.query.endDay = ""; | 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 | async _QueryClassList() { | 189 | async _QueryClassList() { |
776 | const fetchClassList = | 190 | const fetchClassList = |
777 | this.role == "ROLE_BANZHUREN" | 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 | const { data, status, info } = await fetchClassList(); | 196 | const { data, status, info } = await fetchClassList(); |
781 | if (status === 0) { | 197 | if (status === 0) { |
782 | this.classList = data.list.map((item) => { | 198 | this.classList = data.list.map((item) => { |
@@ -785,7 +201,7 @@ export default { | @@ -785,7 +201,7 @@ export default { | ||
785 | label: item.className, | 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 | } else { | 205 | } else { |
790 | this.$message.error(info); | 206 | this.$message.error(info); |
791 | } | 207 | } |
@@ -793,275 +209,191 @@ export default { | @@ -793,275 +209,191 @@ export default { | ||
793 | async _QuerySubjectList() { | 209 | async _QuerySubjectList() { |
794 | const fetchSubjectList = | 210 | const fetchSubjectList = |
795 | this.role == "ROLE_BANZHUREN" | 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 | const { data, status, info } = await fetchSubjectList({ | 218 | const { data, status, info } = await fetchSubjectList({ |
800 | - classId: this.query.classId, | 219 | + classIds: classIds, |
801 | }); | 220 | }); |
802 | if (status === 0) { | 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 | } else { | 228 | } else { |
820 | this.$message.error(info); | 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 | </script> | 250 | </script> |
1028 | - | ||
1029 | <style> | 251 | <style> |
1030 | div::-webkit-scrollbar { | 252 | div::-webkit-scrollbar { |
1031 | width: 3px; | 253 | width: 3px; |
1032 | height: 10px; | 254 | height: 10px; |
1033 | } | 255 | } |
256 | + | ||
1034 | div::-webkit-scrollbar-thumb { | 257 | div::-webkit-scrollbar-thumb { |
1035 | border-radius: 10px; | 258 | border-radius: 10px; |
1036 | background-color: #ccc; | 259 | background-color: #ccc; |
1037 | } | 260 | } |
1038 | </style> | 261 | </style> |
1039 | <style lang="scss" scoped> | 262 | <style lang="scss" scoped> |
1040 | -.page-container { | ||
1041 | - position: relative; | 263 | +.main { |
1042 | height: 100%; | 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 | </style> | 399 | </style> |
1068 | \ No newline at end of file | 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 | \ No newline at end of file | 349 | \ No newline at end of file |