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 | ... | ... | 
