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 1/9] =?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'
}
}
--
2.44.0.windows.1
From 04ac5dc8b5a5212c4c1de4ff1b50404bf2650d53 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 07:04:21 +0800
Subject: [PATCH 2/9] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E6=89=B9=E9=98=85?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/renderer/src/api/classTask/index.js | 237 +++++
src/renderer/src/hooks/useProcessList.js | 514 ++++++++++
src/renderer/src/layout/components/Header.vue | 1 +
src/renderer/src/router/index.js | 11 +
src/renderer/src/utils/date.js | 25 +
.../src/views/classTask/classTask.vue | 394 +++++++
.../classTask/container/item-dialog-score.vue | 964 ++++++++++++++++++
.../views/classTask/container/item-dialog.vue | 616 +++++++++++
.../views/classTask/container/task-item.vue | 143 +++
9 files changed, 2905 insertions(+)
create mode 100644 src/renderer/src/api/classTask/index.js
create mode 100644 src/renderer/src/hooks/useProcessList.js
create mode 100644 src/renderer/src/views/classTask/classTask.vue
create mode 100644 src/renderer/src/views/classTask/container/item-dialog-score.vue
create mode 100644 src/renderer/src/views/classTask/container/item-dialog.vue
create mode 100644 src/renderer/src/views/classTask/container/task-item.vue
diff --git a/src/renderer/src/api/classTask/index.js b/src/renderer/src/api/classTask/index.js
new file mode 100644
index 0000000..f441957
--- /dev/null
+++ b/src/renderer/src/api/classTask/index.js
@@ -0,0 +1,237 @@
+// 查询evaluation列表
+import request from '@/utils/request'
+
+// 查询反馈列表
+
+// 查询classworkdata列表 班级作业列表
+export function listClassworkdata(query) {
+ return request({
+ url: '/education/classworkdata/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询entpcoursework列表 课程作业列表
+export function listEntpcoursework(query) {
+ return request({
+ url: '/education/entpcoursework/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询classworkeval列表 课堂作业列表
+export function listClassworkeval(query) {
+ return request({
+ url: '/education/classworkeval/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 修改classworkeval
+export function updateClassworkeval(data) {
+ return request({
+ url: '/education/classworkeval',
+ method: 'put',
+ 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}
+ })
+}
diff --git a/src/renderer/src/hooks/useProcessList.js b/src/renderer/src/hooks/useProcessList.js
new file mode 100644
index 0000000..d53f73e
--- /dev/null
+++ b/src/renderer/src/hooks/useProcessList.js
@@ -0,0 +1,514 @@
+export const isJson = (str) => {
+ 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 processList 格式化试题
+ * @param {*} row
+ */
+export const processList = (row) => {
+ for (var i = 0; i < row.length; i++) {
+ if (isJson(row[i].workanalysis)) {
+ //1、先默认格式化 格式化各项内容(待优化, 后续界面显示的为format的值)
+ row[i].titleFormat = row[i].title // 题目
+ row[i].examdateFormat = row[i].examdate // ?考试日期 eg: 2024-07-11 14:39:27"
+ row[i].workdescFormat = row[i].workdesc // 题目选项
+ row[i].workanswerFormat = row[i].workanswer // 题目正确答案
+ if (row[i].workanswerFormat == null || row[i].workanswerFormat == '') {
+ row[i].workanswerFormat = '见试题解答内容'
+ }
+
+ // workanalysis 解析内容(analyse:解答; method:分析; discuss:点评; )
+ var jjj = JSON.parse(row[i].workanalysis)
+ row[i].analyse = jjj.analyse
+ row[i].method = jjj.method
+ row[i].discuss = jjj.discuss
+ //row[i].discusscollapse = false;
+ if (row[i].examdate !== null && row[i].examdate !== undefined) {
+ row[i].examdate = row[i].examdate.substring(0, 10)
+ }
+
+ // 具体题型数据结构处理
+ if (row[i].worktype == '复合题') {
+ // 旧类型
+ if (row[i].title.indexOf('!@#$%') !== -1) {
+ // 1.选项解析替换
+ const options = JSON.parse(row[i].workdesc)
+ // 题目(背景材料+复合题目)
+ const bjTitle = row[i].title.split('!@#$%')[0]
+ const tmTitles = row[i].title.split('!@#$%').filter((it, ix) => ix > 0)
+ // console.log(bjTitle,'背景标题');
+ // console.log(tmTitles,'复合题目');
+ let titls = []
+ options.forEach((element, index1) => {
+ const workDescArr = element.split('#&')
+ let tmp = ''
+ let j = 0
+ for (; j < workDescArr.length; j++) {
+ if (j % 2 == 0) {
+ tmp += `
`
+ }
+ 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 < optionsArr.length; j++) {
+ if (j % 2 == 0) {
+ tmp += ``
+ }
+ 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 < workDescArr.length; j++) {
+ if (j % 2 == 0) {
+ tmp += ``
+ }
+ 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
+ }
+ }
+
+ /*
+ //2、处理单选题
+ if(row[i].worktype == '单选题' || row[i].worktype == '多选题' ){
+ //1.选项前增加ABCD workdesc: "①②#&①③#&②④#&③④" || "为了活着
#&为了填报肚子
#&为了吃饭而吃饭
"
+ let workDescArr = [];
+ if(row[i].workdesc.indexOf('[')!==-1 && row[i].workdesc.indexOf(']')!==-1) {
+ //123会直接被转换, 且不是数组对象, 故手动判断是否有[和]两个字符
+ workDescArr = JSON.parse(row[i].workdesc);
+ }
+ else if(row[i].workdesc.indexOf('#&')) {
+ workDescArr = row[i].workdesc.split('#&');
+ }
+ else if(row[i].workdesc.indexOf(',')){
+ workDescArr = row[i].workdesc.split(',');
+ }
+ else {
+ // 待考虑
+ workDescArr.push(item.workdesc)
+ }
+
+
+
+ //2.答案 - 数字转为ABCD
+ if(row[i].worktype == '单选题') {
+ const str2Char = String.fromCharCode(65+Number(row[i].workanswer));
+ row[i].workanswerFormat = str2Char;
+ } else if (row[i].worktype == '多选题') {
+ const answerArr = row[i].workanswer.split('#&');
+ let arr2Char = '';
+ for(let k=0; k]*>/g, "").split('#&'),'????')
+ // 填空题答案
+ row[i].workanswerFormat = row[i].workanswer.replace(/#&/g,", ");
+ // 填空选项不需要展示,
+ row[i].workdescFormat = '';
+ }
+ else if(row[i].worktype == '判断题'){
+ // console.log(row[i].workanswer.replace(/<[^>]*>/g, "").split('#&'),'????')
+ // 判断题答案
+ row[i].workanswerFormat = row[i].workanswer.replace(/#&/g,", ");
+ // 判断选项不需要展示,
+ row[i].workdescFormat = '';
+ }
+ else if(row[i].worktype == '复合题') {
+ // 1.选项解析替换
+ const options = JSON.parse(row[i].workdesc);
+ // 题目(背景材料+复合题目)
+ const bjTitle = row[i].title.split('!@#$%')[0];
+ const tmTitles = row[i].title.split('!@#$%').filter((it,ix)=>ix>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}.${jsonArr[j]}
`;
+ if(j%2 == 1){
+ tmp += '';
+ }
+ }
+
+ if(j%2== 0){
+ tmp += '';
+ }
+ workdesc = tmp;
+ }
+
+ row[i].workdescFormat = workdesc; // 题目选项
+
+
+ // 答案处理
+ let workanswer = '';
+ if(row[i].workanswer && row[i].workanswer != '') {
+ // 因答案内容存在多种格式: 1.["123","1234"] 2.123#&1234 3.123
+ if(row[i].workanswer.indexOf('[')!==-1 && row[i].workanswer.indexOf(']')!==-1) {
+ //123会直接被转换, 且不是数组对象, 故手动判断是否有[和]两个字符
+ let json = JSON.parse(row[i].workanswer);
+ // 单选、多选 需要 数字转为ABCD
+ if(row[i].worktype == '单选题') {
+ const str2Char = String.fromCharCode(65+Number(json[0]));
+ workanswer = str2Char;
+ } else if (row[i].worktype == '多选题') {
+ // const answerArr = row[i].workanswer.split('#&');
+ let arr2Char = '';
+ for(let k=0; k';
+ }
+ workanswer = arr2Char;
+ row[i].titleFormat = row[i].titleFormat.replace(/!@#\$%/g, '');
+ } else {
+ workanswer = json.join('、');
+ }
+ } else if(row[i].workanswer.indexOf('#&')) {
+ // 意味着多个答案或者填空内容
+ let workanswerList = row[i].workanswer.split('#&');
+ if(row[i].worktype == '多选题') {
+ // 数字转为ABCD
+ let arr2Char = '';
+ for(let k=0; k {
+ 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?'':'、');
+ }
+ })
+ arr.push(value);
+ indexLabel++;
+ })
+ const answer = arr.join('
');
+
+ row[i].workanswerFormat = answer;
+ }
+ else if(row[i].worktype == '主观题') {
+ // 1.选项解析替换---主观题没选项
+ // 题目(背景材料+主观题目)
+ const bjTitle = row[i].title.split('!@#$%')[0];
+ const tmTitles = row[i].title.split('!@#$%').filter((it,ix)=>ix>0);
+ // console.log(bjTitle,'背景标题');
+ // console.log(tmTitles,'主观题目');
+ let titls = [];
+ const s = [];
+ tmTitles.map((it,ix)=>{
+ s.push(it);
+ })
+ // console.log(s,'?????????????????')
+
+ row[i].titleFormat = bjTitle + s.join('');
+ // 填空选项不需要展示,
+ row[i].workdescFormat = '';
+
+ //2.答案
+ // 填空题答案
+ const workanswerList = JSON.parse(row[i].workanswer);
+ let tmp='';
+ workanswerList&&workanswerList.map((item,index)=>{
+ tmp += ''+(index+1)+'.'+item.replace(/#&/g, ',')+'
';
+ })
+ row[i].workanswerFormat = tmp;
+
+ }
+ else {
+ //处理答案
+ row[i].workanswerFormat = '见试题解答内容';
+ }
+ */
+ }
+ }
+}
diff --git a/src/renderer/src/layout/components/Header.vue b/src/renderer/src/layout/components/Header.vue
index e7a4e04..e151832 100644
--- a/src/renderer/src/layout/components/Header.vue
+++ b/src/renderer/src/layout/components/Header.vue
@@ -37,6 +37,7 @@
个人中心
课程预约
班级中心
+ 作业批改
退出登录
diff --git a/src/renderer/src/router/index.js b/src/renderer/src/router/index.js
index 14b0cd0..000314e 100644
--- a/src/renderer/src/router/index.js
+++ b/src/renderer/src/router/index.js
@@ -1,3 +1,8 @@
+/*
+ * @Author: 苦逼程序猿
+ * @Date: 2024-09-06 16:15:32
+ * @Warning: 千行代码,Bug露锋芒。
+ */
import { createRouter, createWebHashHistory } from 'vue-router'
import Layout from '../layout/index.vue'
@@ -57,6 +62,12 @@ export const constantRoutes = [
name: 'class',
meta: {title: '班级中心'},
},
+ {
+ path: '/classTask',
+ component: () => import('@/views/classTask/classTask.vue'),
+ name: 'class',
+ meta: {title: '作业批改'},
+ },
]
},
...toolRouters
diff --git a/src/renderer/src/utils/date.js b/src/renderer/src/utils/date.js
index f70414b..2a178ca 100644
--- a/src/renderer/src/utils/date.js
+++ b/src/renderer/src/utils/date.js
@@ -108,4 +108,29 @@ export const getAfterMinutes = (m) => {
let minutes = afterMinutes.getMinutes();
minutes = minutes < 10 ? ('0' + minutes) : minutes
return `${hours}:${minutes}`;
+}
+
+/**
+ * 表格时间格式化
+ */
+export function formatDate(cellValue) {
+ if (cellValue == null || cellValue == "") return "";
+ var date = new Date(cellValue)
+ var year = date.getFullYear()
+ var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
+ var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
+ var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
+ var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
+ var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
+ return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
+}
+export function getTimeDate() {
+ var date = new Date()
+ var year = date.getFullYear()
+ var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
+ var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
+ var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
+ var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
+ var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
+ return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
}
\ No newline at end of file
diff --git a/src/renderer/src/views/classTask/classTask.vue b/src/renderer/src/views/classTask/classTask.vue
new file mode 100644
index 0000000..98a5d7b
--- /dev/null
+++ b/src/renderer/src/views/classTask/classTask.vue
@@ -0,0 +1,394 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+ {{ classWorkFormScore.name }} 答题详情
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ quItem.worktag }}
+
+
+
+
+
+
+
+
+ 【答案】
+
+ 【分析】
+
+ 【解答】
+
+ 【点评】
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 参考答案:
+
+ {{ quItem.workanswerFormat.replace(/<[^>]+>/g, '') }}
+
+
+
+
+
+ 学生答案:
+
+
+ {{ stuItem.feedcontent.replace('#', '、') }}
+
+
+
+
+ {{
+ JSON.parse(quItem.workdesc)
+ .map((item, index) => {
+ if (item == stuItem.feedcontent) {
+ return String.fromCharCode(65 + Number(index))
+ }
+ })
+ .filter(Boolean)[0]
+ }}
+
+
+
+
+
+
+
+
+
+
+
+
+ 分
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 温馨提示:点击图片可放大预览
+
+
+
+
+
+
+
+
+ 温馨提示:点击此处 可预览其他类型附件!
+
+
+
+
+
+
+
+
+
+
+
+
学生答题附件内容
+
+
+
+ 温馨提示:点击图片可放大预览
+
+
+
+
+
+
+
+
+ 温馨提示:点击此处 可预览其他类型附件!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+ 预览
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+ 预览
+
+
+
+
+
+
+ 预览展示区域
+ 温馨提示:若预览失败,{{ props.name }}可点击此处下载!
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+
+ {{ classWorkAnalysis.title }}答题情况
+ {{
+ classWorkAnalysis.worktype
+ }}
+
+
+
+
+ 作业批阅
+ 作业概况
+ 作业报告
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 待批阅
+
+ 优
+ 优-
+ 良
+ 良-
+ 差
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+
+
+
+ {{ item.worktype }}
+
+
+
+
+
+ {{ item.classcaption }}
+ | 截止时间:{{ item.deaddate }} | {{ tabactive }}
+
+
+
+
+ {{ item.workdataresultcount }}/{{ item.workdatacount }}
+ 已交
+
+
+ 2
+ 待批阅
+
+
+ {{ item.averagetime?item.averagetime:0 }}分钟
+ 平均用时
+
+
+ {{ item.scoingRate }}
+ 得分率
+
+
+
+
+
--
2.44.0.windows.1
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 3/9] =?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 @@
-
+
+
{{ classWorkFormScore.name }} 答题详情
@@ -410,11 +411,12 @@
+
@@ -468,13 +470,13 @@
>
-
+ />
@@ -488,12 +490,10 @@ import useUserStore from '@/store/modules/user'
import { ref, reactive } from 'vue'
// import { Plus } from '@element-plus/icons-vue'
import { ElMessageBox, ElMessage } from 'element-plus'
-import { updateClassworkeval } from '@/api/classTask'
+import { updateClassworkeval, updateClassworkdata } from '@/api/classTask'
import { getTimeDate } from '@/utils/date'
-// import ReFilePreview from '@/components/ReFilePreview/index.vue'
+import ReFilePreview from '@/components/refile-preview/index.vue'
-// import mammoth from 'mammoth'
-// import * as XLSX from 'xlsx'
const userStore = useUserStore()
const router = useRouter()
@@ -864,6 +864,16 @@ const onSubmit = () => {
return
}
+ var formd = {
+ id: dialogProps.value.studentObj.id, // this.activeClassWork.id;
+ status: '1',//0 未批阅; 1 已批阅
+ updatedate: getTimeDate,// = year+'-'+month+'-'+day+' '+hh+':'+mm;
+ };
+ // 更新作业批改状态
+ updateClassworkdata(formd).then(res => {
+ })
+
+ // 更新题目批改
classWorkFormScore.teacherRating &&
classWorkFormScore.teacherRating.map((item, index) => {
const queryParams = {
diff --git a/src/renderer/src/views/classTask/container/item-dialog.vue b/src/renderer/src/views/classTask/container/item-dialog.vue
index 4519b62..06ad733 100644
--- a/src/renderer/src/views/classTask/container/item-dialog.vue
+++ b/src/renderer/src/views/classTask/container/item-dialog.vue
@@ -54,12 +54,11 @@
-
+
@@ -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 }}
待批阅
--
2.44.0.windows.1
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 4/9] =?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 @@
+
+
+
+
+
+
+
+
+ {{item.def?.titletext}}
+
+ {{index+1}}
+
+
+ {{item.type}} {{getRatioTxt(item)}}
+ {{item.points}}%
+
+
+
+ 作答情况
+ (已经完成 {{item.accSum}} 人)
+
+
+
+
+
+
+
+
+
+
+ {{it.studentIds.length}} 人/占 {{ratio_1(it, item.accSum)}}%
+
+
+
+
+
+
+
+ {{getStudentName(sid)}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
答题情况
+
+
+
+
+
+
+
+ {{index+1}}
+
+
+
+
+
+
+
+
+
+
+
+
\ 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)}}分钟
+
+
平均用时
--
2.44.0.windows.1
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 5/9] =?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: '作业统计',
--
2.44.0.windows.1
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 6/9] =?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 @@
+
+
+
+
+
+
+ {{stuItem.studentname}}
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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 @@
+
+
+
+
+
+
+
+ {{scope.row.scoingRate + '%'}}
+
+
+
+
+
+
+
+
\ 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 @@
+
-
--
2.44.0.windows.1
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 9/9] 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}
- })
-}
--
2.44.0.windows.1