Commit 9309dc5d890aab5ff73ff7df9be2945454fdec58

Authored by 梁保满
1 parent 225a00b6

任课老师接口完成

src/api/apis/apis.js
@@ -26,6 +26,233 @@ export default { @@ -26,6 +26,233 @@ export default {
26 data, 26 data,
27 }); 27 });
28 }, 28 },
  29 + // 班主任首页数据
  30 + classIndex(data) {
  31 + return service({
  32 + url: setUpUrls.classIndex,
  33 + method: "POST",
  34 + data,
  35 + });
  36 + },
  37 + //班主任-查询管理的班级
  38 + cTClassList(data) {
  39 + return service({
  40 + url: setUpUrls.cTClassList,
  41 + method: "POST",
  42 + data,
  43 + });
  44 + },
  45 + //班主任-查询管理班级授课科目
  46 + cTSubjectList(data) {
  47 + return service({
  48 + url: setUpUrls.cTSubjectList,
  49 + method: "POST",
  50 + data,
  51 + });
  52 + },
  53 + //班主任-查询阶段问答报表
  54 + cTPhaseAnswerReport(data) {
  55 + return service({
  56 + url: setUpUrls.cTPhaseAnswerReport,
  57 + method: "POST",
  58 + data,
  59 + });
  60 + },
  61 + //班主任-查询阶段互动报表
  62 + cTPhaseInteractiveReport(data) {
  63 + return service({
  64 + url: setUpUrls.cTPhaseInteractiveReport,
  65 + method: "POST",
  66 + data,
  67 + });
  68 + },
  69 + //班主任-查询阶段测练报表
  70 + cTPhaseExamReport(data) {
  71 + return service({
  72 + url: setUpUrls.cTPhaseExamReport,
  73 + method: "POST",
  74 + data,
  75 + });
  76 + },
  77 +
  78 + //任课老师-查询管理的班级
  79 + tClassList(data) {
  80 + return service({
  81 + url: setUpUrls.tClassList,
  82 + method: "POST",
  83 + data,
  84 + });
  85 + },
  86 + //任课老师-查询管理班级授课科目
  87 + tSubjectList(data) {
  88 + return service({
  89 + url: setUpUrls.tSubjectList,
  90 + method: "POST",
  91 + data,
  92 + });
  93 + },
  94 + //任课老师-分页查询课时报表列表
  95 + periodReportList(data) {
  96 + return service({
  97 + url: setUpUrls.periodReportList,
  98 + method: "POST",
  99 + data,
  100 + });
  101 + },
  102 + //任课老师-查询阶段问答报表
  103 + phaseAnswerReport(data) {
  104 + return service({
  105 + url: setUpUrls.phaseAnswerReport,
  106 + method: "POST",
  107 + data,
  108 + });
  109 + },
  110 + //任课老师-查询阶段互动报表
  111 + phaseInteractiveReport(data) {
  112 + return service({
  113 + url: setUpUrls.phaseInteractiveReport,
  114 + method: "POST",
  115 + data,
  116 + });
  117 + },
  118 + //任课老师-查询课时题目列表
  119 + periodQuestionList(data) {
  120 + return service({
  121 + url: setUpUrls.periodQuestionList,
  122 + method: "POST",
  123 + data,
  124 + });
  125 + },
  126 + //任课老师-设置课时报表答案
  127 + setPeriodAnswer(data) {
  128 + return service({
  129 + url: setUpUrls.setPeriodAnswer,
  130 + method: "POST",
  131 + data,
  132 + });
  133 + },
  134 + //任课老师-查询课时报表详情
  135 + periodDetail(data) {
  136 + return service({
  137 + url: setUpUrls.periodDetail,
  138 + method: "POST",
  139 + data,
  140 + });
  141 + },
  142 + //任课老师-分页查询课时题目统计列表
  143 + periodQuestionReport(data) {
  144 + return service({
  145 + url: setUpUrls.periodQuestionReport,
  146 + method: "POST",
  147 + data,
  148 + });
  149 + },
  150 + //任课老师-查询课时学生答题明细
  151 + periodStudentReport(data) {
  152 + return service({
  153 + url: setUpUrls.periodStudentReport,
  154 + method: "POST",
  155 + data,
  156 + });
  157 + },
  158 + //任课老师-分页查询即时测报表
  159 + examReportList(data) {
  160 + return service({
  161 + url: setUpUrls.examReportList,
  162 + method: "POST",
  163 + data,
  164 + });
  165 + },
  166 + //任课老师-查询阶段测练报表
  167 + phaseExamReport(data) {
  168 + return service({
  169 + url: setUpUrls.phaseExamReport,
  170 + method: "POST",
  171 + data,
  172 + });
  173 + },
  174 + //任课老师-查询即时测报表题目列表
  175 + examQuestionList(data) {
  176 + return service({
  177 + url: setUpUrls.examQuestionList,
  178 + method: "POST",
  179 + data,
  180 + });
  181 + },
  182 + //任课老师-设置即时测报表答案
  183 + setExamAnswer(data) {
  184 + return service({
  185 + url: setUpUrls.setExamAnswer,
  186 + method: "POST",
  187 + data,
  188 + });
  189 + },
  190 + //任课老师-查询即时测报表详情
  191 + examDetail(data) {
  192 + return service({
  193 + url: setUpUrls.examDetail,
  194 + method: "POST",
  195 + data,
  196 + });
  197 + },
  198 + //任课老师-下载导入主观题分模板
  199 + subjectiveScoreTemplate(data) {
  200 + return service({
  201 + url: setUpUrls.subjectiveScoreTemplate,
  202 + method: "POST",
  203 + data,
  204 + });
  205 + },
  206 + //任课老师-导入主观题得分
  207 + importSubjectiveScore(data) {
  208 + return service({
  209 + url: setUpUrls.importSubjectiveScore,
  210 + method: "POST",
  211 + data,
  212 + });
  213 + },
  214 + //任课老师-分页查询即时测题目统计
  215 + examQuestionReport(data) {
  216 + return service({
  217 + url: setUpUrls.examQuestionReport,
  218 + method: "POST",
  219 + data,
  220 + });
  221 + },
  222 + //任课老师-查询即时测学生统计
  223 + examStudentReport(data) {
  224 + return service({
  225 + url: setUpUrls.examStudentReport,
  226 + method: "POST",
  227 + data,
  228 + });
  229 + },
  230 + //任课老师-重新判分
  231 + reScore(data) {
  232 + return service({
  233 + url: setUpUrls.reScore,
  234 + method: "POST",
  235 + data,
  236 + });
  237 + },
  238 + //任课老师-数据导出
  239 + exportData(data) {
  240 + return service({
  241 + url: setUpUrls.exportData,
  242 + method: "POST",
  243 + data,
  244 + });
  245 + },
  246 + //任课老师-数据导入
  247 + importData(data) {
  248 + return service({
  249 + url: setUpUrls.importData,
  250 + method: "POST",
  251 + data,
  252 + });
  253 + },
  254 +
  255 +
