Commit 255e2506f2be1faa5f97e4a098961b2e471db2a6

Authored by 梁保满
1 parent dbbfc6c5

飞书bug及优化

src/api/apis/apis.js
@@ -201,6 +201,7 @@ export default { @@ -201,6 +201,7 @@ export default {
201 url: setUpUrls.subjectiveScoreTemplate, 201 url: setUpUrls.subjectiveScoreTemplate,
202 method: "POST", 202 method: "POST",
203 data, 203 data,
  204 + responseType: 'arraybuffer',
204 }); 205 });
205 }, 206 },
206 //任课老师-导入主观题得分 207 //任课老师-导入主观题得分
@@ -236,11 +237,14 @@ export default { @@ -236,11 +237,14 @@ export default {
236 }); 237 });
237 }, 238 },
238 //任课老师-数据导出 239 //任课老师-数据导出
239 - exportData(data) { 240 + exportData() {
240 return service({ 241 return service({
241 url: setUpUrls.exportData, 242 url: setUpUrls.exportData,
242 method: "POST", 243 method: "POST",
243 - data, 244 + responseType: 'arraybuffer',
  245 + headers:{
  246 + 'Content-Type':'application/octet-stream'
  247 + }
244 }); 248 });
245 }, 249 },
246 //任课老师-数据导入 250 //任课老师-数据导入
@@ -251,6 +255,33 @@ export default { @@ -251,6 +255,33 @@ export default {
251 data, 255 data,
252 }); 256 });
253 }, 257 },
  258 + //任课老师-导出阶段问答报表
  259 + exportPhaseAnswerReport(data) {
  260 + return service({
  261 + url: setUpUrls.exportPhaseAnswerReport,
  262 + method: "POST",
  263 + data,
  264 + responseType: 'arraybuffer',
  265 + });
  266 + },
  267 + //任课老师-导出阶段互动报表
  268 + exportPhaseInteractiveReport(data) {
  269 + return service({
  270 + url: setUpUrls.exportPhaseInteractiveReport,
  271 + method: "POST",
  272 + data,
  273 + responseType: 'arraybuffer',
  274 + });
  275 + },
  276 + //任课老师-导出单课时报表
  277 + exportPeriodReport(data) {
  278 + return service({
  279 + url: setUpUrls.exportPeriodReport,
  280 + method: "POST",
  281 + data,
  282 + responseType: 'arraybuffer',
  283 + });
  284 + },
254 285
255 286
256 // 查询角色列表 287 // 查询角色列表
@@ -501,6 +532,15 @@ export default { @@ -501,6 +532,15 @@ export default {
501 data, 532 data,
502 }); 533 });
503 }, 534 },
  535 + // 导出设备使用分析
  536 + exportUsageAnalysis(data) {
  537 + return service({
  538 + url: setUpUrls.exportUsageAnalysis,
  539 + method: "POST",
  540 + data,
  541 + responseType: 'arraybuffer',
  542 + });
  543 + },
