Commit e5e4a3e681d5488e29e9dfbdc63f8cb47188af3e

Authored by 梁保满
1 parent ae0a304c

v1.3

src/api/apis/apis.js
... ... @@ -567,6 +567,15 @@ export default {
567 567 data,
568 568 });
569 569 },
  570 + // 导出设备列表
  571 + exportDevice(data) {
  572 + return service({
  573 + url: setUpUrls.exportDevice,
  574 + method: "POST",
  575 + data,
  576 + responseType: 'arraybuffer',
  577 + });
  578 + },
570 579 // 查询设备详情
571 580 deviceDetail(data) {
572 581 return service({
... ... @@ -704,6 +713,38 @@ export default {
704 713 responseType: 'arraybuffer',
705 714 });
706 715 },
  716 + // 班级归档
  717 + classArchiving(data) {
  718 + return service({
  719 + url: setUpUrls.classArchiving,
  720 + method: "POST",
  721 + data,
  722 + });
  723 + },
  724 + // 查询学校已归档班级列表
  725 + archivingClassList(data) {
  726 + return service({
  727 + url: setUpUrls.archivingClassList,
  728 + method: "POST",
  729 + data,
  730 + });
  731 + },
  732 + // 学生换班
  733 + studentChangeClass(data) {
  734 + return service({
  735 + url: setUpUrls.studentChangeClass,
  736 + method: "POST",
  737 + data,
  738 + });
  739 + },
  740 + // 升级年级
  741 + upgradeGrade(data) {
  742 + return service({
  743 + url: setUpUrls.upgradeGrade,
  744 + method: "POST",
  745 + data,
  746 + });
  747 + },
707 748  
708 749 /**
709 750 * 集团管理员-学校管理
... ...
src/api/axios.js
... ... @@ -67,7 +67,6 @@ service.interceptors.response.use(
67 67  
68 68 if (status === 403 || status === 401) {
69 69 if (data.status === 999) {
70   - console.log(data.data)
71 70 if (data.data) {
72 71 window.location.href = data.data;
73 72 } else {
... ...
src/api/urls/apis.js
... ... @@ -140,6 +140,8 @@ export default {
140 140 keyboardReport: "/api_html/school/manager/keyboardReport",
141 141 // 分页查询设备列表
142 142 deviceList: "/api_html/school/manager/deviceList",
  143 + // 导出设备列表
  144 + exportDevice: "/api_html/school/manager/exportDevice",
143 145 // 查询设备详情
144 146 deviceDetail: "/api_html/school/manager/deviceDetail",
145 147 // 分页查询设备日志列表
... ... @@ -174,6 +176,15 @@ export default {
174 176 latestClickersApp: "/api_html/school/manager/latestClickersApp",
175 177 // 发卡导出
176 178 exportClickersLog: "/api_html/school/manager/exportClickersLog",
  179 + /*v1.3*/
  180 + // 班级归档
  181 + classArchiving: "/api_html/school/manager/classArchiving",
  182 + // 查询学校已归档班级列表
  183 + archivingClassList: "/api_html/school/manager/archivingClassList",
  184 + // 学生换班
  185 + studentChangeClass: "/api_html/school/manager/studentChangeClass",
  186 + // 升级年级
  187 + upgradeGrade: "/api_html/school/manager/upgradeGrade",
177 188  
178 189  
179 190 // 查询区域列表
... ...
src/components/charts/pieChart.vue
... ... @@ -64,7 +64,6 @@ export default {
64 64 label: {
65 65 normal: {
66 66 formatter(v) {
67   - console.log(v)
68 67 let rate = v.data.rate*100
69 68 return v.name + rate.toFixed(2) + "%";
70 69 },
... ...
src/components/setAnswer.vue
... ... @@ -446,7 +446,6 @@ export default {
446 446 i--;
447 447 }
448 448 }
449   - console.log(questionList);
450 449 const { data, status, message } = await this.$request.setPeriodAnswer({
451 450 periodId: this.paperId,
452 451 questionList: questionList,
... ...
src/router/index.js
... ... @@ -12,18 +12,24 @@ const ExaminationPaper = () => import("@/views/examinationPaper/index")
12 12 const ExaminationPaperAdd = () => import("@/views/examinationPaper/add")
13 13 const ExaminationPaperEdit = () => import("@/views/examinationPaper/edit")
14 14 const ExaminationPaperRecycle = () => import("@/views/examinationPaper/recycle")
  15 +const ExaminationPaperArchiving = () => import("@/views/examinationPaper/archiving")
15 16 const Portrait = () => import("@/views/portrait/index")
16 17 const PortraitDetail = () => import("@/views/portrait/detail")
17 18 const CSExaminationPaper = () => import("@/views/examinationPaper/index")
18   -const CSExaminationPaperAdd = () => import("@/views/standard/examinationPaper/add")
19   -const CSExaminationPaperEdit = () => import("@/views/standard/examinationPaper/edit")
20   -const CSExaminationPaperRecycle = () => import("@/views/standard/examinationPaper/recycle")
  19 +// const CSExaminationPaperAdd = () => import("@/views/standard/examinationPaper/add")
  20 +// const CSExaminationPaperEdit = () => import("@/views/standard/examinationPaper/edit")
  21 +// const CSExaminationPaperRecycle = () => import("@/views/standard/examinationPaper/recycle")
  22 +const CSExaminationPaperAdd = () => import("@/views/examinationPaper/add")
  23 +const CSExaminationPaperEdit = () => import("@/views/examinationPaper/edit")
  24 +const CSExaminationPaperRecycle = () => import("@/views/examinationPaper/recycle")
21 25  
22 26  
23 27 const Ask = () => import("@/views/standard/ask/index")
24 28 const AskAnalysis = () => import("@/views/standard/ask/analysis")
  29 +const AskArchiving = () => import("@/views/standard/ask/archiving")
25 30 const Test = () => import("@/views/standard/test/index")
26 31 const TestAnalysis = () => import("@/views/standard/test/analysis")
  32 +const TestArchiving = () => import("@/views/standard/test/archiving")
27 33 const DataSync = () => import("@/views/standard/dataSync/index")
28 34 const Card = () => import("@/views/standard/card/index")
29 35 const Analysis = () => import("@/views/standard/analysis/index")
... ... @@ -34,13 +40,16 @@ const DownClient = () => import("@/views/standard/down/client")
34 40 const SetUpAccount = () => import("@/views/standard/setUp/account")
35 41 const SetUpConglomerate = () => import("@/views/standard/setUp/conglomerate")
36 42 const SetUpSchool = () => import("@/views/standard/setUp/school")
37   -const SetUpStudent = () => import("@/views/standard/setUp/student")
38 43 const SetUpTeacher = () => import("@/views/standard/setUp/teacher")
  44 +const SetUpStudent = () => import("@/views/standard/setUp/student")
  45 +const ArchivedClazz = () => import("@/views/standard/setUp/archivedClazz")
39 46  
40 47 const PersonalAsk = () => import("@/views/personal/ask/index")
41 48 const PersonalAskAnalysis = () => import("@/views/personal/ask/analysis")
  49 +const PersonalArchiving = () => import("@/views/personal/ask/archiving")
42 50 const PersonalTest = () => import("@/views/personal/test/index")
43 51 const PersonalTestAnalysis = () => import("@/views/personal/test/analysis")
  52 +const PersonalTestArchiving = () => import("@/views/personal/test/archiving")
44 53 const PersonalDataSync = () => import("@/views/personal/dataSync/index")
45 54 const PersonalSetUpStudent = () => import("@/views/personal/setUp/student")
46 55 const PersonalDown = () => import("@/views/personal/down/index")
... ... @@ -115,7 +124,7 @@ let defaultRouter = [
115 124 }
116 125 ]
117 126  
118   -let addrouters = [
  127 +let addrouters = [
119 128 {
120 129 path: "/examinationPaper",
121 130 iconCls: "fa fa-file-text", // 图标样式class
... ... @@ -149,11 +158,20 @@ let addrouters = [
149 158 {
150 159 path: "/examinationPaperRecycle",
151 160 iconCls: "", // 图标样式class
152   - name: "已归档答题卡",
  161 + name: "回收站答题卡",
153 162 component: ExaminationPaperRecycle,
154 163 parent: "examinationPaper",
155 164 children: []
156 165 },
  166 + {
  167 + path: "/examinationPaperArchiving",
  168 + iconCls: "", // 图标样式class
  169 + name: "已归档答题卡",
  170 + component: ExaminationPaperArchiving,
  171 + parent: "examinationPaper",
  172 + hidden: true,
  173 + children: []
  174 + },
157 175 ]
158 176 },
159 177 {
... ... @@ -182,6 +200,15 @@ let addrouters = [
182 200 component: AskAnalysis,
183 201 parent: "ask",
184 202 children: []
  203 + },
  204 + {
  205 + path: "/askArchiving",
  206 + iconCls: "", // 图标样式class
  207 + name: "随堂问已归档报表分析",
  208 + component: AskArchiving,
  209 + parent: "ask",
  210 + hidden: true,
  211 + children: []
185 212 }
186 213 ]
187 214 },
... ... @@ -209,6 +236,15 @@ let addrouters = [
209 236 component: TestAnalysis,
210 237 parent: "test",
211 238 children: []
  239 + },
  240 + {
  241 + path: "/testArchiving",
  242 + iconCls: "", // 图标样式class
  243 + name: "即时测已归档报表分析",
  244 + component: TestArchiving,
  245 + parent: "test",
  246 + hidden: true,
  247 + children: []
212 248 }
213 249  
214 250 ]
... ... @@ -272,6 +308,14 @@ let addrouters = [
272 308 component: SetUpStudent,
273 309 children: []
274 310 },
  311 + {
  312 + path: "/archivedClazz",
  313 + iconCls: "fa fa-list-ul",
  314 + name: '已归档班级',
  315 + component: ArchivedClazz,
  316 + hidden: true,
  317 + children: []
  318 + },
275 319 ]
276 320 },
277 321 {
... ... @@ -401,7 +445,7 @@ let addrouters = [
401 445 // ]
402 446 // },
403 447 ]
404   -let csAddrouters = [
  448 +let csAddrouters = [
405 449 {
406 450 path: "/examinationPaper",
407 451 iconCls: "fa fa-file-text", // 图标样式class
... ... @@ -435,11 +479,20 @@ let csAddrouters = [
435 479 {
436 480 path: "/examinationPaperRecycle",
437 481 iconCls: "", // 图标样式class
438   - name: "已归档答题卡",
  482 + name: "回收站答题卡",
439 483 component: CSExaminationPaperRecycle,
440 484 parent: "examinationPaper",
441 485 children: []
442 486 },
  487 + {
  488 + path: "/examinationPaperArchiving",
  489 + iconCls: "", // 图标样式class
  490 + name: "已归档答题卡",
  491 + component: ExaminationPaperArchiving,
  492 + parent: "examinationPaper",
  493 + hidden: true,
  494 + children: []
  495 + },
443 496 ]
444 497 },
445 498 {
... ... @@ -711,11 +764,20 @@ const addroutersPersonal = [
711 764 {
712 765 path: "/examinationPaperRecycle",
713 766 iconCls: "", // 图标样式class
714   - name: "已归档答题卡",
  767 + name: "回收站答题卡",
715 768 component: ExaminationPaperRecycle,
716 769 parent: "examinationPaper",
717 770 children: []
718 771 },
  772 + {
  773 + path: "/examinationPaperArchiving",
  774 + iconCls: "", // 图标样式class
  775 + name: "已归档答题卡",
  776 + component: ExaminationPaperArchiving,
  777 + parent: "examinationPaper",
  778 + hidden: true,
  779 + children: []
  780 + },
719 781 ]
720 782 },
721 783 {
... ... @@ -744,6 +806,15 @@ const addroutersPersonal = [
744 806 component: PersonalAskAnalysis,
745 807 parent: "ask",
746 808 children: []
  809 + },
  810 + {
  811 + path: "/askArchiving",
  812 + iconCls: "", // 图标样式class
  813 + name: "随堂已归档问报表分析",
  814 + component: PersonalArchiving,
  815 + parent: "ask",
  816 + hidden:true,
  817 + children: []
747 818 }
748 819 ]
749 820 },
... ... @@ -771,6 +842,15 @@ const addroutersPersonal = [
771 842 component: PersonalTestAnalysis,
772 843 parent: "test",
773 844 children: []
  845 + },
  846 + {
  847 + path: "/testArchiving",
  848 + iconCls: "", // 图标样式class
  849 + name: "即时已归档测报表分析",
  850 + component: PersonalTestArchiving,
  851 + parent: "test",
  852 + hidden:true,
  853 + children: []
774 854 }
775 855  
776 856 ]
... ... @@ -901,4 +981,4 @@ const addRoutersAdmin = [
901 981 export default new Router({
902 982 routes: defaultRouter
903 983 })
904   -export { defaultRouter, addrouters,addroutersPersonal,addRoutersAdmin ,csAddrouters}
  984 +export { defaultRouter, addrouters, addroutersPersonal, addRoutersAdmin, csAddrouters }
... ...
src/router/permission.js
... ... @@ -9,6 +9,9 @@ router.beforeEach((to, from, next) => {
9 9 next();
10 10 } else {
11 11 if (store.getters.token) {
  12 + if (to.path == '/device' && from.path == '/deviceLog') {
  13 + to.query.back = true
  14 + }
12 15 next();
13 16 } else {
14 17 if (store.getters.info && store.getters.addRouters) {
... ... @@ -17,7 +20,6 @@ router.beforeEach((to, from, next) => {
17 20 let authorityRouterObj = userInfo.permissions.filter((item) => {
18 21 return item.roleName == userInfo.showRoleName;
19 22 });
20   - console.log([...authorityRouterObj[0]?.authorityRouter])
21 23 store.commit("setRouters", [...authorityRouterObj[0]?.authorityRouter]);
22 24 store.commit("setInfo", { ...userInfo });
23 25 store.getters.addRouters.forEach((res) => {
... ...
src/utils/index.js
... ... @@ -453,7 +453,6 @@ export function checkAnswer(
453 453 s = filtterChar(s, questionType == 3 && questionCount > 1, optionCount);
454 454 if (questionType == 2) {
455 455 //单选
456   - console.log(s.length + " " + questionCount);
457 456 if (s.length > questionCount) {
458 457 s = s.substring(0, questionCount);
459 458 }
... ... @@ -679,7 +678,6 @@ export function formatClass(data) {
679 678 }
680 679 }
681 680 });
682   - console.log(sectionNameArr);
683 681 return sectionNameArr;
684 682 }
685 683 export function formatGradeClass(data) {
... ... @@ -748,44 +746,52 @@ export function formatGradeNameClass(data) {
748 746 return gradeNameArr;
749 747 }
750 748  
751   -export function tablePrint(id) {
  749 +export function tablePrint(id, title) {
752 750 let divs = document.getElementById(id);
753 751 let awin = window.open("", "_blank");
754 752 awin.document.getElementsByTagName(
755 753 "head"
756 754 )[0].innerHTML = `<style> @media print {@page {size:A4 landscape;margin:10mm}
757 755 body{margin:5mm;font-size:8px;}}
  756 + body{-webkit-print-color-adjust: exact;}
  757 + .tit{text-align:center;font-size:20px;color:#333;line-height:24px;font-weight:700;padding:10px 0;margin:0;}
758 758 .table-box,.el-table,.el-table__body-wrapper,.el-table--border{max-height:99999999px!important;height:auto;width:auto!important}
759 759 .el-table{width:100%}
760 760 .el-table,.el-table__body-wrapper{max-height:auto}
761 761 .el-table .el-table__cell{padding:12px 0}
762   - .el-table thead tr:first-child th.el-table__cell{border-top: 1px solid #EBEEF5;}
763   - .el-table thead tr:first-child th.el-table__cell:first-child{border-left: 1px solid #EBEEF5;}
764   - .el-table tbody tr td.el-table__cell:first-child{border-left: 1px solid #EBEEF5;}
765   - .el-table td.el-table__cell{border-bottom: 1px solid #EBEEF5;}
766   - .el-table--border .el-table__cell{border-right: 1px solid #EBEEF5;}
767   - .el-table--border th.el-table__cell, .el-table__fixed-right-patch{border-bottom: 1px solid #EBEEF5;}
  762 + .el-table thead tr:first-child th.el-table__cell{border-top: 1px solid #ccc;background:#ccc}
  763 + .el-table thead tr:first-child th.el-table__cell:first-child{border-left: 1px solid #ccc;}
  764 + .el-table tbody tr td.el-table__cell:first-child{border-left: 1px solid #ccc;}
  765 + .el-table td.el-table__cell{border-bottom: 1px solid #ccc;}
  766 + .el-table--border .el-table__cell{border-right: 1px solid #ccc;}
  767 + .el-table--border th.el-table__cell, .el-table__fixed-right-patch{border-bottom: 1px solid #ccc;}
768 768 .el-table .el-table__cell.gutter{border:none!important;}
769 769 .el-table__fixed{display:none!important}
770 770 .el-table .el-table__cell.is-center{text-align:center!important}
771 771 .el-table .el-table__cell.is-hidden>*{visibility: inherit;}
772 772 ul,li{margin:0;padding:0;list-style:none}
773 773 .hui-box{display: flex;text-align: center;}
774   - .hui-box .s-txt{width: 60px;line-height: 144px;background: #e2e2e2;font-size: 16px;color: #fff;font-weight: 700;border:1px solid #e2e2e2;box-sizing:border-box}
775   - .hui-ul{border-top: 1px solid #e2e2e2;}
  774 + .hui-box .s-txt{width: 60px;line-height: 144px;background: #ccc;font-size: 16px;color: #fff;font-weight: 700;border:1px solid #ccc;box-sizing:border-box}
  775 + .hui-ul{border-top: 1px solid #ccc;}
776 776 .hui-li{display: flex;}
777   - .hui-s{height: 48px;line-height: 48px;border-right: 1px solid #e2e2e2;border-bottom: 1px solid #e2e2e2;box-sizing: border-box;}
  777 + .hui-s{height: 48px;line-height: 48px;border-right: 1px solid #ccc;border-bottom: 1px solid #ccc;box-sizing: border-box;}
778 778 .hui-s.s1{width: 100px;}
779 779 .hui-s.s2{ width: 110px;}
780 780 .hui-s.s3{width: 120px;}
781   - .info { display: flex;flex-wrap: wrap;border-left: 1px solid #e2e2e2;border-top: 1px solid #e2e2e2;margin-bottom: 12px;}
782   - .info-item {width: 25%;height: 50px;box-sizing: border-box;flex-shrink: 0;background: #f8f8f8;border-right: 1px solid #e2e2e2;border-bottom: 1px solid #e2e2e2;line-height: 50px;text-align: center;}
  781 + .info { display: flex;flex-wrap: wrap;border-left: 1px solid #ccc;border-top: 1px solid #ccc;margin-bottom: 12px;}
  782 + .info-item {width: 25%;height: 50px;box-sizing: border-box;flex-shrink: 0;background: #f8f8f8;border-right: 1px solid #ccc;border-bottom: 1px solid #ccc;line-height: 50px;text-align: center;}
783 783 </style>`;
784 784 let aDom = divs.cloneNode(true);
785 785 let aTbody = aDom
786 786 .getElementsByClassName("el-table__body")[0]
787 787 .getElementsByTagName("tbody")[0];
788 788 aDom.getElementsByClassName("el-table__header")[0].append(aTbody);
  789 + if (title) {
  790 + let pTit = awin.document.createElement('p')
  791 + pTit.className = "tit"
  792 + pTit.innerHTML = title
  793 + awin.document.body.append(pTit)
  794 + }
789 795 awin.document.body.append(aDom);
790 796 awin.print();
791 797 awin.close()
... ...
src/views/admin/account/index.vue
... ... @@ -178,16 +178,6 @@
178 178 </el-input>
179 179 </el-col>
180 180 </el-form-item>
181   - <!-- <el-form-item label="密码:" prop="password">
182   - <el-col :span="12">
183   - <el-input
184   - placeholder="请输入密码"
185   - v-model.trim="formCount.password"
186   - maxlength="18"
187   - >
188   - </el-input>
189   - </el-col>
190   - </el-form-item> -->
191 181 <el-form-item label="联系人姓名:" prop="contactPerson">
192 182 <el-col :span="12">
193 183 <el-input
... ... @@ -219,6 +209,13 @@
219 209 </el-input>
220 210 </el-col>
221 211 </el-form-item>
  212 + <el-form-item label="使用模式:" v-if="formCount.versionType == 1">
  213 + <el-radio-group v-model="formCount.usageMode">
  214 + <el-radio :label="0">班级专用</el-radio>
  215 + <el-radio :label="1">多班复用</el-radio>
  216 + <el-radio :label="2">用户配置 </el-radio>
  217 + </el-radio-group>
  218 + </el-form-item>
222 219 </el-form>
223 220 <div class="dialog-footer" slot="footer">
224 221 <el-button @click="saveCount">确 定</el-button>
... ... @@ -327,6 +324,8 @@ export default {
327 324 tenantName: "",
328 325 contactPerson: "",
329 326 contactPhone: "",
  327 + versionType:"",
  328 + usageMode:""
330 329 },
331 330 ruleCount: {
332 331 loginName: [{ required: true, message: "请输入账号", trigger: "blur" }],
... ... @@ -374,7 +373,7 @@ export default {
374 373 this.formAddCount.usageMode = "";
375 374 this.diaAdd = true;
376 375 },
377   - versionTypeChange(){
  376 + versionTypeChange() {
378 377 this.formAddCount.usageMode = "";
379 378 },
380 379 saveAddCount() {
... ... @@ -405,10 +404,11 @@ export default {
405 404 this.formCount.tenantName = obj.tenantName;
406 405 this.formCount.contactPerson = obj.realName;
407 406 this.formCount.contactPhone = obj.phone;
  407 + this.formCount.versionType = obj.versionType;
  408 + this.formCount.usageMode = obj.usageMode;
408 409 this.diaCount = true;
409 410 },
410 411 handleDropdownClick(value, item) {
411   - console.log(item);
412 412 //更多
413 413 if (value == 2) {
414 414 this.$confirm("确定要删除这条账号信息吗?", "提示", {
... ... @@ -452,7 +452,6 @@ export default {
452 452 },
453 453 async updateUser(obj, type) {
454 454 let query = {};
455   - console.log(query);
456 455 if (type == 1) {
457 456 query.available = obj.available == 0 ? 1 : 0;
458 457 }
... ...
src/views/examinationPaper/archiving.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <back-box>
  4 + <template slot="title">
  5 + <span>已归档答题卡</span>
  6 + </template>
  7 + </back-box>
  8 + <div class="answer-header">
  9 + <div class="sel-box">
  10 + <el-select
  11 + class="sel"
  12 + v-model="query.classId"
  13 + placeholder="选择班级"
  14 + @change="changClazz"
  15 + >
  16 + <el-option
  17 + v-for="item in classList"
  18 + :key="item.value"
  19 + :label="item.label"
  20 + :value="item.value"
  21 + >
  22 + </el-option>
  23 + </el-select>
  24 + <el-select
  25 + class="sel"
  26 + v-model="query.subjectName"
  27 + placeholder="选择科目"
  28 + @change="_QueryData()"
  29 + >
  30 + <el-option
  31 + v-for="item in subjectList"
  32 + :key="item.value"
  33 + :label="item.label"
  34 + :value="item.value"
  35 + >
  36 + </el-option>
  37 + </el-select>
  38 + <el-select
  39 + class="sel"
  40 + v-model="query.tagId"
  41 + placeholder="选择类型"
  42 + @change="_QueryData()"
  43 + >
  44 + <el-option
  45 + v-for="item in typeList"
  46 + :key="item.label"
  47 + :label="item.label"
  48 + :value="item.value"
  49 + >{{ item.label }}
  50 + </el-option>
  51 + </el-select>
  52 + <el-input
  53 + placeholder="试卷名称"
  54 + v-model="query.title"
  55 + class="input-with-select"
  56 + @keyup.enter.native="_QueryData(true)"
  57 + >
  58 + <el-button
  59 + slot="append"
  60 + icon="el-icon-search"
  61 + @click="_QueryData(true)"
  62 + ></el-button>
  63 + </el-input>
  64 + </div>
  65 + </div>
  66 + <ul class="content" v-if="tableData && tableData.length">
  67 + <li class="item" v-for="item in tableData" :key="item.id">
  68 + <div class="pic-box">
  69 + <p class="i-box"><i class="fa fa-map-o"></i></p>
  70 + <p class="ids">{{ item.id }}</p>
  71 + </div>
  72 + <div class="info">
  73 + <p class="title">
  74 + {{ item.title }}
  75 + <span class="label" v-if="!!item.tag">{{ item.tag }}</span>
  76 + </p>
  77 + <p class="num">
  78 + 总题数:{{ item.questionNum }}
  79 + <em class="s-line">|</em>
  80 + 预计时长:{{ item.examsDuration }}
  81 + </p>
  82 + <p class="person">
  83 + {{ item.realName }}<em class="s-line">|</em
  84 + ><span class="date">{{ item.modifiedTime }}</span>
  85 + </p>
  86 + </div>
  87 + <div class="btn-box">
  88 + <el-tooltip effect="dark" content="复制" placement="bottom">
  89 + <el-button
  90 + class="edit"
  91 + type="info"
  92 + size="mini"
  93 + circle
  94 + icon="fa fa-archive-copy"
  95 + @click="toAdd(item)"
  96 + ></el-button>
  97 + </el-tooltip>
  98 + </div>
  99 + </li>
  100 + </ul>
  101 + <div class="pagination-box">
  102 + <el-pagination
  103 + small=""
  104 + layout="total,prev, pager, next"
  105 + :hide-on-single-page="true"
  106 + :total="total"
  107 + @current-change="changePage"
  108 + :current-page="page"
  109 + :page-size="size"
  110 + >
  111 + </el-pagination>
  112 + </div>
  113 + <el-empty
  114 + v-if="!loading && tableData.length == 0"
  115 + content="没有更多数据"
  116 + :image-size="100"
  117 + ></el-empty>
  118 + </div>
  119 +</template>
  120 +
  121 +<script>
  122 +export default {
  123 + name: "examinationPaperArchiving",
  124 + data() {
  125 + return {
  126 + code: "",
  127 + role: "",
  128 + loading: false,
  129 + query: {
  130 + classId: "",
  131 + subjectName: "",
  132 + tagId: "",
  133 + title: "",
  134 + },
  135 + classList: [],
  136 + subjectList: [],
  137 + typeList: [],
  138 + tableData: null,
  139 + total: 0,
  140 + page: 1,
  141 + size: 20,
  142 + };
  143 + },
  144 + async created() {
  145 + this.code = localStorage.getItem("csCode") || "";
  146 + this.role =
  147 + this.$store.getters.info.showRole ||
  148 + this.$store.getters.info.permissions[0].role;
  149 + await this._QueryClassList();
  150 + if (!this.query.classId) {
  151 + return;
  152 + }
  153 + await this._QuerySubjectList();
  154 + this._QueryData();
  155 + this._QueryTypeList();
  156 + },
  157 + methods: {
  158 + toAdd(item) {
  159 + this.$router.push({
  160 + path: "/examinationPaperAdd",
  161 + query: {
  162 + type: 2,
  163 + paperId: item.id,
  164 + },
  165 + });
  166 + },
  167 + changePage(page) {
  168 + this.page = page;
  169 + this._QueryData(this.query.title);
  170 + },
  171 + //切换班级
  172 + async changClazz() {
  173 + await this._QuerySubjectList();
  174 + this._QueryData(false);
  175 + },
  176 + // 查找答题卡类型
  177 + async _QueryTypeList() {
  178 + if (!this.query.classId) return;
  179 + let fetchTypeNames =
  180 + this.role == "ROLE_PERSONAL"
  181 + ? this.$request.pPaperTagList
  182 + : this.$request.fetchTypeNames;
  183 +
  184 + const { data, status, info } = await fetchTypeNames({
  185 + classId: this.query.classId,
  186 + type: 0,
  187 + });
  188 + if (status === 0) {
  189 + this.typeList =
  190 + data.list.map((item) => {
  191 + return {
  192 + value: item.tagId,
  193 + label: item.tag,
  194 + };
  195 + }) || [];
  196 + this.typeList.unshift({
  197 + value: "",
  198 + label: "请选择标签",
  199 + });
  200 + } else {
  201 + this.$message.error(info);
  202 + }
  203 + },
  204 + // 查找班级
  205 + async _QueryClassList() {
  206 + this.loading = true;
  207 + let fetchClassList =
  208 + this.role == "ROLE_PERSONAL"
  209 + ? this.$request.pClassList
  210 + : this.$request.fetchClassList;
  211 +
  212 + const { data, status, info } = await fetchClassList({ status: 1 });
  213 + if (status === 0) {
  214 + if (!!data.list) {
  215 + this.classList =
  216 + data.list?.map((item) => {
  217 + return {
  218 + value: this.role == "ROLE_PERSONAL" ? item.id : item.classId,
  219 + label: item.className,
  220 + };
  221 + }) || [];
  222 + this.query.classId = this.classList[0]?.value;
  223 + }
  224 + } else {
  225 + this.$message.error(info);
  226 + }
  227 + },
  228 + // 查找科目
  229 + async _QuerySubjectList() {
  230 + if (!this.query.classId) return;
  231 + let fetchSubjectList =
  232 + this.role == "ROLE_PERSONAL"
  233 + ? this.$request.pSubjectList
  234 + : this.$request.fetchSubjectList;
  235 +
  236 + const { data, status, info } = await fetchSubjectList({
  237 + classId: this.query.classId,
  238 + status: 1,
  239 + });
  240 + if (status === 0) {
  241 + this.subjectList =
  242 + data.subjectNames?.map((item) => {
  243 + return {
  244 + value: item,
  245 + label: item,
  246 + };
  247 + }) || [];
  248 + this.query.subjectName = this.subjectList[0]?.value;
  249 + } else {
  250 + this.$message.error(info);
  251 + }
  252 + },
  253 + async _QueryData(type) {
  254 + if (!this.query.classId) return;
  255 + this.loading = true;
  256 + //获取答题卡列表
  257 + let query = {};
  258 + if (!type) {
  259 + this.query.title = "";
  260 + query = { ...this.query };
  261 + } else {
  262 + query = { title: this.query.title };
  263 + this.query.tagId = "";
  264 + // this.query.subjectName = "";
  265 + }
  266 + query.classId = this.query.classId;
  267 + query.subjectName = this.query.subjectName;
  268 + for (let key in query) {
  269 + if (!query[key]) {
  270 + query[key] = null;
  271 + }
  272 + }
  273 + if (!query.classId) {
  274 + this.total = 0;
  275 + this.tableData = [];
  276 + this.loading = false;
  277 + return;
  278 + }
  279 + this.loading = true;
  280 + let fetchPaperList =
  281 + this.role == "ROLE_PERSONAL"
  282 + ? this.$request.pPaperList
  283 + : this.$request.fetchPaperList;
  284 +
  285 + const { data, status, info } = await fetchPaperList({
  286 + ...query,
  287 + status: 1,
  288 + page: this.page,
  289 + size: this.size,
  290 + status: 3,
  291 + });
  292 + this.loading = false;
  293 + if (status === 0) {
  294 + this.total = data.total;
  295 + this.tableData = (data.list && [...data.list]) || [];
  296 + } else {
  297 + this.$message.error(info);
  298 + }
  299 + },
  300 + },
  301 +};
  302 +</script>
  303 +
  304 +<style scoped lang="scss">
  305 +.content {
  306 + margin: 0 20px;
  307 + background: #f8f8f8;
  308 + padding: 12px;
  309 + border-radius: 20px;
  310 + .item {
  311 + display: flex;
  312 + align-items: center;
  313 + width: 100%;
  314 + overflow: hidden;
  315 + box-sizing: border-box;
  316 + padding: 12px;
  317 + border-radius: 20px;
  318 + background: #fff;
  319 + margin-bottom: 12px;
  320 + &:last-of-type {
  321 + margin-bottom: 0;
  322 + }
  323 + .pic-box {
  324 + width: 80px;
  325 + height: 80px;
  326 + border-radius: 10px;
  327 + margin-right: 10px;
  328 + flex-shrink: 0;
  329 + background: #d7d7d7;
  330 + text-align: center;
  331 + color: #fff;
  332 + font-weight: 500;
  333 + .i-box {
  334 + padding-top: 10px;
  335 + font-size: 32px;
  336 + margin-bottom: 3px;
  337 + }
  338 + }
  339 + .info {
  340 + min-height: 80px;
  341 + flex: 1;
  342 + overflow: hidden;
  343 + display: flex;
  344 + flex-direction: column;
  345 + justify-content: space-between;
  346 + .s-line {
  347 + padding: 0 5px;
  348 + color: #e2e2e2;
  349 + }
  350 + .title {
  351 + font-size: 16px;
  352 + color: #222;
  353 + font-weight: 500;
  354 + .label {
  355 + display: inline-block;
  356 + font-size: 12px;
  357 + color: #2e9afe;
  358 + line-height: 16px;
  359 + padding: 0 10px;
  360 + border: 1px solid #2e9afe;
  361 + border-radius: 10px;
  362 + transform: translateY(-2px);
  363 + }
  364 + }
  365 + .person {
  366 + color: #666;
  367 + }
  368 + }
  369 + .clazz {
  370 + font-size: 14px;
  371 + font-weight: 500;
  372 + position: relative;
  373 + position: relative;
  374 + &.active {
  375 + color: #667ffd;
  376 + }
  377 + .el-icon-success {
  378 + position: absolute;
  379 + right: 0;
  380 + top: -5px;
  381 + color: #667ffd;
  382 + }
  383 + &:last-of-type {
  384 + .el-icon-success {
  385 + right: -18px;
  386 + }
  387 + }
  388 + }
  389 + .btn-box {
  390 + flex-shrink: 0;
  391 + .edit {
  392 + margin-right: 12px;
  393 + }
  394 + }
  395 + }
  396 +}
  397 +.answer-header {
  398 + .sel-box {
  399 + .sel {
  400 + min-width: 160px;
  401 + }
  402 + :deep(.el-cascader__tags) {
  403 + flex-wrap: nowrap;
  404 + }
  405 + }
  406 +}
  407 +</style>
0 408 \ No newline at end of file
... ...
src/views/examinationPaper/edit.vue
... ... @@ -551,7 +551,6 @@ export default {
551 551 this.dialogStem = true;
552 552 },
553 553 openTag(obj, type, index, indexs) {
554   - console.log(obj);
555 554 //难度,知识点
556 555 this.stem = { ...this.stem, obj };
557 556 this.stem.type = type;
... ... @@ -1073,7 +1072,6 @@ export default {
1073 1072 }
1074 1073 }
1075 1074 }
1076   - console.log(this.questionList);
1077 1075 } else {
1078 1076 this.$message.error(info);
1079 1077 }
... ... @@ -1095,7 +1093,7 @@ export default {
1095 1093 position: fixed;
1096 1094 right: 40px;
1097 1095 bottom: 20px;
1098   - padding: 10px 0 20px;
  1096 + padding: 10px 0 5px;
1099 1097 background: #fff;
1100 1098 text-align: right;
1101 1099 margin-left: 140px;
... ...
src/views/examinationPaper/index.vue
... ... @@ -5,6 +5,21 @@
5 5 <span>备题组卷</span>
6 6 </template>
7 7 <template slot="btns">
  8 + <el-tooltip
  9 + v-if="!code"
  10 + effect="dark"
  11 + content="已归档试卷"
  12 + placement="bottom"
  13 + >
  14 + <el-button
  15 + type="primary"
  16 + icon="fa fa-archive"
  17 + size="mini"
  18 + plain
  19 + circle
  20 + @click="toArchiving"
  21 + ></el-button>
  22 + </el-tooltip>
8 23 <el-button
9 24 type="primary"
10 25 size="mini"
... ... @@ -199,6 +214,7 @@ export default {
199 214 name: "examinationPaper",
200 215 data() {
201 216 return {
  217 + code: "",
202 218 loading: false,
203 219 userName: "",
204 220 dialogVisible: false,
... ... @@ -228,11 +244,15 @@ export default {
228 244 };
229 245 },
230 246 async created() {
  247 + this.code = localStorage.getItem("csCode") || "";
231 248 this.role =
232 249 this.$store.getters.info.showRole ||
233 250 this.$store.getters.info.permissions[0].role;
234 251 this.userName = this.$store.getters.info.name || "";
235 252 await this._QueryClassList();
  253 + if (!this.query.classId) {
  254 + return;
  255 + }
236 256 await this._QuerySubjectList();
237 257 this._QueryData();
238 258 this._QueryTypeList();
... ... @@ -243,6 +263,11 @@ export default {
243 263 window.location.reload();
244 264 }, 500);
245 265 },
  266 + toArchiving() {
  267 + this.$router.push({
  268 + path: "/examinationPaperArchiving",
  269 + });
  270 + },
246 271 toAdd(query) {
247 272 let routerItem = {
248 273 path: "/examinationPaperAdd",
... ... @@ -358,7 +383,6 @@ export default {
358 383 : this.$request.fetchClassList;
359 384  
360 385 const { data, status, info } = await fetchClassList();
361   - console.log(status);
362 386 if (status === 0) {
363 387 if (!!data.list) {
364 388 this.classList =
... ...
src/views/examinationPaper/recycle.vue
... ... @@ -292,7 +292,6 @@ export default {
292 292 ? this.$request.pClassList
293 293 : this.$request.fetchClassList;
294 294 const { data, status, info } = await fetchClassList();
295   - console.log(status);
296 295 if (status === 0) {
297 296 if (!!data.list) {
298 297 this.classList =
... ...
src/views/personal/ask/analysis.vue
... ... @@ -9,27 +9,11 @@
9 9 <div class="tab-box">
10 10 <span
11 11 class="tab-item"
12   - :class="type == 1 ? 'active' : ''"
13   - @click="setType(1)"
14   - >答题表现</span
15   - >
16   - <span
17   - class="tab-item"
18   - :class="type == 2 ? 'active' : ''"
19   - @click="setType(2)"
20   - >学生问答表现</span
21   - >
22   - <span
23   - class="tab-item"
24   - :class="type == 3 ? 'active' : ''"
25   - @click="setType(3)"
26   - >学生互动表现</span
27   - >
28   - <span
29   - class="tab-item"
30   - :class="type == 4 ? 'active' : ''"
31   - @click="setType(4)"
32   - >签到明细</span
  12 + v-for="(item, index) in tabList"
  13 + :key="index"
  14 + :class="type == index + 1 ? 'active' : ''"
  15 + @click="setType(index + 1)"
  16 + >{{ item }}</span
33 17 >
34 18 </div>
35 19 <div v-loading="loading">
... ... @@ -366,23 +350,29 @@ export default {
366 350 id: "",
367 351 questionList: [],
368 352 },
  353 + tabList: ["答题表现", "学生问答表现", "学生互动表现", "签到明细"],
369 354 detail: {},
370 355 tableData: [],
371 356 optionsList: [],
372 357 page: 1,
373 358 size: 20,
374 359 total: 0,
  360 + status: 0,
375 361 };
376 362 },
377 363 created() {
378 364 this.id = this.$route.query.id;
  365 + this.status = this.$route.query.status ? this.$route.query.status : 0;
379 366 this.title = this.$route.query.title;
380 367 this._QueryData();
381 368 this.periodDetail();
382 369 },
383 370 methods: {
384 371 print() {
385   - tablePrint("print-content");
  372 + tablePrint(
  373 + "print-content",
  374 + this.detail.title + "_" + this.tabList[this.type - 1]
  375 + );
386 376 },
387 377 setType(type) {
388 378 this.type = type;
... ... @@ -524,7 +514,7 @@ export default {
524 514 let blob = new Blob([data], {
525 515 type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
526 516 });
527   - downloadFile("随堂问-单课时报表.xlsx", blob);
  517 + downloadFile(this.status?"随堂问-已归档单课时报表.xlsx":"随堂问-单课时报表.xlsx", blob);
528 518 } else {
529 519 this.$message.error("下载失败");
530 520 }
... ...
src/views/personal/ask/archiving.vue 0 → 100644
  1 +<template>
  2 + <div class="main" ref="main">
  3 + <back-box>
  4 + <template slot="title">
  5 + <span>问答-已归档数据报表</span>
  6 + </template>
  7 + </back-box>
  8 + <div class="answer-header">
  9 + <div class="sel-box">
  10 + <el-select
  11 + class="sel"
  12 + v-model="query.classId"
  13 + placeholder="选择班级"
  14 + @change="changeclass"
  15 + >
  16 + <el-option
  17 + v-for="item in classList"
  18 + :key="item.value"
  19 + :label="item.label"
  20 + :value="item.value"
  21 + >
  22 + </el-option>
  23 + </el-select>
  24 + <el-select
  25 + class="sel"
  26 + multiple
  27 + collapse-tags
  28 + v-model="query.subjectNames"
  29 + placeholder="选择科目"
  30 + @change="changeSub"
  31 + >
  32 + <el-option
  33 + v-for="item in subjectList"
  34 + :key="item.value"
  35 + :label="item.label"
  36 + :value="item.value"
  37 + >
  38 + </el-option>
  39 + </el-select>
  40 + <div class="d1">
  41 + <el-date-picker
  42 + v-model="query.startDay"
  43 + type="date"
  44 + @change="handleChangeTimeStart"
  45 + placeholder="选择日期时间"
  46 + value-format="yyyy-MM-dd"
  47 + >
  48 + </el-date-picker>
  49 + ~
  50 + <el-date-picker
  51 + v-model="query.endDay"
  52 + type="date"
  53 + placeholder="选择日期时间"
  54 + @change="handleChangeTimeEnd"
  55 + value-format="yyyy-MM-dd"
  56 + >
  57 + </el-date-picker>
  58 + </div>
  59 + <p class="p1">
  60 + <span @click="setDate(1)" :class="[date == 1 ? 'active' : '', 's1']"
  61 + >今天</span
  62 + >
  63 + <span @click="setDate(2)" :class="[date == 2 ? 'active' : '', 's1']"
  64 + >本周</span
  65 + >
  66 + <span @click="setDate(3)" :class="[date == 3 ? 'active' : '', 's1']"
  67 + >本月</span
  68 + >
  69 + <span @click="setDate(4)" :class="[date == 4 ? 'active' : '', 's1']"
  70 + >本季度</span
  71 + >
  72 + </p>
  73 + <el-button type="primary" round @click="_QueryData()">筛选</el-button>
  74 + </div>
  75 + </div>
  76 + <div class="table-box">
  77 + <el-radio-group
  78 + v-model="tabIndex"
  79 + @change="tabChange"
  80 + style="margin-bottom: 20px"
  81 + >
  82 + <template v-for="(item, index) in tabList">
  83 + <el-radio-button
  84 + v-if="index == 0 || query.startDay != query.endDay"
  85 + :key="index"
  86 + :label="index + 1"
  87 + >{{ item }}</el-radio-button
  88 + >
  89 + </template>
  90 + </el-radio-group>
  91 + <div class="table-cont" v-loading="loading">
  92 + <div id="print-content">
  93 + <div v-show="tabIndex == 1">
  94 + <el-table
  95 + :data="tableData"
  96 + border
  97 + style="width: 100%"
  98 + @sort-change="sortChange"
  99 + >
  100 + <el-table-column
  101 + prop="title"
  102 + label="课时"
  103 + align="center"
  104 + ></el-table-column>
  105 + <el-table-column
  106 + prop="questionNum"
  107 + label="题目总数"
  108 + align="center"
  109 + width="100"
  110 + ></el-table-column>
  111 + <el-table-column
  112 + prop="startTime"
  113 + label="上课时间"
  114 + align="center"
  115 + ></el-table-column>
  116 + <el-table-column
  117 + prop="participationRate"
  118 + label="参与度"
  119 + sortable="custom"
  120 + align="center"
  121 + >
  122 + <template slot-scope="scoped"
  123 + >{{ scoped.row.participationRate }}%</template
  124 + ></el-table-column
  125 + >
  126 + <el-table-column
  127 + prop="answerCorrectRate"
  128 + label="已答总正确率"
  129 + sortable="custom"
  130 + align="center"
  131 + >
  132 + <template slot-scope="scoped"
  133 + >{{ scoped.row.answerCorrectRate }}%</template
  134 + >
  135 + </el-table-column>
  136 + <el-table-column
  137 + prop="classCorrectRate"
  138 + label="班级总正确率"
  139 + sortable="custom"
  140 + align="center"
  141 + ><template slot-scope="scoped"
  142 + >{{ scoped.row.classCorrectRate }}%</template
  143 + ></el-table-column
  144 + >
  145 + <el-table-column label="操作" align="center">
  146 + <template slot-scope="scoped">
  147 + <el-tooltip effect="dark" content="详情" placement="top">
  148 + <el-button
  149 + type="primary"
  150 + circle
  151 + size="mini"
  152 + icon="fa fa-arrow-right"
  153 + @click="linkTo(scoped.row)"
  154 + ></el-button>
  155 + </el-tooltip>
  156 + </template>
  157 + </el-table-column>
  158 + </el-table>
  159 + </div>
  160 + <div v-show="tabIndex == 2">
  161 + <el-table
  162 + id="print-content2"
  163 + :max-height="tableMaxHeight"
  164 + :data="tableData"
  165 + border
  166 + style="width: 100%"
  167 + >
  168 + <el-table-column
  169 + prop="studentCode"
  170 + label="学号"
  171 + align="center"
  172 + fixed
  173 + ></el-table-column>
  174 + <el-table-column
  175 + prop="studentName"
  176 + label="姓名"
  177 + align="center"
  178 + fixed
  179 + width="100"
  180 + ></el-table-column>
  181 + <el-table-column
  182 + v-for="(item, index) in phaseOption"
  183 + :key="index"
  184 + :label="item"
  185 + align="center"
  186 + >
  187 + <el-table-column
  188 + align="center"
  189 + :label="index == 0 ? '总课时数' : '课时数'"
  190 + :prop="'periodCount' + item"
  191 + >
  192 + </el-table-column>
  193 + <el-table-column
  194 + align="center"
  195 + :label="index == 0 ? '总出题数' : '出题数'"
  196 + :prop="'questionNum' + item"
  197 + >
  198 + </el-table-column>
  199 + <el-table-column
  200 + align="center"
  201 + :label="index == 0 ? '总参与度' : '参与度'"
  202 + :prop="'participationRate' + item"
  203 + ><template slot-scope="scoped"
  204 + >{{ scoped.row["participationRate" + item] }}%</template
  205 + >
  206 + </el-table-column>
  207 + <el-table-column
  208 + align="center"
  209 + :label="index == 0 ? '总正确率' : '正确率'"
  210 + :prop="'correctRate' + item"
  211 + ><template slot-scope="scoped"
  212 + >{{ scoped.row["correctRate" + item] }}%</template
  213 + >
  214 + </el-table-column>
  215 + </el-table-column>
  216 + </el-table>
  217 + </div>
  218 + <div v-show="tabIndex == 3">
  219 + <el-table
  220 + id="print-content3"
  221 + :max-height="tableMaxHeight"
  222 + :data="tableData"
  223 + border
  224 + style="width: 100%"
  225 + >
  226 + <el-table-column
  227 + prop="studentCode"
  228 + label="学号"
  229 + align="center"
  230 + ></el-table-column>
  231 + <el-table-column
  232 + prop="studentName"
  233 + label="姓名"
  234 + align="center"
  235 + width="100"
  236 + ></el-table-column>
  237 + <el-table-column
  238 + v-for="(item, index) in phaseInter"
  239 + :key="index"
  240 + :label="item"
  241 + align="center"
  242 + >
  243 + <el-table-column
  244 + align="center"
  245 + v-if="index == 0"
  246 + label="参与分"
  247 + sortable
  248 + :prop="'interactionsNum' + item"
  249 + >
  250 + </el-table-column>
  251 + <el-table-column
  252 + v-else
  253 + align="center"
  254 + label="互动数"
  255 + :prop="'interactionsNum' + item"
  256 + >
  257 + </el-table-column>
  258 + <el-table-column
  259 + v-if="index == 0"
  260 + align="center"
  261 + label="对错分"
  262 + sortable
  263 + :prop="'interactionsCorrectNum' + item"
  264 + >
  265 + </el-table-column>
  266 + <el-table-column
  267 + v-else
  268 + align="center"
  269 + label="参与数"
  270 + :prop="'interactionsCorrectNum' + item"
  271 + >
  272 + </el-table-column>
  273 + </el-table-column>
  274 + </el-table>
  275 + </div>
  276 + </div>
  277 + <div class="pagination-box" v-show="tabIndex == 1">
  278 + <el-pagination
  279 + small=""
  280 + layout="total,prev, pager, next"
  281 + :hide-on-single-page="true"
  282 + :total="total"
  283 + @current-change="changePage"
  284 + :current-page="page"
  285 + :page-size="size"
  286 + >
  287 + </el-pagination>
  288 + </div>
  289 + <p
  290 + class="down"
  291 + v-if="(tabIndex == 3 || tabIndex == 2) && tableData.length"
  292 + >
  293 + <el-button
  294 + @click="exportData"
  295 + type="primary"
  296 + plain
  297 + round
  298 + icon="fa fa-cloud-download"
  299 + >导出报表</el-button
  300 + >
  301 + <el-button
  302 + @click="print"
  303 + type="primary"
  304 + plain
  305 + round
  306 + icon="el-icon-printer"
  307 + >打印</el-button
  308 + >
  309 + </p>
  310 + </div>
  311 + </div>
  312 + </div>
  313 +</template>
  314 +
  315 +<script>
  316 +import { formatDate, tablePrint, downloadFile } from "utils";
  317 +import BusEvent from "@/utils/busEvent";
  318 +export default {
  319 + data() {
  320 + return {
  321 + tableMaxHeight: 300,
  322 + loading: false,
  323 + form: { questionList: [] },
  324 + date: "", //今天-昨天-本周
  325 + query: {
  326 + //搜索条件
  327 + classId: "",
  328 + subjectNames: [],
  329 + startDay: "",
  330 + endDay: "",
  331 + day: "",
  332 + },
  333 + tabList: ["单课时报表", "阶段问答报表", "阶段互动报表"],
  334 + custom: {
  335 + //单课时排序
  336 + orderField: null,
  337 + orderType: null,
  338 + },
  339 + classList: [], //班级
  340 + subjectList: [], //科目
  341 + tabIndex: 1, //选项卡
  342 + tableData: [],
  343 + phaseOption: [], //问答补充数据
  344 + phaseInter: [], //互动补充数据
  345 + page: 1,
  346 + size: 20,
  347 + total: 0,
  348 + };
  349 + },
  350 + async created() {
  351 + await this._QueryClassList();
  352 + if (!this.query.classId) {
  353 + return;
  354 + }
  355 + await this._QuerySubjectList();
  356 + await this.setDate(1);
  357 + let startDay = this.query?.startDay;
  358 + if (!startDay) {
  359 + this.query.startDay = new Date();
  360 + this.query.endDay = new Date();
  361 + }
  362 + },
  363 + activated() {
  364 + const that = this;
  365 + BusEvent.$on("keepAlive", async function () {
  366 + await that._QueryClassList();
  367 + if (!that.query.classId) {
  368 + return;
  369 + }
  370 + await that._QuerySubjectList();
  371 + await that.setDate(1);
  372 + let startDay = that.query?.startDay;
  373 + if (!startDay) {
  374 + that.query.startDay = new Date();
  375 + that.query.endDay = new Date();
  376 + }
  377 + });
  378 + },
  379 + methods: {
  380 + toArchiving() {
  381 + this.$router.push({
  382 + path: "/askArchiving",
  383 + });
  384 + },
  385 + print() {
  386 + tablePrint("print-content", "随堂问-" + this.tabList[this.tabIndex - 1]);
  387 + },
  388 + changeSub(val) {
  389 + let sub;
  390 + if (val && val.length) {
  391 + let leng = val.length - 1;
  392 + sub = val[leng];
  393 + }
  394 + this.query.subjectNames = val.filter((item) => {
  395 + return sub != "全部" ? item != "全部" : item == "全部";
  396 + });
  397 + },
  398 + linkTo(obj) {
  399 + //去详情
  400 + this.$router.push({
  401 + path: "/askAnalysis",
  402 + query: {
  403 + id: obj.id,
  404 + title: obj.title,
  405 + status: 1,
  406 + },
  407 + });
  408 + },
  409 + setDate(index) {
  410 + const that = this;
  411 + this.date = index == this.date ? "" : index;
  412 + let aYear = new Date().getFullYear();
  413 + let aMonth = new Date().getMonth() + 1;
  414 + that.query.day = "";
  415 + that.query.startDay = "";
  416 + that.query.endDay = "";
  417 + switch (index) {
  418 + case 1:
  419 + that.query.day = formatDate(new Date(), "yyyy-MM-dd");
  420 + that.query.startDay = that.query.day;
  421 + that.query.endDay = that.query.day;
  422 + that.tabIndex = 1;
  423 + break;
  424 + case 2:
  425 + let day = new Date().getDay();
  426 + if (day == 0) {
  427 + //中国式星期天是一周的最后一天
  428 + day = 7;
  429 + }
  430 + day--;
  431 + let aTime = new Date().getTime() - 24 * 60 * 60 * 1000 * day;
  432 + that.query.startDay = formatDate(new Date(aTime), "yyyy-MM-dd");
  433 + that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
  434 + break;
  435 + case 3:
  436 + aMonth = aMonth < 10 ? "0" + aMonth : aMonth;
  437 + that.query.startDay = `${aYear}-${aMonth}-01`;
  438 + that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
  439 + break;
  440 + case 4:
  441 + if (aMonth > 0 && aMonth < 4) {
  442 + aMonth = "1";
  443 + } else if (aMonth > 3 && aMonth < 7) {
  444 + aMonth = "4";
  445 + } else if (aMonth > 6 && aMonth < 10) {
  446 + aMonth = "7";
  447 + } else {
  448 + aMonth = "10";
  449 + }
  450 +
  451 + aMonth = aMonth < 10 ? "0" + aMonth : aMonth;
  452 + that.query.startDay = `${aYear}-${aMonth}-01`;
  453 + that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
  454 + break;
  455 + }
  456 + this.page = 1;
  457 + this._QueryData();
  458 + },
  459 + handleChangeTimeStart(val) {
  460 + this.query.day = "";
  461 + this.date = "";
  462 + if (this.query.endDay) {
  463 + if (new Date(val).getTime() > new Date(this.query.endDay).getTime()) {
  464 + this.$message.error("任务结束时间不能任务开始时间前面,请重新设置");
  465 + this.query.startDay = "";
  466 + }
  467 + }
  468 + },
  469 + handleChangeTimeEnd(val) {
  470 + this.query.day = "";
  471 + this.date = "";
  472 + if (this.query.startDay) {
  473 + if (new Date(val).getTime() < new Date(this.query.startDay).getTime()) {
  474 + this.$message.error("任务结束时间不能任务开始时间前面,请重新设置");
  475 + this.query.endDay = "";
  476 + }
  477 + }
  478 + },
  479 + tabChange() {
  480 + this.tableMaxHeight = this.$refs.main.offsetHeight;
  481 + this.page = 1;
  482 + this.tableData = [];
  483 + this._QueryData();
  484 + },
  485 + sortChange(obj) {
  486 + this.custom.orderField =
  487 + obj.prop == "participationRate"
  488 + ? 1
  489 + : obj.prop == "answerCorrectRate"
  490 + ? 2
  491 + : 3;
  492 + this.custom.orderType = obj.order == "ascending" ? 0 : 1;
  493 + this.page = 1;
  494 + this._QueryData();
  495 + },
  496 + changePage(page) {
  497 + this.page = page;
  498 + this._QueryData();
  499 + },
  500 + async changeclass() {
  501 + await this._QuerySubjectList();
  502 + this.page = 1;
  503 + this._QueryData();
  504 + },
  505 + async changClazz() {
  506 + await this._QuerySubjectList();
  507 + // await this.setDate(1);
  508 + this._QueryData();
  509 + },
  510 + async _QueryClassList() {
  511 + const { data, status, info } = await this.$request.pClassList({
  512 + status: 1,
  513 + });
  514 + if (status === 0) {
  515 + this.classList = data.list.map((item) => {
  516 + return {
  517 + value: item.id,
  518 + label: item.className,
  519 + };
  520 + });
  521 + this.query.classId = this.classList[0]?.value;
  522 + } else {
  523 + this.$message.error(info);
  524 + }
  525 + },
  526 + async _QuerySubjectList() {
  527 + if (!this.query.classId) return;
  528 + const { data, status, info } = await this.$request.pSubjectList({
  529 + classId: this.query.classId,
  530 + status: 1,
  531 + });
  532 + if (status === 0) {
  533 + this.query.subjectNames = [];
  534 + this.subjectList =
  535 + data.subjectNames?.map((item) => {
  536 + return {
  537 + value: item,
  538 + label: item,
  539 + };
  540 + }) || [];
  541 + this.subjectList.unshift({
  542 + value: "全部",
  543 + label: "全部",
  544 + });
  545 + this.query.subjectNames.push(this.subjectList[0]?.value);
  546 + } else {
  547 + this.$message.error(info);
  548 + }
  549 + },
  550 + async _QueryData() {
  551 + if (!this.query.classId) return;
  552 + if (this.tabIndex == 1) {
  553 + this.periodReportList();
  554 + } else if (this.tabIndex == 2) {
  555 + this.phaseAnswerReport();
  556 + } else if (this.tabIndex == 3) {
  557 + this.phaseInteractiveReport();
  558 + }
  559 + },
  560 + //分页查询课时报表列表
  561 + async periodReportList() {
  562 + this.loading = true;
  563 + let query = {};
  564 + for (let key in this.query) {
  565 + if (this.query[key] != "") {
  566 + query[key] = this.query[key];
  567 + }
  568 + }
  569 + if (this.custom.orderField !== null) {
  570 + query = { ...query, ...this.custom };
  571 + }
  572 +
  573 + if (
  574 + query["subjectNames"] &&
  575 + query["subjectNames"].length == 1 &&
  576 + query["subjectNames"][0] == "全部"
  577 + ) {
  578 + query["subjectNames"] = this.subjectList.map((item) => {
  579 + return item.value;
  580 + });
  581 + query["subjectNames"].shift();
  582 + }
  583 + if (!query["subjectNames"]) {
  584 + this.$message.warning("请选择科目");
  585 + return;
  586 + }
  587 + const { data, status, info } = await this.$request.pPeriodReportList({
  588 + ...query,
  589 + page: this.page,
  590 + size: this.size,
  591 + });
  592 + this.loading = false;
  593 + if (status === 0) {
  594 + this.tableData = (data?.list && [...data?.list]) || [];
  595 + this.total = data.count;
  596 + } else {
  597 + this.$message.error(info);
  598 + }
  599 + },
  600 + //查询阶段问答报表
  601 + async phaseAnswerReport() {
  602 + this.loading = true;
  603 + let query = {};
  604 + for (let key in this.query) {
  605 + if (this.query[key] != "") {
  606 + query[key] = this.query[key];
  607 + }
  608 + }
  609 + if (
  610 + query["subjectNames"] &&
  611 + query["subjectNames"].length == 1 &&
  612 + query["subjectNames"][0] == "全部"
  613 + ) {
  614 + query["subjectNames"] = this.subjectList.map((item) => {
  615 + return item.value;
  616 + });
  617 + query["subjectNames"].shift();
  618 + }
  619 + if (!query["subjectNames"]) {
  620 + this.$message.warning("请选择科目");
  621 + return;
  622 + }
  623 + const { data, status, info } = await this.$request.pPhaseAnswerReport({
  624 + ...query,
  625 + });
  626 + this.loading = false;
  627 + if (status === 0) {
  628 + let subjectName = [];
  629 + let tableData = data?.list.map((item) => {
  630 + let params = {};
  631 + item.dataList.map((items, index) => {
  632 + if (!subjectName.includes(items.subjectName)) {
  633 + subjectName.push(items.subjectName);
  634 + }
  635 + params["answerCorrectRate" + items.subjectName] =
  636 + items.answerCorrectRate;
  637 + params["correctRate" + items.subjectName] = items.correctRate;
  638 + params["participationRate" + items.subjectName] =
  639 + items.participationRate;
  640 + params["periodCount" + items.subjectName] = items.periodCount;
  641 + params["questionNum" + items.subjectName] = items.questionNum;
  642 + });
  643 + return {
  644 + ...item,
  645 + ...params,
  646 + };
  647 + });
  648 + this.phaseOption = [...subjectName];
  649 + this.tableData = tableData.sort((a, b) => {
  650 + return a.studentCode - b.studentCode;
  651 + });
  652 +
  653 + this.total = data.count;
  654 + } else {
  655 + this.$message.error(info);
  656 + }
  657 + },
  658 + //查询阶段互动报表
  659 + async phaseInteractiveReport() {
  660 + this.loading = true;
  661 + let query = {};
  662 + for (let key in this.query) {
  663 + if (this.query[key] != "") {
  664 + query[key] = this.query[key];
  665 + }
  666 + }
  667 +
  668 + if (
  669 + query["subjectNames"] &&
  670 + query["subjectNames"].length == 1 &&
  671 + query["subjectNames"][0] == "全部"
  672 + ) {
  673 + query["subjectNames"] = this.subjectList.map((item) => {
  674 + return item.value;
  675 + });
  676 + query["subjectNames"].shift();
  677 + }
  678 + if (!query["subjectNames"]) {
  679 + this.$message.warning("请选择科目");
  680 + return;
  681 + }
  682 + const { data, status, info } =
  683 + await this.$request.pPhaseInteractiveReport({
  684 + ...query,
  685 + });
  686 + this.loading = false;
  687 + if (status === 0) {
  688 + let subjectName = [];
  689 + let tableData = data?.list.map((item) => {
  690 + let params = {};
  691 + item.dataList.map((items, index) => {
  692 + if (!subjectName.includes(items.subjectName)) {
  693 + subjectName.push(items.subjectName);
  694 + }
  695 + params["interactionsNum" + items.subjectName] =
  696 + items.interactionsNum;
  697 + params["interactionsCorrectNum" + items.subjectName] =
  698 + items.interactionsCorrectNum;
  699 + });
  700 + return {
  701 + ...item,
  702 + ...params,
  703 + };
  704 + });
  705 + this.phaseInter = [...subjectName];
  706 + this.tableData = tableData.sort((a, b) => {
  707 + return a.studentCode - b.studentCode;
  708 + });
  709 +
  710 + this.total = data.count;
  711 + } else {
  712 + this.$message.error(info);
  713 + }
  714 + },
  715 + //导出
  716 + async exportData() {
  717 + if (this.exportLoading == true) return;
  718 + let query = {};
  719 + for (let key in this.query) {
  720 + if (this.query[key] != "") {
  721 + query[key] = this.query[key];
  722 + }
  723 + }
  724 +
  725 + if (
  726 + query["subjectNames"] &&
  727 + query["subjectNames"].length == 1 &&
  728 + query["subjectNames"][0] == "全部"
  729 + ) {
  730 + query["subjectNames"] = this.subjectList.map((item) => {
  731 + return item.value;
  732 + });
  733 + query["subjectNames"].shift();
  734 + }
  735 + if (!query["subjectNames"]) {
  736 + this.$message.warning("请选择科目");
  737 + return;
  738 + }
  739 + this.exportLoading = true;
  740 + const data = await this.$request.pExportPhaseReport({ ...query });
  741 + this.exportLoading = false;
  742 + if (data) {
  743 + let blob = new Blob([data], {
  744 + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  745 + });
  746 + downloadFile("随堂问-已归档阶段报表.xlsx", blob);
  747 + } else {
  748 + this.$message.error("下载失败");
  749 + }
  750 + },
  751 + },
  752 +};
  753 +</script>
  754 +<style>
  755 +div::-webkit-scrollbar {
  756 + width: 3px;
  757 + height: 10px;
  758 +}
  759 +div::-webkit-scrollbar-thumb {
  760 + border-radius: 10px;
  761 + background-color: #ccc;
  762 +}
  763 +</style>
  764 +<style lang="scss" scoped>
  765 +.main {
  766 + height: 100%;
  767 +}
  768 +.table-box {
  769 + margin: 0 20px;
  770 + padding: 16px;
  771 + background: #f8f8f8;
  772 + border-radius: 5px;
  773 + .table-cont {
  774 + min-height: 300px;
  775 + }
  776 + :deep(.fa-arrow-right) {
  777 + padding-left: 2px;
  778 + }
  779 + :deep(.fa-file-text) {
  780 + padding-left: 2px;
  781 + }
  782 +}
  783 +
  784 +.fa-exchange {
  785 + color: #667ffd;
  786 + cursor: pointer;
  787 + font-size: 16px;
  788 + margin-left: 10px;
  789 +}
  790 +.dia-btn {
  791 + border-radius: 20px;
  792 + margin: 0 20px;
  793 + padding: 10px 20px;
  794 +}
  795 +.dia-tips {
  796 + padding-bottom: 10px;
  797 +}
  798 +.dia-question-box {
  799 + padding: 16px 16px 1px;
  800 + background: #f8f8f8;
  801 + border-radius: 10px;
  802 +
  803 + .answer-s {
  804 + width: 36px;
  805 + height: 28px;
  806 + cursor: pointer;
  807 + }
  808 +}
  809 +.set-questions {
  810 + display: flex;
  811 + margin-bottom: 12px;
  812 + width: 100%;
  813 + .qs-num {
  814 + flex-shrink: 0;
  815 + margin-right: 10px;
  816 + }
  817 + .qs-options {
  818 + flex: 1;
  819 + .ipt {
  820 + margin-bottom: 5px;
  821 + }
  822 + }
  823 + .delButton {
  824 + border-color: #ff6868;
  825 + background: #ff6868 url("../../../assets/images/arrow.png") no-repeat center;
  826 + background-size: 19px;
  827 + color: transparent;
  828 + }
  829 + .ac {
  830 + border-color: #ff6868;
  831 + background: #ff6868;
  832 + color: #fff;
  833 + }
  834 +}
  835 +.down {
  836 + padding-top: 16px;
  837 +}
  838 +</style>
0 839 \ No newline at end of file
... ...
src/views/personal/ask/index.vue
... ... @@ -4,6 +4,23 @@
4 4 <template slot="title">
5 5 <span>问答-数据报表</span>
6 6 </template>
  7 + <template slot="btns">
  8 + <el-tooltip
  9 + v-if="!code"
  10 + effect="dark"
  11 + content="已归档试卷"
  12 + placement="bottom"
  13 + >
  14 + <el-button
  15 + type="primary"
  16 + icon="fa fa-archive"
  17 + size="mini"
  18 + plain
  19 + circle
  20 + @click="toArchiving"
  21 + ></el-button>
  22 + </el-tooltip>
  23 + </template>
7 24 </back-box>
8 25 <div class="answer-header">
9 26 <div class="sel-box">
... ... @@ -79,13 +96,14 @@
79 96 @change="tabChange"
80 97 style="margin-bottom: 20px"
81 98 >
82   - <el-radio-button :label="1">单课时报表</el-radio-button>
83   - <el-radio-button :label="2" v-if="query.startDay != query.endDay"
84   - >阶段问答报表</el-radio-button
85   - >
86   - <el-radio-button :label="3" v-if="query.startDay != query.endDay"
87   - >阶段互动报表</el-radio-button
88   - >
  99 + <template v-for="(item, index) in tabList">
  100 + <el-radio-button
  101 + v-if="index == 0 || query.startDay != query.endDay"
  102 + :key="index"
  103 + :label="index + 1"
  104 + >{{ item }}</el-radio-button
  105 + >
  106 + </template>
89 107 </el-radio-group>
90 108 <div class="table-cont" v-loading="loading">
91 109 <div id="print-content">
... ... @@ -348,6 +366,7 @@ export default {
348 366 endDay: "",
349 367 day: "",
350 368 },
  369 + tabList: ["单课时报表", "阶段问答报表", "阶段互动报表"],
351 370 custom: {
352 371 //单课时排序
353 372 orderField: null,
... ... @@ -366,6 +385,9 @@ export default {
366 385 },
367 386 async created() {
368 387 await this._QueryClassList();
  388 + if (!this.query.classId) {
  389 + return;
  390 + }
369 391 await this._QuerySubjectList();
370 392 await this.setDate(1);
371 393 let startDay = this.query?.startDay;
... ... @@ -377,19 +399,27 @@ export default {
377 399 activated() {
378 400 const that = this;
379 401 BusEvent.$on("keepAlive", async function () {
380   - await that._QueryClassList();
381   - await that._QuerySubjectList();
382   - await that.setDate(1);
383   - let startDay = that.query?.startDay;
384   - if (!startDay) {
385   - that.query.startDay = new Date();
386   - that.query.endDay = new Date();
387   - }
  402 + await that._QueryClassList();
  403 + if (!that.query.classId) {
  404 + return;
  405 + }
  406 + await that._QuerySubjectList();
  407 + await that.setDate(1);
  408 + let startDay = that.query?.startDay;
  409 + if (!startDay) {
  410 + that.query.startDay = new Date();
  411 + that.query.endDay = new Date();
  412 + }
388 413 });
389 414 },
390 415 methods: {
  416 + toArchiving() {
  417 + this.$router.push({
  418 + path: "/askArchiving",
  419 + });
  420 + },
391 421 print() {
392   - tablePrint("print-content");
  422 + tablePrint("print-content", "随堂问-" + this.tabList[this.tabIndex - 1]);
393 423 },
394 424 changeSub(val) {
395 425 let sub;
... ... @@ -397,7 +427,6 @@ export default {
397 427 let leng = val.length - 1;
398 428 sub = val[leng];
399 429 }
400   - console.log(val);
401 430 this.query.subjectNames = val.filter((item) => {
402 431 return sub != "全部" ? item != "全部" : item == "全部";
403 432 });
... ...
src/views/personal/card/index.vue
... ... @@ -144,7 +144,6 @@ export default {
144 144 async _QueryGradeList() {
145 145 this.loading = true;
146 146 const { data, status, info } = await this.$request.gradeList();
147   - console.log(status);
148 147 if (status === 0) {
149 148 if (!!data.list) {
150 149 this.gradeList =
... ... @@ -196,7 +195,6 @@ export default {
196 195 size: 20,
197 196 });
198 197 this.loading = false;
199   - console.log(status);
200 198 if (status === 0) {
201 199 this.tableData = data.list || [];
202 200 this.total = data.count;
... ...
src/views/personal/test/analysis.vue
... ... @@ -5,7 +5,7 @@
5 5 <span>单卷分析</span>
6 6 </template>
7 7 </back-box>
8   - <div class="tips" v-if="paperModifyLog.modifiedTime">
  8 + <div class="tips" v-if="paperModifyLog.modifiedTime || status">
9 9 <p class="tips-p">
10 10 <i class="fa fa-bell-o"></i>
11 11 {{
... ... @@ -29,28 +29,12 @@
29 29 <div class="page-content">
30 30 <div class="tab-box">
31 31 <span
  32 + v-for="(item, index) in tabList"
  33 + :key="item"
32 34 class="tab-item"
33   - :class="type == 1 ? 'active' : ''"
34   - @click="setType(1)"
35   - >试题分析</span
36   - >
37   - <span
38   - class="tab-item"
39   - :class="type == 2 ? 'active' : ''"
40   - @click="setType(2)"
41   - >成绩排名</span
42   - >
43   - <span
44   - class="tab-item"
45   - :class="type == 3 ? 'active' : ''"
46   - @click="setType(3)"
47   - >小题分报表</span
48   - >
49   - <span
50   - class="tab-item"
51   - :class="type == 4 ? 'active' : ''"
52   - @click="setType(4)"
53   - >作答明细表</span
  35 + :class="type == index + 1 ? 'active' : ''"
  36 + @click="setType(index + 1)"
  37 + >{{ item }}</span
54 38 >
55 39 </div>
56 40 <div id="print-content" class="table-box" v-loading="loading">
... ... @@ -398,7 +382,7 @@
398 382 >打印</el-button
399 383 >
400 384 </div>
401   - <div>
  385 + <div v-if="!status">
402 386 <el-button
403 387 v-if="examReport.subjectiveScore != 0"
404 388 @click="diaUp = true"
... ... @@ -442,6 +426,7 @@ export default {
442 426 data() {
443 427 return {
444 428 role: "",
  429 + status: 0,
445 430 tableMaxHeight: 600,
446 431 loading: false,
447 432 exportLoading: false,
... ... @@ -451,6 +436,7 @@ export default {
451 436 title: "",
452 437 score: "",
453 438 type: 1,
  439 + tabList: ["试题分析", "成绩排名", "小题分报表", "作答明细表"],
454 440 paperModifyLog: {
455 441 realName: "",
456 442 modifiedTime: "",
... ... @@ -486,12 +472,13 @@ export default {
486 472 this.$store.getters.info.showRole ||
487 473 this.$store.getters.info.permissions[0].role;
488 474 this.id = this.$route.query.id;
  475 + this.status = this.$route.query.status ? this.$route.query.status : 0;
489 476 this.title = this.$route.query.title || "";
490 477 this._QueryData();
491 478 },
492 479 methods: {
493 480 print() {
494   - tablePrint("print-content");
  481 + tablePrint("print-content", this.title + this.tabList[this.type - 1]);
495 482 },
496 483 upSuccess(res) {
497 484 //导入成功
... ...
src/views/personal/test/archiving.vue 0 → 100644
  1 +<template>
  2 + <div ref="main" class="page-container">
  3 + <back-box>
  4 + <template slot="title">
  5 + <span>即时测-已归档数据报表</span>
  6 + </template>
  7 + </back-box>
  8 + <div class="answer-header">
  9 + <div class="sel-box">
  10 + <el-select
  11 + class="sel"
  12 + v-model="query.classId"
  13 + placeholder="选择班级"
  14 + @change="changeclass"
  15 + >
  16 + <el-option
  17 + v-for="item in classList"
  18 + :key="item.value"
  19 + :label="item.label"
  20 + :value="item.value"
  21 + >
  22 + </el-option>
  23 + </el-select>
  24 + <el-select
  25 + class="sel"
  26 + multiple
  27 + v-model="query.subjectNames"
  28 + placeholder="选择科目"
  29 + collapse-tags
  30 + @change="changeSub"
  31 + >
  32 + <el-option
  33 + v-for="item in subjectList"
  34 + :key="item.value"
  35 + :label="item.label"
  36 + :value="item.value"
  37 + >
  38 + </el-option>
  39 + </el-select>
  40 + <div class="d1">
  41 + <el-date-picker
  42 + v-model="query.startDay"
  43 + type="date"
  44 + @change="handleChangeTimeStart"
  45 + placeholder="选择日期时间"
  46 + value-format="yyyy-MM-dd"
  47 + >
  48 + </el-date-picker>
  49 + ~
  50 + <el-date-picker
  51 + v-model="query.endDay"
  52 + type="date"
  53 + placeholder="选择日期时间"
  54 + @change="handleChangeTimeEnd"
  55 + value-format="yyyy-MM-dd"
  56 + >
  57 + </el-date-picker>
  58 + </div>
  59 + <p class="p1">
  60 + <span @click="setDate(1)" :class="[date == 1 ? 'active' : '', 's1']"
  61 + >今天</span
  62 + >
  63 + <span @click="setDate(2)" :class="[date == 2 ? 'active' : '', 's1']"
  64 + >本周</span
  65 + >
  66 + <span @click="setDate(3)" :class="[date == 3 ? 'active' : '', 's1']"
  67 + >本月</span
  68 + >
  69 + <span @click="setDate(4)" :class="[date == 4 ? 'active' : '', 's1']"
  70 + >本季度</span
  71 + >
  72 + </p>
  73 + <el-button type="primary" round @click="_QueryData()">筛选</el-button>
  74 + </div>
  75 + </div>
  76 + <div class="table-box">
  77 + <el-radio-group
  78 + v-model="tabIndex"
  79 + @change="changeTab"
  80 + style="margin-bottom: 20px"
  81 + >
  82 + <template v-for="(item, index) in tabList">
  83 + <el-radio-button
  84 + v-if="index == 0 || query.startDay != query.endDay"
  85 + :key="index"
  86 + :label="index + 1"
  87 + >{{ item }}</el-radio-button
  88 + >
  89 + </template>
  90 + </el-radio-group>
  91 + <div v-show="tabIndex == 1" v-loading="loading">
  92 + <el-table :data="tableData" border style="width: 100%">
  93 + <el-table-column
  94 + prop="title"
  95 + label="试卷名称"
  96 + fixed
  97 + align="center"
  98 + ></el-table-column>
  99 + <el-table-column
  100 + prop="examPaperScore"
  101 + label="卷面分"
  102 + align="center"
  103 + width="100"
  104 + ></el-table-column>
  105 + <el-table-column prop="answeredNum" label="测验人数" align="center"
  106 + ><template slot-scope="scoped">{{
  107 + `${scoped.row.answeredNum}/${scoped.row.classPersonNum}`
  108 + }}</template></el-table-column
  109 + >
  110 + <el-table-column
  111 + prop="examStartTime"
  112 + label="测验时间"
  113 + width="100"
  114 + align="center"
  115 + ></el-table-column>
  116 + <el-table-column prop="avgScore" label="班平均分" align="center"
  117 + ><template slot-scope="scoped">{{
  118 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  119 + scoped.row.answerNum == 0) &&
  120 + scoped.row.recordStatus == 0
  121 + ? "-"
  122 + : scoped.row.avgScore
  123 + }}</template></el-table-column
  124 + >
  125 + <el-table-column prop="highestScore" label="班最高分" align="center"
  126 + ><template slot-scope="scoped">{{
  127 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  128 + scoped.row.answerNum == 0) &&
  129 + scoped.row.recordStatus == 0
  130 + ? "-"
  131 + : scoped.row.highestScore
  132 + }}</template></el-table-column
  133 + >
  134 + <el-table-column prop="lowestScore" label="班最低分" align="center"
  135 + ><template slot-scope="scoped">{{
  136 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  137 + scoped.row.answerNum == 0) &&
  138 + scoped.row.recordStatus == 0
  139 + ? "-"
  140 + : scoped.row.lowestScore
  141 + }}</template></el-table-column
  142 + >
  143 + <el-table-column
  144 + prop="excellenRate"
  145 + label="优秀数(率)"
  146 + sortable
  147 + align="center"
  148 + width="110"
  149 + class-name="p0"
  150 + ><template slot-scope="scoped">
  151 + <p
  152 + v-if="
  153 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  154 + scoped.row.answerNum == 0) &&
  155 + scoped.row.arecordStatus == 0
  156 + "
  157 + >
  158 + "-"
  159 + </p>
  160 + <template v-else>
  161 + <p>{{ scoped.row.excellenNum }}</p>
  162 + <p v-if="scoped.row.excellenNum">
  163 + {{ `(${scoped.row.excellenRate}%)` }}
  164 + </p>
  165 + </template>
  166 + </template></el-table-column
  167 + >
  168 + <el-table-column
  169 + prop="goodRate"
  170 + label="良好数(率)"
  171 + sortable
  172 + align="center"
  173 + width="110"
  174 + class-name="p0"
  175 + ><template slot-scope="scoped">
  176 + <p
  177 + v-if="
  178 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  179 + scoped.row.answerNum == 0) &&
  180 + scoped.row.arecordStatus == 0
  181 + "
  182 + >
  183 + "-"
  184 + </p>
  185 + <template v-else>
  186 + <p>{{ scoped.row.goodNum }}</p>
  187 + <p v-if="scoped.row.goodNum">
  188 + {{ `(${scoped.row.goodRate}%)` }}
  189 + </p>
  190 + </template>
  191 + </template></el-table-column
  192 + >
  193 + <el-table-column
  194 + prop="passRate"
  195 + label="及格数(率)"
  196 + sortable
  197 + align="center"
  198 + width="110"
  199 + class-name="p0"
  200 + ><template slot-scope="scoped">
  201 + <p
  202 + v-if="
  203 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  204 + scoped.row.answerNum == 0) &&
  205 + scoped.row.arecordStatus == 0
  206 + "
  207 + >
  208 + "-"
  209 + </p>
  210 + <template v-else>
  211 + <p>{{ scoped.row.passNum }}</p>
  212 + <p v-if="scoped.row.passNum">
  213 + {{ `(${scoped.row.passRate}%)` }}
  214 + </p>
  215 + </template>
  216 + </template></el-table-column
  217 + >
  218 + <el-table-column
  219 + prop="failedRate"
  220 + label="不及格数(率)"
  221 + sortable
  222 + align="center"
  223 + width="130"
  224 + class-name="p0"
  225 + ><template slot-scope="scoped">
  226 + <p
  227 + v-if="
  228 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  229 + scoped.row.answerNum == 0) &&
  230 + scoped.row.arecordStatus == 0
  231 + "
  232 + >
  233 + "-"
  234 + </p>
  235 + <template v-else>
  236 + <p>{{ scoped.row.failedNum }}</p>
  237 + <p v-if="scoped.row.failedNum">
  238 + {{ `(${scoped.row.failedRate}%)` }}
  239 + </p>
  240 + </template>
  241 + </template></el-table-column
  242 + >
  243 + <el-table-column label="操作" align="center">
  244 + <template slot-scope="scoped">
  245 + <el-tooltip effect="dark" content="详情" placement="top">
  246 + <el-button
  247 + type="primary"
  248 + circle
  249 + size="mini"
  250 + icon="fa fa-arrow-right"
  251 + @click="linkTo(scoped.row)"
  252 + ></el-button>
  253 + </el-tooltip>
  254 + </template>
  255 + </el-table-column>
  256 + </el-table>
  257 + <div class="pagination-box">
  258 + <el-pagination
  259 + small=""
  260 + layout="total,prev, pager, next"
  261 + :hide-on-single-page="true"
  262 + :total="total"
  263 + @current-change="changePage"
  264 + :current-page="page"
  265 + :page-size="size"
  266 + >
  267 + </el-pagination>
  268 + </div>
  269 + </div>
  270 + <div v-show="tabIndex == 2" v-loading="loading">
  271 + <el-empty
  272 + :image-size="100"
  273 + v-if="!tableData.length && loading == false"
  274 + description="没有更多数据"
  275 + ></el-empty>
  276 + <template v-if="tableData.length && loading == false">
  277 + <el-table
  278 + id="print-content"
  279 + :data="tableData"
  280 + :max-height="tableMaxHeight"
  281 + border
  282 + style="width: 100%"
  283 + >
  284 + <el-table-column
  285 + prop="studentCode"
  286 + label="学号"
  287 + align="center"
  288 + fixed
  289 + ></el-table-column>
  290 + <el-table-column
  291 + prop="studentName"
  292 + label="姓名"
  293 + fixed
  294 + align="center"
  295 + ></el-table-column>
  296 + <el-table-column
  297 + align="center"
  298 + v-for="(item, index) in answerList"
  299 + :key="index"
  300 + :label="item"
  301 + >
  302 + <el-table-column
  303 + :prop="'examCount' + item"
  304 + label="测练数"
  305 + align="center"
  306 + :class-name="index % 2 == 0 ? 'bg' : ''"
  307 + ></el-table-column>
  308 + <el-table-column
  309 + :prop="'participationCount' + item"
  310 + label="参与数"
  311 + align="center"
  312 + :class-name="index % 2 == 0 ? 'bg' : ''"
  313 + ></el-table-column>
  314 + <el-table-column
  315 + :prop="'score' + item"
  316 + label="总分"
  317 + align="center"
  318 + :class-name="index % 2 == 0 ? 'bg' : ''"
  319 + ></el-table-column>
  320 + <el-table-column
  321 + :prop="'classRank' + item"
  322 + label="班名"
  323 + align="center"
  324 + :class-name="index % 2 == 0 ? 'bg' : ''"
  325 + ></el-table-column>
  326 + </el-table-column>
  327 + </el-table>
  328 + </template>
  329 + </div>
  330 + <p class="down" v-if="tabIndex == 2 && tableData.length">
  331 + <el-button
  332 + type="primary"
  333 + plain
  334 + round
  335 + icon="fa fa-cloud-download"
  336 + @click="downExl"
  337 + >导出报表</el-button
  338 + >
  339 + <el-button
  340 + @click="print"
  341 + type="primary"
  342 + plain
  343 + round
  344 + icon="el-icon-printer"
  345 + >打印</el-button
  346 + >
  347 + </p>
  348 + </div>
  349 + </div>
  350 +</template>
  351 +
  352 +<script>
  353 +import { formatDate, downloadFile, tablePrint } from "utils";
  354 +import BusEvent from "@/utils/busEvent";
  355 +export default {
  356 + data() {
  357 + return {
  358 + exportLoading: false,
  359 + tableMaxHeight: 300,
  360 + loading: false,
  361 + date: "", //今天-昨天-本周
  362 + query: {
  363 + //搜索条件
  364 + classId: "",
  365 + subjectNames: [],
  366 + startDay: "",
  367 + endDay: "",
  368 + day: "",
  369 + },
  370 + tabList: ["单卷测练报表", "阶段测练报表"],
  371 + classList: [], //班级
  372 + subjectList: [], //科目
  373 + tabIndex: 1, //选项卡
  374 + tableData: [],
  375 + answerList: [], //设置多卷内容供tableStage表格数据用
  376 + page: 1,
  377 + size: 20,
  378 + total: 0,
  379 + };
  380 + },
  381 + async created() {
  382 + await this._QueryClassList();
  383 + if (!this.query.classId) {
  384 + return;
  385 + }
  386 + await this._QuerySubjectList();
  387 + await this.setDate(1);
  388 + let startDay = this.query?.startDay;
  389 + if (!startDay) {
  390 + this.query.startDay = new Date();
  391 + this.query.endDay = new Date();
  392 + }
  393 + },
  394 + activated() {
  395 + const that = this;
  396 + BusEvent.$on("keepAlive", async function () {
  397 + await that._QueryClassList();
  398 + if (!that.query.classId) {
  399 + return;
  400 + }
  401 + await that._QuerySubjectList();
  402 + await that.setDate(1);
  403 + let startDay = that.query?.startDay;
  404 + if (!startDay) {
  405 + that.query.startDay = new Date();
  406 + that.query.endDay = new Date();
  407 + }
  408 + });
  409 + },
  410 + methods: {
  411 + print() {
  412 + tablePrint("print-content", "即时测-" + this.tabList[this.tabIndex - 1]);
  413 + },
  414 + changeSub(val) {
  415 + let sub;
  416 + if (val && val.length) {
  417 + let leng = val.length - 1;
  418 + sub = val[leng];
  419 + }
  420 + console.log(val);
  421 + this.query.subjectNames = val.filter((item) => {
  422 + return sub != "全部" ? item != "全部" : item == "全部";
  423 + });
  424 + },
  425 + linkTo(obj) {
  426 + //去详情
  427 + this.$router.push({
  428 + path: "/testAnalysis",
  429 + query: {
  430 + id: obj.id,
  431 + title: obj.title,
  432 + score: obj.examPaperScore,
  433 + status: 1,
  434 + },
  435 + });
  436 + },
  437 + setDate(index) {
  438 + const that = this;
  439 + this.date = index == this.date ? "" : index;
  440 + let aYear = new Date().getFullYear();
  441 + let aMonth = new Date().getMonth() + 1;
  442 + that.query.day = "";
  443 + that.query.startDay = "";
  444 + that.query.endDay = "";
  445 + switch (index) {
  446 + case 1:
  447 + that.query.day = formatDate(new Date(), "yyyy-MM-dd");
  448 + that.query.startDay = that.query.day;
  449 + that.query.endDay = that.query.day;
  450 + that.tabIndex = 1;
  451 + break;
  452 + case 2:
  453 + let day = new Date().getDay();
  454 + if (day == 0) {
  455 + //中国式星期天是一周的最后一天
  456 + day = 7;
  457 + }
  458 + day--;
  459 + let aTime = new Date().getTime() - 24 * 60 * 60 * 1000 * day;
  460 + that.query.startDay = formatDate(new Date(aTime), "yyyy-MM-dd");
  461 + that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
  462 + break;
  463 + case 3:
  464 + aMonth = aMonth < 10 ? "0" + aMonth : aMonth;
  465 + that.query.startDay = `${aYear}-${aMonth}-01`;
  466 + that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
  467 + break;
  468 + case 4:
  469 + if (aMonth > 0 && aMonth < 4) {
  470 + aMonth = "1";
  471 + } else if (aMonth > 3 && aMonth < 7) {
  472 + aMonth = "4";
  473 + } else if (aMonth > 6 && aMonth < 10) {
  474 + aMonth = "7";
  475 + } else {
  476 + aMonth = "10";
  477 + }
  478 +
  479 + aMonth = aMonth < 10 ? "0" + aMonth : aMonth;
  480 + that.query.startDay = `${aYear}-${aMonth}-01`;
  481 + that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
  482 + break;
  483 + }
  484 + this.page = 1;
  485 + this._QueryData();
  486 + },
  487 + handleChangeTimeStart(val) {
  488 + this.query.day = "";
  489 + this.date = "";
  490 + if (this.query.endDay) {
  491 + if (new Date(val).getTime() > new Date(this.query.endDay).getTime()) {
  492 + this.$message.error("任务结束时间不能任务开始时间前面,请重新设置");
  493 + this.query.startDay = "";
  494 + }
  495 + }
  496 + },
  497 + handleChangeTimeEnd(val) {
  498 + this.query.day = "";
  499 + this.date = "";
  500 + if (this.query.startDay) {
  501 + if (new Date(val).getTime() < new Date(this.query.startDay).getTime()) {
  502 + this.$message.error("任务结束时间不能任务开始时间前面,请重新设置");
  503 + this.query.endDay = "";
  504 + }
  505 + }
  506 + },
  507 + changePage(page) {
  508 + this.page = page;
  509 + this._QueryData();
  510 + },
  511 + changeTab() {
  512 + this.tableMaxHeight = this.$refs.main.offsetHeight;
  513 + this.page = 1;
  514 + this._QueryData();
  515 + },
  516 +
  517 + async changeclass() {
  518 + await this._QuerySubjectList();
  519 + this.page = 1;
  520 + this._QueryData();
  521 + },
  522 +
  523 + async changClazz() {
  524 + this.page = 1;
  525 + await this._QuerySubjectList();
  526 + await this._QueryData();
  527 + },
  528 + async _QueryClassList() {
  529 + const { data, status, info } = await this.$request.pClassList({
  530 + status: 1,
  531 + });
  532 + if (status === 0) {
  533 + this.classList = data.list.map((item) => {
  534 + return {
  535 + value: item.id,
  536 + label: item.className,
  537 + };
  538 + });
  539 + this.query.classId = this.classList[0]?.value;
  540 + } else {
  541 + this.$message.error(info);
  542 + }
  543 + },
  544 + async _QuerySubjectList() {
  545 + if (!this.query.classId) return;
  546 + const { data, status, info } = await this.$request.pSubjectList({
  547 + classId: this.query.classId,
  548 + status: 1,
  549 + });
  550 + if (status === 0) {
  551 + this.query.subjectNames = [];
  552 + this.subjectList =
  553 + data.subjectNames?.map((item) => {
  554 + return {
  555 + value: item,
  556 + label: item,
  557 + };
  558 + }) || [];
  559 + this.subjectList.unshift({
  560 + value: "全部",
  561 + label: "全部",
  562 + });
  563 + this.query.subjectNames.push(this.subjectList[0]?.value);
  564 + } else {
  565 + this.$message.error(info);
  566 + }
  567 + },
  568 + async _QueryData() {
  569 + if (!this.query.classId) return;
  570 + this.tableData = [];
  571 + if (this.tabIndex == 1) {
  572 + this.examReportList();
  573 + } else {
  574 + this.phaseExamReport();
  575 + }
  576 + },
  577 + //单卷测练
  578 + async examReportList() {
  579 + this.loading = true;
  580 + let query = {};
  581 + for (let key in this.query) {
  582 + if (this.query[key] != "") {
  583 + query[key] = this.query[key];
  584 + }
  585 + }
  586 +
  587 + if (
  588 + query["subjectNames"] &&
  589 + query["subjectNames"].length == 1 &&
  590 + query["subjectNames"][0] == "全部"
  591 + ) {
  592 + query["subjectNames"] = this.subjectList.map((item) => {
  593 + return item.value;
  594 + });
  595 + query["subjectNames"].shift();
  596 + }
  597 + if (!query["subjectNames"]) {
  598 + this.$message.warning("请选择科目");
  599 + return;
  600 + }
  601 + const { data, status, info } = await this.$request.pExamReportList({
  602 + ...query,
  603 + page: this.page,
  604 + size: this.size,
  605 + });
  606 + this.loading = false;
  607 + if (status === 0) {
  608 + this.tableData = (data?.list && [...data?.list]) || [];
  609 + this.total = data?.count || 0;
  610 + } else {
  611 + this.$message.error(info);
  612 + }
  613 + },
  614 + //多卷测练
  615 + async phaseExamReport() {
  616 + this.loading = true;
  617 + let query = {};
  618 + for (let key in this.query) {
  619 + if (this.query[key] != "") {
  620 + query[key] = this.query[key];
  621 + }
  622 + }
  623 +
  624 + if (
  625 + query["subjectNames"] &&
  626 + query["subjectNames"]?.length == 1 &&
  627 + query["subjectNames"][0] == "全部"
  628 + ) {
  629 + query["subjectNames"] = this.subjectList.map((item) => {
  630 + return item.value;
  631 + });
  632 + query["subjectNames"]?.shift();
  633 + }
  634 + // 测试
  635 + query["subjectName"] = "政治";
  636 + delete query["subjectNames"];
  637 + // end
  638 + const { data, status, info } = await this.$request.pPhaseExamReport({
  639 + ...query,
  640 + });
  641 + this.loading = false;
  642 + if (status === 0) {
  643 + this.total = data.count;
  644 + let subjectName = [];
  645 + this.tableData = data?.list.map((item) => {
  646 + let params = {};
  647 + item.dataList?.map((items, index) => {
  648 + if (!subjectName.includes(items.subjectName)) {
  649 + subjectName.push(items.subjectName);
  650 + }
  651 + params["examCount" + items.subjectName] = items.examCount;
  652 + params["participationCount" + items.subjectName] =
  653 + items.participationCount;
  654 + params["score" + items.subjectName] = items.score;
  655 + params["classRank" + items.subjectName] = items.classRank;
  656 + });
  657 + return {
  658 + ...item,
  659 + ...params,
  660 + };
  661 + });
  662 + this.answerList = [...subjectName];
  663 + } else {
  664 + this.$message.error(info);
  665 + }
  666 + },
  667 + async downExl() {
  668 + if (this.exportLoading == true) return;
  669 + let query = {};
  670 + for (let key in this.query) {
  671 + if (this.query[key] != "") {
  672 + query[key] = this.query[key];
  673 + }
  674 + }
  675 + if (
  676 + query["subjectNames"] &&
  677 + query["subjectNames"].length == 1 &&
  678 + query["subjectNames"][0] == "全部"
  679 + ) {
  680 + query["subjectNames"] = this.subjectList.map((item) => {
  681 + return item.value;
  682 + });
  683 + query["subjectNames"].shift();
  684 + }
  685 + if (!query["subjectNames"]) {
  686 + this.$message.warning("请选择科目");
  687 + return;
  688 + }
  689 + const data = await this.$request.pExportPhaseExamReport({ ...query });
  690 + this.exportLoading = false;
  691 + if (data && !data.code) {
  692 + let blob = new Blob([data], {
  693 + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  694 + });
  695 + downloadFile("即时测-已归档阶段测练报表.xlsx", blob);
  696 + } else {
  697 + this.$message.error(data.info);
  698 + }
  699 + },
  700 + },
  701 +};
  702 +</script>
  703 +
  704 +<style>
  705 +div::-webkit-scrollbar {
  706 + width: 3px;
  707 + height: 10px;
  708 +}
  709 +div::-webkit-scrollbar-thumb {
  710 + border-radius: 10px;
  711 + background-color: #ccc;
  712 +}
  713 +</style>
  714 +<style lang="scss" scoped>
  715 +.page-container {
  716 + position: relative;
  717 + height: 100%;
  718 + &.active {
  719 + overflow: hidden;
  720 + }
  721 +}
  722 +.table-box {
  723 + margin: 0 20px;
  724 + padding: 16px;
  725 + background: #f8f8f8;
  726 + border-radius: 5px;
  727 + :deep(.fa-arrow-right) {
  728 + padding-left: 2px;
  729 + }
  730 + :deep(.fa-file-text) {
  731 + padding-left: 2px;
  732 + }
  733 +}
  734 +.click-b {
  735 + cursor: pointer;
  736 + color: #409eff;
  737 + text-decoration: underline;
  738 +}
  739 +.down {
  740 + padding-top: 16px;
  741 +}
  742 +</style>
0 743 \ No newline at end of file
... ...
src/views/personal/test/index.vue
... ... @@ -79,12 +79,14 @@
79 79 @change="changeTab"
80 80 style="margin-bottom: 20px"
81 81 >
82   - <el-radio-button :label="1">单卷测练报表</el-radio-button>
83   - <el-radio-button
84   - :label="2"
85   - v-show="this.query.startDay != this.query.endDay"
86   - >阶段测练报表</el-radio-button
87   - >
  82 + <template v-for="(item, index) in tabList">
  83 + <el-radio-button
  84 + v-if="index == 0 || query.startDay != query.endDay"
  85 + :key="index"
  86 + :label="index + 1"
  87 + >{{ item }}</el-radio-button
  88 + >
  89 + </template>
88 90 </el-radio-group>
89 91 <div v-show="tabIndex == 1" v-loading="loading">
90 92 <el-table :data="tableData" border style="width: 100%">
... ... @@ -438,6 +440,7 @@ export default {
438 440 endDay: "",
439 441 day: "",
440 442 },
  443 + tabList: ["单卷测练报表", "阶段测练报表"],
441 444 classList: [], //班级
442 445 subjectList: [], //科目
443 446 tabIndex: 1, //选项卡
... ... @@ -450,6 +453,9 @@ export default {
450 453 },
451 454 async created() {
452 455 await this._QueryClassList();
  456 + if (!this.query.classId) {
  457 + return;
  458 + }
453 459 await this._QuerySubjectList();
454 460 await this.setDate(1);
455 461 let startDay = this.query?.startDay;
... ... @@ -461,19 +467,22 @@ export default {
461 467 activated() {
462 468 const that = this;
463 469 BusEvent.$on("keepAlive", async function () {
464   - await that._QueryClassList();
465   - await that._QuerySubjectList();
466   - await that.setDate(1);
467   - let startDay = that.query?.startDay;
468   - if (!startDay) {
469   - that.query.startDay = new Date();
470   - that.query.endDay = new Date();
471   - }
  470 + await that._QueryClassList();
  471 + if (!that.query.classId) {
  472 + return;
  473 + }
  474 + await that._QuerySubjectList();
  475 + await that.setDate(1);
  476 + let startDay = that.query?.startDay;
  477 + if (!startDay) {
  478 + that.query.startDay = new Date();
  479 + that.query.endDay = new Date();
  480 + }
472 481 });
473 482 },
474 483 methods: {
475 484 print() {
476   - tablePrint("print-content");
  485 + tablePrint("print-content", "即时测-" + this.tabList[this.tabIndex - 1]);
477 486 },
478 487 changeSub(val) {
479 488 let sub;
... ... @@ -622,9 +631,9 @@ export default {
622 631 this.page = 1;
623 632 this._QueryData();
624 633 },
625   - upSuccess(res) {
626   - //导入成功
627   - this.$message.success("导入成功")
  634 + upSuccess(res) {
  635 + //导入成功
  636 + this.$message.success("导入成功");
628 637 this.diaUp = false;
629 638 this._QueryData();
630 639 },
... ...
src/views/standard/ask/analysis.vue
... ... @@ -9,27 +9,11 @@
9 9 <div class="tab-box">
10 10 <span
11 11 class="tab-item"
12   - :class="type == 1 ? 'active' : ''"
13   - @click="setType(1)"
14   - >答题表现</span
15   - >
16   - <span
17   - class="tab-item"
18   - :class="type == 2 ? 'active' : ''"
19   - @click="setType(2)"
20   - >学生问答表现</span
21   - >
22   - <span
23   - class="tab-item"
24   - :class="type == 3 ? 'active' : ''"
25   - @click="setType(3)"
26   - >学生互动表现</span
27   - >
28   - <span
29   - class="tab-item"
30   - :class="type == 4 ? 'active' : ''"
31   - @click="setType(4)"
32   - >签到明细</span
  12 + v-for="(item, index) in tabList"
  13 + :key="index"
  14 + :class="type == index + 1 ? 'active' : ''"
  15 + @click="setType(index + 1)"
  16 + >{{ item }}</span
33 17 >
34 18 </div>
35 19 <div v-loading="loading">
... ... @@ -353,22 +337,28 @@ export default {
353 337 id: "",
354 338 questionList: [],
355 339 },
  340 + tabList: ["答题表现", "学生问答表现", "学生互动表现", "签到明细"],
356 341 detail: {},
357 342 tableData: [],
358 343 optionsList: [],
359 344 page: 1,
360 345 size: 20,
361 346 total: 0,
  347 + status: 0,
362 348 };
363 349 },
364 350 created() {
365 351 this.id = this.$route.query.id;
  352 + this.status = this.$route.query.status ? this.$route.query.status : 0;
366 353 this._QueryData();
367 354 this.periodDetail();
368 355 },
369 356 methods: {
370 357 print() {
371   - tablePrint("print-content");
  358 + tablePrint(
  359 + "print-content",
  360 + this.detail.title + "_" + this.tabList[this.type - 1]
  361 + );
372 362 },
373 363 setType(type) {
374 364 this.type = type;
... ... @@ -522,7 +512,7 @@ export default {
522 512 let blob = new Blob([data], {
523 513 type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
524 514 });
525   - downloadFile("随堂问-单课时报表.xlsx", blob);
  515 + downloadFile(this.status?"随堂问-已归档单课时报表.xlsx":"随堂问-单课时报表.xlsx", blob);
526 516 } else {
527 517 this.$message.error("下载失败");
528 518 }
... ...
src/views/standard/ask/archiving.vue 0 → 100644
  1 +<template>
  2 + <div class="main" ref="main">
  3 + <back-box>
  4 + <template slot="title">
  5 + <span>问答-已归档数据报表</span>
  6 + </template>
  7 + </back-box>
  8 + <div class="answer-header">
  9 + <div class="sel-box">
  10 + <el-select
  11 + class="sel"
  12 + v-model="query.classId"
  13 + placeholder="选择班级"
  14 + @change="changeclass"
  15 + >
  16 + <el-option
  17 + v-for="item in classList"
  18 + :key="item.value"
  19 + :label="item.label"
  20 + :value="item.value"
  21 + >
  22 + </el-option>
  23 + </el-select>
  24 + <el-select
  25 + v-if="role == 'ROLE_BANZHUREN' || role == 'ROLE_PERSONAL'"
  26 + class="sel"
  27 + multiple
  28 + v-model="query.subjectNames"
  29 + placeholder="选择科目"
  30 + @change="changeSub"
  31 + >
  32 + <el-option
  33 + v-for="item in subjectList"
  34 + :key="item.value"
  35 + :label="item.label"
  36 + :value="item.value"
  37 + >
  38 + </el-option>
  39 + </el-select>
  40 + <el-select
  41 + v-else
  42 + class="sel"
  43 + v-model="query.subjectNames"
  44 + placeholder="选择科目"
  45 + >
  46 + <el-option
  47 + v-for="item in subjectList"
  48 + :key="item.value"
  49 + :label="item.label"
  50 + :value="item.value"
  51 + >
  52 + </el-option>
  53 + </el-select>
  54 + <div class="d1">
  55 + <el-date-picker
  56 + v-model="query.startDay"
  57 + type="date"
  58 + @change="handleChangeTimeStart"
  59 + placeholder="选择日期时间"
  60 + value-format="yyyy-MM-dd"
  61 + >
  62 + </el-date-picker>
  63 + ~
  64 + <el-date-picker
  65 + v-model="query.endDay"
  66 + type="date"
  67 + placeholder="选择日期时间"
  68 + @change="handleChangeTimeEnd"
  69 + value-format="yyyy-MM-dd"
  70 + >
  71 + </el-date-picker>
  72 + </div>
  73 + <p class="p1">
  74 + <span @click="setDate(1)" :class="[date == 1 ? 'active' : '', 's1']"
  75 + >今天</span
  76 + >
  77 + <span @click="setDate(2)" :class="[date == 2 ? 'active' : '', 's1']"
  78 + >本周</span
  79 + >
  80 + <span @click="setDate(3)" :class="[date == 3 ? 'active' : '', 's1']"
  81 + >本月</span
  82 + >
  83 + <span @click="setDate(4)" :class="[date == 4 ? 'active' : '', 's1']"
  84 + >本季度</span
  85 + >
  86 + </p>
  87 + <el-button type="primary" round @click="_QueryData()">筛选</el-button>
  88 + </div>
  89 + </div>
  90 + <div class="table-box">
  91 + <el-radio-group
  92 + v-model="tabIndex"
  93 + @change="tabChange"
  94 + style="margin-bottom: 20px"
  95 + >
  96 + <template v-for="(item, index) in tabList">
  97 + <el-radio-button
  98 + v-if="index == 0 || query.startDay != query.endDay"
  99 + :key="index"
  100 + :label="index + 1"
  101 + >{{ item }}</el-radio-button
  102 + >
  103 + </template>
  104 + </el-radio-group>
  105 + <div class="table-cont" v-loading="loading">
  106 + <div id="print-content">
  107 + <div v-show="tabIndex == 1">
  108 + <el-table
  109 + :data="tableData"
  110 + border
  111 + style="width: 100%"
  112 + @sort-change="sortChange"
  113 + >
  114 + <el-table-column
  115 + prop="title"
  116 + label="课时"
  117 + align="center"
  118 + ></el-table-column>
  119 + <el-table-column
  120 + prop="questionNum"
  121 + label="题目总数"
  122 + align="center"
  123 + width="100"
  124 + ></el-table-column>
  125 + <el-table-column
  126 + prop="startTime"
  127 + label="上课时间"
  128 + align="center"
  129 + ></el-table-column>
  130 + <el-table-column
  131 + prop="participationRate"
  132 + label="参与度"
  133 + sortable="custom"
  134 + align="center"
  135 + >
  136 + <template slot-scope="scoped"
  137 + >{{ scoped.row.participationRate }}%</template
  138 + ></el-table-column
  139 + >
  140 + <el-table-column
  141 + prop="answerCorrectRate"
  142 + label="已答总正确率"
  143 + sortable="custom"
  144 + align="center"
  145 + >
  146 + <template slot-scope="scoped"
  147 + >{{ scoped.row.answerCorrectRate }}%</template
  148 + >
  149 + </el-table-column>
  150 + <el-table-column
  151 + prop="classCorrectRate"
  152 + label="班级总正确率"
  153 + sortable="custom"
  154 + align="center"
  155 + ><template slot-scope="scoped"
  156 + >{{ scoped.row.classCorrectRate }}%</template
  157 + ></el-table-column
  158 + >
  159 + <el-table-column label="操作" align="center">
  160 + <template slot-scope="scoped">
  161 + <el-tooltip effect="dark" content="详情" placement="top">
  162 + <el-button
  163 + type="primary"
  164 + circle
  165 + size="mini"
  166 + icon="fa fa-arrow-right"
  167 + @click="linkTo(scoped.row)"
  168 + ></el-button>
  169 + </el-tooltip>
  170 + </template>
  171 + </el-table-column>
  172 + </el-table>
  173 + </div>
  174 + <div v-show="tabIndex == 2">
  175 + <el-table
  176 + id="print-content2"
  177 + v-if="role == 'ROLE_JIAOSHI'"
  178 + :max-height="tableMaxHeight"
  179 + :data="tableData"
  180 + border
  181 + style="width: 100%"
  182 + >
  183 + <el-table-column
  184 + prop="studentCode"
  185 + label="学号"
  186 + fixed
  187 + align="center"
  188 + ></el-table-column>
  189 + <el-table-column
  190 + prop="studentName"
  191 + label="姓名"
  192 + fixed
  193 + align="center"
  194 + width="100"
  195 + ></el-table-column>
  196 + <el-table-column
  197 + prop="answerTimes"
  198 + label="累计答题次数"
  199 + sortable
  200 + align="center"
  201 + ></el-table-column>
  202 + <el-table-column
  203 + prop="correctAnswerTimes"
  204 + label="累计答对次数"
  205 + sortable
  206 + align="center"
  207 + ></el-table-column>
  208 + <el-table-column
  209 + prop="participationRate"
  210 + label="总参与度"
  211 + sortable
  212 + align="center"
  213 + >
  214 + <template slot-scope="scoped"
  215 + >{{ scoped.row.participationRate }}%</template
  216 + ></el-table-column
  217 + >
  218 + <el-table-column
  219 + prop="correctRate"
  220 + label="总正确率"
  221 + sortable
  222 + align="center"
  223 + >
  224 + <template slot-scope="scoped"
  225 + >{{ scoped.row.correctRate }}%</template
  226 + ></el-table-column
  227 + >
  228 + <el-table-column
  229 + prop="answerCorrectRate"
  230 + label="已答总正确率"
  231 + sortable
  232 + align="center"
  233 + >
  234 + <template slot-scope="scoped"
  235 + >{{ scoped.row.answerCorrectRate }}%</template
  236 + >
  237 + </el-table-column>
  238 + <el-table-column
  239 + prop="classRank"
  240 + label="总正确率班排名"
  241 + sortable
  242 + align="center"
  243 + ></el-table-column>
  244 + </el-table>
  245 + <el-table
  246 + id="print-content2"
  247 + :max-height="tableMaxHeight"
  248 + v-else
  249 + :data="tableData"
  250 + border
  251 + style="width: 100%"
  252 + >
  253 + <el-table-column
  254 + prop="studentCode"
  255 + label="学号"
  256 + align="center"
  257 + fixed
  258 + ></el-table-column>
  259 + <el-table-column
  260 + prop="studentName"
  261 + label="姓名"
  262 + align="center"
  263 + fixed
  264 + width="100"
  265 + ></el-table-column>
  266 + <el-table-column
  267 + v-for="(item, index) in phaseOption"
  268 + :key="index"
  269 + :label="item"
  270 + align="center"
  271 + >
  272 + <el-table-column
  273 + align="center"
  274 + :label="index == 0 ? '总课时数' : '课时数'"
  275 + :prop="'periodCount' + item"
  276 + >
  277 + </el-table-column>
  278 + <el-table-column
  279 + align="center"
  280 + :label="index == 0 ? '总出题数' : '出题数'"
  281 + :prop="'questionNum' + item"
  282 + >
  283 + </el-table-column>
  284 + <el-table-column
  285 + align="center"
  286 + :label="index == 0 ? '总参与度' : '参与度'"
  287 + :prop="'participationRate' + item"
  288 + ><template slot-scope="scoped"
  289 + >{{ scoped.row["participationRate" + item] }}%</template
  290 + >
  291 + </el-table-column>
  292 + <el-table-column
  293 + align="center"
  294 + :label="index == 0 ? '总正确率' : '正确率'"
  295 + :prop="'correctRate' + item"
  296 + ><template slot-scope="scoped"
  297 + >{{ scoped.row["correctRate" + item] }}%</template
  298 + >
  299 + </el-table-column>
  300 + </el-table-column>
  301 + </el-table>
  302 + </div>
  303 + <div v-show="tabIndex == 3">
  304 + <el-table
  305 + id="print-content3"
  306 + v-if="role == 'ROLE_JIAOSHI'"
  307 + :max-height="tableMaxHeight"
  308 + :data="tableData"
  309 + border
  310 + style="width: 100%"
  311 + >
  312 + <el-table-column
  313 + prop="studentCode"
  314 + label="学号"
  315 + fixed
  316 + align="center"
  317 + ></el-table-column>
  318 + <el-table-column
  319 + prop="studentName"
  320 + label="姓名"
  321 + fixed
  322 + align="center"
  323 + width="100"
  324 + ></el-table-column>
  325 + <el-table-column
  326 + prop="rushAnswerTimes"
  327 + label="抢答成功次数"
  328 + sortable
  329 + align="center"
  330 + ></el-table-column>
  331 + <el-table-column
  332 + prop="rushAnswerCorrectTimes"
  333 + label="抢答答对次数"
  334 + sortable
  335 + align="center"
  336 + ></el-table-column>
  337 + <el-table-column
  338 + prop="checkAnswerTimes"
  339 + label="抽答次数"
  340 + sortable
  341 + align="center"
  342 + ></el-table-column>
  343 + <el-table-column
  344 + prop="checkAnswerCorrectTimes"
  345 + label="抽答答对次数"
  346 + sortable
  347 + align="center"
  348 + ></el-table-column>
  349 + <el-table-column
  350 + prop="interactionsNum"
  351 + label="参与得分"
  352 + sortable
  353 + align="center"
  354 + ></el-table-column>
  355 + <el-table-column
  356 + prop="interactionsCorrectNum"
  357 + label="对错得分"
  358 + sortable
  359 + align="center"
  360 + ></el-table-column>
  361 + </el-table>
  362 + <el-table
  363 + id="print-content3"
  364 + v-else
  365 + :max-height="tableMaxHeight"
  366 + :data="tableData"
  367 + border
  368 + style="width: 100%"
  369 + >
  370 + <el-table-column
  371 + prop="studentCode"
  372 + label="学号"
  373 + align="center"
  374 + ></el-table-column>
  375 + <el-table-column
  376 + prop="studentName"
  377 + label="姓名"
  378 + align="center"
  379 + width="100"
  380 + ></el-table-column>
  381 + <el-table-column
  382 + v-for="(item, index) in phaseInter"
  383 + :key="index"
  384 + :label="item"
  385 + align="center"
  386 + >
  387 + <el-table-column
  388 + align="center"
  389 + v-if="index == 0"
  390 + label="参与分"
  391 + sortable
  392 + :prop="'interactionsNum' + item"
  393 + >
  394 + </el-table-column>
  395 + <el-table-column
  396 + v-else
  397 + align="center"
  398 + label="互动数"
  399 + :prop="'interactionsNum' + item"
  400 + >
  401 + </el-table-column>
  402 + <el-table-column
  403 + v-if="index == 0"
  404 + align="center"
  405 + label="对错分"
  406 + sortable
  407 + :prop="'interactionsCorrectNum' + item"
  408 + >
  409 + </el-table-column>
  410 + <el-table-column
  411 + v-else
  412 + align="center"
  413 + label="参与数"
  414 + :prop="'interactionsCorrectNum' + item"
  415 + >
  416 + </el-table-column>
  417 + </el-table-column>
  418 + </el-table>
  419 + </div>
  420 + </div>
  421 + <div class="pagination-box" v-show="tabIndex == 1">
  422 + <el-pagination
  423 + small=""
  424 + layout="total,prev, pager, next"
  425 + :hide-on-single-page="true"
  426 + :total="total"
  427 + @current-change="changePage"
  428 + :current-page="page"
  429 + :page-size="size"
  430 + >
  431 + </el-pagination>
  432 + </div>
  433 + <p
  434 + class="down"
  435 + v-if="(tabIndex == 3 || tabIndex == 2) && tableData.length"
  436 + >
  437 + <el-button
  438 + @click="exportData"
  439 + type="primary"
  440 + plain
  441 + round
  442 + icon="fa fa-cloud-download"
  443 + >导出报表</el-button
  444 + >
  445 + <el-button
  446 + v-if="!this.$store.getters.code"
  447 + @click="print"
  448 + type="primary"
  449 + plain
  450 + round
  451 + icon="el-icon-printer"
  452 + >打印</el-button
  453 + >
  454 + </p>
  455 + </div>
  456 + </div>
  457 + </div>
  458 +</template>
  459 +
  460 +<script>
  461 +import { formatDate, downloadFile, tablePrint } from "utils";
  462 +import BusEvent from "@/utils/busEvent";
  463 +export default {
  464 + data() {
  465 + return {
  466 + tableMaxHeight: 300,
  467 + code: "",
  468 + role: "",
  469 + loading: false,
  470 + date: "", //今天-昨天-本周
  471 + query: {
  472 + //搜索条件
  473 + classId: "",
  474 + subjectNames: "",
  475 + startDay: "",
  476 + endDay: "",
  477 + day: "",
  478 + },
  479 + tabList: ["单课时报表", "阶段问答报表", "阶段互动报表"],
  480 + custom: {
  481 + //单课时排序
  482 + orderField: null,
  483 + orderType: null,
  484 + },
  485 + classList: [], //班级
  486 + subjectList: [], //科目
  487 + tabIndex: 1, //选项卡
  488 + tableData: [],
  489 + phaseOption: [], //问答补充数据
  490 + phaseInter: [], //互动补充数据
  491 + page: 1,
  492 + size: 20,
  493 + total: 0,
  494 + };
  495 + },
  496 + async created() {
  497 + this.code = localStorage.getItem("csCode") || "";
  498 + this.role =
  499 + this.$store.getters.info.showRole ||
  500 + this.$store.getters.info.permissions[0].role;
  501 + this.query.subjectNames = this.role == "ROLE_BANZHUREN" ? [] : "";
  502 + await this._QueryClassList();
  503 + if (!this.query.classId) {
  504 + return;
  505 + }
  506 + await this._QuerySubjectList();
  507 + await this.setDate(1);
  508 + let startDay = this.query?.startDay;
  509 + if (!startDay) {
  510 + this.query.startDay = new Date();
  511 + this.query.endDay = new Date();
  512 + }
  513 + },
  514 + activated() {
  515 + const that = this;
  516 + BusEvent.$on("keepAlive", async function () {
  517 + that.query.subjectNames = that.role == "ROLE_BANZHUREN" ? [] : "";
  518 + await that._QueryClassList();
  519 + if (!that.query.classId) {
  520 + return;
  521 + }
  522 + await that._QuerySubjectList();
  523 + await that.setDate(1);
  524 + let startDay = that.query?.startDay;
  525 + if (!startDay) {
  526 + that.query.startDay = new Date();
  527 + that.query.endDay = new Date();
  528 + }
  529 + });
  530 + },
  531 + methods: {
  532 + print() {
  533 + tablePrint(
  534 + "print-content",
  535 + "随堂问-已归档" + this.tabList[this.tabIndex - 1]
  536 + );
  537 + },
  538 + changeSub(val) {
  539 + let sub;
  540 + if (val && val.length) {
  541 + let leng = val.length - 1;
  542 + sub = val[leng];
  543 + }
  544 + console.log(val);
  545 + this.query.subjectNames = val.filter((item) => {
  546 + return sub != "全部" ? item != "全部" : item == "全部";
  547 + });
  548 + },
  549 + linkTo(obj) {
  550 + //去详情
  551 + this.$router.push({
  552 + path: "/askAnalysis",
  553 + query: {
  554 + id: obj.id,
  555 + status: 1,
  556 + },
  557 + });
  558 + },
  559 + setDate(index) {
  560 + const that = this;
  561 + this.date = index == this.date ? "" : index;
  562 + let aYear = new Date().getFullYear();
  563 + let aMonth = new Date().getMonth() + 1;
  564 + that.query.day = "";
  565 + that.query.startDay = "";
  566 + that.query.endDay = "";
  567 + switch (index) {
  568 + case 1:
  569 + that.query.day = formatDate(new Date(), "yyyy-MM-dd");
  570 + that.query.startDay = that.query.day;
  571 + that.query.endDay = that.query.day;
  572 + that.tabIndex = 1;
  573 + break;
  574 + case 2:
  575 + let day = new Date().getDay();
  576 + if (day == 0) {
  577 + //中国式星期天是一周的最后一天
  578 + day = 7;
  579 + }
  580 + day--;
  581 + let aTime = new Date().getTime() - 24 * 60 * 60 * 1000 * day;
  582 + that.query.startDay = formatDate(new Date(aTime), "yyyy-MM-dd");
  583 + that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
  584 + break;
  585 + case 3:
  586 + aMonth = aMonth < 10 ? "0" + aMonth : aMonth;
  587 + that.query.startDay = `${aYear}-${aMonth}-01`;
  588 + that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
  589 + break;
  590 + case 4:
  591 + if (aMonth > 0 && aMonth < 4) {
  592 + aMonth = "1";
  593 + } else if (aMonth > 3 && aMonth < 7) {
  594 + aMonth = "4";
  595 + } else if (aMonth > 6 && aMonth < 10) {
  596 + aMonth = "7";
  597 + } else {
  598 + aMonth = "10";
  599 + }
  600 +
  601 + aMonth = aMonth < 10 ? "0" + aMonth : aMonth;
  602 + that.query.startDay = `${aYear}-${aMonth}-01`;
  603 + that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
  604 + break;
  605 + }
  606 + this.page = 1;
  607 + this._QueryData();
  608 + },
  609 + handleChangeTimeStart(val) {
  610 + this.query.day = "";
  611 + this.date = "";
  612 + if (this.query.endDay) {
  613 + if (new Date(val).getTime() > new Date(this.query.endDay).getTime()) {
  614 + this.$message.error("任务结束时间不能任务开始时间前面,请重新设置");
  615 + this.query.startDay = "";
  616 + }
  617 + }
  618 + },
  619 + handleChangeTimeEnd(val) {
  620 + this.query.day = "";
  621 + this.date = "";
  622 + if (this.query.startDay) {
  623 + if (new Date(val).getTime() < new Date(this.query.startDay).getTime()) {
  624 + this.$message.error("任务结束时间不能任务开始时间前面,请重新设置");
  625 + this.query.endDay = "";
  626 + }
  627 + }
  628 + },
  629 + tabChange() {
  630 + this.tableMaxHeight = this.$refs.main.offsetHeight;
  631 + this.page = 1;
  632 + this.tableData = [];
  633 + this._QueryData();
  634 + },
  635 + sortChange(obj) {
  636 + this.custom.orderField =
  637 + obj.prop == "participationRate"
  638 + ? 1
  639 + : obj.prop == "answerCorrectRate"
  640 + ? 2
  641 + : 3;
  642 + this.custom.orderType = obj.order == "ascending" ? 0 : 1;
  643 + this.page = 1;
  644 + this._QueryData();
  645 + },
  646 + changePage(page) {
  647 + this.page = page;
  648 + this._QueryData();
  649 + },
  650 + async changeclass() {
  651 + await this._QuerySubjectList();
  652 + this.page = 1;
  653 + this._QueryData();
  654 + },
  655 + async changClazz() {
  656 + await this._QuerySubjectList();
  657 + // await this.setDate(1);
  658 + this._QueryData();
  659 + },
  660 + async _QueryClassList() {
  661 + const fetchClassList =
  662 + this.role == "ROLE_BANZHUREN"
  663 + ? this.$request.cTClassList
  664 + : this.$request.tClassList;
  665 + const { data, status, info } = await fetchClassList({ status: 1 });
  666 + if (status === 0) {
  667 + this.classList = data.list.map((item) => {
  668 + return {
  669 + value: item.classId,
  670 + label: item.className,
  671 + };
  672 + });
  673 + this.query.classId = this.classList[0]?.value;
  674 + } else {
  675 + this.$message.error(info);
  676 + }
  677 + },
  678 + async _QuerySubjectList() {
  679 + const fetchSubjectList =
  680 + this.role == "ROLE_BANZHUREN"
  681 + ? this.$request.cTSubjectList
  682 + : this.$request.tSubjectList;
  683 +
  684 + const { data, status, info } = await fetchSubjectList({
  685 + classId: this.query.classId,
  686 + status: 1,
  687 + });
  688 + if (status === 0) {
  689 + this.subjectList =
  690 + data.subjectNames?.map((item) => {
  691 + return {
  692 + value: item,
  693 + label: item,
  694 + };
  695 + }) || [];
  696 + if (this.role == "ROLE_BANZHUREN") {
  697 + this.subjectList.unshift({
  698 + value: "全部",
  699 + label: "全部",
  700 + });
  701 + this.query.subjectNames.push(this.subjectList[0]?.value);
  702 + } else {
  703 + this.query.subjectNames = this.subjectList[0]?.value;
  704 + }
  705 + } else {
  706 + this.$message.error(info);
  707 + }
  708 + },
  709 + async _QueryData() {
  710 + if (this.tabIndex == 1) {
  711 + this.periodReportList();
  712 + } else if (this.tabIndex == 2) {
  713 + this.phaseAnswerReport();
  714 + } else if (this.tabIndex == 3) {
  715 + this.phaseInteractiveReport();
  716 + }
  717 + },
  718 + //分页查询课时报表列表
  719 + async periodReportList() {
  720 + this.loading = true;
  721 + let query = {};
  722 + for (let key in this.query) {
  723 + if (this.query[key] != "") {
  724 + query[key] = this.query[key];
  725 + }
  726 + }
  727 + if (this.custom.orderField !== null) {
  728 + query = { ...query, ...this.custom };
  729 + }
  730 + if (this.role != "ROLE_BANZHUREN") {
  731 + query.subjectNames = [query.subjectNames];
  732 + } else {
  733 + if (
  734 + query["subjectNames"] &&
  735 + query["subjectNames"].length == 1 &&
  736 + query["subjectNames"][0] == "全部"
  737 + ) {
  738 + query["subjectNames"] = this.subjectList.map((item) => {
  739 + return item.value;
  740 + });
  741 + query["subjectNames"].shift();
  742 + }
  743 + if (!query["subjectNames"]) {
  744 + this.$message.warning("请选择科目");
  745 + return;
  746 + }
  747 + }
  748 + const { data, status, info } = await this.$request.periodReportList({
  749 + ...query,
  750 + page: this.page,
  751 + size: this.size,
  752 + });
  753 + this.loading = false;
  754 + if (status === 0) {
  755 + this.tableData = (data?.list && [...data?.list]) || [];
  756 + this.total = data?.count || 0;
  757 + } else {
  758 + this.$message.error(info);
  759 + }
  760 + },
  761 + //查询阶段问答报表
  762 + async phaseAnswerReport() {
  763 + this.loading = true;
  764 + let query = {};
  765 + for (let key in this.query) {
  766 + if (this.query[key] != "") {
  767 + if (key == "subjectNames" && this.role != "ROLE_BANZHUREN") {
  768 + query["subjectName"] = this.query[key];
  769 + } else {
  770 + query[key] = this.query[key];
  771 + }
  772 + }
  773 + }
  774 + if (this.role == "ROLE_BANZHUREN") {
  775 + if (
  776 + query["subjectNames"] &&
  777 + query["subjectNames"].length == 1 &&
  778 + query["subjectNames"][0] == "全部"
  779 + ) {
  780 + query["subjectNames"] = this.subjectList.map((item) => {
  781 + return item.value;
  782 + });
  783 + query["subjectNames"].shift();
  784 + }
  785 + if (!query["subjectNames"]) {
  786 + this.$message.warning("请选择科目");
  787 + return;
  788 + }
  789 + }
  790 + const phaseAnswerReport =
  791 + this.role == "ROLE_BANZHUREN"
  792 + ? this.$request.cTPhaseAnswerReport
  793 + : this.$request.phaseAnswerReport;
  794 +
  795 + const { data, status, info } = await phaseAnswerReport({
  796 + ...query,
  797 + });
  798 + this.loading = false;
  799 + if (status === 0) {
  800 + if (this.role == "ROLE_BANZHUREN") {
  801 + let subjectName = [];
  802 + let tableData = data?.list.map((item) => {
  803 + let params = {};
  804 + item.dataList.map((items, index) => {
  805 + if (!subjectName.includes(items.subjectName)) {
  806 + subjectName.push(items.subjectName);
  807 + }
  808 + params["answerCorrectRate" + items.subjectName] =
  809 + items.answerCorrectRate;
  810 + params["correctRate" + items.subjectName] = items.correctRate;
  811 + params["participationRate" + items.subjectName] =
  812 + items.participationRate;
  813 + params["periodCount" + items.subjectName] = items.periodCount;
  814 + params["questionNum" + items.subjectName] = items.questionNum;
  815 + });
  816 + return {
  817 + ...item,
  818 + ...params,
  819 + };
  820 + });
  821 + this.phaseOption = [...subjectName];
  822 + this.tableData = tableData.sort((a, b) => {
  823 + return a.studentCode - b.studentCode;
  824 + });
  825 + } else {
  826 + this.tableData =
  827 + (data?.list &&
  828 + [...data?.list].sort((a, b) => {
  829 + return a.studentCode - b.studentCode;
  830 + })) ||
  831 + [];
  832 + }
  833 + this.total = data.count;
  834 + } else {
  835 + this.$message.error(info);
  836 + }
  837 + },
  838 + //查询阶段互动报表
  839 + async phaseInteractiveReport() {
  840 + this.loading = true;
  841 + let query = {};
  842 + for (let key in this.query) {
  843 + if (this.query[key] != "") {
  844 + if (key == "subjectNames" && this.role != "ROLE_BANZHUREN") {
  845 + query["subjectName"] = this.query[key];
  846 + } else {
  847 + query[key] = this.query[key];
  848 + }
  849 + }
  850 + }
  851 + if (this.role == "ROLE_BANZHUREN") {
  852 + if (
  853 + query["subjectNames"] &&
  854 + query["subjectNames"].length == 1 &&
  855 + query["subjectNames"][0] == "全部"
  856 + ) {
  857 + query["subjectNames"] = this.subjectList.map((item) => {
  858 + return item.value;
  859 + });
  860 + query["subjectNames"].shift();
  861 + }
  862 + if (!query["subjectNames"]) {
  863 + this.$message.warning("请选择科目");
  864 + return;
  865 + }
  866 + }
  867 + const phaseInteractiveReport =
  868 + this.role == "ROLE_BANZHUREN"
  869 + ? this.$request.cTPhaseInteractiveReport
  870 + : this.$request.phaseInteractiveReport;
  871 +
  872 + const { data, status, info } = await phaseInteractiveReport({
  873 + ...query,
  874 + });
  875 + this.loading = false;
  876 + if (status === 0) {
  877 + if (this.role == "ROLE_BANZHUREN") {
  878 + let subjectName = [];
  879 + let tableData = data?.list.map((item) => {
  880 + let params = {};
  881 + item.dataList.map((items, index) => {
  882 + if (!subjectName.includes(items.subjectName)) {
  883 + subjectName.push(items.subjectName);
  884 + }
  885 + params["interactionsNum" + items.subjectName] =
  886 + items.interactionsNum;
  887 + params["interactionsCorrectNum" + items.subjectName] =
  888 + items.interactionsCorrectNum;
  889 + });
  890 + return {
  891 + ...item,
  892 + ...params,
  893 + };
  894 + });
  895 + this.phaseInter = [...subjectName];
  896 + this.tableData = tableData.sort((a, b) => {
  897 + return a.studentCode - b.studentCode;
  898 + });
  899 + } else {
  900 + this.tableData =
  901 + (data?.list &&
  902 + [...data?.list].sort((a, b) => {
  903 + return a.studentCode - b.studentCode;
  904 + })) ||
  905 + [];
  906 + }
  907 + this.total = data.count;
  908 + } else {
  909 + this.$message.error(info);
  910 + }
  911 + },
  912 + //导出
  913 + async exportData() {
  914 + if (this.exportLoading == true) return;
  915 + let query = {};
  916 + for (let key in this.query) {
  917 + if (this.query[key] != "") {
  918 + if (key == "subjectNames" && this.role != "ROLE_BANZHUREN") {
  919 + query["subjectName"] = this.query[key];
  920 + } else {
  921 + query[key] = this.query[key];
  922 + }
  923 + }
  924 + }
  925 + if (this.role == "ROLE_BANZHUREN") {
  926 + if (
  927 + query["subjectNames"] &&
  928 + query["subjectNames"].length == 1 &&
  929 + query["subjectNames"][0] == "全部"
  930 + ) {
  931 + query["subjectNames"] = this.subjectList.map((item) => {
  932 + return item.value;
  933 + });
  934 + query["subjectNames"].shift();
  935 + }
  936 + if (!query["subjectNames"]) {
  937 + this.$message.warning("请选择科目");
  938 + return;
  939 + }
  940 + }
  941 + this.exportLoading = true;
  942 + let exportData;
  943 + if (this.role == "ROLE_BANZHUREN") {
  944 + exportData =
  945 + this.tabIndex == 2
  946 + ? this.$request.cTExportPhaseAnswerReport
  947 + : this.$request.cTExportPhaseInteractiveReport;
  948 + } else {
  949 + exportData =
  950 + this.tabIndex == 2
  951 + ? this.$request.exportPhaseAnswerReport
  952 + : this.$request.exportPhaseInteractiveReport;
  953 + }
  954 + const data = await exportData({ ...query });
  955 + this.exportLoading = false;
  956 + if (data) {
  957 + let blob = new Blob([data], {
  958 + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  959 + });
  960 + downloadFile("随堂问-已归档阶段报表.xlsx", blob);
  961 + } else {
  962 + this.$message.error("下载失败");
  963 + }
  964 + },
  965 + },
  966 +};
  967 +</script>
  968 +<style>
  969 +div::-webkit-scrollbar {
  970 + width: 3px;
  971 + height: 10px;
  972 +}
  973 +div::-webkit-scrollbar-thumb {
  974 + border-radius: 10px;
  975 + background-color: #ccc;
  976 +}
  977 +</style>
  978 +<style lang="scss" scoped>
  979 +.main {
  980 + height: 100%;
  981 +}
  982 +.table-box {
  983 + margin: 0 20px;
  984 + padding: 16px;
  985 + background: #f8f8f8;
  986 + border-radius: 5px;
  987 + .table-cont {
  988 + min-height: 300px;
  989 + }
  990 + :deep(.fa-arrow-right) {
  991 + padding-left: 2px;
  992 + }
  993 + :deep(.fa-file-text) {
  994 + padding-left: 2px;
  995 + }
  996 +}
  997 +
  998 +.fa-exchange {
  999 + color: #667ffd;
  1000 + cursor: pointer;
  1001 + font-size: 16px;
  1002 + margin-left: 10px;
  1003 +}
  1004 +.dia-btn {
  1005 + border-radius: 20px;
  1006 + margin: 0 20px;
  1007 + padding: 10px 20px;
  1008 +}
  1009 +.dia-tips {
  1010 + padding-bottom: 10px;
  1011 +}
  1012 +.dia-question-box {
  1013 + padding: 16px 16px 1px;
  1014 + background: #f8f8f8;
  1015 + border-radius: 10px;
  1016 +
  1017 + .answer-s {
  1018 + width: 36px;
  1019 + height: 28px;
  1020 + cursor: pointer;
  1021 + }
  1022 +}
  1023 +.set-questions {
  1024 + display: flex;
  1025 + margin-bottom: 12px;
  1026 + width: 100%;
  1027 + .qs-num {
  1028 + flex-shrink: 0;
  1029 + margin-right: 10px;
  1030 + }
  1031 + .qs-options {
  1032 + flex: 1;
  1033 + .ipt {
  1034 + margin-bottom: 5px;
  1035 + }
  1036 + }
  1037 + .delButton {
  1038 + border-color: #ff6868;
  1039 + background: #ff6868 url("../../../assets/images/arrow.png") no-repeat center;
  1040 + background-size: 19px;
  1041 + color: transparent;
  1042 + }
  1043 + .ac {
  1044 + border-color: #ff6868;
  1045 + background: #ff6868;
  1046 + color: #fff;
  1047 + }
  1048 +}
  1049 +.down {
  1050 + padding-top: 16px;
  1051 +}
  1052 +</style>
0 1053 \ No newline at end of file
... ...
src/views/standard/ask/index.vue
... ... @@ -4,6 +4,23 @@
4 4 <template slot="title">
5 5 <span>问答-数据报表</span>
6 6 </template>
  7 + <template slot="btns">
  8 + <el-tooltip
  9 + v-if="!code"
  10 + effect="dark"
  11 + content="已归档试卷"
  12 + placement="bottom"
  13 + >
  14 + <el-button
  15 + type="primary"
  16 + icon="fa fa-archive"
  17 + size="mini"
  18 + plain
  19 + circle
  20 + @click="toArchiving"
  21 + ></el-button>
  22 + </el-tooltip>
  23 + </template>
7 24 </back-box>
8 25 <div class="answer-header">
9 26 <div class="sel-box">
... ... @@ -93,16 +110,14 @@
93 110 @change="tabChange"
94 111 style="margin-bottom: 20px"
95 112 >
96   - <el-radio-button :label="1">单课时报表</el-radio-button>
97   - <!-- <el-radio-button :label="2" v-if="this.role != 'ROLE_BANZHUREN'"
98   - >阶段问答报表</el-radio-button
99   - > -->
100   - <el-radio-button :label="2" v-if="query.startDay != query.endDay"
101   - >阶段问答报表</el-radio-button
102   - >
103   - <el-radio-button :label="3" v-if="query.startDay != query.endDay"
104   - >阶段互动报表</el-radio-button
105   - >
  113 + <template v-for="(item, index) in tabList">
  114 + <el-radio-button
  115 + v-if="index == 0 || query.startDay != query.endDay"
  116 + :key="index"
  117 + :label="index + 1"
  118 + >{{ item }}</el-radio-button
  119 + >
  120 + </template>
106 121 </el-radio-group>
107 122 <div class="table-cont" v-loading="loading">
108 123 <div id="print-content">
... ... @@ -485,6 +500,7 @@ export default {
485 500 data() {
486 501 return {
487 502 tableMaxHeight: 300,
  503 + code: "",
488 504 role: "",
489 505 loading: false,
490 506 date: "", //今天-昨天-本周
... ... @@ -496,6 +512,7 @@ export default {
496 512 endDay: "",
497 513 day: "",
498 514 },
  515 + tabList: ["单课时报表", "阶段问答报表", "阶段互动报表"],
499 516 custom: {
500 517 //单课时排序
501 518 orderField: null,
... ... @@ -513,11 +530,15 @@ export default {
513 530 };
514 531 },
515 532 async created() {
  533 + this.code = localStorage.getItem("csCode") || "";
516 534 this.role =
517 535 this.$store.getters.info.showRole ||
518 536 this.$store.getters.info.permissions[0].role;
519 537 this.query.subjectNames = this.role == "ROLE_BANZHUREN" ? [] : "";
520 538 await this._QueryClassList();
  539 + if (!this.query.classId) {
  540 + return;
  541 + }
521 542 await this._QuerySubjectList();
522 543 await this.setDate(1);
523 544 let startDay = this.query?.startDay;
... ... @@ -529,20 +550,28 @@ export default {
529 550 activated() {
530 551 const that = this;
531 552 BusEvent.$on("keepAlive", async function () {
532   - that.query.subjectNames = that.role == "ROLE_BANZHUREN" ? [] : "";
533   - await that._QueryClassList();
534   - await that._QuerySubjectList();
535   - await that.setDate(1);
536   - let startDay = that.query?.startDay;
537   - if (!startDay) {
538   - that.query.startDay = new Date();
539   - that.query.endDay = new Date();
540   - }
  553 + that.query.subjectNames = that.role == "ROLE_BANZHUREN" ? [] : "";
  554 + await that._QueryClassList();
  555 + if (!that.query.classId) {
  556 + return;
  557 + }
  558 + await that._QuerySubjectList();
  559 + await that.setDate(1);
  560 + let startDay = that.query?.startDay;
  561 + if (!startDay) {
  562 + that.query.startDay = new Date();
  563 + that.query.endDay = new Date();
  564 + }
541 565 });
542 566 },
543 567 methods: {
  568 + toArchiving() {
  569 + this.$router.push({
  570 + path: "/askArchiving",
  571 + });
  572 + },
544 573 print() {
545   - tablePrint("print-content");
  574 + tablePrint("print-content", "随堂问-" + this.tabList[this.tabIndex - 1]);
546 575 },
547 576 changeSub(val) {
548 577 let sub;
... ... @@ -926,7 +955,6 @@ export default {
926 955 this.$message.error(info);
927 956 }
928 957 },
929   - setDownQuery() {},
930 958 //导出
931 959 async exportData() {
932 960 if (this.exportLoading == true) return;
... ...
src/views/standard/card/index.vue
... ... @@ -79,7 +79,7 @@
79 79 ></el-table-column>
80 80 <el-table-column align="center" label="年级">
81 81 <template slot-scope="scope">
82   - <span>{{ scope.row.classList[0].gradeName }}</span>
  82 + <span>{{ scope.row.classList[0]?.gradeName }}</span>
83 83 </template>
84 84 </el-table-column>
85 85 <el-table-column align="center" label="班级">
... ...
src/views/standard/device/index.vue
... ... @@ -112,6 +112,23 @@
112 112 align="center"
113 113 ></el-table-column>
114 114 <el-table-column
  115 + v-if="role == 'ROLE_JITUAN'"
  116 + prop="schoolName"
  117 + label="学校"
  118 + align="center"
  119 + ></el-table-column>
  120 + <el-table-column
  121 + v-if="role == 'ROLE_JITUAN'"
  122 + prop="gradeName"
  123 + label="年级"
  124 + align="center"
  125 + ><template slot-scope="scoped">
  126 + <p v-for="(item, index) in scoped.row.classList" :key="index">
  127 + {{ item.gradeName }}
  128 + </p>
  129 + </template></el-table-column
  130 + >
  131 + <el-table-column
115 132 prop="roomName"
116 133 label="所在教室"
117 134 align="center"
... ... @@ -248,6 +265,23 @@
248 265 </p></template
249 266 ></el-table-column
250 267 >
  268 + <el-table-column
  269 + v-if="role == 'ROLE_JITUAN'"
  270 + prop="schoolName"
  271 + label="学校"
  272 + align="center"
  273 + ></el-table-column>
  274 + <el-table-column
  275 + v-if="role == 'ROLE_JITUAN'"
  276 + prop="gradeName"
  277 + label="年级"
  278 + align="center"
  279 + ><template slot-scope="scoped">
  280 + <p v-for="(item, index) in scoped.row.classList" :key="index">
  281 + {{ item.gradeName }}
  282 + </p>
  283 + </template></el-table-column
  284 + >
251 285 <el-table-column prop="class" label="关联班级" align="center">
252 286 <template slot-scope="scoped">
253 287 <p v-for="(item, index) in scoped.row.classList" :key="index">
... ... @@ -333,6 +367,12 @@
333 367 </template></el-table-column
334 368 >
335 369 <el-table-column
  370 + v-if="role == 'ROLE_JITUAN'"
  371 + prop="schoolName"
  372 + label="学校"
  373 + align="center"
  374 + ></el-table-column>
  375 + <el-table-column
336 376 prop="lastUpdateTime"
337 377 label="最近更新"
338 378 align="center"
... ... @@ -386,7 +426,7 @@
386 426 >
387 427 </el-pagination>
388 428 </div>
389   - <!-- <p class="down" v-if="tableData.length">
  429 + <p class="down" v-if="tableData.length">
390 430 <el-button
391 431 type="primary"
392 432 plain
... ... @@ -395,7 +435,7 @@
395 435 @click="downExl"
396 436 >导出报表</el-button
397 437 >
398   - </p> -->
  438 + </p>
399 439 </div>
400 440 </div>
401 441 <el-dialog title="设备导入" :visible.sync="diaUp" width="400">
... ... @@ -494,7 +534,6 @@ import scatterChart from &quot;@/components/charts/scatterChart&quot;;
494 534 import _ from "lodash";
495 535 import { downloadFile, getBlob, formatGradeNameClass } from "@/utils";
496 536 import api from "@/api/apis/apis";
497   -import BusEvent from "@/utils/busEvent";
498 537 export default {
499 538 components: { pieChart, scatterChart },
500 539 watch: {
... ... @@ -578,6 +617,7 @@ export default {
578 617 selectionTabIds: [],
579 618 page: 1,
580 619 size: 20,
  620 + isBack: false,
581 621 };
582 622 },
583 623 created() {
... ... @@ -615,16 +655,16 @@ export default {
615 655 if (this.role == "ROLE_XUEXIAO") {
616 656 this._QueryDataSchool();
617 657 }
618   - this.stationReport();
619 658 this._QueryGradeList();
620   - this._QueryData();
621 659 if (this.role == "ROLE_JITUAN") {
622 660 this.showSchool();
623 661 }
624 662 },
625 663 activated() {
626 664 const that = this;
627   - BusEvent.$on("keepAlive", async function () {
  665 + this.isBack = this.$route.query.back ? this.$route.query.back : false;
  666 + console.log(this.$route.query.back);
  667 + if (!this.isBack) {
628 668 that.type = 1;
629 669 that.page = 1;
630 670 that.total = 0;
... ... @@ -635,7 +675,7 @@ export default {
635 675 that.query.type = "";
636 676 that.stationReport();
637 677 that._QueryData();
638   - });
  678 + }
639 679 },
640 680 methods: {
641 681 upSuccess(res) {
... ... @@ -806,16 +846,14 @@ export default {
806 846 }
807 847 },
808 848 async downExl() {
809   - //报表到处
  849 + //报表导出
810 850 if (this.exportLoading == true) return;
811   - const exportPhaseExamReport =
812   - this.type == 1
813   - ? this.$request.cTExportPhaseExamReport
814   - : this.type == 1
815   - ? this.$request.exportPhaseExamReport
816   - : this.$request.exportPhaseExamReport;
  851 + let query = this.setQuery();
817 852 this.exportLoading = true;
818   - const data = await exportPhaseExamReport({ ...this.query });
  853 + const data = await this.$request.exportDevice({
  854 + ...query,
  855 + deviceType: this.type,
  856 + });
819 857 this.exportLoading = false;
820 858 if (data && !data.code) {
821 859 let blob = new Blob([data], {
... ... @@ -1114,7 +1152,7 @@ export default {
1114 1152 padding: 20px 0 12px;
1115 1153 }
1116 1154 .down {
1117   - padding:0 0 16px 20px;
  1155 + padding: 0 0 16px 20px;
1118 1156 }
1119 1157 .content {
1120 1158 background: #f8f8f8;
... ... @@ -1157,7 +1195,7 @@ export default {
1157 1195 }
1158 1196 }
1159 1197 .table-box {
1160   - padding: 20px;
  1198 + padding: 20px 20px 0;
1161 1199 .answer-header {
1162 1200 padding: 0;
1163 1201 margin-bottom: 12px;
... ...
src/views/standard/setUp/archivedClazz.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <back-box>
  4 + <template slot="title">
  5 + <span>已归档班级</span>
  6 + </template>
  7 + </back-box>
  8 + <div class="page-content" v-loading="loading">
  9 + <el-table :data="tableData" border style="width: 100%">
  10 + <el-table-column
  11 + prop="gradeName"
  12 + label="年级"
  13 + fixed
  14 + align="center"
  15 + ></el-table-column>
  16 + <el-table-column
  17 + prop="className"
  18 + label="班级名称"
  19 + fixed
  20 + align="center"
  21 + ></el-table-column>
  22 + <el-table-column
  23 + prop="studentCount"
  24 + label="学生数量"
  25 + fixed
  26 + align="center"
  27 + ></el-table-column>
  28 + <el-table-column
  29 + prop="modifiedTime"
  30 + label="归档时间"
  31 + fixed
  32 + align="center"
  33 + ></el-table-column>
  34 + </el-table>
  35 + </div>
  36 + <!-- <div class="pagination-box">
  37 + <el-pagination
  38 + small=""
  39 + layout="total,prev, pager, next"
  40 + :hide-on-single-page="true"
  41 + :total="total"
  42 + @current-change="changePage"
  43 + :current-page="page"
  44 + :page-size="size"
  45 + >
  46 + </el-pagination>
  47 + </div> -->
  48 + </div>
  49 +</template>
  50 +
  51 +<script>
  52 +export default {
  53 + data() {
  54 + return {
  55 + role: "",
  56 + loading: false,
  57 + tableData: [],
  58 + total: 0,
  59 + page: 1,
  60 + size: 20,
  61 + };
  62 + },
  63 + async created() {
  64 + this._QueryData();
  65 + },
  66 + methods: {
  67 + changePage(page) {
  68 + this.page = page;
  69 + this._QueryData(this.query.title);
  70 + },
  71 + async _QueryData() {
  72 + this.loading = true;
  73 + const { data, status, info } = await this.$request.archivingClassList();
  74 + this.loading = false;
  75 + if (status === 0) {
  76 + this.total = data.total;
  77 + this.tableData = (data.list && [...data.list]) || [];
  78 + } else {
  79 + this.$message.error(info);
  80 + }
  81 + },
  82 + },
  83 +};
  84 +</script>
  85 +
  86 +<style lang="scss" scoped>
  87 +.page-content {
  88 + padding: 20px;
  89 +}
  90 +</style>
0 91 \ No newline at end of file
... ...
src/views/standard/setUp/school.vue
... ... @@ -59,7 +59,12 @@
59 59 </li>
60 60 </ul>
61 61 <div class="grade-box">
62   - <p class="h-title">年级管理</p>
  62 + <p class="h-title">
  63 + 年级管理
  64 + <span class="popconfirm-box" @click="diaUpgradeGrade = true">
  65 + 年级升级<i class="fa fa-level-up"></i>
  66 + </span>
  67 + </p>
63 68 <ul class="grade-info">
64 69 <li
65 70 class="grade-item"
... ... @@ -205,6 +210,15 @@
205 210 <el-button @click="diaSchool = false">取 消</el-button>
206 211 </div>
207 212 </el-dialog>
  213 + <el-dialog title="班级升级" :visible.sync="diaUpgradeGrade" width="400">
  214 + <p>注意该操作会将所有年级升级,请谨慎操作!</p>
  215 + <div class="dialog-footer" slot="footer">
  216 + <el-button type="danger" @click="_UpgradeGrade()">确认升级</el-button>
  217 + <el-button type="primary" @click="diaUpgradeGrade = false"
  218 + >取 消</el-button
  219 + >
  220 + </div>
  221 + </el-dialog>
208 222 </div>
209 223 </template>
210 224  
... ... @@ -300,6 +314,7 @@ export default {
300 314 { id: "7", name: "高补" },
301 315 ],
302 316 subjectList: [],
  317 + diaUpgradeGrade: false, //班级升级
303 318 };
304 319 },
305 320 created() {
... ... @@ -316,7 +331,7 @@ export default {
316 331 showClose: true,
317 332 message: `成功(${res.data.success})`,
318 333 type: "success",
319   - duration:5000
  334 + duration: 5000,
320 335 });
321 336 this.diaUp = false;
322 337 this._QueryDataSchool();
... ... @@ -377,6 +392,19 @@ export default {
377 392 }
378 393 });
379 394 },
  395 + async _UpgradeGrade() {
  396 + this.loading = true;
  397 + const { data, status, info } = await this.$request.upgradeGrade();
  398 + this.loading = false;
  399 + if (status === 0) {
  400 + this.$message.success("升级成功~");
  401 + this.diaUpgradeGrade = false;
  402 + this._QueryDataGrade();
  403 + this._QuerySubject();
  404 + } else {
  405 + this.$message.error(info);
  406 + }
  407 + },
380 408 async editGrade() {
381 409 //保存修改年级信息
382 410 if (!this.formGrade.subjectNames.length) {
... ... @@ -505,6 +533,23 @@ export default {
505 533 }
506 534 .grade-box {
507 535 padding: 20px;
  536 + .h-title {
  537 + display: flex;
  538 + justify-content: space-between;
  539 + align-items: center;
  540 + .popconfirm-box {
  541 + cursor: pointer;
  542 + font-size: 14px;
  543 + color: #999;
  544 + .fa-level-up{
  545 + font-size:16px;
  546 + padding-left:2px;
  547 + }
  548 + &:hover {
  549 + color: #f30;
  550 + }
  551 + }
  552 + }
508 553 .grade-info {
509 554 display: flex;
510 555 flex-wrap: wrap;
... ...
src/views/standard/setUp/student.vue
... ... @@ -34,6 +34,12 @@
34 34 </back-box>
35 35  
36 36 <div class="page-content">
  37 + <template v-if="!code && role !== 'ROLE_PERSONAL'">
  38 + <p class="tips" v-show="archivedTotal">
  39 + <span>另有{{ archivedTotal }}个班级已经归档,</span>
  40 + <router-link to="/archivedClazz">点击查看&gt;&gt;</router-link>
  41 + </p>
  42 + </template>
37 43 <div class="stu-box">
38 44 <div class="stu-list">
39 45 <div class="h-title">
... ... @@ -55,22 +61,31 @@
55 61 <ul class="stu-ul">
56 62 <li
57 63 class="stu-item"
58   - v-for="item in classList"
  64 + v-for="(item, index) in classList"
59 65 :key="item.id"
60 66 :class="query.classId == item.id ? 'active' : ''"
61 67 @click="classDetail(item)"
62 68 >
63   - <i
64   - v-if="!code"
65   - class="el-icon-edit-outline"
66   - @click.stop="setClass(item)"
67   - ></i>
  69 + <template v-if="!code && role !== 'ROLE_PERSONAL'">
  70 + <div class="popconfirm-box">
  71 + <el-popconfirm
  72 + title="确定要将该班级归档吗?"
  73 + @confirm="archivingClass(item, index)"
  74 + >
  75 + <i slot="reference" class="fa fa-file-archive-o"></i>
  76 + </el-popconfirm>
  77 + </div>
  78 + <i
  79 + class="el-icon-edit-outline"
  80 + @click.stop="setClass(item)"
  81 + ></i>
  82 + </template>
68 83 {{ item.className }}({{ item.studentCount }})
69 84 </li>
70 85 </ul>
71 86 </div>
72 87 <div class="stu-detail">
73   - <div class="clazz-detail">
  88 + <div class="clazz-detail" v-if="clazzDetail.stationSn">
74 89 <p>基站SN:{{ clazzDetail.stationSn }}</p>
75 90 <p>配对码:{{ clazzDetail.pairingCode }}</p>
76 91 <p>频点:{{ clazzDetail.frequency }}</p>
... ... @@ -116,6 +131,7 @@
116 131 >
117 132 <i class="el-icon-delete" slot="reference"></i>
118 133 </el-popconfirm>
  134 + <i class="el-icon-user-solid" @click="openChangeClazz(item)"></i>
119 135 <p class="name">{{ item.studentName }}</p>
120 136 <p class="p1">答题器:{{ item.clickerSn || "--" }}</p>
121 137 <p class="p1">长学号:{{ item.studentCode }}</p>
... ... @@ -130,6 +146,52 @@
130 146 </div>
131 147 </div>
132 148 </div>
  149 + <el-dialog title="学生调班" :visible.sync="diaChangeClass" width="400">
  150 + <el-form
  151 + class="form-box"
  152 + ref="formStuCla"
  153 + :model="formStuCla"
  154 + :rules="rulesStuCla"
  155 + label-width="160px"
  156 + >
  157 + <el-form-item label="学生姓名:">
  158 + <span>{{ formStuCla.studentName }}</span>
  159 + </el-form-item>
  160 + <el-form-item label="当前班级:">
  161 + <span>{{ formStuCla.className }}</span>
  162 + </el-form-item>
  163 + <el-form-item label="调到班级:">
  164 + <el-col :span="10">
  165 + <el-select
  166 + class="sel"
  167 + v-model="formStuCla.classId"
  168 + placeholder="选择年级"
  169 + >
  170 + <el-option
  171 + v-for="item in classList"
  172 + :key="item.id"
  173 + :label="item.className"
  174 + :value="item.id"
  175 + >
  176 + </el-option>
  177 + </el-select>
  178 + </el-col>
  179 + </el-form-item>
  180 + <el-form-item label="长学号:" prop="studentCode">
  181 + <el-col :span="10">
  182 + <el-input
  183 + maxlength="12"
  184 + placeholder="输入学生长学号"
  185 + v-model.trim="formStuCla.studentCode"
  186 + />
  187 + </el-col>
  188 + </el-form-item>
  189 + </el-form>
  190 + <div class="dialog-footer" slot="footer">
  191 + <el-button @click="changeStu">确 定</el-button>
  192 + <el-button @click="diaChangeClass = false">取 消</el-button>
  193 + </div>
  194 + </el-dialog>
133 195 <el-dialog title="添加学生" :visible.sync="diaStu" width="400">
134 196 <el-form
135 197 ref="formBox"
... ... @@ -234,7 +296,7 @@
234 296 </template>
235 297  
236 298 <script>
237   -import { downloadFile, getBlob } from "@/utils";
  299 +import _ from "lodash";
238 300 export default {
239 301 data() {
240 302 return {
... ... @@ -244,6 +306,7 @@ export default {
244 306 url: "/api_html/school/manager/importStudentClicker",
245 307 diaStu: false,
246 308 diaClass: false,
  309 + diaChangeClass: false,
247 310 clazzDetail: { stationSn: "", pairingCode: "", frequency: "" },
248 311 query: {
249 312 gradeName: "",
... ... @@ -277,6 +340,22 @@ export default {
277 340 { required: true, message: "请输入班级名称", trigger: "blur" },
278 341 ],
279 342 },
  343 + formStuCla: {
  344 + studentName: "",
  345 + studentId: "",
  346 + oldClassId: "",
  347 + className: "",
  348 + classId: "",
  349 + studentCode: "",
  350 + },
  351 + rulesStuCla: {
  352 + className: [
  353 + { required: true, message: "请输入班级名称", trigger: "blur" },
  354 + ],
  355 + studentCode: [
  356 + { required: true, message: "请输入学生号", trigger: "blur" },
  357 + ],
  358 + },
280 359 gradeName: "",
281 360 gradeList: [],
282 361 classList: [],
... ... @@ -290,6 +369,7 @@ export default {
290 369 teacherCourseList: [],
291 370 teacherGradeList: [],
292 371 },
  372 + archivedTotal: 0, //已归档班级
293 373 };
294 374 },
295 375 async created() {
... ... @@ -297,6 +377,7 @@ export default {
297 377 this.role =
298 378 this.$store.getters.info.showRole ||
299 379 this.$store.getters.info.permissions[0].role;
  380 + this._QueryArchivedNum();
300 381 await this._QueryDataGrade();
301 382 await this._QueryClass();
302 383 this._QueryData(3);
... ... @@ -316,8 +397,10 @@ export default {
316 397 this.clazzDetail.frequency = obj.frequency;
317 398 this.query.classId = obj.id;
318 399 this.formStu.className = obj.className;
  400 + this.formStuCla.className = obj.className;
319 401 this._QueryData(3);
320 402 },
  403 +
321 404 setClass(obj) {
322 405 this.formClass.gradeName = obj.gradeName;
323 406 this.formClass.classId = obj.id;
... ... @@ -358,23 +441,7 @@ export default {
358 441 this.diaUp = false;
359 442 this._QueryData(3);
360 443 },
361   - async removeStu(obj, index) {
362   - const { data, status, info } = await this.$request.delStudent({
363   - studentId: obj.id,
364   - });
365   - if (status === 0) {
366   - this.$message.success("删除成功");
367   - this.studentList.splice(index, 1);
368   - this._QueryClass();
369   - } else {
370   - this.$message.error(info);
371   - }
372   - },
373   - async changeGrade(val) {
374   - this.query.classId = "";
375   - await this._QueryClass(val);
376   - this._QueryData(3);
377   - },
  444 + //添加学生
378 445 addStu() {
379 446 let query = {};
380 447 for (let key in this.formStu) {
... ... @@ -412,6 +479,81 @@ export default {
412 479 }
413 480 });
414 481 },
  482 + //学生调班弹窗
  483 + openChangeClazz(obj) {
  484 + this.formStuCla.studentId = obj.id;
  485 + this.formStuCla.studentName = obj.studentName;
  486 + this.formStuCla.studentCode = obj.studentCode;
  487 + this.formStuCla.classId = this.query.classId;
  488 + this.formStuCla.oldClassId = this.query.classId;
  489 + this.diaChangeClass = true;
  490 + },
  491 + //学生调班
  492 + changeStu: _.throttle(
  493 + function () {
  494 + this.$refs.formStuCla.validate(async (valid) => {
  495 + if (valid) {
  496 + const { data, status, info } =
  497 + await this.$request.studentChangeClass({
  498 + studentId: this.formStuCla.studentId,
  499 + oldClassId: this.formStuCla.oldClassId,
  500 + classId: this.formStuCla.classId,
  501 + studentCode: this.formStuCla.studentCode,
  502 + });
  503 + if (status == 0) {
  504 + this.diaChangeClass = false;
  505 + this.$message.success(info);
  506 + this._QueryData();
  507 + } else {
  508 + this.$message.error(info);
  509 + }
  510 + } else {
  511 + this.$message.error("数据有误请检查!");
  512 + }
  513 + });
  514 + },
  515 + 2000,
  516 + { leading: true, trailing: false }
  517 + ),
  518 + //班级归档
  519 + async archivingClass(obj, index) {
  520 + const { data, status, info } = await this.$request.classArchiving({
  521 + classId: obj.id,
  522 + });
  523 + if (status === 0) {
  524 + this.$message.success("归档成功");
  525 + this.classList.splice(index, 1);
  526 + this.setClass(this.classList[index]);
  527 + this.diaClass = false;
  528 + } else {
  529 + this.$message.error(info);
  530 + }
  531 + },
  532 + async removeStu(obj, index) {
  533 + const { data, status, info } = await this.$request.delStudent({
  534 + studentId: obj.id,
  535 + });
  536 + if (status === 0) {
  537 + this.$message.success("删除成功");
  538 + this.studentList.splice(index, 1);
  539 + this._QueryClass();
  540 + } else {
  541 + this.$message.error(info);
  542 + }
  543 + },
  544 + async changeGrade(val) {
  545 + this.query.classId = "";
  546 + await this._QueryClass(val);
  547 + this._QueryData(3);
  548 + },
  549 + async _QueryArchivedNum() {
  550 + const { data, status, info } = await this.$request.archivingClassList();
  551 + if (status === 0) {
  552 + this.archivedTotal = data?.count || 0;
  553 + } else {
  554 + this.$message.error(info);
  555 + }
  556 + },
415 557 async _QueryData(type) {
416 558 let query = {};
417 559 query.gradeName = this.query.gradeName;
... ... @@ -464,6 +606,7 @@ export default {
464 606 this.classList = [...data.list] || [];
465 607 this.query.classId = this.classList[0]?.id;
466 608 this.formStu.className = this.classList[0]?.className;
  609 + this.formStuCla.className = this.classList[0]?.className;
467 610 this.clazzDetail.stationSn = this.classList[0]?.stationSn;
468 611 this.clazzDetail.pairingCode = this.classList[0]?.pairingCode;
469 612 this.clazzDetail.frequency = this.classList[0]?.frequency;
... ... @@ -494,13 +637,20 @@ export default {
494 637 .page-content {
495 638 padding: 20px;
496 639 }
  640 +.tips {
  641 + display: flex;
  642 + line-height: 16px;
  643 + font-size: 14px;
  644 + color: #999;
  645 + margin-bottom: 10px;
  646 +}
497 647 .stu-box {
498 648 display: flex;
499 649 background: #f8f8f8;
500 650 border-radius: 10px;
501 651 overflow: hidden;
502 652 .answer-header {
503   - padding-top: 0;
  653 + padding-top: 10px;
504 654 }
505 655 .stu-list {
506 656 max-height: 80vh;
... ... @@ -519,18 +669,32 @@ export default {
519 669 .el-icon-edit-outline {
520 670 position: absolute;
521 671 top: 8px;
522   - right: 12px;
  672 + right: 4px;
523 673 font-size: 20px;
524 674 display: none;
525 675 &:hover {
526 676 color: #667ffd;
527 677 }
528 678 }
  679 + .popconfirm-box {
  680 + position: absolute;
  681 + top: 6px;
  682 + right: 31px;
  683 + font-size: 17px;
  684 + line-height: 24px;
  685 + display: none;
  686 + &:hover {
  687 + color: #667ffd;
  688 + }
  689 + }
529 690 &:hover {
530 691 background: #eee;
531 692 .el-icon-edit-outline {
532 693 display: block;
533 694 }
  695 + .popconfirm-box {
  696 + display: block;
  697 + }
534 698 }
535 699 &.active {
536 700 color: #667ffd;
... ... @@ -565,6 +729,19 @@ export default {
565 729 margin: 0 20px 20px 0;
566 730 padding: 0 12px 5px;
567 731 position: relative;
  732 + .el-icon-user-solid {
  733 + position: absolute;
  734 + top: 8px;
  735 + left: 8px;
  736 + font-size: 18px;
  737 + color: #666;
  738 + padding: 2px;
  739 + display: none;
  740 + cursor: pointer;
  741 + &:hover {
  742 + color: #667ffd;
  743 + }
  744 + }
568 745 .el-icon-delete {
569 746 position: absolute;
570 747 top: 8px;
... ... @@ -578,6 +755,9 @@ export default {
578 755 }
579 756 }
580 757 &:hover {
  758 + .el-icon-user-solid {
  759 + display: block;
  760 + }
581 761 .el-icon-delete {
582 762 display: block;
583 763 }
... ... @@ -598,7 +778,7 @@ export default {
598 778 }
599 779 .clazz-detail {
600 780 display: flex;
601   - padding: 12px 12px 10px 20px;
  781 + padding: 12px 12px 0 20px;
602 782 p {
603 783 margin-right: 16px;
604 784 color: #666;
... ...
src/views/standard/test/analysis.vue
... ... @@ -5,7 +5,7 @@
5 5 <span>单卷分析</span>
6 6 </template>
7 7 </back-box>
8   - <div class="tips" v-if="paperModifyLog.modifiedTime">
  8 + <div class="tips" v-if="paperModifyLog.modifiedTime || status">
9 9 <p class="tips-p">
10 10 <i class="fa fa-bell-o"></i>
11 11 {{
... ... @@ -29,34 +29,18 @@
29 29 <div class="page-content">
30 30 <div class="tab-box">
31 31 <span
  32 + v-for="(item, index) in tabList"
  33 + :key="item"
32 34 class="tab-item"
33   - :class="type == 1 ? 'active' : ''"
34   - @click="setType(1)"
35   - >试题分析</span
36   - >
37   - <span
38   - class="tab-item"
39   - :class="type == 2 ? 'active' : ''"
40   - @click="setType(2)"
41   - >成绩排名</span
42   - >
43   - <span
44   - class="tab-item"
45   - :class="type == 3 ? 'active' : ''"
46   - @click="setType(3)"
47   - >小题分报表</span
48   - >
49   - <span
50   - class="tab-item"
51   - :class="type == 4 ? 'active' : ''"
52   - @click="setType(4)"
53   - >作答明细表</span
  35 + :class="type == index ? 'active' : ''"
  36 + @click="setType(index)"
  37 + >{{ item }}</span
54 38 >
55 39 </div>
56 40 <div id="print-content" class="table-box" v-loading="loading">
57 41 <el-table
58 42 :max-height="tableMaxHeight"
59   - v-show="type == 1"
  43 + v-show="type == 0"
60 44 :data="tableData"
61 45 border
62 46 style="width: 100%"
... ... @@ -147,7 +131,7 @@
147 131 >
148 132 </el-table-column>
149 133 </el-table>
150   - <div class="hui-box" v-show="type == 1">
  134 + <div class="hui-box" v-show="type == 0">
151 135 <span class="s-txt">汇总</span>
152 136 <ul class="hui-ul">
153 137 <li class="hui-li">
... ... @@ -189,7 +173,7 @@
189 173 </ul>
190 174 </div>
191 175 <el-table
192   - v-show="type == 2"
  176 + v-show="type == 1"
193 177 :max-height="tableMaxHeight"
194 178 :data="tableData2"
195 179 border
... ... @@ -261,7 +245,7 @@
261 245 </el-table-column>
262 246 </el-table>
263 247 <el-table
264   - v-show="type == 3"
  248 + v-show="type == 2"
265 249 :max-height="tableMaxHeight"
266 250 :data="tableData2"
267 251 border
... ... @@ -309,7 +293,7 @@
309 293 </el-table>
310 294 <el-table
311 295 :max-height="tableMaxHeight"
312   - v-show="type == 4"
  296 + v-show="type == 3"
313 297 :data="tableData2"
314 298 border
315 299 style="width: 100%"
... ... @@ -381,7 +365,7 @@
381 365 >打印</el-button
382 366 >
383 367 </div>
384   - <div>
  368 + <div v-if="!status">
385 369 <el-button
386 370 v-if="examReport.subjectiveScore != 0"
387 371 @click="diaUp = true"
... ... @@ -425,6 +409,7 @@ export default {
425 409 data() {
426 410 return {
427 411 role: "",
  412 + status: 0,
428 413 tableMaxHeight: 600,
429 414 loading: false,
430 415 exportLoading: false,
... ... @@ -433,7 +418,8 @@ export default {
433 418 id: "",
434 419 title: "",
435 420 score: "",
436   - type: 1,
  421 + tabList: ["试题分析", "成绩排名", "小题分报表", "作答明细表"],
  422 + type: 0,
437 423 paperModifyLog: {
438 424 realName: "",
439 425 modifiedTime: "",
... ... @@ -469,12 +455,13 @@ export default {
469 455 this.$store.getters.info.showRole ||
470 456 this.$store.getters.info.permissions[0].role;
471 457 this.id = this.$route.query.id;
  458 + this.status = this.$route.query.status ? this.$route.query.status : 0;
472 459 this.title = this.$route.query.title || "";
473 460 this._QueryData();
474 461 },
475 462 methods: {
476 463 print() {
477   - tablePrint("print-content");
  464 + tablePrint("print-content", this.title + this.tabList[this.type]);
478 465 },
479 466 upSuccess(res) {
480 467 //导入成功
... ... @@ -653,7 +640,7 @@ export default {
653 640 });
654 641 this.optionsList = [...optionsList];
655 642 this.total = data.count;
656   - this.setType(1);
  643 + this.setType(0);
657 644 } else {
658 645 this.$message.error(info);
659 646 }
... ... @@ -670,7 +657,12 @@ export default {
670 657 let blob = new Blob([data], {
671 658 type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
672 659 });
673   - downloadFile("即时测-单卷测练报表.xlsx", blob);
  660 + downloadFile(
  661 + this.status
  662 + ? "即时测-已归档单卷测练报表.xlsx"
  663 + : "即时测-单卷测练报表.xlsx",
  664 + blob
  665 + );
674 666 } else {
675 667 this.$message.error("下载失败");
676 668 }
... ...
src/views/standard/test/archiving.vue 0 → 100644
  1 +<template>
  2 + <div ref="main" class="page-container">
  3 + <back-box>
  4 + <template slot="title">
  5 + <span>即时测-已归档数据报表</span>
  6 + </template>
  7 + </back-box>
  8 + <div class="answer-header">
  9 + <div class="sel-box">
  10 + <el-select
  11 + class="sel"
  12 + v-model="query.classId"
  13 + placeholder="选择班级"
  14 + @change="changeclass"
  15 + >
  16 + <el-option
  17 + v-for="item in classList"
  18 + :key="item.value"
  19 + :label="item.label"
  20 + :value="item.value"
  21 + >
  22 + </el-option>
  23 + </el-select>
  24 + <el-select
  25 + v-if="role == 'ROLE_BANZHUREN'"
  26 + class="sel"
  27 + multiple
  28 + v-model="query.subjectNames"
  29 + placeholder="选择科目"
  30 + @change="changeSub"
  31 + >
  32 + <el-option
  33 + v-for="item in subjectList"
  34 + :key="item.value"
  35 + :label="item.label"
  36 + :value="item.value"
  37 + >
  38 + </el-option>
  39 + </el-select>
  40 + <el-select
  41 + v-else
  42 + class="sel"
  43 + v-model="query.subjectNames"
  44 + placeholder="选择科目"
  45 + >
  46 + <el-option
  47 + v-for="item in subjectList"
  48 + :key="item.value"
  49 + :label="item.label"
  50 + :value="item.value"
  51 + >
  52 + </el-option>
  53 + </el-select>
  54 + <div class="d1">
  55 + <el-date-picker
  56 + v-model="query.startDay"
  57 + type="date"
  58 + @change="handleChangeTimeStart"
  59 + placeholder="选择日期时间"
  60 + value-format="yyyy-MM-dd"
  61 + >
  62 + </el-date-picker>
  63 + ~
  64 + <el-date-picker
  65 + v-model="query.endDay"
  66 + type="date"
  67 + placeholder="选择日期时间"
  68 + @change="handleChangeTimeEnd"
  69 + value-format="yyyy-MM-dd"
  70 + >
  71 + </el-date-picker>
  72 + </div>
  73 + <p class="p1">
  74 + <span @click="setDate(1)" :class="[date == 1 ? 'active' : '', 's1']"
  75 + >今天</span
  76 + >
  77 + <span @click="setDate(2)" :class="[date == 2 ? 'active' : '', 's1']"
  78 + >本周</span
  79 + >
  80 + <span @click="setDate(3)" :class="[date == 3 ? 'active' : '', 's1']"
  81 + >本月</span
  82 + >
  83 + <span @click="setDate(4)" :class="[date == 4 ? 'active' : '', 's1']"
  84 + >本季度</span
  85 + >
  86 + </p>
  87 + <el-button type="primary" round @click="_QueryData()">筛选</el-button>
  88 + </div>
  89 + </div>
  90 + <div class="table-box">
  91 + <el-radio-group
  92 + v-model="tabIndex"
  93 + @change="changeTab"
  94 + style="margin-bottom: 20px"
  95 + >
  96 + <template v-for="(item, index) in tabList">
  97 + <el-radio-button
  98 + v-if="index == 0 || query.startDay != query.endDay"
  99 + :key="index"
  100 + :label="index + 1"
  101 + >{{ item }}</el-radio-button
  102 + >
  103 + </template>
  104 + </el-radio-group>
  105 + <div v-show="tabIndex == 1" v-loading="loading">
  106 + <el-table :data="tableData" border style="width: 100%">
  107 + <el-table-column
  108 + prop="title"
  109 + label="试卷名称"
  110 + fixed
  111 + align="center"
  112 + ></el-table-column>
  113 + <el-table-column
  114 + prop="examPaperScore"
  115 + label="卷面分"
  116 + align="center"
  117 + width="68"
  118 + ></el-table-column>
  119 + <el-table-column prop="answeredNum" label="测验人数" align="center"
  120 + ><template slot-scope="scoped">{{
  121 + `${scoped.row.answeredNum}/${scoped.row.classPersonNum}`
  122 + }}</template></el-table-column
  123 + >
  124 + <el-table-column
  125 + prop="examStartTime"
  126 + label="测验时间"
  127 + width="100"
  128 + align="center"
  129 + ></el-table-column>
  130 + <el-table-column prop="avgScore" label="班平均分" align="center"
  131 + ><template slot-scope="scoped">{{
  132 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  133 + scoped.row.answerNum == 0) &&
  134 + scoped.row.recordStatus == 0
  135 + ? "-"
  136 + : scoped.row.avgScore
  137 + }}</template></el-table-column
  138 + >
  139 + <el-table-column prop="highestScore" label="班最高分" align="center"
  140 + ><template slot-scope="scoped">{{
  141 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  142 + scoped.row.answerNum == 0) &&
  143 + scoped.row.recordStatus == 0
  144 + ? "-"
  145 + : scoped.row.highestScore
  146 + }}</template></el-table-column
  147 + >
  148 + <el-table-column prop="lowestScore" label="班最低分" align="center"
  149 + ><template slot-scope="scoped">{{
  150 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  151 + scoped.row.answerNum == 0) &&
  152 + scoped.row.recordStatus == 0
  153 + ? "-"
  154 + : scoped.row.lowestScore
  155 + }}</template></el-table-column
  156 + >
  157 + <el-table-column
  158 + prop="excellenRate"
  159 + label="优秀数(率)"
  160 + sortable
  161 + align="center"
  162 + width="110"
  163 + class-name="p0"
  164 + ><template slot-scope="scoped">
  165 + <p
  166 + v-if="
  167 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  168 + scoped.row.answerNum == 0) &&
  169 + scoped.row.arecordStatus == 0
  170 + "
  171 + >
  172 + "-"
  173 + </p>
  174 + <template v-else>
  175 + <p>{{ scoped.row.excellenNum }}</p>
  176 + <p v-if="scoped.row.excellenNum">
  177 + {{ `(${scoped.row.excellenRate}%)` }}
  178 + </p>
  179 + </template>
  180 + </template></el-table-column
  181 + >
  182 + <el-table-column
  183 + prop="goodRate"
  184 + label="良好数(率)"
  185 + sortable
  186 + align="center"
  187 + width="110"
  188 + class-name="p0"
  189 + ><template slot-scope="scoped">
  190 + <p
  191 + v-if="
  192 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  193 + scoped.row.answerNum == 0) &&
  194 + scoped.row.arecordStatus == 0
  195 + "
  196 + >
  197 + "-"
  198 + </p>
  199 + <template v-else>
  200 + <p>{{ scoped.row.goodNum }}</p>
  201 + <p v-if="scoped.row.goodNum">
  202 + {{ `(${scoped.row.goodRate}%)` }}
  203 + </p>
  204 + </template>
  205 + </template></el-table-column
  206 + >
  207 + <el-table-column
  208 + prop="passRate"
  209 + label="及格数(率)"
  210 + sortable
  211 + align="center"
  212 + width="110"
  213 + class-name="p0"
  214 + ><template slot-scope="scoped">
  215 + <p
  216 + v-if="
  217 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  218 + scoped.row.answerNum == 0) &&
  219 + scoped.row.arecordStatus == 0
  220 + "
  221 + >
  222 + "-"
  223 + </p>
  224 + <template v-else>
  225 + <p>{{ scoped.row.passNum }}</p>
  226 + <p v-if="scoped.row.passNum">
  227 + {{ `(${scoped.row.passRate}%)` }}
  228 + </p>
  229 + </template>
  230 + </template></el-table-column
  231 + >
  232 + <el-table-column
  233 + prop="failedRate"
  234 + label="不及格数(率)"
  235 + sortable
  236 + align="center"
  237 + width="130"
  238 + class-name="p0"
  239 + ><template slot-scope="scoped">
  240 + <p
  241 + v-if="
  242 + (scoped.row.subjectiveScore == scoped.row.examPaperScore ||
  243 + scoped.row.answerNum == 0) &&
  244 + scoped.row.arecordStatus == 0
  245 + "
  246 + >
  247 + "-"
  248 + </p>
  249 + <template v-else>
  250 + <p>{{ scoped.row.failedNum }}</p>
  251 + <p v-if="scoped.row.failedNum">
  252 + {{ `(${scoped.row.failedRate}%)` }}
  253 + </p>
  254 + </template>
  255 + </template></el-table-column
  256 + >
  257 + <el-table-column label="操作" align="center">
  258 + <template slot-scope="scoped">
  259 + <el-tooltip effect="dark" content="详情" placement="top">
  260 + <el-button
  261 + type="primary"
  262 + circle
  263 + size="mini"
  264 + icon="fa fa-arrow-right"
  265 + @click="linkTo(scoped.row)"
  266 + ></el-button>
  267 + </el-tooltip>
  268 + </template>
  269 + </el-table-column>
  270 + </el-table>
  271 + <div class="pagination-box">
  272 + <el-pagination
  273 + small=""
  274 + layout="total,prev, pager, next"
  275 + :hide-on-single-page="true"
  276 + :total="total"
  277 + @current-change="changePage"
  278 + :current-page="page"
  279 + :page-size="size"
  280 + >
  281 + </el-pagination>
  282 + </div>
  283 + </div>
  284 + <div v-show="tabIndex == 2" v-loading="loading">
  285 + <el-empty
  286 + :image-size="100"
  287 + v-if="!tableData.length && loading == false"
  288 + description="没有更多数据"
  289 + ></el-empty>
  290 + <template v-if="tableData.length && loading == false">
  291 + <div id="print-content">
  292 + <el-table
  293 + :max-height="tableMaxHeight"
  294 + v-if="role == 'ROLE_JIAOSHI'"
  295 + :data="tableData"
  296 + border
  297 + style="width: 100%"
  298 + >
  299 + <el-table-column
  300 + prop="studentCode"
  301 + label="学号"
  302 + align="center"
  303 + fixed
  304 + ></el-table-column>
  305 + <el-table-column
  306 + prop="studentName"
  307 + label="姓名"
  308 + fixed
  309 + align="center"
  310 + ></el-table-column>
  311 + <el-table-column
  312 + align="center"
  313 + v-for="(item, index) in answerList"
  314 + :key="index"
  315 + :label="item.title"
  316 + >
  317 + <el-table-column
  318 + :prop="'score' + index"
  319 + :label="index == 0 ? '总分' : '成绩'"
  320 + align="center"
  321 + :class-name="index % 2 == 0 ? 'bg' : ''"
  322 + ></el-table-column>
  323 + <el-table-column
  324 + :prop="'classRank' + index"
  325 + label="班名"
  326 + align="center"
  327 + :class-name="index % 2 == 0 ? 'bg' : ''"
  328 + ></el-table-column>
  329 + </el-table-column>
  330 + </el-table>
  331 + <el-table
  332 + v-else
  333 + :data="tableData"
  334 + :max-height="tableMaxHeight"
  335 + border
  336 + style="width: 100%"
  337 + >
  338 + <el-table-column
  339 + prop="studentCode"
  340 + label="学号"
  341 + align="center"
  342 + fixed
  343 + ></el-table-column>
  344 +
  345 + <el-table-column
  346 + prop="studentName"
  347 + label="姓名"
  348 + fixed
  349 + align="center"
  350 + ></el-table-column>
  351 + <el-table-column
  352 + align="center"
  353 + v-for="(item, index) in answerList"
  354 + :key="index"
  355 + :label="item"
  356 + >
  357 + <el-table-column
  358 + :prop="'examCount' + item"
  359 + label="测练数"
  360 + align="center"
  361 + :class-name="index % 2 == 0 ? 'bg' : ''"
  362 + ></el-table-column>
  363 + <el-table-column
  364 + :prop="'participationCount' + item"
  365 + label="参与数"
  366 + align="center"
  367 + :class-name="index % 2 == 0 ? 'bg' : ''"
  368 + ></el-table-column>
  369 + <el-table-column
  370 + :prop="'score' + item"
  371 + label="总分"
  372 + align="center"
  373 + :class-name="index % 2 == 0 ? 'bg' : ''"
  374 + ></el-table-column>
  375 + <el-table-column
  376 + :prop="'classRank' + item"
  377 + label="班名"
  378 + align="center"
  379 + :class-name="index % 2 == 0 ? 'bg' : ''"
  380 + ></el-table-column>
  381 + </el-table-column>
  382 + </el-table>
  383 + </div>
  384 + </template>
  385 + </div>
  386 + <p class="down" v-if="tabIndex == 2 && tableData.length">
  387 + <el-button
  388 + type="primary"
  389 + plain
  390 + round
  391 + icon="fa fa-cloud-download"
  392 + @click="downExl"
  393 + >导出报表</el-button
  394 + >
  395 + <el-button
  396 + v-if="!this.$store.getters.code"
  397 + @click="print"
  398 + type="primary"
  399 + plain
  400 + round
  401 + icon="el-icon-printer"
  402 + >打印</el-button
  403 + >
  404 + </p>
  405 + </div>
  406 + </div>
  407 +</template>
  408 +
  409 +<script>
  410 +import { formatDate, downloadFile, tablePrint } from "utils";
  411 +import BusEvent from "@/utils/busEvent";
  412 +export default {
  413 + data() {
  414 + return {
  415 + exportLoading: false,
  416 + tableMaxHeight: 300,
  417 + role: "",
  418 + loading: false,
  419 + loadingDown: false,
  420 + url: "/api_html/teaching/importSubjectiveScore",
  421 + examId: "",
  422 + form: {
  423 + id: "",
  424 + title: "",
  425 + examPaperScore: "",
  426 + },
  427 + date: "", //今天-昨天-本周
  428 + query: {
  429 + //搜索条件
  430 + classId: "",
  431 + subjectNames: "",
  432 + startDay: "",
  433 + endDay: "",
  434 + day: "",
  435 + },
  436 + tabList: ["单卷测练报表", "阶段测练报表"],
  437 + classList: [], //班级
  438 + subjectList: [], //科目
  439 + tabIndex: 1, //选项卡
  440 + tableData: [],
  441 + answerList: [], //设置多卷内容供tableStage表格数据用
  442 + page: 1,
  443 + size: 20,
  444 + total: 0,
  445 + };
  446 + },
  447 + async created() {
  448 + this.role =
  449 + this.$store.getters.info.showRole ||
  450 + this.$store.getters.info.permissions[0].role;
  451 + await this._QueryClassList();
  452 + if (!this.query.classId) {
  453 + return;
  454 + }
  455 + await this._QuerySubjectList();
  456 + await this.setDate(1);
  457 + let startDay = this.query?.startDay;
  458 + if (!startDay) {
  459 + this.query.startDay = new Date();
  460 + this.query.endDay = new Date();
  461 + }
  462 + },
  463 + activated() {
  464 + const that = this;
  465 + BusEvent.$on("keepAlive", async function () {
  466 + that.query.subjectNames = that.role == "ROLE_BANZHUREN" ? [] : "";
  467 + await that._QueryClassList();
  468 + if (!that.query.classId) {
  469 + return;
  470 + }
  471 + await that._QuerySubjectList();
  472 + await that.setDate(1);
  473 + let startDay = that.query?.startDay;
  474 + if (!startDay) {
  475 + that.query.startDay = new Date();
  476 + that.query.endDay = new Date();
  477 + }
  478 + });
  479 + },
  480 + methods: {
  481 + print() {
  482 + tablePrint("print-content", "即时测-" + this.tabList[this.tabIndex - 1]);
  483 + },
  484 + changeSub(val) {
  485 + //科目改变触发事件
  486 + let sub;
  487 + if (val && val.length) {
  488 + let leng = val.length - 1;
  489 + sub = val[leng];
  490 + }
  491 + console.log(val);
  492 + this.query.subjectNames = val.filter((item) => {
  493 + return sub != "全部" ? item != "全部" : item == "全部";
  494 + });
  495 + },
  496 + linkTo(obj) {
  497 + //去详情
  498 + this.$router.push({
  499 + path: "/testAnalysis",
  500 + query: {
  501 + id: obj.id,
  502 + title: obj.title,
  503 + score: obj.examPaperScore,
  504 + status: 1,
  505 + },
  506 + });
  507 + },
  508 +
  509 + setDate(index) {
  510 + const that = this;
  511 + this.date = index == this.date ? "" : index;
  512 + let aYear = new Date().getFullYear();
  513 + let aMonth = new Date().getMonth() + 1;
  514 + that.query.day = "";
  515 + that.query.startDay = "";
  516 + that.query.endDay = "";
  517 + switch (index) {
  518 + case 1:
  519 + that.query.day = formatDate(new Date(), "yyyy-MM-dd");
  520 + that.query.startDay = that.query.day;
  521 + that.query.endDay = that.query.day;
  522 + that.tabIndex = 1;
  523 + break;
  524 + case 2:
  525 + let day = new Date().getDay();
  526 + if (day == 0) {
  527 + //中国式星期天是一周的最后一天
  528 + day = 7;
  529 + }
  530 + day--;
  531 + let aTime = new Date().getTime() - 24 * 60 * 60 * 1000 * day;
  532 + that.query.startDay = formatDate(new Date(aTime), "yyyy-MM-dd");
  533 + that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
  534 + break;
  535 + case 3:
  536 + aMonth = aMonth < 10 ? "0" + aMonth : aMonth;
  537 + that.query.startDay = `${aYear}-${aMonth}-01`;
  538 + that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
  539 + break;
  540 + case 4:
  541 + if (aMonth > 0 && aMonth < 4) {
  542 + aMonth = "1";
  543 + } else if (aMonth > 3 && aMonth < 7) {
  544 + aMonth = "4";
  545 + } else if (aMonth > 6 && aMonth < 10) {
  546 + aMonth = "7";
  547 + } else {
  548 + aMonth = "10";
  549 + }
  550 +
  551 + aMonth = aMonth < 10 ? "0" + aMonth : aMonth;
  552 + that.query.startDay = `${aYear}-${aMonth}-01`;
  553 + that.query.endDay = formatDate(new Date(), "yyyy-MM-dd");
  554 + break;
  555 + }
  556 + this.page = 1;
  557 + this._QueryData();
  558 + },
  559 + handleChangeTimeStart(val) {
  560 + this.query.day = "";
  561 + this.date = "";
  562 + if (this.query.endDay) {
  563 + if (new Date(val).getTime() > new Date(this.query.endDay).getTime()) {
  564 + this.$message.error("任务结束时间不能任务开始时间前面,请重新设置");
  565 + this.query.startDay = "";
  566 + }
  567 + }
  568 + },
  569 + handleChangeTimeEnd(val) {
  570 + this.query.day = "";
  571 + this.date = "";
  572 + if (this.query.startDay) {
  573 + if (new Date(val).getTime() < new Date(this.query.startDay).getTime()) {
  574 + this.$message.error("任务结束时间不能任务开始时间前面,请重新设置");
  575 + this.query.endDay = "";
  576 + }
  577 + }
  578 + },
  579 + changePage(page) {
  580 + this.page = page;
  581 + this._QueryData();
  582 + },
  583 + changeTab() {
  584 + this.tableMaxHeight = this.$refs.main.offsetHeight;
  585 + this.page = 1;
  586 + this._QueryData();
  587 + },
  588 +
  589 + async changeclass() {
  590 + await this._QuerySubjectList();
  591 + this.page = 1;
  592 + this._QueryData();
  593 + },
  594 + async changClazz() {
  595 + this.page = 1;
  596 + await this._QuerySubjectList();
  597 + await this._QueryData();
  598 + },
  599 + async _QueryClassList() {
  600 + const fetchClassList =
  601 + this.role == "ROLE_BANZHUREN"
  602 + ? this.$request.cTClassList
  603 + : this.$request.tClassList;
  604 + const { data, status, info } = await fetchClassList({ status: 1 });
  605 + if (status === 0) {
  606 + this.classList = data.list.map((item) => {
  607 + return {
  608 + value: item.classId,
  609 + label: item.className,
  610 + };
  611 + });
  612 + this.query.classId = this.classList[0]?.value;
  613 + } else {
  614 + this.$message.error(info);
  615 + }
  616 + },
  617 + async _QuerySubjectList() {
  618 + const fetchSubjectList =
  619 + this.role == "ROLE_BANZHUREN"
  620 + ? this.$request.cTSubjectList
  621 + : this.$request.tSubjectList;
  622 +
  623 + const { data, status, info } = await fetchSubjectList({
  624 + classId: this.query.classId,
  625 + status: 1,
  626 + });
  627 + if (status === 0) {
  628 + this.subjectList =
  629 + data.subjectNames?.map((item) => {
  630 + return {
  631 + value: item,
  632 + label: item,
  633 + };
  634 + }) || [];
  635 + if (this.role == "ROLE_BANZHUREN") {
  636 + this.subjectList.unshift({
  637 + value: "全部",
  638 + label: "全部",
  639 + });
  640 + this.query.subjectNames.push(this.subjectList[0]?.value);
  641 + } else {
  642 + this.query.subjectNames = this.subjectList[0]?.value;
  643 + }
  644 + } else {
  645 + this.$message.error(info);
  646 + }
  647 + },
  648 + async _QueryData() {
  649 + this.tableData = [];
  650 + if (this.tabIndex == 1) {
  651 + this.examReportList();
  652 + } else {
  653 + this.phaseExamReport();
  654 + }
  655 + },
  656 + //单卷测练
  657 + async examReportList() {
  658 + this.loading = true;
  659 + let query = {};
  660 + for (let key in this.query) {
  661 + if (this.query[key] != "") {
  662 + query[key] = this.query[key];
  663 + }
  664 + }
  665 + if (this.role != "ROLE_BANZHUREN") {
  666 + query.subjectNames = [query.subjectNames];
  667 + } else {
  668 + if (
  669 + query["subjectNames"] &&
  670 + query["subjectNames"].length == 1 &&
  671 + query["subjectNames"][0] == "全部"
  672 + ) {
  673 + query["subjectNames"] = this.subjectList.map((item) => {
  674 + return item.value;
  675 + });
  676 + query["subjectNames"].shift();
  677 + }
  678 + if (!query["subjectNames"]) {
  679 + this.$message.warning("请选择科目");
  680 + return;
  681 + }
  682 + }
  683 + const { data, status, info } = await this.$request.examReportList({
  684 + ...query,
  685 + page: this.page,
  686 + size: this.size,
  687 + });
  688 + this.loading = false;
  689 + if (status === 0) {
  690 + this.tableData = (data?.list && [...data?.list]) || [];
  691 + this.total = data?.count || 0;
  692 + } else {
  693 + this.$message.error(info);
  694 + }
  695 + },
  696 + //多卷测练
  697 + async phaseExamReport() {
  698 + this.loading = true;
  699 + let query = {};
  700 + for (let key in this.query) {
  701 + if (this.query[key] != "") {
  702 + if (key == "subjectNames" && this.role != "ROLE_BANZHUREN") {
  703 + query["subjectName"] = this.query[key];
  704 + } else {
  705 + query[key] = this.query[key];
  706 + }
  707 + }
  708 + }
  709 + if (this.role == "ROLE_BANZHUREN") {
  710 + if (
  711 + query["subjectNames"] &&
  712 + query["subjectNames"]?.length == 1 &&
  713 + query["subjectNames"][0] == "全部"
  714 + ) {
  715 + query["subjectNames"] = this.subjectList.map((item) => {
  716 + return item.value;
  717 + });
  718 + query["subjectNames"]?.shift();
  719 + }
  720 + }
  721 + const phaseExamReport =
  722 + this.role == "ROLE_BANZHUREN"
  723 + ? this.$request.cTPhaseExamReport
  724 + : this.$request.phaseExamReport;
  725 + const { data, status, info } = await phaseExamReport({
  726 + ...query,
  727 + });
  728 + this.loading = false;
  729 + if (status === 0) {
  730 + this.total = data.count;
  731 + if (this.role == "ROLE_BANZHUREN") {
  732 + let subjectName = [];
  733 + this.tableData = data?.list.map((item) => {
  734 + let params = {};
  735 + item.dataList.map((items, index) => {
  736 + if (!subjectName.includes(items.subjectName)) {
  737 + subjectName.push(items.subjectName);
  738 + }
  739 + params["examCount" + items.subjectName] = items.examCount;
  740 + params["participationCount" + items.subjectName] =
  741 + items.participationCount;
  742 + params["score" + items.subjectName] = items.score;
  743 + params["classRank" + items.subjectName] = items.classRank;
  744 + });
  745 + return {
  746 + ...item,
  747 + ...params,
  748 + };
  749 + });
  750 + this.answerList = [...subjectName];
  751 + } else {
  752 + let dataIdsList = [],
  753 + dataList = [];
  754 + data?.list.map((item) => {
  755 + item.examList.map((items) => {
  756 + if (!dataIdsList.includes(items.title)) {
  757 + dataIdsList.push(items.title);
  758 + dataList.push(items);
  759 + }
  760 + });
  761 + });
  762 + console.log(dataList);
  763 + this.tableData = data?.list.map((item) => {
  764 + let params = {};
  765 + dataIdsList.map((ids, index) => {
  766 + params["score" + index] = "--";
  767 + params["classRank" + index] = "--";
  768 + item.examList.map((items) => {
  769 + if (items.title == ids) {
  770 + params["score" + index] = items.score;
  771 + params["classRank" + index] = items.classRank;
  772 + }
  773 + });
  774 + });
  775 + return {
  776 + ...item,
  777 + ...params,
  778 + };
  779 + });
  780 + this.answerList = dataList;
  781 + }
  782 + } else {
  783 + this.$message.error(info);
  784 + }
  785 + },
  786 + async downExl() {
  787 + //报表到处
  788 + if (this.exportLoading == true) return;
  789 + let query = {};
  790 + for (let key in this.query) {
  791 + if (this.query[key] != "") {
  792 + if (key == "subjectNames" && this.role != "ROLE_BANZHUREN") {
  793 + query["subjectName"] = this.query[key];
  794 + } else {
  795 + query[key] = this.query[key];
  796 + }
  797 + }
  798 + }
  799 + if (this.role == "ROLE_BANZHUREN") {
  800 + if (
  801 + query["subjectNames"] &&
  802 + query["subjectNames"].length == 1 &&
  803 + query["subjectNames"][0] == "全部"
  804 + ) {
  805 + query["subjectNames"] = this.subjectList.map((item) => {
  806 + return item.value;
  807 + });
  808 + query["subjectNames"].shift();
  809 + }
  810 + if (!query["subjectNames"]) {
  811 + this.$message.warning("请选择科目");
  812 + return;
  813 + }
  814 + }
  815 + const exportPhaseExamReport =
  816 + this.role == "ROLE_BANZHUREN"
  817 + ? this.$request.cTExportPhaseExamReport
  818 + : this.$request.exportPhaseExamReport;
  819 + this.exportLoading = true;
  820 + const data = await exportPhaseExamReport({ ...query });
  821 + this.exportLoading = false;
  822 + if (data && !data.code) {
  823 + let blob = new Blob([data], {
  824 + type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  825 + });
  826 + downloadFile("即时测-已归档阶段测练报表.xlsx", blob);
  827 + } else {
  828 + this.$message.error(data.info);
  829 + }
  830 + },
  831 + },
  832 +};
  833 +</script>
  834 +
  835 +<style>
  836 +div::-webkit-scrollbar {
  837 + width: 3px;
  838 + height: 10px;
  839 +}
  840 +div::-webkit-scrollbar-thumb {
  841 + border-radius: 10px;
  842 + background-color: #ccc;
  843 +}
  844 +</style>
  845 +<style lang="scss" scoped>
  846 +.page-container {
  847 + position: relative;
  848 + height: 100%;
  849 + &.active {
  850 + overflow: hidden;
  851 + }
  852 +}
  853 +.table-box {
  854 + margin: 0 20px;
  855 + padding: 16px;
  856 + background: #f8f8f8;
  857 + border-radius: 5px;
  858 + :deep(.fa-arrow-right) {
  859 + padding-left: 2px;
  860 + }
  861 + :deep(.fa-file-text) {
  862 + padding-left: 2px;
  863 + }
  864 +}
  865 +.down {
  866 + padding-top: 16px;
  867 +}
  868 +.click-b {
  869 + cursor: pointer;
  870 + color: #409eff;
  871 + text-decoration: underline;
  872 +}
  873 +</style>
0 874 \ No newline at end of file
... ...
src/views/standard/test/index.vue
... ... @@ -4,6 +4,23 @@
4 4 <template slot="title">
5 5 <span>即时测-数据报表</span>
6 6 </template>
  7 + <template slot="btns">
  8 + <el-tooltip
  9 + v-if="!code"
  10 + effect="dark"
  11 + content="已归档试卷"
  12 + placement="bottom"
  13 + >
  14 + <el-button
  15 + type="primary"
  16 + icon="fa fa-archive"
  17 + size="mini"
  18 + plain
  19 + circle
  20 + @click="toArchiving"
  21 + ></el-button>
  22 + </el-tooltip>
  23 + </template>
7 24 </back-box>
8 25 <div class="answer-header">
9 26 <div class="sel-box">
... ... @@ -93,12 +110,14 @@
93 110 @change="changeTab"
94 111 style="margin-bottom: 20px"
95 112 >
96   - <el-radio-button :label="1">单卷测练报表</el-radio-button>
97   - <el-radio-button
98   - :label="2"
99   - v-show="this.query.startDay != this.query.endDay"
100   - >阶段测练报表</el-radio-button
101   - >
  113 + <template v-for="(item, index) in tabList">
  114 + <el-radio-button
  115 + v-if="index == 0 || query.startDay != query.endDay"
  116 + :key="index"
  117 + :label="index + 1"
  118 + >{{ item }}</el-radio-button
  119 + >
  120 + </template>
102 121 </el-radio-group>
103 122 <div v-show="tabIndex == 1" v-loading="loading">
104 123 <el-table :data="tableData" border style="width: 100%">
... ... @@ -485,6 +504,7 @@ import BusEvent from &quot;@/utils/busEvent&quot;;
485 504 export default {
486 505 data() {
487 506 return {
  507 + code: "",
488 508 exportLoading: false,
489 509 tableMaxHeight: 300,
490 510 role: "",
... ... @@ -507,6 +527,7 @@ export default {
507 527 endDay: "",
508 528 day: "",
509 529 },
  530 + tabList: ["单卷测练报表", "阶段测练报表"],
510 531 classList: [], //班级
511 532 subjectList: [], //科目
512 533 tabIndex: 1, //选项卡
... ... @@ -518,10 +539,14 @@ export default {
518 539 };
519 540 },
520 541 async created() {
  542 + this.code = localStorage.getItem("csCode") || "";
521 543 this.role =
522 544 this.$store.getters.info.showRole ||
523 545 this.$store.getters.info.permissions[0].role;
524 546 await this._QueryClassList();
  547 + if (!this.query.classId) {
  548 + return;
  549 + }
525 550 await this._QuerySubjectList();
526 551 await this.setDate(1);
527 552 let startDay = this.query?.startDay;
... ... @@ -533,20 +558,25 @@ export default {
533 558 activated() {
534 559 const that = this;
535 560 BusEvent.$on("keepAlive", async function () {
536   - that.query.subjectNames = that.role == "ROLE_BANZHUREN" ? [] : "";
537   - await that._QueryClassList();
538   - await that._QuerySubjectList();
539   - await that.setDate(1);
540   - let startDay = that.query?.startDay;
541   - if (!startDay) {
542   - that.query.startDay = new Date();
543   - that.query.endDay = new Date();
544   - }
  561 + // if (that.$route.path == "/test") {
  562 + that.query.subjectNames = that.role == "ROLE_BANZHUREN" ? [] : "";
  563 + await that._QueryClassList();
  564 + if (!that.query.classId) {
  565 + return;
  566 + }
  567 + await that._QuerySubjectList();
  568 + await that.setDate(1);
  569 + let startDay = that.query?.startDay;
  570 + if (!startDay) {
  571 + that.query.startDay = new Date();
  572 + that.query.endDay = new Date();
  573 + }
  574 + // }
545 575 });
546 576 },
547 577 methods: {
548 578 print() {
549   - tablePrint("print-content");
  579 + tablePrint("print-content", "即时测-" + this.tabList[this.tabIndex - 1]);
550 580 },
551 581 changeSub(val) {
552 582 //科目改变触发事件
... ... @@ -560,6 +590,11 @@ export default {
560 590 return sub != "全部" ? item != "全部" : item == "全部";
561 591 });
562 592 },
  593 + toArchiving() {
  594 + this.$router.push({
  595 + path: "/testArchiving",
  596 + });
  597 + },
563 598 linkTo(obj) {
564 599 //去详情
565 600 this.$router.push({
... ... @@ -573,12 +608,15 @@ export default {
573 608 },
574 609 toPortrait(obj) {
575 610 //暂时不上线
576   - return
  611 + return;
577 612 if (this.$store.getters.code) {
578 613 return;
579 614 }
580 615 let subjectNames = [];
581   - subjectNames = this.role == 'ROLE_BANZHUREN'?[...this.query["subjectNames"]]:[this.query["subjectNames"]];
  616 + subjectNames =
  617 + this.role == "ROLE_BANZHUREN"
  618 + ? [...this.query["subjectNames"]]
  619 + : [this.query["subjectNames"]];
582 620 if (
583 621 this.query["subjectNames"] &&
584 622 this.query["subjectNames"]?.length == 1 &&
... ... @@ -600,7 +638,7 @@ export default {
600 638 studentCode: obj.studentCode,
601 639 startDay: this.query.startDay,
602 640 endDay: this.query.endDay,
603   - date:this.date
  641 + date: this.date,
604 642 },
605 643 });
606 644 },
... ... @@ -698,9 +736,9 @@ export default {
698 736 this.page = 1;
699 737 this._QueryData();
700 738 },
701   - upSuccess(res) {
702   - //导入成功
703   - this.$message.success("导入成功")
  739 + upSuccess(res) {
  740 + //导入成功
  741 + this.$message.success("导入成功");
704 742 this.diaUp = false;
705 743 this._QueryData();
706 744 },
... ...