Commit 6bca489df6140d21609dd2d04323ddc06147d429

Authored by LH_PC
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,70 +18,73 @@ export default {
18 const $app = this.$refs.app; 18 const $app = this.$refs.app;
19 // 设置 屏幕 百分比 尺寸 适配 19 // 设置 屏幕 百分比 尺寸 适配
20 const standardScale = "100%" / "100%"; 20 const standardScale = "100%" / "100%";
21 - var minHeight = 1080;  
22 window.addEventListener( 21 window.addEventListener(
23 "resize", 22 "resize",
24 _.debounce(function () { 23 _.debounce(function () {
  24 +
25 const docHeight = document.body.clientHeight; 25 const docHeight = document.body.clientHeight;
  26 +
26 const docWidth = document.body.clientWidth; 27 const docWidth = document.body.clientWidth;
27 - 28 +
28 if (docWidth < 1700) { 29 if (docWidth < 1700) {
  30 +
29 const currentScale = docHeight / docWidth; 31 const currentScale = docHeight / docWidth;
  32 +
30 let [scale, translate] = [0, 0]; 33 let [scale, translate] = [0, 0];
  34 +
31 if (currentScale < standardScale) { 35 if (currentScale < standardScale) {
32 // 以高度计算 36 // 以高度计算
33 scale = docHeight / 1080; 37 scale = docHeight / 1080;
  38 +
34 const shouleWidth = 1920 * scale; 39 const shouleWidth = 1920 * scale;
35 40
36 const offsetWidth = docWidth - shouleWidth; 41 const offsetWidth = docWidth - shouleWidth;
  42 +
37 translate = 43 translate =
38 offsetWidth > 0 ? `translate(${offsetWidth / 2}px, 0)` : ""; 44 offsetWidth > 0 ? `translate(${offsetWidth / 2}px, 0)` : "";
  45 +
39 } else { 46 } else {
40 // 以宽度计算 47 // 以宽度计算
41 scale = docWidth / 1920; 48 scale = docWidth / 1920;
  49 +
42 const shouleHeight = 1080 * scale; 50 const shouleHeight = 1080 * scale;
  51 +
43 const offsetHeight = docHeight - shouleHeight; 52 const offsetHeight = docHeight - shouleHeight;
  53 +
44 translate = 54 translate =
45 offsetHeight > 0 ? `translate(0, ${offsetHeight / 2}px)` : ""; 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 if (docHeight <= 700) { 58 if (docHeight <= 700) {
  59 +
57 $app.style.cssText = ` 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 else if (docHeight <= 750) { 67 else if (docHeight <= 750) {
  68 +
65 $app.style.cssText = ` 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 else { 76 else {
73 $app.style.cssText = ` 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 } else { 85 } else {
82 $app.style.cssText = ''; 86 $app.style.cssText = '';
83 } 87 }
84 -  
85 }), 88 }),
86 300 89 300
87 ); 90 );
@@ -103,8 +106,7 @@ export default { @@ -103,8 +106,7 @@ export default {
103 body { 106 body {
104 margin: 0px; 107 margin: 0px;
105 padding: 0px; 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 -webkit-font-smoothing: antialiased; 110 -webkit-font-smoothing: antialiased;
109 } 111 }
110 112
src/api/apis/apis.js
@@ -23,8 +23,14 @@ const downService = (url, data) =&gt; { @@ -23,8 +23,14 @@ const downService = (url, data) =&gt; {
23 responseType: 'arraybuffer', 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 gTestExamReport(data) { 34 gTestExamReport(data) {
29 return defaltService(setUpUrls.gtestExamReport, data) 35 return defaltService(setUpUrls.gtestExamReport, data)
30 }, 36 },
@@ -60,7 +66,7 @@ export default { @@ -60,7 +66,7 @@ export default {
60 gExportPhaseInteractiveReport(data) { 66 gExportPhaseInteractiveReport(data) {
61 return downService(setUpUrls.gExportPhaseInteractiveReport, data) 67 return downService(setUpUrls.gExportPhaseInteractiveReport, data)
62 }, 68 },
63 - 69 +
64 // 年级组长-首页统计数据 70 // 年级组长-首页统计数据
65 gIndex(data) { 71 gIndex(data) {
66 return defaltService(setUpUrls.gIndex, data) 72 return defaltService(setUpUrls.gIndex, data)
@@ -146,8 +152,27 @@ export default { @@ -146,8 +152,27 @@ export default {
146 return defaltService(setUpUrls.tClassList, data) 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 tPaperDetail(data) { 177 tPaperDetail(data) {
153 return defaltService(setUpUrls.tPaperDetail, data) 178 return defaltService(setUpUrls.tPaperDetail, data)
@@ -168,6 +193,18 @@ export default { @@ -168,6 +193,18 @@ export default {
168 tClassdiffExamReport(data) { 193 tClassdiffExamReport(data) {
169 return defaltService(setUpUrls.tclassdiffExamReport, data) 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 tListExamReport(data) { 209 tListExamReport(data) {
173 return defaltService(setUpUrls.tListExamReport, data) 210 return defaltService(setUpUrls.tListExamReport, data)
@@ -926,8 +963,12 @@ export default { @@ -926,8 +963,12 @@ export default {
926 // 查询即时测多班默认等级列表 963 // 查询即时测多班默认等级列表
927 defaultLevels(data) { 964 defaultLevels(data) {
928 return defaltService(setUpUrls.defaultLevels, data) 965 return defaltService(setUpUrls.defaultLevels, data)
  966 + }, // 查询即时测多班默认等级列表
  967 + gdefaultLevels(data) {
  968 + return defaltService(setUpUrls.gdefaultLevels, data)
929 }, 969 },
930 970
  971 +
931 // 删除随堂问报表 972 // 删除随堂问报表
932 deletePaperReport(data) { 973 deletePaperReport(data) {
933 return defaltService(setUpUrls.deletePaperReport, data) 974 return defaltService(setUpUrls.deletePaperReport, data)
src/api/urls/apis.js
1 1
2 export default { 2 export default {
  3 + // 年级组长-查询报表列表
  4 + gKnowledge: "/api_html/knowledge/list",
3 // 年级组长-查询报表列表 5 // 年级组长-查询报表列表
4 gListExamReport: "/api_html/grade/manager/listExamReport", 6 gListExamReport: "/api_html/grade/manager/listExamReport",
5 // 年级组长-查询管理的班级 7 // 年级组长-查询管理的班级
@@ -8,6 +10,9 @@ export default { @@ -8,6 +10,9 @@ export default {
8 gExportPhaseAnswerReport: "/api_html/grade/manager/exportPhaseAnswerReport", 10 gExportPhaseAnswerReport: "/api_html/grade/manager/exportPhaseAnswerReport",
9 // 年级组长-导出阶段测练 11 // 年级组长-导出阶段测练
10 gExportPhaseExamReport: "/api_html/grade/manager/exportPhaseExamReport", 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 gExportPhaseInteractiveReport: "/api_html/grade/manager/exportPhaseInteractiveReport", 17 gExportPhaseInteractiveReport: "/api_html/grade/manager/exportPhaseInteractiveReport",
13 // 年级组长-成绩测验单 18 // 年级组长-成绩测验单
@@ -63,19 +68,21 @@ export default { @@ -63,19 +68,21 @@ export default {
63 // 任课老师-班级情况对比 68 // 任课老师-班级情况对比
64 tclassdiffExamReport: "/api_html/teaching/classdiffExamReport", 69 tclassdiffExamReport: "/api_html/teaching/classdiffExamReport",
65 tClassFromGrade: "/api_html/teaching/grade/classList", 70 tClassFromGrade: "/api_html/teaching/grade/classList",
  71 + tClassGrade:'/api_html/teaching/grade',
66 //任课老师-测验成绩单 72 //任课老师-测验成绩单
67 tTestExamReport: "/api_html/teaching/testExamReport", 73 tTestExamReport: "/api_html/teaching/testExamReport",
68 //任课老师-查询答题卡详情 74 //任课老师-查询答题卡详情
69 tPaperDetail: "/api_html/teaching/paperDetail", 75 tPaperDetail: "/api_html/teaching/paperDetail",
70 //任课老师-查询管理班级授课科目 76 //任课老师-查询管理班级授课科目
71 tSubjectList: "/api_html/teaching/subjectList", 77 tSubjectList: "/api_html/teaching/subjectList",
72 - tListExamReport: "/api_html/teaching/listExamReport", 78 + tListExamReport: "/api_html/teaching/listExamReport",
73 //任课老师-分页查询课时报表列表 79 //任课老师-分页查询课时报表列表
74 periodReportList: "/api_html/teaching/periodReportList", 80 periodReportList: "/api_html/teaching/periodReportList",
75 //任课老师-查询阶段问答报表 81 //任课老师-查询阶段问答报表
76 phaseAnswerReport: "/api_html/teaching/phaseAnswerReport", 82 phaseAnswerReport: "/api_html/teaching/phaseAnswerReport",
77 //任课老师-查询阶段互动报表 83 //任课老师-查询阶段互动报表
78 phaseInteractiveReport: "/api_html/teaching/phaseInteractiveReport", 84 phaseInteractiveReport: "/api_html/teaching/phaseInteractiveReport",
  85 + exportPhaseExamReport: "/api_html/teaching/exportPhaseExamReport",
79 //任课老师-查询课时题目列表 86 //任课老师-查询课时题目列表
80 periodQuestionList: "/api_html/teaching/periodQuestionList", 87 periodQuestionList: "/api_html/teaching/periodQuestionList",
81 //任课老师-设置课时报表答案 88 //任课老师-设置课时报表答案
@@ -116,8 +123,7 @@ export default { @@ -116,8 +123,7 @@ export default {
116 exportPhaseInteractiveReport: "/api_html/teaching/exportPhaseInteractiveReport", 123 exportPhaseInteractiveReport: "/api_html/teaching/exportPhaseInteractiveReport",
117 //任课老师-导出单课时报表 124 //任课老师-导出单课时报表
118 exportPeriodReport: "/api_html/teaching/exportPeriodReport", 125 exportPeriodReport: "/api_html/teaching/exportPeriodReport",
119 - //任课老师-导出阶段测练报表  
120 - exportPhaseExamReport: "/api_html/teaching/exportPhaseExamReport", 126 +
121 //任课老师-导出单卷测练报表 127 //任课老师-导出单卷测练报表
122 exportExamReport: "/api_html/teaching/exportExamReport", 128 exportExamReport: "/api_html/teaching/exportExamReport",
123 //任课老师-查询学生列表 129 //任课老师-查询学生列表
@@ -475,6 +481,7 @@ export default { @@ -475,6 +481,7 @@ export default {
475 exportExamMultiReport: "/api_html/teaching/exportExamMultiReport", 481 exportExamMultiReport: "/api_html/teaching/exportExamMultiReport",
476 //查询即时测多班默认等级列表 482 //查询即时测多班默认等级列表
477 defaultLevels: "/api_html/teaching/defaultLevels", 483 defaultLevels: "/api_html/teaching/defaultLevels",
  484 + gdefaultLevels: "/api_html/grade/manager/defaultLevels",
478 //教学班模版下载 485 //教学班模版下载
479 tClassAndStudentTemplate: "/api_html/school/manager/tClassAndStudentTemplate", 486 tClassAndStudentTemplate: "/api_html/school/manager/tClassAndStudentTemplate",
480 //教学班导出 487 //教学班导出
src/assets/css/index.scss
@@ -27,12 +27,29 @@ @@ -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 .green-el-button { 46 .green-el-button {
31 background-color: rgba(65, 204, 149, 1); 47 background-color: rgba(65, 204, 149, 1);
32 color: white; 48 color: white;
33 border-color: rgba(65, 204, 149, 1); 49 border-color: rgba(65, 204, 149, 1);
34 50
35 - :focus,:hover { 51 + :focus,
  52 + :hover {
36 background-color: rgba(65, 204, 149, 1); 53 background-color: rgba(65, 204, 149, 1);
37 color: white; 54 color: white;
38 border-color: rgba(65, 204, 149, 1); 55 border-color: rgba(65, 204, 149, 1);
@@ -56,7 +73,7 @@ @@ -56,7 +73,7 @@
56 flex-wrap: nowrap; 73 flex-wrap: nowrap;
57 74
58 .sel { 75 .sel {
59 - width: 8%; 76 + width: 10%;
60 min-width: 160px; 77 min-width: 160px;
61 margin-right: 20px; 78 margin-right: 20px;
62 } 79 }
@@ -78,7 +95,7 @@ @@ -78,7 +95,7 @@
78 } 95 }
79 96
80 .input-with-select { 97 .input-with-select {
81 - width: 200px; 98 + width: 230px;
82 height: 36px; 99 height: 36px;
83 margin-right: 50px; 100 margin-right: 50px;
84 border-radius: 20px; 101 border-radius: 20px;
@@ -290,6 +307,31 @@ ul { @@ -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 .default-title { 336 .default-title {
295 height: 36px; 337 height: 36px;
@@ -302,6 +344,7 @@ ul { @@ -302,6 +344,7 @@ ul {
302 text-transform: none; 344 text-transform: none;
303 } 345 }
304 346
  347 +
305 // 默认实体 348 // 默认实体
306 .default-body { 349 .default-body {
307 font-size: 14px; 350 font-size: 14px;
@@ -329,6 +372,9 @@ ul { @@ -329,6 +372,9 @@ ul {
329 padding: 0px !important; 372 padding: 0px !important;
330 373
331 .default-table { 374 .default-table {
  375 + width: 100% !important;
  376 + height: 100% !important;
  377 +
332 th { 378 th {
333 font-weight: 400; 379 font-weight: 400;
334 font-size: 14px; 380 font-size: 14px;
@@ -336,11 +382,14 @@ ul { @@ -336,11 +382,14 @@ ul {
336 text-align: left; 382 text-align: left;
337 font-style: normal; 383 font-style: normal;
338 text-transform: none; 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,8 +428,8 @@ ul {
379 padding: 14px 20px !important; 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 .filter-input, 435 .filter-input,
@@ -395,10 +444,14 @@ ul { @@ -395,10 +444,14 @@ ul {
395 444
396 input { 445 input {
397 // border: 1px solid #DCDFE6; 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 .el-button { 455 .el-button {
403 width: auto; 456 width: auto;
404 line-height: 0px; 457 line-height: 0px;
@@ -409,4 +462,59 @@ ul { @@ -409,4 +462,59 @@ ul {
409 background-color: rgb(107, 126, 245); 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 \ No newline at end of file 521 \ No newline at end of file
src/assets/images/example.jpg deleted

519 KB

src/components/backBox.vue
1 <template> 1 <template>
2 - <div class="back"> 2 + <div class="back default-title">
3 <div class="back-l" @click="back"> 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 <slot name="title"></slot> 5 <slot name="title"></slot>
6 </div> 6 </div>
7 <div class="back-r"> 7 <div class="back-r">
@@ -55,7 +55,6 @@ export default { @@ -55,7 +55,6 @@ export default {
55 align-items: center; 55 align-items: center;
56 cursor: pointer; 56 cursor: pointer;
57 flex-shrink: 0; 57 flex-shrink: 0;
58 - font-size: 18px;  
59 font-weight: 500; 58 font-weight: 500;
60 } 59 }
61 60
@@ -66,7 +65,6 @@ export default { @@ -66,7 +65,6 @@ export default {
66 } 65 }
67 66
68 .fa-mail-reply-all { 67 .fa-mail-reply-all {
69 - font-size: 28px;  
70 color: #b3b3b3; 68 color: #b3b3b3;
71 margin-right: 12px; 69 margin-right: 12px;
72 } 70 }
src/components/charts/lineChart.vue
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 </template> 3 </template>
4 4
5 <script> 5 <script>
  6 +import 'echarts/lib/component/dataZoom'
6 export default { 7 export default {
7 name: "lineChart", 8 name: "lineChart",
8 props: { 9 props: {
@@ -11,7 +12,7 @@ export default { @@ -11,7 +12,7 @@ export default {
11 xAxis: Array, 12 xAxis: Array,
12 colors: Array, 13 colors: Array,
13 formatterYAxis: true, 14 formatterYAxis: true,
14 - tooltipFormatter:false 15 + tooltipFormatter: false
15 }, 16 },
16 watch: { 17 watch: {
17 params: { 18 params: {
@@ -19,6 +20,7 @@ export default { @@ -19,6 +20,7 @@ export default {
19 if (val.length) { 20 if (val.length) {
20 this.initData(); 21 this.initData();
21 } 22 }
  23 + console.log(val)
22 }, 24 },
23 deep: true, 25 deep: true,
24 }, 26 },
@@ -33,6 +35,43 @@ export default { @@ -33,6 +35,43 @@ export default {
33 this.initData(); 35 this.initData();
34 }, 36 },
35 methods: { 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 setOption() { 75 setOption() {
37 const that = this; 76 const that = this;
38 const options = { 77 const options = {
@@ -43,10 +82,27 @@ export default { @@ -43,10 +82,27 @@ export default {
43 confine: true, 82 confine: true,
44 formatter(v) { 83 formatter(v) {
45 let html = `<p>${v.seriesName}</p>` 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 return html 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 legend: { 106 legend: {
51 show: true, 107 show: true,
52 top: 0, 108 top: 0,
@@ -54,18 +110,37 @@ export default { @@ -54,18 +110,37 @@ export default {
54 itemHeight: 15, 110 itemHeight: 15,
55 icon: "circle" 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 xAxis: { 125 xAxis: {
58 type: "category", 126 type: "category",
59 data: this.xAxis, 127 data: this.xAxis,
60 axisLine: { show: true, lineStyle: { color: "#e2e2e2" } }, 128 axisLine: { show: true, lineStyle: { color: "#e2e2e2" } },
61 axisTick: { 129 axisTick: {
  130 + alignWithLabel: false,
62 show: false, 131 show: false,
63 }, 132 },
  133 + triggerEvent: true,
64 axisLabel: { 134 axisLabel: {
65 color: "#333", 135 color: "#333",
66 interval: 0, 136 interval: 0,
67 width: Math.ceil(600 / this.xAxis.length), 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 yAxis: { 146 yAxis: {
@@ -100,7 +175,7 @@ export default { @@ -100,7 +175,7 @@ export default {
100 data: item.value, 175 data: item.value,
101 }; 176 };
102 }), 177 }),
103 - }; 178 + };
104 return options; 179 return options;
105 }, 180 },
106 initData() { 181 initData() {
@@ -112,6 +187,7 @@ export default { @@ -112,6 +187,7 @@ export default {
112 this.chart?.clear(); 187 this.chart?.clear();
113 this.chart.setOption(options, true); 188 this.chart.setOption(options, true);
114 this.chart.off("click"); 189 this.chart.off("click");
  190 + this.extension(this.chart)
115 this.chart.on("click", "series", (params) => { 191 this.chart.on("click", "series", (params) => {
116 // this.$emit("clickPieChart", params); 192 // this.$emit("clickPieChart", params);
117 }); 193 });
src/components/charts/pieChart.vue
@@ -99,7 +99,7 @@ export default { @@ -99,7 +99,7 @@ export default {
99 }; 99 };
100 </script> 100 </script>
101 101
102 -<style lang="scss" scoped> 102 +<style scoped>
103 .chart { 103 .chart {
104 height: 100%; 104 height: 100%;
105 } 105 }
src/components/lang/langSelect.vue
@@ -40,12 +40,12 @@ export default { @@ -40,12 +40,12 @@ export default {
40 } 40 }
41 </script> 41 </script>
42 <style> 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 </style> 45 </style>
46 <style scoped> 46 <style scoped>
47 .international-icon { 47 .international-icon {
48 - font-size: 20px; 48 +
49 cursor: pointer; 49 cursor: pointer;
50 vertical-align: -5px !important; 50 vertical-align: -5px !important;
51 } 51 }
src/components/setAnswer.vue
@@ -82,8 +82,7 @@ @@ -82,8 +82,7 @@
82 <el-dialog :close-on-click-modal="false" 82 <el-dialog :close-on-click-modal="false"
83 title="批量设置答案" 83 title="批量设置答案"
84 :visible.sync="diaSetAns" 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 <div class="qs-options set-questions"> 87 <div class="qs-options set-questions">
89 <p>{{ setSubPro(formAns.qusType) }}:</p> 88 <p>{{ setSubPro(formAns.qusType) }}:</p>
src/config/index.js
@@ -7,6 +7,7 @@ const modeUrl = { @@ -7,6 +7,7 @@ const modeUrl = {
7 }, 7 },
8 // 生产环境 8 // 生产环境
9 production: { 9 production: {
  10 + baseURL: "/api/",
10 authBaseURL: "", 11 authBaseURL: "",
11 $cdn:"" 12 $cdn:""
12 }, 13 },
src/store/index.js
@@ -56,7 +56,7 @@ const store = new Vuex.Store({ @@ -56,7 +56,7 @@ const store = new Vuex.Store({
56 } 56 }
57 57
58 let aRouters = addrouterList.filter((item) => { 58 let aRouters = addrouterList.filter((item) => {
59 - 59 +
60 let path = item.children[0]?.path.replace("/", ""); 60 let path = item.children[0]?.path.replace("/", "");
61 if (routers?.includes(path) == true) return item; 61 if (routers?.includes(path) == true) return item;
62 else if (item.demoRoles?.includes(state.info.showRole) == true) return item; 62 else if (item.demoRoles?.includes(state.info.showRole) == true) return item;
@@ -66,9 +66,9 @@ const store = new Vuex.Store({ @@ -66,9 +66,9 @@ const store = new Vuex.Store({
66 return itemFilter.demoRoles?.includes(state.info.showRole) == true 66 return itemFilter.demoRoles?.includes(state.info.showRole) == true
67 }); 67 });
68 if (item.children.length >= 1) return item; 68 if (item.children.length >= 1) return item;
69 - }  
70 - return null;  
71 - }); 69 + }
  70 + return null;
  71 + });
72 state.addRouters = aRouters; // 保存动态路由用来addRouter 72 state.addRouters = aRouters; // 保存动态路由用来addRouter
73 state.routers = defaultRouter.concat(aRouters); // 所有有权限的路由表,用来生成菜单列表 73 state.routers = defaultRouter.concat(aRouters); // 所有有权限的路由表,用来生成菜单列表
74 localStorage.setItem("addRouters", JSON.stringify(routers)); 74 localStorage.setItem("addRouters", JSON.stringify(routers));
@@ -85,7 +85,8 @@ const store = new Vuex.Store({ @@ -85,7 +85,8 @@ const store = new Vuex.Store({
85 }, 85 },
86 setClasses(state, data) { 86 setClasses(state, data) {
87 state.classes = data; 87 state.classes = data;
88 - localStorage.setItem("classes", data); 88 + console.log(state)
  89 + localStorage.setItem('store', "classes", data);
89 }, 90 },
90 setRefreshTestList(state, data) { 91 setRefreshTestList(state, data) {
91 state.refreshTestList = data; 92 state.refreshTestList = data;
src/utils/index.js
@@ -106,6 +106,32 @@ export function deepClone(obj) { @@ -106,6 +106,32 @@ export function deepClone(obj) {
106 return result; 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 // // 3DES加密 135 // // 3DES加密
110 // export function desEncrypt (str, key = encryptKey, iv = encryptIV) { 136 // export function desEncrypt (str, key = encryptKey, iv = encryptIV) {
111 // var cryptoKey = CryptoJS.enc.Utf8.parse(key) 137 // var cryptoKey = CryptoJS.enc.Utf8.parse(key)
@@ -840,6 +866,7 @@ export function tablePrint(id, title, type = null) { @@ -840,6 +866,7 @@ export function tablePrint(id, title, type = null) {
840 .tit{text-align:center;font-size:20px;color:#333;line-height:24px;font-weight:700;padding:10px 0;margin:0;} 866 .tit{text-align:center;font-size:20px;color:#333;line-height:24px;font-weight:700;padding:10px 0;margin:0;}
841 .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;} 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 .el-table{width:100%} 868 .el-table{width:100%}
  869 + .print-hidden{display:none;}
843 .el-table,.el-table__body-wrapper{max-height:auto} 870 .el-table,.el-table__body-wrapper{max-height:auto}
844 .el-table .el-table__cell{padding:12px 0} 871 .el-table .el-table__cell{padding:12px 0}
845 .el-table thead tr:first-child th.el-table__cell{border-top: 1px solid #ccc} 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,7 +50,7 @@
50 }}</template> 50 }}</template>
51 </el-table-column> 51 </el-table-column>
52 </el-table-column> 52 </el-table-column>
53 - <el-table-column label="查看雷达图"> 53 + <el-table-column label="查看雷达图" fixed="right" width="100" align="center">
54 <template slot-scope="scoped"> 54 <template slot-scope="scoped">
55 <el-button type="text" @click="openRandarChart(scoped.row)">查看</el-button> 55 <el-button type="text" @click="openRandarChart(scoped.row)">查看</el-button>
56 </template> 56 </template>
@@ -63,32 +63,27 @@ @@ -63,32 +63,27 @@
63 <el-table class="default-table" :data="interactionList"> 63 <el-table class="default-table" :data="interactionList">
64 <el-table-column prop="studentCode" label="学号"></el-table-column> 64 <el-table-column prop="studentCode" label="学号"></el-table-column>
65 <el-table-column prop="studentName" label="姓名"></el-table-column> 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 <el-table-column v-for="(item, index) in interactionOptions" :key="index" :label="item"> 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 <template slot-scope="scoped">{{ 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 }}</template> 76 }}</template>
74 </el-table-column> 77 </el-table-column>
75 - <el-table-column v-else label="互动数" :prop="'interactionsNum' + item"> 78 + <el-table-column label="参与数" :prop="'interactionsNum' + item">
76 <template slot-scope="scoped">{{ 79 <template slot-scope="scoped">{{
77 scoped.row["interactionsNum" + item] || 80 scoped.row["interactionsNum" + item] ||
78 Number(scoped.row["interactionsNum" + item]) === 0 81 Number(scoped.row["interactionsNum" + item]) === 0
79 ? scoped.row["interactionsNum" + item] 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 }}</template> 84 }}</template>
90 </el-table-column> 85 </el-table-column>
91 - <el-table-column v-else label="参与数" :prop="'interactionsCorrectNum' + item"> 86 + <el-table-column label="答对数" :prop="'interactionsCorrectNum' + item">
92 <template slot-scope="scoped">{{ 87 <template slot-scope="scoped">{{
93 scoped.row["interactionsCorrectNum" + item] || 88 scoped.row["interactionsCorrectNum" + item] ||
94 Number(scoped.row["interactionsCorrectNum" + item]) === 0 89 Number(scoped.row["interactionsCorrectNum" + item]) === 0
@@ -101,18 +96,16 @@ @@ -101,18 +96,16 @@
101 </el-row> 96 </el-row>
102 </div> 97 </div>
103 </div> 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 <div class="chart-box"> 101 <div class="chart-box">
108 - <RadarChart id="askRadarChart" :params="radarChart" :tooltipFormatter="true" /> 102 + <RadarChart id="radarChart" :params="radarChart" />
109 </div> 103 </div>
110 </el-dialog> 104 </el-dialog>
111 </div> 105 </div>
112 </template> 106 </template>
113 <script> 107 <script>
114 -import { formatDate } from "utils";  
115 -import { downloadFile, tablePrint } from "@/utils"; 108 +import { downloadFile, tablePrint, formatDate } from "@/utils";
116 import RadarChart from "@/components/charts/radarChart"; 109 import RadarChart from "@/components/charts/radarChart";
117 export default { 110 export default {
118 name: "askbzrMutli", 111 name: "askbzrMutli",
@@ -148,6 +141,7 @@ export default { @@ -148,6 +141,7 @@ export default {
148 interactionList: [], 141 interactionList: [],
149 interactionOptions: [], 142 interactionOptions: [],
150 interactionSubjects: [], 143 interactionSubjects: [],
  144 + redarVisible: false,
151 radarChart: { 145 radarChart: {
152 title: "", 146 title: "",
153 indicator: [ 147 indicator: [
@@ -174,7 +168,25 @@ export default { @@ -174,7 +168,25 @@ export default {
174 await this._changeType(); 168 await this._changeType();
175 }, 169 },
176 methods: { 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 _print() { 190 _print() {
179 191
180 tablePrint("print-content", this.currentType); 192 tablePrint("print-content", this.currentType);
@@ -227,7 +239,6 @@ export default { @@ -227,7 +239,6 @@ export default {
227 return aTime; 239 return aTime;
228 }, 240 },
229 async _multipleSubjectAnswers() { 241 async _multipleSubjectAnswers() {
230 -  
231 const answersRequest = 242 const answersRequest =
232 this.role == "ROLE_PERSONAL" 243 this.role == "ROLE_PERSONAL"
233 ? this.$request.pPhaseAnswerReport 244 ? this.$request.pPhaseAnswerReport
@@ -236,10 +247,9 @@ export default { @@ -236,10 +247,9 @@ export default {
236 let query = { 247 let query = {
237 periodIds: this.$props.askReportIds, 248 periodIds: this.$props.askReportIds,
238 classIds: [this.$props.queryParams.class], 249 classIds: [this.$props.queryParams.class],
239 - subjectNames: [this.$props.queryParams.subjectNames], 250 + subjectNames: [...this.$props.queryParams.subjects],
240 }; 251 };
241 252
242 -  
243 let answersResponse = await answersRequest({ 253 let answersResponse = await answersRequest({
244 ...query 254 ...query
245 }); 255 });
@@ -297,6 +307,7 @@ export default { @@ -297,6 +307,7 @@ export default {
297 let query = { 307 let query = {
298 periodIds: this.$props.askReportIds, 308 periodIds: this.$props.askReportIds,
299 classIds: [this.$props.queryParams.class], 309 classIds: [this.$props.queryParams.class],
  310 + subjectNames: [...this.$props.queryParams.subjects],
300 }; 311 };
301 312
302 let interactionReponse = await interactionRequest({ 313 let interactionReponse = await interactionRequest({
@@ -312,23 +323,25 @@ export default { @@ -312,23 +323,25 @@ export default {
312 323
313 this.interactionList = interactionReponse.data?.list?.map((item) => { 324 this.interactionList = interactionReponse.data?.list?.map((item) => {
314 let params = {}; 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 subjectName.push(items.subjectName); 328 subjectName.push(items.subjectName);
318 } 329 }
  330 + params["answerTimes" + items.subjectName] =
  331 + items.answerTimes;
319 params["interactionsNum" + items.subjectName] = 332 params["interactionsNum" + items.subjectName] =
320 items.interactionsNum; 333 items.interactionsNum;
321 params["interactionsCorrectNum" + items.subjectName] = 334 params["interactionsCorrectNum" + items.subjectName] =
322 items.interactionsCorrectNum; 335 items.interactionsCorrectNum;
323 }); 336 });
  337 +
324 return { 338 return {
325 ...item, 339 ...item,
326 ...params, 340 ...params,
327 }; 341 };
328 }); 342 });
329 - 343 + console.log(this.interactionList)
330 this.interactionOptions = [...subjectName]; 344 this.interactionOptions = [...subjectName];
331 - console.log(this.interactionOptions)  
332 }, 345 },
333 openRandarChart(obj) { 346 openRandarChart(obj) {
334 this.radarChart = { 347 this.radarChart = {
@@ -345,7 +358,7 @@ export default { @@ -345,7 +358,7 @@ export default {
345 ], 358 ],
346 seriesData: [], 359 seriesData: [],
347 }; 360 };
348 - this.radarChart.title = obj.studentName + "-多科-多课时作答表现图"; 361 + this.radarChart.title = obj.studentName + "-多科阶段作答表现图";
349 let dataList = obj.dataList.slice(1, obj.dataList.length); 362 let dataList = obj.dataList.slice(1, obj.dataList.length);
350 let subjectList = dataList.map((item) => item.subjectName); 363 let subjectList = dataList.map((item) => item.subjectName);
351 subjectList.map((item, index) => { 364 subjectList.map((item, index) => {
@@ -377,7 +390,7 @@ export default { @@ -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,11 +3,23 @@
3 <el-table class="default-table" :data="$props.datas" border> 3 <el-table class="default-table" :data="$props.datas" border>
4 <el-table-column prop="subjectName" label="科目" width="180" /> 4 <el-table-column prop="subjectName" label="科目" width="180" />
5 <el-table-column prop="title" label="课时名称" /> 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 <el-table-column prop="questionNum" label="题目总数" width="180" /> 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 <el-table-column label="操作" width="200"> 23 <el-table-column label="操作" width="200">
12 <template slot-scope="scoped"> 24 <template slot-scope="scoped">
13 <template v-if="scoped.row.answerNum == 0"> 25 <template v-if="scoped.row.answerNum == 0">
@@ -42,9 +54,10 @@ export default { @@ -42,9 +54,10 @@ export default {
42 id: dataRow.id, 54 id: dataRow.id,
43 }); 55 });
44 if (status != 0) { 56 if (status != 0) {
  57 + this.$message.success("删除成功!");
45 this.$message.error(info); 58 this.$message.error(info);
46 } 59 }
47 - this.$emit("resfer"); 60 + this.$emit("opration");
48 }, 61 },
49 _linkToDetail(dataRow) { 62 _linkToDetail(dataRow) {
50 this.$router.push({ 63 this.$router.push({
src/views/basic/askTestQuestion/components/askSummaryReport.vue
@@ -63,15 +63,15 @@ @@ -63,15 +63,15 @@
63 </div> 63 </div>
64 <div class="row-line"> 64 <div class="row-line">
65 <span class="line-subfix">总参与度:</span> 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 </div> 67 </div>
68 <div class="row-line"> 68 <div class="row-line">
69 <span class="line-subfix">班级正确率:</span> 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 </div> 71 </div>
72 <div class="row-line"> 72 <div class="row-line">
73 <span class="line-subfix">已达正确率:</span> 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 </div> 75 </div>
76 <div class="row-line"> 76 <div class="row-line">
77 <span class="line-subfix">反馈时长:</span> 77 <span class="line-subfix">反馈时长:</span>
@@ -81,7 +81,7 @@ @@ -81,7 +81,7 @@
81 <el-row class="row-table"> 81 <el-row class="row-table">
82 <el-table class="default-table" :data="singleSubjectSummary" border> 82 <el-table class="default-table" :data="singleSubjectSummary" border>
83 <el-table-column prop="title" label="课时-题号" /> 83 <el-table-column prop="title" label="课时-题号" />
84 - <el-table-column label="题干" width="120"> 84 + <el-table-column label="题干" width="80">
85 <template slot-scope="scoped"> 85 <template slot-scope="scoped">
86 <el-button type="text" @click="openStem(scoped.row)">查看</el-button> 86 <el-button type="text" @click="openStem(scoped.row)">查看</el-button>
87 </template> 87 </template>
@@ -91,18 +91,26 @@ @@ -91,18 +91,26 @@
91 </el-table-column> 91 </el-table-column>
92 <el-table-column prop="answeredNum" label="答题人数" width="100" /> 92 <el-table-column prop="answeredNum" label="答题人数" width="100" />
93 <el-table-column prop="correctAnswerNum" label="答对人数" width="100" /> 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 <template slot-scope="scoped">{{ scoped.row.participationRate }}%</template> 95 <template slot-scope="scoped">{{ scoped.row.participationRate }}%</template>
96 </el-table-column> 96 </el-table-column>
97 - <el-table-column prop="classCorrectRate" label="班级正确率(单题)" width="150"> 97 + <el-table-column prop="classCorrectRate" label="班级正确率(单题)" width="170">
98 <template slot-scope="scoped">{{ scoped.row.classCorrectRate }}%</template> 98 <template slot-scope="scoped">{{ scoped.row.classCorrectRate }}%</template>
99 </el-table-column> 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 <template slot-scope="scoped">{{ scoped.row.answerCorrectRate }}%</template> 102 <template slot-scope="scoped">{{ scoped.row.answerCorrectRate }}%</template>
103 </el-table-column> 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 <el-table-column prop="correctAnswer" label="正确答案(单题)" width="150"> 114 <el-table-column prop="correctAnswer" label="正确答案(单题)" width="150">
107 <template slot-scope="scoped"> 115 <template slot-scope="scoped">
108 {{ 116 {{
@@ -182,7 +190,7 @@ @@ -182,7 +190,7 @@
182 <el-table-column prop="correctRate" label="总正确率" width="120"> 190 <el-table-column prop="correctRate" label="总正确率" width="120">
183 <template slot-scope="scoped">{{ scoped.row.correctRate }}%</template> 191 <template slot-scope="scoped">{{ scoped.row.correctRate }}%</template>
184 </el-table-column> 192 </el-table-column>
185 - <el-table-column prop="correctRateRank" label="总正确率排名" width="120" /> 193 + <el-table-column prop="correctRateRank" label="总正确率排名" width="140" />
186 <el-table-column prop="answerCorrectRate" label="已答正确率" width="120"> 194 <el-table-column prop="answerCorrectRate" label="已答正确率" width="120">
187 <template slot-scope="scoped">{{ scoped.row.answerCorrectRate }}%</template> 195 <template slot-scope="scoped">{{ scoped.row.answerCorrectRate }}%</template>
188 </el-table-column> 196 </el-table-column>
@@ -203,20 +211,20 @@ @@ -203,20 +211,20 @@
203 <el-table-column prop="interactionsCorrectNum" label="对错得分" width="210" /> 211 <el-table-column prop="interactionsCorrectNum" label="对错得分" width="210" />
204 <el-table-column prop="rushAnswerTimes" label="抢答成功次数" width="210" /> 212 <el-table-column prop="rushAnswerTimes" label="抢答成功次数" width="210" />
205 <el-table-column prop="rushAnswerCorrectTimes" label="抢答答对次数" width="210" /> 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 </el-table> 216 </el-table>
209 </el-row> 217 </el-row>
210 </div> 218 </div>
211 </div> 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 <div class="chart-box"> 222 <div class="chart-box">
215 <LineChart id="askLineChart" :params="lineChart.data" :xAxis="lineChart.xAxis" 223 <LineChart id="askLineChart" :params="lineChart.data" :xAxis="lineChart.xAxis"
216 :tooltipFormatter="true" /> 224 :tooltipFormatter="true" />
217 </div> 225 </div>
218 </el-dialog> 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 <iframe v-if="stem && stem.src" :src="stem.src" style="width: 100%;min-height: 400px;" /> 228 <iframe v-if="stem && stem.src" :src="stem.src" style="width: 100%;min-height: 400px;" />
221 </el-dialog> 229 </el-dialog>
222 <ExportDia :exportStudent="exportStudent" :diaShow="diaShow" @cancel="cancel" @exportData="_exportData" 230 <ExportDia :exportStudent="exportStudent" :diaShow="diaShow" @cancel="cancel" @exportData="_exportData"
@@ -224,7 +232,7 @@ @@ -224,7 +232,7 @@
224 </div> 232 </div>
225 </template> 233 </template>
226 <script> 234 <script>
227 -import { formatDate } from "utils"; 235 +import { formatDate,getKnowledge } from "utils";
228 import { downloadFile, tablePrint } from "@/utils"; 236 import { downloadFile, tablePrint } from "@/utils";
229 import LineChart from "@/components/charts/lineChart"; 237 import LineChart from "@/components/charts/lineChart";
230 export default { 238 export default {
@@ -234,7 +242,8 @@ export default { @@ -234,7 +242,8 @@ export default {
234 }, 242 },
235 props: { 243 props: {
236 askReportIds: Array, 244 askReportIds: Array,
237 - queryParams: Object 245 + queryParams: Object,
  246 + role: "",
238 }, 247 },
239 248
240 watch: { 249 watch: {
@@ -287,9 +296,9 @@ export default { @@ -287,9 +296,9 @@ export default {
287 this.diaShow = true; 296 this.diaShow = true;
288 }, 297 },
289 _print() { 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 cancel() { 303 cancel() {
295 this.diaShow = false; 304 this.diaShow = false;
@@ -333,7 +342,7 @@ export default { @@ -333,7 +342,7 @@ export default {
333 } else { 342 } else {
334 this.$message.error("下载失败"); 343 this.$message.error("下载失败");
335 } 344 }
336 - }, 345 + },
337 async refresh() { 346 async refresh() {
338 await this._changeType(); 347 await this._changeType();
339 await this._detail(); 348 await this._detail();
@@ -366,21 +375,30 @@ export default { @@ -366,21 +375,30 @@ export default {
366 return tit; 375 return tit;
367 }, 376 },
368 setDuration(times) { 377 setDuration(times) {
  378 +
  379 + if (!Number(times)) return "0分0秒";
369 let m = parseInt(times / 1000 / 60); 380 let m = parseInt(times / 1000 / 60);
370 let s = parseInt((times / 1000) % 60); 381 let s = parseInt((times / 1000) % 60);
371 let ms = times; 382 let ms = times;
372 let aTime; 383 let aTime;
  384 +
373 if (times == 0) { 385 if (times == 0) {
374 aTime = `0`; 386 aTime = `0`;
375 } else { 387 } else {
376 if (m == 0 && s == 0) { 388 if (m == 0 && s == 0) {
377 aTime = `${ms}毫秒`; 389 aTime = `${ms}毫秒`;
378 - } else if (m == 0 && s != 0) { 390 + } else if (m == 0) {
379 aTime = `${s}秒`; 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 return aTime; 402 return aTime;
385 }, 403 },
386 async _detail() { 404 async _detail() {
@@ -495,7 +513,8 @@ export default { @@ -495,7 +513,8 @@ export default {
495 this.total = interactiveListReponse.data.count; 513 this.total = interactiveListReponse.data.count;
496 }, 514 },
497 openLineChart(chartRow) { 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 this.lineChart.visible = true; 518 this.lineChart.visible = true;
500 let participationRate = []; 519 let participationRate = [];
501 let correctRate = []; 520 let correctRate = [];
@@ -519,8 +538,7 @@ export default { @@ -519,8 +538,7 @@ export default {
519 name: "已答正确率", 538 name: "已答正确率",
520 value: answerCorrectRate, 539 value: answerCorrectRate,
521 }, 540 },
522 - ];  
523 - console.log(this.lineChart) 541 + ];
524 }, 542 },
525 openStem(stemRow) { 543 openStem(stemRow) {
526 this.stem.src = stemRow.screenshot ?? ""; 544 this.stem.src = stemRow.screenshot ?? "";
@@ -553,7 +571,7 @@ export default { @@ -553,7 +571,7 @@ export default {
553 } 571 }
554 572
555 .row-line { 573 .row-line {
556 - width: calc(20% - 2px); 574 + width: calc(20% - 4px);
557 border: 1px solid #ebeef5; 575 border: 1px solid #ebeef5;
558 background: #f5f7fa; 576 background: #f5f7fa;
559 display: inline-block; 577 display: inline-block;
src/views/basic/askTestQuestion/components/testBzrMulti.vue
@@ -9,21 +9,14 @@ @@ -9,21 +9,14 @@
9 </div> 9 </div>
10 </el-row> 10 </el-row>
11 <el-row class="row-table"> 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 <el-table-column prop="title" label="试卷名称"></el-table-column> 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 <template slot-scope="scoped"> 20 <template slot-scope="scoped">
28 {{ `${scoped.row.answeredNum}/${scoped.row.classPersonNum}` }} 21 {{ `${scoped.row.answeredNum}/${scoped.row.classPersonNum}` }}
29 </template> 22 </template>
@@ -44,7 +37,7 @@ @@ -44,7 +37,7 @@
44 </div> 37 </div>
45 </el-row> 38 </el-row>
46 <el-row class="row-table"> 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 <el-table-column prop="studentCode" label="学号" fixed></el-table-column> 41 <el-table-column prop="studentCode" label="学号" fixed></el-table-column>
49 42
50 <el-table-column prop="studentName" label="姓名" fixed> 43 <el-table-column prop="studentName" label="姓名" fixed>
@@ -106,10 +99,10 @@ @@ -106,10 +99,10 @@
106 </el-container> 99 </el-container>
107 100
108 </div> 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 :append-to-body="true"> 103 :append-to-body="true">
111 <div class="chart-box"> 104 <div class="chart-box">
112 - <RadarChart id="askRadarChart" :params="radarChart" :tooltipFormatter="true" /> 105 + <RadarChart id="testRadarChart" :params="radarChart" />
113 </div> 106 </div>
114 </el-dialog> 107 </el-dialog>
115 </div> 108 </div>
@@ -151,6 +144,7 @@ export default { @@ -151,6 +144,7 @@ export default {
151 answerList: [], 144 answerList: [],
152 multipleSelection: [], 145 multipleSelection: [],
153 multipleSelectionObj: {}, 146 multipleSelectionObj: {},
  147 + redarVisible: false,
154 radarChart: { 148 radarChart: {
155 title: "", 149 title: "",
156 indicator: [ 150 indicator: [
@@ -177,16 +171,53 @@ export default { @@ -177,16 +171,53 @@ export default {
177 }, 171 },
178 methods: { 172 methods: {
179 _print() { 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 _checkboxDisabled(obj) { 216 _checkboxDisabled(obj) {
186 if (obj.examStartTime) { 217 if (obj.examStartTime) {
187 - return false;  
188 - } else {  
189 return true; 218 return true;
  219 + } else {
  220 + return false;
190 } 221 }
191 }, 222 },
192 async refresh() { 223 async refresh() {
@@ -245,28 +276,36 @@ export default { @@ -245,28 +276,36 @@ export default {
245 this.exportStudent = []; 276 this.exportStudent = [];
246 }, 277 },
247 openRandarChart(obj) { 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 this.radarChart = { 290 this.radarChart = {
249 indicator: [ 291 indicator: [
250 { 292 {
251 name: "", 293 name: "",
252 - max: 100, 294 + max: max,
253 axisLabel: { 295 axisLabel: {
254 show: true, 296 show: true,
255 showMaxLabel: true, 297 showMaxLabel: true,
256 - formatter: "{value}%",  
257 }, 298 },
258 }, 299 },
259 ], 300 ],
260 seriesData: [], 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 subjectList.map((item, index) => { 303 subjectList.map((item, index) => {
266 if (index < 1) { 304 if (index < 1) {
267 this.radarChart.indicator[index].name = item; 305 this.radarChart.indicator[index].name = item;
  306 + this.radarChart.indicator[index].max = max;
268 } else { 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,31 +313,36 @@ export default {
274 let num = this.radarChart.indicator.length; 313 let num = this.radarChart.indicator.length;
275 for (let i = 0; i < 6; i++) { 314 for (let i = 0; i < 6; i++) {
276 if (i >= num) { 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 this.radarChart.seriesData = [ 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 async _loadData() { 339 async _loadData() {
  340 +
297 var classIds = []; 341 var classIds = [];
298 var subjects = []; 342 var subjects = [];
299 var ids = []; 343 var ids = [];
300 -  
301 this.$props.list?.map((item) => { 344 this.$props.list?.map((item) => {
  345 +
302 if (this.multipleSelection.includes(item.id)) { 346 if (this.multipleSelection.includes(item.id)) {
303 subjects.push(item.subjectName); 347 subjects.push(item.subjectName);
304 classIds.push(item.classId); 348 classIds.push(item.classId);
@@ -326,6 +370,7 @@ export default { @@ -326,6 +370,7 @@ export default {
326 if (!subjectName.includes(items.subjectName)) { 370 if (!subjectName.includes(items.subjectName)) {
327 subjectName.push(items.subjectName); 371 subjectName.push(items.subjectName);
328 } 372 }
  373 + console.log(items)
329 params["examCount" + items.subjectName] = items.examCount; 374 params["examCount" + items.subjectName] = items.examCount;
330 params["participationCount" + items.subjectName] = 375 params["participationCount" + items.subjectName] =
331 items.participationCount; 376 items.participationCount;
src/views/basic/askTestQuestion/components/testListReport.vue
1 <template> 1 <template>
2 <div ref="main"> 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 <el-table-column prop="subjectName" label="科目" width="180" /> 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 <el-table-column prop="title" label="报表名称" /> 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 <el-table-column prop="classCorrectRate" label="测验人数/班级人数" width="180"> 8 <el-table-column prop="classCorrectRate" label="测验人数/班级人数" width="180">
9 <template slot-scope="scoped">{{ `${scoped.row.answeredNum}/${scoped.row.classPersonNum}` }}</template> 9 <template slot-scope="scoped">{{ `${scoped.row.answeredNum}/${scoped.row.classPersonNum}` }}</template>
10 </el-table-column> 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 <el-table-column label="操作" width="240"> 13 <el-table-column label="操作" width="240">
14 <template slot-scope="scoped"> 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 (scoped.row.recordStatus != 0 && 16 (scoped.row.recordStatus != 0 &&
17 scoped.row.subjectiveScore == scoped.row.examPaperScore) 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 <el-button style="color:red; " slot="reference" class="delete" type="text"> 20 <el-button style="color:red; " slot="reference" class="delete" type="text">
23 删除 21 删除
24 </el-button> 22 </el-button>
25 </el-popconfirm> 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 </template> 29 </template>
34 <template v-if="role != 'ROLE_BANZHUREN' && scoped.row.examPaperId != 0"> 30 <template v-if="role != 'ROLE_BANZHUREN' && scoped.row.examPaperId != 0">
35 <template> 31 <template>
36 <el-popover placement="bottom" ref="popoverRef"> 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 @click="openScoreSet(scoped.row, 1)">录入总得分</el-button> 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 </div> 37 </div>
47 - <el-button slot="reference" type="text" 38 + <el-button style="margin-right: 10px;" slot="reference" type="text"
48 @click="queryStatus(scoped.row)">录入分数</el-button> 39 @click="queryStatus(scoped.row)">录入分数</el-button>
49 </el-popover> 40 </el-popover>
50 </template> 41 </template>
@@ -62,12 +53,17 @@ import ScoreSet from &quot;../../test/components/scoreSet.vue&quot;; @@ -62,12 +53,17 @@ import ScoreSet from &quot;../../test/components/scoreSet.vue&quot;;
62 export default { 53 export default {
63 name: "testListReport", 54 name: "testListReport",
64 props: { 55 props: {
65 - datas: Array, 56 + datas: Array || null,
66 }, 57 },
67 components: { 58 components: {
68 ScoreSet 59 ScoreSet
69 }, 60 },
70 watch: { 61 watch: {
  62 + 'diaScoreSet'(value) {
  63 + if (value == false) {
  64 + // this.$emit('opration');
  65 + }
  66 + },
71 '$props.datas'(value) { 67 '$props.datas'(value) {
72 if (this.role == "ROLE_BANZHUREN") { 68 if (this.role == "ROLE_BANZHUREN") {
73 this.isMultipleClass = false; 69 this.isMultipleClass = false;
@@ -84,12 +80,13 @@ export default { @@ -84,12 +80,13 @@ export default {
84 return item; 80 return item;
85 }) || []; 81 }) || [];
86 } 82 }
87 - }, 83 + }
88 }, 84 },
89 created() { 85 created() {
90 this.role = 86 this.role =
91 this.$store.getters.info.showRole || 87 this.$store.getters.info.showRole ||
92 this.$store.getters.info.permissions[0].role; 88 this.$store.getters.info.permissions[0].role;
  89 +
93 }, 90 },
94 methods: { 91 methods: {
95 _linkToDetail(dataRow) { 92 _linkToDetail(dataRow) {
@@ -113,13 +110,12 @@ export default { @@ -113,13 +110,12 @@ export default {
113 this.diaScoreSet = true; 110 this.diaScoreSet = true;
114 }, 111 },
115 async _removeReport(obj, index) { 112 async _removeReport(obj, index) {
116 - this.tableData[index].loading = true;  
117 const { data, status, info } = await this.$request.deleteReport({ 113 const { data, status, info } = await this.$request.deleteReport({
118 id: obj.id, 114 id: obj.id,
119 }); 115 });
120 if (status === 0) { 116 if (status === 0) {
121 this.$message.success("删除成功!"); 117 this.$message.success("删除成功!");
122 - this._QueryData(); 118 + this.$emit('opration');
123 } else { 119 } else {
124 this.$message.error(info); 120 this.$message.error(info);
125 } 121 }
@@ -143,7 +139,7 @@ export default { @@ -143,7 +139,7 @@ export default {
143 }, 139 },
144 //修改分数成功 140 //修改分数成功
145 SuccessScoreSet() { 141 SuccessScoreSet() {
146 - this._QueryData(); 142 + this.$emit('opration');
147 this.closeScoreSet(); 143 this.closeScoreSet();
148 }, 144 },
149 //修改答案 145 //修改答案
src/views/basic/askTestQuestion/components/testMultiClassReport.vue
@@ -8,19 +8,19 @@ @@ -8,19 +8,19 @@
8 </el-row> 8 </el-row>
9 <el-row class="row-type" style="margin-top: 10px;"> 9 <el-row class="row-type" style="margin-top: 10px;">
10 <el-table v-if="$props.params" class="default-table" :data="listReport"> 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 <el-table-column prop="classCorrectRate" label="已考班级"> 13 <el-table-column prop="classCorrectRate" label="已考班级">
14 <template slot-scope="scoped"> 14 <template slot-scope="scoped">
15 <el-checkbox-group v-model="scoped.row.checkedClassList"> 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 {{ item.className }} 17 {{ item.className }}
18 </el-checkbox> 18 </el-checkbox>
19 </el-checkbox-group> 19 </el-checkbox-group>
20 </template> 20 </template>
21 </el-table-column> 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 <template slot-scope="scoped"> 24 <template slot-scope="scoped">
25 <el-button type="text" @click="_linkToDetail(scoped.row)">查看</el-button> 25 <el-button type="text" @click="_linkToDetail(scoped.row)">查看</el-button>
26 </template> 26 </template>
@@ -48,9 +48,7 @@ export default { @@ -48,9 +48,7 @@ export default {
48 } 48 }
49 }, 49 },
50 methods: { 50 methods: {
51 - _linkToDetail(dataRow) {  
52 -  
53 - console.log(dataRow) 51 + _linkToDetail(dataRow) {
54 this.$router.push({ 52 this.$router.push({
55 path: "/testReportDetail", 53 path: "/testReportDetail",
56 query: { 54 query: {
@@ -59,15 +57,16 @@ export default { @@ -59,15 +57,16 @@ export default {
59 id: dataRow.paperId, 57 id: dataRow.paperId,
60 title: dataRow.paperName, 58 title: dataRow.paperName,
61 subjectName: dataRow.subjectName, 59 subjectName: dataRow.subjectName,
  60 + diffType: this.currentType,
62 }, 61 },
63 }); 62 });
64 }, 63 },
65 async _loadDatas() { 64 async _loadDatas() {
66 - 65 +
67 var dataRequestParams = { 66 var dataRequestParams = {
68 classIds: this.$props.params.class ? [this.$props.params.class] : 67 classIds: this.$props.params.class ? [this.$props.params.class] :
69 this.$props.params.classIds ? [...this.$props.params.classIds] : null, 68 this.$props.params.classIds ? [...this.$props.params.classIds] : null,
70 - diffType: this.currentType == "任课班级对比" ? "0" : "1", 69 + diffType: this.currentType == "任课班级对比" ? "1" : "0",
71 end: this.$props.params.dataRange ? this.$props.params.dataRange[1] : null, 70 end: this.$props.params.dataRange ? this.$props.params.dataRange[1] : null,
72 start: this.$props.params.dataRange ? this.$props.params.dataRange[0] : null, 71 start: this.$props.params.dataRange ? this.$props.params.dataRange[0] : null,
73 subjects: this.$props.params.subject ? [this.$props.params.subject] : 72 subjects: this.$props.params.subject ? [this.$props.params.subject] :
src/views/basic/askTestQuestion/components/testSummaryReport.vue
@@ -9,14 +9,28 @@ @@ -9,14 +9,28 @@
9 <div id="print-content"> 9 <div id="print-content">
10 <el-row class="row-table"> 10 <el-row class="row-table">
11 <el-table border class="default-table" :data="stageReport" style="width: 100%"> 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 <template slot-scope="scoped"> 14 <template slot-scope="scoped">
15 {{ scoped.row.studentName }} 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 :label="item.title"> 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 :class-name="index % 2 == 0 ? 'bg' : ''"> 34 :class-name="index % 2 == 0 ? 'bg' : ''">
21 <template slot-scope="scoped"> 35 <template slot-scope="scoped">
22 {{ 36 {{
@@ -27,7 +41,7 @@ @@ -27,7 +41,7 @@
27 }} 41 }}
28 </template> 42 </template>
29 </el-table-column> 43 </el-table-column>
30 - <el-table-column :prop="'classRank' + index" label="排名" align="center" 44 + <el-table-column :prop="'classRank' + index" label="排名"
31 :class-name="index % 2 == 0 ? 'bg' : ''"> 45 :class-name="index % 2 == 0 ? 'bg' : ''">
32 <template slot-scope="scoped">{{ 46 <template slot-scope="scoped">{{
33 scoped.row["classRank" + index] || 47 scoped.row["classRank" + index] ||
@@ -37,7 +51,7 @@ @@ -37,7 +51,7 @@
37 }}</template> 51 }}</template>
38 </el-table-column> 52 </el-table-column>
39 </el-table-column> 53 </el-table-column>
40 - <el-table-column label="查看折线图" align="center"> 54 + <el-table-column label="查看折线图" fixed="right" align="center" width="120">
41 <template slot-scope="scoped"> 55 <template slot-scope="scoped">
42 <el-button type="text" @click="_openLineChart(scoped.row)">查看</el-button> 56 <el-button type="text" @click="_openLineChart(scoped.row)">查看</el-button>
43 </template> 57 </template>
@@ -49,8 +63,7 @@ @@ -49,8 +63,7 @@
49 <el-dialog class="chart-dia" :visible.sync="lineChart.visible" :title="lineChart.title" width="800" 63 <el-dialog class="chart-dia" :visible.sync="lineChart.visible" :title="lineChart.title" width="800"
50 :append-to-body="true"> 64 :append-to-body="true">
51 <div class="chart-box"> 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 </div> 67 </div>
55 </el-dialog> 68 </el-dialog>
56 <ExportDia :exportStudent="exportStudent" :diaShow="diaShow" @cancel="cancel" @exportData="exportData" 69 <ExportDia :exportStudent="exportStudent" :diaShow="diaShow" @cancel="cancel" @exportData="exportData"
@@ -68,7 +81,8 @@ export default { @@ -68,7 +81,8 @@ export default {
68 }, 81 },
69 props: { 82 props: {
70 testReportIds: Array, 83 testReportIds: Array,
71 - queryParams: Object 84 + queryParams: Object,
  85 + role: "",
72 }, 86 },
73 async created() { 87 async created() {
74 await this._phaseExamReport(); 88 await this._phaseExamReport();
@@ -101,6 +115,9 @@ export default { @@ -101,6 +115,9 @@ export default {
101 }; 115 };
102 }, 116 },
103 methods: { 117 methods: {
  118 + _headerClick(currentItem) {
  119 + this.$emit("headerClick", currentItem);
  120 + },
104 async _export() { 121 async _export() {
105 this.diaShow = true; 122 this.diaShow = true;
106 }, 123 },
@@ -116,7 +133,9 @@ export default { @@ -116,7 +133,9 @@ export default {
116 let query = { 133 let query = {
117 examIds: this.$props.testReportIds, 134 examIds: this.$props.testReportIds,
118 classIds: [this.$props.queryParams.class], 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 const { data, status, info } = await phaseExamReport({ 141 const { data, status, info } = await phaseExamReport({
@@ -139,6 +158,7 @@ export default { @@ -139,6 +158,7 @@ export default {
139 } 158 }
140 }); 159 });
141 }); 160 });
  161 + console.log('lsit', data?.list)
142 this.stageReport = data?.list.map((item) => { 162 this.stageReport = data?.list.map((item) => {
143 let params = {}; 163 let params = {};
144 dataIdsList.map((ids, index) => { 164 dataIdsList.map((ids, index) => {
@@ -177,21 +197,26 @@ export default { @@ -177,21 +197,26 @@ export default {
177 ? this.$request.pExportPhaseExamReport 197 ? this.$request.pExportPhaseExamReport
178 : this.$request.exportPhaseExamReport; 198 : this.$request.exportPhaseExamReport;
179 199
  200 +
180 const data = await exportPhaseExamReport({ 201 const data = await exportPhaseExamReport({
181 examIds: this.$props.testReportIds, 202 examIds: this.$props.testReportIds,
182 classIds: [this.$props.queryParams.class], 203 classIds: [this.$props.queryParams.class],
183 subjectName: [this.$props.queryParams.subject], 204 subjectName: [this.$props.queryParams.subject],
  205 + startDay: this.$props.queryParams?.dateRange[0] ?? null,
  206 + endDay: this.$props.queryParams?.dateRange[1] ?? null,
184 ...query 207 ...query
185 }); 208 });
186 209
  210 +
187 if (data) { 211 if (data) {
  212 +
188 this.cancel(); 213 this.cancel();
189 214
190 let blob = new Blob([data], { 215 let blob = new Blob([data], {
191 type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 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 downloadFile(this.status ? "即时测-已归档单课时报表.xlsx" : name, blob); 221 downloadFile(this.status ? "即时测-已归档单课时报表.xlsx" : name, blob);
197 } else { 222 } else {
@@ -202,8 +227,9 @@ export default { @@ -202,8 +227,9 @@ export default {
202 tablePrint("print-content", "即时测-已归档单课时报表"); 227 tablePrint("print-content", "即时测-已归档单课时报表");
203 }, 228 },
204 _titleClick() { }, 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 this.lineChart.visible = true; 233 this.lineChart.visible = true;
208 let score = []; 234 let score = [];
209 let classRank = []; 235 let classRank = [];
@@ -262,7 +288,6 @@ export default { @@ -262,7 +288,6 @@ export default {
262 288
263 .chart-dia { 289 .chart-dia {
264 .chart-box { 290 .chart-box {
265 - width: 100%;  
266 height: 300px; 291 height: 300px;
267 } 292 }
268 293
@@ -270,4 +295,8 @@ export default { @@ -270,4 +295,8 @@ export default {
270 padding: 0 0 20px 0; 295 padding: 0 0 20px 0;
271 } 296 }
272 } 297 }
  298 +
  299 +.overClick:hover {
  300 + cursor: pointer;
  301 +}
273 </style> 302 </style>
src/views/basic/askTestQuestion/detail.vue
@@ -17,7 +17,20 @@ @@ -17,7 +17,20 @@
17 <el-option v-for="(item, index) in types" :lable="item.name" :key="index" :value="item.name" /> 17 <el-option v-for="(item, index) in types" :lable="item.name" :key="index" :value="item.name" />
18 </el-select> 18 </el-select>
19 <div style="float: right;"> 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 icon="el-icon-upload2">导出报表</el-button> 34 icon="el-icon-upload2">导出报表</el-button>
22 <el-button type="primary" @click="_print" class="opration-btn" 35 <el-button type="primary" @click="_print" class="opration-btn"
23 icon="el-icon-printer">打印报表</el-button> 36 icon="el-icon-printer">打印报表</el-button>
@@ -26,6 +39,16 @@ @@ -26,6 +39,16 @@
26 </div> 39 </div>
27 <el-main> 40 <el-main>
28 <div style=" padding: 20px;" id="print-content"> 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 <div v-if="dataType == '1' && currentType == '试题分析'"> 52 <div v-if="dataType == '1' && currentType == '试题分析'">
30 <el-row class="row-subfix"> 53 <el-row class="row-subfix">
31 <div class="row-line"> 54 <div class="row-line">
@@ -78,15 +101,15 @@ @@ -78,15 +101,15 @@
78 </div> 101 </div>
79 <div class="row-line"> 102 <div class="row-line">
80 <span class="line-subfix">总参与度:</span> 103 <span class="line-subfix">总参与度:</span>
81 - <span class="line-value">{{ detail.participationRate }}</span> 104 + <span class="line-value">{{ detail.participationRate }}%</span>
82 </div> 105 </div>
83 <div class="row-line"> 106 <div class="row-line">
84 <span class="line-subfix">班级正确率:</span> 107 <span class="line-subfix">班级正确率:</span>
85 - <span class="line-value">{{ detail.classCorrectRate }}</span> 108 + <span class="line-value">{{ detail.classCorrectRate }}%</span>
86 </div> 109 </div>
87 <div class="row-line"> 110 <div class="row-line">
88 <span class="line-subfix">已达正确率:</span> 111 <span class="line-subfix">已达正确率:</span>
89 - <span class="line-value">{{ detail.answerCorrectRate }}</span> 112 + <span class="line-value">{{ detail.answerCorrectRate }}%</span>
90 </div> 113 </div>
91 <div class="row-line"> 114 <div class="row-line">
92 <span class="line-subfix">反馈时长:</span> 115 <span class="line-subfix">反馈时长:</span>
@@ -96,7 +119,7 @@ @@ -96,7 +119,7 @@
96 <el-row class="row-table"> 119 <el-row class="row-table">
97 <el-table class="default-table" :data="askItemAnalysis"> 120 <el-table class="default-table" :data="askItemAnalysis">
98 <el-table-column prop="title" label="课时-题号" /> 121 <el-table-column prop="title" label="课时-题号" />
99 - <el-table-column label="题干" width="120"> 122 + <el-table-column label="题干" width="80">
100 <template slot-scope="scoped"> 123 <template slot-scope="scoped">
101 <el-button type="text" size="mini" @click="openStem(scoped.row)">查看</el-button> 124 <el-button type="text" size="mini" @click="openStem(scoped.row)">查看</el-button>
102 </template> 125 </template>
@@ -106,14 +129,14 @@ @@ -106,14 +129,14 @@
106 </el-table-column> 129 </el-table-column>
107 <el-table-column prop="answeredNum" label="答题人数" width="100" /> 130 <el-table-column prop="answeredNum" label="答题人数" width="100" />
108 <el-table-column prop="correctAnswerNum" label="答对人数" width="100" /> 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 <template slot-scope="scoped">{{ scoped.row.participationRate }}%</template> 133 <template slot-scope="scoped">{{ scoped.row.participationRate }}%</template>
111 </el-table-column> 134 </el-table-column>
112 - <el-table-column prop="classCorrectRate" label="班级正确率(单题)" width="150"> 135 + <el-table-column prop="classCorrectRate" label="班级正确率(单题)" width="170">
113 <template slot-scope="scoped">{{ scoped.row.classCorrectRate }}%</template> 136 <template slot-scope="scoped">{{ scoped.row.classCorrectRate }}%</template>
114 </el-table-column> 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 <template slot-scope="scoped">{{ scoped.row.answerCorrectRate }}%</template> 140 <template slot-scope="scoped">{{ scoped.row.answerCorrectRate }}%</template>
118 </el-table-column> 141 </el-table-column>
119 142
@@ -142,6 +165,8 @@ @@ -142,6 +165,8 @@
142 <div v-if="dataType == '1' && currentType == '学生作答表现'"> 165 <div v-if="dataType == '1' && currentType == '学生作答表现'">
143 <el-row class="row-table" style="margin-top:0px;"> 166 <el-row class="row-table" style="margin-top:0px;">
144 <el-table class="default-table" :data="askPeriodQuestionItems"> 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 <el-table-column prop="answerTimes" label="答题次数"></el-table-column> 170 <el-table-column prop="answerTimes" label="答题次数"></el-table-column>
146 <el-table-column prop="consumingDuration" label="答题耗时"><template slot-scope="scoped">{{ 171 <el-table-column prop="consumingDuration" label="答题耗时"><template slot-scope="scoped">{{
147 setDuration(scoped.row.consumingDuration) 172 setDuration(scoped.row.consumingDuration)
@@ -259,16 +284,109 @@ @@ -259,16 +284,109 @@
259 :key="index" v-for="(item, index) in studentHeader" /> 284 :key="index" v-for="(item, index) in studentHeader" />
260 </el-table> 285 </el-table>
261 </el-row> 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 </el-table> 329 </el-table>
267 </el-row> 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 </el-table> 390 </el-table>
273 </el-row> 391 </el-row>
274 <el-row class="row-subfix"> 392 <el-row class="row-subfix">
@@ -278,10 +396,10 @@ @@ -278,10 +396,10 @@
278 <el-table-column prop="student" label="答错学生"> 396 <el-table-column prop="student" label="答错学生">
279 <template slot-scope="scoped"> 397 <template slot-scope="scoped">
280 <span>总计 <span style="color:red;"> 398 <span>总计 <span style="color:red;">
281 - {{ scoped.row.details.filter(item => !item.isRight).length }}</span> 人 399 + {{ scoped.row.missPeopleNumber }}</span> 人
282 </span> 400 </span>
283 <span style="margin: 10px 0;" 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 选{{ item.option }}:{{ item.students.join("/") }} 403 选{{ item.option }}:{{ item.students.join("/") }}
286 </span> 404 </span>
287 <span></span> 405 <span></span>
@@ -291,21 +409,37 @@ @@ -291,21 +409,37 @@
291 </el-row> 409 </el-row>
292 </div> 410 </div>
293 <div v-if="dataType == '2' && currentType == '试题分析'"> 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 <el-table-column prop="questionIndex" label="题号" width="60"></el-table-column> 413 <el-table-column prop="questionIndex" label="题号" width="60"></el-table-column>
296 <el-table-column prop="questionType" label="题型" width="100"> 414 <el-table-column prop="questionType" label="题型" width="100">
297 <template slot-scope="scope"> 415 <template slot-scope="scope">
298 {{ setSubPro(scope.row.questionType) }} 416 {{ setSubPro(scope.row.questionType) }}
299 </template> 417 </template>
300 </el-table-column> 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 <el-table-column prop="score" width="100" label="满分值"></el-table-column> 420 <el-table-column prop="score" width="100" label="满分值"></el-table-column>
303 <el-table-column width="110" prop="highestScore" label="班最高分"></el-table-column> 421 <el-table-column width="110" prop="highestScore" label="班最高分"></el-table-column>
304 <el-table-column width="110" prop="lowestScore" label="班最低分"></el-table-column> 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 <el-table-column prop="correctAnswer" label="答案"><template slot-scope="scoped">{{ 443 <el-table-column prop="correctAnswer" label="答案"><template slot-scope="scoped">{{
310 scoped.row.correctAnswer == 1 444 scoped.row.correctAnswer == 1
311 ? "✓" 445 ? "✓"
@@ -318,20 +452,18 @@ @@ -318,20 +452,18 @@
318 :prop="'count' + index" width="120"><template slot-scope="scope"> 452 :prop="'count' + index" width="120"><template slot-scope="scope">
319 <p class="persent"> 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 ? `${scope.row["option" + index]}(${scope.row["persent" + index] 457 ? `${scope.row["option" + index]}(${scope.row["persent" + index]
325 })` 458 })`
326 - : ""  
327 - }} 459 + : "" }}
328 </p> 460 </p>
329 </template> 461 </template>
330 </el-table-column> 462 </el-table-column>
331 </el-table> 463 </el-table>
332 </div> 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 <el-table-column prop="studentCode" label="学号" width="120"></el-table-column> 467 <el-table-column prop="studentCode" label="学号" width="120"></el-table-column>
336 <el-table-column prop="studentName" label="姓名"></el-table-column> 468 <el-table-column prop="studentName" label="姓名"></el-table-column>
337 <el-table-column prop="examScore" label="总分"></el-table-column> 469 <el-table-column prop="examScore" label="总分"></el-table-column>
@@ -359,8 +491,8 @@ @@ -359,8 +491,8 @@
359 </el-table-column> 491 </el-table-column>
360 </el-table> 492 </el-table>
361 </div> 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 <el-table-column prop="studentCode" label="学号" width="120"></el-table-column> 496 <el-table-column prop="studentCode" label="学号" width="120"></el-table-column>
365 <el-table-column prop="studentName" label="姓名"></el-table-column> 497 <el-table-column prop="studentName" label="姓名"></el-table-column>
366 <el-table-column prop="examScore" label="总分"></el-table-column> 498 <el-table-column prop="examScore" label="总分"></el-table-column>
@@ -368,21 +500,21 @@ @@ -368,21 +500,21 @@
368 <el-table-column prop="objectiveExamScore" label="客观题分"></el-table-column> 500 <el-table-column prop="objectiveExamScore" label="客观题分"></el-table-column>
369 <el-table-column prop="subjectiveExamScore" label="主观题分"></el-table-column> 501 <el-table-column prop="subjectiveExamScore" label="主观题分"></el-table-column>
370 </el-table-column> 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 </el-table-column> 505 </el-table-column>
374 </el-table> 506 </el-table>
375 </div> 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 <el-table-column prop="studentCode" width="120" label="学号"></el-table-column> 510 <el-table-column prop="studentCode" width="120" label="学号"></el-table-column>
379 <el-table-column prop="studentName" label="姓名"></el-table-column> 511 <el-table-column prop="studentName" label="姓名"></el-table-column>
380 <el-table-column prop="className" label="班级"></el-table-column> 512 <el-table-column prop="className" label="班级"></el-table-column>
381 <el-table-column prop="examScore" label="总分"></el-table-column> 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 :label="'Q' + item.id"> 515 :label="'Q' + item.id">
384 <template slot-scope="scope"> 516 <template slot-scope="scope">
385 - <span v-if="testStudents[index]?.questionType == 5">*</span> 517 + <span v-if="studentAnsered[index]?.questionType == 5">*</span>
386 <span v-else-if="scope.row['answer' + item.id]" 518 <span v-else-if="scope.row['answer' + item.id]"
387 :class="scope.row['isRight' + item.id] ? '' : 'error'"> 519 :class="scope.row['isRight' + item.id] ? '' : 'error'">
388 {{ scope.row["answer" + item.id] }} 520 {{ scope.row["answer" + item.id] }}
@@ -403,7 +535,8 @@ @@ -403,7 +535,8 @@
403 </el-table-column> 535 </el-table-column>
404 <el-table-column prop="title" label="参与度" width="120"> 536 <el-table-column prop="title" label="参与度" width="120">
405 <template slot-scope="scoped"> 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 </template> 540 </template>
408 </el-table-column> 541 </el-table-column>
409 <el-table-column prop="avg" label="班平均分" width="120" /> 542 <el-table-column prop="avg" label="班平均分" width="120" />
@@ -411,40 +544,54 @@ @@ -411,40 +544,54 @@
411 <el-table-column prop="low" label="班最低分" width="120" /> 544 <el-table-column prop="low" label="班最低分" width="120" />
412 <el-table-column prop="front20" label="前20名均分" width="120" /> 545 <el-table-column prop="front20" label="前20名均分" width="120" />
413 <el-table-column prop="last20" label="后20名均分" width="120" /> 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 <template slot-scope="scoped"> 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 </template> 551 </template>
433 </el-table-column> 552 </el-table-column>
434 </el-table> 553 </el-table>
435 </div> 554 </div>
436 <div v-if="dataType == '3' && currentType == '试题分析'"> 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 <el-table-column prop="questionIndex" label="题号" width="120" /> 557 <el-table-column prop="questionIndex" label="题号" width="120" />
439 <el-table-column prop="questionType" label="题型" width="100"> 558 <el-table-column prop="questionType" label="题型" width="100">
440 <template slot-scope="scope"> 559 <template slot-scope="scope">
441 {{ setSubPro(scope.row.questionType) }} 560 {{ setSubPro(scope.row.questionType) }}
442 </template> 561 </template>
443 </el-table-column> 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 <el-table-column prop="score" label="满分值" width="120" /> 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 <el-table-column prop="correctAnswer" label="答案" width="120" /> 595 <el-table-column prop="correctAnswer" label="答案" width="120" />
449 <el-table-column v-for="(item, index) in testPaperExamReportOptions" :key="index" 596 <el-table-column v-for="(item, index) in testPaperExamReportOptions" :key="index"
450 :label="item.title" :prop="'count' + index" width="120"> 597 :label="item.title" :prop="'count' + index" width="120">
@@ -470,13 +617,89 @@ @@ -470,13 +617,89 @@
470 <el-table-column prop="name" label="姓名" /> 617 <el-table-column prop="name" label="姓名" />
471 <el-table-column prop="className" label="班级" /> 618 <el-table-column prop="className" label="班级" />
472 <el-table-column prop="exam" label="分数" /> 619 <el-table-column prop="exam" label="分数" />
473 - <el-table-column prop="title" label="成绩等级" /> 620 + <el-table-column prop="lever" label="成绩等级" />
474 </el-table> 621 </el-table>
475 </div> 622 </div>
476 </div> 623 </div>
477 </el-main> 624 </el-main>
478 <el-dialog class="stem" :visible.sync="stem.visible" :title="'题干'" width="800" :append-to-body="true"> 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 </el-dialog> 703 </el-dialog>
481 </el-container> 704 </el-container>
482 </template> 705 </template>
@@ -484,6 +707,7 @@ @@ -484,6 +707,7 @@
484 import { formatDate, downloadFile, tablePrint } from "utils"; 707 import { formatDate, downloadFile, tablePrint } from "utils";
485 export default { 708 export default {
486 name: "reportDetail", 709 name: "reportDetail",
  710 + components: { testScoreSet: () => import("./components/testScoreSet.vue"), },
487 async created() { 711 async created() {
488 this.role = 712 this.role =
489 713
@@ -506,9 +730,36 @@ export default { @@ -506,9 +730,36 @@ export default {
506 this.currentType = this.types[0]?.name ?? "" 730 this.currentType = this.types[0]?.name ?? ""
507 731
508 await this._changeType(); 732 await this._changeType();
  733 +
  734 + await this._queryDefaultLevels();
  735 +
  736 + if (this.dataType == '2') {
  737 + await this._examDetail();
  738 + }
509 }, 739 },
510 data() { 740 data() {
511 return { 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 titleInfo: [], 763 titleInfo: [],
513 studentList: [], 764 studentList: [],
514 studentHeader: [], 765 studentHeader: [],
@@ -538,10 +789,9 @@ export default { @@ -538,10 +789,9 @@ export default {
538 label: "主观分", 789 label: "主观分",
539 }, 790 },
540 ], 791 ],
541 - questionList: [],  
542 - questionHeaders: [],  
543 - questionOtherList: [],  
544 - questionOtherHeaders: [], 792 + question4List: [],
  793 + question7List: [],
  794 + question10List: [],
545 questionTotal: [], 795 questionTotal: [],
546 dataType: null, 796 dataType: null,
547 classIds: [], 797 classIds: [],
@@ -579,6 +829,11 @@ export default { @@ -579,6 +829,11 @@ export default {
579 testStudents: [], 829 testStudents: [],
580 // 报表学生选项 830 // 报表学生选项
581 testStudentOptions: [], 831 testStudentOptions: [],
  832 + studentAnsered: [],
  833 + studentAnseredOptions: [],
  834 + studentRank: [],
  835 + studentQuestions: [],
  836 + studentQuestionOptions: [],
582 // 报表题目详情 837 // 报表题目详情
583 testQuestions: [], 838 testQuestions: [],
584 // 报表题目选项 839 // 报表题目选项
@@ -599,7 +854,7 @@ export default { @@ -599,7 +854,7 @@ export default {
599 tit = "主观题"; 854 tit = "主观题";
600 break; 855 break;
601 default: 856 default:
602 - tit = "其他"; 857 + tit = type;
603 } 858 }
604 return tit; 859 return tit;
605 }, 860 },
@@ -662,9 +917,11 @@ export default { @@ -662,9 +917,11 @@ export default {
662 detail: {}, 917 detail: {},
663 currentType: null, 918 currentType: null,
664 classdiffExamReport: [], 919 classdiffExamReport: [],
  920 + classdiffLevelOptions: [],
665 testPaperExamReport: [], 921 testPaperExamReport: [],
666 testStudentExamReport: [], 922 testStudentExamReport: [],
667 testPaperExamReportOptions: [], 923 testPaperExamReportOptions: [],
  924 + diffType: 0,
668 //题干数据对象 925 //题干数据对象
669 stem: { 926 stem: {
670 visible: false, 927 visible: false,
@@ -673,12 +930,171 @@ export default { @@ -673,12 +930,171 @@ export default {
673 } 930 }
674 }, 931 },
675 methods: { 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 async _export() { 1091 async _export() {
677 if (this.dataType == "1") { 1092 if (this.dataType == "1") {
678 1093
679 let exportPeriodReport = ""; 1094 let exportPeriodReport = "";
680 1095
681 var query = {}; 1096 var query = {};
  1097 +
682 query.periodId = this.ids[0]; 1098 query.periodId = this.ids[0];
683 1099
684 exportPeriodReport = 1100 exportPeriodReport =
@@ -701,7 +1117,6 @@ export default { @@ -701,7 +1117,6 @@ export default {
701 } 1117 }
702 } 1118 }
703 else if (this.dataType == "2") { 1119 else if (this.dataType == "2") {
704 -  
705 const exportExamReport = 1120 const exportExamReport =
706 this.role == "ROLE_PERSONAL" 1121 this.role == "ROLE_PERSONAL"
707 ? this.$request.pExportExamReport 1122 ? this.$request.pExportExamReport
@@ -711,8 +1126,6 @@ export default { @@ -711,8 +1126,6 @@ export default {
711 examId: this.ids[0] 1126 examId: this.ids[0]
712 }); 1127 });
713 1128
714 - this.exportLoading = false;  
715 -  
716 if (!data.status) { 1129 if (!data.status) {
717 let blob = new Blob([data], { 1130 let blob = new Blob([data], {
718 type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 1131 type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
@@ -727,6 +1140,37 @@ export default { @@ -727,6 +1140,37 @@ export default {
727 this.$message.error(data.info); 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 _print() { 1176 _print() {
@@ -778,6 +1222,30 @@ export default { @@ -778,6 +1222,30 @@ export default {
778 } 1222 }
779 }, 1223 },
780 async _testPaperExamReport() { 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 const request = this.$request.tPaperExamReport; 1249 const request = this.$request.tPaperExamReport;
782 1250
783 let response = await request({ 1251 let response = await request({
@@ -789,10 +1257,45 @@ export default { @@ -789,10 +1257,45 @@ export default {
789 this.$message.error(response.info); 1257 this.$message.error(response.info);
790 return; 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 let tableData = response.data?.map((item) => { 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 let params = {}; 1299 let params = {};
797 1300
798 const detail = item?.details ?? []; 1301 const detail = item?.details ?? [];
@@ -803,6 +1306,7 @@ export default { @@ -803,6 +1306,7 @@ export default {
803 let defaultArr = detail?.filter((item) => { 1306 let defaultArr = detail?.filter((item) => {
804 return item.option != "未答"; 1307 return item.option != "未答";
805 }); 1308 });
  1309 +
806 optionsList.map((items, index) => { 1310 optionsList.map((items, index) => {
807 if (index != 4) { 1311 if (index != 4) {
808 params["count" + index] = 1312 params["count" + index] =
@@ -830,6 +1334,8 @@ export default { @@ -830,6 +1334,8 @@ export default {
830 } 1334 }
831 }); 1335 });
832 1336
  1337 +
  1338 +
833 return { 1339 return {
834 ...item, 1340 ...item,
835 ...params, 1341 ...params,
@@ -842,13 +1348,48 @@ export default { @@ -842,13 +1348,48 @@ export default {
842 1348
843 this.testPaperExamReportOptions = [...optionsList]; 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 async _testStudentExamReport() { 1376 async _testStudentExamReport() {
847 const request = this.$request.tgStudentExamReport; 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 let response = await request({ 1389 let response = await request({
850 paperId: this.ids[0], 1390 paperId: this.ids[0],
851 classIds: this.classIds, 1391 classIds: this.classIds,
  1392 + reportRange: paramObj
852 }); 1393 });
853 1394
854 if (response.status != 0) { 1395 if (response.status != 0) {
@@ -859,25 +1400,45 @@ export default { @@ -859,25 +1400,45 @@ export default {
859 this.testStudentExamReport = response.data; 1400 this.testStudentExamReport = response.data;
860 }, 1401 },
861 async _classdiffExamReport() { 1402 async _classdiffExamReport() {
862 - 1403 + this.classdiffExamReport = [];
  1404 + this.classdiffLevelOptions = [];
863 const classDiffRequest = this.$request.tClassdiffExamReport; 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 let classDiffResponse = await classDiffRequest({ 1416 let classDiffResponse = await classDiffRequest({
866 paperId: this.ids[0], 1417 paperId: this.ids[0],
867 classIds: this.classIds, 1418 classIds: this.classIds,
  1419 + reportRange: paramObj
868 }); 1420 });
869 1421
870 if (classDiffResponse.status != 0) { 1422 if (classDiffResponse.status != 0) {
871 this.$message.error(classDiffResponse.info); 1423 this.$message.error(classDiffResponse.info);
872 return; 1424 return;
873 } 1425 }
  1426 +
874 var index = 0; 1427 var index = 0;
875 1428
876 this.classdiffExamReport = classDiffResponse.data.map((item) => { 1429 this.classdiffExamReport = classDiffResponse.data.map((item) => {
877 item.index = index + 1; 1430 item.index = index + 1;
878 index += 1; 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 return item; 1438 return item;
880 }); 1439 });
  1440 +
  1441 + console.log(this.fromData)
881 }, 1442 },
882 openStem(stemRow) { 1443 openStem(stemRow) {
883 this.stem.src = stemRow.screenshot ?? ""; 1444 this.stem.src = stemRow.screenshot ?? "";
@@ -890,8 +1451,8 @@ export default { @@ -890,8 +1451,8 @@ export default {
890 const request = this.$request.tTestExamReport; 1451 const request = this.$request.tTestExamReport;
891 1452
892 let response = await request({ 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 if (response.status != 0) { 1458 if (response.status != 0) {
@@ -951,202 +1512,241 @@ export default { @@ -951,202 +1512,241 @@ export default {
951 1512
952 this.studentList = [...studentResults]; 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 else { 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 async _loadAskInteractives() { 1752 async _loadAskInteractives() {
@@ -1301,6 +1901,14 @@ export default { @@ -1301,6 +1901,14 @@ export default {
1301 }, 1901 },
1302 async _loadTestStudentReport() { 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 const examStudentReport = 1912 const examStudentReport =
1305 this.role == "ROLE_PERSONAL" 1913 this.role == "ROLE_PERSONAL"
1306 ? this.$request.pExamStudentReport 1914 ? this.$request.pExamStudentReport
@@ -1317,7 +1925,7 @@ export default { @@ -1317,7 +1925,7 @@ export default {
1317 1925
1318 let optionsList = []; 1926 let optionsList = [];
1319 1927
1320 - this.testStudents = data?.list.map((item) => { 1928 + let rTestStudents = data?.list.map((item) => {
1321 let params = {}; 1929 let params = {};
1322 const detail = JSON.parse(item.detail); 1930 const detail = JSON.parse(item.detail);
1323 if (detail.length) { 1931 if (detail.length) {
@@ -1342,9 +1950,21 @@ export default { @@ -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 return a.id - b.id; 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 async _loadTestQuestionReport() { 1969 async _loadTestQuestionReport() {
1350 //试题分析 1970 //试题分析
@@ -1365,11 +1985,62 @@ export default { @@ -1365,11 +1985,62 @@ export default {
1365 return; 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 let tableData = data?.list?.map((item) => { 2039 let tableData = data?.list?.map((item) => {
1371 let params = {}; 2040 let params = {};
  2041 +
1372 const detail = JSON.parse(item.detail); 2042 const detail = JSON.parse(item.detail);
  2043 +
1373 let lastOPtion = detail?.find((item) => { 2044 let lastOPtion = detail?.find((item) => {
1374 return item.option == "未答"; 2045 return item.option == "未答";
1375 }); 2046 });
@@ -1378,31 +2049,58 @@ export default { @@ -1378,31 +2049,58 @@ export default {
1378 }); 2049 });
1379 2050
1380 optionsList.map((items, index) => { 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 return { 2104 return {
1407 ...item, 2105 ...item,
1408 ...params, 2106 ...params,
@@ -1414,6 +2112,58 @@ export default { @@ -1414,6 +2112,58 @@ export default {
1414 }); 2112 });
1415 2113
1416 this.testQuestionOptions = [...optionsList]; 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,7 +2175,7 @@ export default {
1425 2175
1426 .row-line { 2176 .row-line {
1427 overflow: hidden; 2177 overflow: hidden;
1428 - width: calc(20% - 2px); 2178 + width: calc(20% - 4px);
1429 border: 1px solid #ebeef5; 2179 border: 1px solid #ebeef5;
1430 background: #f5f7fa; 2180 background: #f5f7fa;
1431 display: inline-block; 2181 display: inline-block;
@@ -1445,4 +2195,69 @@ export default { @@ -1445,4 +2195,69 @@ export default {
1445 .red { 2195 .red {
1446 color: #f30; 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 </style> 2263 </style>
1449 \ No newline at end of file 2264 \ No newline at end of file
src/views/basic/askTestQuestion/gradeAnalysis.vue
@@ -4,8 +4,8 @@ @@ -4,8 +4,8 @@
4 <div class="default-title">即时测报表</div> 4 <div class="default-title">即时测报表</div>
5 </el-header> 5 </el-header>
6 <div class="default-filter"> 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 <el-select v-model="query.grade" class="filter-select" placeholder="选择年级"> 9 <el-select v-model="query.grade" class="filter-select" placeholder="选择年级">
10 <el-option v-for="item in classList" :key="item.grade" :label="item.gradeName" :value="item.grade" /> 10 <el-option v-for="item in classList" :key="item.grade" :label="item.gradeName" :value="item.grade" />
11 </el-select> 11 </el-select>
@@ -107,16 +107,19 @@ export default { @@ -107,16 +107,19 @@ export default {
107 this.$message.error('选择对象考试班级为空,请刷新列表'); 107 this.$message.error('选择对象考试班级为空,请刷新列表');
108 return; 108 return;
109 } 109 }
110 - 110 +
111 var classListStr = JSON.stringify(currentRow.classInfos); 111 var classListStr = JSON.stringify(currentRow.classInfos);
112 112
113 var paperId = currentRow.paperId; 113 var paperId = currentRow.paperId;
114 114
115 var title = currentRow.paperName; 115 var title = currentRow.paperName;
116 - 116 +
117 let routerItem = { 117 let routerItem = {
118 path: "/testGradeReportDetail", 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 this.$router.push(routerItem); 125 this.$router.push(routerItem);
src/views/basic/askTestQuestion/gradeAnalysisDetail.vue
@@ -11,33 +11,41 @@ @@ -11,33 +11,41 @@
11 </el-header> 11 </el-header>
12 <div class="default-filter"> 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 <el-checkbox-group style="display: inline-block" v-model="checkedClassInfos" @change="_handleCheckedClassChange"> 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 <el-checkbox class="_el-checkbox" v-for="classItem in classInfos" :key="classItem.classId" 17 <el-checkbox class="_el-checkbox" v-for="classItem in classInfos" :key="classItem.classId"
17 - :label="classItem.className"> 18 + :label="classItem.classId">
18 {{ classItem.className }} 19 {{ classItem.className }}
19 </el-checkbox> 20 </el-checkbox>
20 </el-checkbox-group> 21 </el-checkbox-group>
  22 + <el-button type="primary" style='float: right;' @click="_anys">分析</el-button>
21 </div> 23 </div>
22 <el-main> 24 <el-main>
23 - <div style="position: relative"> 25 + <div style="position: relative" Id="print-content">
24 <el-tabs v-model="tabType" v-loading="queryLoading" type="card" class="default-tabs"> 26 <el-tabs v-model="tabType" v-loading="queryLoading" type="card" class="default-tabs">
25 <el-tab-pane :name="'成绩测验单'" :label="`成绩测验单`" style="padding: 0 20px"> 27 <el-tab-pane :name="'成绩测验单'" :label="`成绩测验单`" style="padding: 0 20px">
26 <div style="height: calc(100% - 80px);"> 28 <div style="height: calc(100% - 80px);">
27 - <el-row class="row-subfix"> 29 + <el-row class="row-subfix print-hidden">
28 <div style="float: right;margin-bottom: 20px;"> 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 </div> 37 </div>
32 </el-row> 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 <div class="row-line"> 40 <div class="row-line">
35 <span class="line-subfix">班级:</span> 41 <span class="line-subfix">班级:</span>
36 <span class="line-value">{{ item.className }}</span> 42 <span class="line-value">{{ item.className }}</span>
37 </div> 43 </div>
38 <div class="row-line"> 44 <div class="row-line">
39 <span class="line-subfix">试卷名称:</span> 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 </div> 49 </div>
42 <div class="row-line"> 50 <div class="row-line">
43 <span class="line-subfix">测验时间:</span> 51 <span class="line-subfix">测验时间:</span>
@@ -45,7 +53,7 @@ @@ -45,7 +53,7 @@
45 </div> 53 </div>
46 </el-row> 54 </el-row>
47 <el-row class="row-subfix"> 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 <el-table-column prop="testCount" label="测验人数" width="120" /> 57 <el-table-column prop="testCount" label="测验人数" width="120" />
50 <el-table-column prop="avg" label="平均分" width="120" /> 58 <el-table-column prop="avg" label="平均分" width="120" />
51 <el-table-column prop="hight" label="最高分" width="120" /> 59 <el-table-column prop="hight" label="最高分" width="120" />
@@ -58,34 +66,124 @@ @@ -58,34 +66,124 @@
58 </el-table> 66 </el-table>
59 </el-row> 67 </el-row>
60 <el-row class="row-subfix"> 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 <el-table-column :width="item.label == '学号' ? 120 : 0" :prop="item.prop" :label="item.label" 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 </el-table> 72 </el-table>
65 </el-row> 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 </el-table> 150 </el-table>
71 </el-row> 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 </el-table> 174 </el-table>
77 </el-row> 175 </el-row>
78 <el-row class="row-subfix"> 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 <el-table-column prop="quesion" label="题号" width="120" /> 178 <el-table-column prop="quesion" label="题号" width="120" />
81 <el-table-column prop="anwser" label="答案" width="120" /> 179 <el-table-column prop="anwser" label="答案" width="120" />
82 <el-table-column prop="student" label="答错学生"> 180 <el-table-column prop="student" label="答错学生">
83 <template slot-scope="scoped"> 181 <template slot-scope="scoped">
84 <span>总计 <span style="color:red;"> 182 <span>总计 <span style="color:red;">
85 - {{ scoped.row.details.filter(item => !item.isRight).length }}</span> 人 183 + {{ scoped.row.missPeopleNumber }}</span> 人
86 </span> 184 </span>
87 <span style="margin: 10px 0;" 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 选{{ item.option }}:{{ item.students.join("/") }} 187 选{{ item.option }}:{{ item.students.join("/") }}
90 </span> 188 </span>
91 <span></span> 189 <span></span>
@@ -94,35 +192,174 @@ @@ -94,35 +192,174 @@
94 </el-table> 192 </el-table>
95 </el-row> 193 </el-row>
96 </div> 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 </el-tab-pane> 329 </el-tab-pane>
102 <el-tab-pane :name="'班级对比情况'" :label="`班级对比情况`" style="padding: 0 20px"> 330 <el-tab-pane :name="'班级对比情况'" :label="`班级对比情况`" style="padding: 0 20px">
103 <div style="float: right;margin-bottom: 20px;"> 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 </div> 337 </div>
107 <el-table class="default-table" :data="classdiffExamReport"> 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 <template slot-scope="scoped"> 342 <template slot-scope="scoped">
112 {{ scoped.row.testCount }} / {{ scoped.row.classCount }} 343 {{ scoped.row.testCount }} / {{ scoped.row.classCount }}
113 </template> 344 </template>
114 </el-table-column> 345 </el-table-column>
115 - <el-table-column prop="title" label="参与度" width="120"> 346 + <el-table-column prop="title" label="参与度" width="100">
116 <template slot-scope="scoped"> 347 <template slot-scope="scoped">
117 - {{ scoped.row.testCount / scoped.row.classCount }} 348 + {{ Number(scoped.row.testCount * 100 / scoped.row.classCount).toFixed(2) }}%
118 </template> 349 </template>
119 </el-table-column> 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 <el-table-column prop="front20" label="前20名均分" width="120" /> 354 <el-table-column prop="front20" label="前20名均分" width="120" />
124 <el-table-column prop="last20" label="后20名均分" width="120" /> 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 <template slot-scope="scoped"> 363 <template slot-scope="scoped">
127 {{ scoped.row.excellenRate }}% 364 {{ scoped.row.excellenRate }}%
128 </template> 365 </template>
@@ -141,35 +378,77 @@ @@ -141,35 +378,77 @@
141 <template slot-scope="scoped"> 378 <template slot-scope="scoped">
142 {{ scoped.row.passRate }}% 379 {{ scoped.row.passRate }}%
143 </template> 380 </template>
144 - </el-table-column> 381 + </el-table-column> -->
145 </el-table> 382 </el-table>
146 </el-tab-pane> 383 </el-tab-pane>
147 <el-tab-pane :name="'试题分析表'" :label="`试题分析表`" style="padding: 0 20px"> 384 <el-tab-pane :name="'试题分析表'" :label="`试题分析表`" style="padding: 0 20px">
148 <div style="float: right;margin-bottom: 20px;"> 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 </div> 392 </div>
152 - <el-table class="default-table" :data="testPaperExamReport"> 393 + <el-table class="default-table" :data="testPaperExamReport" :span-method="arraySpanMethod">
153 <el-table-column prop="questionIndex" label="题号" width="120" /> 394 <el-table-column prop="questionIndex" label="题号" width="120" />
154 <el-table-column prop="questionType" label="题型" width="100"> 395 <el-table-column prop="questionType" label="题型" width="100">
155 <template slot-scope="scope"> 396 <template slot-scope="scope">
156 {{ setSubPro(scope.row.questionType) }} 397 {{ setSubPro(scope.row.questionType) }}
157 </template> 398 </template>
158 </el-table-column> 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 <el-table-column prop="correctAnswer" label="答案" width="120" /> 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 :prop="'count' + index" width="120"> 444 :prop="'count' + index" width="120">
166 <template slot-scope="scope"> 445 <template slot-scope="scope">
167 <p class="persent"> 446 <p class="persent">
168 {{ 447 {{
169 - scope.row.questionType == "5" 448 + scope.row["option" + index] == "?" ? "未答" : scope.row.questionType == "5"
170 ? "" 449 ? ""
171 : scope.row["option" + index] 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,40 +459,139 @@
180 </el-tab-pane> 459 </el-tab-pane>
181 <el-tab-pane :name="'学生成绩排行'" :label="`学生成绩排行`" style="padding: 0 20px"> 460 <el-tab-pane :name="'学生成绩排行'" :label="`学生成绩排行`" style="padding: 0 20px">
182 <div style="float: right;margin-bottom: 20px;"> 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 </div> 464 </div>
186 <el-table class="default-table" style="margin-top: 10px" :data="testStudentExamReport"> 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 <el-table-column prop="code" label="学号" /> 467 <el-table-column prop="code" label="学号" />
189 <el-table-column prop="name" label="姓名" /> 468 <el-table-column prop="name" label="姓名" />
190 <el-table-column prop="className" label="班级" /> 469 <el-table-column prop="className" label="班级" />
191 <el-table-column prop="exam" label="分数" /> 470 <el-table-column prop="exam" label="分数" />
192 - <el-table-column prop="title" label="成绩等级" /> 471 + <el-table-column prop="lever" label="成绩等级" />
193 </el-table> 472 </el-table>
194 </el-tab-pane> 473 </el-tab-pane>
  474 +
195 </el-tabs> 475 </el-tabs>
196 </div> 476 </div>
197 </el-main> 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 </el-container> 552 </el-container>
199 </template> 553 </template>
200 554
201 <script> 555 <script>
  556 +import { formatDate, downloadFile, tablePrint } from "utils";
202 export default { 557 export default {
203 data() { 558 data() {
204 return { 559 return {
  560 + studentLevelDialog: false,
205 checkAll: true, 561 checkAll: true,
206 isIndeterminate: true, 562 isIndeterminate: true,
207 title: "", 563 title: "",
  564 + defaultLevels: [],
208 paperId: null, 565 paperId: null,
  566 + lowLevel: 20,
  567 + anyLowLevel: 20,
209 classInfos: [], 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 checkedClassInfos: [], 582 checkedClassInfos: [],
211 queryLoading: false, 583 queryLoading: false,
212 tabType: "0", 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 studentMapping: [ 595 studentMapping: [
218 { 596 {
219 key: "code", 597 key: "code",
@@ -240,11 +618,6 @@ export default { @@ -240,11 +618,6 @@ export default {
240 label: "主观分", 618 label: "主观分",
241 }, 619 },
242 ], 620 ],
243 - questionList: [],  
244 - questionHeaders: [],  
245 - questionOtherList: [],  
246 - questionOtherHeaders: [],  
247 - questionTotal: [],  
248 testPaperExamReport: [], 621 testPaperExamReport: [],
249 testPaperExamReportOptions: [], 622 testPaperExamReportOptions: [],
250 testStudentExamReport: [], 623 testStudentExamReport: [],
@@ -252,12 +625,40 @@ export default { @@ -252,12 +625,40 @@ export default {
252 }; 625 };
253 }, 626 },
254 watch: { 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 case "成绩测验单": 660 case "成绩测验单":
260 - await this._testExamReport(); 661 + await this._testExamReport(0);
261 break; 662 break;
262 case "班级对比情况": 663 case "班级对比情况":
263 await this._classdiffExamReport(); 664 await this._classdiffExamReport();
@@ -269,28 +670,200 @@ export default { @@ -269,28 +670,200 @@ export default {
269 await this._testStudentExamReport(); 670 await this._testStudentExamReport();
270 break; 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 _handleCheckAllChange(val) { 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 _handleCheckedClassChange(value) { 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 _detailQ(id) { }, 868 _detailQ(id) { },
296 setSubPro(type) { 869 setSubPro(type) {
@@ -309,19 +882,33 @@ export default { @@ -309,19 +882,33 @@ export default {
309 tit = "主观题"; 882 tit = "主观题";
310 break; 883 break;
311 default: 884 default:
312 - tit = "其他"; 885 + tit = type;
313 } 886 }
314 return tit; 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 const request = this.$request.gTestExamReport; 907 const request = this.$request.gTestExamReport;
321 908
322 let response = await request({ 909 let response = await request({
323 paperId: this.paperId, 910 paperId: this.paperId,
324 - classIds: this.checkedClassInfos.map((item) => item.classId), 911 + classIds: [this.checkedClassInfos[page]],
325 }); 912 });
326 913
327 if (response.status != 0) { 914 if (response.status != 0) {
@@ -329,8 +916,8 @@ export default { @@ -329,8 +916,8 @@ export default {
329 return; 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 var studentHeaders = []; 921 var studentHeaders = [];
335 922
336 var studentResults = []; 923 var studentResults = [];
@@ -349,7 +936,7 @@ export default { @@ -349,7 +936,7 @@ export default {
349 } 936 }
350 } 937 }
351 938
352 - this.studentHeader = [...studentHeaders]; 939 + demoTestTranscript.studentHeader = [...studentHeaders];
353 940
354 for (var isp = 0; isp < response.data.gradeExamStudentReports.length; isp++) { 941 for (var isp = 0; isp < response.data.gradeExamStudentReports.length; isp++) {
355 942
@@ -379,230 +966,321 @@ export default { @@ -379,230 +966,321 @@ export default {
379 studentResults.push(item); 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 else { 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 async _testPaperExamReport() { 1212 async _testPaperExamReport() {
  1213 +
  1214 + this.testPaperExamReport = [];
  1215 +
  1216 + this.testPaperExamReportOptions = [];
  1217 +
  1218 + if (!this.checkedClassInfos || this.checkedClassInfos?.length <= 0) return;
  1219 +
583 const request = this.$request.gPaperExamReport; 1220 const request = this.$request.gPaperExamReport;
584 1221
585 let response = await request({ 1222 let response = await request({
586 paperId: this.paperId, 1223 paperId: this.paperId,
587 - classIds: this.checkedClassInfos.map((item) => item.classId), 1224 + classIds: this.checkedClassInfos,
588 }); 1225 });
589 1226
590 if (response.status != 0) { 1227 if (response.status != 0) {
591 this.$message.error(response.info); 1228 this.$message.error(response.info);
592 return; 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 let tableData = response.data?.map((item) => { 1270 let tableData = response.data?.map((item) => {
  1271 +
598 let params = {}; 1272 let params = {};
  1273 +
599 const detail = item.details; 1274 const detail = item.details;
  1275 +
600 let lastOPtion = detail?.find((item) => { 1276 let lastOPtion = detail?.find((item) => {
601 return item.option == "未答"; 1277 return item.option == "未答";
602 }); 1278 });
  1279 +
603 let defaultArr = detail?.filter((item) => { 1280 let defaultArr = detail?.filter((item) => {
604 return item.option != "未答"; 1281 return item.option != "未答";
605 }); 1282 });
  1283 +
606 optionsList.map((items, index) => { 1284 optionsList.map((items, index) => {
607 if (index != 4) { 1285 if (index != 4) {
608 params["count" + index] = 1286 params["count" + index] =
@@ -624,12 +1302,28 @@ export default { @@ -624,12 +1302,28 @@ export default {
624 items["title"] = "选项" + (index + 1); 1302 items["title"] = "选项" + (index + 1);
625 } else { 1303 } else {
626 items["title"] = "未答"; 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 params["option" + index] = "?"; 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 return { 1327 return {
634 ...item, 1328 ...item,
635 ...params, 1329 ...params,
@@ -637,18 +1331,57 @@ export default { @@ -637,18 +1331,57 @@ export default {
637 }); 1331 });
638 1332
639 this.testPaperExamReport = tableData?.sort((a, b) => { 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 this.testPaperExamReportOptions = [...optionsList]; 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 async _testStudentExamReport() { 1366 async _testStudentExamReport() {
  1367 + this.testStudentExamReport = [];
  1368 + if (!this.checkedClassInfos || this.checkedClassInfos?.length <= 0) return;
  1369 +
647 const request = this.$request.gStudentExamReport; 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 let response = await request({ 1381 let response = await request({
650 paperId: this.paperId, 1382 paperId: this.paperId,
651 - classIds: this.checkedClassInfos.map((item) => item.classId), 1383 + classIds: this.checkedClassInfos,
  1384 + reportRange: paramObj
652 }); 1385 });
653 1386
654 if (response.status != 0) { 1387 if (response.status != 0) {
@@ -659,11 +1392,26 @@ export default { @@ -659,11 +1392,26 @@ export default {
659 this.testStudentExamReport = response.data; 1392 this.testStudentExamReport = response.data;
660 }, 1393 },
661 async _classdiffExamReport() { 1394 async _classdiffExamReport() {
  1395 +
  1396 + this.classdiffExamReport = [];
  1397 +
  1398 + if (!this.checkedClassInfos || this.checkedClassInfos?.length <= 0) return;
  1399 +
662 const request = this.$request.gClassdiffExamReport; 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 let response = await request({ 1411 let response = await request({
665 paperId: this.paperId, 1412 paperId: this.paperId,
666 - classIds: this.checkedClassInfos.map((item) => item.classId), 1413 + classIds: this.checkedClassInfos,
  1414 + reportRange: paramObj
667 }); 1415 });
668 1416
669 if (response.status != 0) { 1417 if (response.status != 0) {
@@ -675,6 +1423,7 @@ export default { @@ -675,6 +1423,7 @@ export default {
675 this.classdiffExamReport = response.data.map((item) => { 1423 this.classdiffExamReport = response.data.map((item) => {
676 item.index = index + 1; 1424 item.index = index + 1;
677 index += 1; 1425 index += 1;
  1426 +
678 return item; 1427 return item;
679 }); 1428 });
680 }, 1429 },
@@ -694,7 +1443,11 @@ export default { @@ -694,7 +1443,11 @@ export default {
694 padding: 10px !important; 1443 padding: 10px !important;
695 } 1444 }
696 1445
  1446 +
697 .row-line { 1447 .row-line {
  1448 + overflow: hidden; //超出宽度隐藏
  1449 + white-space: nowrap; //强制文字在一行
  1450 + text-overflow: ellipsis; //文字溢出显示省略号
698 width: calc(33% - 2px); 1451 width: calc(33% - 2px);
699 border: 1px solid #ebeef5; 1452 border: 1px solid #ebeef5;
700 background: #f5f7fa; 1453 background: #f5f7fa;
@@ -705,5 +1458,71 @@ export default { @@ -705,5 +1458,71 @@ export default {
705 .line-subfix { 1458 .line-subfix {
706 margin-left: 10px; 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 </style> 1528 </style>
src/views/basic/askTestQuestion/index.vue
@@ -7,16 +7,16 @@ @@ -7,16 +7,16 @@
7 <el-dropdown v-if="this.dataType == '2'" :hide-on-click="true" style="float: right;margin-right: 50px;"> 7 <el-dropdown v-if="this.dataType == '2'" :hide-on-click="true" style="float: right;margin-right: 50px;">
8 <el-button :size="'small'" :icon="'el-icon-plus'" class="green-el-button">添加试卷</el-button> 8 <el-button :size="'small'" :icon="'el-icon-plus'" class="green-el-button">添加试卷</el-button>
9 <el-dropdown-menu slot="dropdown"> 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 <el-dropdown-item @click.native="createAnwseredCard()">创建答题卡</el-dropdown-item> 11 <el-dropdown-item @click.native="createAnwseredCard()">创建答题卡</el-dropdown-item>
12 </el-dropdown-menu> 12 </el-dropdown-menu>
13 </el-dropdown> 13 </el-dropdown>
14 <el-button style="float: right;margin-right: 50px;" :size="'small'" :icon="'el-icon-plus'" 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 </el-header> 16 </el-header>
17 <div class="default-filter"> 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 <el-select @change="_changeClass" v-model="query.class" class="filter-select" placeholder="选择班级"> 20 <el-select @change="_changeClass" v-model="query.class" class="filter-select" placeholder="选择班级">
21 <el-option v-for="item in classList" :key="item.classId" :label="item.className" 21 <el-option v-for="item in classList" :key="item.classId" :label="item.className"
22 :value="item.classId" /> 22 :value="item.classId" />
@@ -34,7 +34,7 @@ @@ -34,7 +34,7 @@
34 筛选 34 筛选
35 </el-button> 35 </el-button>
36 <el-radio-group v-model="dateStatus" class="default-date-radio-group"> 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 <el-radio-button label="onWeek">本周</el-radio-button> 38 <el-radio-button label="onWeek">本周</el-radio-button>
39 <el-radio-button label="onMonth">本月</el-radio-button> 39 <el-radio-button label="onMonth">本月</el-radio-button>
40 </el-radio-group> 40 </el-radio-group>
@@ -42,192 +42,206 @@ @@ -42,192 +42,206 @@
42 <el-main> 42 <el-main>
43 <div style='position: relative;'> 43 <div style='position: relative;'>
44 <el-tabs v-model="tabType" v-loading="queryLoading" type="card" class="default-tabs"> 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 {{ item.title }} 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 </div> 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 </span> 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 </div> 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 </div> 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 </div> 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 </div> 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 </div> 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 </div> 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 </span> 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 </div> 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 </el-tab-pane> 224 </el-tab-pane>
211 <div slot="tab-bar"> 225 <div slot="tab-bar">
212 <el-button type="primary" icon="el-icon-plus">新增</el-button> 226 <el-button type="primary" icon="el-icon-plus">新增</el-button>
213 </div> 227 </div>
214 </el-tabs> 228 </el-tabs>
215 <el-button size='mini' v-if="role == 'ROLE_PERSONAL' || role == 'ROLE_JIAOSHI'" @click="recycle" 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 </div> 231 </div>
218 </el-main> 232 </el-main>
219 <el-footer class="el-footer-pagination"> 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 </el-pagination> 236 </el-pagination>
224 </el-footer> 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 <upload :url="url" :params="{ type: importType }" @upSuccess="upSuccess" fileName="下载"> 240 <upload :url="url" :params="{ type: importType }" @upSuccess="upSuccess" fileName="下载">
227 <div class="down-box p0" slot="down"> 241 <div class="down-box p0" slot="down">
228 <p class="down-head" v-if="importType == 1"> 242 <p class="down-head" v-if="importType == 1">
229 <span>第一步:</span> 243 <span>第一步:</span>
230 - <el-link type="primary" @click="downExcel">下载模板,</el-link> 244 + <!-- <el-link type="primary" @click="downExcel">下载模板,</el-link> -->
231 <span>或者导出菁优网试卷/组卷网(学科网)试卷; 245 <span>或者导出菁优网试卷/组卷网(学科网)试卷;
232 为保证第三方试卷导入成功,请注意参考导出示例:</span> 246 为保证第三方试卷导入成功,请注意参考导出示例:</span>
233 <span class="img-box"> 247 <span class="img-box">
@@ -241,7 +255,9 @@ @@ -241,7 +255,9 @@
241 </span> 255 </span>
242 </p> 256 </p>
243 <p class="down-head" v-if="importType == 2"> 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 <span class="img-box"> 261 <span class="img-box">
246 <el-image class="img" :src="examplePic" :preview-src-list="examplePicList"> 262 <el-image class="img" :src="examplePic" :preview-src-list="examplePicList">
247 </el-image> 263 </el-image>
@@ -266,10 +282,10 @@ @@ -266,10 +282,10 @@
266 </template> 282 </template>
267 283
268 <script> 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 import example2 from "@/assets/images/example2.png"; 287 import example2 from "@/assets/images/example2.png";
272 - 288 +import axios from "axios";
273 289
274 export default { 290 export default {
275 data() { 291 data() {
@@ -309,7 +325,7 @@ export default { @@ -309,7 +325,7 @@ export default {
309 sharedCount: 0 325 sharedCount: 0
310 }; 326 };
311 }, 327 },
312 - watch: { 328 + watch: {
313 '$route'() { 329 '$route'() {
314 this.dataType = location.href.endsWith("askPreparationQuestions") ? "1" : "2"; 330 this.dataType = location.href.endsWith("askPreparationQuestions") ? "1" : "2";
315 this._serach(); 331 this._serach();
@@ -323,16 +339,37 @@ export default { @@ -323,16 +339,37 @@ export default {
323 this.query.dateRange = [dateRange.startDay, dateRange.endDay]; 339 this.query.dateRange = [dateRange.startDay, dateRange.endDay];
324 } 340 }
325 }, 341 },
326 - created() { 342 + async created() {
327 this.dataType = location.href.endsWith("askPreparationQuestions") ? "1" : "2"; 343 this.dataType = location.href.endsWith("askPreparationQuestions") ? "1" : "2";
328 this.code = this.$store.getters.csCode; 344 this.code = this.$store.getters.csCode;
329 this.role = 345 this.role =
330 this.$store.getters.info.showRole || 346 this.$store.getters.info.showRole ||
331 this.$store.getters.info.permissions[0].role; 347 this.$store.getters.info.permissions[0].role;
332 - this._loadQueryDatas(); 348 + this.dateStatus = "onWeek";
  349 + await this._loadQueryDatas();
333 }, 350 },
334 methods: { 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 this.listPage.page = value; 373 this.listPage.page = value;
337 await this._serach(); 374 await this._serach();
338 }, 375 },
@@ -345,7 +382,7 @@ export default { @@ -345,7 +382,7 @@ export default {
345 } 382 }
346 this.$router.push(routerItem); 383 this.$router.push(routerItem);
347 }, 384 },
348 - createAnwseredCard() { 385 + createAnwseredCard(params) {
349 let routerItem = { 386 let routerItem = {
350 path: "/testPaperAdd", 387 path: "/testPaperAdd",
351 query: { 388 query: {
@@ -356,7 +393,7 @@ export default { @@ -356,7 +393,7 @@ export default {
356 }; 393 };
357 this.$router.push(routerItem); 394 this.$router.push(routerItem);
358 }, 395 },
359 - import(type) { 396 + importQuestion(type) {
360 this.importType = type; 397 this.importType = type;
361 this.diaUp = true; 398 this.diaUp = true;
362 }, 399 },
@@ -373,13 +410,48 @@ export default { @@ -373,13 +410,48 @@ export default {
373 }); 410 });
374 this.diaUp = false; 411 this.diaUp = false;
375 let params = JSON.stringify(res.data); 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 } else { 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 async _changeClass() { 455 async _changeClass() {
384 await this._loadSubjectData(); 456 await this._loadSubjectData();
385 }, 457 },
@@ -488,7 +560,7 @@ export default { @@ -488,7 +560,7 @@ export default {
488 this.createdCount = data?.myCount || 0; 560 this.createdCount = data?.myCount || 0;
489 this.sharedCount = data?.gradeCount || 0; 561 this.sharedCount = data?.gradeCount || 0;
490 this.listPage.total = data.total; 562 this.listPage.total = data.total;
491 - 563 +
492 if (this.tabType == "0") { 564 if (this.tabType == "0") {
493 this.defaultList = []; 565 this.defaultList = [];
494 if (data?.list) this.defaultList = [...data?.list]; 566 if (data?.list) this.defaultList = [...data?.list];
@@ -504,11 +576,18 @@ export default { @@ -504,11 +576,18 @@ export default {
504 query: { id: id }, 576 query: { id: id },
505 }; 577 };
506 if (this.dataType == '2') { 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 this.$router.push(routerItem); 588 this.$router.push(routerItem);
510 }, 589 },
511 - _copy(currentRow) { 590 + _copy(currentRow) {
512 let routerItem = { 591 let routerItem = {
513 path: "/askPreparationQuestionsAdd", 592 path: "/askPreparationQuestionsAdd",
514 query: { 593 query: {
@@ -530,19 +609,21 @@ export default { @@ -530,19 +609,21 @@ export default {
530 609
531 }, 610 },
532 _updateQ(item) { 611 _updateQ(item) {
533 - console.log(item) 612 +
534 var currentClass = this.classList.find(item => item.classId == this.query.class); 613 var currentClass = this.classList.find(item => item.classId == this.query.class);
535 614
536 let routerItem = { 615 let routerItem = {
537 path: "/askPreparationQuestionsUpdate", 616 path: "/askPreparationQuestionsUpdate",
538 query: { 617 query: {
539 - paperId: item.id, paperType: 1, 618 + paperId: item.id,
  619 + paperType: 1,
540 classId: currentClass.classId, 620 classId: currentClass.classId,
541 gradeName: currentClass.gradeName 621 gradeName: currentClass.gradeName
542 }, 622 },
543 }; 623 };
544 624
545 if (this.dataType == '2') { 625 if (this.dataType == '2') {
  626 + routerItem.query.paperType = 2;
546 routerItem.path = "/testPaperQuestionsUpdate"; 627 routerItem.path = "/testPaperQuestionsUpdate";
547 } 628 }
548 629
@@ -610,12 +691,15 @@ export default { @@ -610,12 +691,15 @@ export default {
610 color: #667FFD; 691 color: #667FFD;
611 line-height: 32px; 692 line-height: 32px;
612 padding: 0 10px; 693 padding: 0 10px;
613 - height: 32px;  
614 margin-right: 10px; 694 margin-right: 10px;
  695 + height: 32px;
  696 + margin-top: 3px;
615 } 697 }
616 698
  699 + width: 48.5%;
  700 + display: inline-block;
617 margin-bottom: 10px; 701 margin-bottom: 10px;
618 - height: 180px; 702 + min-height: 190px;
619 border: 1px solid #E6E9F4; 703 border: 1px solid #E6E9F4;
620 border-radius: 10px 10px 10px 10px; 704 border-radius: 10px 10px 10px 10px;
621 box-shadow: 0px 4px 14px 0px rgba(0, 0, 0, 0.08); 705 box-shadow: 0px 4px 14px 0px rgba(0, 0, 0, 0.08);
@@ -628,13 +712,20 @@ export default { @@ -628,13 +712,20 @@ export default {
628 font-size: 14px; 712 font-size: 14px;
629 font-weight: 400; 713 font-weight: 400;
630 714
  715 + .descption-label {
  716 + min-width: 120px;
  717 + }
  718 +
631 .descption-tag-text { 719 .descption-tag-text {
632 margin-bottom: 20px; 720 margin-bottom: 20px;
633 display: flex; 721 display: flex;
634 justify-content: flex-start; 722 justify-content: flex-start;
635 align-items: center; 723 align-items: center;
  724 + width: calc(100% - 5px);
636 } 725 }
637 726
  727 +
  728 +
638 .descption-text { 729 .descption-text {
639 height: 30px; 730 height: 30px;
640 margin-top: 10px; 731 margin-top: 10px;
@@ -660,13 +751,17 @@ export default { @@ -660,13 +751,17 @@ export default {
660 } 751 }
661 752
662 .title-text { 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 .dropdown-button { 766 .dropdown-button {
672 .el-button { 767 .el-button {
@@ -682,7 +777,7 @@ export default { @@ -682,7 +777,7 @@ export default {
682 } 777 }
683 778
684 .left { 779 .left {
685 - height: 180px; 780 + height: 190px;
686 background-color: #41CC95; 781 background-color: #41CC95;
687 vertical-align: middle; 782 vertical-align: middle;
688 border-radius: 10px 0px 0px 10px; 783 border-radius: 10px 0px 0px 10px;
src/views/basic/askTestQuestion/recycle.vue
@@ -32,7 +32,7 @@ @@ -32,7 +32,7 @@
32 <el-main> 32 <el-main>
33 <div style='position: relative;'> 33 <div style='position: relative;'>
34 <el-tabs v-model="tabType" v-loading="queryLoading" type="card" class="default-tabs"> 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 <el-table class="default-table" :data="defaultList"> 36 <el-table class="default-table" :data="defaultList">
37 <el-table-column prop="id" label="试卷ID" width="100"></el-table-column> 37 <el-table-column prop="id" label="试卷ID" width="100"></el-table-column>
38 <el-table-column prop="title" label="试卷名称"></el-table-column> 38 <el-table-column prop="title" label="试卷名称"></el-table-column>
@@ -56,7 +56,7 @@ @@ -56,7 +56,7 @@
56 </el-table-column> 56 </el-table-column>
57 </el-table> 57 </el-table>
58 </el-tab-pane> 58 </el-tab-pane>
59 - <el-tab-pane :name="'1'" :label="`共享课件(${sharedCount})`"> 59 + <el-tab-pane :name="'1'" :label="`被共享的(${sharedCount})`">
60 <el-table class="default-table" :data="sharedList"> 60 <el-table class="default-table" :data="sharedList">
61 <el-table-column prop="id" label="试卷ID" width="100"></el-table-column> 61 <el-table-column prop="id" label="试卷ID" width="100"></el-table-column>
62 <el-table-column prop="title" label="试卷名称"></el-table-column> 62 <el-table-column prop="title" label="试卷名称"></el-table-column>
@@ -66,11 +66,11 @@ @@ -66,11 +66,11 @@
66 <el-table-column prop="createdTime" label="创建时间"></el-table-column> 66 <el-table-column prop="createdTime" label="创建时间"></el-table-column>
67 <el-table-column prop="modifiedTime" label="删除时间"></el-table-column> 67 <el-table-column prop="modifiedTime" label="删除时间"></el-table-column>
68 <el-table-column prop="createdTime" label="操作"> 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 </el-button> 72 </el-button>
73 - <el-popconfirm title="确定删除这张答题卡吗?" @confirm="remove(item)"> 73 + <el-popconfirm title="确定删除这张答题卡吗?" @confirm="remove(scoped.row)">
74 <el-button style="color:red;margin-left: 10px;" slot="reference" class="delete" 74 <el-button style="color:red;margin-left: 10px;" slot="reference" class="delete"
75 type="text" size="mini"> 75 type="text" size="mini">
76 删除 76 删除
@@ -96,6 +96,7 @@ @@ -96,6 +96,7 @@
96 </el-container> 96 </el-container>
97 </template> 97 </template>
98 <script> 98 <script>
  99 +import { setDateRules } from "utils";
99 export default { 100 export default {
100 data() { 101 data() {
101 return { 102 return {
@@ -139,12 +140,21 @@ export default { @@ -139,12 +140,21 @@ export default {
139 this.$store.getters.info.showRole || 140 this.$store.getters.info.showRole ||
140 this.$store.getters.info.permissions[0].role; 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 await this._loadQueryDatas(); 146 await this._loadQueryDatas();
143 await this._serach(); 147 await this._serach();
144 148
145 }, 149 },
  150 + watch: {
  151 + 'tabType'() {
  152 + this.listPage.page = 1;
  153 + this._serach();
  154 + }
  155 + },
146 methods: { 156 methods: {
147 - async modify(obj) { 157 + async modify(obj) {
148 //恢复答题卡 158 //恢复答题卡
149 let modifyPaper = 159 let modifyPaper =
150 this.role == "ROLE_PERSONAL" 160 this.role == "ROLE_PERSONAL"
@@ -152,10 +162,12 @@ export default { @@ -152,10 +162,12 @@ export default {
152 : this.$request.modifyPaper; 162 : this.$request.modifyPaper;
153 const { data, status, info } = await modifyPaper({ 163 const { data, status, info } = await modifyPaper({
154 paperId: obj.id, 164 paperId: obj.id,
155 - status: 1, 165 + share: this.tabType == '0' ? "0" : "1",
  166 + status: 1
156 }); 167 });
157 if (status == 0) { 168 if (status == 0) {
158 let type = this.query.title ? 1 : 0; 169 let type = this.query.title ? 1 : 0;
  170 + this.$message.success(info);
159 this._serach(type); 171 this._serach(type);
160 } else { 172 } else {
161 this.$message.error(info); 173 this.$message.error(info);
@@ -169,9 +181,13 @@ export default { @@ -169,9 +181,13 @@ export default {
169 : this.$request.delPaper; 181 : this.$request.delPaper;
170 const { data, status, info } = await delPaper({ 182 const { data, status, info } = await delPaper({
171 paperId: obj.id, 183 paperId: obj.id,
  184 + share: this.tabType == '0' ? "0" : "1",
  185 + status: 2
  186 +
172 }); 187 });
173 if (status == 0) { 188 if (status == 0) {
174 let type = this.query.title ? 1 : 0; 189 let type = this.query.title ? 1 : 0;
  190 + this.$message.success(info);
175 this._serach(type); 191 this._serach(type);
176 } else { 192 } else {
177 this.$message.error(info); 193 this.$message.error(info);
@@ -284,7 +300,7 @@ export default { @@ -284,7 +300,7 @@ export default {
284 } 300 }
285 this.queryLoading = false; 301 this.queryLoading = false;
286 this.createdCount = data?.myCount || 0; 302 this.createdCount = data?.myCount || 0;
287 - this.sharedCount = data?.gradeCount || 0; 303 + this.sharedCount = data?.delShare || 0;
288 this.listPage.total = data.total; 304 this.listPage.total = data.total;
289 if (this.tabType == "0") { 305 if (this.tabType == "0") {
290 this.defaultList = []; 306 this.defaultList = [];
src/views/basic/askTestQuestion/report.vue
@@ -4,24 +4,29 @@ @@ -4,24 +4,29 @@
4 <div class="default-title">{{ dataType == "1" ? '随堂问报表' : '即时测报表' }}</div> 4 <div class="default-title">{{ dataType == "1" ? '随堂问报表' : '即时测报表' }}</div>
5 </el-header> 5 </el-header>
6 <div class="default-filter"> 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 <el-select @change="_changeClass" v-model="query.class" class="filter-select" placeholder="选择班级"> 9 <el-select @change="_changeClass" v-model="query.class" class="filter-select" placeholder="选择班级">
10 <el-option v-for="item in classList " :key="item.classId" :label="item.className" :value="item.classId" /> 10 <el-option v-for="item in classList " :key="item.classId" :label="item.className" :value="item.classId" />
11 </el-select> 11 </el-select>
12 <el-select v-model="query.subject" v-if="role == 'ROLE_JIAOSHI'" placeholder="选择科目" class="filter-select"> 12 <el-select v-model="query.subject" v-if="role == 'ROLE_JIAOSHI'" placeholder="选择科目" class="filter-select">
13 <el-option v-for=" item in subjectList" :key="item" :label="item" :value="item" /> 13 <el-option v-for=" item in subjectList" :key="item" :label="item" :value="item" />
14 </el-select> 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 class="filter-select"> 16 class="filter-select">
17 <el-option v-for="item in subjectList" :key="item" :label="item" :value="item"> 17 <el-option v-for="item in subjectList" :key="item" :label="item" :value="item">
18 <!-- <el-checkbox :checked="checkedSubject.indexOf(item) >= 0" @click="subjectCheck(item)">{{ item }}</el-checkbox> --> 18 <!-- <el-checkbox :checked="checkedSubject.indexOf(item) >= 0" @click="subjectCheck(item)">{{ item }}</el-checkbox> -->
19 </el-option> 19 </el-option>
20 </el-select> 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 </el-date-picker> 23 </el-date-picker>
24 <el-button type="primary" @click="_serach"> 筛选 </el-button> 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 </div> 30 </div>
26 <el-main> 31 <el-main>
27 <div style="position: relative"> 32 <div style="position: relative">
@@ -31,37 +36,43 @@ @@ -31,37 +36,43 @@
31 :queryParams="query" /> 36 :queryParams="query" />
32 </el-tab-pane> 37 </el-tab-pane>
33 <el-tab-pane v-if="dataType == 1 && role == 'ROLE_JIAOSHI'" :name="'1'" :label="`单课时报表`"> 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 </el-tab-pane> 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 <askBzrMulti v-if="apiDatas.askReportIds" :askReportIds="apiDatas.askReportIds" :queryParams="query" /> 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 </el-tab-pane> 49 </el-tab-pane>
42 <el-tab-pane v-if="dataType == 2 && role == 'ROLE_JIAOSHI'" :name="'0'" :label="`阶段报表`"> 50 <el-tab-pane v-if="dataType == 2 && role == 'ROLE_JIAOSHI'" :name="'0'" :label="`阶段报表`">
43 <testSummaryReport v-if="apiDatas.testReportIds" :testReportIds="apiDatas.testReportIds" 51 <testSummaryReport v-if="apiDatas.testReportIds" :testReportIds="apiDatas.testReportIds"
44 - :queryParams="query" /> 52 + @headerClick="_headerClick" :queryParams="query" />
45 </el-tab-pane> 53 </el-tab-pane>
46 <el-tab-pane v-if="dataType == 2 && role == 'ROLE_JIAOSHI'" :name="'1'" :label="`单卷报表`"> 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 </el-tab-pane> 56 </el-tab-pane>
49 <el-tab-pane v-if="dataType == 2 && role == 'ROLE_JIAOSHI'" :name="'2'" :label="`多班对比报表`"> 57 <el-tab-pane v-if="dataType == 2 && role == 'ROLE_JIAOSHI'" :name="'2'" :label="`多班对比报表`">
50 <testMultiClassReport :params="query" /> 58 <testMultiClassReport :params="query" />
51 </el-tab-pane> 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 <testBzrMulti v-if="apiDatas.testReportIds" :list="apiDatas.testReportList" 62 <testBzrMulti v-if="apiDatas.testReportIds" :list="apiDatas.testReportList"
54 :testReportIds="apiDatas.testReportIds" :queryParams="query" /> 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 </el-tab-pane> 69 </el-tab-pane>
59 <div slot="tab-bar"> 70 <div slot="tab-bar">
60 <el-button type="primary" icon="el-icon-plus">新增</el-button> 71 <el-button type="primary" icon="el-icon-plus">新增</el-button>
61 </div> 72 </div>
62 </el-tabs> 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 </div> 77 </div>
67 </el-main> 78 </el-main>
@@ -69,6 +80,7 @@ @@ -69,6 +80,7 @@
69 </template> 80 </template>
70 81
71 <script> 82 <script>
  83 +import { setDateRules } from "@/utils";
72 export default { 84 export default {
73 name: "repo", 85 name: "repo",
74 components: { 86 components: {
@@ -111,9 +123,15 @@ export default { @@ -111,9 +123,15 @@ export default {
111 testReportList: null, 123 testReportList: null,
112 }, 124 },
113 queryLoading: false, 125 queryLoading: false,
  126 + dateStatus: "0"
114 }; 127 };
115 }, 128 },
116 watch: { 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 '$route'() { 135 '$route'() {
118 this.dataType = location.href.endsWith("askReport") ? "1" : "2"; 136 this.dataType = location.href.endsWith("askReport") ? "1" : "2";
119 this._loadQueryDatas(); 137 this._loadQueryDatas();
@@ -127,14 +145,16 @@ export default { @@ -127,14 +145,16 @@ export default {
127 } 145 }
128 }, 146 },
129 async 'query.subjects'(value) { 147 async 'query.subjects'(value) {
130 - console.log(value)  
131 if (this.role == "ROLE_BANZHUREN") { 148 if (this.role == "ROLE_BANZHUREN") {
132 if (value.length == 1 && value[0] != '全部科目') { 149 if (value.length == 1 && value[0] != '全部科目') {
133 this.query.status = 'single'; 150 this.query.status = 'single';
  151 + this.tabType = '1';
134 await this._serach(); 152 await this._serach();
135 } 153 }
136 else { 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,9 +166,30 @@ export default {
146 this.role = 166 this.role =
147 this.$store.getters.info.showRole || 167 this.$store.getters.info.showRole ||
148 this.$store.getters.info.permissions[0].role; 168 this.$store.getters.info.permissions[0].role;
  169 + this.dateStatus = "onWeek";
149 await this._loadQueryDatas(); 170 await this._loadQueryDatas();
150 }, 171 },
151 methods: { 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 async _changeClass() { 193 async _changeClass() {
153 await this._loadSubjectData(); 194 await this._loadSubjectData();
154 }, 195 },
@@ -202,7 +243,7 @@ export default { @@ -202,7 +243,7 @@ export default {
202 }, 243 },
203 _recycle() { }, 244 _recycle() { },
204 async _serach() { 245 async _serach() {
205 - 246 +
206 this.queryLoading = true; 247 this.queryLoading = true;
207 var queryParams = { 248 var queryParams = {
208 classId: "", 249 classId: "",
@@ -214,12 +255,15 @@ export default { @@ -214,12 +255,15 @@ export default {
214 255
215 queryParams.classId = this.query.class; 256 queryParams.classId = this.query.class;
216 queryParams.classIds = [this.query.class]; 257 queryParams.classIds = [this.query.class];
217 - if (this.query.subjects) { 258 +
  259 + if (this.query.subjects && this.role == 'ROLE_BANZHUREN') {
218 queryParams.subjectNames = this.query.subjects; 260 queryParams.subjectNames = this.query.subjects;
  261 + queryParams.subject = queryParams.subjectNames[0];
219 } 262 }
220 else { 263 else {
221 queryParams.subjectNames = [this.query.subject]; 264 queryParams.subjectNames = [this.query.subject];
222 } 265 }
  266 + console.log(queryParams, this.query.subject)
223 267
224 queryParams.startDay = this.query.dateRange 268 queryParams.startDay = this.query.dateRange
225 ? this.query.dateRange[0] 269 ? this.query.dateRange[0]
@@ -266,10 +310,15 @@ export default { @@ -266,10 +310,15 @@ export default {
266 this.$message.error(testReportResponse.info); 310 this.$message.error(testReportResponse.info);
267 return; 311 return;
268 } 312 }
  313 +
269 this.apiDatas.testReportList = [...testReportResponse?.data?.list ?? []]; 314 this.apiDatas.testReportList = [...testReportResponse?.data?.list ?? []];
  315 +
270 this.apiDatas.testReportIds = [...this.apiDatas.testReportList?.map((item) => item.id) ?? []]; 316 this.apiDatas.testReportIds = [...this.apiDatas.testReportList?.map((item) => item.id) ?? []];
  317 +
271 } 318 }
  319 +
272 this.tabIndexs += 1; 320 this.tabIndexs += 1;
  321 +
273 this.queryLoading = false; 322 this.queryLoading = false;
274 323
275 }, 324 },
@@ -288,6 +337,17 @@ export default { @@ -288,6 +337,17 @@ export default {
288 }; 337 };
289 this.$router.push(routerItem); 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 async _deleteDetermineQ(id) { 351 async _deleteDetermineQ(id) {
292 let modifyPaper = 352 let modifyPaper =
293 this.role == "ROLE_PERSONAL" 353 this.role == "ROLE_PERSONAL"
src/views/basic/askTestQuestion/update.vue
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 <back-box class="detailBack"> 4 <back-box class="detailBack">
5 <template slot="title"> 5 <template slot="title">
6 <span class="default-title"> 6 <span class="default-title">
7 - {{ type == 1 ? "修改试卷" : "修改答案" }}</span> 7 + {{ isViewer ? "详情" : type == 1 ? paperType == 1 ? "修改课件" : "修改试卷" : "修改答案" }}</span>
8 </template> 8 </template>
9 </back-box> 9 </back-box>
10 </el-header> 10 </el-header>
@@ -21,103 +21,207 @@ @@ -21,103 +21,207 @@
21 <div class="answer-title" :class="type == 1 ? 't-left' : ''"> 21 <div class="answer-title" :class="type == 1 ? 't-left' : ''">
22 <p class="name-box"> 22 <p class="name-box">
23 <span>试卷名称:</span> 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 </p> 25 </p>
26 <p class="name-box"> 26 <p class="name-box">
27 <span>分享范围:</span> 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 </p> 31 </p>
32 </div> 32 </div>
33 <div class="question-box"> 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 </div> 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 </div> 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 </div> 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 ? 'answer-active' 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 ? 'answer-active' 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 </div> 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 </div> 217 </div>
111 </div> 218 </div>
112 </div> 219 </div>
113 </div> 220 </div>
114 </div> 221 </div>
115 </div> 222 </div>
116 - <div v-if="paperType == 2">  
117 - <div class="paper"></div>  
118 - </div>  
119 </div> 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 :modal-append-to-body="false" :append-to-body="true"> 225 :modal-append-to-body="false" :append-to-body="true">
122 <div> 226 <div>
123 <el-row class="row-subfix"> 227 <el-row class="row-subfix">
@@ -126,23 +230,26 @@ @@ -126,23 +230,26 @@
126 <span class="line-value">{{ gradeName }}</span> 230 <span class="line-value">{{ gradeName }}</span>
127 </div> 231 </div>
128 </el-row> 232 </el-row>
129 - <el-row class="row-subfix"> 233 + <el-row class="row-subfix" style="margin-top: 20px;">
130 <span class="line-subfix" style="float: left;">班级:</span> 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 <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" 238 <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll"
134 @change="handleCheckAllChange">全选</el-checkbox> 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 </el-checkbox-group> 245 </el-checkbox-group>
139 </span> 246 </span>
140 </div> 247 </div>
141 </el-row> 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 </div> 253 </div>
147 </el-dialog> 254 </el-dialog>
148 <el-dialog :close-on-click-modal="false" title="批量设置答案" :visible.sync="diaSetAns" width="400" 255 <el-dialog :close-on-click-modal="false" title="批量设置答案" :visible.sync="diaSetAns" width="400"
@@ -215,8 +322,8 @@ @@ -215,8 +322,8 @@
215 <el-button @click="dialogStem = false">确定</el-button> 322 <el-button @click="dialogStem = false">确定</el-button>
216 </div> 323 </div>
217 </el-dialog> 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 <div> 327 <div>
221 <el-form ref="form" :model="stem" label-width="160px"> 328 <el-form ref="form" :model="stem" label-width="160px">
222 <el-form-item label="知识点:"> 329 <el-form-item label="知识点:">
@@ -236,8 +343,8 @@ @@ -236,8 +343,8 @@
236 </el-dialog> 343 </el-dialog>
237 </div> 344 </div>
238 <div class="content-fi"> 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 </div> 348 </div>
242 </el-main> 349 </el-main>
243 </el-container> 350 </el-container>
@@ -251,10 +358,13 @@ export default { @@ -251,10 +358,13 @@ export default {
251 return { 358 return {
252 role: "", 359 role: "",
253 title: "", 360 title: "",
  361 + classSharingType: false,
254 gradeName: "", 362 gradeName: "",
255 checkAll: false, 363 checkAll: false,
256 checkedClass: [], 364 checkedClass: [],
257 gradeClass: [], 365 gradeClass: [],
  366 + subjectName: "",
  367 + isViewer: false,
258 isIndeterminate: true, 368 isIndeterminate: true,
259 type: 1, //1:答题卡 2:即时测报表题目列表 3:课时题目列表 369 type: 1, //1:答题卡 2:即时测报表题目列表 3:课时题目列表
260 questionList: [], 370 questionList: [],
@@ -362,8 +472,10 @@ export default { @@ -362,8 +472,10 @@ export default {
362 this.type = this.$route.query.type || 1; 472 this.type = this.$route.query.type || 1;
363 this.examType = this.$route.query.examType || 2; 473 this.examType = this.$route.query.examType || 2;
364 this.paperType = this.$route.query.paperType || 2; 474 this.paperType = this.$route.query.paperType || 2;
  475 + this.isViewer = this.$route.query.isViewer || false;
365 this.classId = this.$route.query.classId || -1; 476 this.classId = this.$route.query.classId || -1;
366 this.gradeName = this.$route.query.gradeName || ""; 477 this.gradeName = this.$route.query.gradeName || "";
  478 + this.subjectName = this.$route.query.subjectName || "";
367 this.form.title = this.$route.query.title || ""; 479 this.form.title = this.$route.query.title || "";
368 this._QueryDetail(); 480 this._QueryDetail();
369 this._GradeList(); 481 this._GradeList();
@@ -373,7 +485,7 @@ export default { @@ -373,7 +485,7 @@ export default {
373 this.classSharingType = false; 485 this.classSharingType = false;
374 }, 486 },
375 handleCheckAllChange(val) { 487 handleCheckAllChange(val) {
376 - this.checkedClass = val ? this.gradeClass : []; 488 + this.checkedClass = val ? this.gradeClass?.map(item => item.id) : [];
377 this.isIndeterminate = false; 489 this.isIndeterminate = false;
378 }, 490 },
379 handleCheckedClassChange(value) { 491 handleCheckedClassChange(value) {
@@ -382,13 +494,21 @@ export default { @@ -382,13 +494,21 @@ export default {
382 this.isIndeterminate = checkedCount > 0 && checkedCount < this.checkedClass.length; 494 this.isIndeterminate = checkedCount > 0 && checkedCount < this.checkedClass.length;
383 }, 495 },
384 async _selectClassSharingType() { 496 async _selectClassSharingType() {
  497 +
  498 + if (this.isViewer) return;
  499 +
  500 + this.gradeClass = [];
  501 +
385 this.classSharingType = true; 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 if (classResponse.status != 0) { 506 if (classResponse.status != 0) {
389 this.$message.error(classResponse.info); 507 this.$message.error(classResponse.info);
390 } 508 }
391 - this.gradeClass = classResponse.data; 509 +
  510 + this.gradeClass = [...classResponse.data];
  511 +
392 }, 512 },
393 // v1.5 513 // v1.5
394 //上传截图 514 //上传截图
@@ -403,7 +523,7 @@ export default { @@ -403,7 +523,7 @@ export default {
403 } 523 }
404 this.stem.screenshot = obj.screenshot || ""; 524 this.stem.screenshot = obj.screenshot || "";
405 this.stem.answerScreenshot = ""; 525 this.stem.answerScreenshot = "";
406 - return; 526 + // return;
407 } else if (type == 3) { 527 } else if (type == 3) {
408 } else if (type == 4) { 528 } else if (type == 4) {
409 var current = this.questionList[index].subQuestions[indexs]; 529 var current = this.questionList[index].subQuestions[indexs];
@@ -516,6 +636,16 @@ export default { @@ -516,6 +636,16 @@ export default {
516 } 636 }
517 return tit; 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 setBigNum(num) { 649 setBigNum(num) {
520 let txt = ""; 650 let txt = "";
521 let bigNum = [ 651 let bigNum = [
@@ -759,7 +889,6 @@ export default { @@ -759,7 +889,6 @@ export default {
759 }); 889 });
760 //更新答题卡 890 //更新答题卡
761 let modifyPaper, params; 891 let modifyPaper, params;
762 - console.log(this.type)  
763 if (this.type == 1) { 892 if (this.type == 1) {
764 modifyPaper = 893 modifyPaper =
765 this.role == "ROLE_PERSONAL" 894 this.role == "ROLE_PERSONAL"
@@ -796,7 +925,16 @@ export default { @@ -796,7 +925,16 @@ export default {
796 ...params, 925 ...params,
797 }); 926 });
798 if (status == 0) { 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 } else { 938 } else {
801 this.$message.error(message); 939 this.$message.error(message);
802 } 940 }
@@ -837,7 +975,7 @@ export default { @@ -837,7 +975,7 @@ export default {
837 ...this.form.paperModifyLog, 975 ...this.form.paperModifyLog,
838 }; 976 };
839 this.form = deepClone(data); 977 this.form = deepClone(data);
840 - console.log(this.form.sharingType) 978 +
841 questionList = this.form.questionList.map((item) => { 979 questionList = this.form.questionList.map((item) => {
842 if (item.subQuestions) { 980 if (item.subQuestions) {
843 item.subQuestions.map((subQuestion) => { 981 item.subQuestions.map((subQuestion) => {
@@ -855,13 +993,17 @@ export default { @@ -855,13 +993,17 @@ export default {
855 } 993 }
856 return item; 994 return item;
857 }); 995 });
  996 +
  997 +
858 } else { 998 } else {
859 questionList = data.list.sort((a, b) => { 999 questionList = data.list.sort((a, b) => {
860 return a.questionIndex - b.questionIndex; 1000 return a.questionIndex - b.questionIndex;
861 }); 1001 });
862 } 1002 }
863 this.questionList = questionList; 1003 this.questionList = questionList;
  1004 + console.log(this.questionList)
864 this.formateQuestion(); 1005 this.formateQuestion();
  1006 + this.checkedClass = data.classList?.map(item => item.classId);
865 } else { 1007 } else {
866 this.$message.error(info); 1008 this.$message.error(info);
867 } 1009 }
@@ -997,7 +1139,22 @@ export default { @@ -997,7 +1139,22 @@ export default {
997 }, 1139 },
998 }; 1140 };
999 </script> 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 .screenshot-box { 1158 .screenshot-box {
1002 width: 600px; 1159 width: 600px;
1003 } 1160 }
@@ -1019,7 +1176,7 @@ export default { @@ -1019,7 +1176,7 @@ export default {
1019 </style> 1176 </style>
1020 <style lang="scss" scoped> 1177 <style lang="scss" scoped>
1021 .content-fi { 1178 .content-fi {
1022 - padding-top: 7px; 1179 + padding-top: 12px;
1023 width: 200px; 1180 width: 200px;
1024 margin: 0px auto; 1181 margin: 0px auto;
1025 } 1182 }
@@ -1308,4 +1465,17 @@ export default { @@ -1308,4 +1465,17 @@ export default {
1308 .row-subfix { 1465 .row-subfix {
1309 margin-bottom: 10px; 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 </style> 1481 </style>
src/views/basic/card/index.vue
@@ -36,11 +36,11 @@ @@ -36,11 +36,11 @@
36 <el-option label="换班" :value="2"></el-option> 36 <el-option label="换班" :value="2"></el-option>
37 </el-select> 37 </el-select>
38 <div class="d1"> 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 value-format="yyyy-MM-dd"> 40 value-format="yyyy-MM-dd">
41 </el-date-picker> 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 value-format="yyyy-MM-dd"> 44 value-format="yyyy-MM-dd">
45 </el-date-picker> 45 </el-date-picker>
46 </div> 46 </div>
src/views/basic/dataSync/index.vue
@@ -162,7 +162,7 @@ export default { @@ -162,7 +162,7 @@ export default {
162 justify-content: center; 162 justify-content: center;
163 163
164 .down-item { 164 .down-item {
165 - width: 400px; 165 + width: 450px;
166 height: 330px; 166 height: 330px;
167 border-radius: 20px; 167 border-radius: 20px;
168 margin: 20px; 168 margin: 20px;
src/views/basic/device/index.vue
@@ -1457,7 +1457,7 @@ export default { @@ -1457,7 +1457,7 @@ export default {
1457 align-items: center; 1457 align-items: center;
1458 1458
1459 .p1 { 1459 .p1 {
1460 - font-size: 28px; 1460 + font-size: 28px !important;
1461 } 1461 }
1462 } 1462 }
1463 1463
@@ -1473,7 +1473,7 @@ export default { @@ -1473,7 +1473,7 @@ export default {
1473 .loading { 1473 .loading {
1474 text-align: center; 1474 text-align: center;
1475 line-height: 36px; 1475 line-height: 36px;
1476 - font-size: 16px; 1476 + font-size: 16px !important;
1477 color: #666; 1477 color: #666;
1478 } 1478 }
1479 1479
src/views/basic/down/index.vue
@@ -31,8 +31,7 @@ @@ -31,8 +31,7 @@
31 <el-button plan round @click="downCard">发卡软件下载</el-button> 31 <el-button plan round @click="downCard">发卡软件下载</el-button>
32 </div> 32 </div>
33 <div class="down-item" v-loading="loading"> 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 4.5.2,以便于授课端可正常使用。 35 4.5.2,以便于授课端可正常使用。
37 </p> 36 </p>
38 <el-button plan round @click="downNet">.Net环境下载</el-button> 37 <el-button plan round @click="downNet">.Net环境下载</el-button>
@@ -140,7 +139,7 @@ export default { @@ -140,7 +139,7 @@ export default {
140 margin-left: 160px; 139 margin-left: 160px;
141 140
142 .down-item { 141 .down-item {
143 - width: 200px; 142 + width: 300px;
144 padding: 50px 20px; 143 padding: 50px 20px;
145 border-radius: 20px; 144 border-radius: 20px;
146 margin: 20px; 145 margin: 20px;
@@ -149,8 +148,7 @@ export default { @@ -149,8 +148,7 @@ export default {
149 justify-content: center; 148 justify-content: center;
150 align-items: center; 149 align-items: center;
151 background: #f8f8f8; 150 background: #f8f8f8;
152 - box-shadow: 2px 2px 5px #ccc;  
153 - 151 + box-shadow: 2px 2px 5px #ccc;
154 .txt { 152 .txt {
155 font-size: 16px; 153 font-size: 16px;
156 color: #7f7f7f; 154 color: #7f7f7f;
src/views/basic/setUp/archived.vue
@@ -7,90 +7,108 @@ @@ -7,90 +7,108 @@
7 </back-box> 7 </back-box>
8 <div class="page-content"> 8 <div class="page-content">
9 <el-steps :active="step" align-center class="step"> 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 <el-step title="3 分班后任课老师"></el-step> 12 <el-step title="3 分班后任课老师"></el-step>
13 - <el-step title="4 授课端指引"></el-step>  
14 </el-steps> 13 </el-steps>
15 <ul v-loading="loading"> 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 </div> 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 </el-popconfirm> 59 </el-popconfirm>
51 </div> 60 </div>
52 </li> 61 </li>
53 <li v-show="step == 1"> 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 <p class="down-txt" slot="down"> 82 <p class="down-txt" slot="down">
57 - 通过Excel名单导入学生名单模板,点击  
58 - <el-link type="primary" @click="downStudentExcel">导出未分配学生</el-link>  
59 - 。 83 + 通过Excel名单导入学生名单模板
60 </p> 84 </p>
61 </upload> 85 </upload>
62 - </div> 86 + </el-row>
63 </li> 87 </li>
64 <li v-show="step == 2"> 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 <p class="down-txt" slot="down"> 101 <p class="down-txt" slot="down">
68 - 通过Excel名单导入任课老师名单模板,点击  
69 - <el-link type="primary" @click="downTeacherExcel">导出未分配教师</el-link>。 102 + 通过Excel名单导入任课老师名单模板
70 </p> 103 </p>
71 </upload> 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 </li> 106 </li>
88 -  
89 <li v-show="step != 0"> 107 <li v-show="step != 0">
90 <div class="btn-box"> 108 <div class="btn-box">
91 <el-button class="btn" round @click="step -= 1">上一步</el-button> 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 </div> 112 </div>
95 </li> 113 </li>
96 </ul> 114 </ul>
@@ -109,31 +127,67 @@ export default { @@ -109,31 +127,67 @@ export default {
109 step: 0, 127 step: 0,
110 grade: "", 128 grade: "",
111 gradeList: [], 129 gradeList: [],
112 - classIds: [], 130 + checkAll: false,
  131 + checkedClass: [],
113 classList: [], 132 classList: [],
114 urlClazz: "/api_html/school/manager/importClassAndStudent", 133 urlClazz: "/api_html/school/manager/importClassAndStudent",
115 urlTeacher: "/api_html/school/manager/importTeacher", 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 created() { 144 created() {
121 this._QueryDataGrade(); 145 this._QueryDataGrade();
122 }, 146 },
123 methods: { 147 methods: {
  148 + async _downNameList() {
  149 + this.loadingDown = true;
  150 + await this.downStudentExcel();
  151 + await this.downTeacherExcel();
  152 + this.loadingDown = false;
  153 + },
124 handleCheckAllChange(val) { 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 toClazz() { 192 toClazz() {
139 this.$router.push({ 193 this.$router.push({
@@ -166,41 +220,53 @@ export default { @@ -166,41 +220,53 @@ export default {
166 }, 220 },
167 //导出学生名单 221 //导出学生名单
168 async downStudentExcel() { 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 if (data) { 228 if (data) {
173 let blob = new Blob([data], { 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 } else { 233 } else {
178 this.$message.error("下载失败"); 234 this.$message.error("下载失败");
179 } 235 }
180 }, 236 },
181 //导出任课老师名单 237 //导出任课老师名单
182 async downTeacherExcel() { 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 if (data) { 242 if (data) {
187 let blob = new Blob([data], { 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 } else { 247 } else {
192 this.$message.error("下载失败"); 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 async _ClassArchiving() { 262 async _ClassArchiving() {
197 - if (!this.classIds.length) { 263 + if (!this.checkedClass.length) {
198 this.$message.warning("班级不能为空,请选择班级~"); 264 this.$message.warning("班级不能为空,请选择班级~");
199 return; 265 return;
200 } 266 }
201 this.loading = true; 267 this.loading = true;
202 const { status, info } = await this.$request.classArchiving({ 268 const { status, info } = await this.$request.classArchiving({
203 - classIds: [...this.classIds], 269 + classIds: [...this.checkedClass],
204 }); 270 });
205 this.loading = false; 271 this.loading = false;
206 if (status === 0) { 272 if (status === 0) {
@@ -234,14 +300,12 @@ export default { @@ -234,14 +300,12 @@ export default {
234 this.loadingClass = true; 300 this.loadingClass = true;
235 const { data, status, info } = await this.$request.schoolClassList({ 301 const { data, status, info } = await this.$request.schoolClassList({
236 grade: this.grade, 302 grade: this.grade,
  303 + type: 0
237 }); 304 });
238 this.loadingClass = false; 305 this.loadingClass = false;
239 if (status === 0) { 306 if (status === 0) {
240 this.classList = (data.list && [...data.list]) || []; 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 } else { 309 } else {
246 this.$message.error(info); 310 this.$message.error(info);
247 } 311 }
src/views/basic/setUp/clazz.vue
@@ -6,37 +6,14 @@ @@ -6,37 +6,14 @@
6 </template> 6 </template>
7 <template slot="btns" v-if="!code"> 7 <template slot="btns" v-if="!code">
8 <el-tooltip effect="dark" content="导入班级名单" placement="bottom"> 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 </el-tooltip> 10 </el-tooltip>
18 <el-tooltip effect="dark" content="导出班级名单" placement="bottom"> 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 </el-tooltip> 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 </el-tooltip> 17 </el-tooltip>
41 </template> 18 </template>
42 </back-box> 19 </back-box>
@@ -45,42 +22,23 @@ @@ -45,42 +22,23 @@
45 <p class="tab-box"> 22 <p class="tab-box">
46 <el-radio-group v-model="type" @change="_QueryData"> 23 <el-radio-group v-model="type" @change="_QueryData">
47 <el-radio-button :label="0">行政班</el-radio-button> 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 </el-radio-group> 26 </el-radio-group>
50 </p> 27 </p>
51 <div class="grade-item" v-for="(item, index) in dataList"> 28 <div class="grade-item" v-for="(item, index) in dataList">
52 <p class="h-title"> 29 <p class="h-title">
53 <span>{{ item.gradeName }}</span> 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 <span class="txt" v-if="index == 0">拖动班级进行排序</span> 34 <span class="txt" v-if="index == 0">拖动班级进行排序</span>
67 </p> 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 <li class="clazz-li" v-for="clazz in item.classList" :key="item.id"> 39 <li class="clazz-li" v-for="clazz in item.classList" :key="item.id">
79 <div class="clazz-item"> 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 <p class="clazz-name ellipsis"> 42 <p class="clazz-name ellipsis">
85 {{ clazz.className }} 43 {{ clazz.className }}
86 </p> 44 </p>
@@ -94,34 +52,48 @@ @@ -94,34 +52,48 @@
94 </div> 52 </div>
95 </div> 53 </div>
96 </div> 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 <div class="dialog-footer" slot="footer"> 91 <div class="dialog-footer" slot="footer">
110 <el-button @click="diaUp = false">取 消</el-button> 92 <el-button @click="diaUp = false">取 消</el-button>
111 </div> 93 </div>
112 </el-dialog> 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 <el-form-item label="所在年级:"> 97 <el-form-item label="所在年级:">
126 <span>{{ formClass.gradeName }}</span> 98 <span>{{ formClass.gradeName }}</span>
127 </el-form-item> 99 </el-form-item>
@@ -140,20 +112,14 @@ @@ -140,20 +112,14 @@
140 </el-form-item> 112 </el-form-item>
141 <el-form-item label="入学年份:"> 113 <el-form-item label="入学年份:">
142 <el-col :span="10"> 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 </el-date-picker> 116 </el-date-picker>
149 </el-col> 117 </el-col>
150 </el-form-item> 118 </el-form-item>
151 </el-form> 119 </el-form>
152 <div class="dialog-footer" slot="footer"> 120 <div class="dialog-footer" slot="footer">
153 <el-popconfirm title="确定删除该班级吗?" @confirm="_RemoveClass"> 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 </el-popconfirm> 123 </el-popconfirm>
158 <el-button @click="_SaveClass" type="primary">确 定</el-button> 124 <el-button @click="_SaveClass" type="primary">确 定</el-button>
159 <el-button @click="diaClass = false">取 消</el-button> 125 <el-button @click="diaClass = false">取 消</el-button>
@@ -163,11 +129,7 @@ @@ -163,11 +129,7 @@
163 </el-popconfirm> --> 129 </el-popconfirm> -->
164 </div> 130 </div>
165 </el-dialog> 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 <p slot="title" class="dia-tit"> 133 <p slot="title" class="dia-tit">
172 {{ formClass.gradeName }} 134 {{ formClass.gradeName }}
173 <span class="tips">(默认科目和已经有任课老师的科目不能删除)</span> 135 <span class="tips">(默认科目和已经有任课老师的科目不能删除)</span>
@@ -176,54 +138,25 @@ @@ -176,54 +138,25 @@
176 <el-form-item label="科目:"> 138 <el-form-item label="科目:">
177 <div class="subject-box"> 139 <div class="subject-box">
178 <el-checkbox-group v-model="subjectNames"> 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 <el-checkbox v-if="!item.checked" :label="item.value">{{ 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 <!-- <i 148 <!-- <i
204 class="el-icon el-icon-close" 149 class="el-icon el-icon-close"
205 v-show="item.checked" 150 v-show="item.checked"
206 @click="resetSub(item)" 151 @click="resetSub(item)"
207 ></i> --> 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 </p> 154 </p>
214 </el-checkbox-group> 155 </el-checkbox-group>
215 </div> 156 </div>
216 <el-col :span="8"> 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 </el-input> 160 </el-input>
228 </el-col> 161 </el-col>
229 </el-form-item> 162 </el-form-item>
@@ -255,6 +188,7 @@ export default { @@ -255,6 +188,7 @@ export default {
255 }, 188 },
256 data() { 189 data() {
257 return { 190 return {
  191 + hasTeachingClass: false,
258 code: "", 192 code: "",
259 loading: false, 193 loading: false,
260 loadingDown: false, 194 loadingDown: false,
@@ -355,6 +289,18 @@ export default { @@ -355,6 +289,18 @@ export default {
355 : ""; 289 : "";
356 this.diaClass = true; 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 async _RemoveClass() { 304 async _RemoveClass() {
359 const { data, status, info } = await this.$request.deleteClass({ 305 const { data, status, info } = await this.$request.deleteClass({
360 id: this.formClass.classId, 306 id: this.formClass.classId,
@@ -485,7 +431,22 @@ export default { @@ -485,7 +431,22 @@ export default {
485 } 431 }
486 }, 432 },
487 async _QueryData() { 433 async _QueryData() {
  434 +
488 this.loading = true; 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 this.dataList = []; 450 this.dataList = [];
490 let { data, status, info } = await this.$request.classManager({ 451 let { data, status, info } = await this.$request.classManager({
491 type: this.type, 452 type: this.type,
@@ -691,7 +652,7 @@ export default { @@ -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 display: none; 656 display: none;
696 } 657 }
697 } 658 }
src/views/basic/test/components/scoreSet.vue
@@ -8,51 +8,19 @@ @@ -8,51 +8,19 @@
8 </div> 8 </div>
9 <div class="set-content"> 9 <div class="set-content">
10 <div class="test-title"> 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 <p class="p1">{{ title }}</p> 13 <p class="p1">{{ title }}</p>
23 <p class="p2">卷面总分:{{ examScore }}分</p> 14 <p class="p2">卷面总分:{{ examScore }}分</p>
24 </div> 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 <template v-else>{{ scoped.row.all }}</template> 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 <!-- <el-input 24 <!-- <el-input
57 v-if="scoped.row.showSetScore" 25 v-if="scoped.row.showSetScore"
58 type="number" 26 type="number"
@@ -61,8 +29,7 @@ @@ -61,8 +29,7 @@
61 @input="setOtherScore($event, scoped.row)" 29 @input="setOtherScore($event, scoped.row)"
62 ></el-input> --> 30 ></el-input> -->
63 <template>{{ scoped.row.object }}</template> 31 <template>{{ scoped.row.object }}</template>
64 - </template></el-table-column  
65 - > 32 + </template></el-table-column>
66 <el-table-column prop="subjectiveScore" label="主观题分" align="center"> 33 <el-table-column prop="subjectiveScore" label="主观题分" align="center">
67 <template slot-scope="scoped"> 34 <template slot-scope="scoped">
68 <!-- <el-input 35 <!-- <el-input
@@ -76,56 +43,29 @@ @@ -76,56 +43,29 @@
76 </template> 43 </template>
77 </el-table-column> 44 </el-table-column>
78 <!-- <el-table-column v-for="(item, index) in questionList" :key="index" :label="'第' + cNum[index] + '大题'" --> 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 <template slot-scope="scoped"> 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 </template> 58 </template>
106 </el-table-column> 59 </el-table-column>
107 </el-table> 60 </el-table>
108 </div> 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 <template slot="down"> 66 <template slot="down">
126 <p class="down-txt"> 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 </p> 69 </p>
130 <p class="down-txt">第二步:上传完成编辑的模板文件并导入。</p> 70 <p class="down-txt">第二步:上传完成编辑的模板文件并导入。</p>
131 </template> 71 </template>
@@ -160,8 +100,11 @@ export default { @@ -160,8 +100,11 @@ export default {
160 url: "/api_html/teaching/importScore", 100 url: "/api_html/teaching/importScore",
161 tableData: [], 101 tableData: [],
162 questionList: [], 102 questionList: [],
  103 + dataReponse: [],
  104 + tableDataIndex: 0,
163 cNum: cNum, 105 cNum: cNum,
164 tableMaxHeight: 300, 106 tableMaxHeight: 300,
  107 + studentList: [],
165 }; 108 };
166 }, 109 },
167 watch: { 110 watch: {
@@ -209,7 +152,7 @@ export default { @@ -209,7 +152,7 @@ export default {
209 if (obj.scoreMap[keys] == 0) { 152 if (obj.scoreMap[keys] == 0) {
210 obj.scoreMap[keys] = 0; 153 obj.scoreMap[keys] = 0;
211 } else { 154 } else {
212 - obj.scoreMap[keys] = ""; 155 + obj.scoreMap[keys] = 0;
213 } 156 }
214 } else { 157 } else {
215 let num = Number(obj.scoreMap[keys]); 158 let num = Number(obj.scoreMap[keys]);
@@ -238,8 +181,9 @@ export default { @@ -238,8 +181,9 @@ export default {
238 }); 181 });
239 this.loading = false; 182 this.loading = false;
240 if (status === 0) { 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 if (this.questionList.length == 0) { 187 if (this.questionList.length == 0) {
244 this.questionList = Object.keys(studentList[0].scoreMap).map( 188 this.questionList = Object.keys(studentList[0].scoreMap).map(
245 (item) => { 189 (item) => {
@@ -269,7 +213,6 @@ export default { @@ -269,7 +213,6 @@ export default {
269 item.scoreMap[keys] = num; 213 item.scoreMap[keys] = num;
270 } 214 }
271 }); 215 });
272 -  
273 return item; 216 return item;
274 }) || []; 217 }) || [];
275 this.setTableHeight(); 218 this.setTableHeight();
@@ -310,10 +253,68 @@ export default { @@ -310,10 +253,68 @@ export default {
310 253
311 //导入成功 254 //导入成功
312 upSuccess(res) { 255 upSuccess(res) {
  256 +
313 this.$message.success("导入成功"); 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 this.diaUp = false; 317 this.diaUp = false;
315 - // this.closeScoreSet();  
316 - this.$emit("SuccessScoreSet");  
317 }, 318 },
318 async downExcel() { 319 async downExcel() {
319 //模板下载 320 //模板下载
@@ -338,10 +339,10 @@ export default { @@ -338,10 +339,10 @@ export default {
338 <style lang="scss" scoped> 339 <style lang="scss" scoped>
339 .set-container { 340 .set-container {
340 position: fixed; 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 background: #fff; 346 background: #fff;
346 z-index: 2000; 347 z-index: 2000;
347 overflow-y: auto; 348 overflow-y: auto;
src/views/examinationPaper/add.vue
@@ -3,10 +3,40 @@ @@ -3,10 +3,40 @@
3 <div ref="content" class="content-box"> 3 <div ref="content" class="content-box">
4 <back-box> 4 <back-box>
5 <template slot="title"> 5 <template slot="title">
6 - <span>{{ "创建答题卡" }}</span> 6 + <span>{{ isUpload ? "导入试卷" : "创建答题卡" }}</span>
7 </template> 7 </template>
8 </back-box> 8 </back-box>
9 <div class="content"> 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 <el-steps :active="step" finish-status="success" simple style="margin: 20px 0"> 40 <el-steps :active="step" finish-status="success" simple style="margin: 20px 0">
11 <el-step title="基础信息" icon="el-icon-edit"></el-step> 41 <el-step title="基础信息" icon="el-icon-edit"></el-step>
12 <el-step v-if="!isUpload" title="题目编辑" icon="el-icon-tickets"></el-step> 42 <el-step v-if="!isUpload" title="题目编辑" icon="el-icon-tickets"></el-step>
@@ -49,7 +79,8 @@ @@ -49,7 +79,8 @@
49 <el-form-item v-if="role != 'ROLE_PERSONAL'" label="分享范围:" prop="sharingType"> 79 <el-form-item v-if="role != 'ROLE_PERSONAL'" label="分享范围:" prop="sharingType">
50 <el-radio-group v-model="form.sharingType"> 80 <el-radio-group v-model="form.sharingType">
51 <el-radio :label="0">任课班级分享</el-radio> 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 </el-radio-group> 84 </el-radio-group>
54 </el-form-item> 85 </el-form-item>
55 </el-form> 86 </el-form>
@@ -57,7 +88,8 @@ @@ -57,7 +88,8 @@
57 <el-button type="danger" plain round @click="linkBack">取消</el-button> 88 <el-button type="danger" plain round @click="linkBack">取消</el-button>
58 <el-button type="primary" round @click="isUpload ? setStep2() : setStep1()">下一步</el-button> 89 <el-button type="primary" round @click="isUpload ? setStep2() : setStep1()">下一步</el-button>
59 </div> 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 <div class="dia-content"> 93 <div class="dia-content">
62 <p class="add-type" v-for="item in tagList" :key="item.id"> 94 <p class="add-type" v-for="item in tagList" :key="item.id">
63 <el-row :gutter="10"> 95 <el-row :gutter="10">
@@ -217,7 +249,8 @@ @@ -217,7 +249,8 @@
217 <el-button :type="form.questionList.length == 0 ? 'info' : 'primary'" round 249 <el-button :type="form.questionList.length == 0 ? 'info' : 'primary'" round
218 @click="setStep2">下一步</el-button> 250 @click="setStep2">下一步</el-button>
219 </div> 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 <div class="dia-content"> 254 <div class="dia-content">
222 <el-form ref="form" :model="questionForm" :rules="questionFormRules" label-width="100px"> 255 <el-form ref="form" :model="questionForm" :rules="questionFormRules" label-width="100px">
223 <el-form-item label="标题:"> 256 <el-form-item label="标题:">
@@ -514,7 +547,7 @@ @@ -514,7 +547,7 @@
514 </div> 547 </div>
515 </div> 548 </div>
516 <el-dialog :close-on-click-modal="false" :title="stem.type == 1 ? '上传题干' : '上传题目解析'" :visible.sync="dialogStem" 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 <div class="upload-box"> 551 <div class="upload-box">
519 <div v-loading="iframeLoading"> 552 <div v-loading="iframeLoading">
520 <template v-if="stem.type == 1"> 553 <template v-if="stem.type == 1">
@@ -535,7 +568,8 @@ @@ -535,7 +568,8 @@
535 <el-button @click="dialogStem = false">确定</el-button> 568 <el-button @click="dialogStem = false">确定</el-button>
536 </div> 569 </div>
537 </el-dialog> 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 <div> 573 <div>
540 <el-form ref="form" :model="stem" label-width="160px"> 574 <el-form ref="form" :model="stem" label-width="160px">
541 <el-form-item label="知识点:"> 575 <el-form-item label="知识点:">
@@ -620,6 +654,13 @@ export default { @@ -620,6 +654,13 @@ export default {
620 }, 654 },
621 data() { 655 data() {
622 return { 656 return {
  657 + shareClass: [],
  658 + role: "",
  659 + checkedClass: [],
  660 + classSharingType: false,
  661 + gradeName: "",
  662 + isIndeterminate: false,
  663 + checkAll: false,
623 role: "", 664 role: "",
624 step: 0, //步骤 665 step: 0, //步骤
625 gradeClassList: [], //年级-班级数据 666 gradeClassList: [], //年级-班级数据
@@ -744,6 +785,18 @@ export default { @@ -744,6 +785,18 @@ export default {
744 } 785 }
745 }, 786 },
746 methods: { 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 // v1.5 800 // v1.5
748 //上传截图 801 //上传截图
749 openStem(obj, index, indexs, type) { 802 openStem(obj, index, indexs, type) {
@@ -825,13 +878,25 @@ export default { @@ -825,13 +878,25 @@ export default {
825 ) 878 )
826 .then(() => { }) 879 .then(() => { })
827 .catch(() => { 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,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 openQuestion() { 1269 openQuestion() {
1187 this.questionForm = { ...questionForm }; 1270 this.questionForm = { ...questionForm };
1188 this.addQuestionVisible = true; 1271 this.addQuestionVisible = true;
@@ -1437,16 +1520,28 @@ export default { @@ -1437,16 +1520,28 @@ export default {
1437 }, 1520 },
1438 async save() { 1521 async save() {
1439 if (this.saveLoading) return; 1522 if (this.saveLoading) return;
  1523 +
1440 this.saveLoading = true; 1524 this.saveLoading = true;
  1525 +
1441 this.formatQuestionList(); 1526 this.formatQuestionList();
  1527 +
1442 let formDatas = deepClone(this.form); 1528 let formDatas = deepClone(this.form);
  1529 +
  1530 + formDatas.questionList = formDatas.questionList.filter(item => {
  1531 + return item.subQuestions?.length >= 1;
  1532 + });
  1533 +
1443 for (let i = 0; i < formDatas.questionList.length; i++) { 1534 for (let i = 0; i < formDatas.questionList.length; i++) {
1444 delete formDatas.questionList[i].show; 1535 delete formDatas.questionList[i].show;
1445 } 1536 }
  1537 +
1446 let addPaper = 1538 let addPaper =
1447 this.role == "ROLE_PERSONAL" 1539 this.role == "ROLE_PERSONAL"
1448 ? this.$request.pAddPaper 1540 ? this.$request.pAddPaper
1449 : this.$request.addPaper; 1541 : this.$request.addPaper;
  1542 +
  1543 + formDatas.classIds = this.checkedClass.join(",");
  1544 +
1450 const { data, status, info } = await addPaper({ 1545 const { data, status, info } = await addPaper({
1451 ...formDatas, 1546 ...formDatas,
1452 }); 1547 });
src/views/examinationPaper/addQs.vue
@@ -7,6 +7,37 @@ @@ -7,6 +7,37 @@
7 </template> 7 </template>
8 </back-box> 8 </back-box>
9 <div class="content"> 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 <el-steps :active="step" finish-status="success" simple style="margin: 20px 0"> 41 <el-steps :active="step" finish-status="success" simple style="margin: 20px 0">
11 <el-step title="基础信息" icon="el-icon-edit"></el-step> 42 <el-step title="基础信息" icon="el-icon-edit"></el-step>
12 <el-step title="题目编辑" icon="el-icon-tickets"></el-step> 43 <el-step title="题目编辑" icon="el-icon-tickets"></el-step>
@@ -36,7 +67,8 @@ @@ -36,7 +67,8 @@
36 <el-form-item v-if="role != 'ROLE_PERSONAL'" label="分享范围:" prop="sharingType"> 67 <el-form-item v-if="role != 'ROLE_PERSONAL'" label="分享范围:" prop="sharingType">
37 <el-radio-group v-model="form.sharingType"> 68 <el-radio-group v-model="form.sharingType">
38 <el-radio :label="0">任课班级分享</el-radio> 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 </el-radio-group> 72 </el-radio-group>
41 </el-form-item> 73 </el-form-item>
42 </el-form> 74 </el-form>
@@ -59,7 +91,7 @@ @@ -59,7 +91,7 @@
59 <div class="qs-options qs-options2">选项设置</div> 91 <div class="qs-options qs-options2">选项设置</div>
60 <div class="qs-upload">题干</div> 92 <div class="qs-upload">题干</div>
61 <div class="qs-upload">题目解析</div> 93 <div class="qs-upload">题目解析</div>
62 - <div class="qs-upload" v-if="knowledgeData.length">知识点</div> 94 + <div class="qs-upload" >知识点</div>
63 <div class="qs-set">操作</div> 95 <div class="qs-set">操作</div>
64 </li> 96 </li>
65 </ul> 97 </ul>
@@ -99,8 +131,8 @@ @@ -99,8 +131,8 @@
99 </p> 131 </p>
100 <p v-if="question.questionType == 3" class="answer-box"> 132 <p v-if="question.questionType == 3" class="answer-box">
101 <span class="answer-s" v-for="option in question.answerOptions?.split(',')" :class="question.correctAnswer?.includes(option) 133 <span class="answer-s" v-for="option in question.answerOptions?.split(',')" :class="question.correctAnswer?.includes(option)
102 - ? 'active'  
103 - : '' 134 + ? 'active'
  135 + : ''
104 " :key="option" @click="changAnswer(question, option)">{{ option }}</span> 136 " :key="option" @click="changAnswer(question, option)">{{ option }}</span>
105 </p> 137 </p>
106 <p v-if="question.questionType == 2" class="answer-box"> 138 <p v-if="question.questionType == 2" class="answer-box">
@@ -125,7 +157,7 @@ @@ -125,7 +157,7 @@
125 <el-button class="icon-tickets" type="primary" circle size="mini" icon="el-icon-tickets" 157 <el-button class="icon-tickets" type="primary" circle size="mini" icon="el-icon-tickets"
126 @click="openStem(question, 2, index)"></el-button> 158 @click="openStem(question, 2, index)"></el-button>
127 </div> 159 </div>
128 - <div class="qs-upload" v-if="knowledgeData.length"> 160 + <div class="qs-upload" >
129 <el-button type="primary" circle size="mini" icon="el-icon-price-tag" 161 <el-button type="primary" circle size="mini" icon="el-icon-price-tag"
130 @click="openKnowledge(question, index)"></el-button> 162 @click="openKnowledge(question, index)"></el-button>
131 </div> 163 </div>
@@ -179,8 +211,8 @@ @@ -179,8 +211,8 @@
179 <span class="answer-s" v-for="option in subQuestions.answerOptions?.split( 211 <span class="answer-s" v-for="option in subQuestions.answerOptions?.split(
180 ',' 212 ','
181 )" :class="subQuestions.correctAnswer?.includes(option) 213 )" :class="subQuestions.correctAnswer?.includes(option)
182 - ? 'active'  
183 - : '' 214 + ? 'active'
  215 + : ''
184 " :key="option" @click="changAnswer(subQuestions, option)">{{ option }}</span> 216 " :key="option" @click="changAnswer(subQuestions, option)">{{ option }}</span>
185 </p> 217 </p>
186 <p v-if="subQuestions.questionType == 2" class="answer-box"> 218 <p v-if="subQuestions.questionType == 2" class="answer-box">
@@ -206,17 +238,8 @@ @@ -206,17 +238,8 @@
206 <div class="qs-upload"> 238 <div class="qs-upload">
207 <el-button class="icon-tickets" type="primary" circle size="mini" icon="el-icon-tickets" 239 <el-button class="icon-tickets" type="primary" circle size="mini" icon="el-icon-tickets"
208 @click="openStem(subQuestions, 2, index, indexs)"></el-button> 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 <el-button type="primary" circle size="mini" icon="el-icon-price-tag" 243 <el-button type="primary" circle size="mini" icon="el-icon-price-tag"
221 @click="openKnowledge(subQuestions, index, indexs)"></el-button> 244 @click="openKnowledge(subQuestions, index, indexs)"></el-button>
222 </div> 245 </div>
@@ -233,7 +256,7 @@ @@ -233,7 +256,7 @@
233 </template> 256 </template>
234 </div> 257 </div>
235 <el-dialog :close-on-click-modal="false" title="批量设置答案" :visible.sync="diaSetAns" width="400" 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 <div class="qs-options"> 260 <div class="qs-options">
238 <p class="dia-tips"> 261 <p class="dia-tips">
239 请点击选项按钮设置答案,多选题题目之间用“,”隔开,若添加5道题:“AC,AD,BD,AC,CD” 262 请点击选项按钮设置答案,多选题题目之间用“,”隔开,若添加5道题:“AC,AD,BD,AC,CD”
@@ -284,8 +307,8 @@ @@ -284,8 +307,8 @@
284 <el-button round @click="step = 0">上一步</el-button> 307 <el-button round @click="step = 0">上一步</el-button>
285 <el-button type="primary" round @click="toStep(2)">下一步</el-button> 308 <el-button type="primary" round @click="toStep(2)">下一步</el-button>
286 </div> 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 <div class="upload-box"> 312 <div class="upload-box">
290 <div v-loading="iframeLoading"> 313 <div v-loading="iframeLoading">
291 <template v-if="stem.type == 1"> 314 <template v-if="stem.type == 1">
@@ -306,14 +329,10 @@ @@ -306,14 +329,10 @@
306 <el-button @click="dialogStem = false">保存</el-button> 329 <el-button @click="dialogStem = false">保存</el-button>
307 </div> 330 </div>
308 </el-dialog> 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 <div> 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 </div> 336 </div>
318 <div slot="footer"> 337 <div slot="footer">
319 <el-button @click="dialogKnowledge = false">取 消</el-button> 338 <el-button @click="dialogKnowledge = false">取 消</el-button>
@@ -354,10 +373,20 @@ @@ -354,10 +373,20 @@
354 <script> 373 <script>
355 import { deepClone, checkAnswer } from "utils"; 374 import { deepClone, checkAnswer } from "utils";
356 import knowledgeList from "assets/js/knowledgeList.js"; 375 import knowledgeList from "assets/js/knowledgeList.js";
  376 +import knowledgePoints from "@/components/knowledgePoints"
357 export default { 377 export default {
  378 + components: {
  379 + knowledgePoints
  380 + },
358 data() { 381 data() {
359 return { 382 return {
  383 + shareClass: [],
360 role: "", 384 role: "",
  385 + checkedClass: [],
  386 + classSharingType: false,
  387 + gradeName: "",
  388 + isIndeterminate: false,
  389 + checkAll: false,
361 step: 0, //步骤 390 step: 0, //步骤
362 gradeClassList: [], //年级-班级数据 391 gradeClassList: [], //年级-班级数据
363 gradeList: [], //年级 392 gradeList: [], //年级
@@ -405,6 +434,8 @@ export default { @@ -405,6 +434,8 @@ export default {
405 screenshot: "", //题干图片地址 434 screenshot: "", //题干图片地址
406 answerScreenshot: "", //题目解析图片地址 435 answerScreenshot: "", //题目解析图片地址
407 knowledge: [], //知识点 436 knowledge: [], //知识点
  437 + subjectName: "",
  438 + sectionName: "",
408 }, 439 },
409 type: 1, //1-创建,2-复制答题卡 440 type: 1, //1-创建,2-复制答题卡
410 questionOptions: [ 441 questionOptions: [
@@ -423,33 +454,33 @@ export default { @@ -423,33 +454,33 @@ export default {
423 subjectName: "", 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 watch: { 484 watch: {
454 step: function () { 485 step: function () {
455 this.$nextTick(function () { 486 this.$nextTick(function () {
@@ -488,6 +519,31 @@ export default { @@ -488,6 +519,31 @@ export default {
488 } 519 }
489 }, 520 },
490 methods: { 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 // v1.5 547 // v1.5
492 //上传截图 548 //上传截图
493 openStem(obj, type, index, indexs) { 549 openStem(obj, type, index, indexs) {
@@ -550,6 +606,16 @@ export default { @@ -550,6 +606,16 @@ export default {
550 this.stem.index = index; 606 this.stem.index = index;
551 this.stem.indexs = indexs; 607 this.stem.indexs = indexs;
552 this.stem.knowledge = (obj.knowledge && obj.knowledge.split("#")) || []; 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 this.dialogKnowledge = true; 619 this.dialogKnowledge = true;
554 }, 620 },
555 // 知识点 621 // 知识点
@@ -578,13 +644,25 @@ export default { @@ -578,13 +644,25 @@ export default {
578 ) 644 )
579 .then(() => { }) 645 .then(() => { })
580 .catch(() => { 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,6 +1103,13 @@ export default {
1025 this.saveLoading = true; 1103 this.saveLoading = true;
1026 this.formatQuestionList(); 1104 this.formatQuestionList();
1027 let formDatas = deepClone(this.form); 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 let addPaper = 1113 let addPaper =
1029 this.role == "ROLE_PERSONAL" 1114 this.role == "ROLE_PERSONAL"
1030 ? this.$request.pAddPaper 1115 ? this.$request.pAddPaper
@@ -1046,14 +1131,26 @@ export default { @@ -1046,14 +1131,26 @@ export default {
1046 }); 1131 });
1047 } 1132 }
1048 else { 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 } else { 1154 } else {
1058 this.$message.error(info); 1155 this.$message.error(info);
1059 } 1156 }
src/views/examinationPaper/index.vue
@@ -181,7 +181,7 @@ @@ -181,7 +181,7 @@
181 <script> 181 <script>
182 import { downloadFile } from "@/utils"; 182 import { downloadFile } from "@/utils";
183 import axios from "axios"; 183 import axios from "axios";
184 -import example from "@/assets/images/example.jpg"; 184 +import example from "@/assets/images/example.png";
185 import example2 from "@/assets/images/example2.png"; 185 import example2 from "@/assets/images/example2.png";
186 export default { 186 export default {
187 name: "examinationPaper", 187 name: "examinationPaper",
src/views/layout/header/header.vue
@@ -397,7 +397,7 @@ ul.el-menu { @@ -397,7 +397,7 @@ ul.el-menu {
397 justify-content: center; 397 justify-content: center;
398 margin: 0 5px; 398 margin: 0 5px;
399 p { 399 p {
400 - line-height: 16px; 400 + line-height: 20px;
401 font-size: 12px; 401 font-size: 12px;
402 } 402 }
403 } 403 }
src/views/login/index.vue
@@ -171,7 +171,7 @@ $cursor: #000; @@ -171,7 +171,7 @@ $cursor: #000;
171 } 171 }
172 .login-container { 172 .login-container {
173 width: 100%; 173 width: 100%;
174 - height: 100vh; 174 + height: 150vh;
175 background: url("../../assets/images/login-bg.png") no-repeat; 175 background: url("../../assets/images/login-bg.png") no-repeat;
176 background-size: cover; 176 background-size: cover;
177 overflow: hidden; 177 overflow: hidden;
@@ -215,8 +215,7 @@ $cursor: #000; @@ -215,8 +215,7 @@ $cursor: #000;
215 padding: 30px 35px 0; 215 padding: 30px 35px 0;
216 border-radius: 10px; 216 border-radius: 10px;
217 background: #fff; 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 box-sizing: border-box; 219 box-sizing: border-box;
221 } 220 }
222 221
vue.config.js
@@ -11,7 +11,7 @@ module.exports = { @@ -11,7 +11,7 @@ module.exports = {
11 lintOnSave: false, //是否开启编译时是否不符合eslint提示 11 lintOnSave: false, //是否开启编译时是否不符合eslint提示
12 productionSourceMap: false, // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。 12 productionSourceMap: false, // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
13 devServer: { 13 devServer: {
14 - hot:true, 14 + hot: true,
15 port: 8081, // 端口 15 port: 8081, // 端口
16 open: false, // 启动后打开浏览器 16 open: false, // 启动后打开浏览器
17 compress: true, 17 compress: true,
@@ -23,10 +23,11 @@ module.exports = { @@ -23,10 +23,11 @@ module.exports = {
23 proxy: { 23 proxy: {
24 "/": { 24 "/": {
25 // target:"http://ezquiz.sunvotecloud.cn", 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 changeOrigin: true, 29 changeOrigin: true,
29 - ws:true, 30 + ws: true,
30 }, 31 },
31 }, 32 },
32 disableHostCheck: true 33 disableHostCheck: true