504 544
505 /** 545 /**
506 * 集团管理员-学校管理 546 * 集团管理员-学校管理
@@ -641,4 +681,20 @@ export default { @@ -641,4 +681,20 @@ export default {
641 data, 681 data,
642 }); 682 });
643 }, 683 },
  684 + // 导出学校使用对比
  685 + exportSchoolContrast(data) {
  686 + return service({
  687 + url: setUpUrls.exportSchoolContrast,
  688 + method: "POST",
  689 + data,
  690 + });
  691 + },
  692 + // 导出年级使用对比
  693 + exportGradeContrast(data) {
  694 + return service({
  695 + url: setUpUrls.exportGradeContrast,
  696 + method: "POST",
  697 + data,
  698 + });
  699 + },
644 }; 700 };
src/api/axios.js
@@ -15,7 +15,7 @@ const service = axios.create({ @@ -15,7 +15,7 @@ const service = axios.create({
15 service.interceptors.request.use( 15 service.interceptors.request.use(
16 (config) => { 16 (config) => {
17 NProgress.start(); 17 NProgress.start();
18 - config.headers["Content-Type"] = "application/json;charset=UTF-8"; 18 + // config.headers["Content-Type"] = "application/json;charset=UTF-8";
19 19
20 const source = axios.CancelToken.source(); 20 const source = axios.CancelToken.source();
21 store.commit("setTokenSources", [source.token, source.cancel]); 21 store.commit("setTokenSources", [source.token, source.cancel]);
@@ -47,16 +47,15 @@ service.interceptors.response.use( @@ -47,16 +47,15 @@ service.interceptors.response.use(
47 window.location.href = res.data; 47 window.location.href = res.data;
48 } else { 48 } else {
49 router.push({ path: "/login" }); 49 router.push({ path: "/login" });
50 - if (res.message.includes("不存在")) { 50 + if (res.info.includes("不存在")) {
51 Message({ 51 Message({
52 - message: res.message, 52 + info: res.info,
53 type: "error", 53 type: "error",
54 duration: 3 * 1000, 54 duration: 3 * 1000,
55 }); 55 });
56 } 56 }
57 } 57 }
58 } 58 }
59 - return  
60 } else { 59 } else {
61 // Cookies.set("access_token", response.data.message, { expires: 1 / 12 }) 60 // Cookies.set("access_token", response.data.message, { expires: 1 / 12 })
62 } 61 }
@@ -73,7 +72,7 @@ service.interceptors.response.use( @@ -73,7 +72,7 @@ service.interceptors.response.use(
73 if (data.status === 999) { 72 if (data.status === 999) {
74 console.log(data.data) 73 console.log(data.data)
75 if (data.data) { 74 if (data.data) {
76 - window.location.href = data.data; 75 + window.location.href = data.data;
77 } else { 76 } else {
78 Message({ 77 Message({
79 message: data.info, 78 message: data.info,
src/api/urls/apis.js
@@ -63,6 +63,12 @@ export default { @@ -63,6 +63,12 @@ export default {
63 exportData: "/api_html/teaching/exportData", 63 exportData: "/api_html/teaching/exportData",
64 //任课老师-数据导入 64 //任课老师-数据导入
65 importData: "/api_html/teaching/importData", 65 importData: "/api_html/teaching/importData",
  66 + //任课老师-导出阶段问答报表
  67 + exportPhaseAnswerReport: "/api_html/teaching/exportPhaseAnswerReport",
  68 + //任课老师-导出阶段互动报表
  69 + exportPhaseInteractiveReport: "/api_html/teaching/exportPhaseInteractiveReport",
  70 + //任课老师-导出单课时报表
  71 + exportPeriodReport: "/api_html/teaching/exportPeriodReport",
66 72
67 73
68 74
@@ -130,6 +136,8 @@ export default { @@ -130,6 +136,8 @@ export default {
130 usageAnalysis: "/api_html/school/manager/usageAnalysis", 136 usageAnalysis: "/api_html/school/manager/usageAnalysis",
131 // 发卡记录 137 // 发卡记录
132 cardList: "/api_html/school/manager/cardList", 138 cardList: "/api_html/school/manager/cardList",
  139 + // 导出设备使用分析
  140 + exportUsageAnalysis: "/api_html/school/manager/exportUsageAnalysis",
133 141
134 142
135 // 查询区域列表 143 // 查询区域列表
@@ -167,4 +175,8 @@ export default { @@ -167,4 +175,8 @@ export default {
167 schoolContrast: "/api_html/tenant/schoolContrast", 175 schoolContrast: "/api_html/tenant/schoolContrast",
168 // 年级使用对比 176 // 年级使用对比
169 gradeContrast: "/api_html/tenant/gradeContrast", 177 gradeContrast: "/api_html/tenant/gradeContrast",
  178 + // 导出学校使用对比
  179 + exportSchoolContrast: "/api_html/tenant/exportSchoolContrast",
  180 + // 导出年级使用对比
  181 + exportGradeContrast: "/api_html/tenant/exportGradeContrast",
170 } 182 }
src/components/upload.vue
@@ -76,17 +76,18 @@ export default { @@ -76,17 +76,18 @@ export default {
76 // } 76 // }
77 }, 77 },
78 upSuccess(res) { 78 upSuccess(res) {
79 - if (res && res.code == 0 && res.success) { 79 + debugger
  80 + if (res && res.status == 0 ) {
80 this.$message.success("上传成功"); 81 this.$message.success("上传成功");
81 this.$emit("upSuccess"); 82 this.$emit("upSuccess");
82 } else { 83 } else {
83 - this.$message.error(res.message); 84 + this.$message.error(res.info);
84 } 85 }
85 }, 86 },
86 upError(res) { 87 upError(res) {
  88 + debugger
87 if (res && res.status == 0) { 89 if (res && res.status == 0) {
88 - this.$message.success("上传成功");  
89 - this.$emit("upSuccess"); 90 + this.$message.error("上传失败");
90 } else { 91 } else {
91 this.$message.error(res.message); 92 this.$message.error(res.message);
92 } 93 }
src/router/index.js
@@ -168,22 +168,22 @@ let addrouters = [ //测试用,后续后端获取 @@ -168,22 +168,22 @@ let addrouters = [ //测试用,后续后端获取
168 168
169 ] 169 ]
170 }, 170 },
171 - {  
172 - path: "/portrait",  
173 - iconCls: "fa fa-users", // 图标样式class  
174 - name: "学生画像",  
175 - component: Layout,  
176 - alone: true,  
177 - children: [  
178 - {  
179 - path: "/portrait",  
180 - iconCls: "fa fa-users", // 图标样式class  
181 - name: "",  
182 - component: Portrait,  
183 - children: []  
184 - }  
185 - ]  
186 - }, 171 + // {
  172 + // path: "/portrait",
  173 + // iconCls: "fa fa-users", // 图标样式class
  174 + // name: "学生画像",
  175 + // component: Layout,
  176 + // alone: true,
  177 + // children: [
  178 + // {
  179 + // path: "/portrait",
  180 + // iconCls: "fa fa-users", // 图标样式class
  181 + // name: "",
  182 + // component: Portrait,
  183 + // children: []
  184 + // }
  185 + // ]
  186 + // },
187 187
188 { 188 {
189 path: "/setUpConglomerate", 189 path: "/setUpConglomerate",
@@ -246,22 +246,22 @@ let addrouters = [ //测试用,后续后端获取 @@ -246,22 +246,22 @@ let addrouters = [ //测试用,后续后端获取
246 }, 246 },
247 ] 247 ]
248 }, 248 },
249 - {  
250 - path: "/card",  
251 - iconCls: "fa fa-id-card", // 图标样式class  
252 - name: "发卡记录",  
253 - component: Layout,  
254 - alone: true,  
255 - children: [  
256 - {  
257 - path: "/card",  
258 - iconCls: "fa fa-id-card", // 图标样式class  
259 - name: "",  
260 - component: Card,  
261 - children: []  
262 - }  
263 - ]  
264 - }, 249 + // {
  250 + // path: "/card",
  251 + // iconCls: "fa fa-id-card", // 图标样式class
  252 + // name: "发卡记录",
  253 + // component: Layout,
  254 + // alone: true,
  255 + // children: [
  256 + // {
  257 + // path: "/card",
  258 + // iconCls: "fa fa-id-card", // 图标样式class
  259 + // name: "",
  260 + // component: Card,
  261 + // children: []
  262 + // }
  263 + // ]
  264 + // },
265 { 265 {
266 path: "/device", 266 path: "/device",
267 iconCls: "fa fa-dashboard", // 图标样式class 267 iconCls: "fa fa-dashboard", // 图标样式class
src/utils/index.js
@@ -709,3 +709,35 @@ export function formatGradeClass(data) { @@ -709,3 +709,35 @@ export function formatGradeClass(data) {
709 }); 709 });
710 return gradeNameArr; 710 return gradeNameArr;
711 } 711 }
  712 +export function formatGradeNameClass(data) {
  713 + let gradeName = [];
  714 + let gradeNameArr = [];
  715 + data.map((item) => {
  716 + if (!gradeName.includes(item.gradeName)) {
  717 + gradeName.push(item.gradeName);
  718 + gradeNameArr.push({
  719 + value: item.gradeName,
  720 + label: item.gradeName,
  721 + grade: item.grade,
  722 + children: [
  723 + {
  724 + value: item.classCode,
  725 + label: item.className,
  726 + },
  727 + ],
  728 + });
  729 + } else {
  730 + let gradeIndex = 0;
  731 + gradeNameArr.map((items, index) => {
  732 + if (items.value == item.gradeName) {
  733 + gradeIndex = index;
  734 + }
  735 + });
  736 + gradeNameArr[gradeIndex].children.push({
  737 + value: item.classCode,
  738 + label: item.className,
  739 + });
  740 + }
  741 + });
  742 + return gradeNameArr;
  743 +}
src/views/analysis/index.vue
@@ -96,9 +96,7 @@ @@ -96,9 +96,7 @@
96 :label=" 96 :label="
97 role == 'ROLE_JITUAN' 97 role == 'ROLE_JITUAN'
98 ? item.schoolName || item.gradeName 98 ? item.schoolName || item.gradeName
99 - : query.gradeName == ''  
100 - ? item.gradeName  
101 - : item.className 99 + : item.gradeName || item.className
102 " 100 "
103 > 101 >
104 <template> 102 <template>
@@ -116,7 +114,7 @@ @@ -116,7 +114,7 @@
116 </el-table-column> 114 </el-table-column>
117 </el-table> 115 </el-table>
118 <p class="down" v-if="role != 'ROLE_JITUAN'"> 116 <p class="down" v-if="role != 'ROLE_JITUAN'">
119 - <el-button plain round icon="fa fa-cloud-download" 117 + <el-button @click="downExc" plain round icon="fa fa-cloud-download"
120 >导出报表</el-button 118 >导出报表</el-button
121 > 119 >
122 </p> 120 </p>
@@ -126,10 +124,11 @@ @@ -126,10 +124,11 @@
126 </template> 124 </template>
127 125
128 <script> 126 <script>
129 -import { formatDate } from "@/utils"; 127 +import { formatDate,downloadFile } from "@/utils";
130 export default { 128 export default {
131 data() { 129 data() {
132 return { 130 return {
  131 + exportLoading: false,
133 role: "", 132 role: "",
134 date: "", //今天-本周-本月-本季度 133 date: "", //今天-本周-本月-本季度
135 type: 1, //集团管理员 表格切换 134 type: 1, //集团管理员 表格切换
@@ -159,6 +158,35 @@ export default { @@ -159,6 +158,35 @@ export default {
159 } 158 }
160 }, 159 },
161 methods: { 160 methods: {
  161 + async downExc() {
  162 + if (this.exportLoading == true) return;
  163 + let query = {};
  164 + for (let key in this.query) {
  165 + if (this.query[key] != "") {
  166 + if (key == "gradeName") {
  167 + query[key] = this.query[key] == "全部" ? "" : this.query[key];
  168 + } else {
  169 + query[key] = this.query[key];
  170 + }
  171 + }
  172 + }
  173 + if (this.role == "ROLE_JITUAN") {
  174 + delete query.gradeName;
  175 + } else {
  176 + delete query.regionId;
  177 + }
  178 + this.exportLoading = true;
  179 + const data = await this.$request.exportUsageAnalysis({ ...query });
  180 + this.exportLoading = false;
  181 + if (data) {
  182 + let blob = new Blob([data], {
  183 + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  184 + });
  185 + downloadFile("使用分析.xlsx", blob);
  186 + } else {
  187 + this.$message.error("下载失败");
  188 + }
  189 + },
162 changeType(val) { 190 changeType(val) {
163 if (val == 1) { 191 if (val == 1) {
164 this.query.regionId = ""; 192 this.query.regionId = "";
@@ -185,7 +213,7 @@ export default { @@ -185,7 +213,7 @@ export default {
185 //中国式星期天是一周的最后一天 213 //中国式星期天是一周的最后一天
186 day = 7; 214 day = 7;
187 } 215 }
188 - day-- 216 + day--;
189 let aTime = new Date().getTime() - 24 * 60 * 60 * 1000 * day; 217 let aTime = new Date().getTime() - 24 * 60 * 60 * 1000 * day;
190 that.query.startDay = formatDate(new Date(aTime), "yyyy-MM-dd"); 218 that.query.startDay = formatDate(new Date(aTime), "yyyy-MM-dd");
191 that.query.endDay = formatDate(new Date(), "yyyy-MM-dd"); 219 that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
@@ -241,7 +269,7 @@ export default { @@ -241,7 +269,7 @@ export default {
241 for (let key in this.query) { 269 for (let key in this.query) {
242 if (this.query[key] != "") { 270 if (this.query[key] != "") {
243 if (key == "gradeName") { 271 if (key == "gradeName") {
244 - query[key] = this.query[key]=="全部"?"":this.query[key]; 272 + query[key] = this.query[key] == "全部" ? "" : this.query[key];
245 } else { 273 } else {
246 query[key] = this.query[key]; 274 query[key] = this.query[key];
247 } 275 }
@@ -282,12 +310,12 @@ export default { @@ -282,12 +310,12 @@ export default {
282 } 310 }
283 } 311 }
284 } else { 312 } else {
285 - if (this.query.gradeName == "") { 313 + if (this.query.gradeName == "全部") {
286 if (!dataIdsList.includes(items.grade)) { 314 if (!dataIdsList.includes(items.grade)) {
287 dataIdsList.push(items.grade); 315 dataIdsList.push(items.grade);
288 dataList.push(items); 316 dataList.push(items);
289 } 317 }
290 - } else if (this.query.gradeName) { 318 + } else{
291 if (!dataIdsList.includes(items.classId)) { 319 if (!dataIdsList.includes(items.classId)) {
292 dataIdsList.push(items.classId); 320 dataIdsList.push(items.classId);
293 dataList.push(items); 321 dataList.push(items);
@@ -316,7 +344,7 @@ export default { @@ -316,7 +344,7 @@ export default {
316 } 344 }
317 } 345 }
318 } else { 346 } else {
319 - if (this.query.gradeName == "") { 347 + if (this.query.gradeName == "全部") {
320 if (items.grade == ids) { 348 if (items.grade == ids) {
321 params["examCount" + index] = items.examCount; 349 params["examCount" + index] = items.examCount;
322 params["periodCount" + index] = items.periodCount; 350 params["periodCount" + index] = items.periodCount;
@@ -335,8 +363,8 @@ export default { @@ -335,8 +363,8 @@ export default {
335 ...params, 363 ...params,
336 }; 364 };
337 }); 365 });
338 - this.dataList = dataList.sort((a,b)=>{  
339 - return a.grade-b.grade 366 + this.dataList = dataList.sort((a, b) => {
  367 + return a.grade - b.grade;
340 }); 368 });
341 } else { 369 } else {
342 this.$message.error(info); 370 this.$message.error(info);
src/views/ask/analysis.vue
@@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
41 <li class="info-item">签到人数:{{ detail.answeredNum }}</li> 41 <li class="info-item">签到人数:{{ detail.answeredNum }}</li>
42 <li class="info-item">题目总数:{{ detail.questionNum }}</li> 42 <li class="info-item">题目总数:{{ detail.questionNum }}</li>
43 <li class="info-item">答题总数:{{ detail.totalAnswersNum }}</li> 43 <li class="info-item">答题总数:{{ detail.totalAnswersNum }}</li>
44 - <li class="info-item">课时时长:{{ detail.duration / 60 }}分钟</li> 44 + <li class="info-item">课时时长:{{ detail.duration }}分钟</li>
45 <li class="info-item">总参与度::{{ detail.participationRate }}%</li> 45 <li class="info-item">总参与度::{{ detail.participationRate }}%</li>
46 <li class="info-item"> 46 <li class="info-item">
47 班级总正确率:{{ detail.classCorrectRate }}% 47 班级总正确率:{{ detail.classCorrectRate }}%
@@ -50,7 +50,7 @@ @@ -50,7 +50,7 @@
50 已答总正确率:{{ detail.answerCorrectRate }}% 50 已答总正确率:{{ detail.answerCorrectRate }}%
51 </li> 51 </li>
52 <li class="info-item"> 52 <li class="info-item">
53 - 反馈时长:{{ detail.consumingDuration / 60 }}分钟 53 + 反馈时长:{{ detail.consumingDuration }}分钟
54 </li> 54 </li>
55 </ul> 55 </ul>
56 <el-table v-if="type == 1" :data="tableData" border style="width: 100%"> 56 <el-table v-if="type == 1" :data="tableData" border style="width: 100%">
@@ -103,16 +103,24 @@ @@ -103,16 +103,24 @@
103 >{{ scoped.row.answerCorrectRate }}%</template 103 >{{ scoped.row.answerCorrectRate }}%</template
104 ></el-table-column 104 ></el-table-column
105 > 105 >
106 - <el-table-column  
107 - prop="correctAnswer"  
108 - label="正确答案"  
109 - align="center"  
110 - > <template slot-scope="scoped">{{scoped.row.correctAnswer==1?"✓":scoped.row.correctAnswer==2?"✗":scoped.row.correctAnswer}}</template></el-table-column>  
111 - <el-table-column  
112 - prop="fallible"  
113 - label="干扰答案"  
114 - align="center"  
115 - ><template slot-scope="scoped">{{scoped.row.fallible==1?"✓":scoped.row.fallible==2?"✗":scoped.row.fallible}}</template></el-table-column> 106 + <el-table-column prop="correctAnswer" label="正确答案" align="center">
  107 + <template slot-scope="scoped">{{
  108 + scoped.row.correctAnswer == 1
  109 + ? "✓"
  110 + : scoped.row.correctAnswer == 2
  111 + ? "✗"
  112 + : scoped.row.correctAnswer
  113 + }}</template></el-table-column
  114 + >
  115 + <el-table-column prop="fallible" label="干扰答案" align="center"
  116 + ><template slot-scope="scoped">{{
  117 + scoped.row.fallible == 1
  118 + ? "✓"
  119 + : scoped.row.fallible == 2
  120 + ? "✗"
  121 + : scoped.row.fallible
  122 + }}</template></el-table-column
  123 + >
116 <!-- <el-table-column prop="screenshot" label="题干" align="center"> 124 <!-- <el-table-column prop="screenshot" label="题干" align="center">
117 <template slot-scope="scoped"> 125 <template slot-scope="scoped">
118 <el-image 126 <el-image
@@ -141,7 +149,7 @@ @@ -141,7 +149,7 @@
141 align="center" 149 align="center"
142 ></el-table-column> 150 ></el-table-column>
143 <el-table-column 151 <el-table-column
144 - prop="correctAnswerNum" 152 + prop="duration"
145 label="答题耗时" 153 label="答题耗时"
146 align="center" 154 align="center"
147 ></el-table-column> 155 ></el-table-column>
@@ -177,6 +185,17 @@ @@ -177,6 +185,17 @@
177 >{{ scoped.row.answerCorrectRate }}%</template 185 >{{ scoped.row.answerCorrectRate }}%</template
178 ></el-table-column 186 ></el-table-column
179 > 187 >
  188 + <el-table-column
  189 + v-for="(item, index) in optionsList"
  190 + :key="index"
  191 + :label="'Q' + (index + 1)"
  192 + align="center"
  193 + ><template slot-scope="scoped">
  194 + <span :class="scoped.row['isRight' + index] ? '' : 'red'">{{
  195 + scoped.row["answer" + index]
  196 + }}</span>
  197 + </template>
  198 + </el-table-column>
180 </el-table> 199 </el-table>
181 <el-table v-if="type == 3" :data="tableData" border style="width: 100%"> 200 <el-table v-if="type == 3" :data="tableData" border style="width: 100%">
182 <el-table-column 201 <el-table-column
@@ -266,7 +285,7 @@ @@ -266,7 +285,7 @@
266 icon="fa fa-cloud-download" 285 icon="fa fa-cloud-download"
267 >导出报表</el-button 286 >导出报表</el-button
268 > 287 >
269 - <el-button @click="edit" type="primary" round>修改答案</el-button> 288 + <!-- <el-button @click="edit" type="primary" round>修改答案</el-button> -->
270 </p> 289 </p>
271 </div> 290 </div>
272 </div> 291 </div>
@@ -296,6 +315,7 @@ export default { @@ -296,6 +315,7 @@ export default {
296 }, 315 },
297 detail: {}, 316 detail: {},
298 tableData: [], 317 tableData: [],
  318 + optionsList: [],
299 page: 1, 319 page: 1,
300 size: 20, 320 size: 20,
301 total: 0, 321 total: 0,
@@ -364,6 +384,12 @@ export default { @@ -364,6 +384,12 @@ export default {
364 }); 384 });
365 if (status == 0) { 385 if (status == 0) {
366 this.detail = { ...data }; 386 this.detail = { ...data };
  387 + this.detail.duration = this.detail.duration
  388 + ? (this.detail.duration / 60).toFixed(2)
  389 + : 0;
  390 + this.detail.consumingDuration = this.detail.consumingDuration
  391 + ? (this.detail.consumingDuration / 60).toFixed(2)
  392 + : 0;
367 } else { 393 } else {
368 this.$message.error(info); 394 this.$message.error(info);
369 } 395 }
@@ -390,7 +416,34 @@ export default { @@ -390,7 +416,34 @@ export default {
390 }); 416 });
391 this.loading = false; 417 this.loading = false;
392 if (status === 0) { 418 if (status === 0) {
393 - this.tableData = [...data?.list]; 419 + if (this.type == 2) {
  420 + let optionsList = [];
  421 + this.tableData = data?.list.map((item) => {
  422 + let params = {};
  423 + const detail = JSON.parse(item.detail);
  424 + if (detail.length > optionsList.length) {
  425 + optionsList = [...detail];
  426 + }
  427 + detail.map((items, index) => {
  428 + params["isRight" + index] = items.isRight;
  429 + params["answer" + index] =
  430 + items.answer == 1
  431 + ? "✓"
  432 + : items.answer == 2
  433 + ? "✗"
  434 + : items.answer;
  435 + });
  436 + return {
  437 + ...item,
  438 + ...params,
  439 + };
  440 + });
  441 + this.optionsList = [...optionsList];
  442 + } else {
  443 + this.tableData = data?.list.sort((a,b)=>{
  444 + return a.questionIndex-b.questionIndex
  445 + });
  446 + }
394 this.total = data.count; 447 this.total = data.count;
395 } else { 448 } else {
396 this.$message.error(info); 449 this.$message.error(info);
@@ -398,12 +451,17 @@ export default { @@ -398,12 +451,17 @@ export default {
398 }, 451 },
399 //导出 452 //导出
400 async exportData() { 453 async exportData() {
401 - // if (this.exportLoading = true) return; 454 + if (this.exportLoading == true) return;
402 this.exportLoading = true; 455 this.exportLoading = true;
403 - const { data, status, info } = await this.$request.exportData(); 456 + const data = await this.$request.exportPeriodReport({
  457 + periodId: this.id,
  458 + });
404 this.exportLoading = false; 459 this.exportLoading = false;
405 if (data) { 460 if (data) {
406 - downloadFile(this.detail.title + "报表", data); 461 + let blob = new Blob([data], {
  462 + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  463 + });
  464 + downloadFile("随堂问-单课时报表.xlsx", blob);
407 } else { 465 } else {
408 this.$message.error(info); 466 this.$message.error(info);
409 } 467 }
@@ -428,6 +486,7 @@ div::-webkit-scrollbar-thumb { @@ -428,6 +486,7 @@ div::-webkit-scrollbar-thumb {
428 display: flex; 486 display: flex;
429 justify-content: space-between; 487 justify-content: space-between;
430 } 488 }
  489 +.red{color:#f30}
431 .page-content { 490 .page-content {
432 padding: 20px 20px 0; 491 padding: 20px 20px 0;
433 } 492 }
src/views/ask/index.vue
@@ -7,7 +7,12 @@ @@ -7,7 +7,12 @@
7 </back-box> 7 </back-box>
8 <div class="answer-header"> 8 <div class="answer-header">
9 <div class="sel-box"> 9 <div class="sel-box">
10 - <el-select class="sel" v-model="query.classId" placeholder="选择班级"> 10 + <el-select
  11 + class="sel"
  12 + v-model="query.classId"
  13 + placeholder="选择班级"
  14 + @change="changeclass"
  15 + >
11 <el-option 16 <el-option
12 v-for="item in classList" 17 v-for="item in classList"
13 :key="item.value" 18 :key="item.value"
@@ -105,331 +110,346 @@ @@ -105,331 +110,346 @@
105 <span>总课时数:10</span> 110 <span>总课时数:10</span>
106 <span>互动总数:22</span> 111 <span>互动总数:22</span>
107 </p> --> 112 </p> -->
108 - <div v-show="tabIndex == 1">  
109 - <el-table  
110 - :data="tableData"  
111 - border  
112 - style="width: 100%"  
113 - @sort-change="sortChange"  
114 - >  
115 - <el-table-column  
116 - prop="title"  
117 - label="课时"  
118 - align="center"  
119 - ></el-table-column>  
120 - <el-table-column  
121 - prop="questionNum"  
122 - label="题目总数"  
123 - align="center"  
124 - width="100"  
125 - ></el-table-column>  
126 - <el-table-column  
127 - prop="startTime"  
128 - label="上课时间"  
129 - align="center"  
130 - ></el-table-column>  
131 - <el-table-column  
132 - prop="participationRate"  
133 - label="参与度"  
134 - sortable="custom"  
135 - align="center"  
136 - >  
137 - <template slot-scope="scoped"  
138 - >{{ scoped.row.participationRate }}%</template  
139 - ></el-table-column 113 + <div class="table-cont" v-loading="loading">
  114 + <div v-show="tabIndex == 1">
  115 + <el-table
  116 + :data="tableData"
  117 + border
  118 + style="width: 100%"
  119 + @sort-change="sortChange"
140 > 120 >
141 - <el-table-column  
142 - prop="answerCorrectRate"  
143 - label="已答总正确率"  
144 - sortable="custom"  
145 - align="center"  
146 - >  
147 - <template slot-scope="scoped"  
148 - >{{ scoped.row.answerCorrectRate }}%</template 121 + <el-table-column
  122 + prop="title"
  123 + label="课时"
  124 + align="center"
  125 + ></el-table-column>
  126 + <el-table-column
  127 + prop="questionNum"
  128 + label="题目总数"
  129 + align="center"
  130 + width="100"
  131 + ></el-table-column>
  132 + <el-table-column
  133 + prop="startTime"
  134 + label="上课时间"
  135 + align="center"
  136 + ></el-table-column>
  137 + <el-table-column
  138 + prop="participationRate"
  139 + label="参与度"
  140 + sortable="custom"
  141 + align="center"
149 > 142 >
150 - </el-table-column>  
151 - <el-table-column  
152 - prop="classCorrectRate"  
153 - label="班级总正确率"  
154 - sortable="custom"  
155 - align="center"  
156 - ><template slot-scope="scoped"  
157 - >{{ scoped.row.classCorrectRate }}%</template  
158 - ></el-table-column  
159 - >  
160 - <el-table-column label="操作" align="center">  
161 - <template slot-scope="scoped">  
162 - <el-tooltip  
163 - effect="dark"  
164 - v-if="scoped.row.answerNum == 0"  
165 - content="设置答案"  
166 - placement="top"  
167 - >  
168 - <el-button  
169 - type="primary"  
170 - circle  
171 - size="mini"  
172 - icon="fa fa-file-text"  
173 - @click="edit(scoped.row)"  
174 - ></el-button>  
175 - </el-tooltip>  
176 - <el-tooltip v-else effect="dark" content="详情" placement="top">  
177 - <el-button  
178 - type="primary"  
179 - circle  
180 - size="mini"  
181 - icon="fa fa-arrow-right"  
182 - @click="linkTo(scoped.row)"  
183 - ></el-button>  
184 - </el-tooltip>  
185 - </template>  
186 - </el-table-column>  
187 - </el-table>  
188 - </div>  
189 - <div v-show="tabIndex == 2">  
190 - <el-table  
191 - v-if="role == 'ROLE_JIAOSHI'"  
192 - :data="tableData"  
193 - border  
194 - style="width: 100%"  
195 - :default-sort="{ prop: 'answerTimes', order: 'descending' }"  
196 - >  
197 - <el-table-column  
198 - prop="studentCode"  
199 - label="学号"  
200 - align="center"  
201 - ></el-table-column>  
202 - <el-table-column  
203 - prop="studentName"  
204 - label="姓名"  
205 - align="center"  
206 - width="100"  
207 - ></el-table-column>  
208 - <el-table-column  
209 - prop="answerTimes"  
210 - label="累计答题次数"  
211 - sortable  
212 - align="center"  
213 - ></el-table-column>  
214 - <el-table-column  
215 - prop="correctAnswerTimes"  
216 - label="累计答对次数"  
217 - sortable  
218 - align="center"  
219 - ></el-table-column>  
220 - <el-table-column  
221 - prop="participationRate"  
222 - label="总参与度"  
223 - sortable  
224 - align="center"  
225 - >  
226 - <template slot-scope="scoped"  
227 - >{{ scoped.row.participationRate }}%</template  
228 - ></el-table-column  
229 - >  
230 - <el-table-column  
231 - prop="correctRate"  
232 - label="总正确率"  
233 - sortable  
234 - align="center"  
235 - >  
236 - <template slot-scope="scoped"  
237 - >{{ scoped.row.correctRate }}%</template  
238 - ></el-table-column  
239 - >  
240 - <el-table-column  
241 - prop="answerCorrectRate"  
242 - label="已答总正确率"  
243 - sortable  
244 - align="center"  
245 - >  
246 - <template slot-scope="scoped"  
247 - >{{ scoped.row.answerCorrectRate }}%</template 143 + <template slot-scope="scoped"
  144 + >{{ scoped.row.participationRate }}%</template
  145 + ></el-table-column
248 > 146 >
249 - </el-table-column>  
250 - <el-table-column  
251 - prop="classRank"  
252 - label="总正确率班排名"  
253 - sortable  
254 - align="center"  
255 - ></el-table-column>  
256 - </el-table>  
257 - <el-table :max-height="tableMaxHeight" v-else :data="tableData" border style="width: 100%">  
258 - <el-table-column  
259 - prop="studentCode"  
260 - label="学号"  
261 - align="center"  
262 - fixed  
263 - ></el-table-column>  
264 - <el-table-column  
265 - prop="studentName"  
266 - label="姓名"  
267 - align="center"  
268 - fixed  
269 - width="100"  
270 - ></el-table-column>  
271 - <el-table-column  
272 - v-for="(item, index) in phaseOption"  
273 - :key="index"  
274 - :label="item"  
275 - align="center"  
276 - >  
277 <el-table-column 147 <el-table-column
  148 + prop="answerCorrectRate"
  149 + label="已答总正确率"
  150 + sortable="custom"
278 align="center" 151 align="center"
279 - :label="index == 0 ? '总课时数' : '课时数'"  
280 - :prop="'periodCount' + item"  
281 > 152 >
  153 + <template slot-scope="scoped"
  154 + >{{ scoped.row.answerCorrectRate }}%</template
  155 + >
282 </el-table-column> 156 </el-table-column>
283 <el-table-column 157 <el-table-column
  158 + prop="classCorrectRate"
  159 + label="班级总正确率"
  160 + sortable="custom"
284 align="center" 161 align="center"
285 - :label="index == 0 ? '总出题数' : '出题数'"  
286 - :prop="'questionNum' + item" 162 + ><template slot-scope="scoped"
  163 + >{{ scoped.row.classCorrectRate }}%</template
  164 + ></el-table-column
287 > 165 >
  166 + <el-table-column label="操作" align="center">
  167 + <template slot-scope="scoped">
  168 + <el-tooltip
  169 + effect="dark"
  170 + v-if="scoped.row.answerNum == 0"
  171 + content="设置答案"
  172 + placement="top"
  173 + >
  174 + <el-button
  175 + type="primary"
  176 + circle
  177 + size="mini"
  178 + icon="fa fa-file-text"
  179 + @click="edit(scoped.row)"
  180 + ></el-button>
  181 + </el-tooltip>
  182 + <el-tooltip v-else effect="dark" content="详情" placement="top">
  183 + <el-button
  184 + type="primary"
  185 + circle
  186 + size="mini"
  187 + icon="fa fa-arrow-right"
  188 + @click="linkTo(scoped.row)"
  189 + ></el-button>
  190 + </el-tooltip>
  191 + </template>
288 </el-table-column> 192 </el-table-column>
  193 + </el-table>
  194 + </div>
  195 + <div v-show="tabIndex == 2">
  196 + <el-table
  197 + v-if="role == 'ROLE_JIAOSHI'"
  198 + :max-height="tableMaxHeight"
  199 + :data="tableData"
  200 + border
  201 + style="width: 100%"
  202 + >
289 <el-table-column 203 <el-table-column
  204 + prop="studentCode"
  205 + label="学号"
  206 + fixed
290 align="center" 207 align="center"
291 - :label="index == 0 ? '总参与度' : '参与度'"  
292 - :prop="'participationRate' + item"  
293 - >  
294 - </el-table-column> 208 + ></el-table-column>
295 <el-table-column 209 <el-table-column
  210 + prop="studentName"
  211 + label="姓名"
  212 + fixed
296 align="center" 213 align="center"
297 - :label="index == 0 ? '总正确率' : '正确率'"  
298 - :prop="'correctRate' + item"  
299 - ><template slot-scope="scoped">{{scoped.row['correctRate' + item]}}%</template>  
300 - </el-table-column>  
301 - </el-table-column>  
302 - </el-table>  
303 - </div>  
304 - <div v-show="tabIndex == 3">  
305 - <el-table  
306 - v-if="role == 'ROLE_JIAOSHI'"  
307 - :data="tableData"  
308 - border  
309 - style="width: 100%"  
310 - :default-sort="{ prop: 'answerTimes', order: 'descending' }"  
311 - >  
312 - <el-table-column  
313 - prop="studentCode"  
314 - label="学号"  
315 - align="center"  
316 - ></el-table-column>  
317 - <el-table-column  
318 - prop="studentName"  
319 - label="姓名"  
320 - align="center"  
321 - width="100"  
322 - ></el-table-column>  
323 - <el-table-column  
324 - prop="rushAnswerTimes"  
325 - label="抢答成功次数"  
326 - sortable  
327 - align="center"  
328 - ></el-table-column>  
329 - <el-table-column  
330 - prop="rushAnswerCorrectTimes"  
331 - label="抢答答对次数"  
332 - sortable  
333 - align="center"  
334 - ></el-table-column>  
335 - <el-table-column  
336 - prop="checkAnswerTimes"  
337 - label="抽答次数"  
338 - sortable  
339 - align="center"  
340 - ></el-table-column>  
341 - <el-table-column  
342 - prop="checkAnswerCorrectTimes"  
343 - label="抽答答对次数"  
344 - sortable  
345 - align="center"  
346 - ></el-table-column>  
347 - <el-table-column  
348 - prop="interactionsNum"  
349 - label="参与得分"  
350 - sortable  
351 - align="center"  
352 - ></el-table-column>  
353 - <el-table-column  
354 - prop="interactionsCorrectNum"  
355 - label="对错得分"  
356 - sortable  
357 - align="center"  
358 - ></el-table-column>  
359 - </el-table>  
360 - <el-table v-else :data="tableData" border style="width: 100%">  
361 - <el-table-column  
362 - prop="studentCode"  
363 - label="学号"  
364 - align="center"  
365 - ></el-table-column>  
366 - <el-table-column  
367 - prop="studentName"  
368 - label="姓名"  
369 - align="center"  
370 - width="100"  
371 - ></el-table-column>  
372 - <el-table-column  
373 - v-for="(item, index) in phaseInter"  
374 - :key="index"  
375 - :label="item"  
376 - align="center"  
377 - > 214 + width="100"
  215 + ></el-table-column>
378 <el-table-column 216 <el-table-column
  217 + prop="answerTimes"
  218 + label="累计答题次数"
  219 + sortable
379 align="center" 220 align="center"
380 - v-if="index == 0"  
381 - label="参与分" 221 + ></el-table-column>
  222 + <el-table-column
  223 + prop="correctAnswerTimes"
  224 + label="累计答对次数"
  225 + sortable
  226 + align="center"
  227 + ></el-table-column>
  228 + <el-table-column
  229 + prop="participationRate"
  230 + label="总参与度"
382 sortable 231 sortable
383 - :prop="'interactionsNum' + item" 232 + align="center"
  233 + >
  234 + <template slot-scope="scoped"
  235 + >{{ scoped.row.participationRate }}%</template
  236 + ></el-table-column
384 > 237 >
385 - </el-table-column>  
386 <el-table-column 238 <el-table-column
387 - v-else 239 + prop="correctRate"
  240 + label="总正确率"
  241 + sortable
388 align="center" 242 align="center"
389 - label="互动数"  
390 - :prop="'interactionsNum' + item"  
391 > 243 >
392 - </el-table-column> 244 + <template slot-scope="scoped"
  245 + >{{ scoped.row.correctRate }}%</template
  246 + ></el-table-column
  247 + >
393 <el-table-column 248 <el-table-column
394 - v-if="index == 0" 249 + prop="answerCorrectRate"
  250 + label="已答总正确率"
  251 + sortable
395 align="center" 252 align="center"
396 - label="对错分" 253 + >
  254 + <template slot-scope="scoped"
  255 + >{{ scoped.row.answerCorrectRate }}%</template
  256 + >
  257 + </el-table-column>
  258 + <el-table-column
  259 + prop="classRank"
  260 + label="总正确率班排名"
397 sortable 261 sortable
398 - :prop="'interactionsCorrectNum' + item" 262 + align="center"
  263 + ></el-table-column>
  264 + </el-table>
  265 + <el-table
  266 + :max-height="tableMaxHeight"
  267 + v-else
  268 + :data="tableData"
  269 + border
  270 + style="width: 100%"
  271 + >
  272 + <el-table-column
  273 + prop="studentCode"
  274 + label="学号"
  275 + align="center"
  276 + fixed
  277 + ></el-table-column>
  278 + <el-table-column
  279 + prop="studentName"
  280 + label="姓名"
  281 + align="center"
  282 + fixed
  283 + width="100"
  284 + ></el-table-column>
  285 + <el-table-column
  286 + v-for="(item, index) in phaseOption"
  287 + :key="index"
  288 + :label="item"
  289 + align="center"
399 > 290 >
  291 + <el-table-column
  292 + align="center"
  293 + :label="index == 0 ? '总课时数' : '课时数'"
  294 + :prop="'periodCount' + item"
  295 + >
  296 + </el-table-column>
  297 + <el-table-column
  298 + align="center"
  299 + :label="index == 0 ? '总出题数' : '出题数'"
  300 + :prop="'questionNum' + item"
  301 + >
  302 + </el-table-column>
  303 + <el-table-column
  304 + align="center"
  305 + :label="index == 0 ? '总参与度' : '参与度'"
  306 + :prop="'participationRate' + item"
  307 + ><template slot-scope="scoped"
  308 + >{{ scoped.row["participationRate" + item] }}%</template
  309 + >
  310 + </el-table-column>
  311 + <el-table-column
  312 + align="center"
  313 + :label="index == 0 ? '总正确率' : '正确率'"
  314 + :prop="'correctRate' + item"
  315 + ><template slot-scope="scoped"
  316 + >{{ scoped.row["correctRate" + item] }}%</template
  317 + >
  318 + </el-table-column>
400 </el-table-column> 319 </el-table-column>
  320 + </el-table>
  321 + </div>
  322 + <div v-show="tabIndex == 3">
  323 + <el-table
  324 + v-if="role == 'ROLE_JIAOSHI'"
  325 + :data="tableData"
  326 + border
  327 + style="width: 100%"
  328 + >
  329 + <el-table-column
  330 + prop="studentCode"
  331 + label="学号"
  332 + fixed
  333 + align="center"
  334 + ></el-table-column>
  335 + <el-table-column
  336 + prop="studentName"
  337 + label="姓名"
  338 + fixed
  339 + align="center"
  340 + width="100"
  341 + ></el-table-column>
401 <el-table-column 342 <el-table-column
402 - v-else 343 + prop="rushAnswerTimes"
  344 + label="抢答成功次数"
  345 + sortable
  346 + align="center"
  347 + ></el-table-column>
  348 + <el-table-column
  349 + prop="rushAnswerCorrectTimes"
  350 + label="抢答答对次数"
  351 + sortable
  352 + align="center"
  353 + ></el-table-column>
  354 + <el-table-column
  355 + prop="checkAnswerTimes"
  356 + label="抽答次数"
  357 + sortable
  358 + align="center"
  359 + ></el-table-column>
  360 + <el-table-column
  361 + prop="checkAnswerCorrectTimes"
  362 + label="抽答答对次数"
  363 + sortable
  364 + align="center"
  365 + ></el-table-column>
  366 + <el-table-column
  367 + prop="interactionsNum"
  368 + label="参与得分"
  369 + sortable
  370 + align="center"
  371 + ></el-table-column>
  372 + <el-table-column
  373 + prop="interactionsCorrectNum"
  374 + label="对错得分"
  375 + sortable
  376 + align="center"
  377 + ></el-table-column>
  378 + </el-table>
  379 + <el-table v-else :data="tableData" border style="width: 100%">
  380 + <el-table-column
  381 + prop="studentCode"
  382 + label="学号"
  383 + align="center"
  384 + ></el-table-column>
  385 + <el-table-column
  386 + prop="studentName"
  387 + label="姓名"
  388 + align="center"
  389 + width="100"
  390 + ></el-table-column>
  391 + <el-table-column
  392 + v-for="(item, index) in phaseInter"
  393 + :key="index"
  394 + :label="item"
403 align="center" 395 align="center"
404 - label="参与数"  
405 - :prop="'interactionsCorrectNum' + item"  
406 > 396 >
  397 + <el-table-column
  398 + align="center"
  399 + v-if="index == 0"
  400 + label="参与分"
  401 + sortable
  402 + :prop="'interactionsNum' + item"
  403 + >
  404 + </el-table-column>
  405 + <el-table-column
  406 + v-else
  407 + align="center"
  408 + label="互动数"
  409 + :prop="'interactionsNum' + item"
  410 + >
  411 + </el-table-column>
  412 + <el-table-column
  413 + v-if="index == 0"
  414 + align="center"
  415 + label="对错分"
  416 + sortable
  417 + :prop="'interactionsCorrectNum' + item"
  418 + >
  419 + </el-table-column>
  420 + <el-table-column
  421 + v-else
  422 + align="center"
  423 + label="参与数"
  424 + :prop="'interactionsCorrectNum' + item"
  425 + >
  426 + </el-table-column>
407 </el-table-column> 427 </el-table-column>
408 - </el-table-column>  
409 - </el-table>  
410 - </div>  
411 - <div class="pagination-box" v-show="tabIndex == 1">  
412 - <el-pagination  
413 - small=""  
414 - layout="total,prev, pager, next"  
415 - :hide-on-single-page="true"  
416 - :total="total"  
417 - @current-change="changePage"  
418 - :current-page="page"  
419 - :page-size="size"  
420 - >  
421 - </el-pagination> 428 + </el-table>
  429 + </div>
  430 + <div class="pagination-box" v-show="tabIndex == 1">
  431 + <el-pagination
  432 + small=""
  433 + layout="total,prev, pager, next"
  434 + :hide-on-single-page="true"
  435 + :total="total"
  436 + @current-change="changePage"
  437 + :current-page="page"
  438 + :page-size="size"
  439 + >
  440 + </el-pagination>
  441 + </div>
  442 + <p class="down" v-if="tabIndex == 3 || tabIndex == 2">
  443 + <el-button
  444 + @click="exportData"
  445 + type="info"
  446 + plain
  447 + round
  448 + icon="fa fa-cloud-download"
  449 + >导出报表</el-button
  450 + >
  451 + </p>
422 </div> 452 </div>
423 - <p class="down" v-if="tabIndex == 3 || tabIndex == 2">  
424 - <el-button  
425 - @click="exportData"  
426 - type="info"  
427 - plain  
428 - round  
429 - icon="fa fa-cloud-download"  
430 - >导出报表</el-button  
431 - >  
432 - </p>  
433 </div> 453 </div>
434 <set-answer 454 <set-answer
435 :diaVisible="dialogVisible" 455 :diaVisible="dialogVisible"
@@ -446,7 +466,7 @@ import { formatDate, deepClone, downloadFile } from &quot;utils&quot;; @@ -446,7 +466,7 @@ import { formatDate, deepClone, downloadFile } from &quot;utils&quot;;
446 export default { 466 export default {
447 data() { 467 data() {
448 return { 468 return {
449 - tableMaxHeight:300, 469 + tableMaxHeight: 300,
450 role: "", 470 role: "",
451 loading: false, 471 loading: false,
452 dialogVisible: false, 472 dialogVisible: false,
@@ -603,7 +623,7 @@ export default { @@ -603,7 +623,7 @@ export default {
603 this._QueryData(); 623 this._QueryData();
604 }, 624 },
605 tabChange() { 625 tabChange() {
606 - this.tableMaxHeight = this.$refs.main.offsetHeight 626 + this.tableMaxHeight = this.$refs.main.offsetHeight;
607 this.page = 1; 627 this.page = 1;
608 this.tableData = []; 628 this.tableData = [];
609 this._QueryData(); 629 this._QueryData();
@@ -623,6 +643,11 @@ export default { @@ -623,6 +643,11 @@ export default {
623 this.page = page; 643 this.page = page;
624 this._QueryData(); 644 this._QueryData();
625 }, 645 },
  646 + async changeclass(){
  647 + await this._QuerySubjectList()
  648 + this.page = 1
  649 + this._QueryData()
  650 + },
626 async changClazz() { 651 async changClazz() {
627 await this._QuerySubjectList(); 652 await this._QuerySubjectList();
628 // await this.setDate(1); 653 // await this.setDate(1);
@@ -769,7 +794,7 @@ export default { @@ -769,7 +794,7 @@ export default {
769 if (status === 0) { 794 if (status === 0) {
770 if (this.role == "ROLE_BANZHUREN") { 795 if (this.role == "ROLE_BANZHUREN") {
771 let subjectName = []; 796 let subjectName = [];
772 - this.tableData = data?.list.map((item) => { 797 + let tableData = data?.list.map((item) => {
773 let params = {}; 798 let params = {};
774 item.dataList.map((items, index) => { 799 item.dataList.map((items, index) => {
775 if (!subjectName.includes(items.subjectName)) { 800 if (!subjectName.includes(items.subjectName)) {
@@ -789,8 +814,16 @@ export default { @@ -789,8 +814,16 @@ export default {
789 }; 814 };
790 }); 815 });
791 this.phaseOption = [...subjectName]; 816 this.phaseOption = [...subjectName];
  817 + this.tableData = tableData.sort((a, b) => {
  818 + return a.studentCode - b.studentCode;
  819 + });
792 } else { 820 } else {
793 - this.tableData = (data?.list && [...data?.list]) || []; 821 + this.tableData =
  822 + (data?.list &&
  823 + [...data?.list].sort((a, b) => {
  824 + return a.studentCode - b.studentCode;
  825 + })) ||
  826 + [];
794 } 827 }
795 this.total = data.count; 828 this.total = data.count;
796 } else { 829 } else {
@@ -838,7 +871,7 @@ export default { @@ -838,7 +871,7 @@ export default {
838 if (status === 0) { 871 if (status === 0) {
839 if (this.role == "ROLE_BANZHUREN") { 872 if (this.role == "ROLE_BANZHUREN") {
840 let subjectName = []; 873 let subjectName = [];
841 - this.tableData = data?.list.map((item) => { 874 + let tableData = data?.list.map((item) => {
842 let params = {}; 875 let params = {};
843 item.dataList.map((items, index) => { 876 item.dataList.map((items, index) => {
844 if (!subjectName.includes(items.subjectName)) { 877 if (!subjectName.includes(items.subjectName)) {
@@ -855,24 +888,71 @@ export default { @@ -855,24 +888,71 @@ export default {
855 }; 888 };
856 }); 889 });
857 this.phaseInter = [...subjectName]; 890 this.phaseInter = [...subjectName];
  891 + this.tableData = tableData.sort((a, b) => {
  892 + return a.studentCode - b.studentCode;
  893 + });
858 } else { 894 } else {
859 - this.tableData = (data?.list && [...data?.list]) || []; 895 + this.tableData =
  896 + (data?.list &&
  897 + [...data?.list].sort((a, b) => {
  898 + return a.studentCode - b.studentCode;
  899 + })) ||
  900 + [];
860 } 901 }
861 this.total = data.count; 902 this.total = data.count;
862 } else { 903 } else {
863 this.$message.error(info); 904 this.$message.error(info);
864 } 905 }
865 }, 906 },
  907 + setDownQuery() {},
866 //导出 908 //导出
867 async exportData() { 909 async exportData() {
868 - if ((this.exportLoading = true)) return; 910 + if (this.exportLoading == true) return;
  911 + let query = {};
  912 + for (let key in this.query) {
  913 + if (this.query[key] != "") {
  914 + if (key == "subjectNames" && this.role != "ROLE_BANZHUREN") {
  915 + query["subjectName"] = this.query[key];
  916 + } else {
  917 + query[key] = this.query[key];
  918 + }
  919 + }
  920 + }
  921 + if (this.role == "ROLE_BANZHUREN") {
  922 + if (
  923 + query["subjectNames"] &&
  924 + query["subjectNames"].length == 1 &&
  925 + query["subjectNames"][0] == "全部"
  926 + ) {
  927 + query["subjectNames"] = this.subjectList.map((item) => {
  928 + return item.value;
  929 + });
  930 + query["subjectNames"].shift();
  931 + }
  932 + if (!query["subjectNames"]) {
  933 + this.$message.warning("请选择科目");
  934 + return;
  935 + }
  936 + }
869 this.exportLoading = true; 937 this.exportLoading = true;
870 - const { data, status, info } = await this.$request.exportData(); 938 + const exportData =
  939 + this.tabIndex == 2
  940 + ? this.$request.exportPhaseAnswerReport
  941 + : this.$request.exportPhaseInteractiveReport;
  942 + const data = await exportData({ ...query });
871 this.exportLoading = false; 943 this.exportLoading = false;
872 if (data) { 944 if (data) {
873 - downloadFile("报表", data); 945 + let blob = new Blob([data], {
  946 + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  947 + });
  948 + downloadFile(
  949 + this.tabIndex == 2
  950 + ? "随堂问-阶段问答报表.xlsx"
  951 + : "随堂问-阶段互动报表.xlsx",
  952 + blob
  953 + );
874 } else { 954 } else {
875 - this.$message.error(info); 955 + this.$message.error("下载失败");
876 } 956 }
877 }, 957 },
878 }, 958 },
@@ -889,14 +969,17 @@ div::-webkit-scrollbar-thumb { @@ -889,14 +969,17 @@ div::-webkit-scrollbar-thumb {
889 } 969 }
890 </style> 970 </style>
891 <style lang="scss" scoped> 971 <style lang="scss" scoped>
892 -.main{  
893 - height:100%; 972 +.main {
  973 + height: 100%;
894 } 974 }
895 .table-box { 975 .table-box {
896 margin: 0 20px; 976 margin: 0 20px;
897 padding: 16px; 977 padding: 16px;
898 background: #f8f8f8; 978 background: #f8f8f8;
899 border-radius: 5px; 979 border-radius: 5px;
  980 + .table-cont {
  981 + min-height: 300px;
  982 + }
900 :deep(.fa-arrow-right) { 983 :deep(.fa-arrow-right) {
901 padding-left: 2px; 984 padding-left: 2px;
902 } 985 }
src/views/dataSync/index.vue
@@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
16 ref="upload" 16 ref="upload"
17 :action="url" 17 :action="url"
18 :multiple="false" 18 :multiple="false"
19 - :data="{ id: id }"  
20 :with-credentials="true" 19 :with-credentials="true"
21 :limit="1" 20 :limit="1"
22 :on-change="change" 21 :on-change="change"
@@ -35,9 +34,11 @@ @@ -35,9 +34,11 @@
35 <p class="txt"> 34 <p class="txt">
36 本功能将云平台的数据导出到U盘。待导出数据包括4套答题卡。 35 本功能将云平台的数据导出到U盘。待导出数据包括4套答题卡。
37 </p> 36 </p>
38 - <div class="btn-box btn-box2">  
39 - <i class="fa fa-cloud-download" @click="getAppDownloadUrl"></i>  
40 - <el-button type="primary" round>发卡软件下载</el-button> 37 + <div class="btn-box btn-box2" v-loading="downLoading">
  38 + <i class="fa fa-cloud-download" @click="downloadFile"></i>
  39 + <el-button type="primary" round @click="downloadFile"
  40 + >文件下载</el-button
  41 + >
41 </div> 42 </div>
42 </div> 43 </div>
43 </div> 44 </div>
@@ -45,25 +46,35 @@ @@ -45,25 +46,35 @@
45 </template> 46 </template>
46 47
47 <script> 48 <script>
  49 +import { downloadFile } from "@/utils";
48 export default { 50 export default {
49 data() { 51 data() {
50 return { 52 return {
51 - url: "xxx",  
52 - id: "", 53 + downLoading: false,
  54 + // url: "/api_html/teaching/importData",
  55 + url: "",
  56 + file: {},
53 }; 57 };
54 }, 58 },
55 methods: { 59 methods: {
56 - async getAppDownloadUrl() {  
57 - const { data, status, info } = await this.$request.getAppDownloadUrl();  
58 - if (status == 0) {  
59 - // this.tableData = [...data.list] || [];  
60 - const a = document.createElement("a");  
61 - a.href = data.downloadUrl;  
62 - document.body.appendChild(a);  
63 - a.click();  
64 - a.remove(); 60 + async downloadFile() {
  61 + if (this.downLoading) return;
  62 + this.downLoading = true;
  63 + const data = await this.$request.exportData();
  64 + this.downLoading = false;
  65 + console.log(data)
  66 + if (data) {
  67 + let blob = new Blob([data], {type: 'application/octet-stream'})
  68 + const url = URL.createObjectURL(blob);
  69 + const link = document.createElement("a");
  70 + document.body.appendChild(link);
  71 + link.download = "文件.json";
  72 + link.href = url;
  73 + link.click();
  74 + document.body.removeChild(link);
  75 + URL.revokeObjectURL(url);
65 } else { 76 } else {
66 - this.$message.error(info); 77 + this.$message.error("下载失败,请重试");
67 } 78 }
68 }, 79 },
69 async submitUpload() { 80 async submitUpload() {
@@ -128,12 +139,12 @@ export default { @@ -128,12 +139,12 @@ export default {
128 text-align: center; 139 text-align: center;
129 } 140 }
130 } 141 }
131 - .upload-demo{ 142 + .upload-demo {
132 display: flex; 143 display: flex;
133 justify-content: center; 144 justify-content: center;
134 } 145 }
135 :deep(.el-upload) { 146 :deep(.el-upload) {
136 - margin:0 auto; 147 + margin: 0 auto;
137 } 148 }
138 .btn-box { 149 .btn-box {
139 display: flex; 150 display: flex;
src/views/device/index.vue
@@ -120,7 +120,7 @@ @@ -120,7 +120,7 @@
120 ></el-table-column> 120 ></el-table-column>
121 <el-table-column label="关联班级" align="center"> 121 <el-table-column label="关联班级" align="center">
122 <template slot-scope="scoped"> 122 <template slot-scope="scoped">
123 - <p v-for="item in scoped.row.classList" :key="item.classId"> 123 + <p v-for="(item,index) in scoped.row.classList" :key="index">
124 {{ item.className }} 124 {{ item.className }}
125 </p> 125 </p>
126 </template> 126 </template>
@@ -347,7 +347,7 @@ @@ -347,7 +347,7 @@
347 align="center" 347 align="center"
348 ></el-table-column> 348 ></el-table-column>
349 <el-table-column 349 <el-table-column
350 - prop="otaVersionNumber" 350 + prop="otaVersionName"
351 label="版本号" 351 label="版本号"
352 align="center" 352 align="center"
353 ></el-table-column> 353 ></el-table-column>
@@ -388,7 +388,7 @@ @@ -388,7 +388,7 @@
388 </div> 388 </div>
389 </div> 389 </div>
390 <el-dialog title="设备导入" :visible.sync="diaUp" width="400"> 390 <el-dialog title="设备导入" :visible.sync="diaUp" width="400">
391 - <up-load id="downDevice" :url="url" fileName="设备信息"> 391 + <up-load id="downDevice" :url="url" @upSuccess="upSuccess" fileName="设备信息">
392 <p class="down-txt" slot="down"> 392 <p class="down-txt" slot="down">
393 通过Excel名单导入设备,需要提供设备编码,点击 393 通过Excel名单导入设备,需要提供设备编码,点击
394 <el-link type="danger" @click="downExcel">模板下载</el-link> 。 394 <el-link type="danger" @click="downExcel">模板下载</el-link> 。
@@ -446,7 +446,7 @@ @@ -446,7 +446,7 @@
446 clearable 446 clearable
447 v-model="form.classIds" 447 v-model="form.classIds"
448 :options="gradeList" 448 :options="gradeList"
449 - :props="{ expandTrigger: 'hover',checkStrictly: true }" 449 + :props="{ expandTrigger: 'hover', checkStrictly: true }"
450 :show-all-levels="false" 450 :show-all-levels="false"
451 ></el-cascader> 451 ></el-cascader>
452 </el-col> 452 </el-col>
@@ -477,7 +477,8 @@ @@ -477,7 +477,8 @@
477 import pieChart from "@/components/charts/pieChart"; 477 import pieChart from "@/components/charts/pieChart";
478 import scatterChart from "@/components/charts/scatterChart"; 478 import scatterChart from "@/components/charts/scatterChart";
479 import _ from "lodash"; 479 import _ from "lodash";
480 -import { downloadFile, formatClass } from "@/utils"; 480 +import { downloadFile, formatClass, formatGradeNameClass } from "@/utils";
  481 +import api from "@/api/apis/apis";
481 export default { 482 export default {
482 components: { pieChart, scatterChart }, 483 components: { pieChart, scatterChart },
483 watch: { 484 watch: {
@@ -508,7 +509,11 @@ export default { @@ -508,7 +509,11 @@ export default {
508 gradeList: [], 509 gradeList: [],
509 gradeListAll: [], 510 gradeListAll: [],
510 schoolAll: [], 511 schoolAll: [],
511 - props: { multiple: true, checkStrictly: true }, 512 + props: {
  513 + multiple: true,
  514 + checkStrictly: true,
  515 + lazy: true,
  516 + },
512 type: 1, 517 type: 1,
513 query: { 518 query: {
514 classId: [], 519 classId: [],
@@ -532,7 +537,7 @@ export default { @@ -532,7 +537,7 @@ export default {
532 { label: "3月以上", value: 6 }, 537 { label: "3月以上", value: 6 },
533 ], 538 ],
534 form: { 539 form: {
535 - deviceId:"", 540 + deviceId: "",
536 frequency: "", 541 frequency: "",
537 pairingCode: "", 542 pairingCode: "",
538 classIds: [], 543 classIds: [],
@@ -566,6 +571,32 @@ export default { @@ -566,6 +571,32 @@ export default {
566 } 571 }
567 }); 572 });
568 this.role = role ? role : this.$store.getters.info.permissions[0].role; 573 this.role = role ? role : this.$store.getters.info.permissions[0].role;
  574 + if (this.role == "ROLE_JITUAN") {
  575 + this.props.lazyLoad = function (node, resolve) {
  576 + const { level } = node;
  577 + if (level == 2) {
  578 + console.log(node);
  579 + api
  580 + .tenantClassList({
  581 + schoolId: node.data.value,
  582 + })
  583 + .then((res) => {
  584 + let children = formatGradeNameClass(res.data?.list).sort(
  585 + (a, b) => {
  586 + return a.grade - b.grade;
  587 + }
  588 + );
  589 + console.log();
  590 +
  591 + const nodes = [...children];
  592 + // 通过调用resolve将子节点数据返回,通知组件数据加载完成
  593 + resolve(nodes);
  594 + });
  595 + } else {
  596 + resolve(node);
  597 + }
  598 + };
  599 + }
569 this.stationReport(); 600 this.stationReport();
570 this._QueryGradeList(); 601 this._QueryGradeList();
571 this._QueryData(); 602 this._QueryData();
@@ -574,18 +605,21 @@ export default { @@ -574,18 +605,21 @@ export default {
574 } 605 }
575 }, 606 },
576 methods: { 607 methods: {
  608 + upSuccess(){//导入成功
  609 + this.diaUp = false
  610 + this._QueryData();
  611 + },
577 edit(obj) { 612 edit(obj) {
578 - for(let key in this.form){  
579 - if(key=="classIds"){  
580 - this.form[key] = obj.classList?.map(item=>{  
581 - return [item.classId]  
582 - })  
583 - }else{  
584 - this.form[key] = obj[key]  
585 - 613 + for (let key in this.form) {
  614 + if (key == "classIds") {
  615 + this.form[key] = obj.classList?.map((item) => {
  616 + return [item.classId];
  617 + });
  618 + } else {
  619 + this.form[key] = obj[key];
586 } 620 }
587 } 621 }
588 - this.diaAnswerEqu=true 622 + this.diaAnswerEqu = true;
589 }, 623 },
590 linkTo(obj, type) { 624 linkTo(obj, type) {
591 this.$router.push({ 625 this.$router.push({
@@ -708,7 +742,7 @@ export default { @@ -708,7 +742,7 @@ export default {
708 }); 742 });
709 downloadFile(`设备信息.xlsx`, blob); 743 downloadFile(`设备信息.xlsx`, blob);
710 } else { 744 } else {
711 - this.$message.error(data.message); 745 + this.$message.error(data.info);
712 } 746 }
713 }, 747 },
714 748
@@ -718,15 +752,17 @@ export default { @@ -718,15 +752,17 @@ export default {
718 if (valid) { 752 if (valid) {
719 if (this.loadingAnswerEqu) return; 753 if (this.loadingAnswerEqu) return;
720 this.loadingAnswerEqu = true; 754 this.loadingAnswerEqu = true;
721 - let query = {...this.form}  
722 - query.classIds = query.classIds.map(item=>{  
723 - return item[1]  
724 - })  
725 - const { data, status, info } = await this.$request.updateDevice({...query}); 755 + let query = { ...this.form };
  756 + query.classIds = query.classIds.map((item) => {
  757 + return item[1];
  758 + });
  759 + const { data, status, info } = await this.$request.updateDevice({
  760 + ...query,
  761 + });
726 this.loadingAnswerEqu = false; 762 this.loadingAnswerEqu = false;
727 console.log(status); 763 console.log(status);
728 if (status === 0) { 764 if (status === 0) {
729 - this.diaAnswerEqu=false 765 + this.diaAnswerEqu = false;
730 this._QueryData(); 766 this._QueryData();
731 } else { 767 } else {
732 this.$message.error(info); 768 this.$message.error(info);
@@ -859,18 +895,43 @@ export default { @@ -859,18 +895,43 @@ export default {
859 if (this.role == "ROLE_JITUAN") { 895 if (this.role == "ROLE_JITUAN") {
860 query.regionIds = []; 896 query.regionIds = [];
861 query.schoolIds = []; 897 query.schoolIds = [];
  898 + query.gradeNames = [];
  899 + query.classIds = [];
862 this.query.classId?.map((item) => { 900 this.query.classId?.map((item) => {
863 if (item.length == 1) { 901 if (item.length == 1) {
864 if (!query.regionIds.includes(item[0])) { 902 if (!query.regionIds.includes(item[0])) {
865 query.regionIds.push(item[0]); 903 query.regionIds.push(item[0]);
866 } 904 }
867 - } else { 905 + } else if (item.length == 2) {
868 if (!query.schoolIds.includes(item[1])) { 906 if (!query.schoolIds.includes(item[1])) {
869 query.schoolIds.push(item[1]); 907 query.schoolIds.push(item[1]);
870 } 908 }
871 - if (query.regionIds.includes(item[0])) {  
872 - query.regionIds.remove(item[0]); 909 + query.regionIds.includes(item[0])
  910 + ? query.regionIds.remove(item[0])
  911 + : "";
  912 + } else if (item.length == 3) {
  913 + if (!query.gradeNames.includes(item[2])) {
  914 + query.gradeNames.push(item[2]);
873 } 915 }
  916 + query.regionIds.includes(item[0])
  917 + ? query.regionIds.remove(item[0])
  918 + : "";
  919 + query.schoolIds.includes(item[1])
  920 + ? query.schoolIds.remove(item[1])
  921 + : "";
  922 + } else if (item.length == 4) {
  923 + if (!query.classIds.includes(item[3])) {
  924 + query.classIds.push(item[3]);
  925 + }
  926 + query.regionIds.includes(item[0])
  927 + ? query.regionIds.remove(item[0])
  928 + : "";
  929 + query.schoolIds.includes(item[1])
  930 + ? query.schoolIds.remove(item[1])
  931 + : "";
  932 + query.gradeNames.includes(item[2])
  933 + ? query.gradeNames.remove(item[2])
  934 + : "";
874 } 935 }
875 }); 936 });
876 } else { 937 } else {
@@ -917,10 +978,12 @@ export default { @@ -917,10 +978,12 @@ export default {
917 this.loading = false; 978 this.loading = false;
918 if (status == 0) { 979 if (status == 0) {
919 this.tableData = 980 this.tableData =
920 - data?.list&&data?.list.map((item) => {  
921 - item.upgradeFlag = item.upgradeFlag == 1 ? true : false;  
922 - return item;  
923 - }) || []; 981 + (data?.list &&
  982 + data?.list.map((item) => {
  983 + item.upgradeFlag = item.upgradeFlag == 1 ? true : false;
  984 + return item;
  985 + })) ||
  986 + [];
924 this.total = data.count; 987 this.total = data.count;
925 } else { 988 } else {
926 this.$message.error(info); 989 this.$message.error(info);
@@ -937,8 +1000,8 @@ export default { @@ -937,8 +1000,8 @@ export default {
937 .tab-box { 1000 .tab-box {
938 margin-bottom: 12px; 1001 margin-bottom: 12px;
939 } 1002 }
940 -.sel{  
941 - width:100%; 1003 +.sel {
  1004 + width: 100%;
942 } 1005 }
943 .content { 1006 .content {
944 background: #f8f8f8; 1007 background: #f8f8f8;
src/views/examinationPaper/add.vue
@@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
25 > 25 >
26 <el-form-item label="答题卡名称:" prop="title"> 26 <el-form-item label="答题卡名称:" prop="title">
27 <el-input 27 <el-input
28 - class="sel2" 28 + class="sel2"
29 type="text" 29 type="text"
30 placeholder="请输入答题卡名称" 30 placeholder="请输入答题卡名称"
31 v-model.trim="form.title" 31 v-model.trim="form.title"
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 </el-form-item> 37 </el-form-item>
38 <el-form-item label="测验类型:"> 38 <el-form-item label="测验类型:">
39 <el-select v-model="form.tagId" placeholder="选择测验类型"> 39 <el-select v-model="form.tagId" placeholder="选择测验类型">
  40 + <el-option label="--" value=""> </el-option>
40 <el-option 41 <el-option
41 v-for="item in answerTypeList" 42 v-for="item in answerTypeList"
42 :key="item.id" 43 :key="item.id"
@@ -81,7 +82,7 @@ @@ -81,7 +82,7 @@
81 </el-option> 82 </el-option>
82 </el-select> 83 </el-select>
83 </el-form-item> 84 </el-form-item>
84 - <el-form-item label="考试时长:" prop="examsDuration"> 85 + <el-form-item label="考试时长:">
85 <el-input-number 86 <el-input-number
86 size="medium" 87 size="medium"
87 :min="1" 88 :min="1"
@@ -328,6 +329,7 @@ @@ -328,6 +329,7 @@
328 :value="item.value" 329 :value="item.value"
329 > 330 >
330 </el-option> 331 </el-option>
  332 + <el-option label="混合题题型" :value="6"> </el-option>
331 </el-select> 333 </el-select>
332 </el-form-item> 334 </el-form-item>
333 <el-form-item label="默认题数:"> 335 <el-form-item label="默认题数:">
@@ -340,6 +342,38 @@ @@ -340,6 +342,38 @@
340 label="label" 342 label="label"
341 ></el-input-number> 343 ></el-input-number>
342 </el-form-item> 344 </el-form-item>
  345 + <el-form-item
  346 + label="默认选项:"
  347 + v-show="
  348 + questionForm.questionType != 4 ||
  349 + questionForm.questionType != 5
  350 + "
  351 + >
  352 + <el-input-number
  353 + v-model="questionForm.selectNum"
  354 + :min="3"
  355 + :max="7"
  356 + :step-strictly="true"
  357 + :step="1"
  358 + label="label"
  359 + ></el-input-number>
  360 + </el-form-item>
  361 + <el-form-item
  362 + label="默认分数:"
  363 + v-show="
  364 + questionForm.questionType != 4 ||
  365 + questionForm.questionType != 5
  366 + "
  367 + >
  368 + <el-input-number
  369 + v-model="questionForm.score"
  370 + :min="1"
  371 + :max="100"
  372 + :step-strictly="true"
  373 + :step="1"
  374 + label="label"
  375 + ></el-input-number>
  376 + </el-form-item>
343 </el-form> 377 </el-form>
344 </div> 378 </div>
345 <div class="dialog-footer" slot="footer"> 379 <div class="dialog-footer" slot="footer">
@@ -465,6 +499,8 @@ const questionForm = { @@ -465,6 +499,8 @@ const questionForm = {
465 questionTitle: "", 499 questionTitle: "",
466 questionType: 2, 500 questionType: 2,
467 number: 10, 501 number: 10,
  502 + selectNum: 4,
  503 + score: 1,
468 }; 504 };
469 const subQuesOptions = { 505 const subQuesOptions = {
470 questionType: 2, 506 questionType: 2,
@@ -486,12 +522,12 @@ export default { @@ -486,12 +522,12 @@ export default {
486 return Number(score).toFixed(2); 522 return Number(score).toFixed(2);
487 }, 523 },
488 }, 524 },
489 - watch:{  
490 - step:function(){  
491 - this.$nextTick(function(){  
492 - this.$refs.content.scrollTop = 0  
493 - })  
494 - } 525 + watch: {
  526 + step: function () {
  527 + this.$nextTick(function () {
  528 + this.$refs.content.scrollTop = 0;
  529 + });
  530 + },
495 }, 531 },
496 data() { 532 data() {
497 return { 533 return {
@@ -680,7 +716,12 @@ export default { @@ -680,7 +716,12 @@ export default {
680 let subQuestions = []; 716 let subQuestions = [];
681 let questionsOptions = { 717 let questionsOptions = {
682 ...subQuesOptions, 718 ...subQuesOptions,
683 - questionType: this.questionForm.questionType, 719 + selectNum: this.questionForm.selectNum,
  720 + score: this.questionForm.score,
  721 + questionType:
  722 + this.questionForm.questionType == 6
  723 + ? 2
  724 + : this.questionForm.questionType,
684 }; 725 };
685 switch (questionsOptions.questionType) { 726 switch (questionsOptions.questionType) {
686 case 2: 727 case 2:
@@ -840,8 +881,8 @@ export default { @@ -840,8 +881,8 @@ export default {
840 // item.questionIndex = index + 1; 881 // item.questionIndex = index + 1;
841 item.questionType = 0; 882 item.questionType = 0;
842 item.subQuestions.map((items, indexs) => { 883 item.subQuestions.map((items, indexs) => {
843 - items.questionId = this.setNum(index,indexs)  
844 - items.questionIndex = this.setNum(index,indexs); 884 + items.questionId = this.setNum(index, indexs);
  885 + items.questionIndex = this.setNum(index, indexs);
845 }); 886 });
846 }); 887 });
847 const { data, status, info } = await this.$request.addPaper({ 888 const { data, status, info } = await this.$request.addPaper({
@@ -956,12 +997,12 @@ export default { @@ -956,12 +997,12 @@ export default {
956 .red { 997 .red {
957 color: #f30; 998 color: #f30;
958 } 999 }
959 -.sel2{  
960 - width:480px; 1000 +.sel2 {
  1001 + width: 480px;
961 } 1002 }
962 -.content-box{  
963 - width:100%;  
964 - height:100%; 1003 +.content-box {
  1004 + width: 100%;
  1005 + height: 100%;
965 overflow-y: auto; 1006 overflow-y: auto;
966 } 1007 }
967 .content { 1008 .content {
@@ -1086,6 +1127,26 @@ export default { @@ -1086,6 +1127,26 @@ export default {
1086 border-top: 1px solid #e2e2e2; 1127 border-top: 1px solid #e2e2e2;
1087 margin: 12px 0; 1128 margin: 12px 0;
1088 } 1129 }
  1130 +.qs-options {
  1131 + .answer-s {
  1132 + display: inline-block;
  1133 + width: 30px;
  1134 + height: 30px;
  1135 + border: 1px solid #e2e2e2;
  1136 + border-radius: 3px;
  1137 + margin: 0 6px;
  1138 + font-size: 16px;
  1139 + color: #333;
  1140 + text-align: center;
  1141 + line-height: 30px;
  1142 + cursor: pointer;
  1143 + &.active {
  1144 + background: #5e78fa;
  1145 + border-color: #5e78fa;
  1146 + color: #fff;
  1147 + }
  1148 + }
  1149 +}
1089 .sub-questions { 1150 .sub-questions {
1090 width: 100%; 1151 width: 100%;
1091 display: flex; 1152 display: flex;
src/views/index/mainIndex.vue
@@ -115,7 +115,7 @@ @@ -115,7 +115,7 @@
115 </div> 115 </div>
116 <div class="text" v-else-if="item.path == '/analysis'"> 116 <div class="text" v-else-if="item.path == '/analysis'">
117 <p class="p1">使用分析</p> 117 <p class="p1">使用分析</p>
118 - <p class="p2">按软件功能、题型统计使用频率。</p> 118 + <p class="p2">按学校、学段统计使用频率。</p>
119 </div> 119 </div>
120 </li> 120 </li>
121 </template> 121 </template>
@@ -173,6 +173,24 @@ export default { @@ -173,6 +173,24 @@ export default {
173 }, 173 },
174 watch: { 174 watch: {
175 "$store.getters.info.showRoleName": function (val) { 175 "$store.getters.info.showRoleName": function (val) {
  176 + this._Init(val)
  177 + this._QueryData();
  178 + },
  179 + },
  180 + created() {
  181 + this._Init(this.$store.getters.info.showRoleName);
  182 + this._QueryData();
  183 + },
  184 + methods: {
  185 + getImgs(path) {
  186 + return require(`@/assets/nav${path}.png`);
  187 + },
  188 + links(path) {
  189 + this.$router.push({
  190 + path: path,
  191 + });
  192 + },
  193 + _Init(val) {
176 let type = ""; 194 let type = "";
177 this.$store.getters.info.permissions.map((item) => { 195 this.$store.getters.info.permissions.map((item) => {
178 if (item.roleName == val) { 196 if (item.roleName == val) {
@@ -187,39 +205,16 @@ export default { @@ -187,39 +205,16 @@ export default {
187 }; 205 };
188 }); 206 });
189 }, 207 },
190 - },  
191 - created() {  
192 - let type = "";  
193 - this.$store.getters.info.permissions.map((item) => {  
194 - if (item.roleName == this.$store.getters.info.showRoleName) {  
195 - type = item.role; 208 + _QueryData() {
  209 + if (this.type == "ROLE_XUEXIAO") {
  210 + this.schoolIndex();
  211 + } else if (this.type == "ROLE_JIAOSHI") {
  212 + this.teacherIndex();
  213 + } else if (this.type == "ROLE_JITUAN") {
  214 + this.tenantIndex();
  215 + } else if (this.type == "ROLE_BANZHUREN") {
  216 + this.classIndex();
196 } 217 }
197 - });  
198 - this.type = type ? type : this.$store.getters.info.permissions[0].role;  
199 - this.navList = this.$store.getters.addRouters.map((item) => {  
200 - return {  
201 - name: item.name,  
202 - path: item.children[0].path,  
203 - };  
204 - });  
205 - if (this.type == "ROLE_XUEXIAO") {  
206 - this.schoolIndex();  
207 - } else if (this.type == "ROLE_JIAOSHI" ) {  
208 - this.teacherIndex();  
209 - } else if (this.type == "ROLE_JITUAN") {  
210 - this.tenantIndex();  
211 - }else if (this.type == "ROLE_BANZHUREN") {  
212 - this.classIndex();  
213 - }  
214 - },  
215 - methods: {  
216 - getImgs(path) {  
217 - return require(`@/assets/nav${path}.png`);  
218 - },  
219 - links(path) {  
220 - this.$router.push({  
221 - path: path,  
222 - });  
223 }, 218 },
224 async teacherIndex() { 219 async teacherIndex() {
225 const { data, status, info } = await this.$request.teacherIndex(); 220 const { data, status, info } = await this.$request.teacherIndex();
src/views/login/index.vue
@@ -94,15 +94,17 @@ export default { @@ -94,15 +94,17 @@ export default {
94 passwordType: "password", 94 passwordType: "password",
95 loginForm: { 95 loginForm: {
96 // username: "15911715665", 96 // username: "15911715665",
97 - // password: "Csiy88888",  
98 - username: "18687826606",  
99 - password: "Pw826606#", 97 + // password: "715665",
  98 + // username: "18687826606",
  99 + // password: "Pw826606#",
100 // username: "18893712576", 100 // username: "18893712576",
101 // password: "712576", 101 // password: "712576",
102 - // username: "13247726488",  
103 - // password: "726488", 102 + username: "13247726488",
  103 + password: "726488",
104 // username: "13319607658", 104 // username: "13319607658",
105 // password: "Pw607658#", 105 // password: "Pw607658#",
  106 + // username: "18213902650",
  107 + // password: "Pw902650#",
106 }, 108 },
107 loginRules: { 109 loginRules: {
108 username: [ 110 username: [
src/views/setUp/account.vue
@@ -184,7 +184,6 @@ @@ -184,7 +184,6 @@
184 </el-table> 184 </el-table>
185 <div class="pagination-box"> 185 <div class="pagination-box">
186 <el-pagination 186 <el-pagination
187 - small=""  
188 layout="total,prev, pager, next" 187 layout="total,prev, pager, next"
189 :hide-on-single-page="true" 188 :hide-on-single-page="true"
190 :total="total" 189 :total="total"
@@ -283,7 +282,10 @@ @@ -283,7 +282,10 @@
283 </el-select> 282 </el-select>
284 </el-col> 283 </el-col>
285 </el-form-item> 284 </el-form-item>
286 - <el-form-item label="选择管辖范围:" :prop="formAddCount.roleId == 3?'regionId':'schoolId'"> 285 + <el-form-item
  286 + label="选择管辖范围:"
  287 + :prop="formAddCount.roleId == 3 ? 'regionId' : 'schoolId'"
  288 + >
287 <el-col :span="12"> 289 <el-col :span="12">
288 <el-select 290 <el-select
289 v-show="formAddCount.roleId == 3" 291 v-show="formAddCount.roleId == 3"
@@ -320,7 +322,7 @@ @@ -320,7 +322,7 @@
320 </div> 322 </div>
321 </el-dialog> 323 </el-dialog>
322 <el-dialog title="导入账号名单" :visible.sync="diaUp" width="600"> 324 <el-dialog title="导入账号名单" :visible.sync="diaUp" width="600">
323 - <up-load id="downTeacher" :url="url" fileName="教师名单"> 325 + <up-load id="downTeacher" :url="url" @upSuccess="upSuccess" fileName="教师名单">
324 <p class="down-txt" slot="down"> 326 <p class="down-txt" slot="down">
325 通过Excel名单导入账号名单,点击 327 通过Excel名单导入账号名单,点击
326 <el-link type="danger" @click="downExcel">模板下载</el-link> 。 328 <el-link type="danger" @click="downExcel">模板下载</el-link> 。
@@ -415,6 +417,10 @@ export default { @@ -415,6 +417,10 @@ export default {
415 this._QueryData(4); 417 this._QueryData(4);
416 }, 418 },
417 methods: { 419 methods: {
  420 + upSuccess(){//导入成功
  421 + this.diaUp = false
  422 + this._QueryData(4);
  423 + },
418 async downExcel() { 424 async downExcel() {
419 let data = await this.$request.downDevice(); 425 let data = await this.$request.downDevice();
420 if (data && !data.code) { 426 if (data && !data.code) {
@@ -503,7 +509,7 @@ export default { @@ -503,7 +509,7 @@ export default {
503 }); 509 });
504 if (status === 0) { 510 if (status === 0) {
505 this.$message.success(info); 511 this.$message.success(info);
506 - this.diaCount=false 512 + this.diaCount = false;
507 this._QueryData(4); 513 this._QueryData(4);
508 } else { 514 } else {
509 this.$message.error(info); 515 this.$message.error(info);
@@ -648,7 +654,6 @@ export default { @@ -648,7 +654,6 @@ export default {
648 let query = this.setQuery(type); 654 let query = this.setQuery(type);
649 this.loading = true; 655 this.loading = true;
650 this.tableData = []; 656 this.tableData = [];
651 - this.total = 0;  
652 const { data, status, info } = 657 const { data, status, info } =
653 this.role != "ROLE_JITUAN" 658 this.role != "ROLE_JITUAN"
654 ? await this.$request.userPage({ 659 ? await this.$request.userPage({
src/views/setUp/school.vue
@@ -81,7 +81,7 @@ @@ -81,7 +81,7 @@
81 </div> 81 </div>
82 </div> 82 </div>
83 <el-dialog title="导入学校名单" :visible.sync="diaUp" width="400"> 83 <el-dialog title="导入学校名单" :visible.sync="diaUp" width="400">
84 - <up-load id="downDevice" :url="url" fileName="学校名单"> 84 + <up-load id="downDevice" :url="url" @upSuccess="upSuccess" fileName="学校名单">
85 <p class="down-txt" slot="down"> 85 <p class="down-txt" slot="down">
86 通过Excel名单导入学校名单,点击 86 通过Excel名单导入学校名单,点击
87 <el-link type="danger" @click="downExcel">模板下载</el-link> 。 87 <el-link type="danger" @click="downExcel">模板下载</el-link> 。
@@ -292,6 +292,11 @@ export default { @@ -292,6 +292,11 @@ export default {
292 this._QuerySubject(); 292 this._QuerySubject();
293 }, 293 },
294 methods: { 294 methods: {
  295 + upSuccess(){//导入成功
  296 + this.diaUp = false
  297 + this._QueryDataSchool();
  298 + this._QueryDataGrade();
  299 + },
295 setGrade(obj) { 300 setGrade(obj) {
296 this.formGrade.subjectNames = obj.subjectNames; 301 this.formGrade.subjectNames = obj.subjectNames;
297 this.formGrade.classList = obj.classList; 302 this.formGrade.classList = obj.classList;
src/views/setUp/student.vue
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 <template slot="title"> 4 <template slot="title">
5 <span>学生管理</span> 5 <span>学生管理</span>
6 </template> 6 </template>
7 - <template slot="btns"> 7 + <template slot="btns" v-if="!code">
8 <el-tooltip effect="dark" content="添加学生" placement="bottom"> 8 <el-tooltip effect="dark" content="添加学生" placement="bottom">
9 <el-button 9 <el-button
10 type="primary" 10 type="primary"
@@ -44,7 +44,11 @@ @@ -44,7 +44,11 @@
44 :class="query.classId == item.id ? 'active' : ''" 44 :class="query.classId == item.id ? 'active' : ''"
45 @click="classDetail(item)" 45 @click="classDetail(item)"
46 > 46 >
47 - <i class="el-icon-edit-outline" @click.stop="setClass(item)"></i> 47 + <i
  48 + v-if="!code"
  49 + class="el-icon-edit-outline"
  50 + @click.stop="setClass(item)"
  51 + ></i>
48 {{ item.className }}({{ item.studentCount }}) 52 {{ item.className }}({{ item.studentCount }})
49 </li> 53 </li>
50 </ul> 54 </ul>
@@ -85,6 +89,7 @@ @@ -85,6 +89,7 @@
85 :key="item.id" 89 :key="item.id"
86 > 90 >
87 <el-popconfirm 91 <el-popconfirm
  92 + v-if="!code"
88 title="确定删除吗?" 93 title="确定删除吗?"
89 @confirm="removeStu(item, index)" 94 @confirm="removeStu(item, index)"
90 > 95 >
@@ -122,12 +127,20 @@ @@ -122,12 +127,20 @@
122 </el-form-item> 127 </el-form-item>
123 <el-form-item label="学生姓名:" prop="studentName"> 128 <el-form-item label="学生姓名:" prop="studentName">
124 <el-col :span="10"> 129 <el-col :span="10">
125 - <el-input maxlength="30" placeholder="输入学生姓名" v-model.trim="formStu.studentName" /> 130 + <el-input
  131 + maxlength="30"
  132 + placeholder="输入学生姓名"
  133 + v-model.trim="formStu.studentName"
  134 + />
126 </el-col> 135 </el-col>
127 </el-form-item> 136 </el-form-item>
128 <el-form-item label="长学号:" prop="studentCode"> 137 <el-form-item label="长学号:" prop="studentCode">
129 <el-col :span="10"> 138 <el-col :span="10">
130 - <el-input maxlength="12" placeholder="输入学生长学号" v-model.trim="formStu.studentCode" /> 139 + <el-input
  140 + maxlength="12"
  141 + placeholder="输入学生长学号"
  142 + v-model.trim="formStu.studentCode"
  143 + />
131 </el-col> 144 </el-col>
132 </el-form-item> 145 </el-form-item>
133 <el-form-item label="短学号:"> 146 <el-form-item label="短学号:">
@@ -193,6 +206,7 @@ import { downloadFile } from &quot;@/utils&quot;; @@ -193,6 +206,7 @@ import { downloadFile } from &quot;@/utils&quot;;
193 export default { 206 export default {
194 data() { 207 data() {
195 return { 208 return {
  209 + code: "",
196 url: "", 210 url: "",
197 diaStu: false, 211 diaStu: false,
198 diaClass: false, 212 diaClass: false,
@@ -244,6 +258,7 @@ export default { @@ -244,6 +258,7 @@ export default {
244 }; 258 };
245 }, 259 },
246 async created() { 260 async created() {
  261 + this.code = localStorage.getItem("csCode") || "";
247 await this._QueryDataGrade(); 262 await this._QueryDataGrade();
248 await this._QueryClass(); 263 await this._QueryClass();
249 this._QueryData(3); 264 this._QueryData(3);
@@ -317,6 +332,14 @@ export default { @@ -317,6 +332,14 @@ export default {
317 this.loading = true; 332 this.loading = true;
318 this.$refs.formBox.validate(async (valid) => { 333 this.$refs.formBox.validate(async (valid) => {
319 if (valid) { 334 if (valid) {
  335 + let hasName = this.studentList.find((item) => {
  336 + return item.studentName == this.formStu.studentName;
  337 + });
  338 + console.log(hasName);
  339 + if (hasName) {
  340 + this.$message.warning("学生姓名已存在");
  341 + return;
  342 + }
320 const { data, status, info } = await this.$request.addStudent({ 343 const { data, status, info } = await this.$request.addStudent({
321 classId: this.query.classId, 344 classId: this.query.classId,
322 ...query, 345 ...query,
src/views/setUp/teacher.vue
@@ -217,7 +217,7 @@ @@ -217,7 +217,7 @@
217 </div> 217 </div>
218 </div> 218 </div>
219 <el-dialog title="导入教师名单" :visible.sync="diaUp" width="600"> 219 <el-dialog title="导入教师名单" :visible.sync="diaUp" width="600">
220 - <up-load id="downTeacher" :url="url" fileName="教师名单"> 220 + <up-load id="downTeacher" :url="url" @upSuccess="upSuccess" fileName="教师名单">
221 <p class="down-txt" slot="down"> 221 <p class="down-txt" slot="down">
222 通过Excel名单导入教师名单,点击 222 通过Excel名单导入教师名单,点击
223 <el-link type="danger" @click="downExcel">模板下载</el-link> 。 223 <el-link type="danger" @click="downExcel">模板下载</el-link> 。
@@ -423,6 +423,10 @@ export default { @@ -423,6 +423,10 @@ export default {
423 await this._QueryClass(); 423 await this._QueryClass();
424 }, 424 },
425 methods: { 425 methods: {
  426 + upSuccess(){//导入成功
  427 + this.diaUp = false
  428 + this._QueryData(10);
  429 + },
426 addRoleList() { 430 addRoleList() {
427 //添加教师角色 431 //添加教师角色
428 this.formTeacher.roleList.push({ 432 this.formTeacher.roleList.push({
src/views/test/analysis.vue
@@ -53,326 +53,334 @@ @@ -53,326 +53,334 @@
53 >作答明细表</span 53 >作答明细表</span
54 > 54 >
55 </div> 55 </div>
56 - <el-table :max-height="tableMaxHeight" v-show="type == 1" :data="tableData" border style="width: 100%">  
57 - <el-table-column  
58 - prop="questionIndex"  
59 - label="题号"  
60 - align="center"  
61 - fixed  
62 - width="60"  
63 - ></el-table-column>  
64 - <el-table-column  
65 - prop="questionType"  
66 - label="题型"  
67 - align="center"  
68 - fixed  
69 - width="100"  
70 - ><template slot-scope="scope">{{  
71 - setSubPro(scope.row.questionType)  
72 - }}</template></el-table-column 56 + <div class="table-box" v-loading="loading">
  57 + <el-table
  58 + :max-height="tableMaxHeight"
  59 + v-show="type == 1"
  60 + :data="tableData"
  61 + border
  62 + style="width: 100%"
73 > 63 >
74 - <el-table-column  
75 - prop="score"  
76 - width="100"  
77 - label="满分值"  
78 - sortable  
79 - align="center"  
80 - ></el-table-column>  
81 - <el-table-column  
82 - width="110"  
83 - prop="highestScore"  
84 - label="班最高分"  
85 - sortable  
86 - align="center"  
87 - ></el-table-column>  
88 - <el-table-column  
89 - width="110"  
90 - prop="lowestScore"  
91 - label="班最低分"  
92 - sortable  
93 - align="center"  
94 - ></el-table-column>  
95 - <el-table-column  
96 - width="110"  
97 - prop="avgScore"  
98 - label="班平均分"  
99 - sortable  
100 - align="center"  
101 - ></el-table-column>  
102 - <el-table-column  
103 - prop="classScoringRate"  
104 - width="120"  
105 - sortable  
106 - label="班级得分率"  
107 - align="center"  
108 - ><template slot-scope="scoped"  
109 - >{{ scoped.row.classScoringRate }}%</template  
110 - ></el-table-column  
111 - >  
112 - <el-table-column prop="correctAnswer" label="答案" align="center"  
113 - ><template slot-scope="scoped">{{  
114 - scoped.row.correctAnswer == 1  
115 - ? "✓"  
116 - : scoped.row.correctAnswer == 2  
117 - ? "✗"  
118 - : scoped.row.correctAnswer  
119 - }}</template>  
120 - </el-table-column>  
121 - <el-table-column  
122 - v-for="(item, index) in optionsList"  
123 - :key="index"  
124 - :label="'选项' + (index + 1)"  
125 - :prop="'count' + index"  
126 - align="center"  
127 - >  
128 - </el-table-column>  
129 - </el-table>  
130 - <div class="hui-box" v-show="type == 1">  
131 - <span class="s-txt">汇总</span>  
132 - <ul class="hui-ul">  
133 - <li class="hui-li">  
134 - <span class="hui-s s1">主观题</span>  
135 - <span class="hui-s s1">{{ paperModifyLog.subjectiveScore }}</span>  
136 - <span class="hui-s s2">{{  
137 - paperModifyLog.subjectiveHighestScore  
138 - }}</span>  
139 - <span class="hui-s s2">{{  
140 - paperModifyLog.subjectiveLowestScore  
141 - }}</span>  
142 - <span class="hui-s s2">{{  
143 - paperModifyLog.subjectiveAvgScore  
144 - }}</span>  
145 - <span class="hui-s s3"  
146 - >{{ paperModifyLog.subjectiveClassScoringRate }}%</span  
147 - >  
148 - </li>  
149 - <li class="hui-li">  
150 - <span class="hui-s s1">客观题</span>  
151 - <span class="hui-s s1">{{ paperModifyLog.objectiveScore }}</span>  
152 - <span class="hui-s s2">{{  
153 - paperModifyLog.objectiveHighestScore  
154 - }}</span>  
155 - <span class="hui-s s2">{{  
156 - paperModifyLog.objectiveLowestScore  
157 - }}</span>  
158 - <span class="hui-s s2">{{ paperModifyLog.objectiveAvgScore }}</span>  
159 - <span class="hui-s s3"  
160 - >{{ paperModifyLog.objectiveClassScoringRate }}%</span  
161 - >  
162 - </li>  
163 - <li class="hui-li">  
164 - <span class="hui-s s1">整卷</span>  
165 - <span class="hui-s s1">{{ paperModifyLog.examPaperScore }}</span>  
166 - <span class="hui-s s2">{{ paperModifyLog.highestScore }}</span>  
167 - <span class="hui-s s2">{{ paperModifyLog.lowestScore }}</span>  
168 - <span class="hui-s s2">{{ paperModifyLog.avgScore }}</span>  
169 - <span class="hui-s s3">{{ paperModifyLog.classScoringRate }}%</span>  
170 - </li>  
171 - </ul>  
172 - </div>  
173 - <el-table  
174 - v-show="type == 2"  
175 - :max-height="tableMaxHeight"  
176 - :data="tableData2"  
177 - border  
178 - style="width: 100%"  
179 - :default-sort="{ prop: 'dadui', order: 'descending' }"  
180 - >  
181 - <el-table-column  
182 - prop="studentCode"  
183 - label="学号"  
184 - align="center"  
185 - fixed  
186 - ></el-table-column>  
187 - <el-table-column  
188 - prop="studentName"  
189 - label="姓名"  
190 - fixed  
191 - align="center"  
192 - ></el-table-column>  
193 - <el-table-column  
194 - prop="examScore"  
195 - label="总分"  
196 - sortable  
197 - align="center"  
198 - ></el-table-column>  
199 - <el-table-column  
200 - prop="scoringRate"  
201 - label="得分率"  
202 - sortable  
203 - align="center"  
204 - ><template slot-scope="scope"  
205 - >{{ scope.row.scoringRate }}%</template  
206 - ></el-table-column  
207 - >  
208 - <el-table-column  
209 - prop="classRank"  
210 - label="班名"  
211 - sortable  
212 - align="center"  
213 - ></el-table-column>  
214 - <el-table-column label="客观题" align="center">  
215 <el-table-column 64 <el-table-column
216 - prop="objectiveExamScore"  
217 - label="得分" 65 + prop="questionIndex"
  66 + label="题号"
218 align="center" 67 align="center"
  68 + fixed
  69 + width="60"
219 ></el-table-column> 70 ></el-table-column>
220 <el-table-column 71 <el-table-column
221 - prop="objectiveScoringRate"  
222 - label="得分率" 72 + prop="questionType"
  73 + label="题型"
223 align="center" 74 align="center"
224 - ><template slot-scope="scope"  
225 - >{{ scope.row.objectiveScoringRate }}%</template  
226 - ></el-table-column 75 + fixed
  76 + width="100"
  77 + ><template slot-scope="scope">{{
  78 + setSubPro(scope.row.questionType)
  79 + }}</template></el-table-column
227 > 80 >
228 - </el-table-column>  
229 - <el-table-column label="主观题" align="center">  
230 <el-table-column 81 <el-table-column
231 - prop="subjectiveExamScore"  
232 - label="得分" 82 + prop="score"
  83 + width="100"
  84 + label="满分值"
  85 + sortable
233 align="center" 86 align="center"
234 ></el-table-column> 87 ></el-table-column>
235 <el-table-column 88 <el-table-column
236 - prop="subjectiveScoringRate"  
237 - label="得分率" 89 + width="110"
  90 + prop="highestScore"
  91 + label="班最高分"
  92 + sortable
238 align="center" 93 align="center"
239 - ><template slot-scope="scope"  
240 - >{{ scope.row.subjectiveScoringRate }}%</template 94 + ></el-table-column>
  95 + <el-table-column
  96 + width="110"
  97 + prop="lowestScore"
  98 + label="班最低分"
  99 + sortable
  100 + align="center"
  101 + ></el-table-column>
  102 + <el-table-column
  103 + width="110"
  104 + prop="avgScore"
  105 + label="班平均分"
  106 + sortable
  107 + align="center"
  108 + ></el-table-column>
  109 + <el-table-column
  110 + prop="classScoringRate"
  111 + width="120"
  112 + sortable
  113 + label="班级得分率"
  114 + align="center"
  115 + ><template slot-scope="scoped"
  116 + >{{ scoped.row.classScoringRate }}%</template
241 ></el-table-column 117 ></el-table-column
242 > 118 >
243 - </el-table-column>  
244 - </el-table>  
245 - <el-table  
246 - v-show="type == 3"  
247 - :max-height="tableMaxHeight"  
248 - :data="tableData2"  
249 - border  
250 - style="width: 100%"  
251 - :default-sort="{ prop: '', order: 'descending' }"  
252 - >  
253 - <el-table-column  
254 - prop="studentCode"  
255 - label="学号"  
256 - fixed  
257 - align="center"  
258 - ></el-table-column>  
259 - <el-table-column  
260 - prop="studentName"  
261 - label="姓名"  
262 - fixed  
263 - align="center"  
264 - ></el-table-column>  
265 - <el-table-column  
266 - prop="examScore"  
267 - label="总分"  
268 - sortable  
269 - align="center"  
270 - ></el-table-column>  
271 - <el-table-column label="分数组成" align="center"> 119 + <el-table-column prop="correctAnswer" label="答案" align="center"
  120 + ><template slot-scope="scoped">{{
  121 + scoped.row.correctAnswer == 1
  122 + ? "✓"
  123 + : scoped.row.correctAnswer == 2
  124 + ? "✗"
  125 + : scoped.row.correctAnswer
  126 + }}</template>
  127 + </el-table-column>
  128 + <el-table-column
  129 + v-for="(item, index) in optionsList"
  130 + :key="index"
  131 + :label="item.title"
  132 + :prop="'count' + index"
  133 + align="center"
  134 + ><template slot-scope="scope">{{
  135 + scope.row.questionType == "5"
  136 + ? ""
  137 + : scope.row["option" + index]
  138 + ? `${scope.row["option" + index]}(${
  139 + scope.row["present" + index]
  140 + })`
  141 + : ""
  142 + }}</template>
  143 + </el-table-column>
  144 + </el-table>
  145 + <div class="hui-box" v-show="type == 1">
  146 + <span class="s-txt">汇总</span>
  147 + <ul class="hui-ul">
  148 + <li class="hui-li">
  149 + <span class="hui-s s1">主观题</span>
  150 + <span class="hui-s s1">{{ examReport.subjectiveScore }}</span>
  151 + <span class="hui-s s2">{{
  152 + examReport.subjectiveHighestScore
  153 + }}</span>
  154 + <span class="hui-s s2">{{
  155 + examReport.subjectiveLowestScore
  156 + }}</span>
  157 + <span class="hui-s s2">{{ examReport.subjectiveAvgScore }}</span>
  158 + <span class="hui-s s3"
  159 + >{{ examReport.subjectiveClassScoringRate }}%</span
  160 + >
  161 + </li>
  162 + <li class="hui-li">
  163 + <span class="hui-s s1">客观题</span>
  164 + <span class="hui-s s1">{{ examReport.objectiveScore }}</span>
  165 + <span class="hui-s s2">{{
  166 + examReport.objectiveHighestScore
  167 + }}</span>
  168 + <span class="hui-s s2">{{
  169 + examReport.objectiveLowestScore
  170 + }}</span>
  171 + <span class="hui-s s2">{{ examReport.objectiveAvgScore }}</span>
  172 + <span class="hui-s s3"
  173 + >{{ examReport.objectiveClassScoringRate }}%</span
  174 + >
  175 + </li>
  176 + <li class="hui-li">
  177 + <span class="hui-s s1">整卷</span>
  178 + <span class="hui-s s1">{{ examReport.examPaperScore }}</span>
  179 + <span class="hui-s s2">{{ examReport.highestScore }}</span>
  180 + <span class="hui-s s2">{{ examReport.lowestScore }}</span>
  181 + <span class="hui-s s2">{{ examReport.avgScore }}</span>
  182 + <span class="hui-s s3">{{ examReport.classScoringRate }}%</span>
  183 + </li>
  184 + </ul>
  185 + </div>
  186 + <el-table
  187 + v-show="type == 2"
  188 + :max-height="tableMaxHeight"
  189 + :data="tableData2"
  190 + border
  191 + style="width: 100%"
  192 + :default-sort="{ prop: 'dadui', order: 'descending' }"
  193 + >
272 <el-table-column 194 <el-table-column
273 - prop="objectiveExamScore"  
274 - label="客观题分" 195 + prop="studentCode"
  196 + label="学号"
275 align="center" 197 align="center"
  198 + fixed
276 ></el-table-column> 199 ></el-table-column>
277 <el-table-column 200 <el-table-column
278 - prop="subjectiveExamScore"  
279 - label="主观题分" 201 + prop="studentName"
  202 + label="姓名"
  203 + fixed
280 align="center" 204 align="center"
281 ></el-table-column> 205 ></el-table-column>
282 - </el-table-column>  
283 - <el-table-column  
284 - align="center"  
285 - v-for="(item, index) in questionList"  
286 - :key="index"  
287 - :label="'题目' + item.id"  
288 - :prop="'score' + item.id"  
289 - >  
290 - </el-table-column>  
291 - </el-table>  
292 - <el-table  
293 - :max-height="tableMaxHeight"  
294 - v-show="type == 4"  
295 - :data="tableData2"  
296 - border  
297 - style="width: 100%"  
298 - :default-sort="{ prop: '', order: 'descending' }"  
299 - >  
300 - <el-table-column  
301 - prop="studentCode"  
302 - label="学号"  
303 - fixed  
304 - align="center"  
305 - ></el-table-column>  
306 - <el-table-column  
307 - prop="studentName"  
308 - label="姓名"  
309 - fixed  
310 - align="center"  
311 - ></el-table-column>  
312 - <el-table-column  
313 - prop="className"  
314 - label="班级"  
315 - align="center"  
316 - ></el-table-column>  
317 - <el-table-column  
318 - prop="examScore"  
319 - label="总分"  
320 - sortable  
321 - align="center"  
322 - ></el-table-column>  
323 - <el-table-column  
324 - align="center"  
325 - v-for="(item, index) in questionList"  
326 - :key="index"  
327 - :label="'题目' + item.id"  
328 - >  
329 - <template slot-scope="scope">  
330 - <span  
331 - v-if="scope.row['answer' + item.id]"  
332 - :class="scope.row['isRight' + item.id] ? '' : 'error'" 206 + <el-table-column
  207 + prop="examScore"
  208 + label="总分"
  209 + sortable
  210 + align="center"
  211 + ></el-table-column>
  212 + <el-table-column
  213 + prop="scoringRate"
  214 + label="得分率"
  215 + sortable
  216 + align="center"
  217 + ><template slot-scope="scope"
  218 + >{{ scope.row.scoringRate }}%</template
  219 + ></el-table-column
  220 + >
  221 + <el-table-column
  222 + prop="classRank"
  223 + label="班名"
  224 + sortable
  225 + align="center"
  226 + ></el-table-column>
  227 + <el-table-column label="客观题" align="center">
  228 + <el-table-column
  229 + prop="objectiveExamScore"
  230 + label="得分"
  231 + align="center"
  232 + ></el-table-column>
  233 + <el-table-column
  234 + prop="objectiveScoringRate"
  235 + label="得分率"
  236 + align="center"
  237 + ><template slot-scope="scope"
  238 + >{{ scope.row.objectiveScoringRate }}%</template
  239 + ></el-table-column
333 > 240 >
334 - {{ scope.row["answer" + item.id] }}  
335 - </span>  
336 - <span  
337 - v-else  
338 - :class="scope.row['questionType' + item.id] == 5 ? '' : 'error'" 241 + </el-table-column>
  242 + <el-table-column label="主观题" align="center">
  243 + <el-table-column
  244 + prop="subjectiveExamScore"
  245 + label="得分"
  246 + align="center"
  247 + ></el-table-column>
  248 + <el-table-column
  249 + prop="subjectiveScoringRate"
  250 + label="得分率"
  251 + align="center"
  252 + ><template slot-scope="scope"
  253 + >{{ scope.row.subjectiveScoringRate }}%</template
  254 + ></el-table-column
339 > 255 >
340 - {{ scope.row["questionType" + item.id] == 5 ? "*" : "-" }}  
341 - </span>  
342 - </template>  
343 - </el-table-column>  
344 - </el-table>  
345 - <div class="pagination-box" v-show="type == 1">  
346 - <el-pagination  
347 - small=""  
348 - layout="total,prev, pager, next"  
349 - :hide-on-single-page="true"  
350 - :total="total"  
351 - @current-change="changePage"  
352 - :current-page="page"  
353 - :page-size="size" 256 + </el-table-column>
  257 + </el-table>
  258 + <el-table
  259 + v-show="type == 3"
  260 + :max-height="tableMaxHeight"
  261 + :data="tableData2"
  262 + border
  263 + style="width: 100%"
  264 + :default-sort="{ prop: '', order: 'descending' }"
354 > 265 >
355 - </el-pagination>  
356 - </div>  
357 - <div class="down">  
358 - <el-button  
359 - @click="exportData"  
360 - type="info"  
361 - plain  
362 - round  
363 - icon="fa fa-cloud-download"  
364 - >导出报表</el-button 266 + <el-table-column
  267 + prop="studentCode"
  268 + label="学号"
  269 + fixed
  270 + align="center"
  271 + ></el-table-column>
  272 + <el-table-column
  273 + prop="studentName"
  274 + label="姓名"
  275 + fixed
  276 + align="center"
  277 + ></el-table-column>
  278 + <el-table-column
  279 + prop="examScore"
  280 + label="总分"
  281 + sortable
  282 + align="center"
  283 + ></el-table-column>
  284 + <el-table-column label="分数组成" align="center">
  285 + <el-table-column
  286 + prop="objectiveExamScore"
  287 + label="客观题分"
  288 + align="center"
  289 + ></el-table-column>
  290 + <el-table-column
  291 + prop="subjectiveExamScore"
  292 + label="主观题分"
  293 + align="center"
  294 + ></el-table-column>
  295 + </el-table-column>
  296 + <el-table-column
  297 + align="center"
  298 + v-for="(item, index) in questionList"
  299 + :key="index"
  300 + :label="'题目' + item.id"
  301 + :prop="'score' + item.id"
  302 + >
  303 + </el-table-column>
  304 + </el-table>
  305 + <el-table
  306 + :max-height="tableMaxHeight"
  307 + v-show="type == 4"
  308 + :data="tableData2"
  309 + border
  310 + style="width: 100%"
  311 + :default-sort="{ prop: '', order: 'descending' }"
365 > 312 >
366 - <div> 313 + <el-table-column
  314 + prop="studentCode"
  315 + label="学号"
  316 + fixed
  317 + align="center"
  318 + ></el-table-column>
  319 + <el-table-column
  320 + prop="studentName"
  321 + label="姓名"
  322 + fixed
  323 + align="center"
  324 + ></el-table-column>
  325 + <el-table-column
  326 + prop="className"
  327 + label="班级"
  328 + align="center"
  329 + ></el-table-column>
  330 + <el-table-column
  331 + prop="examScore"
  332 + label="总分"
  333 + sortable
  334 + align="center"
  335 + ></el-table-column>
  336 + <el-table-column
  337 + align="center"
  338 + v-for="(item, index) in questionList"
  339 + :key="index"
  340 + :label="'题目' + item.id"
  341 + >
  342 + <template slot-scope="scope">
  343 + <span
  344 + v-if="scope.row['answer' + item.id]"
  345 + :class="scope.row['isRight' + item.id] ? '' : 'error'"
  346 + >
  347 + {{ scope.row["answer" + item.id] }}
  348 + </span>
  349 + <span
  350 + v-else
  351 + :class="scope.row['questionType' + item.id] == 5 ? '' : 'error'"
  352 + >
  353 + {{ scope.row["questionType" + item.id] == 5 ? "*" : "-" }}
  354 + </span>
  355 + </template>
  356 + </el-table-column>
  357 + </el-table>
  358 + <div class="down">
367 <el-button 359 <el-button
368 - v-if="paperModifyLog.subjectiveScore != 0"  
369 - @click="diaUp = true"  
370 - type="primary" 360 + @click="exportData"
  361 + type="info"
  362 + plain
371 round 363 round
372 - v-loading="exportLoading"  
373 - >导入主观题分数</el-button 364 + icon="fa fa-cloud-download"
  365 + >导出报表</el-button
374 > 366 >
375 - <el-button @click="edit" type="primary" round>修改答案</el-button> 367 + <div>
  368 + <el-button
  369 + v-if="examReport.subjectiveScore != 0"
  370 + @click="diaUp = true"
  371 + type="primary"
  372 + round
  373 + v-loading="exportLoading"
  374 + >导入主观题分数</el-button
  375 + >
  376 + <el-button
  377 + @click="edit"
  378 + type="primary"
  379 + v-if="examReport.subjectiveScore != examReport.examPaperScore"
  380 + round
  381 + >修改答案</el-button
  382 + >
  383 + </div>
376 </div> 384 </div>
377 </div> 385 </div>
378 <div class="edit-dia" v-show="dialogVisible" height="100%"> 386 <div class="edit-dia" v-show="dialogVisible" height="100%">
@@ -385,7 +393,12 @@ @@ -385,7 +393,12 @@
385 /> 393 />
386 </div> 394 </div>
387 <el-dialog title="导入主观题分数" :visible.sync="diaUp" width="600"> 395 <el-dialog title="导入主观题分数" :visible.sync="diaUp" width="600">
388 - <up-load :url="url" :examId="id" fileName="教师名单"> 396 + <up-load
  397 + :url="url"
  398 + :examId="id"
  399 + @upSuccess="upSuccess"
  400 + fileName="教师名单"
  401 + >
389 <template slot="down"> 402 <template slot="down">
390 <p class="down-txt"> 403 <p class="down-txt">
391 第一步:下载模板并编辑完成学生分数 404 第一步:下载模板并编辑完成学生分数
@@ -409,7 +422,7 @@ export default { @@ -409,7 +422,7 @@ export default {
409 components: { editAnswer }, 422 components: { editAnswer },
410 data() { 423 data() {
411 return { 424 return {
412 - tableMaxHeight:300, 425 + tableMaxHeight: 600,
413 loading: false, 426 loading: false,
414 exportLoading: false, 427 exportLoading: false,
415 diaUp: false, 428 diaUp: false,
@@ -422,6 +435,8 @@ export default { @@ -422,6 +435,8 @@ export default {
422 paperModifyLog: { 435 paperModifyLog: {
423 realName: "", 436 realName: "",
424 modifiedTime: "", 437 modifiedTime: "",
  438 + },
  439 + examReport: {
425 subjectiveScore: 0, 440 subjectiveScore: 0,
426 subjectiveHighestScore: "", 441 subjectiveHighestScore: "",
427 subjectiveLowestScore: "", 442 subjectiveLowestScore: "",
@@ -454,9 +469,15 @@ export default { @@ -454,9 +469,15 @@ export default {
454 this._QueryData(); 469 this._QueryData();
455 }, 470 },
456 methods: { 471 methods: {
457 - setType(type){  
458 - this.tableMaxHeight = this.$refs.main.offsetHeight-120  
459 - this.type=type 472 + upSuccess() {
  473 + //导入成功
  474 + this.diaUp = false;
  475 + this._QueryData();
  476 + },
  477 + setType(type) {
  478 + console.log(this.$refs.main.offsetHeight - 50);
  479 + this.tableMaxHeight = this.$refs.main.offsetHeight;
  480 + this.type = type;
460 }, 481 },
461 setSubPro(type) { 482 setSubPro(type) {
462 let tit; 483 let tit;
@@ -517,9 +538,10 @@ export default { @@ -517,9 +538,10 @@ export default {
517 }); 538 });
518 this.loading = false; 539 this.loading = false;
519 if (status === 0) { 540 if (status === 0) {
520 - if (data.examReport) {  
521 - this.paperModifyLog = { ...data.examReport }; 541 + if (data.paperModifyLog) {
  542 + this.paperModifyLog = { ...data?.paperModifyLog };
522 } 543 }
  544 + this.examReport = { ...data?.examReport };
523 } else { 545 } else {
524 this.$message.error(info); 546 this.$message.error(info);
525 } 547 }
@@ -556,7 +578,6 @@ export default { @@ -556,7 +578,6 @@ export default {
556 if (detail.length > optionsList.length) { 578 if (detail.length > optionsList.length) {
557 optionsList = [...detail]; 579 optionsList = [...detail];
558 } 580 }
559 - console.log(detail);  
560 detail.map((items, index) => { 581 detail.map((items, index) => {
561 params["que" + items.id] = items.id; 582 params["que" + items.id] = items.id;
562 params["score" + items.id] = Number(items.score).toFixed(2); 583 params["score" + items.id] = Number(items.score).toFixed(2);
@@ -570,7 +591,10 @@ export default { @@ -570,7 +591,10 @@ export default {
570 ...params, 591 ...params,
571 }; 592 };
572 }); 593 });
573 - this.questionList = [...optionsList]; 594 + console.log();
  595 + this.questionList = optionsList.sort((a, b) => {
  596 + return a.id - b.id;
  597 + });
574 } else { 598 } else {
575 this.$message.error(info); 599 this.$message.error(info);
576 } 600 }
@@ -581,40 +605,69 @@ export default { @@ -581,40 +605,69 @@ export default {
581 let { data, info, status } = await this.$request.examQuestionReport({ 605 let { data, info, status } = await this.$request.examQuestionReport({
582 examId: this.id, 606 examId: this.id,
583 page: this.page, 607 page: this.page,
584 - size: this.size, 608 + // size: this.size,
  609 + size: 9999,
585 }); 610 });
586 this.loading = false; 611 this.loading = false;
587 if (status === 0) { 612 if (status === 0) {
588 - let optionsList = [];  
589 - this.tableData = data?.list.map((item) => { 613 + let optionsList = [{}, {}, {}, {}, {}];
  614 + let tableData = data?.list.map((item) => {
590 let params = {}; 615 let params = {};
591 -  
592 const detail = JSON.parse(item.detail); 616 const detail = JSON.parse(item.detail);
593 - if (detail.length > optionsList.length) {  
594 - optionsList = [...detail];  
595 - }  
596 - console.log(detail);  
597 - detail.map((items, index) => {  
598 - params["count" + index] = items.count;  
599 - params["option" + index] =  
600 - items.option == 1 ? "✓" : items.option == 2 ? "✗" : items.option; 617 + let lastOPtion = detail?.find((item) => {
  618 + return item.option == "未答";
  619 + });
  620 + let defaultArr = detail?.filter((item) => {
  621 + return item.option != "未答";
  622 + });
  623 +
  624 + optionsList.map((items, index) => {
  625 + if (index != 4) {
  626 + params["count" + index] =
  627 + defaultArr[index]?.option != "未答" ? defaultArr[index]?.count : "";
  628 + params["present" + index] =
  629 + defaultArr[index]?.option != "未答" ? defaultArr[index]?.present : "";
  630 + params["option" + index] =
  631 + defaultArr[index]?.option != "未答"
  632 + ? defaultArr[index]?.option == 1
  633 + ? "✓"
  634 + : defaultArr[index]?.option == 2
  635 + ? "✗"
  636 + : defaultArr[index]?.option
  637 + : "";
  638 + items["title"] = "选项" + (index + 1);
  639 + } else {
  640 + items["title"] = "未答";
  641 + params["count" + index] = lastOPtion.count;
  642 + params["present" + index] = lastOPtion.present;
  643 + params["option" + index] =
  644 + lastOPtion.option == 1
  645 + ? "✓"
  646 + : lastOPtion.option == 2
  647 + ? "✗"
  648 + : lastOPtion.option;
  649 + }
601 }); 650 });
602 return { 651 return {
603 ...item, 652 ...item,
604 ...params, 653 ...params,
605 }; 654 };
606 }); 655 });
  656 + this.tableData = tableData.sort((a, b) => {
  657 + return a.questionIndex - b.questionIndex;
  658 + });
607 this.optionsList = [...optionsList]; 659 this.optionsList = [...optionsList];
608 this.total = data.count; 660 this.total = data.count;
  661 + this.setType(1);
609 } else { 662 } else {
610 this.$message.error(info); 663 this.$message.error(info);
611 } 664 }
612 }, 665 },
613 //导出 666 //导出
614 async exportData() { 667 async exportData() {
615 - if ((this.exportLoading = true)) return; 668 + if (this.exportLoading == true) return;
616 this.exportLoading = true; 669 this.exportLoading = true;
617 - const { data, status, info } = await this.$request.exportData(); 670 + const { data, status, info } = await this.$request.exportPeriodReport();
618 this.exportLoading = false; 671 this.exportLoading = false;
619 if (data) { 672 if (data) {
620 downloadFile(this.title + "报表", data); 673 downloadFile(this.title + "报表", data);
@@ -638,7 +691,10 @@ div::-webkit-scrollbar-thumb { @@ -638,7 +691,10 @@ div::-webkit-scrollbar-thumb {
638 <style lang="scss" scoped> 691 <style lang="scss" scoped>
639 .page-container { 692 .page-container {
640 position: relative; 693 position: relative;
641 - min-height: 100%; 694 + height: 100%;
  695 + .table-box {
  696 + min-height: 100%;
  697 + }
642 &.active { 698 &.active {
643 overflow: hidden; 699 overflow: hidden;
644 } 700 }
@@ -671,7 +727,7 @@ div::-webkit-scrollbar-thumb { @@ -671,7 +727,7 @@ div::-webkit-scrollbar-thumb {
671 background-color: #ffebec; 727 background-color: #ffebec;
672 font-size: 14px; 728 font-size: 14px;
673 color: #fd9795; 729 color: #fd9795;
674 - margin: 10px 20px 20px 20px; 730 + margin: 10px 20px 0 20px;
675 display: flex; 731 display: flex;
676 &-p { 732 &-p {
677 flex: 1; 733 flex: 1;
src/views/test/editAnswer.vue
@@ -294,7 +294,6 @@ @@ -294,7 +294,6 @@
294 import { deepClone, checkAnswer } from "utils"; 294 import { deepClone, checkAnswer } from "utils";
295 export default { 295 export default {
296 props: { 296 props: {
297 - id: "",  
298 title: "", 297 title: "",
299 score: "", 298 score: "",
300 }, 299 },
@@ -310,6 +309,7 @@ export default { @@ -310,6 +309,7 @@ export default {
310 }, 309 },
311 data() { 310 data() {
312 return { 311 return {
  312 + id:"",
313 diaSetAns: false, 313 diaSetAns: false,
314 form: {}, 314 form: {},
315 questionList: [], 315 questionList: [],
@@ -488,6 +488,7 @@ export default { @@ -488,6 +488,7 @@ export default {
488 }, 488 },
489 async edit(id) { 489 async edit(id) {
490 //修改答案 490 //修改答案
  491 + this.id = id
491 const { data, status, info } = await this.$request.examQuestionList({ 492 const { data, status, info } = await this.$request.examQuestionList({
492 examId: id, 493 examId: id,
493 }); 494 });
src/views/test/index.vue
@@ -7,11 +7,7 @@ @@ -7,11 +7,7 @@
7 </back-box> 7 </back-box>
8 <div class="answer-header"> 8 <div class="answer-header">
9 <div class="sel-box"> 9 <div class="sel-box">
10 - <el-select  
11 - class="sel"  
12 - v-model="query.classId"  
13 - placeholder="选择班级"  
14 - > 10 + <el-select class="sel" v-model="query.classId" placeholder="选择班级" @change="changeclass">
15 <el-option 11 <el-option
16 v-for="item in classList" 12 v-for="item in classList"
17 :key="item.value" 13 :key="item.value"
@@ -93,10 +89,10 @@ @@ -93,10 +89,10 @@
93 style="margin-bottom: 20px" 89 style="margin-bottom: 20px"
94 > 90 >
95 <el-radio-button :label="1">单卷测练报表</el-radio-button> 91 <el-radio-button :label="1">单卷测练报表</el-radio-button>
96 - <el-radio-button :label="2">阶段测练报表</el-radio-button> 92 + <el-radio-button :label="2" v-show="this.query.startDay!=this.query.endDay">阶段测练报表</el-radio-button>
97 </el-radio-group> 93 </el-radio-group>
98 <div v-show="tabIndex == 1" v-loading="loading"> 94 <div v-show="tabIndex == 1" v-loading="loading">
99 - <el-table :data="tableData" border style="width: 100%"> 95 + <el-table :data="tableData" :show-header="tableData.length?true:false" border style="width: 100%">
100 <el-table-column 96 <el-table-column
101 prop="title" 97 prop="title"
102 label="试卷名称" 98 label="试卷名称"
@@ -120,24 +116,24 @@ @@ -120,24 +116,24 @@
120 ></el-table-column> 116 ></el-table-column>
121 <el-table-column prop="avgScore" label="班平均分" align="center" 117 <el-table-column prop="avgScore" label="班平均分" align="center"
122 ><template slot-scope="scoped">{{ 118 ><template slot-scope="scoped">{{
123 - scoped.row.subjectiveScore == scoped.row.examPaperScore ||  
124 - scoped.row.answerNum == 0 119 + (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.answerNum == 0) &&
  120 + scoped.row.recordStatus == 0
125 ? "-" 121 ? "-"
126 : scoped.row.avgScore 122 : scoped.row.avgScore
127 }}</template></el-table-column 123 }}</template></el-table-column
128 > 124 >
129 <el-table-column prop="highestScore" label="班最高分" align="center" 125 <el-table-column prop="highestScore" label="班最高分" align="center"
130 ><template slot-scope="scoped">{{ 126 ><template slot-scope="scoped">{{
131 - scoped.row.subjectiveScore == scoped.row.examPaperScore ||  
132 - scoped.row.answerNum == 0 127 + (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.answerNum == 0) &&
  128 + scoped.row.recordStatus == 0
133 ? "-" 129 ? "-"
134 : scoped.row.highestScore 130 : scoped.row.highestScore
135 }}</template></el-table-column 131 }}</template></el-table-column
136 > 132 >
137 <el-table-column prop="lowestScore" label="班最低分" align="center" 133 <el-table-column prop="lowestScore" label="班最低分" align="center"
138 ><template slot-scope="scoped">{{ 134 ><template slot-scope="scoped">{{
139 - scoped.row.subjectiveScore == scoped.row.examPaperScore ||  
140 - scoped.row.answerNum == 0 135 + (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.answerNum == 0) &&
  136 + scoped.row.recordStatus == 0
141 ? "-" 137 ? "-"
142 : scoped.row.lowestScore 138 : scoped.row.lowestScore
143 }}</template></el-table-column 139 }}</template></el-table-column
@@ -148,10 +144,12 @@ @@ -148,10 +144,12 @@
148 sortable 144 sortable
149 align="center" 145 align="center"
150 ><template slot-scope="scoped">{{ 146 ><template slot-scope="scoped">{{
151 - scoped.row.subjectiveScore == scoped.row.examPaperScore ||  
152 - scoped.row.answerNum == 0 147 + (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.answerNum == 0) &&
  148 + scoped.row.recordStatus == 0
153 ? "-" 149 ? "-"
154 - : scoped.row.excellenNum?`${scoped.row.excellenNum}/${scoped.row.excellenRate}%`:scoped.row.excellenNum 150 + : scoped.row.excellenNum
  151 + ? `${scoped.row.excellenNum}/${scoped.row.excellenRate}%`
  152 + : scoped.row.excellenNum
155 }}</template></el-table-column 153 }}</template></el-table-column
156 > 154 >
157 <el-table-column 155 <el-table-column
@@ -161,10 +159,12 @@ @@ -161,10 +159,12 @@
161 align="center" 159 align="center"
162 ><template slot-scope="scoped" 160 ><template slot-scope="scoped"
163 >{{ 161 >{{
164 - scoped.row.subjectiveScore == scoped.row.examPaperScore ||  
165 - scoped.row.answerNum == 0 162 + (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.answerNum == 0) &&
  163 + scoped.row.recordStatus == 0
166 ? "-" 164 ? "-"
167 - : scoped.row.goodNum?`${scoped.row.goodNum}/${scoped.row.goodRate}%`:scoped.row.goodNum 165 + : scoped.row.goodNum
  166 + ? `${scoped.row.goodNum}/${scoped.row.goodRate}%`
  167 + : scoped.row.goodNum
168 }} 168 }}
169 </template></el-table-column 169 </template></el-table-column
170 > 170 >
@@ -175,10 +175,12 @@ @@ -175,10 +175,12 @@
175 align="center" 175 align="center"
176 ><template slot-scope="scoped" 176 ><template slot-scope="scoped"
177 >{{ 177 >{{
178 - scoped.row.subjectiveScore == scoped.row.examPaperScore ||  
179 - scoped.row.answerNum == 0  
180 - ? "-"  
181 - : scoped.row.passNum?`${scoped.row.passNum}/${scoped.row.passRate}%`:scoped.row.passNum 178 + (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.answerNum == 0) &&
  179 + scoped.row.recordStatus == 0
  180 + ? "-"
  181 + : scoped.row.passNum
  182 + ? `${scoped.row.passNum}/${scoped.row.passRate}%`
  183 + : scoped.row.passNum
182 }} 184 }}
183 </template></el-table-column 185 </template></el-table-column
184 > 186 >
@@ -188,16 +190,18 @@ @@ -188,16 +190,18 @@
188 sortable 190 sortable
189 align="center" 191 align="center"
190 ><template slot-scope="scoped">{{ 192 ><template slot-scope="scoped">{{
191 - scoped.row.subjectiveScore == scoped.row.examPaperScore ||  
192 - scoped.row.answerNum == 0 193 + (scoped.row.subjectiveScore == scoped.row.examPaperScore || scoped.row.nswerNum == 0) &&
  194 + scoped.row.arecordStatus== 0
193 ? "-" 195 ? "-"
194 - : scoped.row.failedNum?`${scoped.row.failedNum}/${scoped.row.failedRate}%`:scoped.row.failedNum 196 + : scoped.row.failedNum
  197 + ? `${scoped.row.failedNum}/${scoped.row.failedRate}%`
  198 + : scoped.row.failedNum
195 }}</template></el-table-column 199 }}</template></el-table-column
196 > 200 >
197 <el-table-column label="操作" align="center"> 201 <el-table-column label="操作" align="center">
198 <template slot-scope="scoped"> 202 <template slot-scope="scoped">
199 <el-tooltip 203 <el-tooltip
200 - v-if="scoped.row.answerNum != 0" 204 + v-if="scoped.row.answerNum != 0 || (scoped.row.recordStatus != 0 &&scoped.row.subjectiveScore == scoped.row.examPaperScore)"
201 effect="dark" 205 effect="dark"
202 content="详情" 206 content="详情"
203 placement="top" 207 placement="top"
@@ -211,9 +215,9 @@ @@ -211,9 +215,9 @@
211 ></el-button> 215 ></el-button>
212 </el-tooltip> 216 </el-tooltip>
213 <el-tooltip 217 <el-tooltip
214 - v-else 218 + v-if="scoped.row.answerNum == 0 && scoped.row.subjectiveScore != scoped.row.examPaperScore"
215 effect="dark" 219 effect="dark"
216 - content="修改答案" 220 + content="设置答案"
217 placement="top" 221 placement="top"
218 > 222 >
219 <el-button 223 <el-button
@@ -225,7 +229,7 @@ @@ -225,7 +229,7 @@
225 ></el-button> 229 ></el-button>
226 </el-tooltip> 230 </el-tooltip>
227 <el-tooltip 231 <el-tooltip
228 - v-if="scoped.row.subjectiveScore == scoped.row.examPaperScore" 232 + v-if="scoped.row.subjectiveScore == scoped.row.examPaperScore && scoped.row.recordStatus == 0"
229 effect="dark" 233 effect="dark"
230 content="导入主观题" 234 content="导入主观题"
231 placement="top" 235 placement="top"
@@ -256,8 +260,10 @@ @@ -256,8 +260,10 @@
256 </div> 260 </div>
257 <div v-show="tabIndex == 2" v-loading="loading"> 261 <div v-show="tabIndex == 2" v-loading="loading">
258 <el-table 262 <el-table
  263 + :max-height="tableMaxHeight"
259 v-if="role == 'ROLE_JIAOSHI'" 264 v-if="role == 'ROLE_JIAOSHI'"
260 :data="tableData" 265 :data="tableData"
  266 + :show-header="tableData.length?true:false"
261 border 267 border
262 style="width: 100%" 268 style="width: 100%"
263 > 269 >
@@ -291,7 +297,14 @@ @@ -291,7 +297,14 @@
291 ></el-table-column> 297 ></el-table-column>
292 </el-table-column> 298 </el-table-column>
293 </el-table> 299 </el-table>
294 - <el-table :max-height="tableMaxHeight" v-else :data="tableData" border style="width: 100%"> 300 + <el-table
  301 + :show-header="tableData.length?true:false"
  302 + :max-height="tableMaxHeight"
  303 + v-else
  304 + :data="tableData"
  305 + border
  306 + style="width: 100%"
  307 + >
295 <el-table-column 308 <el-table-column
296 prop="studentCode" 309 prop="studentCode"
297 label="学号" 310 label="学号"
@@ -340,7 +353,7 @@ @@ -340,7 +353,7 @@
340 </p> 353 </p>
341 </div> 354 </div>
342 <el-dialog title="导入主观题分数" :visible.sync="diaUp" width="600"> 355 <el-dialog title="导入主观题分数" :visible.sync="diaUp" width="600">
343 - <up-load :url="url" :examId="examId" fileName="教师名单"> 356 + <up-load :url="url" :examId="examId" @upSuccess="upSuccess" fileName="主观题分数" v-loading="loadingDown">
344 <template slot="down"> 357 <template slot="down">
345 <p class="down-txt"> 358 <p class="down-txt">
346 第一步:下载模板并编辑完成学生分数 359 第一步:下载模板并编辑完成学生分数
@@ -372,10 +385,11 @@ export default { @@ -372,10 +385,11 @@ export default {
372 components: { editAnswer }, 385 components: { editAnswer },
373 data() { 386 data() {
374 return { 387 return {
375 - tableMaxHeight:300, 388 + tableMaxHeight: 300,
376 role: "", 389 role: "",
377 loading: false, 390 loading: false,
378 diaUp: false, 391 diaUp: false,
  392 + loadingDown:false,
379 url: "/api_html/teaching/importSubjectiveScore", 393 url: "/api_html/teaching/importSubjectiveScore",
380 examId: "", 394 examId: "",
381 dialogVisible: false, 395 dialogVisible: false,
@@ -417,13 +431,13 @@ export default { @@ -417,13 +431,13 @@ export default {
417 } 431 }
418 }, 432 },
419 methods: { 433 methods: {
420 - changeSub(val) { 434 + changeSub(val) {
421 let sub; 435 let sub;
422 if (val && val.length) { 436 if (val && val.length) {
423 let leng = val.length - 1; 437 let leng = val.length - 1;
424 sub = val[leng]; 438 sub = val[leng];
425 } 439 }
426 - console.log(val) 440 + console.log(val);
427 this.query.subjectNames = val.filter((item) => { 441 this.query.subjectNames = val.filter((item) => {
428 return sub != "全部" ? item != "全部" : item == "全部"; 442 return sub != "全部" ? item != "全部" : item == "全部";
429 }); 443 });
@@ -529,14 +543,25 @@ export default { @@ -529,14 +543,25 @@ export default {
529 this.dialogVisible = true; 543 this.dialogVisible = true;
530 }, 544 },
531 changeTab() { 545 changeTab() {
532 - this.tableMaxHeight = this.$refs.main.offsetHeight-100 546 + this.tableMaxHeight = this.$refs.main.offsetHeight;
533 this.page = 1; 547 this.page = 1;
534 this._QueryData(); 548 this._QueryData();
535 }, 549 },
  550 + upSuccess(){//导入成功
  551 + this.diaUp = false
  552 + this._QueryData();
  553 + },
  554 + async changeclass(){
  555 + await this._QuerySubjectList()
  556 + this.page = 1
  557 + this._QueryData()
  558 + },
536 async downExcel() { 559 async downExcel() {
  560 + this.loadingDown = true
537 let data = await this.$request.subjectiveScoreTemplate({ 561 let data = await this.$request.subjectiveScoreTemplate({
538 - examId: this.id, 562 + examId: this.examId,
539 }); 563 });
  564 + this.loadingDown = false
540 if (data && !data.code) { 565 if (data && !data.code) {
541 let blob = new Blob([data], { 566 let blob = new Blob([data], {
542 type: "application/vnd.ms-excel;charset=utf-8", 567 type: "application/vnd.ms-excel;charset=utf-8",
@@ -629,7 +654,7 @@ export default { @@ -629,7 +654,7 @@ export default {
629 }); 654 });
630 query["subjectNames"].shift(); 655 query["subjectNames"].shift();
631 } 656 }
632 - if (!query["subjectNames"]) { 657 + if (!query["subjectNames"]) {
633 this.$message.warning("请选择科目"); 658 this.$message.warning("请选择科目");
634 return; 659 return;
635 } 660 }
@@ -754,7 +779,7 @@ div::-webkit-scrollbar-thumb { @@ -754,7 +779,7 @@ div::-webkit-scrollbar-thumb {
754 <style lang="scss" scoped> 779 <style lang="scss" scoped>
755 .page-container { 780 .page-container {
756 position: relative; 781 position: relative;
757 - min-height: 100%; 782 + height: 100%;
758 &.active { 783 &.active {
759 overflow: hidden; 784 overflow: hidden;
760 } 785 }