diff --git a/.gitignore b/.gitignore index 8fabdfc..1b0a45a 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ pnpm-debug.log* src/views/portrait/test.vue /src/.vs /.vs +/.vs/slnx.sqlite diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite deleted file mode 100644 index de16a4e..0000000 --- a/.vs/slnx.sqlite +++ /dev/null diff --git a/src/api/apis/apis.js b/src/api/apis/apis.js index 0cdc997..3860fda 100644 --- a/src/api/apis/apis.js +++ b/src/api/apis/apis.js @@ -1049,15 +1049,15 @@ export default { }, // 获取科目列表 getSubjectList(data) { - return defaltService(setUpUrls.subjectList, data); + return defaltService(setUpUrls.teacherSubjectList, data); }, // 获取年级信息 getClassList(data) { - return defaltService(setUpUrls.classList, data); + return defaltService(setUpUrls.teacherClassList, data); }, // 获取班级信息 getGradeList(data) { - return defaltGetService(setUpUrls.gradeList, data); + return defaltGetService(setUpUrls.teacherGradeList, data); }, // 获取班级信息 getWrongQuestionSave(data) { diff --git a/src/api/urls/apis.js b/src/api/urls/apis.js index 57f6d20..1863662 100644 --- a/src/api/urls/apis.js +++ b/src/api/urls/apis.js @@ -496,18 +496,16 @@ export default { listStudentsAndQuestions: "/api_html/teaching/listStudentsAndQuestions", //分页查询授课端日志列表 deviceZipLogList: "/api_html/school/manager/deviceZipLogList", - //获取即时测报表录分情况 getScoreType: "/api_html/teaching/getScoreType", - // 获取错题本列表 wrongQuestionList: "api_html/teaching/wrongQuestion/list", // 获取科目列表 - subjectList: "api_html/teaching/subjectList", + teacherSubjectList: "api_html/teaching/subjectList", // 获取年级信息 - classList: "api_html/teaching/classList", + teacherClassList: "api_html/teaching/classList", // 获取班级信息 - gradeList: "api_html/teaching/grade", - // 保存试卷信息 + teacherGradeList: "api_html/teaching/grade", + // 保存接口 getWrongQuestionSave: "api_html/teaching/wrongQuestion/save", }; diff --git a/src/utils/index.js b/src/utils/index.js index dabccf0..252f7ab 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -613,6 +613,17 @@ export function getBlob(url) { ); }); } +export function fetchHTML(url) { + return new Promise((resolve) => { + resolve( + service({ + url: url, + withCredentials: false, + method: "get" + }) + ); + }); +} /** * 打包压缩下载 */ @@ -871,7 +882,316 @@ export function formatGradeNameClass(data) { }); return gradeNameArr; } -_; + +///试卷定制化打印 +export async function paperPrint(paper) { + let printWin = window.open("", "_blank", "width=800,height=600,resizable=no"); + var browser = getBrowserEngine(printWin); + var subjectName = paper.subjectName; + var paperTitle = paper.title; + var paperQuestions = paper.questionList; + function getBrowserEngine(windowParams) { + if (windowParams.navigator.userAgent.indexOf("Edge") > -1) { + return "EdgeHTML"; + } + if (windowParams.navigator.userAgent.indexOf("Edg") > -1) { + return "Blink"; // Microsoft Edge (Chromium) + } + if (windowParams.navigator.userAgent.indexOf("Firefox") > -1) { + return "Gecko"; + } + if (windowParams.navigator.userAgent.indexOf("Trident") > -1) { + return "Trident"; // IE + } + if (/Chrome/.test(windowParams.navigator.userAgent) && /Google Inc/.test(windowParams.navigator.vendor)) { + return 'Google Chrome'; + } + if (/360/.test(windowParams.navigator.userAgent) || /QIHU/.test(windowParams.navigator.userAgent)) { + return '360 Browser'; + } + return "Blink"; // Assume it's Chrome, Safari, or an alternative Blink-based browser + } + function numberToChinese(num) { + const chineseDigits = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"]; + const chineseUnits = ["", "十", "百", "千", "万", "亿"]; + + let result = ''; + let unitPos = 0; // 单位的位置 + let zeroFlag = false; // 是否出现过零 + + if (num === 0) { + return chineseDigits[0]; // 特殊情况,0 返回 "零" + } + + // 处理数字,每次取一位并加上单位 + while (num > 0) { + const currentDigit = num % 10; // 取最后一位数字 + if (currentDigit === 0) { + if (!zeroFlag) { + result = chineseDigits[currentDigit] + result; // 只在出现零时添加 + zeroFlag = true; // 标记零已经出现 + } + } else { + result = chineseDigits[currentDigit] + chineseUnits[unitPos] + result; + zeroFlag = false; // 重置零的标记 + } + + num = Math.floor(num / 10); // 去掉最后一位数字 + unitPos++; + } + + // 处理 '一十' 和 '一百' 等情况 + if (result.startsWith('一十')) { + result = result.substring(1); // 去掉 '一',例如 '一十' -> '十' + } + + return result; + } + function htmlParseDom(html, getStyleScripts) { + var tempDom = document.createElement('div'); + tempDom.innerHTML = html; + var doms = tempDom.querySelectorAll('p'); + if (getStyleScripts == true) { + var styleDoms = tempDom.querySelectorAll('style'); + var scriptDoms = tempDom.querySelectorAll('script'); + return { + doms: doms, + styles: styleDoms, + scripts: scriptDoms + } + } + return { doms: doms } + } + function generatePageParams() { + const totalHeightPx = Math.max( + printWin.document.documentElement.scrollHeight, // 整个文档高度 + printWin.document.body.scrollHeight // Body 的高度 + ); + const totalHeightMM = totalHeightPx * 25.4 / 96; + // ie浏览器高度 + var A4HeightMM = 287; + if (browser == "Google Chrome") { + A4HeightMM = 297; + } + var pages = Math.ceil(totalHeightMM / A4HeightMM) + 1; + for (var page = 0; page < pages; page++) { + var pageFooteDiv = printWin.document.createElement('div'); + pageFooteDiv.classList.add('page-footer'); + pageFooteDiv.innerText = `${paperTitle} ${subjectName} 第${page + 1}页(共${pages}页)`; + pageFooteDiv.style.top = (page + 1) * A4HeightMM + (page * 5.5) + 'mm'; + printWin.document.body.appendChild(pageFooteDiv); + } + } + // size: A4 portrait; + // size: A3 landscape; + + printWin.document.title = "中天易教"; + const style = printWin.document.createElement('style'); + style.innerHTML = ` + @media print + { + @page { + size: A4 portrait; + height: 300mm; + margin-top:5mm; + margin-bottom:10mm; + margin-left:2mm; + margin-right:2mm; + } + + body { + counter-reset: page-number; /* 重置页码计数器 */ + } + + mn { + padding-top:2px; + } + } + table tfoot { + height: 0px; + display: table-footer-group; + } + table thead { + height: 20px; + display: table-header-group; + } + .student-input { + text-align:center; + margin-bottom:10px; + span + { + margin-right:10px; + } + } + .page-left { + height: 1100px; + width:30px; + position:fixed; + top:0; + left:0; + } + .page-right { + height:1100px; + width:30px; + position:fixed; + top:0; + right:0; + } + .page-header { + height:20px; + width:100%; + text-align:center; + position:fixed; + top:0; + left:0; + } + .page-footer { + height:20px; + width:100%; + text-align:center; + position: absolute; + } + h3,h2 + { + margin:3px 0px 3px 0px; + } + .title-header + { + .title-content { + text-align:center; + } + } + b + { + font-weight:500; + margin:10px 0px; + } + p,table + { + font-size:16px; + margin:0px; + padding:0px 0px 2px 0px; + + margin-block-start:0px; + margin-block-end: 0px; + margin-inline-start: 0px; + margin-inline-end: 0px; + span,*,image,img,tr,td + { + font-size:16px; + line-height:20px !important; + } + img,image + { + margin:0px; + padding:0px; + transform: scale(0.65); + transform-origin: center; + } + }`; + + printWin.document.head.appendChild(style); + + const titleBoxDom = printWin.document.createElement('div'); + titleBoxDom.classList.add('title-header'); + const titleDom = printWin.document.createElement('h3'); + titleDom.innerText = paperTitle; + titleDom.classList.add('title-content'); + const subjectDom = printWin.document.createElement('h2'); + subjectDom.innerText = subjectName; + subjectDom.classList.add('title-content'); + titleBoxDom.appendChild(titleDom); + titleBoxDom.appendChild(subjectDom); + printWin.document.body.appendChild(titleBoxDom); + + const studentInputBoxDom = printWin.document.createElement('div'); + studentInputBoxDom.classList.add('student-input'); + const studentClassInputDom = printWin.document.createElement('span'); + studentClassInputDom.innerHTML = '班级:________________'; + const studentNameInputDom = printWin.document.createElement('span'); + studentNameInputDom.innerHTML = '姓名:________________'; + const studentNoInputDom = printWin.document.createElement('span'); + studentNoInputDom.innerHTML = '学号:________________'; + studentInputBoxDom.appendChild(studentClassInputDom); + studentInputBoxDom.appendChild(studentNameInputDom); + studentInputBoxDom.appendChild(studentNoInputDom); + printWin.document.body.appendChild(studentInputBoxDom); + + const tableDom = printWin.document.createElement('table'); + const theadDom = printWin.document.createElement('thead'); + const theadTrDom = printWin.document.createElement('tr'); + theadTrDom.appendChild(printWin.document.createElement('th')); + theadTrDom.appendChild(printWin.document.createElement('th')); + theadTrDom.appendChild(printWin.document.createElement('th')); + theadDom.appendChild(theadTrDom); + tableDom.appendChild(theadDom); + + const tbodyDom = printWin.document.createElement('tbody'); + + for (var iof = 0; iof < paperQuestions.length; iof++) { + var item = paperQuestions[iof]; + if (!item || !item.subQuestions) continue; + + const tbodyTrDom = printWin.document.createElement('tr'); + const tbodyLeftAltTdDom = printWin.document.createElement('td'); + const tbodyContentTdDom = printWin.document.createElement('td'); + const tbodyRightAltTdDom = printWin.document.createElement('td'); + + const questionTitleDom = printWin.document.createElement('div'); + questionTitleDom.innerText = `${numberToChinese(iof + 1)}、${item.questionTitle}(本节共${item.subQuestions.length}小题,共${item.score}分)`; + + tbodyContentTdDom.appendChild(questionTitleDom); + tbodyTrDom.appendChild(tbodyLeftAltTdDom); + tbodyTrDom.appendChild(tbodyContentTdDom); + tbodyTrDom.appendChild(tbodyRightAltTdDom); + tbodyDom.appendChild(tbodyTrDom); + + for (var idof = 0; idof < item.subQuestions.length; idof++) { + const qTbodyTrDom = printWin.document.createElement('tr'); + const qTbodyLeftAltTdDom = printWin.document.createElement('td'); + const qTbodyContentTdDom = printWin.document.createElement('td'); + const qTbodyRightAltTdDom = printWin.document.createElement('td'); + + const questionDom = printWin.document.createElement('div'); + var subItem = item.subQuestions[idof]; + var screenshotHtml = await fetchHTML(subItem.screenshot); + var getStyleScripts = iof == 0 && idof == 0; + var screenshotObject = htmlParseDom(screenshotHtml, getStyleScripts); + var screenshotDoms = screenshotObject.doms; + if (screenshotDoms.length <= 0) continue; + for (var dom = 0; dom < screenshotDoms.length; dom++) { + var screenshotDom = screenshotDoms[dom]; + questionDom.appendChild(screenshotDom); + } + qTbodyContentTdDom.appendChild(questionDom); + qTbodyTrDom.appendChild(qTbodyLeftAltTdDom); + qTbodyTrDom.appendChild(qTbodyContentTdDom); + qTbodyTrDom.appendChild(qTbodyRightAltTdDom); + tbodyDom.appendChild(qTbodyTrDom); + } + } + tableDom.appendChild(tbodyDom); + printWin.document.body.appendChild(tableDom); + + const tfootDom = printWin.document.createElement('tfoot'); + const tfootTrDom = printWin.document.createElement('tr'); + tfootTrDom.appendChild(printWin.document.createElement('td')); + tfootTrDom.appendChild(printWin.document.createElement('td')); + tfootTrDom.appendChild(printWin.document.createElement('td')); + tfootDom.appendChild(tfootTrDom); + tableDom.appendChild(tfootDom); + // generatePageParams(); + const iamges = printWin.document.querySelectorAll('img'); + if (iamges.length >= 1) { + iamges[iamges.length - 1].onload = function () { + printWin.print(); + printWin.close(); + } + } else { + printWin.print(); + printWin.close(); + } +} export function tablePrint(options) { var id = options.id; @@ -883,22 +1203,23 @@ export function tablePrint(options) { var diffNumber = options.diffNumber ?? 0; var diffStNumber = options.diffStNumber ?? 0; let divs = document.getElementById(id); - let awin = window.open("中天易教", "_blank"); - awin.document.getElementsByTagName("head")[0].innerHTML = `