Commit 27fca4d6a0c617b1bb45ad81e099c98f89f1e719

Authored by LH_PC
2 parents def1d479 78ff4d94

Merge branch 'ezTeach-2.0.0.0.release' of http://120.78.57.84/baoman/Ezquiz_Plat…

…form into ezTeach-2.0.0.0.release
src/api/apis/apis.js
... ... @@ -8,11 +8,11 @@ const defaltService = (url, data) => {
8 8 data,
9 9 });
10 10 };
11   -const defaltGetService = (url, data) => {
  11 +const defaltGetService = (url, params) => {
12 12 return service({
13 13 url: url,
14   - method: "Get",
15   - data,
  14 + method: "GET",
  15 + params,
16 16 });
17 17 };
18 18 const downService = (url, data) => {
... ... @@ -193,6 +193,35 @@ export default {
193 193 tPaperDetail(data) {
194 194 return defaltService(setUpUrls.tPaperDetail, data);
195 195 },
  196 + tPaperDownload(paperId, title) {
  197 + return new Promise((resolve, reject) => {
  198 + service({
  199 + method: "get",
  200 + url: setUpUrls.tPaperDownload + "?id=" + paperId, // 请求地址
  201 + responseType: "blob" // 表明返回服务器返回的数据类型
  202 + }).then(
  203 + (response) => {
  204 + resolve(response);
  205 + console.log(response)
  206 + let fileName = title + ".docx";
  207 + if (window.navigator.msSaveOrOpenBlob) {
  208 + navigator.msSaveBlob(response, fileName);
  209 + } else {
  210 + let link = document.createElement("a");
  211 + link.href = window.URL.createObjectURL(response);
  212 + link.download = fileName;
  213 + link.click();
  214 + window.URL.revokeObjectURL(link.href);
  215 + }
  216 + },
  217 + (err) => {
  218 + reject(err);
  219 + }
  220 + );
  221 + });
  222 +
  223 + // return defaltGetService(setUpUrls.tPaperDownload + "?id=" + paperId);
  224 + },
196 225 //任课老师-查询管理班级授课科目
197 226 tSubjectList(data) {
198 227 return defaltService(setUpUrls.tSubjectList, data);
... ...
src/api/urls/apis.js
... ... @@ -78,6 +78,7 @@ export default {
78 78 tTestExamReport: "/api_html/teaching/testExamReport",
79 79 //任课老师-查询答题卡详情
80 80 tPaperDetail: "/api_html/teaching/paperDetail",
  81 + tPaperDownload: "/api_html/teaching/wrongQuestion/download",
81 82 //任课老师-查询管理班级授课科目
82 83 tSubjectList: "/api_html/teaching/subjectList",
83 84 tListExamReport: "/api_html/teaching/listExamReport",
... ... @@ -505,7 +506,7 @@ export default {
505 506 // 获取年级信息
506 507 teacherClassList: "api_html/teaching/classList",
507 508 // 获取班级信息
508   - teacherGradeList: "api_html/teaching/grade",
  509 + teacherGradeList: "api_html/teaching/gradeByTeacher",
509 510 // 保存接口
510 511 getWrongQuestionSave: "api_html/teaching/wrongQuestion/save",
511 512 };
... ...
src/assets/images/aside/wrong-question-default.png 0 → 100644

6.1 KB

src/assets/images/aside/wrong-question.png 0 → 100644

5.88 KB

src/router/index.js
... ... @@ -346,8 +346,8 @@ let addrouters = [
346 346 },
347 347 {
348 348 path: "/wrongQuestion",
349   - iconImage: require("@/assets/images/aside/suitangwen-baobiao-default.png"),
350   - selectedIconImage: require("@/assets/images/aside/suitangwen-baobiao-selected.png"),
  349 + iconImage: require("@/assets/images/aside/wrong-question-default.png"),
  350 + selectedIconImage: require("@/assets/images/aside/wrong-question.png"),
351 351 name: "错题组卷",
352 352 demoRoles: ["ROLE_JIAOSHI"],
353 353 component: wrongQuestion,
... ...
src/utils/index.js
... ... @@ -614,13 +614,18 @@ export function getBlob(url) {
614 614 });
615 615 }
616 616 export function fetchHTML(url) {
617   - var xhr = new XMLHttpRequest();
618   - xhr.open("GET", url, false);
619   - xhr.send();
620   - if (xhr.status === 200) {
621   - return xhr.responseText;
622   - } else {
623   - return null;
  617 + try {
  618 + var xhr = new XMLHttpRequest();
  619 + xhr.open("GET", url, false);
  620 + xhr.send();
  621 + if (xhr.status === 200) {
  622 + return xhr.responseText;
  623 + } else {
  624 + return "";
  625 + }
  626 + }
  627 + catch (e) {
  628 + return "";
624 629 }
625 630 }
626 631 /**
... ... @@ -990,7 +995,6 @@ export function paperPrint(paper) {
990 995 // size: A4 portrait;
991 996 // size: A3 landscape;
992 997  
993   - printWin.document.title = "中天易教";
994 998 const style = printWin.document.createElement('style');
995 999 style.innerHTML = `
996 1000 @media print
... ... @@ -998,7 +1002,7 @@ export function paperPrint(paper) {
998 1002 @page {
999 1003 size: A4 portrait;
1000 1004 margin-top:0mm;
1001   - margin-bottom:10mm;
  1005 + margin-bottom:8.5mm;
1002 1006 margin-left:4mm;
1003 1007 margin-right:4mm;
1004 1008 }
... ...
src/views/basic/askTestQuestion/components/wrongQuestionDialog.vue
... ... @@ -37,6 +37,11 @@
37 37 style="padding: 0 200px"
38 38 />
39 39 </div>
  40 + <div class="binding">
  41 + <div class="size color">班级:_____________</div>
  42 + <div class="size color">姓名:_____________</div>
  43 + <div class="size color">学号:_____________</div>
  44 + </div>
40 45 <div class="test-group">
41 46 <div
42 47 class="outer-item"
... ... @@ -59,7 +64,7 @@
59 64 <div
60 65 class="test-group-title"
61 66 :class="{
62   - border: selectedIndex == group.questionType,
  67 + borderTitle: selectedIndex == group.questionType,
63 68 }"
64 69 @mouseenter="handleGroupMouseEnter(group.questionType, 'all')"
65 70 >
... ... @@ -95,7 +100,7 @@
95 100 left: tooltipPosition.x + 'px',
96 101 }"
97 102 >
98   - 单击设置试卷标题
  103 + 单击修改大题名称
99 104 </div>
100 105  
101 106 <span
... ... @@ -158,10 +163,18 @@
158 163 >分
159 164 </div>
160 165 <div class="edit-button">
161   - <el-button class="button-width" type="primary" @click="handleSava"
  166 + <el-button
  167 + :disabled="dataYesNo(groups)"
  168 + class="button-width"
  169 + type="primary"
  170 + @click="handleSava"
162 171 >保存试卷</el-button
163 172 >
164   - <el-button class="button-width" plain @click="handleSava('print')"
  173 + <el-button
  174 + :disabled="dataYesNo(groups)"
  175 + class="button-width"
  176 + plain
  177 + @click="handleSava('print')"
165 178 >保存并打印</el-button
166 179 >
167 180 <el-button
... ... @@ -177,10 +190,10 @@
177 190 </div>
178 191 </div>
179 192 <div class="edit-info">
180   - <div class="title size color" style="padding: 15px 0 0 10px">
  193 + <div class="title size color" style="padding: 10px 0 5px 10px">
181 194 题目排序
182   - <span class="title size" style="color: #999999"
183   - >(拖拽题号可拖拽排序)</span
  195 + <span class="title size font-weight" style="color: #999999"
  196 + >(拖拽题号可排序)</span
184 197 >
185 198 </div>
186 199 <!-- 外层容器,允许拖拽整个组 -->
... ... @@ -202,7 +215,10 @@
202 215 v-model="group.questionScore"
203 216 :min="1"
204 217 :max="30"
205   - style="width: 100px"
  218 + style="width: 120px"
  219 + :precision="1"
  220 + :step="0.5"
  221 + @change="handleInput"
206 222 ></el-input-number>
207 223 </div>
208 224 </div>
... ... @@ -232,7 +248,6 @@
232 248 </el-dialog>
233 249 </template>
234 250 <script>
235   -import { number } from "echarts";
236 251 import draggable from "vuedraggable";
237 252 import { paperPrint } from "@/utils";
238 253 export default {
... ... @@ -273,6 +288,13 @@ export default {
273 288 return null;
274 289 },
275 290 },
  291 + userId: {
  292 + // uid
  293 + type: [String, Number],
  294 + default() {
  295 + return null;
  296 + },
  297 + },
276 298 },
277 299 data() {
278 300 return {
... ... @@ -301,24 +323,32 @@ export default {
301 323 visible(val) {
302 324 if (val) {
303 325 // 上面数据测试
304   - this.testData = JSON.parse(localStorage.getItem("testData")) || [];
305   - this.groups = JSON.parse(localStorage.getItem("question")) || [];
  326 + this.testData =
  327 + JSON.parse(localStorage.getItem(this.userId + "testData")) || [];
  328 + this.groups =
  329 + JSON.parse(localStorage.getItem(this.userId + "question")) || [];
306 330 // 如果都没有直接return 执行初始化
307 331 if (this.groups.length == 0) {
308 332 this.init();
309   - localStorage.setItem("testData", JSON.stringify(this.list));
  333 + localStorage.setItem(
  334 + this.userId + "testData",
  335 + JSON.stringify(this.list)
  336 + );
310 337 return;
311 338 }
312 339 // 如果一致 就直接赋值
313 340 if (
314 341 this.arraysHaveSameIds(this.testData, this.list) &&
315   - JSON.parse(localStorage.getItem("question"))
  342 + JSON.parse(localStorage.getItem(this.userId + "question"))
316 343 ) {
317 344 return;
318 345 } else {
319 346 let data = this.findMissingIds(this.testData, this.list);
320 347 this.testData = this.list;
321   - localStorage.setItem("testData", JSON.stringify(this.testData));
  348 + localStorage.setItem(
  349 + this.userId + "testData",
  350 + JSON.stringify(this.testData)
  351 + );
322 352 this.testAddDel(this.groups, data.addArr, data.delArr);
323 353 }
324 354 } else {
... ... @@ -345,7 +375,10 @@ export default {
345 375 this.groups.reduce((accumulator, current) => {
346 376 return accumulator.concat(current.subQuestionIds);
347 377 }, []) || [];
348   - localStorage.setItem("testData", JSON.stringify(this.testData));
  378 + localStorage.setItem(
  379 + this.userId + "testData",
  380 + JSON.stringify(this.testData)
  381 + );
349 382 },
350 383 /** 按钮 - 取消 */
351 384 handleClose() {
... ... @@ -369,7 +402,10 @@ export default {
369 402 allItems.forEach((item, index) => {
370 403 item.globalIndex = index + 1;
371 404 });
372   - localStorage.setItem("question", JSON.stringify(this.groups));
  405 + localStorage.setItem(
  406 + this.userId + "question",
  407 + JSON.stringify(this.groups)
  408 + );
373 409 },
374 410 classifyByType(arr) {
375 411 const result = {};
... ... @@ -396,7 +432,9 @@ export default {
396 432 const doc = iframeRef.contentDocument || iframeRef.contentWindow.document;
397 433 const body = iframeRef.contentWindow.document.body;
398 434 body.style.overflowX = "hidden"; // 不允许出现横向滚动条
399   - const height = body.scrollHeight; // 获取内容的高度
  435 + const height = body.offsetHeight; // 获取内容的高度
  436 + console.log(height, "height");
  437 + console.log(body, "body");
400 438 iframeRef.style.height = `${height + 20}px`; // 设置 iframe 的高度
401 439 // 获取第一个P标签
402 440 const firstP = doc.getElementsByTagName("p")[0];
... ... @@ -420,7 +458,10 @@ export default {
420 458 // 保存修改后的内容,回车或失去焦点时触发
421 459 save() {
422 460 this.isEditing = false;
423   - localStorage.setItem("question", JSON.stringify(this.groups));
  461 + localStorage.setItem(
  462 + this.userId + "question",
  463 + JSON.stringify(this.groups)
  464 + );
424 465 },
425 466  
426 467 // 单题title修改
... ... @@ -437,7 +478,10 @@ export default {
437 478 // 单体title保存
438 479 groupSave(index) {
439 480 this.$set(this.groups[index], "input", false);
440   - localStorage.setItem("question", JSON.stringify(this.groups));
  481 + localStorage.setItem(
  482 + this.userId + "question",
  483 + JSON.stringify(this.groups)
  484 + );
441 485 },
442 486 // 高亮
443 487 selectItem(id, type) {
... ... @@ -455,10 +499,16 @@ export default {
455 499 let _index = this.groups.findIndex((item) => item.questionType == id);
456 500 if (_index != -1) {
457 501 this.groups.splice(_index, 1);
458   - localStorage.setItem("question", JSON.stringify(this.groups));
  502 + localStorage.setItem(
  503 + this.userId + "question",
  504 + JSON.stringify(this.groups)
  505 + );
459 506 this.updateGlobalIndexes();
460 507 this.testDataFun();
461   - localStorage.setItem("testlist", JSON.stringify(this.testData));
  508 + localStorage.setItem(
  509 + this.userId + "testlist",
  510 + JSON.stringify(this.testData)
  511 + );
462 512 this.$emit("setQuestions");
463 513 }
464 514 } else {
... ... @@ -469,10 +519,16 @@ export default {
469 519 );
470 520 }
471 521 });
472   - localStorage.setItem("question", JSON.stringify(this.groups));
  522 + localStorage.setItem(
  523 + this.userId + "question",
  524 + JSON.stringify(this.groups)
  525 + );
473 526 this.updateGlobalIndexes();
474 527 this.testDataFun();
475   - localStorage.setItem("testlist", JSON.stringify(this.testData));
  528 + localStorage.setItem(
  529 + this.userId + "testlist",
  530 + JSON.stringify(this.testData)
  531 + );
476 532 this.$emit("setQuestions");
477 533 }
478 534 },
... ... @@ -546,18 +602,24 @@ export default {
546 602 return false;
547 603 },
548 604 processString(input) {
549   - // 正则表达式:匹配最多三位数字
550   - const regex = /^(\d{1,3})/;
551   -
552   - // 测试字符串是否以数字开头
553   - const match = input.match(regex);
  605 + // 正则表达式:
  606 + const regexs = [/[0-9]+[.)]/, /(\d+分)/, /^(\d{1,3})/];
554 607  
555   - if (match) {
556   - // 如果匹配,去掉开头的数字并返回剩余部分
557   - return input.substring(match[0].length + 1).trim();
  608 + // 使用正则表达式匹配并处理输入字符串
  609 + for (const regex of regexs) {
  610 + const match = input.match(regex);
  611 + if (match) {
  612 + if (regex === regexs[2]) {
  613 + // 如果匹配第三条规则,使用substring截取返回结果的长度加1
  614 + const matchLength = match[0].length;
  615 + return input.substring(matchLength + 1).trim();
  616 + } else {
  617 + // 如果匹配第一条或第二条规则,替换匹配的部分
  618 + input = input.replace(regex, "");
  619 + }
  620 + }
558 621 }
559 622  
560   - // 如果没有匹配,直接返回原字符串
561 623 return input;
562 624 },
563 625  
... ... @@ -607,16 +669,14 @@ export default {
607 669 // 删除数据
608 670 arr3.forEach((item3) => {
609 671 // 在 array1 中找到匹配的 type
610   - let matchedArray1Item = arr1.find(
611   - (item1) => item1.questionType == item3.questionType
  672 + let matchedArray1Item = arr1.find((item1) =>
  673 + item1.subQuestionIds.filter((item) => item.id == item3.id)
612 674 );
613 675 if (matchedArray1Item) {
614 676 // 如果找到了匹配的 type,遍历 matchedArray1Item 的 items
615 677 let _index = matchedArray1Item.subQuestionIds.findIndex(
616 678 (item) => item.id === item3.id
617 679 );
618   - console.log("_index");
619   -
620 680 if (_index != -1) {
621 681 matchedArray1Item.subQuestionIds.splice(_index, 1);
622 682 }
... ... @@ -672,10 +732,21 @@ export default {
672 732 if (res.status == 0) {
673 733 this.groups = [];
674 734 this.testData = [];
675   - localStorage.setItem("testlist", JSON.stringify(this.testData));
676   - localStorage.setItem("question", JSON.stringify(this.groups));
  735 + localStorage.setItem(
  736 + this.userId + "testlist",
  737 + JSON.stringify(this.testData)
  738 + );
  739 + localStorage.setItem(
  740 + this.userId + "question",
  741 + JSON.stringify(this.groups)
  742 + );
677 743 this.$emit("setQuestions");
678 744 this.handleClose();
  745 + this.$message({
  746 + message: "已保存到“即时测-组卷-我自编的”",
  747 + type: "success",
  748 + });
  749 +
679 750 if (type == "print") {
680 751 this.$request
681 752 .tPaperDetail({
... ... @@ -692,7 +763,7 @@ export default {
692 763 // 清空
693 764 handleClear() {
694 765 this.$confirm("确定要清空试题篮内的全部题目吗?", "提示", {
695   - confirmButtonText: "确定",
  766 + confirmButtonText: "清空",
696 767 cancelButtonText: "取消",
697 768 confirmButtonClass: "el-button--danger1",
698 769 cancelButtonClass: "el-button--primary",
... ... @@ -704,10 +775,16 @@ export default {
704 775 .then(() => {
705 776 this.groups = [];
706 777 this.testDataFun();
707   - localStorage.setItem("question", JSON.stringify(this.groups));
708   - localStorage.setItem("testlist", JSON.stringify(this.testData));
  778 + localStorage.setItem(
  779 + this.userId + "question",
  780 + JSON.stringify(this.groups)
  781 + );
  782 + localStorage.setItem(
  783 + this.userId + "testlist",
  784 + JSON.stringify(this.testData)
  785 + );
  786 +
709 787 this.$emit("setQuestions");
710   - this.handleClose();
711 788 })
712 789 .catch(() => {
713 790 console.log("取消");
... ... @@ -724,6 +801,30 @@ export default {
724 801 return sum + Number(item.questionScore) * item.subQuestionIds.length;
725 802 }, 0);
726 803 },
  804 +
  805 + // 当分数发生变化的时候
  806 + handleInput() {
  807 + localStorage.setItem(
  808 + this.userId + "question",
  809 + JSON.stringify(this.groups)
  810 + );
  811 + },
  812 + dataYesNo(data) {
  813 + if (data.length < 1) {
  814 + return true;
  815 + }
  816 + let list = [];
  817 + data.forEach((item) => {
  818 + list.push(...item.subQuestionIds);
  819 + });
  820 + console.log(list, "list");
  821 +
  822 + if (list.length < 1) {
  823 + return true;
  824 + } else {
  825 + return false;
  826 + }
  827 + },
727 828 },
728 829 };
729 830 </script>
... ... @@ -739,9 +840,9 @@ export default {
739 840 .test {
740 841 flex: 1;
741 842 height: fit-content;
742   - max-height: 742px;
  843 + height: 742px;
743 844 overflow-y: auto;
744   - box-shadow: 0 0 10px 0 #999999;
  845 + box-shadow: 0 0 10px 0 #cfcfcf;
745 846 margin-right: 20px;
746 847 box-sizing: border-box;
747 848 padding: 0 20px;
... ... @@ -763,13 +864,17 @@ export default {
763 864 justify-content: space-around;
764 865 align-items: center;
765 866 }
766   -
  867 + .binding {
  868 + display: flex;
  869 + padding: 20px 80px;
  870 + justify-content: space-around;
  871 + }
767 872 .test-group {
768 873 .test-group-title {
769 874 position: relative;
770 875 height: 40px;
771   - line-height: 30px;
772   - padding: 10px 0 0 0;
  876 + line-height: 40px;
  877 + padding: 0;
773 878 }
774 879 }
775 880 }
... ... @@ -782,7 +887,8 @@ export default {
782 887 .edit-title {
783 888 width: 100%;
784 889 height: 200px;
785   - border: 1px solid #999999;
  890 + border: 1px solid #cfcfcf;
  891 + border-radius: 5px;
786 892  
787 893 .edit-title-info {
788 894 height: 60px;
... ... @@ -814,11 +920,12 @@ export default {
814 920  
815 921 .edit-info {
816 922 flex: 1;
817   - border: 1px solid #999999;
  923 + border: 1px solid #cfcfcf;
818 924 margin-top: 20px;
819 925 max-height: 500px;
820 926 padding: 10px;
821 927 overflow: auto;
  928 + border-radius: 5px;
822 929  
823 930 .group-item {
824 931 margin: 10px;
... ... @@ -831,20 +938,21 @@ export default {
831 938 height: 40px;
832 939 justify-content: space-between;
833 940 cursor: pointer;
  941 + padding: 0 10px;
834 942 }
835 943 }
836 944  
837 945 .questions {
838 946 display: flex;
839 947 flex-wrap: wrap;
840   -
  948 + padding: 10px 0;
841 949 .question-item {
842 950 width: 35px;
843 951 height: 35px;
844 952 border: 1px solid rgb(172, 188, 249);
845 953 border-radius: 4px;
846 954 cursor: grab;
847   - margin: 5px 8px;
  955 + margin: 0 10px 10px 10px;
848 956 line-height: 35px;
849 957 text-align: center;
850 958 font-size: 16px !important;
... ... @@ -881,6 +989,7 @@ export default {
881 989 .border {
882 990 border: 1px solid rgb(173, 190, 250);
883 991 position: relative;
  992 + border-radius: 3px;
884 993  
885 994 .border-del {
886 995 position: absolute;
... ... @@ -893,7 +1002,7 @@ export default {
893 1002 color: rgb(67, 141, 255);
894 1003 font-size: 14px !important;
895 1004 line-height: 28px;
896   - font-weight: 600;
  1005 +
897 1006 cursor: pointer;
898 1007 }
899 1008 }
... ... @@ -918,9 +1027,16 @@ export default {
918 1027 background: rgb(233, 237, 253);
919 1028 width: fit-content;
920 1029 }
  1030 +.borderTitle {
  1031 + background: rgba(102, 127, 253, 0.1);
  1032 + padding: 0;
  1033 +}
921 1034  
922 1035 .title-bg {
923 1036 background: rgb(115, 142, 246);
924 1037 border-bottom: 1px solid rgb(115, 142, 246);
925 1038 }
926   -</style>
927 1039 \ No newline at end of file
  1040 +.font-weight {
  1041 + font-weight: 400;
  1042 +}
  1043 +</style>
... ...
src/views/basic/askTestQuestion/index.vue
... ... @@ -72,6 +72,8 @@
72 72 @click.native="_detailQ(item.id)">查看</el-dropdown-item>
73 73 <el-dropdown-item v-if="dataType != 1"
74 74 @click.native="_print(item)">打印</el-dropdown-item>
  75 + <el-dropdown-item v-if="dataType != 1"
  76 + @click.native="_download(item)">下载</el-dropdown-item>
75 77 <el-dropdown-item @click.native="_updateQ(item)">修改</el-dropdown-item>
76 78 <el-dropdown-item @click.native="_copy(item)">复制</el-dropdown-item>
77 79 <el-dropdown-item>
... ... @@ -658,7 +660,12 @@ export default {
658 660 }
659 661 paperPrint(data);
660 662 this.$loading.close();
661   - })
  663 + })
  664 + },
  665 + async _download(item) {
  666 + this.$loading.open();
  667 + await this.$request.tPaperDownload(item.id, item.title);
  668 + this.$loading.close();
662 669 },
663 670 _updateQ(item) {
664 671  
... ...
src/views/basic/askTestQuestion/wrongQuestion.vue
1 1 <template>
2 2 <div class="page-content" v-loading="queryLoading">
3 3 <div class="page-title">
4   - <span class="default-title">错题组卷</span>
  4 + <span class="default-title"
  5 + >错题组卷
  6 + <span class="font-weight size" style="color: #666666"
  7 + >(暂仅包含即时测内使用"导入的试卷"测验后产生的错题,不包含授课端截屏保存的错题)</span
  8 + ></span
  9 + >
  10 +
5 11 <div>
6 12 <el-select
7 13 v-model="formData.grade"
... ... @@ -71,7 +77,7 @@
71 77 </el-col>
72 78 <el-col class="col-margin" :span="8">
73 79 <span style="font-weight: 600">得分率:</span>
74   - <div>
  80 + <div style="font-size: 16px !important">
75 81 <el-input
76 82 v-model="formData.startScoreRate"
77 83 type="number"
... ... @@ -94,7 +100,7 @@
94 100 %
95 101 </div>
96 102 </el-col>
97   - <el-col class="col-margin" :span="7"
  103 + <el-col class="col-margin" :span="6"
98 104 ><span
99 105 style="font-weight: 600; width: fit-content; white-space: nowrap"
100 106 >题型:</span
... ... @@ -109,7 +115,7 @@
109 115 {{ item.label }}
110 116 </div></el-col
111 117 >
112   - <el-col class="col-margin" :span="2"
  118 + <el-col class="col-margin" style="margin-left: 10px" :span="2"
113 119 ><el-button
114 120 @click="handleSearch"
115 121 style="background: #6b73f5"
... ... @@ -130,13 +136,21 @@
130 136 >道题)</span
131 137 >
132 138 </div>
  139 + <div
  140 + style="text-align: center; line-height: 400px"
  141 + v-if="topicList.length < 1"
  142 + >
  143 + 筛选条件下,暂无题目
  144 + </div>
133 145 <div class="topic" v-for="(item, index) in topicList" :key="index">
134 146 <div class="topic-title">
135 147 <div style="display: flex">
136 148 <div style="display: flex; align-items: center">
137   - <span class="size"> 第 {{ item.questionIndex }} 题 </span>
  149 + <span class="size font-weight">
  150 + 第 {{ item.questionIndex }} 题
  151 + </span>
138 152 <div
139   - class="select-box Selected size"
  153 + class="select-box Selected size font-weight"
140 154 style="padding: 3px 5px; margin-right: 20px"
141 155 >
142 156 {{
... ... @@ -148,39 +162,46 @@
148 162 </div>
149 163 <div>
150 164 <span class="color size"> 得分率: </span>
151   - <span class="score-color size">{{ item.scoreRate }}%</span>
152   - <span class="size">({{ item.joinClassNames }})</span>
  165 + <span class="score-color size"
  166 + >{{ formatNumber(item.scoreRate) }}%</span
  167 + >
  168 + <span class="size font-weight"
  169 + >({{ item.joinClassNames }})</span
  170 + >
153 171 </div>
154 172 </div>
155 173 <div>
156   - <span class="color size">来自试卷:</span
157   - ><span class="size">{{ item.paperName }}</span>
158   - <span class="color size" style="margin-left: 20px"
  174 + <span class="color size font-weight">来自试卷:</span
  175 + ><span class="size font-weight">{{ item.paperName }}</span>
  176 + <span class="color size font-weight" style="margin-left: 20px"
159 177 >测试时间:</span
160   - ><span class="size">{{ item.testTime }}</span>
  178 + ><span class="size font-weight">{{ item.testTime }}</span>
161 179 </div>
162 180 </div>
163 181  
164 182 <iframe
165   - class="topic-info"
166 183 :src="item.screenshot"
167 184 :ref="'iframe' + index"
168   - style="width: 100%"
  185 + style="width: 100%; border: none"
169 186 @load="onIFrameLoad(index)"
170 187 />
171 188 <!-- <div class="topic-info" v-html="item.modifiedHtml"></div> -->
172 189 <div class="topic-bottom">
173   - <div>
  190 + <div style="padding-left: 20px">
174 191 <span
175 192 v-if="item.answerScreenshot"
176   - class="knowledge size"
  193 + class="knowledge size font-weight"
177 194 @click="handleAnalysis(item.answerScreenshot)"
178 195 ><i class="el-icon-key"></i>查看解析</span
179 196 >
180   - <span class="color size">知识点:</span>
181   - <span class="size">{{ item.knowledge }}</span>
  197 + <span class="color size font-weight">知识点:</span>
  198 + <span v-if="item.knowledge" class="size">{{
  199 + item.knowledge
  200 + }}</span>
  201 + <span v-else class="size color font-weight">未标注</span>
182 202 </div>
183 203 <el-button
  204 + style="margin-right: 20px"
184 205 v-if="!questions.some((obj) => item.id === obj.id)"
185 206 class="button"
186 207 type="primary"
... ... @@ -190,9 +211,9 @@
190 211 <el-button
191 212 v-else
192 213 plain
193   - style="padding: 5px 10px"
  214 + style="padding: 5px 10px; margin-right: 20px"
194 215 @click="handleDel(item)"
195   - >移试卷</el-button
  216 + >移试卷</el-button
196 217 >
197 218 </div>
198 219 </div>
... ... @@ -219,6 +240,7 @@
219 240 questions.map((item) => item.id)
220 241 )
221 242 "
  243 + style="margin-right: 20px"
222 244 @click="handleAllTest()"
223 245 >全选本页</el-button
224 246 >
... ... @@ -227,8 +249,8 @@
227 249 class="button-size"
228 250 v-else
229 251 plain
230   - style="padding: 5px 10px"
231   - >移除本页</el-button
  252 + style="padding: 5px 10px; margin-right: 20px"
  253 + >移出本页</el-button
232 254 >
233 255 </div>
234 256 <div class="shopping" @click="handleShop">
... ... @@ -247,6 +269,7 @@
247 269 :sectionId="formData.sectionId"
248 270 :gradeId="formData.grade"
249 271 @setQuestions="setQuestions"
  272 + :userId="userId"
250 273 />
251 274 <analysisDialog
252 275 :visible.sync="analysisVisible"
... ... @@ -254,11 +277,12 @@
254 277 />
255 278 </div>
256 279 </template>
257   -
258   - <script>
259   -import { setDateRules } from "@/utils";
  280 +
  281 +<script>
  282 +import { setDateRules, getKnowledge } from "@/utils";
260 283 import wrongQuestionDialog from "./components/wrongQuestionDialog.vue";
261 284 import analysisDialog from "./components/analysisDialog.vue";
  285 +
262 286 export default {
263 287 components: {
264 288 wrongQuestionDialog,
... ... @@ -288,8 +312,8 @@ export default {
288 312 classList: [],
289 313 // 时间选择
290 314 dateList: [
291   - { type: "onDay", name: "今天" },
292 315 { type: "onWeek", name: "本周" },
  316 + { type: "onMonth", name: "本月" },
293 317 { type: "term", name: "本学期" },
294 318 ],
295 319 // 题型选择
... ... @@ -306,27 +330,34 @@ export default {
306 330 formData: {
307 331 classId: 1, // 班级选中
308 332 // type: "onDay", // 时间类型
309   - type: "onDay", // 时间类型
  333 + type: "onWeek", // 时间类型
310 334 dateRange: ["2022-03-01", "2023-05-01"], // 开始结束时间
311 335 startScoreRate: 0, // 开始区间
312   - endScoreRate: 100, // 结束区间
  336 + endScoreRate: 60, // 结束区间
313 337 questionType: null, // 题型
314 338 subjectName: null, // 科目
315 339 grade: null, // 年级
316 340 gradeName: null, // 年级名称
317 341 },
  342 + userId: "",
318 343 questions: [],
319 344 };
320 345 },
321 346 created() {
  347 + let user = JSON.parse(localStorage.getItem("info"));
  348 + this.userId = user.uid;
322 349 this.handleDate(this.formData.type);
323 350 this.queryLoading = true;
324 351 this.getGradeList();
325   - if (!localStorage.getItem("testlist")) {
326   - localStorage.setItem("testlist", JSON.stringify(this.questions));
  352 + if (!localStorage.getItem(this.userId + "testlist")) {
  353 + localStorage.setItem(
  354 + this.userId + "testlist",
  355 + JSON.stringify(this.questions)
  356 + );
327 357 } else {
328   - this.questions = JSON.parse(localStorage.getItem("testlist"));
329   - console.log(this.questions, "===");
  358 + this.questions = JSON.parse(
  359 + localStorage.getItem(this.userId + "testlist")
  360 + );
330 361 }
331 362 },
332 363 methods: {
... ... @@ -369,22 +400,29 @@ export default {
369 400 return list;
370 401 },
371 402 // 获取列表
372   - async getList() {
  403 + async getList(type) {
  404 + if (type) {
  405 + this.listPage.page = 1;
  406 + }
373 407 let param = {
374 408 ...this.listPage,
375 409 ...this.formData,
  410 + startScoreRate: this.formData.startScoreRate.toString(),
  411 + endScoreRate: this.formData.endScoreRate.toString(),
376 412 startDate: this.formData.dateRange[0],
377 413 endDate: this.formData.dateRange[1],
378 414 };
379 415 let data = await this.$request.getWrongQuestionList(param);
380 416 this.queryLoading = false;
381   - this.topicList = data.data.records;
  417 + this.topicList = data.data.records.map((item) => {
  418 + return { ...item, knowledge: getKnowledge(item.knowledge) };
  419 + });
382 420 this.listPage.total = data.data.total;
383 421 // this.topicList = await this.loadAndModifyHTML(data.data.records);
384 422 },
385 423 pageSizeChange(value) {
386 424 this.listPage.page = value;
387   - this.handleSearch();
  425 + this.getList();
388 426 },
389 427  
390 428 // 全选按钮
... ... @@ -414,74 +452,91 @@ export default {
414 452 if (value < this.minValue) {
415 453 this.formData.startScoreRate = this.minValue; // 修正值
416 454 }
417   - if (value > this.maxValue) {
418   - this.formData.startScoreRate = this.maxValue; // 修正值
419   - }
420 455 if (value > this.formData.endScoreRate) {
421 456 this.formData.startScoreRate = this.formData.endScoreRate;
422 457 }
  458 +
  459 + if (!value) {
  460 + this.formData.startScoreRate = 0;
  461 + }
423 462 },
424 463 // 输入不超过100
425 464 endValidateInput(value) {
426 465 if (value < this.minValue) {
427 466 this.formData.endScoreRate = this.minValue; // 修正值
428 467 }
  468 +
  469 + if (value < this.formData.startScoreRate) {
  470 + this.formData.endScoreRate = this.formData.startScoreRate;
  471 + }
429 472 if (value > this.maxValue) {
430 473 this.formData.endScoreRate = this.maxValue; // 修正值
431 474 }
432   - if (value < this.formData.startScoreRate) {
433   - this.formData.endScoreRate = this.formData.startScoreRate;
  475 + if (!value) {
  476 + this.formData.endScoreRate = 0;
434 477 }
435 478 },
436 479  
437 480 // 搜索按钮
438 481 handleSearch() {
439 482 this.queryLoading = true;
440   - this.getList();
  483 + this.getList("type");
441 484 },
442 485  
443 486 // 加入试卷
444 487 handleAddTest(item) {
445 488 // if (this.questions.includes(item.id)) return;
446 489 if (this.questions.some((obj) => obj.id === item.id)) return;
447   - this.questions = JSON.parse(localStorage.getItem("testlist")) || [];
  490 + this.questions =
  491 + JSON.parse(localStorage.getItem(this.userId + "testlist")) || [];
448 492 this.questions.push(item);
449   - localStorage.setItem("testlist", JSON.stringify(this.questions));
  493 + localStorage.setItem(
  494 + this.userId + "testlist",
  495 + JSON.stringify(this.questions)
  496 + );
450 497 },
451 498 // 移除试卷
452 499 handleDel(item) {
453 500 let _index = this.questions.findIndex((obj) => obj.id === item.id);
454 501 if (_index !== -1) {
455 502 this.questions.splice(_index, 1); // 从索引位置删除一个元素
456   - localStorage.setItem("testlist", JSON.stringify(this.questions));
  503 + localStorage.setItem(
  504 + this.userId + "testlist",
  505 + JSON.stringify(this.questions)
  506 + );
457 507 }
458 508 },
459 509 // 全部选中
460 510 handleAllTest() {
461 511 // 获取原来的localStorage
462   - let list = JSON.parse(localStorage.getItem("testlist")) || [];
  512 + let list =
  513 + JSON.parse(localStorage.getItem(this.userId + "testlist")) || [];
463 514  
464 515 let ids = this.topicList.map((item) => {
465 516 return item;
466 517 });
467   - console.log(list, "-=-11-=");
468   -
469 518 this.questions = this.removeDuplicates([...ids, ...list]);
470   - localStorage.setItem("testlist", JSON.stringify(this.questions));
  519 + localStorage.setItem(
  520 + this.userId + "testlist",
  521 + JSON.stringify(this.questions)
  522 + );
471 523 },
472 524 // 全部删除
473 525 handleDelTest() {
474   - let list = this.removeMatchingValues(
475   - this.topicList.map((item) => item.id),
476   - this.questions.map((item) => item.id)
477   - );
  526 + let list = this.removeMatchingValues(this.topicList, this.questions);
478 527 this.questions = list;
479   - localStorage.setItem("testlist", JSON.stringify(this.questions));
  528 + localStorage.setItem(
  529 + this.userId + "testlist",
  530 + JSON.stringify(this.questions)
  531 + );
480 532 },
481 533 // 重置 去除locastorage 以及 questions
482 534 handleRest() {
483 535 this.questions = [];
484   - localStorage.setItem("testlist", JSON.stringify(this.questions));
  536 + localStorage.setItem(
  537 + this.userId + "testlist",
  538 + JSON.stringify(this.questions)
  539 + );
485 540 },
486 541 // 去重
487 542 removeDuplicates(arr) {
... ... @@ -496,11 +551,11 @@ export default {
496 551 },
497 552 // 去除第二数组中存在第一数组中的值
498 553 removeMatchingValues(arr1, arr2) {
499   - // 将第一个数组的值存入 Set,提高查找效率
500   - const valuesSet = new Set(arr1);
  554 + const arr1Ids = arr1.map((item) => item.id);
  555 + const res = arr2.filter((item) => !arr1Ids.includes(item.id));
  556 + console.log(res, "res");
501 557  
502   - // 过滤第二个数组,保留不在 Set 中的值
503   - return arr2.filter((value) => !valuesSet.has(value));
  558 + return res;
504 559 },
505 560  
506 561 // 判断第一个数组在第二个种是否全部存在
... ... @@ -514,18 +569,12 @@ export default {
514 569  
515 570 // 购物车触发弹框
516 571 handleShop() {
517   - if (this.questions.length > 0) {
518   - this.visible = true;
519   - }
  572 + this.visible = true;
520 573 },
521 574  
522 575 // 获取科目列表
523 576 async getSubject(params) {
524   - console.log(params, "params");
525   -
526 577 let data = await this.$request.getSubjectList(params);
527   - console.log(data, "--------");
528   -
529 578 this.subjectList = data.data.subjectNames;
530 579 this.formData.subjectName = this.subjectList[0];
531 580 this.getClassList();
... ... @@ -533,13 +582,9 @@ export default {
533 582 // 获取年级列表
534 583 async getGradeList() {
535 584 let data = await this.$request.getClassList();
536   - console.log(data, "----------data");
537   -
538 585 this.gradeList = Array.from(
539 586 new Map(data.data.list.map((item) => [item.grade, item])).values()
540 587 );
541   - console.log(this.gradeList, "gradeList");
542   -
543 588 this.formData.grade = this.gradeList[0].grade;
544 589 this.formData.sectionId = this.gradeList[0].section;
545 590 this.formData.gradeName = this.gradeList.find(
... ... @@ -549,16 +594,18 @@ export default {
549 594 },
550 595 // 获取班级信息
551 596 async getClassList() {
552   - let data = await this.$request.getClassList({
  597 + let data = await this.$request.getGradeList({
553 598 grade: this.formData.grade,
554 599 subjectName: this.formData.subjectName,
555 600 });
556 601 this.classList = [
557 602 { className: "全部", classId: null },
558   - ...data.data.list,
  603 + ...data.data.map((item) => {
  604 + return { className: item.className, classId: item.id };
  605 + }),
559 606 ];
560 607 this.formData.classId = null;
561   - this.getList();
  608 + this.getList("type");
562 609 },
563 610  
564 611 // 年级改变
... ... @@ -575,29 +622,52 @@ export default {
575 622 this.getClassList();
576 623 },
577 624 processString(input) {
578   - // 正则表达式:匹配最多三位数字
579   - const regex = /^(\d{1,3})/;
580   -
581   - // 测试字符串是否以数字开头
582   - const match = input.match(regex);
583   -
584   - if (match) {
585   - // 如果匹配,去掉开头的数字并返回剩余部分
586   - return input.substring(match[0].length + 1).trim();
  625 + // 正则表达式:
  626 + const regexs = [/[0-9]+[.)]/, /(\d+分)/, /^(\d{1,3})/];
  627 +
  628 + // 使用正则表达式匹配并处理输入字符串
  629 + for (const regex of regexs) {
  630 + const match = input.match(regex);
  631 + if (match) {
  632 + if (regex === regexs[2]) {
  633 + // 如果匹配第三条规则,使用substring截取返回结果的长度加1
  634 + const matchLength = match[0].length;
  635 + return input.substring(matchLength + 1).trim();
  636 + } else {
  637 + // 如果匹配第一条或第二条规则,替换匹配的部分
  638 + input = input.replace(regex, "");
  639 + }
  640 + }
587 641 }
588 642  
589   - // 如果没有匹配,直接返回原字符串
590 643 return input;
591 644 },
592 645  
593 646 // 获取ref
594 647 onIFrameLoad(index) {
595 648 const iframeRef = this.$refs["iframe" + index][0]; // 获取对应的 iframe
  649 + // const doc = iframeRef.contentDocument || iframeRef.contentWindow.document;
  650 + // const body = iframeRef.contentWindow.document.body;
  651 + // body.style.overflowX = "hidden"; // 不允许出现横向滚动条
  652 + // const height = body.scrollHeight; // 获取内容的高度
  653 + // iframeRef.style.height = `${height}px`; // 设置 iframe 的高度
  654 + // // 获取第一个P标签
  655 + // const firstP = doc.getElementsByTagName("p")[0];
  656 + // // 或者修改第一个 < p > 标签的内容;
  657 + // if (firstP) {
  658 + // let a = this.processString(firstP.innerHTML);
  659 + // firstP.innerHTML = a;
  660 + // }
596 661 const doc = iframeRef.contentDocument || iframeRef.contentWindow.document;
597 662 const body = iframeRef.contentWindow.document.body;
598 663 body.style.overflowX = "hidden"; // 不允许出现横向滚动条
599   - const height = body.scrollHeight; // 获取内容的高度
600   - iframeRef.style.height = `${height}px`; // 设置 iframe 的高度
  664 + const height = body.offsetHeight; // 获取内容的高度
  665 + console.log(height, "height");
  666 + // console.log("body.offsetHeight:", body.offsetHeight);
  667 + // console.log("body.clientHeight:", body.clientHeight);
  668 + // console.log("body.scrollHeight:", body.scrollHeight);
  669 +
  670 + iframeRef.style.height = `${height + 20}px`; // 设置 iframe 的高度
601 671 // 获取第一个P标签
602 672 const firstP = doc.getElementsByTagName("p")[0];
603 673 // 或者修改第一个 < p > 标签的内容;
... ... @@ -609,7 +679,8 @@ export default {
609 679  
610 680 // 子集删除后 父级需要更新
611 681 setQuestions() {
612   - this.questions = JSON.parse(localStorage.getItem("testlist")) || [];
  682 + this.questions =
  683 + JSON.parse(localStorage.getItem(this.userId + "testlist")) || [];
613 684 },
614 685  
615 686 // 查看解析
... ... @@ -617,11 +688,29 @@ export default {
617 688 this.analysisUrl = url;
618 689 this.analysisVisible = true;
619 690 },
  691 +
  692 + // 保留两位小数
  693 + formatNumber(num) {
  694 + // 检查是否是数字
  695 + if (typeof num !== "number") {
  696 + throw new Error("输入必须是数字");
  697 + }
  698 +
  699 + // 检查小数位数
  700 + const parts = num.toString().split(".");
  701 + if (parts.length === 2 && parts[1].length > 2) {
  702 + // 如果小数部分超过两位,保留两位小数
  703 + return parseFloat(num.toFixed(2));
  704 + } else {
  705 + // 否则返回原数据
  706 + return num;
  707 + }
  708 + },
620 709 },
621 710 };
622 711 </script>
623   -
624   - <style lang="scss" scoped>
  712 +
  713 +<style lang="scss" scoped>
625 714 .page-content {
626 715 box-sizing: border-box;
627 716 padding: 0 20px;
... ... @@ -661,12 +750,10 @@ export default {
661 750 }
662 751 }
663 752 .topic {
664   - height: fit-content;
665   - max-height: 500px;
666 753 margin-top: 15px;
667 754 display: flex;
668 755 flex-direction: column;
669   - box-shadow: 0px 0px 9px 0px #999999;
  756 + box-shadow: 0px 0px 9px 0px #cfcfcf;
670 757 border-radius: 5px;
671 758 .topic-title {
672 759 height: 45px;
... ... @@ -678,19 +765,14 @@ export default {
678 765 padding: 0 20px;
679 766 border-radius: 5px 5px 0 0;
680 767 }
681   - .topic-info {
682   - overflow-y: auto;
683   - max-height: 300px;
684   - }
685 768 .topic-bottom {
686 769 height: 45px;
687 770 display: flex;
688 771 align-items: center;
689 772 justify-content: space-between;
690   - margin: 0 20px;
691 773 font-weight: 600;
692 774 box-sizing: border-box;
693   - border-top: 1px solid #d2cdcd;
  775 + border-top: 1px dashed #e0dbdb;
694 776 .knowledge {
695 777 color: rgb(105, 134, 205);
696 778 margin-right: 30px;
... ... @@ -704,15 +786,14 @@ export default {
704 786 display: flex;
705 787 justify-content: space-between;
706 788 align-items: center;
707   - border-top: 1px solid #666666;
  789 + border-top: 1px solid #cfcfcf;
708 790 background: #ffffff;
709   - box-shadow: 0 0 3px 0 #666666;
710 791 padding: 5px 20px 0 20px;
711 792 }
712 793  
713 794 .shopping {
714   - width: 40px;
715   - height: 120px;
  795 + width: 50px;
  796 + height: 135px;
716 797 position: fixed;
717 798 top: 30%;
718 799 right: 0;
... ... @@ -730,13 +811,13 @@ export default {
730 811 text-align: center;
731 812 cursor: pointer;
732 813 .shopping-select {
733   - width: 20px;
734   - height: 20px;
  814 + width: 25px;
  815 + height: 25px;
735 816 border-radius: 50%;
736   - background: yellow;
737   - color: red;
738   - line-height: 20px;
  817 + background: #eb5151;
  818 + color: #ffffff;
739 819 font-size: 12px !important;
  820 + line-height: 25px;
740 821 }
741 822 .size {
742 823 font-size: 14px !important;
... ... @@ -752,6 +833,7 @@ export default {
752 833 margin: 10px 0;
753 834 display: flex;
754 835 align-items: center;
  836 + font-size: 16px !important;
755 837 }
756 838 .button {
757 839 background: #6b73f5;
... ... @@ -761,6 +843,7 @@ export default {
761 843 padding: 5px 10px;
762 844 border-radius: 5px;
763 845 margin: 0 8px;
  846 + font-size: 16px !important;
764 847 cursor: pointer;
765 848 white-space: nowrap;
766 849 width: fit-content;
... ... @@ -781,4 +864,15 @@ export default {
781 864 .size {
782 865 font-size: 14px !important;
783 866 }
784   -</style>
785 867 \ No newline at end of file
  868 +.font-weight {
  869 + font-weight: 400;
  870 +}
  871 +.filter-datePicker {
  872 + font-size: 16px !important;
  873 +}
  874 +::v-deep .el-button {
  875 + span {
  876 + font-size: 16px !important;
  877 + }
  878 +}
  879 +</style>
... ...