diff --git a/.env.production b/.env.production
index 05e26a6..e103054 100644
--- a/.env.production
+++ b/.env.production
@@ -18,4 +18,4 @@ VITE_APP_RES_FILE_PATH = 'https://prev.ysaix.com:7868/src/assets/textbook/booktx
VITE_APP_BUILD_BASE_PATH = 'https://prev.ysaix.com:7868/'
-VITE_SHOW_DEV_TOOLS = 'true'
+VITE_SHOW_DEV_TOOLS = 'false'
diff --git a/.env.test b/.env.test
index 3d671e1..ea57966 100644
--- a/.env.test
+++ b/.env.test
@@ -17,3 +17,5 @@ VITE_BUILD_COMPRESS = gzip
VITE_APP_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktxt/'
VITE_APP_BUILD_BASE_PATH = 'https://file.ysaix.com:7868/'
+
+VITE_SHOW_DEV_TOOLS = 'true'
diff --git a/.env.old b/.env.yc
similarity index 89%
rename from .env.old
rename to .env.yc
index 8640aa3..e103054 100644
--- a/.env.old
+++ b/.env.yc
@@ -1,5 +1,5 @@
# 页面标题
-VITE_APP_TITLE = AIX智慧课堂
+VITE_APP_TITLE = 文枢课堂
# 生产环境配置
VITE_APP_ENV = 'production'
@@ -17,3 +17,5 @@ VITE_BUILD_COMPRESS = gzip
VITE_APP_RES_FILE_PATH = 'https://prev.ysaix.com:7868/src/assets/textbook/booktxt/'
VITE_APP_BUILD_BASE_PATH = 'https://prev.ysaix.com:7868/'
+
+VITE_SHOW_DEV_TOOLS = 'false'
diff --git a/electron-builder-old.yml b/electron-builder-yc.yml
similarity index 84%
rename from electron-builder-old.yml
rename to electron-builder-yc.yml
index 9dfb51e..c3fddbc 100644
--- a/electron-builder-old.yml
+++ b/electron-builder-yc.yml
@@ -1,10 +1,10 @@
appId: com.electron.app
-productName: AIx
+productName: 文枢课堂
directories:
output: dist
buildResources: build
win:
- executableName: AIx
+ executableName: 文枢课堂
icon: resources/logo2.ico
files:
- '!**/.vscode/*'
@@ -17,7 +17,7 @@ asarUnpack:
nsis:
oneClick: false
allowToChangeInstallationDirectory: true
- artifactName: ${name}-${version}-setup.${ext}
+ artifactName: ${name}-yc-${version}-setup.${ext}
shortcutName: ${productName}
uninstallDisplayName: ${productName}
createDesktopShortcut: always
@@ -30,7 +30,7 @@ mac:
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
notarize: false
dmg:
- artifactName: ${name}-${version}.${ext}
+ artifactName: ${name}-yc-${version}.${ext}
linux:
target:
- AppImage
@@ -39,11 +39,11 @@ linux:
maintainer: electronjs.org
category: Utility
appImage:
- artifactName: ${name}-${version}.${ext}
+ artifactName: ${name}-yc-${version}.${ext}
npmRebuild: false
publish:
provider: generic
- url: https://prev.ysaix.com:7868/src/assets/smarttalk/
+ url: https://prev.ysaix.com:7868/src/assets/smarttalkyc/
electronDownload:
mirror: https://npmmirror.com/mirrors/electron/
# 额外依赖打包到输出目录
diff --git a/package.json b/package.json
index 75da1f6..57803ba 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,9 @@
{
"name": "aix-win",
- "version": "2.1.12",
+ "version": "2.1.36",
"description": "",
"main": "./out/main/index.js",
- "author": "example.com",
+ "author": "上海交大重庆人工智能研究院",
"homepage": "https://electron-vite.org",
"scripts": {
"format": "prettier --write .",
@@ -16,7 +16,7 @@
"build:dev": "npm run build && electron-builder --win --config ./electron-builder-test.yml",
"build:test": "electron-vite build --mode test && electron-builder --win --config ./electron-builder.yml",
"build:prod": "electron-vite build --mode production && electron-builder --win --config ./electron-builder-prod.yml",
- "build:lt": "electron-vite build --mode lt && electron-builder --win --config ./electron-builder-lt.yml",
+ "build:yc": "electron-vite build --mode yc && electron-builder --win --config ./electron-builder-yc.yml",
"build:mac": "electron-vite build --mode production && electron-builder --mac --config ./electron-builder-prod.yml",
"build:linux": "npm run build && electron-builder --linux"
},
diff --git a/src/main/index.js b/src/main/index.js
index 87a0ef1..22f49a2 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -46,7 +46,7 @@ if(!gotTheLock){
function createLoginWindow() {
if (loginWindow) return
loginWindow = new BrowserWindow({
- width: 888,
+ width: import.meta.env.MODE==='yc'?1160:888,
height: 520,
show: false,
frame: false,
@@ -175,6 +175,7 @@ async function createLinkWin(data) {
data.fullPath += '?urlSource=smarttalk&t' + Date.now()
}
linkWin[data.key].loadURL(data.fullPath)
+ if (import.meta.env.VITE_SHOW_DEV_TOOLS === 'true') linkWin[data.key].webContents.openDevTools()
linkWin[data.key].once('ready-to-show', () => {
linkWin[data.key].show()
@@ -271,12 +272,13 @@ app.on('window-all-closed', () => {
function handleAll() {
const chatInstance = chat.initialize() // im-chat 实例
// 新窗口创建-监听
- ipcMain.on('new-window', (e, data) => {
+ ipcMain.handle('new-window', (e, data) => {
const { id, type } = data
const win = BrowserWindow.fromId(id)
win.type = type // 绑定独立标识
remote.enable(win.webContents) // 开启远程服务
chatInstance.enable(win.webContents) // 开启im-chat
+ console.log(`主进程 [${type}]: 窗口注册-远程代理-完毕(${Date.now()})`)
})
// 用于监听-状态管理变化-同步所有窗口
ipcMain.handle('pinia-state-change', (e, storeName, jsonStr) => {
diff --git a/src/main/store.js b/src/main/store.js
index a34bd90..22e61dd 100644
--- a/src/main/store.js
+++ b/src/main/store.js
@@ -23,7 +23,9 @@ const defaultData = {
curNode: null, // 当前选中的节点
defaultExpandedKeys: [], //展开的节点
subjectTree: [] // "树结构" 章节
- }
+ },
+ env: {}, // 不走同步 Pinia - 变量
+ curr: {} // 不走同步 Pinia - 当前信息
},
local: { // 本地(永久localStorage)
},
diff --git a/src/renderer/src/api/classTask/index.js b/src/renderer/src/api/classTask/index.js
index bf03614..8a95531 100644
--- a/src/renderer/src/api/classTask/index.js
+++ b/src/renderer/src/api/classTask/index.js
@@ -71,6 +71,16 @@ export function updateClassworkeval(data) {
})
}
+
+// 修改classworkeval
+export function updateClassworkevalList(data) {
+ return request({
+ url: '/education/classworkeval/updateList',
+ method: 'put',
+ data: data
+ })
+}
+
// 修改classworkdata
export function updateClassworkdata(data) {
return request({
@@ -79,6 +89,13 @@ export function updateClassworkdata(data) {
data: data
})
}
+export function updateClassWorkDataAutoFinish(data) {
+ return request({
+ url: '/education/classworkdata/updAutoFinish',
+ method: 'put',
+ data: data
+ })
+}
// 修改classwork
export function updateClasswork(data) {
@@ -108,90 +125,90 @@ export function addClassworkeval(data) {
// 查询evaluationclue列表
export function listEvaluationclue(query) {
return request({
- url: '/education/evaluationclue/list',
- method: 'get',
- params: query
+ url: '/education/evaluationclue/list',
+ method: 'get',
+ params: query
})
}
// 查询evaluationclue详细
export function getEvaluationclue(id) {
return request({
- url: '/education/evaluationclue/' + id,
- method: 'get'
+ url: '/education/evaluationclue/' + id,
+ method: 'get'
})
}
// 新增evaluationclue
export function addEvaluationclueReturnId(data) {
return request({
- url: '/education/evaluationclue/addReturnId',
- method: 'post',
- data: data
+ url: '/education/evaluationclue/addReturnId',
+ method: 'post',
+ data: data
})
}
// 新增evaluationclue
export function addEvaluationclue(data) {
return request({
- url: '/education/evaluationclue',
- method: 'post',
- data: data
+ url: '/education/evaluationclue',
+ method: 'post',
+ data: data
})
}
// 修改evaluationclue
export function updateEvaluationclue(data) {
return request({
- url: '/education/evaluationclue',
- method: 'put',
- data: data
+ url: '/education/evaluationclue',
+ method: 'put',
+ data: data
})
}
// 删除evaluationclue
export function delEvaluationclue(id) {
return request({
- url: '/education/evaluationclue/' + id,
- method: 'delete'
+ url: '/education/evaluationclue/' + id,
+ method: 'delete'
})
}
// 新增evaluationclue,保存base64图片
export function saveBase64File(data) {
return request({
- url: '/education/evaluationclue/saveBase64File',
- method: 'post',
- data: data
+ url: '/education/evaluationclue/saveBase64File',
+ method: 'post',
+ data: data
})
}
// 新增evaluationclue,上传
export function saveEvaluationClueUploadFile(data) {
return request({
- url: '/education/evaluationclue/saveUploadFile',
- method: 'post',
- data: data
+ url: '/education/evaluationclue/saveUploadFile',
+ method: 'post',
+ data: data
})
}
// 读取文件内容
export function readFile(data) {
return fetch(import.meta.env.VITE_APP_RES_FILE_PATH + data.cluelink, {
- method: "get",
- headers: {
- 'Content-Type': 'text/plain', // 请求头设置为纯文本
- 'Accept': 'text/plain' // 接受头设置为纯文本
- },
+ method: "get",
+ headers: {
+ 'Content-Type': 'text/plain', // 请求头设置为纯文本
+ 'Accept': 'text/plain' // 接受头设置为纯文本
+ },
})
- .then(response => response.text())
- .then(text => {
- return Promise.resolve(text);
- })
- .catch(error => {
- console.error('读取文件出错:', error);
- return Promise.reject();
- });
+ .then(response => response.text())
+ .then(text => {
+ return Promise.resolve(text);
+ })
+ .catch(error => {
+ console.error('读取文件出错:', error);
+ return Promise.reject();
+ });
/*return request({
url: '/education/evaluationclue/readFile',
method: 'post',
diff --git a/src/renderer/src/api/file/index.js b/src/renderer/src/api/file/index.js
index e655614..7d401d6 100644
--- a/src/renderer/src/api/file/index.js
+++ b/src/renderer/src/api/file/index.js
@@ -24,6 +24,13 @@ export const getPrepareById = (id) => {
})
}
+export const addFileToKj = (id) => {
+ return request({
+ url: '/smarttalk/file/addFileToKj/' + id,
+ method: 'get'
+ })
+}
+
export function deleteSmarttalk(id) {
return request({
url: '/smarttalk/file/' + id,
@@ -53,3 +60,14 @@ export const moveSmarttalk = (params) => {
params
})
}
+
+export const addFileToPrepareThird = (data) => {
+ return request({
+ url: '/smarttalk/file/addFileToPrepareThird',
+ method: 'post',
+ headers: {
+ 'Content-Type': 'multipart/form-data'
+ },
+ data
+ })
+}
diff --git a/src/renderer/src/assets/iconfont/iconfont.css b/src/renderer/src/assets/iconfont/iconfont.css
index 75ba33d..f13d533 100644
--- a/src/renderer/src/assets/iconfont/iconfont.css
+++ b/src/renderer/src/assets/iconfont/iconfont.css
@@ -1,9 +1,9 @@
@font-face {
font-family: "iconfont"; /* Project id 2794390 */
- src: url('iconfont.woff2?t=1728543886557') format('woff2'),
- url('iconfont.woff?t=1728543886557') format('woff'),
- url('iconfont.ttf?t=1728543886557') format('truetype'),
- url('iconfont.svg?t=1728543886557#iconfont') format('svg');
+ src: url('iconfont.woff2?t=1732002934577') format('woff2'),
+ url('iconfont.woff?t=1732002934577') format('woff'),
+ url('iconfont.ttf?t=1732002934577') format('truetype'),
+ url('iconfont.svg?t=1732002934577#iconfont') format('svg');
}
.iconfont {
@@ -14,6 +14,26 @@
-moz-osx-font-smoothing: grayscale;
}
+.icon-a-shiyanpingshiyanyanjiu:before {
+ content: "\e9a0";
+}
+
+.icon-banji2:before {
+ content: "\e6c0";
+}
+
+.icon-set:before {
+ content: "\e691";
+}
+
+.icon-shouye:before {
+ content: "\e637";
+}
+
+.icon-gongzuotai:before {
+ content: "\e690";
+}
+
.icon-A1:before {
content: "\e635";
}
diff --git a/src/renderer/src/assets/iconfont/iconfont.js b/src/renderer/src/assets/iconfont/iconfont.js
index e5c0dbb..9d75b40 100644
--- a/src/renderer/src/assets/iconfont/iconfont.js
+++ b/src/renderer/src/assets/iconfont/iconfont.js
@@ -1 +1 @@
-window._iconfont_svg_string_2794390='',(c=>{var h=(l=(l=document.getElementsByTagName("script"))[l.length-1]).getAttribute("data-injectcss"),l=l.getAttribute("data-disable-injectsvg");if(!l){var a,t,i,z,p,v=function(h,l){l.parentNode.insertBefore(h,l)};if(h&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(h){console&&console.log(h)}}a=function(){var h,l=document.createElement("div");l.innerHTML=c._iconfont_svg_string_2794390,(l=l.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",l=l,(h=document.body).firstChild?v(l,h.firstChild):h.appendChild(l))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(a,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),a()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(i=a,z=c.document,p=!1,d(),z.onreadystatechange=function(){"complete"==z.readyState&&(z.onreadystatechange=null,M())})}function M(){p||(p=!0,i())}function d(){try{z.documentElement.doScroll("left")}catch(h){return void setTimeout(d,50)}M()}})(window);
\ No newline at end of file
+window._iconfont_svg_string_2794390='',(c=>{var l=(h=(h=document.getElementsByTagName("script"))[h.length-1]).getAttribute("data-injectcss"),h=h.getAttribute("data-disable-injectsvg");if(!h){var a,t,i,z,p,v=function(l,h){h.parentNode.insertBefore(l,h)};if(l&&!c.__iconfont__svg__cssinject__){c.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(l){console&&console.log(l)}}a=function(){var l,h=document.createElement("div");h.innerHTML=c._iconfont_svg_string_2794390,(h=h.getElementsByTagName("svg")[0])&&(h.setAttribute("aria-hidden","true"),h.style.position="absolute",h.style.width=0,h.style.height=0,h.style.overflow="hidden",h=h,(l=document.body).firstChild?v(h,l.firstChild):l.appendChild(h))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(a,0):(t=function(){document.removeEventListener("DOMContentLoaded",t,!1),a()},document.addEventListener("DOMContentLoaded",t,!1)):document.attachEvent&&(i=a,z=c.document,p=!1,d(),z.onreadystatechange=function(){"complete"==z.readyState&&(z.onreadystatechange=null,M())})}function M(){p||(p=!0,i())}function d(){try{z.documentElement.doScroll("left")}catch(l){return void setTimeout(d,50)}M()}})(window);
\ No newline at end of file
diff --git a/src/renderer/src/assets/iconfont/iconfont.json b/src/renderer/src/assets/iconfont/iconfont.json
index de96ea7..d2cf203 100644
--- a/src/renderer/src/assets/iconfont/iconfont.json
+++ b/src/renderer/src/assets/iconfont/iconfont.json
@@ -1,10 +1,45 @@
{
"id": "2794390",
- "name": "electron",
+ "name": "文枢2.1",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
+ {
+ "icon_id": "41507853",
+ "name": "实验瓶",
+ "font_class": "a-shiyanpingshiyanyanjiu",
+ "unicode": "e9a0",
+ "unicode_decimal": 59808
+ },
+ {
+ "icon_id": "1017928",
+ "name": "班级",
+ "font_class": "banji2",
+ "unicode": "e6c0",
+ "unicode_decimal": 59072
+ },
+ {
+ "icon_id": "376364",
+ "name": "设置",
+ "font_class": "set",
+ "unicode": "e691",
+ "unicode_decimal": 59025
+ },
+ {
+ "icon_id": "5835474",
+ "name": "首页",
+ "font_class": "shouye",
+ "unicode": "e637",
+ "unicode_decimal": 58935
+ },
+ {
+ "icon_id": "19108133",
+ "name": "工作台",
+ "font_class": "gongzuotai",
+ "unicode": "e690",
+ "unicode_decimal": 59024
+ },
{
"icon_id": "11657531",
"name": "A",
diff --git a/src/renderer/src/assets/iconfont/iconfont.svg b/src/renderer/src/assets/iconfont/iconfont.svg
index 105c931..76a5447 100644
--- a/src/renderer/src/assets/iconfont/iconfont.svg
+++ b/src/renderer/src/assets/iconfont/iconfont.svg
@@ -14,6 +14,16 @@
/>
+
+
+
+
+
+
+
+
+
+
diff --git a/src/renderer/src/assets/iconfont/iconfont.ttf b/src/renderer/src/assets/iconfont/iconfont.ttf
index efbbc57..1a9b595 100644
Binary files a/src/renderer/src/assets/iconfont/iconfont.ttf and b/src/renderer/src/assets/iconfont/iconfont.ttf differ
diff --git a/src/renderer/src/assets/iconfont/iconfont.woff b/src/renderer/src/assets/iconfont/iconfont.woff
index 8fd280e..8a98877 100644
Binary files a/src/renderer/src/assets/iconfont/iconfont.woff and b/src/renderer/src/assets/iconfont/iconfont.woff differ
diff --git a/src/renderer/src/assets/iconfont/iconfont.woff2 b/src/renderer/src/assets/iconfont/iconfont.woff2
index f0667a9..6d80dc0 100644
Binary files a/src/renderer/src/assets/iconfont/iconfont.woff2 and b/src/renderer/src/assets/iconfont/iconfont.woff2 differ
diff --git a/src/renderer/src/assets/images/login/yc-logo.png b/src/renderer/src/assets/images/login/yc-logo.png
new file mode 100644
index 0000000..59db44e
Binary files /dev/null and b/src/renderer/src/assets/images/login/yc-logo.png differ
diff --git a/src/renderer/src/assets/images/login/ycpeitu.png b/src/renderer/src/assets/images/login/ycpeitu.png
new file mode 100644
index 0000000..433a296
Binary files /dev/null and b/src/renderer/src/assets/images/login/ycpeitu.png differ
diff --git a/src/renderer/src/components/choose-textbook/index.vue b/src/renderer/src/components/choose-textbook/index.vue
index 3c4414d..9f6c27d 100644
--- a/src/renderer/src/components/choose-textbook/index.vue
+++ b/src/renderer/src/components/choose-textbook/index.vue
@@ -139,16 +139,23 @@ const handleNodeClick = (data) => {
* data : 当前节点数据
*/
let nodeData = cloneDeep(toRaw(data));
-
//增加一个label 之前取的label
nodeData.label = nodeData.itemtitle
- // 父级节点 如果当前是一级节点 父级则为null
- let parent = {
- id: nodeData.parentid,
- label: nodeData.parenttitle,
- itemtitle: nodeData.parenttitle
- }
- const parentNode = nodeData.parentid ? parent : null
+
+ let parentNode
+ // 存在children 则为一级节点
+ if(nodeData.children){
+ // 为一级节点
+ parentNode = null
+ }
+ else{
+ parentNode = {
+ id: nodeData.parentid,
+ label: nodeData.parenttitle,
+ itemtitle: nodeData.parenttitle
+ }
+ }
+
nodeData.parentNode = parentNode
let curData = {
textBook: {
diff --git a/src/renderer/src/components/exam-question/examDetailsDrawer.vue b/src/renderer/src/components/exam-question/examDetailsDrawer.vue
new file mode 100644
index 0000000..12de43c
--- /dev/null
+++ b/src/renderer/src/components/exam-question/examDetailsDrawer.vue
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+ {{activeExam.worktag}}
+
+
+
+
+ 【答案】
+
+ 【分析】
+
+ 【解答】
+
+ 【点评】
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/renderer/src/components/set-homework/index.vue b/src/renderer/src/components/set-homework/index.vue
index 17127b8..a237a80 100644
--- a/src/renderer/src/components/set-homework/index.vue
+++ b/src/renderer/src/components/set-homework/index.vue
@@ -213,7 +213,7 @@ const delStudent = (index) => {
const onSubmit = (formEl) => {
if (!formEl) return
// 课堂id
- const classRoomId = sessionStore.get('curClassRoom.id')
+ const classRoomId = sessionStore.get('curr.curClassRoom.id')
formEl.validate((valid) => {
if (valid) {
/**
@@ -244,7 +244,8 @@ const onSubmit = (formEl) => {
entpcourseworklist: '[' + props.rows[i].entpcourseworklist + ']',
needMsgNotifine: 'false',
msgkey: 'newclasswork',
- title: '作业任务',
+ //title: '作业任务',
+ title: props.rows[i].title,
msgcontent: '',
teachername: userInfo.nickName,
unixstamp: new Date().getTime(),
@@ -254,14 +255,16 @@ const onSubmit = (formEl) => {
ary.push(obj)
}
}
+ console.log('ary->', ary)
setLoading.value = true
saveByClassWorkArray({
classworkarray: JSON.stringify(ary)
})
.then((res) => {
+
setLoading.value = false
ElMessage.success('操作成功')
- emit('on-success', res.data)
+ emit('on-success', res)
cloneDialog(formEl)
})
.catch(() => {
diff --git a/src/renderer/src/components/thirdFile-preview/index.vue b/src/renderer/src/components/thirdFile-preview/index.vue
new file mode 100644
index 0000000..391ddd6
--- /dev/null
+++ b/src/renderer/src/components/thirdFile-preview/index.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/renderer/src/components/window-tools/index.vue b/src/renderer/src/components/window-tools/index.vue
index da66f80..b2d9057 100644
--- a/src/renderer/src/components/window-tools/index.vue
+++ b/src/renderer/src/components/window-tools/index.vue
@@ -8,9 +8,10 @@
+onMounted(() =>{
+ isMaxSize.value = Remote.getCurrentWindow().isMaximized()
+})
+
+
\ No newline at end of file
+
diff --git a/src/renderer/src/hooks/useProcessList.js b/src/renderer/src/hooks/useProcessList.js
index 1a1ca4f..e7329eb 100644
--- a/src/renderer/src/hooks/useProcessList.js
+++ b/src/renderer/src/hooks/useProcessList.js
@@ -15,9 +15,10 @@ export const isJson = (str) => {
/**
* @description processList 格式化试题
- * @param {*} row
+ * @param {*} row
+ * @param {*} aloneOption 选择题中选项是否为每行一个
*/
-export const processList = (row) => {
+export const processList = (row, aloneOption=false) => {
for (var i = 0; i < row.length; i++) {
if (isJson(row[i].workanalysis)) {
//1、先默认格式化 格式化各项内容(待优化, 后续界面显示的为format的值)
@@ -55,19 +56,25 @@ export const processList = (row) => {
const workDescArr = element.split('#&')
let tmp = ''
let j = 0
- for (; j < workDescArr.length; j++) {
- if (j % 2 == 0) {
- tmp += `
`
+ for(; j${char}.${workDescArr[j]}
`;
}
- const char = String.fromCharCode(65 + j)
- tmp += `${char}.${workDescArr[j]}
`
- if (j % 2 == 1) {
- tmp += ''
+ else {
+ if(j%2 == 0){
+ tmp += ``;
+ }
+
+ tmp += `
${char}.${workDescArr[j]}
`;
+ if(j%2 == 1){
+ tmp += '
';
+ }
}
}
// j此刻已自增1, 故当选项为单数时, 需要补充结束标签
- if (j % 2 == 1) {
- tmp += ''
+ if(!aloneOption && j%2 == 1){
+ tmp += '';
}
// workDescArr为 [''] 表示为 判断题或者填空题,这里不需要选项
@@ -136,31 +143,36 @@ export const processList = (row) => {
* ]
*/
let workDescArr = JSON.parse(row[i].workdesc)
- let workDescHtml = ``
workDescArr.map((item, index) => {
if (item.type == '单选题' || item.type == '多选题') {
- workDescHtml += `
${index + 1}. ${item.title}
`
+ workDescHtml += `
${index + 1}. ${item.title}
`
let tmp = ''
let j = 0
let optionsArr = item.options
- for (; j < optionsArr.length; j++) {
- if (j % 2 == 0) {
- tmp += `
`
+ for(; j${char}.${optionsArr[j]}
`;
}
- const char = String.fromCharCode(65 + j)
- tmp += `
${char}.${optionsArr[j]}
`
- if (j % 2 == 1) {
- tmp += '
'
+ else {
+ if(j%2 == 0){
+ tmp += ``;
+ }
+
+ tmp += `
${char}.${optionsArr[j]}
`;
+ if(j%2 == 1){
+ tmp += '
';
+ }
}
}
// j此刻已自增1, 故当选项为单数时, 需要补充结束标签
- if (j % 2 == 1) {
- tmp += ''
+ if(!aloneOption && j%2 == 1){
+ tmp += '';
}
-
workDescHtml += tmp
} else if (item.type == '填空题' || item.type == '判断题' || item.type == '主观题') {
- workDescHtml += `${index + 1}. ${item.title}
`
+ workDescHtml += `${index + 1}. ${item.title}
`
}
})
workDescHtml += ''
@@ -265,18 +277,24 @@ export const processList = (row) => {
// 处理[选项显示] - 拼接ABCD首序号
let tmp = ''
let j = 0
- for (; j < workDescArr.length; j++) {
- if (j % 2 == 0) {
- tmp += ``
+ for(; j${char}.${workDescArr[j]}
`;
}
- const char = String.fromCharCode(65 + j)
- tmp += `${char}.${workDescArr[j]}
`
- if (j % 2 == 1) {
- tmp += ''
+ else {
+ if(j%2 == 0){
+ tmp += ``;
+ }
+
+ tmp += `
${char}.${workDescArr[j]}
`;
+ if(j%2 == 1){
+ tmp += '
';
+ }
}
}
- if (j % 2 == 0) {
- tmp += ''
+ if(!aloneOption && j%2== 0){
+ tmp += '';
}
row[i].workdescFormat = tmp
diff --git a/src/renderer/src/layout/components/Header.vue b/src/renderer/src/layout/components/Header.vue
index 6b3e875..e07e422 100644
--- a/src/renderer/src/layout/components/Header.vue
+++ b/src/renderer/src/layout/components/Header.vue
@@ -29,11 +29,15 @@
-
@@ -61,25 +56,29 @@ import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
import { listByDeadDate, listClassworkdata } from '@/api/classTask'
import TaskItem from '@/views/classTask/container/classTask/task-item.vue'
-// import ItemDialog from '@/views/classTask/container/item-dialog.vue'
import { useToolState } from '@/store/modules/tool'
-import { getCurrentTime } from '@/utils/date'
+import { getDateFormatDate, getTheOtherDay, getTheOtheNextDay } from '@/utils/date'
import useUserStore from '@/store/modules/user'
-import useClassTaskStore from "@/store/modules/classTask";
import {createWindow} from '@/utils/tool'
-import {sessionStore} from '@/utils/store'
import {debounce } from '@/utils/comm'
const toolState = useToolState();
-
-const classTaskStore = useClassTaskStore()
const userStore = useUserStore().user
-// const itemDialogRef = ref(null)
-const tabOptions = ref(['进行中', '已结束'])
-const tabActive = ref('进行中')
+
+const tabOptions = ref(['待批改', '已批改'])
+const tabActive = ref('待批改')
const dataList = ref([])
-const EndDate = ref(getCurrentTime('YYYY-MM-DD'))
+// 默认起止时间:当前日期前2天后3天;默认查询一周的数据
+const startEndDate = ref([
+ getTheOtherDay(3),
+ getTheOtheNextDay(3),
+])
+const defaultTime = ref<[Date, Date]>([
+ getTheOtherDay(3),
+ getTheOtheNextDay(3),
+])
+
// 所有班级作业列表
const classWorkList = ref([])
@@ -91,23 +90,18 @@ const loading = ref(false)
const activeDataList = computed(() => {
return classWorkList.value
})
+const doneDataList = computed(() => {
+ return classWorkList.value
+})
const deleteReserv = (item) => {
console.log('删除待开发', item)
// dataList.value = dataList.value.filter((is) => {
// return is.id !== item.id
// })
}
-const doneDataList = computed(() => {
- return classWorkList.value
-})
-// 当日之后的日期禁用
-const disabledDate = (time) => {
- return time.getTime() > Date.now()
-}
-// 截止日期改变
-const changeEndDate = (val) => {
- console.log('截止日期改变', val)
+const changeStartEndDate = (val) => {
+ console.log('起止日期改变', val)
getData() // 加载数据
}
@@ -115,245 +109,202 @@ const changeEndDate = (val) => {
const getData = async () => {
classWorkList.value = []
loading.value = true
- // 1、班级列表
- // getClassList()
- // 2、班级作业
+ // 1、班级作业
await getClassWorkList()
- // 3、班级学生作业 包含多个班级
+ // 2、班级学生作业 包含多个班级
getStudentClassWorkData()
loading.value = false
}
+
/**
- * 1、获取班级列表数据
- * TODO 这里暂时取班级id的list,后续需要在修改
- */
-const getClassList = () => {
- if(classTaskStore.classListIds.length==0){
- // 获取 班级列表ids 这里暂时取班级id的list,后续需要在修改
- classTaskStore.listClassmain({ classuserid: userStore.userId, pageSize: 100, status: 'open' })
- }
-}
-/**
- * 2、获取班级作业
+ * 1、获取班级作业
*/
const getClassWorkList = async () => {
- //if(classTaskStore.classListIds.length>0){
- {
- // 班级作业数据,包含多个班级 homeworklist
- const response = await listByDeadDate({
- edituserid: userStore.userId, // 老师的id
- edustage: userStore.edustage, // 学段
- edusubject: userStore.edusubject,//学科
- // deaddate: tabActive.value === '进行中'? getTomorrow() : EndDate.value,// 进行中:明天,已结束:选择的日期 弃用
- deaddate: EndDate.value,// 进行中:明天,已结束:选择的日期
- status: '1', // 作业状态:1-已发布
- orderby: 'deaddate DESC',
- pageSize: 100,
- })
+ // 班级作业数据,包含多个班级 homeworklist
+ const response = await listByDeadDate({
+ edituserid: userStore.userId, // 老师的id
+ edustage: userStore.edustage, // 学段
+ edusubject: userStore.edusubject,//学科
+ startdate: tabActive.value === '待批改'? '' : getDateFormatDate(startEndDate.value[0]),
+ deaddate: tabActive.value === '待批改'? '' : getDateFormatDate(startEndDate.value[1]),// 待批改:明天,已批改:选择的日期
+ status: tabActive.value === '待批改'? '1' : '2', // 作业状态:1-已发布
+ orderby: 'deaddate DESC',
+ pageSize: 100,
+ })
- /**
- * 2024-10-17 由于 后面截止时间加了 时分,特加判断
- * 1、进行中、以前是以明天判断。现改为传当天的日期,并根据当前日期的时分与截止日期进行判断,
- * 2、已结束、以前默认是以明天判断。现依然以明天为判断,并根据当前日期时分大于截止日期时分判断。
- */
- let list = [];
- if(tabActive.value === '进行中'){
- // 进行中 当前日期时间 小于 截止 日期时间
- list = response.rows&&response.rows.filter(item => item.deaddate && getCurrentTime('YYYY-MM-DD HH:mm') < item.deaddate); // 进行中
- }else{
- list = response.rows&&response.rows.filter(item => item.deaddate && getCurrentTime('YYYY-MM-DD HH:mm') > item.deaddate); // 已结束
+ let list = response.rows || [];
+ for (var i = 0; i < list.length; i++) {
+ // 初始化部分新增字段值
+ list[i].workdatalist = [] // 当前任务中有多少个学生的数据集合
+ list[i].workdatalistVisible = false
+ list[i].feedtimelength = 0 // 已交的学生人中,汇总计算用时
+ list[i].rightAnswerCount = 0
+ list[i].scoingRate = 0 + '%' // 得分率
+ list[i].averagetime = 0 // 平均用时
+
+ // ----------------------------------------------
+ // 处理任务类型的UI
+ if (list[i].worktype == '学习目标定位') {
+ list[i].workclass = 'success'
+ list[i].workcodesList = JSON.parse(list[i].workcodes)
+ } else if (list[i].worktype == '教材研读') {
+ list[i].workclass = 'primary'
+ } else if (list[i].worktype == '框架梳理') {
+ list[i].workclass = 'warning'
+ } else if (list[i].worktype == '学科定位') {
+ list[i].workclass = 'info'
+ } else if (list[i].worktype == '习题训练') {
+ list[i].workclass = 'danger'
+ } else {
+ list[i].workclass = ''
}
-
-
- for (var i = 0; i < list.length; i++) {
- // 初始化部分新增字段值
- list[i].workdatalist = []
- list[i].workdatacount = 0 // 人数
- list[i].workdatalistVisible = false
- list[i].workdatafeedbackcount = 0 // 已交人数
- list[i].feedtimelength = 0
- list[i].rightAnswerCount = 0
- list[i].scoingRate = 0 + '%' // 得分率
- list[i].averagetime = 0 // 平均用时
-
- // ----------------------------------------------
- // 处理任务类型的UI
- if (list[i].worktype == '学习目标定位') {
- list[i].workclass = 'success'
- list[i].workcodesList = JSON.parse(list[i].workcodes)
- } else if (list[i].worktype == '教材研读') {
- list[i].workclass = 'primary'
- } else if (list[i].worktype == '框架梳理') {
- list[i].workclass = 'warning'
- } else if (list[i].worktype == '学科定位') {
- list[i].workclass = 'info'
- } else if (list[i].worktype == '习题训练') {
- list[i].workclass = 'danger'
- } else {
- list[i].workclass = ''
- }
- // 如果是习题训练任务,则检查一共有多少道
- if (list[i].entpcourseworklist != '') {
- list[i].entpcourseworklistarray = JSON.parse(
- '[' + list[i].entpcourseworklist + ']'
- )
- } else {
- list[i].entpcourseworklistarray = []
- }
- // 根据 classworkdatastudentids 初始化判断分配的人数
- if (
- list[i].classworkdatastudentids != '' &&
- list[i].classworkdatastudentids != null &&
- list[i].classworkdatastudentids != 'null'
- ) {
- const stuList = JSON.parse('[' + list[i].classworkdatastudentids + ']')
- list[i].workdatacount = stuList.length
- }
+ // 如果是习题训练任务,则检查一共有多少道
+ if (list[i].entpcourseworklist != '') {
+ list[i].entpcourseworklistarray = JSON.parse(
+ '[' + list[i].entpcourseworklist + ']'
+ )
+ } else {
+ list[i].entpcourseworklistarray = []
}
- // 显示分配人数(workdatacount)>0 的
- if (list && list.length > 0) {
- classWorkList.value = list && list.filter((item) => item.workdatacount > 0)
- //TODO: 这里没分页,貌似这个 total 不重要,后续看
- total.value = 0
- }else{
- classWorkList.value = []
- total.value = 0
- }
- loading.value = false
}
+
+ // 显示分配人数(workdataresultsum)>0 的
+ if (list && list.length > 0) {
+ classWorkList.value = list && list.filter((item) => item.workdataresultsum > 0)
+ //TODO: 这里没分页,貌似这个 total 不重要,后续看
+ total.value = 0
+ }else{
+ classWorkList.value = []
+ total.value = 0
+ }
+ loading.value = false
}
/**
- * 3、获取多个班级学生作业数据
+ * 2、获取多个班级学生作业数据
+ * 查询已交的列表
+ * @param workList :需要更新的作业list
+ * @param Refresh :true 不用刷新,false 需要刷新
*/
-const getStudentClassWorkData = async() => {
- // const { chapterId } = await useGetHomework(props.bookobj.node)
- // this.entpcourseid = chapterId
- //if(classTaskStore.classListIds.length>0){
- // listClassworkdataByDeadDate({
- // edituserid: userStore.userId, // 老师的id
- // classids: classTaskStore.classListIds.join(','),
- // edusubject: userStore.edusubject,//学科
- // deaddate: tabActive.value === '进行中'? getTomorrow() : EndDate.value,// 进行中:明天,已结束:选择的日期
- // deaddate: EndDate.value,// 进行中:明天,已结束:选择的日期
- // //status: '1', // 作业状态:1-已发布
- // orderby: "deaddate DESC",//
- // pageSize: 1000,
- // })
+const getStudentClassWorkData = async(workList = [], Refresh = true) => {
+ // 获取 已交的 列表数据(workdataresultcount 已交的学生数)
+ let SubmitClWorkList = [];
+ if(Refresh){
+ SubmitClWorkList = classWorkList.value.filter((item) => item.workdataresultcount > 0) ;
+ }else{
+ SubmitClWorkList = workList;
+ }
- // listClassworkdataNew({
- // classworkids: ids, // 作业id
- // edituserid: userStore.userId, // 老师的id
- // edusubject: userStore.edusubject,//学科
- // evalStatus: 1,
- // pageSize: 1000,
- // })
+ console.log('有提交的作业', SubmitClWorkList)
+ const ids = SubmitClWorkList&&SubmitClWorkList.map((item) => item.id).join(',');
+ if (ids == '') {
+ return;
+ }
+ listClassworkdata({
+ classworkids: ids,
+ pageSize: 1000,
+ }).then((res) => {
+ for (var t = 0; t < classWorkList.value.length; t++) {
+ for (var i = 0; i < res.rows.length; i++) {
+ // finishtimelength != '0' 已交
+ if (res.rows[i].classworkid == classWorkList.value[t].id && res.rows[i].finishtimelength != '0') {
+ console.log('==================')
+ // 有几个学生完成/正在完成学习任务
+ // 至少resultcount不是0
+ //classWorkList.value[t].workdataresultcount++
-
- {
- const ids = classWorkList.value.map((item) => item.id).join(',');
- if (ids == '') {
- return;
- }
- listClassworkdata({
- classworkids: ids,
- pageSize: 1000,
- }).then((res) => {
- 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 && res.rows[i].finishtimelength != '0') {
- console.log('==================')
- // 有几个学生完成/正在完成学习任务
- // 至少resultcount不是0
- classWorkList.value[t].workdatafeedbackcount++
+ // 已交的学生人中,汇总计算用时
+ classWorkList.value[t].feedtimelength += parseInt(res.rows[i].finishtimelength)
- // 在参与学习任务的人中,汇总计算用时
- classWorkList.value[t].feedtimelength += parseInt(res.rows[i].finishtimelength)
+ // 计算得分率
+ if (
+ res.rows[i].classworkevallist != '' &&
+ res.rows[i].classworkevallist != null &&
+ res.rows[i].classworkevallist != 'null'
+ ) {
+ let replacedString = res.rows[i].classworkevallist.replace(/""/g, '"')
+ // 将标签中双引号改为转义, 测试数据: "{\"id\":172907, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":358520, \"feedcontent\":\"④①⑤③②\", \"score\":4, \"rightanswer\":\"④①⑤③②\"},{\"id\":172908, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":358521, \"feedcontent\":\"气壮山威,鲲鹏展翅楚云飞\", \"score\":4, \"rightanswer\":\"志远天高,春风杨柳麓山青\"},{\"id\":172909, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":363096, \"feedcontent\":\"《红烛》化用“蜡矩”这一古典意象,赋予它新的含义,赞美了红烛以“蜡炬成灰”来点亮世界的奉献精神。\", \"score\":4, \"rightanswer\":\"《立在地球边上放号》中,全诗采用间接抒情的方式,描绘了太平洋的浪潮,吟唱了一曲惊心动魄的力的颂歌,意在赞美摧毁旧世界、创造新生活的“五四”精神。\"},{\"id\":172910, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":363098, \"feedcontent\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,
浮想联翩。\", \"score\":4, \"rightanswer\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,
浮想联翩。\"},{\"id\":172911, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":363100, \"feedcontent\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,
浮想联翩。\", \"score\":4, \"rightanswer\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,
浮想联翩。\"}"
+ replacedString = escapeHtmlQuotes(res.rows[i].classworkevallist).replace(
+ /"(\[.*\])"/g,
+ '$1'
+ )
+ replacedString = escapeHtmlQuotes(res.rows[i].classworkevallist)
+ var evalarray
+ try {
+ evalarray = JSON.parse('[' + res.rows[i].classworkevallist + ']')
+ } catch {
+ evalarray = JSON.parse('[' + replacedString + ']')
+ }
- // 计算得分率
- if (
- res.rows[i].classworkevallist != '' &&
- res.rows[i].classworkevallist != null &&
- res.rows[i].classworkevallist != 'null'
- ) {
- let replacedString = res.rows[i].classworkevallist.replace(/""/g, '"')
- // 将标签中双引号改为转义, 测试数据: "{\"id\":172907, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":358520, \"feedcontent\":\"④①⑤③②\", \"score\":4, \"rightanswer\":\"④①⑤③②\"},{\"id\":172908, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":358521, \"feedcontent\":\"气壮山威,鲲鹏展翅楚云飞\", \"score\":4, \"rightanswer\":\"志远天高,春风杨柳麓山青\"},{\"id\":172909, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":363096, \"feedcontent\":\"《红烛》化用“蜡矩”这一古典意象,赋予它新的含义,赞美了红烛以“蜡炬成灰”来点亮世界的奉献精神。\", \"score\":4, \"rightanswer\":\"《立在地球边上放号》中,全诗采用间接抒情的方式,描绘了太平洋的浪潮,吟唱了一曲惊心动魄的力的颂歌,意在赞美摧毁旧世界、创造新生活的“五四”精神。\"},{\"id\":172910, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":363098, \"feedcontent\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,
浮想联翩。\", \"score\":4, \"rightanswer\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,
浮想联翩。\"},{\"id\":172911, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":363100, \"feedcontent\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,
浮想联翩。\", \"score\":4, \"rightanswer\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,
浮想联翩。\"}"
- replacedString = escapeHtmlQuotes(res.rows[i].classworkevallist).replace(
- /"(\[.*\])"/g,
- '$1'
- )
- replacedString = escapeHtmlQuotes(res.rows[i].classworkevallist)
- var evalarray
- try {
- evalarray = JSON.parse('[' + res.rows[i].classworkevallist + ']')
- } catch {
- evalarray = JSON.parse('[' + replacedString + ']')
+ for (var e = 0; e < evalarray.length; e++) {
+ if (res.rows[i].worktype == '常规作业') {
+ evalarray[e].feedcontent = escapeHtmlQuotes(evalarray[e].feedcontent).replace(
+ /"(\[.*\])"/g,
+ '$1'
+ )
+ evalarray[e].feedcontent = escapeHtmlQuotes(evalarray[e].feedcontent)
}
-
- for (var e = 0; e < evalarray.length; e++) {
- if (res.rows[i].worktype == '常规作业') {
- evalarray[e].feedcontent = escapeHtmlQuotes(evalarray[e].feedcontent).replace(
- /"(\[.*\])"/g,
- '$1'
- )
- evalarray[e].feedcontent = escapeHtmlQuotes(evalarray[e].feedcontent)
- }
- if (evalarray[e].feedcontent == evalarray[e].rightanswer) {
- // 正确,得分
- classWorkList.value[t].rightAnswerCount++
- }
+ if (evalarray[e].feedcontent == evalarray[e].rightanswer) {
+ // 正确,得分
+ classWorkList.value[t].rightAnswerCount++
}
}
}
- // 当前这个学习任务,共推送给了几个学生,workdatacount
- if (res.rows[i].classworkid == classWorkList.value[t].id) {
- classWorkList.value[t].workdatalist.push(res.rows[i])
- }
}
- // 计算完成进度 workdatacount人数要大于0
- if (
- classWorkList.value[t].workdataresultcount > 0 &&
- classWorkList.value[t].workdatacount > 0
- ) {
- classWorkList.value[t].finishpercent = parseInt(
- (classWorkList.value[t].workdataresultcount / classWorkList.value[t].workdatacount) * 100
- )
- } else {
- classWorkList.value[t].finishpercent = 0
+ // 当前这个学习任务,共推送给了几个学生,workdataresultsum
+ if (res.rows[i].classworkid == classWorkList.value[t].id) {
+ classWorkList.value[t].workdatalist.push(res.rows[i])
}
-
- // 以下四个参数,都要计算
- // 2024-04-12,酉阳,by jackyshen
-
- // 计算参与学习任务的平均用时
- if (classWorkList.value[t].workdatafeedbackcount > 0) {
- classWorkList.value[t].averagetime = Math.ceil(classWorkList.value[t].feedtimelength / classWorkList.value[t].workdatafeedbackcount / 60).toFixed(0)
- } else {
- classWorkList.value[t].averagetime = 0
- }
-
- // 计算批阅异常,需要获取每个题目的类型,找出主观题
- // 暂缓
-
- // 计算平均得分率: 正确题数/(题目总数*学生人数)*100
- if (
- classWorkList.value[t].entpcourseworklistarray &&
- classWorkList.value[t].entpcourseworklistarray.length > 0
- ) {
- var dd =
- (classWorkList.value[t].rightAnswerCount /
- (classWorkList.value[t].entpcourseworklistarray.length *
- classWorkList.value[t].workdatacount)) *
- 100
- classWorkList.value[t].scoingRate = dd.toFixed(0) + '%'
- } else {
- classWorkList.value[t].scoingRate = '0%'
- }
- // 设定典型作答,需要获取每个题目的类型,找出主观题
- // 暂缓
}
- })
- }
+
+
+ // 计算完成进度: workdataresultcount 学生提交了的个数; workdataresultsum 人数要大于0;
+ if (classWorkList.value[t].workdataresultcount > 0 && classWorkList.value[t].workdataresultsum > 0 ) {
+ classWorkList.value[t].finishpercent = parseInt(
+ (classWorkList.value[t].workdataresultcount / classWorkList.value[t].workdataresultsum) * 100
+ )
+ } else {
+ classWorkList.value[t].finishpercent = 0
+ }
+
+ /** 计算 已批阅进度 */
+ // workdataresultsum 人数 teacherrationgcount 已批阅人数
+ // 已批阅百分比: (人数-已批阅数) / 人数 * 100
+ if (classWorkList.value[t].workdataresultsum > 0) {
+ classWorkList.value[t].teacherCorrectionProgress = parseInt(
+ ((classWorkList.value[t].teacherrationgcount) / classWorkList.value[t].workdataresultsum) * 100
+ )
+ } else {
+ classWorkList.value[t].teacherCorrectionProgress = 0
+ }
+
+ // 以下四个参数,都要计算
+ // 2024-04-12,酉阳,by jackyshen
+
+ // 计算参与学习任务的平均用时:学生总用时/ 提交学生数
+ if (classWorkList.value[t].workdataresultcount > 0) {
+ classWorkList.value[t].averagetime = Math.ceil(classWorkList.value[t].feedtimelength / classWorkList.value[t].workdataresultcount / 60).toFixed(0)
+ } else {
+ classWorkList.value[t].averagetime = 0
+ }
+
+ // 计算平均得分率: 正确题数/(题目总数*学生人数)*100
+ if (
+ classWorkList.value[t].entpcourseworklistarray &&
+ classWorkList.value[t].entpcourseworklistarray.length > 0
+ ) {
+ var dd =
+ (classWorkList.value[t].rightAnswerCount /
+ (classWorkList.value[t].entpcourseworklistarray.length *
+ classWorkList.value[t].workdataresultsum)) *
+ 100
+ classWorkList.value[t].scoingRate = dd.toFixed(0) + '%'
+ } else {
+ classWorkList.value[t].scoingRate = '0%'
+ }
+ }
+ })
+
}
@@ -379,6 +330,7 @@ const getStudentClassWorkDataPolling = () => {
getStudentVisible()
// 在轮询
pollingST.value = setInterval(() => {
+ console.log('轮询查询学生作业进度')
getStudentVisible()
}, 1000 * 10)
}
@@ -413,75 +365,56 @@ onUnmounted(() => {
// [作业反馈] - 实际查询逻辑
const getStudentVisible = async () => {
- if (classTaskStore.classListIds.length <= 0) {
- return
+ if(!classWorkList.value.length>0){
+ return;
}
- // 班级作业数据,多个班级
const response = await listByDeadDate({
- classidarray: classTaskStore.classListIds.join(','),
edituserid: userStore.userId, // 老师的id
- edustage: userStore.edustage,// 学段
+ edustage: userStore.edustage, // 学段
edusubject: userStore.edusubject,//学科
- // deaddate: tabActive.value === '进行中'? getTomorrow() : EndDate.value,// 进行中:明天,已结束:选择的日期
- deaddate: EndDate.value,// 进行中:明天,已结束:选择的日期
- status: '1', // 作业状态:1-已发布
- // orderby: 'concat(deaddate,uniquekey) DESC',
+ startdate: tabActive.value === '待批改'? '' : getDateFormatDate(startEndDate.value[0]),
+ deaddate: tabActive.value === '待批改'? '' : getDateFormatDate(startEndDate.value[1]),// 待批改:明天,已批改:选择的日期
+ status: tabActive.value === '待批改'? '1' : '2', // 作业状态:1-已发布
orderby: 'deaddate DESC',
- pageSize: 100
+ pageSize: 100,
})
- /**
- * 2024-10-17 由于 后面截止时间加了 时分,特加判断
- * 1、进行中、以前是以明天判断。现改为传当天的日期,并根据当前日期的时分与截止日期进行判断,
- * 2、已结束、以前默认是以明天判断。现依然以明天为判断,并根据当前日期时分大于截止日期时分判断。
- */
- let list = [];
- if(tabActive.value === '进行中'){
- // 进行中 当前日期时间 小于 截止 日期时间
- list = response.rows&&response.rows.filter(item => item.deaddate && getCurrentTime('YYYY-MM-DD HH:mm') < item.deaddate); // 进行中
- }else{
- list = response.rows&&response.rows.filter(item => item.deaddate && getCurrentTime('YYYY-MM-DD HH:mm') > item.deaddate); // 已结束
- }
+ let list = response.rows || [];
- const curWorkList = list
-
- /**
- * warn: 这里仅更新了finishpercent(进度条), 且当前作业布置推送新任务时, curWorkList中会查到新的任务与当前页面中this.classWorkList长度不一致,
- * 故这里需循环this.classWorkList且只更新当前页面中的存在的任务进度
- */
- for (let t = 0; t < classWorkList.value.length; t++) {
- // 当前时间超过[作业任务]截止时间的跳过
- // if( getDateTime > classWorkList.value[t].deaddate ){
- // continue;
- // }
- // 确保当前拿到的任务与页面中存在的任务能一对一(避免因删除其他操作而删除作业任务导致两个数组的index不统一而越界)
- let curWork = curWorkList.find((work) => work.id === classWorkList.value[t].id)
- // workdataresultcount 完成人数 workdatacount人数要大于0
- if (curWork && curWork.workdataresultcount > 0 && classWorkList.value[t].workdatacount > 0) {
- classWorkList.value[t].workdataresultcount = curWork.workdataresultcount
- // 桌面端貌似不需要进度条了?
- classWorkList.value[t].finishpercent = parseInt(
- (classWorkList.value[t].workdataresultcount / classWorkList.value[t].workdatacount) * 100
- )
- // 计算参与学习任务的平均用时
- if (classWorkList.value[t].workdatafeedbackcount > 0) {
- classWorkList.value[t].averagetime = Math.ceil(classWorkList.value[t].feedtimelength / classWorkList.value[t].workdatafeedbackcount / 60).toFixed(0)
- } else {
- classWorkList.value[t].averagetime = 0
+ let newList = [];
+ for(let i = 0; i < classWorkList.value.length; i++){
+ // 父list的id与子list的id相等,在进行对比;若是不等? 有可能是老师批阅完了这个list数据,变成了已批改状态中,则父list数据需要删除
+ const isList = list.filter((item) => item.id === classWorkList.value[i].id);
+ if(isList.length === 0){
+ // 父list的id与子list的id不相等,则删除父list数据
+ classWorkList.value.splice(i,1);
+ }
+ for(let j = 0; j < list.length; j++){
+ // workdataresultcount 学生提交了的个数;
+ if(classWorkList.value[i].id === list[j].id && classWorkList.value[i].workdataresultcount != list[j].workdataresultcount){
+ // 学生提交数 != 学生提交数?
+ newList.push(list[j]);
}
- // 更新批阅数
- classWorkList.value[t].teacherrationgcount = curWork.teacherrationgcount
- } else {
- // 学生未完成,但是老师批改了?
- if(curWork && curWork.workdataresultcount == 0){
- // 更新批改数
- classWorkList.value[t].teacherrationgcount = curWork.teacherrationgcount
+ // teacherrationgcount 已批阅人数
+ if(classWorkList.value[i].id === list[j].id && classWorkList.value[i].teacherrationgcount != list[j].teacherrationgcount){
+ // 更新批阅进度条
+ if (classWorkList.value[i].workdataresultsum > 0) {
+ // 更新批阅数、 进度条
+ classWorkList.value[i].teacherrationgcount = list[j].teacherrationgcount;
+ classWorkList.value[i].teacherCorrectionProgress = parseInt(
+ ((list[j].teacherrationgcount) / list[j].workdataresultsum) * 100
+ )
+ } else {
+ classWorkList.value[i].teacherCorrectionProgress = 0
+ }
}
- classWorkList.value[t].finishpercent = 0
}
}
-
- return 1
+ if(newList.length>0){
+ // 更新学生提交后的数据? 作业进度条、平均用时、得分率
+ const list = newList&&newList.filter((item) => item.workdataresultcount > 0) ;
+ getStudentClassWorkData(list,false);
+ }
}
@@ -489,16 +422,27 @@ const getStudentVisible = async () => {
watch(
() => [dataList, toolState.isTaskWin],
() => {
- console.log('=监听到批改窗口打开了===', toolState.isTaskWin)
+ console.log('监听--批改窗口是否打开===', toolState.isTaskWin)
if(!toolState.isTaskWin){
-
- closeDialog();// 开启轮询
+ if(tabActive.value === '待批改'){
+ closeDialog();// 开启轮询
+ }
}
}
)
+
watch(tabActive, (newVal,oldVal)=>{
console.log('newVal',newVal);
getData() // 加载数据
+ if(newVal === '待批改'){
+ // 轮询查询
+ console.log('监听---开启轮询')
+ closeDialog();
+ }else{
+ // 关闭轮询
+ console.log('监听---关闭轮询')
+ clearInterval(pollingST.value);
+ }
})
diff --git a/src/renderer/src/views/classTask/container/classOverview.vue b/src/renderer/src/views/classTask/container/classOverview.vue
index fbe48ce..33c7726 100644
--- a/src/renderer/src/views/classTask/container/classOverview.vue
+++ b/src/renderer/src/views/classTask/container/classOverview.vue
@@ -72,15 +72,15 @@ const props = defineProps({
},
})
let studentList = ref([]) // 学生数据
-const stuHasAnswers = ref([]) // 已经答过题的学生不管对错
// 初始-数据处理
const initData = () => {
- console.log('xxx', props)
// window.test = activeCourse
studentList.value = props.activeData.studentList || []
const activeWorkFeedList = props.activeData.workFeedList || []
const quizlist = props.activeData.quizlist || []
+ console.log(quizlist,'quizlist');
+
// 习题特殊处理
let data = quizlist.map(o => {
// 解析题选项
@@ -90,7 +90,9 @@ const initData = () => {
let rightIds = [] // 正确学生
let hasAnswers= [] // 答过题的学生
let timeAnalyse = [] // 平均时长和编号
+ // let subjectCourese = [] // 题目编号
const quizFeedList = activeWorkFeedList.filter(f => f.entpcourseworkid == o.id) // 做该题的列表
+
let children = []
const allStudents = [];
if (o.worktype == '单选题') { // '单选题','多选题'
@@ -101,6 +103,11 @@ const initData = () => {
// 改选项的学生id
const studentIds = quizFeedList.filter(f => f.feedcontent==v&&f.finishtimelength!='0').map(f => f.studentid)||[];
accSum += studentIds.length;
+ // 该到题的用时时间
+ timeAnalyse = quizFeedList.reduce((acc, cur) => {
+ return acc + (cur.timelength ? Number(cur.timelength) : 0);
+ },0)
+
if (isOk) {
activeIds.push(...studentIds)
}
@@ -115,7 +122,7 @@ const initData = () => {
const res = isSame((f.feedcontent||'').split(','), workanswer);
return f.entpcourseworkid == o.id && f.finishtimelength!='0' && res;
});
-
+
const list = workdesc.includes('#&') ? workdesc.split('#&') : isJson(workdesc)?JSON.parse(workdesc):[];
children = list.map((v,i) => {
const isOne = o.worktype == '单选题'
@@ -128,6 +135,10 @@ const initData = () => {
if (studentIds.length>0) {
allStudents.push(...studentIds);
}
+ // 该到题的用时时间
+ timeAnalyse = quizFeedList.reduce((acc, cur) => {
+ return acc + (cur.timelength ? Number(cur.timelength) : 0);
+ },0)
if(isOk) {
activeIds=[...new Set(activeIds.concat(studentIds))] // 多选去重
}
@@ -136,8 +147,12 @@ const initData = () => {
})
}
else if (o.worktype == '填空题') { // 填空题
- const regex = /(.*?)/g // 定义正则表达式,匹配 xxx 格式的内容
- children = (o.title||'').match(regex).map((v,i) => {
+ let title = o.title.replace(/_{3,}/g, '_____'); //将3-10的下划线统一格式为5个
+ let regex = /(.*?)/g // 定义正则表达式,匹配 xxx 格式的内容
+ if (title.indexOf('_____') != -1) {
+ regex = /_{5}/g // 定义正则表达式,匹配 xxx 格式的内容
+ }
+ children = (title||'').match(regex).map((v,i) => {
const def = `填空项 ${i+1}`
//const code = '( )'
const code = '(略)', txt=v
@@ -146,6 +161,10 @@ const initData = () => {
activeIds=[...new Set(activeIds.concat(studentIds))] // 多选去重
hasAnswers=[...new Set(hasAnswers.concat(studentIds))]
accSum = activeIds.length
+ // 该到题的用时时间
+ timeAnalyse = quizFeedList.reduce((acc, cur) => {
+ return acc + (cur.timelength ? Number(cur.timelength) : 0);
+ },0)
return { def, code, txt, isOk:true, studentIds }
})
} else if (o.worktype == '判断题') { // 判断题
@@ -187,6 +206,10 @@ const initData = () => {
accSum += studentIds.length;
if(isOk) activeIds.push(...studentIds)
hasAnswers.push(...studentIds)
+ // 该到题的用时时间
+ timeAnalyse = quizFeedList.reduce((acc, cur) => {
+ return acc + (cur.timelength ? Number(cur.timelength) : 0);
+ },0)
return { def: v, code: v, isOk, studentIds }
})
} else { // 论述题
@@ -196,6 +219,10 @@ const initData = () => {
activeIds=[...new Set(activeIds.concat(studentIds))] // 多选去重
hasAnswers=[...new Set(hasAnswers.concat(studentIds))]
accSum = activeIds.length
+ // 该到题的用时时间
+ timeAnalyse = quizFeedList.reduce((acc, cur) => {
+ return acc + (cur.timelength ? Number(cur.timelength) : 0);
+ },0)
children = [{ def, code, isOk:true, studentIds }]
}
@@ -215,11 +242,10 @@ const initData = () => {
}
// def: 原始题数据 type 类型 active: 选中 points: 得分率, accSum 题解答人数
- return { def: o, id: o.id, type: o.worktype, active: [], points, accSum, rightSum, children,hasAnswers }
+ return { def: o, id: o.id, type: o.worktype, active: [], points, accSum, rightSum, children,hasAnswers,timeAnalyse,score:o.workScore }
})
- console.log('获取数据: ', data)
- stuHasAnswers.value = [...data[0].hasAnswers]
- provide('hasAnswer', stuHasAnswers.value)
+ if (data.length === 0) return
+ useOverview.getAllData([...data])
}
// 百分比现在 0-100
const percent = v => v > 1 ? 1 : v < 0 ? 0 : Math.round(v * 100)
@@ -232,6 +258,20 @@ const isJson = str => {if(typeof str == 'string'){
if(typeof res == 'object' && res) return true
} catch (error) {}}return false
}
+// 获取到学生的平均回答时间
+const groupByField = (array, field) => {
+ const groupedMap = {};
+ array.forEach(item => {
+ const key = item[field];
+ if (!groupedMap[key]) {
+ groupedMap[key] = [];
+ }
+ groupedMap[key].push(item);
+ });
+
+ // 将映射对象转换为二维数组
+ return Object.values(groupedMap);
+}
watch(() => props.tableList,() => {
useOverview.getTableList(props.tableList)
diff --git a/src/renderer/src/views/classTask/container/classOverview/distribution.vue b/src/renderer/src/views/classTask/container/classOverview/distribution.vue
index 5ff15c1..ab7a702 100644
--- a/src/renderer/src/views/classTask/container/classOverview/distribution.vue
+++ b/src/renderer/src/views/classTask/container/classOverview/distribution.vue
@@ -14,8 +14,8 @@
-
-
-
diff --git a/src/renderer/src/views/classTask/container/newTask/taskTypeView.vue b/src/renderer/src/views/classTask/container/newTask/taskTypeView.vue
index 431913f..de215d4 100644
--- a/src/renderer/src/views/classTask/container/newTask/taskTypeView.vue
+++ b/src/renderer/src/views/classTask/container/newTask/taskTypeView.vue
@@ -55,6 +55,7 @@
-
-
+
+
@@ -99,7 +105,7 @@
-
+
@@ -115,17 +121,54 @@
+
+
-
+ @change="getPaginationList" />
+
@@ -224,29 +267,37 @@
+
+
+
diff --git a/src/renderer/src/views/classTask/container/quizStats.vue b/src/renderer/src/views/classTask/container/quizStats.vue
index de5b73b..da72dcc 100644
--- a/src/renderer/src/views/classTask/container/quizStats.vue
+++ b/src/renderer/src/views/classTask/container/quizStats.vue
@@ -1,9 +1,9 @@
-
-
+
+
-
+
{{item.def?.titletext}}
@@ -54,13 +54,13 @@
-
+
-
提交情况
+
-
+
+
+ 试题详情
+
+
+
+
+
+ {{ activeExam.worktag }}
+
+
+
+
+
+
+
+
+ 【答案】
+
+ 【分析】
+
+ 【解答】
+
+ 【点评】
+
+
+
+
+
+
+
+
+
+
+
@@ -84,7 +118,9 @@ import { ref, defineExpose, onMounted, reactive, computed, watch, nextTick, watc
// import * as elementPlus from 'element-plus' // ElMessage ElMessageBox
let colorArr = [] // 进度颜色值 -- 静态数据
// const attrs = useAttrs() // props中未定义属性
-const activeTopic = ref(0) // 展开的题
+const activeTopic = ref(1) // 展开的题
+const activeExam = ref({}) // 展开的试题
+const activeExamFlag = ref(['1']) // 展开的试题
let dataList = ref([]) // 左侧数据
let studentList = ref([]) // 学生数据
const props = defineProps({ // 参数 defineProps
@@ -115,7 +151,10 @@ colorArr = [
// === 初始加载完 ===
onMounted(() => {
- activeTopic.value = dataList.value.map((_, index) => index + 1);
+ //activeTopic.value = dataList.value.map((_, index) => index + 1);
+ if (dataList.value[activeTopic.value-1].def != null && dataList.value[activeTopic.value-1].def != undefined) {
+ activeExam.value = dataList.value[activeTopic.value-1].def;
+ }
})
// === 方法(methods) ===
@@ -185,8 +224,13 @@ const initData = () => {
})
}
else if (o.worktype == '填空题') { // 填空题
- const regex = /(.*?)/g // 定义正则表达式,匹配 xxx 格式的内容
- children = (o.title||'').match(regex).map((v,i) => {
+ //console.log('填空题->', o.title);
+ let title = o.title.replace(/_{3,}/g, '_____'); //将3-10的下划线统一格式为5个
+ let regex = /(.*?)/g // 定义正则表达式,匹配 xxx 格式的内容
+ if (title.indexOf('_____') != -1) {
+ regex = /_{5}/g // 定义正则表达式,匹配 xxx 格式的内容
+ }
+ children = (title||'').match(regex).map((v,i) => {
const def = `填空项 ${i+1}`
//const code = '( )'
const code = '(略)', txt=v
@@ -285,6 +329,18 @@ const clickInfo = async ind => {
setTimeout(() => {scrollToElement('collapse-' + ind)}, 300);
// elementPlus.ElMessage.warning('功能未开放!')
}
+
+// 点击试题
+const clickItem = async (index) => {
+ if (index > dataList.length-1 ) {
+ return
+ }
+ if (dataList.value[index].def == null || dataList.value[index].def == undefined) {
+ return;
+ }
+ activeExam.value = dataList.value[index].def;
+}
+
// === 通用工具 ===
// 滚动到指定位置
const scrollToElement = id => {
@@ -313,8 +369,14 @@ watchEffect(() => { initData() })
background: #F2F3F5;
height: 100%;
margin: 0 !important;
- .left{padding-left: 0 !important; height: 100%;}
- .right{padding-right: 0 !important;}
+ .left{
+ padding-left: 0 !important;
+ height: 100%;
+ }
+ .right{
+ padding-right: 0 !important;
+ height: 100%;
+ }
.c-item{
padding: 10px;
background: #fff;
@@ -362,7 +424,7 @@ watchEffect(() => { initData() })
margin-bottom: 10px;
}
.respond{
- height: calc(100% - 65px);
+ /* height: calc(100% - 65px);*/
overflow: auto;
.el-space{padding: 5px;}
.card-warp{
@@ -376,6 +438,17 @@ watchEffect(() => { initData() })
flex-direction: column;
}
}
+
+ .item-card {
+ max-width: 100%;
+ margin-bottom: 10px;
+ text-align: left;
+ font-size: 18px;
+
+ :deep(.el-collapse-item__content){
+ font-size: 18px;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/renderer/src/views/classTask/teachClassTask.vue b/src/renderer/src/views/classTask/teachClassTask.vue
index 5f9e3e1..c84d588 100644
--- a/src/renderer/src/views/classTask/teachClassTask.vue
+++ b/src/renderer/src/views/classTask/teachClassTask.vue
@@ -57,8 +57,8 @@
style="margin-bottom: 1px"
@change="tableRadioChange"
>
-
-
+
+
{{ scope.row.updatedate }}
-
+
+
+ {{scope.row.getScore || 0}}
+
+
+
-
+
待批阅
- 完美
- 优秀
- 良好
- 及格
- 不及格
@@ -157,6 +162,8 @@ import ItemDialogScore from '@/views/classTask/container/classTask/item-dialog-s
import quizStats from '@/views/classTask/container/quizStats.vue'
import ClassOverview from '@/views/classTask/container/classOverview.vue'
import {sessionStore} from '@/utils/store'
+import Chat from '@/utils/chat' // im 登录初始化
+
const { proxy } = getCurrentInstance()
const emit = defineEmits(['cle-click'])
@@ -172,7 +179,7 @@ const classWorkAnalysis = reactive({
entpcourseworklistarray: [], // 当前学习任务所包含的试题ID
})
const tableRadio = reactive({
- value: '1', // 已交
+ value: 1, // 已交
list: [], // 已交list
num1: 0, // 已交人数
num0: 0 // 未交人数
@@ -203,35 +210,38 @@ const classWorkAnalysisScore = reactive({
// form.name = newValue.label
// }
// )
-const openDialog = (data) => {
+const openDialog = (data, isInit=true) => {
console.log(data, '点击的item完成情况')
+
+ if (isInit) {
+ classWorkAnalysis.title = data.uniquekey ? data.uniquekey + '--' : ''
+ classWorkAnalysis.worktype = data.worktype
+ classWorkAnalysis.workclass = data.workclass
+ // 重置学生列表
+ tableRadio.list = []
+ tableRadio.value = 1
+ tableRadio.num0 = 0
+ tableRadio.num1 = 0
- classWorkAnalysis.title = data.uniquekey ? data.uniquekey + '--' : ''
- classWorkAnalysis.worktype = data.worktype
- classWorkAnalysis.workclass = data.workclass
- // 重置学生列表
- tableRadio.list = []
- tableRadio.value = '1'
- tableRadio.num0 = 0
- tableRadio.num1 = 0
+ classWorkAnalysis.open = true
+ // 默认显示是学生作业反馈
+ classWorkAnalysis.view = 'studentview'
+ // 当前学习任务所包含的试题ID
+ classWorkAnalysis.entpcourseworklistarray = data.entpcourseworklistarray
+ // 默认选中的学生
+ classWorkAnalysis.activeStudentQuizlist = []
+ // 默认选中的试题
+ classWorkAnalysis.activeQuizAnalysisData = []
- classWorkAnalysis.open = true
- // 默认显示是学生作业反馈
- classWorkAnalysis.view = 'studentview'
- // 当前学习任务所包含的试题ID
- classWorkAnalysis.entpcourseworklistarray = data.entpcourseworklistarray
- // 默认选中的学生
- classWorkAnalysis.activeStudentQuizlist = []
- // 默认选中的试题
- classWorkAnalysis.activeQuizAnalysisData = []
-
- classWorkAnalysis.row = data
- window.test = this
- // zdg: 学生列表
- const studentArr = data.classworkdatastudentids
- ? JSON.parse(`[${data.classworkdatastudentids}]`)
- : []
- classWorkActiveData.studentList = studentArr
+ classWorkAnalysis.row = data
+ window.test = this
+ // zdg: 学生列表
+ const studentArr = data.classworkdatastudentids
+ ? JSON.parse(`[${data.classworkdatastudentids}]`)
+ : []
+ classWorkActiveData.studentList = studentArr
+ }
+
/** 学生完成情况分析--获取作业学生list数据 */
getClassWorkStudentList(data.id)
@@ -248,6 +258,7 @@ const openDialog = (data) => {
}
classWorkAnalysis.quizlist = idres.rows
classWorkActiveData.quizlist = idres.rows // zdg: 作业概览组件使用
+ processList(classWorkActiveData.quizlist);
// 统计每个题目的正误率
// 这个学习任务所有题目+所有学生的答题数据 , pageSize: 100
@@ -334,7 +345,7 @@ const getClassWorkStudentList = (rowId) => {
}
// 老师批阅状态 默认0 未批改
- response.rows[i].teacherRating = 0
+ response.rows[i].rating = 0
// 计算每个学生的得分率
if (
@@ -343,35 +354,44 @@ const getClassWorkStudentList = (rowId) => {
response.rows[i].classworkevallist != 'null'
) {
// 将标签中双引号改为转义, 测试数据: "{\"id\":172910, \"feedcontent\":\"毛泽东,浮想联翩。\", \"score\":4, \"rightanswer\":\"毛泽东重,浮想联翩。\"},{\"id\":172911, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":363100, \"feedcontent\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,浮想联翩。\", \"score\":4, \"rightanswer\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,浮想联翩。\"}"
- // 常规作业(去除【】前后引号).replace(/"(\[.*\])"/g, '$1'); :eg: "feedcontent\":\"[{\"name\":\"Bliss.jpg\",\"url\":\"https://wzyzoss.3b8daa474.jpg\"}]\",
+ // 主题作业(去除【】前后引号).replace(/"(\[.*\])"/g, '$1'); :eg: "feedcontent\":\"[{\"name\":\"Bliss.jpg\",\"url\":\"https://wzyzoss.3b8daa474.jpg\"}]\",
// json转换会报错; .replace(/""/g, '"') eg: ""宇宙环境安全""
response.rows[i].classworkevallist = escapeHtmlQuotes(response.rows[i].classworkevallist)
//console.log('学生完成情况分析classworkevallist', response.rows[i].classworkevallist)
const evalarray = JSON.parse('[' + response.rows[i].classworkevallist + ']')
var scoingCount = 0
var feedcount = 0
+ let score = 0
for (var e = 0; e < evalarray.length; e++) {
if (evalarray[e].feedcontent != '') {
feedcount++
// 与答案对比正误。注意注意,这里仅限单选题
if (evalarray[e].feedcontent == evalarray[e].rightanswer) {
scoingCount++
+ score += evalarray[e].score;
+ evalarray[e].teacherRating = evalarray[e].score
}
+
}
}
+
+ const allTeacherRating = evalarray.reduce((acc, cur) => acc + cur.teacherRating, 0) // 老师评分
//console.log(evalarray, 'evalarray------------------------------------')
if (feedcount > 0) {
// 多个题目的总得分率: 正确题数/(题目数*100)
- response.rows[i].scoingRate = ((scoingCount / feedcount) * 100).toFixed(0) + '%'
+ response.rows[i].scoingRate = ((score / allTeacherRating) * 100).toFixed(0) + '%'
+ response.rows[i].getScore = allTeacherRating
} else {
response.rows[i].scoingRate = '0%'
+ response.rows[i].getScore = 0
}
// 批阅状态 优良类 :注意:这里题目中的评价都是一样的,所以取第一个
if (evalarray[0].rating != '') {
- response.rows[i].teacherRating = evalarray[0].rating
+ response.rows[i].rating = evalarray[0].rating
}
} else {
response.rows[i].scoingRate = '0%'
+ response.rows[i].getScore = 0
}
}
classWorkAnalysis.classworkdata = response.rows
@@ -381,14 +401,61 @@ const getClassWorkStudentList = (rowId) => {
tableRadio.list =
classWorkAnalysis.classworkdata &&
classWorkAnalysis.classworkdata.filter((item) => item.finishtimelength != '0')
- tableRadio.value = '1'
+ tableRadio.value = 1
tableRadio.num0 = classWorkAnalysis.classworkdata.length - tableRadio.list.length
tableRadio.num1 = tableRadio.list.length
+ // 自动批阅判断
+ teacherCriticism();
})
.catch(() => {
loading_dt_table.value = false
})
}
+/**
+ * 自动批阅判断:
+ * 已交 并 作业类型为习题训练
+ */
+const teacherCriticism = ()=>{
+ // 已交的list才自动批阅判断
+ if(tableRadio.value == 1 && classWorkAnalysis.worktype == '习题训练'){
+ // 只有习题训练才会自动批阅
+ tableRadio.list = tableRadio.list.map((item) => {
+ return {
+ ...item,
+ rating : item.rating || checkWorkType(item)
+ }
+ })
+ }
+}
+const checkWorkType = (item) => {
+ //这里判断题目类型
+ const subType = classWorkActiveData.quizlist.map(item => item.worktype)
+ const objectiveQuestion = ['单选题','多选题','判断题']
+ let rating = 0
+ //判断题目是不是客观题
+ if(subType.every(item => objectiveQuestion.includes(item))){
+ // 获取学生答题列表 scoingRate 得分率
+ const score = extractedNumber(item.scoingRate)
+ if(0<=score && score<=59){
+ rating = 5
+ }else if(60<=score && score<=69){
+ rating = 4
+ }else if(70<=score && score<=79){
+ rating = 3
+ }else if(80<=score && score<=99){
+ rating = 2
+ }else{
+ rating = 1
+ }
+ }
+ return rating
+
+}
+// 获取百分比的数字
+const extractedNumber = (score) => {
+ const match = score.match(/\d+/);
+ return match ? parseInt(match[0], 10) : null;
+}
/** 2、查看某一个学生的学习任务完成详情*/
const getStudentClassWorkDataDetail = (row) => {
// 这里取出的是学生完成情况
@@ -505,14 +572,16 @@ const tableRadioChange = (e) => {
isopen_dtwk_table.value = false;
console.log(e,'??????')
console.log("学生列表:", classWorkAnalysis.classworkdata)
- if(e=='1'){
+ if(e==1){
tableRadio.list = classWorkAnalysis.classworkdata.filter(item => item.finishtimelength != '0')
- tableRadio.value = '1';
+ tableRadio.value = 1;
tableRadio.num0 = classWorkAnalysis.classworkdata.length - tableRadio.list.length;
tableRadio.num1 = tableRadio.list.length;
- }else if(e=='0'){
+ // 自动批阅判断
+ teacherCriticism();
+ }else if(e==0){
tableRadio.list = classWorkAnalysis.classworkdata.filter(item => item.finishtimelength == '0')
- tableRadio.value = '0';
+ tableRadio.value = 0;
tableRadio.num0 = tableRadio.list.length;
tableRadio.num1 = classWorkAnalysis.classworkdata.length - tableRadio.list.length;
}
@@ -570,6 +639,10 @@ const getWorkFeedList = async() =>{
function: 训练报告的处理
*/
const handleClassOverviewOpen = (type) =>{
+ // 每次进来都重新调用一次
+ if(type == 'report') {
+ getWorkFeedList();
+ }
// 关闭右侧批阅ui
isopen_dtwk_table.value = false;
classWorkAnalysis.view = type
@@ -580,6 +653,7 @@ const handleClassOverviewOpen = (type) =>{
response.rows.forEach(item => {
let rightAnswer = 0
let answers = 0
+ let score = 0
if(!item.classworkevallist) return
// 使用正则表达式替换字符串值中的双引号为单引号
let replacedString = item.classworkevallist.replace(/""/g, "\"");
@@ -598,12 +672,18 @@ const handleClassOverviewOpen = (type) =>{
//正确答案,仅限单选题
if(itemTopic.feedcontent === itemTopic.rightanswer){
rightAnswer ++
+ score += itemTopic.score
+ itemTopic.teacherRating = itemTopic.score
}
}
})
- rightAnswer > 0?item.scoingRate = (rightAnswer/answers * 100).toFixed(0):item.scoingRate = ''
+ const allTeacherRating = allTopic.reduce((acc, cur) => acc + cur.teacherRating, 0)
+
+ rightAnswer > 0?item.scoingRate = (score/allTeacherRating * 100).toFixed(0):item.scoingRate = ''
+ item.getScore = allTeacherRating
}else{
item.scoingRate = ''
+ item.getScore = 0
}
//获得总分
const point = allTopic.reduce((acc, cur) => {
@@ -632,16 +712,62 @@ const closeDialog = () => {
emit('cle-click')
}
-onMounted(() => {
+// im监听消息回调
+const msgHandle = (msg) => {
+ const { type, data } = msg
+ switch(type) {
+ case 'TIMAddRecvNewMsgCallback': // 收到新消息 data=[]
+ {
+ (data||[]).forEach(o => {
+ const msgArr = o?.message_elem_array||[]
+ msgArr.forEach(info => {
+ const msgType = info?.elem_type // 消息类型 TIMElemType
+ const msgData = !!info.text_elem_content ? JSON.parse(info.text_elem_content)||'' : ''
+ // 处理学生端反馈得消息
+ //console.log('msgData->', msgData);
+ if (msgData.msgKey == "finishHomework"){
+ // 刷新
+ const data = JSON.parse(localStorage.getItem('teachClassWorkItem'));
+ //console.log('data->', data);
+ openDialog(data, false);
+ }
+ })
+ })
+ }
+ break
+ }
+}
+const reloadTimer = ref(0); // 开启定时查询,作业id是否刷新了,刷新了就重新获取
+const cutid = ref(0); // 当前初始化的作业id
+onMounted(() => {
const data = JSON.parse(localStorage.getItem('teachClassWorkItem'));
// const data = sessionStore.get('teachClassWorkItem');
- // const data = localStorage.getItem('teachClassWorkItem');
- console.log(data,'????????????????????' )
if(data){
openDialog(data)
}
+ // 开始定时查询
+ cutid.value = data.id;
+ isReloadTimer();
+
+ // im监听消息
+ if (!Chat.imChat) {
+ Chat.init(true, true, msgHandle);
+ } else {
+ Chat.listenMsg(msgHandle);
+ }
})
+const isReloadTimer = () =>{
+ clearInterval(reloadTimer.value) // 关闭定时器
+ // 开启定时查询,作业id是否刷新了,刷新了就重新获取
+ reloadTimer.value = setInterval(() => {
+ const data = JSON.parse(localStorage.getItem('teachClassWorkItem'));
+ if(cutid.value != data.id){
+ cutid.value = data.id;
+ openDialog(data)
+ }
+ }, 1000)
+}
watch(classWorkAnalysis, (newVal, oldVal) => {
if(newVal.view != 'quizStats'){
@@ -652,6 +778,7 @@ watch(classWorkAnalysis, (newVal, oldVal) => {
onUnmounted(() => {
clearInterval(classWorkActiveData.timerId) // 关闭定时器 逐题讲评的
+ clearInterval(reloadTimer.value) // 关闭定时器 查询作业id是否刷新了
})
// defineExpose({
@@ -697,7 +824,7 @@ onUnmounted(() => {
overflow: hidden;
.classwork-score{
- // overflow-y: auto;
+ /* overflow-y: auto; */
height: 100%;
}
}
diff --git a/src/renderer/src/views/desktop/container/work-trend.vue b/src/renderer/src/views/desktop/container/work-trend.vue
index d723e5a..38391f5 100644
--- a/src/renderer/src/views/desktop/container/work-trend.vue
+++ b/src/renderer/src/views/desktop/container/work-trend.vue
@@ -14,14 +14,15 @@
{{ item.uniquekey }}
- {{
- getCurrentTime('YYYY-MM-DD HH:mm') > item.deaddate ? '已结束' : '进行中' }}
- {{ item.worktype }}
+
+ 待批改
+ {{ item.worktype }}
{{ item.classcaption }} | 截止时间:{{ item.deaddate }}
-
{{ item.workdataresultcount }} / {{ item.workdatacount }}
+
{{ item.workdataresultcount }} / {{ item.workdataresultsum }}
已交
@@ -52,9 +53,10 @@ const getHomework = async () => {
const { edustage, edusubject } = user
try {
const { rows } = await homeworklist({ edituserid: user.userId, edustage, edusubject, deaddate: getTomorrow(), status: '1', orderby: 'deaddate DESC', pageSize: 500 })
- // 只展示进行中的
- homeworkList.value = rows.filter(item => item.deaddate && item.uniquekey && getCurrentTime('YYYY-MM-DD HH:mm') < item.deaddate) // 当前日期的时分与截止日期进行判断
- // homeworkList.value = rows.filter(item => item.deaddate && item.uniquekey && getTomorrow() <= item.deaddate) //大于今天的才算进行中 弃用
+ // 只展示待批改的
+ //homeworkList.value = rows.filter(item => item.deaddate && item.uniquekey && getCurrentTime('YYYY-MM-DD HH:mm') < item.deaddate) // 当前日期的时分与截止日期进行判断
+ // homeworkList.value = rows.filter(item => item.deaddate && item.uniquekey && getTomorrow() <= item.deaddate) //大于今天的才算待批改 弃用
+ homeworkList.value = rows || [];
homeworkList.value.forEach((item) => {
// 处理任务类型的UI
if (item.worktype == '学习目标定位') {
@@ -72,7 +74,6 @@ const getHomework = async () => {
item.workclass = ''
}
- item.workdatacount = JSON.parse('[' + item.classworkdatastudentids + ']').length
// 如果是习题训练任务,则检查一共有多少道
if (item.entpcourseworklist != '') {
item.entpcourseworklistarray = JSON.parse(
@@ -102,7 +103,8 @@ const onClickItem = (item) => {
}
const tagType = (time) => {
- return getCurrentTime('YYYY-MM-DD HH:mm') > time ? 'info' : 'warning'
+ return 'warning';
+ //return getCurrentTime('YYYY-MM-DD HH:mm') > time ? 'info' : 'warning'
}
diff --git a/src/renderer/src/views/examReport/container/examReview.vue b/src/renderer/src/views/examReport/container/examReview.vue
index 181acbe..6503399 100644
--- a/src/renderer/src/views/examReport/container/examReview.vue
+++ b/src/renderer/src/views/examReport/container/examReview.vue
@@ -17,10 +17,12 @@
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/renderer/src/views/experiment/components/videoLog.vue b/src/renderer/src/views/experiment/components/videoLog.vue
new file mode 100644
index 0000000..3842f41
--- /dev/null
+++ b/src/renderer/src/views/experiment/components/videoLog.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/renderer/src/views/experiment/index.vue b/src/renderer/src/views/experiment/index.vue
new file mode 100644
index 0000000..ab5ac04
--- /dev/null
+++ b/src/renderer/src/views/experiment/index.vue
@@ -0,0 +1,259 @@
+
+
+
+
+
+
+
+
+
+
+ {{ item.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.fileShowName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/renderer/src/views/fullScreenPdf/index.vue b/src/renderer/src/views/fullScreenPdf/index.vue
index cb404c8..2f85aa9 100644
--- a/src/renderer/src/views/fullScreenPdf/index.vue
+++ b/src/renderer/src/views/fullScreenPdf/index.vue
@@ -18,7 +18,10 @@ const loadPdfAnimation = (path) => {
},2000)
}
onMounted(() => {
- const bookpath = localStorage.getItem('PDF-LOCAL-PATH')
+ const pdfUrl1 = localStorage.getItem('PDF-TOOL-PATH')
+ const pdfUrl2 = localStorage.getItem('PDF-LOCAL-PATH')
+ console.log('tool-pdf 地址: ',pdfUrl1, pdfUrl2)
+ const bookpath = pdfUrl1 || pdfUrl2
// const filepath = import.meta.env.VITE_APP_RES_FILE_PATH + bookpath
// const isDev = process.env.NODE_ENV == 'development'
// if (isDev)
@@ -28,7 +31,7 @@ onMounted(() => {
// const newpath = getStaticUrl(bookpath, 'user', 'selfFile', true)
loadPdfAnimation(bookpath)
// pdfUrl.value = filepath
- // console.log('课件路径',newpath);
+ // console.log('课件路径',bookpath);
})
diff --git a/src/renderer/src/views/login/index.vue b/src/renderer/src/views/login/index.vue
index b883d6d..7a346e8 100644
--- a/src/renderer/src/views/login/index.vue
+++ b/src/renderer/src/views/login/index.vue
@@ -1,264 +1,13 @@
-
-
-
-
-
-
-
-
账号登录
-
-
-
-
-
-
-
-
- 记住密码
-
-
-
-
- 登录
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/src/renderer/src/views/login/yc-login.vue b/src/renderer/src/views/login/yc-login.vue
new file mode 100644
index 0000000..5350d7e
--- /dev/null
+++ b/src/renderer/src/views/login/yc-login.vue
@@ -0,0 +1,279 @@
+
+
+
+
+
+
+
+
+
永川中小学
+
人工智能赋能科学素养与劳动技能系统
+
+
+
+
+
+
+
+
+ 记住密码
+
+
+
+
+ 登录
+
+
+
+ 重庆市永川区教育委员会
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/renderer/src/views/prepare/components/chooseTextbook.vue b/src/renderer/src/views/prepare/components/chooseTextbook.vue
new file mode 100644
index 0000000..144720f
--- /dev/null
+++ b/src/renderer/src/views/prepare/components/chooseTextbook.vue
@@ -0,0 +1,308 @@
+
+
+
+
+ {{ curBook.data.itemtitle }}
+
+
+
+
+
+ {{ node.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ item.itemtitle }}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/renderer/src/views/prepare/components/treeLog.vue b/src/renderer/src/views/prepare/components/treeLog.vue
new file mode 100644
index 0000000..90b2fa7
--- /dev/null
+++ b/src/renderer/src/views/prepare/components/treeLog.vue
@@ -0,0 +1,64 @@
+
+
+
+
+
diff --git a/src/renderer/src/views/prepare/container/ai-ppt.vue b/src/renderer/src/views/prepare/container/ai-ppt.vue
index cefe091..f8cdc12 100644
--- a/src/renderer/src/views/prepare/container/ai-ppt.vue
+++ b/src/renderer/src/views/prepare/container/ai-ppt.vue
@@ -620,7 +620,7 @@ const changeCursor = (cursorStyle) => {
};
onMounted(() => {
- // let url = "https://bjcdn.openstorage.cn/xinghuo-privatedata/%2Ftmp/apiTempFiledf28bf990a4c40ffb7477ed4b65392c27232357022409613439/%E3%80%8A%E9%9D%99%E5%A5%B3%E3%80%8B%E6%B7%B1%E5%BA%A6%E8%A7%A3%E8%AF%BB%E4%B8%8E%E7%A0%94%E7%A9%B6.pptx"
+ // let url = "https://bjcdn.openstorage.cn/xinghuo-privatedata/%2Ftmp/apiTempFileba724e0344f74e1480535eedf3ebec661601807661085006275/%E9%87%91%E9%A9%AC%E5%A5%96%E5%B0%B4%E5%B0%AC%E4%BA%8B%E4%BB%B6%E5%88%86%E6%9E%90%E4%B8%8E%E5%BA%94%E5%AF%B9%E7%AD%96%E7%95%A5.pptx"
// creatAIPPT(props.currentNode.itemtitle + '.pptx',url, props.uploadData).then((res) => {
// emit('addSuccess',res)
// })
diff --git a/src/renderer/src/views/prepare/container/class-start.vue b/src/renderer/src/views/prepare/container/class-start.vue
index ec0d01d..7913a5c 100644
--- a/src/renderer/src/views/prepare/container/class-start.vue
+++ b/src/renderer/src/views/prepare/container/class-start.vue
@@ -226,7 +226,7 @@ const getClasscourseList = async type => {
const {classid} = classForm.form
const {entpcourseid} = myClassActive.value
if (!classid || !entpcourseid) return
- const params = {classid, entpcourseid, entpcoursefileid: 0}
+ const params = {classid, entpcourseid, entpcoursefileid: 0, pageSize: 1000}
const res = await Http_Classcourse.listClasscourse(params)
if (res.code == 200) {
// zdg: 排序id大的在前(最新的)
@@ -255,9 +255,9 @@ const createClasscourse = async () => {
entpcourseid, evalid, coursetitle,
plandate: curDate, opendate: curDate
}
- await Http_Classcourse.addClasscourseReturnId(params)
+ teacherForm.form.classcourseid = await Http_Classcourse.addClasscourseReturnId(params)
dt.loading = false
- getClasscourseList('update') // 更新列表
+ // getClasscourseList('update') // 更新列表
ElMessage.success('创建课程-成功')
}
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 eeb77d0..c2e3e90 100644
--- a/src/renderer/src/views/prepare/container/file-list-item.vue
+++ b/src/renderer/src/views/prepare/container/file-list-item.vue
@@ -126,6 +126,12 @@
下载
+
+
+
+ 加入课件
+
+
@@ -153,7 +159,7 @@ import FileImage from '@/components/file-image/index.vue'
import { asyncLocalFile } from '@/utils/talkFile'
import { toTimeText } from '@/utils/date'
import { ElMessage, ElMessageBox } from 'element-plus'
-import { deleteSmarttalk, updateSmarttalk, getPrepareById } from '@/api/file'
+import { deleteSmarttalk, updateSmarttalk, getPrepareById, addFileToKj } from '@/api/file'
import useUserStore from '@/store/modules/user'
import outLink from '@/utils/linkConfig'
@@ -183,6 +189,14 @@ export default {
}
},
methods: {
+ adToKj(item) {
+ addFileToKj(item.id).then(res=>{
+ console.log(res)
+ item.fileFlag = "课件"
+ },error=>{
+ console.log(error)
+ })
+ },
editTalk(item) {
console.log(item,this.userInfo,'this.userInfo')
ElMessageBox.prompt('请输入新的名称', '重命名', {
@@ -266,14 +280,14 @@ export default {
cookie,
fileType: item.fileType
})
- ipcRenderer.on('listen-file-change-on' + item.fileNewName, () => {
+ /*ipcRenderer.on('listen-file-change-on' + item.fileNewName, () => {
items.async = 'on'
})
ipcRenderer.on('listen-file-change-success' + item.fileNewName, (e, { data, md5 }) => {
items.fileSize = data.fileSize
items.md5 = md5
items.async = true
- })
+ })*/
}
})
})
diff --git a/src/renderer/src/views/prepare/container/kj-list-item.vue b/src/renderer/src/views/prepare/container/kj-list-item.vue
index 7a9a56a..8936e22 100644
--- a/src/renderer/src/views/prepare/container/kj-list-item.vue
+++ b/src/renderer/src/views/prepare/container/kj-list-item.vue
@@ -357,14 +357,14 @@ export default {
cookie,
fileType: item.fileType
})
- ipcRenderer.on('listen-file-change-on' + item.fileNewName, () => {
+ /*ipcRenderer.on('listen-file-change-on' + item.fileNewName, () => {
items.async = 'on'
})
ipcRenderer.on('listen-file-change-success' + item.fileNewName, (e, { data, md5 }) => {
items.fileSize = data.fileSize
items.md5 = md5
items.async = true
- })
+ })*/
}
})
})
diff --git a/src/renderer/src/views/prepare/index.vue b/src/renderer/src/views/prepare/index.vue
index 5285014..f73f8a5 100644
--- a/src/renderer/src/views/prepare/index.vue
+++ b/src/renderer/src/views/prepare/index.vue
@@ -178,6 +178,7 @@ import ClassReserv from '@/views/classManage/classReserv.vue'
import classStart from './container/class-start.vue' // 预备上课
import MsgEnum from '@/plugins/imChat/msgEnum' // im 消息枚举
import Chat from '@/utils/chat' // im 登录初始化
+import TreeLog from './components/treeLog.vue'
if (!Chat.imChat) Chat.init()
const toolStore = useToolState()
@@ -235,7 +236,9 @@ export default {
isOpenHomework: false,
// 当前上课课程
activeClass: null,
- pptDialog: false
+ pptDialog: false,
+ // 打开章节的弹窗
+ treelogRef:null
}
},
computed: {
@@ -534,7 +537,7 @@ export default {
}
},
clickChoose(value) {
- this.checkFileList = value ? this.currentFileList : []
+ this.checkFileList = value ? this.currentSCFileList : []
},
deleteTalk(item) {
let index = this.currentFileList.indexOf(item)
@@ -630,12 +633,18 @@ export default {
})
},
async nodeClick(data) {
+ console.log(data,'data');
+
if (this.currentNode.id === data.node.id) return
this.curBookImg = data.textBook.curBookImg
this.curBookPath = data.textBook.curBookPath
const path = await this.getBookPathFromServer(data.textBook.curBookPath)
const localpath = getAppInstallUrl('pdfjs-dist/web/viewer.html', 'user', '\\out\\renderer', true) + "?file="
localStorage.setItem('PDF-LOCAL-PATH',localpath + encodeURIComponent(import.meta.env.VITE_APP_RES_FILE_PATH + path))
+ // 相关数据存储session中
+ sessionStore.set('curr.textBook', data.textBook)
+ sessionStore.set('env.pdfBasePath', localpath)
+ sessionStore.set('env.fileBasePath', import.meta.env.VITE_APP_RES_FILE_PATH)
this.checkFileList = []
this.currentWorkList = []
let cata = parseCataByNode(data.node)
diff --git a/src/renderer/src/views/resource/container/resoure-list.vue b/src/renderer/src/views/resource/container/resoure-list.vue
index 517d97f..5d08082 100644
--- a/src/renderer/src/views/resource/container/resoure-list.vue
+++ b/src/renderer/src/views/resource/container/resoure-list.vue
@@ -161,7 +161,11 @@ const delRow = (item) => {
}
// 加入备课
-const addLesson = ({ id }) => {
+const addLesson = ({ id, fileSize }) => {
+ if (fileSize>1024*1024*150) {
+ ElMessage.warning('文件超过150M,暂停超过150M资源的下载,请重新选择')
+ return
+ }
let data = {
id,
fileRoot: '备课',
@@ -190,6 +194,8 @@ const handleRow = (item) => {
})
curRow.value = item
isShow.value = true
+ console.log(item,'item');
+
}
diff --git a/src/renderer/src/views/resource/container/resoure-search.vue b/src/renderer/src/views/resource/container/resoure-search.vue
index 9d3344e..d0f8d61 100644
--- a/src/renderer/src/views/resource/container/resoure-search.vue
+++ b/src/renderer/src/views/resource/container/resoure-search.vue
@@ -18,21 +18,17 @@
-
-
-
+
+
+
+
+
+
diff --git a/src/renderer/src/views/resource/container/third-list.vue b/src/renderer/src/views/resource/container/third-list.vue
index 7021b61..085e2ac 100644
--- a/src/renderer/src/views/resource/container/third-list.vue
+++ b/src/renderer/src/views/resource/container/third-list.vue
@@ -7,12 +7,11 @@
v-for="item in sourceStore.thirdResult.list"
:key="item.itemId"
class="list-item"
- @click="handleRow"
+ @click="handleRow(item)"
>
-
+
+
+ 备课
@@ -66,35 +69,28 @@
@current-change="handleCurrentChange"
/>
-
-
-
-
-
-
-
-
+
+
diff --git a/src/renderer/src/views/tool/components/upvote.vue b/src/renderer/src/views/tool/components/upvote.vue
index 91c1fcc..4b8eb9e 100644
--- a/src/renderer/src/views/tool/components/upvote.vue
+++ b/src/renderer/src/views/tool/components/upvote.vue
@@ -1,6 +1,6 @@
- 点赞
+ 点赞
疑惑
@@ -257,12 +257,12 @@ defineExpose({ trigger })
border-radius: 3px;
min-width: 15px;
// height: 500px;
- &.like{
- background-image: linear-gradient(to top, #fef0f0, #f56c6c);
+ &.like{ // 点赞
+ background-image: linear-gradient(to top, #d2f0cb, #2f9e44);
// animation: striped-flow 5s linear infinite;
}
- &.doubt{
- background-image: linear-gradient(to top, #fdf6ec, #e6a23c);
+ &.doubt{ // 疑惑
+ background-image: linear-gradient(to top, #ebc6c6, #ff0000);
}
}
}
diff --git a/src/renderer/src/views/tool/createHomework.js b/src/renderer/src/views/tool/createHomework.js
index be3006f..bb633d8 100644
--- a/src/renderer/src/views/tool/createHomework.js
+++ b/src/renderer/src/views/tool/createHomework.js
@@ -1,37 +1,225 @@
+
import useUserStore from '@/store/modules/user'
import { addClassworkReturnId } from '@/api/teaching/classwork'
+import { listClassworkdata } from '@/api/classTask'
+import { homeworklist } from '@/api/teaching/classwork'
-export const createHomework = ({ uniquekey, evalid, data, entpcourseid }) =>{
- const usertore = useUserStore().user
- var formObj = {};
- formObj.id = 0;
- formObj.deaddate = '';
- formObj.entpid = usertore.deptId;
- formObj.level = 1;
- formObj.parentid = 0;
- formObj.worktype = '常规作业';
- formObj.workkey = '';
- formObj.worktag = '';
+export const createHomework = ({ uniquekey, evalid, data, entpcourseid }) => {
+ const usertore = useUserStore().user
- formObj.uniquekey = uniquekey;
-
- formObj.classid = 0;
- formObj.classcourseid = 0;
+ var formObj = {}
+ formObj.id = 0
- formObj.entpcourseid = entpcourseid;
+ formObj.deaddate = ''
+ formObj.entpid = usertore.deptId
+ formObj.level = 1
+ formObj.parentid = 0
+ formObj.worktype = '常规作业'
+ formObj.workkey = ''
+ formObj.worktag = ''
- formObj.slideid = 0;
+ formObj.uniquekey = uniquekey
- formObj.workcodes = JSON.stringify(data);
+ formObj.classid = 0
+ formObj.classcourseid = 0
- formObj.edusubject = usertore.edusubject;
- formObj.evalid = evalid
+ formObj.entpcourseid = entpcourseid
- formObj.edustage = usertore.edustage;
- formObj.status = '';
- formObj.edituserid = usertore.userId;
- formObj.entpcourseworklist = JSON.stringify([{'id':-2, 'score': '10'}]);
- return addClassworkReturnId(formObj)
+ formObj.slideid = 0
+
+ formObj.workcodes = JSON.stringify(data)
+
+ formObj.edusubject = usertore.edusubject
+ formObj.evalid = evalid
+
+ formObj.edustage = usertore.edustage
+ formObj.status = ''
+ formObj.edituserid = usertore.userId
+ formObj.entpcourseworklist = JSON.stringify([{ id: -2, score: '10' }])
+ return addClassworkReturnId(formObj)
+}
+
+let classWorkList = []
+
+// 将标签中的双引号增加转义
+let escapeHtmlQuotes = (str) => {
+ // 后端已replace双引号, 故前端不用在处理
+ const regex1 = /\\+/g; // 匹配多个反斜杠
+ let result = str.replace(regex1, '\\');
+ result = str.replace(/(?'); //替换\n而不替换\\n 为 \\n
+ return result;
+}
+
+/**
+ * 获取班级作业
+ */
+export const getClassWorkList = async (id) => {
+ // 班级作业数据,包含多个班级 homeworklist
+ const response = await homeworklist({ id })
+
+ /**
+ * 2024-10-17 由于 后面截止时间加了 时分,特加判断
+ * 1、待批改、以前是以明天判断。现改为传当天的日期,并根据当前日期的时分与截止日期进行判断,
+ * 2、已批改、以前默认是以明天判断。现依然以明天为判断,并根据当前日期时分大于截止日期时分判断。
+ */
+
+ let list = response.rows
+
+ for (var i = 0; i < list.length; i++) {
+ // 初始化部分新增字段值
+ list[i].workdatalist = []
+ list[i].workdatalistVisible = false
+ list[i].workdatafeedbackcount = 0 // 已交人数
+ list[i].feedtimelength = 0
+ list[i].rightAnswerCount = 0
+ list[i].scoingRate = 0 + '%' // 得分率
+ list[i].averagetime = 0 // 平均用时
+
+ // ----------------------------------------------
+ // 处理任务类型的UI
+ if (list[i].worktype == '学习目标定位') {
+ list[i].workclass = 'success'
+ list[i].workcodesList = JSON.parse(list[i].workcodes)
+ } else if (list[i].worktype == '教材研读') {
+ list[i].workclass = 'primary'
+ } else if (list[i].worktype == '框架梳理') {
+ list[i].workclass = 'warning'
+ } else if (list[i].worktype == '学科定位') {
+ list[i].workclass = 'info'
+ } else if (list[i].worktype == '习题训练') {
+ list[i].workclass = 'danger'
+ } else {
+ list[i].workclass = ''
+ }
+ // 如果是习题训练任务,则检查一共有多少道
+ if (list[i].entpcourseworklist != '') {
+ list[i].entpcourseworklistarray = JSON.parse('[' + list[i].entpcourseworklist + ']')
+ } else {
+ list[i].entpcourseworklistarray = []
+ }
+ }
+ // 显示分配人数(workdataresultsum)>0 的
+ if (list && list.length > 0) {
+ classWorkList = list && list.filter((item) => item.workdataresultsum > 0)
+ //TODO: 这里没分页,貌似这个 total 不重要,后续看
+ } else {
+ classWorkList = []
+ }
+
+ return classWorkList
+}
+
+export const getStudentClassWorkData = async () => {
+ const ids = classWorkList.map((item) => item.id).join(',')
+ if (ids == '') {
+ return
+ }
+ const res = await listClassworkdata({
+ classworkids: ids,
+ pageSize: 1000
+ })
+
+ for (var t = 0; t < classWorkList.length; t++) {
+ for (var i = 0; i < res.rows.length; i++) {
+ if (
+ res.rows[i].classworkid == classWorkList[t].id &&
+ res.rows[i].finishtimelength != '0'
+ ) {
+ console.log('==================')
+ // 有几个学生完成/正在完成学习任务
+ // 至少resultcount不是0
+ classWorkList[t].workdatafeedbackcount++
+
+ // 在参与学习任务的人中,汇总计算用时
+ classWorkList[t].feedtimelength += parseInt(res.rows[i].finishtimelength)
+
+ // 计算得分率
+ if (
+ res.rows[i].classworkevallist != '' &&
+ res.rows[i].classworkevallist != null &&
+ res.rows[i].classworkevallist != 'null'
+ ) {
+ let replacedString = res.rows[i].classworkevallist.replace(/""/g, '"')
+ // 将标签中双引号改为转义, 测试数据: "{\"id\":172907, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":358520, \"feedcontent\":\"④①⑤③②\", \"score\":4, \"rightanswer\":\"④①⑤③②\"},{\"id\":172908, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":358521, \"feedcontent\":\"气壮山威,鲲鹏展翅楚云飞\", \"score\":4, \"rightanswer\":\"志远天高,春风杨柳麓山青\"},{\"id\":172909, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":363096, \"feedcontent\":\"《红烛》化用“蜡矩”这一古典意象,赋予它新的含义,赞美了红烛以“蜡炬成灰”来点亮世界的奉献精神。\", \"score\":4, \"rightanswer\":\"《立在地球边上放号》中,全诗采用间接抒情的方式,描绘了太平洋的浪潮,吟唱了一曲惊心动魄的力的颂歌,意在赞美摧毁旧世界、创造新生活的“五四”精神。\"},{\"id\":172910, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":363098, \"feedcontent\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,浮想联翩。\", \"score\":4, \"rightanswer\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,浮想联翩。\"},{\"id\":172911, \"rating\":0, \"teacherRating\":0, \"entpcourseworkid\":363100, \"feedcontent\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,浮想联翩。\", \"score\":4, \"rightanswer\":\"毛泽东重游橘子洲,面对如画的秋色和大好的革命形势,回忆过去战斗的岁月,不禁心潮起伏,浮想联翩。\"}"
+ replacedString = escapeHtmlQuotes(res.rows[i].classworkevallist).replace(
+ /"(\[.*\])"/g,
+ '$1'
+ )
+ replacedString = escapeHtmlQuotes(res.rows[i].classworkevallist)
+ var evalarray
+ try {
+ evalarray = JSON.parse('[' + res.rows[i].classworkevallist + ']')
+ } catch {
+ evalarray = JSON.parse('[' + replacedString + ']')
+ }
+
+ for (var e = 0; e < evalarray.length; e++) {
+ if (res.rows[i].worktype == '常规作业') {
+ evalarray[e].feedcontent = escapeHtmlQuotes(evalarray[e].feedcontent).replace(
+ /"(\[.*\])"/g,
+ '$1'
+ )
+ evalarray[e].feedcontent = escapeHtmlQuotes(evalarray[e].feedcontent)
+ }
+ if (evalarray[e].feedcontent == evalarray[e].rightanswer) {
+ // 正确,得分
+ classWorkList[t].rightAnswerCount++
+ }
+ }
+ }
+ }
+ // 当前这个学习任务,共推送给了几个学生,workdataresultsum
+ if (res.rows[i].classworkid == classWorkList[t].id) {
+ classWorkList[t].workdatalist.push(res.rows[i])
+ }
+ }
+ // 计算完成进度 workdataresultsum 人数要大于0
+ if (
+ classWorkList[t].workdataresultcount > 0 &&
+ classWorkList[t].workdataresultsum > 0
+ ) {
+ classWorkList[t].finishpercent = parseInt(
+ (classWorkList[t].workdataresultcount / classWorkList[t].workdataresultsum) * 100
+ )
+ } else {
+ classWorkList[t].finishpercent = 0
+ }
+
+ // 以下四个参数,都要计算
+ // 2024-04-12,酉阳,by jackyshen
+
+ // 计算参与学习任务的平均用时
+ if (classWorkList[t].workdatafeedbackcount > 0) {
+ classWorkList[t].averagetime = Math.ceil(
+ classWorkList[t].feedtimelength / classWorkList[t].workdatafeedbackcount / 60
+ ).toFixed(0)
+ } else {
+ classWorkList[t].averagetime = 0
+ }
+
+ // 计算批阅异常,需要获取每个题目的类型,找出主观题
+ // 暂缓
+
+ // 计算平均得分率: 正确题数/(题目总数*学生人数)*100
+ if (
+ classWorkList[t].entpcourseworklistarray &&
+ classWorkList[t].entpcourseworklistarray.length > 0
+ ) {
+ var dd =
+ (classWorkList[t].rightAnswerCount /
+ (classWorkList[t].entpcourseworklistarray.length *
+ classWorkList[t].workdataresultsum)) *
+ 100
+ classWorkList[t].scoingRate = dd.toFixed(0) + '%'
+ } else {
+ classWorkList[t].scoingRate = '0%'
+ }
+
+
+ // 设定典型作答,需要获取每个题目的类型,找出主观题
+ // 暂缓
+ }
+ return classWorkList
}
diff --git a/src/renderer/src/views/tool/sphere.vue b/src/renderer/src/views/tool/sphere.vue
index 452a63c..cf204d5 100644
--- a/src/renderer/src/views/tool/sphere.vue
+++ b/src/renderer/src/views/tool/sphere.vue
@@ -1,10 +1,12 @@
+
+
-
+
@@ -13,7 +15,7 @@
-
+
-->
@@ -62,11 +64,13 @@ const isDrag = ref(false) // 开始拖拽
const dragtime = ref(0) // 拖拽时间-计算点击还是拖动
const isShow = ref(false) // 是否显示-画板
const isOver = ref(false) // 是否下课
-const isOpenBook = ref(false)
+const isOpenBook = ref(false) // 是否打开pdf课本
+const isMask = ref(false) // 是否显示遮罩层
const toolStore = useToolState() // 状态管理
const boardVueRef=ref(null) // 画板ref
const upvoteRef = ref(null) // 点赞 ref
const imChatRef = ref(null) // im-chat ref
+const sideVueRef = ref(null) // 侧边栏 ref
const classObj = reactive({ // 课程相关
id: route.query.reservId, // 课程id
data: {} // 课程信息
@@ -83,6 +87,8 @@ const btnList = [ // 工具栏按钮列表
// { label: '聚焦', value: 'focus', icon: 'icon-jujiao' },
// { label: '更多', value: 'more', icon: 'icon-xiazai9' },
]
+let timingSide = null // 计时器-侧边栏
+
// === 页面加载完毕 ===
onMounted(async() => {
if (!electron) return // 浏览器端
@@ -90,7 +96,6 @@ onMounted(async() => {
// window.test1 = toolStore
getClassInfo() // 获取课堂详情 ex3
resetStatus() // 开启重置状态-监听
-
})
// ==== 方法 ===
@@ -98,7 +103,7 @@ onMounted(async() => {
const getClassInfo = async () => {
const { data } = await classManageApi.getClassInfo(classObj.id)
classObj.data = data
- sessionStore.set('curClassRoom', classObj) // 课堂信息-缓存
+ sessionStore.set('curr.curClassRoom', classObj) // 课堂信息-缓存
// 群id
let timGroupId = data?.ex3 || ''
console.log('获取群ID:', timGroupId)
@@ -140,7 +145,8 @@ const logoHandle = (e,t) => {
// 底部工具栏:移入移出-是否穿透
const mouseChange = (bool) => {
let resBool = false
- if (bool == 0) return setIgnore(resBool) // 移入不穿透
+ // console.log('mouseChange:', bool, resBool)
+ if (!bool) return setIgnore(resBool) // 移入不穿透
if (tabActive.value == 'select') resBool = !!bool
else {
if (!isShow.value) resBool = !!bool
@@ -148,12 +154,10 @@ const mouseChange = (bool) => {
const isPdf = !resBool && toolStore.isPdfWin
if (isPdf) resBool = true
}
- console.log('mouseChange:', bool, resBool)
+ // console.log('mouseChange:', bool, resBool)
setIgnore(resBool)
}
-const touchChange = (e) => {
- console.log(e)
-}
+
// im-chat: 聊天事件 {type, data}
const chatChange = (type, data, ...args) => {
if (type == 'createGroup') { // 创建群-监听
@@ -185,14 +189,6 @@ const setIgnore = (bool) => {ipcMsgSend('tool-sphere:set:ignore', bool)}
// 重置状态: 鼠标|画板
const resetStatus = () => {
if (toolStore.isToolWin) return // 已经打开过-忽略
- // 以下代码废弃-暂时无用
- // ipcMain?.removeHandler('tool-sphere:reset') // 避免已绑定,先移除在绑定
- // ipcMain?.handle?.('tool-sphere:reset', () => {
- // setTimeout(() => {
- // boardVueRef.value.handleMode(tabActive.value)
- // mouseChange(1)
- // }, 500)
- // })
toolStore.isToolWin = true // 标记状态
}
// 侧边工具栏: 移入移出
@@ -202,13 +198,16 @@ const sideMouse = e => {
setIgnore(false) // 关闭窗口鼠标-穿透
return
}
- mouseChange(type == 'mouseleave')
+ // 打开内容且触发移出事件时
+ const bool = isMask.value && type =='mouseleave'
+ if (bool) mouseChange(false) // 不穿透
+ else mouseChange(type == 'mouseleave')
}
// 侧边工具栏: 操作变化
const sideChange = async o => {
// console.log(o)
switch(o.prop) {
- case 'book':
+ case 'bookOpen':
if(isOpenBook.value) {
isOpenBook.value = false
ElMessage.info('已经打开课本了哦')
@@ -218,7 +217,14 @@ const sideChange = async o => {
isOpenBook.value = true
}
break
+ case 'book':
+ isMask.value = !isMask.value
+ break
+ case 'close': // 关闭
+ maskChange(false)
+ break
case 'resource': // 资源
+ isMask.value = !isMask.value
break
case 'interact': // 互动
break
@@ -255,6 +261,13 @@ const sideChange = async o => {
}
}
+// 遮罩层-触发事件
+const maskChange = (bool) => {
+ isMask.value = false
+ bool && sideVueRef.value.closeActive() // 关闭侧边栏内容窗口
+ mouseChange(true) // 允许穿透
+}
+
// === 监听器 ===
watchEffect(() => {
if (isOver.value) return // 下课, 不往下执行
@@ -274,6 +287,12 @@ watchEffect(() => {
.warp-all{
position: relative;
}
+// 遮罩层
+.mask{
+ position: fixed;
+ inset: 0;
+ background: rgba(1, 1, 1, 0.3);
+}
// 底部工具栏
.tool-bottom-all{
// width: 45vw;
@@ -316,6 +335,7 @@ watchEffect(() => {
}
}
}
+// 底部动画
.a-fade-leave-active,.a-fade-enter-active{
transition: all .3s;
}