From 954f43d8b390dc340227073969bafb483c405aa8 Mon Sep 17 00:00:00 2001 From: baigl <552301061@qq.com> Date: Fri, 19 Jul 2024 14:31:54 +0800 Subject: [PATCH 01/21] =?UTF-8?q?vscode=20=E8=A1=8C=E5=B0=BE=E7=88=86?= =?UTF-8?q?=E7=BA=A2eslintrc=20=E5=85=B3=E9=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.cjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 55db58d..517a19c 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -10,6 +10,7 @@ module.exports = { ], rules: { 'vue/require-default-prop': 'off', - 'vue/multi-word-component-names': 'off' + 'vue/multi-word-component-names': 'off', + 'prettier/prettier': 'off' } } From d7097535346756f537f6075c76d8a6178dc65f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Czouyf=E2=80=9D?= <80906036@qq.com> Date: Sat, 7 Sep 2024 18:07:32 +0800 Subject: [PATCH 02/21] =?UTF-8?q?[=E8=80=83=E8=AF=95=E5=88=86=E6=9E=90]=20?= =?UTF-8?q?-=20=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/education/entpCourseWork.js | 111 +++++++ src/renderer/src/assets/styles/JYStyle.css | 99 ++++++ .../src/layout/components/AppMain.vue | 5 +- src/renderer/src/layout/components/Header.vue | 2 +- src/renderer/src/main.js | 15 + src/renderer/src/router/index.js | 6 + src/renderer/src/utils/examQuestion/jyeoo.js | 268 +++++++++++++++ src/renderer/src/utils/examQuestion/tool.js | 310 ++++++++++++++++++ .../views/examReport/container/examMocks..vue | 3 + .../views/examReport/container/examReview.vue | 99 ++++++ .../examReport/container/pointAnalysis.vue | 3 + src/renderer/src/views/examReport/index.vue | 241 ++++++++++++++ src/renderer/src/views/homePage/index.vue | 2 +- 13 files changed, 1160 insertions(+), 4 deletions(-) create mode 100644 src/renderer/src/api/education/entpCourseWork.js create mode 100644 src/renderer/src/assets/styles/JYStyle.css create mode 100644 src/renderer/src/utils/examQuestion/jyeoo.js create mode 100644 src/renderer/src/utils/examQuestion/tool.js create mode 100644 src/renderer/src/views/examReport/container/examMocks..vue create mode 100644 src/renderer/src/views/examReport/container/examReview.vue create mode 100644 src/renderer/src/views/examReport/container/pointAnalysis.vue create mode 100644 src/renderer/src/views/examReport/index.vue diff --git a/src/renderer/src/api/education/entpCourseWork.js b/src/renderer/src/api/education/entpCourseWork.js new file mode 100644 index 0000000..0ba694c --- /dev/null +++ b/src/renderer/src/api/education/entpCourseWork.js @@ -0,0 +1,111 @@ +import request from '@/utils/request' + +// 查询entpcoursework列表 +export function listEntpcoursework(query) { + return request({ + url: '/education/entpcoursework/list', + method: 'get', + params: query + }) +} + +// 查询entpcoursework详细 +export function getEntpcoursework(id) { + return request({ + url: '/education/entpcoursework/' + id, + method: 'get' + }) +} + +// 新增entpcoursework +export function addEntpcoursework(data) { + return request({ + url: '/education/entpcoursework', + method: 'post', + data: data + }) +} + +// 修改entpcoursework +export function updateEntpcoursework(data) { + return request({ + url: '/education/entpcoursework', + method: 'put', + data: data + }) +} + +// 删除entpcoursework +export function delEntpcoursework(id) { + return request({ + url: '/education/entpcoursework/' + id, + method: 'delete' + }) +} + + +// xuekubaoapi +export function xuekubaoAPI(data) { + return request({ + url: '/education/entpcoursework/xuekubaoapi', + method: 'post', + data: data + }) +} + +// PPT文件上传 +export function uploadEntpcourseworkFile(data) { + return request({ + url: '/education/entpcoursework/uploadWord', + method: 'post', + data: data + }) +} + + +// 查询entpcoursework列表 +export function listEntpcourseworkNew(query) { + return request({ + url: '/education/entpcoursework/new/list', + method: 'get', + params: query + }) +} + + +/** + * @desc: 学科网接口api + * @return: {*} + * @param {*} path 请求路径 /xopqbm/questions(无需全拼, 后端学科网sdk自动处理) + * @param {*} method 请求方式 post/get + * @param {*} params 请求参数 {key: value,} + */ +export function xkwAPI(path, method, isPostBody, params) { + return request({ + url: '/xkw/post', + method: 'post', + data: { + path: path, + method: method, + isPostBody: isPostBody, + params: params, + } + }) +} + +/** + * @desc: 图文识别接口 python_OCR_api + * @return: {*} + * @param {*} path 请求路径 /ocrApi/data + * @param {*} method 请求方式 post + * @param {*} params 请求参数 {key: value,} + */ +export function pyOCRAPI(path) { + return request({ + url: '/ocrApi/data', + method: 'post', + data: { + imageBas64: path, + } + }) +} \ No newline at end of file diff --git a/src/renderer/src/assets/styles/JYStyle.css b/src/renderer/src/assets/styles/JYStyle.css new file mode 100644 index 0000000..f44e280 --- /dev/null +++ b/src/renderer/src/assets/styles/JYStyle.css @@ -0,0 +1,99 @@ +body{font-family: "微软雅黑", Arial,"宋体"; color: #333;} +a{ text-decoration: none; color: #2489f6;} +dl, ul, ol, ul { list-style: none; padding: 0; margin: 0; } +.wrapper{ width: 1200px; margin: 0 auto; } +.ques-detail{} +.ques-detail ul li{margin-bottom: 20px;border: 1px solid #dadada;background: #fff;border-radius: 10px;} +.ques-detail ul li:last-child{ margin-bottom: 0; } + +table.edittable{ border-collapse: collapse; text-align: center; margin: 2px; } +table.edittable th, table.edittable td{ line-height: 30px; padding: 5px; white-space: normal; word-break: break-all; border: 1px solid #000; vertical-align: middle; } +table.composition{ border-collapse: collapse; text-align: left; margin: 2px; width: 98%; } +table.composition th, table.composition td{ line-height: 30px; white-space: normal; word-break: break-all; border-width: 0px; vertical-align: middle; } +table.composition2{ border-collapse: collapse;width:auto } +table.composition2 th, table.composition2 td{text-align:left;line-height:30px; white-space:normal;word-break:break-all;border:none;border-width: 0px;vertical-align: middle; } +.MathJye{ border: 0 none; direction: ltr; line-height: normal; display: inline-block; float: none; font-family: 'Times New Roman','宋体'; font-size: 15px; font-style: normal; font-weight: normal; letter-spacing: 1px; line-height: normal; margin: 0; padding: 0; text-align: left; text-indent: 0; text-transform: none; white-space: nowrap; word-spacing: normal; word-wrap: normal; -webkit-text-size-adjust: none; } +.MathJye div, .MathJye span{ border: 0 none; margin: 0; padding: 0; line-height: normal; text-align: left; height: auto; _height: auto; white-space: normal; } +.MathJye table{ border-collapse: collapse; margin: 0; padding: 0; text-align: center; vertical-align: middle; line-height: normal; font-size: inherit; *font-size: 100%; _font-size: 100%; font-style: normal; font-weight: normal; border: 0; float: none; display: inline-block; *display: inline; zoom: 0; } +.MathJye table td{ padding: 0; font-size: inherit; line-height: normal; white-space: nowrap; border: 0 none; width: auto; _height: auto; } +.MathJye_mi{ font-style: italic; } +.flipv{-ms-transform: scaleX(-1);-moz-transform: scaleX(-1);-webkit-transform: scaleX(-1);-o-transform: scaleX(-1);transform: scaleX(-1);filter: FlipH;} +.fliph{-ms-transform: scaleY(-1);-moz-transform: scaleY(-1);-webkit-transform: scaleY(-1);-o-transform: scaleY(-1);transform: scaleY(-1);filter: FlipV;} +.mathjye-bold{font-weight:800} +.mathjye-del{text-decoration:line-through} +.mathjye-underline{border-bottom:1px solid #000;padding-bottom:2px;} +@-moz-document url-prefix() {.mathjye-underline{padding-bottom:0px;}} +.mathjye-underpline{border-bottom:2px dotted #000; padding-bottom:3px;} +@-moz-document url-prefix() {.mathjye-underpline {padding-bottom:1px;}} +.mathjye-underpoint{background: url(http://img.jyeoo.net/images/formula/point.png) no-repeat center bottom; padding-bottom:4px;} +.mathjye-underpoint2{border-bottom:2px dotted #000; padding-bottom:3px;} +@-moz-document url-prefix() {.mathjye-underpoint{padding-bottom:1px;}} +.mathjye-underwave{background: url(http://img.jyeoo.net/images/formula/wave.png) bottom repeat-x; padding-bottom:4px;} +@-moz-document url-prefix() {.mathjye-underwave {padding-bottom:1px;}} +.mathjye-alignleft{display:block;text-align:left;} +.mathjye-aligncenter{display:block;text-align:center;} +.mathjye-alignright{display:block;text-align:right;} + + +/*试题*/ +.artpreview fieldset { padding-top: 10px; font-size: 14px; clear: both; overflow: hidden; zoom: 1; line-height: 24px; font-family: 'Times New Roman',宋体,sans-serif; position: relative; } +.artpreview fieldset legend { padding: 5px 0; display: block; margin: 5px; background: #f1f1f1; color: #000; overflow: hidden; zoom: 1; } +.queserror { border: 1px dotted #f00; padding: 2px; } +fieldset.quesborder {display: block;padding: 0;line-height: 25px;letter-spacing: 1px;word-break: break-all;margin: 0;} +fieldset.queserror { border: 1px solid #f00; font-size: 12px; padding: 2px; margin-bottom: 1px; } +fieldset.quesborder td, fieldset.queserror td { line-height: 16px; } +fieldset.quesborder em, fieldset.queserror em { font-style: normal; font-weight: bold; position: absolute; left: 20px; } +fieldset.thiserror1 { border: 1px solid #f00; } +fieldset.thiserror1 legend { border: 4px solid #f00; } +fieldset.thiserror2 { border: 1px solid #ADCD3C; } +fieldset.thiserror2 legend { border: 4px solid #ADCD3C; } +fieldset.thisques { border: 1px solid blue; } +fieldset.thison { border: 1px solid #A9C9E2; } +fieldset.thison div.border { border: 1px solid #ADCD3C; background-color: #F2FDDB; } +fieldset, img { border: 0 none; } +table.thison { border: 1px solid #00F; } +table.thiserr { border: 1px solid #F00; } +fieldset.thisvip1 { border: 1px solid #00F; } +fieldset.thisvip1 legend { border: 4px solid #00F; } +fieldset.status17 { border: 1px solid #ff00ff; } +fieldset.status17 legend { border: 4px solid #ff00ff; } +.selectoption { vertical-align: middle; font-size: 14px; padding: 2px; } +.selectoption:hover { color: #EA8511; } +.selectoption label { padding: 4px; line-height: 24px; } +fieldset.quesbordere { border: 2px dotted #f00; } +.answer { border: 1px dotted #ffffff; } +ol.answer li, ul.answer li { padding: 1px; font-size: 14px; } +ol.answer li:hover { background: #f2f2f2; } +.collapseContainerPanel { border: 0; } +.collapsePanelHeader { height: 30px; font-weight: bold; padding: 6px 0 0 0; } +.collapseHeaderContent { float: left; padding-left: 5px; } +.collapseContent { margin: 0; padding: 0; border: 1px solid #ccc; border-top: 0; } +.pt0 { padding: 2px 0 5px 0; font-size: 14px; font-family: "黑体",sans-serif; font-weight: 700; } +.pt1 {overflow: hidden;zoom: 1;clear: both;line-height: 25px;font-size: 14px;padding: 20px;position: relative;word-break: break-word;} +fieldset.quesborder .pt1 em { position: static; } +.pt1 img { position: relative; } +.pt2 {padding: 20px;padding-top: 0;} +.pt3, .pt4, .pt5, .pt6, .pt7 { clear: both; zoom: 1; position: relative; padding: 0px 20px 20px 80px; } +.pt8 a:link, .pt8 a:visited { margin-right: 10px; padding: 2px 5px; } +.pt8 a:hover { background: #fc0; } +.pt9 { padding: 20px; border: 0 none; color: #999999; font-size: 12px; } +.fieldtip {height: 36px;line-height: 36px;background-color: #f4f4f4;border-top: 1px solid #dadada;padding: 0 20px;color: #666666;position: relative;font-size: 12px;border-radius: 0 0 10px 10px;} +.newFieldtip .pt1, .newFieldtip .pt2, .newFieldtip .pt3, .newFieldtip .pt4, .newFieldtip .pt5, .newFieldtip .pt6, .newFieldtip .pt7, .newFieldtip .pt8, .newFieldtip.pt9, .newFieldtip + .fieldtip { padding: 0; } +fieldset img { max-width: 100%; } + +.fieldtip-left {float: left;} +.fieldtip-left >* {margin-right: 20px;} +.fieldtip-right { float: right; } +.fieldtip-right>* { margin-left: 20px; display: inline-block; color: #666666; } +.fieldtip .btn {display: inline-block;margin-bottom: 0;font-weight: normal;text-align: center;vertical-align: middle;-ms-touch-action: manipulation;touch-action: manipulation;cursor: pointer;background-image: none;border: 1px solid transparent;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;font-size: 14px;border-radius: 4px;color: #ffffff;background-color: #ff8a00;line-height: 18px;min-width: 28px;padding: 0 5px;} +.fieldtip .btn:hover, .fieldtip .btn:active, .fieldtip .btn:active:hover, .fieldtip .btn:hover { color: #ffffff; background-color: #faad4a; } + +/*填空题*/ +div.quizPutTag { display: inline-block; *display: inline; padding: 3px 10px 1px 10px; margin: 0 3px; font-size: 14px; min-width: 1em; min-height: 16px; line-height: 18px; height: auto; border-bottom: 1px solid #0033FF; text-decoration: none; zoom: 1; color: #127176; word-break: break-all; } +div.quizPutTag:hover { color: #f60; } +div.quizPutTag img { cursor: pointer; width: 200px; margin-left: 10px; } +.sanwser { padding: 4px 10px; margin: 0px; border: 1px solid #ADCD3C; background-color: #F2FDDB; color: #000; display: none; } +/*答案*/ +.selectoption label.s, div.s { border: 1px solid #91cbed; background-color: #deeeff; display: inline-block; } +.selectoption label.s.sh, div.s.sh { margin: 1px; border: none; background: none; } +del { text-decoration: none; color: #f00; font-style: normal; font-weight: normal; } \ No newline at end of file diff --git a/src/renderer/src/layout/components/AppMain.vue b/src/renderer/src/layout/components/AppMain.vue index a526b2f..0a4eb3c 100644 --- a/src/renderer/src/layout/components/AppMain.vue +++ b/src/renderer/src/layout/components/AppMain.vue @@ -72,8 +72,9 @@ const title = reactive([ child1: [] }, { - name: '高考研究', - url: '/education/colentrance', + name: '考试分析', + url: '/examReport', + type: 'hash', img: 'iconfont icon-icon_kaoshifenxi', child1: [] } diff --git a/src/renderer/src/layout/components/Header.vue b/src/renderer/src/layout/components/Header.vue index e7a4e04..640de6f 100644 --- a/src/renderer/src/layout/components/Header.vue +++ b/src/renderer/src/layout/components/Header.vue @@ -76,7 +76,7 @@ const handleOutLink = (path, type, name) => { fullPath = fullPath.replaceAll('//', '/') const { levelFirstId, levelSecondId } = JSON.parse(localStorage.getItem('unitId')) let unitId = levelSecondId ? levelSecondId :levelFirstId - if(name == '教材分析' || name == '高考研究'){ + if(name == '教材分析' || name == '考试分析'){ fullPath += `?unitId=${unitId}` } // 通知主进程 diff --git a/src/renderer/src/main.js b/src/renderer/src/main.js index da34555..b5fb488 100644 --- a/src/renderer/src/main.js +++ b/src/renderer/src/main.js @@ -8,6 +8,7 @@ import 'element-plus/dist/index.css' import './assets/iconfont/iconfont.css' import './assets/iconfont/iconfont' import 'virtual:windi.css' +import request from "@/utils/request"; import { store } from '@/store' import App from './App.vue' @@ -20,6 +21,20 @@ if(process.env.NODE_ENV != 'development') { // 非开发环境,将日志打印 const app = createApp(App) + +//专为菁优网配置的请求转发 +app.config.globalProperties.$requestGetJYW = (url,config)=>{ + config.params = config.params?config.params:{} + config.params["getjypath"] = url; + return request({ + url: "/jy/proxy", + method: config.method||"get", + params: config.params + }) +} + + + app.use(router) .use(store) .use(ElementPlus, { locale: zhLocale }).mount('#app') \ No newline at end of file diff --git a/src/renderer/src/router/index.js b/src/renderer/src/router/index.js index 14b0cd0..761d589 100644 --- a/src/renderer/src/router/index.js +++ b/src/renderer/src/router/index.js @@ -57,6 +57,12 @@ export const constantRoutes = [ name: 'class', meta: {title: '班级中心'}, }, + { + path: '/examReport', + component: () => import('@/views/examReport/index.vue'), + name: 'examReport', + meta: {title: '考试分析'} + }, ] }, ...toolRouters diff --git a/src/renderer/src/utils/examQuestion/jyeoo.js b/src/renderer/src/utils/examQuestion/jyeoo.js new file mode 100644 index 0000000..6ccf22f --- /dev/null +++ b/src/renderer/src/utils/examQuestion/jyeoo.js @@ -0,0 +1,268 @@ +const JY_TOKEN = 'CA82641DA86072DEFD39E287335E035FDA6AEEC0549B58F54F4408734C8683FFAF0585CFA3B25091E588A03A65C66A80F5FF613F539D600954007A35DFFBFDC3C7BB982771C5E13F0918642CFD7596CE3718F06E5579238D92EC809AC6F4C82A9FE4B0E232A67DD3594D4DAC1C219CCBC4A7A093344446107EB11DC317526D0594249DEBBD82B740C794CF5A7065E1982B7779AF16AD25D7'; +const JY_SUBJECT = [ + {id: 10, subject: 'math3', name: '小学数学'}, + {id: 11, subject: 'chinese3', name: '小学语文'}, + {id: 12, subject: 'english3', name: '小学英语'}, + {id: 14, subject: 'science3', name: '小学科学'}, + {id: 15, subject: 'politics3', name: '小学道德与法治'}, + {id: 20, subject: 'math', name: '初中数学'}, + {id: 21, subject: 'physics', name: '初中物理'}, + {id: 22, subject: 'chemistry', name: '初中化学'}, + {id: 23, subject: 'bio', name: '初中生物'}, + {id: 24, subject: 'science', name: '初中科学'}, + {id: 25, subject: 'geography', name: '初中地理'}, + {id: 26, subject: 'chinese', name: '初中语文'}, + {id: 27, subject: 'english', name: '初中英语'}, + {id: 28, subject: 'politics', name: '初中道德与法治'}, + {id: 29, subject: 'history', name: '初中历史'}, + {id: 30, subject: 'math2', name: '高中数学'}, + {id: 31, subject: 'physics2', name: '高中物理'}, + {id: 32, subject: 'chemistry2', name: '高中化学'}, + {id: 33, subject: 'bio2', name: '高中生物'}, + {id: 35, subject: 'geography2', name: '高中地理'}, + {id: 36, subject: 'chinese2', name: '高中语文'}, + {id: 37, subject: 'english2', name: '高中英语'}, + {id: 38, subject: 'politics2', name: '高中政治'}, + {id: 39, subject: 'history2', name: '高中历史'}, +]; + + +export const JYApiListCT = async (_this, name = '高中历史') => { + if (name === '初中政治') { + name = '初中道德与法治'; + } + const obj = JY_SUBJECT.filter(item => item.name == name); + if(obj.length < 1) { + return []; + } + const res = await _this.$requestGetJYW(`/${obj[0].subject}/common`, { + headers: { + authorization: `Token ${JY_TOKEN}` + }, + params: { + tp: 1, + }, + }); + if (res.code !== 200) { + return []; + } + let arrCT = [{ + label: '不限', + value: { + "Value": "不限", + "Key": 0 + } + }] + res.data.forEach(item=> { + if (item.Value === '选择题') { + item.Value = '单选题'; + } + const tmp = { + label: item.Value, + value: { + "Value": item.Value, + "Key": item.Key + } + } + arrCT.push(tmp); + }) + return arrCT; +} + +export const JYApiListOriginYear = () => { + const arrYear = [{label: '不限', value: '-1'}]; + let i = 0; + for( ; i < 10; i++) { + const year = new Date().getFullYear(); + const s ={ + label: `${year - i}`, + value: `${year - i}`, + } + arrYear.push(s); + }; + //arrYear.push({label: '更早', value: '0'}) + return arrYear; +} + +export const JYApiListSO = async (_this, name = '高中历史') => { + if (name === '初中政治') { + name = '初中道德与法治'; + } + + const obj = JY_SUBJECT.filter(item => item.name == name); + if(obj.length < 1) { + return []; + } + const res = await _this.$requestGetJYW(`/${obj[0].subject}/common`, { + headers: { + authorization: `Token ${JY_TOKEN}` + }, + params: { + tp: 2, + }, + }); + if (res.code !== 200) { + return []; + } + const arrSO = [{"Value": "不限", "Key": 0}, ...res.data]; + return arrSO; +} + + + +export const JYApiListPoint = async (_this, name = '高中历史') => { + if (name === '初中政治') { + name = '初中道德与法治'; + } + + const obj = JY_SUBJECT.filter(item => item.name == name); + if(obj.length < 1) { + return []; + } + const res = await _this.$requestGetJYW(`/${obj[0].subject}/point`, { + headers: { + authorization: `Token ${JY_TOKEN}` + }, + }); + if (res.code !== 200) { + return []; + } + return res.data; +} + + +/** + * @desc: 获取菁优网的版本内容 + * @return: {*} + */ +export const JYApiListVersion = async (_this, query, hasPoints=true) => { + const listVersion = { + status: 0, + msg: '', + data: [], + }; + if (query.stage === '' || query.subject === '') { + listVersion.msg = '未选中学段或学科!'; + return listVersion; + } + let name = `${query.stage}${query.subject}`; + if (name === '初中政治') { + name = '初中道德与法治'; + } + const result = JY_SUBJECT.filter( item => item.name===name); + if (result.length === 0) { + listVersion.msg = `[${name}]未找到对应菁优网教材版本, 请检查学段或学科是否匹配!`; + return listVersion; + } + const JYBook = await _this.$requestGetJYW(`/${result[0].subject}/book2`, { + headers: { + // JYToken仅占位, 实际后续已未使用该token + authorization: `Token ${JY_TOKEN}` + }, + }); + if (JYBook.code !== 200) { + listVersion.msg = `[${name}]获取菁优网教材版本失败!`; + return listVersion; + } + query.list.forEach(ele => { + if (ele.thirdkey == null) { + listVersion.msg = `[${name}-${ele.itemtitle}]菁优网教材字段标识未设置!`; + return; + } + let nPos = ele.thirdkey.indexOf('-'); + if (nPos === -1) { + listVersion.msg = `[${name}-${ele.itemtitle}-${ele.thirdkey}]菁优网教材字段标识设置有误!`; + return; + } + let editionName = ele.thirdkey.substring(0, nPos); + let typeName = ele.thirdkey.substring(nPos+1); + const resVersion = JYBook.data.filter( item => { + // 高中以typeName为标识, 而小学/初中以Name为标识 + const JYTypeName = query.stage=='高中' ? item.TypeName : item.Name; + if (item.EditionName.trim() === editionName.trim() && JYTypeName.trim() === typeName.trim()) { + return true; + } + }) + + if (resVersion.length === 0) { + listVersion.msg = `[${name}-${ele.thirdkey}]菁优网教材字段标识查询不存在!`; + return; + } + if (resVersion[0].Children.length === 0) { + listVersion.msg = `[${name}]菁优网教材字段标识查询单元内容为空!`; + return; + } + const children = JYApiListLession(resVersion[0], hasPoints); + // 高中以typeName为标识, 而小学/初中以Name为标识 + let JYTypeName = query.stage=='高中' ? resVersion[0].TypeName : resVersion[0].Name; + JYTypeName = JYTypeName.trim(); + const reset = { + id: resVersion[0].ID, + label: resVersion[0].Name.trim(), + nodeType: 'version', + children: children, + editionName: resVersion[0].EditionName.trim(), + typeName: JYTypeName, + } + listVersion.data.push(reset); + }) + + if(listVersion.data.length > 0){ + listVersion.status = 1; + } + return listVersion; +} + + +const JYApiListLession = (item, hasPoints) => { + const list = []; + item.Children.forEach(element => { + const tempList = formatCurJYLession(element, hasPoints); + list.push(tempList); + }); + return list; +} + +const formatCurJYLession = (item, hasPoints) => { + const obj = { + id: item.ID, + label: item.Name.trim(), + nodeType: 'unit', + children: [], + } + if(hasPoints) { + if (item.Children.length === 0 && !item.hasOwnProperty('Points')) { + obj.nodeType = 'points'; + obj.id = item.No; + return obj; + } + else if (item.Children.length > 0 ){ + for(let i=0; i 0){ + obj.nodeType = 'lession'; + for(let i=0; i 0 ){ + for(let i=0; i{ + if (typeof str == 'string') { + try { + let obj=JSON.parse(str); + if(typeof obj == 'object' && obj ){ + return true; + }else{ + return false; + } + } catch(e) { + return false; + } + } +}; + + +/** + * @description processExamQuestion 格式化试题 + * @param {*} row + */ +export const processExamQuestion = (row) => { + for (var i=0; iix>0); + // console.log(bjTitle,'背景标题'); + // console.log(tmTitles,'复合题目'); + let titls = []; + options.forEach((element,index1) => { + const workDescArr = element.split('#&'); + let tmp = ''; + let j=0; + for(; j`; + } + const char = String.fromCharCode(65+j); + tmp += `
${char}.${workDescArr[j]}
`; + if(j%2 == 1){ + tmp += ''; + } + + } + // j此刻已自增1, 故当选项为单数时, 需要补充结束标签 + if(j%2 == 1){ + tmp += ''; + } + + // workDescArr为 [''] 表示为 判断题或者填空题,这里不需要选项 + if(workDescArr[0] != ''){ + titls.splice(index1, 1, tmp); + }else{ + titls.splice(index1, 1, ''); + } + }); + const s = []; + tmTitles.map((it,ix)=>{ + s.push(it); + titls.map((it2,ix2)=>{ + if(ix == ix2){ + s.push(it2); + } + }) + }) + // console.log(s,'?????????????????') + + row[i].titleFormat = bjTitle + s.join(''); + row[i].workdescFormat = ''; + + + //2.答案 - 数字转为ABCD + const answerArr = JSON.parse(row[i].workanswer); + let indexLabel = 1; + let arr = []; + answerArr.forEach(item => { + const arrTmp = item.answer.split('#&'); + let value = `(${indexLabel})`; + arrTmp.forEach((element,i) => { + if(item.type == '单选题' || item.type == '多选题'){ + value += `${String.fromCharCode(65+Number(element))}`; + } + if(item.type == '判断题' || item.type == '填空题'){ + // 去除下 html标签 + value += `${element.replace(/<[^>]+>/g, '')}`+ (i==arrTmp.length-1?'':'、'); + } + if(item.type == '主观题') { + if(element){ + console.log(element,'element') + value += item.answer; + }else{ + value += '答案不唯一,请参考分析解答点评!'; + } + } + }) + arr.push(value); + indexLabel++; + }) + const answer = arr.join('
'); + + row[i].workanswerFormat = answer; + } + else { + // 处理[题干显示] - 不再需要处理 + // row[i].titleFormat = row[i].title; // 仅占位提示 + + /** + * 处理[选项显示] - 特殊结构 + * [ + * {type: '单选题', title: '题目1', options: ['ABC123','ABC123']}, + * {type: '多选题', title: '题目1', options: ['ABC123','ABC123']}, + * {type: '填空题', title: '题目1', options: []}, + * {type: '判断题', title: '题目1', options: []}, + * {type: '主观题', title: '题目1', options: []}, + * ] + */ + let workDescArr = JSON.parse(row[i].workdesc); + let workDescHtml = `
${index+1}. ${item.title}
`; + let tmp = ''; + let j=0; + let optionsArr = item.options; + for(; j`; + } + const char = String.fromCharCode(65+j); + tmp += `
${char}.${optionsArr[j]}
`; + if(j%2 == 1){ + tmp += ''; + } + } + // j此刻已自增1, 故当选项为单数时, 需要补充结束标签 + if(j%2 == 1){ + tmp += ''; + } + + workDescHtml += tmp; + } + else if(item.type == '填空题' || item.type == '判断题' || item.type == '主观题'){ + workDescHtml += `
${index+1}. ${item.title}
`; + } + }) + workDescHtml += ''; + row[i].workdescFormat = workDescHtml; + + /** + * 处理[答案显示] - 特殊结构 + * [ + * {type: '单选题', answer: ['0']}, + * {type: '多选题', answer: ['0','1']}, + * {type: '填空题', answer: ['填空1','填空2']}, + * {type: '判断题', answer: ['0'/'1']}, + * {type: '主观题', answer: [xxxx]}, + * ] + */ + let workAnswerArr = JSON.parse(row[i].workanswer); + let workAnswerHtml = ``; + workAnswerArr.map( (item, index) => { + const answerArr = item.answer; //JSON.parse(item.answer); + if(item.type == '单选题' || item.type == '多选题'){ + const answer = answerArr.map( (item) => { + return String.fromCharCode(65+Number(item)) + }).join(''); + workAnswerHtml += `
${index+1}. ${answer}
`; + } + else if(item.type == '填空题' ){ + const answer = answerArr.join('、'); + workAnswerHtml += `
${index+1}. ${answer}
`; + } + else if(item.type == '判断题' ){ + const answer = answerArr.map( (item) => { + return item === '1' ? '正确' : '错误' + }).join('、'); + workAnswerHtml += `
${index+1}. ${answer}
`; + } + else if(item.type == '主观题' ){ + // 复合题里面的主观题只有一个答案,或没填 + const answer = answerArr.join('、'); + if(answerArr[0]){ + workAnswerHtml += `
${index+1}. ${answer}
`; + }else{ + workAnswerHtml += `
${index+1}. ${answer}答案不唯一,请参考分析解答点评!
`; + } + } + }) + row[i].workanswerFormat = workAnswerHtml; + } + + } + else if(row[i].worktype == '主观题' || (row[i].worktype!=='单选题' && row[i].worktype!=='多选题' && row[i].worktype!=='填空题' && row[i].worktype!=='判断题')) { + // 处理[选项显示] - 主观题中无选项, 故置空 + row[i].workdescFormat = ''; + row[i].workanswerFormat = ''; + // 答案处理- eg: "\"不唯一的答案,参考\"" + if (row[i].workanswer && row[i].workanswer != '') { + row[i].workanswerFormat = JSON.parse(row[i].workanswer); + } + } + else { + // 单选题|多选题|填空题|判断题|主观题?(待确认是否归在这里) + // 通用选项结构 ['ABC123','ABC123'] | ['ABC123','ABC123'] | [](填空题无选项) | [](判断题无选项) + let workDescArr = []; + if (row[i].workdesc.charAt(0) === '[' && row[i].workdesc.charAt(row[i].workdesc.length - 1) === ']') { + //123会直接被转换, 且不是数组对象, 故手动判断是否有[和]两个字符 + workDescArr = JSON.parse(row[i].workdesc); + } + else if(row[i].workdesc.indexOf('#&') !== -1) { + workDescArr = row[i].workdesc.split('#&'); + } + else if(row[i].workdesc.indexOf(',') !== -1){ + workDescArr = row[i].workdesc.split(','); + } + else { + // 单字符串直接添加至空数组(待考虑确认) + workDescArr.push(row[i].workdesc); + } + + // 单选题|多选题|填空题|判断题|主观题?(待确认是否归在这里) + // 通用答案结构 ['0'] | ['0','1'] | ['填空1','填空2'] | ['0'/'1'] + let workAnswerArr = []; + if (row[i].workanswer.charAt(0) === '[' && row[i].workanswer.charAt(row[i].workanswer.length - 1) === ']') { + // 123会直接被转换, 且不是数组对象, 故手动判断是否有[和]两个字符 + workAnswerArr = JSON.parse(row[i].workanswer); + } + else if(row[i].workanswer.indexOf('#&') !== -1) { + workAnswerArr = row[i].workanswer.split('#&'); + } + else if(row[i].workanswer.indexOf(',') !== -1){ + workAnswerArr = row[i].workanswer.split(','); + } + else { + // 单字符串直接添加至空数组(待考虑确认) + workAnswerArr.push(row[i].workanswer); + } + + // 具体题型处理 + if(row[i].worktype == '单选题' || row[i].worktype == '多选题' ){ + // 处理[选项显示] - 拼接ABCD首序号 + let tmp = ''; + let j=0; + for(; j`; + } + const char = String.fromCharCode(65+j); + tmp += `
${char}.${workDescArr[j]}
`; + if(j%2 == 1){ + tmp += ''; + } + } + if(j%2== 0){ + tmp += ''; + } + row[i].workdescFormat = tmp; + + // 处理[答案显示] - 转换ABCD + let arr2Char = workAnswerArr.map( (item) => { + return String.fromCharCode(65+Number(item)) + }).join(''); + row[i].workanswerFormat = arr2Char; + } + else if(row[i].worktype == '填空题'){ + // 处理[选项显示] - 填空题中无选项, 故置空 + row[i].workdescFormat = ''; + + // 处理[答案显示] - 逗号连接 + row[i].workanswerFormat = workAnswerArr.join('、'); + } + else if(row[i].worktype == '判断题'){ + // 处理[选项显示] - 判断题中无选项, 故置空 + row[i].workdescFormat = ''; + + // 处理[答案显示] - 1-正常 0-错误 + const answer = workAnswerArr.map( (item) => { + return item === '1' ? '正确' : '错误' + }).join('、'); + row[i].workanswerFormat = answer; + } + } + } + } +} \ No newline at end of file diff --git a/src/renderer/src/views/examReport/container/examMocks..vue b/src/renderer/src/views/examReport/container/examMocks..vue new file mode 100644 index 0000000..e93cf4f --- /dev/null +++ b/src/renderer/src/views/examReport/container/examMocks..vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/renderer/src/views/examReport/container/examReview.vue b/src/renderer/src/views/examReport/container/examReview.vue new file mode 100644 index 0000000..0295275 --- /dev/null +++ b/src/renderer/src/views/examReport/container/examReview.vue @@ -0,0 +1,99 @@ + + + + + \ No newline at end of file diff --git a/src/renderer/src/views/examReport/container/pointAnalysis.vue b/src/renderer/src/views/examReport/container/pointAnalysis.vue new file mode 100644 index 0000000..5acb979 --- /dev/null +++ b/src/renderer/src/views/examReport/container/pointAnalysis.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/src/renderer/src/views/examReport/index.vue b/src/renderer/src/views/examReport/index.vue new file mode 100644 index 0000000..2163459 --- /dev/null +++ b/src/renderer/src/views/examReport/index.vue @@ -0,0 +1,241 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/renderer/src/views/homePage/index.vue b/src/renderer/src/views/homePage/index.vue index 4471853..173d324 100644 --- a/src/renderer/src/views/homePage/index.vue +++ b/src/renderer/src/views/homePage/index.vue @@ -112,7 +112,7 @@ const title = reactive([ ] }, { - name: '高考研究', + name: '考试分析', url: '/education/colentrance', img: 'iconfont icon-icon_kaoshifenxi', child1: [] From 25d026bd130ec8eb1132ff3bf4497868aa20c9df Mon Sep 17 00:00:00 2001 From: zhangxuelin <959231531@qq.com> Date: Mon, 9 Sep 2024 01:14:26 +0800 Subject: [PATCH 03/21] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/src/views/classBegins/index.vue | 3 + .../src/views/login/components/Register.vue | 247 ++++++++++++++++++ .../views/login/components/forgotPassword.vue | 0 src/renderer/src/views/login/index.vue | 20 +- 4 files changed, 267 insertions(+), 3 deletions(-) create mode 100644 src/renderer/src/views/login/components/Register.vue create mode 100644 src/renderer/src/views/login/components/forgotPassword.vue diff --git a/src/renderer/src/views/classBegins/index.vue b/src/renderer/src/views/classBegins/index.vue index ccc2af4..9e9c83d 100644 --- a/src/renderer/src/views/classBegins/index.vue +++ b/src/renderer/src/views/classBegins/index.vue @@ -104,6 +104,9 @@ const switchPageMode = () => { } } onMounted(async () => { + window.addEventListener('focus', () => { + console.log(11111111111111) + }) const isDev = process.env.NODE_ENV == 'development' // toolState.showBoardAll = false // 隐藏画板 toolState.isPdfWin=true //设置打开pdf窗口 diff --git a/src/renderer/src/views/login/components/Register.vue b/src/renderer/src/views/login/components/Register.vue new file mode 100644 index 0000000..1889b04 --- /dev/null +++ b/src/renderer/src/views/login/components/Register.vue @@ -0,0 +1,247 @@ + + + + diff --git a/src/renderer/src/views/login/components/forgotPassword.vue b/src/renderer/src/views/login/components/forgotPassword.vue new file mode 100644 index 0000000..e69de29 diff --git a/src/renderer/src/views/login/index.vue b/src/renderer/src/views/login/index.vue index b11d241..730a34e 100644 --- a/src/renderer/src/views/login/index.vue +++ b/src/renderer/src/views/login/index.vue @@ -21,12 +21,20 @@ placeholder="请输入密码" /> - 记住密码 +
+ 记住密码 + 阅读并同意《xxx》 +
+ 登录 + @@ -48,6 +56,8 @@ + + + + diff --git a/src/renderer/src/views/classTask/container/item-dialog-score.vue b/src/renderer/src/views/classTask/container/item-dialog-score.vue new file mode 100644 index 0000000..fcd5ee4 --- /dev/null +++ b/src/renderer/src/views/classTask/container/item-dialog-score.vue @@ -0,0 +1,964 @@ + + + + + diff --git a/src/renderer/src/views/classTask/container/item-dialog.vue b/src/renderer/src/views/classTask/container/item-dialog.vue new file mode 100644 index 0000000..4519b62 --- /dev/null +++ b/src/renderer/src/views/classTask/container/item-dialog.vue @@ -0,0 +1,616 @@ + + + + + + diff --git a/src/renderer/src/views/classTask/container/task-item.vue b/src/renderer/src/views/classTask/container/task-item.vue new file mode 100644 index 0000000..9e7142e --- /dev/null +++ b/src/renderer/src/views/classTask/container/task-item.vue @@ -0,0 +1,143 @@ + + + From 7cb84ffe37632f8e4d3b63547cc80b99acd67393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E4=BA=86=E4=B8=AA=E7=99=BD?= <543593352@qq.com> Date: Mon, 9 Sep 2024 15:50:55 +0800 Subject: [PATCH 05/21] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=89=B9=E9=98=85?= =?UTF-8?q?=EF=BC=9A=E9=99=84=E4=BB=B6=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 5 +- src/renderer/src/api/classTask/index.js | 9 + .../src/components/refile-preview/index.vue | 118 ++++++++ .../src/components/refile-preview/types.ts | 7 + .../components/refile-preview/useReadFile.ts | 261 ++++++++++++++++++ .../src/views/classTask/classTask.vue | 38 +-- .../classTask/container/item-dialog-score.vue | 26 +- .../views/classTask/container/item-dialog.vue | 25 +- .../views/classTask/container/task-item.vue | 9 +- 9 files changed, 464 insertions(+), 34 deletions(-) create mode 100644 src/renderer/src/components/refile-preview/index.vue create mode 100644 src/renderer/src/components/refile-preview/types.ts create mode 100644 src/renderer/src/components/refile-preview/useReadFile.ts diff --git a/package.json b/package.json index 946990a..75644fa 100644 --- a/package.json +++ b/package.json @@ -34,10 +34,13 @@ "electron-updater": "^6.1.7", "element-plus": "^2.7.6", "fabric": "^5.3.0", + "im_electron_sdk": "^8.0.5904", + "@vue-office/docx": "^1.6.2", + "@vue-office/excel": "^1.7.11", + "@vue-office/pdf": "^2.0.2", "js-cookie": "^3.0.5", "jsencrypt": "^3.3.2", "jsondiffpatch": "0.6.0", - "im_electron_sdk": "^8.0.5904", "lodash": "^4.17.21", "pdfjs-dist": "4.4.168", "pinia": "^2.1.7", diff --git a/src/renderer/src/api/classTask/index.js b/src/renderer/src/api/classTask/index.js index f441957..a6ebe4b 100644 --- a/src/renderer/src/api/classTask/index.js +++ b/src/renderer/src/api/classTask/index.js @@ -39,6 +39,15 @@ export function updateClassworkeval(data) { }) } +// 修改classworkdata +export function updateClassworkdata(data) { + return request({ + url: '/education/classworkdata', + method: 'put', + data: data + }) +} + diff --git a/src/renderer/src/components/refile-preview/index.vue b/src/renderer/src/components/refile-preview/index.vue new file mode 100644 index 0000000..227a465 --- /dev/null +++ b/src/renderer/src/components/refile-preview/index.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/renderer/src/components/refile-preview/types.ts b/src/renderer/src/components/refile-preview/types.ts new file mode 100644 index 0000000..167bbff --- /dev/null +++ b/src/renderer/src/components/refile-preview/types.ts @@ -0,0 +1,7 @@ +export interface FileProps { + id?: number; + type?: string; + fileType?: string; + raw?: File; + filePath?: string; +} diff --git a/src/renderer/src/components/refile-preview/useReadFile.ts b/src/renderer/src/components/refile-preview/useReadFile.ts new file mode 100644 index 0000000..d93e785 --- /dev/null +++ b/src/renderer/src/components/refile-preview/useReadFile.ts @@ -0,0 +1,261 @@ +import type { FileProps } from "@/components/refile-preview/types"; +import { onUnmounted, ref } from "vue"; +import axios from "axios"; + +export function useHooks(props: FileProps) { + const excelOptions = { + xls: props.fileType !== "xlsx", //预览xlsx文件设为false;预览xls文件设为true + minColLength: 0, // excel最少渲染多少列,如果想实现xlsx文件内容有几列,就渲染几列,可以将此值设置为0. + minRowLength: 0, // excel最少渲染多少行,如果想实现根据xlsx实际函数渲染,可以将此值设置为0. + widthOffset: 10, //如果渲染出来的结果感觉单元格宽度不够,可以在默认渲染的列表宽度上再加 Npx宽 + heightOffset: 10, //在默认渲染的列表高度上再加 Npx高 + beforeTransformData: workbookData => { + return workbookData; + }, //底层通过exceljs获取excel文件内容,通过该钩子函数,可以对获取的excel文件内容进行修改,比如某个单元格的数据显示不正确,可以在此自行修改每个单元格的value值。 + transformData: workbookData => { + return workbookData; + } //将获取到的excel数据进行处理之后且渲染到页面之前,可通过transformData对即将渲染的数据及样式进行修改,此时每个单元格的text值就是即将渲染到页面上的内容 + }; + const src = ref(); + const filePreviewRef = ref(); + /** + * 渲染完成 + */ + const renderedHandler = () => { + console.log("渲染完成"); + }; + /** + * 渲染失败 + * @param e + */ + const errorHandler = e => { + console.log("渲染失败", e); + }; + + /** + * 渲染文件 + */ + async function renderTheFile() { + if (props.type === "local") { + console.log("本地文件" + props.fileType); + isImage(props.fileType) && localImagePreview(props.raw); + isDoc(props.fileType) && localOfficePreview(props.raw); + isText(props.fileType) && localTextPreview(props.raw); + isVideo(props.fileType) && localVideoPreview(props.raw); + isAudio(props.fileType) && localAudioPreview(props.raw); + } else { + if (isVideo(props.fileType)) { + src.value = + import.meta.env.VITE_APP_BASE_URL + + "/upload/attachments/getTeamOfVideo?id=" + + props.id; + return; + } + if (isText(props.fileType)) { + const response = await axios.get( + import.meta.env.VITE_STATIC_URL + props.filePath, + { + responseType: "text" + } + ); + src.value = response.data; + return; + } + src.value = import.meta.env.VITE_STATIC_URL + props.filePath; + } + } + + /** + * 校验图片类型 + * @param type + */ + function isImage(type: string) { + const types = [ + "jpg", + "png", + "gif", + "jpeg", + "bmp", + "webp", + "svg", + "tiff", + "tif", + "jpeg", + "jfif", + "pjpeg", + "pjp" + ]; + return types.includes(type); + } + + /** + * 校验文档类型 + * @param type + */ + function isDoc(type: string) { + const types = ["docx", "doc", "xlsx", "xls", "pdf"]; + return types.includes(type); + } + + /** + * 校验文本类型 + * @param type + */ + function isText(type: string) { + const types = [ + "txt", + "md", + "log", + "json", + "xml", + "html", + "css", + "js", + "java", + "c", + "cpp", + "h", + "hpp", + "py", + "rb", + "go", + "sh", + "bat", + "ps1", + "psm1", + "ps1xml", + "psc1", + "psd1", + "psm1", + "ps1xml", + "psc1", + "psd1", + "ps1xml", + "psc1", + "ps1xml", + "psc1", + "psd1" + ]; + return types.includes(type); + } + + // 检验视频格式 + function isVideo(type: string) { + const types = [ + "mp4", + "avi", + "rmvb", + "mkv", + "flv", + "wmv", + "mov", + "webm", + "m4v", + "mpg", + "mpeg", + "3gp", + "3g2", + "vob", + "ogv", + "ogg", + "mts", + "m2ts", + "ts", + "m2v", + "mpe", + "mpv", + "m4p", + "m4v", + "mpv2", + "m4v", + "m4p", + "m4v", + "m4p" + ]; + return types.includes(type); + } + + // 检验音频文件 + function isAudio(type: string) { + const types = ["mp3", "wav", "ogg", "flac", "aac", "wma", "m4a", "wma"]; + return types.includes(type); + } + + /** + * 预览本地Office文件 + * @param file + */ + function localOfficePreview(file: File) { + const reader = new FileReader(); + reader.readAsArrayBuffer(file); + reader.onload = loadEvent => { + const arrayBuffer = loadEvent.target.result; + const blob = new Blob([arrayBuffer], { + type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + }); + src.value = URL.createObjectURL(blob); + }; + } + + /** + * 预览本地图片 + * @param file + */ + function localImagePreview(file: File) { + const reader = new FileReader(); + reader.onload = e => { + src.value = e.target.result; + }; + reader.readAsDataURL(file); + } + + /** + * 预览本地文本 + * @param file + */ + function localTextPreview(file: File) { + const reader = new FileReader(); + reader.onload = e => { + src.value = e.target.result; + }; + reader.readAsText(file); + } + + /** + * 预览本地视频 + * @param file + */ + function localVideoPreview(file: File) { + src.value = URL.createObjectURL(file); + } + + function localAudioPreview(file: File) { + const reader = new FileReader(); + reader.onloadend = () => { + const blob = new Blob([reader.result], { type: "audio/mpeg" }); + src.value = URL.createObjectURL(blob); + }; + reader.readAsArrayBuffer(file); + } + + // 清理工作:当组件卸载时释放URL对象 + onUnmounted(() => { + if (src.value) { + isVideo(props.fileType) && URL.revokeObjectURL(src.value); + isAudio(props.fileType) && URL.revokeObjectURL(src.value); + } + }); + return { + excelOptions, + src, + filePreviewRef, + isImage, + renderedHandler, + errorHandler, + renderTheFile, + isVideo, + isText, + isAudio + }; +} + diff --git a/src/renderer/src/views/classTask/classTask.vue b/src/renderer/src/views/classTask/classTask.vue index 98a5d7b..1425e8c 100644 --- a/src/renderer/src/views/classTask/classTask.vue +++ b/src/renderer/src/views/classTask/classTask.vue @@ -92,7 +92,9 @@ const getData = () => { // 班级作业数据,包含多个班级 homeworklist({ classidarray: classListIds.value.join(','), - entpcourseid: '', // 章节id? 这里要全课程的作业 不分章节? + //entpcourseid: '', // 章节id? 这里要全课程的作业 不分章节? 根据学段学科查询所有的作业 + edustage: userStore.edustage,// 学段 + edusubject: userStore.edusubject,//学科 orderby: 'uniquekey DESC', pageSize: 100 }).then((response) => { @@ -101,7 +103,7 @@ const getData = () => { response.rows[i].workdatalist = [] response.rows[i].workdatacount = 0 // 人数 response.rows[i].workdatalistVisible = false - response.rows[i].workdatafeedbackcount = 0 + response.rows[i].workdatafeedbackcount = 0 // 已交人数 response.rows[i].feedtimelength = 0 response.rows[i].rightAnswerCount = 0 response.rows[i].scoingRate = 0 + '%' // 得分率 @@ -142,10 +144,10 @@ const getData = () => { } } - // 显示分配人数>0 的 + // 显示分配人数(workdatacount)>0 的 if (response.rows && response.rows.length > 0) { - classWorkList.value = - response.rows && response.rows.filter((item) => item.workdatacount > 0) + classWorkList.value = response.rows && response.rows.filter((item) => item.workdatacount > 0) + // classWorkList.value = response.rows && response.rows.filter((item) => item.workdatacount > 0 && item.uniquekey == '语文-0808-1') //TODO: 这里没分页,貌似这个 total 不重要,后续看 total.value = response.total } @@ -211,7 +213,9 @@ const getStudentVisible = async () => { // 班级作业数据,多个班级 const response = await homeworklist({ classidarray: classListIds.value.join(','), - entpcourseid: '', // 章节???这里不需要,全课程的 + //entpcourseid: '', // 章节id? 这里要全课程的作业 不分章节? 根据学段学科查询所有的作业 + edustage: userStore.edustage,// 学段 + edusubject: userStore.edusubject,//学科 orderby: 'uniquekey DESC', pageSize: 100 }) @@ -228,7 +232,7 @@ const getStudentVisible = async () => { // } // 确保当前拿到的任务与页面中存在的任务能一对一(避免因删除其他操作而删除作业任务导致两个数组的index不统一而越界) let curWork = curWorkList.find((work) => work.id === classWorkList.value[t].id) - // workdataresultcount 完成人数 workdatacount人数要大于0 + // workdataresultcount 完成人数 workdatacount人数要大于0 if (curWork && curWork.workdataresultcount > 0 && classWorkList.value[t].workdatacount > 0) { classWorkList.value[t].workdataresultcount = curWork.workdataresultcount // 桌面端貌似不需要进度条了? @@ -236,12 +240,8 @@ const getStudentVisible = async () => { (classWorkList.value[t].workdataresultcount / classWorkList.value[t].workdatacount) * 100 ) // 计算参与学习任务的平均用时 - console.log('平均用时??---', classWorkList.value[t].workdatafeedbackcount) if (classWorkList.value[t].workdatafeedbackcount > 0) { - classWorkList.value[t].averagetime = ( - classWorkList.value[t].feedtimelength / classWorkList.value[t].workdatafeedbackcount - ).toFixed(0) - console.log('平均用时---', classWorkList.value[t].averagetime) + classWorkList.value[t].averagetime = (classWorkList.value[t].feedtimelength / classWorkList.value[t].workdatafeedbackcount).toFixed(0) } else { classWorkList.value[t].averagetime = 0 } @@ -257,15 +257,18 @@ const getStudentVisible = async () => { const getStudentClassWorkData = () => { // 再查找多个班级里,每个学生的作业数据 console.log('======????????""""""""""') + //TODO 这里id变动,看后续用什么判断 listClassworkdata({ classids: classListIds.value.join(','), - entpcourseid: '', // 章节id? 这里要全课程的作业 不分章节? + //entpcourseid: '', // 章节id? 这里要全课程的作业 不分章节? 根据学段学科查询所有的作业 + edustage: userStore.edustage,// 学段 + edusubject: userStore.edusubject,//学科 + orderby: "deaddate DESC", pageSize: 1000 }).then((res) => { - console.log('多个班级里,每个学生的作业数据', res.rows) for (var t = 0; t < classWorkList.value.length; t++) { for (var i = 0; i < res.rows.length; i++) { - if (res.rows[i].classworkid == classWorkList.value[t].id) { + if (res.rows[i].uniquekey == classWorkList.value[t].uniquekey) { // if (res.rows[i].classworkid == classWorkList.value[t].id && res.rows[i].resultcount > 0) { console.log('==================') // 有几个学生完成/正在完成学习任务 @@ -332,10 +335,7 @@ const getStudentClassWorkData = () => { // 计算参与学习任务的平均用时 if (classWorkList.value[t].workdatafeedbackcount > 0) { - classWorkList.value[t].averagetime = - ( - classWorkList.value[t].feedtimelength / classWorkList.value[t].workdatafeedbackcount - ).toFixed(0) + classWorkList.value[t].averagetime = (classWorkList.value[t].feedtimelength / classWorkList.value[t].workdatafeedbackcount).toFixed(0) } else { classWorkList.value[t].averagetime = 0 } diff --git a/src/renderer/src/views/classTask/container/item-dialog-score.vue b/src/renderer/src/views/classTask/container/item-dialog-score.vue index fcd5ee4..619cc44 100644 --- a/src/renderer/src/views/classTask/container/item-dialog-score.vue +++ b/src/renderer/src/views/classTask/container/item-dialog-score.vue @@ -1,6 +1,7 @@ - +
@@ -491,6 +491,25 @@ const handleClassWorkAnalysissScoreOpen = (row) => { } //#endregion +/** 批阅:已交未交事件 */ +const tableRadioChange = (e) => { + // 关闭右侧批阅ui + isopen_dtwk_table.value = false; + console.log(e,'??????') + console.log("学生列表:", classWorkAnalysis.classworkdata) + if(e=='1'){ + tableRadio.list = classWorkAnalysis.classworkdata.filter(item => item.resultcount > 0) + tableRadio.value = '1'; + tableRadio.num0 = classWorkAnalysis.classworkdata.length - tableRadio.list.length; + tableRadio.num1 = tableRadio.list.length; + }else if(e=='0'){ + tableRadio.list = classWorkAnalysis.classworkdata.filter(item => item.resultcount == 0) + tableRadio.value = '0'; + tableRadio.num0 = tableRadio.list.length; + tableRadio.num1 = classWorkAnalysis.classworkdata.length - tableRadio.list.length; + } +} + // 将标签中的双引号增加转义 const escapeHtmlQuotes = (str) => { // 后端已replace双引号, 故前端不用在处理 diff --git a/src/renderer/src/views/classTask/container/task-item.vue b/src/renderer/src/views/classTask/container/task-item.vue index 9e7142e..44d93df 100644 --- a/src/renderer/src/views/classTask/container/task-item.vue +++ b/src/renderer/src/views/classTask/container/task-item.vue @@ -14,13 +14,16 @@  |  截止时间:{{ item.deaddate }}  | {{ tabactive }}
- +
- {{ item.workdataresultcount }}/{{ item.workdatacount }} + + {{ item.workdataresultcount }} + {{ item.workdataresultcount }} + /{{ item.workdatacount }} 已交
- 2 + {{ item.teacherRationgCount?item.teacherRationgCount:0 }} 待批阅
From d1b7101ba508f95d75ca7af3051438bd662c4e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Czouyf=E2=80=9D?= <80906036@qq.com> Date: Mon, 9 Sep 2024 16:44:24 +0800 Subject: [PATCH 06/21] =?UTF-8?q?[=E8=80=83=E8=AF=95=E5=88=86=E6=9E=90]=20?= =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=E6=98=BE=E7=A4=BA=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/src/utils/examQuestion/jyeoo.js | 12 +- .../{examMocks..vue => examMocks.vue} | 0 .../views/examReport/container/examReview.vue | 4 +- src/renderer/src/views/examReport/index.vue | 121 +++++++++++++----- 4 files changed, 92 insertions(+), 45 deletions(-) rename src/renderer/src/views/examReport/container/{examMocks..vue => examMocks.vue} (100%) diff --git a/src/renderer/src/utils/examQuestion/jyeoo.js b/src/renderer/src/utils/examQuestion/jyeoo.js index 6ccf22f..8fb0a67 100644 --- a/src/renderer/src/utils/examQuestion/jyeoo.js +++ b/src/renderer/src/utils/examQuestion/jyeoo.js @@ -47,11 +47,8 @@ export const JYApiListCT = async (_this, name = '高中历史') => { return []; } let arrCT = [{ - label: '不限', - value: { - "Value": "不限", - "Key": 0 - } + label: "不限", + value: 0 }] res.data.forEach(item=> { if (item.Value === '选择题') { @@ -59,10 +56,7 @@ export const JYApiListCT = async (_this, name = '高中历史') => { } const tmp = { label: item.Value, - value: { - "Value": item.Value, - "Key": item.Key - } + value: item.Key, } arrCT.push(tmp); }) diff --git a/src/renderer/src/views/examReport/container/examMocks..vue b/src/renderer/src/views/examReport/container/examMocks.vue similarity index 100% rename from src/renderer/src/views/examReport/container/examMocks..vue rename to src/renderer/src/views/examReport/container/examMocks.vue diff --git a/src/renderer/src/views/examReport/container/examReview.vue b/src/renderer/src/views/examReport/container/examReview.vue index 0295275..3f964c3 100644 --- a/src/renderer/src/views/examReport/container/examReview.vue +++ b/src/renderer/src/views/examReport/container/examReview.vue @@ -61,6 +61,7 @@ const showExamAnalyseDrawer = (row) => { .table-main { width: 100%; height: 100%; + text-align: left; .main-title { overflow: hidden; @@ -91,9 +92,10 @@ const showExamAnalyseDrawer = (row) => { padding: 1% 2%; border: 2px dotted; display: flex; + text-align: left; .drawer-main-col{ - padding: 6px 0px; + padding: 10px 0px; } } \ No newline at end of file diff --git a/src/renderer/src/views/examReport/index.vue b/src/renderer/src/views/examReport/index.vue index 2163459..8a67c39 100644 --- a/src/renderer/src/views/examReport/index.vue +++ b/src/renderer/src/views/examReport/index.vue @@ -8,7 +8,7 @@ @@ -18,7 +18,7 @@ @@ -28,7 +28,7 @@ @@ -42,12 +42,12 @@ @change="queryExamQuestionByParams" >
-
+
{ // 2.获取试题集合 curNode.value = data.node; - const queryParams = { - pageNum: 1, - pageSize: 100, + // 查询本地 + // const params = { + // pageNum: 1, + // pageSize: 100, + // workgroup: '1', + // edusubject: curNode.value.edusubject, + // evalid: curNode.value.id, + // orderby: 'concat(worktype,worktag) DESC', + // } + // const res = await listEntpcoursework(params); + // listExamQuestion.value = res.rows; + + // 查询本地+菁优网(后端处理) + const params = { + eid: curNode.value.id, workgroup: '1', + worktype: '不限', + workTypeId: '0', edusubject: curNode.value.edusubject, - evalid: curNode.value.id, - orderby: 'concat(worktype,worktag) DESC', + edustage: curNode.value.edustage, + sectionName: curNode.value.itemtitle, } - const res = await listEntpcoursework(queryParams); - listExamQuestion.value = res.rows; - //this.queryParams.total = res.total; + const res = await listEntpcourseworkNew(params); + if(res.data == null) { + listExamQuestion.value = []; + // queryParams.total = 0 + loading.value = false; + return; + } + listExamQuestion.value = res.data; + // queryParams.total = res.total; // 格式化试题 processExamQuestion(listExamQuestion.value); loading.value = false; } +/** + * @desc: 切换节点 + * @return: {*} + * @param {*} item + * @param {*} key + */ +const changeTaskView = (item, key) => { + curTask.viewkey = item; +} + const getWorkType = async (data) => { const selName = `${data.edustage}${data.edusubject}` const curName = `${curNode.value.edustage}${curNode.value.edusubject}` @@ -154,22 +185,42 @@ const getWorkType = async (data) => { const queryExamQuestionByParams = async () => { loading.value = true; - const params = { - pageNum: 1, - pageSize: 100, - workgroup: '1', - edusubject: curNode.value.edusubject, - evalid: curNode.value.id, - worktype: queryParams.workType, - orderby: 'concat(worktype,worktag) DESC', - } - if (queryParams.workType == '不限') { - delete params.worktype; - } + // 查询本地 + // const params = { + // pageNum: 1, + // pageSize: 100, + // workgroup: '1', + // edusubject: curNode.value.edusubject, + // evalid: curNode.value.id, + // worktype: queryParams.workType.Value, + // orderby: 'concat(worktype,worktag) DESC', + // } + // if (queryParams.workType == '不限') { + // delete params.worktype; + // } - const res = await listEntpcoursework(params); - listExamQuestion.value = res.rows; - //this.queryParams.total = res.total; + // const res = await listEntpcoursework(params); + // listExamQuestion.value = res.rows; + + // 查询本地+菁优网(后端处理) + const params = { + eid: curNode.value.id, + workgroup: '1', + worktype: queryParams.workType.label, + workTypeId: queryParams.workType.value, + edusubject: curNode.value.edusubject, + edustage: curNode.value.edustage, + sectionName: curNode.value.itemtitle, + } + const res = await listEntpcourseworkNew(params); + if(res.data == null) { + listExamQuestion.value = []; + // queryParams.total = 0 + loading.value = false; + return; + } + listExamQuestion.value = res.data; + // queryParams.total = res.total; // 格式化试题 processExamQuestion(listExamQuestion.value); loading.value = false; From ed7a8a124e615d8bd539d6c93e6c78898b73218d Mon Sep 17 00:00:00 2001 From: zhuhao <979263092@qq.com> Date: Mon, 9 Sep 2024 16:54:04 +0800 Subject: [PATCH 07/21] =?UTF-8?q?=E6=96=87=E4=BB=B6=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/file-preview/index.vue | 35 ++++++++++++++----- .../views/resource/container/resoure-list.vue | 22 +++++++----- src/renderer/src/views/resource/store.js | 4 ++- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/src/renderer/src/components/file-preview/index.vue b/src/renderer/src/components/file-preview/index.vue index 350695b..9b2326d 100644 --- a/src/renderer/src/components/file-preview/index.vue +++ b/src/renderer/src/components/file-preview/index.vue @@ -1,5 +1,5 @@ diff --git a/src/renderer/src/views/resource/store.js b/src/renderer/src/views/resource/store.js index e48ce6f..b3c3ea3 100644 --- a/src/renderer/src/views/resource/store.js +++ b/src/renderer/src/views/resource/store.js @@ -94,6 +94,7 @@ export default defineStore('resource', { getSmarttalkPage(data).then((res) => { this.result.total = res.total this.result.list = res.rows + this.loading = false }) }else{ let data = JSON.parse(JSON.stringify(this.thirdQuery)) @@ -107,12 +108,13 @@ export default defineStore('resource', { if(res.data.code === 0){ this.thirdResult.total = res.data.page.totalCount this.thirdResult.list = [...res.data.data] + this.loading = false } } }) } } finally { - this.loading = false + // this.loading = false } }, changeTab(val) { From 5bda6cfad291fafb37e59a9d79aaacd7bd4e65b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E4=BA=86=E4=B8=AA=E7=99=BD?= <543593352@qq.com> Date: Mon, 9 Sep 2024 17:14:57 +0800 Subject: [PATCH 08/21] =?UTF-8?q?=E6=89=B9=E9=98=85=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/classTask/classTask.vue | 8 +- .../classTask/container/item-dialog-score.vue | 4 +- .../views/classTask/container/item-dialog.vue | 2 +- .../views/classTask/container/quizStats.vue | 278 ++++++++++++++++++ .../views/classTask/container/task-item.vue | 17 +- 5 files changed, 301 insertions(+), 8 deletions(-) create mode 100644 src/renderer/src/views/classTask/container/quizStats.vue diff --git a/src/renderer/src/views/classTask/classTask.vue b/src/renderer/src/views/classTask/classTask.vue index 1425e8c..2e7d354 100644 --- a/src/renderer/src/views/classTask/classTask.vue +++ b/src/renderer/src/views/classTask/classTask.vue @@ -245,6 +245,8 @@ const getStudentVisible = async () => { } else { classWorkList.value[t].averagetime = 0 } + // 更新批阅数 + classWorkList.value[t].teacherrationgcount = curWork.teacherrationgcount } else { classWorkList.value[t].finishpercent = 0 } @@ -256,8 +258,6 @@ const getStudentVisible = async () => { // 获取多个班级学生作业数据 const getStudentClassWorkData = () => { // 再查找多个班级里,每个学生的作业数据 - console.log('======????????""""""""""') - //TODO 这里id变动,看后续用什么判断 listClassworkdata({ classids: classListIds.value.join(','), //entpcourseid: '', // 章节id? 这里要全课程的作业 不分章节? 根据学段学科查询所有的作业 @@ -268,8 +268,8 @@ const getStudentClassWorkData = () => { }).then((res) => { for (var t = 0; t < classWorkList.value.length; t++) { for (var i = 0; i < res.rows.length; i++) { - if (res.rows[i].uniquekey == classWorkList.value[t].uniquekey) { - // if (res.rows[i].classworkid == classWorkList.value[t].id && res.rows[i].resultcount > 0) { + //if (res.rows[i].uniquekey == classWorkList.value[t].uniquekey) { + if (res.rows[i].classworkid == classWorkList.value[t].id && res.rows[i].resultcount > 0) { console.log('==================') // 有几个学生完成/正在完成学习任务 // 至少resultcount不是0 diff --git a/src/renderer/src/views/classTask/container/item-dialog-score.vue b/src/renderer/src/views/classTask/container/item-dialog-score.vue index 619cc44..8437c5e 100644 --- a/src/renderer/src/views/classTask/container/item-dialog-score.vue +++ b/src/renderer/src/views/classTask/container/item-dialog-score.vue @@ -98,7 +98,8 @@ 学生答案: - + + - +
diff --git a/src/renderer/src/views/classTask/container/quizStats.vue b/src/renderer/src/views/classTask/container/quizStats.vue new file mode 100644 index 0000000..9e18d9b --- /dev/null +++ b/src/renderer/src/views/classTask/container/quizStats.vue @@ -0,0 +1,278 @@ + + + + \ No newline at end of file diff --git a/src/renderer/src/views/classTask/container/task-item.vue b/src/renderer/src/views/classTask/container/task-item.vue index 44d93df..ae63cc1 100644 --- a/src/renderer/src/views/classTask/container/task-item.vue +++ b/src/renderer/src/views/classTask/container/task-item.vue @@ -23,11 +23,24 @@ 已交
- {{ item.teacherRationgCount?item.teacherRationgCount:0 }} + + {{ item.teacherrationgcount?item.workdatacount - item.teacherrationgcount:item.workdatacount }} 待批阅
- {{ item.averagetime?item.averagetime:0 }}分钟 + + + + {{ item.averagetime }}分钟 + + + 1小时 + + + {{ Math.floor(item.averagetime / 60)}}小时 + {{ Math.floor(item.averagetime % 60)}}分钟 + + 平均用时
From 44002ae78d420d69482bf010587a4d955a7a5923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E4=BA=86=E4=B8=AA=E7=99=BD?= <543593352@qq.com> Date: Mon, 9 Sep 2024 17:28:25 +0800 Subject: [PATCH 09/21] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=89=B9=E6=94=B9?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 7 +++---- src/renderer/src/layout/components/Header.vue | 1 - src/renderer/src/views/desktop/index.vue | 3 ++- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 0275ad5..0774367 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,9 @@ "@electron/remote": "^2.1.2", "@element-plus/icons-vue": "^2.3.1", "@vitejs/plugin-vue-jsx": "^4.0.0", + "@vue-office/docx": "^1.6.2", + "@vue-office/excel": "^1.7.11", + "@vue-office/pdf": "^2.0.2", "@vueuse/core": "^10.11.0", "cropperjs": "^1.6.2", "crypto-js": "^4.2.0", @@ -36,10 +39,6 @@ "element-plus": "^2.7.6", "fabric": "^5.3.0", "im_electron_sdk": "^8.0.5904", - "@vue-office/docx": "^1.6.2", - "@vue-office/excel": "^1.7.11", - "@vue-office/pdf": "^2.0.2", - "im_electron_sdk": "^8.0.5904", "js-cookie": "^3.0.5", "jsencrypt": "^3.3.2", "jsondiffpatch": "0.6.0", diff --git a/src/renderer/src/layout/components/Header.vue b/src/renderer/src/layout/components/Header.vue index f4bcf9f..8501952 100644 --- a/src/renderer/src/layout/components/Header.vue +++ b/src/renderer/src/layout/components/Header.vue @@ -46,7 +46,6 @@ 个人中心 课程预约 班级中心 - 作业批改 退出登录 diff --git a/src/renderer/src/views/desktop/index.vue b/src/renderer/src/views/desktop/index.vue index 323bf74..091b970 100644 --- a/src/renderer/src/views/desktop/index.vue +++ b/src/renderer/src/views/desktop/index.vue @@ -120,7 +120,8 @@ const menuList = [{ }, { name: '作业批改', - icon: 'icon-pigai' + icon: 'icon-pigai', + path: '/classTask' }, { name: '作业统计', From 2d89ef8de3ce9f6f626d62dacb3da58873503d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E4=BA=86=E4=B8=AA=E7=99=BD?= <543593352@qq.com> Date: Mon, 9 Sep 2024 17:53:55 +0800 Subject: [PATCH 10/21] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=89=B9=E6=94=B9?= =?UTF-8?q?=EF=BC=9A=E6=A6=82=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../classTask/container/item-dialog-score.vue | 2 +- .../views/classTask/container/item-dialog.vue | 37 +++++++++++++++++++ .../views/classTask/container/quizStats.vue | 9 +++-- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/renderer/src/views/classTask/container/item-dialog-score.vue b/src/renderer/src/views/classTask/container/item-dialog-score.vue index 8437c5e..105574a 100644 --- a/src/renderer/src/views/classTask/container/item-dialog-score.vue +++ b/src/renderer/src/views/classTask/container/item-dialog-score.vue @@ -869,7 +869,7 @@ const onSubmit = () => { var formd = { id: dialogProps.value.studentObj.id, // this.activeClassWork.id; status: '1',//0 未批阅; 1 已批阅 - updatedate: getTimeDate,// = year+'-'+month+'-'+day+' '+hh+':'+mm; + updatedate: getTimeDate(),// = year+'-'+month+'-'+day+' '+hh+':'+mm; }; // 更新作业批改状态 updateClassworkdata(formd).then(res => { diff --git a/src/renderer/src/views/classTask/container/item-dialog.vue b/src/renderer/src/views/classTask/container/item-dialog.vue index 02ad4ba..685fe29 100644 --- a/src/renderer/src/views/classTask/container/item-dialog.vue +++ b/src/renderer/src/views/classTask/container/item-dialog.vue @@ -161,6 +161,8 @@ import { ElMessage } from 'element-plus' import { getCurrentTime, getAfterMinutes } from '@/utils/date' import { processList } from '@/hooks/useProcessList' import ItemDialogScore from '@/views/classTask/container/item-dialog-score.vue' +// zdg: 组件导入 +import quizStats from '@/views/classTask/container/quizStats.vue' const { proxy } = getCurrentInstance() const emit = defineEmits(['addSuccess']) @@ -521,6 +523,41 @@ const escapeHtmlQuotes = (str) => { // }) } +//#region 作业概况 +// 查看学生-作业概览 +const workHandle = (type) => { + // 关闭右侧批阅ui + isopen_dtwk_table.value = false; + classWorkAnalysis.view = type + const isClose = type != 'quizStats' && !! classWorkActiveData.timerId + const isOpen = type == 'quizStats' && !classWorkActiveData.timerId + if (isClose) clearInterval(classWorkActiveData.timerId) // 关闭定时器 + if (isOpen) { + // 轮询 更新学生作答数据 + classWorkActiveData.timerId = setInterval(() => { + console.log('zdg: 定时执行') + getWorkFeedList() + }, 20 * 1000); + } +} +// 获取学生答题回馈数据-更新 +const getWorkFeedList = async() =>{ + const workid = classWorkAnalysis.row.id + const res = await listClassworkeval({workid, isFinish: 1, pageSize: 1000}) + const getStudentid = (workdataid) => { // 获取学生id + const classworkdata = (classWorkAnalysis.classworkdata||[]).find(o => o.id === workdataid) + return classworkdata ? classworkdata.studentid : '' + } + res.rows.forEach(o => { o.studentid = getStudentid(o.workdataid) }) + classWorkActiveData.workFeedList = res.rows +} + + + + +//#endregion + + defineExpose({ openDialog }) diff --git a/src/renderer/src/views/classTask/container/quizStats.vue b/src/renderer/src/views/classTask/container/quizStats.vue index 9e18d9b..f493cb5 100644 --- a/src/renderer/src/views/classTask/container/quizStats.vue +++ b/src/renderer/src/views/classTask/container/quizStats.vue @@ -70,13 +70,14 @@ diff --git a/src/renderer/src/views/classTask/container/classOverview/distribution.vue b/src/renderer/src/views/classTask/container/classOverview/distribution.vue new file mode 100644 index 0000000..5ff15c1 --- /dev/null +++ b/src/renderer/src/views/classTask/container/classOverview/distribution.vue @@ -0,0 +1,23 @@ + + + + + \ No newline at end of file diff --git a/src/renderer/src/views/classTask/container/classOverview/distribution/echarts.vue b/src/renderer/src/views/classTask/container/classOverview/distribution/echarts.vue new file mode 100644 index 0000000..9f6ae08 --- /dev/null +++ b/src/renderer/src/views/classTask/container/classOverview/distribution/echarts.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/src/renderer/src/views/classTask/container/classOverview/distribution/stuList.vue b/src/renderer/src/views/classTask/container/classOverview/distribution/stuList.vue new file mode 100644 index 0000000..df21f66 --- /dev/null +++ b/src/renderer/src/views/classTask/container/classOverview/distribution/stuList.vue @@ -0,0 +1,115 @@ + + + + + \ No newline at end of file diff --git a/src/renderer/src/views/classTask/container/classOverview/knowledge.vue b/src/renderer/src/views/classTask/container/classOverview/knowledge.vue new file mode 100644 index 0000000..851f587 --- /dev/null +++ b/src/renderer/src/views/classTask/container/classOverview/knowledge.vue @@ -0,0 +1,104 @@ + + + + + \ No newline at end of file diff --git a/src/renderer/src/views/classTask/container/classOverview/timeAnalyse.vue b/src/renderer/src/views/classTask/container/classOverview/timeAnalyse.vue new file mode 100644 index 0000000..c65e5ae --- /dev/null +++ b/src/renderer/src/views/classTask/container/classOverview/timeAnalyse.vue @@ -0,0 +1,184 @@ + + + + + diff --git a/src/renderer/src/views/classTask/container/item-dialog.vue b/src/renderer/src/views/classTask/container/item-dialog.vue index 685fe29..3f371d2 100644 --- a/src/renderer/src/views/classTask/container/item-dialog.vue +++ b/src/renderer/src/views/classTask/container/item-dialog.vue @@ -3,7 +3,7 @@ v-model="classWorkAnalysis.open" :modal-append-to-body="false" class="clwk_dialog" - style="width: 90%; height: 85%" + style="width: 90%; height: 85vh" :show-close="false" top="8vh" append-to-body @@ -63,7 +63,7 @@
@@ -143,6 +143,7 @@
+
-
@@ -124,7 +113,6 @@ import {captchaImg,sendCode,deptTree,getDept,listClassmain,listEvaluation,signIn import { ElMessage } from 'element-plus' import {setToken, removeToken } from '@/utils/auth' import { regionData, codeToText } from 'element-china-area-data' -import array from 'lodash/array' const ruleFormRef = ref(null) const activeIndex=ref(1) const ruleForm = reactive({ @@ -180,7 +168,23 @@ const rules = reactive({ ], idNumber: [ { required: true, message: '身份证号码是必填项', trigger: 'blur' }, - { pattern: /^\d{17}[\dX]$/, message: '身份证号码格式不正确', trigger: 'blur' }, + { + validator: (rule, value, callback) => { + if (!value) { + callback(); + return; + } + // 正则表达式同时支持15位和18位身份证号码 + const pattern = /^(?:\d{15}|\d{17}[\dX])$/; + const valid = pattern.test(value); + if (!valid) { + callback(new Error('身份证号码格式不正确')); + } else { + callback(); + } + }, + trigger: 'blur' + } ], password: [ { required: true, message: '请输入密码', trigger: 'blur' }, @@ -228,6 +232,7 @@ const OpenModel = () =>{ // 关闭弹窗 const handleClose = () => { if (ruleFormRef.value) ruleFormRef.value.resetFields() + removeToken(); activeIndex.value=1 dialogVisible.value=false } @@ -275,11 +280,12 @@ const getSubject = async ()=>{ allSubjectList.value = rows.data } + const submitForm = async (formEl) => { if (!formEl) return await formEl.validate((valid, fields) => { if (valid) { - console.log(ruleForm) + var araname = codeToText[ruleForm.address[0]] + '-' + codeToText[ruleForm.address[1]] + '-' + codeToText[ruleForm.address[2]]; var form={ mobile:ruleForm.phoneNumber, code:ruleForm.Code, @@ -287,16 +293,18 @@ const submitForm = async (formEl) => { idCard:ruleForm.idNumber, password:ruleForm.password, confirmPassword:ruleForm.confirmPassword, - schoolId:ruleForm.school.join(','), + schoolId:ruleForm.school[2], classIds:ruleForm.class.join(','), - subjectIds:ruleForm.discipline.join(','), - area:ruleForm.address.join(','), + subjectIds:ruleForm.discipline.map(o=>o.id).join(','), + subject:ruleForm.discipline.map(o=>o.itemtitle).join(','), + areaIds:ruleForm.address.join(','), + area:araname } signIn(form).then(res=>{ if(res.code==200){ - ElMessage.success('注册成功') + ElMessage.success('您已注册成功,等待学校管理员审核') if (ruleFormRef.value) ruleFormRef.value.resetFields() - ruleForm={ + var restValue={ name: '', idNumber:'', phoneNumber: '', @@ -307,6 +315,7 @@ const submitForm = async (formEl) => { discipline:[], school:[], } + Object.assign(ruleForm, restValue); activeIndex.value=1 dialogVisible.value=false }else{ @@ -436,7 +445,7 @@ const gradeName = (key) =>{ } } onMounted(()=>{ - + }) defineExpose({ OpenModel, diff --git a/src/renderer/src/views/login/index.vue b/src/renderer/src/views/login/index.vue index 72b8861..8f803ee 100644 --- a/src/renderer/src/views/login/index.vue +++ b/src/renderer/src/views/login/index.vue @@ -32,8 +32,9 @@ >
From 6be4b3526e4d3d8bb51b7e663743a80a23e82784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E4=BA=86=E4=B8=AA=E7=99=BD?= <543593352@qq.com> Date: Tue, 10 Sep 2024 11:30:45 +0800 Subject: [PATCH 15/21] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=89=B9=E6=94=B9?= =?UTF-8?q?=EF=BC=9A=E4=BC=98=E5=8C=96=E8=BD=AE=E8=AF=A2=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/classTask/classTask.vue | 33 +++++++++++++++---- .../views/classTask/container/item-dialog.vue | 32 ++++++++++++++---- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/renderer/src/views/classTask/classTask.vue b/src/renderer/src/views/classTask/classTask.vue index 2e7d354..bfacb90 100644 --- a/src/renderer/src/views/classTask/classTask.vue +++ b/src/renderer/src/views/classTask/classTask.vue @@ -15,7 +15,7 @@ :key="index" :item="item" :tabactive="tabActive" - @click="itemDialogRef.openDialog(item)" + @click="onClickItem(item)" @delete-reserv="deleteReserv(item)" >
- + From 7a4cc9eb6404d518f297868ce27045b0720c9eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E4=BA=86=E4=B8=AA=E7=99=BD?= <543593352@qq.com> Date: Tue, 10 Sep 2024 13:49:46 +0800 Subject: [PATCH 16/21] 1 --- src/renderer/src/api/classTask/index.js | 197 ------------------------ 1 file changed, 197 deletions(-) diff --git a/src/renderer/src/api/classTask/index.js b/src/renderer/src/api/classTask/index.js index a6ebe4b..cd13685 100644 --- a/src/renderer/src/api/classTask/index.js +++ b/src/renderer/src/api/classTask/index.js @@ -47,200 +47,3 @@ export function updateClassworkdata(data) { data: data }) } - - - - - - - - - -// 0------------------------ -// 查询班级列表 -export function listClassmain(query) { - return request({ - url: '/education/classmain/list', - method: 'get', - params: query - }) -} -// 查询学生列表 -export function listClassuser(query) { - return request({ - url: '/education/classuser/list', - method: 'get', - params: query - }) -} -// 新增班级 -export function addClassmain(data) { - return request({ - url: '/education/classmain', - method: 'post', - data: data - }) -} -// 查询所有学科的列表 -export function listEvaluation(query) { - return request({ - url: '/education/evaluation/list', - method: 'get', - params: query - }) -} -// 新增小组 -export function addClassgroup(data) { - return request({ - url: '/education/classgroup', - method: 'post', - data: data - }) -} -//班级详情 -export function getClassmain(id) { - return request({ - url: '/education/classmain/' + id, - method: 'get' - }) -} -// 获取小组列表 -export function listClassgroup(query) { - return request({ - url: '/education/classgroup/new/list', - method: 'get', - params: query - }) -} -//删除小组 -export function delClassgroup(id) { - return request({ - url: '/education/classgroup/' + id, - method: 'delete' - }) -} -//查询小组信息 -export function getClassgroup(id) { - return request({ - url: '/education/classgroup/' + id, - method: 'get' - }) -} -//修改小组信息 -export function updateClassgroup(data) { - return request({ - url: '/education/classgroup', - method: 'put', - data: data - }) -} -//新增学生 -export function addStudentmain(data) { - return request({ - url: '/education/studentmain', - method: 'post', - data: data - }) -} -//修改学生信息 -export function updateStudentmain(data) { - return request({ - url: '/education/studentmain', - method: 'put', - data: data - }) -} -//获取学生信息 -export function getStudentmain(id) { - return request({ - url: '/education/studentmain/' + id, - method: 'get' - }) -} -//删除学生 -export function leaveClass(data) { - return request({ - url: '/education/classuser/leaveClass', - method: 'post', - data: data - }) -} -//删除学生所有数据 -export function removeStudentDataAll(id) { - return request({ - url: '/education/studentmain/removeStudent/' + id, - method: 'post' - }) -} -//删除教室 -export function delClassroom(id) { - return request({ - url: '/education/classroom/' + id, - method: 'delete' - }) -} -//导入学生 -export function addStudentmainByNameArray(data) { - return request({ - url: '/education/studentmain/addByNameArray', - method: 'post', - data: data - }) -} -//新增课程预约 -export function addSmartClassReserv(data) { - return request({ - url: '/smarttalk/classReserv/addSmartClassReserv', - method: 'post', - data: data - }) -} -//修改课程预约 -export function updateSmartClassReserv(data) { - return request({ - url: '/smarttalk/classReserv/updateSmartClassReserv', - method: 'post', - data: data - }) -} -//查询课程预约 -export function getSelfReserv() { - return request({ - url: '/smarttalk/classReserv/getSelfReserv', - method: 'get' - }) -} -export function deleteSmartReserv(id) { - return request({ - url: '/smarttalk/classReserv/' + id, - method: 'delete' - }) -} -export function startClass(id, ex3) { - const params = {id} - !!ex3 && (params.ex3 = ex3) - return request({ - url: '/smarttalk/classReserv/startClass', - method: 'get', - params - }) -} -export function endClass(id) { - return request({ - url: '/smarttalk/classReserv/endClass', - method: 'get', - params: {id} - }) -} -/** - * @description 获取课堂信息 - * @param {*} id - * @returns - */ -export function getClassInfo(id) { - return request({ - url: '/smarttalk/classReserv/selectById', - method: 'get', - params: {id} - }) -} From 53f43019e9d6db66b688964c7249e6e4eece7fa0 Mon Sep 17 00:00:00 2001 From: zhuhao <979263092@qq.com> Date: Tue, 10 Sep 2024 14:01:58 +0800 Subject: [PATCH 17/21] =?UTF-8?q?APT=E5=85=A5=E5=8F=A3=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/education/entpcoursefile.js | 162 ++++++++++++++++++ src/renderer/src/api/file/index.js | 8 + .../prepare/container/file-list-item.vue | 4 + src/renderer/src/views/prepare/index.vue | 153 ++++++++++++++--- 4 files changed, 299 insertions(+), 28 deletions(-) create mode 100644 src/renderer/src/api/education/entpcoursefile.js diff --git a/src/renderer/src/api/education/entpcoursefile.js b/src/renderer/src/api/education/entpcoursefile.js new file mode 100644 index 0000000..c6c26c5 --- /dev/null +++ b/src/renderer/src/api/education/entpcoursefile.js @@ -0,0 +1,162 @@ +import request from '@/utils/request' + +// 查询entpcoursefile列表 +export function listEntpcoursefile(query) { + return request({ + url: '/education/entpcoursefile/list', + method: 'get', + params: query + }) +} +// zdg:查询entpcoursefile列表-新 +export function listEntpcoursefileNew(query) { + return request({ + url: '/education/entpcoursefile/new/list', + method: 'get', + params: query + }) +} +// 查询entpcoursefile详细 +export function getEntpcoursefile(id) { + return request({ + url: '/education/entpcoursefile/' + id, + method: 'get' + }) +} + +// 新增entpcoursefile +export function addEntpcoursefile(data) { + return request({ + url: '/education/entpcoursefile', + method: 'post', + data: data + }) +} + +// 新增entpcoursefile +export function addEntpcoursefileReturnId(data) { + return request({ + url: '/education/entpcoursefile/addReturnId', + method: 'post', + data: data + }) +} + + +// addFromId +export function addFromId(fromid, toid, entpid, entpcourseid, edituserid) { + return request({ + url: '/education/entpcoursefile/addFromId/'+fromid+'/'+toid+'/'+entpid+'/'+entpcourseid+'/'+edituserid, + method: 'post' + }) +} + +// 修改entpcoursefile +export function updateEntpcoursefile(data) { + return request({ + url: '/education/entpcoursefile', + method: 'put', + data: data + }) +} +// 新增 修改接口 +export function updateEntpcoursefileNew(data) { + return request({ + url: '/education/entpcoursefile/newUpdateFile', + method: 'post', + data: data + }) +} + +// updateFileByIds +export function updateFileByIds(data) { + return request({ + url: '/education/entpcoursefile/updateFileByIds', + method: 'post', + data: data + }) +} + +// updateFileByArray +export function updateFileByArray(data) { + return request({ + url: '/education/entpcoursefile/updateFileByArray', + method: 'post', + data: data + }) +} + +// 修改entpcoursefile +export function updateFile2Redis(data) { + return request({ + url: '/education/entpcoursefile/updateFile2Redis', + method: 'post', + data: data + }) +} + +// 删除entpcoursefile +export function delEntpcoursefile(id) { + return request({ + url: '/education/entpcoursefile/' + id, + method: 'delete' + }) +} + +// 保存base64图片,返回url +export function saveEntpCourseBase64File(data) { + return request({ + url: '/education/entpcoursefile/saveBase64File', + method: 'post', + data: data + }) +} + + +// 文件上传 +export function saveEntpCourseBase64File2(data) { + return request({ + url: '/education/entpcoursefile/saveBase64File2', + method: 'post', + data: data + }) +} + +// 保存PPT页面预览base64图片,返回url +export function savePPTPreviewBase64File(data) { + return request({ + url: '/education/entpcoursefile/savePreviewBase64', + method: 'post', + data: data + }) +} + + +// PPT文件上传 +export function saveEntpCoursePPT(data) { + return request({ + url: '/education/entpcoursefile/importPPT', + method: 'post', + data: data + }) +} + +// PPT文件解析 +export function parsePPT(data) { + return request({ + url: '/education/entpcoursefile/parsePPT', + method: 'post', + data: data + }) +} + + +// 修改ppt.slide.index +export function updateSlideIndex(data) { + return request({ + url: '/education/entpcoursefile/saveSlideOrder', + method: 'post', + data: data + }) +} + diff --git a/src/renderer/src/api/file/index.js b/src/renderer/src/api/file/index.js index 5bfe721..e655614 100644 --- a/src/renderer/src/api/file/index.js +++ b/src/renderer/src/api/file/index.js @@ -9,6 +9,14 @@ export const getSmarttalkPage = (params) => { }) } +export const creatAPT = (params) => { + return request({ + url: '/smarttalk/file/createApt', + method: 'post', + params + }) +} + export const getPrepareById = (id) => { return request({ url: '/smarttalk/file/' + id, diff --git a/src/renderer/src/views/prepare/container/file-list-item.vue b/src/renderer/src/views/prepare/container/file-list-item.vue index 8c4f2dc..bd7922e 100644 --- a/src/renderer/src/views/prepare/container/file-list-item.vue +++ b/src/renderer/src/views/prepare/container/file-list-item.vue @@ -230,6 +230,10 @@ export default { } }, openFileWin(items) { + if (items.fileFlag === 'apt') { + console.log(items); + return + } if (!items||!items.fileSuffix) return; getPrepareById(items.id).then((item) => { Object.assign(items, item) diff --git a/src/renderer/src/views/prepare/index.vue b/src/renderer/src/views/prepare/index.vue index b0b4004..7c14742 100644 --- a/src/renderer/src/views/prepare/index.vue +++ b/src/renderer/src/views/prepare/index.vue @@ -20,11 +20,14 @@
- + @@ -60,9 +63,21 @@ 作业反馈 布置作业 上传资料 - 新建课件 + + + 新建课件 + + + @@ -110,11 +124,7 @@ - + import { Check } from '@element-plus/icons-vue' import Reserv from '@/views/prepare/container/reserv.vue' +import { ArrowDown } from '@element-plus/icons-vue' diff --git a/src/renderer/src/views/classManage/index.vue b/src/renderer/src/views/classManage/index.vue index edb48b9..d83e8e6 100644 --- a/src/renderer/src/views/classManage/index.vue +++ b/src/renderer/src/views/classManage/index.vue @@ -12,6 +12,11 @@ + @@ -28,7 +33,7 @@ - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + {{userStore.nickName}} + - - - - - - - - - - - - {{ userStore.nickName }} - - - + + +