29 // 查询角色列表 256 // 查询角色列表
30 roleList(data) { 257 roleList(data) {
31 return service({ 258 return service({
src/api/urls/apis.js
@@ -6,6 +6,68 @@ export default { @@ -6,6 +6,68 @@ export default {
6 schoolIndex: "/api_html/school/manager/index", 6 schoolIndex: "/api_html/school/manager/index",
7 // 学校管理员首页数据 7 // 学校管理员首页数据
8 tenantIndex: "/api_html/tenant/index", 8 tenantIndex: "/api_html/tenant/index",
  9 + // 班主任首页数据
  10 + classIndex: "/api_html/class/manager/index",
  11 + //班主任-查询管理的班级
  12 + cTClassList: "/api_html/class/manager/classList",
  13 + //班主任-查询管理班级授课科目
  14 + cTSubjectList: "/api_html/class/manager/subjectList",
  15 + //班主任-查询阶段问答报表
  16 + cTPhaseAnswerReport: "/api_html/class/manager/phaseAnswerReport",
  17 + //班主任-查询阶段互动报表
  18 + cTPhaseInteractiveReport: "/api_html/class/manager/phaseInteractiveReport",
  19 + //班主任-查询阶段测练报表
  20 + cTPhaseExamReport: "/api_html/class/manager/phaseExamReport",
  21 +
  22 + //任课老师-查询管理班级
  23 + tClassList: "/api_html/teaching/classList",
  24 + //任课老师-查询管理班级授课科目
  25 + tSubjectList: "/api_html/teaching/subjectList",
  26 + //任课老师-分页查询课时报表列表
  27 + periodReportList: "/api_html/teaching/periodReportList",
  28 + //任课老师-查询阶段问答报表
  29 + phaseAnswerReport: "/api_html/teaching/phaseAnswerReport",
  30 + //任课老师-查询阶段互动报表
  31 + phaseInteractiveReport: "/api_html/teaching/phaseInteractiveReport",
  32 + //任课老师-查询课时题目列表
  33 + periodQuestionList: "/api_html/teaching/periodQuestionList",
  34 + //任课老师-设置课时报表答案
  35 + setPeriodAnswer: "/api_html/teaching/setPeriodAnswer",
  36 + //任课老师-查询课时报表详情
  37 + periodDetail: "/api_html/teaching/periodDetail",
  38 + //任课老师-分页查询课时题目统计列表
  39 + periodQuestionReport: "/api_html/teaching/periodQuestionReport",
  40 + //任课老师-查询课时学生答题明细
  41 + periodStudentReport: "/api_html/teaching/periodStudentReport",
  42 + //任课老师-分页查询即时测报表
  43 + examReportList: "/api_html/teaching/examReportList",
  44 + //任课老师-查询阶段测练报表
  45 + phaseExamReport: "/api_html/teaching/phaseExamReport",
  46 + //任课老师-查询即时测报表题目列表
  47 + examQuestionList: "/api_html/teaching/examQuestionList",
  48 + //任课老师-设置即时测报表答案
  49 + setExamAnswer: "/api_html/teaching/setExamAnswer",
  50 + //任课老师-查询即时测报表详情
  51 + examDetail: "/api_html/teaching/examDetail",
  52 + //任课老师-下载导入主观题分模板
  53 + subjectiveScoreTemplate: "/api_html/teaching/subjectiveScoreTemplate",
  54 + //任课老师-导入主观题得分
  55 + importSubjectiveScore: "/api_html/teaching/importSubjectiveScore",
  56 + //任课老师-分页查询即时测题目统计
  57 + examQuestionReport: "/api_html/teaching/examQuestionReport",
  58 + //任课老师-查询即时测学生统计
  59 + examStudentReport: "/api_html/teaching/examStudentReport",
  60 + //任课老师-重新判分
  61 + reScore: "/api_html/teaching/reScore",
  62 + //任课老师-数据导出
  63 + exportData: "/api_html/teaching/exportData",
  64 + //任课老师-数据导入
  65 + importData: "/api_html/teaching/importData",
  66 +
  67 +
  68 +
  69 +
  70 +
9 // 查询角色列表 71 // 查询角色列表
10 roleList: "/api_html/school/manager/roleList", 72 roleList: "/api_html/school/manager/roleList",
11 // 分页查询账号 73 // 分页查询账号
@@ -68,8 +130,8 @@ export default { @@ -68,8 +130,8 @@ export default {
68 usageAnalysis: "/api_html/school/manager/usageAnalysis", 130 usageAnalysis: "/api_html/school/manager/usageAnalysis",
69 // 发卡记录 131 // 发卡记录
70 cardList: "/api_html/school/manager/cardList", 132 cardList: "/api_html/school/manager/cardList",
71 -  
72 - 133 +
  134 +
73 // 查询区域列表 135 // 查询区域列表
74 regionList: "/api_html/tenant/regionList", 136 regionList: "/api_html/tenant/regionList",
75 // 查询学校列表 137 // 查询学校列表
@@ -100,7 +162,7 @@ export default { @@ -100,7 +162,7 @@ export default {
100 tenantGradeList: "/api_html/tenant/gradeList", 162 tenantGradeList: "/api_html/tenant/gradeList",
101 // 查询学校班级 163 // 查询学校班级
102 tenantClassList: "/api_html/tenant/classList", 164 tenantClassList: "/api_html/tenant/classList",
103 - 165 +
104 // 学校使用对比 166 // 学校使用对比
105 schoolContrast: "/api_html/tenant/schoolContrast", 167 schoolContrast: "/api_html/tenant/schoolContrast",
106 // 年级使用对比 168 // 年级使用对比
src/assets/css/index.scss
@@ -120,7 +120,7 @@ @@ -120,7 +120,7 @@
120 .down-txt{ 120 .down-txt{
121 display: flex; 121 display: flex;
122 align-items: center; 122 align-items: center;
123 - justify-content: center; 123 + padding-left: 160px;
124 } 124 }
125 .h-title{ 125 .h-title{
126 padding-left:12px; 126 padding-left:12px;
src/components/setAnswer.vue
@@ -8,145 +8,64 @@ @@ -8,145 +8,64 @@
8 > 8 >
9 <div class="el-dialog-content"> 9 <div class="el-dialog-content">
10 <p class="title"> 10 <p class="title">
11 - 设置答案 <i class="fa fa-exchange" @click="editType = !editType"></i> 11 + 设置答案 <i class="fa fa-exchange"></i>
12 <!-- 设置答案 --> 12 <!-- 设置答案 -->
13 <i class="el-icon-close" @click="cancel"></i> 13 <i class="el-icon-close" @click="cancel"></i>
14 </p> 14 </p>
15 - <div v-if="editType">  
16 - <div v-for="(item, index) in FormQuestionList" :key="index">  
17 - <template v-for="(subQuestions, indexs) in item.subQuestions">  
18 - <div  
19 - class="sub-questions"  
20 - :key="indexs"  
21 - v-if="subQuestions.correctAnswer" 15 + <div class="dia-question-box">
  16 + <p class="dia-tips">点击批量设置答案按钮,批量设置答案</p>
  17 + <div v-for="(subQuestions, index) in FormQuestionList" :key="index">
  18 + <p
  19 + class="set-ans-btn"
  20 + v-if="
  21 + subQuestions.qusType &&
  22 + subQuestions.subNum &&
  23 + subQuestions.subNum > 4
  24 + "
  25 + >
  26 + <el-button type="primary" @click="setFormAns(index)"
  27 + >批量设置答案</el-button
22 > 28 >
23 - <div class="qs-num">题{{ subQuestions.questionIndex }}</div>  
24 - <div class="qs-options qs-options2">  
25 - <p v-if="subQuestions.questionType == 4" class="answer-box">  
26 - <span  
27 - class="answer-s"  
28 - :class="subQuestions.correctAnswer == 1 ? 'active' : ''"  
29 - @click="subQuestions.correctAnswer = 1"  
30 - >✓</span  
31 - >  
32 - <span  
33 - class="answer-s"  
34 - :class="subQuestions.correctAnswer == 2 ? 'active' : ''"  
35 - @click="subQuestions.correctAnswer = 2"  
36 - >✗</span  
37 - >  
38 - </p>  
39 - <p v-if="subQuestions.questionType == 3" class="answer-box">  
40 - <span  
41 - class="answer-s"  
42 - v-for="option in subQuestions.answerOptions"  
43 - :class="  
44 - subQuestions.correctAnswer.includes(option)  
45 - ? 'active'  
46 - : ''  
47 - "  
48 - :key="option"  
49 - @click="changAnswer(subQuestions, option)"  
50 - >{{ option }}</span  
51 - >  
52 - </p>  
53 - <p v-if="subQuestions.questionType == 2" class="answer-box">  
54 - <span  
55 - class="answer-s"  
56 - v-for="option in subQuestions.answerOptions"  
57 - :class="  
58 - subQuestions.correctAnswer == option ? 'active' : ''  
59 - "  
60 - :key="option"  
61 - @click="subQuestions.correctAnswer = option"  
62 - >{{ option }}</span  
63 - >  
64 - </p>  
65 - </div>  
66 - </div>  
67 - </template>  
68 - </div>  
69 - </div>  
70 - <div v-else>  
71 - <p class="dia-tips">  
72 - 请点击选项按钮设置答案,多选题题目之间用“,”隔开,若添加5道题:“AC,AD,BD,AC,CD”  
73 - </p>  
74 - <div class="dia-question-box">  
75 - <div v-for="(item, index) in FormQuestionList2" :key="index">  
76 - <div class="set-questions">  
77 - <div class="qs-num">  
78 - <p class="txt">{{ item.name }}</p>  
79 - <p class="num">共{{ item.list.length }}题</p>  
80 - </div>  
81 - <div class="qs-options">  
82 - <p class="ipt">  
83 - <el-input  
84 - v-model="item.answerList"  
85 - @keydown.native="keydownAnswer($event)"  
86 - ></el-input>  
87 - </p>  
88 - <p class="answer-box">  
89 - <template v-if="item.list[0].questionType == 4">  
90 - <span  
91 - class="answer-s active"  
92 - @click="  
93 - item.answerList.length < item.list.length  
94 - ? (item.answerList += '✓')  
95 - : ''  
96 - "  
97 - >✓</span  
98 - >  
99 - <span  
100 - class="answer-s active"  
101 - @click="  
102 - item.answerList.length < item.list.length  
103 - ? (item.answerList += '✗')  
104 - : ''  
105 - "  
106 - >✗</span  
107 - >  
108 - </template>  
109 - <template v-if="item.list[0].questionType == 3">  
110 - <span  
111 - class="answer-s active"  
112 - v-for="option in item.list[0].answerOptions"  
113 - :key="option"  
114 - @click="setAnswer(item, option)"  
115 - >{{ option }}</span  
116 - >  
117 - <span  
118 - class="answer-s active"  
119 - @click="  
120 - item.answerList.split(',').length < item.list.length  
121 - ? (item.answerList += ',')  
122 - : ''  
123 - "  
124 - >,</span  
125 - >  
126 - </template>  
127 - <template  
128 - v-if="item.list[0].questionType == 2"  
129 - class="answer-box"  
130 - >  
131 - <span  
132 - class="answer-s active"  
133 - v-for="option in item.list[0].answerOptions"  
134 - :key="option"  
135 - @click="  
136 - item.answerList.length < item.list.length  
137 - ? (item.answerList += option)  
138 - : ''  
139 - "  
140 - >{{ option }}</span  
141 - >  
142 - </template>  
143 - <span  
144 - class="answer-s delButton"  
145 - @click="item.answerList = item.answerList.slice(0, -1)"  
146 - >x</span  
147 - >  
148 - </p>  
149 - </div> 29 + </p>
  30 + <div class="sub-questions" :key="index" v-else>
  31 + <div class="qs-num">题{{ subQuestions.questionIndex }}</div>
  32 + <div class="qs-options qs-options2">
  33 + <p v-if="subQuestions.questionType == 4" class="answer-box">
  34 + <span
  35 + class="answer-s"
  36 + :class="subQuestions.correctAnswer == 1 ? 'active' : ''"
  37 + @click="subQuestions.correctAnswer = 1"
  38 + >✓</span
  39 + >
  40 + <span
  41 + class="answer-s"
  42 + :class="subQuestions.correctAnswer == 2 ? 'active' : ''"
  43 + @click="subQuestions.correctAnswer = 2"
  44 + >✗</span
  45 + >
  46 + </p>
  47 + <p v-if="subQuestions.questionType == 3" class="answer-box">
  48 + <span
  49 + class="answer-s"
  50 + v-for="option in subQuestions.answerOptions.split(',')"
  51 + :class="
  52 + subQuestions.correctAnswer.includes(option) ? 'active' : ''
  53 + "
  54 + :key="option"
  55 + @click="changAnswer(subQuestions, option)"
  56 + >{{ option }}</span
  57 + >
  58 + </p>
  59 + <p v-if="subQuestions.questionType == 2" class="answer-box">
  60 + <span
  61 + class="answer-s"
  62 + v-for="option in subQuestions.answerOptions.split(',')"
  63 + :class="subQuestions.correctAnswer == option ? 'active' : ''"
  64 + :key="option"
  65 + @click="subQuestions.correctAnswer = option"
  66 + >{{ option }}</span
  67 + >
  68 + </p>
150 </div> 69 </div>
151 </div> 70 </div>
152 </div> 71 </div>
@@ -160,6 +79,84 @@ @@ -160,6 +79,84 @@
160 > 79 >
161 </div> 80 </div>
162 </div> 81 </div>
  82 + <el-dialog
  83 + title="批量设置答案"
  84 + :visible.sync="diaSetAns"
  85 + width="400"
  86 + :modal-append-to-body="false"
  87 + >
  88 + <div class="qs-options">
  89 + <p>{{ setSubPro(formAns.qusType) }}:</p>
  90 + <p class="ipt">
  91 + <el-input
  92 + v-model="formAns.answerList"
  93 + @keydown.native="keydownAnswer($event)"
  94 + ></el-input>
  95 + </p>
  96 + <p class="answer-box">
  97 + <template v-if="formAns.qusType == 4">
  98 + <span
  99 + class="answer-s active"
  100 + @click="
  101 + formAns.answerList.length < formAns.subNum
  102 + ? (formAns.answerList += '✓')
  103 + : ''
  104 + "
  105 + >✓</span
  106 + >
  107 + <span
  108 + class="answer-s active"
  109 + @click="
  110 + formAns.answerList.length < formAns.subNum
  111 + ? (formAns.answerList += '✗')
  112 + : ''
  113 + "
  114 + >✗</span
  115 + >
  116 + </template>
  117 + <template v-if="formAns.qusType == 3">
  118 + <span
  119 + class="answer-s active"
  120 + v-for="option in formAns.answerOptions.split(',')"
  121 + :key="option"
  122 + @click="setMultiple(formAns, option)"
  123 + >{{ option }}</span
  124 + >
  125 + <span
  126 + class="answer-s active"
  127 + @click="
  128 + formAns.answerList.split(',').length < formAns.subNum
  129 + ? (formAns.answerList += ',')
  130 + : ''
  131 + "
  132 + >,</span
  133 + >
  134 + </template>
  135 + <template v-if="formAns.qusType == 2" class="answer-box">
  136 + <span
  137 + class="answer-s active"
  138 + v-for="option in formAns.answerOptions.split(',')"
  139 + :key="option"
  140 + @click="
  141 + formAns.answerList.length < formAns.subNum
  142 + ? (formAns.answerList += option)
  143 + : ''
  144 + "
  145 + >{{ option }}</span
  146 + >
  147 + </template>
  148 + <span
  149 + class="answer-s delButton"
  150 + @click="formAns.answerList = formAns.answerList.slice(0, -1)"
  151 + >x</span
  152 + >
  153 + </p>
  154 + </div>
  155 + <div class="dialog-footer" slot="footer">
  156 + <el-button @click="saveFormAns">确 定</el-button>
  157 + <el-button @click="diaSetAns = false">取 消</el-button>
  158 + </div>
  159 + </el-dialog>
163 </div> 160 </div>
164 </template> 161 </template>
165 162
@@ -174,62 +171,116 @@ export default { @@ -174,62 +171,116 @@ export default {
174 }, 171 },
175 data() { 172 data() {
176 return { 173 return {
  174 + diaSetAns: false,
177 editType: true, //修改答案模式 175 editType: true, //修改答案模式
178 FormQuestionList: [], 176 FormQuestionList: [],
179 - FormQuestionList2: [], 177 + FormQuestionList: [],
  178 + formAns: {
  179 + endIndex: 0, //相同题目最后一位题目的questionIndex
  180 + qusType: "", //题目类型
  181 + subNum: 0, //数量
  182 + answerOptions: [], //答案选项
  183 + answerList: "", //答案列表-字符串
  184 + },
180 }; 185 };
181 }, 186 },
182 watch: { 187 watch: {
183 questionList: { 188 questionList: {
184 - handler: function () {  
185 - this.FormQuestionList = deepClone(this.questionList);  
186 - this.FormQuestionList2 = [];  
187 - console.log(this.questionList);  
188 - // 组合每道大题中的相同题目  
189 - let questionList = deepClone(this.questionList);  
190 - let jsons = {};  
191 - let answerOptions = [];  
192 - for (let i = 0; i < questionList.length; i++) {  
193 - questionList[i].subQuestions.map((items) => {  
194 - let txt = this.setSubPro(items.questionType);  
195 - if (jsons[txt]) {  
196 - jsons[txt].push(items); 189 + handler: function (val) {
  190 + const questions = deepClone(val).sort((a, b) => {
  191 + return a.questionIndex - b.questionIndex;
  192 + });
  193 + this.FormQuestionList = deepClone(questions);
  194 + let types = [{}];
  195 + let addndex = 0;
  196 + this.FormQuestionList?.map((sub, index) => {
  197 + if (!!sub.questionType) {
  198 + if (sub.questionType == types[addndex].qusType) {
  199 + //同类型批量答案+1
  200 + types[addndex].subNum += 1;
  201 + if (
  202 + types[addndex].answerOptions.length < sub.answerOptions.length
  203 + ) {
  204 + types[addndex].answerOptions = sub.answerOptions;
  205 + }
  206 + types[addndex].answerList += this.setAnswer(
  207 + sub.questionType,
  208 + sub.correctAnswer
  209 + );
  210 + if (index == this.questionList.length - 1) {
  211 + //循环最后类型数量大于等于5,保存批量答案
  212 + if (types[addndex].subNum && types[addndex].subNum >= 5) {
  213 + types[addndex].endIndex = sub.questionIndex;
  214 + types[addndex].index = index;
  215 + }
  216 + }
197 } else { 217 } else {
198 - jsons[txt] = [items];  
199 - }  
200 - if (items.questionType == 2 || items.questionType == 3) {  
201 - if (items.answerOptions.length > answerOptions.length) {  
202 - answerOptions = items.answerOptions; 218 + if (types[addndex].subNum && types[addndex].subNum >= 5) {
  219 + //不同类型时如果原有类型数量大于等于5,保存批量答案
  220 + types[addndex].endIndex =
  221 + this.questionList[index - 1].questionIndex;
  222 + types[addndex].index = index;
  223 + addndex += 1;
  224 + types[addndex] = {};
203 } 225 }
204 - jsons[txt][0].answerOptions = answerOptions;  
205 - }  
206 - });  
207 - console.log(jsons);  
208 - }  
209 - this.FormQuestionList2 = Object.keys(jsons).map((item) => {  
210 - let answerList = "";  
211 - jsons[item].map((items, index) => {  
212 - if (items.questionType == 2) {  
213 - answerList += items.correctAnswer;  
214 - } else if (items.questionType == 3) {  
215 - answerList +=  
216 - items.correctAnswer +  
217 - (jsons[item].length - 1 != index ? "," : "");  
218 - } else if (items.questionType == 4) {  
219 - answerList += items.correctAnswer == 1 ? "✓" : "✗"; 226 + //不同类型初始化批量答案
  227 + types[addndex].qusType = sub.questionType;
  228 + types[addndex].subNum = 1;
  229 + types[addndex].answerOptions = sub.answerOptions;
  230 + types[addndex].answerList = this.setAnswer(
  231 + sub.questionType,
  232 + sub.correctAnswer
  233 + );
220 } 234 }
221 - });  
222 - return {  
223 - name: item,  
224 - list: jsons[item],  
225 - answerList: answerList,  
226 - }; 235 + }
227 }); 236 });
  237 + for (let i = 0; i < types.length; i++) {
  238 + if (types[i].qusType == 3) {
  239 + types[i].answerList = types[i].answerList.slice(0, -1);
  240 + }
  241 + if (types[i].subNum >= 5) {
  242 + item.subQuestions.splice(
  243 + types[i].index + i + 1,
  244 + 0,
  245 + deepClone(types[i])
  246 + );
  247 + }
  248 + }
228 }, 249 },
229 deep: true, 250 deep: true,
230 }, 251 },
231 }, 252 },
232 methods: { 253 methods: {
  254 + setFormAns(indexs) {
  255 + //初始化要修改的答案
  256 + this.formAns = { ...this.FormQuestionList[indexs] };
  257 + this.diaSetAns = true;
  258 + },
  259 + saveFormAns() {
  260 + //批量修改答案
  261 + let EndIndex;
  262 + let subNum = this.formAns.subNum - 1;
  263 + this.FormQuestionList.some((item, index) => {
  264 + if (this.formAns.endIndex == item.questionIndex) {
  265 + EndIndex = index;
  266 + return;
  267 + }
  268 + });
  269 + for (let i = 0; i <= subNum; i++) {
  270 + let correctAnswer = "";
  271 + if (this.formAns.qusType == 2) {
  272 + correctAnswer = this.formAns.answerList[subNum - i];
  273 + } else if (this.formAns.qusType == 3) {
  274 + correctAnswer = this.formAns.answerList.split(",")[subNum - i];
  275 +
  276 + console.log(this.formAns.answerList.split(",")[subNum - i]);
  277 + } else if (this.formAns.qusType == 4) {
  278 + correctAnswer = this.formAns.answerList[subNum - i] == "✓" ? 1 : 2;
  279 + }
  280 + this.questionList[EndIndex - i].correctAnswer = correctAnswer;
  281 + }
  282 + this.diaSetAns = false;
  283 + },
233 setSubPro(type) { 284 setSubPro(type) {
234 let tit; 285 let tit;
235 switch (type) { 286 switch (type) {
@@ -270,15 +321,26 @@ export default { @@ -270,15 +321,26 @@ export default {
270 event.returnValue = ""; 321 event.returnValue = "";
271 } 322 }
272 }, 323 },
273 - setAnswer(obj, answer) { 324 + setAnswer(type, ans) {
  325 + let txt = "";
  326 + if (type == 2) {
  327 + txt = ans;
  328 + } else if (type == 3) {
  329 + txt = ans + ",";
  330 + } else if (type == 4) {
  331 + txt = ans == 1 ? "✓" : "✗";
  332 + }
  333 + return txt;
  334 + },
  335 + setMultiple(obj, answer) {
274 //多选答案设置 336 //多选答案设置
275 obj.answerList += answer; 337 obj.answerList += answer;
276 let str = obj.answerList; 338 let str = obj.answerList;
277 let str2 = checkAnswer( 339 let str2 = checkAnswer(
278 str, 340 str,
279 3, 341 3,
280 - obj.list[0].answerOptions,  
281 - obj.list.length 342 + obj.answerOptions.split(",").length,
  343 + obj.answerList.length
282 ); 344 );
283 obj.answerList = str2; 345 obj.answerList = str2;
284 }, 346 },
@@ -294,39 +356,16 @@ export default { @@ -294,39 +356,16 @@ export default {
294 } 356 }
295 }, 357 },
296 async saveAnswer() { 358 async saveAnswer() {
297 - let questionList = [],  
298 - questionList2 = [];  
299 - if (this.editType) {  
300 - questionList = [...this.FormQuestionList];  
301 - } else {  
302 - this.FormQuestionList2.map((item) => {  
303 - item.list.map((items, index) => {  
304 - if (items.questionType == 2 ) {  
305 - items.correctAnswer = item.answerList.split("")[index];  
306 - } else if (items.questionType == 3) {  
307 - items.correctAnswer = item.answerList.split(",")[index];  
308 - }else if (items.questionType == 4) {  
309 - items.correctAnswer = item.answerList[index] == "✓" ? 1 : 2;  
310 - }  
311 - questionList2.push(items);  
312 - });  
313 - });  
314 - questionList = this.FormQuestionList.map((item) => {  
315 - let subQuestions = item.subQuestions.map((items) => {  
316 - items.correctAnswer = questionList2.find((question) => {  
317 - return question.questionIndex == items.questionIndex;  
318 - })?.correctAnswer;  
319 - return items;  
320 - });  
321 - return {  
322 - ...item,  
323 - subQuestions: [...subQuestions],  
324 - };  
325 - }); 359 + let questionList = [];
  360 + for (let i = 0; i < this.FormQuestionList.length; i++) {
  361 + if (this.FormQuestionList[i].qusType) {
  362 + this.FormQuestionList.splice(i, 1);
  363 + i--;
  364 + }
326 } 365 }
327 console.log(questionList); 366 console.log(questionList);
328 - const { data, status, message } = await this.$request.modifyPaper({  
329 - paperId: this.paperId, 367 + const { data, status, message } = await this.$request.setPeriodAnswer({
  368 + periodId: this.paperId,
330 questionList: questionList, 369 questionList: questionList,
331 }); 370 });
332 if (status == 0) { 371 if (status == 0) {
src/components/upload.vue
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 ref="upload" 7 ref="upload"
8 :action="url" 8 :action="url"
9 :multiple="false" 9 :multiple="false"
10 - :data="{ id: id }" 10 + :data="{ ...query }"
11 :with-credentials="true" 11 :with-credentials="true"
12 :limit="1" 12 :limit="1"
13 :on-change="change" 13 :on-change="change"
@@ -34,6 +34,10 @@ export default { @@ -34,6 +34,10 @@ export default {
34 type: String, 34 type: String,
35 default: "", 35 default: "",
36 }, 36 },
  37 + examId: {
  38 + type: String,
  39 + default: "",
  40 + },
37 url: { 41 url: {
38 type: String, 42 type: String,
39 default: "", 43 default: "",
@@ -44,6 +48,19 @@ export default { @@ -44,6 +48,19 @@ export default {
44 default: "模板", 48 default: "模板",
45 }, 49 },
46 }, 50 },
  51 + computed: {
  52 + query: function () {
  53 + if (this.id) {
  54 + return {
  55 + id: this.id,
  56 + };
  57 + } else if (this.examId) {
  58 + return {
  59 + examId: this.examId,
  60 + };
  61 + }
  62 + },
  63 + },
47 data() { 64 data() {
48 return { 65 return {
49 file: null, 66 file: null,
src/views/ask/analysis.vue
@@ -10,150 +10,413 @@ @@ -10,150 +10,413 @@
10 <span 10 <span
11 class="tab-item" 11 class="tab-item"
12 :class="type == 1 ? 'active' : ''" 12 :class="type == 1 ? 'active' : ''"
13 - @click="type = 1" 13 + @click="setType(1)"
14 >答题表现</span 14 >答题表现</span
15 > 15 >
16 <span 16 <span
17 class="tab-item" 17 class="tab-item"
18 :class="type == 2 ? 'active' : ''" 18 :class="type == 2 ? 'active' : ''"
19 - @click="type = 2" 19 + @click="setType(2)"
20 >学生问答表现</span 20 >学生问答表现</span
21 > 21 >
22 <span 22 <span
23 class="tab-item" 23 class="tab-item"
24 :class="type == 3 ? 'active' : ''" 24 :class="type == 3 ? 'active' : ''"
25 - @click="type = 3" 25 + @click="setType(3)"
26 >学生互动表现</span 26 >学生互动表现</span
27 > 27 >
28 <span 28 <span
29 class="tab-item" 29 class="tab-item"
30 :class="type == 4 ? 'active' : ''" 30 :class="type == 4 ? 'active' : ''"
31 - @click="type = 4" 31 + @click="setType(4)"
32 >签到明细</span 32 >签到明细</span
33 > 33 >
34 </div> 34 </div>
35 - <ul class="info">  
36 - <li class="info-item">科目:语文</li>  
37 - <li class="info-item">课时:课时1</li>  
38 - <li class="info-item">上课时间:2022-11-9 21:30</li>  
39 - <li class="info-item">下课时间:2022-11-9 21:30</li>  
40 - <li class="info-item">签到人数:45</li>  
41 - <li class="info-item">题目总数:8</li>  
42 - <li class="info-item">答题总数:8</li>  
43 - <li class="info-item">课时时长:45分钟</li>  
44 - <li class="info-item">总参与度::80%</li>  
45 - <li class="info-item">班级总正确率:82%</li>  
46 - <li class="info-item">已答总正确率:89%</li>  
47 - <li class="info-item">反馈时长:15分钟</li>  
48 - </ul>  
49 - <el-table  
50 - :data="tableData"  
51 - border  
52 - style="width: 100%"  
53 - :default-sort="{ prop: 'dadui', order: 'descending' }"  
54 - >  
55 - <el-table-column  
56 - prop="questionIndex"  
57 - label="题号"  
58 - align="center"  
59 - ><template slot-scope="scoped">Q{{scoped.row.questionIndex}}</template></el-table-column>  
60 - <el-table-column  
61 - prop="questionType"  
62 - label="题型"  
63 - align="center"  
64 - ></el-table-column>  
65 - <el-table-column  
66 - prop="dati"  
67 - label="答题人数"  
68 - sortable  
69 - align="center"  
70 - ></el-table-column>  
71 - <el-table-column  
72 - prop="dadui"  
73 - label="答对人数"  
74 - sortable  
75 - align="center"  
76 - ></el-table-column>  
77 - <el-table-column  
78 - prop="canyu"  
79 - label="班级参与度"  
80 - sortable  
81 - align="center"  
82 - ><template slot-scope="scoped">{{scoped.row.canyu}}%</template></el-table-column>  
83 - <el-table-column  
84 - prop="banjidadui"  
85 - label="班级正确率"  
86 - sortable  
87 - align="center"  
88 - ><template slot-scope="scoped">{{scoped.row.banjidadui}}%</template></el-table-column>  
89 - <el-table-column  
90 - prop="yida"  
91 - label="已答正确率"  
92 - sortable  
93 - align="center"  
94 - ><template slot-scope="scoped">{{scoped.row.yida}}%</template></el-table-column>  
95 - <el-table-column  
96 - prop="correctAnswer"  
97 - label="正确答案"  
98 - align="center"  
99 - ></el-table-column>  
100 - <el-table-column  
101 - prop="ganrao"  
102 - label="干扰答案"  
103 - align="center"  
104 - ></el-table-column>  
105 - </el-table> 35 + <div v-loading="loading">
  36 + <ul class="info" v-if="type == 1">
  37 + <li class="info-item">科目:{{ detail.subjectName }}</li>
  38 + <li class="info-item">课时:{{ detail.title }}</li>
  39 + <li class="info-item">上课时间:{{ detail.startTime }}</li>
  40 + <li class="info-item">下课时间:{{ detail.endTime }}</li>
  41 + <li class="info-item">签到人数:{{ detail.answeredNum }}</li>
  42 + <li class="info-item">题目总数:{{ detail.questionNum }}</li>
  43 + <li class="info-item">答题总数:{{ detail.totalAnswersNum }}</li>
  44 + <li class="info-item">课时时长:{{ detail.duration / 60 }}分钟</li>
  45 + <li class="info-item">总参与度::{{ detail.participationRate }}%</li>
  46 + <li class="info-item">
  47 + 班级总正确率:{{ detail.classCorrectRate }}%
  48 + </li>
  49 + <li class="info-item">
  50 + 已答总正确率:{{ detail.answerCorrectRate }}%
  51 + </li>
  52 + <li class="info-item">
  53 + 反馈时长:{{ detail.consumingDuration / 60 }}分钟
  54 + </li>
  55 + </ul>
  56 + <el-table v-if="type == 1" :data="tableData" border style="width: 100%">
  57 + <el-table-column prop="questionIndex" label="题号" align="center"
  58 + ><template slot-scope="scoped"
  59 + >Q{{ scoped.row.questionIndex }}</template
  60 + ></el-table-column
  61 + >
  62 + <el-table-column prop="questionType" label="题型" align="center">
  63 + <template slot-scope="scoped">{{
  64 + setSubPro(scoped.row.questionType)
  65 + }}</template>
  66 + </el-table-column>
  67 + <el-table-column
  68 + prop="answeredNum"
  69 + label="答题人数"
  70 + sortable
  71 + align="center"
  72 + ></el-table-column>
  73 + <el-table-column
  74 + prop="correctAnswerNum"
  75 + label="答对人数"
  76 + sortable
  77 + align="center"
  78 + ></el-table-column>
  79 + <el-table-column
  80 + prop="canyu"
  81 + label="班级参与度"
  82 + sortable
  83 + align="center"
  84 + ><template slot-scope="scoped"
  85 + >{{ scoped.row.canyu }}%</template
  86 + ></el-table-column
  87 + >
  88 + <el-table-column
  89 + prop="classCorrectRate"
  90 + label="班级正确率"
  91 + sortable
  92 + align="center"
  93 + ><template slot-scope="scoped"
  94 + >{{ scoped.row.classCorrectRate }}%</template
  95 + ></el-table-column
  96 + >
  97 + <el-table-column
  98 + prop="answerCorrectRate"
  99 + label="已答正确率"
  100 + sortable
  101 + align="center"
  102 + ><template slot-scope="scoped"
  103 + >{{ scoped.row.answerCorrectRate }}%</template
  104 + ></el-table-column
  105 + >
  106 + <el-table-column
  107 + prop="correctAnswer"
  108 + label="正确答案"
  109 + align="center"
  110 + ></el-table-column>
  111 + <el-table-column
  112 + prop="fallible"
  113 + label="干扰答案"
  114 + align="center"
  115 + ></el-table-column>
  116 + <el-table-column prop="screenshot" label="题干" align="center">
  117 + <template slot-scope="scoped">
  118 + <el-image
  119 + style="width: 60px; height: 40px"
  120 + :src="scoped.row.screenshot"
  121 + :preview-src-list="[scoped.row.screenshot]"
  122 + >
  123 + </el-image></template
  124 + ></el-table-column>
  125 + </el-table>
  126 + <el-table v-if="type == 2" :data="tableData" border style="width: 100%">
  127 + <el-table-column
  128 + prop="studentCode"
  129 + label="学号"
  130 + align="center"
  131 + ></el-table-column>
  132 + <el-table-column
  133 + prop="studentName"
  134 + label="姓名"
  135 + align="center"
  136 + ></el-table-column>
  137 + <el-table-column
  138 + prop="answerTimes"
  139 + label="答题次数"
  140 + align="center"
  141 + ></el-table-column>
  142 + <el-table-column
  143 + prop="correctAnswerNum"
  144 + label="答题耗时"
  145 + align="center"
  146 + ></el-table-column>
  147 + <el-table-column
  148 + prop="correctAnswerTimes"
  149 + label="答对次数"
  150 + align="center"
  151 + ></el-table-column>
  152 + <el-table-column
  153 + prop="participationRate"
  154 + label="参与度"
  155 + sortable
  156 + align="center"
  157 + ><template slot-scope="scoped"
  158 + >{{ scoped.row.participationRate }}%</template
  159 + ></el-table-column
  160 + >
  161 + <el-table-column
  162 + prop="correctRate"
  163 + label="正确率"
  164 + sortable
  165 + align="center"
  166 + ><template slot-scope="scoped"
  167 + >{{ scoped.row.correctRate }}%</template
  168 + ></el-table-column
  169 + >
  170 + <el-table-column
  171 + prop="answerCorrectRate"
  172 + label="已答正确率"
  173 + sortable
  174 + align="center"
  175 + ><template slot-scope="scoped"
  176 + >{{ scoped.row.answerCorrectRate }}%</template
  177 + ></el-table-column
  178 + >
  179 + </el-table>
  180 + <el-table v-if="type == 3" :data="tableData" border style="width: 100%">
  181 + <el-table-column
  182 + prop="studentCode"
  183 + label="学号"
  184 + align="center"
  185 + ></el-table-column>
  186 + <el-table-column
  187 + prop="studentName"
  188 + label="姓名"
  189 + align="center"
  190 + ></el-table-column>
  191 + <el-table-column
  192 + prop="rushAnswerTimes"
  193 + label="抢答成功次数"
  194 + sortable
  195 + align="center"
  196 + ></el-table-column>
  197 + <el-table-column
  198 + prop="rushAnswerCorrectTimes"
  199 + label="答对次数"
  200 + sortable
  201 + align="center"
  202 + ></el-table-column>
  203 + <el-table-column
  204 + prop="checkAnswerTimes"
  205 + label="抽答次数"
  206 + sortable
  207 + align="center"
  208 + ></el-table-column>
  209 + <el-table-column
  210 + prop="checkAnswerCorrectTimes"
  211 + label="抽答答对次数"
  212 + sortable
  213 + align="center"
  214 + ></el-table-column>
  215 + <el-table-column
  216 + prop="interactionsNum"
  217 + label="参与得分"
  218 + sortable
  219 + align="center"
  220 + ></el-table-column>
  221 + <el-table-column
  222 + prop="interactionsCorrectNum"
  223 + label="对错得分"
  224 + sortable
  225 + align="center"
  226 + ></el-table-column>
  227 + </el-table>
  228 + <el-table v-if="type == 4" :data="tableData" border style="width: 100%">
  229 + <el-table-column
  230 + prop="studentName"
  231 + label="姓名"
  232 + align="center"
  233 + ></el-table-column>
  234 + <el-table-column
  235 + prop="checkInTime"
  236 + label="签到时间"
  237 + sortable
  238 + align="center"
  239 + ></el-table-column>
  240 + <el-table-column
  241 + prop="makeUpTime"
  242 + label="补签时间"
  243 + sortable
  244 + align="center"
  245 + ></el-table-column>
  246 + </el-table>
  247 + <div class="pagination-box" v-show="type == 1">
  248 + <el-pagination
  249 + small=""
  250 + layout="total,prev, pager, next"
  251 + :hide-on-single-page="true"
  252 + :total="total"
  253 + @current-change="changePage"
  254 + :current-page="page"
  255 + :page-size="size"
  256 + >
  257 + </el-pagination>
  258 + </div>
  259 + <p class="down">
  260 + <el-button
  261 + @click="exportData"
  262 + type="info"
  263 + plain
  264 + round
  265 + icon="fa fa-cloud-download"
  266 + >导出报表</el-button
  267 + >
  268 + <el-button @click="edit" type="primary" round>设置答案</el-button>
  269 + </p>
  270 + </div>
106 </div> 271 </div>
  272 +
  273 + <set-answer
  274 + :diaVisible="dialogVisible"
  275 + :questionList="form.questionList"
  276 + :paperId="form.id"
  277 + @saveSuccess="handleSuccess"
  278 + @cancel="cancel"
  279 + />
107 </div> 280 </div>
108 </template> 281 </template>
109 282
110 <script> 283 <script>
  284 +import { downloadFile } from "@/utils";
111 export default { 285 export default {
112 data() { 286 data() {
113 return { 287 return {
  288 + dialogVisible: false,
  289 + loading: false,
114 id: "", 290 id: "",
115 type: 1, 291 type: 1,
116 - tableData: [  
117 - {  
118 - questionIndex: 1,  
119 - questionType: "单选题",  
120 - dati: 5,  
121 - dadui: 60,  
122 - canyu: 50,  
123 - banjidadui: 80,  
124 - yida: 90,  
125 - correctAnswer:"A",  
126 - ganrao:"C"  
127 - },  
128 - {  
129 - questionIndex: 2,  
130 - questionType: "单选题",  
131 - dati: 6,  
132 - dadui: 80,  
133 - canyu: 60,  
134 - banjidadui: 90,  
135 - yida: 100,  
136 - correctAnswer:"B",  
137 - ganrao:"D"  
138 - },  
139 - ], 292 + form: {
  293 + id: "",
  294 + questionList: [],
  295 + },
  296 + detail: {},
  297 + tableData: [],
  298 + page: 1,
  299 + size: 20,
  300 + total: 0,
140 }; 301 };
141 }, 302 },
142 created() { 303 created() {
143 this.id = this.$route.query.id; 304 this.id = this.$route.query.id;
144 - // this._QueryData() 305 + this._QueryData();
  306 + this.periodDetail();
145 }, 307 },
146 methods: { 308 methods: {
  309 + setType(type) {
  310 + this.type = type;
  311 + this.page = 1;
  312 + this._QueryData();
  313 + },
  314 + setSubPro(type) {
  315 + let tit;
  316 + switch (type) {
  317 + case 2:
  318 + tit = "单选题";
  319 + break;
  320 + case 3:
  321 + tit = "多选题";
  322 + break;
  323 + case 4:
  324 + tit = "判断题";
  325 + break;
  326 + case 5:
  327 + tit = "主观题";
  328 + break;
  329 + default:
  330 + tit = "其他";
  331 + }
  332 + return tit;
  333 + },
  334 + cancel() {
  335 + this.dialogVisible = false;
  336 + },
  337 + handleSuccess() {
  338 + this.dialogVisible = false;
  339 + },
  340 + async edit() {
  341 + if (this.editLoading) return;
  342 + this.editLoading = true;
  343 + const { data, status, info } = await this.$request.periodQuestionList({
  344 + examId: this.id,
  345 + });
  346 + this.editLoading = false;
  347 + if (status === 0) {
  348 + this.form.id = this.id;
  349 + this.form.questionList = (data.list && [...data.list]) || [];
  350 + this.dialogVisible = true;
  351 + } else {
  352 + this.$message.error(info);
  353 + }
  354 + },
  355 + changePage(page) {
  356 + this.page = page;
  357 + this._QueryData();
  358 + },
  359 + async periodDetail() {
  360 + let { data, info, status } = await this.$request.periodDetail({
  361 + periodId: this.id,
  362 + });
  363 + if (status == 0) {
  364 + this.detail = { ...data };
  365 + } else {
  366 + this.$message.error(info);
  367 + }
  368 + },
147 async _QueryData() { 369 async _QueryData() {
148 - let { data, info, status } = this.$request.quizDetail({  
149 - id: this.id, 370 + const queryData =
  371 + this.type == 1
  372 + ? this.$request.periodQuestionReport
  373 + : this.$request.periodStudentReport;
  374 + let query = {};
  375 + if (this.type == 2) {
  376 + query.type = 1;
  377 + } else if (this.type == 3) {
  378 + query.type = 2;
  379 + } else if (this.type == 4) {
  380 + query.type = 3;
  381 + }
  382 + this.loading = true;
  383 + let { data, info, status } = await queryData({
  384 + periodId: this.id,
  385 + page: this.page,
  386 + size: this.size,
  387 + ...query,
150 }); 388 });
  389 + this.loading = false;
  390 + if (status === 0) {
  391 + this.tableData = [...data?.list];
  392 + this.total = data.count;
  393 + } else {
  394 + this.$message.error(info);
  395 + }
  396 + },
  397 + //导出
  398 + async exportData() {
  399 + // if (this.exportLoading = true) return;
  400 + this.exportLoading = true;
  401 + const { data, status, info } = await this.$request.exportData();
  402 + this.exportLoading = false;
  403 + if (data) {
  404 + downloadFile(this.detail.title + "报表", data);
  405 + } else {
  406 + this.$message.error(info);
  407 + }
151 }, 408 },
152 }, 409 },
153 }; 410 };
154 </script> 411 </script>
155 412
156 <style lang="scss" scoped> 413 <style lang="scss" scoped>
  414 +.down {
  415 + padding-top: 20px;
  416 + width: 100%;
  417 + display: flex;
  418 + justify-content: space-between;
  419 +}
157 .page-content { 420 .page-content {
158 padding: 20px 20px 0; 421 padding: 20px 20px 0;
159 } 422 }
src/views/ask/index.vue
@@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
25 v-if="role == 'ROLE_BANZHUREN'" 25 v-if="role == 'ROLE_BANZHUREN'"
26 class="sel" 26 class="sel"
27 multiple 27 multiple
28 - v-model="query.subjectId" 28 + v-model="query.subjectNames"
29 placeholder="选择科目" 29 placeholder="选择科目"
30 @change="_QueryData" 30 @change="_QueryData"
31 > 31 >
@@ -40,7 +40,7 @@ @@ -40,7 +40,7 @@
40 <el-select 40 <el-select
41 v-else 41 v-else
42 class="sel" 42 class="sel"
43 - v-model="query.subjectId" 43 + v-model="query.subjectNames"
44 placeholder="选择科目" 44 placeholder="选择科目"
45 @change="_QueryData" 45 @change="_QueryData"
46 > 46 >
@@ -89,60 +89,78 @@ @@ -89,60 +89,78 @@
89 </div> 89 </div>
90 </div> 90 </div>
91 <div class="table-box"> 91 <div class="table-box">
92 - <el-radio-group v-model="tabIndex" style="margin-bottom: 20px"> 92 + <el-radio-group
  93 + v-model="tabIndex"
  94 + @change="tabChange"
  95 + style="margin-bottom: 20px"
  96 + >
93 <el-radio-button :label="1">单课时报表</el-radio-button> 97 <el-radio-button :label="1">单课时报表</el-radio-button>
94 - <el-radio-button :label="2" v-if="this.role != 'ROLE_BANZHUREN'" 98 + <!-- <el-radio-button :label="2" v-if="this.role != 'ROLE_BANZHUREN'"
95 >阶段问答报表</el-radio-button 99 >阶段问答报表</el-radio-button
  100 + > -->
  101 + <el-radio-button :label="2" v-if="query.startDay != query.endDay"
  102 + >阶段问答报表</el-radio-button
  103 + >
  104 + <el-radio-button :label="3" v-if="query.startDay != query.endDay"
  105 + >阶段互动报表</el-radio-button
96 > 106 >
97 - <el-radio-button :label="3">阶段互动报表</el-radio-button>  
98 </el-radio-group> 107 </el-radio-group>
99 - <p class="table-tit" v-if="tabIndex != 1"> 108 + <!-- <p class="table-tit" v-if="tabIndex != 1">
100 <span>总课时数:10</span> 109 <span>总课时数:10</span>
101 <span>互动总数:22</span> 110 <span>互动总数:22</span>
102 - </p> 111 + </p> -->
103 <div v-if="tabIndex == 1"> 112 <div v-if="tabIndex == 1">
104 <el-table 113 <el-table
105 :data="tableData" 114 :data="tableData"
106 border 115 border
107 style="width: 100%" 116 style="width: 100%"
108 - :default-sort="{ prop: 'canyudu', order: 'descending' }" 117 + @sort-change="sortChange"
109 > 118 >
110 <el-table-column 119 <el-table-column
111 - prop="keshi" 120 + prop="title"
112 label="课时" 121 label="课时"
113 align="center" 122 align="center"
114 ></el-table-column> 123 ></el-table-column>
115 <el-table-column 124 <el-table-column
116 - prop="zongshu" 125 + prop="questionNum"
117 label="题目总数" 126 label="题目总数"
118 align="center" 127 align="center"
119 width="100" 128 width="100"
120 ></el-table-column> 129 ></el-table-column>
121 <el-table-column 130 <el-table-column
122 - prop="shijian" 131 + prop="startTime"
123 label="上课时间" 132 label="上课时间"
124 align="center" 133 align="center"
125 ></el-table-column> 134 ></el-table-column>
126 <el-table-column 135 <el-table-column
127 - prop="canyudu" 136 + prop="participationRate"
128 label="参与度" 137 label="参与度"
129 - sortable 138 + sortable="custom"
130 align="center" 139 align="center"
131 - > <template slot-scope="scoped">{{scoped.row.canyudu}}%</template></el-table-column> 140 + >
  141 + <template slot-scope="scoped"
  142 + >{{ scoped.row.participationRate }}%</template
  143 + ></el-table-column
  144 + >
132 <el-table-column 145 <el-table-column
133 - prop="zhengque" 146 + prop="answerCorrectRate"
134 label="已答总正确率" 147 label="已答总正确率"
135 - sortable 148 + sortable="custom"
136 align="center" 149 align="center"
137 > 150 >
138 - <template slot-scope="scoped">{{scoped.row.zhengque}}%</template> 151 + <template slot-scope="scoped"
  152 + >{{ scoped.row.answerCorrectRate }}%</template
  153 + >
139 </el-table-column> 154 </el-table-column>
140 <el-table-column 155 <el-table-column
141 - prop="allzheng" 156 + prop="correctRate"
142 label="班级总正确率" 157 label="班级总正确率"
143 - sortable 158 + sortable="custom"
144 align="center" 159 align="center"
145 - ><template slot-scope="scoped">{{scoped.row.allzheng}}%</template></el-table-column> 160 + ><template slot-scope="scoped"
  161 + >{{ scoped.row.correctRate }}%</template
  162 + ></el-table-column
  163 + >
146 <el-table-column label="操作" align="center"> 164 <el-table-column label="操作" align="center">
147 <template slot-scope="scoped"> 165 <template slot-scope="scoped">
148 <el-tooltip effect="dark" content="详情" placement="top"> 166 <el-tooltip effect="dark" content="详情" placement="top">
@@ -169,56 +187,66 @@ @@ -169,56 +187,66 @@
169 </div> 187 </div>
170 <div v-if="tabIndex == 2"> 188 <div v-if="tabIndex == 2">
171 <el-table 189 <el-table
172 - :data="tableAsk" 190 + :data="tableData"
173 border 191 border
174 style="width: 100%" 192 style="width: 100%"
175 - :default-sort="{ prop: 'cishu', order: 'descending' }" 193 + :default-sort="{ prop: 'answerTimes', order: 'descending' }"
176 > 194 >
177 <el-table-column 195 <el-table-column
178 - prop="xuehao" 196 + prop="studentCode"
179 label="学号" 197 label="学号"
180 align="center" 198 align="center"
181 ></el-table-column> 199 ></el-table-column>
182 <el-table-column 200 <el-table-column
183 - prop="xingming" 201 + prop="studentName"
184 label="姓名" 202 label="姓名"
185 align="center" 203 align="center"
186 width="100" 204 width="100"
187 ></el-table-column> 205 ></el-table-column>
188 <el-table-column 206 <el-table-column
189 - prop="cishu" 207 + prop="answerTimes"
190 label="累计答题次数" 208 label="累计答题次数"
191 sortable 209 sortable
192 align="center" 210 align="center"
193 ></el-table-column> 211 ></el-table-column>
194 <el-table-column 212 <el-table-column
195 - prop="dadui" 213 + prop="correctAnswerTimes"
196 label="累计答对次数" 214 label="累计答对次数"
197 sortable 215 sortable
198 align="center" 216 align="center"
199 ></el-table-column> 217 ></el-table-column>
200 <el-table-column 218 <el-table-column
201 - prop="canyudu" 219 + prop="participationRate"
202 label="总参与度" 220 label="总参与度"
203 sortable 221 sortable
204 align="center" 222 align="center"
205 - > <template slot-scope="scoped">{{scoped.row.canyudu}}%</template></el-table-column> 223 + >
  224 + <template slot-scope="scoped"
  225 + >{{ scoped.row.participationRate }}%</template
  226 + ></el-table-column
  227 + >
206 <el-table-column 228 <el-table-column
207 - prop="allzheng" 229 + prop="correctRate"
208 label="总正确率" 230 label="总正确率"
209 sortable 231 sortable
210 align="center" 232 align="center"
211 - > <template slot-scope="scoped">{{scoped.row.allzheng}}%</template></el-table-column> 233 + >
  234 + <template slot-scope="scoped"
  235 + >{{ scoped.row.correctRate }}%</template
  236 + ></el-table-column
  237 + >
212 <el-table-column 238 <el-table-column
213 - prop="yidazheng" 239 + prop="answerCorrectRate"
214 label="已答总正确率" 240 label="已答总正确率"
215 sortable 241 sortable
216 align="center" 242 align="center"
217 > 243 >
218 - <template slot-scope="scoped">{{scoped.row.yidazheng}}%</template> 244 + <template slot-scope="scoped"
  245 + >{{ scoped.row.answerCorrectRate }}%</template
  246 + >
219 </el-table-column> 247 </el-table-column>
220 <el-table-column 248 <el-table-column
221 - prop="zongpaiming" 249 + prop="classRank"
222 label="总正确率班排名" 250 label="总正确率班排名"
223 sortable 251 sortable
224 align="center" 252 align="center"
@@ -227,42 +255,42 @@ @@ -227,42 +255,42 @@
227 </div> 255 </div>
228 <div v-if="tabIndex == 3"> 256 <div v-if="tabIndex == 3">
229 <el-table 257 <el-table
230 - :data="tableAsk" 258 + :data="tableData"
231 border 259 border
232 style="width: 100%" 260 style="width: 100%"
233 - :default-sort="{ prop: 'cishu', order: 'descending' }" 261 + :default-sort="{ prop: 'answerTimes', order: 'descending' }"
234 > 262 >
235 <el-table-column 263 <el-table-column
236 - prop="xuehao" 264 + prop="studentCode"
237 label="学号" 265 label="学号"
238 align="center" 266 align="center"
239 ></el-table-column> 267 ></el-table-column>
240 <el-table-column 268 <el-table-column
241 - prop="xingming" 269 + prop="studentName"
242 label="姓名" 270 label="姓名"
243 align="center" 271 align="center"
244 width="100" 272 width="100"
245 ></el-table-column> 273 ></el-table-column>
246 <el-table-column 274 <el-table-column
247 - prop="cishu" 275 + prop="rushAnswerTimes"
248 label="抢答成功次数" 276 label="抢答成功次数"
249 sortable 277 sortable
250 align="center" 278 align="center"
251 ></el-table-column> 279 ></el-table-column>
252 <el-table-column 280 <el-table-column
253 - prop="dadui"  
254 - label="答对次数" 281 + prop="rushAnswerCorrectTimes"
  282 + label="抢答答对次数"
255 sortable 283 sortable
256 align="center" 284 align="center"
257 ></el-table-column> 285 ></el-table-column>
258 <el-table-column 286 <el-table-column
259 - prop="chouda" 287 + prop="checkAnswerTimes"
260 label="抽答次数" 288 label="抽答次数"
261 sortable 289 sortable
262 align="center" 290 align="center"
263 ></el-table-column> 291 ></el-table-column>
264 <el-table-column 292 <el-table-column
265 - prop="choudadui" 293 + prop="checkAnswerCorrectTimes"
266 label="抽答答对次数" 294 label="抽答答对次数"
267 sortable 295 sortable
268 align="center" 296 align="center"
@@ -281,218 +309,79 @@ @@ -281,218 +309,79 @@
281 ></el-table-column> 309 ></el-table-column>
282 </el-table> 310 </el-table>
283 </div> 311 </div>
284 - <p class="down" v-if="tabIndex == 3||tabIndex == 2">  
285 - <el-button type="info" plain round icon="fa fa-cloud-download">导出报表</el-button> 312 + <div class="pagination-box" v-show="tabIndex == 1">
  313 + <el-pagination
  314 + small=""
  315 + layout="total,prev, pager, next"
  316 + :hide-on-single-page="true"
  317 + :total="total"
  318 + @current-change="changePage"
  319 + :current-page="page"
  320 + :page-size="size"
  321 + >
  322 + </el-pagination>
  323 + </div>
  324 + <p class="down" v-if="tabIndex == 3 || tabIndex == 2">
  325 + <el-button
  326 + @click="exportData"
  327 + type="info"
  328 + plain
  329 + round
  330 + icon="fa fa-cloud-download"
  331 + >导出报表</el-button
  332 + >
286 </p> 333 </p>
287 </div> 334 </div>
288 - <set-answer :diaVisible="dialogVisible" :questionList="form.questionList" :paperId="form.id" @saveSuccess="handleSuccess" @cancel="cancel"/> 335 + <set-answer
  336 + :diaVisible="dialogVisible"
  337 + :questionList="form.questionList"
  338 + :paperId="form.id"
  339 + @saveSuccess="handleSuccess"
  340 + @cancel="cancel"
  341 + />
289 </div> 342 </div>
290 </template> 343 </template>
291 344
292 <script> 345 <script>
293 -import { formatDate, deepClone, checkAnswer } from "utils"; 346 +import { formatDate, deepClone, downloadFile } from "utils";
294 export default { 347 export default {
295 data() { 348 data() {
296 return { 349 return {
297 role: "", 350 role: "",
298 loading: false, 351 loading: false,
299 - dialogVisible:false, 352 + dialogVisible: false,
300 form: { questionList: [] }, 353 form: { questionList: [] },
301 date: "", //今天-昨天-本周 354 date: "", //今天-昨天-本周
302 query: { 355 query: {
303 //搜索条件 356 //搜索条件
304 classId: "", 357 classId: "",
305 - subjectId: "", 358 + subjectNames: "",
306 startDay: "", 359 startDay: "",
307 endDay: "", 360 endDay: "",
308 day: "", 361 day: "",
309 }, 362 },
  363 + custom: {
  364 + //单课时排序
  365 + orderField: null,
  366 + orderType: null,
  367 + },
310 classList: [], //班级 368 classList: [], //班级
311 subjectList: [], //科目 369 subjectList: [], //科目
312 tabIndex: 1, //选项卡 370 tabIndex: 1, //选项卡
313 - tableData: [  
314 - //单课时报表  
315 - {  
316 - id: 1,  
317 - keshi: "课时一",  
318 - zongshu: 10,  
319 - shijian: "2022-11-9 21:30至22:30",  
320 - canyudu: 60,  
321 - zhengque: 90,  
322 - allzheng: 80,  
323 - questionList: [  
324 - {  
325 - questionTitle: "f",  
326 - score: 1,  
327 - subQuestions: [  
328 - {  
329 - questionIndex: 1,  
330 - questionType: 2,  
331 - score: 1,  
332 - partScore: 0,  
333 - selectNum: 4,  
334 - answerOptions: ["A", "B", "C", "D"],  
335 - correctAnswer: "B",  
336 - },  
337 - {  
338 - questionIndex: 2,  
339 - questionType: 2,  
340 - score: 1,  
341 - partScore: 0,  
342 - selectNum: 4,  
343 - answerOptions: ["A", "B", "C", "D", "E", "F"],  
344 - correctAnswer: "A",  
345 - },  
346 - {  
347 - questionIndex: 3,  
348 - questionType: 3,  
349 - score: 1,  
350 - partScore: 0,  
351 - selectNum: 4,  
352 - answerOptions: ["A", "B", "C", "D", "E", "F"],  
353 - correctAnswer: "AB",  
354 - },  
355 - {  
356 - questionIndex: 4,  
357 - questionType: 3,  
358 - score: 1,  
359 - partScore: 0,  
360 - selectNum: 4,  
361 - answerOptions: ["A", "B", "C", "D", "E", "F"],  
362 - correctAnswer: "AB",  
363 - },  
364 - {  
365 - questionIndex: 5,  
366 - questionType: 4,  
367 - score: 1,  
368 - partScore: 0,  
369 - selectNum: 0,  
370 - answerOptions: [],  
371 - correctAnswer: "1",  
372 - },  
373 - ],  
374 - },  
375 - {  
376 - questionTitle: "f",  
377 - score: 1,  
378 - subQuestions: [  
379 - {  
380 - questionIndex: 6,  
381 - questionType: 2,  
382 - score: 1,  
383 - partScore: 0,  
384 - selectNum: 4,  
385 - answerOptions: ["A", "B", "C", "D"],  
386 - correctAnswer: "B",  
387 - },  
388 - {  
389 - questionIndex: 7,  
390 - questionType: 2,  
391 - score: 1,  
392 - partScore: 0,  
393 - selectNum: 4,  
394 - answerOptions: ["A", "B", "C", "D", "E", "F"],  
395 - correctAnswer: "A",  
396 - },  
397 - {  
398 - questionIndex: 8,  
399 - questionType: 3,  
400 - score: 1,  
401 - partScore: 0,  
402 - selectNum: 4,  
403 - answerOptions: ["A", "B", "C", "D", "E", "F"],  
404 - correctAnswer: "AB",  
405 - },  
406 - {  
407 - questionIndex: 9,  
408 - questionType: 3,  
409 - score: 1,  
410 - partScore: 0,  
411 - selectNum: 4,  
412 - answerOptions: ["A", "B", "C", "D", "E", "F"],  
413 - correctAnswer: "AB",  
414 - },  
415 - {  
416 - questionIndex: 10,  
417 - questionType: 4,  
418 - score: 1,  
419 - partScore: 0,  
420 - selectNum: 0,  
421 - answerOptions: [],  
422 - correctAnswer: "1",  
423 - },  
424 - ],  
425 - },  
426 - ],  
427 - },  
428 - {  
429 - id: 2,  
430 - keshi: "课时二",  
431 - zongshu: 8,  
432 - shijian: "2022-11-10 21:30至22:30",  
433 - canyudu: 70,  
434 - zhengque: 80,  
435 - allzheng: 60,  
436 - questionList: [  
437 - {  
438 - questionTitle: "a",  
439 - score: 1,  
440 - subQuestions: [  
441 - {  
442 - questionIndex: 2,  
443 - questionType: 3,  
444 - score: 1,  
445 - partScore: 0,  
446 - selectNum: 4,  
447 - answerOptions: ["A", "B", "C", "D"],  
448 - correctAnswer: "A,C",  
449 - },  
450 - ],  
451 - },  
452 - ],  
453 - },  
454 - ],  
455 - tableAsk: [  
456 - {  
457 - xuehao: 1,  
458 - xingming: "丁芳菲",  
459 - cishu: 5,  
460 - dadui: 60,  
461 - canyudu: 90,  
462 - allzheng: 80,  
463 - yidazheng: 50,  
464 - zongpaiming: 5,  
465 - },  
466 - {  
467 - xuehao: 1,  
468 - xingming: "丁芳菲2",  
469 - cishu: 3,  
470 - dadui: 20,  
471 - canyudu: 80,  
472 - allzheng: 60,  
473 - yidazheng: 65,  
474 - zongpaiming: 4,  
475 - },  
476 - ],  
477 - tableStage: [  
478 - {  
479 - xuehao: 1,  
480 - xingming: "丁芳菲",  
481 - cishu: 5,  
482 - dadui: 60,  
483 - chouda: 90,  
484 - choudadui: 80,  
485 - canyu: 50,  
486 - duicuo: 5,  
487 - },  
488 - ], 371 + tableData: [],
  372 + page: 1,
  373 + size: 20,
  374 + total: 0,
489 }; 375 };
490 }, 376 },
491 async created() { 377 async created() {
492 - this.role = this.$store.getters.info.permissions.find(item=>item.roleName == this.$store.getters.info.showRoleName)?.role; 378 + this.role = this.$store.getters.info.permissions.find(
  379 + (item) => item.roleName == this.$store.getters.info.showRoleName
  380 + )?.role;
  381 + this.query.subjectNames = this.role == "ROLE_BANZHUREN" ? [] : "";
493 await this._QueryClassList(); 382 await this._QueryClassList();
494 await this._QuerySubjectList(); 383 await this._QuerySubjectList();
495 - // await this.setDate(1); 384 + await this.setDate(1);
496 let startDay = this.query?.startDay; 385 let startDay = this.query?.startDay;
497 if (!startDay) { 386 if (!startDay) {
498 this.query.startDay = new Date(); 387 this.query.startDay = new Date();
@@ -509,8 +398,7 @@ export default { @@ -509,8 +398,7 @@ export default {
509 }, 398 },
510 }); 399 });
511 }, 400 },
512 -  
513 - setDate(index) { 401 + setDate(index) {
514 const that = this; 402 const that = this;
515 this.date = index == this.date ? "" : index; 403 this.date = index == this.date ? "" : index;
516 let aYear = new Date().getFullYear(); 404 let aYear = new Date().getFullYear();
@@ -540,7 +428,7 @@ export default { @@ -540,7 +428,7 @@ export default {
540 that.query.endDay = formatDate(new Date(), "yyyy-MM-dd"); 428 that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
541 break; 429 break;
542 case 4: 430 case 4:
543 - if (aMonth > 1 && aMonth < 4) { 431 + if (aMonth > 0 && aMonth < 4) {
544 aMonth = "01"; 432 aMonth = "01";
545 } else if (aMonth > 3 && aMonth < 7) { 433 } else if (aMonth > 3 && aMonth < 7) {
546 aMonth = "04"; 434 aMonth = "04";
@@ -578,23 +466,57 @@ export default { @@ -578,23 +466,57 @@ export default {
578 } 466 }
579 } 467 }
580 }, 468 },
581 - edit(item) {  
582 - this.form = deepClone(item);  
583 - this.dialogVisible = true; 469 + async edit(item) {
  470 + if (this.editLoading) return;
  471 + this.editLoading = true;
  472 + const { data, status, info } = await this.$request.periodQuestionList({
  473 + periodId: item.id,
  474 + });
  475 + this.editLoading = false;
  476 + if (status === 0) {
  477 + this.form.id = item.id;
  478 + this.form.questionList = (data.list && [...data.list]) || [];
  479 + this.dialogVisible = true;
  480 + } else {
  481 + this.$message.error(info);
  482 + }
584 }, 483 },
585 - cancel(){  
586 - this.dialogVisible = false 484 + cancel() {
  485 + this.dialogVisible = false;
587 }, 486 },
588 - handleSuccess(){  
589 - this.dialogVisible = false  
590 - this._QueryData() 487 + handleSuccess() {
  488 + this.dialogVisible = false;
  489 + },
  490 + tabChange() {
  491 + this.page = 1;
  492 + this._QueryData();
  493 + },
  494 + sortChange(obj) {
  495 + this.custom.orderField =
  496 + obj.prop == "participationRate"
  497 + ? 1
  498 + : obj.prop == "answerCorrectRate"
  499 + ? 2
  500 + : 3;
  501 + this.custom.orderType = obj.order == "ascending" ? 0 : 1;
  502 + this.page = 1;
  503 + this._QueryData();
  504 + },
  505 + changePage(page) {
  506 + this.page = page;
  507 + this._QueryData();
591 }, 508 },
592 async changClazz() { 509 async changClazz() {
593 await this._QuerySubjectList(); 510 await this._QuerySubjectList();
594 - await this.setDate(1); 511 + // await this.setDate(1);
  512 + this._QueryData()
595 }, 513 },
596 async _QueryClassList() { 514 async _QueryClassList() {
597 - const { data, status, info } = await this.$request.fetchClassList(); 515 + const fetchClassList =
  516 + this.role == "ROLE_BANZHUREN"
  517 + ? this.$request.cTClassList
  518 + : this.$request.tClassList;
  519 + const { data, status, info } = await fetchClassList();
598 if (status === 0) { 520 if (status === 0) {
599 this.classList = data.list.map((item) => { 521 this.classList = data.list.map((item) => {
600 return { 522 return {
@@ -608,43 +530,170 @@ export default { @@ -608,43 +530,170 @@ export default {
608 } 530 }
609 }, 531 },
610 async _QuerySubjectList() { 532 async _QuerySubjectList() {
611 - const { data, status, info } = await this.$request.fetchSubjectList(  
612 - {classId: this.query.classId,}  
613 - ); 533 + const fetchSubjectList =
  534 + this.role == "ROLE_BANZHUREN"
  535 + ? this.$request.cTSubjectList
  536 + : this.$request.tSubjectList;
  537 +
  538 + const { data, status, info } = await fetchSubjectList({
  539 + classId: this.query.classId,
  540 + });
614 if (status === 0) { 541 if (status === 0) {
615 - this.subjectList = data.subjectNames?.map((item) => {  
616 - return {  
617 - value: item,  
618 - label: item,  
619 - };  
620 - })||[]; 542 + this.subjectList =
  543 + data.subjectNames?.map((item) => {
  544 + return {
  545 + value: item,
  546 + label: item,
  547 + };
  548 + }) || [];
621 if (this.role == "ROLE_BANZHUREN") { 549 if (this.role == "ROLE_BANZHUREN") {
622 this.subjectList.unshift({ 550 this.subjectList.unshift({
623 - value: "", 551 + value: "全部",
624 label: "全部", 552 label: "全部",
625 }); 553 });
626 - this.query.subjectId = [this.subjectList[0]?.value];  
627 - }else{  
628 - this.query.subjectId = this.subjectList[0]?.value; 554 + this.query.subjectNames.push(this.subjectList[0]?.value);
  555 + } else {
  556 + this.query.subjectNames = this.subjectList[0]?.value;
629 } 557 }
630 } else { 558 } else {
631 this.$message.error(info); 559 this.$message.error(info);
632 } 560 }
633 }, 561 },
634 async _QueryData() { 562 async _QueryData() {
  563 + if (this.tabIndex == 1) {
  564 + this.periodReportList();
  565 + } else if (this.tabIndex == 2) {
  566 + this.phaseAnswerReport();
  567 + } else if (this.tabIndex == 3) {
  568 + this.phaseInteractiveReport();
  569 + }
  570 + },
  571 + //分页查询课时报表列表
  572 + async periodReportList() {
635 this.loading = true; 573 this.loading = true;
636 - //多课时对比  
637 let query = {}; 574 let query = {};
638 for (let key in this.query) { 575 for (let key in this.query) {
639 if (this.query[key] != "") { 576 if (this.query[key] != "") {
640 query[key] = this.query[key]; 577 query[key] = this.query[key];
641 } 578 }
642 } 579 }
643 - const { data, status, info } = await this.$request.fetchQuizList({ 580 + if (this.custom.orderField !== null) {
  581 + query = { ...query, ...this.custom };
  582 + }
  583 + if (this.role != "ROLE_BANZHUREN") {
  584 + query.subjectNames = [query.subjectNames];
  585 + } else {
  586 + if (
  587 + query["subjectNames"].length == 1 &&
  588 + query["subjectNames"][0] == "全部"
  589 + ) {
  590 + query["subjectNames"] = this.subjectList.map((item) => {
  591 + return item.value;
  592 + });
  593 + query["subjectNames"].shift();
  594 + }
  595 + }
  596 + const { data, status, info } = await this.$request.periodReportList({
  597 + ...query,
  598 + page: this.page,
  599 + size: this.size,
  600 + });
  601 + this.loading = false;
  602 + if (status === 0) {
  603 + this.tableData = (data?.list && [...data?.list]) || [];
  604 + this.total = data.count;
  605 + } else {
  606 + this.$message.error(info);
  607 + }
  608 + },
  609 + //查询阶段问答报表
  610 + async phaseAnswerReport() {
  611 + this.loading = true;
  612 + let query = {};
  613 + for (let key in this.query) {
  614 + if (this.query[key] != "") {
  615 + if (key == "subjectNames" && this.role != "ROLE_BANZHUREN") {
  616 + query["subjectName"] = this.query[key];
  617 + } else {
  618 + query[key] = this.query[key];
  619 + }
  620 + }
  621 + }
  622 + if (this.role == "ROLE_BANZHUREN") {
  623 + if (
  624 + query["subjectNames"].length == 1 &&
  625 + query["subjectNames"][0] == "全部"
  626 + ) {
  627 + query["subjectNames"] = this.subjectList.map((item) => {
  628 + return item.value;
  629 + });
  630 + query["subjectNames"].shift();
  631 + }
  632 + }
  633 + const phaseAnswerReport =
  634 + this.role == "ROLE_BANZHUREN"
  635 + ? this.$request.cTPhaseAnswerReport
  636 + : this.$request.phaseAnswerReport;
  637 +
  638 + const { data, status, info } = await phaseAnswerReport({
644 ...query, 639 ...query,
645 }); 640 });
646 this.loading = false; 641 this.loading = false;
647 if (status === 0) { 642 if (status === 0) {
  643 + this.tableData = (data?.list && [...data?.list]) || [];
  644 + this.total = data.count;
  645 + } else {
  646 + this.$message.error(info);
  647 + }
  648 + },
  649 + //查询阶段互动报表
  650 + async phaseInteractiveReport() {
  651 + this.loading = true;
  652 + let query = {};
  653 + for (let key in this.query) {
  654 + if (this.query[key] != "") {
  655 + if (key == "subjectNames" && this.role != "ROLE_BANZHUREN") {
  656 + query["subjectName"] = this.query[key];
  657 + } else {
  658 + query[key] = this.query[key];
  659 + }
  660 + }
  661 + }
  662 + if (this.role == "ROLE_BANZHUREN") {
  663 + if (
  664 + query["subjectNames"].length == 1 &&
  665 + query["subjectNames"][0] == "全部"
  666 + ) {
  667 + query["subjectNames"] = this.subjectList.map((item) => {
  668 + return item.value;
  669 + });
  670 + query["subjectNames"].shift();
  671 + }
  672 + }
  673 + const phaseInteractiveReport =
  674 + this.role == "ROLE_BANZHUREN"
  675 + ? this.$request.cTPhaseInteractiveReport
  676 + : this.$request.phaseInteractiveReport;
  677 +
  678 + const { data, status, info } = await phaseInteractiveReport({
  679 + ...query,
  680 + });
  681 + this.loading = false;
  682 + if (status === 0) {
  683 + this.tableData = (data?.list && [...data?.list]) || [];
  684 + this.total = data.count;
  685 + } else {
  686 + this.$message.error(info);
  687 + }
  688 + },
  689 + //导出
  690 + async exportData() {
  691 + if ((this.exportLoading = true)) return;
  692 + this.exportLoading = true;
  693 + const { data, status, info } = await this.$request.exportData();
  694 + this.exportLoading = false;
  695 + if (data) {
  696 + downloadFile("报表", data);
648 } else { 697 } else {
649 this.$message.error(info); 698 this.$message.error(info);
650 } 699 }
@@ -667,7 +716,6 @@ export default { @@ -667,7 +716,6 @@ export default {
667 } 716 }
668 } 717 }
669 718
670 -  
671 .fa-exchange { 719 .fa-exchange {
672 color: #667ffd; 720 color: #667ffd;
673 cursor: pointer; 721 cursor: pointer;
src/views/examinationPaper/add.vue
@@ -836,12 +836,12 @@ export default { @@ -836,12 +836,12 @@ export default {
836 this.saveLoading = true; 836 this.saveLoading = true;
837 //添加题目ID、序号 837 //添加题目ID、序号
838 this.form.questionList.map((item, index) => { 838 this.form.questionList.map((item, index) => {
839 - item.questionId = index + 1;  
840 - item.questionIndex = index + 1; 839 + // item.questionId = index + 1;
  840 + // item.questionIndex = index + 1;
841 item.questionType = 0; 841 item.questionType = 0;
842 item.subQuestions.map((items, indexs) => { 842 item.subQuestions.map((items, indexs) => {
843 - items.questionId = indexs + 1;  
844 - items.questionIndex = indexs + 1; 843 + items.questionId = this.setNum(index,indexs)
  844 + items.questionIndex = this.setNum(index,indexs);
845 }); 845 });
846 }); 846 });
847 const { data, status, info } = await this.$request.addPaper({ 847 const { data, status, info } = await this.$request.addPaper({
src/views/index/mainIndex.vue
@@ -204,10 +204,12 @@ export default { @@ -204,10 +204,12 @@ export default {
204 }); 204 });
205 if (this.type == "ROLE_XUEXIAO") { 205 if (this.type == "ROLE_XUEXIAO") {
206 this.schoolIndex(); 206 this.schoolIndex();
207 - } else if (this.type == "ROLE_JIAOSHI" || this.type == "ROLE_BANZHUREN") { 207 + } else if (this.type == "ROLE_JIAOSHI" ) {
208 this.teacherIndex(); 208 this.teacherIndex();
209 } else if (this.type == "ROLE_JITUAN") { 209 } else if (this.type == "ROLE_JITUAN") {
210 this.tenantIndex(); 210 this.tenantIndex();
  211 + }else if (this.type == "ROLE_BANZHUREN") {
  212 + this.classIndex();
211 } 213 }
212 }, 214 },
213 methods: { 215 methods: {
@@ -243,6 +245,14 @@ export default { @@ -243,6 +245,14 @@ export default {
243 this.$message.error(info); 245 this.$message.error(info);
244 } 246 }
245 }, 247 },
  248 + async classIndex() {
  249 + const { data, status, info } = await this.$request.classIndex();
  250 + if (status === 0) {
  251 + this.dataInfo = { ...data };
  252 + } else {
  253 + this.$message.error(info);
  254 + }
  255 + },
246 }, 256 },
247 }; 257 };
248 </script> 258 </script>
src/views/login/index.vue
@@ -93,12 +93,16 @@ export default { @@ -93,12 +93,16 @@ export default {
93 loginForm: { 93 loginForm: {
94 // username: "15911715665", 94 // username: "15911715665",
95 // password: "Csiy88888", 95 // password: "Csiy88888",
96 - username: "13610050254",  
97 - password: "Pw050254#",  
98 - // username: "18946034886",  
99 - // password: "Pw034886#", 96 + // username: "13610050254",
  97 + // password: "Pw050254#",
100 // username: "18332123505", 98 // username: "18332123505",
101 // password: "Pw123505#", 99 // password: "Pw123505#",
  100 + // username: "18946034886",
  101 + // password: "Pw034886#",
  102 + // username: "18893712576",
  103 + // password: "Pw712576#",
  104 + username: "13247726488",
  105 + password: "726488",
102 106
103 }, 107 },
104 loginRules: { 108 loginRules: {
@@ -184,9 +188,9 @@ $cursor: #000; @@ -184,9 +188,9 @@ $cursor: #000;
184 border-radius: 0px; 188 border-radius: 0px;
185 font-size: 16px; 189 font-size: 16px;
186 color: $light_gray; 190 color: $light_gray;
187 - height: 52px; 191 + height:48px;
  192 + line-height: 48px;
188 caret-color: $cursor; 193 caret-color: $cursor;
189 -  
190 &:-webkit-autofill { 194 &:-webkit-autofill {
191 box-shadow: 0 0 0px 1000px #e5e5e5 inset !important; 195 box-shadow: 0 0 0px 1000px #e5e5e5 inset !important;
192 -webkit-text-fill-color: $cursor !important; 196 -webkit-text-fill-color: $cursor !important;
src/views/setUp/account.vue
@@ -194,11 +194,6 @@ @@ -194,11 +194,6 @@
194 > 194 >
195 </el-pagination> 195 </el-pagination>
196 </div> 196 </div>
197 - <el-empty  
198 - v-if="!loading && tableData.length == 0"  
199 - content="没有更多数据"  
200 - :image-size="100"  
201 - ></el-empty>  
202 </div> 197 </div>
203 <el-dialog title="修改账号信息" :visible.sync="diaCount" width="400"> 198 <el-dialog title="修改账号信息" :visible.sync="diaCount" width="400">
204 <el-form 199 <el-form
@@ -288,7 +283,7 @@ @@ -288,7 +283,7 @@
288 </el-select> 283 </el-select>
289 </el-col> 284 </el-col>
290 </el-form-item> 285 </el-form-item>
291 - <el-form-item label="选择管辖范围:" prop="regionId"> 286 + <el-form-item label="选择管辖范围:" :prop="formAddCount.roleId == 3?'regionId':'schoolId'">
292 <el-col :span="12"> 287 <el-col :span="12">
293 <el-select 288 <el-select
294 v-show="formAddCount.roleId == 3" 289 v-show="formAddCount.roleId == 3"
@@ -385,7 +380,7 @@ export default { @@ -385,7 +380,7 @@ export default {
385 password: "", 380 password: "",
386 roleId: "", 381 roleId: "",
387 regionId: "", 382 regionId: "",
388 - schoolId:"" 383 + schoolId: "",
389 }, 384 },
390 addSelectSchoolList: [], 385 addSelectSchoolList: [],
391 ruleAddCount: { 386 ruleAddCount: {
@@ -396,6 +391,9 @@ export default { @@ -396,6 +391,9 @@ export default {
396 regionId: [ 391 regionId: [
397 { required: true, message: "请选择权限区域", trigger: "blur" }, 392 { required: true, message: "请选择权限区域", trigger: "blur" },
398 ], 393 ],
  394 + schoolId: [
  395 + { required: true, message: "请选择权限区域", trigger: "blur" },
  396 + ],
399 }, 397 },
400 }; 398 };
401 }, 399 },
@@ -460,7 +458,11 @@ export default { @@ -460,7 +458,11 @@ export default {
460 }); 458 });
461 }, 459 },
462 setCount(obj) { 460 setCount(obj) {
463 - this.formCount.userId = obj.userId; 461 + if (this.role != "ROLE_JITUAN") {
  462 + this.formCount.userId = obj.userId;
  463 + } else {
  464 + this.formCount.id = obj.id;
  465 + }
464 this.formCount.loginName = obj.loginName; 466 this.formCount.loginName = obj.loginName;
465 this.formCount.realName = obj.realName; 467 this.formCount.realName = obj.realName;
466 this.diaCount = true; 468 this.diaCount = true;
@@ -533,19 +535,21 @@ export default { @@ -533,19 +535,21 @@ export default {
533 } 535 }
534 }, 536 },
535 async updateUser(obj, type) { 537 async updateUser(obj, type) {
536 - let query = {  
537 - userId: obj.id,  
538 - type: type,  
539 - }; 538 + let query = {};
  539 + console.log(query);
540 if (type == 1) { 540 if (type == 1) {
541 query.available = obj.available == 0 ? 1 : 0; 541 query.available = obj.available == 0 ? 1 : 0;
542 } 542 }
543 const { data, status, info } = 543 const { data, status, info } =
544 this.role != "ROLE_JITUAN" 544 this.role != "ROLE_JITUAN"
545 ? await this.$request.updateUser({ 545 ? await this.$request.updateUser({
  546 + userId: obj.userId,
  547 + type: type,
546 ...query, 548 ...query,
547 }) 549 })
548 : await this.$request.tenantUpdateUser({ 550 : await this.$request.tenantUpdateUser({
  551 + id: obj.id,
  552 + type: type,
549 ...query, 553 ...query,
550 }); 554 });
551 if (status === 0) { 555 if (status === 0) {
src/views/setUp/student.vue
@@ -143,7 +143,7 @@ @@ -143,7 +143,7 @@
143 </el-form-item> 143 </el-form-item>
144 <el-form-item label="答题器编码:"> 144 <el-form-item label="答题器编码:">
145 <el-col :span="10"> 145 <el-col :span="10">
146 - <el-input maxlength="8" v-model.trim="formStu.clickerSn" /> 146 + <el-input v-model.trim="formStu.clickerSn" />
147 </el-col> 147 </el-col>
148 </el-form-item> 148 </el-form-item>
149 </el-form> 149 </el-form>
src/views/setUp/teacher.vue
@@ -252,7 +252,7 @@ @@ -252,7 +252,7 @@
252 <el-col :span="10"> 252 <el-col :span="10">
253 <el-input 253 <el-input
254 type="number" 254 type="number"
255 - moninput="if(value.length > 11) value = value.slice(0,11)" 255 + oninput="if(value.length > 11) value = value.slice(0,11)"
256 v-model.trim="formTeacher.loginName" 256 v-model.trim="formTeacher.loginName"
257 /> 257 />
258 </el-col> 258 </el-col>
@@ -442,7 +442,7 @@ export default { @@ -442,7 +442,7 @@ export default {
442 teacherName: "", 442 teacherName: "",
443 loginName: "", 443 loginName: "",
444 sex: 1, 444 sex: 1,
445 - managerList: [], 445 + roleList: [],
446 }; 446 };
447 this.diaTeacher = true; 447 this.diaTeacher = true;
448 }, 448 },
src/views/test/analysis.vue
1 <template> 1 <template>
2 - <div> 2 + <div class="page-container" :class="dialogVisible ? 'active' : ''">
3 <back-box> 3 <back-box>
4 <template slot="title"> 4 <template slot="title">
5 <span>单卷分析</span> 5 <span>单卷分析</span>
@@ -13,8 +13,10 @@ @@ -13,8 +13,10 @@
13 }}修改了答案,是否重新记分? 13 }}修改了答案,是否重新记分?
14 </p> 14 </p>
15 <div class="btn-box"> 15 <div class="btn-box">
16 - <el-button type="danger" round size="mini">重新计分</el-button>  
17 - <el-button type="danger" round plain size="mini">暂时不计</el-button> 16 + <el-button type="danger" round @click="_ReScore" size="mini"
  17 + >重新计分</el-button
  18 + >
  19 + <el-button type="danger" round plain size="mini" @click="paperModifyLog.modifiedTime = ''">暂时不计</el-button>
18 </div> 20 </div>
19 </div> 21 </div>
20 <div class="page-content"> 22 <div class="page-content">
@@ -44,54 +46,48 @@ @@ -44,54 +46,48 @@
44 >作答明细表</span 46 >作答明细表</span
45 > 47 >
46 </div> 48 </div>
47 - <el-table  
48 - v-if="type == 1"  
49 - :data="tableData"  
50 - border  
51 - style="width: 100%"  
52 - :default-sort="{ prop: 'dadui', order: 'descending' }"  
53 - >  
54 - <el-table-column prop="questionIndex" label="题号" align="center"  
55 - ><template slot-scope="scoped"  
56 - >Q{{ scoped.row.questionIndex }}</template  
57 - ></el-table-column  
58 - > 49 + <el-table v-if="type == 1" :data="tableData" border style="width: 100%">
59 <el-table-column 50 <el-table-column
60 - prop="questionType"  
61 - label="题型" 51 + prop="questionIndex"
  52 + label="题号"
62 align="center" 53 align="center"
63 ></el-table-column> 54 ></el-table-column>
  55 + <el-table-column prop="questionType" label="题型" align="center"
  56 + ><template slot-scope="scope">{{
  57 + setSubPro(scope.row.questionType)
  58 + }}</template></el-table-column
  59 + >
64 <el-table-column 60 <el-table-column
65 - prop="manfen" 61 + prop="score"
66 label="满分值" 62 label="满分值"
67 sortable 63 sortable
68 align="center" 64 align="center"
69 ></el-table-column> 65 ></el-table-column>
70 <el-table-column 66 <el-table-column
71 - prop="zuigao" 67 + prop="highestScore"
72 label="班最高分" 68 label="班最高分"
73 sortable 69 sortable
74 align="center" 70 align="center"
75 ></el-table-column> 71 ></el-table-column>
76 <el-table-column 72 <el-table-column
77 - prop="zuidi" 73 + prop="lowestScore"
78 label="班最低分" 74 label="班最低分"
79 sortable 75 sortable
80 align="center" 76 align="center"
81 ></el-table-column> 77 ></el-table-column>
82 <el-table-column 78 <el-table-column
83 - prop="pingjun" 79 + prop="avgScore"
84 label="班平均分" 80 label="班平均分"
85 sortable 81 sortable
86 align="center" 82 align="center"
87 ></el-table-column> 83 ></el-table-column>
88 <el-table-column 84 <el-table-column
89 - prop="defenlv" 85 + prop="scoringRate"
90 sortable 86 sortable
91 label="班级得分率" 87 label="班级得分率"
92 align="center" 88 align="center"
93 ><template slot-scope="scoped" 89 ><template slot-scope="scoped"
94 - >{{ scoped.row.defenlv }}%</template 90 + >{{ scoped.row.scoringRate }}%</template
95 ></el-table-column 91 ></el-table-column
96 > 92 >
97 <el-table-column 93 <el-table-column
@@ -100,20 +96,12 @@ @@ -100,20 +96,12 @@
100 align="center" 96 align="center"
101 ></el-table-column> 97 ></el-table-column>
102 <el-table-column 98 <el-table-column
103 - prop="x1"  
104 - label="选项1"  
105 - align="center"  
106 - ></el-table-column>  
107 - <el-table-column  
108 - prop="x2"  
109 - label="选项1"  
110 - align="center"  
111 - ></el-table-column>  
112 - <el-table-column  
113 - prop="weida"  
114 - label="未答"  
115 - align="center"  
116 - ></el-table-column> 99 + v-for="(item, index) in optionsList"
  100 + :key="index"
  101 + :label="item.option"
  102 + :prop="item.option"
  103 + >
  104 + </el-table-column>
117 </el-table> 105 </el-table>
118 <el-table 106 <el-table
119 v-if="type == 2" 107 v-if="type == 2"
@@ -123,91 +111,100 @@ @@ -123,91 +111,100 @@
123 :default-sort="{ prop: 'dadui', order: 'descending' }" 111 :default-sort="{ prop: 'dadui', order: 'descending' }"
124 > 112 >
125 <el-table-column 113 <el-table-column
126 - prop="xuehao" 114 + prop="studentCode"
127 label="学号" 115 label="学号"
128 align="center" 116 align="center"
129 fixed 117 fixed
130 ></el-table-column> 118 ></el-table-column>
131 <el-table-column 119 <el-table-column
132 - prop="xingming" 120 + prop="studentName"
133 label="姓名" 121 label="姓名"
134 fixed 122 fixed
135 align="center" 123 align="center"
136 ></el-table-column> 124 ></el-table-column>
137 <el-table-column 125 <el-table-column
138 - prop="totalScore" 126 + prop="examPaperScore"
139 label="总分" 127 label="总分"
140 sortable 128 sortable
141 align="center" 129 align="center"
142 ></el-table-column> 130 ></el-table-column>
143 <el-table-column 131 <el-table-column
144 - prop="defenlv" 132 + prop="scoringRate"
145 label="得分率" 133 label="得分率"
146 sortable 134 sortable
147 align="center" 135 align="center"
148 - ></el-table-column> 136 + ><template slot-scope="scope"
  137 + >{{ scope.row.scoringRate }}%</template
  138 + ></el-table-column
  139 + >
149 <el-table-column 140 <el-table-column
150 - prop="rank" 141 + prop="classRank"
151 label="班名" 142 label="班名"
152 sortable 143 sortable
153 align="center" 144 align="center"
154 ></el-table-column> 145 ></el-table-column>
155 <el-table-column label="客观题" align="center"> 146 <el-table-column label="客观题" align="center">
156 <el-table-column 147 <el-table-column
157 - prop="defen1" 148 + prop="objectiveExamScore"
158 label="得分" 149 label="得分"
159 align="center" 150 align="center"
160 ></el-table-column> 151 ></el-table-column>
161 <el-table-column 152 <el-table-column
162 - prop="defenlv1" 153 + prop="objectiveScoringRate"
163 label="得分率" 154 label="得分率"
164 align="center" 155 align="center"
165 - ></el-table-column> 156 + ><template slot-scope="scope"
  157 + >{{ scope.row.objectiveScoringRate }}%</template
  158 + ></el-table-column
  159 + >
166 </el-table-column> 160 </el-table-column>
167 <el-table-column label="主观题" align="center"> 161 <el-table-column label="主观题" align="center">
168 <el-table-column 162 <el-table-column
169 - prop="defen2" 163 + prop="subjectiveExamScore"
170 label="得分" 164 label="得分"
171 align="center" 165 align="center"
172 ></el-table-column> 166 ></el-table-column>
173 <el-table-column 167 <el-table-column
174 - prop="defenlv2" 168 + prop="subjectiveScoringRate"
175 label="得分率" 169 label="得分率"
176 align="center" 170 align="center"
177 - ></el-table-column> 171 + ><template slot-scope="scope"
  172 + >{{ scope.row.subjectiveScoringRate }}%</template
  173 + ></el-table-column
  174 + >
178 </el-table-column> 175 </el-table-column>
179 </el-table> 176 </el-table>
180 <el-table 177 <el-table
181 v-if="type == 3" 178 v-if="type == 3"
182 - :data="tableData3" 179 + :data="tableData2"
183 border 180 border
184 style="width: 100%" 181 style="width: 100%"
185 :default-sort="{ prop: '', order: 'descending' }" 182 :default-sort="{ prop: '', order: 'descending' }"
186 > 183 >
187 <el-table-column 184 <el-table-column
188 - prop="xuehao" 185 + prop="studentCode"
189 label="学号" 186 label="学号"
190 align="center" 187 align="center"
191 ></el-table-column> 188 ></el-table-column>
192 <el-table-column 189 <el-table-column
193 - prop="xingming" 190 + prop="studentName"
194 label="姓名" 191 label="姓名"
195 align="center" 192 align="center"
196 ></el-table-column> 193 ></el-table-column>
197 <el-table-column 194 <el-table-column
198 - prop="totalScore" 195 + prop="examPaperScore"
199 label="总分" 196 label="总分"
200 sortable 197 sortable
201 align="center" 198 align="center"
202 ></el-table-column> 199 ></el-table-column>
203 <el-table-column label="分数组成" align="center"> 200 <el-table-column label="分数组成" align="center">
204 <el-table-column 201 <el-table-column
205 - prop="keguan" 202 + prop="objectiveScore"
206 label="客观题分" 203 label="客观题分"
207 align="center" 204 align="center"
208 ></el-table-column> 205 ></el-table-column>
209 <el-table-column 206 <el-table-column
210 - prop="zhuguan" 207 + prop="subjectiveScore"
211 label="主观题分" 208 label="主观题分"
212 align="center" 209 align="center"
213 ></el-table-column> 210 ></el-table-column>
@@ -216,43 +213,35 @@ @@ -216,43 +213,35 @@
216 align="center" 213 align="center"
217 v-for="(item, index) in questionList" 214 v-for="(item, index) in questionList"
218 :key="index" 215 :key="index"
219 - :label="item.title"  
220 - 216 + :label="'题目' + item.id"
  217 + :prop="'score' + item.id"
221 > 218 >
222 - <template v-for="items in item.subQuestions">  
223 - <el-table-column  
224 - :key="items.questionIndex"  
225 - :prop="'score' + items.questionIndex"  
226 - :label="`${items.questionIndex}`"  
227 - align="center"  
228 - ></el-table-column>  
229 - </template>  
230 </el-table-column> 219 </el-table-column>
231 </el-table> 220 </el-table>
232 <el-table 221 <el-table
233 v-if="type == 4" 222 v-if="type == 4"
234 - :data="tableData4" 223 + :data="tableData2"
235 border 224 border
236 style="width: 100%" 225 style="width: 100%"
237 :default-sort="{ prop: '', order: 'descending' }" 226 :default-sort="{ prop: '', order: 'descending' }"
238 > 227 >
239 <el-table-column 228 <el-table-column
240 - prop="xuehao" 229 + prop="studentCode"
241 label="学号" 230 label="学号"
242 align="center" 231 align="center"
243 ></el-table-column> 232 ></el-table-column>
244 <el-table-column 233 <el-table-column
245 - prop="xingming" 234 + prop="studentName"
246 label="姓名" 235 label="姓名"
247 align="center" 236 align="center"
248 ></el-table-column> 237 ></el-table-column>
249 <el-table-column 238 <el-table-column
250 - prop="banji" 239 + prop="className"
251 label="班级" 240 label="班级"
252 align="center" 241 align="center"
253 ></el-table-column> 242 ></el-table-column>
254 <el-table-column 243 <el-table-column
255 - prop="totalScore" 244 + prop="examPaperScore"
256 label="总分" 245 label="总分"
257 sortable 246 sortable
258 align="center" 247 align="center"
@@ -261,129 +250,306 @@ @@ -261,129 +250,306 @@
261 align="center" 250 align="center"
262 v-for="(item, index) in questionList" 251 v-for="(item, index) in questionList"
263 :key="index" 252 :key="index"
264 - :label="item.title" 253 + :label="'题目' + item.id"
265 > 254 >
266 - <template v-for="items in item.subQuestions">  
267 - <el-table-column  
268 - :key="items.questionIndex"  
269 - :prop="'daan' + items.questionIndex"  
270 - :label="`${items.questionIndex}`"  
271 - align="center"  
272 - ></el-table-column> 255 + <template slot-scope="scope">
  256 + <span
  257 + v-if="scope.row['answer' + item.id]"
  258 + :class="scope.row['isRight' + item.id] ? '' : 'error'"
  259 + >
  260 + {{ scope.row["answer" + item.id] }}
  261 + </span>
  262 + <span
  263 + v-else
  264 + :class="scope.row['questionType' + item.id] == 5 ? '' : 'error'"
  265 + >
  266 + {{ scope.row["questionType" + item.id] == 5 ? "*" : "-" }}
  267 + </span>
273 </template> 268 </template>
274 </el-table-column> 269 </el-table-column>
275 </el-table> 270 </el-table>
  271 + <div class="pagination-box" v-show="type == 1">
  272 + <el-pagination
  273 + small=""
  274 + layout="total,prev, pager, next"
  275 + :hide-on-single-page="true"
  276 + :total="total"
  277 + @current-change="changePage"
  278 + :current-page="page"
  279 + :page-size="size"
  280 + >
  281 + </el-pagination>
  282 + </div>
  283 + <div class="down">
  284 + <el-button
  285 + @click="exportData"
  286 + type="info"
  287 + plain
  288 + round
  289 + icon="fa fa-cloud-download"
  290 + >导出报表</el-button
  291 + >
  292 + <div>
  293 + <el-button
  294 + @click="diaUp = true"
  295 + type="primary"
  296 + round
  297 + v-loading="exportLoading"
  298 + >导入主观题分数</el-button
  299 + >
  300 + <el-button @click="edit" type="primary" round>设置答案</el-button>
  301 + </div>
  302 + </div>
  303 + <div class="edit-dia" v-show="dialogVisible" height="100%">
  304 + <editAnswer
  305 + :id="id"
  306 + :title="title"
  307 + :score="score"
  308 + @cancel="cancel"
  309 + @saveSuccess="saveSuccess"
  310 + />
  311 + </div>
  312 + <el-dialog title="导入主观题分数" :visible.sync="diaUp" width="600">
  313 + <up-load :url="url" :examId="id" fileName="教师名单">
  314 + <template slot="down">
  315 + <p class="down-txt">
  316 + 第一步:下载模板并编辑完成学生分数
  317 + <el-link type="danger" @click="downExcel">模板下载</el-link> 。
  318 + </p>
  319 + <p class="down-txt">第二步:上传完成编辑的模板文件并导入。</p>
  320 + </template>
  321 + </up-load>
  322 + <div class="dialog-footer" slot="footer">
  323 + <el-button @click="diaUp = false">取 消</el-button>
  324 + </div>
  325 + </el-dialog>
276 </div> 326 </div>
277 </div> 327 </div>
278 </template> 328 </template>
279 329
280 <script> 330 <script>
  331 +import { downloadFile } from "@/utils";
  332 +import editAnswer from "./editAnswer.vue";
281 export default { 333 export default {
  334 + components: { editAnswer },
282 data() { 335 data() {
283 return { 336 return {
  337 + loading: false,
  338 + exportLoading: false,
  339 + diaUp: false,
  340 + dialogVisible: false,
  341 + url: "/api_html/teaching/importSubjectiveScore",
284 id: "", 342 id: "",
  343 + title: "",
  344 + score: "",
285 type: 1, 345 type: 1,
286 paperModifyLog: { 346 paperModifyLog: {
287 - realName: "张老师",  
288 - modifiedTime: "12-20", 347 + realName: "",
  348 + modifiedTime: "",
289 }, 349 },
290 - tableData: [  
291 - {  
292 - questionIndex: 1,  
293 - questionType: "单选题",  
294 - manfen: 100,  
295 - zuigao: 100,  
296 - zuidi: 20,  
297 - pingjun: 80,  
298 - defenlv: 90,  
299 - correctAnswer: "A",  
300 - x1: "A",  
301 - x2: "B",  
302 - weida: "",  
303 - },  
304 - {  
305 - questionIndex: 2,  
306 - questionType: "单选题",  
307 - manfen: 100,  
308 - zuigao: 99,  
309 - zuidi: 50,  
310 - pingjun: 90,  
311 - defenlv: 100,  
312 - correctAnswer: "B",  
313 - x1: "A",  
314 - x2: "B",  
315 - weida: "",  
316 - },  
317 - ],  
318 - tableData2: [  
319 - {  
320 - xuehao: 1,  
321 - xingming: "丁芳菲",  
322 - totalScore: 5,  
323 - defenlv: 50,  
324 - rank: 1,  
325 - defen1: 1,  
326 - defenlv1: 1,  
327 - defen2: 1,  
328 - defenlv2: 1,  
329 - },  
330 - ],  
331 - tableData3: [  
332 - {  
333 - xuehao: 1,  
334 - xingming: "丁芳菲",  
335 - totalScore: 5,  
336 - rank: 1,  
337 - keguan: 20,  
338 - zhuguan: 20,  
339 - score1: 1,  
340 - score2: 2,  
341 - score3: 3,  
342 - score4: 4,  
343 - },  
344 - ],  
345 - tableData4: [  
346 - {  
347 - xuehao: 1,  
348 - xingming: "丁芳菲",  
349 - banji: 'xx',  
350 - totalScore: 5,  
351 - daan1: 1,  
352 - daan2: 2,  
353 - daan3: 3,  
354 - daan4: 4,  
355 - },  
356 - ],  
357 - questionList: [{  
358 - title:'大题1',  
359 - subQuestions:[  
360 - {questionIndex:1, daan:1},  
361 - {questionIndex:2, daan:1},  
362 - ]  
363 - },{  
364 - title:'大题2',  
365 - subQuestions:[  
366 - {questionIndex:3, daan:2},  
367 - {questionIndex:4, daan:2},  
368 - ]  
369 - }], 350 + tableData: [],
  351 + optionsList: [],
  352 + tableData2: [],
  353 + questionList: [],
  354 + page: 1,
  355 + size: 20,
  356 + total: 0,
370 }; 357 };
371 }, 358 },
372 created() { 359 created() {
373 this.id = this.$route.query.id; 360 this.id = this.$route.query.id;
374 - // this._QueryData() 361 + this.title = this.$route.query.title || "";
  362 + this.score = this.$route.query.score || "";
  363 + this._QueryData();
375 }, 364 },
376 methods: { 365 methods: {
  366 + setSubPro(type) {
  367 + let tit;
  368 + switch (type) {
  369 + case 2:
  370 + tit = "单选题";
  371 + break;
  372 + case 3:
  373 + tit = "多选题";
  374 + break;
  375 + case 4:
  376 + tit = "判断题";
  377 + break;
  378 + case 5:
  379 + tit = "主观题";
  380 + break;
  381 + }
  382 + return tit;
  383 + },
  384 + edit() {
  385 + this.dialogVisible = true;
  386 + },
  387 + cancel() {
  388 + this.dialogVisible = false;
  389 + },
  390 + saveSuccess() {
  391 + this.dialogVisible = false;
  392 + this._QueryData();
  393 + },
  394 + changePage(page) {
  395 + this.page = page;
  396 + this.examQuestionReport();
  397 + },
  398 + async downExcel() {
  399 + let data = await this.$request.subjectiveScoreTemplate({
  400 + examId: this.id,
  401 + });
  402 + if (data && !data.code) {
  403 + let blob = new Blob([data], {
  404 + type: "application/vnd.ms-excel;charset=utf-8",
  405 + });
  406 + downloadFile(`主观题模版.xlsx`, blob);
  407 + } else {
  408 + this.$message.error(data.message);
  409 + }
  410 + },
377 async _QueryData() { 411 async _QueryData() {
378 - let { data, info, status } = this.$request.quizDetail({  
379 - id: this.id, 412 + this.examDetail();
  413 + this.examStudentReport();
  414 + this.examQuestionReport();
  415 + },
  416 + async examDetail() {
  417 + //详情
  418 + this.loading = true;
  419 + let { data, info, status } = await this.$request.examDetail({
  420 + examId: this.id,
380 }); 421 });
  422 + this.loading = false;
  423 + if (status === 0) {
  424 + if (data.paperModifyLog) {
  425 + this.paperModifyLog = { ...data.paperModifyLog };
  426 + }
  427 + } else {
  428 + this.$message.error(info);
  429 + }
  430 + },
  431 + async _ReScore() {
  432 + //重新记分
  433 + this.loading = true;
  434 + let { data, info, status } = await this.$request.reScore({
  435 + examId: this.id,
  436 + });
  437 + this.loading = false;
  438 + if (status === 0) {
  439 + this.$message.success(info);
  440 + this._QueryData()
  441 + this.paperModifyLog.modifiedTime=""
  442 + this.paperModifyLog.realName=""
  443 + } else {
  444 + this.$message.error(info);
  445 + }
  446 + },
  447 + async examStudentReport() {
  448 + //成绩排名-小题分-作答明细
  449 + this.loading = true;
  450 + let { data, info, status } = await this.$request.examStudentReport({
  451 + examId: this.id,
  452 + });
  453 + this.loading = false;
  454 + if (status === 0) {
  455 + let optionsList = [];
  456 + this.tableData2 = data?.list.map((item) => {
  457 + let params = {};
  458 +
  459 + const detail = JSON.parse(item.detail);
  460 + if (detail.length > optionsList.length) {
  461 + optionsList = [...detail];
  462 + }
  463 + console.log(detail);
  464 + detail.map((items, index) => {
  465 + params["que" + items.id] = items.id;
  466 + params["score" + items.id] = items.score;
  467 + params["answer" + items.id] = items.answer;
  468 + params["isRight" + items.id] = items.isRight;
  469 + params["questionType" + items.id] = items.questionType;
  470 + });
  471 + return {
  472 + ...item,
  473 + ...params,
  474 + };
  475 + });
  476 + this.questionList = [...optionsList];
  477 + } else {
  478 + this.$message.error(info);
  479 + }
  480 + },
  481 + async examQuestionReport() {
  482 + //试题分析
  483 + this.loading = true;
  484 + let { data, info, status } = await this.$request.examQuestionReport({
  485 + examId: this.id,
  486 + page: this.page,
  487 + size: this.size,
  488 + });
  489 + this.loading = false;
  490 + if (status === 0) {
  491 + let optionsList = [];
  492 + this.tableData = data?.list.map((item) => {
  493 + let params = {};
  494 +
  495 + const detail = JSON.parse(item.detail);
  496 + if (detail.length > optionsList.length) {
  497 + optionsList = [...detail];
  498 + }
  499 + console.log(detail);
  500 + detail.map((items, index) => {
  501 + params[items.option] = items.count;
  502 + });
  503 + return {
  504 + ...item,
  505 + ...params,
  506 + };
  507 + });
  508 + this.optionsList = [...optionsList];
  509 + this.total = data.count;
  510 + } else {
  511 + this.$message.error(info);
  512 + }
  513 + },
  514 + //导出
  515 + async exportData() {
  516 + if ((this.exportLoading = true)) return;
  517 + this.exportLoading = true;
  518 + const { data, status, info } = await this.$request.exportData();
  519 + this.exportLoading = false;
  520 + if (data) {
  521 + downloadFile(this.title + "报表", data);
  522 + } else {
  523 + this.$message.error(info);
  524 + }
381 }, 525 },
382 }, 526 },
383 }; 527 };
384 </script> 528 </script>
385 529
386 <style lang="scss" scoped> 530 <style lang="scss" scoped>
  531 +.page-container {
  532 + position: relative;
  533 + &.active {
  534 + height: 100%;
  535 + overflow: hidden;
  536 + }
  537 + .edit-dia {
  538 + position: absolute;
  539 + left: 0;
  540 + top: 0;
  541 + right: 0;
  542 + bottom: 0;
  543 + width: 100%;
  544 + height: calc(100vh - 70px);
  545 + background: #fff;
  546 + overflow-y: auto;
  547 + z-index: 10;
  548 + }
  549 +}
  550 +.error {
  551 + color: #f30;
  552 +}
387 .page-content { 553 .page-content {
388 padding: 20px 20px 0; 554 padding: 20px 20px 0;
389 } 555 }
@@ -431,4 +597,10 @@ export default { @@ -431,4 +597,10 @@ export default {
431 } 597 }
432 } 598 }
433 } 599 }
  600 +.down {
  601 + padding-top: 20px;
  602 + width: 100%;
  603 + display: flex;
  604 + justify-content: space-between;
  605 +}
434 </style> 606 </style>
435 \ No newline at end of file 607 \ No newline at end of file
src/views/test/editAnswer.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <div class="back">
  4 + <div class="back-l" @click="cancel">
  5 + <i class="fa fa-mail-reply-all"></i>
  6 + <p>修改答案</p>
  7 + </div>
  8 + </div>
  9 + <div class="form-box">
  10 + <div class="answer-title">
  11 + <p class="name">{{ title }}</p>
  12 + <p class="totals">卷面总分:{{ score }}分</p>
  13 + </div>
  14 + <div v-if="questionList && questionList.length">
  15 + <template v-if="questionList[0].subQuestions">
  16 + <div v-for="(question, index) in questionList" :key="index">
  17 + <p class="question-title">
  18 + <span>{{ setBigNum(index) }}、</span>
  19 + <span class="title-txt">{{ question.questionTitle }}</span>
  20 + <span>共 {{ question.score }} 分</span>
  21 + </p>
  22 + <ul class="questions-ul">
  23 + <li class="sub-questions">
  24 + <div class="qs-num">题号</div>
  25 + <div class="qs-type">题型</div>
  26 + <div class="qs-score">分数</div>
  27 + <div class="qs-partScore">漏选得分</div>
  28 + <div class="qs-options qs-options2">选项设置</div>
  29 + </li>
  30 + <li
  31 + v-for="(subQuestions, indexs) in question.subQuestions"
  32 + :key="indexs"
  33 + >
  34 + <p
  35 + class="set-ans-btn"
  36 + v-if="
  37 + subQuestions.qusType &&
  38 + subQuestions.subNum &&
  39 + subQuestions.subNum > 4
  40 + "
  41 + >
  42 + <el-button type="primary" @click="setFormAns(indexs, index)"
  43 + >批量设置答案</el-button
  44 + >
  45 + </p>
  46 + <div v-else class="sub-questions">
  47 + <div class="qs-num">{{ subQuestions.questionIndex }}</div>
  48 + <div class="qs-type">
  49 + {{ setSubPro(subQuestions.questionType) }}
  50 + </div>
  51 + <div class="qs-score">
  52 + {{ subQuestions.score }}
  53 + </div>
  54 + <div class="qs-partScore">
  55 + <p v-if="subQuestions.questionType != 3">--</p>
  56 + <p v-else>{{ subQuestions.partScore }}</p>
  57 + </div>
  58 + <div class="qs-options qs-options2">
  59 + <p v-if="subQuestions.questionType == 5">--</p>
  60 + <p v-if="subQuestions.questionType == 4" class="answer-box">
  61 + <span
  62 + class="answer-s"
  63 + :class="subQuestions.correctAnswer == 1 ? 'active' : ''"
  64 + @click="subQuestions.correctAnswer = 1"
  65 + >✓</span
  66 + >
  67 + <span
  68 + class="answer-s"
  69 + :class="subQuestions.correctAnswer == 2 ? 'active' : ''"
  70 + @click="subQuestions.correctAnswer = 2"
  71 + >✗</span
  72 + >
  73 + </p>
  74 + <p v-if="subQuestions.questionType == 3" class="answer-box">
  75 + <template
  76 + v-for="option in subQuestions.answerOptions.split(',')"
  77 + >
  78 + <span
  79 + v-if="option"
  80 + class="answer-s"
  81 + :class="
  82 + subQuestions.correctAnswer.includes(option)
  83 + ? 'active'
  84 + : ''
  85 + "
  86 + :key="option"
  87 + @click="changAnswer(subQuestions, option)"
  88 + >{{ option }}</span
  89 + >
  90 + </template>
  91 + </p>
  92 + <p v-if="subQuestions.questionType == 2" class="answer-box">
  93 + <template
  94 + v-for="option in subQuestions.answerOptions.split(',')"
  95 + >
  96 + <span
  97 + class="answer-s"
  98 + v-if="option"
  99 + :class="
  100 + subQuestions.correctAnswer == option ? 'active' : ''
  101 + "
  102 + :key="option"
  103 + @click="subQuestions.correctAnswer = option"
  104 + >{{ option }}</span
  105 + >
  106 + </template>
  107 + </p>
  108 + </div>
  109 + </div>
  110 + </li>
  111 + </ul>
  112 + </div>
  113 + </template>
  114 + <ul class="questions-ul" v-else>
  115 + <li class="sub-questions">
  116 + <div class="qs-num">题号</div>
  117 + <div class="qs-type">题型</div>
  118 + <div class="qs-score">分数</div>
  119 + <div class="qs-partScore">漏选得分</div>
  120 + <div class="qs-options qs-options2">选项设置</div>
  121 + </li>
  122 + <li v-for="(subQuestions, indexs) in questionList" :key="indexs">
  123 + <p
  124 + class="set-ans-btn"
  125 + v-if="
  126 + subQuestions.qusType &&
  127 + subQuestions.subNum &&
  128 + subQuestions.subNum > 4
  129 + "
  130 + >
  131 + <el-button type="primary" @click="setFormAns(indexs, index)"
  132 + >批量设置答案</el-button
  133 + >
  134 + </p>
  135 + <div v-else class="sub-questions">
  136 + <div class="qs-num">{{ subQuestions.questionIndex }}</div>
  137 + <div class="qs-type">
  138 + {{ setSubPro(subQuestions.questionType) }}
  139 + </div>
  140 + <div class="qs-score">
  141 + {{ subQuestions.score }}
  142 + </div>
  143 + <div class="qs-partScore">
  144 + <p v-if="subQuestions.questionType != 3">--</p>
  145 + <p v-else>{{ subQuestions.partScore }}</p>
  146 + </div>
  147 + <div class="qs-options qs-options2">
  148 + <p v-if="subQuestions.questionType == 5">--</p>
  149 + <p v-if="subQuestions.questionType == 4" class="answer-box">
  150 + <span
  151 + class="answer-s"
  152 + :class="subQuestions.correctAnswer == 1 ? 'active' : ''"
  153 + @click="subQuestions.correctAnswer = 1"
  154 + >✓</span
  155 + >
  156 + <span
  157 + class="answer-s"
  158 + :class="subQuestions.correctAnswer == 2 ? 'active' : ''"
  159 + @click="subQuestions.correctAnswer = 2"
  160 + >✗</span
  161 + >
  162 + </p>
  163 + <p v-if="subQuestions.questionType == 3" class="answer-box">
  164 + <template
  165 + v-for="option in subQuestions.answerOptions.split(',')"
  166 + >
  167 + <span
  168 + v-if="option"
  169 + class="answer-s"
  170 + :class="
  171 + subQuestions.correctAnswer.includes(option)
  172 + ? 'active'
  173 + : ''
  174 + "
  175 + :key="option"
  176 + @click="changAnswer(subQuestions, option)"
  177 + >{{ option }}</span
  178 + >
  179 + </template>
  180 + </p>
  181 + <p v-if="subQuestions.questionType == 2" class="answer-box">
  182 + <template
  183 + v-for="option in subQuestions.answerOptions.split(',')"
  184 + >
  185 + <span
  186 + class="answer-s"
  187 + v-if="option"
  188 + :class="
  189 + subQuestions.correctAnswer == option ? 'active' : ''
  190 + "
  191 + :key="option"
  192 + @click="subQuestions.correctAnswer = option"
  193 + >{{ option }}</span
  194 + >
  195 + </template>
  196 + </p>
  197 + </div>
  198 + </div>
  199 + </li>
  200 + </ul>
  201 + </div>
  202 + <div class="btn-box">
  203 + <el-button type="danger" plain round @click="cancel"
  204 + >取消</el-button
  205 + >
  206 + <el-button type="primary" round @click="saveAnswer">保存</el-button>
  207 + </div>
  208 + </div>
  209 + <el-dialog
  210 + title="批量设置答案"
  211 + :visible.sync="diaSetAns"
  212 + width="400"
  213 + :modal-append-to-body="false"
  214 + >
  215 + <div class="qs-options">
  216 + <p class="dia-tips">
  217 + 请点击选项按钮设置答案,多选题题目之间用“,”隔开,若添加5道题:“AC,AD,BD,AC,CD”
  218 + </p>
  219 + <p>{{ setSubPro(formAns.qusType) }}:</p>
  220 + <p class="ipt">
  221 + <el-input
  222 + v-model="formAns.answerList"
  223 + @keydown.native="keydownAnswer($event)"
  224 + ></el-input>
  225 + </p>
  226 + <p class="answer-box">
  227 + <template v-if="formAns.qusType == 4">
  228 + <span
  229 + class="answer-s active"
  230 + @click="
  231 + formAns.answerList.length < formAns.subNum
  232 + ? (formAns.answerList += '✓')
  233 + : ''
  234 + "
  235 + >✓</span
  236 + >
  237 + <span
  238 + class="answer-s active"
  239 + @click="
  240 + formAns.answerList.length < formAns.subNum
  241 + ? (formAns.answerList += '✗')
  242 + : ''
  243 + "
  244 + >✗</span
  245 + >
  246 + </template>
  247 + <template v-if="formAns.qusType == 3">
  248 + <span
  249 + class="answer-s active"
  250 + v-for="option in formAns.answerOptions.split(',')"
  251 + :key="option"
  252 + @click="setMultiple(formAns, option)"
  253 + >{{ option }}</span
  254 + >
  255 + <span
  256 + class="answer-s active"
  257 + @click="
  258 + formAns.answerList.split(',').length < formAns.subNum
  259 + ? (formAns.answerList += ',')
  260 + : ''
  261 + "
  262 + >,</span
  263 + >
  264 + </template>
  265 + <template v-if="formAns.qusType == 2" class="answer-box">
  266 + <span
  267 + class="answer-s active"
  268 + v-for="option in formAns.answerOptions.split(',')"
  269 + :key="option"
  270 + @click="
  271 + formAns.answerList.length < formAns.subNum
  272 + ? (formAns.answerList += option)
  273 + : ''
  274 + "
  275 + >{{ option }}</span
  276 + >
  277 + </template>
  278 + <span
  279 + class="answer-s delButton"
  280 + @click="formAns.answerList = formAns.answerList.slice(0, -1)"
  281 + >x</span
  282 + >
  283 + </p>
  284 + </div>
  285 + <div class="dialog-footer" slot="footer">
  286 + <el-button @click="saveFormAns">确 定</el-button>
  287 + <el-button @click="diaSetAns = false">取 消</el-button>
  288 + </div>
  289 + </el-dialog>
  290 + </div>
  291 +</template>
  292 +
  293 +<script>
  294 +import { deepClone, checkAnswer } from "utils";
  295 +export default {
  296 + props: {
  297 + id: "",
  298 + title: "",
  299 + score: "",
  300 + },
  301 + watch: {
  302 + id: {
  303 + handler: function (val) {
  304 + if (val) {
  305 + this.edit();
  306 + }
  307 + },
  308 + immediate: true,
  309 + },
  310 + },
  311 + data() {
  312 + return {
  313 + diaSetAns: false,
  314 + form: {},
  315 + questionList: [],
  316 + formAns: {
  317 + listIndex: 0, //大题位置
  318 + endIndex: 0, //相同题目最后一位题目的questionIndex
  319 + qusType: "", //题目类型
  320 + subNum: 0, //数量
  321 + answerOptions: [], //答案选项
  322 + answerList: "", //答案列表-字符串
  323 + },
  324 + };
  325 + },
  326 + created() {
  327 + // this.edit();
  328 + },
  329 + methods: {
  330 + cancel() {
  331 + this.$emit("cancel");
  332 + },
  333 + setSubPro(type) {
  334 + let tit;
  335 + switch (type) {
  336 + case 2:
  337 + tit = "单选题";
  338 + break;
  339 + case 3:
  340 + tit = "多选题";
  341 + break;
  342 + case 4:
  343 + tit = "判断题";
  344 + break;
  345 + case 5:
  346 + tit = "主观题";
  347 + break;
  348 + }
  349 + return tit;
  350 + },
  351 + setBigNum(num) {
  352 + let txt = "";
  353 + let bigNum = [
  354 + "一",
  355 + "二",
  356 + "三",
  357 + "四",
  358 + "五",
  359 + "六",
  360 + "七",
  361 + "八",
  362 + "九",
  363 + "十",
  364 + "十一",
  365 + "十二",
  366 + "十三",
  367 + "十四",
  368 + "十五",
  369 + "十六",
  370 + "十七",
  371 + "十八",
  372 + "十九",
  373 + "二十",
  374 + ];
  375 + txt = bigNum[num];
  376 +
  377 + return txt;
  378 + },
  379 + keydownAnswer(event) {
  380 + //快速答案设置禁止输入
  381 + if (
  382 + event.key == "Meta" ||
  383 + event.key == "CapsLock" ||
  384 + event.key == "Shift" ||
  385 + event.key == "Enter" ||
  386 + event.key == "Alt" ||
  387 + event.key == "Backspace" ||
  388 + event.key == "Delete" ||
  389 + event.key == "ArrowUp" ||
  390 + event.key == "ArrowDown" ||
  391 + event.key == "ArrowLeft" ||
  392 + event.key == "v" ||
  393 + event.key == "V" ||
  394 + event.key == "ArrowRight"
  395 + ) {
  396 + return;
  397 + } else {
  398 + event.returnValue = "";
  399 + }
  400 + },
  401 + setAnswer(type, ans) {
  402 + let txt = "";
  403 + if (type == 2) {
  404 + txt = ans;
  405 + } else if (type == 3) {
  406 + txt = ans + ",";
  407 + } else if (type == 4) {
  408 + txt = ans == 1 ? "✓" : "✗";
  409 + }
  410 + return txt;
  411 + },
  412 + setMultiple(obj, answer) {
  413 + //多选答案设置
  414 + obj.answerList += answer;
  415 + let str = obj.answerList;
  416 + let str2 = checkAnswer(
  417 + str,
  418 + 3,
  419 + obj.answerOptions.split(",").length,
  420 + obj.answerList.length
  421 + );
  422 + obj.answerList = str2;
  423 + },
  424 + changAnswer(sub, option) {
  425 + //设置多选答案
  426 + let str = new RegExp(option, "g");
  427 + if (sub.correctAnswer?.includes(option)) {
  428 + sub.correctAnswer = sub.correctAnswer.replace(str, "");
  429 + } else {
  430 + let arrs = (sub.correctAnswer && sub.correctAnswer.split("")) || [];
  431 + arrs.push(option);
  432 + sub.correctAnswer = arrs.sort().join("");
  433 + }
  434 + },
  435 + setFormAns(indexs, index) {
  436 + //初始化要修改的答案
  437 + if (this.questionList[0].subQuestions) {
  438 + this.formAns = { ...this.questionList[index].subQuestions[indexs] };
  439 + this.formAns.listIndex = index;
  440 + } else {
  441 + this.formAns = { ...this.questionList[indexs] };
  442 + this.formAns.listIndex = indexs;
  443 + }
  444 + this.diaSetAns = true;
  445 + },
  446 + saveFormAns() {
  447 + //批量修改答案
  448 + let EndIndex;
  449 + let subNum = this.formAns.subNum - 1;
  450 + if (this.questionList[this.formAns.listIndex].subQuestions) {
  451 + this.questionList[this.formAns.listIndex].subQuestions.some(
  452 + (item, index) => {
  453 + if (this.formAns.endIndex == item.questionIndex) {
  454 + EndIndex = index;
  455 + return;
  456 + }
  457 + }
  458 + );
  459 + } else {
  460 + this.questionList.some((item, index) => {
  461 + if (this.formAns.endIndex == item.questionIndex) {
  462 + EndIndex = index;
  463 + return;
  464 + }
  465 + });
  466 + }
  467 +
  468 + for (let i = 0; i <= subNum; i++) {
  469 + let correctAnswer = "";
  470 + if (this.formAns.qusType == 2) {
  471 + correctAnswer = this.formAns.answerList[subNum - i];
  472 + } else if (this.formAns.qusType == 3) {
  473 + correctAnswer = this.formAns.answerList.split(",")[subNum - i];
  474 +
  475 + console.log(this.formAns.answerList.split(",")[subNum - i]);
  476 + } else if (this.formAns.qusType == 4) {
  477 + correctAnswer = this.formAns.answerList[subNum - i] == "✓" ? 1 : 2;
  478 + }
  479 + if (this.questionList[0].subQuestions) {
  480 + this.questionList[this.formAns.listIndex].subQuestions[
  481 + EndIndex - i
  482 + ].correctAnswer = correctAnswer;
  483 + } else {
  484 + this.questionList[EndIndex - i].correctAnswer = correctAnswer;
  485 + }
  486 + }
  487 + this.diaSetAns = false;
  488 + },
  489 + async edit() {
  490 + //修改答案
  491 + const { data, status, info } = await this.$request.examQuestionList({
  492 + examId: this.id,
  493 + });
  494 + if (status == 0) {
  495 + this.questionList = deepClone(data?.list || []);
  496 + } else {
  497 + this.$message.error(info);
  498 + }
  499 + if (!!this.questionList[0].subQuestions) {
  500 + this.questionList?.map((item) => {
  501 + let types = [{}];
  502 + let addndex = 0;
  503 + item.subQuestions.map((sub, index) => {
  504 + if (!!sub.questionType) {
  505 + if (sub.questionType == types[addndex].qusType) {
  506 + //同类型批量答案+1
  507 + types[addndex].subNum += 1;
  508 + if (
  509 + types[addndex].answerOptions.length < sub.answerOptions.length
  510 + ) {
  511 + types[addndex].answerOptions = sub.answerOptions;
  512 + }
  513 + types[addndex].answerList += this.setAnswer(
  514 + sub.questionType,
  515 + sub.correctAnswer
  516 + );
  517 + if (index == item.subQuestions.length - 1) {
  518 + //循环最后类型数量大于等于5,保存批量答案
  519 + if (types[addndex].subNum && types[addndex].subNum >= 5) {
  520 + types[addndex].endIndex = sub.questionIndex;
  521 + types[addndex].index = index;
  522 + }
  523 + }
  524 + } else {
  525 + if (types[addndex].subNum && types[addndex].subNum >= 5) {
  526 + //不同类型时如果原有类型数量大于等于5,保存批量答案
  527 + types[addndex].endIndex =
  528 + item.subQuestions[index - 1].questionIndex;
  529 + types[addndex].index = index;
  530 + addndex += 1;
  531 + types[addndex] = {};
  532 + }
  533 + //不同类型初始化批量答案
  534 + types[addndex].qusType = sub.questionType;
  535 + types[addndex].subNum = 1;
  536 + types[addndex].answerOptions = sub.answerOptions;
  537 + types[addndex].answerList = this.setAnswer(
  538 + sub.questionType,
  539 + sub.correctAnswer
  540 + );
  541 + }
  542 + }
  543 + });
  544 + for (let i = 0; i < types.length; i++) {
  545 + if (types[i].qusType == 3) {
  546 + types[i].answerList = types[i].answerList.slice(0, -1);
  547 + }
  548 + if (types[i].subNum >= 5) {
  549 + item.subQuestions.splice(
  550 + types[i].index + i + 1,
  551 + 0,
  552 + deepClone(types[i])
  553 + );
  554 + }
  555 + }
  556 + });
  557 + } else {
  558 + let types = [{}];
  559 + let addndex = 0;
  560 + this.questionList?.map((sub, index) => {
  561 + if (!!sub.questionType) {
  562 + if (sub.questionType == types[addndex].qusType) {
  563 + //同类型批量答案+1
  564 + types[addndex].subNum += 1;
  565 + if (
  566 + types[addndex].answerOptions.length < sub.answerOptions.length
  567 + ) {
  568 + types[addndex].answerOptions = sub.answerOptions;
  569 + }
  570 + types[addndex].answerList += this.setAnswer(
  571 + sub.questionType,
  572 + sub.correctAnswer
  573 + );
  574 + if (index == this.questionList.length - 1) {
  575 + //循环最后类型数量大于等于5,保存批量答案
  576 + if (types[addndex].subNum && types[addndex].subNum >= 5) {
  577 + types[addndex].endIndex = sub.questionIndex;
  578 + types[addndex].index = index;
  579 + }
  580 + }
  581 + } else {
  582 + if (types[addndex].subNum && types[addndex].subNum >= 5) {
  583 + //不同类型时如果原有类型数量大于等于5,保存批量答案
  584 + types[addndex].endIndex =
  585 + this.questionList[index - 1].questionIndex;
  586 + types[addndex].index = index;
  587 + addndex += 1;
  588 + types[addndex] = {};
  589 + }
  590 + //不同类型初始化批量答案
  591 + types[addndex].qusType = sub.questionType;
  592 + types[addndex].subNum = 1;
  593 + types[addndex].answerOptions = sub.answerOptions;
  594 + types[addndex].answerList = this.setAnswer(
  595 + sub.questionType,
  596 + sub.correctAnswer
  597 + );
  598 + }
  599 + }
  600 + });
  601 + for (let i = 0; i < types.length; i++) {
  602 + if (types[i].qusType == 3) {
  603 + types[i].answerList = types[i].answerList.slice(0, -1);
  604 + }
  605 + if (types[i].subNum >= 5) {
  606 + item.subQuestions.splice(
  607 + types[i].index + i + 1,
  608 + 0,
  609 + deepClone(types[i])
  610 + );
  611 + }
  612 + }
  613 + }
  614 +
  615 + this.dialogVisible = true;
  616 + },
  617 + async saveAnswer() {
  618 + //保存答案
  619 + for (let i = 0; i < this.questionList.length; i++) {
  620 + if (this.questionList[0].subQuestions) {
  621 + for (let j = 0; j < this.questionList[i].subQuestions.length; j++) {
  622 + if (this.questionList[i].subQuestions[j].qusType) {
  623 + this.questionList[i].subQuestions.splice(j, 1);
  624 + }
  625 + }
  626 + } else {
  627 + if (this.questionList[i].qusType) {
  628 + this.questionList.splice(i, 1);
  629 + i--
  630 + }
  631 + }
  632 + }
  633 + const { data, status, message } = await this.$request.setExamAnswer({
  634 + examId: this.id,
  635 + questionList: [...this.questionList],
  636 + });
  637 + if (status == 0) {
  638 + this.$emit("saveSuccess");
  639 + } else {
  640 + this.$message.error(message);
  641 + }
  642 + },
  643 + },
  644 +};
  645 +</script>
  646 +
  647 +<style lang="scss" scoped>
  648 +.back {
  649 + width: 100%;
  650 + height: 56px;
  651 + border-bottom: 1px solid #e2e2e2;
  652 + display: flex;
  653 + align-items: center;
  654 + padding: 0 20px;
  655 + box-sizing: border-box;
  656 + .back-l {
  657 + display: flex;
  658 + align-items: center;
  659 + cursor: pointer;
  660 + flex-shrink: 0;
  661 + font-size: 18px;
  662 + font-weight: 500;
  663 + }
  664 + .fa-mail-reply-all {
  665 + font-size: 28px;
  666 + color: #b3b3b3;
  667 + margin-right: 12px;
  668 + }
  669 +}
  670 +.form-box {
  671 + padding: 20px;
  672 +}
  673 +.answer-title {
  674 + text-align: center;
  675 + font-size: 20px;
  676 + color: #333;
  677 + font-weight: 700;
  678 + padding-bottom: 20px;
  679 + .totals {
  680 + font-size: 16px;
  681 + color: #888;
  682 + font-weight: normal;
  683 + }
  684 +}
  685 +.question-title {
  686 + line-height: 40px;
  687 + .ipt {
  688 + width: 300px;
  689 + margin: 0 16px 0 10px;
  690 + :deep(.el-input__inner) {
  691 + border-radius: 20px;
  692 + border-color: #667ffd;
  693 + background: rgba($color: #667ffd, $alpha: 0.05);
  694 + }
  695 + }
  696 + .delete {
  697 + margin-right: 8px;
  698 + }
  699 + .title-txt {
  700 + margin-right: 20px;
  701 + font-size: 16px;
  702 + font-weight: 700;
  703 + }
  704 +}
  705 +.questions-ul {
  706 + border-left: 1px solid #e2e2e2;
  707 + border-top: 1px solid #e2e2e2;
  708 + margin: 12px 0;
  709 +}
  710 +.sub-questions {
  711 + width: 100%;
  712 + display: flex;
  713 + border-bottom: 1px solid #e2e2e2;
  714 + & > div {
  715 + min-height: 40px;
  716 + padding: 5px;
  717 + flex-shrink: 0;
  718 + border-right: 1px solid #e2e2e2;
  719 + display: flex;
  720 + justify-content: center;
  721 + align-items: center;
  722 + }
  723 + .qs-num {
  724 + width: 80px;
  725 + }
  726 + .qs-type {
  727 + width: 160px;
  728 + }
  729 + .qs-score,
  730 + .qs-partScore {
  731 + width: 160px;
  732 + }
  733 + .qs-options {
  734 + flex: 1;
  735 + }
  736 + .qs-set {
  737 + width: 80px;
  738 + }
  739 + .qs-options2 {
  740 + text-align: left;
  741 + justify-content: flex-start;
  742 + padding-left: 20px;
  743 + .answer-s {
  744 + cursor: pointer;
  745 + }
  746 + }
  747 + :deep(.el-select) {
  748 + .el-input__inner {
  749 + border-radius: 20px;
  750 + border-color: #667ffd;
  751 + width: 150px;
  752 + height: 32px;
  753 + line-height: 32px;
  754 + background: rgba($color: #667ffd, $alpha: 0.05);
  755 + }
  756 + .el-input__icon {
  757 + line-height: 32px;
  758 + }
  759 + }
  760 +}
  761 +.set-ans-btn {
  762 + width: 100%;
  763 + padding: 10px 0 10px 630px;
  764 + box-sizing: border-box;
  765 + border-bottom: 1px solid #e2e2e2;
  766 +}
  767 +.fa-exchange {
  768 + color: #667ffd;
  769 + cursor: pointer;
  770 + font-size: 16px;
  771 + margin-left: 10px;
  772 +}
  773 +.dia-btn {
  774 + border-radius: 20px;
  775 + margin: 0 20px;
  776 + padding: 10px 20px;
  777 +}
  778 +.dia-tips {
  779 + padding-bottom: 10px;
  780 +}
  781 +.answer-s {
  782 + width: 32px;
  783 + height: 28px;
  784 + cursor: pointer;
  785 + user-select: none;
  786 +}
  787 +.set-questions {
  788 + display: flex;
  789 + margin-bottom: 12px;
  790 + width: 100%;
  791 + .qs-num {
  792 + flex-shrink: 0;
  793 + margin-right: 10px;
  794 + }
  795 +}
  796 +.qs-options {
  797 + flex: 1;
  798 + .ipt {
  799 + margin-bottom: 5px;
  800 + }
  801 + .delButton {
  802 + border-color: #ff6868;
  803 + background: #ff6868 url("../../assets/images/arrow.png") no-repeat center;
  804 + background-size: 19px;
  805 + cursor: pointer;
  806 + color: transparent;
  807 + }
  808 + .ac {
  809 + border-color: #ff6868;
  810 + background: #ff6868;
  811 + color: #fff;
  812 + }
  813 +}
  814 +</style>
0 \ No newline at end of file 815 \ No newline at end of file
src/views/test/index.vue
1 <template> 1 <template>
2 - <div class="page-container"> 2 + <div class="page-container" :class="dialogVisible ? 'active' : ''">
3 <back-box> 3 <back-box>
4 <template slot="title"> 4 <template slot="title">
5 <span>即时测-数据报表</span> 5 <span>即时测-数据报表</span>
@@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
25 v-if="role == 'ROLE_BANZHUREN'" 25 v-if="role == 'ROLE_BANZHUREN'"
26 class="sel" 26 class="sel"
27 multiple 27 multiple
28 - v-model="query.subjectId" 28 + v-model="query.subjectNames"
29 placeholder="选择科目" 29 placeholder="选择科目"
30 @change="_QueryData" 30 @change="_QueryData"
31 > 31 >
@@ -40,7 +40,7 @@ @@ -40,7 +40,7 @@
40 <el-select 40 <el-select
41 v-else 41 v-else
42 class="sel" 42 class="sel"
43 - v-model="query.subjectId" 43 + v-model="query.subjectNames"
44 placeholder="选择科目" 44 placeholder="选择科目"
45 @change="_QueryData" 45 @change="_QueryData"
46 > 46 >
@@ -89,87 +89,86 @@ @@ -89,87 +89,86 @@
89 </div> 89 </div>
90 </div> 90 </div>
91 <div class="table-box"> 91 <div class="table-box">
92 - <el-radio-group v-model="tabIndex" style="margin-bottom: 20px"> 92 + <el-radio-group
  93 + v-model="tabIndex"
  94 + @change="changeTab"
  95 + style="margin-bottom: 20px"
  96 + >
93 <el-radio-button :label="1">单卷测练报表</el-radio-button> 97 <el-radio-button :label="1">单卷测练报表</el-radio-button>
94 <el-radio-button :label="2">阶段测练报表</el-radio-button> 98 <el-radio-button :label="2">阶段测练报表</el-radio-button>
95 </el-radio-group> 99 </el-radio-group>
96 - <div v-if="tabIndex == 1">  
97 - <el-table  
98 - :data="tableData"  
99 - border  
100 - style="width: 100%"  
101 - :default-sort="{ prop: '', order: 'descending' }"  
102 - > 100 + <div v-if="tabIndex == 1" v-loading="loading">
  101 + <el-table :data="tableData" border style="width: 100%">
103 <el-table-column 102 <el-table-column
104 prop="title" 103 prop="title"
105 label="试卷名称" 104 label="试卷名称"
106 align="center" 105 align="center"
107 ></el-table-column> 106 ></el-table-column>
108 <el-table-column 107 <el-table-column
109 - prop="totalScore" 108 + prop="examPaperScore"
110 label="卷面分" 109 label="卷面分"
111 align="center" 110 align="center"
112 width="100" 111 width="100"
113 ></el-table-column> 112 ></el-table-column>
114 <el-table-column 113 <el-table-column
115 - prop="ceyan" 114 + prop="answeredNum"
116 label="测验人数" 115 label="测验人数"
117 align="center" 116 align="center"
118 ></el-table-column> 117 ></el-table-column>
119 <el-table-column 118 <el-table-column
120 - prop="shijian" 119 + prop="examStartTime"
121 label="测验时间" 120 label="测验时间"
122 align="center" 121 align="center"
123 ></el-table-column> 122 ></el-table-column>
124 <el-table-column 123 <el-table-column
125 - prop="pingjun" 124 + prop="avgScore"
126 label="班平均分" 125 label="班平均分"
127 align="center" 126 align="center"
128 ></el-table-column> 127 ></el-table-column>
129 <el-table-column 128 <el-table-column
130 - prop="zuigao" 129 + prop="highestScore"
131 label="班最高分" 130 label="班最高分"
132 align="center" 131 align="center"
133 ></el-table-column> 132 ></el-table-column>
134 <el-table-column 133 <el-table-column
135 - prop="zuidi" 134 + prop="lowestScore"
136 label="班最低分" 135 label="班最低分"
137 align="center" 136 align="center"
138 ></el-table-column> 137 ></el-table-column>
139 <el-table-column 138 <el-table-column
140 - prop="youxiu" 139 + prop="excellenRate"
141 label="优秀数(率)" 140 label="优秀数(率)"
142 sortable 141 sortable
143 align="center" 142 align="center"
144 ><template slot-scope="scoped" 143 ><template slot-scope="scoped"
145 - >{{ scoped.row.youxiu }}%</template 144 + >{{ scoped.row.excellenRate }}%</template
146 ></el-table-column 145 ></el-table-column
147 > 146 >
148 <el-table-column 147 <el-table-column
149 - prop="lianghao" 148 + prop="goodRate"
150 label="良好数(率)" 149 label="良好数(率)"
151 sortable 150 sortable
152 align="center" 151 align="center"
153 ><template slot-scope="scoped" 152 ><template slot-scope="scoped"
154 - >{{ scoped.row.lianghao }}%</template 153 + >{{ scoped.row.goodRate }}%</template
155 ></el-table-column 154 ></el-table-column
156 > 155 >
157 <el-table-column 156 <el-table-column
158 - prop="jige" 157 + prop="passRate"
159 label="及格数(率)" 158 label="及格数(率)"
160 sortable 159 sortable
161 align="center" 160 align="center"
162 ><template slot-scope="scoped" 161 ><template slot-scope="scoped"
163 - >{{ scoped.row.jige }}%</template 162 + >{{ scoped.row.passRate }}%</template
164 ></el-table-column 163 ></el-table-column
165 > 164 >
166 <el-table-column 165 <el-table-column
167 - prop="bujige" 166 + prop="failedRate"
168 label="不及格数(率)" 167 label="不及格数(率)"
169 sortable 168 sortable
170 align="center" 169 align="center"
171 ><template slot-scope="scoped" 170 ><template slot-scope="scoped"
172 - >{{ scoped.row.bujige }}%</template 171 + >{{ scoped.row.failedRate }}%</template
173 ></el-table-column 172 ></el-table-column
174 > 173 >
175 <el-table-column label="操作" align="center"> 174 <el-table-column label="操作" align="center">
@@ -195,38 +194,33 @@ @@ -195,38 +194,33 @@
195 </template> 194 </template>
196 </el-table-column> 195 </el-table-column>
197 </el-table> 196 </el-table>
  197 + <div class="pagination-box">
  198 + <el-pagination
  199 + small=""
  200 + layout="total,prev, pager, next"
  201 + :hide-on-single-page="true"
  202 + :total="total"
  203 + @current-change="changePage"
  204 + :current-page="page"
  205 + :page-size="size"
  206 + >
  207 + </el-pagination>
  208 + </div>
198 </div> 209 </div>
199 - <div v-if="tabIndex == 2">  
200 - <el-table  
201 - :data="tableStage"  
202 - border  
203 - style="width: 100%"  
204 - :default-sort="{ prop: '', order: 'descending' }"  
205 - > 210 + <div v-if="tabIndex == 2" v-loading="loading">
  211 + <el-table :data="tableData" border style="width: 100%">
206 <el-table-column 212 <el-table-column
207 - prop="xuehao" 213 + prop="studentCode"
208 label="学号" 214 label="学号"
209 align="center" 215 align="center"
210 fixed 216 fixed
211 ></el-table-column> 217 ></el-table-column>
212 <el-table-column 218 <el-table-column
213 - prop="xingming" 219 + prop="studentName"
214 label="姓名" 220 label="姓名"
215 fixed 221 fixed
216 align="center" 222 align="center"
217 ></el-table-column> 223 ></el-table-column>
218 - <el-table-column label="阶段汇总" align="center">  
219 - <el-table-column  
220 - prop="totalScore"  
221 - label="总分"  
222 - align="center"  
223 - ></el-table-column>  
224 - <el-table-column  
225 - prop="rank"  
226 - label="排名"  
227 - align="center"  
228 - ></el-table-column>  
229 - </el-table-column>  
230 <el-table-column 224 <el-table-column
231 align="center" 225 align="center"
232 v-for="(item, index) in answerList" 226 v-for="(item, index) in answerList"
@@ -234,12 +228,12 @@ @@ -234,12 +228,12 @@
234 :label="item.title" 228 :label="item.title"
235 > 229 >
236 <el-table-column 230 <el-table-column
237 - :prop="item.title + 'totalScore'"  
238 - label="成绩" 231 + :prop="'score' + index"
  232 + label="总分/成绩"
239 align="center" 233 align="center"
240 ></el-table-column> 234 ></el-table-column>
241 <el-table-column 235 <el-table-column
242 - :prop="item.title + 'rank'" 236 + :prop="'classRank' + index"
243 label="班名" 237 label="班名"
244 align="center" 238 align="center"
245 ></el-table-column> 239 ></el-table-column>
@@ -253,227 +247,37 @@ @@ -253,227 +247,37 @@
253 </p> 247 </p>
254 </div> 248 </div>
255 <div class="edit-dia" v-show="dialogVisible" height="100%"> 249 <div class="edit-dia" v-show="dialogVisible" height="100%">
256 - <div class="back">  
257 - <div class="back-l" @click="dialogVisible = false">  
258 - <i class="fa fa-mail-reply-all"></i>  
259 - <p>修改答案</p>  
260 - </div>  
261 - </div>  
262 - <div class="form-box">  
263 - <div class="answer-title">  
264 - <p class="name">{{ form.title }}</p>  
265 - <p class="totals">卷面总分:{{ form.score }}分</p>  
266 - </div>  
267 - <div v-if="questionList && questionList.length">  
268 - <div v-for="(question, index) in questionList" :key="index">  
269 - <p class="question-title">  
270 - <span>{{ setBigNum(index) }}、</span>  
271 - <span class="title-txt">{{ question.questionTitle }}</span>  
272 - <span>共 {{ question.score }} 分</span>  
273 - </p>  
274 - <ul class="questions-ul">  
275 - <li class="sub-questions">  
276 - <div class="qs-num">题号</div>  
277 - <div class="qs-type">题型</div>  
278 - <div class="qs-score">分数</div>  
279 - <div class="qs-partScore">漏选得分</div>  
280 - <div class="qs-options qs-options2">选项设置</div>  
281 - </li>  
282 - <li  
283 - v-for="(subQuestions, indexs) in question.subQuestions"  
284 - :key="indexs"  
285 - >  
286 - <p  
287 - class="set-ans-btn"  
288 - v-if="  
289 - subQuestions.qusType &&  
290 - subQuestions.subNum &&  
291 - subQuestions.subNum > 4  
292 - "  
293 - >  
294 - <el-button type="primary" @click="setFormAns(index, indexs)"  
295 - >批量设置答案</el-button  
296 - >  
297 - </p>  
298 - <div v-else class="sub-questions">  
299 - <div class="qs-num">{{ subQuestions.questionIndex }}</div>  
300 - <div class="qs-type">  
301 - {{ setSubPro(subQuestions.questionType) }}  
302 - </div>  
303 - <div class="qs-score">  
304 - {{ subQuestions.score }}  
305 - </div>  
306 - <div class="qs-partScore">  
307 - <p v-if="subQuestions.questionType != 3">--</p>  
308 - <p v-else>{{ subQuestions.partScore }}</p>  
309 - </div>  
310 - <div class="qs-options qs-options2">  
311 - <p v-if="subQuestions.questionType == 5">--</p>  
312 - <p v-if="subQuestions.questionType == 4" class="answer-box">  
313 - <span  
314 - class="answer-s"  
315 - :class="subQuestions.correctAnswer == 1 ? 'active' : ''"  
316 - @click="subQuestions.correctAnswer = 1"  
317 - >✓</span  
318 - >  
319 - <span  
320 - class="answer-s"  
321 - :class="subQuestions.correctAnswer == 2 ? 'active' : ''"  
322 - @click="subQuestions.correctAnswer = 2"  
323 - >✗</span  
324 - >  
325 - </p>  
326 - <p v-if="subQuestions.questionType == 3" class="answer-box">  
327 - <template  
328 - v-for="option in subQuestions.answerOptions.split(',')"  
329 - >  
330 - <span  
331 - v-if="option"  
332 - class="answer-s"  
333 - :class="  
334 - subQuestions.correctAnswer.includes(option)  
335 - ? 'active'  
336 - : ''  
337 - "  
338 - :key="option"  
339 - @click="changAnswer(subQuestions, option)"  
340 - >{{ option }}</span  
341 - >  
342 - </template>  
343 - </p>  
344 - <p v-if="subQuestions.questionType == 2" class="answer-box">  
345 - <template  
346 - v-for="option in subQuestions.answerOptions.split(',')"  
347 - >  
348 - <span  
349 - class="answer-s"  
350 - v-if="option"  
351 - :class="  
352 - subQuestions.correctAnswer == option ? 'active' : ''  
353 - "  
354 - :key="option"  
355 - @click="subQuestions.correctAnswer = option"  
356 - >{{ option }}</span  
357 - >  
358 - </template>  
359 - </p>  
360 - </div>  
361 - </div>  
362 - </li>  
363 - </ul>  
364 - </div>  
365 - </div>  
366 - <div class="btn-box">  
367 - <el-button type="danger" plain round @click="dialogVisible = false"  
368 - >取消</el-button  
369 - >  
370 - <el-button type="primary" round @click="saveAnswer">保存</el-button>  
371 - </div>  
372 - </div> 250 + <editAnswer
  251 + :id="form.id"
  252 + :title="form.title"
  253 + :score="form.examPaperScore"
  254 + @cancel="cancel"
  255 + @saveSuccess="saveSuccess"
  256 + />
373 </div> 257 </div>
374 - <el-dialog title="批量设置答案" :visible.sync="diaSetAns" width="400">  
375 - <div class="qs-options">  
376 - <p class="dia-tips">  
377 - 请点击选项按钮设置答案,多选题题目之间用“,”隔开,若添加5道题:“AC,AD,BD,AC,CD”  
378 - </p>  
379 - <p>{{ setSubPro(formAns.qusType) }}:</p>  
380 - <p class="ipt">  
381 - <el-input  
382 - v-model="formAns.answerList"  
383 - @keydown.native="keydownAnswer($event)"  
384 - ></el-input>  
385 - </p>  
386 - <p class="answer-box">  
387 - <template v-if="formAns.qusType == 4">  
388 - <span  
389 - class="answer-s active"  
390 - @click="  
391 - formAns.answerList.length < formAns.subNum  
392 - ? (formAns.answerList += '✓')  
393 - : ''  
394 - "  
395 - >✓</span  
396 - >  
397 - <span  
398 - class="answer-s active"  
399 - @click="  
400 - formAns.answerList.length < formAns.subNum  
401 - ? (formAns.answerList += '✗')  
402 - : ''  
403 - "  
404 - >✗</span  
405 - >  
406 - </template>  
407 - <template v-if="formAns.qusType == 3">  
408 - <span  
409 - class="answer-s active"  
410 - v-for="option in formAns.answerOptions"  
411 - :key="option"  
412 - @click="setMultiple(formAns, option)"  
413 - >{{ option }}</span  
414 - >  
415 - <span  
416 - class="answer-s active"  
417 - @click="  
418 - formAns.answerList.split(',').length < formAns.subNum  
419 - ? (formAns.answerList += ',')  
420 - : ''  
421 - "  
422 - >,</span  
423 - >  
424 - </template>  
425 - <template v-if="formAns.qusType == 2" class="answer-box">  
426 - <span  
427 - class="answer-s active"  
428 - v-for="option in formAns.answerOptions"  
429 - :key="option"  
430 - @click="  
431 - formAns.answerList.length < formAns.subNum  
432 - ? (formAns.answerList += option)  
433 - : ''  
434 - "  
435 - >{{ option }}</span  
436 - >  
437 - </template>  
438 - <span  
439 - class="answer-s delButton"  
440 - @click="formAns.answerList = formAns.answerList.slice(0, -1)"  
441 - >x</span  
442 - >  
443 - </p>  
444 - </div>  
445 - <div class="dialog-footer" slot="footer">  
446 - <el-button @click="saveFormAns">确 定</el-button>  
447 - <el-button @click="diaSetAns = false">取 消</el-button>  
448 - </div>  
449 - </el-dialog>  
450 </div> 258 </div>
451 </template> 259 </template>
452 260
453 <script> 261 <script>
454 -import { formatDate, deepClone, checkAnswer } from "utils"; 262 +import { formatDate } from "utils";
  263 +import editAnswer from "./editAnswer.vue";
455 export default { 264 export default {
  265 + components: { editAnswer },
456 data() { 266 data() {
457 return { 267 return {
458 role: "", 268 role: "",
459 loading: false, 269 loading: false,
460 dialogVisible: false, 270 dialogVisible: false,
461 - diaSetAns: false,  
462 - form: {},  
463 - questionList: [],  
464 - formAns: {  
465 - listIndex: 0, //大题位置  
466 - endIndex: 0, //相同题目最后一位题目的questionIndex  
467 - qusType: "", //题目类型  
468 - subNum: 0, //数量  
469 - answerOptions: [], //答案选项  
470 - answerList: "", //答案列表-字符串 271 + form: {
  272 + id: "",
  273 + title: "",
  274 + examPaperScore: "",
471 }, 275 },
472 date: "", //今天-昨天-本周 276 date: "", //今天-昨天-本周
473 query: { 277 query: {
474 //搜索条件 278 //搜索条件
475 classId: "", 279 classId: "",
476 - subjectId: "", 280 + subjectNames: "",
477 startDay: "", 281 startDay: "",
478 endDay: "", 282 endDay: "",
479 day: "", 283 day: "",
@@ -481,207 +285,11 @@ export default { @@ -481,207 +285,11 @@ export default {
481 classList: [], //班级 285 classList: [], //班级
482 subjectList: [], //科目 286 subjectList: [], //科目
483 tabIndex: 1, //选项卡 287 tabIndex: 1, //选项卡
484 - tableData: [  
485 - {  
486 - title: "试卷一",  
487 - totalScore: 10,  
488 - ceyan: "40/50",  
489 - shijian: "2022-11-9 21:30至22:30",  
490 - pingjun: 60,  
491 - zuigao: 90,  
492 - zuidi: 50,  
493 - youxiu: 50,  
494 - lianghao: 40,  
495 - jige: 30,  
496 - bujige: 20,  
497 - questionList: [  
498 - {  
499 - questionTitle: "f",  
500 - score: 1,  
501 - subQuestions: [  
502 - {  
503 - questionIndex: 1,  
504 - questionType: 2,  
505 - score: 1,  
506 - partScore: 0,  
507 - selectNum: 4,  
508 - answerOptions: "A, B, C, D",  
509 - correctAnswer: "B",  
510 - },  
511 - {  
512 - questionIndex: 2,  
513 - questionType: 2,  
514 - score: 1,  
515 - partScore: 0,  
516 - selectNum: 4,  
517 - answerOptions: "A, B, C, D,E,F",  
518 - correctAnswer: "A",  
519 - },  
520 - {  
521 - questionIndex: 3,  
522 - questionType: 2,  
523 - score: 1,  
524 - partScore: 0,  
525 - selectNum: 4,  
526 - answerOptions: "A, B, C, D,E,F",  
527 - correctAnswer: "A",  
528 - },  
529 - {  
530 - questionIndex: 4,  
531 - questionType: 2,  
532 - score: 1,  
533 - partScore: 0,  
534 - selectNum: 4,  
535 - answerOptions: "A, B, C, D,E,F",  
536 - correctAnswer: "A",  
537 - },  
538 - {  
539 - questionIndex: 5,  
540 - questionType: 2,  
541 - score: 1,  
542 - partScore: 0,  
543 - selectNum: 4,  
544 - answerOptions: "A, B, C, D,E,F",  
545 - correctAnswer: "A",  
546 - },  
547 - {  
548 - questionIndex: 6,  
549 - questionType: 3,  
550 - score: 1,  
551 - partScore: 0,  
552 - selectNum: 4,  
553 - answerOptions: "A, B, C, D,E,F",  
554 - correctAnswer: "AB",  
555 - },  
556 - {  
557 - questionIndex: 7,  
558 - questionType: 4,  
559 - score: 1,  
560 - partScore: 0,  
561 - selectNum: 0,  
562 - answerOptions: [],  
563 - correctAnswer: "1",  
564 - },  
565 - {  
566 - questionIndex: 8,  
567 - questionType: 3,  
568 - score: 1,  
569 - partScore: 0,  
570 - selectNum: 4,  
571 - answerOptions: "A, B, C, D,E,F",  
572 - correctAnswer: "AB",  
573 - },  
574 - {  
575 - questionIndex: 9,  
576 - questionType: 3,  
577 - score: 1,  
578 - partScore: 0,  
579 - selectNum: 4,  
580 - answerOptions: "A, B, C, D,E,F",  
581 - correctAnswer: "AB",  
582 - },  
583 - {  
584 - questionIndex: 10,  
585 - questionType: 3,  
586 - score: 1,  
587 - partScore: 0,  
588 - selectNum: 4,  
589 - answerOptions: "A, B, C, D,E,F",  
590 - correctAnswer: "AB",  
591 - },  
592 - {  
593 - questionIndex: 11,  
594 - questionType: 3,  
595 - score: 1,  
596 - partScore: 0,  
597 - selectNum: 4,  
598 - answerOptions: "A, B, C, D,E,F",  
599 - correctAnswer: "AB",  
600 - },  
601 - {  
602 - questionIndex: 12,  
603 - questionType: 3,  
604 - score: 1,  
605 - partScore: 0,  
606 - selectNum: 4,  
607 - answerOptions: "A, B, C, D,E,F",  
608 - correctAnswer: "AB",  
609 - },  
610 - {  
611 - questionIndex: 13,  
612 - questionType: 4,  
613 - score: 1,  
614 - partScore: 0,  
615 - selectNum: 0,  
616 - answerOptions: [],  
617 - correctAnswer: "1",  
618 - },  
619 - ],  
620 - },  
621 - ],  
622 - },  
623 - {  
624 - title: "试卷二",  
625 - totalScore: 20,  
626 - ceyan: "30/50",  
627 - shijian: "2022-11-9 21:30至22:30",  
628 - pingjun: 80,  
629 - zuigao: 92,  
630 - zuidi: 53,  
631 - youxiu: 45,  
632 - lianghao: 56,  
633 - jige: 20,  
634 - bujige: 30,  
635 - },  
636 - ],  
637 - tableStage: [  
638 - {  
639 - xuehao: 1,  
640 - xingming: "丁芳菲",  
641 - totalScore: 5,  
642 - rank: 1,  
643 - 周测卷20221130totalScore: 10,  
644 - 周测卷20221130rank: 0,  
645 - 周测卷20221131totalScore: 11,  
646 - 周测卷20221131rank: 1,  
647 - 周测卷20221132totalScore: 12,  
648 - 周测卷20221132rank: 2,  
649 - 周测卷20221132totalScore: 13,  
650 - 周测卷20221132rank: 3,  
651 - },  
652 - {  
653 - xuehao: 2,  
654 - xingming: "丁芳",  
655 - totalScore: 4,  
656 - rank: 2,  
657 - 周测卷20221130totalScore: 20,  
658 - 周测卷20221130rank: 3,  
659 - 周测卷20221131totalScore: 21,  
660 - 周测卷20221131rank: 4,  
661 - 周测卷20221132totalScore: 22,  
662 - 周测卷20221132rank: 5,  
663 - 周测卷20221132totalScore: 22,  
664 - 周测卷20221132rank: 5,  
665 - },  
666 - ],  
667 - answerList: [  
668 - //设置多卷内容供tableStage表格数据用  
669 - {  
670 - title: "周测卷20221130",  
671 - totalScore: 6,  
672 - rank: 2,  
673 - },  
674 - {  
675 - title: "周测卷20221131",  
676 - totalScore: 7,  
677 - rank: 3,  
678 - },  
679 - {  
680 - title: "周测卷20221132",  
681 - totalScore: 8,  
682 - rank: 4,  
683 - },  
684 - ], 288 + tableData: [],
  289 + answerList: [], //设置多卷内容供tableStage表格数据用
  290 + page: 1,
  291 + size: 20,
  292 + total: 0,
685 }; 293 };
686 }, 294 },
687 async created() { 295 async created() {
@@ -690,7 +298,7 @@ export default { @@ -690,7 +298,7 @@ export default {
690 )?.role; 298 )?.role;
691 await this._QueryClassList(); 299 await this._QueryClassList();
692 await this._QuerySubjectList(); 300 await this._QuerySubjectList();
693 - // await this.setDate(1); 301 + await this.setDate(1);
694 let startDay = this.query?.startDay; 302 let startDay = this.query?.startDay;
695 if (!startDay) { 303 if (!startDay) {
696 this.query.startDay = new Date(); 304 this.query.startDay = new Date();
@@ -704,54 +312,17 @@ export default { @@ -704,54 +312,17 @@ export default {
704 path: "/testAnalysis", 312 path: "/testAnalysis",
705 query: { 313 query: {
706 id: obj.id, 314 id: obj.id,
  315 + title: obj.title,
  316 + score: obj.examPaperScore,
707 }, 317 },
708 }); 318 });
709 }, 319 },
710 - setSubPro(type) {  
711 - let tit;  
712 - switch (type) {  
713 - case 2:  
714 - tit = "单选题";  
715 - break;  
716 - case 3:  
717 - tit = "多选题";  
718 - break;  
719 - case 4:  
720 - tit = "判断题";  
721 - break;  
722 - case 5:  
723 - tit = "主观题";  
724 - break;  
725 - }  
726 - return tit; 320 + cancel() {
  321 + this.dialogVisible = false;
727 }, 322 },
728 - setBigNum(num) {  
729 - let txt = "";  
730 - let bigNum = [  
731 - "一",  
732 - "二",  
733 - "三",  
734 - "四",  
735 - "五",  
736 - "六",  
737 - "七",  
738 - "八",  
739 - "九",  
740 - "十",  
741 - "十一",  
742 - "十二",  
743 - "十三",  
744 - "十四",  
745 - "十五",  
746 - "十六",  
747 - "十七",  
748 - "十八",  
749 - "十九",  
750 - "二十",  
751 - ];  
752 - txt = bigNum[num];  
753 -  
754 - return txt; 323 + saveSuccess() {
  324 + this.dialogVisible = false;
  325 + this._QueryData();
755 }, 326 },
756 setDate(index) { 327 setDate(index) {
757 const that = this; 328 const that = this;
@@ -783,7 +354,7 @@ export default { @@ -783,7 +354,7 @@ export default {
783 that.query.endDay = formatDate(new Date(), "yyyy-MM-dd"); 354 that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
784 break; 355 break;
785 case 4: 356 case 4:
786 - if (aMonth > 1 && aMonth < 4) { 357 + if (aMonth > 0 && aMonth < 4) {
787 aMonth = "01"; 358 aMonth = "01";
788 } else if (aMonth > 3 && aMonth < 7) { 359 } else if (aMonth > 3 && aMonth < 7) {
789 aMonth = "04"; 360 aMonth = "04";
@@ -821,175 +392,29 @@ export default { @@ -821,175 +392,29 @@ export default {
821 } 392 }
822 } 393 }
823 }, 394 },
824 - keydownAnswer(event) {  
825 - //快速答案设置禁止输入  
826 - if (  
827 - event.key == "Meta" ||  
828 - event.key == "CapsLock" ||  
829 - event.key == "Shift" ||  
830 - event.key == "Enter" ||  
831 - event.key == "Alt" ||  
832 - event.key == "Backspace" ||  
833 - event.key == "Delete" ||  
834 - event.key == "ArrowUp" ||  
835 - event.key == "ArrowDown" ||  
836 - event.key == "ArrowLeft" ||  
837 - event.key == "v" ||  
838 - event.key == "V" ||  
839 - event.key == "ArrowRight"  
840 - ) {  
841 - return;  
842 - } else {  
843 - event.returnValue = "";  
844 - }  
845 - },  
846 - setAnswer(type, ans) {  
847 - let txt = "";  
848 - if (type == 2) {  
849 - txt = ans;  
850 - } else if (type == 3) {  
851 - txt = ans + ",";  
852 - } else if (type == 4) {  
853 - txt = ans == 1 ? "✓" : "✗";  
854 - }  
855 - return txt;  
856 - },  
857 - setMultiple(obj, answer) {  
858 - //多选答案设置  
859 - obj.answerList += answer;  
860 - let str = obj.answerList;  
861 - let str2 = checkAnswer(  
862 - str,  
863 - 3,  
864 - obj.answerOptions.split(",").length,  
865 - obj.answerList.length  
866 - );  
867 - obj.answerList = str2; 395 + changePage(page) {
  396 + this.page = page;
  397 + this._QueryData();
868 }, 398 },
869 edit(item) { 399 edit(item) {
870 - //修改答案  
871 - this.form = deepClone(item);  
872 - this.questionList = deepClone(item?.questionList || []);  
873 - this.questionList?.map((item) => {  
874 - let types = [{}];  
875 - let addndex = 0;  
876 - item.subQuestions.map((sub, index) => {  
877 - if (!!sub.questionType) {  
878 - if (sub.questionType == types[addndex].qusType) {  
879 - //同类型批量答案+1  
880 - types[addndex].subNum += 1;  
881 - if (  
882 - types[addndex].answerOptions.length < sub.answerOptions.length  
883 - ) {  
884 - types[addndex].answerOptions = sub.answerOptions;  
885 - }  
886 - types[addndex].answerList += this.setAnswer(  
887 - sub.questionType,  
888 - sub.correctAnswer  
889 - );  
890 - if (index == item.subQuestions.length - 1) {  
891 - //循环最后类型数量大于等于5,保存批量答案  
892 - if (types[addndex].subNum && types[addndex].subNum >= 5) {  
893 - types[addndex].endIndex = sub.questionIndex;  
894 - types[addndex].index = index;  
895 - }  
896 - }  
897 - } else {  
898 - if (types[addndex].subNum && types[addndex].subNum >= 5) {  
899 - //不同类型时如果原有类型数量大于等于5,保存批量答案  
900 - types[addndex].endIndex =  
901 - item.subQuestions[index - 1].questionIndex;  
902 - types[addndex].index = index;  
903 - addndex += 1;  
904 - types[addndex] = {};  
905 - }  
906 - //不同类型初始化批量答案  
907 - types[addndex].qusType = sub.questionType;  
908 - types[addndex].subNum = 1;  
909 - types[addndex].answerOptions = sub.answerOptions;  
910 - types[addndex].answerList = this.setAnswer(  
911 - sub.questionType,  
912 - sub.correctAnswer  
913 - );  
914 - }  
915 - }  
916 - });  
917 - for (let i = 0; i < types.length; i++) {  
918 - if (types[i].qusType == 3) {  
919 - types[i].answerList = types[i].answerList.slice(0, -1);  
920 - }  
921 - if (types[i].subNum >= 5) {  
922 - item.subQuestions.splice(  
923 - types[i].index + i,  
924 - 0,  
925 - deepClone(types[i])  
926 - );  
927 - }  
928 - }  
929 - }); 400 + this.form = { ...item };
930 this.dialogVisible = true; 401 this.dialogVisible = true;
931 }, 402 },
932 - setFormAns(index, indexs) {  
933 - //初始化要修改的答案  
934 - this.formAns = { ...this.questionList[index].subQuestions[indexs] };  
935 - this.formAns.listIndex = index;  
936 - this.diaSetAns = true;  
937 - },  
938 - saveFormAns() {  
939 - //批量修改答案  
940 - let EndIndex;  
941 - let subNum = this.formAns.subNum - 1;  
942 - this.questionList[this.formAns.listIndex].subQuestions.some(  
943 - (item, index) => {  
944 - if (this.formAns.endIndex == item.questionIndex) {  
945 - EndIndex = index;  
946 - return;  
947 - }  
948 - }  
949 - );  
950 - for (let i = 0; i <= subNum; i++) {  
951 - let correctAnswer = "";  
952 - if (this.formAns.qusType == 2) {  
953 - correctAnswer = this.formAns.answerList[subNum - i];  
954 - } else if (this.formAns.qusType == 3) {  
955 - correctAnswer = this.formAns.answerList.split(",")[subNum - i];  
956 -  
957 - console.log(this.formAns.answerList.split(",")[subNum - i]);  
958 - } else if (this.formAns.qusType == 4) {  
959 - correctAnswer = this.formAns.answerList[subNum - i] == "✓" ? 1 : 2;  
960 - }  
961 - this.questionList[this.formAns.listIndex].subQuestions[  
962 - EndIndex - i  
963 - ].correctAnswer = correctAnswer;  
964 - }  
965 - this.diaSetAns = false;  
966 - },  
967 - async saveAnswer() {  
968 - //保存答案  
969 - for (let i = 0; i < this.questionList.length; i++) {  
970 - for (let j = 0; j < this.questionList[i].subQuestions.length; j++) {  
971 - if (this.questionList[i].subQuestions[j].qusType) {  
972 - this.questionList[i].subQuestions.splice(j, 1);  
973 - }  
974 - }  
975 - }  
976 - const { data, status, message } = await this.$request.modifyPaper({  
977 - paperId: this.form.id,  
978 - questionList: [...this.questionList],  
979 - });  
980 - if (status == 0) {  
981 - this._QueryData();  
982 - } else {  
983 - this.$message.error(message);  
984 - } 403 + changeTab() {
  404 + this.page = 1;
  405 + this._QueryData();
985 }, 406 },
986 -  
987 async changClazz() { 407 async changClazz() {
  408 + this.page = 1;
988 await this._QuerySubjectList(); 409 await this._QuerySubjectList();
989 - await this.setDate(1); 410 + await this._QueryData();
990 }, 411 },
991 async _QueryClassList() { 412 async _QueryClassList() {
992 - const { data, status, info } = await this.$request.fetchClassList(); 413 + const fetchClassList =
  414 + this.role == "ROLE_BANZHUREN"
  415 + ? this.$request.cTClassList
  416 + : this.$request.tClassList;
  417 + const { data, status, info } = await fetchClassList();
993 if (status === 0) { 418 if (status === 0) {
994 this.classList = data.list.map((item) => { 419 this.classList = data.list.map((item) => {
995 return { 420 return {
@@ -1003,7 +428,12 @@ export default { @@ -1003,7 +428,12 @@ export default {
1003 } 428 }
1004 }, 429 },
1005 async _QuerySubjectList() { 430 async _QuerySubjectList() {
1006 - const { data, status, info } = await this.$request.fetchSubjectList({ 431 + const fetchSubjectList =
  432 + this.role == "ROLE_BANZHUREN"
  433 + ? this.$request.cTSubjectList
  434 + : this.$request.tSubjectList;
  435 +
  436 + const { data, status, info } = await fetchSubjectList({
1007 classId: this.query.classId, 437 classId: this.query.classId,
1008 }); 438 });
1009 if (status === 0) { 439 if (status === 0) {
@@ -1016,31 +446,135 @@ export default { @@ -1016,31 +446,135 @@ export default {
1016 }) || []; 446 }) || [];
1017 if (this.role == "ROLE_BANZHUREN") { 447 if (this.role == "ROLE_BANZHUREN") {
1018 this.subjectList.unshift({ 448 this.subjectList.unshift({
1019 - value: "", 449 + value: "全部",
1020 label: "全部", 450 label: "全部",
1021 }); 451 });
1022 - this.query.subjectId = [this.subjectList[0]?.value]; 452 + this.query.subjectNames.push(this.subjectList[0]?.value);
1023 } else { 453 } else {
1024 - this.query.subjectId = this.subjectList[0]?.value; 454 + this.query.subjectNames = this.subjectList[0]?.value;
1025 } 455 }
1026 } else { 456 } else {
1027 this.$message.error(info); 457 this.$message.error(info);
1028 } 458 }
1029 }, 459 },
1030 async _QueryData() { 460 async _QueryData() {
  461 + this.tableData = [];
  462 + if (this.tabIndex == 1) {
  463 + this.examReportList();
  464 + } else {
  465 + this.phaseExamReport();
  466 + }
  467 + },
  468 + //单卷测练
  469 + async examReportList() {
1031 this.loading = true; 470 this.loading = true;
1032 - //多课时对比  
1033 let query = {}; 471 let query = {};
1034 for (let key in this.query) { 472 for (let key in this.query) {
1035 if (this.query[key] != "") { 473 if (this.query[key] != "") {
1036 query[key] = this.query[key]; 474 query[key] = this.query[key];
1037 } 475 }
1038 } 476 }
1039 - const { data, status, info } = await this.$request.fetchQuizList({ 477 + if (this.role != "ROLE_BANZHUREN") {
  478 + query.subjectNames = [query.subjectNames];
  479 + } else {
  480 + if (
  481 + query["subjectNames"].length == 1 &&
  482 + query["subjectNames"][0] == "全部"
  483 + ) {
  484 + query["subjectNames"] = this.subjectList.map((item) => {
  485 + return item.value;
  486 + });
  487 + query["subjectNames"].shift();
  488 + }
  489 + }
  490 + const { data, status, info } = await this.$request.examReportList({
1040 ...query, 491 ...query,
  492 + page: this.page,
  493 + size: this.size,
1041 }); 494 });
1042 this.loading = false; 495 this.loading = false;
1043 if (status === 0) { 496 if (status === 0) {
  497 + this.tableData = (data?.list && [...data?.list]) || [];
  498 + this.total = data.count;
  499 + } else {
  500 + this.$message.error(info);
  501 + }
  502 + },
  503 + //多卷测练
  504 + async phaseExamReport() {
  505 + this.loading = true;
  506 + let query = {};
  507 + for (let key in this.query) {
  508 + if (this.query[key] != "") {
  509 + if (key == "subjectNames" && this.role != "ROLE_BANZHUREN") {
  510 + query["subjectName"] = this.query[key];
  511 + } else {
  512 + query[key] = this.query[key];
  513 + }
  514 + }
  515 + }
  516 + if (this.role == "ROLE_BANZHUREN") {
  517 + if (
  518 + query["subjectNames"].length == 1 &&
  519 + query["subjectNames"][0] == "全部"
  520 + ) {
  521 + query["subjectNames"] = this.subjectList.map((item) => {
  522 + return item.value;
  523 + });
  524 + query["subjectNames"].shift();
  525 + }
  526 + }
  527 + const phaseExamReport =
  528 + this.role == "ROLE_BANZHUREN"
  529 + ? this.$request.cTPhaseExamReport
  530 + : this.$request.phaseExamReport;
  531 + const { data, status, info } = await phaseExamReport({
  532 + ...query,
  533 + });
  534 + this.loading = false;
  535 + if (status === 0) {
  536 + this.total = data.count;
  537 + let dataIdsList = [],
  538 + dataList = [];
  539 + data?.list.map((item) => {
  540 + item.examList.map((items) => {
  541 + if (this.role == "ROLE_JITUAN") {
  542 + // if (!dataIdsList.includes(items.grade)) {
  543 + // dataIdsList.push(items.grade);
  544 + // dataList.push(items);
  545 + // }
  546 + } else {
  547 + if (!dataIdsList.includes(items.title)) {
  548 + dataIdsList.push(items.title);
  549 + dataList.push(items);
  550 + }
  551 + }
  552 + });
  553 + });
  554 + console.log(dataList);
  555 + this.tableData = data?.list.map((item) => {
  556 + let params = {};
  557 + dataIdsList.map((ids, index) => {
  558 + params["score" + index] = "--";
  559 + params["classRank" + index] = "--";
  560 + item.examList.map((items) => {
  561 + if (this.role == "ROLE_JITUAN") {
  562 + if (items.title == ids) {
  563 + }
  564 + } else {
  565 + if (items.title == ids) {
  566 + params["score" + index] = items.score;
  567 + params["classRank" + index] = items.classRank;
  568 + }
  569 + }
  570 + });
  571 + });
  572 + return {
  573 + ...item,
  574 + ...params,
  575 + };
  576 + });
  577 + this.answerList = dataList;
1044 } else { 578 } else {
1045 this.$message.error(info); 579 this.$message.error(info);
1046 } 580 }
@@ -1049,7 +583,24 @@ export default { @@ -1049,7 +583,24 @@ export default {
1049 }; 583 };
1050 </script> 584 </script>
1051 585
  586 +<style>
  587 +div::-webkit-scrollbar {
  588 + width: 3px;
  589 + height: 10px;
  590 +}
  591 +div::-webkit-scrollbar-thumb {
  592 + border-radius: 10px;
  593 + background-color: #ccc;
  594 +}
  595 +</style>
1052 <style lang="scss" scoped> 596 <style lang="scss" scoped>
  597 +.page-container {
  598 + position: relative;
  599 + &.active {
  600 + height: 100%;
  601 + overflow: hidden;
  602 + }
  603 +}
1053 .table-box { 604 .table-box {
1054 margin: 0 20px; 605 margin: 0 20px;
1055 padding: 16px; 606 padding: 16px;
@@ -1062,60 +613,9 @@ export default { @@ -1062,60 +613,9 @@ export default {
1062 padding-left: 2px; 613 padding-left: 2px;
1063 } 614 }
1064 } 615 }
1065 -  
1066 -.fa-exchange {  
1067 - color: #667ffd;  
1068 - cursor: pointer;  
1069 - font-size: 16px;  
1070 - margin-left: 10px;  
1071 -}  
1072 -.dia-btn {  
1073 - border-radius: 20px;  
1074 - margin: 0 20px;  
1075 - padding: 10px 20px;  
1076 -}  
1077 -.dia-tips {  
1078 - padding-bottom: 10px;  
1079 -}  
1080 -.answer-s {  
1081 - width: 32px;  
1082 - height: 28px;  
1083 - cursor: pointer;  
1084 - user-select: none;  
1085 -}  
1086 -.set-questions {  
1087 - display: flex;  
1088 - margin-bottom: 12px;  
1089 - width: 100%;  
1090 - .qs-num {  
1091 - flex-shrink: 0;  
1092 - margin-right: 10px;  
1093 - }  
1094 -}  
1095 -.qs-options {  
1096 - flex: 1;  
1097 - .ipt {  
1098 - margin-bottom: 5px;  
1099 - }  
1100 - .delButton {  
1101 - border-color: #ff6868;  
1102 - background: #ff6868 url("../../assets/images/arrow.png") no-repeat center;  
1103 - background-size: 19px;  
1104 - cursor: pointer;  
1105 - color: transparent;  
1106 - }  
1107 - .ac {  
1108 - border-color: #ff6868;  
1109 - background: #ff6868;  
1110 - color: #fff;  
1111 - }  
1112 -}  
1113 .down { 616 .down {
1114 padding-top: 16px; 617 padding-top: 16px;
1115 } 618 }
1116 -.page-container {  
1117 - position: relative;  
1118 -}  
1119 .edit-dia { 619 .edit-dia {
1120 position: absolute; 620 position: absolute;
1121 left: 0; 621 left: 0;
@@ -1123,128 +623,9 @@ export default { @@ -1123,128 +623,9 @@ export default {
1123 right: 0; 623 right: 0;
1124 bottom: 0; 624 bottom: 0;
1125 width: 100%; 625 width: 100%;
1126 - height: calc(100vh - 80px); 626 + height: calc(100vh - 70px);
1127 background: #fff; 627 background: #fff;
1128 overflow-y: auto; 628 overflow-y: auto;
1129 z-index: 10; 629 z-index: 10;
1130 - .back {  
1131 - width: 100%;  
1132 - height: 56px;  
1133 - border-bottom: 1px solid #e2e2e2;  
1134 - display: flex;  
1135 - align-items: center;  
1136 - padding: 0 20px;  
1137 - box-sizing: border-box;  
1138 - .back-l {  
1139 - display: flex;  
1140 - align-items: center;  
1141 - cursor: pointer;  
1142 - flex-shrink: 0;  
1143 - font-size: 18px;  
1144 - font-weight: 500;  
1145 - }  
1146 - .fa-mail-reply-all {  
1147 - font-size: 28px;  
1148 - color: #b3b3b3;  
1149 - margin-right: 12px;  
1150 - }  
1151 - }  
1152 - .form-box {  
1153 - padding: 20px;  
1154 - }  
1155 - .answer-title {  
1156 - text-align: center;  
1157 - font-size: 20px;  
1158 - color: #333;  
1159 - font-weight: 700;  
1160 - padding-bottom: 20px;  
1161 - .totals {  
1162 - font-size: 16px;  
1163 - color: #888;  
1164 - font-weight: normal;  
1165 - }  
1166 - }  
1167 - .question-title {  
1168 - line-height: 40px;  
1169 - .ipt {  
1170 - width: 300px;  
1171 - margin: 0 16px 0 10px;  
1172 - :deep(.el-input__inner) {  
1173 - border-radius: 20px;  
1174 - border-color: #667ffd;  
1175 - background: rgba($color: #667ffd, $alpha: 0.05);  
1176 - }  
1177 - }  
1178 - .delete {  
1179 - margin-right: 8px;  
1180 - }  
1181 - .title-txt {  
1182 - margin-right: 20px;  
1183 - font-size: 16px;  
1184 - font-weight: 700;  
1185 - }  
1186 - }  
1187 - .questions-ul {  
1188 - border-left: 1px solid #e2e2e2;  
1189 - border-top: 1px solid #e2e2e2;  
1190 - margin: 12px 0;  
1191 - }  
1192 - .sub-questions {  
1193 - width: 100%;  
1194 - display: flex;  
1195 - border-bottom: 1px solid #e2e2e2;  
1196 - & > div {  
1197 - min-height: 40px;  
1198 - padding: 5px;  
1199 - flex-shrink: 0;  
1200 - border-right: 1px solid #e2e2e2;  
1201 - display: flex;  
1202 - justify-content: center;  
1203 - align-items: center;  
1204 - }  
1205 - .qs-num {  
1206 - width: 80px;  
1207 - }  
1208 - .qs-type {  
1209 - width: 160px;  
1210 - }  
1211 - .qs-score,  
1212 - .qs-partScore {  
1213 - width: 160px;  
1214 - }  
1215 - .qs-options {  
1216 - flex: 1;  
1217 - }  
1218 - .qs-set {  
1219 - width: 80px;  
1220 - }  
1221 - .qs-options2 {  
1222 - text-align: left;  
1223 - justify-content: flex-start;  
1224 - padding-left: 20px;  
1225 - .answer-s {  
1226 - cursor: pointer;  
1227 - }  
1228 - }  
1229 - :deep(.el-select) {  
1230 - .el-input__inner {  
1231 - border-radius: 20px;  
1232 - border-color: #667ffd;  
1233 - width: 150px;  
1234 - height: 32px;  
1235 - line-height: 32px;  
1236 - background: rgba($color: #667ffd, $alpha: 0.05);  
1237 - }  
1238 - .el-input__icon {  
1239 - line-height: 32px;  
1240 - }  
1241 - }  
1242 - }  
1243 - .set-ans-btn {  
1244 - width: 100%;  
1245 - padding: 10px 0 10px 630px;  
1246 - box-sizing: border-box;  
1247 - border-bottom: 1px solid #e2e2e2;  
1248 - }  
1249 } 630 }
1250 </style> 631 </style>
1251 \ No newline at end of file 632 \ No newline at end of file