Commit 255e2506f2be1faa5f97e4a098961b2e471db2a6

Authored by 梁保满
1 parent dbbfc6c5

飞书bug及优化

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