Commit 6bca489df6140d21609dd2d04323ddc06147d429
1 parent
f45b3c05
云平台二期UI
Showing
42 changed files
with
3994 additions
and
1427 deletions
.vs/Ezquiz_Platform/FileContentIndex/55df62fa-5432-4cfd-bb10-cbdb5e263ba4.vsidx deleted
No preview for this file type
.vs/slnx.sqlite
No preview for this file type
src/App.vue
... | ... | @@ -18,70 +18,73 @@ export default { |
18 | 18 | const $app = this.$refs.app; |
19 | 19 | // 设置 屏幕 百分比 尺寸 适配 |
20 | 20 | const standardScale = "100%" / "100%"; |
21 | - var minHeight = 1080; | |
22 | 21 | window.addEventListener( |
23 | 22 | "resize", |
24 | 23 | _.debounce(function () { |
24 | + | |
25 | 25 | const docHeight = document.body.clientHeight; |
26 | + | |
26 | 27 | const docWidth = document.body.clientWidth; |
27 | - | |
28 | + | |
28 | 29 | if (docWidth < 1700) { |
30 | + | |
29 | 31 | const currentScale = docHeight / docWidth; |
32 | + | |
30 | 33 | let [scale, translate] = [0, 0]; |
34 | + | |
31 | 35 | if (currentScale < standardScale) { |
32 | 36 | // 以高度计算 |
33 | 37 | scale = docHeight / 1080; |
38 | + | |
34 | 39 | const shouleWidth = 1920 * scale; |
35 | 40 | |
36 | 41 | const offsetWidth = docWidth - shouleWidth; |
42 | + | |
37 | 43 | translate = |
38 | 44 | offsetWidth > 0 ? `translate(${offsetWidth / 2}px, 0)` : ""; |
45 | + | |
39 | 46 | } else { |
40 | 47 | // 以宽度计算 |
41 | 48 | scale = docWidth / 1920; |
49 | + | |
42 | 50 | const shouleHeight = 1080 * scale; |
51 | + | |
43 | 52 | const offsetHeight = docHeight - shouleHeight; |
53 | + | |
44 | 54 | translate = |
45 | 55 | offsetHeight > 0 ? `translate(0, ${offsetHeight / 2}px)` : ""; |
46 | - } | |
47 | - | |
48 | - if (docHeight <= 600) { | |
49 | - $app.style.cssText = ` | |
50 | - transform: scale(${scale}) ${translate}; | |
51 | - transform-origin: top left; | |
52 | - min-width: 1920px; | |
53 | - min-height:500px; | |
54 | - `; | |
55 | - } | |
56 | + } | |
57 | + | |
56 | 58 | if (docHeight <= 700) { |
59 | + | |
57 | 60 | $app.style.cssText = ` |
58 | - transform: scale(${scale}) ${translate}; | |
59 | - transform-origin: top left; | |
60 | - min-width: 1920px; | |
61 | - min-height:900px; | |
62 | - `; | |
61 | + transform: scale(${scale}) ${translate}; | |
62 | + transform-origin: top left; | |
63 | + min-width: 1920px; | |
64 | + min-height: 850px; | |
65 | + `; | |
63 | 66 | } |
64 | 67 | else if (docHeight <= 750) { |
68 | + | |
65 | 69 | $app.style.cssText = ` |
66 | - transform: scale(${scale}) ${translate}; | |
67 | - transform-origin: top left; | |
68 | - min-width: 1920px; | |
69 | - min-height:920px; | |
70 | - `; | |
70 | + transform: scale(${scale}) ${translate}; | |
71 | + transform-origin: top left; | |
72 | + min-width: 1920px; | |
73 | + min-height:920px; | |
74 | + `; | |
71 | 75 | } |
72 | 76 | else { |
73 | 77 | $app.style.cssText = ` |
74 | - transform: scale(${scale}) ${translate}; | |
75 | - transform-origin: top left; | |
76 | - min-width: 1920px; | |
77 | - min-height:1080px; | |
78 | - `; | |
78 | + transform: scale(${scale}) ${translate}; | |
79 | + transform-origin: top left; | |
80 | + min-width: 1920px; | |
81 | + min-height:1080px; | |
82 | + `; | |
79 | 83 | } |
80 | 84 | |
81 | 85 | } else { |
82 | 86 | $app.style.cssText = ''; |
83 | 87 | } |
84 | - | |
85 | 88 | }), |
86 | 89 | 300 |
87 | 90 | ); |
... | ... | @@ -103,8 +106,7 @@ export default { |
103 | 106 | body { |
104 | 107 | margin: 0px; |
105 | 108 | padding: 0px; |
106 | - font-family: Microsoft YaHei, Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, SimSun, sans-serif; | |
107 | - font-size: 14px; | |
109 | + font-family: Microsoft YaHei, Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, SimSun, sans-serif; | |
108 | 110 | -webkit-font-smoothing: antialiased; |
109 | 111 | } |
110 | 112 | ... | ... |
src/api/apis/apis.js
... | ... | @@ -23,8 +23,14 @@ const downService = (url, data) => { |
23 | 23 | responseType: 'arraybuffer', |
24 | 24 | }); |
25 | 25 | } |
26 | -export default { | |
27 | - // 年级组长-成绩测验单 | |
26 | +export default { | |
27 | + // 知识点 | |
28 | + gKnowledge(section, subject) { | |
29 | + return defaltService(setUpUrls.gtestExamReport, { | |
30 | + ...subject, ...section | |
31 | + }) | |
32 | + }, | |
33 | + // 年级组长-成绩测验单 | |
28 | 34 | gTestExamReport(data) { |
29 | 35 | return defaltService(setUpUrls.gtestExamReport, data) |
30 | 36 | }, |
... | ... | @@ -60,7 +66,7 @@ export default { |
60 | 66 | gExportPhaseInteractiveReport(data) { |
61 | 67 | return downService(setUpUrls.gExportPhaseInteractiveReport, data) |
62 | 68 | }, |
63 | - | |
69 | + | |
64 | 70 | // 年级组长-首页统计数据 |
65 | 71 | gIndex(data) { |
66 | 72 | return defaltService(setUpUrls.gIndex, data) |
... | ... | @@ -146,8 +152,27 @@ export default { |
146 | 152 | return defaltService(setUpUrls.tClassList, data) |
147 | 153 | }, |
148 | 154 | //任课老师-查询管理的班级 |
149 | - tClassFromGrade(data) { | |
150 | - return defaltGetService(setUpUrls.tClassFromGrade + "?classId=" + data) | |
155 | + tClassFromGrade(classId = null, subjectName = null) { | |
156 | + var requestParams = []; | |
157 | + if (classId) { | |
158 | + requestParams.push("classId=" + classId); | |
159 | + } | |
160 | + if (subjectName) { | |
161 | + requestParams.push("subjectName=" + subjectName); | |
162 | + } | |
163 | + var requestUrl = setUpUrls.tClassFromGrade + (requestParams.length >= 1 ? "?" + requestParams.join("&") : ""); | |
164 | + return defaltGetService(requestUrl) | |
165 | + }, | |
166 | + tClassGrade(grade = null, subjectName = null) { | |
167 | + var requestParams = []; | |
168 | + if (grade) { | |
169 | + requestParams.push("grade=" + grade); | |
170 | + } | |
171 | + if (subjectName) { | |
172 | + requestParams.push("subjectName=" + subjectName); | |
173 | + } | |
174 | + var requestUrl = setUpUrls.tClassGrade + (requestParams.length >= 1 ? "?" + requestParams.join("&") : ""); | |
175 | + return defaltGetService(requestUrl) | |
151 | 176 | }, |
152 | 177 | tPaperDetail(data) { |
153 | 178 | return defaltService(setUpUrls.tPaperDetail, data) |
... | ... | @@ -168,6 +193,18 @@ export default { |
168 | 193 | tClassdiffExamReport(data) { |
169 | 194 | return defaltService(setUpUrls.tclassdiffExamReport, data) |
170 | 195 | }, |
196 | + tgexportPhaseExamReport(data) { | |
197 | + return downService(setUpUrls.gExportPhaseExamReport, data) | |
198 | + }, | |
199 | + tgexportPhaseExamReport2(data) { | |
200 | + return downService(setUpUrls.gexportPhaseExamReport2, data) | |
201 | + }, | |
202 | + tgexportPhaseExamReport3(data) { | |
203 | + return downService(setUpUrls.gexportPhaseExamReport3, data) | |
204 | + }, | |
205 | + tgexportPhaseExamReport4(data) { | |
206 | + return downService(setUpUrls.gexportPhaseExamReport4, data) | |
207 | + }, | |
171 | 208 | //任课老师-查询管理班级授课科目 |
172 | 209 | tListExamReport(data) { |
173 | 210 | return defaltService(setUpUrls.tListExamReport, data) |
... | ... | @@ -926,8 +963,12 @@ export default { |
926 | 963 | // 查询即时测多班默认等级列表 |
927 | 964 | defaultLevels(data) { |
928 | 965 | return defaltService(setUpUrls.defaultLevels, data) |
966 | + }, // 查询即时测多班默认等级列表 | |
967 | + gdefaultLevels(data) { | |
968 | + return defaltService(setUpUrls.gdefaultLevels, data) | |
929 | 969 | }, |
930 | 970 | |
971 | + | |
931 | 972 | // 删除随堂问报表 |
932 | 973 | deletePaperReport(data) { |
933 | 974 | return defaltService(setUpUrls.deletePaperReport, data) | ... | ... |
src/api/urls/apis.js
1 | 1 | |
2 | 2 | export default { |
3 | + // 年级组长-查询报表列表 | |
4 | + gKnowledge: "/api_html/knowledge/list", | |
3 | 5 | // 年级组长-查询报表列表 |
4 | 6 | gListExamReport: "/api_html/grade/manager/listExamReport", |
5 | 7 | // 年级组长-查询管理的班级 |
... | ... | @@ -8,6 +10,9 @@ export default { |
8 | 10 | gExportPhaseAnswerReport: "/api_html/grade/manager/exportPhaseAnswerReport", |
9 | 11 | // 年级组长-导出阶段测练 |
10 | 12 | gExportPhaseExamReport: "/api_html/grade/manager/exportPhaseExamReport", |
13 | + gexportPhaseExamReport2: "/api_html/grade/manager/exportPhaseExamReport2", | |
14 | + gexportPhaseExamReport3: "/api_html/grade/manager/exportPhaseExamReport3", | |
15 | + gexportPhaseExamReport4: "/api_html/grade/manager/exportPhaseExamReport4", | |
11 | 16 | // 年级组长-导出阶段问答 |
12 | 17 | gExportPhaseInteractiveReport: "/api_html/grade/manager/exportPhaseInteractiveReport", |
13 | 18 | // 年级组长-成绩测验单 |
... | ... | @@ -63,19 +68,21 @@ export default { |
63 | 68 | // 任课老师-班级情况对比 |
64 | 69 | tclassdiffExamReport: "/api_html/teaching/classdiffExamReport", |
65 | 70 | tClassFromGrade: "/api_html/teaching/grade/classList", |
71 | + tClassGrade:'/api_html/teaching/grade', | |
66 | 72 | //任课老师-测验成绩单 |
67 | 73 | tTestExamReport: "/api_html/teaching/testExamReport", |
68 | 74 | //任课老师-查询答题卡详情 |
69 | 75 | tPaperDetail: "/api_html/teaching/paperDetail", |
70 | 76 | //任课老师-查询管理班级授课科目 |
71 | 77 | tSubjectList: "/api_html/teaching/subjectList", |
72 | - tListExamReport: "/api_html/teaching/listExamReport", | |
78 | + tListExamReport: "/api_html/teaching/listExamReport", | |
73 | 79 | //任课老师-分页查询课时报表列表 |
74 | 80 | periodReportList: "/api_html/teaching/periodReportList", |
75 | 81 | //任课老师-查询阶段问答报表 |
76 | 82 | phaseAnswerReport: "/api_html/teaching/phaseAnswerReport", |
77 | 83 | //任课老师-查询阶段互动报表 |
78 | 84 | phaseInteractiveReport: "/api_html/teaching/phaseInteractiveReport", |
85 | + exportPhaseExamReport: "/api_html/teaching/exportPhaseExamReport", | |
79 | 86 | //任课老师-查询课时题目列表 |
80 | 87 | periodQuestionList: "/api_html/teaching/periodQuestionList", |
81 | 88 | //任课老师-设置课时报表答案 |
... | ... | @@ -116,8 +123,7 @@ export default { |
116 | 123 | exportPhaseInteractiveReport: "/api_html/teaching/exportPhaseInteractiveReport", |
117 | 124 | //任课老师-导出单课时报表 |
118 | 125 | exportPeriodReport: "/api_html/teaching/exportPeriodReport", |
119 | - //任课老师-导出阶段测练报表 | |
120 | - exportPhaseExamReport: "/api_html/teaching/exportPhaseExamReport", | |
126 | + | |
121 | 127 | //任课老师-导出单卷测练报表 |
122 | 128 | exportExamReport: "/api_html/teaching/exportExamReport", |
123 | 129 | //任课老师-查询学生列表 |
... | ... | @@ -475,6 +481,7 @@ export default { |
475 | 481 | exportExamMultiReport: "/api_html/teaching/exportExamMultiReport", |
476 | 482 | //查询即时测多班默认等级列表 |
477 | 483 | defaultLevels: "/api_html/teaching/defaultLevels", |
484 | + gdefaultLevels: "/api_html/grade/manager/defaultLevels", | |
478 | 485 | //教学班模版下载 |
479 | 486 | tClassAndStudentTemplate: "/api_html/school/manager/tClassAndStudentTemplate", |
480 | 487 | //教学班导出 | ... | ... |
src/assets/css/index.scss
... | ... | @@ -27,12 +27,29 @@ |
27 | 27 | } |
28 | 28 | } |
29 | 29 | |
30 | +.lowLevelClass { | |
31 | + color: white; | |
32 | + background: #FFA41C; | |
33 | + background-size: 200% 200%; | |
34 | + height: 100%; | |
35 | + width: 100%; | |
36 | +} | |
37 | + | |
38 | +.overflowText { | |
39 | + white-space: nowrap; | |
40 | + width: calc(100% - 5px); //文字宽度 | |
41 | + overflow: hidden; //超出宽度隐藏 | |
42 | + white-space: nowrap; //强制文字在一行 | |
43 | + text-overflow: ellipsis; //文字溢出显示省略号 | |
44 | +} | |
45 | + | |
30 | 46 | .green-el-button { |
31 | 47 | background-color: rgba(65, 204, 149, 1); |
32 | 48 | color: white; |
33 | 49 | border-color: rgba(65, 204, 149, 1); |
34 | 50 | |
35 | - :focus,:hover { | |
51 | + :focus, | |
52 | + :hover { | |
36 | 53 | background-color: rgba(65, 204, 149, 1); |
37 | 54 | color: white; |
38 | 55 | border-color: rgba(65, 204, 149, 1); |
... | ... | @@ -56,7 +73,7 @@ |
56 | 73 | flex-wrap: nowrap; |
57 | 74 | |
58 | 75 | .sel { |
59 | - width: 8%; | |
76 | + width: 10%; | |
60 | 77 | min-width: 160px; |
61 | 78 | margin-right: 20px; |
62 | 79 | } |
... | ... | @@ -78,7 +95,7 @@ |
78 | 95 | } |
79 | 96 | |
80 | 97 | .input-with-select { |
81 | - width: 200px; | |
98 | + width: 230px; | |
82 | 99 | height: 36px; |
83 | 100 | margin-right: 50px; |
84 | 101 | border-radius: 20px; |
... | ... | @@ -290,6 +307,31 @@ ul { |
290 | 307 | } |
291 | 308 | } |
292 | 309 | |
310 | + | |
311 | +.parent-number { | |
312 | + position: relative; | |
313 | +} | |
314 | + | |
315 | +.parent-number::after { | |
316 | + content: '%'; | |
317 | + display: inline-block; | |
318 | + height: 20px; | |
319 | + line-height: 20px; | |
320 | + width: 20px; | |
321 | + text-align: center; | |
322 | + position: absolute; | |
323 | + right: 52px; | |
324 | + top: 50%; | |
325 | + transform: translateY(-50%); | |
326 | +} | |
327 | + | |
328 | +.parent-number .el-input__inner { | |
329 | + // 不加这行的话,当文本框里数值很大时,会和单位重叠 | |
330 | + padding-left: 30px; | |
331 | + padding-right: 48px; | |
332 | +} | |
333 | + | |
334 | + | |
293 | 335 | // 默认标题 |
294 | 336 | .default-title { |
295 | 337 | height: 36px; |
... | ... | @@ -302,6 +344,7 @@ ul { |
302 | 344 | text-transform: none; |
303 | 345 | } |
304 | 346 | |
347 | + | |
305 | 348 | // 默认实体 |
306 | 349 | .default-body { |
307 | 350 | font-size: 14px; |
... | ... | @@ -329,6 +372,9 @@ ul { |
329 | 372 | padding: 0px !important; |
330 | 373 | |
331 | 374 | .default-table { |
375 | + width: 100% !important; | |
376 | + height: 100% !important; | |
377 | + | |
332 | 378 | th { |
333 | 379 | font-weight: 400; |
334 | 380 | font-size: 14px; |
... | ... | @@ -336,11 +382,14 @@ ul { |
336 | 382 | text-align: left; |
337 | 383 | font-style: normal; |
338 | 384 | text-transform: none; |
339 | - border:1px solid #ebeef5; | |
385 | + border: 1px solid #ebeef5; | |
340 | 386 | } |
341 | 387 | |
342 | - tr,td { | |
343 | - height: 40px; border:1px solid #ebeef5; | |
388 | + tr, | |
389 | + td { | |
390 | + height: 40px; | |
391 | + padding: 5px 0px !important; | |
392 | + border: 1px solid #ebeef5; | |
344 | 393 | } |
345 | 394 | } |
346 | 395 | |
... | ... | @@ -379,8 +428,8 @@ ul { |
379 | 428 | padding: 14px 20px !important; |
380 | 429 | |
381 | 430 | * { |
382 | - height: 32px; | |
383 | - line-height: 32px; | |
431 | + height: 40px; | |
432 | + line-height: 40px; | |
384 | 433 | } |
385 | 434 | |
386 | 435 | .filter-input, |
... | ... | @@ -395,10 +444,14 @@ ul { |
395 | 444 | |
396 | 445 | input { |
397 | 446 | // border: 1px solid #DCDFE6; |
398 | - height: 31px; | |
447 | + height: calc(100% - 10px); | |
399 | 448 | } |
400 | 449 | } |
401 | 450 | |
451 | + .el-select__tags .el-tag { | |
452 | + height: 24px !important; | |
453 | + } | |
454 | + | |
402 | 455 | .el-button { |
403 | 456 | width: auto; |
404 | 457 | line-height: 0px; |
... | ... | @@ -409,4 +462,59 @@ ul { |
409 | 462 | background-color: rgb(107, 126, 245); |
410 | 463 | } |
411 | 464 | } |
465 | +} | |
466 | + | |
467 | +@media screen and (max-width: 1921px) and (max-height: 1081px) { | |
468 | + * :not(.p1, .fa, .el-button, .el-icon-upload, h1, h2, h3, h4, h5, h6) { | |
469 | + font-size: 18px !important; | |
470 | + | |
471 | + .default-title { | |
472 | + font-size: 24px !important; | |
473 | + } | |
474 | + | |
475 | + .el-button * { | |
476 | + font-size: 16px !important; | |
477 | + } | |
478 | + | |
479 | + .el-select-dropdown__item * { | |
480 | + font-size: 16px !important; | |
481 | + } | |
482 | + | |
483 | + .el-form :not(h1, h2, h3, h4, h5, h6), | |
484 | + .el-dropdown-menu__item, | |
485 | + .el-cascader-node__label { | |
486 | + font-size: 16px !important; | |
487 | + } | |
488 | + | |
489 | + } | |
490 | +} | |
491 | + | |
492 | +@media screen and (min-width: 1921px) and (min-height: 1081px) { | |
493 | + * :not(.p1, .fa, .el-button, .el-icon-upload, h1, h2, h3, h4, h5, h6) { | |
494 | + | |
495 | + font-size: 14px !important; | |
496 | + | |
497 | + .default-body .default-filter * { | |
498 | + line-height: 38px !important; | |
499 | + } | |
500 | + | |
501 | + .card-content { | |
502 | + width: 48% !important; | |
503 | + } | |
504 | + | |
505 | + .default-title { | |
506 | + font-size: 24px !important; | |
507 | + } | |
508 | + | |
509 | + .el-select-dropdown__item * { | |
510 | + font-size: 12px !important; | |
511 | + } | |
512 | + | |
513 | + .el-form :not(h1, h2, h3, h4, h5, h6), | |
514 | + .el-dropdown-menu__item, | |
515 | + .el-cascader-node__label { | |
516 | + font-size: 12px !important; | |
517 | + } | |
518 | + | |
519 | + } | |
412 | 520 | } |
413 | 521 | \ No newline at end of file | ... | ... |
src/assets/images/example.jpg deleted
519 KB
src/components/backBox.vue
1 | 1 | <template> |
2 | - <div class="back"> | |
2 | + <div class="back default-title"> | |
3 | 3 | <div class="back-l" @click="back"> |
4 | - <i class="fa fa-mail-reply-all"></i> | |
4 | + <i class="fa fa-mail-reply-all "></i> | |
5 | 5 | <slot name="title"></slot> |
6 | 6 | </div> |
7 | 7 | <div class="back-r"> |
... | ... | @@ -55,7 +55,6 @@ export default { |
55 | 55 | align-items: center; |
56 | 56 | cursor: pointer; |
57 | 57 | flex-shrink: 0; |
58 | - font-size: 18px; | |
59 | 58 | font-weight: 500; |
60 | 59 | } |
61 | 60 | |
... | ... | @@ -66,7 +65,6 @@ export default { |
66 | 65 | } |
67 | 66 | |
68 | 67 | .fa-mail-reply-all { |
69 | - font-size: 28px; | |
70 | 68 | color: #b3b3b3; |
71 | 69 | margin-right: 12px; |
72 | 70 | } | ... | ... |
src/components/charts/lineChart.vue
... | ... | @@ -3,6 +3,7 @@ |
3 | 3 | </template> |
4 | 4 | |
5 | 5 | <script> |
6 | +import 'echarts/lib/component/dataZoom' | |
6 | 7 | export default { |
7 | 8 | name: "lineChart", |
8 | 9 | props: { |
... | ... | @@ -11,7 +12,7 @@ export default { |
11 | 12 | xAxis: Array, |
12 | 13 | colors: Array, |
13 | 14 | formatterYAxis: true, |
14 | - tooltipFormatter:false | |
15 | + tooltipFormatter: false | |
15 | 16 | }, |
16 | 17 | watch: { |
17 | 18 | params: { |
... | ... | @@ -19,6 +20,7 @@ export default { |
19 | 20 | if (val.length) { |
20 | 21 | this.initData(); |
21 | 22 | } |
23 | + console.log(val) | |
22 | 24 | }, |
23 | 25 | deep: true, |
24 | 26 | }, |
... | ... | @@ -33,6 +35,43 @@ export default { |
33 | 35 | this.initData(); |
34 | 36 | }, |
35 | 37 | methods: { |
38 | + extension(chart) { | |
39 | + // 注意这里,是以X轴显示内容过长为例,如果是y轴的话,需要把params.componentType == 'xAxis'改为yAxis | |
40 | + // 判断是否创建过div框,如果创建过就不再创建了 | |
41 | + // 该div用来盛放文本显示内容的,方便对其悬浮位置进行处理 | |
42 | + var elementDiv = document.getElementById('extension') | |
43 | + if (!elementDiv) { | |
44 | + var div = document.createElement('div') | |
45 | + div.setAttribute('id', 'extension') | |
46 | + div.style.display = 'block' | |
47 | + document.querySelector('html').appendChild(div) | |
48 | + } | |
49 | + chart.on('mouseover', function (params) { | |
50 | + if (params.componentType == 'xAxis') { | |
51 | + var elementDiv = document.querySelector('#extension') | |
52 | + //设置悬浮文本的位置以及样式 | |
53 | + var elementStyle = | |
54 | + 'position: absolute;z-index: 99999;color: #fff;padding: 5px;display: inline;border-radius: 4px;background-color: #303133;box-shadow: rgba(0, 0, 0, 0.3) 2px 2px 8px' | |
55 | + elementDiv.style.cssText = elementStyle | |
56 | + elementDiv.innerHTML = params.value | |
57 | + document.querySelector('html').onmousemove = function (event) { | |
58 | + var elementDiv = document.querySelector('#extension') | |
59 | + var xx = event.pageX - 10 | |
60 | + var yy = event.pageY + 15 | |
61 | + elementDiv.style.top = yy + 'px' | |
62 | + elementDiv.style.left = xx + 'px' | |
63 | + } | |
64 | + } | |
65 | + }) | |
66 | + chart.on('mouseout', function (params) { | |
67 | + //注意这里,我是以X轴显示内容过长为例,如果是y轴的话,需要改为yAxis | |
68 | + if (params.componentType == 'xAxis') { | |
69 | + var elementDiv = document.querySelector('#extension') | |
70 | + | |
71 | + elementDiv.style.cssText = 'display:none' | |
72 | + } | |
73 | + }) | |
74 | + }, | |
36 | 75 | setOption() { |
37 | 76 | const that = this; |
38 | 77 | const options = { |
... | ... | @@ -43,10 +82,27 @@ export default { |
43 | 82 | confine: true, |
44 | 83 | formatter(v) { |
45 | 84 | let html = `<p>${v.seriesName}</p>` |
46 | - html += `${v.marker} ${v.name}:${Number(v.value)}${that.tooltipFormatter?'%':''}` | |
85 | + html += `${v.marker} ${v.name}:${Number(v.value)}${that.tooltipFormatter ? '%' : ''}` | |
47 | 86 | return html |
48 | 87 | }, |
49 | 88 | }, |
89 | + dataZoom: [{ | |
90 | + type: 'slider',//给x轴设置滚动条 | |
91 | + show: true, //flase直接隐藏图形 | |
92 | + xAxisIndex: [0], | |
93 | + bottom: 0, | |
94 | + height: 20, | |
95 | + showDetail: false, | |
96 | + startValue: 0,//滚动条的起始位置 | |
97 | + endValue: 9 //滚动条的截止位置(按比例分割你的柱状图x轴长度) | |
98 | + }, | |
99 | + { | |
100 | + type: 'inside',//设置鼠标滚轮缩放 | |
101 | + show: true, | |
102 | + xAxisIndex: [0], | |
103 | + startValue: 0, | |
104 | + endValue: 9 | |
105 | + }], | |
50 | 106 | legend: { |
51 | 107 | show: true, |
52 | 108 | top: 0, |
... | ... | @@ -54,18 +110,37 @@ export default { |
54 | 110 | itemHeight: 15, |
55 | 111 | icon: "circle" |
56 | 112 | }, |
113 | + grid: { | |
114 | + top: '3%', | |
115 | + right: '3%', | |
116 | + bottom: '3%', | |
117 | + left: '0%', | |
118 | + // 包含文本 | |
119 | + containLabel: true, | |
120 | + // 是否显示网格线 | |
121 | + show: true, | |
122 | + // 边框颜色 | |
123 | + borderColor: 'rgba(0, 240, 255, 0.3)', | |
124 | + }, | |
57 | 125 | xAxis: { |
58 | 126 | type: "category", |
59 | 127 | data: this.xAxis, |
60 | 128 | axisLine: { show: true, lineStyle: { color: "#e2e2e2" } }, |
61 | 129 | axisTick: { |
130 | + alignWithLabel: false, | |
62 | 131 | show: false, |
63 | 132 | }, |
133 | + triggerEvent: true, | |
64 | 134 | axisLabel: { |
65 | 135 | color: "#333", |
66 | 136 | interval: 0, |
67 | 137 | width: Math.ceil(600 / this.xAxis.length), |
68 | - overflow: "breakAll" | |
138 | + formatter: function (value) { | |
139 | + if (value.length > 3) { | |
140 | + return `${value.slice(0, 3)}...` | |
141 | + } | |
142 | + return value | |
143 | + } | |
69 | 144 | }, |
70 | 145 | }, |
71 | 146 | yAxis: { |
... | ... | @@ -100,7 +175,7 @@ export default { |
100 | 175 | data: item.value, |
101 | 176 | }; |
102 | 177 | }), |
103 | - }; | |
178 | + }; | |
104 | 179 | return options; |
105 | 180 | }, |
106 | 181 | initData() { |
... | ... | @@ -112,6 +187,7 @@ export default { |
112 | 187 | this.chart?.clear(); |
113 | 188 | this.chart.setOption(options, true); |
114 | 189 | this.chart.off("click"); |
190 | + this.extension(this.chart) | |
115 | 191 | this.chart.on("click", "series", (params) => { |
116 | 192 | // this.$emit("clickPieChart", params); |
117 | 193 | }); | ... | ... |
src/components/charts/pieChart.vue
src/components/lang/langSelect.vue
... | ... | @@ -40,12 +40,12 @@ export default { |
40 | 40 | } |
41 | 41 | </script> |
42 | 42 | <style> |
43 | - .international .el-dropdown-link { cursor: pointer; color: #666666; font-size: 14px; } | |
44 | - .el-icon-arrow-down { font-size: 14px; } | |
43 | + .international .el-dropdown-link { cursor: pointer; color: #666666; } | |
44 | + | |
45 | 45 | </style> |
46 | 46 | <style scoped> |
47 | 47 | .international-icon { |
48 | - font-size: 20px; | |
48 | + | |
49 | 49 | cursor: pointer; |
50 | 50 | vertical-align: -5px !important; |
51 | 51 | } | ... | ... |
src/components/setAnswer.vue
... | ... | @@ -82,8 +82,7 @@ |
82 | 82 | <el-dialog :close-on-click-modal="false" |
83 | 83 | title="批量设置答案" |
84 | 84 | :visible.sync="diaSetAns" |
85 | - width="400" :append-to-body="true" | |
86 | - :modal-append-to-body="false" | |
85 | + width="400" :append-to-body="true" | |
87 | 86 | > |
88 | 87 | <div class="qs-options set-questions"> |
89 | 88 | <p>{{ setSubPro(formAns.qusType) }}:</p> | ... | ... |
src/config/index.js
src/store/index.js
... | ... | @@ -56,7 +56,7 @@ const store = new Vuex.Store({ |
56 | 56 | } |
57 | 57 | |
58 | 58 | let aRouters = addrouterList.filter((item) => { |
59 | - | |
59 | + | |
60 | 60 | let path = item.children[0]?.path.replace("/", ""); |
61 | 61 | if (routers?.includes(path) == true) return item; |
62 | 62 | else if (item.demoRoles?.includes(state.info.showRole) == true) return item; |
... | ... | @@ -66,9 +66,9 @@ const store = new Vuex.Store({ |
66 | 66 | return itemFilter.demoRoles?.includes(state.info.showRole) == true |
67 | 67 | }); |
68 | 68 | if (item.children.length >= 1) return item; |
69 | - } | |
70 | - return null; | |
71 | - }); | |
69 | + } | |
70 | + return null; | |
71 | + }); | |
72 | 72 | state.addRouters = aRouters; // 保存动态路由用来addRouter |
73 | 73 | state.routers = defaultRouter.concat(aRouters); // 所有有权限的路由表,用来生成菜单列表 |
74 | 74 | localStorage.setItem("addRouters", JSON.stringify(routers)); |
... | ... | @@ -85,7 +85,8 @@ const store = new Vuex.Store({ |
85 | 85 | }, |
86 | 86 | setClasses(state, data) { |
87 | 87 | state.classes = data; |
88 | - localStorage.setItem("classes", data); | |
88 | + console.log(state) | |
89 | + localStorage.setItem('store', "classes", data); | |
89 | 90 | }, |
90 | 91 | setRefreshTestList(state, data) { |
91 | 92 | state.refreshTestList = data; | ... | ... |
src/utils/index.js
... | ... | @@ -106,6 +106,32 @@ export function deepClone(obj) { |
106 | 106 | return result; |
107 | 107 | } |
108 | 108 | |
109 | +export function getKnowledge(knowledge) { | |
110 | + | |
111 | + if (!knowledge) return ""; | |
112 | + | |
113 | + var splitPoints = s.Split(','); | |
114 | + | |
115 | + var result = ""; | |
116 | + | |
117 | + splitPoints.forEach(split => { | |
118 | + | |
119 | + var ss = split.Split('#').filter(dd => dd.length >= 1); | |
120 | + | |
121 | + if (ss.length > 0) { | |
122 | + result += ss[ss.Length - 1] + ";"; | |
123 | + } | |
124 | + }) | |
125 | + | |
126 | + if (result.length > 1) result = result.substring(0, result.length - 1); | |
127 | + | |
128 | + if (result.length == 1) { | |
129 | + return ""; | |
130 | + } | |
131 | + | |
132 | + return result; | |
133 | +} | |
134 | + | |
109 | 135 | // // 3DES加密 |
110 | 136 | // export function desEncrypt (str, key = encryptKey, iv = encryptIV) { |
111 | 137 | // var cryptoKey = CryptoJS.enc.Utf8.parse(key) |
... | ... | @@ -840,6 +866,7 @@ export function tablePrint(id, title, type = null) { |
840 | 866 | .tit{text-align:center;font-size:20px;color:#333;line-height:24px;font-weight:700;padding:10px 0;margin:0;} |
841 | 867 | .table-box,.el-table,.el-table__body-wrapper,.el-table--border{max-height:99999999px!important;height:auto;width:auto!important;max-width:1400px;margin: 0 auto;} |
842 | 868 | .el-table{width:100%} |
869 | + .print-hidden{display:none;} | |
843 | 870 | .el-table,.el-table__body-wrapper{max-height:auto} |
844 | 871 | .el-table .el-table__cell{padding:12px 0} |
845 | 872 | .el-table thead tr:first-child th.el-table__cell{border-top: 1px solid #ccc} | ... | ... |
src/views/basic/askTestQuestion/components/askBzrMulti.vue
... | ... | @@ -50,7 +50,7 @@ |
50 | 50 | }}</template> |
51 | 51 | </el-table-column> |
52 | 52 | </el-table-column> |
53 | - <el-table-column label="查看雷达图"> | |
53 | + <el-table-column label="查看雷达图" fixed="right" width="100" align="center"> | |
54 | 54 | <template slot-scope="scoped"> |
55 | 55 | <el-button type="text" @click="openRandarChart(scoped.row)">查看</el-button> |
56 | 56 | </template> |
... | ... | @@ -63,32 +63,27 @@ |
63 | 63 | <el-table class="default-table" :data="interactionList"> |
64 | 64 | <el-table-column prop="studentCode" label="学号"></el-table-column> |
65 | 65 | <el-table-column prop="studentName" label="姓名"></el-table-column> |
66 | + <el-table-column prop="interactionsNum全部科目" label="参与分"></el-table-column> | |
67 | + <el-table-column prop="interactionsCorrectNum全部科目" label="对错分"></el-table-column> | |
66 | 68 | <el-table-column v-for="(item, index) in interactionOptions" :key="index" :label="item"> |
67 | - <el-table-column v-if="index == 0" label="参与分" :prop="'interactionsNum' + item"> | |
69 | + | |
70 | + <el-table-column label="互动数" :prop="'answerTimes' + item"> | |
68 | 71 | <template slot-scope="scoped">{{ |
69 | - scoped.row["interactionsNum" + item] || | |
70 | - Number(scoped.row["interactionsNum" + item]) === 0 | |
71 | - ? scoped.row["interactionsNum" + item] | |
72 | + scoped.row["answerTimes" + item] || | |
73 | + Number(scoped.row["answerTimes" + item]) === 0 | |
74 | + ? scoped.row["answerTimes" + item] | |
72 | 75 | : "-" |
73 | 76 | }}</template> |
74 | 77 | </el-table-column> |
75 | - <el-table-column v-else label="互动数" :prop="'interactionsNum' + item"> | |
78 | + <el-table-column label="参与数" :prop="'interactionsNum' + item"> | |
76 | 79 | <template slot-scope="scoped">{{ |
77 | 80 | scoped.row["interactionsNum" + item] || |
78 | 81 | Number(scoped.row["interactionsNum" + item]) === 0 |
79 | 82 | ? scoped.row["interactionsNum" + item] |
80 | 83 | : "-" |
81 | - }}</template> | |
82 | - </el-table-column> | |
83 | - <el-table-column v-if="index == 0" label="对错分" :prop="'interactionsCorrectNum' + item"> | |
84 | - <template slot-scope="scoped">{{ | |
85 | - scoped.row["interactionsCorrectNum" + item] || | |
86 | - Number(scoped.row["interactionsCorrectNum" + item]) === 0 | |
87 | - ? scoped.row["interactionsCorrectNum" + item] | |
88 | - : "-" | |
89 | 84 | }}</template> |
90 | 85 | </el-table-column> |
91 | - <el-table-column v-else label="参与数" :prop="'interactionsCorrectNum' + item"> | |
86 | + <el-table-column label="答对数" :prop="'interactionsCorrectNum' + item"> | |
92 | 87 | <template slot-scope="scoped">{{ |
93 | 88 | scoped.row["interactionsCorrectNum" + item] || |
94 | 89 | Number(scoped.row["interactionsCorrectNum" + item]) === 0 |
... | ... | @@ -101,18 +96,16 @@ |
101 | 96 | </el-row> |
102 | 97 | </div> |
103 | 98 | </div> |
104 | - | |
105 | - <el-dialog :append-to-body="true" class="chart-dia" @close="radarChart.visible=false" :visible="radarChart.visible" | |
106 | - :title="radarChart.title" width="800" > | |
99 | + <el-dialog :append-to-body="true" class="chart-dia" :visible.sync="redarVisible" :title="radarChart.title" | |
100 | + width="800"> | |
107 | 101 | <div class="chart-box"> |
108 | - <RadarChart id="askRadarChart" :params="radarChart" :tooltipFormatter="true" /> | |
102 | + <RadarChart id="radarChart" :params="radarChart" /> | |
109 | 103 | </div> |
110 | 104 | </el-dialog> |
111 | 105 | </div> |
112 | 106 | </template> |
113 | 107 | <script> |
114 | -import { formatDate } from "utils"; | |
115 | -import { downloadFile, tablePrint } from "@/utils"; | |
108 | +import { downloadFile, tablePrint, formatDate } from "@/utils"; | |
116 | 109 | import RadarChart from "@/components/charts/radarChart"; |
117 | 110 | export default { |
118 | 111 | name: "askbzrMutli", |
... | ... | @@ -148,6 +141,7 @@ export default { |
148 | 141 | interactionList: [], |
149 | 142 | interactionOptions: [], |
150 | 143 | interactionSubjects: [], |
144 | + redarVisible: false, | |
151 | 145 | radarChart: { |
152 | 146 | title: "", |
153 | 147 | indicator: [ |
... | ... | @@ -174,7 +168,25 @@ export default { |
174 | 168 | await this._changeType(); |
175 | 169 | }, |
176 | 170 | methods: { |
177 | - _import() { }, | |
171 | + async _import() { | |
172 | + | |
173 | + var importReport = this.currentType == '学生多科互动表现' ? this.$request.cTExportPhaseInteractiveReport : this.$request.cTExportPhaseAnswerReport; | |
174 | + | |
175 | + const data = await importReport({ | |
176 | + periodIds: this.$props.askReportIds, | |
177 | + classIds: [this.$props.queryParams.class], | |
178 | + subjectNames: [...this.$props.queryParams.subjects], | |
179 | + }); | |
180 | + | |
181 | + if (data) { | |
182 | + let blob = new Blob([data], { | |
183 | + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | |
184 | + }); | |
185 | + downloadFile(`随堂问-多科汇总分析报表.xlsx`, blob); | |
186 | + } else { | |
187 | + this.$message.error("下载失败"); | |
188 | + } | |
189 | + }, | |
178 | 190 | _print() { |
179 | 191 | |
180 | 192 | tablePrint("print-content", this.currentType); |
... | ... | @@ -227,7 +239,6 @@ export default { |
227 | 239 | return aTime; |
228 | 240 | }, |
229 | 241 | async _multipleSubjectAnswers() { |
230 | - | |
231 | 242 | const answersRequest = |
232 | 243 | this.role == "ROLE_PERSONAL" |
233 | 244 | ? this.$request.pPhaseAnswerReport |
... | ... | @@ -236,10 +247,9 @@ export default { |
236 | 247 | let query = { |
237 | 248 | periodIds: this.$props.askReportIds, |
238 | 249 | classIds: [this.$props.queryParams.class], |
239 | - subjectNames: [this.$props.queryParams.subjectNames], | |
250 | + subjectNames: [...this.$props.queryParams.subjects], | |
240 | 251 | }; |
241 | 252 | |
242 | - | |
243 | 253 | let answersResponse = await answersRequest({ |
244 | 254 | ...query |
245 | 255 | }); |
... | ... | @@ -297,6 +307,7 @@ export default { |
297 | 307 | let query = { |
298 | 308 | periodIds: this.$props.askReportIds, |
299 | 309 | classIds: [this.$props.queryParams.class], |
310 | + subjectNames: [...this.$props.queryParams.subjects], | |
300 | 311 | }; |
301 | 312 | |
302 | 313 | let interactionReponse = await interactionRequest({ |
... | ... | @@ -312,23 +323,25 @@ export default { |
312 | 323 | |
313 | 324 | this.interactionList = interactionReponse.data?.list?.map((item) => { |
314 | 325 | let params = {}; |
315 | - item.dataList?.map((items, index) => { | |
316 | - if (!subjectName.includes(items.subjectName)) { | |
326 | + item.dataList?.filter((items, index) => { | |
327 | + if (!subjectName.includes(items.subjectName) && items.subjectName != '全部科目') { | |
317 | 328 | subjectName.push(items.subjectName); |
318 | 329 | } |
330 | + params["answerTimes" + items.subjectName] = | |
331 | + items.answerTimes; | |
319 | 332 | params["interactionsNum" + items.subjectName] = |
320 | 333 | items.interactionsNum; |
321 | 334 | params["interactionsCorrectNum" + items.subjectName] = |
322 | 335 | items.interactionsCorrectNum; |
323 | 336 | }); |
337 | + | |
324 | 338 | return { |
325 | 339 | ...item, |
326 | 340 | ...params, |
327 | 341 | }; |
328 | 342 | }); |
329 | - | |
343 | + console.log(this.interactionList) | |
330 | 344 | this.interactionOptions = [...subjectName]; |
331 | - console.log(this.interactionOptions) | |
332 | 345 | }, |
333 | 346 | openRandarChart(obj) { |
334 | 347 | this.radarChart = { |
... | ... | @@ -345,7 +358,7 @@ export default { |
345 | 358 | ], |
346 | 359 | seriesData: [], |
347 | 360 | }; |
348 | - this.radarChart.title = obj.studentName + "-多科-多课时作答表现图"; | |
361 | + this.radarChart.title = obj.studentName + "-多科阶段作答表现图"; | |
349 | 362 | let dataList = obj.dataList.slice(1, obj.dataList.length); |
350 | 363 | let subjectList = dataList.map((item) => item.subjectName); |
351 | 364 | subjectList.map((item, index) => { |
... | ... | @@ -377,7 +390,7 @@ export default { |
377 | 390 | }, |
378 | 391 | ]; |
379 | 392 | |
380 | - this.radarChart.visible = true; | |
393 | + this.redarVisible = true; | |
381 | 394 | } |
382 | 395 | } |
383 | 396 | }; | ... | ... |
src/views/basic/askTestQuestion/components/askListReport.vue
... | ... | @@ -3,11 +3,23 @@ |
3 | 3 | <el-table class="default-table" :data="$props.datas" border> |
4 | 4 | <el-table-column prop="subjectName" label="科目" width="180" /> |
5 | 5 | <el-table-column prop="title" label="课时名称" /> |
6 | - <el-table-column prop="participationRate" label="总参与度" width="180" /> | |
7 | - <el-table-column prop="answerCorrectRate" label="已答正确率" width="180" /> | |
8 | - <el-table-column prop="classCorrectRate" label="班级正确率" width="180" /> | |
6 | + <el-table-column prop="participationRate" label="总参与度" width="180" > | |
7 | + <template slot-scope="scoped"> | |
8 | + {{ scoped.row.participationRate }}% | |
9 | + </template> | |
10 | + </el-table-column> | |
11 | + <el-table-column prop="answerCorrectRate" label="已答正确率" width="180" > | |
12 | + <template slot-scope="scoped"> | |
13 | + {{ scoped.row.answerCorrectRate }}% | |
14 | + </template> | |
15 | + </el-table-column> | |
16 | + <el-table-column prop="classCorrectRate" label="班级正确率" width="180" > | |
17 | + <template slot-scope="scoped"> | |
18 | + {{ scoped.row.classCorrectRate }}% | |
19 | + </template> | |
20 | + </el-table-column> | |
9 | 21 | <el-table-column prop="questionNum" label="题目总数" width="180" /> |
10 | - <el-table-column prop="startTime" label="上课时间" width="180" /> | |
22 | + <el-table-column prop="startTime" label="上课时间" width="220" /> | |
11 | 23 | <el-table-column label="操作" width="200"> |
12 | 24 | <template slot-scope="scoped"> |
13 | 25 | <template v-if="scoped.row.answerNum == 0"> |
... | ... | @@ -42,9 +54,10 @@ export default { |
42 | 54 | id: dataRow.id, |
43 | 55 | }); |
44 | 56 | if (status != 0) { |
57 | + this.$message.success("删除成功!"); | |
45 | 58 | this.$message.error(info); |
46 | 59 | } |
47 | - this.$emit("resfer"); | |
60 | + this.$emit("opration"); | |
48 | 61 | }, |
49 | 62 | _linkToDetail(dataRow) { |
50 | 63 | this.$router.push({ | ... | ... |
src/views/basic/askTestQuestion/components/askSummaryReport.vue
... | ... | @@ -63,15 +63,15 @@ |
63 | 63 | </div> |
64 | 64 | <div class="row-line"> |
65 | 65 | <span class="line-subfix">总参与度:</span> |
66 | - <span class="line-value">{{ detail.participationRate }}</span> | |
66 | + <span class="line-value">{{ detail.participationRate ? detail.participationRate : 0 }}%</span> | |
67 | 67 | </div> |
68 | 68 | <div class="row-line"> |
69 | 69 | <span class="line-subfix">班级正确率:</span> |
70 | - <span class="line-value">{{ detail.classCorrectRate }}</span> | |
70 | + <span class="line-value">{{ detail.classCorrectRate ? detail.classCorrectRate : 0 }}%</span> | |
71 | 71 | </div> |
72 | 72 | <div class="row-line"> |
73 | 73 | <span class="line-subfix">已达正确率:</span> |
74 | - <span class="line-value">{{ detail.answerCorrectRate }}</span> | |
74 | + <span class="line-value">{{ detail.answerCorrectRate ? detail.answerCorrectRate : 0 }}%</span> | |
75 | 75 | </div> |
76 | 76 | <div class="row-line"> |
77 | 77 | <span class="line-subfix">反馈时长:</span> |
... | ... | @@ -81,7 +81,7 @@ |
81 | 81 | <el-row class="row-table"> |
82 | 82 | <el-table class="default-table" :data="singleSubjectSummary" border> |
83 | 83 | <el-table-column prop="title" label="课时-题号" /> |
84 | - <el-table-column label="题干" width="120"> | |
84 | + <el-table-column label="题干" width="80"> | |
85 | 85 | <template slot-scope="scoped"> |
86 | 86 | <el-button type="text" @click="openStem(scoped.row)">查看</el-button> |
87 | 87 | </template> |
... | ... | @@ -91,18 +91,26 @@ |
91 | 91 | </el-table-column> |
92 | 92 | <el-table-column prop="answeredNum" label="答题人数" width="100" /> |
93 | 93 | <el-table-column prop="correctAnswerNum" label="答对人数" width="100" /> |
94 | - <el-table-column prop="participationRate" label="班级参与度(单题)" width="150"> | |
94 | + <el-table-column prop="participationRate" label="班级参与度(单题)" width="170"> | |
95 | 95 | <template slot-scope="scoped">{{ scoped.row.participationRate }}%</template> |
96 | 96 | </el-table-column> |
97 | - <el-table-column prop="classCorrectRate" label="班级正确率(单题)" width="150"> | |
97 | + <el-table-column prop="classCorrectRate" label="班级正确率(单题)" width="170"> | |
98 | 98 | <template slot-scope="scoped">{{ scoped.row.classCorrectRate }}%</template> |
99 | 99 | </el-table-column> |
100 | 100 | |
101 | - <el-table-column prop="answerCorrectRate" label="已答正确率(单题)" width="150"> | |
101 | + <el-table-column prop="answerCorrectRate" label="已答正确率(单题)" width="170"> | |
102 | 102 | <template slot-scope="scoped">{{ scoped.row.answerCorrectRate }}%</template> |
103 | 103 | </el-table-column> |
104 | 104 | |
105 | - <el-table-column prop="knowledge" label="知识点(单题)" width="150" /> | |
105 | + <el-table-column prop="knowledge" label="知识点(单题)" width="150"> | |
106 | + <template slot-scope="scoped"> | |
107 | + <el-tooltip effect="dark" :content="scoped.row.knowledge" placement="left"> | |
108 | + <span class="overflowText"> | |
109 | + {{ scoped.row.knowledge }} | |
110 | + </span> | |
111 | + </el-tooltip> | |
112 | + </template> | |
113 | + </el-table-column> | |
106 | 114 | <el-table-column prop="correctAnswer" label="正确答案(单题)" width="150"> |
107 | 115 | <template slot-scope="scoped"> |
108 | 116 | {{ |
... | ... | @@ -182,7 +190,7 @@ |
182 | 190 | <el-table-column prop="correctRate" label="总正确率" width="120"> |
183 | 191 | <template slot-scope="scoped">{{ scoped.row.correctRate }}%</template> |
184 | 192 | </el-table-column> |
185 | - <el-table-column prop="correctRateRank" label="总正确率排名" width="120" /> | |
193 | + <el-table-column prop="correctRateRank" label="总正确率排名" width="140" /> | |
186 | 194 | <el-table-column prop="answerCorrectRate" label="已答正确率" width="120"> |
187 | 195 | <template slot-scope="scoped">{{ scoped.row.answerCorrectRate }}%</template> |
188 | 196 | </el-table-column> |
... | ... | @@ -203,20 +211,20 @@ |
203 | 211 | <el-table-column prop="interactionsCorrectNum" label="对错得分" width="210" /> |
204 | 212 | <el-table-column prop="rushAnswerTimes" label="抢答成功次数" width="210" /> |
205 | 213 | <el-table-column prop="rushAnswerCorrectTimes" label="抢答答对次数" width="210" /> |
206 | - <el-table-column prop="checkAnswerTimes" label="被抽打次数" width="210" /> | |
207 | - <el-table-column prop="checkAnswerCorrectTimes" label="抽打答对次数" width="210" /> | |
214 | + <el-table-column prop="checkAnswerTimes" label="被抽答次数" width="210" /> | |
215 | + <el-table-column prop="checkAnswerCorrectTimes" label="抽答答对次数" width="210" /> | |
208 | 216 | </el-table> |
209 | 217 | </el-row> |
210 | 218 | </div> |
211 | 219 | </div> |
212 | - <el-dialog :append-to-body="true" class="chart-dia" :visible.sync="lineChart.visible" :title="lineChart.title" width="800" | |
213 | - > | |
220 | + <el-dialog :append-to-body="true" class="chart-dia" :visible.sync="lineChart.visible" :title="lineChart.title" | |
221 | + width="800"> | |
214 | 222 | <div class="chart-box"> |
215 | 223 | <LineChart id="askLineChart" :params="lineChart.data" :xAxis="lineChart.xAxis" |
216 | 224 | :tooltipFormatter="true" /> |
217 | 225 | </div> |
218 | 226 | </el-dialog> |
219 | - <el-dialog :append-to-body="true" class="stem" :visible.sync="stem.visible" :title="'题干'" width="800" > | |
227 | + <el-dialog :append-to-body="true" class="stem" :visible.sync="stem.visible" :title="'题干'" width="800"> | |
220 | 228 | <iframe v-if="stem && stem.src" :src="stem.src" style="width: 100%;min-height: 400px;" /> |
221 | 229 | </el-dialog> |
222 | 230 | <ExportDia :exportStudent="exportStudent" :diaShow="diaShow" @cancel="cancel" @exportData="_exportData" |
... | ... | @@ -224,7 +232,7 @@ |
224 | 232 | </div> |
225 | 233 | </template> |
226 | 234 | <script> |
227 | -import { formatDate } from "utils"; | |
235 | +import { formatDate,getKnowledge } from "utils"; | |
228 | 236 | import { downloadFile, tablePrint } from "@/utils"; |
229 | 237 | import LineChart from "@/components/charts/lineChart"; |
230 | 238 | export default { |
... | ... | @@ -234,7 +242,8 @@ export default { |
234 | 242 | }, |
235 | 243 | props: { |
236 | 244 | askReportIds: Array, |
237 | - queryParams: Object | |
245 | + queryParams: Object, | |
246 | + role: "", | |
238 | 247 | }, |
239 | 248 | |
240 | 249 | watch: { |
... | ... | @@ -287,9 +296,9 @@ export default { |
287 | 296 | this.diaShow = true; |
288 | 297 | }, |
289 | 298 | _print() { |
290 | - let title = this.detail.title || this.subjectNames.join(); | |
291 | - | |
292 | - tablePrint("print-content", title + "_" + this.currentType); | |
299 | + let title = this.detail.title || this.subjectNames.join(); | |
300 | + | |
301 | + tablePrint("print-content", title + "_" + this.currentType); | |
293 | 302 | }, |
294 | 303 | cancel() { |
295 | 304 | this.diaShow = false; |
... | ... | @@ -333,7 +342,7 @@ export default { |
333 | 342 | } else { |
334 | 343 | this.$message.error("下载失败"); |
335 | 344 | } |
336 | - }, | |
345 | + }, | |
337 | 346 | async refresh() { |
338 | 347 | await this._changeType(); |
339 | 348 | await this._detail(); |
... | ... | @@ -366,21 +375,30 @@ export default { |
366 | 375 | return tit; |
367 | 376 | }, |
368 | 377 | setDuration(times) { |
378 | + | |
379 | + if (!Number(times)) return "0分0秒"; | |
369 | 380 | let m = parseInt(times / 1000 / 60); |
370 | 381 | let s = parseInt((times / 1000) % 60); |
371 | 382 | let ms = times; |
372 | 383 | let aTime; |
384 | + | |
373 | 385 | if (times == 0) { |
374 | 386 | aTime = `0`; |
375 | 387 | } else { |
376 | 388 | if (m == 0 && s == 0) { |
377 | 389 | aTime = `${ms}毫秒`; |
378 | - } else if (m == 0 && s != 0) { | |
390 | + } else if (m == 0) { | |
379 | 391 | aTime = `${s}秒`; |
380 | - } else if (m != 0 && s != 0) { | |
381 | - aTime = `${m}分${s}秒`; | |
392 | + } else { | |
393 | + if (s == 0) { | |
394 | + aTime = `${m}分`; | |
395 | + } | |
396 | + else { | |
397 | + aTime = `${m}分${s}秒`; | |
398 | + } | |
382 | 399 | } |
383 | 400 | } |
401 | + // c=(aTime); | |
384 | 402 | return aTime; |
385 | 403 | }, |
386 | 404 | async _detail() { |
... | ... | @@ -495,7 +513,8 @@ export default { |
495 | 513 | this.total = interactiveListReponse.data.count; |
496 | 514 | }, |
497 | 515 | openLineChart(chartRow) { |
498 | - this.lineChart.title = `${chartRow.studentName}-${this.currentType}`; | |
516 | + var subejct = this.$props.role == 'ROLE_BANZHUREN' ? this.$props.queryParams.subjects[0] : this.$props.queryParams.subject; | |
517 | + this.lineChart.title = `${chartRow.studentName}-${subejct}-多课时作答表现图`; | |
499 | 518 | this.lineChart.visible = true; |
500 | 519 | let participationRate = []; |
501 | 520 | let correctRate = []; |
... | ... | @@ -519,8 +538,7 @@ export default { |
519 | 538 | name: "已答正确率", |
520 | 539 | value: answerCorrectRate, |
521 | 540 | }, |
522 | - ]; | |
523 | - console.log(this.lineChart) | |
541 | + ]; | |
524 | 542 | }, |
525 | 543 | openStem(stemRow) { |
526 | 544 | this.stem.src = stemRow.screenshot ?? ""; |
... | ... | @@ -553,7 +571,7 @@ export default { |
553 | 571 | } |
554 | 572 | |
555 | 573 | .row-line { |
556 | - width: calc(20% - 2px); | |
574 | + width: calc(20% - 4px); | |
557 | 575 | border: 1px solid #ebeef5; |
558 | 576 | background: #f5f7fa; |
559 | 577 | display: inline-block; | ... | ... |
src/views/basic/askTestQuestion/components/testBzrMulti.vue
... | ... | @@ -9,21 +9,14 @@ |
9 | 9 | </div> |
10 | 10 | </el-row> |
11 | 11 | <el-row class="row-table"> |
12 | - <el-table class="default-table" :data="$props.list"> | |
13 | - <el-table-column width="48"> | |
14 | - <template slot="header"> | |
15 | - <el-checkbox v-model="checkedAll" @change="_checkAll"></el-checkbox> | |
16 | - </template> | |
17 | - <template slot-scope="scope"> | |
18 | - <el-checkbox v-model="multipleSelection" :label="scope.row.id" | |
19 | - :disabled="_checkboxDisabled(scope.row)"><span></span></el-checkbox> | |
20 | - </template> | |
21 | - </el-table-column> | |
22 | - <el-table-column prop="subjectName" label="科目"></el-table-column> | |
23 | - <el-table-column prop="className" label="班级"></el-table-column> | |
12 | + <el-table class="default-table" :data="$props.list" @selection-change="_tableSelectedChange"> | |
13 | + <el-table-column type="selection" width="48" :selectable="_checkboxDisabled" /> | |
14 | + | |
15 | + <el-table-column prop="subjectName" label="科目" width="100"></el-table-column> | |
16 | + <el-table-column prop="className" label="班级" width="100"></el-table-column> | |
24 | 17 | <el-table-column prop="title" label="试卷名称"></el-table-column> |
25 | - <el-table-column prop="examPaperScore" label="卷面分"></el-table-column> | |
26 | - <el-table-column label="测验人数/班级人数"> | |
18 | + <el-table-column prop="examPaperScore" label="卷面分" width="100"></el-table-column> | |
19 | + <el-table-column label="测验人数/班级人数" width="200"> | |
27 | 20 | <template slot-scope="scoped"> |
28 | 21 | {{ `${scoped.row.answeredNum}/${scoped.row.classPersonNum}` }} |
29 | 22 | </template> |
... | ... | @@ -44,7 +37,7 @@ |
44 | 37 | </div> |
45 | 38 | </el-row> |
46 | 39 | <el-row class="row-table"> |
47 | - <el-table :maxHeight="660" :data="selectedList" style="width: 100%" class="default-table"> | |
40 | + <el-table :data="selectedList" style="width: 100%" class="default-table"> | |
48 | 41 | <el-table-column prop="studentCode" label="学号" fixed></el-table-column> |
49 | 42 | |
50 | 43 | <el-table-column prop="studentName" label="姓名" fixed> |
... | ... | @@ -106,10 +99,10 @@ |
106 | 99 | </el-container> |
107 | 100 | |
108 | 101 | </div> |
109 | - <el-dialog class="chart-dia" :visible.sync="radarChart.visible" :title="radarChart.title" width="800" | |
102 | + <el-dialog class="chart-dia" :visible.sync="redarVisible" :title="radarChart.title" width="800" | |
110 | 103 | :append-to-body="true"> |
111 | 104 | <div class="chart-box"> |
112 | - <RadarChart id="askRadarChart" :params="radarChart" :tooltipFormatter="true" /> | |
105 | + <RadarChart id="testRadarChart" :params="radarChart" /> | |
113 | 106 | </div> |
114 | 107 | </el-dialog> |
115 | 108 | </div> |
... | ... | @@ -151,6 +144,7 @@ export default { |
151 | 144 | answerList: [], |
152 | 145 | multipleSelection: [], |
153 | 146 | multipleSelectionObj: {}, |
147 | + redarVisible: false, | |
154 | 148 | radarChart: { |
155 | 149 | title: "", |
156 | 150 | indicator: [ |
... | ... | @@ -177,16 +171,53 @@ export default { |
177 | 171 | }, |
178 | 172 | methods: { |
179 | 173 | _print() { |
174 | + tablePrint("print-content", this.currentType); | |
175 | + }, | |
176 | + _checkAll() { | |
177 | + // this.multipleSelection = [...] | |
178 | + }, | |
179 | + _tableSelectedChange(values) { | |
180 | 180 | |
181 | + this.multipleSelection = values.map(items => items.id); | |
182 | + }, | |
183 | + async _import() { | |
181 | 184 | |
182 | - tablePrint("print-content", this.currentType); | |
185 | + var testReport = this.$request.cTExportPhaseExamReport; | |
186 | + | |
187 | + var classIds = []; | |
188 | + var subjects = []; | |
189 | + var ids = []; | |
190 | + | |
191 | + this.$props.list?.map((item) => { | |
192 | + if (this.multipleSelection.includes(item.id)) { | |
193 | + subjects.push(item.subjectName); | |
194 | + classIds.push(item.classId); | |
195 | + } | |
196 | + }); | |
197 | + | |
198 | + ids = [...this.multipleSelection]; | |
199 | + | |
200 | + | |
201 | + const data = await testReport({ | |
202 | + classIds: classIds, | |
203 | + examIds: ids, | |
204 | + subjectNames: subjects | |
205 | + }); | |
206 | + | |
207 | + if (data) { | |
208 | + let blob = new Blob([data], { | |
209 | + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | |
210 | + }); | |
211 | + downloadFile(`即时测-多科汇总分析报表.xlsx`, blob); | |
212 | + } else { | |
213 | + this.$message.error("下载失败"); | |
214 | + } | |
183 | 215 | }, |
184 | - _checkAll() { }, | |
185 | 216 | _checkboxDisabled(obj) { |
186 | 217 | if (obj.examStartTime) { |
187 | - return false; | |
188 | - } else { | |
189 | 218 | return true; |
219 | + } else { | |
220 | + return false; | |
190 | 221 | } |
191 | 222 | }, |
192 | 223 | async refresh() { |
... | ... | @@ -245,28 +276,36 @@ export default { |
245 | 276 | this.exportStudent = []; |
246 | 277 | }, |
247 | 278 | openRandarChart(obj) { |
279 | + | |
280 | + let max = 0; | |
281 | + | |
282 | + const dataList = obj.dataList.slice(1, obj.dataList.length); | |
283 | + let subjectList = dataList.map((item) => { | |
284 | + let score = Number(item.highestScore || item.score); | |
285 | + max = score > max ? score : max; | |
286 | + return item.subjectName; | |
287 | + }); | |
288 | + max += 10; | |
289 | + max = max > 150 ? 150 : max; | |
248 | 290 | this.radarChart = { |
249 | 291 | indicator: [ |
250 | 292 | { |
251 | 293 | name: "", |
252 | - max: 100, | |
294 | + max: max, | |
253 | 295 | axisLabel: { |
254 | 296 | show: true, |
255 | 297 | showMaxLabel: true, |
256 | - formatter: "{value}%", | |
257 | 298 | }, |
258 | 299 | }, |
259 | 300 | ], |
260 | 301 | seriesData: [], |
261 | 302 | }; |
262 | - this.radarChart.title = obj.studentName + "-多科-多课时作答表现图"; | |
263 | - let dataList = obj.dataList.slice(1, obj.dataList.length); | |
264 | - let subjectList = dataList.map((item) => item.subjectName); | |
265 | 303 | subjectList.map((item, index) => { |
266 | 304 | if (index < 1) { |
267 | 305 | this.radarChart.indicator[index].name = item; |
306 | + this.radarChart.indicator[index].max = max; | |
268 | 307 | } else { |
269 | - this.radarChart.indicator.push({ name: item, max: 100 }); | |
308 | + this.radarChart.indicator.push({ name: item, max: max }); | |
270 | 309 | } |
271 | 310 | }); |
272 | 311 | // 为了美观 |
... | ... | @@ -274,31 +313,36 @@ export default { |
274 | 313 | let num = this.radarChart.indicator.length; |
275 | 314 | for (let i = 0; i < 6; i++) { |
276 | 315 | if (i >= num) { |
277 | - this.radarChart.indicator.push({ name: "", max: 100 }); | |
316 | + this.radarChart.indicator.push({ name: "", max: max }); | |
278 | 317 | } |
279 | 318 | } |
280 | 319 | } |
281 | - let participationRate = dataList.map((item) => item.participationRate); | |
282 | - let correctRate = dataList.map((item) => item.correctRate); | |
283 | 320 | this.radarChart.seriesData = [ |
284 | 321 | { |
285 | - value: participationRate, | |
286 | - name: "参与度", | |
322 | + value: dataList.map((item) => item.highestScore), | |
323 | + name: "班级最高分", | |
287 | 324 | }, |
288 | 325 | { |
289 | - value: correctRate, | |
290 | - name: "正确率", | |
326 | + value: dataList.map((item) => item.avgScore), | |
327 | + name: "班平均分", | |
291 | 328 | }, |
292 | - ]; | |
329 | + { | |
330 | + value: dataList.map((item) => item.score), | |
331 | + name: "本人得分", | |
332 | + }, | |
333 | + ]; | |
293 | 334 | |
294 | - this.radarChart.visible = true; | |
335 | + this.radarChart.title = obj.studentName + "-多科阶段作答表现图"; | |
336 | + console.log(this.radarChart) | |
337 | + this.redarVisible = true; | |
295 | 338 | }, |
296 | 339 | async _loadData() { |
340 | + | |
297 | 341 | var classIds = []; |
298 | 342 | var subjects = []; |
299 | 343 | var ids = []; |
300 | - | |
301 | 344 | this.$props.list?.map((item) => { |
345 | + | |
302 | 346 | if (this.multipleSelection.includes(item.id)) { |
303 | 347 | subjects.push(item.subjectName); |
304 | 348 | classIds.push(item.classId); |
... | ... | @@ -326,6 +370,7 @@ export default { |
326 | 370 | if (!subjectName.includes(items.subjectName)) { |
327 | 371 | subjectName.push(items.subjectName); |
328 | 372 | } |
373 | + console.log(items) | |
329 | 374 | params["examCount" + items.subjectName] = items.examCount; |
330 | 375 | params["participationCount" + items.subjectName] = |
331 | 376 | items.participationCount; | ... | ... |
src/views/basic/askTestQuestion/components/testListReport.vue
1 | 1 | <template> |
2 | 2 | <div ref="main"> |
3 | - <el-table class="default-table" :data="tableData"> | |
3 | + <el-table v-if="$props.datas" class="default-table" :data="$props.datas"> | |
4 | 4 | <el-table-column prop="subjectName" label="科目" width="180" /> |
5 | - <el-table-column prop="className" label="班级" width="180" /> | |
5 | + <el-table-column prop="className" label="班级" width="130" /> | |
6 | 6 | <el-table-column prop="title" label="报表名称" /> |
7 | - <el-table-column prop="examPaperScore" label="卷面分" width="180" /> | |
7 | + <el-table-column prop="examPaperScore" label="卷面分" width="130" /> | |
8 | 8 | <el-table-column prop="classCorrectRate" label="测验人数/班级人数" width="180"> |
9 | 9 | <template slot-scope="scoped">{{ `${scoped.row.answeredNum}/${scoped.row.classPersonNum}` }}</template> |
10 | 10 | </el-table-column> |
11 | - <el-table-column prop="questionNum" label="测验时长" width="180" /> | |
12 | - <el-table-column prop="createdTime" label="测验开始时间" width="180" /> | |
11 | + <el-table-column prop="questionNum" label="测验时长" width="130" /> | |
12 | + <el-table-column prop="createdTime" label="测验开始时间" width="210" /> | |
13 | 13 | <el-table-column label="操作" width="240"> |
14 | 14 | <template slot-scope="scoped"> |
15 | - <el-tooltip v-if="scoped.row.answerNum != 0 || | |
15 | + <el-button style="margin-right: 10px;" v-if="scoped.row.answerNum != 0 || | |
16 | 16 | (scoped.row.recordStatus != 0 && |
17 | 17 | scoped.row.subjectiveScore == scoped.row.examPaperScore) |
18 | - " effect="dark" content="详情" style="margin-right: 10px;" placement="top"> | |
19 | - <el-button type="text" @click="_linkToDetail(scoped.row)">查看</el-button> | |
20 | - </el-tooltip> | |
21 | - <el-popconfirm style="margin-right: 10px;" title="确定删除这张答题卡吗?" @confirm="_removeReport(scoped.row)"> | |
18 | + " type="text" @click="_linkToDetail(scoped.row)">查看</el-button> | |
19 | + <el-popconfirm style="margin-right: 10px;" title="确定删除这次记录吗?" @confirm="_removeReport(scoped.row)"> | |
22 | 20 | <el-button style="color:red; " slot="reference" class="delete" type="text"> |
23 | 21 | 删除 |
24 | 22 | </el-button> |
25 | 23 | </el-popconfirm> |
26 | - <template v-if="scoped.row.answerNum == 0 && | |
27 | - scoped.row.subjectiveScore != scoped.row.examPaperScore | |
28 | - "> | |
29 | - <el-tooltip v-if="role != 'ROLE_BANZHUREN'" effect="dark" content="设置答案" placement="top"> | |
30 | - <el-button type="text" icon="fa fa-file-text" @click="edit(scoped.row)"></el-button> | |
31 | - </el-tooltip> | |
32 | - <template v-else>未设置答案</template> | |
24 | + <template | |
25 | + v-if="scoped.row.answerNum == 0 && scoped.row.subjectiveScore != scoped.row.examPaperScore"> | |
26 | + <el-button style="margin-right: 10px;" v-if="role != 'ROLE_BANZHUREN'" type="text" | |
27 | + @click="edit(scoped.row)">设置答案</el-button> | |
28 | + <template v-else> <span style="margin-right: 10px;">未设置答案</span> </template> | |
33 | 29 | </template> |
34 | 30 | <template v-if="role != 'ROLE_BANZHUREN' && scoped.row.examPaperId != 0"> |
35 | 31 | <template> |
36 | 32 | <el-popover placement="bottom" ref="popoverRef"> |
37 | - <div style="display: flex" v-loading="scoped.row.showSelect == 0 || | |
38 | - scoped.row.showSelect == 1 | |
39 | - ? false | |
40 | - : true | |
41 | - "> | |
42 | - <el-button v-if="scoped.row.showSelect == 0" size="mini" | |
33 | + <div style="display: flex"> | |
34 | + <el-button v-if="scoped.row.showSelect == 0" | |
43 | 35 | @click="openScoreSet(scoped.row, 1)">录入总得分</el-button> |
44 | - <el-button type="primary" size="mini" | |
45 | - @click="openScoreSet(scoped.row, 2)">录入小题分</el-button> | |
36 | + <el-button type="primary" @click="openScoreSet(scoped.row, 2)">录入小题分</el-button> | |
46 | 37 | </div> |
47 | - <el-button slot="reference" type="text" | |
38 | + <el-button style="margin-right: 10px;" slot="reference" type="text" | |
48 | 39 | @click="queryStatus(scoped.row)">录入分数</el-button> |
49 | 40 | </el-popover> |
50 | 41 | </template> |
... | ... | @@ -62,12 +53,17 @@ import ScoreSet from "../../test/components/scoreSet.vue"; |
62 | 53 | export default { |
63 | 54 | name: "testListReport", |
64 | 55 | props: { |
65 | - datas: Array, | |
56 | + datas: Array || null, | |
66 | 57 | }, |
67 | 58 | components: { |
68 | 59 | ScoreSet |
69 | 60 | }, |
70 | 61 | watch: { |
62 | + 'diaScoreSet'(value) { | |
63 | + if (value == false) { | |
64 | + // this.$emit('opration'); | |
65 | + } | |
66 | + }, | |
71 | 67 | '$props.datas'(value) { |
72 | 68 | if (this.role == "ROLE_BANZHUREN") { |
73 | 69 | this.isMultipleClass = false; |
... | ... | @@ -84,12 +80,13 @@ export default { |
84 | 80 | return item; |
85 | 81 | }) || []; |
86 | 82 | } |
87 | - }, | |
83 | + } | |
88 | 84 | }, |
89 | 85 | created() { |
90 | 86 | this.role = |
91 | 87 | this.$store.getters.info.showRole || |
92 | 88 | this.$store.getters.info.permissions[0].role; |
89 | + | |
93 | 90 | }, |
94 | 91 | methods: { |
95 | 92 | _linkToDetail(dataRow) { |
... | ... | @@ -113,13 +110,12 @@ export default { |
113 | 110 | this.diaScoreSet = true; |
114 | 111 | }, |
115 | 112 | async _removeReport(obj, index) { |
116 | - this.tableData[index].loading = true; | |
117 | 113 | const { data, status, info } = await this.$request.deleteReport({ |
118 | 114 | id: obj.id, |
119 | 115 | }); |
120 | 116 | if (status === 0) { |
121 | 117 | this.$message.success("删除成功!"); |
122 | - this._QueryData(); | |
118 | + this.$emit('opration'); | |
123 | 119 | } else { |
124 | 120 | this.$message.error(info); |
125 | 121 | } |
... | ... | @@ -143,7 +139,7 @@ export default { |
143 | 139 | }, |
144 | 140 | //修改分数成功 |
145 | 141 | SuccessScoreSet() { |
146 | - this._QueryData(); | |
142 | + this.$emit('opration'); | |
147 | 143 | this.closeScoreSet(); |
148 | 144 | }, |
149 | 145 | //修改答案 | ... | ... |
src/views/basic/askTestQuestion/components/testMultiClassReport.vue
... | ... | @@ -8,19 +8,19 @@ |
8 | 8 | </el-row> |
9 | 9 | <el-row class="row-type" style="margin-top: 10px;"> |
10 | 10 | <el-table v-if="$props.params" class="default-table" :data="listReport"> |
11 | - <el-table-column prop="subjectName" label="科目" width="180" /> | |
12 | - <el-table-column prop="paperName" label="试卷名称" width="240" /> | |
11 | + <el-table-column prop="subjectName" label="科目" width="100" /> | |
12 | + <el-table-column prop="paperName" label="试卷名称" /> | |
13 | 13 | <el-table-column prop="classCorrectRate" label="已考班级"> |
14 | 14 | <template slot-scope="scoped"> |
15 | 15 | <el-checkbox-group v-model="scoped.row.checkedClassList"> |
16 | - <el-checkbox v-for="(item, index) in scoped.row.classInfos" :label="item.classId"> | |
16 | + <el-checkbox :key="index" v-for="(item, index) in scoped.row.classInfos" :label="item.classId"> | |
17 | 17 | {{ item.className }} |
18 | 18 | </el-checkbox> |
19 | 19 | </el-checkbox-group> |
20 | 20 | </template> |
21 | 21 | </el-table-column> |
22 | - <el-table-column prop="score" label="卷面分" width="180" /> | |
23 | - <el-table-column label="操作" width="240"> | |
22 | + <el-table-column prop="score" label="卷面分" width="100" /> | |
23 | + <el-table-column label="操作" width="100"> | |
24 | 24 | <template slot-scope="scoped"> |
25 | 25 | <el-button type="text" @click="_linkToDetail(scoped.row)">查看</el-button> |
26 | 26 | </template> |
... | ... | @@ -48,9 +48,7 @@ export default { |
48 | 48 | } |
49 | 49 | }, |
50 | 50 | methods: { |
51 | - _linkToDetail(dataRow) { | |
52 | - | |
53 | - console.log(dataRow) | |
51 | + _linkToDetail(dataRow) { | |
54 | 52 | this.$router.push({ |
55 | 53 | path: "/testReportDetail", |
56 | 54 | query: { |
... | ... | @@ -59,15 +57,16 @@ export default { |
59 | 57 | id: dataRow.paperId, |
60 | 58 | title: dataRow.paperName, |
61 | 59 | subjectName: dataRow.subjectName, |
60 | + diffType: this.currentType, | |
62 | 61 | }, |
63 | 62 | }); |
64 | 63 | }, |
65 | 64 | async _loadDatas() { |
66 | - | |
65 | + | |
67 | 66 | var dataRequestParams = { |
68 | 67 | classIds: this.$props.params.class ? [this.$props.params.class] : |
69 | 68 | this.$props.params.classIds ? [...this.$props.params.classIds] : null, |
70 | - diffType: this.currentType == "任课班级对比" ? "0" : "1", | |
69 | + diffType: this.currentType == "任课班级对比" ? "1" : "0", | |
71 | 70 | end: this.$props.params.dataRange ? this.$props.params.dataRange[1] : null, |
72 | 71 | start: this.$props.params.dataRange ? this.$props.params.dataRange[0] : null, |
73 | 72 | subjects: this.$props.params.subject ? [this.$props.params.subject] : | ... | ... |
src/views/basic/askTestQuestion/components/testSummaryReport.vue
... | ... | @@ -9,14 +9,28 @@ |
9 | 9 | <div id="print-content"> |
10 | 10 | <el-row class="row-table"> |
11 | 11 | <el-table border class="default-table" :data="stageReport" style="width: 100%"> |
12 | - <el-table-column prop="studentCode" label="学号" align="center" fixed></el-table-column> | |
13 | - <el-table-column prop="studentName" label="姓名" fixed align="center"> | |
12 | + <el-table-column prop="studentCode" label="学号" fixed></el-table-column> | |
13 | + <el-table-column prop="studentName" label="姓名" fixed> | |
14 | 14 | <template slot-scope="scoped"> |
15 | 15 | {{ scoped.row.studentName }} |
16 | - </template></el-table-column> | |
17 | - <el-table-column v-if="answerList" align="center" v-for="(item, index) in answerList" :key="index" | |
16 | + </template> | |
17 | + </el-table-column> | |
18 | + <el-table-column v-if="answerList" v-for="(item, index) in answerList" :key="index" | |
18 | 19 | :label="item.title"> |
19 | - <el-table-column :prop="'score' + index" :label="index == 0 ? '总分' : '总分'" align="center" | |
20 | + <template slot='header' slot-scope="scope" label="use show-overflow-tooltip" | |
21 | + show-overflow-tooltip> | |
22 | + <el-tooltip v-if="item.title != '阶段汇总'" effect="dark" :content="item.title" | |
23 | + placement="left"> | |
24 | + <span class="overflowText overClick" @click="_headerClick(item)" | |
25 | + style="color:rgb(121,138,245);width: 100%;height: 100%;"> | |
26 | + {{ item.title }} | |
27 | + </span> | |
28 | + </el-tooltip> | |
29 | + <span v-else> | |
30 | + {{ item.title }} | |
31 | + </span> | |
32 | + </template> | |
33 | + <el-table-column :prop="'score' + index" :label="index == 0 ? '总分' : '总分'" | |
20 | 34 | :class-name="index % 2 == 0 ? 'bg' : ''"> |
21 | 35 | <template slot-scope="scoped"> |
22 | 36 | {{ |
... | ... | @@ -27,7 +41,7 @@ |
27 | 41 | }} |
28 | 42 | </template> |
29 | 43 | </el-table-column> |
30 | - <el-table-column :prop="'classRank' + index" label="排名" align="center" | |
44 | + <el-table-column :prop="'classRank' + index" label="排名" | |
31 | 45 | :class-name="index % 2 == 0 ? 'bg' : ''"> |
32 | 46 | <template slot-scope="scoped">{{ |
33 | 47 | scoped.row["classRank" + index] || |
... | ... | @@ -37,7 +51,7 @@ |
37 | 51 | }}</template> |
38 | 52 | </el-table-column> |
39 | 53 | </el-table-column> |
40 | - <el-table-column label="查看折线图" align="center"> | |
54 | + <el-table-column label="查看折线图" fixed="right" align="center" width="120"> | |
41 | 55 | <template slot-scope="scoped"> |
42 | 56 | <el-button type="text" @click="_openLineChart(scoped.row)">查看</el-button> |
43 | 57 | </template> |
... | ... | @@ -49,8 +63,7 @@ |
49 | 63 | <el-dialog class="chart-dia" :visible.sync="lineChart.visible" :title="lineChart.title" width="800" |
50 | 64 | :append-to-body="true"> |
51 | 65 | <div class="chart-box"> |
52 | - <LineChart id="askLineChart" :params="lineChart.data" :xAxis="lineChart.xAxis" | |
53 | - :tooltipFormatter="true" /> | |
66 | + <LineChart id="askLineChart" :params="lineChart.data" :xAxis="lineChart.xAxis" /> | |
54 | 67 | </div> |
55 | 68 | </el-dialog> |
56 | 69 | <ExportDia :exportStudent="exportStudent" :diaShow="diaShow" @cancel="cancel" @exportData="exportData" |
... | ... | @@ -68,7 +81,8 @@ export default { |
68 | 81 | }, |
69 | 82 | props: { |
70 | 83 | testReportIds: Array, |
71 | - queryParams: Object | |
84 | + queryParams: Object, | |
85 | + role: "", | |
72 | 86 | }, |
73 | 87 | async created() { |
74 | 88 | await this._phaseExamReport(); |
... | ... | @@ -101,6 +115,9 @@ export default { |
101 | 115 | }; |
102 | 116 | }, |
103 | 117 | methods: { |
118 | + _headerClick(currentItem) { | |
119 | + this.$emit("headerClick", currentItem); | |
120 | + }, | |
104 | 121 | async _export() { |
105 | 122 | this.diaShow = true; |
106 | 123 | }, |
... | ... | @@ -116,7 +133,9 @@ export default { |
116 | 133 | let query = { |
117 | 134 | examIds: this.$props.testReportIds, |
118 | 135 | classIds: [this.$props.queryParams.class], |
119 | - subjectName: [this.$props.queryParams.subject] | |
136 | + subjectName: [this.$props.queryParams.subject], | |
137 | + startDay: this.$props.queryParams.dateRange[0] ?? null, | |
138 | + endDay: this.$props.queryParams.dateRange[1] ?? null, | |
120 | 139 | }; |
121 | 140 | |
122 | 141 | const { data, status, info } = await phaseExamReport({ |
... | ... | @@ -139,6 +158,7 @@ export default { |
139 | 158 | } |
140 | 159 | }); |
141 | 160 | }); |
161 | + console.log('lsit', data?.list) | |
142 | 162 | this.stageReport = data?.list.map((item) => { |
143 | 163 | let params = {}; |
144 | 164 | dataIdsList.map((ids, index) => { |
... | ... | @@ -177,21 +197,26 @@ export default { |
177 | 197 | ? this.$request.pExportPhaseExamReport |
178 | 198 | : this.$request.exportPhaseExamReport; |
179 | 199 | |
200 | + | |
180 | 201 | const data = await exportPhaseExamReport({ |
181 | 202 | examIds: this.$props.testReportIds, |
182 | 203 | classIds: [this.$props.queryParams.class], |
183 | 204 | subjectName: [this.$props.queryParams.subject], |
205 | + startDay: this.$props.queryParams?.dateRange[0] ?? null, | |
206 | + endDay: this.$props.queryParams?.dateRange[1] ?? null, | |
184 | 207 | ...query |
185 | 208 | }); |
186 | 209 | |
210 | + | |
187 | 211 | if (data) { |
212 | + | |
188 | 213 | this.cancel(); |
189 | 214 | |
190 | 215 | let blob = new Blob([data], { |
191 | 216 | type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
192 | 217 | }); |
193 | 218 | |
194 | - let name = `即时测-单科多卷报表.xlsx`; | |
219 | + let name = `即时测-${this.$props.queryParams.subject}-单科多卷报表.xlsx`; | |
195 | 220 | |
196 | 221 | downloadFile(this.status ? "即时测-已归档单课时报表.xlsx" : name, blob); |
197 | 222 | } else { |
... | ... | @@ -202,8 +227,9 @@ export default { |
202 | 227 | tablePrint("print-content", "即时测-已归档单课时报表"); |
203 | 228 | }, |
204 | 229 | _titleClick() { }, |
205 | - _openLineChart(chartRow) { | |
206 | - this.lineChart.title = `${chartRow.studentName}-${chartRow.subjectName}-多课时作答表现图`; | |
230 | + _openLineChart(chartRow) { | |
231 | + var subejct = this.$props.role == 'ROLE_BANZHUREN' ? this.$props.queryParams.subjects[0] : this.$props.queryParams.subject; | |
232 | + this.lineChart.title = `${chartRow.studentName}-${subejct}-即时测-多卷作答表现图`; | |
207 | 233 | this.lineChart.visible = true; |
208 | 234 | let score = []; |
209 | 235 | let classRank = []; |
... | ... | @@ -262,7 +288,6 @@ export default { |
262 | 288 | |
263 | 289 | .chart-dia { |
264 | 290 | .chart-box { |
265 | - width: 100%; | |
266 | 291 | height: 300px; |
267 | 292 | } |
268 | 293 | |
... | ... | @@ -270,4 +295,8 @@ export default { |
270 | 295 | padding: 0 0 20px 0; |
271 | 296 | } |
272 | 297 | } |
298 | + | |
299 | +.overClick:hover { | |
300 | + cursor: pointer; | |
301 | +} | |
273 | 302 | </style> | ... | ... |
src/views/basic/askTestQuestion/detail.vue
... | ... | @@ -17,7 +17,20 @@ |
17 | 17 | <el-option v-for="(item, index) in types" :lable="item.name" :key="index" :value="item.name" /> |
18 | 18 | </el-select> |
19 | 19 | <div style="float: right;"> |
20 | - <el-button type="primary" @click="_export" class="opration-btn" | |
20 | + <span v-if="(dataType == '2' && currentType == '测验成绩单') || | |
21 | + (dataType == '2' && currentType == '试题分析') || | |
22 | + (dataType == '3' && currentType == '学生成绩排名榜')"> | |
23 | + 单题低分率: | |
24 | + <el-input-number class="parent-number" v-model="lowLevel" :min="1" :max="100" label="低分率"> | |
25 | + </el-input-number> | |
26 | + </span> | |
27 | + | |
28 | + <el-button v-if="(dataType == '3' && currentType == '班级对比情况表') || | |
29 | + (dataType == '3' && currentType == '学生成绩排名榜')" @click="_studentLevelSet" | |
30 | + class="green-el-button"> | |
31 | + 设置学生成绩等级 | |
32 | + </el-button> | |
33 | + <el-button type="primary" style="margin-left:10px;" @click="_export" class="opration-btn" | |
21 | 34 | icon="el-icon-upload2">导出报表</el-button> |
22 | 35 | <el-button type="primary" @click="_print" class="opration-btn" |
23 | 36 | icon="el-icon-printer">打印报表</el-button> |
... | ... | @@ -26,6 +39,16 @@ |
26 | 39 | </div> |
27 | 40 | <el-main> |
28 | 41 | <div style=" padding: 20px;" id="print-content"> |
42 | + <div style="margin-bottom:20px;background:#ffb3b3;padding:10px 20px;" class="tips" | |
43 | + v-if="paperModifyLog.modifiedTime && !status"> | |
44 | + <p class="tips-p"> | |
45 | + <i class="fa fa-bell-o"></i> | |
46 | + {{ `${paperModifyLog.modifiedTime} ${paperModifyLog.realName}` }}修改了答案,是否重新记分? | |
47 | + <el-button type="danger" round @click="_reScore" size="mini">重新计分</el-button> | |
48 | + <el-button type="danger" round plain size="mini" | |
49 | + @click="paperModifyLog.modifiedTime = ''">暂时不计</el-button> | |
50 | + </p> | |
51 | + </div> | |
29 | 52 | <div v-if="dataType == '1' && currentType == '试题分析'"> |
30 | 53 | <el-row class="row-subfix"> |
31 | 54 | <div class="row-line"> |
... | ... | @@ -78,15 +101,15 @@ |
78 | 101 | </div> |
79 | 102 | <div class="row-line"> |
80 | 103 | <span class="line-subfix">总参与度:</span> |
81 | - <span class="line-value">{{ detail.participationRate }}</span> | |
104 | + <span class="line-value">{{ detail.participationRate }}%</span> | |
82 | 105 | </div> |
83 | 106 | <div class="row-line"> |
84 | 107 | <span class="line-subfix">班级正确率:</span> |
85 | - <span class="line-value">{{ detail.classCorrectRate }}</span> | |
108 | + <span class="line-value">{{ detail.classCorrectRate }}%</span> | |
86 | 109 | </div> |
87 | 110 | <div class="row-line"> |
88 | 111 | <span class="line-subfix">已达正确率:</span> |
89 | - <span class="line-value">{{ detail.answerCorrectRate }}</span> | |
112 | + <span class="line-value">{{ detail.answerCorrectRate }}%</span> | |
90 | 113 | </div> |
91 | 114 | <div class="row-line"> |
92 | 115 | <span class="line-subfix">反馈时长:</span> |
... | ... | @@ -96,7 +119,7 @@ |
96 | 119 | <el-row class="row-table"> |
97 | 120 | <el-table class="default-table" :data="askItemAnalysis"> |
98 | 121 | <el-table-column prop="title" label="课时-题号" /> |
99 | - <el-table-column label="题干" width="120"> | |
122 | + <el-table-column label="题干" width="80"> | |
100 | 123 | <template slot-scope="scoped"> |
101 | 124 | <el-button type="text" size="mini" @click="openStem(scoped.row)">查看</el-button> |
102 | 125 | </template> |
... | ... | @@ -106,14 +129,14 @@ |
106 | 129 | </el-table-column> |
107 | 130 | <el-table-column prop="answeredNum" label="答题人数" width="100" /> |
108 | 131 | <el-table-column prop="correctAnswerNum" label="答对人数" width="100" /> |
109 | - <el-table-column prop="participationRate" label="班级参与度(单题)" width="150"> | |
132 | + <el-table-column prop="participationRate" label="班级参与度(单题)" width="170"> | |
110 | 133 | <template slot-scope="scoped">{{ scoped.row.participationRate }}%</template> |
111 | 134 | </el-table-column> |
112 | - <el-table-column prop="classCorrectRate" label="班级正确率(单题)" width="150"> | |
135 | + <el-table-column prop="classCorrectRate" label="班级正确率(单题)" width="170"> | |
113 | 136 | <template slot-scope="scoped">{{ scoped.row.classCorrectRate }}%</template> |
114 | 137 | </el-table-column> |
115 | 138 | |
116 | - <el-table-column prop="answerCorrectRate" label="已答正确率(单题)" width="150"> | |
139 | + <el-table-column prop="answerCorrectRate" label="已答正确率(单题)" width="170"> | |
117 | 140 | <template slot-scope="scoped">{{ scoped.row.answerCorrectRate }}%</template> |
118 | 141 | </el-table-column> |
119 | 142 | |
... | ... | @@ -142,6 +165,8 @@ |
142 | 165 | <div v-if="dataType == '1' && currentType == '学生作答表现'"> |
143 | 166 | <el-row class="row-table" style="margin-top:0px;"> |
144 | 167 | <el-table class="default-table" :data="askPeriodQuestionItems"> |
168 | + <el-table-column prop="studentCode" label="学号"></el-table-column> | |
169 | + <el-table-column prop="studentName" label="姓名"></el-table-column> | |
145 | 170 | <el-table-column prop="answerTimes" label="答题次数"></el-table-column> |
146 | 171 | <el-table-column prop="consumingDuration" label="答题耗时"><template slot-scope="scoped">{{ |
147 | 172 | setDuration(scoped.row.consumingDuration) |
... | ... | @@ -259,16 +284,109 @@ |
259 | 284 | :key="index" v-for="(item, index) in studentHeader" /> |
260 | 285 | </el-table> |
261 | 286 | </el-row> |
262 | - <el-row class="row-subfix"> | |
263 | - <el-table class="default-table" style="margin-top: 10px" :data="questionList"> | |
264 | - <el-table-column :width="item.label == '题号&答案' ? 80 : 0" :prop="item.prop" | |
265 | - :label="item.label" :key="index" v-for="(item, index) in questionHeaders" /> | |
287 | + <el-row class="row-subfix" style="margin-top:10px"> | |
288 | + <el-table class="default-table" v-if="question4List && question4List.length >= 1" | |
289 | + :data="question4List"> | |
290 | + <el-table-column prop="column0" width="100" label="题号&答案" /> | |
291 | + <el-table-column prop="column1" label="得分率"> | |
292 | + <template slot-scope="scoped"> | |
293 | + <div | |
294 | + :class="Number(scoped.row.column1?.replace('%', '')) <= lowLevel ? 'lowLevelClass' : ''"> | |
295 | + {{ scoped.row.column1 }} | |
296 | + </div> | |
297 | + </template> | |
298 | + </el-table-column> | |
299 | + <el-table-column prop="column2" label="选项1" /> | |
300 | + <el-table-column prop="column3" label="选项2" /> | |
301 | + <el-table-column prop="column4" label="选项3" /> | |
302 | + <el-table-column prop="column5" label="选项4" /> | |
303 | + <el-table-column prop="column6" width="100" label="题号&答案" /> | |
304 | + <el-table-column prop="column7" label="得分率"> | |
305 | + <template slot-scope="scoped"> | |
306 | + <div | |
307 | + :class="Number(scoped.row.column7?.replace('%', '')) <= lowLevel ? 'lowLevelClass' : ''"> | |
308 | + {{ scoped.row.column7 }} | |
309 | + </div> | |
310 | + </template> | |
311 | + </el-table-column> | |
312 | + <el-table-column prop="column8" label="选项1" /> | |
313 | + <el-table-column prop="column9" label="选项2" /> | |
314 | + <el-table-column prop="column10" label="选项3" /> | |
315 | + <el-table-column prop="column11" label="选项4" /> | |
316 | + <el-table-column prop="column12" width="100" label="题号&答案" /> | |
317 | + <el-table-column prop="column13" label="得分率"> | |
318 | + <template slot-scope="scoped"> | |
319 | + <div | |
320 | + :class="Number(scoped.row.column13?.replace('%', '')) <= lowLevel ? 'lowLevelClass' : ''"> | |
321 | + {{ scoped.row.column13 }} | |
322 | + </div> | |
323 | + </template> | |
324 | + </el-table-column> | |
325 | + <el-table-column prop="column14" label="选项1" /> | |
326 | + <el-table-column prop="column15" label="选项2" /> | |
327 | + <el-table-column prop="column16" label="选项3" /> | |
328 | + <el-table-column prop="column17" label="选项4" /> | |
266 | 329 | </el-table> |
267 | 330 | </el-row> |
268 | - <el-row class="row-subfix" v-if="questionOtherList && questionOtherList.length >= 1"> | |
269 | - <el-table class="default-table" style="margin-top: 10px" :data="questionOtherList"> | |
270 | - <el-table-column :prop="item.prop" :label="item.label" :key="index" | |
271 | - v-for="(item, index) in questionOtherHeaders" /> | |
331 | + <el-row class="row-subfix" style="margin-top:10px"> | |
332 | + <el-table class="default-table" v-if="question7List && question7List.length >= 1" | |
333 | + :data="question7List"> | |
334 | + <el-table-column prop="column0" width="100" label="题号&答案" /> | |
335 | + <el-table-column prop="column1" label="得分率"> | |
336 | + <template slot-scope="scoped"> | |
337 | + <div | |
338 | + :class="Number(scoped.row.column1?.replace('%', '')) <= lowLevel ? 'lowLevelClass' : ''"> | |
339 | + {{ scoped.row?.column1 }} | |
340 | + </div> | |
341 | + </template> | |
342 | + </el-table-column> | |
343 | + <el-table-column prop="column2" label="选项1" /> | |
344 | + <el-table-column prop="column3" label="选项2" /> | |
345 | + <el-table-column prop="column4" label="选项3" /> | |
346 | + <el-table-column prop="column5" label="选项4" /> | |
347 | + <el-table-column prop="column6" label="选项5" /> | |
348 | + <el-table-column prop="column7" label="选项6" /> | |
349 | + <el-table-column prop="column8" label="选项7" /> | |
350 | + <el-table-column prop="column9" width="100" label="题号&答案" /> | |
351 | + <el-table-column prop="column10" label="得分率"> | |
352 | + <template slot-scope="scoped"> | |
353 | + <div | |
354 | + :class="Number(scoped.row.column10?.replace('%', '')) <= lowLevel ? 'lowLevelClass' : ''"> | |
355 | + {{ scoped.row?.column10 }} | |
356 | + </div> | |
357 | + </template> | |
358 | + </el-table-column> | |
359 | + <el-table-column prop="column11" label="选项1" /> | |
360 | + <el-table-column prop="column12" label="选项2" /> | |
361 | + <el-table-column prop="column13" label="选项3" /> | |
362 | + <el-table-column prop="column14" label="选项4" /> | |
363 | + <el-table-column prop="column15" label="选项5" /> | |
364 | + <el-table-column prop="column16" label="选项6" /> | |
365 | + <el-table-column prop="column17" label="选项7" /> | |
366 | + </el-table> | |
367 | + </el-row> | |
368 | + <el-row class="row-subfix"> | |
369 | + <el-table class="default-table" v-if="question10List && question10List.length >= 1" | |
370 | + :data="question10List"> | |
371 | + <el-table-column prop="column0" width="100" label="题号&答案" /> | |
372 | + <el-table-column prop="column1" label="得分率"> | |
373 | + <template slot-scope="scoped"> | |
374 | + <div | |
375 | + :class="Number(scoped.row.column1?.replace('%', '')) <= lowLevel ? 'lowLevelClass' : ''"> | |
376 | + {{ scoped.row?.column1 }} | |
377 | + </div> | |
378 | + </template> | |
379 | + </el-table-column> | |
380 | + <el-table-column prop="column2" label="选项1" /> | |
381 | + <el-table-column prop="column3" label="选项2" /> | |
382 | + <el-table-column prop="column4" label="选项3" /> | |
383 | + <el-table-column prop="column5" label="选项4" /> | |
384 | + <el-table-column prop="column6" label="选项5" /> | |
385 | + <el-table-column prop="column7" label="选项6" /> | |
386 | + <el-table-column prop="column8" label="选项7" /> | |
387 | + <el-table-column prop="column9" label="选项8" /> | |
388 | + <el-table-column prop="column10" label="选项9" /> | |
389 | + <el-table-column prop="column11" label="选项10" /> | |
272 | 390 | </el-table> |
273 | 391 | </el-row> |
274 | 392 | <el-row class="row-subfix"> |
... | ... | @@ -278,10 +396,10 @@ |
278 | 396 | <el-table-column prop="student" label="答错学生"> |
279 | 397 | <template slot-scope="scoped"> |
280 | 398 | <span>总计 <span style="color:red;"> |
281 | - {{ scoped.row.details.filter(item => !item.isRight).length }}</span> 人 | |
399 | + {{ scoped.row.missPeopleNumber }}</span> 人 | |
282 | 400 | </span> |
283 | 401 | <span style="margin: 10px 0;" |
284 | - v-for="(item, index) in scoped.row.details.filter(item => !item.isRight)"> | |
402 | + v-for="(item, index) in scoped.row.details.filter(item => !item.right)"> | |
285 | 403 | 选{{ item.option }}:{{ item.students.join("/") }} |
286 | 404 | </span> |
287 | 405 | <span></span> |
... | ... | @@ -291,21 +409,37 @@ |
291 | 409 | </el-row> |
292 | 410 | </div> |
293 | 411 | <div v-if="dataType == '2' && currentType == '试题分析'"> |
294 | - <el-table class="default-table" :data="testQuestions"> | |
412 | + <el-table class="default-table" :data="testQuestions" :span-method="singgleSpanMethod"> | |
295 | 413 | <el-table-column prop="questionIndex" label="题号" width="60"></el-table-column> |
296 | 414 | <el-table-column prop="questionType" label="题型" width="100"> |
297 | 415 | <template slot-scope="scope"> |
298 | 416 | {{ setSubPro(scope.row.questionType) }} |
299 | 417 | </template> |
300 | 418 | </el-table-column> |
301 | - <el-table-column prop="score" width="100" label="知识点"></el-table-column> | |
419 | + <el-table-column prop="knowledge" width="100" label="知识点"></el-table-column> | |
302 | 420 | <el-table-column prop="score" width="100" label="满分值"></el-table-column> |
303 | 421 | <el-table-column width="110" prop="highestScore" label="班最高分"></el-table-column> |
304 | 422 | <el-table-column width="110" prop="lowestScore" label="班最低分"></el-table-column> |
305 | - <el-table-column width="110" prop="avgScore" label="班平均分"></el-table-column> | |
306 | - <el-table-column prop="classScoringRate" width="120" label="班级得分率"><template | |
307 | - slot-scope="scoped">{{ scoped.row.classScoringRate | |
308 | - }}%</template></el-table-column> | |
423 | + <el-table-column width="110" prop="avgScore" label="班平均分"> | |
424 | + <template slot-scope="scoped"> | |
425 | + <div v-if="scoped.row.type != 'colspan'"> | |
426 | + {{ scoped.row.avgScore }} | |
427 | + </div> | |
428 | + <div :class="scoped.row.avgScore <= lowLevel ? 'lowLevelClass' : ''" v-else> | |
429 | + {{ Number(scoped.row.avgScore).toFixed(2) }}% | |
430 | + </div> | |
431 | + </template> | |
432 | + </el-table-column> | |
433 | + <el-table-column prop="classScoringRate" width="120" label="已考得分率"> | |
434 | + <template slot-scope="scoped"> | |
435 | + <div v-if="scoped.row.type == 'colspan'"> | |
436 | + {{ scoped.row.classScoringRate }} | |
437 | + </div> | |
438 | + <div :class="scoped.row.classScoringRate <= lowLevel ? 'lowLevelClass' : ''" v-else> | |
439 | + {{ Number(scoped.row.classScoringRate).toFixed(2) }}% | |
440 | + </div> | |
441 | + </template> | |
442 | + </el-table-column> | |
309 | 443 | <el-table-column prop="correctAnswer" label="答案"><template slot-scope="scoped">{{ |
310 | 444 | scoped.row.correctAnswer == 1 |
311 | 445 | ? "✓" |
... | ... | @@ -318,20 +452,18 @@ |
318 | 452 | :prop="'count' + index" width="120"><template slot-scope="scope"> |
319 | 453 | <p class="persent"> |
320 | 454 | {{ |
321 | - scope.row.questionType == "5" | |
322 | - ? "" | |
323 | - : scope.row["option" + index] | |
455 | + scope.row["option" + index] == "?" ? "未答" : scope.row.questionType == "5" ? "" : | |
456 | + scope.row["option" + index] | |
324 | 457 | ? `${scope.row["option" + index]}(${scope.row["persent" + index] |
325 | 458 | })` |
326 | - : "" | |
327 | - }} | |
459 | + : "" }} | |
328 | 460 | </p> |
329 | 461 | </template> |
330 | 462 | </el-table-column> |
331 | 463 | </el-table> |
332 | 464 | </div> |
333 | - <div v-if="dataType == '2' && currentType == '成绩排名'"> | |
334 | - <el-table class="default-table" :data="testStudents"> | |
465 | + <div v-if="dataType == '2' && currentType == '成绩排名'" ref="studentRank"> | |
466 | + <el-table :key="studentRank.length" class="default-table" :data="studentRank"> | |
335 | 467 | <el-table-column prop="studentCode" label="学号" width="120"></el-table-column> |
336 | 468 | <el-table-column prop="studentName" label="姓名"></el-table-column> |
337 | 469 | <el-table-column prop="examScore" label="总分"></el-table-column> |
... | ... | @@ -359,8 +491,8 @@ |
359 | 491 | </el-table-column> |
360 | 492 | </el-table> |
361 | 493 | </div> |
362 | - <div v-if="dataType == '2' && currentType == '小题分报表'"> | |
363 | - <el-table class="default-table" :data="testStudents"> | |
494 | + <div v-if="dataType == '2' && currentType == '小题分报表'" ref="studentQuestions"> | |
495 | + <el-table :key="studentQuestions.length" class="default-table" :data="studentQuestions"> | |
364 | 496 | <el-table-column prop="studentCode" label="学号" width="120"></el-table-column> |
365 | 497 | <el-table-column prop="studentName" label="姓名"></el-table-column> |
366 | 498 | <el-table-column prop="examScore" label="总分"></el-table-column> |
... | ... | @@ -368,21 +500,21 @@ |
368 | 500 | <el-table-column prop="objectiveExamScore" label="客观题分"></el-table-column> |
369 | 501 | <el-table-column prop="subjectiveExamScore" label="主观题分"></el-table-column> |
370 | 502 | </el-table-column> |
371 | - <el-table-column v-for="(item, index) in testStudentOptions" :key="index" :label="'Q' + item.id" | |
372 | - :prop="'score' + item.id"> | |
503 | + <el-table-column v-for="(item, index) in studentQuestionOptions" :key="index" | |
504 | + :label="'Q' + item.id" :prop="'score' + item.id"> | |
373 | 505 | </el-table-column> |
374 | 506 | </el-table> |
375 | 507 | </div> |
376 | - <div v-if="dataType == '2' && currentType == '作答明细'"> | |
377 | - <el-table class="default-table" :data="testStudents"> | |
508 | + <div v-if="dataType == '2' && currentType == '作答明细'" ref="studentAnsered"> | |
509 | + <el-table :key="studentAnsered.length" class="default-table" :data="studentAnsered"> | |
378 | 510 | <el-table-column prop="studentCode" width="120" label="学号"></el-table-column> |
379 | 511 | <el-table-column prop="studentName" label="姓名"></el-table-column> |
380 | 512 | <el-table-column prop="className" label="班级"></el-table-column> |
381 | 513 | <el-table-column prop="examScore" label="总分"></el-table-column> |
382 | - <el-table-column v-for="(item, index) in testStudentOptions" :key="index" | |
514 | + <el-table-column v-for="(item, index) in studentAnseredOptions" :key="index" | |
383 | 515 | :label="'Q' + item.id"> |
384 | 516 | <template slot-scope="scope"> |
385 | - <span v-if="testStudents[index]?.questionType == 5">*</span> | |
517 | + <span v-if="studentAnsered[index]?.questionType == 5">*</span> | |
386 | 518 | <span v-else-if="scope.row['answer' + item.id]" |
387 | 519 | :class="scope.row['isRight' + item.id] ? '' : 'error'"> |
388 | 520 | {{ scope.row["answer" + item.id] }} |
... | ... | @@ -403,7 +535,8 @@ |
403 | 535 | </el-table-column> |
404 | 536 | <el-table-column prop="title" label="参与度" width="120"> |
405 | 537 | <template slot-scope="scoped"> |
406 | - {{ scoped.row.testCount / scoped.row.classCount }} | |
538 | + {{ Number(scoped.row.testCount * 100 / scoped.row.classCount).toFixed(2) }}% | |
539 | + | |
407 | 540 | </template> |
408 | 541 | </el-table-column> |
409 | 542 | <el-table-column prop="avg" label="班平均分" width="120" /> |
... | ... | @@ -411,40 +544,54 @@ |
411 | 544 | <el-table-column prop="low" label="班最低分" width="120" /> |
412 | 545 | <el-table-column prop="front20" label="前20名均分" width="120" /> |
413 | 546 | <el-table-column prop="last20" label="后20名均分" width="120" /> |
414 | - <el-table-column prop="excellenRate" label="优秀数(率)" width="120"> | |
547 | + <el-table-column v-for="(item, index) in defaultLevels.levels" :key="index" | |
548 | + :label="item[0] ? item[0] + '数(率)' : ''"> | |
415 | 549 | <template slot-scope="scoped"> |
416 | - {{ scoped.row.excellenRate }}% | |
417 | - </template> | |
418 | - </el-table-column> | |
419 | - <el-table-column prop="goodRate" label="良好数(率)" width="120"> | |
420 | - <template slot-scope="scoped"> | |
421 | - {{ scoped.row.goodRate }}% | |
422 | - </template> | |
423 | - </el-table-column> | |
424 | - <el-table-column prop="passRate" label="合格数(率)" width="120"> | |
425 | - <template slot-scope="scoped"> | |
426 | - {{ scoped.row.passRate }}% | |
427 | - </template> | |
428 | - </el-table-column> | |
429 | - <el-table-column prop="failedRate" label="不合格数(率)" width="120"> | |
430 | - <template slot-scope="scoped"> | |
431 | - {{ scoped.row.passRate }}% | |
550 | + {{ scoped.row.leverValues[item[0]] }} | |
432 | 551 | </template> |
433 | 552 | </el-table-column> |
434 | 553 | </el-table> |
435 | 554 | </div> |
436 | 555 | <div v-if="dataType == '3' && currentType == '试题分析'"> |
437 | - <el-table class="default-table" :data="testPaperExamReport"> | |
556 | + <el-table class="default-table" :data="testPaperExamReport" :span-method="arraySpanMethod"> | |
438 | 557 | <el-table-column prop="questionIndex" label="题号" width="120" /> |
439 | 558 | <el-table-column prop="questionType" label="题型" width="100"> |
440 | 559 | <template slot-scope="scope"> |
441 | 560 | {{ setSubPro(scope.row.questionType) }} |
442 | 561 | </template> |
443 | 562 | </el-table-column> |
444 | - <el-table-column prop="score" label="知识点" /> | |
563 | + <el-table-column prop="knowledge" label="知识点"> | |
564 | + <template slot-scope="scoped"> | |
565 | + <el-tooltip effect="dark" :content="scoped.row.knowledge" placement="left"> | |
566 | + <span class="overflowText"> | |
567 | + {{ scoped.row.knowledge }} | |
568 | + </span> | |
569 | + </el-tooltip> | |
570 | + </template> | |
571 | + </el-table-column> | |
445 | 572 | <el-table-column prop="score" label="满分值" width="120" /> |
446 | - <el-table-column prop="avgScore" label="年级平均分" width="120" /> | |
447 | - <el-table-column prop="gradeScoringRate" label="年级得分率" width="120" /> | |
573 | + <el-table-column prop="avgScore" label="年级平均分" width="120"> | |
574 | + <template slot-scope="scoped"> | |
575 | + <div v-if="scoped.row.type == 'colspan'" | |
576 | + :class="scoped.row.avgScore <= lowLevel ? 'lowLevelClass' : ''"> | |
577 | + {{ Number(scoped.row.avgScore).toFixed(2) }} % | |
578 | + </div> | |
579 | + <div v-else> | |
580 | + {{ scoped.row.avgScore }} | |
581 | + </div> | |
582 | + </template> | |
583 | + </el-table-column> | |
584 | + <el-table-column prop="gradeScoringRate" label="年级得分率" width="120"> | |
585 | + <template slot-scope="scoped"> | |
586 | + <div v-if="scoped.row.type == 'colspan'"> | |
587 | + {{ scoped.row.gradeScoringRate }} | |
588 | + </div> | |
589 | + <div v-else="scoped.row.gradeScoringRate" | |
590 | + :class="scoped.row.gradeScoringRate <= lowLevel ? 'lowLevelClass' : ''"> | |
591 | + {{ Number(scoped.row.gradeScoringRate).toFixed(2) }} % | |
592 | + </div> | |
593 | + </template> | |
594 | + </el-table-column> | |
448 | 595 | <el-table-column prop="correctAnswer" label="答案" width="120" /> |
449 | 596 | <el-table-column v-for="(item, index) in testPaperExamReportOptions" :key="index" |
450 | 597 | :label="item.title" :prop="'count' + index" width="120"> |
... | ... | @@ -470,13 +617,89 @@ |
470 | 617 | <el-table-column prop="name" label="姓名" /> |
471 | 618 | <el-table-column prop="className" label="班级" /> |
472 | 619 | <el-table-column prop="exam" label="分数" /> |
473 | - <el-table-column prop="title" label="成绩等级" /> | |
620 | + <el-table-column prop="lever" label="成绩等级" /> | |
474 | 621 | </el-table> |
475 | 622 | </div> |
476 | 623 | </div> |
477 | 624 | </el-main> |
478 | 625 | <el-dialog class="stem" :visible.sync="stem.visible" :title="'题干'" width="800" :append-to-body="true"> |
479 | - <iframe v-if="stem&&stem.src" :src="stem.src" style="width: 100%;min-height: 400px;" /> | |
626 | + <iframe v-if="stem && stem.src" :src="stem.src" style="width: 100%;min-height: 400px;" /> | |
627 | + </el-dialog> | |
628 | + <el-dialog :append-to-body="true" :close-on-click-modal="false" title="学生等级设置" | |
629 | + :visible.sync="studentLevelDialog" width="900px" @closed="_studentLevelClose"> | |
630 | + <el-container class="default-body" style="background: transparent !important;"> | |
631 | + <el-main> | |
632 | + <div class="default-main"> | |
633 | + <el-form class="use-form"> | |
634 | + <el-form-item class="use-form-item-box"> | |
635 | + <el-form-item label="等级设置模式" class="use-form-item"> | |
636 | + <el-select size="small" v-model="fromData.levelType"> | |
637 | + <el-option label="按分数比例" :value="0"></el-option> | |
638 | + <el-option label="按已考人数比例" :value="1"></el-option> | |
639 | + </el-select> | |
640 | + </el-form-item> | |
641 | + </el-form-item> | |
642 | + <el-form-item> | |
643 | + <div class="dia-tab-box"> | |
644 | + <p class="dia-tab-tit"> | |
645 | + <span class="item1 boxitem">序号</span> | |
646 | + <span class="item2 boxitem"><i>*</i>等级名称</span> | |
647 | + <span class="item3 boxitem"><i>*</i>等级最高</span> | |
648 | + <span class="item3 boxitem"><i>*</i>等级最低</span> | |
649 | + <span class="item boxitem">操作</span> | |
650 | + </p> | |
651 | + <div class="dia-tab-item" v-for="(item, index) in fromData.levels" :key="index"> | |
652 | + <span class="item1 boxitem">{{ index + 1 }}</span> | |
653 | + <p class="item2 boxitem"> | |
654 | + <el-input class="score-ipt" v-model="item[0]" :maxlength="12" | |
655 | + @keydown.native="keydownRange($event)"></el-input> | |
656 | + </p> | |
657 | + <p class="item3 boxitem"> | |
658 | + <el-input class="score-ipt" type="number" v-model="item[1]" :min="item[2]" | |
659 | + :max="index == 0 ? 100 : fromData.levels[index - 1][2]" | |
660 | + @keydown.native="keydownRange($event)"></el-input> | |
661 | + <span class="descption"> | |
662 | + % | |
663 | + <template v-if="fromData.levelType == 0"> | |
664 | + ( | |
665 | + {{ index != 0 ? "不含" : "" }} | |
666 | + {{ Number(((item[1] / 100) * examPaperScore).toFixed(1)) }}分 | |
667 | + ) | |
668 | + </template> | |
669 | + <template v-else>{{ index != 0 ? "不含" : "" }}</template> | |
670 | + </span> | |
671 | + </p> | |
672 | + <p class="item3 boxitem"> | |
673 | + <el-input class="score-ipt" type="number" v-model="item[2]" :min="0" | |
674 | + :max="item[1]" @keydown.native="keydownRange($event)"></el-input> | |
675 | + <span class="descption"> | |
676 | + % | |
677 | + <template v-if="fromData.levelType == 0"> | |
678 | + ({{ Number(((item[2] / 100) * examPaperScore).toFixed(1)) }}分) | |
679 | + </template> | |
680 | + </span> | |
681 | + </p> | |
682 | + <p class="item boxitem"> | |
683 | + <el-link type="danger" :underline="false" | |
684 | + @click="fromData.levels.splice(index, 1)">删除</el-link> | |
685 | + </p> | |
686 | + </div> | |
687 | + <div class="add"> | |
688 | + <p @click="fromData.levels.push(['', '', ''])"> | |
689 | + <el-button size="mini" icon="el-icon-plus" circle | |
690 | + type="primary"></el-button>添加一行 | |
691 | + </p> | |
692 | + </div> | |
693 | + </div> | |
694 | + </el-form-item> | |
695 | + </el-form> | |
696 | + </div> | |
697 | + </el-main> | |
698 | + </el-container> | |
699 | + <div class="dialog-footer" slot="footer" align="right"> | |
700 | + <el-button type="info" :size="'small'" @click="studentLevelDialog = false">取 消</el-button> | |
701 | + <el-button type="primary" class="green-el-button" :size="'small'" @click="_savefrom">保存</el-button> | |
702 | + </div> | |
480 | 703 | </el-dialog> |
481 | 704 | </el-container> |
482 | 705 | </template> |
... | ... | @@ -484,6 +707,7 @@ |
484 | 707 | import { formatDate, downloadFile, tablePrint } from "utils"; |
485 | 708 | export default { |
486 | 709 | name: "reportDetail", |
710 | + components: { testScoreSet: () => import("./components/testScoreSet.vue"), }, | |
487 | 711 | async created() { |
488 | 712 | this.role = |
489 | 713 | |
... | ... | @@ -506,9 +730,36 @@ export default { |
506 | 730 | this.currentType = this.types[0]?.name ?? "" |
507 | 731 | |
508 | 732 | await this._changeType(); |
733 | + | |
734 | + await this._queryDefaultLevels(); | |
735 | + | |
736 | + if (this.dataType == '2') { | |
737 | + await this._examDetail(); | |
738 | + } | |
509 | 739 | }, |
510 | 740 | data() { |
511 | 741 | return { |
742 | + status: 0, | |
743 | + //导出相关 | |
744 | + paperModifyLog: {}, | |
745 | + diaShow: false, | |
746 | + exportStudent: [], | |
747 | + showSelect: true, //是否显示录总分 | |
748 | + showAllSetScore: false, //当前操作试卷可录总分分状态 | |
749 | + showSetScore: false, //当前操作试卷可录小题分状态 | |
750 | + lowLevel: 20, | |
751 | + defaultLevels: [], | |
752 | + examPaperScore: 100, //卷面最高分 | |
753 | + fromData: { | |
754 | + levelType: 0, | |
755 | + levels: [ | |
756 | + ["优秀", 100, 90], | |
757 | + ["良好", 89.9, 70], | |
758 | + ["合格", 69.9, 60], | |
759 | + ["不合格", 59.9, 0], | |
760 | + ], | |
761 | + }, | |
762 | + studentLevelDialog: false, | |
512 | 763 | titleInfo: [], |
513 | 764 | studentList: [], |
514 | 765 | studentHeader: [], |
... | ... | @@ -538,10 +789,9 @@ export default { |
538 | 789 | label: "主观分", |
539 | 790 | }, |
540 | 791 | ], |
541 | - questionList: [], | |
542 | - questionHeaders: [], | |
543 | - questionOtherList: [], | |
544 | - questionOtherHeaders: [], | |
792 | + question4List: [], | |
793 | + question7List: [], | |
794 | + question10List: [], | |
545 | 795 | questionTotal: [], |
546 | 796 | dataType: null, |
547 | 797 | classIds: [], |
... | ... | @@ -579,6 +829,11 @@ export default { |
579 | 829 | testStudents: [], |
580 | 830 | // 报表学生选项 |
581 | 831 | testStudentOptions: [], |
832 | + studentAnsered: [], | |
833 | + studentAnseredOptions: [], | |
834 | + studentRank: [], | |
835 | + studentQuestions: [], | |
836 | + studentQuestionOptions: [], | |
582 | 837 | // 报表题目详情 |
583 | 838 | testQuestions: [], |
584 | 839 | // 报表题目选项 |
... | ... | @@ -599,7 +854,7 @@ export default { |
599 | 854 | tit = "主观题"; |
600 | 855 | break; |
601 | 856 | default: |
602 | - tit = "其他"; | |
857 | + tit = type; | |
603 | 858 | } |
604 | 859 | return tit; |
605 | 860 | }, |
... | ... | @@ -662,9 +917,11 @@ export default { |
662 | 917 | detail: {}, |
663 | 918 | currentType: null, |
664 | 919 | classdiffExamReport: [], |
920 | + classdiffLevelOptions: [], | |
665 | 921 | testPaperExamReport: [], |
666 | 922 | testStudentExamReport: [], |
667 | 923 | testPaperExamReportOptions: [], |
924 | + diffType: 0, | |
668 | 925 | //题干数据对象 |
669 | 926 | stem: { |
670 | 927 | visible: false, |
... | ... | @@ -673,12 +930,171 @@ export default { |
673 | 930 | } |
674 | 931 | }, |
675 | 932 | methods: { |
933 | + async _examDetail() { | |
934 | + const examDetail = | |
935 | + this.role == "ROLE_PERSONAL" | |
936 | + ? this.$request.pExamDetail | |
937 | + : this.$request.examDetail; | |
938 | + | |
939 | + let { data, info, status } = await examDetail({ | |
940 | + examId: this.ids[0], | |
941 | + }); | |
942 | + console.log('detail', data, data.paperModifyLog) | |
943 | + if (status === 0) { | |
944 | + if (data.paperModifyLog) { | |
945 | + this.paperModifyLog = { ...data?.paperModifyLog }; | |
946 | + } | |
947 | + } else { | |
948 | + this.$message.error(info); | |
949 | + } | |
950 | + }, | |
951 | + async _reScore() { | |
952 | + //重新记分 | |
953 | + let { data, info, status } = await this.$request.reScore({ | |
954 | + examId: this.ids[0], | |
955 | + }); | |
956 | + if (status === 0) { | |
957 | + this.$message.success(info); | |
958 | + await this._changeType(); | |
959 | + this.paperModifyLog.modifiedTime = ""; | |
960 | + this.paperModifyLog.realName = ""; | |
961 | + } else { | |
962 | + this.$message.error(info); | |
963 | + } | |
964 | + }, | |
965 | + _closeScoreSet() { | |
966 | + this.scoreSet.diaScoreSet = false; | |
967 | + }, | |
968 | + _successScoreSet() { | |
969 | + this._changeType(); | |
970 | + this._closeScoreSet(); | |
971 | + }, | |
972 | + async _queryDefaultLevels() { | |
973 | + | |
974 | + const { data, info, status } = await this.$request.defaultLevels(); | |
975 | + | |
976 | + if (status != 0) { | |
977 | + this.$message.error(info); | |
978 | + return; | |
979 | + } | |
980 | + | |
981 | + this.defaultLevels = { ...data } || { | |
982 | + levelType: 0, | |
983 | + levels: [ | |
984 | + ["优秀", 100, 90], | |
985 | + ["良好", 89.9, 70], | |
986 | + ["合格", 69.9, 60], | |
987 | + ["不合格", 59.9, 0], | |
988 | + ], | |
989 | + }; | |
990 | + | |
991 | + this.defaultLevels.type = 0 | |
992 | + | |
993 | + this.fromData.levelType = this.defaultLevels.levelType; | |
994 | + | |
995 | + this.fromData.levels = [...this.defaultLevels.levels]; | |
996 | + | |
997 | + sessionStorage.setItem( | |
998 | + "levelFromData", | |
999 | + JSON.stringify(this.defaultLevels) | |
1000 | + ); | |
1001 | + }, | |
1002 | + singgleSpanMethod({ row, column, rowIndex, columnIndex }) { | |
1003 | + if (rowIndex == this.testQuestions?.length - 3) { | |
1004 | + if (columnIndex == 0) { | |
1005 | + return [3, 1]; | |
1006 | + } | |
1007 | + // else if (columnIndex == 6) { | |
1008 | + // return [3, 1]; | |
1009 | + // } | |
1010 | + // else if (columnIndex == 7) { | |
1011 | + // return [3, 5]; | |
1012 | + // } | |
1013 | + else { | |
1014 | + return [1, 1] | |
1015 | + } | |
1016 | + } | |
1017 | + else { | |
1018 | + return [1, 1] | |
1019 | + } | |
1020 | + }, | |
1021 | + arraySpanMethod({ row, column, rowIndex, columnIndex }) { | |
1022 | + if (rowIndex == this.testPaperExamReport?.length - 3) { | |
1023 | + if (columnIndex == 0) { | |
1024 | + return [3, 1]; | |
1025 | + } | |
1026 | + else if (columnIndex == 6) { | |
1027 | + return [3, 1]; | |
1028 | + } | |
1029 | + else if (columnIndex == 7) { | |
1030 | + return [3, 5]; | |
1031 | + } | |
1032 | + else { | |
1033 | + return [1, 1] | |
1034 | + } | |
1035 | + } | |
1036 | + else { | |
1037 | + return [1, 1] | |
1038 | + } | |
1039 | + | |
1040 | + }, | |
1041 | + async _savefrom() { | |
1042 | + for (let i = 0; i < this.fromData.levels.length; i++) { | |
1043 | + if (this.fromData.levels[i].includes("")) { | |
1044 | + this.$message.warning("请补全编号" + (i + 1) + "设置信息!"); | |
1045 | + return; | |
1046 | + } | |
1047 | + } | |
1048 | + if (this.fromData.levels.length == 0) { | |
1049 | + this.$message.warning("请添加等级设置!"); | |
1050 | + return; | |
1051 | + } | |
1052 | + let nums = []; | |
1053 | + let ERR_OK = false; | |
1054 | + this.fromData.levels.map((item) => { | |
1055 | + nums.push(Number(item[1])); | |
1056 | + nums.push(Number(item[2])); | |
1057 | + }); | |
1058 | + for (let i = 0; i < nums.length; i++) { | |
1059 | + if (nums[i + 1] && nums[i + 1] > nums[i]) { | |
1060 | + ERR_OK = true; | |
1061 | + this.$message.warning("高等级比例不能低于低等级比例!请检查"); | |
1062 | + break; | |
1063 | + } | |
1064 | + } | |
1065 | + if (ERR_OK) return; | |
1066 | + this.tableData = []; | |
1067 | + this.tableData2 = []; | |
1068 | + this.defaultLevels.type = this.fromData.type; | |
1069 | + this.defaultLevels.levelType = this.fromData.levelType; | |
1070 | + this.defaultLevels.levels = [...this.fromData.levels]; | |
1071 | + sessionStorage.setItem("levelFromData", JSON.stringify(this.fromData)); | |
1072 | + this.studentLevelDialog = false; | |
1073 | + await this._changeType(); | |
1074 | + }, | |
1075 | + _studentLevelClose() { | |
1076 | + let levelFromData = sessionStorage.getItem("levelFromData"); | |
1077 | + if (levelFromData) { | |
1078 | + levelFromData = JSON.parse(levelFromData); | |
1079 | + this.fromData.type = levelFromData.type; | |
1080 | + this.fromData.levelType = levelFromData.levelType; | |
1081 | + this.fromData.levels = [...levelFromData.levels]; | |
1082 | + } else { | |
1083 | + this.fromData.type = 0; | |
1084 | + this.fromData.levelType = this.defaultLevels.levelType; | |
1085 | + this.fromData.levels = [...this.defaultLevels.levels]; | |
1086 | + } | |
1087 | + }, | |
1088 | + _studentLevelSet() { | |
1089 | + this.studentLevelDialog = true; | |
1090 | + }, | |
676 | 1091 | async _export() { |
677 | 1092 | if (this.dataType == "1") { |
678 | 1093 | |
679 | 1094 | let exportPeriodReport = ""; |
680 | 1095 | |
681 | 1096 | var query = {}; |
1097 | + | |
682 | 1098 | query.periodId = this.ids[0]; |
683 | 1099 | |
684 | 1100 | exportPeriodReport = |
... | ... | @@ -701,7 +1117,6 @@ export default { |
701 | 1117 | } |
702 | 1118 | } |
703 | 1119 | else if (this.dataType == "2") { |
704 | - | |
705 | 1120 | const exportExamReport = |
706 | 1121 | this.role == "ROLE_PERSONAL" |
707 | 1122 | ? this.$request.pExportExamReport |
... | ... | @@ -711,8 +1126,6 @@ export default { |
711 | 1126 | examId: this.ids[0] |
712 | 1127 | }); |
713 | 1128 | |
714 | - this.exportLoading = false; | |
715 | - | |
716 | 1129 | if (!data.status) { |
717 | 1130 | let blob = new Blob([data], { |
718 | 1131 | type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", |
... | ... | @@ -727,6 +1140,37 @@ export default { |
727 | 1140 | this.$message.error(data.info); |
728 | 1141 | } |
729 | 1142 | } |
1143 | + else if (this.dataType == '3') { | |
1144 | + | |
1145 | + let paramObj = JSON.parse(JSON.stringify(this.fromData)) | |
1146 | + | |
1147 | + if (paramObj.levelType == 0) { | |
1148 | + paramObj.levels = paramObj.levels.map((item) => { | |
1149 | + item[1] = ((item[1] / 100) * this.examPaperScore).toFixed(1); | |
1150 | + item[2] = ((item[2] / 100) * this.examPaperScore).toFixed(1); | |
1151 | + return item; | |
1152 | + }); | |
1153 | + } | |
1154 | + | |
1155 | + const data = await this.$request.exportExamMultiReport({ | |
1156 | + examIds: this.classdiffExamReport?.map(item => item.examId) ?? [], | |
1157 | + levels: paramObj.levels, | |
1158 | + levelType: paramObj.levelType, | |
1159 | + }); | |
1160 | + | |
1161 | + | |
1162 | + if (!data.status) { | |
1163 | + let blob = new Blob([data], { | |
1164 | + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | |
1165 | + }); | |
1166 | + downloadFile( | |
1167 | + '多班对比.xlsx', | |
1168 | + blob | |
1169 | + ); | |
1170 | + } else { | |
1171 | + this.$message.error(data.info); | |
1172 | + } | |
1173 | + } | |
730 | 1174 | |
731 | 1175 | }, |
732 | 1176 | _print() { |
... | ... | @@ -778,6 +1222,30 @@ export default { |
778 | 1222 | } |
779 | 1223 | }, |
780 | 1224 | async _testPaperExamReport() { |
1225 | + //主观 | |
1226 | + var subjective = { | |
1227 | + sum: 0.0, | |
1228 | + avg: 0.0, | |
1229 | + rate: 0.0, | |
1230 | + number: 0 | |
1231 | + }; | |
1232 | + | |
1233 | + //客观 | |
1234 | + var objective = { | |
1235 | + sum: 0.0, | |
1236 | + avg: 0.0, | |
1237 | + rate: 0.0, | |
1238 | + number: 0 | |
1239 | + }; | |
1240 | + | |
1241 | + //汇总 | |
1242 | + var summary = { | |
1243 | + sum: 0.0, | |
1244 | + avg: 0.0, | |
1245 | + rate: 0.0, | |
1246 | + number: 0 | |
1247 | + }; | |
1248 | + | |
781 | 1249 | const request = this.$request.tPaperExamReport; |
782 | 1250 | |
783 | 1251 | let response = await request({ |
... | ... | @@ -789,10 +1257,45 @@ export default { |
789 | 1257 | this.$message.error(response.info); |
790 | 1258 | return; |
791 | 1259 | } |
1260 | + | |
1261 | + var maxOption = 0; | |
1262 | + response.data.forEach((item) =>{ | |
1263 | + if(item.details){ | |
1264 | + if(maxOption < item.details.length) | |
1265 | + { | |
1266 | + maxOption = item.details.length; | |
1267 | + } | |
1268 | + } | |
1269 | + | |
1270 | + }) | |
1271 | + | |
1272 | + let optionsList = []; | |
792 | 1273 | |
793 | - let optionsList = [{}, {}, {}, {}, {}]; | |
1274 | + for(var io=0;io<maxOption;io++){ | |
1275 | + optionsList.push({}) | |
1276 | + } | |
1277 | + | |
1278 | + // let optionsList = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}]; | |
794 | 1279 | |
795 | 1280 | let tableData = response.data?.map((item) => { |
1281 | + | |
1282 | + summary.sum += parseFloat(item.score); | |
1283 | + summary.avg += parseFloat(item.avgScore); | |
1284 | + summary.rate += parseFloat(item.gradeScoringRate); | |
1285 | + summary.number += 1; | |
1286 | + if (item.questionType == 5) { | |
1287 | + subjective.sum += parseFloat(item.score); | |
1288 | + subjective.rate += parseFloat(item.gradeScoringRate); | |
1289 | + subjective.avg += parseFloat(item.avgScore); | |
1290 | + subjective.number += 1; | |
1291 | + } | |
1292 | + else { | |
1293 | + objective.sum += parseFloat(item.score); | |
1294 | + objective.rate += parseFloat(item.gradeScoringRate); | |
1295 | + objective.avg += parseFloat(item.avgScore); | |
1296 | + objective.number += 1; | |
1297 | + } | |
1298 | + | |
796 | 1299 | let params = {}; |
797 | 1300 | |
798 | 1301 | const detail = item?.details ?? []; |
... | ... | @@ -803,6 +1306,7 @@ export default { |
803 | 1306 | let defaultArr = detail?.filter((item) => { |
804 | 1307 | return item.option != "未答"; |
805 | 1308 | }); |
1309 | + | |
806 | 1310 | optionsList.map((items, index) => { |
807 | 1311 | if (index != 4) { |
808 | 1312 | params["count" + index] = |
... | ... | @@ -830,6 +1334,8 @@ export default { |
830 | 1334 | } |
831 | 1335 | }); |
832 | 1336 | |
1337 | + | |
1338 | + | |
833 | 1339 | return { |
834 | 1340 | ...item, |
835 | 1341 | ...params, |
... | ... | @@ -842,13 +1348,48 @@ export default { |
842 | 1348 | |
843 | 1349 | this.testPaperExamReportOptions = [...optionsList]; |
844 | 1350 | |
1351 | + this.testPaperExamReport.push({ | |
1352 | + questionIndex: "汇总", | |
1353 | + questionType: "客观题", | |
1354 | + score: objective.sum, | |
1355 | + avgScore: objective.avg == 0 ? 0 : Number(objective.avg).toFixed(2), | |
1356 | + gradeScoringRate: objective.avg == 0 ? 0 : Number(objective.avg * 100 / objective.sum).toFixed(2), | |
1357 | + correctAnswer: "备注" | |
1358 | + }) | |
1359 | + | |
1360 | + this.testPaperExamReport.push({ | |
1361 | + questionIndex: "主观题", | |
1362 | + type: "colspan", | |
1363 | + knowledge: subjective.sum, | |
1364 | + score: subjective.avg == 0 ? 0 : Number(subjective.avg).toFixed(2), | |
1365 | + avgScore: subjective.avg == 0 ? 0 : Number(subjective.avg * 100 / subjective.sum).toFixed(2) | |
1366 | + }) | |
1367 | + | |
1368 | + this.testPaperExamReport.push({ | |
1369 | + questionIndex: "合计", | |
1370 | + type: "colspan", | |
1371 | + knowledge: summary.sum, | |
1372 | + score: summary.avg == 0 ? 0 : Number(summary.avg).toFixed(2), | |
1373 | + avgScore: summary.avg == 0 ? 0 : Number(summary.avg * 100 / summary.sum).toFixed(2) | |
1374 | + }) | |
845 | 1375 | }, |
846 | 1376 | async _testStudentExamReport() { |
847 | 1377 | const request = this.$request.tgStudentExamReport; |
848 | 1378 | |
1379 | + let paramObj = JSON.parse(JSON.stringify(this.fromData)) | |
1380 | + if (paramObj.levelType == 0) { | |
1381 | + paramObj.levels = paramObj.levels.map((item) => { | |
1382 | + item[1] = ((item[1] / 100) * this.examPaperScore).toFixed(1); | |
1383 | + item[2] = ((item[2] / 100) * this.examPaperScore).toFixed(1); | |
1384 | + return item; | |
1385 | + }); | |
1386 | + } | |
1387 | + | |
1388 | + | |
849 | 1389 | let response = await request({ |
850 | 1390 | paperId: this.ids[0], |
851 | 1391 | classIds: this.classIds, |
1392 | + reportRange: paramObj | |
852 | 1393 | }); |
853 | 1394 | |
854 | 1395 | if (response.status != 0) { |
... | ... | @@ -859,25 +1400,45 @@ export default { |
859 | 1400 | this.testStudentExamReport = response.data; |
860 | 1401 | }, |
861 | 1402 | async _classdiffExamReport() { |
862 | - | |
1403 | + this.classdiffExamReport = []; | |
1404 | + this.classdiffLevelOptions = []; | |
863 | 1405 | const classDiffRequest = this.$request.tClassdiffExamReport; |
864 | 1406 | |
1407 | + let paramObj = JSON.parse(JSON.stringify(this.fromData)) | |
1408 | + if (paramObj.levelType == 0) { | |
1409 | + paramObj.levels = paramObj.levels.map((item) => { | |
1410 | + item[1] = ((item[1] / 100) * this.examPaperScore).toFixed(1); | |
1411 | + item[2] = ((item[2] / 100) * this.examPaperScore).toFixed(1); | |
1412 | + return item; | |
1413 | + }); | |
1414 | + } | |
1415 | + | |
865 | 1416 | let classDiffResponse = await classDiffRequest({ |
866 | 1417 | paperId: this.ids[0], |
867 | 1418 | classIds: this.classIds, |
1419 | + reportRange: paramObj | |
868 | 1420 | }); |
869 | 1421 | |
870 | 1422 | if (classDiffResponse.status != 0) { |
871 | 1423 | this.$message.error(classDiffResponse.info); |
872 | 1424 | return; |
873 | 1425 | } |
1426 | + | |
874 | 1427 | var index = 0; |
875 | 1428 | |
876 | 1429 | this.classdiffExamReport = classDiffResponse.data.map((item) => { |
877 | 1430 | item.index = index + 1; |
878 | 1431 | index += 1; |
1432 | + var cols = 0; | |
1433 | + item.keys.forEach(toam => { | |
1434 | + this.classdiffLevelOptions.push(toam); | |
1435 | + item[toam] = item.leverValues[cols]; | |
1436 | + cols += 1; | |
1437 | + }) | |
879 | 1438 | return item; |
880 | 1439 | }); |
1440 | + | |
1441 | + console.log(this.fromData) | |
881 | 1442 | }, |
882 | 1443 | openStem(stemRow) { |
883 | 1444 | this.stem.src = stemRow.screenshot ?? ""; |
... | ... | @@ -890,8 +1451,8 @@ export default { |
890 | 1451 | const request = this.$request.tTestExamReport; |
891 | 1452 | |
892 | 1453 | let response = await request({ |
893 | - paperId: this.ids[0], | |
894 | - classIds: this.classIds, | |
1454 | + examIds: [this.ids[0]], | |
1455 | + classIds: this.classIds | |
895 | 1456 | }); |
896 | 1457 | |
897 | 1458 | if (response.status != 0) { |
... | ... | @@ -951,202 +1512,241 @@ export default { |
951 | 1512 | |
952 | 1513 | this.studentList = [...studentResults]; |
953 | 1514 | |
954 | - var otherDatas = []; | |
1515 | + var show4Area = true; //显示4选项区域 | |
955 | 1516 | |
956 | - var questionHeaders = []; | |
1517 | + var show7Area = true; //显示7选项区域 | |
957 | 1518 | |
958 | - var questionResults = []; | |
1519 | + var show10Area = true; //显示10选项区域 | |
959 | 1520 | |
960 | - var questionOtherHeaders = []; | |
1521 | + var optionNumList = []; | |
961 | 1522 | |
962 | - var questionOtherResults = []; | |
1523 | + var maxOptions = 4; | |
963 | 1524 | |
964 | - var defaultQuestion = 6; | |
1525 | + var minOptions = 10; //最多10个选项 | |
965 | 1526 | |
966 | - var defaultCount = 3; | |
1527 | + var questionList = response.data.questionInfos; | |
967 | 1528 | |
968 | - var defaultQuestionCount = 4; | |
1529 | + questionList = questionList.sort((prev, next) => { return prev.questionIndex - next.questionIndex }); | |
969 | 1530 | |
970 | - var maxQuestionCount = 4; | |
1531 | + for (var i = 0; i < questionList.length; i++) { | |
971 | 1532 | |
972 | - var optionSt = 1; | |
1533 | + var correctAnswerValue = questionList[i].correctAnswer == "1" ? "✓" : questionList[i].correctAnswer == 2 ? "✗" : questionList[i].correctAnswer; | |
973 | 1534 | |
974 | - for (var qheader = 0; qheader < defaultQuestion * defaultCount; qheader++) { | |
975 | - if (qheader == 0 || qheader % 6 == 0) { | |
976 | - questionHeaders.push({ | |
977 | - prop: "column_" + qheader, | |
978 | - label: "题号&答案", | |
979 | - }); | |
980 | - continue; | |
981 | - } else if (qheader == 1 || (qheader - 1) % 6 == 0) { | |
982 | - questionHeaders.push({ | |
983 | - prop: "column_" + qheader, | |
984 | - label: "得分率", | |
985 | - }); | |
986 | - optionSt = 1; | |
987 | - continue; | |
988 | - } else { | |
989 | - questionHeaders.push({ | |
990 | - prop: "column_" + qheader, | |
991 | - label: "选项" + optionSt, | |
992 | - }); | |
993 | - optionSt += 1; | |
1535 | + var missCount = 0; | |
1536 | + | |
1537 | + var missI = questionList[i].details.filter(item => !item.right); | |
1538 | + | |
1539 | + missI.forEach(itemsa => { | |
1540 | + missCount = Number(missCount) + Number(itemsa.students?.length ?? 0) | |
1541 | + }); | |
1542 | + this.questionTotal.push({ | |
1543 | + quesion: "Q" + (questionList[i].questionIndex), | |
1544 | + anwser: correctAnswerValue ?? "-----", | |
1545 | + details: questionList[i].details, | |
1546 | + missPeopleNumber: missCount | |
1547 | + }) | |
1548 | + if ((questionList[i].questionType == 2)) { | |
1549 | + //单选题可能有超过4个选项,多选题是固定的 | |
1550 | + if (questionList[i].details?.length > maxOptions) { | |
1551 | + maxOptions = questionList[i].details.filter(iam => { return iam.option.indexOf('未答') < 0 })?.length; | |
1552 | + } | |
1553 | + //单选题可能有超过4个选项,多选题是固定的 | |
1554 | + if (questionList[i].details?.length < minOptions) { | |
1555 | + minOptions = questionList[i].details.filter(iam => { return iam.option.indexOf('未答') < 0 })?.length; | |
1556 | + } | |
1557 | + | |
1558 | + optionNumList.push(questionList[i].details.filter(iam => { return iam.option.indexOf('未答') < 0 })?.length); | |
1559 | + } | |
1560 | + | |
1561 | + if (questionList[i].questionType == 4) { | |
1562 | + minOptions = 2; | |
1563 | + optionNumList.push(2); | |
994 | 1564 | } |
995 | 1565 | } |
996 | 1566 | |
997 | - var noPassIndex = 0; | |
1567 | + show4Area = minOptions <= 4; | |
998 | 1568 | |
999 | - this.questionHeaders = questionHeaders; | |
1569 | + show7Area = optionNumList.filter(o => o > 4 && o <= 7); | |
1000 | 1570 | |
1001 | - var itema = null; | |
1571 | + show10Area = optionNumList.filter(o => o > 7); | |
1002 | 1572 | |
1003 | - response.data.questionInfos = [...response.data.questionInfos] | |
1004 | 1573 | |
1005 | - for (var qIndex = 0; qIndex < response.data.questionInfos.length; qIndex++) { | |
1574 | + var currentRow = {}; | |
1006 | 1575 | |
1007 | - var currentData = response.data.questionInfos[qIndex]; | |
1576 | + if (show4Area) { | |
1008 | 1577 | |
1009 | - var filterDetail = currentData.details.filter(fl => fl.option != '未答'); | |
1578 | + var areaList = []; | |
1010 | 1579 | |
1011 | - var correctAnswerValue = currentData.correctAnswer == "1" ? "✓" : currentData.correctAnswer == 2 ? "✗" : currentData.correctAnswer; | |
1580 | + var quesRow = Math.ceil(questionList?.length * 1.00 / 3); | |
1012 | 1581 | |
1013 | - this.questionTotal.push({ | |
1014 | - quesion: "Q" + (qIndex + 1), | |
1015 | - anwser: correctAnswerValue ?? "-----", | |
1016 | - details: currentData.details | |
1017 | - }) | |
1018 | - | |
1019 | - if (filterDetail.length > defaultQuestionCount || filterDetail.length > maxQuestionCount) { | |
1020 | - currentData.index = qIndex; | |
1021 | - otherDatas.push(currentData); | |
1022 | - if (filterDetail.length > maxQuestionCount) { | |
1023 | - maxQuestionCount = filterDetail.length; | |
1024 | - } | |
1025 | - continue; | |
1582 | + for (var irow = 0; irow < quesRow; irow++) { | |
1583 | + areaList.push({}); | |
1026 | 1584 | } |
1027 | - else { | |
1028 | - if (noPassIndex > defaultCount) { | |
1029 | - questionResults.push(itema) | |
1030 | - itema = null; | |
1031 | - noPassIndex = 0; | |
1032 | - } | |
1033 | - var stPass = noPassIndex * defaultQuestion; | |
1034 | - if (!itema) itema = {} | |
1035 | 1585 | |
1036 | - var correctAnswerValue = currentData.correctAnswer == "1" ? "✓" : currentData.correctAnswer == 2 ? "✗" : currentData.correctAnswer; | |
1586 | + for (var i = 0; i < questionList?.length; i++) { | |
1587 | + | |
1588 | + var col = parseInt(i / quesRow); | |
1037 | 1589 | |
1038 | - itema["column_" + (stPass)] = (qIndex + 1) + "" + correctAnswerValue; | |
1039 | - itema["column_" + (stPass + 1)] = (currentData.gradeScoringRate * 100) + "%"; | |
1590 | + var row = parseInt(i % quesRow); | |
1040 | 1591 | |
1041 | - var value = "------"; | |
1592 | + var question = questionList[i]; | |
1042 | 1593 | |
1043 | - for (var iOption = 0; iOption < defaultQuestion - 2; iOption++) { | |
1044 | - var currentOption = filterDetail[iOption]; | |
1045 | - if (currentOption) { | |
1046 | - var optionValue = currentOption.option == "1" ? "✓" : currentOption.option == 2 ? "✗" : currentOption.option; | |
1594 | + var currentRow = areaList[row]; | |
1047 | 1595 | |
1048 | - itema["column_" + (stPass + iOption + 2)] = optionValue + "(" + (currentOption.persent ?? "0%") + ")"; | |
1596 | + var correctAnswerValue = question.correctAnswer == "1" ? "✓" : question.correctAnswer == "2" ? "✗" : question.correctAnswer; | |
1597 | + | |
1598 | + var details = question.details.filter(fl => { | |
1599 | + return fl.option.indexOf('未答') < 0; | |
1600 | + }); | |
1601 | + | |
1602 | + | |
1603 | + for (var ilr = 0; ilr < 6; ilr++) { | |
1604 | + | |
1605 | + if (ilr == 0) { | |
1606 | + currentRow['column' + Number(6 * col + ilr)] = question.questionIndex + correctAnswerValue; | |
1607 | + } | |
1608 | + else if (ilr == 1) { | |
1609 | + currentRow['column' + Number(6 * col + ilr)] = (question.gradeScoringRate * 100).toFixed(2) + '%'; | |
1049 | 1610 | } |
1050 | 1611 | else { |
1051 | - itema["column_" + (stPass + iOption + 2)] = value | |
1612 | + | |
1613 | + var questionDetail = details[ilr - 2]; | |
1614 | + | |
1615 | + var questionColumn = 'column' + Number(6 * col + ilr); | |
1616 | + | |
1617 | + if (details.length <= 4) { | |
1618 | + | |
1619 | + var questionOption = questionDetail ? (questionDetail.option == "1" ? "✓" : questionDetail.option == "2" ? "✗" : questionDetail.option) : "- -" | |
1620 | + | |
1621 | + if (questionOption != "- -") questionOption += "(" + questionDetail.persent + ")"; | |
1622 | + | |
1623 | + currentRow[questionColumn] = questionOption; | |
1624 | + } | |
1625 | + else { | |
1626 | + currentRow[questionColumn] = "--"; | |
1627 | + } | |
1052 | 1628 | } |
1053 | 1629 | } |
1054 | - | |
1055 | - noPassIndex += 1 | |
1056 | 1630 | } |
1057 | 1631 | |
1058 | - if (qIndex >= response.data.questionInfos.length - 1 && noPassIndex != 0) { | |
1059 | - questionResults.push(itema) | |
1060 | - itema = null; | |
1061 | - } | |
1632 | + this.question4List = [...areaList] | |
1633 | + | |
1062 | 1634 | } |
1063 | 1635 | |
1064 | - optionSt = 1; | |
1065 | 1636 | |
1066 | - maxQuestionCount += 2; | |
1637 | + if (show7Area && show7Area.length > -1) { | |
1067 | 1638 | |
1068 | - this.questionList = [...questionResults] | |
1639 | + var areaList = []; | |
1069 | 1640 | |
1070 | - var otherCount = parseInt(defaultQuestion * defaultCount / maxQuestionCount); | |
1641 | + var quesRow = Math.ceil(show7Area.length * 1.00 / 2); | |
1071 | 1642 | |
1072 | - itema = null; | |
1643 | + var num = 0; | |
1073 | 1644 | |
1074 | - for (var qOHeader = 0; qOHeader < maxQuestionCount * otherCount; qOHeader++) { | |
1075 | - if (qOHeader == 0 || qOHeader % (maxQuestionCount) == 0) { | |
1076 | - questionOtherHeaders.push({ | |
1077 | - prop: "column_" + qOHeader, | |
1078 | - label: "题号&答案", | |
1079 | - }); | |
1080 | - continue; | |
1081 | - } else if (qOHeader == 1 || (qOHeader - 1) % (maxQuestionCount) == 0) { | |
1082 | - questionOtherHeaders.push({ | |
1083 | - prop: "column_" + qOHeader, | |
1084 | - label: "得分率", | |
1085 | - }); | |
1086 | - optionSt = 1; | |
1087 | - continue; | |
1088 | - } else { | |
1089 | - questionOtherHeaders.push({ | |
1090 | - prop: "column_" + qOHeader, | |
1091 | - label: "选项" + optionSt, | |
1645 | + for (var irow = 0; irow < quesRow; irow++) { | |
1646 | + areaList.push({}); | |
1647 | + } | |
1648 | + | |
1649 | + for (var i = 0; i < questionList?.length; i++) { | |
1650 | + | |
1651 | + var question = questionList[i]; | |
1652 | + | |
1653 | + var details = question.details.filter(fl => { | |
1654 | + return fl.option.indexOf('未答') < 0; | |
1092 | 1655 | }); |
1093 | - optionSt += 1; | |
1656 | + | |
1657 | + if (question.questionType == 2 && details.length > 4 && details.length <= 7) { | |
1658 | + | |
1659 | + var col = parseInt(num / quesRow); | |
1660 | + | |
1661 | + var row = parseInt(num % quesRow); | |
1662 | + | |
1663 | + var currentRow = areaList[row]; | |
1664 | + | |
1665 | + var correctAnswerValue = question.correctAnswer == "1" ? "✓" : question.correctAnswer == 2 ? "✗" : question.correctAnswer; | |
1666 | + | |
1667 | + for (var ilr = 0; ilr < 9; ilr++) { | |
1668 | + | |
1669 | + if (ilr == 0) { | |
1670 | + currentRow['column' + Number(9 * col + ilr)] = question.questionIndex + correctAnswerValue; | |
1671 | + } | |
1672 | + else if (ilr == 1) { | |
1673 | + | |
1674 | + currentRow['column' + Number(9 * col + ilr)] = (question.gradeScoringRate * 100).toFixed(2) + '%'; | |
1675 | + } | |
1676 | + else { | |
1677 | + | |
1678 | + var questionDetail = details[ilr - 2]; | |
1679 | + | |
1680 | + var questionColumn = 'column' + Number(9 * col + ilr); | |
1681 | + | |
1682 | + currentRow[questionColumn] = questionDetail ? questionDetail.option + "(" + questionDetail.persent + ")" : "- -"; | |
1683 | + } | |
1684 | + } | |
1685 | + | |
1686 | + num = num + 1; | |
1687 | + } | |
1688 | + | |
1094 | 1689 | } |
1690 | + | |
1691 | + this.question7List = [...areaList] | |
1095 | 1692 | } |
1096 | 1693 | |
1097 | - this.questionOtherHeaders = questionOtherHeaders; | |
1098 | 1694 | |
1099 | - noPassIndex = 0; | |
1695 | + if (show10Area && show10Area.length > -1) { | |
1100 | 1696 | |
1101 | - for (var qOIndex = 0; qOIndex < otherDatas.length; qOIndex++) { | |
1697 | + var areaList = []; | |
1102 | 1698 | |
1103 | - var currentData = otherDatas[qOIndex]; | |
1699 | + var quesRow = show10Area.length; | |
1104 | 1700 | |
1105 | - var filterDetail = currentData.details.filter(fl => fl.option != '未答'); | |
1701 | + var num = 0; | |
1106 | 1702 | |
1107 | - if (noPassIndex >= otherCount) { | |
1108 | - questionOtherResults.push(itema) | |
1109 | - itema = null; | |
1110 | - noPassIndex = 0; | |
1703 | + for (var irow = 0; irow < quesRow; irow++) { | |
1704 | + areaList.push({}); | |
1111 | 1705 | } |
1112 | 1706 | |
1113 | - var stPass = noPassIndex * maxQuestionCount; | |
1707 | + for (var i = 0; i < questionList?.length; i++) { | |
1114 | 1708 | |
1115 | - if (!itema) itema = {} | |
1709 | + var question = questionList[i]; | |
1116 | 1710 | |
1117 | - var correctAnswerValue = currentData.correctAnswer == "1" ? "✓" : currentData.correctAnswer == 2 ? "✗" : currentData.correctAnswer; | |
1711 | + var details = question.details.filter(fl => { | |
1712 | + return fl.option.indexOf('未答') < 0; | |
1713 | + }); | |
1118 | 1714 | |
1119 | - itema["column_" + (stPass)] = (Number(currentData.index) + 1) + "" + correctAnswerValue; | |
1715 | + if (question.questionType == 2 && details.length > 7) { | |
1716 | + var col = parseInt(num / quesRow); | |
1120 | 1717 | |
1121 | - itema["column_" + (stPass + 1)] = (currentData.gradeScoringRate * 100) + "%"; | |
1718 | + var row = num; | |
1122 | 1719 | |
1123 | - var value = "------"; | |
1720 | + var currentRow = areaList[row]; | |
1124 | 1721 | |
1125 | - for (var iOption = 0; iOption < maxQuestionCount - 2; iOption++) { | |
1722 | + var correctAnswerValue = question.correctAnswer == "1" ? "✓" : question.correctAnswer == 2 ? "✗" : question.correctAnswer; | |
1126 | 1723 | |
1127 | - var currentOption = filterDetail[iOption]; | |
1724 | + for (var ilr = 0; ilr < 12; ilr++) { | |
1128 | 1725 | |
1129 | - if (currentOption) { | |
1726 | + if (ilr == 0) { | |
1727 | + currentRow['column' + Number(12 * col + ilr)] = question.questionIndex + correctAnswerValue; | |
1728 | + } | |
1729 | + else if (ilr == 1) { | |
1730 | + currentRow['column' + Number(12 * col + ilr)] = (question.gradeScoringRate * 100).toFixed(2) + '%'; | |
1731 | + } | |
1732 | + else { | |
1130 | 1733 | |
1131 | - var optionValue = currentOption.option == "1" ? "✓" : currentOption.option == 2 ? "✗" : currentOption.option; | |
1734 | + var questionDetail = details[ilr - 2]; | |
1132 | 1735 | |
1133 | - itema["column_" + (stPass + iOption + 2)] = optionValue + "(" + (currentOption.persent ?? "0%") + ")"; | |
1134 | - } | |
1135 | - else { | |
1136 | - itema["column_" + (stPass + iOption + 2)] = value | |
1137 | - } | |
1138 | - } | |
1736 | + var questionColumn = 'column' + Number(12 * col + ilr); | |
1139 | 1737 | |
1140 | - noPassIndex += 1 | |
1738 | + currentRow[questionColumn] = questionDetail ? questionDetail.option + "(" + questionDetail.persent + ")" : "- -"; | |
1739 | + } | |
1740 | + } | |
1141 | 1741 | |
1142 | - if (qOIndex >= otherDatas.length - 1 && noPassIndex != 0) { | |
1742 | + num = num + 1; | |
1743 | + } | |
1143 | 1744 | |
1144 | - questionOtherResults.push(itema) | |
1145 | - itema = null; | |
1146 | 1745 | } |
1746 | + | |
1747 | + this.question10List = [...areaList] | |
1147 | 1748 | } |
1148 | 1749 | |
1149 | - this.questionOtherList = [...questionOtherResults] | |
1150 | 1750 | |
1151 | 1751 | }, |
1152 | 1752 | async _loadAskInteractives() { |
... | ... | @@ -1301,6 +1901,14 @@ export default { |
1301 | 1901 | }, |
1302 | 1902 | async _loadTestStudentReport() { |
1303 | 1903 | |
1904 | + this.testStudents = []; | |
1905 | + this.testStudentOptions = []; | |
1906 | + this.studentAnsered = []; | |
1907 | + this.studentAnseredOptions = []; | |
1908 | + this.studentRank = []; | |
1909 | + this.studentQuestions = []; | |
1910 | + this.studentQuestionOptions = []; | |
1911 | + | |
1304 | 1912 | const examStudentReport = |
1305 | 1913 | this.role == "ROLE_PERSONAL" |
1306 | 1914 | ? this.$request.pExamStudentReport |
... | ... | @@ -1317,7 +1925,7 @@ export default { |
1317 | 1925 | |
1318 | 1926 | let optionsList = []; |
1319 | 1927 | |
1320 | - this.testStudents = data?.list.map((item) => { | |
1928 | + let rTestStudents = data?.list.map((item) => { | |
1321 | 1929 | let params = {}; |
1322 | 1930 | const detail = JSON.parse(item.detail); |
1323 | 1931 | if (detail.length) { |
... | ... | @@ -1342,9 +1950,21 @@ export default { |
1342 | 1950 | }; |
1343 | 1951 | }); |
1344 | 1952 | |
1345 | - this.testStudentOptions = optionsList.sort((a, b) => { | |
1953 | + let rtestStudentOptions = optionsList.sort((a, b) => { | |
1346 | 1954 | return a.id - b.id; |
1347 | 1955 | }); |
1956 | + | |
1957 | + if (this.currentType == "成绩排名") { | |
1958 | + this.studentRank = [...rTestStudents] | |
1959 | + } | |
1960 | + else if (this.currentType == "小题分报表") { | |
1961 | + this.studentQuestions = [...rTestStudents] | |
1962 | + this.studentQuestionOptions = [...rtestStudentOptions] | |
1963 | + } | |
1964 | + else if (this.currentType == "作答明细") { | |
1965 | + this.studentAnsered = [...rTestStudents] | |
1966 | + this.studentAnseredOptions = [...rtestStudentOptions] | |
1967 | + } | |
1348 | 1968 | }, |
1349 | 1969 | async _loadTestQuestionReport() { |
1350 | 1970 | //试题分析 |
... | ... | @@ -1365,11 +1985,62 @@ export default { |
1365 | 1985 | return; |
1366 | 1986 | } |
1367 | 1987 | |
1368 | - let optionsList = [{}, {}, {}, {}, {}]; | |
1988 | + //主观 | |
1989 | + var subjective = { | |
1990 | + sum: 0.0, | |
1991 | + avg: 0.0, | |
1992 | + rate: 0.0, | |
1993 | + number: 0, | |
1994 | + max: 0, | |
1995 | + min: 9999, | |
1996 | + answeredRate: 0 | |
1997 | + }; | |
1998 | + | |
1999 | + //客观 | |
2000 | + var objective = { | |
2001 | + sum: 0.0, | |
2002 | + avg: 0.0, | |
2003 | + rate: 0.0, | |
2004 | + number: 0, | |
2005 | + max: 0, | |
2006 | + min: 9999, | |
2007 | + answeredRate: 0 | |
2008 | + }; | |
2009 | + | |
2010 | + //汇总 | |
2011 | + var summary = { | |
2012 | + sum: 0.0, | |
2013 | + avg: 0.0, | |
2014 | + rate: 0.0, | |
2015 | + number: 0, | |
2016 | + max: 0, | |
2017 | + min: 9999, | |
2018 | + answeredRate: 0 | |
2019 | + }; | |
2020 | + | |
2021 | + var maxOption = 0; | |
2022 | + | |
2023 | + data?.list?.forEach((item) =>{ | |
2024 | + | |
2025 | + const detail = JSON.parse(item.detail); | |
2026 | + | |
2027 | + if(maxOption < detail.length) | |
2028 | + { | |
2029 | + maxOption = detail.length; | |
2030 | + } | |
2031 | + }) | |
2032 | + | |
2033 | + let optionsList = []; | |
2034 | + | |
2035 | + for(var io=0;io<maxOption;io++){ | |
2036 | + optionsList.push({}) | |
2037 | + } | |
1369 | 2038 | |
1370 | 2039 | let tableData = data?.list?.map((item) => { |
1371 | 2040 | let params = {}; |
2041 | + | |
1372 | 2042 | const detail = JSON.parse(item.detail); |
2043 | + | |
1373 | 2044 | let lastOPtion = detail?.find((item) => { |
1374 | 2045 | return item.option == "未答"; |
1375 | 2046 | }); |
... | ... | @@ -1378,31 +2049,58 @@ export default { |
1378 | 2049 | }); |
1379 | 2050 | |
1380 | 2051 | optionsList.map((items, index) => { |
1381 | - if (index != 4) { | |
1382 | - params["count" + index] = | |
1383 | - defaultArr[index]?.option != "未答" | |
1384 | - ? defaultArr[index]?.count | |
1385 | - : ""; | |
1386 | - params["persent" + index] = | |
1387 | - defaultArr[index]?.option != "未答" | |
1388 | - ? defaultArr[index]?.persent | |
1389 | - : ""; | |
1390 | - params["option" + index] = | |
1391 | - defaultArr[index]?.option != "未答" | |
1392 | - ? defaultArr[index]?.option == 1 | |
1393 | - ? "✓" | |
1394 | - : defaultArr[index]?.option == 2 | |
1395 | - ? "✗" | |
1396 | - : defaultArr[index]?.option | |
1397 | - : ""; | |
1398 | - items["title"] = "选项" + (index + 1); | |
1399 | - } else { | |
1400 | - items["title"] = "未答"; | |
1401 | - params["count" + index] = lastOPtion.count; | |
1402 | - params["persent" + index] = lastOPtion.persent; | |
1403 | - params["option" + index] = "?"; | |
1404 | - } | |
2052 | + params["count" + index] = | |
2053 | + defaultArr[index]?.option != "未答" | |
2054 | + ? defaultArr[index]?.count | |
2055 | + : ""; | |
2056 | + params["persent" + index] = | |
2057 | + defaultArr[index]?.option != "未答" | |
2058 | + ? defaultArr[index]?.persent | |
2059 | + : ""; | |
2060 | + params["option" + index] = | |
2061 | + defaultArr[index]?.option != "未答" | |
2062 | + ? defaultArr[index]?.option == 1 | |
2063 | + ? "✓" | |
2064 | + : defaultArr[index]?.option == 2 | |
2065 | + ? "✗" | |
2066 | + : defaultArr[index]?.option | |
2067 | + : ""; | |
2068 | + items["title"] = "选项" + (index + 1); | |
2069 | + // if (index != 4) { | |
2070 | + | |
2071 | + // } else { | |
2072 | + // items["title"] = "未答"; | |
2073 | + // params["count" + index] = lastOPtion.count; | |
2074 | + // params["persent" + index] = lastOPtion.persent; | |
2075 | + // params["option" + index] = "?"; | |
2076 | + // } | |
1405 | 2077 | }); |
2078 | + | |
2079 | + summary.sum += parseFloat(item.score); | |
2080 | + summary.avg += parseFloat(item.avgScore); | |
2081 | + summary.rate += parseFloat(item.classScoringRate); | |
2082 | + summary.number += 1; | |
2083 | + summary.max = item.highestScore > summary.max ? item.highestScore : summary.max; | |
2084 | + summary.min = item.lowestScore < summary.min ? item.lowestScore : summary.min; | |
2085 | + | |
2086 | + if (item.questionType == 5) { | |
2087 | + subjective.sum += parseFloat(item.score); | |
2088 | + subjective.avg += parseFloat(item.avgScore); | |
2089 | + subjective.rate += parseFloat(item.classScoringRate); | |
2090 | + subjective.number += 1; | |
2091 | + subjective.max = item.highestScore > summary.max ? item.highestScore : summary.max; | |
2092 | + subjective.min = item.lowestScore < summary.min ? item.lowestScore : summary.min; | |
2093 | + } | |
2094 | + | |
2095 | + else { | |
2096 | + objective.sum += parseFloat(item.score); | |
2097 | + objective.avg += parseFloat(item.avgScore); | |
2098 | + objective.rate += parseFloat(item.classScoringRate); | |
2099 | + objective.number += 1; | |
2100 | + objective.max = item.highestScore > summary.max ? item.highestScore : summary.max; | |
2101 | + objective.min = item.lowestScore < summary.min ? item.lowestScore : summary.min; | |
2102 | + } | |
2103 | + | |
1406 | 2104 | return { |
1407 | 2105 | ...item, |
1408 | 2106 | ...params, |
... | ... | @@ -1414,6 +2112,58 @@ export default { |
1414 | 2112 | }); |
1415 | 2113 | |
1416 | 2114 | this.testQuestionOptions = [...optionsList]; |
2115 | + | |
2116 | + this.testQuestions.push({ | |
2117 | + questionIndex: "汇总", | |
2118 | + questionType: "主观题", | |
2119 | + //满分值 | |
2120 | + score: subjective.sum, | |
2121 | + //最高分 | |
2122 | + highestScore: subjective.max, | |
2123 | + //最低分 | |
2124 | + lowestScore: subjective.min == 9999 ? 0 : subjective.min, | |
2125 | + //平均分 | |
2126 | + avgScore: subjective.avg == 0 ? 0 : Number(subjective.avg).toFixed(2), | |
2127 | + //已考得分率 | |
2128 | + classScoringRate: subjective.sum == 0 ? 0 : Number(subjective.avg * 100 / subjective.sum).toFixed(2) | |
2129 | + }) | |
2130 | + | |
2131 | + this.testQuestions.push({ | |
2132 | + questionIndex: "客观题", | |
2133 | + type: "colspan", | |
2134 | + //满分值 | |
2135 | + knowledge: objective.sum, | |
2136 | + //最高分 | |
2137 | + score: objective.max, | |
2138 | + //最低分 | |
2139 | + highestScore: objective.min == 9999 ? 0 : objective.min, | |
2140 | + //平均分 | |
2141 | + lowestScore: objective.avg == 0 ? 0 : Number(objective.avg).toFixed(2), | |
2142 | + //已考得分率 | |
2143 | + avgScore: objective.sum == 0 ? 0 : Number(objective.avg * 100 / objective.sum).toFixed(2) | |
2144 | + }) | |
2145 | + | |
2146 | + | |
2147 | + | |
2148 | + this.testQuestions.push({ | |
2149 | + questionIndex: "合计", | |
2150 | + type: "colspan", | |
2151 | + //满分值 | |
2152 | + knowledge: summary.sum, | |
2153 | + //最高分 | |
2154 | + score: summary.max, | |
2155 | + //最低分 | |
2156 | + highestScore: summary.min == 9999 ? 0 : summary.min, | |
2157 | + //平均分 | |
2158 | + lowestScore: summary.avg == 0 ? 0 : Number(summary.avg).toFixed(2), | |
2159 | + //已考得分率 | |
2160 | + avgScore: summary.sum == 0 ? 0 : Number(summary.avg / summary.sum * 100).toFixed(2) | |
2161 | + }) | |
2162 | + }, | |
2163 | + keydownRange(event) { | |
2164 | + if (event.key == "-" || event.key == "e") { | |
2165 | + event.returnValue = ""; | |
2166 | + } | |
1417 | 2167 | } |
1418 | 2168 | } |
1419 | 2169 | } |
... | ... | @@ -1425,7 +2175,7 @@ export default { |
1425 | 2175 | |
1426 | 2176 | .row-line { |
1427 | 2177 | overflow: hidden; |
1428 | - width: calc(20% - 2px); | |
2178 | + width: calc(20% - 4px); | |
1429 | 2179 | border: 1px solid #ebeef5; |
1430 | 2180 | background: #f5f7fa; |
1431 | 2181 | display: inline-block; |
... | ... | @@ -1445,4 +2195,69 @@ export default { |
1445 | 2195 | .red { |
1446 | 2196 | color: #f30; |
1447 | 2197 | } |
2198 | + | |
2199 | +.dia-tab-box { | |
2200 | + font-size: 14px; | |
2201 | + | |
2202 | + .boxitem { | |
2203 | + border: 1px solid #DCDFE6; | |
2204 | + margin: 0px !important; | |
2205 | + | |
2206 | + * { | |
2207 | + border: none; | |
2208 | + } | |
2209 | + } | |
2210 | + | |
2211 | + .dia-tab-tit, | |
2212 | + .dia-tab-item { | |
2213 | + | |
2214 | + | |
2215 | + i { | |
2216 | + color: #f30; | |
2217 | + padding-right: 5px; | |
2218 | + } | |
2219 | + | |
2220 | + display: flex; | |
2221 | + | |
2222 | + .item { | |
2223 | + width: 80px; | |
2224 | + } | |
2225 | + | |
2226 | + .item1 { | |
2227 | + padding-left: 10px; | |
2228 | + width: 10%; | |
2229 | + } | |
2230 | + | |
2231 | + .item2 { | |
2232 | + width: 18%; | |
2233 | + } | |
2234 | + | |
2235 | + .item3 { | |
2236 | + padding-left: 12px; | |
2237 | + flex: 1; | |
2238 | + } | |
2239 | + | |
2240 | + .score-ipt { | |
2241 | + width: 100px; | |
2242 | + } | |
2243 | + } | |
2244 | + | |
2245 | + .dia-tab-tit { | |
2246 | + background: rgb(245, 247, 250) !important | |
2247 | + } | |
2248 | + | |
2249 | + .add { | |
2250 | + display: flex; | |
2251 | + justify-content: center; | |
2252 | + margin: 0 auto; | |
2253 | + | |
2254 | + p { | |
2255 | + cursor: pointer; | |
2256 | + } | |
2257 | + | |
2258 | + .el-button { | |
2259 | + margin-right: 6px; | |
2260 | + } | |
2261 | + } | |
2262 | +} | |
1448 | 2263 | </style> |
1449 | 2264 | \ No newline at end of file | ... | ... |
src/views/basic/askTestQuestion/gradeAnalysis.vue
... | ... | @@ -4,8 +4,8 @@ |
4 | 4 | <div class="default-title">即时测报表</div> |
5 | 5 | </el-header> |
6 | 6 | <div class="default-filter"> |
7 | - <el-input v-model="query.paper" placeholder="搜索试卷" suffix-icon="el-icon-search" class="filter-input" | |
8 | - type="number" clearable /> | |
7 | + <!-- <el-input v-model="query.paper" placeholder="搜索试卷" suffix-icon="el-icon-search" class="filter-input" | |
8 | + type="number" clearable /> --> | |
9 | 9 | <el-select v-model="query.grade" class="filter-select" placeholder="选择年级"> |
10 | 10 | <el-option v-for="item in classList" :key="item.grade" :label="item.gradeName" :value="item.grade" /> |
11 | 11 | </el-select> |
... | ... | @@ -107,16 +107,19 @@ export default { |
107 | 107 | this.$message.error('选择对象考试班级为空,请刷新列表'); |
108 | 108 | return; |
109 | 109 | } |
110 | - | |
110 | + | |
111 | 111 | var classListStr = JSON.stringify(currentRow.classInfos); |
112 | 112 | |
113 | 113 | var paperId = currentRow.paperId; |
114 | 114 | |
115 | 115 | var title = currentRow.paperName; |
116 | - | |
116 | + | |
117 | 117 | let routerItem = { |
118 | 118 | path: "/testGradeReportDetail", |
119 | - query: { classListStr: classListStr, paperId: paperId, title: title }, | |
119 | + query: { | |
120 | + classListStr: classListStr, paperId: paperId, title: title, | |
121 | + examIds: currentRow.examIds.join(",") | |
122 | + }, | |
120 | 123 | }; |
121 | 124 | |
122 | 125 | this.$router.push(routerItem); | ... | ... |
src/views/basic/askTestQuestion/gradeAnalysisDetail.vue
... | ... | @@ -11,33 +11,41 @@ |
11 | 11 | </el-header> |
12 | 12 | <div class="default-filter"> |
13 | 13 | 已考班级: |
14 | + <el-checkbox style="margin-right:15px;" class="_el-checkbox" :checked="checkAll" | |
15 | + @change="_handleCheckAllChange">全选</el-checkbox> | |
14 | 16 | <el-checkbox-group style="display: inline-block" v-model="checkedClassInfos" @change="_handleCheckedClassChange"> |
15 | - <el-checkbox class="_el-checkbox" v-model="checkAll" @change="_handleCheckAllChange">全选</el-checkbox> | |
16 | 17 | <el-checkbox class="_el-checkbox" v-for="classItem in classInfos" :key="classItem.classId" |
17 | - :label="classItem.className"> | |
18 | + :label="classItem.classId"> | |
18 | 19 | {{ classItem.className }} |
19 | 20 | </el-checkbox> |
20 | 21 | </el-checkbox-group> |
22 | + <el-button type="primary" style='float: right;' @click="_anys">分析</el-button> | |
21 | 23 | </div> |
22 | 24 | <el-main> |
23 | - <div style="position: relative"> | |
25 | + <div style="position: relative" Id="print-content"> | |
24 | 26 | <el-tabs v-model="tabType" v-loading="queryLoading" type="card" class="default-tabs"> |
25 | 27 | <el-tab-pane :name="'成绩测验单'" :label="`成绩测验单`" style="padding: 0 20px"> |
26 | 28 | <div style="height: calc(100% - 80px);"> |
27 | - <el-row class="row-subfix"> | |
29 | + <el-row class="row-subfix print-hidden"> | |
28 | 30 | <div style="float: right;margin-bottom: 20px;"> |
29 | - <el-button type="primary" class="opration-btn" icon="el-icon-upload2">导出报表</el-button> | |
30 | - <el-button type="primary" class="opration-btn" icon="el-icon-printer">打印报表</el-button> | |
31 | + 单题低分率: | |
32 | + <el-input-number class="parent-number" v-model="lowLevel" :min="1" :max="100" label="低分率"> | |
33 | + </el-input-number> | |
34 | + <el-button style="margin-left:10px;" @click="_import" type="primary" class="opration-btn" | |
35 | + icon="el-icon-upload2">导出报表</el-button> | |
36 | + <el-button @click="_print" type="primary" class="opration-btn" icon="el-icon-printer">打印报表</el-button> | |
31 | 37 | </div> |
32 | 38 | </el-row> |
33 | - <el-row class="row-subfix" :key="index" v-for="(item, index) in titleInfo"> | |
39 | + <el-row class="row-subfix" :key="index" v-for="(item, index) in testTranscript.titleInfo || []"> | |
34 | 40 | <div class="row-line"> |
35 | 41 | <span class="line-subfix">班级:</span> |
36 | 42 | <span class="line-value">{{ item.className }}</span> |
37 | 43 | </div> |
38 | 44 | <div class="row-line"> |
39 | 45 | <span class="line-subfix">试卷名称:</span> |
40 | - <span class="line-value">{{ item.paperName }}</span> | |
46 | + <el-tooltip effect="dark" :content="item.paperName" placement="left"> | |
47 | + <span class="line-value">{{ item.paperName }}</span> | |
48 | + </el-tooltip> | |
41 | 49 | </div> |
42 | 50 | <div class="row-line"> |
43 | 51 | <span class="line-subfix">测验时间:</span> |
... | ... | @@ -45,7 +53,7 @@ |
45 | 53 | </div> |
46 | 54 | </el-row> |
47 | 55 | <el-row class="row-subfix"> |
48 | - <el-table class="default-table" style="margin-top: 10px" :data="titleInfo"> | |
56 | + <el-table class="default-table" style="margin-top: 10px" :data="testTranscript.titleInfo || []"> | |
49 | 57 | <el-table-column prop="testCount" label="测验人数" width="120" /> |
50 | 58 | <el-table-column prop="avg" label="平均分" width="120" /> |
51 | 59 | <el-table-column prop="hight" label="最高分" width="120" /> |
... | ... | @@ -58,34 +66,124 @@ |
58 | 66 | </el-table> |
59 | 67 | </el-row> |
60 | 68 | <el-row class="row-subfix"> |
61 | - <el-table class="default-table" style="margin-top: 10px" :data="studentList"> | |
69 | + <el-table class="default-table" style="margin-top: 10px" :data="testTranscript.studentList || []"> | |
62 | 70 | <el-table-column :width="item.label == '学号' ? 120 : 0" :prop="item.prop" :label="item.label" |
63 | - :key="index" v-for="(item, index) in studentHeader" /> | |
71 | + :key="index" v-for="(item, index) in testTranscript.studentHeader || []" /> | |
64 | 72 | </el-table> |
65 | 73 | </el-row> |
66 | - <el-row class="row-subfix"> | |
67 | - <el-table class="default-table" style="margin-top: 10px" :data="questionList"> | |
68 | - <el-table-column :width="item.label == '题号&答案' ? 80 : 0" :prop="item.prop" :label="item.label" | |
69 | - :key="index" v-for="(item, index) in questionHeaders" /> | |
74 | + <el-row class="row-subfix" style="margin-top:10px"> | |
75 | + <el-table class="default-table" | |
76 | + v-if="testTranscript && testTranscript.question4List && testTranscript.question4List.length >= 1" | |
77 | + :data="testTranscript.question4List"> | |
78 | + <el-table-column prop="column0" label="题号&答案" /> | |
79 | + <el-table-column prop="column1" label="得分率"> | |
80 | + <template slot-scope="scoped"> | |
81 | + <div :class="Number(scoped.row.column1?.replace('%', '')) <= lowLevel ? 'lowLevelClass' : ''"> | |
82 | + {{ scoped.row.column1 }} | |
83 | + </div> | |
84 | + </template> | |
85 | + </el-table-column> | |
86 | + <el-table-column prop="column2" label="选项1" /> | |
87 | + <el-table-column prop="column3" label="选项2" /> | |
88 | + <el-table-column prop="column4" label="选项3" /> | |
89 | + <el-table-column prop="column5" label="选项4" /> | |
90 | + <el-table-column prop="column6" label="题号&答案" /> | |
91 | + <el-table-column prop="column7" label="得分率"> | |
92 | + <template slot-scope="scoped"> | |
93 | + <div :class="Number(scoped.row.column7?.replace('%', '')) <= lowLevel ? 'lowLevelClass' : ''"> | |
94 | + {{ scoped.row.column7 }} | |
95 | + </div> | |
96 | + </template> | |
97 | + </el-table-column> | |
98 | + <el-table-column prop="column8" label="选项1" /> | |
99 | + <el-table-column prop="column9" label="选项2" /> | |
100 | + <el-table-column prop="column10" label="选项3" /> | |
101 | + <el-table-column prop="column11" label="选项4" /> | |
102 | + <el-table-column prop="column12" label="题号&答案" /> | |
103 | + <el-table-column prop="column13" label="得分率"> | |
104 | + <template slot-scope="scoped"> | |
105 | + <div :class="Number(scoped.row.column13?.replace('%', '')) <= lowLevel ? 'lowLevelClass' : ''"> | |
106 | + {{ scoped.row.column13 }} | |
107 | + </div> | |
108 | + </template> | |
109 | + </el-table-column> | |
110 | + <el-table-column prop="column14" label="选项1" /> | |
111 | + <el-table-column prop="column15" label="选项2" /> | |
112 | + <el-table-column prop="column16" label="选项3" /> | |
113 | + <el-table-column prop="column17" label="选项4" /> | |
114 | + </el-table> | |
115 | + </el-row> | |
116 | + <el-row class="row-subfix" style="margin-top:10px"> | |
117 | + <el-table class="default-table" | |
118 | + v-if="testTranscript && testTranscript.question7List && testTranscript.question7List.length >= 1" | |
119 | + :data="testTranscript.question7List"> | |
120 | + <el-table-column prop="column0" label="题号&答案" /> | |
121 | + <el-table-column prop="column1" label="得分率"> | |
122 | + <template slot-scope="scoped"> | |
123 | + <div :class="Number(scoped.row.column1?.replace('%', '')) <= lowLevel ? 'lowLevelClass' : ''"> | |
124 | + {{ scoped.row?.column1 }} | |
125 | + </div> | |
126 | + </template> | |
127 | + </el-table-column> | |
128 | + <el-table-column prop="column2" label="选项1" /> | |
129 | + <el-table-column prop="column3" label="选项2" /> | |
130 | + <el-table-column prop="column4" label="选项3" /> | |
131 | + <el-table-column prop="column5" label="选项4" /> | |
132 | + <el-table-column prop="column6" label="选项5" /> | |
133 | + <el-table-column prop="column7" label="选项6" /> | |
134 | + <el-table-column prop="column8" label="选项7" /> | |
135 | + <el-table-column prop="column9" label="题号&答案" /> | |
136 | + <el-table-column prop="column10" label="得分率"> | |
137 | + <template slot-scope="scoped"> | |
138 | + <div :class="Number(scoped.row.column10?.replace('%', '')) <= lowLevel ? 'lowLevelClass' : ''"> | |
139 | + {{ scoped.row?.column10 }} | |
140 | + </div> | |
141 | + </template> | |
142 | + </el-table-column> | |
143 | + <el-table-column prop="column11" label="选项1" /> | |
144 | + <el-table-column prop="column12" label="选项2" /> | |
145 | + <el-table-column prop="column13" label="选项3" /> | |
146 | + <el-table-column prop="column14" label="选项4" /> | |
147 | + <el-table-column prop="column15" label="选项5" /> | |
148 | + <el-table-column prop="column16" label="选项6" /> | |
149 | + <el-table-column prop="column17" label="选项7" /> | |
70 | 150 | </el-table> |
71 | 151 | </el-row> |
72 | - <el-row class="row-subfix" v-if="questionOtherList && questionOtherList.length >= 1"> | |
73 | - <el-table class="default-table" style="margin-top: 10px" :data="questionOtherList"> | |
74 | - <el-table-column :prop="item.prop" :label="item.label" :key="index" | |
75 | - v-for="(item, index) in questionOtherHeaders" /> | |
152 | + <el-row class="row-subfix"> | |
153 | + <el-table class="default-table" | |
154 | + v-if="testTranscript && testTranscript.question10List && testTranscript.question10List.length >= 1" | |
155 | + :data="testTranscript.question10List"> | |
156 | + <el-table-column prop="column0" label="题号&答案" /> | |
157 | + <el-table-column prop="column1" label="得分率"> | |
158 | + <template slot-scope="scoped"> | |
159 | + <div :class="Number(scoped.row.column1?.replace('%', '')) <= lowLevel ? 'lowLevelClass' : ''"> | |
160 | + {{ scoped.row?.column1 }} | |
161 | + </div> | |
162 | + </template> | |
163 | + </el-table-column> | |
164 | + <el-table-column prop="column2" label="选项1" /> | |
165 | + <el-table-column prop="column3" label="选项2" /> | |
166 | + <el-table-column prop="column4" label="选项3" /> | |
167 | + <el-table-column prop="column5" label="选项4" /> | |
168 | + <el-table-column prop="column6" label="选项5" /> | |
169 | + <el-table-column prop="column7" label="选项6" /> | |
170 | + <el-table-column prop="column8" label="选项7" /> | |
171 | + <el-table-column prop="column9" label="选项8" /> | |
172 | + <el-table-column prop="column10" label="选项9" /> | |
173 | + <el-table-column prop="column11" label="选项10" /> | |
76 | 174 | </el-table> |
77 | 175 | </el-row> |
78 | 176 | <el-row class="row-subfix"> |
79 | - <el-table class="default-table" style="margin-top: 10px" :data="questionTotal"> | |
177 | + <el-table class="default-table" style="margin-top: 10px" :data="testTranscript.questionTotal || []"> | |
80 | 178 | <el-table-column prop="quesion" label="题号" width="120" /> |
81 | 179 | <el-table-column prop="anwser" label="答案" width="120" /> |
82 | 180 | <el-table-column prop="student" label="答错学生"> |
83 | 181 | <template slot-scope="scoped"> |
84 | 182 | <span>总计 <span style="color:red;"> |
85 | - {{ scoped.row.details.filter(item => !item.isRight).length }}</span> 人 | |
183 | + {{ scoped.row.missPeopleNumber }}</span> 人 | |
86 | 184 | </span> |
87 | 185 | <span style="margin: 10px 0;" |
88 | - v-for="(item, index) in scoped.row.details.filter(item => !item.isRight)"> | |
186 | + v-for="(item, index) in scoped.row.details.filter(item => !item.right)"> | |
89 | 187 | 选{{ item.option }}:{{ item.students.join("/") }} |
90 | 188 | </span> |
91 | 189 | <span></span> |
... | ... | @@ -94,35 +192,174 @@ |
94 | 192 | </el-table> |
95 | 193 | </el-row> |
96 | 194 | </div> |
97 | - <div style="height: 80px;"> | |
98 | - <el-pagination background layout="prev, pager, next" :total="testTranscriptCount"> | |
99 | - </el-pagination> | |
100 | - </div> | |
195 | + <div style="height: 80px; width:240px;margin:20px auto;" class="print-hidden"> | |
196 | + <el-button type="default" :size="'small'" @click="_changePage('prev')"> | |
197 | + 上一页</el-button> | |
198 | + {{ currentPage || 0 }}/{{ totalPage || 0 }} | |
199 | + <el-button type="default" style="margin-left:0px" :size="'small'" | |
200 | + @click="_changePage('next')">下一页</el-button> | |
201 | + </div> | |
202 | + <div style="display: none;"> | |
203 | + <div id="test-print"> | |
204 | + <div v-for="(testTranscript, index) in testTranscriptDatas"> | |
205 | + <div style="margin-top:20px"> | |
206 | + <el-row class="row-subfix" :key="index" v-for="(item, index) in testTranscript.titleInfo || []"> | |
207 | + <div class="row-line"> | |
208 | + <span class="line-subfix">班级:</span> | |
209 | + <span class="line-value">{{ item.className }}</span> | |
210 | + </div> | |
211 | + <div class="row-line"> | |
212 | + <span class="line-subfix">试卷名称:</span> | |
213 | + <span class="line-value">{{ item.paperName }}</span> | |
214 | + </div> | |
215 | + <div class="row-line"> | |
216 | + <span class="line-subfix">测验时间:</span> | |
217 | + <span class="line-value">{{ item.testTime }}</span> | |
218 | + </div> | |
219 | + </el-row> | |
220 | + <el-row class="row-subfix"> | |
221 | + <el-table class="default-table" style="margin-top: 10px" :data="testTranscript.titleInfo || []"> | |
222 | + <el-table-column prop="testCount" label="测验人数" width="120" /> | |
223 | + <el-table-column prop="avg" label="平均分" width="120" /> | |
224 | + <el-table-column prop="hight" label="最高分" width="120" /> | |
225 | + <el-table-column prop="low" label="最低分" width="120" /> | |
226 | + <el-table-column prop="title" label="缺考名单"> | |
227 | + <template slot-scope="scoped"> | |
228 | + {{ scoped.row.miss.join("/") }} | |
229 | + </template> | |
230 | + </el-table-column> | |
231 | + </el-table> | |
232 | + </el-row> | |
233 | + <el-row class="row-subfix"> | |
234 | + <el-table class="default-table" style="margin-top: 10px" :data="testTranscript.studentList || []"> | |
235 | + <el-table-column :width="item.label == '学号' ? 120 : 0" :prop="item.prop" :label="item.label" | |
236 | + :key="index" v-for="(item, index) in testTranscript.studentHeader || []" /> | |
237 | + </el-table> | |
238 | + </el-row> | |
239 | + <el-row class="row-subfix" style="margin-top:10px"> | |
240 | + <el-table class="default-table" | |
241 | + v-if="testTranscript && testTranscript.question4List && testTranscript.question4List.length >= 1" | |
242 | + :data="testTranscript.question4List"> | |
243 | + <el-table-column prop="column0" label="题号&答案" /> | |
244 | + <el-table-column prop="column1" label="得分率" /> | |
245 | + <el-table-column prop="column2" label="选项1" /> | |
246 | + <el-table-column prop="column3" label="选项2" /> | |
247 | + <el-table-column prop="column4" label="选项3" /> | |
248 | + <el-table-column prop="column5" label="选项4" /> | |
249 | + <el-table-column prop="column6" label="题号&答案" /> | |
250 | + <el-table-column prop="column7" label="得分率" /> | |
251 | + <el-table-column prop="column8" label="选项1" /> | |
252 | + <el-table-column prop="column9" label="选项2" /> | |
253 | + <el-table-column prop="column10" label="选项3" /> | |
254 | + <el-table-column prop="column11" label="选项4" /> | |
255 | + <el-table-column prop="column12" label="题号&答案" /> | |
256 | + <el-table-column prop="column13" label="得分率" /> | |
257 | + <el-table-column prop="column14" label="选项1" /> | |
258 | + <el-table-column prop="column15" label="选项2" /> | |
259 | + <el-table-column prop="column16" label="选项3" /> | |
260 | + <el-table-column prop="column17" label="选项4" /> | |
261 | + </el-table> | |
262 | + </el-row> | |
263 | + <el-row class="row-subfix" style="margin-top:10px"> | |
264 | + <el-table class="default-table" | |
265 | + v-if="testTranscript && testTranscript.question7List && testTranscript.question7List.length >= 1" | |
266 | + :data="testTranscript.question7List"> | |
267 | + <el-table-column prop="column0" label="题号&答案" /> | |
268 | + <el-table-column prop="column1" label="得分率" /> | |
269 | + <el-table-column prop="column2" label="选项1" /> | |
270 | + <el-table-column prop="column3" label="选项2" /> | |
271 | + <el-table-column prop="column4" label="选项3" /> | |
272 | + <el-table-column prop="column5" label="选项4" /> | |
273 | + <el-table-column prop="column6" label="选项5" /> | |
274 | + <el-table-column prop="column7" label="选项6" /> | |
275 | + <el-table-column prop="column8" label="选项7" /> | |
276 | + <el-table-column prop="column9" label="题号&答案" /> | |
277 | + <el-table-column prop="column10" label="得分率" /> | |
278 | + <el-table-column prop="column11" label="选项1" /> | |
279 | + <el-table-column prop="column12" label="选项2" /> | |
280 | + <el-table-column prop="column13" label="选项3" /> | |
281 | + <el-table-column prop="column14" label="选项4" /> | |
282 | + <el-table-column prop="column15" label="选项5" /> | |
283 | + <el-table-column prop="column16" label="选项6" /> | |
284 | + <el-table-column prop="column17" label="选项7" /> | |
285 | + </el-table> | |
286 | + </el-row> | |
287 | + <el-row class="row-subfix"> | |
288 | + <el-table class="default-table" | |
289 | + v-if="testTranscript && testTranscript.question10List && testTranscript.question10List.length >= 1" | |
290 | + :data="testTranscript.question10List"> | |
291 | + <el-table-column prop="column0" label="题号&答案" /> | |
292 | + <el-table-column prop="column1" label="得分率" /> | |
293 | + <el-table-column prop="column2" label="选项1" /> | |
294 | + <el-table-column prop="column3" label="选项2" /> | |
295 | + <el-table-column prop="column4" label="选项3" /> | |
296 | + <el-table-column prop="column5" label="选项4" /> | |
297 | + <el-table-column prop="column6" label="选项5" /> | |
298 | + <el-table-column prop="column7" label="选项6" /> | |
299 | + <el-table-column prop="column8" label="选项7" /> | |
300 | + <el-table-column prop="column9" label="选项8" /> | |
301 | + <el-table-column prop="column10" label="选项9" /> | |
302 | + <el-table-column prop="column11" label="选项10" /> | |
303 | + </el-table> | |
304 | + </el-row> | |
305 | + <el-row class="row-subfix"> | |
306 | + <el-table class="default-table" style="margin-top: 10px" | |
307 | + :data="testTranscript.questionTotal || []"> | |
308 | + <el-table-column prop="quesion" label="题号" width="120" /> | |
309 | + <el-table-column prop="anwser" label="答案" width="120" /> | |
310 | + <el-table-column prop="student" label="答错学生"> | |
311 | + <template slot-scope="scoped"> | |
312 | + <span>总计 <span style="color:red;"> | |
313 | + {{ scoped.row.missPeopleNumber }}</span> 人 | |
314 | + </span> | |
315 | + <span style="margin: 10px 0;" | |
316 | + v-for="(item, index) in scoped.row.details.filter(item => !item.right)"> | |
317 | + 选{{ item.option }}:{{ item.students.join("/") }} | |
318 | + </span> | |
319 | + <span></span> | |
320 | + </template> | |
321 | + </el-table-column> | |
322 | + </el-table> | |
323 | + </el-row> | |
324 | + </div> | |
325 | + </div> | |
326 | + </div> | |
327 | + </div> | |
328 | + | |
101 | 329 | </el-tab-pane> |
102 | 330 | <el-tab-pane :name="'班级对比情况'" :label="`班级对比情况`" style="padding: 0 20px"> |
103 | 331 | <div style="float: right;margin-bottom: 20px;"> |
104 | - <el-button type="primary" class="opration-btn" icon="el-icon-upload2">导出报表</el-button> | |
105 | - <el-button type="primary" class="opration-btn" icon="el-icon-printer">打印报表</el-button> | |
332 | + <el-button @click="_studentLevelSet" class="green-el-button" type="primary"> | |
333 | + 设置学生成绩等级 | |
334 | + </el-button> | |
335 | + <el-button @click="_import" type="primary" class="opration-btn" icon="el-icon-upload2">导出报表</el-button> | |
336 | + <el-button @click="_print" type="primary" class="opration-btn" icon="el-icon-printer">打印报表</el-button> | |
106 | 337 | </div> |
107 | 338 | <el-table class="default-table" :data="classdiffExamReport"> |
108 | - <el-table-column prop="index" label="序号" width="120" /> | |
109 | - <el-table-column prop="className" label="班级" width="120" /> | |
110 | - <el-table-column label="测验人数/班级人数"> | |
339 | + <el-table-column prop="index" label="序号" width="60" /> | |
340 | + <el-table-column prop="className" label="班级" width="80" /> | |
341 | + <el-table-column label="测验人数/班级人数" width="180"> | |
111 | 342 | <template slot-scope="scoped"> |
112 | 343 | {{ scoped.row.testCount }} / {{ scoped.row.classCount }} |
113 | 344 | </template> |
114 | 345 | </el-table-column> |
115 | - <el-table-column prop="title" label="参与度" width="120"> | |
346 | + <el-table-column prop="title" label="参与度" width="100"> | |
116 | 347 | <template slot-scope="scoped"> |
117 | - {{ scoped.row.testCount / scoped.row.classCount }} | |
348 | + {{ Number(scoped.row.testCount * 100 / scoped.row.classCount).toFixed(2) }}% | |
118 | 349 | </template> |
119 | 350 | </el-table-column> |
120 | - <el-table-column prop="avg" label="班平均分" width="120" /> | |
121 | - <el-table-column prop="hight" label="班最高分" width="120" /> | |
122 | - <el-table-column prop="low" label="班最低分" width="120" /> | |
351 | + <el-table-column prop="avg" label="班平均分" width="100" /> | |
352 | + <el-table-column prop="hight" label="班最高分" width="100" /> | |
353 | + <el-table-column prop="low" label="班最低分" width="100" /> | |
123 | 354 | <el-table-column prop="front20" label="前20名均分" width="120" /> |
124 | 355 | <el-table-column prop="last20" label="后20名均分" width="120" /> |
125 | - <el-table-column prop="excellenRate" label="优秀数(率)" width="120"> | |
356 | + <el-table-column v-for="(item, index) in defaultLevels.levels" :key="index" | |
357 | + :label="item[0] ? item[0] + '数(率)' : ''"> | |
358 | + <template slot-scope="scoped"> | |
359 | + {{ scoped.row.leverValues[item[0]] }} | |
360 | + </template> | |
361 | + </el-table-column> | |
362 | + <!-- <el-table-column prop="excellenRate" label="优秀数(率)" width="120"> | |
126 | 363 | <template slot-scope="scoped"> |
127 | 364 | {{ scoped.row.excellenRate }}% |
128 | 365 | </template> |
... | ... | @@ -141,35 +378,77 @@ |
141 | 378 | <template slot-scope="scoped"> |
142 | 379 | {{ scoped.row.passRate }}% |
143 | 380 | </template> |
144 | - </el-table-column> | |
381 | + </el-table-column> --> | |
145 | 382 | </el-table> |
146 | 383 | </el-tab-pane> |
147 | 384 | <el-tab-pane :name="'试题分析表'" :label="`试题分析表`" style="padding: 0 20px"> |
148 | 385 | <div style="float: right;margin-bottom: 20px;"> |
149 | - <el-button type="primary" class="opration-btn" icon="el-icon-upload2">导出报表</el-button> | |
150 | - <el-button type="primary" class="opration-btn" icon="el-icon-printer">打印报表</el-button> | |
386 | + 单题低分率 | |
387 | + <el-input-number class="parent-number" v-model="lowLevel" :min="1" :max="100" label="低分率"> | |
388 | + </el-input-number> | |
389 | + <el-button @click="_import" type="primary" style="margin-left:10px" class="opration-btn" | |
390 | + icon="el-icon-upload2">导出报表</el-button> | |
391 | + <el-button @click="_print" type="primary" class="opration-btn" icon="el-icon-printer">打印报表</el-button> | |
151 | 392 | </div> |
152 | - <el-table class="default-table" :data="testPaperExamReport"> | |
393 | + <el-table class="default-table" :data="testPaperExamReport" :span-method="arraySpanMethod"> | |
153 | 394 | <el-table-column prop="questionIndex" label="题号" width="120" /> |
154 | 395 | <el-table-column prop="questionType" label="题型" width="100"> |
155 | 396 | <template slot-scope="scope"> |
156 | 397 | {{ setSubPro(scope.row.questionType) }} |
157 | 398 | </template> |
158 | 399 | </el-table-column> |
159 | - <el-table-column prop="score" label="知识点" /> | |
160 | - <el-table-column prop="score" label="满分值" width="120" /> | |
161 | - <el-table-column prop="avgScore" label="年级平均分" width="120" /> | |
162 | - <el-table-column prop="gradeScoringRate" label="年级得分率" width="120" /> | |
400 | + <el-table-column prop="knowledge" label="知识点"> | |
401 | + <template slot-scope="scoped"> | |
402 | + <el-tooltip effect="dark" :content="scoped.row.knowledge" placement="left"> | |
403 | + <span class="overflowText"> | |
404 | + {{ scoped.row.knowledge }} | |
405 | + </span> | |
406 | + </el-tooltip> | |
407 | + </template> | |
408 | + </el-table-column> | |
409 | + <el-table-column prop="score" label="满分值" width="120"> | |
410 | + <template slot-scope="scoped"> | |
411 | + <div v-if="scoped.row.type == 'colspan'"> | |
412 | + {{ Number(scoped.row.score).toFixed(2) }} | |
413 | + </div> | |
414 | + <div v-else> | |
415 | + {{ scoped.row.score }} | |
416 | + </div> | |
417 | + </template> | |
418 | + </el-table-column> | |
419 | + <el-table-column prop="avgScore" label="年级平均分" width="120"> | |
420 | + <template slot-scope="scoped"> | |
421 | + <div v-if="scoped.row.type == 'colspan' && scoped.row.questionType != '客观题'" | |
422 | + :class="Number(scoped.row.avgScore) < lowLevel ? 'lowLevelClass' : ''"> | |
423 | + {{ Number(scoped.row.avgScore).toFixed(2) }} % | |
424 | + </div> | |
425 | + <div v-else> | |
426 | + {{ scoped.row.avgScore }} | |
427 | + </div> | |
428 | + </template> | |
429 | + </el-table-column> | |
430 | + <el-table-column prop="gradeScoringRate" label="年级得分率" width="120"> | |
431 | + <template slot-scope="scoped"> | |
432 | + <div v-if="scoped.row.type == 'colspan'" | |
433 | + :class="scoped.row.gradeScoringRate < lowLevel ? 'lowLevelClass' : ''"> | |
434 | + {{ scoped.row.gradeScoringRate }} % | |
435 | + </div> | |
436 | + <div v-else="scoped.row.gradeScoringRate" | |
437 | + :class="Number(scoped.row.gradeScoringRate * 100) < lowLevel ? 'lowLevelClass' : ''"> | |
438 | + {{ Number(scoped.row.gradeScoringRate * 100).toFixed(2) }} % | |
439 | + </div> | |
440 | + </template> | |
441 | + </el-table-column> | |
163 | 442 | <el-table-column prop="correctAnswer" label="答案" width="120" /> |
164 | - <el-table-column v-for="(item, index) in testPaperExamReportOptions" :key="index" :label="item.title" | |
443 | + <el-table-column v-for="( item, index ) in testPaperExamReportOptions " :key="index" :label="item.title" | |
165 | 444 | :prop="'count' + index" width="120"> |
166 | 445 | <template slot-scope="scope"> |
167 | 446 | <p class="persent"> |
168 | 447 | {{ |
169 | - scope.row.questionType == "5" | |
448 | + scope.row["option" + index] == "?" ? "未答" : scope.row.questionType == "5" | |
170 | 449 | ? "" |
171 | 450 | : scope.row["option" + index] |
172 | - ? `${scope.row["option" + index]}(${scope.row["persent" + index] ?? "0" | |
451 | + ? `${scope.row["option" + index]} (${scope.row["persent" + index] ?? "0" | |
173 | 452 | })` |
174 | 453 | : "" |
175 | 454 | }} |
... | ... | @@ -180,40 +459,139 @@ |
180 | 459 | </el-tab-pane> |
181 | 460 | <el-tab-pane :name="'学生成绩排行'" :label="`学生成绩排行`" style="padding: 0 20px"> |
182 | 461 | <div style="float: right;margin-bottom: 20px;"> |
183 | - <el-button type="primary" class="opration-btn" icon="el-icon-upload2">导出报表</el-button> | |
184 | - <el-button type="primary" class="opration-btn" icon="el-icon-printer">打印报表</el-button> | |
462 | + <el-button @click="_import" type="primary" class="opration-btn" icon="el-icon-upload2">导出报表</el-button> | |
463 | + <el-button @click="_print" type="primary" class="opration-btn" icon="el-icon-printer">打印报表</el-button> | |
185 | 464 | </div> |
186 | 465 | <el-table class="default-table" style="margin-top: 10px" :data="testStudentExamReport"> |
187 | - <el-table-column prop="gradeRank" label="年级排行" /> | |
466 | + <el-table-column prop="gradeRank" label="年级排名" /> | |
188 | 467 | <el-table-column prop="code" label="学号" /> |
189 | 468 | <el-table-column prop="name" label="姓名" /> |
190 | 469 | <el-table-column prop="className" label="班级" /> |
191 | 470 | <el-table-column prop="exam" label="分数" /> |
192 | - <el-table-column prop="title" label="成绩等级" /> | |
471 | + <el-table-column prop="lever" label="成绩等级" /> | |
193 | 472 | </el-table> |
194 | 473 | </el-tab-pane> |
474 | + | |
195 | 475 | </el-tabs> |
196 | 476 | </div> |
197 | 477 | </el-main> |
478 | + <el-dialog :append-to-body="true" :close-on-click-modal="false" title="学生等级设置" :visible.sync="studentLevelDialog" | |
479 | + width="900px" @closed="_studentLevelClose"> | |
480 | + <el-container class="default-body" style="background: transparent !important;"> | |
481 | + <el-main> | |
482 | + <div class="default-main"> | |
483 | + <el-form class="use-form"> | |
484 | + <el-form-item class="use-form-item-box"> | |
485 | + <el-form-item label="等级设置模式" class="use-form-item"> | |
486 | + <el-select size="small" v-model="fromData.levelType"> | |
487 | + <el-option label="按分数比例" :value="0"></el-option> | |
488 | + <el-option label="按已考人数比例" :value="1"></el-option> | |
489 | + </el-select> | |
490 | + </el-form-item> | |
491 | + </el-form-item> | |
492 | + <el-form-item> | |
493 | + <div class="dia-tab-box"> | |
494 | + <p class="dia-tab-tit"> | |
495 | + <span class="item1 boxitem">序号</span> | |
496 | + <span class="item2 boxitem"><i>*</i>等级名称</span> | |
497 | + <span class="item3 boxitem"><i>*</i>等级最高</span> | |
498 | + <span class="item3 boxitem"><i>*</i>等级最低</span> | |
499 | + <span class="item boxitem">操作</span> | |
500 | + </p> | |
501 | + <div class="dia-tab-item" v-for="(item, index) in fromData.levels" :key="index"> | |
502 | + <span class="item1 boxitem">{{ index + 1 }}</span> | |
503 | + <p class="item2 boxitem"> | |
504 | + <el-input class="score-ipt" v-model="item[0]" :maxlength="12" | |
505 | + @keydown.native="keydownRange($event)"></el-input> | |
506 | + </p> | |
507 | + <p class="item3 boxitem"> | |
508 | + <el-input class="score-ipt" type="number" v-model="item[1]" :min="item[2]" | |
509 | + :max="index == 0 ? 100 : fromData.levels[index - 1][2]" | |
510 | + @keydown.native="keydownRange($event)"></el-input> | |
511 | + <span class="descption"> | |
512 | + % | |
513 | + <template v-if="fromData.levelType == 0"> | |
514 | + ( | |
515 | + {{ index != 0 ? "不含" : "" }} | |
516 | + {{ Number(((item[1] / 100) * examPaperScore).toFixed(1)) }}分 | |
517 | + ) | |
518 | + </template> | |
519 | + <template v-else>{{ index != 0 ? "不含" : "" }}</template> | |
520 | + </span> | |
521 | + </p> | |
522 | + <p class="item3 boxitem"> | |
523 | + <el-input class="score-ipt" type="number" v-model="item[2]" :min="0" :max="item[1]" | |
524 | + @keydown.native="keydownRange($event)"></el-input> | |
525 | + <span class="descption"> | |
526 | + % | |
527 | + <template v-if="fromData.levelType == 0"> | |
528 | + ({{ Number(((item[2] / 100) * examPaperScore).toFixed(1)) }}分) | |
529 | + </template> | |
530 | + </span> | |
531 | + </p> | |
532 | + <p class="item boxitem"> | |
533 | + <el-link type="danger" :underline="false" @click="fromData.levels.splice(index, 1)">删除</el-link> | |
534 | + </p> | |
535 | + </div> | |
536 | + <div class="add"> | |
537 | + <p @click="fromData.levels.push(['', '', ''])"> | |
538 | + <el-button size="mini" icon="el-icon-plus" circle type="primary"></el-button>添加一行 | |
539 | + </p> | |
540 | + </div> | |
541 | + </div> | |
542 | + </el-form-item> | |
543 | + </el-form> | |
544 | + </div> | |
545 | + </el-main> | |
546 | + </el-container> | |
547 | + <div class="dialog-footer" slot="footer" align="right"> | |
548 | + <el-button type="info" :size="'small'" @click="studentLevelDialog = false">取 消</el-button> | |
549 | + <el-button type="primary" class="green-el-button" :size="'small'" @click="_savefrom">保存</el-button> | |
550 | + </div> | |
551 | + </el-dialog> | |
198 | 552 | </el-container> |
199 | 553 | </template> |
200 | 554 | |
201 | 555 | <script> |
556 | +import { formatDate, downloadFile, tablePrint } from "utils"; | |
202 | 557 | export default { |
203 | 558 | data() { |
204 | 559 | return { |
560 | + studentLevelDialog: false, | |
205 | 561 | checkAll: true, |
206 | 562 | isIndeterminate: true, |
207 | 563 | title: "", |
564 | + defaultLevels: [], | |
208 | 565 | paperId: null, |
566 | + lowLevel: 20, | |
567 | + anyLowLevel: 20, | |
209 | 568 | classInfos: [], |
569 | + examIds: [], | |
570 | + testTranscriptDatas: [], | |
571 | + testTranscript: { | |
572 | + titleInfo: [], | |
573 | + studentList: [], | |
574 | + studentHeader: [], | |
575 | + question4List: [], | |
576 | + question7List: [], | |
577 | + question10List: [], | |
578 | + questionTotal: [], | |
579 | + }, | |
580 | + currentPage: 0, | |
581 | + totalPage: 0, | |
210 | 582 | checkedClassInfos: [], |
211 | 583 | queryLoading: false, |
212 | 584 | tabType: "0", |
213 | - testTranscriptCount: 0, | |
214 | - titleInfo: [], | |
215 | - studentList: [], | |
216 | - studentHeader: [], | |
585 | + examPaperScore: 100, //卷面最高分 | |
586 | + fromData: { | |
587 | + levelType: 0, | |
588 | + levels: [ | |
589 | + ["优秀", 100, 90], | |
590 | + ["良好", 89.9, 70], | |
591 | + ["合格", 69.9, 60], | |
592 | + ["不合格", 59.9, 0], | |
593 | + ], | |
594 | + }, | |
217 | 595 | studentMapping: [ |
218 | 596 | { |
219 | 597 | key: "code", |
... | ... | @@ -240,11 +618,6 @@ export default { |
240 | 618 | label: "主观分", |
241 | 619 | }, |
242 | 620 | ], |
243 | - questionList: [], | |
244 | - questionHeaders: [], | |
245 | - questionOtherList: [], | |
246 | - questionOtherHeaders: [], | |
247 | - questionTotal: [], | |
248 | 621 | testPaperExamReport: [], |
249 | 622 | testPaperExamReportOptions: [], |
250 | 623 | testStudentExamReport: [], |
... | ... | @@ -252,12 +625,40 @@ export default { |
252 | 625 | }; |
253 | 626 | }, |
254 | 627 | watch: { |
255 | - async tabType(value) { | |
256 | - console.log(value); | |
257 | - this.checkedClassInfos = this.classInfos; | |
258 | - switch (value) { | |
628 | + async tabType() { | |
629 | + await this._anys(); | |
630 | + }, | |
631 | + async checkedClassInfos(value) { | |
632 | + if (value?.length >= 1) { | |
633 | + this.currentPage = 1; | |
634 | + this.totalPage = value.length; | |
635 | + } else { | |
636 | + this.currentPage = 0; | |
637 | + this.totalPage = 0; | |
638 | + } | |
639 | + this.tabType = '成绩测验单'; | |
640 | + this.checkAll = value.length >= this.classInfos.length; | |
641 | + await this._anys(); | |
642 | + }, | |
643 | + async currentPage(value) { | |
644 | + await this._testExamReport(value - 1); | |
645 | + } | |
646 | + }, | |
647 | + async created() { | |
648 | + this.title = this.$route.query.title || ""; | |
649 | + this.paperId = this.$route.query.paperId; | |
650 | + this.classInfos = JSON.parse(this.$route.query.classListStr); | |
651 | + this.examIds = this.$route.query.examIds.split(',') || []; | |
652 | + this.checkedClassInfos = this.classInfos?.map(item => item.classId); | |
653 | + this.tabType = "成绩测验单"; | |
654 | + await this._queryDefaultLevels(); | |
655 | + }, | |
656 | + methods: { | |
657 | + async _anys() { | |
658 | + this.queryLoading = true; | |
659 | + switch (this.tabType) { | |
259 | 660 | case "成绩测验单": |
260 | - await this._testExamReport(); | |
661 | + await this._testExamReport(0); | |
261 | 662 | break; |
262 | 663 | case "班级对比情况": |
263 | 664 | await this._classdiffExamReport(); |
... | ... | @@ -269,28 +670,200 @@ export default { |
269 | 670 | await this._testStudentExamReport(); |
270 | 671 | break; |
271 | 672 | } |
673 | + this.queryLoading = false; | |
272 | 674 | }, |
273 | - }, | |
274 | - async created() { | |
275 | - this.title = this.$route.query.title || ""; | |
675 | + async _queryDefaultLevels() { | |
276 | 676 | |
277 | - this.paperId = this.$route.query.paperId; | |
677 | + const { data, info, status } = await this.$request.gdefaultLevels(); | |
278 | 678 | |
279 | - this.classInfos = JSON.parse(this.$route.query.classListStr); | |
679 | + if (status != 0) { | |
680 | + this.$message.error(info); | |
681 | + return; | |
682 | + } | |
280 | 683 | |
281 | - this.checkedClassInfos = this.classInfos; | |
684 | + this.defaultLevels = { ...data } || { | |
685 | + levelType: 0, | |
686 | + levels: [ | |
687 | + ["优秀", 100, 90], | |
688 | + ["良好", 89.9, 70], | |
689 | + ["合格", 69.9, 60], | |
690 | + ["不合格", 59.9, 0], | |
691 | + ], | |
692 | + }; | |
282 | 693 | |
283 | - this.tabType = "成绩测验单"; | |
284 | - }, | |
285 | - methods: { | |
694 | + this.defaultLevels.type = 0 | |
695 | + | |
696 | + this.fromData.levelType = this.defaultLevels.levelType; | |
697 | + | |
698 | + this.fromData.levels = [...this.defaultLevels.levels]; | |
699 | + | |
700 | + sessionStorage.setItem( | |
701 | + "levelFromData", | |
702 | + JSON.stringify(this.defaultLevels) | |
703 | + ); | |
704 | + }, | |
705 | + async _savefrom() { | |
706 | + for (let i = 0; i < this.fromData.levels.length; i++) { | |
707 | + if (this.fromData.levels[i].includes("")) { | |
708 | + this.$message.warning("请补全编号" + (i + 1) + "设置信息!"); | |
709 | + return; | |
710 | + } | |
711 | + } | |
712 | + if (this.fromData.levels.length == 0) { | |
713 | + this.$message.warning("请添加等级设置!"); | |
714 | + return; | |
715 | + } | |
716 | + let nums = []; | |
717 | + let ERR_OK = false; | |
718 | + this.fromData.levels.map((item) => { | |
719 | + nums.push(Number(item[1])); | |
720 | + nums.push(Number(item[2])); | |
721 | + }); | |
722 | + for (let i = 0; i < nums.length; i++) { | |
723 | + if (nums[i + 1] && nums[i + 1] > nums[i]) { | |
724 | + ERR_OK = true; | |
725 | + this.$message.warning("高等级比例不能低于低等级比例!请检查"); | |
726 | + break; | |
727 | + } | |
728 | + } | |
729 | + if (ERR_OK) return; | |
730 | + this.tableData = []; | |
731 | + this.tableData2 = []; | |
732 | + this.defaultLevels.type = this.fromData.type; | |
733 | + this.defaultLevels.levelType = this.fromData.levelType; | |
734 | + this.defaultLevels.levels = [...this.fromData.levels]; | |
735 | + sessionStorage.setItem("levelFromData", JSON.stringify(this.fromData)); | |
736 | + this.studentLevelDialog = false; | |
737 | + await this._anys(); | |
738 | + // await this._classdiffExamReport(); | |
739 | + }, | |
740 | + _studentLevelSet() { | |
741 | + this.studentLevelDialog = true; | |
742 | + }, | |
743 | + _studentLevelClose() { | |
744 | + let levelFromData = sessionStorage.getItem("levelFromData"); | |
745 | + if (levelFromData) { | |
746 | + levelFromData = JSON.parse(levelFromData); | |
747 | + this.fromData.type = levelFromData.type; | |
748 | + this.fromData.levelType = levelFromData.levelType; | |
749 | + this.fromData.levels = [...levelFromData.levels]; | |
750 | + } else { | |
751 | + this.fromData.type = 0; | |
752 | + this.fromData.levelType = this.defaultLevels.levelType; | |
753 | + this.fromData.levels = [...this.defaultLevels.levels]; | |
754 | + } | |
755 | + }, | |
756 | + arraySpanMethod({ row, column, rowIndex, columnIndex }) { | |
757 | + if (rowIndex == this.testPaperExamReport?.length - 3) { | |
758 | + if (columnIndex == 0) { | |
759 | + return [3, 1]; | |
760 | + } | |
761 | + else if (columnIndex == 6) { | |
762 | + return [3, 1]; | |
763 | + } | |
764 | + else if (columnIndex == 7) { | |
765 | + return [3, 5]; | |
766 | + } | |
767 | + else { | |
768 | + return [1, 1] | |
769 | + } | |
770 | + } | |
771 | + else { | |
772 | + return [1, 1] | |
773 | + } | |
774 | + | |
775 | + }, | |
776 | + keydownRange(event) { | |
777 | + if (event.key == "-" || event.key == "e") { | |
778 | + event.returnValue = ""; | |
779 | + } | |
780 | + }, | |
781 | + _changePage(status) { | |
782 | + if (status == "next") { | |
783 | + if (this.currentPage < this.checkedClassInfos.length) { | |
784 | + this.currentPage += 1; | |
785 | + } | |
786 | + } | |
787 | + else if (status == "prev") { | |
788 | + if (this.currentPage > 1) { | |
789 | + this.currentPage -= 1; | |
790 | + } | |
791 | + } | |
792 | + else { | |
793 | + this.$message.error('异常操作'); | |
794 | + } | |
795 | + }, | |
286 | 796 | _handleCheckAllChange(val) { |
287 | - // this.checkedClassInfos = val ? this.classInfos : []; | |
288 | - // this.isIndeterminate = false; | |
797 | + this.checkAll = val; | |
798 | + if (val) this.checkedClassInfos = this.classInfos.map(item => item.classId); | |
799 | + else this.checkedClassInfos = []; | |
289 | 800 | }, |
290 | 801 | _handleCheckedClassChange(value) { |
291 | - // let checkedCount = value.length; | |
292 | - // this.checkAll = checkedCount === this.cities.length; | |
293 | - // this.isIndeterminate = checkedCount > 0 && checkedCount < this.cities.length; | |
802 | + | |
803 | + }, | |
804 | + async _print() { | |
805 | + if (this.tabType == '成绩测验单') { | |
806 | + if (this.checkedClassInfos.length <= 0) { | |
807 | + this.$message.error('请选中班级'); | |
808 | + return; | |
809 | + } | |
810 | + | |
811 | + this.testTranscriptDatas = []; | |
812 | + for (var page = 0; page < this.checkedClassInfos.length; page++) { | |
813 | + this.testTranscriptDatas.push(await this._testExamReport(page)); | |
814 | + } | |
815 | + setTimeout(() => { | |
816 | + tablePrint("test-print", this.tabType); | |
817 | + }, 500); | |
818 | + } | |
819 | + else { | |
820 | + tablePrint("print-content", this.tabType); | |
821 | + } | |
822 | + }, | |
823 | + async _import() { | |
824 | + let importRequest; | |
825 | + switch (this.tabType) { | |
826 | + case "成绩测验单": { | |
827 | + importRequest = this.$request.tgexportPhaseExamReport; | |
828 | + } break; | |
829 | + case "班级对比情况": { | |
830 | + importRequest = this.$request.tgexportPhaseExamReport2; | |
831 | + } break; | |
832 | + case "试题分析表": { | |
833 | + importRequest = this.$request.tgexportPhaseExamReport3; | |
834 | + } break; | |
835 | + case "学生成绩排行": { | |
836 | + importRequest = this.$request.tgexportPhaseExamReport4; | |
837 | + } break; | |
838 | + } | |
839 | + | |
840 | + let paramObj = JSON.parse(JSON.stringify(this.fromData)) | |
841 | + | |
842 | + if (paramObj.levelType == 0) { | |
843 | + paramObj.levels = paramObj.levels.map((item) => { | |
844 | + item[1] = ((item[1] / 100) * this.examPaperScore).toFixed(1); | |
845 | + item[2] = ((item[2] / 100) * this.examPaperScore).toFixed(1); | |
846 | + return item; | |
847 | + }); | |
848 | + } | |
849 | + var data = await importRequest({ | |
850 | + paperId: this.paperId, | |
851 | + classIds: this.checkedClassInfos ?? [], | |
852 | + examIds: this.classInfos. | |
853 | + filter(item => | |
854 | + this.checkedClassInfos.includes(item.classId)).map(ida => ida.examId), | |
855 | + reportRange: paramObj | |
856 | + }) | |
857 | + | |
858 | + if (data) { | |
859 | + let blob = new Blob([data], { | |
860 | + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | |
861 | + }); | |
862 | + | |
863 | + downloadFile(this.tabType + ".xlsx", blob); | |
864 | + } else { | |
865 | + this.$message.error("下载失败"); | |
866 | + } | |
294 | 867 | }, |
295 | 868 | _detailQ(id) { }, |
296 | 869 | setSubPro(type) { |
... | ... | @@ -309,19 +882,33 @@ export default { |
309 | 882 | tit = "主观题"; |
310 | 883 | break; |
311 | 884 | default: |
312 | - tit = "其他"; | |
885 | + tit = type; | |
313 | 886 | } |
314 | 887 | return tit; |
315 | 888 | }, |
316 | - async _testExamReport() { | |
889 | + async _testExamReport(page, type) { | |
890 | + let demoTestTranscript = { | |
891 | + titleInfo: [], | |
892 | + studentList: [], | |
893 | + studentHeader: [], | |
894 | + question4List: [], | |
895 | + question7List: [], | |
896 | + question10List: [], | |
897 | + questionTotal: [], | |
898 | + }; | |
899 | + | |
900 | + if (type != 1) { | |
901 | + this.testTranscript = demoTestTranscript; | |
902 | + } | |
317 | 903 | |
318 | - this.questionTotal = []; | |
904 | + | |
905 | + if (!this.checkedClassInfos || this.checkedClassInfos?.length <= 0) return; | |
319 | 906 | |
320 | 907 | const request = this.$request.gTestExamReport; |
321 | 908 | |
322 | 909 | let response = await request({ |
323 | 910 | paperId: this.paperId, |
324 | - classIds: this.checkedClassInfos.map((item) => item.classId), | |
911 | + classIds: [this.checkedClassInfos[page]], | |
325 | 912 | }); |
326 | 913 | |
327 | 914 | if (response.status != 0) { |
... | ... | @@ -329,8 +916,8 @@ export default { |
329 | 916 | return; |
330 | 917 | } |
331 | 918 | |
332 | - this.titleInfo = response.data.titleInfos; | |
333 | - console.log(this.titleInfo) | |
919 | + demoTestTranscript.titleInfo = response.data.titleInfos; | |
920 | + | |
334 | 921 | var studentHeaders = []; |
335 | 922 | |
336 | 923 | var studentResults = []; |
... | ... | @@ -349,7 +936,7 @@ export default { |
349 | 936 | } |
350 | 937 | } |
351 | 938 | |
352 | - this.studentHeader = [...studentHeaders]; | |
939 | + demoTestTranscript.studentHeader = [...studentHeaders]; | |
353 | 940 | |
354 | 941 | for (var isp = 0; isp < response.data.gradeExamStudentReports.length; isp++) { |
355 | 942 | |
... | ... | @@ -379,230 +966,321 @@ export default { |
379 | 966 | studentResults.push(item); |
380 | 967 | } |
381 | 968 | |
382 | - this.studentList = [...studentResults]; | |
969 | + demoTestTranscript.studentList = [...studentResults]; | |
383 | 970 | |
384 | - var otherDatas = []; | |
971 | + var show4Area = true; //显示4选项区域 | |
385 | 972 | |
386 | - var questionHeaders = []; | |
973 | + var show7Area = true; //显示7选项区域 | |
387 | 974 | |
388 | - var questionResults = []; | |
975 | + var show10Area = true; //显示10选项区域 | |
389 | 976 | |
390 | - var questionOtherHeaders = []; | |
977 | + var optionNumList = []; | |
391 | 978 | |
392 | - var questionOtherResults = []; | |
979 | + var maxOptions = 4; | |
393 | 980 | |
394 | - var defaultQuestion = 6; | |
981 | + var minOptions = 10; //最多10个选项 | |
395 | 982 | |
396 | - var defaultCount = 3; | |
983 | + var questionList = response.data.questionInfos; | |
397 | 984 | |
398 | - var defaultQuestionCount = 4; | |
985 | + questionList = questionList.sort((prev, next) => { return prev.questionIndex - next.questionIndex }); | |
399 | 986 | |
400 | - var maxQuestionCount = 4; | |
987 | + for (var i = 0; i < questionList.length; i++) { | |
401 | 988 | |
402 | - var optionSt = 1; | |
989 | + var correctAnswerValue = questionList[i].correctAnswer == "1" ? "✓" : questionList[i].correctAnswer == 2 ? "✗" : questionList[i].correctAnswer; | |
403 | 990 | |
404 | - for (var qheader = 0; qheader < defaultQuestion * defaultCount; qheader++) { | |
405 | - if (qheader == 0 || qheader % 6 == 0) { | |
406 | - questionHeaders.push({ | |
407 | - prop: "column_" + qheader, | |
408 | - label: "题号&答案", | |
409 | - }); | |
410 | - continue; | |
411 | - } else if (qheader == 1 || (qheader - 1) % 6 == 0) { | |
412 | - questionHeaders.push({ | |
413 | - prop: "column_" + qheader, | |
414 | - label: "得分率", | |
415 | - }); | |
416 | - optionSt = 1; | |
417 | - continue; | |
418 | - } else { | |
419 | - questionHeaders.push({ | |
420 | - prop: "column_" + qheader, | |
421 | - label: "选项" + optionSt, | |
422 | - }); | |
423 | - optionSt += 1; | |
991 | + var missCount = 0; | |
992 | + | |
993 | + var missI = questionList[i].details.filter(item => !item.right); | |
994 | + | |
995 | + missI.forEach(itemsa => { | |
996 | + missCount = Number(missCount) + Number(itemsa.students?.length ?? 0) | |
997 | + }); | |
998 | + | |
999 | + demoTestTranscript.questionTotal.push({ | |
1000 | + quesion: "Q" + (questionList[i].questionIndex), | |
1001 | + anwser: correctAnswerValue ?? "-----", | |
1002 | + details: questionList[i].details, | |
1003 | + missPeopleNumber: missCount | |
1004 | + }) | |
1005 | + if ((questionList[i].questionType == 2)) { | |
1006 | + //单选题可能有超过4个选项,多选题是固定的 | |
1007 | + if (questionList[i].details?.length > maxOptions) { | |
1008 | + maxOptions = questionList[i].details.filter(iam => { return iam.option.indexOf('未答') < 0 })?.length; | |
1009 | + } | |
1010 | + //单选题可能有超过4个选项,多选题是固定的 | |
1011 | + if (questionList[i].details?.length < minOptions) { | |
1012 | + minOptions = questionList[i].details.filter(iam => { return iam.option.indexOf('未答') < 0 })?.length; | |
1013 | + } | |
1014 | + | |
1015 | + optionNumList.push(questionList[i].details.filter(iam => { return iam.option.indexOf('未答') < 0 })?.length); | |
1016 | + } | |
1017 | + | |
1018 | + if (questionList[i].questionType == 4) { | |
1019 | + minOptions = 2; | |
1020 | + optionNumList.push(2); | |
424 | 1021 | } |
425 | 1022 | } |
426 | 1023 | |
427 | - var noPassIndex = 0; | |
1024 | + console.log(demoTestTranscript.questionTotal) | |
428 | 1025 | |
429 | - this.questionHeaders = questionHeaders; | |
1026 | + show4Area = minOptions <= 4; | |
430 | 1027 | |
431 | - var itema = null; | |
1028 | + show7Area = optionNumList.filter(o => o > 4 && o <= 7); | |
432 | 1029 | |
433 | - response.data.questionInfos = [...response.data.questionInfos] | |
1030 | + show10Area = optionNumList.filter(o => o > 7); | |
434 | 1031 | |
435 | - for (var qIndex = 0; qIndex < response.data.questionInfos.length; qIndex++) { | |
436 | 1032 | |
437 | - var currentData = response.data.questionInfos[qIndex]; | |
1033 | + var currentRow = {}; | |
438 | 1034 | |
439 | - var filterDetail = currentData.details.filter(fl => fl.option != '未答'); | |
1035 | + if (show4Area) { | |
440 | 1036 | |
441 | - var correctAnswerValue = currentData.correctAnswer == "1" ? "✓" : currentData.correctAnswer == 2 ? "✗" : currentData.correctAnswer; | |
1037 | + var areaList = []; | |
442 | 1038 | |
443 | - this.questionTotal.push({ | |
444 | - quesion: "Q" + (qIndex + 1), | |
445 | - anwser: correctAnswerValue ?? "-----", | |
446 | - details: currentData.details | |
447 | - }) | |
1039 | + var quesRow = Math.ceil(questionList?.length * 1.00 / 3); | |
448 | 1040 | |
449 | - if (filterDetail.length > defaultQuestionCount || filterDetail.length > maxQuestionCount) { | |
450 | - currentData.index = qIndex; | |
451 | - otherDatas.push(currentData); | |
452 | - if (filterDetail.length > maxQuestionCount) { | |
453 | - maxQuestionCount = filterDetail.length; | |
454 | - } | |
455 | - continue; | |
1041 | + for (var irow = 0; irow < quesRow; irow++) { | |
1042 | + areaList.push({}); | |
456 | 1043 | } |
457 | - else { | |
458 | - if (noPassIndex > defaultCount) { | |
459 | - questionResults.push(itema) | |
460 | - itema = null; | |
461 | - noPassIndex = 0; | |
462 | - } | |
463 | - var stPass = noPassIndex * defaultQuestion; | |
464 | - if (!itema) itema = {} | |
465 | 1044 | |
466 | - var correctAnswerValue = currentData.correctAnswer == "1" ? "✓" : currentData.correctAnswer == 2 ? "✗" : currentData.correctAnswer; | |
1045 | + for (var i = 0; i < questionList?.length; i++) { | |
467 | 1046 | |
468 | - itema["column_" + (stPass)] = (qIndex + 1) + "" + correctAnswerValue; | |
469 | - itema["column_" + (stPass + 1)] = (currentData.gradeScoringRate * 100) + "%"; | |
1047 | + var col = parseInt(i / quesRow); | |
470 | 1048 | |
471 | - var value = "------"; | |
1049 | + var row = parseInt(i % quesRow); | |
472 | 1050 | |
473 | - for (var iOption = 0; iOption < defaultQuestion - 2; iOption++) { | |
474 | - var currentOption = filterDetail[iOption]; | |
475 | - if (currentOption) { | |
476 | - var optionValue = currentOption.option == "1" ? "✓" : currentOption.option == 2 ? "✗" : currentOption.option; | |
1051 | + var question = questionList[i]; | |
477 | 1052 | |
478 | - itema["column_" + (stPass + iOption + 2)] = optionValue + "(" + (currentOption.persent ?? "0%") + ")"; | |
1053 | + var currentRow = areaList[row]; | |
1054 | + | |
1055 | + var correctAnswerValue = question.correctAnswer == "1" ? "✓" : question.correctAnswer == 2 ? "✗" : question.correctAnswer; | |
1056 | + | |
1057 | + var details = question.details.filter(fl => { | |
1058 | + return fl.option.indexOf('未答') < 0; | |
1059 | + }); | |
1060 | + | |
1061 | + | |
1062 | + for (var ilr = 0; ilr < 6; ilr++) { | |
1063 | + | |
1064 | + if (ilr == 0) { | |
1065 | + currentRow['column' + Number(6 * col + ilr)] = question.questionIndex + correctAnswerValue; | |
1066 | + } | |
1067 | + else if (ilr == 1) { | |
1068 | + currentRow['column' + Number(6 * col + ilr)] = (question.gradeScoringRate * 100).toFixed(2) + '%'; | |
479 | 1069 | } |
480 | 1070 | else { |
481 | - itema["column_" + (stPass + iOption + 2)] = value | |
1071 | + | |
1072 | + var questionDetail = details[ilr - 2]; | |
1073 | + | |
1074 | + var questionColumn = 'column' + Number(6 * col + ilr); | |
1075 | + | |
1076 | + if (details.length <= 4) { | |
1077 | + | |
1078 | + var questionOption = questionDetail ? (questionDetail.option == "1" ? "✓" : questionDetail.option == "2" ? "✗" : questionDetail.option) : "- -" | |
1079 | + | |
1080 | + if (questionOption != "- -") questionOption += "(" + questionDetail.persent + ")"; | |
1081 | + | |
1082 | + currentRow[questionColumn] = questionOption; | |
1083 | + } | |
1084 | + else { | |
1085 | + currentRow[questionColumn] = "--"; | |
1086 | + } | |
482 | 1087 | } |
483 | 1088 | } |
484 | - | |
485 | - noPassIndex += 1 | |
486 | 1089 | } |
487 | 1090 | |
488 | - if (qIndex >= response.data.questionInfos.length - 1 && noPassIndex != 0) { | |
489 | - questionResults.push(itema) | |
490 | - itema = null; | |
491 | - } | |
1091 | + demoTestTranscript.question4List = [...areaList] | |
1092 | + | |
492 | 1093 | } |
493 | 1094 | |
494 | - optionSt = 1; | |
495 | 1095 | |
496 | - maxQuestionCount += 2; | |
1096 | + if (show7Area && show7Area.length > -1) { | |
497 | 1097 | |
498 | - this.questionList = [...questionResults] | |
1098 | + var areaList = []; | |
499 | 1099 | |
500 | - var otherCount = parseInt(defaultQuestion * defaultCount / maxQuestionCount); | |
1100 | + var quesRow = Math.ceil(show7Area.length * 1.00 / 2); | |
501 | 1101 | |
502 | - itema = null; | |
1102 | + var num = 0; | |
503 | 1103 | |
504 | - for (var qOHeader = 0; qOHeader < maxQuestionCount * otherCount; qOHeader++) { | |
505 | - if (qOHeader == 0 || qOHeader % (maxQuestionCount) == 0) { | |
506 | - questionOtherHeaders.push({ | |
507 | - prop: "column_" + qOHeader, | |
508 | - label: "题号&答案", | |
509 | - }); | |
510 | - continue; | |
511 | - } else if (qOHeader == 1 || (qOHeader - 1) % (maxQuestionCount) == 0) { | |
512 | - questionOtherHeaders.push({ | |
513 | - prop: "column_" + qOHeader, | |
514 | - label: "得分率", | |
515 | - }); | |
516 | - optionSt = 1; | |
517 | - continue; | |
518 | - } else { | |
519 | - questionOtherHeaders.push({ | |
520 | - prop: "column_" + qOHeader, | |
521 | - label: "选项" + optionSt, | |
1104 | + for (var irow = 0; irow < quesRow; irow++) { | |
1105 | + areaList.push({}); | |
1106 | + } | |
1107 | + | |
1108 | + for (var i = 0; i < questionList?.length; i++) { | |
1109 | + | |
1110 | + var question = questionList[i]; | |
1111 | + | |
1112 | + var details = question.details.filter(fl => { | |
1113 | + return fl.option.indexOf('未答') < 0; | |
522 | 1114 | }); |
523 | - optionSt += 1; | |
1115 | + | |
1116 | + if (question.questionType == 2 && details.length > 4 && details.length <= 7) { | |
1117 | + | |
1118 | + var col = parseInt(num / quesRow); | |
1119 | + | |
1120 | + var row = parseInt(num % quesRow); | |
1121 | + | |
1122 | + var currentRow = areaList[row]; | |
1123 | + | |
1124 | + var correctAnswerValue = question.correctAnswer == "1" ? "✓" : question.correctAnswer == 2 ? "✗" : question.correctAnswer; | |
1125 | + | |
1126 | + for (var ilr = 0; ilr < 9; ilr++) { | |
1127 | + | |
1128 | + if (ilr == 0) { | |
1129 | + currentRow['column' + Number(9 * col + ilr)] = question.questionIndex + correctAnswerValue; | |
1130 | + } | |
1131 | + else if (ilr == 1) { | |
1132 | + currentRow['column' + Number(9 * col + ilr)] = (question.gradeScoringRate * 100).toFixed(2) + '%'; | |
1133 | + } | |
1134 | + else { | |
1135 | + | |
1136 | + var questionDetail = details[ilr - 2]; | |
1137 | + | |
1138 | + var questionColumn = 'column' + Number(9 * col + ilr); | |
1139 | + | |
1140 | + currentRow[questionColumn] = questionDetail ? questionDetail.option + "(" + questionDetail.persent + ")" : "- -"; | |
1141 | + } | |
1142 | + } | |
1143 | + | |
1144 | + num = num + 1; | |
1145 | + } | |
1146 | + | |
524 | 1147 | } |
1148 | + | |
1149 | + demoTestTranscript.question7List = [...areaList] | |
525 | 1150 | } |
526 | 1151 | |
527 | - this.questionOtherHeaders = questionOtherHeaders; | |
528 | 1152 | |
529 | - noPassIndex = 0; | |
1153 | + if (show10Area && show10Area.length > -1) { | |
530 | 1154 | |
531 | - for (var qOIndex = 0; qOIndex < otherDatas.length; qOIndex++) { | |
1155 | + var areaList = []; | |
532 | 1156 | |
533 | - var currentData = otherDatas[qOIndex]; | |
1157 | + var quesRow = show10Area.length; | |
534 | 1158 | |
535 | - var filterDetail = currentData.details.filter(fl => fl.option != '未答'); | |
1159 | + var num = 0; | |
536 | 1160 | |
537 | - if (noPassIndex >= otherCount) { | |
538 | - questionOtherResults.push(itema) | |
539 | - itema = null; | |
540 | - noPassIndex = 0; | |
1161 | + for (var irow = 0; irow < quesRow; irow++) { | |
1162 | + areaList.push({}); | |
541 | 1163 | } |
542 | 1164 | |
543 | - var stPass = noPassIndex * maxQuestionCount; | |
1165 | + for (var i = 0; i < questionList?.length; i++) { | |
544 | 1166 | |
545 | - if (!itema) itema = {} | |
1167 | + var question = questionList[i]; | |
546 | 1168 | |
547 | - var correctAnswerValue = currentData.correctAnswer == "1" ? "✓" : currentData.correctAnswer == 2 ? "✗" : currentData.correctAnswer; | |
1169 | + var details = question.details.filter(fl => { | |
1170 | + return fl.option.indexOf('未答') < 0; | |
1171 | + }); | |
548 | 1172 | |
549 | - itema["column_" + (stPass)] = (Number(currentData.index) + 1) + "" + correctAnswerValue; | |
1173 | + if (question.questionType == 2 && details.length > 7) { | |
1174 | + var col = parseInt(num / quesRow); | |
550 | 1175 | |
551 | - itema["column_" + (stPass + 1)] = (currentData.gradeScoringRate * 100) + "%"; | |
1176 | + var row = num; | |
552 | 1177 | |
553 | - var value = "------"; | |
1178 | + var currentRow = areaList[row]; | |
554 | 1179 | |
555 | - for (var iOption = 0; iOption < maxQuestionCount - 2; iOption++) { | |
1180 | + var correctAnswerValue = question.correctAnswer == "1" ? "✓" : question.correctAnswer == 2 ? "✗" : question.correctAnswer; | |
556 | 1181 | |
557 | - var currentOption = filterDetail[iOption]; | |
1182 | + for (var ilr = 0; ilr < 12; ilr++) { | |
558 | 1183 | |
559 | - if (currentOption) { | |
1184 | + if (ilr == 0) { | |
1185 | + currentRow['column' + Number(12 * col + ilr)] = question.questionIndex + correctAnswerValue; | |
1186 | + } | |
1187 | + else if (ilr == 1) { | |
1188 | + currentRow['column' + Number(12 * col + ilr)] = (question.gradeScoringRate * 100).toFixed(2) + '%'; | |
1189 | + } | |
1190 | + else { | |
560 | 1191 | |
561 | - var optionValue = currentOption.option == "1" ? "✓" : currentOption.option == 2 ? "✗" : currentOption.option; | |
1192 | + var questionDetail = details[ilr - 2]; | |
562 | 1193 | |
563 | - itema["column_" + (stPass + iOption + 2)] = optionValue + "(" + (currentOption.persent ?? "0%") + ")"; | |
564 | - } | |
565 | - else { | |
566 | - itema["column_" + (stPass + iOption + 2)] = value | |
567 | - } | |
568 | - } | |
1194 | + var questionColumn = 'column' + Number(12 * col + ilr); | |
569 | 1195 | |
570 | - noPassIndex += 1 | |
1196 | + currentRow[questionColumn] = questionDetail ? questionDetail.option + "(" + questionDetail.persent + ")" : "- -"; | |
1197 | + } | |
1198 | + } | |
571 | 1199 | |
572 | - if (qOIndex >= otherDatas.length - 1 && noPassIndex != 0) { | |
1200 | + num = num + 1; | |
1201 | + } | |
573 | 1202 | |
574 | - questionOtherResults.push(itema) | |
575 | - itema = null; | |
576 | 1203 | } |
1204 | + | |
1205 | + demoTestTranscript.question10List = [...areaList] | |
577 | 1206 | } |
578 | 1207 | |
579 | - this.questionOtherList = [...questionOtherResults] | |
1208 | + | |
1209 | + return demoTestTranscript; | |
580 | 1210 | |
581 | 1211 | }, |
582 | 1212 | async _testPaperExamReport() { |
1213 | + | |
1214 | + this.testPaperExamReport = []; | |
1215 | + | |
1216 | + this.testPaperExamReportOptions = []; | |
1217 | + | |
1218 | + if (!this.checkedClassInfos || this.checkedClassInfos?.length <= 0) return; | |
1219 | + | |
583 | 1220 | const request = this.$request.gPaperExamReport; |
584 | 1221 | |
585 | 1222 | let response = await request({ |
586 | 1223 | paperId: this.paperId, |
587 | - classIds: this.checkedClassInfos.map((item) => item.classId), | |
1224 | + classIds: this.checkedClassInfos, | |
588 | 1225 | }); |
589 | 1226 | |
590 | 1227 | if (response.status != 0) { |
591 | 1228 | this.$message.error(response.info); |
592 | 1229 | return; |
593 | 1230 | } |
1231 | + var maxOption = 0; | |
1232 | + response.data.forEach((item) => { | |
1233 | + if (item.details) { | |
1234 | + if (maxOption < item.details.length) { | |
1235 | + maxOption = item.details.length; | |
1236 | + } | |
1237 | + } | |
1238 | + | |
1239 | + }) | |
594 | 1240 | |
595 | - let optionsList = [{}, {}, {}, {}, {}]; | |
1241 | + let optionsList = []; | |
1242 | + | |
1243 | + for (var io = 0; io < maxOption; io++) { | |
1244 | + optionsList.push({}) | |
1245 | + } | |
1246 | + //主观 | |
1247 | + var subjective = { | |
1248 | + sum: 0.0, | |
1249 | + avg: 0.0, | |
1250 | + rate: 0.0, | |
1251 | + number: 0 | |
1252 | + }; | |
1253 | + | |
1254 | + //客观 | |
1255 | + var objective = { | |
1256 | + sum: 0.0, | |
1257 | + avg: 0.0, | |
1258 | + rate: 0.0, | |
1259 | + number: 0 | |
1260 | + }; | |
1261 | + | |
1262 | + //汇总 | |
1263 | + var summary = { | |
1264 | + sum: 0.0, | |
1265 | + avg: 0.0, | |
1266 | + rate: 0.0, | |
1267 | + number: 0 | |
1268 | + }; | |
596 | 1269 | |
597 | 1270 | let tableData = response.data?.map((item) => { |
1271 | + | |
598 | 1272 | let params = {}; |
1273 | + | |
599 | 1274 | const detail = item.details; |
1275 | + | |
600 | 1276 | let lastOPtion = detail?.find((item) => { |
601 | 1277 | return item.option == "未答"; |
602 | 1278 | }); |
1279 | + | |
603 | 1280 | let defaultArr = detail?.filter((item) => { |
604 | 1281 | return item.option != "未答"; |
605 | 1282 | }); |
1283 | + | |
606 | 1284 | optionsList.map((items, index) => { |
607 | 1285 | if (index != 4) { |
608 | 1286 | params["count" + index] = |
... | ... | @@ -624,12 +1302,28 @@ export default { |
624 | 1302 | items["title"] = "选项" + (index + 1); |
625 | 1303 | } else { |
626 | 1304 | items["title"] = "未答"; |
627 | - params["count" + index] = lastOPtion.count; | |
628 | - params["persent" + index] = lastOPtion.persent; | |
1305 | + params["count" + index] = lastOPtion?.count ?? ""; | |
1306 | + params["persent" + index] = lastOPtion?.persent ?? ""; | |
629 | 1307 | params["option" + index] = "?"; |
630 | 1308 | } |
631 | 1309 | }); |
632 | 1310 | |
1311 | + summary.sum += parseFloat(item.score); | |
1312 | + summary.avg += parseFloat(item.avgScore); | |
1313 | + summary.rate += parseFloat(item.gradeScoringRate); | |
1314 | + summary.number += 1; | |
1315 | + if (item.questionType == 5) { | |
1316 | + subjective.sum += parseFloat(item.score); | |
1317 | + subjective.rate += parseFloat(item.gradeScoringRate); | |
1318 | + subjective.avg += parseFloat(item.avgScore); | |
1319 | + subjective.number += 1; | |
1320 | + } | |
1321 | + else { | |
1322 | + objective.sum += parseFloat(item.score); | |
1323 | + objective.rate += parseFloat(item.gradeScoringRate); | |
1324 | + objective.avg += parseFloat(item.avgScore); | |
1325 | + objective.number += 1; | |
1326 | + } | |
633 | 1327 | return { |
634 | 1328 | ...item, |
635 | 1329 | ...params, |
... | ... | @@ -637,18 +1331,57 @@ export default { |
637 | 1331 | }); |
638 | 1332 | |
639 | 1333 | this.testPaperExamReport = tableData?.sort((a, b) => { |
640 | - return a.questionIndex - b.questionIndex; | |
1334 | + return Number(a.questionIndex) - Number(b.questionIndex); | |
641 | 1335 | }); |
642 | 1336 | |
643 | 1337 | this.testPaperExamReportOptions = [...optionsList]; |
644 | 1338 | |
1339 | + console.log(objective, subjective, summary, Number(objective.avg / objective.sum)) | |
1340 | + this.testPaperExamReport.push({ | |
1341 | + questionIndex: "汇总", | |
1342 | + questionType: "客观题", | |
1343 | + type: "colspan", | |
1344 | + score: objective.sum, | |
1345 | + avgScore: objective.avg == 0 ? 0 : Number(objective.avg).toFixed(2), | |
1346 | + gradeScoringRate: objective.avg == 0 ? 0 : Number(objective.avg * 100 / objective.sum).toFixed(2), | |
1347 | + correctAnswer: "备注" | |
1348 | + }) | |
1349 | + | |
1350 | + this.testPaperExamReport.push({ | |
1351 | + questionIndex: "主观题", | |
1352 | + type: "colspan", | |
1353 | + knowledge: subjective.sum, | |
1354 | + score: subjective.avg == 0 ? 0 : Number(subjective.avg).toFixed(2), | |
1355 | + avgScore: subjective.avg == 0 ? 0 : Number(subjective.avg * 100 / subjective.sum).toFixed(2) | |
1356 | + }) | |
1357 | + | |
1358 | + this.testPaperExamReport.push({ | |
1359 | + questionIndex: "合计", | |
1360 | + type: "colspan", | |
1361 | + knowledge: summary.sum, | |
1362 | + score: summary.avg == 0 ? 0 : Number(summary.avg).toFixed(2), | |
1363 | + avgScore: summary.avg == 0 ? 0 : Number(summary.avg * 100 / summary.sum).toFixed(2) | |
1364 | + }) | |
645 | 1365 | }, |
646 | 1366 | async _testStudentExamReport() { |
1367 | + this.testStudentExamReport = []; | |
1368 | + if (!this.checkedClassInfos || this.checkedClassInfos?.length <= 0) return; | |
1369 | + | |
647 | 1370 | const request = this.$request.gStudentExamReport; |
648 | 1371 | |
1372 | + let paramObj = JSON.parse(JSON.stringify(this.fromData)) | |
1373 | + if (paramObj.levelType == 0) { | |
1374 | + paramObj.levels = paramObj.levels.map((item) => { | |
1375 | + item[1] = ((item[1] / 100) * this.examPaperScore).toFixed(1); | |
1376 | + item[2] = ((item[2] / 100) * this.examPaperScore).toFixed(1); | |
1377 | + return item; | |
1378 | + }); | |
1379 | + } | |
1380 | + | |
649 | 1381 | let response = await request({ |
650 | 1382 | paperId: this.paperId, |
651 | - classIds: this.checkedClassInfos.map((item) => item.classId), | |
1383 | + classIds: this.checkedClassInfos, | |
1384 | + reportRange: paramObj | |
652 | 1385 | }); |
653 | 1386 | |
654 | 1387 | if (response.status != 0) { |
... | ... | @@ -659,11 +1392,26 @@ export default { |
659 | 1392 | this.testStudentExamReport = response.data; |
660 | 1393 | }, |
661 | 1394 | async _classdiffExamReport() { |
1395 | + | |
1396 | + this.classdiffExamReport = []; | |
1397 | + | |
1398 | + if (!this.checkedClassInfos || this.checkedClassInfos?.length <= 0) return; | |
1399 | + | |
662 | 1400 | const request = this.$request.gClassdiffExamReport; |
663 | 1401 | |
1402 | + let paramObj = JSON.parse(JSON.stringify(this.fromData)) | |
1403 | + if (paramObj.levelType == 0) { | |
1404 | + paramObj.levels = paramObj.levels.map((item) => { | |
1405 | + item[1] = ((item[1] / 100) * this.examPaperScore).toFixed(1); | |
1406 | + item[2] = ((item[2] / 100) * this.examPaperScore).toFixed(1); | |
1407 | + return item; | |
1408 | + }); | |
1409 | + } | |
1410 | + | |
664 | 1411 | let response = await request({ |
665 | 1412 | paperId: this.paperId, |
666 | - classIds: this.checkedClassInfos.map((item) => item.classId), | |
1413 | + classIds: this.checkedClassInfos, | |
1414 | + reportRange: paramObj | |
667 | 1415 | }); |
668 | 1416 | |
669 | 1417 | if (response.status != 0) { |
... | ... | @@ -675,6 +1423,7 @@ export default { |
675 | 1423 | this.classdiffExamReport = response.data.map((item) => { |
676 | 1424 | item.index = index + 1; |
677 | 1425 | index += 1; |
1426 | + | |
678 | 1427 | return item; |
679 | 1428 | }); |
680 | 1429 | }, |
... | ... | @@ -694,7 +1443,11 @@ export default { |
694 | 1443 | padding: 10px !important; |
695 | 1444 | } |
696 | 1445 | |
1446 | + | |
697 | 1447 | .row-line { |
1448 | + overflow: hidden; //超出宽度隐藏 | |
1449 | + white-space: nowrap; //强制文字在一行 | |
1450 | + text-overflow: ellipsis; //文字溢出显示省略号 | |
698 | 1451 | width: calc(33% - 2px); |
699 | 1452 | border: 1px solid #ebeef5; |
700 | 1453 | background: #f5f7fa; |
... | ... | @@ -705,5 +1458,71 @@ export default { |
705 | 1458 | .line-subfix { |
706 | 1459 | margin-left: 10px; |
707 | 1460 | } |
1461 | + | |
1462 | +} | |
1463 | + | |
1464 | +.dia-tab-box { | |
1465 | + font-size: 14px; | |
1466 | + | |
1467 | + .boxitem { | |
1468 | + border: 1px solid #DCDFE6; | |
1469 | + margin: 0px !important; | |
1470 | + | |
1471 | + * { | |
1472 | + border: none; | |
1473 | + } | |
1474 | + } | |
1475 | + | |
1476 | + .dia-tab-tit, | |
1477 | + .dia-tab-item { | |
1478 | + | |
1479 | + | |
1480 | + i { | |
1481 | + color: #f30; | |
1482 | + padding-right: 5px; | |
1483 | + } | |
1484 | + | |
1485 | + display: flex; | |
1486 | + | |
1487 | + .item { | |
1488 | + width: 80px; | |
1489 | + } | |
1490 | + | |
1491 | + .item1 { | |
1492 | + padding-left: 10px; | |
1493 | + width: 10%; | |
1494 | + } | |
1495 | + | |
1496 | + .item2 { | |
1497 | + width: 18%; | |
1498 | + } | |
1499 | + | |
1500 | + .item3 { | |
1501 | + padding-left: 12px; | |
1502 | + flex: 1; | |
1503 | + } | |
1504 | + | |
1505 | + .score-ipt { | |
1506 | + width: 100px; | |
1507 | + } | |
1508 | + } | |
1509 | + | |
1510 | + .dia-tab-tit { | |
1511 | + background: rgb(245, 247, 250) !important | |
1512 | + } | |
1513 | + | |
1514 | + .add { | |
1515 | + display: flex; | |
1516 | + justify-content: center; | |
1517 | + margin: 0 auto; | |
1518 | + | |
1519 | + p { | |
1520 | + cursor: pointer; | |
1521 | + } | |
1522 | + | |
1523 | + .el-button { | |
1524 | + margin-right: 6px; | |
1525 | + } | |
1526 | + } | |
708 | 1527 | } |
709 | 1528 | </style> | ... | ... |
src/views/basic/askTestQuestion/index.vue
... | ... | @@ -7,16 +7,16 @@ |
7 | 7 | <el-dropdown v-if="this.dataType == '2'" :hide-on-click="true" style="float: right;margin-right: 50px;"> |
8 | 8 | <el-button :size="'small'" :icon="'el-icon-plus'" class="green-el-button">添加试卷</el-button> |
9 | 9 | <el-dropdown-menu slot="dropdown"> |
10 | - <el-dropdown-item @click.native="import(1)">导入试卷</el-dropdown-item> | |
10 | + <el-dropdown-item @click.native="importQuestion(1)">导入试卷</el-dropdown-item> | |
11 | 11 | <el-dropdown-item @click.native="createAnwseredCard()">创建答题卡</el-dropdown-item> |
12 | 12 | </el-dropdown-menu> |
13 | 13 | </el-dropdown> |
14 | 14 | <el-button style="float: right;margin-right: 50px;" :size="'small'" :icon="'el-icon-plus'" |
15 | - class="green-el-button" @click.native="import(2)" v-if="this.dataType == '1'">添加课件</el-button> | |
15 | + class="green-el-button" @click.native="importQuestion(2)" v-if="this.dataType == '1'">添加课件</el-button> | |
16 | 16 | </el-header> |
17 | 17 | <div class="default-filter"> |
18 | - <el-input v-model="query.paper" :placeholder="dataType == '1' ? '搜索课件' : '搜索试卷'" | |
19 | - suffix-icon="el-icon-search" class="filter-input" type="number" clearable /> | |
18 | + <!-- <el-input v-model="query.paper" :placeholder="dataType == '1' ? '搜索课件' : '搜索试卷'" | |
19 | + suffix-icon="el-icon-search" class="filter-input" type="number" clearable /> --> | |
20 | 20 | <el-select @change="_changeClass" v-model="query.class" class="filter-select" placeholder="选择班级"> |
21 | 21 | <el-option v-for="item in classList" :key="item.classId" :label="item.className" |
22 | 22 | :value="item.classId" /> |
... | ... | @@ -34,7 +34,7 @@ |
34 | 34 | 筛选 |
35 | 35 | </el-button> |
36 | 36 | <el-radio-group v-model="dateStatus" class="default-date-radio-group"> |
37 | - <el-radio-button label="onDay">当天</el-radio-button> | |
37 | + <el-radio-button label="onDay">今天</el-radio-button> | |
38 | 38 | <el-radio-button label="onWeek">本周</el-radio-button> |
39 | 39 | <el-radio-button label="onMonth">本月</el-radio-button> |
40 | 40 | </el-radio-group> |
... | ... | @@ -42,192 +42,206 @@ |
42 | 42 | <el-main> |
43 | 43 | <div style='position: relative;'> |
44 | 44 | <el-tabs v-model="tabType" v-loading="queryLoading" type="card" class="default-tabs"> |
45 | - <el-tab-pane :name="'0'" :label="`自编课件(${createdCount})`"> | |
46 | - <el-row> | |
47 | - <el-col :key="index" v-for="( item, index ) in defaultList " :span="12"> | |
48 | - <div class="card-content"> | |
49 | - <el-row> | |
50 | - <el-col :span="6" class="left"> | |
51 | - <div class="left-icon"> | |
52 | - <div class="icon"> | |
53 | - <img src="../../../assets/images/shuben.png" /> | |
54 | - </div> | |
55 | - <div class="text"> | |
56 | - {{ item.id }} | |
57 | - </div> | |
58 | - </div> | |
59 | - </el-col> | |
60 | - <el-col :span="18" class="content"> | |
61 | - <div class="title-text"> | |
45 | + <el-tab-pane :name="'0'" :label="`我自编的(${createdCount})`"> | |
46 | + <div class="card-content" :key="index" v-for="( item, index ) in defaultList "> | |
47 | + <el-row> | |
48 | + <el-col :span="6" class="left"> | |
49 | + <div class="left-icon"> | |
50 | + <div class="icon"> | |
51 | + <img src="../../../assets/images/shuben.png" /> | |
52 | + </div> | |
53 | + <div class="text"> | |
54 | + {{ item.id }} | |
55 | + </div> | |
56 | + </div> | |
57 | + </el-col> | |
58 | + <el-col :span="18" class="content"> | |
59 | + <div class="title-text"> | |
60 | + <el-tooltip effect="dark" :content="item.title" placement="left"> | |
61 | + <div class="title-label overflowText"> | |
62 | 62 | {{ item.title }} |
63 | - <el-dropdown class="dropdown-button" :hide-on-click="false"> | |
64 | - <el-button>操作</el-button> | |
65 | - <el-dropdown-menu slot="dropdown"> | |
66 | - <el-dropdown-item | |
67 | - @click.native="_detailQ(item.id)">查看</el-dropdown-item> | |
68 | - <el-dropdown-item | |
69 | - @click.native="_updateQ(item)">修改</el-dropdown-item> | |
70 | - <el-dropdown-item | |
71 | - @click.native="_copy(item)">复制</el-dropdown-item> | |
72 | - <el-dropdown-item> | |
73 | - <el-popconfirm style="color:gray !important;" | |
74 | - @confirm="_deleteDetermineQ(item.id)" | |
75 | - title="这是一段内容确定删除吗?"> | |
76 | - <el-button style="color:#606266 !important;" | |
77 | - @click.native="_delete(item.id)" type="text" | |
78 | - slot="reference">删除</el-button> | |
79 | - </el-popconfirm> | |
80 | - </el-dropdown-item> | |
81 | - </el-dropdown-menu> | |
82 | - </el-dropdown> | |
83 | - </div> | |
84 | - <div class="descption-tag-text" v-if="role != 'ROLE_PERSONAL'"> | |
85 | - <template> | |
86 | - 授课端同步: | |
87 | - <span class="descption-tag" | |
88 | - v-for="( clazzChild, indexs ) in item.classList " | |
89 | - :key="clazzChild.classId" | |
90 | - :class="clazzChild.keepStatus == 1 ? 'active' : ''"> | |
91 | - {{ clazzChild.className }} | |
92 | - <i v-if="clazzChild.keepStatus == 1" | |
93 | - class="el-icon-success"></i> | |
94 | - </span> | |
95 | - <el-tooltip effect="dark" content="刷新同步状态"> | |
96 | - <img @click="_loadQueryDatas" height="18px" width="18px" | |
97 | - src="../../../assets/images/shuaxin.png" /> | |
98 | - </el-tooltip> | |
99 | - </template> | |
100 | 63 | </div> |
101 | - <div class="descption-text"> | |
102 | - <span class="descption-text-block"> | |
103 | - <div class="pic"> | |
104 | - <img src="../../../assets/images/tishu.png" /> | |
105 | - </div> | |
106 | - <div class="text"> 总题数:</div> | |
107 | - <div class="value">{{ item.questionNum }}</div> | |
108 | - <div class="pic" v-if="dataType == 2" style="margin-left: 44px;"> | |
109 | - <img src="../../../assets/images/tishu.png" /> | |
110 | - </div> | |
111 | - <div class="text" v-if="dataType == 2"> 预计时长:</div> | |
112 | - <div class="value" v-if="dataType == 2">{{ item.examsDuration }} | |
113 | - 分钟 | |
114 | - </div> | |
115 | - <div class="pic" style="margin-left: 44px;"> | |
116 | - <img src="../../../assets/images/tishu.png" /> | |
117 | - </div> | |
118 | - <div class="text"> 创建人:</div> | |
119 | - <div class="value">{{ item.realName }}</div> | |
64 | + </el-tooltip> | |
65 | + <el-dropdown class="dropdown-button" :hide-on-click="false"> | |
66 | + <el-button>操作</el-button> | |
67 | + <el-dropdown-menu slot="dropdown"> | |
68 | + <el-dropdown-item | |
69 | + @click.native="_detailQ(item.id)">查看</el-dropdown-item> | |
70 | + <el-dropdown-item @click.native="_updateQ(item)">修改</el-dropdown-item> | |
71 | + <el-dropdown-item @click.native="_copy(item)">复制</el-dropdown-item> | |
72 | + <el-dropdown-item> | |
73 | + <el-popconfirm style="color:gray !important;" | |
74 | + @confirm="_deleteDetermineQ(item.id)" | |
75 | + :title="dataType == 1 ? '确认删除此课件' : '确认删除此试卷'"> | |
76 | + <el-button style="color:#606266 !important;" | |
77 | + @click.native="_delete(item.id)" type="text" | |
78 | + slot="reference">删除</el-button> | |
79 | + </el-popconfirm> | |
80 | + </el-dropdown-item> | |
81 | + </el-dropdown-menu> | |
82 | + </el-dropdown> | |
83 | + </div> | |
84 | + <div class="descption-tag-text" v-if="role != 'ROLE_PERSONAL'"> | |
85 | + <template> | |
86 | + <span class="descption-label"> 授课端同步:</span> | |
87 | + <div class="descption-box"> | |
88 | + <span class="descption-tag" | |
89 | + v-for="( clazzChild, indexs ) in item.classList " | |
90 | + :key="clazzChild.classId" | |
91 | + :class="clazzChild.keepStatus == 1 ? 'active' : ''"> | |
92 | + {{ clazzChild.className }} | |
93 | + <i v-if="clazzChild.keepStatus == 1" class="el-icon-success"></i> | |
120 | 94 | </span> |
95 | + <el-tooltip effect="dark" content="刷新同步状态"> | |
96 | + <img @click="_serach" height="18px" width="18px" | |
97 | + src="../../../assets/images/shuaxin.png" /> | |
98 | + </el-tooltip> | |
121 | 99 | </div> |
122 | - <div class="descption-text"> | |
123 | - <span class="descption-text-block"> | |
124 | - <div class="pic"><img src="../../../assets/images/rili.png"></img> | |
125 | - </div> | |
126 | - <div class="text"> 更新时间:</div> | |
127 | - <div class="value">{{ item.modifiedTime }}</div> | |
128 | - <span class="sharing-descption" | |
129 | - v-if="item.sharingType == 1">已分享到非任课班级</span> | |
130 | - </span> | |
100 | + </template> | |
101 | + </div> | |
102 | + <div class="descption-text"> | |
103 | + <span class="descption-text-block"> | |
104 | + <div class="pic"> | |
105 | + <img src="../../../assets/images/tishu.png" /> | |
131 | 106 | </div> |
132 | - </el-col> | |
133 | - </el-row> | |
134 | - </div> | |
135 | - </el-col> | |
136 | - </el-row> | |
137 | - </el-tab-pane> | |
138 | - <el-tab-pane :name="'1'" :label="`共享课件(${sharedCount})`"> | |
139 | - <el-row> | |
140 | - <el-col :key="index" v-for="( item, index ) in sharedList " :span="12"> | |
141 | - <div class="card-content"> | |
142 | - <el-row> | |
143 | - <el-col :span="6" class="left"> | |
144 | - <div class="left-icon"> | |
145 | - <div class="icon"> | |
146 | - <img src="../../../assets/images/shuben.png" /> | |
147 | - </div> | |
148 | - <div class="text"> | |
149 | - {{ item.id }} | |
150 | - </div> | |
107 | + <div class="text"> 总题数:</div> | |
108 | + <div class="value">{{ item.questionNum }}</div> | |
109 | + <div class="pic" v-if="dataType == 2" style="margin-left: 44px;"> | |
110 | + <img src="../../../assets/images/tishu.png" /> | |
151 | 111 | </div> |
152 | - </el-col> | |
153 | - <el-col :span="15" class="content"> | |
154 | - <div class="title-text"> | |
155 | - {{ item.title }} | |
112 | + <div class="text" v-if="dataType == 2"> 预计时长:</div> | |
113 | + <div class="value" v-if="dataType == 2">{{ item.examsDuration }} | |
114 | + 分钟 | |
156 | 115 | </div> |
157 | - <div class="descption-tag-text" v-if="role != 'ROLE_PERSONAL'"> | |
158 | - <template> | |
159 | - 授课端同步: | |
160 | - <span class="descption-tag" | |
161 | - v-for="( clazzChild, indexs ) in item.classList " | |
162 | - :key="clazzChild.classId" | |
163 | - :class="clazzChild.keepStatus == 1 ? 'active' : ''"> | |
164 | - {{ clazzChild.className }} | |
165 | - <i v-if="clazzChild.keepStatus == 1" | |
166 | - class="el-icon-success"></i> | |
167 | - </span> | |
168 | - <el-tooltip effect="dark" content="刷新同步状态"> | |
169 | - <img @click="_loadQueryDatas" height="18px" width="18px" | |
170 | - src="../../../assets/images/shuaxin.png" /> | |
171 | - </el-tooltip> | |
172 | - </template> | |
116 | + <div class="pic" style="margin-left: 44px;"> | |
117 | + <img src="../../../assets/images/tishu.png" /> | |
173 | 118 | </div> |
174 | - <div class="descption-text"> | |
175 | - <span class="descption-text-block"> | |
176 | - <div class="pic"><img src="../../../assets/images/tishu.png"></img> | |
177 | - </div> | |
178 | - <div class="text"> 总题数:</div> | |
179 | - <div class="value">{{ item.questionNum }}</div> | |
180 | - | |
181 | - <div class="pic" style="margin-left: 44px;"><img | |
182 | - src="../../../assets/images/tishu.png"></img> | |
183 | - </div> | |
184 | - <div class="text"> 创建人:</div> | |
185 | - <div class="value">{{ item.realName }}</div> | |
186 | - </span> | |
119 | + <div class="text"> 创建人:</div> | |
120 | + <div class="value">{{ item.realName }}</div> | |
121 | + </span> | |
122 | + </div> | |
123 | + <div class="descption-text"> | |
124 | + <span class="descption-text-block"> | |
125 | + <div class="pic"><img src="../../../assets/images/rili.png"></img> | |
187 | 126 | </div> |
188 | - <div class="descption-text"> | |
189 | - <span class="descption-text-block"> | |
190 | - <div class="pic"><img src="../../../assets/images/rili.png"></img> | |
191 | - </div> | |
192 | - <div class="text"> 更新时间:</div> | |
193 | - <div class="value">{{ item.createdTime }}</div> | |
127 | + <div class="text"> 更新时间:</div> | |
128 | + <div class="value">{{ item.modifiedTime }}</div> | |
129 | + <span class="sharing-descption" | |
130 | + v-if="item.sharingType == 1">已分享到非任课班级</span> | |
131 | + </span> | |
132 | + </div> | |
133 | + </el-col> | |
134 | + </el-row> | |
135 | + </div> | |
136 | + </el-tab-pane> | |
137 | + <el-tab-pane :name="'1'" :label="`被共享的(${sharedCount})`"> | |
138 | + <div class="card-content" :key="index" v-for="( item, index ) in sharedList "> | |
139 | + <el-row> | |
140 | + <el-col :span="6" class="left"> | |
141 | + <div class="left-icon"> | |
142 | + <div class="icon"> | |
143 | + <img src="../../../assets/images/shuben.png" /> | |
144 | + </div> | |
145 | + <div class="text"> | |
146 | + {{ item.id }} | |
147 | + </div> | |
148 | + </div> | |
149 | + </el-col> | |
150 | + <el-col :span="18" class="content"> | |
151 | + <div class="title-text"> | |
152 | + <el-tooltip effect="dark" :content="item.title" placement="left"> | |
153 | + <div class="title-label overflowText"> | |
154 | + {{ item.title }} | |
155 | + </div> | |
156 | + </el-tooltip> | |
157 | + <el-dropdown class="dropdown-button" :hide-on-click="false"> | |
158 | + <el-button>操作</el-button> | |
159 | + <el-dropdown-menu slot="dropdown"> | |
160 | + <el-dropdown-item | |
161 | + @click.native="_detailQ(item.id)">查看</el-dropdown-item> | |
162 | + <el-dropdown-item> | |
163 | + <el-popconfirm style="color:gray !important;" | |
164 | + @confirm="_deleteDetermineQ(item.id)" | |
165 | + :title="dataType == 1 ? '确认删除此课件' : '确认删除此试卷'"> | |
166 | + <el-button style="color:#606266 !important;" | |
167 | + @click.native="_delete(item.id)" type="text" | |
168 | + slot="reference">删除</el-button> | |
169 | + </el-popconfirm> | |
170 | + </el-dropdown-item> | |
171 | + </el-dropdown-menu> | |
172 | + </el-dropdown> | |
173 | + </div> | |
174 | + <div class="descption-tag-text" v-if="role != 'ROLE_PERSONAL'"> | |
175 | + <template> | |
176 | + <span class="descption-label"> 授课端同步:</span> | |
177 | + <div class="descption-box"> | |
178 | + <span class="descption-tag" | |
179 | + v-for="( clazzChild, indexs ) in item.classList " | |
180 | + :key="clazzChild.classId" | |
181 | + :class="clazzChild.keepStatus == 1 ? 'active' : ''"> | |
182 | + {{ clazzChild.className }} | |
183 | + <i v-if="clazzChild.keepStatus == 1" class="el-icon-success"></i> | |
194 | 184 | </span> |
185 | + <el-tooltip effect="dark" content="刷新同步状态"> | |
186 | + <img @click="_serach" height="18px" width="18px" | |
187 | + src="../../../assets/images/shuaxin.png" /> | |
188 | + </el-tooltip> | |
189 | + </div> | |
190 | + </template> | |
191 | + </div> | |
192 | + <div class="descption-text"> | |
193 | + <span class="descption-text-block"> | |
194 | + <div class="pic"> | |
195 | + <img src="../../../assets/images/tishu.png" /> | |
196 | + </div> | |
197 | + <div class="text"> 总题数:</div> | |
198 | + <div class="value">{{ item.questionNum }}</div> | |
199 | + <div class="pic" v-if="dataType == 2" style="margin-left: 44px;"> | |
200 | + <img src="../../../assets/images/tishu.png" /> | |
201 | + </div> | |
202 | + <div class="text" v-if="dataType == 2"> 预计时长:</div> | |
203 | + <div class="value" v-if="dataType == 2">{{ item.examsDuration }} | |
204 | + 分钟 | |
205 | + </div> | |
206 | + <div class="pic" style="margin-left: 44px;"> | |
207 | + <img src="../../../assets/images/tishu.png" /> | |
195 | 208 | </div> |
196 | - </el-col> | |
197 | - <el-col :span="3" class="right"> | |
198 | - <el-dropdown :hide-on-click="true"> | |
199 | - <el-button>操作</el-button> | |
200 | - <el-dropdown-menu slot="dropdown"> | |
201 | - <el-dropdown-item>查看</el-dropdown-item> | |
202 | - <el-dropdown-item>删除</el-dropdown-item> | |
203 | - </el-dropdown-menu> | |
204 | - </el-dropdown> | |
205 | - </el-col> | |
206 | - </el-row> | |
207 | - </div> | |
208 | - </el-col> | |
209 | - </el-row> | |
209 | + <div class="text"> 创建人:</div> | |
210 | + <div class="value">{{ item.realName }}</div> | |
211 | + </span> | |
212 | + </div> | |
213 | + <div class="descption-text"> | |
214 | + <span class="descption-text-block"> | |
215 | + <div class="pic"><img src="../../../assets/images/rili.png"></img> | |
216 | + </div> | |
217 | + <div class="text"> 更新时间:</div> | |
218 | + <div class="value">{{ item.modifiedTime }}</div> | |
219 | + </span> | |
220 | + </div> | |
221 | + </el-col> | |
222 | + </el-row> | |
223 | + </div> | |
210 | 224 | </el-tab-pane> |
211 | 225 | <div slot="tab-bar"> |
212 | 226 | <el-button type="primary" icon="el-icon-plus">新增</el-button> |
213 | 227 | </div> |
214 | 228 | </el-tabs> |
215 | 229 | <el-button size='mini' v-if="role == 'ROLE_PERSONAL' || role == 'ROLE_JIAOSHI'" @click="recycle" |
216 | - style='position: absolute;right:40px;top:5px;'>查看回收站</el-button> | |
230 | + style='position: absolute;right:40px;top:2.5px;'>查看回收站</el-button> | |
217 | 231 | </div> |
218 | 232 | </el-main> |
219 | 233 | <el-footer class="el-footer-pagination"> |
220 | - <el-pagination @current-change="pageSizeChange" background layout="prev, pager, next" | |
221 | - :size="listPage.size" :current-page="listPage.page" | |
222 | - :total="listPage.total"> | |
234 | + <el-pagination @current-change="pageSizeChange" background layout="prev, pager, next" :size="listPage.size" | |
235 | + :current-page="listPage.page" :total="listPage.total"> | |
223 | 236 | </el-pagination> |
224 | 237 | </el-footer> |
225 | - <el-dialog :append-to-body="true" :close-on-click-modal="false" title="上传word文档" :visible.sync="diaUp" width="600px"> | |
238 | + <el-dialog :append-to-body="true" :close-on-click-modal="false" title="上传word文档" :visible.sync="diaUp" | |
239 | + width="600px"> | |
226 | 240 | <upload :url="url" :params="{ type: importType }" @upSuccess="upSuccess" fileName="下载"> |
227 | 241 | <div class="down-box p0" slot="down"> |
228 | 242 | <p class="down-head" v-if="importType == 1"> |
229 | 243 | <span>第一步:</span> |
230 | - <el-link type="primary" @click="downExcel">下载模板,</el-link> | |
244 | + <!-- <el-link type="primary" @click="downExcel">下载模板,</el-link> --> | |
231 | 245 | <span>或者导出菁优网试卷/组卷网(学科网)试卷; |
232 | 246 | 为保证第三方试卷导入成功,请注意参考导出示例:</span> |
233 | 247 | <span class="img-box"> |
... | ... | @@ -241,7 +255,9 @@ |
241 | 255 | </span> |
242 | 256 | </p> |
243 | 257 | <p class="down-head" v-if="importType == 2"> |
244 | - <span>第一步:导出菁优网试卷/组卷网(学科网)试卷;为保证第三方试卷导入成功,请注意参考导出示例:</span> | |
258 | + <span>第一步: | |
259 | + <el-link type="primary" @click="downExcel">下载模板,</el-link> | |
260 | + 导出菁优网试卷/组卷网(学科网)试卷;为保证第三方试卷导入成功,请注意参考导出示例:</span> | |
245 | 261 | <span class="img-box"> |
246 | 262 | <el-image class="img" :src="examplePic" :preview-src-list="examplePicList"> |
247 | 263 | </el-image> |
... | ... | @@ -266,10 +282,10 @@ |
266 | 282 | </template> |
267 | 283 | |
268 | 284 | <script> |
269 | -import { setDateRules } from "@/utils"; | |
270 | -import example from "@/assets/images/example.jpg"; | |
285 | +import { setDateRules, downloadFile } from "@/utils"; | |
286 | +import example from "@/assets/images/example.png"; | |
271 | 287 | import example2 from "@/assets/images/example2.png"; |
272 | - | |
288 | +import axios from "axios"; | |
273 | 289 | |
274 | 290 | export default { |
275 | 291 | data() { |
... | ... | @@ -309,7 +325,7 @@ export default { |
309 | 325 | sharedCount: 0 |
310 | 326 | }; |
311 | 327 | }, |
312 | - watch: { | |
328 | + watch: { | |
313 | 329 | '$route'() { |
314 | 330 | this.dataType = location.href.endsWith("askPreparationQuestions") ? "1" : "2"; |
315 | 331 | this._serach(); |
... | ... | @@ -323,16 +339,37 @@ export default { |
323 | 339 | this.query.dateRange = [dateRange.startDay, dateRange.endDay]; |
324 | 340 | } |
325 | 341 | }, |
326 | - created() { | |
342 | + async created() { | |
327 | 343 | this.dataType = location.href.endsWith("askPreparationQuestions") ? "1" : "2"; |
328 | 344 | this.code = this.$store.getters.csCode; |
329 | 345 | this.role = |
330 | 346 | this.$store.getters.info.showRole || |
331 | 347 | this.$store.getters.info.permissions[0].role; |
332 | - this._loadQueryDatas(); | |
348 | + this.dateStatus = "onWeek"; | |
349 | + await this._loadQueryDatas(); | |
333 | 350 | }, |
334 | 351 | methods: { |
335 | - async pageSizeChange(value){ | |
352 | + async downExcel() { | |
353 | + let url; | |
354 | + let that = this; | |
355 | + if (that.dataType == 1) { | |
356 | + url = "static/课件模板.docx"; | |
357 | + } else { | |
358 | + url = "static/试卷模板.docx"; | |
359 | + } | |
360 | + axios(url, { | |
361 | + responseType: "arraybuffer", | |
362 | + }).then((res) => { | |
363 | + let blob = new Blob([res.data], { | |
364 | + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | |
365 | + }); | |
366 | + downloadFile( | |
367 | + that.dataType == 1 ? "课件模板.docx" : "试卷模板.docx", | |
368 | + blob | |
369 | + ); | |
370 | + }); | |
371 | + }, | |
372 | + async pageSizeChange(value) { | |
336 | 373 | this.listPage.page = value; |
337 | 374 | await this._serach(); |
338 | 375 | }, |
... | ... | @@ -345,7 +382,7 @@ export default { |
345 | 382 | } |
346 | 383 | this.$router.push(routerItem); |
347 | 384 | }, |
348 | - createAnwseredCard() { | |
385 | + createAnwseredCard(params) { | |
349 | 386 | let routerItem = { |
350 | 387 | path: "/testPaperAdd", |
351 | 388 | query: { |
... | ... | @@ -356,7 +393,7 @@ export default { |
356 | 393 | }; |
357 | 394 | this.$router.push(routerItem); |
358 | 395 | }, |
359 | - import(type) { | |
396 | + importQuestion(type) { | |
360 | 397 | this.importType = type; |
361 | 398 | this.diaUp = true; |
362 | 399 | }, |
... | ... | @@ -373,13 +410,48 @@ export default { |
373 | 410 | }); |
374 | 411 | this.diaUp = false; |
375 | 412 | let params = JSON.stringify(res.data); |
376 | - if (this.query.type == 2) { | |
377 | - this.toAdd({ params, isUpload: 1 }); | |
413 | + if (this.dataType == 1) { | |
414 | + this.toAdd({ params, isUpload: true }); | |
378 | 415 | } else { |
379 | - this.toAddQs({ params }); | |
416 | + this.toAddQs({ params, isUpload: true }); | |
380 | 417 | } |
381 | 418 | } |
382 | 419 | }, |
420 | + toAdd(query) { | |
421 | + if (!this.query.class) { | |
422 | + this.$message.warning("没有任课班级,请先设置。"); | |
423 | + return; | |
424 | + } | |
425 | + let routerItem = { | |
426 | + path: "/askPreparationQuestionsAdd", | |
427 | + query: { | |
428 | + ...query, | |
429 | + classId: this.query.class, | |
430 | + listType: 2, | |
431 | + listShare: 0, | |
432 | + subjectName: this.query.subject, | |
433 | + }, | |
434 | + }; | |
435 | + this.$router.push(routerItem); | |
436 | + }, | |
437 | + //去备题 | |
438 | + toAddQs(query) { | |
439 | + if (!this.query.class) { | |
440 | + this.$message.warning("没有任课班级,请先设置。"); | |
441 | + return; | |
442 | + } | |
443 | + let routerItem = { | |
444 | + path: "/testPaperAdd", | |
445 | + query: { | |
446 | + ...query, | |
447 | + classId: this.query.class, | |
448 | + listType: 2, | |
449 | + listShare: 0, | |
450 | + subjectName: this.query.subject, | |
451 | + }, | |
452 | + }; | |
453 | + this.$router.push(routerItem); | |
454 | + }, | |
383 | 455 | async _changeClass() { |
384 | 456 | await this._loadSubjectData(); |
385 | 457 | }, |
... | ... | @@ -488,7 +560,7 @@ export default { |
488 | 560 | this.createdCount = data?.myCount || 0; |
489 | 561 | this.sharedCount = data?.gradeCount || 0; |
490 | 562 | this.listPage.total = data.total; |
491 | - | |
563 | + | |
492 | 564 | if (this.tabType == "0") { |
493 | 565 | this.defaultList = []; |
494 | 566 | if (data?.list) this.defaultList = [...data?.list]; |
... | ... | @@ -504,11 +576,18 @@ export default { |
504 | 576 | query: { id: id }, |
505 | 577 | }; |
506 | 578 | if (this.dataType == '2') { |
507 | - routerItem.path = "/testPaperQuestionsDetail"; | |
579 | + var currentClass = this.classList.find(item => item.classId == this.query.class); | |
580 | + routerItem.query.paperId = routerItem.query.id; | |
581 | + routerItem.query.classId = currentClass.classId; | |
582 | + routerItem.query.isViewer = true; | |
583 | + routerItem.query.gradeName = currentClass.gradeName; | |
584 | + routerItem.query.paperType = 2; | |
585 | + routerItem.path = '/testPaperQuestionsUpdate'; | |
586 | + // routerItem.path = "/testPaperQuestionsDetail"; | |
508 | 587 | } |
509 | 588 | this.$router.push(routerItem); |
510 | 589 | }, |
511 | - _copy(currentRow) { | |
590 | + _copy(currentRow) { | |
512 | 591 | let routerItem = { |
513 | 592 | path: "/askPreparationQuestionsAdd", |
514 | 593 | query: { |
... | ... | @@ -530,19 +609,21 @@ export default { |
530 | 609 | |
531 | 610 | }, |
532 | 611 | _updateQ(item) { |
533 | - console.log(item) | |
612 | + | |
534 | 613 | var currentClass = this.classList.find(item => item.classId == this.query.class); |
535 | 614 | |
536 | 615 | let routerItem = { |
537 | 616 | path: "/askPreparationQuestionsUpdate", |
538 | 617 | query: { |
539 | - paperId: item.id, paperType: 1, | |
618 | + paperId: item.id, | |
619 | + paperType: 1, | |
540 | 620 | classId: currentClass.classId, |
541 | 621 | gradeName: currentClass.gradeName |
542 | 622 | }, |
543 | 623 | }; |
544 | 624 | |
545 | 625 | if (this.dataType == '2') { |
626 | + routerItem.query.paperType = 2; | |
546 | 627 | routerItem.path = "/testPaperQuestionsUpdate"; |
547 | 628 | } |
548 | 629 | |
... | ... | @@ -610,12 +691,15 @@ export default { |
610 | 691 | color: #667FFD; |
611 | 692 | line-height: 32px; |
612 | 693 | padding: 0 10px; |
613 | - height: 32px; | |
614 | 694 | margin-right: 10px; |
695 | + height: 32px; | |
696 | + margin-top: 3px; | |
615 | 697 | } |
616 | 698 | |
699 | + width: 48.5%; | |
700 | + display: inline-block; | |
617 | 701 | margin-bottom: 10px; |
618 | - height: 180px; | |
702 | + min-height: 190px; | |
619 | 703 | border: 1px solid #E6E9F4; |
620 | 704 | border-radius: 10px 10px 10px 10px; |
621 | 705 | box-shadow: 0px 4px 14px 0px rgba(0, 0, 0, 0.08); |
... | ... | @@ -628,13 +712,20 @@ export default { |
628 | 712 | font-size: 14px; |
629 | 713 | font-weight: 400; |
630 | 714 | |
715 | + .descption-label { | |
716 | + min-width: 120px; | |
717 | + } | |
718 | + | |
631 | 719 | .descption-tag-text { |
632 | 720 | margin-bottom: 20px; |
633 | 721 | display: flex; |
634 | 722 | justify-content: flex-start; |
635 | 723 | align-items: center; |
724 | + width: calc(100% - 5px); | |
636 | 725 | } |
637 | 726 | |
727 | + | |
728 | + | |
638 | 729 | .descption-text { |
639 | 730 | height: 30px; |
640 | 731 | margin-top: 10px; |
... | ... | @@ -660,13 +751,17 @@ export default { |
660 | 751 | } |
661 | 752 | |
662 | 753 | .title-text { |
663 | - font-weight: bold; | |
664 | - font-size: 20px; | |
665 | - color: #303133; | |
666 | - line-height: 28px; | |
667 | - height: 28px; | |
668 | - text-transform: none; | |
669 | - padding-bottom: 10px !important; | |
754 | + .title-label { | |
755 | + font-weight: bold; | |
756 | + font-size: 24px !important; | |
757 | + color: #303133; | |
758 | + line-height: 28px; | |
759 | + display: inline-block; | |
760 | + width: calc(100% - 100px); | |
761 | + height: 28px; | |
762 | + text-transform: none; | |
763 | + padding-bottom: 10px !important; | |
764 | + } | |
670 | 765 | |
671 | 766 | .dropdown-button { |
672 | 767 | .el-button { |
... | ... | @@ -682,7 +777,7 @@ export default { |
682 | 777 | } |
683 | 778 | |
684 | 779 | .left { |
685 | - height: 180px; | |
780 | + height: 190px; | |
686 | 781 | background-color: #41CC95; |
687 | 782 | vertical-align: middle; |
688 | 783 | border-radius: 10px 0px 0px 10px; | ... | ... |
src/views/basic/askTestQuestion/recycle.vue
... | ... | @@ -32,7 +32,7 @@ |
32 | 32 | <el-main> |
33 | 33 | <div style='position: relative;'> |
34 | 34 | <el-tabs v-model="tabType" v-loading="queryLoading" type="card" class="default-tabs"> |
35 | - <el-tab-pane :name="'0'" :label="`自编课件(${createdCount})`"> | |
35 | + <el-tab-pane :name="'0'" :label="`我自编的(${createdCount})`"> | |
36 | 36 | <el-table class="default-table" :data="defaultList"> |
37 | 37 | <el-table-column prop="id" label="试卷ID" width="100"></el-table-column> |
38 | 38 | <el-table-column prop="title" label="试卷名称"></el-table-column> |
... | ... | @@ -56,7 +56,7 @@ |
56 | 56 | </el-table-column> |
57 | 57 | </el-table> |
58 | 58 | </el-tab-pane> |
59 | - <el-tab-pane :name="'1'" :label="`共享课件(${sharedCount})`"> | |
59 | + <el-tab-pane :name="'1'" :label="`被共享的(${sharedCount})`"> | |
60 | 60 | <el-table class="default-table" :data="sharedList"> |
61 | 61 | <el-table-column prop="id" label="试卷ID" width="100"></el-table-column> |
62 | 62 | <el-table-column prop="title" label="试卷名称"></el-table-column> |
... | ... | @@ -66,11 +66,11 @@ |
66 | 66 | <el-table-column prop="createdTime" label="创建时间"></el-table-column> |
67 | 67 | <el-table-column prop="modifiedTime" label="删除时间"></el-table-column> |
68 | 68 | <el-table-column prop="createdTime" label="操作"> |
69 | - <template> | |
70 | - <el-button class="edit" type="text" size="mini" @click="modify(item)"> | |
69 | + <template slot-scope="scoped"> | |
70 | + <el-button class="edit" type="text" size="mini" @click="modify(scoped.row)"> | |
71 | 71 | 恢复 |
72 | 72 | </el-button> |
73 | - <el-popconfirm title="确定删除这张答题卡吗?" @confirm="remove(item)"> | |
73 | + <el-popconfirm title="确定删除这张答题卡吗?" @confirm="remove(scoped.row)"> | |
74 | 74 | <el-button style="color:red;margin-left: 10px;" slot="reference" class="delete" |
75 | 75 | type="text" size="mini"> |
76 | 76 | 删除 |
... | ... | @@ -96,6 +96,7 @@ |
96 | 96 | </el-container> |
97 | 97 | </template> |
98 | 98 | <script> |
99 | +import { setDateRules } from "utils"; | |
99 | 100 | export default { |
100 | 101 | data() { |
101 | 102 | return { |
... | ... | @@ -139,12 +140,21 @@ export default { |
139 | 140 | this.$store.getters.info.showRole || |
140 | 141 | this.$store.getters.info.permissions[0].role; |
141 | 142 | |
143 | + var dateRange = setDateRules('onDay'); | |
144 | + console.log(dateRange) | |
145 | + this.query.dateRange = [dateRange.startDay, dateRange.endDay]; | |
142 | 146 | await this._loadQueryDatas(); |
143 | 147 | await this._serach(); |
144 | 148 | |
145 | 149 | }, |
150 | + watch: { | |
151 | + 'tabType'() { | |
152 | + this.listPage.page = 1; | |
153 | + this._serach(); | |
154 | + } | |
155 | + }, | |
146 | 156 | methods: { |
147 | - async modify(obj) { | |
157 | + async modify(obj) { | |
148 | 158 | //恢复答题卡 |
149 | 159 | let modifyPaper = |
150 | 160 | this.role == "ROLE_PERSONAL" |
... | ... | @@ -152,10 +162,12 @@ export default { |
152 | 162 | : this.$request.modifyPaper; |
153 | 163 | const { data, status, info } = await modifyPaper({ |
154 | 164 | paperId: obj.id, |
155 | - status: 1, | |
165 | + share: this.tabType == '0' ? "0" : "1", | |
166 | + status: 1 | |
156 | 167 | }); |
157 | 168 | if (status == 0) { |
158 | 169 | let type = this.query.title ? 1 : 0; |
170 | + this.$message.success(info); | |
159 | 171 | this._serach(type); |
160 | 172 | } else { |
161 | 173 | this.$message.error(info); |
... | ... | @@ -169,9 +181,13 @@ export default { |
169 | 181 | : this.$request.delPaper; |
170 | 182 | const { data, status, info } = await delPaper({ |
171 | 183 | paperId: obj.id, |
184 | + share: this.tabType == '0' ? "0" : "1", | |
185 | + status: 2 | |
186 | + | |
172 | 187 | }); |
173 | 188 | if (status == 0) { |
174 | 189 | let type = this.query.title ? 1 : 0; |
190 | + this.$message.success(info); | |
175 | 191 | this._serach(type); |
176 | 192 | } else { |
177 | 193 | this.$message.error(info); |
... | ... | @@ -284,7 +300,7 @@ export default { |
284 | 300 | } |
285 | 301 | this.queryLoading = false; |
286 | 302 | this.createdCount = data?.myCount || 0; |
287 | - this.sharedCount = data?.gradeCount || 0; | |
303 | + this.sharedCount = data?.delShare || 0; | |
288 | 304 | this.listPage.total = data.total; |
289 | 305 | if (this.tabType == "0") { |
290 | 306 | this.defaultList = []; | ... | ... |
src/views/basic/askTestQuestion/report.vue
... | ... | @@ -4,24 +4,29 @@ |
4 | 4 | <div class="default-title">{{ dataType == "1" ? '随堂问报表' : '即时测报表' }}</div> |
5 | 5 | </el-header> |
6 | 6 | <div class="default-filter"> |
7 | - <el-input v-model="query.paper" placeholder="报表名称" suffix-icon="el-icon-search" class="filter-input" type="number" | |
8 | - clearable /> | |
7 | + <!-- <el-input v-model="query.paper" placeholder="报表名称" suffix-icon="el-icon-search" class="filter-input" type="number" | |
8 | + clearable /> --> | |
9 | 9 | <el-select @change="_changeClass" v-model="query.class" class="filter-select" placeholder="选择班级"> |
10 | 10 | <el-option v-for="item in classList " :key="item.classId" :label="item.className" :value="item.classId" /> |
11 | 11 | </el-select> |
12 | 12 | <el-select v-model="query.subject" v-if="role == 'ROLE_JIAOSHI'" placeholder="选择科目" class="filter-select"> |
13 | 13 | <el-option v-for=" item in subjectList" :key="item" :label="item" :value="item" /> |
14 | 14 | </el-select> |
15 | - <el-select v-model="query.subjects" collapse-tags v-if="role == 'ROLE_BANZHUREN'" multiple placeholder="选择科目" | |
15 | + <el-select v-model="query.subjects" style="width: 18%;" collapse-tags v-if="role == 'ROLE_BANZHUREN'" multiple placeholder="选择科目" | |
16 | 16 | class="filter-select"> |
17 | 17 | <el-option v-for="item in subjectList" :key="item" :label="item" :value="item"> |
18 | 18 | <!-- <el-checkbox :checked="checkedSubject.indexOf(item) >= 0" @click="subjectCheck(item)">{{ item }}</el-checkbox> --> |
19 | 19 | </el-option> |
20 | 20 | </el-select> |
21 | - <el-date-picker class="filter-datePicker" v-model="query.dateRange" type="daterange" range-separator="-" | |
22 | - value-format="yyyy-MM-dd"> | |
21 | + <el-date-picker class="filter-datePicker" @change="_dateChange" v-model="query.dateRange" type="daterange" | |
22 | + range-separator="-" value-format="yyyy-MM-dd"> | |
23 | 23 | </el-date-picker> |
24 | 24 | <el-button type="primary" @click="_serach"> 筛选 </el-button> |
25 | + <el-radio-group v-model="dateStatus" class="default-date-radio-group"> | |
26 | + <el-radio-button label="onDay">今天</el-radio-button> | |
27 | + <el-radio-button label="onWeek">本周</el-radio-button> | |
28 | + <el-radio-button label="onMonth">本月</el-radio-button> | |
29 | + </el-radio-group> | |
25 | 30 | </div> |
26 | 31 | <el-main> |
27 | 32 | <div style="position: relative"> |
... | ... | @@ -31,37 +36,43 @@ |
31 | 36 | :queryParams="query" /> |
32 | 37 | </el-tab-pane> |
33 | 38 | <el-tab-pane v-if="dataType == 1 && role == 'ROLE_JIAOSHI'" :name="'1'" :label="`单课时报表`"> |
34 | - <askListReport v-if="apiDatas.askReportList" :datas="apiDatas.askReportList" /> | |
39 | + <askListReport v-if="apiDatas.askReportList" :datas="apiDatas.askReportList" @opration="_serach" /> | |
35 | 40 | </el-tab-pane> |
36 | - <el-tab-pane v-if="dataType == 1 && role == 'ROLE_BANZHUREN'" :name="'0'" :label="`多科表现`" | |
37 | - :queryParams="query"> | |
41 | + <el-tab-pane v-if="dataType == 1 && role == 'ROLE_BANZHUREN' && query.status == 'multi'" :name="'0'" | |
42 | + :label="`多科表现`" :queryParams="query"> | |
38 | 43 | <askBzrMulti v-if="apiDatas.askReportIds" :askReportIds="apiDatas.askReportIds" :queryParams="query" /> |
39 | - <!-- <askSummaryReport v-else-if="query.status == 'single'" :testReportIds="apiDatas.testReportIds" | |
40 | - :queryParams="query" /> --> | |
44 | + </el-tab-pane> | |
45 | + <el-tab-pane v-if="dataType == 1 && role == 'ROLE_BANZHUREN' && query.status == 'single'" :name="'1'" | |
46 | + :label="`单科表现`" :queryParams="query"> | |
47 | + <askSummaryReport :role="role" ref="askSummaryReport" v-if="apiDatas.askReportIds" :askReportIds="apiDatas.askReportIds" | |
48 | + :queryParams="query" /> | |
41 | 49 | </el-tab-pane> |
42 | 50 | <el-tab-pane v-if="dataType == 2 && role == 'ROLE_JIAOSHI'" :name="'0'" :label="`阶段报表`"> |
43 | 51 | <testSummaryReport v-if="apiDatas.testReportIds" :testReportIds="apiDatas.testReportIds" |
44 | - :queryParams="query" /> | |
52 | + @headerClick="_headerClick" :queryParams="query" /> | |
45 | 53 | </el-tab-pane> |
46 | 54 | <el-tab-pane v-if="dataType == 2 && role == 'ROLE_JIAOSHI'" :name="'1'" :label="`单卷报表`"> |
47 | - <testListReport :datas="apiDatas.testReportList" /> | |
55 | + <testListReport :datas="apiDatas.testReportList" @opration="_serach" /> | |
48 | 56 | </el-tab-pane> |
49 | 57 | <el-tab-pane v-if="dataType == 2 && role == 'ROLE_JIAOSHI'" :name="'2'" :label="`多班对比报表`"> |
50 | 58 | <testMultiClassReport :params="query" /> |
51 | 59 | </el-tab-pane> |
52 | - <el-tab-pane v-if="dataType == 2 && role == 'ROLE_BANZHUREN'" :name="'0'" :label="`多科表现`"> | |
60 | + <el-tab-pane v-if="dataType == 2 && role == 'ROLE_BANZHUREN' && query.status == 'multi'" :name="'0'" | |
61 | + :label="`多科表现`"> | |
53 | 62 | <testBzrMulti v-if="apiDatas.testReportIds" :list="apiDatas.testReportList" |
54 | 63 | :testReportIds="apiDatas.testReportIds" :queryParams="query" /> |
55 | - | |
56 | - <!-- <testSummaryReport v-else-if="apiDatas.testReportIds" :testReportIds="apiDatas.testReportIds" | |
57 | - :queryParams="query" /> --> | |
64 | + </el-tab-pane> | |
65 | + <el-tab-pane v-if="dataType == 2 && role == 'ROLE_BANZHUREN' && query.status == 'single'" :name="'1'" | |
66 | + :label="`单科表现`"> | |
67 | + <testSummaryReport v-if="apiDatas.testReportIds" :role="role" :list="apiDatas.testReportList" | |
68 | + :testReportIds="apiDatas.testReportIds" :queryParams="query" /> | |
58 | 69 | </el-tab-pane> |
59 | 70 | <div slot="tab-bar"> |
60 | 71 | <el-button type="primary" icon="el-icon-plus">新增</el-button> |
61 | 72 | </div> |
62 | 73 | </el-tabs> |
63 | - <el-button size='mini' v-if="role == 'ROLE_PERSONAL' || role == 'ROLE_JIAOSHI'" @click="_recycle" | |
64 | - style='position: absolute;right:40px;top:5px;'>查看回收站</el-button> | |
74 | + <!-- <el-button size='mini' v-if="role == 'ROLE_PERSONAL' || role == 'ROLE_JIAOSHI'" @click="_recycle" | |
75 | + style='position: absolute;right:40px;top:5px;'>查看回收站</el-button> --> | |
65 | 76 | |
66 | 77 | </div> |
67 | 78 | </el-main> |
... | ... | @@ -69,6 +80,7 @@ |
69 | 80 | </template> |
70 | 81 | |
71 | 82 | <script> |
83 | +import { setDateRules } from "@/utils"; | |
72 | 84 | export default { |
73 | 85 | name: "repo", |
74 | 86 | components: { |
... | ... | @@ -111,9 +123,15 @@ export default { |
111 | 123 | testReportList: null, |
112 | 124 | }, |
113 | 125 | queryLoading: false, |
126 | + dateStatus: "0" | |
114 | 127 | }; |
115 | 128 | }, |
116 | 129 | watch: { |
130 | + 'dateStatus'(val) { | |
131 | + if (val == -1) return; | |
132 | + var dateRange = setDateRules(val); | |
133 | + this.query.dateRange = [dateRange.startDay, dateRange.endDay]; | |
134 | + }, | |
117 | 135 | '$route'() { |
118 | 136 | this.dataType = location.href.endsWith("askReport") ? "1" : "2"; |
119 | 137 | this._loadQueryDatas(); |
... | ... | @@ -127,14 +145,16 @@ export default { |
127 | 145 | } |
128 | 146 | }, |
129 | 147 | async 'query.subjects'(value) { |
130 | - console.log(value) | |
131 | 148 | if (this.role == "ROLE_BANZHUREN") { |
132 | 149 | if (value.length == 1 && value[0] != '全部科目') { |
133 | 150 | this.query.status = 'single'; |
151 | + this.tabType = '1'; | |
134 | 152 | await this._serach(); |
135 | 153 | } |
136 | 154 | else { |
137 | - | |
155 | + this.query.status = 'multi'; | |
156 | + this.tabType = '0'; | |
157 | + await this._serach(); | |
138 | 158 | } |
139 | 159 | } |
140 | 160 | |
... | ... | @@ -146,9 +166,30 @@ export default { |
146 | 166 | this.role = |
147 | 167 | this.$store.getters.info.showRole || |
148 | 168 | this.$store.getters.info.permissions[0].role; |
169 | + this.dateStatus = "onWeek"; | |
149 | 170 | await this._loadQueryDatas(); |
150 | 171 | }, |
151 | 172 | methods: { |
173 | + _opr() { | |
174 | + alert('opr'); | |
175 | + }, | |
176 | + _dateChange() { | |
177 | + this.dateStatus = -1; | |
178 | + }, | |
179 | + async _ReScore() { | |
180 | + //重新记分 | |
181 | + let { data, info, status } = await this.$request.reScore({ | |
182 | + examId: this.id, | |
183 | + }); | |
184 | + if (status === 0) { | |
185 | + this.$message.success(info); | |
186 | + this._serach(); | |
187 | + this.paperModifyLog.modifiedTime = ""; | |
188 | + this.paperModifyLog.realName = ""; | |
189 | + } else { | |
190 | + this.$message.error(info); | |
191 | + } | |
192 | + }, | |
152 | 193 | async _changeClass() { |
153 | 194 | await this._loadSubjectData(); |
154 | 195 | }, |
... | ... | @@ -202,7 +243,7 @@ export default { |
202 | 243 | }, |
203 | 244 | _recycle() { }, |
204 | 245 | async _serach() { |
205 | - | |
246 | + | |
206 | 247 | this.queryLoading = true; |
207 | 248 | var queryParams = { |
208 | 249 | classId: "", |
... | ... | @@ -214,12 +255,15 @@ export default { |
214 | 255 | |
215 | 256 | queryParams.classId = this.query.class; |
216 | 257 | queryParams.classIds = [this.query.class]; |
217 | - if (this.query.subjects) { | |
258 | + | |
259 | + if (this.query.subjects && this.role == 'ROLE_BANZHUREN') { | |
218 | 260 | queryParams.subjectNames = this.query.subjects; |
261 | + queryParams.subject = queryParams.subjectNames[0]; | |
219 | 262 | } |
220 | 263 | else { |
221 | 264 | queryParams.subjectNames = [this.query.subject]; |
222 | 265 | } |
266 | + console.log(queryParams, this.query.subject) | |
223 | 267 | |
224 | 268 | queryParams.startDay = this.query.dateRange |
225 | 269 | ? this.query.dateRange[0] |
... | ... | @@ -266,10 +310,15 @@ export default { |
266 | 310 | this.$message.error(testReportResponse.info); |
267 | 311 | return; |
268 | 312 | } |
313 | + | |
269 | 314 | this.apiDatas.testReportList = [...testReportResponse?.data?.list ?? []]; |
315 | + | |
270 | 316 | this.apiDatas.testReportIds = [...this.apiDatas.testReportList?.map((item) => item.id) ?? []]; |
317 | + | |
271 | 318 | } |
319 | + | |
272 | 320 | this.tabIndexs += 1; |
321 | + | |
273 | 322 | this.queryLoading = false; |
274 | 323 | |
275 | 324 | }, |
... | ... | @@ -288,6 +337,17 @@ export default { |
288 | 337 | }; |
289 | 338 | this.$router.push(routerItem); |
290 | 339 | }, |
340 | + _headerClick(row) { | |
341 | + this.$router.push({ | |
342 | + path: "/testReportDetail", | |
343 | + query: { | |
344 | + dataType: 2, | |
345 | + classIds: this.query.class, | |
346 | + id: row.examId, | |
347 | + title: row.title | |
348 | + }, | |
349 | + }); | |
350 | + }, | |
291 | 351 | async _deleteDetermineQ(id) { |
292 | 352 | let modifyPaper = |
293 | 353 | this.role == "ROLE_PERSONAL" | ... | ... |
src/views/basic/askTestQuestion/update.vue
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | <back-box class="detailBack"> |
5 | 5 | <template slot="title"> |
6 | 6 | <span class="default-title"> |
7 | - {{ type == 1 ? "修改试卷" : "修改答案" }}</span> | |
7 | + {{ isViewer ? "详情" : type == 1 ? paperType == 1 ? "修改课件" : "修改试卷" : "修改答案" }}</span> | |
8 | 8 | </template> |
9 | 9 | </back-box> |
10 | 10 | </el-header> |
... | ... | @@ -21,103 +21,207 @@ |
21 | 21 | <div class="answer-title" :class="type == 1 ? 't-left' : ''"> |
22 | 22 | <p class="name-box"> |
23 | 23 | <span>试卷名称:</span> |
24 | - <el-input class="ipt-name" v-model="form.title"></el-input> | |
24 | + <el-input :disabled="isViewer" class="ipt-name" v-model="form.title"></el-input> | |
25 | 25 | </p> |
26 | 26 | <p class="name-box"> |
27 | 27 | <span>分享范围:</span> |
28 | - <el-radio class="name-radio" v-model="form.sharingType" :label="0">任课班级分享</el-radio> | |
29 | - <el-radio class="name-radio" @click.native="_selectClassSharingType" v-model="form.sharingType" | |
30 | - :label="1">自定义分享班级</el-radio> | |
28 | + <el-radio :disabled="isViewer" class="name-radio" v-model="form.sharingType" :label="0">任课班级分享</el-radio> | |
29 | + <el-radio :disabled="isViewer" class="name-radio" @click.native="_selectClassSharingType" | |
30 | + v-model="form.sharingType" :label="1">自定义分享班级</el-radio> | |
31 | 31 | </p> |
32 | 32 | </div> |
33 | 33 | <div class="question-box"> |
34 | - <div v-if="paperType == 1"> | |
35 | - <div class="courseware"> | |
36 | - <div class="courseware-title sub-questions"> | |
37 | - <div class="qs-num">题号</div> | |
38 | - <div class="qs-stem">题干</div> | |
39 | - <div class="qs-type">题型</div> | |
40 | - <div class="qs-score">分数</div> | |
41 | - <div class="qs-partScore">漏选得分</div> | |
42 | - <div class="qs-options">选项设置</div> | |
43 | - <div class="qs-oprations">操作</div> | |
44 | - </div> | |
45 | - <div v-for="(question, index) in questionList"> | |
46 | - <div class="courseware-content sub-questions" v-for="(subQuestion, subIndex) in question.subQuestions"> | |
47 | - <div class="qs-num">{{ subQuestion.questionId }}</div> | |
48 | - <div class="qs-stem"> | |
49 | - <iframe style="height: 100% !important" class="screenshot" :src="subQuestion.screenshot"></iframe> | |
50 | - </div> | |
51 | - <div class="qs-type"> | |
52 | - <el-select v-model="subQuestion.questionType"> | |
53 | - <el-option v-for="item in questionOption" :key="item.Key" :label="item.Text" :value="item.Key" /> | |
54 | - </el-select> | |
34 | + <div class="question-content"> | |
35 | + <div v-if="paperType == 1" class="courseware-title sub-questions"> | |
36 | + <div class="qs-num">题号</div> | |
37 | + <div class="qs-stem">题干</div> | |
38 | + <div class="qs-type">题型</div> | |
39 | + <div class="qs-score">分数</div> | |
40 | + <div class="qs-partScore">漏选得分</div> | |
41 | + <div class="qs-options">选项设置</div> | |
42 | + <div v-if="!isViewer" class="qs-oprations">操作</div> | |
43 | + </div> | |
44 | + <div> | |
45 | + <div class="question-contents" v-for="(question, index) in questionList"> | |
46 | + <div :class="paperType != 1 ? 'bigQuestion' : ''"> | |
47 | + <div class="bigQuestionTitle" v-if="paperType != 1"> | |
48 | + {{ question.questionTitle }} | |
49 | + (共{{ question.subQuestions.filter(subQuestion => subQuestion && | |
50 | + subQuestion.questionId && subQuestion.questionType).length }}小题, | |
51 | + 共{{ question.score }}分) | |
55 | 52 | </div> |
56 | - <div class="qs-score"> | |
57 | - <el-input-number class="number-ipt" size="medium" :min="1" :max="200" :precision="2" :step="1" | |
58 | - v-model="subQuestion.score" label="单题分值" /> | |
53 | + <div v-if="paperType == 2 && index == 0" class="courseware-title sub-questions"> | |
54 | + <div class="qs-num">题号</div> | |
55 | + <div class="qs-stem">题干</div> | |
56 | + <div class="qs-type">题型</div> | |
57 | + <div class="qs-score">分数</div> | |
58 | + <div class="qs-partScore">漏选得分</div> | |
59 | + <div class="qs-options">选项设置</div> | |
60 | + <div v-if="!isViewer" class="qs-oprations">操作</div> | |
59 | 61 | </div> |
60 | - <div class="qs-partScore"> | |
61 | - <p v-if="subQuestion.questionType != 3">------</p> | |
62 | - <el-input-number class="number-ipt" v-else size="medium" :min="0" :precision="2" | |
63 | - :max="subQuestion.score" :step="0.5" v-model="subQuestion.partScore" label="漏选得分" /> | |
62 | + | |
63 | + <div class="courseware-content sub-questions" v-if="subQuestion && | |
64 | + subQuestion.questionId && subQuestion.questionType && question.subQuestions" | |
65 | + v-for="(subQuestion, subIndex) in question.subQuestions"> | |
66 | + <div class="qs-num">{{ subQuestion.questionId }}</div> | |
67 | + <div class="qs-stem"> | |
68 | + <iframe style="height: 100% !important" class="screenshot" :src="subQuestion.screenshot"></iframe> | |
69 | + </div> | |
70 | + <div class="qs-type"> | |
71 | + <el-select :disabled="isViewer" v-model="subQuestion.questionType"> | |
72 | + <el-option v-for="item in questionOption" :key="item.Key" :label="item.Text" | |
73 | + :value="item.Key" /> | |
74 | + </el-select> | |
75 | + </div> | |
76 | + <div class="qs-score"> | |
77 | + <el-input-number :disabled="isViewer" class="number-ipt" size="medium" :min="1" :max="200" | |
78 | + :precision="2" :step="1" v-model="subQuestion.score" label="单题分值" /> | |
79 | + </div> | |
80 | + <div class="qs-partScore"> | |
81 | + <p v-if="subQuestion.questionType != 3">------</p> | |
82 | + <el-input-number class="number-ipt" v-else size="medium" :min="0" :precision="2" | |
83 | + :max="subQuestion.score" :step="0.5" v-model="subQuestion.partScore" label="漏选得分" /> | |
84 | + </div> | |
85 | + <div class="qs-options"> | |
86 | + <p v-if="subQuestion.questionType == 5">--</p> | |
87 | + <p v-if="subQuestion.questionType == 4" class="answer-box"> | |
88 | + <span class="answer-s" v-if="!isViewer" | |
89 | + :class="subQuestion.correctAnswer == 1 ? 'answer-active' : ''" | |
90 | + @click="subQuestion.correctAnswer = 1">✓</span> | |
91 | + <span class="answer-s" v-if="!isViewer" | |
92 | + :class="subQuestion.correctAnswer == 2 ? 'answer-active' : ''" | |
93 | + @click="subQuestion.correctAnswer = 2">✗</span> | |
94 | + <span class="answer-s" v-if="isViewer" | |
95 | + :class="subQuestion.correctAnswer == 1 ? 'answer-active' : ''">✓</span> | |
96 | + <span class="answer-s" v-if="isViewer" | |
97 | + :class="subQuestion.correctAnswer == 2 ? 'answer-active' : ''">✗</span> | |
98 | + </p> | |
99 | + <p v-if="subQuestion.questionType == 3" class="answer-box"> | |
100 | + <template :disabled="isViewer" v-for="option in subQuestion.answerOptions.split(',')"> | |
101 | + <span v-if="option && !isViewer" class="answer-s" | |
102 | + :class="subQuestion.correctAnswer.includes(option) ? 'answer-active' : ''" :key="option" | |
103 | + @click="changAnswer(subQuestion, option)">{{ option }}</span> | |
104 | + <span v-if="option && isViewer" class="answer-s" | |
105 | + :class="subQuestion.correctAnswer.includes(option) ? 'answer-active' : ''" :key="option">{{ | |
106 | + option }}</span> | |
107 | + </template> | |
108 | + <span class="answer-s answer-opration" v-if="!isViewer" | |
109 | + @click="openStem(subQuestion, 4, index, subIndex)">+</span> | |
110 | + <span class="answer-s answer-opration" v-if="!isViewer" | |
111 | + @click="openStem(subQuestion, 4, index, subIndex)">-</span> | |
112 | + </p> | |
113 | + <p v-if="subQuestion.questionType == 2" class="answer-box"> | |
114 | + <template :disabled="isViewer" v-for="option in subQuestion.answerOptions.split(',')"> | |
115 | + <span class="answer-s" v-if="option && !isViewer" | |
116 | + :class="subQuestion.correctAnswer == option ? 'answer-active' : ''" :key="option" | |
117 | + @click="subQuestion.correctAnswer = option">{{ option }}</span> | |
118 | + <span v-if="option && isViewer" class="answer-s" | |
119 | + :class="subQuestion.correctAnswer.includes(option) ? 'answer-active' : ''" :key="option">{{ | |
120 | + option }}</span> | |
121 | + </template> | |
122 | + <span class="answer-s answer-opration" v-if="!isViewer" | |
123 | + @click="openStem(subQuestion, 4, index, subIndex)">+</span> | |
124 | + <span class="answer-s answer-opration" v-if="!isViewer" | |
125 | + @click="openStem(subQuestion, 5, index, subIndex)">-</span> | |
126 | + </p> | |
127 | + </div> | |
128 | + <div class="qs-oprations" v-if="!isViewer"> | |
129 | + <div class="qs-set"> | |
130 | + <el-button class="icon-tickets" type="text" | |
131 | + @click="openStem(subQuestion, 1, index, subIndex)">修改题干</el-button> | |
132 | + </div> | |
133 | + <div class="qs-set"> | |
134 | + <el-button class="icon-tickets" type="text" | |
135 | + @click="openStem(subQuestion, 2, index, subIndex)">修改解析</el-button> | |
136 | + </div> | |
137 | + <div class="qs-set" v-if="false"> | |
138 | + <el-button type="text" @click="openKnowledge(subQuestion, index, subIndex)">修改知识点</el-button> | |
139 | + </div> | |
140 | + <div class="qs-set" style="margin-left:10px"> | |
141 | + <el-popconfirm @confirm="_deleteDetermineQ(subIndex, index)" title="这是一小题确定删除吗?"> | |
142 | + <!-- <el-button style="color:red" type="text" slot="reference">删除</el-button> --> | |
143 | + </el-popconfirm> | |
144 | + </div> | |
145 | + </div> | |
64 | 146 | </div> |
65 | - <div class="qs-options"> | |
66 | - <p v-if="subQuestion.questionType == 5">--</p> | |
67 | - <p v-if="subQuestion.questionType == 4" class="answer-box"> | |
68 | - <span class="answer-s" :class="subQuestion.correctAnswer == 1 ? 'answer-active' : '' | |
69 | - " @click="subQuestion.correctAnswer = 1">✓</span> | |
70 | - <span class="answer-s" :class="subQuestion.correctAnswer == 2 ? 'answer-active' : '' | |
71 | - " @click="subQuestion.correctAnswer = 2">✗</span> | |
72 | - </p> | |
73 | - <p v-if="subQuestion.questionType == 3" class="answer-box"> | |
74 | - <template v-for="option in subQuestion.answerOptions.split(',')"> | |
75 | - <span v-if="option" class="answer-s" :class="subQuestion.correctAnswer.includes(option) | |
147 | + <div v-if="!question.subQuestions" class="courseware-content sub-questions"> | |
148 | + <div class="qs-num">{{ question.questionId }}</div> | |
149 | + <div class="qs-stem"> | |
150 | + <iframe style="height: 100% !important" class="screenshot" :src="question.screenshot"></iframe> | |
151 | + </div> | |
152 | + <div class="qs-type"> | |
153 | + <el-select v-model="question.questionType"> | |
154 | + <el-option :disabled="isViewer" v-for="item in questionOption" :key="item.Key" | |
155 | + :label="item.Text" :value="item.Key" /> | |
156 | + </el-select> | |
157 | + </div> | |
158 | + <div class="qs-score"> | |
159 | + <el-input-number :disabled="isViewer" class="number-ipt" size="medium" :min="1" :max="200" | |
160 | + :precision="2" :step="1" v-model="question.score" label="单题分值" /> | |
161 | + </div> | |
162 | + <div class="qs-partScore"> | |
163 | + <p v-if="question.questionType != 3">------</p> | |
164 | + <el-input-number class="number-ipt" v-else size="medium" :min="0" :precision="2" | |
165 | + :max="question.score" :step="0.5" v-model="question.partScore" label="漏选得分" /> | |
166 | + </div> | |
167 | + <div class="qs-options"> | |
168 | + <p v-if="question.questionType == 5">--</p> | |
169 | + <p v-if="question.questionType == 4" class="answer-box"> | |
170 | + <span class="answer-s" :class="question.correctAnswer == 1 ? 'answer-active' : '' | |
171 | + " @click="question.correctAnswer = 1">✓</span> | |
172 | + <span class="answer-s" :class="question.correctAnswer == 2 ? 'answer-active' : '' | |
173 | + " @click="question.correctAnswer = 2">✗</span> | |
174 | + </p> | |
175 | + <p v-if="question.questionType == 3" class="answer-box"> | |
176 | + <template v-for="option in question.answerOptions.split(',')"> | |
177 | + <span v-if="option" class="answer-s" :class="question.correctAnswer.includes(option) | |
76 | 178 | ? 'answer-active' |
77 | 179 | : '' |
78 | - " :key="option" @click="changAnswer(subQuestion, option)">{{ option }}</span> | |
79 | - </template> | |
80 | - <span class="answer-s answer-opration" @click="openStem(subQuestion, 4, index, subIndex)">+</span> | |
81 | - <span class="answer-s answer-opration" @click="openStem(subQuestion, 4, index, subIndex)">-</span> | |
82 | - </p> | |
83 | - <p v-if="subQuestion.questionType == 2" class="answer-box"> | |
84 | - <template v-for="option in subQuestion.answerOptions.split(',')"> | |
85 | - <span class="answer-s" v-if="option" :class="subQuestion.correctAnswer == option | |
180 | + " :key="option" @click="changAnswer(question, option)">{{ option }}</span> | |
181 | + </template> | |
182 | + <span class="answer-s answer-opration" v-if="!isViewer" | |
183 | + @click="openStem(question, 4, index, 0)">+</span> | |
184 | + <span class="answer-s answer-opration" v-if="!isViewer" | |
185 | + @click="openStem(question, 4, index, 0)">-</span> | |
186 | + </p> | |
187 | + <p v-if="question.questionType == 2" class="answer-box"> | |
188 | + <template v-for="option in question.answerOptions.split(',')"> | |
189 | + <span class="answer-s" v-if="option" :class="question.correctAnswer == option | |
86 | 190 | ? 'answer-active' |
87 | 191 | : '' |
88 | - " :key="option" @click="subQuestion.correctAnswer = option">{{ option }}</span> | |
89 | - </template> | |
90 | - <span class="answer-s answer-opration" @click="openStem(subQuestion, 4, index, subIndex)">+</span> | |
91 | - <span class="answer-s answer-opration" @click="openStem(subQuestion, 5, index, subIndex)">-</span> | |
92 | - </p> | |
93 | - </div> | |
94 | - <div class="qs-oprations"> | |
95 | - <div class="qs-set"> | |
96 | - <el-button class="icon-tickets" type="text" circle size="mini" | |
97 | - @click="openStem(subQuestion, 1, index, subIndex)">修改题干</el-button> | |
98 | - </div> | |
99 | - <div class="qs-set"> | |
100 | - <el-button class="icon-tickets" type="text" circle size="mini" | |
101 | - @click="openStem(subQuestion, 2, index, subIndex)">修改解析</el-button> | |
192 | + " :key="option" @click="question.correctAnswer = option">{{ option }}</span> | |
193 | + </template> | |
194 | + <span class="answer-s answer-opration" v-if="!isViewer" | |
195 | + @click="openStem(question, 4, index, 0)">+</span> | |
196 | + <span class="answer-s answer-opration" v-if="!isViewer" | |
197 | + @click="openStem(question, 5, index, 0)">-</span> | |
198 | + </p> | |
102 | 199 | </div> |
103 | - <div class="qs-set"> | |
104 | - <el-button type="text" circle size="mini" | |
105 | - @click="openKnowledge(subQuestion, index, subIndex)">修改知识点</el-button> | |
106 | - </div> | |
107 | - <div class="qs-set"> | |
108 | - <el-button type="text" circle size="mini" | |
109 | - @click="openStem(subQuestion, 3, index, subIndex)">删除</el-button> | |
200 | + <div class="qs-oprations"> | |
201 | + <div class="qs-set"> | |
202 | + <el-button class="icon-tickets" type="text" | |
203 | + @click="openStem(question, 1, index, 0)">修改题干</el-button> | |
204 | + </div> | |
205 | + <div class="qs-set"> | |
206 | + <el-button class="icon-tickets" type="text" | |
207 | + @click="openStem(question, 2, index, 0)">修改解析</el-button> | |
208 | + </div> | |
209 | + <div class="qs-set" v-if="false"> | |
210 | + <el-button type="text" @click="openKnowledge(question, index, 0)">修改知识点</el-button> | |
211 | + </div> | |
212 | + <div class="qs-set" style="margin-left:10px"> | |
213 | + <el-popconfirm @confirm="_deleteDetermineQ(0, index)" title="这是一小题确定删除吗?"> | |
214 | + <!-- <el-button style="color:red" type="text" slot="reference">删除</el-button> --> | |
215 | + </el-popconfirm> | |
216 | + </div> | |
110 | 217 | </div> |
111 | 218 | </div> |
112 | 219 | </div> |
113 | 220 | </div> |
114 | 221 | </div> |
115 | 222 | </div> |
116 | - <div v-if="paperType == 2"> | |
117 | - <div class="paper"></div> | |
118 | - </div> | |
119 | 223 | </div> |
120 | - <el-dialog :close-on-click-modal="false" title="选择班级分享" :visible.sync="classSharingType" width="400" | |
224 | + <el-dialog :close-on-click-modal="false" title="选择班级分享" :visible.sync="classSharingType" width="800" | |
121 | 225 | :modal-append-to-body="false" :append-to-body="true"> |
122 | 226 | <div> |
123 | 227 | <el-row class="row-subfix"> |
... | ... | @@ -126,23 +230,26 @@ |
126 | 230 | <span class="line-value">{{ gradeName }}</span> |
127 | 231 | </div> |
128 | 232 | </el-row> |
129 | - <el-row class="row-subfix"> | |
233 | + <el-row class="row-subfix" style="margin-top: 20px;"> | |
130 | 234 | <span class="line-subfix" style="float: left;">班级:</span> |
131 | - <div class="row-line" style="float: left;"> | |
132 | - <span class="line-value" style=" border-radius: 4px; background: rgb(247,247,250);"> | |
235 | + <div class="row-line" style="float: left; | |
236 | + background:rgb(245,247,250);padding:15px 10px;width: calc(100% - 80px);border-radius:5px;"> | |
237 | + <span class="line-value" style="min-height: 300px;border-radius: 4px; background: rgb(247,247,250);"> | |
133 | 238 | <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" |
134 | 239 | @change="handleCheckAllChange">全选</el-checkbox> |
135 | - <el-checkbox-group v-model="checkedClass" @change="handleCheckedClassChange"> | |
136 | - <el-checkbox v-for="(item, index) in gradeClass" :label="item.id" :key="item.id">{{ | |
137 | - item.className }}</el-checkbox> | |
240 | + <el-checkbox-group v-model="checkedClass" style="margin-top: 15px;" | |
241 | + @change="handleCheckedClassChange"> | |
242 | + <el-checkbox v-for="(item, index) in gradeClass" :label="item.id" :key="item.id"> | |
243 | + {{ item.className }} | |
244 | + </el-checkbox> | |
138 | 245 | </el-checkbox-group> |
139 | 246 | </span> |
140 | 247 | </div> |
141 | 248 | </el-row> |
142 | - <el-row class="row-subfix" style="float:right;margin-right: 20px;"> | |
143 | - <el-button type="danger" @click="() => { classSharingType == false }">取消</el-button> | |
144 | - <el-button type="primary" @click="_checkedClass">确定</el-button> | |
145 | - </el-row> | |
249 | + </div> | |
250 | + <div slot="footer"> | |
251 | + <el-button type="info" :size="'small'" @click="classSharingType = false">取消</el-button> | |
252 | + <el-button type="primary" :size="'small'" @click="_checkedClass">确定</el-button> | |
146 | 253 | </div> |
147 | 254 | </el-dialog> |
148 | 255 | <el-dialog :close-on-click-modal="false" title="批量设置答案" :visible.sync="diaSetAns" width="400" |
... | ... | @@ -215,8 +322,8 @@ |
215 | 322 | <el-button @click="dialogStem = false">确定</el-button> |
216 | 323 | </div> |
217 | 324 | </el-dialog> |
218 | - <el-dialog :append-to-body="true" :close-on-click-modal="false" title="知识点" :visible.sync="dialogKnowledge" width="500px" | |
219 | - :append-to-body="true"> | |
325 | + <el-dialog :append-to-body="true" :close-on-click-modal="false" title="知识点" :visible.sync="dialogKnowledge" | |
326 | + width="500px"> | |
220 | 327 | <div> |
221 | 328 | <el-form ref="form" :model="stem" label-width="160px"> |
222 | 329 | <el-form-item label="知识点:"> |
... | ... | @@ -236,8 +343,8 @@ |
236 | 343 | </el-dialog> |
237 | 344 | </div> |
238 | 345 | <div class="content-fi"> |
239 | - <el-button type="danger" @click="linkBack">取消</el-button> | |
240 | - <el-button type="primary" @click="save">保存</el-button> | |
346 | + <el-button type="info" @click="linkBack">取消</el-button> | |
347 | + <el-button class="green-el-button" @click="save">保存</el-button> | |
241 | 348 | </div> |
242 | 349 | </el-main> |
243 | 350 | </el-container> |
... | ... | @@ -251,10 +358,13 @@ export default { |
251 | 358 | return { |
252 | 359 | role: "", |
253 | 360 | title: "", |
361 | + classSharingType: false, | |
254 | 362 | gradeName: "", |
255 | 363 | checkAll: false, |
256 | 364 | checkedClass: [], |
257 | 365 | gradeClass: [], |
366 | + subjectName: "", | |
367 | + isViewer: false, | |
258 | 368 | isIndeterminate: true, |
259 | 369 | type: 1, //1:答题卡 2:即时测报表题目列表 3:课时题目列表 |
260 | 370 | questionList: [], |
... | ... | @@ -362,8 +472,10 @@ export default { |
362 | 472 | this.type = this.$route.query.type || 1; |
363 | 473 | this.examType = this.$route.query.examType || 2; |
364 | 474 | this.paperType = this.$route.query.paperType || 2; |
475 | + this.isViewer = this.$route.query.isViewer || false; | |
365 | 476 | this.classId = this.$route.query.classId || -1; |
366 | 477 | this.gradeName = this.$route.query.gradeName || ""; |
478 | + this.subjectName = this.$route.query.subjectName || ""; | |
367 | 479 | this.form.title = this.$route.query.title || ""; |
368 | 480 | this._QueryDetail(); |
369 | 481 | this._GradeList(); |
... | ... | @@ -373,7 +485,7 @@ export default { |
373 | 485 | this.classSharingType = false; |
374 | 486 | }, |
375 | 487 | handleCheckAllChange(val) { |
376 | - this.checkedClass = val ? this.gradeClass : []; | |
488 | + this.checkedClass = val ? this.gradeClass?.map(item => item.id) : []; | |
377 | 489 | this.isIndeterminate = false; |
378 | 490 | }, |
379 | 491 | handleCheckedClassChange(value) { |
... | ... | @@ -382,13 +494,21 @@ export default { |
382 | 494 | this.isIndeterminate = checkedCount > 0 && checkedCount < this.checkedClass.length; |
383 | 495 | }, |
384 | 496 | async _selectClassSharingType() { |
497 | + | |
498 | + if (this.isViewer) return; | |
499 | + | |
500 | + this.gradeClass = []; | |
501 | + | |
385 | 502 | this.classSharingType = true; |
386 | - var classResponse = await this.$request.tClassFromGrade(this.classId); | |
503 | + | |
504 | + var classResponse = await this.$request.tClassFromGrade(this.classId, this.form.subjectName); | |
387 | 505 | |
388 | 506 | if (classResponse.status != 0) { |
389 | 507 | this.$message.error(classResponse.info); |
390 | 508 | } |
391 | - this.gradeClass = classResponse.data; | |
509 | + | |
510 | + this.gradeClass = [...classResponse.data]; | |
511 | + | |
392 | 512 | }, |
393 | 513 | // v1.5 |
394 | 514 | //上传截图 |
... | ... | @@ -403,7 +523,7 @@ export default { |
403 | 523 | } |
404 | 524 | this.stem.screenshot = obj.screenshot || ""; |
405 | 525 | this.stem.answerScreenshot = ""; |
406 | - return; | |
526 | + // return; | |
407 | 527 | } else if (type == 3) { |
408 | 528 | } else if (type == 4) { |
409 | 529 | var current = this.questionList[index].subQuestions[indexs]; |
... | ... | @@ -516,6 +636,16 @@ export default { |
516 | 636 | } |
517 | 637 | return tit; |
518 | 638 | }, |
639 | + _deleteDetermineQ(subIndex, index) { | |
640 | + if (this.questionList[index].subQuestions) { | |
641 | + this.questionList[index].subQuestions.splice(subIndex, 1); | |
642 | + if (this.questionList[index].subQuestions?.length == 0) { | |
643 | + this.questionList.splice(index, 1); | |
644 | + } | |
645 | + } else { | |
646 | + this.questionList.splice(index, 1); | |
647 | + } | |
648 | + }, | |
519 | 649 | setBigNum(num) { |
520 | 650 | let txt = ""; |
521 | 651 | let bigNum = [ |
... | ... | @@ -759,7 +889,6 @@ export default { |
759 | 889 | }); |
760 | 890 | //更新答题卡 |
761 | 891 | let modifyPaper, params; |
762 | - console.log(this.type) | |
763 | 892 | if (this.type == 1) { |
764 | 893 | modifyPaper = |
765 | 894 | this.role == "ROLE_PERSONAL" |
... | ... | @@ -796,7 +925,16 @@ export default { |
796 | 925 | ...params, |
797 | 926 | }); |
798 | 927 | if (status == 0) { |
799 | - this.$router.go(-1); | |
928 | + if (this.paperType == 1) { | |
929 | + this.$router.push({ | |
930 | + path: "/askPreparationQuestions", | |
931 | + }); | |
932 | + } | |
933 | + else { | |
934 | + this.$router.push({ | |
935 | + path: "/testPaper", | |
936 | + }); | |
937 | + } | |
800 | 938 | } else { |
801 | 939 | this.$message.error(message); |
802 | 940 | } |
... | ... | @@ -837,7 +975,7 @@ export default { |
837 | 975 | ...this.form.paperModifyLog, |
838 | 976 | }; |
839 | 977 | this.form = deepClone(data); |
840 | - console.log(this.form.sharingType) | |
978 | + | |
841 | 979 | questionList = this.form.questionList.map((item) => { |
842 | 980 | if (item.subQuestions) { |
843 | 981 | item.subQuestions.map((subQuestion) => { |
... | ... | @@ -855,13 +993,17 @@ export default { |
855 | 993 | } |
856 | 994 | return item; |
857 | 995 | }); |
996 | + | |
997 | + | |
858 | 998 | } else { |
859 | 999 | questionList = data.list.sort((a, b) => { |
860 | 1000 | return a.questionIndex - b.questionIndex; |
861 | 1001 | }); |
862 | 1002 | } |
863 | 1003 | this.questionList = questionList; |
1004 | + console.log(this.questionList) | |
864 | 1005 | this.formateQuestion(); |
1006 | + this.checkedClass = data.classList?.map(item => item.classId); | |
865 | 1007 | } else { |
866 | 1008 | this.$message.error(info); |
867 | 1009 | } |
... | ... | @@ -997,7 +1139,22 @@ export default { |
997 | 1139 | }, |
998 | 1140 | }; |
999 | 1141 | </script> |
1000 | -<style> | |
1142 | +<style lang="scss"> | |
1143 | +.line-value { | |
1144 | + color: black; | |
1145 | +} | |
1146 | + | |
1147 | +.question-contents { | |
1148 | + | |
1149 | + .el-input__inner, | |
1150 | + .el-input, | |
1151 | + .el-select, | |
1152 | + .el-input-number__decrease, | |
1153 | + .el-input-number__increase { | |
1154 | + background: white !important; | |
1155 | + } | |
1156 | +} | |
1157 | + | |
1001 | 1158 | .screenshot-box { |
1002 | 1159 | width: 600px; |
1003 | 1160 | } |
... | ... | @@ -1019,7 +1176,7 @@ export default { |
1019 | 1176 | </style> |
1020 | 1177 | <style lang="scss" scoped> |
1021 | 1178 | .content-fi { |
1022 | - padding-top: 7px; | |
1179 | + padding-top: 12px; | |
1023 | 1180 | width: 200px; |
1024 | 1181 | margin: 0px auto; |
1025 | 1182 | } |
... | ... | @@ -1308,4 +1465,17 @@ export default { |
1308 | 1465 | .row-subfix { |
1309 | 1466 | margin-bottom: 10px; |
1310 | 1467 | } |
1468 | + | |
1469 | +.bigQuestion { | |
1470 | + padding: 20px; | |
1471 | + box-shadow: 0px 1px 4px 0px rgba(21, 34, 50, 0.08); | |
1472 | + border: 1px solid #ebeef5; | |
1473 | + border-radius: 5px; | |
1474 | + margin-top: 10px; | |
1475 | + | |
1476 | + .bigQuestionTitle { | |
1477 | + font-size: 16px; | |
1478 | + font-weight: bold; | |
1479 | + } | |
1480 | +} | |
1311 | 1481 | </style> | ... | ... |
src/views/basic/card/index.vue
... | ... | @@ -36,11 +36,11 @@ |
36 | 36 | <el-option label="换班" :value="2"></el-option> |
37 | 37 | </el-select> |
38 | 38 | <div class="d1"> |
39 | - <el-date-picker v-model="query.startDay" type="date" @change="handleChangeTimeStart" placeholder="选择日期时间" | |
39 | + <el-date-picker style="width: 40%;" v-model="query.startDay" type="date" @change="handleChangeTimeStart" placeholder="选择日期时间" | |
40 | 40 | value-format="yyyy-MM-dd"> |
41 | 41 | </el-date-picker> |
42 | 42 | ~ |
43 | - <el-date-picker v-model="query.endDay" type="date" placeholder="选择日期时间" @change="handleChangeTimeEnd" | |
43 | + <el-date-picker style="width: 40%;" v-model="query.endDay" type="date" placeholder="选择日期时间" @change="handleChangeTimeEnd" | |
44 | 44 | value-format="yyyy-MM-dd"> |
45 | 45 | </el-date-picker> |
46 | 46 | </div> | ... | ... |
src/views/basic/dataSync/index.vue
src/views/basic/device/index.vue
... | ... | @@ -1457,7 +1457,7 @@ export default { |
1457 | 1457 | align-items: center; |
1458 | 1458 | |
1459 | 1459 | .p1 { |
1460 | - font-size: 28px; | |
1460 | + font-size: 28px !important; | |
1461 | 1461 | } |
1462 | 1462 | } |
1463 | 1463 | |
... | ... | @@ -1473,7 +1473,7 @@ export default { |
1473 | 1473 | .loading { |
1474 | 1474 | text-align: center; |
1475 | 1475 | line-height: 36px; |
1476 | - font-size: 16px; | |
1476 | + font-size: 16px !important; | |
1477 | 1477 | color: #666; |
1478 | 1478 | } |
1479 | 1479 | ... | ... |
src/views/basic/down/index.vue
... | ... | @@ -31,8 +31,7 @@ |
31 | 31 | <el-button plan round @click="downCard">发卡软件下载</el-button> |
32 | 32 | </div> |
33 | 33 | <div class="down-item" v-loading="loading"> |
34 | - <p class="txt"> | |
35 | - 电脑缺少.NET Framework环境时,请下载安装.NET Framework | |
34 | + <p class="txt">电脑缺少.NET Framework环境时,请下载安装.NET Framework | |
36 | 35 | 4.5.2,以便于授课端可正常使用。 |
37 | 36 | </p> |
38 | 37 | <el-button plan round @click="downNet">.Net环境下载</el-button> |
... | ... | @@ -140,7 +139,7 @@ export default { |
140 | 139 | margin-left: 160px; |
141 | 140 | |
142 | 141 | .down-item { |
143 | - width: 200px; | |
142 | + width: 300px; | |
144 | 143 | padding: 50px 20px; |
145 | 144 | border-radius: 20px; |
146 | 145 | margin: 20px; |
... | ... | @@ -149,8 +148,7 @@ export default { |
149 | 148 | justify-content: center; |
150 | 149 | align-items: center; |
151 | 150 | background: #f8f8f8; |
152 | - box-shadow: 2px 2px 5px #ccc; | |
153 | - | |
151 | + box-shadow: 2px 2px 5px #ccc; | |
154 | 152 | .txt { |
155 | 153 | font-size: 16px; |
156 | 154 | color: #7f7f7f; | ... | ... |
src/views/basic/setUp/archived.vue
... | ... | @@ -7,90 +7,108 @@ |
7 | 7 | </back-box> |
8 | 8 | <div class="page-content"> |
9 | 9 | <el-steps :active="step" align-center class="step"> |
10 | - <el-step title="1 班级归档"></el-step> | |
11 | - <el-step title="2 分班后学生名单"></el-step> | |
10 | + <el-step title="1 解散班级"></el-step> | |
11 | + <el-step title="2 导入班级名单"></el-step> | |
12 | 12 | <el-step title="3 分班后任课老师"></el-step> |
13 | - <el-step title="4 授课端指引"></el-step> | |
14 | 13 | </el-steps> |
15 | 14 | <ul v-loading="loading"> |
16 | - <li v-show="step == 0"> | |
17 | - <div class="form-item"> | |
18 | - <span class="s-txt">选择分班年级:</span> | |
19 | - <el-select class="sel" v-model="grade" placeholder="选择年级" @change="changeGrade"> | |
20 | - <el-option v-for="item in gradeList" :key="item.value" :label="item.label" :value="item.value"> | |
21 | - </el-option> | |
22 | - </el-select> | |
23 | - </div> | |
24 | - <div class="form-item"> | |
25 | - <span class="s-txt">确定班级:</span> | |
26 | - <i class="el-icon-loading" v-show="loadingClass"></i> | |
27 | - <div class="check-box" v-if="classList.length && !loadingClass"> | |
28 | - <!-- <p class="all-check"> | |
29 | - <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" | |
30 | - @change="handleCheckAllChange">全选</el-checkbox> | |
31 | - </p> --> | |
32 | - <el-checkbox-group v-model="classIds" @change="handleCheckedChange"> | |
33 | - <el-checkbox disabled v-for="item in classList" :key="item.id" :label="item.id">{{ | |
34 | - item.className | |
35 | - }}</el-checkbox> | |
36 | - </el-checkbox-group> | |
15 | + <li v-show="step == 0" style="padding:0px 200px;"> | |
16 | + <el-row class="row-subfix" style="margin-top: 20px;"> | |
17 | + <el-row class="row-subfix"> | |
18 | + <div class="row-line"> | |
19 | + <span class="line-subfix">选择年级:</span> | |
20 | + <span class="line-value"> | |
21 | + <el-select class="sel" v-model="grade" placeholder="选择年级" @change="changeGrade"> | |
22 | + <el-option v-for="item in gradeList" :key="item.value" :label="item.label" :value="item.value"> | |
23 | + </el-option> | |
24 | + </el-select> | |
25 | + </span> | |
26 | + </div> | |
27 | + </el-row> | |
28 | + <el-row class="row-subfix" style="margin-top: 20px;"> | |
29 | + <span class="line-subfix" style="float: left;">选择班级:</span> | |
30 | + <div class="row-line" | |
31 | + style="float: left; background:rgb(245,247,250);padding:15px;width: calc(100% - 220px); border-radius:5px;"> | |
32 | + <span class="line-value" style="min-height: 300px;border-radius: 4px; background: rgb(247,247,250);"> | |
33 | + <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" | |
34 | + @change="handleCheckAllChange">全选</el-checkbox> | |
35 | + <el-checkbox-group v-model="checkedClass" style="margin-top: 15px;"> | |
36 | + <el-checkbox v-for="(item, index) in classList" :label="item.id" :key="item.id"> | |
37 | + {{ item.className }} | |
38 | + </el-checkbox> | |
39 | + </el-checkbox-group> | |
40 | + </span> | |
41 | + </div> | |
42 | + </el-row> | |
43 | + </el-row> | |
44 | + <el-row class="row-subfix form-item" style="margin-top: 20px;"> | |
45 | + <span class="line-subfix" style="float: left;"> <i class="el-icon-warning" /></span> | |
46 | + <div class="row-line" style="float: left; width: calc(100% - 220px); border-radius:5px;"> | |
47 | + <div>请谨慎操作,班级归档后,学生解除班级关系且相关老师任课信息将不存在。</div> | |
48 | + <div style="margin-top: 10px;opacity: 0.7;">如需保存解散前的班级名单与任课信息,可点击“保存名单”按钮。</div> | |
37 | 49 | </div> |
38 | - </div> | |
39 | - <div class="form-item"> | |
40 | - <span class="s-txt"></span> | |
41 | - <p class="tips"> | |
42 | - <i class="el-icon-warning"></i>请谨慎操作,班级归档后,学生解除班级关系且相关老师任课信息将不存在。 | |
43 | - </p> | |
44 | - </div> | |
45 | - <div class="btn-box"> | |
46 | - <el-button class="btn" round @click="toClazz">取消</el-button> | |
47 | - <el-popconfirm confirm-button-text="确定" cancel-button-text="取消" icon="el-icon-info" icon-color="red" | |
48 | - title="确定要将所选班级归档吗?" @confirm="_ClassArchiving"> | |
49 | - <el-button class="btn" slot="reference" type="primary" round>归档</el-button> | |
50 | + </el-row> | |
51 | + <div style="margin:0px auto;width: 30%;"> | |
52 | + <el-button style="background: rgb(218,225,235) ;color:black;border:none !important;" | |
53 | + @click="toClazz">取消</el-button> | |
54 | + <el-button type="primary" @click="_downNameList">保存名单</el-button> | |
55 | + <el-popconfirm confirm-button-text="确定" cancel-button-text="取消" title="确定要将所选班级解散吗吗?" | |
56 | + @confirm="_ClassArchiving"> | |
57 | + <el-button slot="reference" v-loading="loadingDown" | |
58 | + style="background: rgb(242,168,65) ;color:white;margin-left: 10px;border:none !important;">确定解散</el-button> | |
50 | 59 | </el-popconfirm> |
51 | 60 | </div> |
52 | 61 | </li> |
53 | 62 | <li v-show="step == 1"> |
54 | - <div class="step-item"> | |
55 | - <upload id="downTeacher" :url="urlClazz" @upSuccess="upStudentSuccess" fileName="学生名单模板"> | |
63 | + <el-row class="row-subfix form-item"> | |
64 | + <div class="row-line" style="float: left;"> | |
65 | + <div>通过导入EXCEL文件方式添加班级名单,请按需求下载对应班级类型板并填写班级名单信息后,导入系统:</div> | |
66 | + <div style="margin-top: 10px;opacity: 0.7;margin-left:20px;"> | |
67 | + 行政班定义:由固定学生、固定教室构成,由专门的班主任进行管理; | |
68 | + </div> | |
69 | + <div style="margin-top: 5px;opacity: 0.7;margin-left:20px;"> | |
70 | + 教学班定义:由不同行政班的学生临时组成,没有专门的班主任,是在选课制基础上,由于教学的需要而产生的。 | |
71 | + </div> | |
72 | + </div> | |
73 | + </el-row> | |
74 | + <el-row class="row-subfix form-item" style="margin-top: 20px;"> | |
75 | + <el-button :icon="'el-icon-document'" @click="_downTemplate(0)">下载行政班名单模板</el-button> | |
76 | + <el-button :icon="'el-icon-document'" @click="_downTemplate(1)">下载教学班名单模板</el-button> | |
77 | + </el-row> | |
78 | + <el-row class="row-subfix form-item" style="margin-top: 20px;"> | |
79 | + <upload id="downTeacher" drag :url="urlClazz" | |
80 | + style="border:rgb(219,226,235) dashed 1px;width: 100%;padding:40px 0px;border-radius: 5px;" | |
81 | + @upSuccess="upStudentSuccess" fileName="学生名单模板"> | |
56 | 82 | <p class="down-txt" slot="down"> |
57 | - 通过Excel名单导入学生名单模板,点击 | |
58 | - <el-link type="primary" @click="downStudentExcel">导出未分配学生</el-link> | |
59 | - 。 | |
83 | + 通过Excel名单导入学生名单模板 | |
60 | 84 | </p> |
61 | 85 | </upload> |
62 | - </div> | |
86 | + </el-row> | |
63 | 87 | </li> |
64 | 88 | <li v-show="step == 2"> |
65 | - <div class="step-item"> | |
66 | - <upload id="downTeacher" :url="urlTeacher" @upSuccess="upTeacherSuccess" fileName="任课老师名单模板"> | |
89 | + <el-row class="row-subfix form-item"> | |
90 | + <div class="row-line" style="float: left;"> | |
91 | + <div>通过导入EXCEL文件方式添加教师任课信息,请按需求下载板并填写任课信息后,导入系统:</div> | |
92 | + </div> | |
93 | + </el-row> | |
94 | + <el-row class="row-subfix form-item" style="margin-top: 20px;"> | |
95 | + <el-button :icon="'el-icon-document'" @click="_downTemplate(2)">下载任课信息模板</el-button> | |
96 | + </el-row> | |
97 | + <el-row class="row-subfix form-item" style="margin-top: 20px;"> | |
98 | + <upload id="downTeacher" drag :url="urlTeacher" | |
99 | + style="border:rgb(219,226,235) dashed 1px;width: 100%;padding:40px 0px;border-radius: 5px;" | |
100 | + @upSuccess="upTeacherSuccess" fileName="任课老师名单模板"> | |
67 | 101 | <p class="down-txt" slot="down"> |
68 | - 通过Excel名单导入任课老师名单模板,点击 | |
69 | - <el-link type="primary" @click="downTeacherExcel">导出未分配教师</el-link>。 | |
102 | + 通过Excel名单导入任课老师名单模板 | |
70 | 103 | </p> |
71 | 104 | </upload> |
72 | - </div> | |
73 | - </li> | |
74 | - <li v-show="step == 3"> | |
75 | - <div class="step-item2"> | |
76 | - <p class="p2"> | |
77 | - <el-button class="btn" type="success" icon="el-icon-check" circle | |
78 | - size="small"></el-button>恭喜您,分班已经完成,分班后老师第一次上课时注意事项: | |
79 | - </p> | |
80 | - <p class="p1"> | |
81 | - 1、点击授课端的设置—应用设置—初始化设置—重新选择绑定班级。 | |
82 | - </p> | |
83 | - <p class="p1"> | |
84 | - 2、点击授课端的设置—班级名册—基站登录—学生完成基站绑定。 | |
85 | - </p> | |
86 | - </div> | |
105 | + </el-row> | |
87 | 106 | </li> |
88 | - | |
89 | 107 | <li v-show="step != 0"> |
90 | 108 | <div class="btn-box"> |
91 | 109 | <el-button class="btn" round @click="step -= 1">上一步</el-button> |
92 | - <el-button v-show="step != 3" class="btn" type="primary" round @click="step += 1">下一步</el-button><el-button | |
93 | - v-show="step == 3" class="btn" type="primary" round @click="toClazz">完成</el-button> | |
110 | + <el-button v-show="step != 2" class="btn" type="primary" round @click="step += 1">下一步</el-button><el-button | |
111 | + v-show="step == 2" class="btn" type="primary" round @click="toClazz">完成</el-button> | |
94 | 112 | </div> |
95 | 113 | </li> |
96 | 114 | </ul> |
... | ... | @@ -109,31 +127,67 @@ export default { |
109 | 127 | step: 0, |
110 | 128 | grade: "", |
111 | 129 | gradeList: [], |
112 | - classIds: [], | |
130 | + checkAll: false, | |
131 | + checkedClass: [], | |
113 | 132 | classList: [], |
114 | 133 | urlClazz: "/api_html/school/manager/importClassAndStudent", |
115 | 134 | urlTeacher: "/api_html/school/manager/importTeacher", |
116 | - checkAll: true, | |
117 | - isIndeterminate: false, | |
135 | + isIndeterminate: true | |
118 | 136 | }; |
119 | 137 | }, |
138 | + watch: { | |
139 | + checkedClass(value) { | |
140 | + this.checkAll = value.length == this.classList.length; | |
141 | + this.isIndeterminate = value.length > 0 && value.length < this.classList.length; | |
142 | + } | |
143 | + }, | |
120 | 144 | created() { |
121 | 145 | this._QueryDataGrade(); |
122 | 146 | }, |
123 | 147 | methods: { |
148 | + async _downNameList() { | |
149 | + this.loadingDown = true; | |
150 | + await this.downStudentExcel(); | |
151 | + await this.downTeacherExcel(); | |
152 | + this.loadingDown = false; | |
153 | + }, | |
124 | 154 | handleCheckAllChange(val) { |
125 | - this.classIds = val | |
126 | - ? this.classList.map((item) => { | |
127 | - return item.id; | |
128 | - }) | |
129 | - : []; | |
130 | - this.isIndeterminate = false; | |
155 | + if (val) this.checkedClass = this.classList.map(item => item.id); | |
156 | + else this.checkedClass = []; | |
131 | 157 | }, |
132 | - handleCheckedChange(value) { | |
133 | - let checkedCount = value.length; | |
134 | - this.checkAll = checkedCount === this.classList.length; | |
135 | - this.isIndeterminate = | |
136 | - checkedCount > 0 && checkedCount < this.classList.length; | |
158 | + async _downTemplate(type) { | |
159 | + | |
160 | + var template = type == 0 ? this.$request.classAndStudentTemplate : this.$request.tClassAndStudentTemplate; | |
161 | + | |
162 | + if (type == 2) template = await this.$request.teacherTemplate; | |
163 | + console.log(type) | |
164 | + let data = await template(); | |
165 | + | |
166 | + if (data && !data.code) { | |
167 | + | |
168 | + let blob = new Blob([data], { | |
169 | + type: "application/vnd.ms-excel;charset=utf-8", | |
170 | + }); | |
171 | + | |
172 | + downloadFile(type == 2 ? "教师任课信息" : type == 0 ? "行政班名单模板" : "教学班名单模板", blob); | |
173 | + } | |
174 | + else { | |
175 | + this.$message.error(data.info); | |
176 | + } | |
177 | + // const classAndStudentTemplate = | |
178 | + // type == 0 | |
179 | + // ? this.$request.classAndStudentTemplate ? type == 2 : | |
180 | + // await this.$request.teacherTemplate() | |
181 | + // : this.$request.tClassAndStudentTemplate; | |
182 | + // let data = await classAndStudentTemplate(); | |
183 | + // if (data && !data.code) { | |
184 | + // let blob = new Blob([data], { | |
185 | + // type: "application/vnd.ms-excel;charset=utf-8", | |
186 | + // }); | |
187 | + // downloadFile(type == 0 ? type == 2 ? "教师任课信息模板" : "行政班名单模板" : "教学班名单模板", blob); | |
188 | + // } else { | |
189 | + // this.$message.error(data.info); | |
190 | + // } | |
137 | 191 | }, |
138 | 192 | toClazz() { |
139 | 193 | this.$router.push({ |
... | ... | @@ -166,41 +220,53 @@ export default { |
166 | 220 | }, |
167 | 221 | //导出学生名单 |
168 | 222 | async downStudentExcel() { |
169 | - this.loadingDown = true; | |
170 | - let data = await this.$request.exportNoClassStudent(); | |
171 | - this.loadingDown = false; | |
223 | + | |
224 | + const exportClassAndStudent = this.$request.exportClassAndStudent; | |
225 | + | |
226 | + let data = await exportClassAndStudent(); | |
227 | + | |
172 | 228 | if (data) { |
173 | 229 | let blob = new Blob([data], { |
174 | - type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | |
230 | + type: "application/vnd.ms-excel;charset=utf-8", | |
175 | 231 | }); |
176 | - downloadFile("未分配学生名单.xlsx", blob); | |
232 | + downloadFile(`班级名单.xlsx`, blob); | |
177 | 233 | } else { |
178 | 234 | this.$message.error("下载失败"); |
179 | 235 | } |
180 | 236 | }, |
181 | 237 | //导出任课老师名单 |
182 | 238 | async downTeacherExcel() { |
183 | - this.loadingDown = true; | |
184 | - let data = await this.$request.exportNoClassTeacher(); | |
185 | - this.loadingDown = false; | |
239 | + | |
240 | + let data = await this.$request.exportTeacher(); | |
241 | + | |
186 | 242 | if (data) { |
187 | 243 | let blob = new Blob([data], { |
188 | - type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | |
244 | + type: "application/vnd.ms-excel;charset=utf-8", | |
189 | 245 | }); |
190 | - downloadFile("未分配教师 名单.xlsx", blob); | |
246 | + downloadFile(`教师名单.xlsx`, blob); | |
191 | 247 | } else { |
192 | 248 | this.$message.error("下载失败"); |
193 | 249 | } |
250 | + // let data = await this.$request.exportNoClassTeacher(); | |
251 | + | |
252 | + // if (data) { | |
253 | + // let blob = new Blob([data], { | |
254 | + // type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | |
255 | + // }); | |
256 | + // downloadFile("未分配教师 名单.xlsx", blob); | |
257 | + // } else { | |
258 | + // this.$message.error("下载失败"); | |
259 | + // } | |
194 | 260 | }, |
195 | 261 | //班级归档 |
196 | 262 | async _ClassArchiving() { |
197 | - if (!this.classIds.length) { | |
263 | + if (!this.checkedClass.length) { | |
198 | 264 | this.$message.warning("班级不能为空,请选择班级~"); |
199 | 265 | return; |
200 | 266 | } |
201 | 267 | this.loading = true; |
202 | 268 | const { status, info } = await this.$request.classArchiving({ |
203 | - classIds: [...this.classIds], | |
269 | + classIds: [...this.checkedClass], | |
204 | 270 | }); |
205 | 271 | this.loading = false; |
206 | 272 | if (status === 0) { |
... | ... | @@ -234,14 +300,12 @@ export default { |
234 | 300 | this.loadingClass = true; |
235 | 301 | const { data, status, info } = await this.$request.schoolClassList({ |
236 | 302 | grade: this.grade, |
303 | + type: 0 | |
237 | 304 | }); |
238 | 305 | this.loadingClass = false; |
239 | 306 | if (status === 0) { |
240 | 307 | this.classList = (data.list && [...data.list]) || []; |
241 | - this.classIds = this.classList.map((item) => { | |
242 | - return item.id; | |
243 | - }); | |
244 | - this.checkAll = true; | |
308 | + this.checkedClass = this.classList.map(item => item.id); | |
245 | 309 | } else { |
246 | 310 | this.$message.error(info); |
247 | 311 | } | ... | ... |
src/views/basic/setUp/clazz.vue
... | ... | @@ -6,37 +6,14 @@ |
6 | 6 | </template> |
7 | 7 | <template slot="btns" v-if="!code"> |
8 | 8 | <el-tooltip effect="dark" content="导入班级名单" placement="bottom"> |
9 | - <el-button | |
10 | - type="primary" | |
11 | - icon="el-icon-upload2" | |
12 | - size="mini" | |
13 | - plain | |
14 | - circle | |
15 | - @click="diaUp = true" | |
16 | - ></el-button> | |
9 | + <el-button type="primary" icon="el-icon-upload2" size="mini" plain circle @click="diaUp = true"></el-button> | |
17 | 10 | </el-tooltip> |
18 | 11 | <el-tooltip effect="dark" content="导出班级名单" placement="bottom"> |
19 | - <el-button | |
20 | - type="primary" | |
21 | - icon="el-icon-download" | |
22 | - size="mini" | |
23 | - plain | |
24 | - circle | |
25 | - @click="exportTeacherExl" | |
26 | - ></el-button> | |
12 | + <el-button type="primary" icon="el-icon-download" size="mini" plain circle | |
13 | + @click="exportTeacherExl"></el-button> | |
27 | 14 | </el-tooltip> |
28 | - <el-tooltip | |
29 | - effect="dark" | |
30 | - content="分班" | |
31 | - placement="bottom" | |
32 | - v-show="type == 0" | |
33 | - > | |
34 | - <img | |
35 | - @click="toArchived" | |
36 | - src="../../../assets/images/fenban.png" | |
37 | - class="fenban" | |
38 | - alt="" | |
39 | - /> | |
15 | + <el-tooltip effect="dark" content="分班" placement="bottom" v-show="type == 0"> | |
16 | + <img @click="toArchived" src="../../../assets/images/fenban.png" class="fenban" alt="" /> | |
40 | 17 | </el-tooltip> |
41 | 18 | </template> |
42 | 19 | </back-box> |
... | ... | @@ -45,42 +22,23 @@ |
45 | 22 | <p class="tab-box"> |
46 | 23 | <el-radio-group v-model="type" @change="_QueryData"> |
47 | 24 | <el-radio-button :label="0">行政班</el-radio-button> |
48 | - <el-radio-button :label="1">教学班</el-radio-button> | |
25 | + <el-radio-button v-if="hasTeachingClass" :label="1">教学班</el-radio-button> | |
49 | 26 | </el-radio-group> |
50 | 27 | </p> |
51 | 28 | <div class="grade-item" v-for="(item, index) in dataList"> |
52 | 29 | <p class="h-title"> |
53 | 30 | <span>{{ item.gradeName }}</span> |
54 | - <span class="s-num" v-if="item.classList" | |
55 | - >(共{{ item.classList.length }}个班)</span | |
56 | - > | |
57 | - <el-button | |
58 | - class="sub-btn" | |
59 | - type="info" | |
60 | - size="mini" | |
61 | - round | |
62 | - plain | |
63 | - @click="openSubject(item)" | |
64 | - >科目管理({{ item.subjectNames.length }})</el-button | |
65 | - > | |
31 | + <span class="s-num" v-if="item.classList">(共{{ item.classList.length }}个班)</span> | |
32 | + <el-button class="sub-btn" type="info" size="mini" round plain @click="openSubject(item)">科目管理({{ | |
33 | + item.subjectNames.length }})</el-button> | |
66 | 34 | <span class="txt" v-if="index == 0">拖动班级进行排序</span> |
67 | 35 | </p> |
68 | - <draggable | |
69 | - tag="ul" | |
70 | - class="grade-info" | |
71 | - v-model="item.classList" | |
72 | - @start="start" | |
73 | - @end="end(item)" | |
74 | - v-bind="{ | |
75 | - animation: 300, | |
76 | - }" | |
77 | - > | |
36 | + <draggable tag="ul" class="grade-info" v-model="item.classList" @start="start" @end="end(item)" v-bind="{ | |
37 | + animation: 300, | |
38 | + }"> | |
78 | 39 | <li class="clazz-li" v-for="clazz in item.classList" :key="item.id"> |
79 | 40 | <div class="clazz-item"> |
80 | - <i | |
81 | - class="el-icon-edit" | |
82 | - @click.stop="setClass(clazz, item.gradeName)" | |
83 | - ></i> | |
41 | + <i class="el-icon-edit" @click.stop="setClass(clazz, item.gradeName)"></i> | |
84 | 42 | <p class="clazz-name ellipsis"> |
85 | 43 | {{ clazz.className }} |
86 | 44 | </p> |
... | ... | @@ -94,34 +52,48 @@ |
94 | 52 | </div> |
95 | 53 | </div> |
96 | 54 | </div> |
97 | - <el-dialog :append-to-body="true" | |
98 | - :close-on-click-modal="false" | |
99 | - title="导入班级名单" | |
100 | - :visible.sync="diaUp" | |
101 | - width="600" | |
102 | - > | |
103 | - <upload :url="url" @upSuccess="upSuccess" fileName="班级名单"> | |
104 | - <p class="down-txt" slot="down"> | |
105 | - 通过Excel名单导入班级名单,点击 | |
106 | - <el-link type="danger" @click="downExcel">模板下载</el-link> 。 | |
107 | - </p> | |
108 | - </upload> | |
55 | + <el-dialog :append-to-body="true" :close-on-click-modal="false" title="添加班级" width="70%" :visible.sync="diaUp"> | |
56 | + <div style="width: 90%;margin:0px auto;"> | |
57 | + <el-row class="row-subfix form-item"> | |
58 | + <div class="row-line" style="float: left;color:black;"> | |
59 | + <div>通过导入文件方式添加班级名单</div> | |
60 | + <div class="row-line" style="margin-top:10px"> | |
61 | + <div style="float:left;">第一步:</div> | |
62 | + <div style="float:left;"> | |
63 | + <div style="margin-bottom: 10px;">无需走班,请 <el-link type="primary" | |
64 | + @click="_downTemplate(0)">下载行政班模板名单;</el-link> | |
65 | + </div> | |
66 | + <div style="margin-bottom: 10px;">需要走班,请按需求 | |
67 | + <el-link type="primary" @click="_downTemplate(0)">下载行政班模板名单;</el-link>或者 | |
68 | + <el-link type="primary" @click="_downTemplate(1)">教学班名单模板</el-link> | |
69 | + </div> | |
70 | + <div style="margin-top: 10px;opacity: 0.7;margin-left:20px;"> | |
71 | + 行政班定义:由固定学生、固定教室构成,由专门的班主任进行管理。 | |
72 | + </div> | |
73 | + <div style="margin-top: 5px;opacity: 0.7;margin-left:20px;"> | |
74 | + 教学班定义:由不同行政班的学生临时组成,没有专门的班主任,是在选课制基础上,由于教学的需要而产生的。 | |
75 | + </div> | |
76 | + </div> | |
77 | + </div> | |
78 | + <div style="float:left;margin-top:10px">第二步:<span>上传完成编辑好的名单文件</span></div> | |
79 | + </div> | |
80 | + </el-row> | |
81 | + <el-row class="row-subfix form-item" style="margin-top: 20px;"> | |
82 | + <upload id="downTeacher" drag :url="url" | |
83 | + style="border:rgb(219,226,235) dashed 1px;margin:0px auto;width: 80%;padding:40px 0px;border-radius: 5px;" | |
84 | + @upSuccess="upSuccess" fileName="班级名单"> | |
85 | + <p class="down-txt" slot="down"> | |
86 | + 通过Excel名单导入班级名单模板 | |
87 | + </p> | |
88 | + </upload> | |
89 | + </el-row> | |
90 | + </div> | |
109 | 91 | <div class="dialog-footer" slot="footer"> |
110 | 92 | <el-button @click="diaUp = false">取 消</el-button> |
111 | 93 | </div> |
112 | 94 | </el-dialog> |
113 | - <el-dialog :append-to-body="true" | |
114 | - :close-on-click-modal="false" | |
115 | - title="修改班级" | |
116 | - :visible.sync="diaClass" | |
117 | - width="400" | |
118 | - > | |
119 | - <el-form | |
120 | - ref="formClass" | |
121 | - :model="formClass" | |
122 | - :rules="rulesClass" | |
123 | - label-width="160px" | |
124 | - > | |
95 | + <el-dialog :append-to-body="true" :close-on-click-modal="false" title="修改班级" :visible.sync="diaClass" width="400"> | |
96 | + <el-form ref="formClass" :model="formClass" :rules="rulesClass" label-width="160px"> | |
125 | 97 | <el-form-item label="所在年级:"> |
126 | 98 | <span>{{ formClass.gradeName }}</span> |
127 | 99 | </el-form-item> |
... | ... | @@ -140,20 +112,14 @@ |
140 | 112 | </el-form-item> |
141 | 113 | <el-form-item label="入学年份:"> |
142 | 114 | <el-col :span="10"> |
143 | - <el-date-picker | |
144 | - v-model="formClass.intoSchoolYear" | |
145 | - type="year" | |
146 | - placeholder="选择年" | |
147 | - > | |
115 | + <el-date-picker v-model="formClass.intoSchoolYear" type="year" placeholder="选择年"> | |
148 | 116 | </el-date-picker> |
149 | 117 | </el-col> |
150 | 118 | </el-form-item> |
151 | 119 | </el-form> |
152 | 120 | <div class="dialog-footer" slot="footer"> |
153 | 121 | <el-popconfirm title="确定删除该班级吗?" @confirm="_RemoveClass"> |
154 | - <el-button class="el-button-del" slot="reference" type="danger" | |
155 | - >删 除</el-button | |
156 | - > | |
122 | + <el-button class="el-button-del" slot="reference" type="danger">删 除</el-button> | |
157 | 123 | </el-popconfirm> |
158 | 124 | <el-button @click="_SaveClass" type="primary">确 定</el-button> |
159 | 125 | <el-button @click="diaClass = false">取 消</el-button> |
... | ... | @@ -163,11 +129,7 @@ |
163 | 129 | </el-popconfirm> --> |
164 | 130 | </div> |
165 | 131 | </el-dialog> |
166 | - <el-dialog :append-to-body="true" | |
167 | - :close-on-click-modal="false" | |
168 | - :visible.sync="diaSubject" | |
169 | - width="400" | |
170 | - > | |
132 | + <el-dialog :append-to-body="true" :close-on-click-modal="false" :visible.sync="diaSubject" width="400"> | |
171 | 133 | <p slot="title" class="dia-tit"> |
172 | 134 | {{ formClass.gradeName }} |
173 | 135 | <span class="tips">(默认科目和已经有任课老师的科目不能删除)</span> |
... | ... | @@ -176,54 +138,25 @@ |
176 | 138 | <el-form-item label="科目:"> |
177 | 139 | <div class="subject-box"> |
178 | 140 | <el-checkbox-group v-model="subjectNames"> |
179 | - <p | |
180 | - class="p1" | |
181 | - v-for="(item, index) in subjectList" | |
182 | - :key="item.default" | |
183 | - > | |
141 | + <p class="p1" v-for="(item, index) in subjectList" :key="item.default"> | |
184 | 142 | <el-checkbox v-if="!item.checked" :label="item.value">{{ |
185 | - item.value | |
186 | - }}</el-checkbox> | |
187 | - <el-input | |
188 | - class="sub-ipt" | |
189 | - v-else | |
190 | - v-model="item.value" | |
191 | - @keyup.enter.native="_EditSub(item)" | |
192 | - ></el-input> | |
193 | - <i | |
194 | - class="el-icon el-icon-edit" | |
195 | - v-show="!item.checked" | |
196 | - @click="item.checked = true" | |
197 | - ></i> | |
198 | - <i | |
199 | - class="el-icon el-icon-check" | |
200 | - v-show="item.checked" | |
201 | - @click="_EditSub(item)" | |
202 | - ></i> | |
143 | + item.value | |
144 | + }}</el-checkbox> | |
145 | + <el-input class="sub-ipt" v-else v-model="item.value" @keyup.enter.native="_EditSub(item)"></el-input> | |
146 | + <i class="el-icon el-icon-edit" v-show="!item.checked" @click="item.checked = true"></i> | |
147 | + <i class="el-icon el-icon-check" v-show="item.checked" @click="_EditSub(item)"></i> | |
203 | 148 | <!-- <i |
204 | 149 | class="el-icon el-icon-close" |
205 | 150 | v-show="item.checked" |
206 | 151 | @click="resetSub(item)" |
207 | 152 | ></i> --> |
208 | - <i | |
209 | - v-show="!item.checked" | |
210 | - class="el-icon el-icon-delete" | |
211 | - @click="_DelSubject(item, index)" | |
212 | - ></i> | |
153 | + <i v-show="!item.checked" class="el-icon el-icon-delete" @click="_DelSubject(item, index)"></i> | |
213 | 154 | </p> |
214 | 155 | </el-checkbox-group> |
215 | 156 | </div> |
216 | 157 | <el-col :span="8"> |
217 | - <el-input | |
218 | - placeholder="添加科目" | |
219 | - v-model.trim="subjectName" | |
220 | - maxlength="30" | |
221 | - > | |
222 | - <i | |
223 | - slot="suffix" | |
224 | - class="el-input__icon el-icon-plus" | |
225 | - @click="addSubjectName" | |
226 | - ></i> | |
158 | + <el-input placeholder="添加科目" v-model.trim="subjectName" maxlength="30"> | |
159 | + <i slot="suffix" class="el-input__icon el-icon-plus" @click="addSubjectName"></i> | |
227 | 160 | </el-input> |
228 | 161 | </el-col> |
229 | 162 | </el-form-item> |
... | ... | @@ -255,6 +188,7 @@ export default { |
255 | 188 | }, |
256 | 189 | data() { |
257 | 190 | return { |
191 | + hasTeachingClass: false, | |
258 | 192 | code: "", |
259 | 193 | loading: false, |
260 | 194 | loadingDown: false, |
... | ... | @@ -355,6 +289,18 @@ export default { |
355 | 289 | : ""; |
356 | 290 | this.diaClass = true; |
357 | 291 | }, |
292 | + async _downTemplate(type) { | |
293 | + const template = type == 0 ? this.$request.classAndStudentTemplate : this.$request.tClassAndStudentTemplate; | |
294 | + let data = await template(); | |
295 | + if (data && !data.code) { | |
296 | + let blob = new Blob([data], { | |
297 | + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | |
298 | + }); | |
299 | + downloadFile(type == 0 ? "行政班名单模板" : "教学班名单模板", blob); | |
300 | + } else { | |
301 | + this.$message.error(data.info); | |
302 | + } | |
303 | + }, | |
358 | 304 | async _RemoveClass() { |
359 | 305 | const { data, status, info } = await this.$request.deleteClass({ |
360 | 306 | id: this.formClass.classId, |
... | ... | @@ -485,7 +431,22 @@ export default { |
485 | 431 | } |
486 | 432 | }, |
487 | 433 | async _QueryData() { |
434 | + | |
488 | 435 | this.loading = true; |
436 | + | |
437 | + var loadTeachingClass = await this.$request.classManager({ | |
438 | + type: 1, | |
439 | + }); | |
440 | + if (loadTeachingClass.status != 0) { | |
441 | + this.$message.error(loadTeachingClass.info); | |
442 | + return; | |
443 | + } | |
444 | + | |
445 | + this.hasTeachingClass = loadTeachingClass.data.list?.find(item => { | |
446 | + return item?.classList?.length >= 1; | |
447 | + }); | |
448 | + console.log(loadTeachingClass.data.list, this.hasTeachingClass) | |
449 | + | |
489 | 450 | this.dataList = []; |
490 | 451 | let { data, status, info } = await this.$request.classManager({ |
491 | 452 | type: this.type, |
... | ... | @@ -691,7 +652,7 @@ export default { |
691 | 652 | } |
692 | 653 | } |
693 | 654 | |
694 | - .is-checked ~ .el-icon-delete { | |
655 | + .is-checked~.el-icon-delete { | |
695 | 656 | display: none; |
696 | 657 | } |
697 | 658 | } | ... | ... |
src/views/basic/test/components/scoreSet.vue
... | ... | @@ -8,51 +8,19 @@ |
8 | 8 | </div> |
9 | 9 | <div class="set-content"> |
10 | 10 | <div class="test-title"> |
11 | - <el-button class="import-btn" round @click="diaUp = true" | |
12 | - >从excel文件导入</el-button | |
13 | - > | |
14 | - <el-button | |
15 | - class="save-btn" | |
16 | - type="primary" | |
17 | - round | |
18 | - :loading="loadingSave" | |
19 | - @click="_SubmitScore" | |
20 | - >保存</el-button | |
21 | - > | |
11 | + <el-button class="import-btn" round @click="diaUp = true">从excel文件导入</el-button> | |
12 | + <el-button class="save-btn" type="primary" round :loading="loadingSave" @click="_SubmitScore">保存</el-button> | |
22 | 13 | <p class="p1">{{ title }}</p> |
23 | 14 | <p class="p2">卷面总分:{{ examScore }}分</p> |
24 | 15 | </div> |
25 | - <el-table | |
26 | - :data="tableData" | |
27 | - border | |
28 | - style="width: 100%" | |
29 | - :max-height="tableMaxHeight" | |
30 | - > | |
31 | - <el-table-column | |
32 | - prop="studentCode" | |
33 | - label="学号" | |
34 | - align="center" | |
35 | - fixed | |
36 | - ></el-table-column> | |
37 | - <el-table-column | |
38 | - prop="studentName" | |
39 | - label="学号" | |
40 | - align="center" | |
41 | - fixed | |
42 | - ></el-table-column> | |
43 | - <el-table-column prop="score" label="总得分" align="center" fixed | |
44 | - ><template slot-scope="scoped"> | |
45 | - <el-input | |
46 | - v-if="showAllSetScore" | |
47 | - type="number" | |
48 | - :min="0" | |
49 | - v-model="scoped.row.all" | |
50 | - ></el-input> | |
16 | + <el-table :key="tableDataIndex" :data="tableData" border style="width: 100%" :max-height="tableMaxHeight"> | |
17 | + <el-table-column prop="studentCode" label="学号" align="center" fixed></el-table-column> | |
18 | + <el-table-column prop="studentName" label="学号" align="center" fixed></el-table-column> | |
19 | + <el-table-column prop="score" label="总得分" align="center" fixed><template slot-scope="scoped"> | |
20 | + <el-input v-if="showAllSetScore" type="number" :min="0" v-model="scoped.row.all"></el-input> | |
51 | 21 | <template v-else>{{ scoped.row.all }}</template> |
52 | - </template></el-table-column | |
53 | - > | |
54 | - <el-table-column prop="objectiveScore" label="客观题分" align="center" | |
55 | - ><template slot-scope="scoped"> | |
22 | + </template></el-table-column> | |
23 | + <el-table-column prop="objectiveScore" label="客观题分" align="center"><template slot-scope="scoped"> | |
56 | 24 | <!-- <el-input |
57 | 25 | v-if="scoped.row.showSetScore" |
58 | 26 | type="number" |
... | ... | @@ -61,8 +29,7 @@ |
61 | 29 | @input="setOtherScore($event, scoped.row)" |
62 | 30 | ></el-input> --> |
63 | 31 | <template>{{ scoped.row.object }}</template> |
64 | - </template></el-table-column | |
65 | - > | |
32 | + </template></el-table-column> | |
66 | 33 | <el-table-column prop="subjectiveScore" label="主观题分" align="center"> |
67 | 34 | <template slot-scope="scoped"> |
68 | 35 | <!-- <el-input |
... | ... | @@ -76,56 +43,29 @@ |
76 | 43 | </template> |
77 | 44 | </el-table-column> |
78 | 45 | <!-- <el-table-column v-for="(item, index) in questionList" :key="index" :label="'第' + cNum[index] + '大题'" --> |
79 | - <el-table-column | |
80 | - v-for="(question, index) in questionList" | |
81 | - :key="index" | |
82 | - :label="'Q' + question.questionId" | |
83 | - align="center" | |
84 | - > | |
46 | + <el-table-column v-for="(question, index) in questionList" :key="index" :label="'Q' + question.questionId" | |
47 | + align="center"> | |
85 | 48 | <template slot-scope="scoped"> |
86 | - <el-input | |
87 | - v-if="showSetScore" | |
88 | - type="number" | |
89 | - :min="0" | |
90 | - :max="question.questionScore" | |
91 | - @input=" | |
92 | - setScore( | |
93 | - $event, | |
94 | - question.questionScore, | |
95 | - scoped.row.scoreMap, | |
96 | - question.questionId, | |
97 | - scoped.row | |
98 | - ) | |
99 | - " | |
100 | - v-model="scoped.row.scoreMap[question.questionId]" | |
101 | - ></el-input> | |
102 | - <template v-else>{{ | |
103 | - scoped.row.scoreMap[question.questionId] | |
104 | - }}</template> | |
49 | + <el-input v-if="showSetScore" type="number" :min="0" :max="question.questionScore" @input="setScore( | |
50 | + $event, | |
51 | + question.questionScore, | |
52 | + scoped.row.scoreMap, | |
53 | + question.questionId, | |
54 | + scoped.row | |
55 | + ) | |
56 | + " v-model="scoped.row.scoreMap[question.questionId]"></el-input> | |
57 | + <template v-else>{{ scoped.row.scoreMap[question.questionId] }}</template> | |
105 | 58 | </template> |
106 | 59 | </el-table-column> |
107 | 60 | </el-table> |
108 | 61 | </div> |
109 | 62 | |
110 | - <el-dialog | |
111 | - :close-on-click-modal="false" | |
112 | - :append-to-body="true" | |
113 | - title="答卷录分" | |
114 | - :visible.sync="diaUp" | |
115 | - width="600px" | |
116 | - top="120px" | |
117 | - > | |
118 | - <upload | |
119 | - :url="url" | |
120 | - :examId="id" | |
121 | - @upSuccess="upSuccess" | |
122 | - fileName="主观题分数" | |
123 | - v-loading="loadingDown" | |
124 | - > | |
63 | + <el-dialog :close-on-click-modal="false" :append-to-body="true" title="答卷录分" :visible.sync="diaUp" width="600px" | |
64 | + top="120px"> | |
65 | + <upload :url="url" :examId="id" @upSuccess="upSuccess" fileName="主观题分数" v-loading="loadingDown"> | |
125 | 66 | <template slot="down"> |
126 | 67 | <p class="down-txt"> |
127 | - 第一步:<el-link type="danger" @click="downExcel">下载模板</el-link | |
128 | - >,并编辑完成学生分数。 | |
68 | + 第一步:<el-link type="danger" @click="downExcel">下载模板</el-link>,并编辑完成学生分数。 | |
129 | 69 | </p> |
130 | 70 | <p class="down-txt">第二步:上传完成编辑的模板文件并导入。</p> |
131 | 71 | </template> |
... | ... | @@ -160,8 +100,11 @@ export default { |
160 | 100 | url: "/api_html/teaching/importScore", |
161 | 101 | tableData: [], |
162 | 102 | questionList: [], |
103 | + dataReponse: [], | |
104 | + tableDataIndex: 0, | |
163 | 105 | cNum: cNum, |
164 | 106 | tableMaxHeight: 300, |
107 | + studentList: [], | |
165 | 108 | }; |
166 | 109 | }, |
167 | 110 | watch: { |
... | ... | @@ -209,7 +152,7 @@ export default { |
209 | 152 | if (obj.scoreMap[keys] == 0) { |
210 | 153 | obj.scoreMap[keys] = 0; |
211 | 154 | } else { |
212 | - obj.scoreMap[keys] = ""; | |
155 | + obj.scoreMap[keys] = 0; | |
213 | 156 | } |
214 | 157 | } else { |
215 | 158 | let num = Number(obj.scoreMap[keys]); |
... | ... | @@ -238,8 +181,9 @@ export default { |
238 | 181 | }); |
239 | 182 | this.loading = false; |
240 | 183 | if (status === 0) { |
241 | - let studentList = data.students || []; | |
242 | - this.questionList = data?.questionList || []; | |
184 | + this.dataReponse = data; | |
185 | + let studentList = this.dataReponse.students || []; | |
186 | + this.questionList = this.dataReponse?.questionList || []; | |
243 | 187 | if (this.questionList.length == 0) { |
244 | 188 | this.questionList = Object.keys(studentList[0].scoreMap).map( |
245 | 189 | (item) => { |
... | ... | @@ -269,7 +213,6 @@ export default { |
269 | 213 | item.scoreMap[keys] = num; |
270 | 214 | } |
271 | 215 | }); |
272 | - | |
273 | 216 | return item; |
274 | 217 | }) || []; |
275 | 218 | this.setTableHeight(); |
... | ... | @@ -310,10 +253,68 @@ export default { |
310 | 253 | |
311 | 254 | //导入成功 |
312 | 255 | upSuccess(res) { |
256 | + | |
313 | 257 | this.$message.success("导入成功"); |
258 | + | |
259 | + let studentList = this.dataReponse.students || []; | |
260 | + | |
261 | + this.tableData = | |
262 | + studentList.map((item) => { | |
263 | + // setScore(); | |
264 | + item.all = 0; //总分 | |
265 | + item.object = 0; //客观题分数 | |
266 | + item.subject = 0; //主观题分数 | |
267 | + var detail = JSON.parse(res.data[item.studentId]); | |
268 | + | |
269 | + var scoreMap = {}; | |
270 | + | |
271 | + if (detail) { | |
272 | + detail.forEach(item => { | |
273 | + scoreMap[item.id] = item.score | |
274 | + }) | |
275 | + } | |
276 | + | |
277 | + item.scoreMap = scoreMap; | |
278 | + | |
279 | + this.questionList.map((question) => { | |
280 | + let keys = question.questionId; | |
281 | + if (!item.scoreMap[keys]) { | |
282 | + if (item.scoreMap[keys] == 0) { | |
283 | + item.scoreMap[keys] = 0; | |
284 | + } else { | |
285 | + item.scoreMap[keys] = ""; | |
286 | + } | |
287 | + } else { | |
288 | + let num = Number(item.scoreMap[keys]); | |
289 | + item.scoreMap[keys] = num; | |
290 | + } | |
291 | + }); | |
292 | + | |
293 | + return item; | |
294 | + }) || []; | |
295 | + | |
296 | + this.setTableHeight(); | |
297 | + | |
298 | + this.tableDataIndex += 1; | |
299 | + // for (let key in res.data) { | |
300 | + | |
301 | + // var detail = JSON.parse(res.data[key]); | |
302 | + | |
303 | + // let studentList = this.dataReponse.students || []; | |
304 | + | |
305 | + | |
306 | + | |
307 | + // // if (student) { | |
308 | + // // for (let scoreMapKey in student?.scoreMap) { | |
309 | + // // var sDetail = detail.find(dl => dl.id == scoreMapKey); | |
310 | + // // if (sDetail) { | |
311 | + // // student.scoreMap[scoreMapKey] = sDetail.score; | |
312 | + // // } | |
313 | + // // } | |
314 | + // // } | |
315 | + // } | |
316 | + // this.setTableHeight(); | |
314 | 317 | this.diaUp = false; |
315 | - // this.closeScoreSet(); | |
316 | - this.$emit("SuccessScoreSet"); | |
317 | 318 | }, |
318 | 319 | async downExcel() { |
319 | 320 | //模板下载 |
... | ... | @@ -338,10 +339,10 @@ export default { |
338 | 339 | <style lang="scss" scoped> |
339 | 340 | .set-container { |
340 | 341 | position: fixed; |
341 | - left: 200px; | |
342 | - top: 50px; | |
343 | - width: calc(100% - 200px); | |
344 | - height: calc(100% - 70px); | |
342 | + left: 250px; | |
343 | + top: 60px; | |
344 | + width: calc(100% - 250px); | |
345 | + height: calc(100% - 80px); | |
345 | 346 | background: #fff; |
346 | 347 | z-index: 2000; |
347 | 348 | overflow-y: auto; | ... | ... |
src/views/examinationPaper/add.vue
... | ... | @@ -3,10 +3,40 @@ |
3 | 3 | <div ref="content" class="content-box"> |
4 | 4 | <back-box> |
5 | 5 | <template slot="title"> |
6 | - <span>{{ "创建答题卡" }}</span> | |
6 | + <span>{{ isUpload ? "导入试卷" : "创建答题卡" }}</span> | |
7 | 7 | </template> |
8 | 8 | </back-box> |
9 | 9 | <div class="content"> |
10 | + <el-dialog :close-on-click-modal="false" title="选择班级分享" :visible.sync="classSharingType" width="800" | |
11 | + :modal-append-to-body="false" :append-to-body="true"> | |
12 | + <div> | |
13 | + <el-row class="row-subfix"> | |
14 | + <div class="row-line"> | |
15 | + <span class="line-subfix">年级:</span> | |
16 | + <span class="line-value">{{ gradeName }}</span> | |
17 | + </div> | |
18 | + </el-row> | |
19 | + <el-row class="row-subfix" style="margin-top: 20px;"> | |
20 | + <span class="line-subfix" style="float: left;">班级:</span> | |
21 | + <div class="row-line" style="float: left; | |
22 | + background:rgb(245,247,250);padding:15px 10px;width: calc(100% - 80px);border-radius:5px;"> | |
23 | + <span class="line-value" style="min-height: 300px;border-radius: 4px; background: rgb(247,247,250);"> | |
24 | + <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" | |
25 | + @change="handleCheckAllChange">全选</el-checkbox> | |
26 | + <el-checkbox-group v-model="checkedClass" style="margin-top: 15px;" @change="handleCheckedClassChange"> | |
27 | + <el-checkbox v-for="(item, index) in shareClass" :label="item.id" :key="item.id"> | |
28 | + {{ item.className }} | |
29 | + </el-checkbox> | |
30 | + </el-checkbox-group> | |
31 | + </span> | |
32 | + </div> | |
33 | + </el-row> | |
34 | + </div> | |
35 | + <div slot="footer"> | |
36 | + <el-button type="info" :size="'small'" @click="classSharingType = false">取消</el-button> | |
37 | + <el-button type="primary" :size="'small'" @click="_checkedClass">确定</el-button> | |
38 | + </div> | |
39 | + </el-dialog> | |
10 | 40 | <el-steps :active="step" finish-status="success" simple style="margin: 20px 0"> |
11 | 41 | <el-step title="基础信息" icon="el-icon-edit"></el-step> |
12 | 42 | <el-step v-if="!isUpload" title="题目编辑" icon="el-icon-tickets"></el-step> |
... | ... | @@ -49,7 +79,8 @@ |
49 | 79 | <el-form-item v-if="role != 'ROLE_PERSONAL'" label="分享范围:" prop="sharingType"> |
50 | 80 | <el-radio-group v-model="form.sharingType"> |
51 | 81 | <el-radio :label="0">任课班级分享</el-radio> |
52 | - <el-radio :label="1">全年级分享</el-radio> | |
82 | + <el-radio class="name-radio" @click.native="_selectClassSharingType" v-model="form.sharingType" | |
83 | + :label="1">自定义分享班级</el-radio> | |
53 | 84 | </el-radio-group> |
54 | 85 | </el-form-item> |
55 | 86 | </el-form> |
... | ... | @@ -57,7 +88,8 @@ |
57 | 88 | <el-button type="danger" plain round @click="linkBack">取消</el-button> |
58 | 89 | <el-button type="primary" round @click="isUpload ? setStep2() : setStep1()">下一步</el-button> |
59 | 90 | </div> |
60 | - <el-dialog :close-on-click-modal="false" title="设置测验类型" :visible.sync="dialogVisible" width="500px"> | |
91 | + <el-dialog :close-on-click-modal="false" title="设置测验类型" :visible.sync="dialogVisible" width="500px" | |
92 | + :append-to-body="true"> | |
61 | 93 | <div class="dia-content"> |
62 | 94 | <p class="add-type" v-for="item in tagList" :key="item.id"> |
63 | 95 | <el-row :gutter="10"> |
... | ... | @@ -217,7 +249,8 @@ |
217 | 249 | <el-button :type="form.questionList.length == 0 ? 'info' : 'primary'" round |
218 | 250 | @click="setStep2">下一步</el-button> |
219 | 251 | </div> |
220 | - <el-dialog :close-on-click-modal="false" title="添加大题" :visible.sync="addQuestionVisible" width="600px"> | |
252 | + <el-dialog :close-on-click-modal="false" title="添加大题" :append-to-body="true" | |
253 | + :visible.sync="addQuestionVisible" width="600px"> | |
221 | 254 | <div class="dia-content"> |
222 | 255 | <el-form ref="form" :model="questionForm" :rules="questionFormRules" label-width="100px"> |
223 | 256 | <el-form-item label="标题:"> |
... | ... | @@ -514,7 +547,7 @@ |
514 | 547 | </div> |
515 | 548 | </div> |
516 | 549 | <el-dialog :close-on-click-modal="false" :title="stem.type == 1 ? '上传题干' : '上传题目解析'" :visible.sync="dialogStem" |
517 | - v-if="dialogStem" width="800px"> | |
550 | + v-if="dialogStem" width="800px" :append-to-body="true"> | |
518 | 551 | <div class="upload-box"> |
519 | 552 | <div v-loading="iframeLoading"> |
520 | 553 | <template v-if="stem.type == 1"> |
... | ... | @@ -535,7 +568,8 @@ |
535 | 568 | <el-button @click="dialogStem = false">确定</el-button> |
536 | 569 | </div> |
537 | 570 | </el-dialog> |
538 | - <el-dialog :close-on-click-modal="false" title="知识点" :visible.sync="dialogKnowledge" width="500px"> | |
571 | + <el-dialog :close-on-click-modal="false" :append-to-body="true" title="知识点" :visible.sync="dialogKnowledge" | |
572 | + width="1200px"> | |
539 | 573 | <div> |
540 | 574 | <el-form ref="form" :model="stem" label-width="160px"> |
541 | 575 | <el-form-item label="知识点:"> |
... | ... | @@ -620,6 +654,13 @@ export default { |
620 | 654 | }, |
621 | 655 | data() { |
622 | 656 | return { |
657 | + shareClass: [], | |
658 | + role: "", | |
659 | + checkedClass: [], | |
660 | + classSharingType: false, | |
661 | + gradeName: "", | |
662 | + isIndeterminate: false, | |
663 | + checkAll: false, | |
623 | 664 | role: "", |
624 | 665 | step: 0, //步骤 |
625 | 666 | gradeClassList: [], //年级-班级数据 |
... | ... | @@ -744,6 +785,18 @@ export default { |
744 | 785 | } |
745 | 786 | }, |
746 | 787 | methods: { |
788 | + _checkedClass() { | |
789 | + this.classSharingType = false; | |
790 | + }, | |
791 | + handleCheckAllChange(val) { | |
792 | + this.checkedClass = val ? this.shareClass?.map(item => item.id) : []; | |
793 | + this.isIndeterminate = false; | |
794 | + }, | |
795 | + handleCheckedClassChange(value) { | |
796 | + let checkedCount = value.length; | |
797 | + this.checkAll = checkedCount === this.checkedClass.length; | |
798 | + this.isIndeterminate = checkedCount > 0 && checkedCount < this.checkedClass.length; | |
799 | + }, | |
747 | 800 | // v1.5 |
748 | 801 | //上传截图 |
749 | 802 | openStem(obj, index, indexs, type) { |
... | ... | @@ -825,13 +878,25 @@ export default { |
825 | 878 | ) |
826 | 879 | .then(() => { }) |
827 | 880 | .catch(() => { |
828 | - this.$router.push({ | |
829 | - path: "/examinationPaper", | |
830 | - query: { | |
831 | - type: this.listType, | |
832 | - share: this.listShare, | |
833 | - }, | |
834 | - }); | |
881 | + if (location.href.indexOf('askPreparationQuestionsAdd') >= 1) { | |
882 | + this.$router.push({ | |
883 | + path: "/askPreparationQuestions" | |
884 | + }); | |
885 | + } | |
886 | + else if (location.href.indexOf('testPaperAdd') >= 1) { | |
887 | + this.$router.push({ | |
888 | + path: "/testPaper" | |
889 | + }); | |
890 | + } | |
891 | + else { | |
892 | + this.$router.push({ | |
893 | + path: "/examinationPaper", | |
894 | + query: { | |
895 | + type: this.listType, | |
896 | + share: this.listShare, | |
897 | + }, | |
898 | + }); | |
899 | + } | |
835 | 900 | }); |
836 | 901 | }, |
837 | 902 | //转换题型显示方式 |
... | ... | @@ -1183,6 +1248,24 @@ export default { |
1183 | 1248 | } |
1184 | 1249 | } |
1185 | 1250 | }, |
1251 | + async _selectClassSharingType() { | |
1252 | + | |
1253 | + this.classSharingType = true; | |
1254 | + | |
1255 | + var grade = this.gradeClassList.find(item => item.gradeName == this.form.gradeName); | |
1256 | + | |
1257 | + var classResponse = await this.$request.tClassGrade(grade?.grade,this.form.subjectName); | |
1258 | + | |
1259 | + if (classResponse.status != 0) { | |
1260 | + this.$message.error(classResponse.info); | |
1261 | + } | |
1262 | + | |
1263 | + this.gradeName = grade.gradeName; | |
1264 | + | |
1265 | + this.shareClass = classResponse.data; | |
1266 | + | |
1267 | + | |
1268 | + }, | |
1186 | 1269 | openQuestion() { |
1187 | 1270 | this.questionForm = { ...questionForm }; |
1188 | 1271 | this.addQuestionVisible = true; |
... | ... | @@ -1437,16 +1520,28 @@ export default { |
1437 | 1520 | }, |
1438 | 1521 | async save() { |
1439 | 1522 | if (this.saveLoading) return; |
1523 | + | |
1440 | 1524 | this.saveLoading = true; |
1525 | + | |
1441 | 1526 | this.formatQuestionList(); |
1527 | + | |
1442 | 1528 | let formDatas = deepClone(this.form); |
1529 | + | |
1530 | + formDatas.questionList = formDatas.questionList.filter(item => { | |
1531 | + return item.subQuestions?.length >= 1; | |
1532 | + }); | |
1533 | + | |
1443 | 1534 | for (let i = 0; i < formDatas.questionList.length; i++) { |
1444 | 1535 | delete formDatas.questionList[i].show; |
1445 | 1536 | } |
1537 | + | |
1446 | 1538 | let addPaper = |
1447 | 1539 | this.role == "ROLE_PERSONAL" |
1448 | 1540 | ? this.$request.pAddPaper |
1449 | 1541 | : this.$request.addPaper; |
1542 | + | |
1543 | + formDatas.classIds = this.checkedClass.join(","); | |
1544 | + | |
1450 | 1545 | const { data, status, info } = await addPaper({ |
1451 | 1546 | ...formDatas, |
1452 | 1547 | }); | ... | ... |
src/views/examinationPaper/addQs.vue
... | ... | @@ -7,6 +7,37 @@ |
7 | 7 | </template> |
8 | 8 | </back-box> |
9 | 9 | <div class="content"> |
10 | + | |
11 | + <el-dialog :close-on-click-modal="false" title="选择班级分享" :visible.sync="classSharingType" width="800" | |
12 | + :modal-append-to-body="false" :append-to-body="true"> | |
13 | + <div> | |
14 | + <el-row class="row-subfix"> | |
15 | + <div class="row-line"> | |
16 | + <span class="line-subfix">年级:</span> | |
17 | + <span class="line-value">{{ gradeName }}</span> | |
18 | + </div> | |
19 | + </el-row> | |
20 | + <el-row class="row-subfix" style="margin-top: 20px;"> | |
21 | + <span class="line-subfix" style="float: left;">班级:</span> | |
22 | + <div class="row-line" style="float: left; | |
23 | + background:rgb(245,247,250);padding:15px 10px;width: calc(100% - 80px);border-radius:5px;"> | |
24 | + <span class="line-value" style="min-height: 300px;border-radius: 4px; background: rgb(247,247,250);"> | |
25 | + <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" | |
26 | + @change="handleCheckAllChange">全选</el-checkbox> | |
27 | + <el-checkbox-group v-model="checkedClass" style="margin-top: 15px;" @change="handleCheckedClassChange"> | |
28 | + <el-checkbox v-for="(item, index) in shareClass" :label="item.id" :key="item.id">{{ | |
29 | + item.className }}</el-checkbox> | |
30 | + </el-checkbox-group> | |
31 | + </span> | |
32 | + </div> | |
33 | + </el-row> | |
34 | + </div> | |
35 | + <div slot="footer"> | |
36 | + <el-button type="info" :size="'small'" @click="classSharingType = false">取消</el-button> | |
37 | + <el-button type="primary" :size="'small'" @click="_checkedClass">确定</el-button> | |
38 | + </div> | |
39 | + </el-dialog> | |
40 | + | |
10 | 41 | <el-steps :active="step" finish-status="success" simple style="margin: 20px 0"> |
11 | 42 | <el-step title="基础信息" icon="el-icon-edit"></el-step> |
12 | 43 | <el-step title="题目编辑" icon="el-icon-tickets"></el-step> |
... | ... | @@ -36,7 +67,8 @@ |
36 | 67 | <el-form-item v-if="role != 'ROLE_PERSONAL'" label="分享范围:" prop="sharingType"> |
37 | 68 | <el-radio-group v-model="form.sharingType"> |
38 | 69 | <el-radio :label="0">任课班级分享</el-radio> |
39 | - <el-radio :label="1">全年级分享</el-radio> | |
70 | + <el-radio class="name-radio" @click.native="_selectClassSharingType" v-model="form.sharingType" | |
71 | + :label="1">自定义分享班级</el-radio> | |
40 | 72 | </el-radio-group> |
41 | 73 | </el-form-item> |
42 | 74 | </el-form> |
... | ... | @@ -59,7 +91,7 @@ |
59 | 91 | <div class="qs-options qs-options2">选项设置</div> |
60 | 92 | <div class="qs-upload">题干</div> |
61 | 93 | <div class="qs-upload">题目解析</div> |
62 | - <div class="qs-upload" v-if="knowledgeData.length">知识点</div> | |
94 | + <div class="qs-upload" >知识点</div> | |
63 | 95 | <div class="qs-set">操作</div> |
64 | 96 | </li> |
65 | 97 | </ul> |
... | ... | @@ -99,8 +131,8 @@ |
99 | 131 | </p> |
100 | 132 | <p v-if="question.questionType == 3" class="answer-box"> |
101 | 133 | <span class="answer-s" v-for="option in question.answerOptions?.split(',')" :class="question.correctAnswer?.includes(option) |
102 | - ? 'active' | |
103 | - : '' | |
134 | + ? 'active' | |
135 | + : '' | |
104 | 136 | " :key="option" @click="changAnswer(question, option)">{{ option }}</span> |
105 | 137 | </p> |
106 | 138 | <p v-if="question.questionType == 2" class="answer-box"> |
... | ... | @@ -125,7 +157,7 @@ |
125 | 157 | <el-button class="icon-tickets" type="primary" circle size="mini" icon="el-icon-tickets" |
126 | 158 | @click="openStem(question, 2, index)"></el-button> |
127 | 159 | </div> |
128 | - <div class="qs-upload" v-if="knowledgeData.length"> | |
160 | + <div class="qs-upload" > | |
129 | 161 | <el-button type="primary" circle size="mini" icon="el-icon-price-tag" |
130 | 162 | @click="openKnowledge(question, index)"></el-button> |
131 | 163 | </div> |
... | ... | @@ -179,8 +211,8 @@ |
179 | 211 | <span class="answer-s" v-for="option in subQuestions.answerOptions?.split( |
180 | 212 | ',' |
181 | 213 | )" :class="subQuestions.correctAnswer?.includes(option) |
182 | - ? 'active' | |
183 | - : '' | |
214 | + ? 'active' | |
215 | + : '' | |
184 | 216 | " :key="option" @click="changAnswer(subQuestions, option)">{{ option }}</span> |
185 | 217 | </p> |
186 | 218 | <p v-if="subQuestions.questionType == 2" class="answer-box"> |
... | ... | @@ -206,17 +238,8 @@ |
206 | 238 | <div class="qs-upload"> |
207 | 239 | <el-button class="icon-tickets" type="primary" circle size="mini" icon="el-icon-tickets" |
208 | 240 | @click="openStem(subQuestions, 2, index, indexs)"></el-button> |
209 | - </div> if (location.href.indexOf('askPreparationQuestionsAdd') >= 1) { | |
210 | - this.$router.push({ | |
211 | - path: "/askPreparationQuestions" | |
212 | - }); | |
213 | - } | |
214 | - else if (location.href.indexOf('testPaperAdd') >= 1) { | |
215 | - this.$router.push({ | |
216 | - path: "/testPaper" | |
217 | - }); | |
218 | - } | |
219 | - <div class="qs-upload" v-if="knowledgeData.length"> | |
241 | + </div> | |
242 | + <div class="qs-upload" > | |
220 | 243 | <el-button type="primary" circle size="mini" icon="el-icon-price-tag" |
221 | 244 | @click="openKnowledge(subQuestions, index, indexs)"></el-button> |
222 | 245 | </div> |
... | ... | @@ -233,7 +256,7 @@ |
233 | 256 | </template> |
234 | 257 | </div> |
235 | 258 | <el-dialog :close-on-click-modal="false" title="批量设置答案" :visible.sync="diaSetAns" width="400" |
236 | - :modal-append-to-body="true"> | |
259 | + :modal-append-to-body="false"> | |
237 | 260 | <div class="qs-options"> |
238 | 261 | <p class="dia-tips"> |
239 | 262 | 请点击选项按钮设置答案,多选题题目之间用“,”隔开,若添加5道题:“AC,AD,BD,AC,CD” |
... | ... | @@ -284,8 +307,8 @@ |
284 | 307 | <el-button round @click="step = 0">上一步</el-button> |
285 | 308 | <el-button type="primary" round @click="toStep(2)">下一步</el-button> |
286 | 309 | </div> |
287 | - <el-dialog :close-on-click-modal="false" :title="stem.type == 1 ? '上传题干' : '上传题目解析'" :visible.sync="dialogStem" | |
288 | - v-if="dialogStem" width="800px"> | |
310 | + <el-dialog :close-on-click-modal="false" :modal-append-to-body="false" | |
311 | + :title="stem.type == 1 ? '上传题干' : '上传题目解析'" :visible.sync="dialogStem" v-if="dialogStem" width="800px"> | |
289 | 312 | <div class="upload-box"> |
290 | 313 | <div v-loading="iframeLoading"> |
291 | 314 | <template v-if="stem.type == 1"> |
... | ... | @@ -306,14 +329,10 @@ |
306 | 329 | <el-button @click="dialogStem = false">保存</el-button> |
307 | 330 | </div> |
308 | 331 | </el-dialog> |
309 | - <el-dialog :close-on-click-modal="false" title="知识点" :visible.sync="dialogKnowledge" width="500px"> | |
332 | + <el-dialog :close-on-click-modal="false" :modal-append-to-body="false" title="知识点" | |
333 | + :visible.sync="dialogKnowledge" width="60%" > | |
310 | 334 | <div> |
311 | - <el-form ref="form" :model="stem" label-width="160px"> | |
312 | - <el-form-item label="知识点:"> | |
313 | - <el-cascader size="small" filterable :show-all-levels="false" collapse clearable placeholder="选择知识点" | |
314 | - v-model="stem.knowledge" :options="knowledgeData" :props="{ expandTrigger: 'hover' }"></el-cascader> | |
315 | - </el-form-item> | |
316 | - </el-form> | |
335 | + <knowledgePoints :sectionName="stem.sectionName" :subjectName="stem.subjectName" :knowledges="stem.knowledge" @points="_points" /> | |
317 | 336 | </div> |
318 | 337 | <div slot="footer"> |
319 | 338 | <el-button @click="dialogKnowledge = false">取 消</el-button> |
... | ... | @@ -354,10 +373,20 @@ |
354 | 373 | <script> |
355 | 374 | import { deepClone, checkAnswer } from "utils"; |
356 | 375 | import knowledgeList from "assets/js/knowledgeList.js"; |
376 | +import knowledgePoints from "@/components/knowledgePoints" | |
357 | 377 | export default { |
378 | + components: { | |
379 | + knowledgePoints | |
380 | + }, | |
358 | 381 | data() { |
359 | 382 | return { |
383 | + shareClass: [], | |
360 | 384 | role: "", |
385 | + checkedClass: [], | |
386 | + classSharingType: false, | |
387 | + gradeName: "", | |
388 | + isIndeterminate: false, | |
389 | + checkAll: false, | |
361 | 390 | step: 0, //步骤 |
362 | 391 | gradeClassList: [], //年级-班级数据 |
363 | 392 | gradeList: [], //年级 |
... | ... | @@ -405,6 +434,8 @@ export default { |
405 | 434 | screenshot: "", //题干图片地址 |
406 | 435 | answerScreenshot: "", //题目解析图片地址 |
407 | 436 | knowledge: [], //知识点 |
437 | + subjectName: "", | |
438 | + sectionName: "", | |
408 | 439 | }, |
409 | 440 | type: 1, //1-创建,2-复制答题卡 |
410 | 441 | questionOptions: [ |
... | ... | @@ -423,33 +454,33 @@ export default { |
423 | 454 | subjectName: "", |
424 | 455 | }; |
425 | 456 | }, |
426 | - computed: { | |
427 | - // 知识点列表 根据学段-科目筛选 | |
428 | - knowledgeData: function () { | |
429 | - let jsons = []; | |
430 | - if (this.form.gradeName && this.form.subjectName) { | |
431 | - let sectionName = ""; | |
432 | - this.gradeClassList.map((item) => { | |
433 | - if (this.form.gradeName == item.gradeName) { | |
434 | - sectionName = item.sectionName; | |
435 | - } | |
436 | - }); | |
437 | - if ( | |
438 | - sectionName && | |
439 | - Object.keys(this.knowledgeList).includes(sectionName) | |
440 | - ) { | |
441 | - if ( | |
442 | - Object.keys(this.knowledgeList[sectionName]).includes( | |
443 | - this.form.subjectName | |
444 | - ) | |
445 | - ) { | |
446 | - jsons = this.knowledgeList[sectionName][this.form.subjectName]; | |
447 | - } | |
448 | - } | |
449 | - } | |
450 | - return jsons; | |
451 | - }, | |
452 | - }, | |
457 | + // computed: { | |
458 | + // // 知识点列表 根据学段-科目筛选 | |
459 | + // knowledgeData: function () { | |
460 | + // let jsons = []; | |
461 | + // if (this.form.gradeName && this.form.subjectName) { | |
462 | + // let sectionName = ""; | |
463 | + // this.gradeClassList.map((item) => { | |
464 | + // if (this.form.gradeName == item.gradeName) { | |
465 | + // sectionName = item.sectionName; | |
466 | + // } | |
467 | + // }); | |
468 | + // if ( | |
469 | + // sectionName && | |
470 | + // Object.keys(this.knowledgeList).includes(sectionName) | |
471 | + // ) { | |
472 | + // if ( | |
473 | + // Object.keys(this.knowledgeList[sectionName]).includes( | |
474 | + // this.form.subjectName | |
475 | + // ) | |
476 | + // ) { | |
477 | + // jsons = this.knowledgeList[sectionName][this.form.subjectName]; | |
478 | + // } | |
479 | + // } | |
480 | + // } | |
481 | + // return jsons; | |
482 | + // }, | |
483 | + // }, | |
453 | 484 | watch: { |
454 | 485 | step: function () { |
455 | 486 | this.$nextTick(function () { |
... | ... | @@ -488,6 +519,31 @@ export default { |
488 | 519 | } |
489 | 520 | }, |
490 | 521 | methods: { |
522 | + _points(point) { | |
523 | + | |
524 | + }, | |
525 | + _checkedClass() { | |
526 | + this.classSharingType = false; | |
527 | + }, | |
528 | + handleCheckAllChange(val) { | |
529 | + this.checkedClass = val ? this.shareClass?.map(item => item.id) : []; | |
530 | + this.isIndeterminate = false; | |
531 | + }, | |
532 | + handleCheckedClassChange(value) { | |
533 | + let checkedCount = value.length; | |
534 | + this.checkAll = checkedCount === this.checkedClass.length; | |
535 | + this.isIndeterminate = checkedCount > 0 && checkedCount < this.checkedClass.length; | |
536 | + }, | |
537 | + async _selectClassSharingType() { | |
538 | + this.classSharingType = true; | |
539 | + var findGrade = this.gradeClassList.find(item => item.gradeName == this.form.gradeName); | |
540 | + this.gradeName = findGrade.gradeName; | |
541 | + var classResponse = await this.$request.tClassGrade(findGrade.grade, this.form.subjectName); | |
542 | + if (classResponse.status != 0) { | |
543 | + this.$message.error(classResponse.info); | |
544 | + } | |
545 | + this.shareClass = classResponse.data; | |
546 | + }, | |
491 | 547 | // v1.5 |
492 | 548 | //上传截图 |
493 | 549 | openStem(obj, type, index, indexs) { |
... | ... | @@ -550,6 +606,16 @@ export default { |
550 | 606 | this.stem.index = index; |
551 | 607 | this.stem.indexs = indexs; |
552 | 608 | this.stem.knowledge = (obj.knowledge && obj.knowledge.split("#")) || []; |
609 | + if (this.form.gradeName && this.form.subjectName) { | |
610 | + var matchClass = this.gradeClassList.find((item) => { | |
611 | + if (this.form.gradeName == item.gradeName) { | |
612 | + return item.sectionName; | |
613 | + } | |
614 | + }); | |
615 | + this.stem.sectionName = matchClass?.sectionName ?? ""; | |
616 | + this.stem.subjectName = this.form.subjectName ?? ""; | |
617 | + } | |
618 | + // this.stem.sectionName = | |
553 | 619 | this.dialogKnowledge = true; |
554 | 620 | }, |
555 | 621 | // 知识点 |
... | ... | @@ -578,13 +644,25 @@ export default { |
578 | 644 | ) |
579 | 645 | .then(() => { }) |
580 | 646 | .catch(() => { |
581 | - this.$router.push({ | |
582 | - path: "/examinationPaper", | |
583 | - query: { | |
584 | - type: this.listType, | |
585 | - share: this.listShare, | |
586 | - }, | |
587 | - }); | |
647 | + if (location.href.indexOf('askPreparationQuestionsAdd') >= 1) { | |
648 | + this.$router.push({ | |
649 | + path: "/askPreparationQuestions" | |
650 | + }); | |
651 | + } | |
652 | + else if (location.href.indexOf('testPaperAdd') >= 1) { | |
653 | + this.$router.push({ | |
654 | + path: "/testPaper" | |
655 | + }); | |
656 | + } | |
657 | + else { | |
658 | + this.$router.push({ | |
659 | + path: "/examinationPaper", | |
660 | + query: { | |
661 | + type: this.listType, | |
662 | + share: this.listShare, | |
663 | + }, | |
664 | + }); | |
665 | + } | |
588 | 666 | }); |
589 | 667 | }, |
590 | 668 | //转换题型显示方式 |
... | ... | @@ -1025,6 +1103,13 @@ export default { |
1025 | 1103 | this.saveLoading = true; |
1026 | 1104 | this.formatQuestionList(); |
1027 | 1105 | let formDatas = deepClone(this.form); |
1106 | + | |
1107 | + formDatas.classIds = this.checkedClass.join(","); | |
1108 | + | |
1109 | + formDatas.questionList = formDatas.questionList.filter(item => { | |
1110 | + return item.subQuestions?.length >= 1; | |
1111 | + }); | |
1112 | + | |
1028 | 1113 | let addPaper = |
1029 | 1114 | this.role == "ROLE_PERSONAL" |
1030 | 1115 | ? this.$request.pAddPaper |
... | ... | @@ -1046,14 +1131,26 @@ export default { |
1046 | 1131 | }); |
1047 | 1132 | } |
1048 | 1133 | else { |
1049 | - this.$router.push({ | |
1050 | - path: "/examinationPaper", | |
1051 | - query: { | |
1052 | - type: this.listType, | |
1053 | - share: this.listShare, | |
1054 | - }, | |
1055 | - }); | |
1056 | - } | |
1134 | + if (location.href.indexOf('askPreparationQuestionsAdd') >= 1) { | |
1135 | + this.$router.push({ | |
1136 | + path: "/askPreparationQuestions" | |
1137 | + }); | |
1138 | + } | |
1139 | + else if (location.href.indexOf('testPaperAdd') >= 1) { | |
1140 | + this.$router.push({ | |
1141 | + path: "/testPaper" | |
1142 | + }); | |
1143 | + } | |
1144 | + else { | |
1145 | + this.$router.push({ | |
1146 | + path: "/examinationPaper", | |
1147 | + query: { | |
1148 | + type: this.listType, | |
1149 | + share: this.listShare, | |
1150 | + }, | |
1151 | + }); | |
1152 | + } | |
1153 | + } | |
1057 | 1154 | } else { |
1058 | 1155 | this.$message.error(info); |
1059 | 1156 | } | ... | ... |
src/views/examinationPaper/index.vue
... | ... | @@ -181,7 +181,7 @@ |
181 | 181 | <script> |
182 | 182 | import { downloadFile } from "@/utils"; |
183 | 183 | import axios from "axios"; |
184 | -import example from "@/assets/images/example.jpg"; | |
184 | +import example from "@/assets/images/example.png"; | |
185 | 185 | import example2 from "@/assets/images/example2.png"; |
186 | 186 | export default { |
187 | 187 | name: "examinationPaper", | ... | ... |
src/views/layout/header/header.vue
src/views/login/index.vue
... | ... | @@ -171,7 +171,7 @@ $cursor: #000; |
171 | 171 | } |
172 | 172 | .login-container { |
173 | 173 | width: 100%; |
174 | - height: 100vh; | |
174 | + height: 150vh; | |
175 | 175 | background: url("../../assets/images/login-bg.png") no-repeat; |
176 | 176 | background-size: cover; |
177 | 177 | overflow: hidden; |
... | ... | @@ -215,8 +215,7 @@ $cursor: #000; |
215 | 215 | padding: 30px 35px 0; |
216 | 216 | border-radius: 10px; |
217 | 217 | background: #fff; |
218 | - box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); | |
219 | - margin-top: 200px; | |
218 | + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); | |
220 | 219 | box-sizing: border-box; |
221 | 220 | } |
222 | 221 | ... | ... |
vue.config.js
... | ... | @@ -11,7 +11,7 @@ module.exports = { |
11 | 11 | lintOnSave: false, //是否开启编译时是否不符合eslint提示 |
12 | 12 | productionSourceMap: false, // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。 |
13 | 13 | devServer: { |
14 | - hot:true, | |
14 | + hot: true, | |
15 | 15 | port: 8081, // 端口 |
16 | 16 | open: false, // 启动后打开浏览器 |
17 | 17 | compress: true, |
... | ... | @@ -23,10 +23,11 @@ module.exports = { |
23 | 23 | proxy: { |
24 | 24 | "/": { |
25 | 25 | // target:"http://ezquiz.sunvotecloud.cn", |
26 | - // target:"http://192.168.3.221:8080", | |
27 | - target:"http://121.40.127.171", | |
26 | + // target:"http://192.168.1.151:8089", | |
27 | + target: "http://121.40.127.171:8089", | |
28 | + // target:"http://127.0.0.1:8089", | |
28 | 29 | changeOrigin: true, |
29 | - ws:true, | |
30 | + ws: true, | |
30 | 31 | }, |
31 | 32 | }, |
32 | 33 | disableHostCheck: true | ... | ... |