Compare commits

...

80 Commits

Author SHA1 Message Date
朱浩 f209bc673f Merge branch 'main' into zhuhao_dev 2024-10-11 15:00:23 +08:00
朱浩 acc20b79f1 #895 V2.1.5 【教学实践】“APT”“PPT”现在创建后是先生成文档,再点击进入,应该改成创建后直接默认打开进入编辑页面 2024-10-11 14:59:23 +08:00
朱浩 b4dca57828 #909 V2.1.5 平台版本号应该在平台内展示出来。方便查阅是否为最新版本 2024-10-11 14:51:46 +08:00
朱浩 3c064ebffd #924 V2.1.5 PPT上课,点击上课之后,默认打开当前课程PPT 2024-10-11 14:41:36 +08:00
朱浩 07fa4c9790 修改资源为活动,去除窗口和互动 2024-10-11 13:42:03 +08:00
朱浩 e253a6c9dc #876 教学实践,上课时检查未结束课程逻辑 2024-10-10 17:42:48 +08:00
zouyf 89097eab31 Merge pull request 'zouyf_dev' (#307) from zouyf_dev into main
Reviewed-on: #307
2024-10-10 16:03:06 +08:00
lyc ef18d4adf4 Merge pull request 'lyc-dev' (#306) from lyc-dev into main 2024-10-10 16:01:01 +08:00
lyc bff59d699f edit 2024-10-10 16:01:22 +08:00
lyc 7d457782cc edit 2024-10-10 16:00:13 +08:00
“zouyf” d0947da293 Merge branch 'main' into zouyf_dev 2024-10-10 15:58:45 +08:00
“zouyf” fd734ab645 客观题不许修改分数 2024-10-10 15:54:38 +08:00
baigl 233d065f9c Merge pull request 'baigl' (#305) from baigl into main
Reviewed-on: #305
2024-10-10 15:53:17 +08:00
白了个白 8b7858615e Merge branch 'main' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk into baigl 2024-10-10 15:46:33 +08:00
白了个白 8dafce9d86 批阅列表ui更改 2024-10-10 15:44:08 +08:00
zouyf ad541fd929 Merge pull request 'zouyf_dev' (#304) from zouyf_dev into main
Reviewed-on: #304
2024-10-10 15:37:11 +08:00
“zouyf” 6038ae3bd6 Merge branch 'main' into zouyf_dev 2024-10-10 15:28:59 +08:00
“zouyf” 93abc4905c [作业批改] - 逐题分析显示优化 2024-10-10 15:28:46 +08:00
白了个白 ccf8f2c8fb 作业批改:ui修改 2024-10-10 15:17:49 +08:00
lyc 05286236b7 Merge branch 'main' into lyc-dev 2024-10-10 15:07:04 +08:00
lyc 039dfe2e09 替换apt图标 2024-10-10 15:06:52 +08:00
lyc 0cd00809ed Merge pull request 'lyc-dev' (#303) from lyc-dev into main 2024-10-10 15:06:46 +08:00
白了个白 e7f439dd0c 1 2024-10-10 14:00:29 +08:00
lyc 95965aa4b5 edit 2024-10-10 10:57:19 +08:00
lyc ad5025f6aa Merge pull request 'edit' (#302) from lyc-dev into main 2024-10-10 10:56:58 +08:00
朱浩 4b2f2aa73a Merge branch 'main' into zhuhao_dev 2024-10-10 10:12:57 +08:00
朱浩 71bd199f4a 打开调试窗口 2024-10-10 10:12:38 +08:00
白了个白 f0313653e6 作业布置:新增推送、批量推送 2024-10-10 09:53:45 +08:00
lyc 615be3302c Merge pull request '修复一些问题' (#301) from lyc-dev into main 2024-10-09 16:55:13 +08:00
lyc 3921c1a425 冲突 2024-10-09 16:55:30 +08:00
lyc 34da5fb432 修复一些问题 2024-10-09 16:52:47 +08:00
zouyf 9c21458c57 Merge pull request '[教学实践] - 作业中增加作业设计及单任务编辑' (#300) from zouyf_dev into main
Reviewed-on: #300
2024-10-09 16:19:26 +08:00
“zouyf” 1a20fcc835 [教学实践] - 作业中增加作业设计及单任务编辑 2024-10-09 16:17:31 +08:00
白了个白 68388b9c86 作业布置:新增课堂展示编辑 2024-10-09 15:14:42 +08:00
白了个白 7a878fc5b0 作业布置:新增常规作业编辑 2024-10-09 14:20:30 +08:00
白了个白 aea10a5bba 作业布置:列表新增 框架梳理编辑 2024-10-09 13:56:18 +08:00
lyc a1c5236c8f 登录-清除缓存的数据 2024-10-09 11:29:18 +08:00
lyc 8bddb166a3 Merge pull request '登录-清除缓存的数据' (#299) from lyc-dev into main 2024-10-09 11:28:54 +08:00
白了个白 4b3c511af1 1 2024-10-09 10:18:29 +08:00
lyc 22c377cd57 结束上课 2024-10-09 09:38:58 +08:00
lyc 8a17273605 Merge pull request '结束上课' (#298) from lyc-dev into main 2024-10-09 09:38:43 +08:00
zhengdegang b13dae5b92 Merge pull request 'zdg' (#297) from zdg into main
Reviewed-on: #297
2024-10-09 09:31:41 +08:00
zdg a7743ba249 优化 2024-10-09 09:30:42 +08:00
zdg 3038223a7f 修复bug 2024-10-09 09:28:52 +08:00
白了个白 acd1cb3485 Merge branch 'main' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk into baigl 2024-10-09 09:25:26 +08:00
lyc 5e247006c5 Merge pull request '去掉返回' (#296) from lyc-dev into main 2024-10-08 14:01:24 +08:00
lyc f2387c709a 去掉返回 2024-10-08 14:01:39 +08:00
lyc 03f98c8beb Merge pull request '去掉返回' (#295) from lyc-dev into main 2024-10-08 11:23:41 +08:00
lyc b085d96c0e 去掉返回 2024-10-08 11:23:16 +08:00
白了个白 2e27d3e7fb 1 2024-09-29 16:11:33 +08:00
白了个白 cc26ea4780 作业布置,模版编辑 2024-09-29 15:36:43 +08:00
zhengdegang 9b5a2ec88d Merge pull request 'zdg' (#294) from zdg into main
Reviewed-on: #294
2024-09-29 15:36:27 +08:00
zdg 32b0cdafc6 Merge branch 'main' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk into zdg 2024-09-29 15:35:35 +08:00
zdg 17e3ee62df 修复二维码异常 2024-09-29 15:35:25 +08:00
zhengdegang 1f43e70175 Merge pull request 'zdg' (#293) from zdg into main
Reviewed-on: #293
2024-09-29 15:15:03 +08:00
zdg 0973128e0e Merge branch 'main' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk into zdg 2024-09-29 15:14:13 +08:00
zdg 61493a7f4e 二维码登录 2024-09-29 15:13:27 +08:00
lyc 3992cc814a Merge pull request '文字描述' (#292) from lyc-dev into main 2024-09-29 11:10:27 +08:00
lyc 19e385ec24 文字描述 2024-09-29 11:10:28 +08:00
baigl bac959c0bb Merge pull request 'baigl' (#291) from baigl into main
Reviewed-on: #291
2024-09-29 09:32:36 +08:00
白了个白 e72710f027 Merge branch 'main' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk into baigl 2024-09-29 09:31:36 +08:00
白了个白 9a74630e56 批阅窗口添加防连点 2024-09-29 09:31:16 +08:00
zhengdegang 28b189e965 Merge pull request 'zdg' (#290) from zdg into main
Reviewed-on: #290
2024-09-27 16:55:38 +08:00
zdg 8ea28d2635 Merge branch 'main' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk into zdg 2024-09-27 16:54:37 +08:00
zdg 352bb9be97 还原二维码 2024-09-27 16:54:29 +08:00
zhengdegang 7c8e10628b Merge pull request '增加刷新二维码' (#289) from zdg into main
Reviewed-on: #289
2024-09-27 16:41:50 +08:00
zdg 0ea299c317 增加刷新二维码 2024-09-27 16:41:19 +08:00
zouyf 5fa328fd93 Merge pull request 'zouyf_dev' (#288) from zouyf_dev into main
Reviewed-on: #288
2024-09-27 16:30:52 +08:00
“zouyf” eab46ec7f4 Merge branch 'main' into zouyf_dev 2024-09-27 16:17:08 +08:00
“zouyf” 81dd59f564 [作业批改] - 由原来班级查询变更为用户id查询作业 2024-09-27 16:16:55 +08:00
lyc 7c36255508 Merge pull request '教学大模型' (#287) from lyc-dev into main 2024-09-27 15:55:45 +08:00
lyc 310d1aee59 教学大模型 2024-09-27 15:55:50 +08:00
zhengdegang 3caa561610 Merge pull request 'zdg' (#286) from zdg into main
Reviewed-on: #286
2024-09-27 15:54:54 +08:00
zdg ada2e63060 Merge branch 'main' of http://27.128.240.72:3000/zhuhao/AIx_Smarttalk into zdg
# Conflicts:
#	src/main/index.js
2024-09-27 15:53:42 +08:00
zdg eaf9d508d4 apt上课-无需登录 2024-09-27 15:52:07 +08:00
朱浩 716c1dd0a9 Merge pull request 'zhuhao_dev' (#285) from zhuhao_dev into main
Reviewed-on: #285
2024-09-27 15:15:28 +08:00
“zouyf” cb15855fc1 Merge branch 'main' into zouyf_dev 2024-09-27 15:11:57 +08:00
“zouyf” 7b3f00ba67 Merge branch 'main' into zouyf_dev
# Conflicts:
#	src/renderer/src/views/classTask/teachClassTask.vue
2024-09-27 14:52:51 +08:00
“zouyf” 2ca4117561 1 2024-09-27 14:50:18 +08:00
zdg 68cf2bae1f 屏蔽注释打印 2024-09-27 09:27:51 +08:00
49 changed files with 1364 additions and 462 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "aix-win", "name": "aix-win",
"version": "2.1.3", "version": "2.1.5",
"description": "", "description": "",
"main": "./out/main/index.js", "main": "./out/main/index.js",
"author": "example.com", "author": "example.com",
@ -66,7 +66,7 @@
"xlsx": "^0.18.5", "xlsx": "^0.18.5",
"less": "^4.2.0", "less": "^4.2.0",
"less-loader": "^7.3.0", "less-loader": "^7.3.0",
"whiteboard_lyc": "^0.0.8" "whiteboard_lyc": "^0.1.3"
}, },
"devDependencies": { "devDependencies": {
"@electron-toolkit/eslint-config": "^1.0.2", "@electron-toolkit/eslint-config": "^1.0.2",

View File

@ -74,7 +74,7 @@ function createLoginWindow() {
updateInit(loginWindow) updateInit(loginWindow)
} }
// loginWindow.webContents.openDevTools() loginWindow.webContents.openDevTools()
loginWindow.once('ready-to-show', () => { loginWindow.once('ready-to-show', () => {
loginWindow.show() loginWindow.show()
}) })
@ -128,7 +128,7 @@ function createMainWindow() {
shell.openExternal(details.url) shell.openExternal(details.url)
return { action: 'deny' } return { action: 'deny' }
}) })
// mainWindow.webContents.openDevTools() mainWindow.webContents.openDevTools()
if (is.dev && process.env['ELECTRON_RENDERER_URL']) { if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL']) mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])

View File

@ -13,6 +13,7 @@ const defaultData = {
showBoardAll: false, // 全屏画板-是否显示 showBoardAll: false, // 全屏画板-是否显示
isPdfWin: false, // pdf窗口是否打开 isPdfWin: false, // pdf窗口是否打开
isToolWin: false, // 工具窗口是否打开 isToolWin: false, // 工具窗口是否打开
isTaskWin: false, // 批改窗口是否打开
curSubjectNode: { curSubjectNode: {
querySearch: {} // 查询资源所需参数 querySearch: {} // 查询资源所需参数
}, },

View File

@ -26,3 +26,13 @@ export class imChat {
// 获取腾讯im-chat appid 签名 // 获取腾讯im-chat appid 签名
static getTxCloudSign = data => ApiService.publicHttp('/system/user/txCloudSign', data) static getTxCloudSign = data => ApiService.publicHttp('/system/user/txCloudSign', data)
} }
// zdg: url跳转-后端存储
export class toLink {
// 设置链接-返回key(默认15分钟有效时间)
static setLink = url => ApiService.publicHttp(`/smarttalk/toLink`, {url}, 'post', null, 'form')
// 获取链接
static getLink = key => ApiService.publicHttp(`/smarttalk/toLink/${key}`)
// 删除链接-缓存
static delLink = key => ApiService.publicHttp(`/smarttalk/toLink/${key}`, null, 'delete')
}

View File

@ -147,10 +147,11 @@ export function updateSmartClassReserv(data) {
}) })
} }
//查询课程预约 //查询课程预约
export function getSelfReserv() { export function getSelfReserv(params) {
return request({ return request({
url: '/smarttalk/classReserv/getSelfReserv', url: '/smarttalk/classReserv/getSelfReserv',
method: 'get' method: 'get',
params
}) })
} }
export function deleteSmartReserv(id) { export function deleteSmartReserv(id) {

View File

@ -27,6 +27,15 @@ export function listClassworkdata(query) {
}) })
} }
// 新接口---查询classworkdata列表 班级作业列表
export function listClassworkdataNew(query) {
return request({
url: '/education/classworkdata/new/list',
method: 'get',
params: query
})
}
// 查询entpcoursework列表 课程作业列表 // 查询entpcoursework列表 课程作业列表
export function listEntpcoursework(query) { export function listEntpcoursework(query) {
return request({ return request({

View File

@ -9,6 +9,14 @@ export function listClasscourse(query) {
}) })
} }
export function listClasscourseNew(query) {
return request({
url: '/education/classcourse/new/list',
method: 'get',
params: query
})
}
// 查询classcourse详细 // 查询classcourse详细
export function getClasscourse(id) { export function getClasscourse(id) {
return request({ return request({

View File

@ -1,9 +1,9 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 2794390 */ font-family: "iconfont"; /* Project id 2794390 */
src: url('iconfont.woff2?t=1727403518918') format('woff2'), src: url('iconfont.woff2?t=1728543886557') format('woff2'),
url('iconfont.woff?t=1727403518918') format('woff'), url('iconfont.woff?t=1728543886557') format('woff'),
url('iconfont.ttf?t=1727403518918') format('truetype'), url('iconfont.ttf?t=1728543886557') format('truetype'),
url('iconfont.svg?t=1727403518918#iconfont') format('svg'); url('iconfont.svg?t=1728543886557#iconfont') format('svg');
} }
.iconfont { .iconfont {
@ -14,6 +14,18 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-A1:before {
content: "\e635";
}
.icon-A:before {
content: "\e6ef";
}
.icon--kejian:before {
content: "\e6a3";
}
.icon-a-1_jiaoxuefansi:before { .icon-a-1_jiaoxuefansi:before {
content: "\e6cd"; content: "\e6cd";
} }

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,27 @@
"css_prefix_text": "icon-", "css_prefix_text": "icon-",
"description": "", "description": "",
"glyphs": [ "glyphs": [
{
"icon_id": "11657531",
"name": "A",
"font_class": "A1",
"unicode": "e635",
"unicode_decimal": 58933
},
{
"icon_id": "12688893",
"name": "A",
"font_class": "A",
"unicode": "e6ef",
"unicode_decimal": 59119
},
{
"icon_id": "6571029",
"name": "课件",
"font_class": "-kejian",
"unicode": "e6a3",
"unicode_decimal": 59043
},
{ {
"icon_id": "37027693", "icon_id": "37027693",
"name": "教学反思", "name": "教学反思",

View File

@ -14,6 +14,12 @@
/> />
<missing-glyph /> <missing-glyph />
<glyph glyph-name="A1" unicode="&#58933;" d="M449 339h121.5L507.5 505.5zM782 834H242C143 834 62 753 62 654v-540c0-99 81-180 180-180h540c99 0 180 81 180 180V654c0 99-81 180-180 180z m-139.5-675l-40.5 103.5H422L381.5 159H287L462.5 609H557l180-450h-94.5z" horiz-adv-x="1024" />
<glyph glyph-name="A" unicode="&#59119;" d="M841.589844 779.507813a65.917969 65.917969 0 0 0 65.917969-65.917969v-659.179688a65.917969 65.917969 0 0 0-65.917969-65.917969H182.410156a65.917969 65.917969 0 0 0-65.917969 65.917969V713.589844a65.917969 65.917969 0 0 0 65.917969 65.917969h659.179688z m0-49.438477H182.410156a16.479492 16.479492 0 0 1-16.21582-13.513183L165.930664 713.589844v-659.179688a16.479492 16.479492 0 0 1 13.513183-16.21582L182.410156 37.930664h659.179688a16.479492 16.479492 0 0 1 16.21582 13.513183L858.069336 54.410156V713.589844a16.479492 16.479492 0 0 1-13.513183 16.21582L841.589844 730.069336zM539.059326 614.712891l188.85498-461.425782h-69.543456l-53.822022 139.746094H411.606933L360.916016 153.287109H296.118652l177.1875 461.425782h65.786133z m-34.277344-48.449707c-5.899658-29.597168-14.172364-58.996582-24.884033-88.165284L429.207031 342.80127h156.456299l-48.153076 127.781982-4.779053 12.689209a1170.900879 1170.900879 0 0 0-27.982178 82.990723z" horiz-adv-x="1024" />
<glyph glyph-name="-kejian" unicode="&#59043;" d="M873.813333 638.293333c27.306667 0 47.786667-30.72 47.786667-64.853333v-436.906667c0-42.666667-27.306667-75.093333-64.853333-75.093333H573.44c-23.893333 0-44.373333-22.186667-44.373333-46.08h-29.013334c0 23.893333-18.773333 46.08-44.373333 46.08H175.786667C136.533333 63.146667 102.4 93.866667 102.4 136.533333V573.44c0 34.133333 27.306667 64.853333 54.613333 64.853333h716.8zM457.386667 97.28c23.893333 0 44.373333-10.24 58.026666-27.306667 13.653333 17.066667 34.133333 27.306667 58.026667 27.306667h281.6c17.066667 0 30.72 15.36 30.72 40.96V573.44c0 10.24-3.413333 18.773333-6.826667 25.6-3.413333 3.413333-5.12 5.12-6.826666 5.12h-716.8c-6.826667 0-18.773333-15.36-18.773334-30.72v-436.906667c0-22.186667 18.773333-40.96 39.253334-40.96h281.6zM837.973333 660.48c0 34.133333-22.186667 64.853333-54.613333 64.853333H609.28c-40.96 0-75.093333-23.893333-93.866667-58.026666-18.773333 34.133333-54.613333 58.026667-93.866666 58.026666H247.466667c-32.426667 0-61.44-30.72-61.44-64.853333l6.826666-494.933333c0-29.013333 23.893333-51.2 52.906667-51.2h213.333333c23.893333 0 44.373333-22.186667 44.373334-46.08h29.013333c0 23.893333 18.773333 46.08 44.373333 46.08h211.626667c29.013333 0 52.906667 23.893333 52.906667 52.906666V660.48zM293.546667 513.706667c-8.533333 0-17.066667 8.533333-17.066667 20.48s6.826667 20.48 17.066667 20.48h158.72c8.533333 0 17.066667-8.533333 17.066666-20.48s-6.826667-20.48-17.066666-20.48h-158.72zM293.546667 426.666667c-8.533333 0-17.066667 8.533333-17.066667 20.48s6.826667 20.48 17.066667 20.48h158.72c8.533333 0 17.066667-8.533333 17.066666-20.48s-6.826667-20.48-17.066666-20.48h-158.72zM293.546667 339.626667c-8.533333 0-17.066667 8.533333-17.066667 20.48s6.826667 20.48 17.066667 20.48h158.72c8.533333 0 17.066667-8.533333 17.066666-20.48s-6.826667-20.48-17.066666-20.48h-158.72zM583.68 513.706667c-8.533333 0-17.066667 8.533333-17.066667 20.48s6.826667 20.48 17.066667 20.48h158.72c8.533333 0 17.066667-8.533333 17.066667-20.48s-6.826667-20.48-17.066667-20.48h-158.72zM583.68 426.666667c-8.533333 0-17.066667 8.533333-17.066667 20.48s6.826667 20.48 17.066667 20.48h158.72c8.533333 0 17.066667-8.533333 17.066667-20.48s-6.826667-20.48-17.066667-20.48h-158.72zM583.68 339.626667c-8.533333 0-17.066667 8.533333-17.066667 20.48s6.826667 20.48 17.066667 20.48h158.72c8.533333 0 17.066667-8.533333 17.066667-20.48s-6.826667-20.48-17.066667-20.48h-158.72z" horiz-adv-x="1024" />
<glyph glyph-name="a-1_jiaoxuefansi" unicode="&#59085;" d="M410.8288 6.4512h195.9936v-63.2832H410.8288zM833.2288 645.4272A348.16 348.16 0 0 1 593.92 832.8192 347.4432 347.4432 0 0 1 509.952 844.8h0.512a311.0912 311.0912 0 0 1-78.4384-10.24 365.8752 365.8752 0 0 1-182.1696-96.6656 345.088 345.088 0 0 1-80.6912-370.4832 366.4896 366.4896 0 0 1 115.3024-155.7504 163.84 163.84 0 0 0 43.8272-54.272A180.224 180.224 0 0 0 342.1184 87.04v-13.5168h327.68v18.432a142.5408 142.5408 0 0 0 18.432 70.0416 163.84 163.84 0 0 0 48.3328 56.6272 357.2736 357.2736 0 0 1 96.8704 121.856 338.6368 338.6368 0 0 1 34.6112 151.3472 348.16 348.16 0 0 1-34.816 153.6z m-25.7024-153.6A278.6304 278.6304 0 0 0 699.392 268.1856a239.8208 239.8208 0 0 1-62.2592-74.4448 233.0624 233.0624 0 0 1-20.48-56.6272h-209.92a224.1536 224.1536 0 0 1-78.4384 126.464 274.7392 274.7392 0 0 0-94.6176 128.7168 303.3088 303.3088 0 0 0-13.824 158.1056 270.5408 270.5408 0 0 0 78.4384 146.7392 305.152 305.152 0 0 0 147.5584 81.3056c20.48 0 43.8272 2.2528 64.6144 2.2528h-0.512a333.9264 333.9264 0 0 0 66.9696-6.7584 283.3408 283.3408 0 0 0 117.6576-56.6272 294.8096 294.8096 0 0 0 82.944-101.6832A305.5616 305.5616 0 0 0 807.5264 496.64zM385.024 578.56a27.8528 27.8528 0 0 1 0-55.7056 27.8528 27.8528 0 1 1 0 55.7056zM385.024 469.6064a27.8528 27.8528 0 0 1 0-55.7056 27.8528 27.8528 0 1 1 0 55.7056zM456.704 467.456h206.6432v-55.6032H456.704zM456.704 578.6624h206.6432v-55.5008H456.704z" horiz-adv-x="1024" /> <glyph glyph-name="a-1_jiaoxuefansi" unicode="&#59085;" d="M410.8288 6.4512h195.9936v-63.2832H410.8288zM833.2288 645.4272A348.16 348.16 0 0 1 593.92 832.8192 347.4432 347.4432 0 0 1 509.952 844.8h0.512a311.0912 311.0912 0 0 1-78.4384-10.24 365.8752 365.8752 0 0 1-182.1696-96.6656 345.088 345.088 0 0 1-80.6912-370.4832 366.4896 366.4896 0 0 1 115.3024-155.7504 163.84 163.84 0 0 0 43.8272-54.272A180.224 180.224 0 0 0 342.1184 87.04v-13.5168h327.68v18.432a142.5408 142.5408 0 0 0 18.432 70.0416 163.84 163.84 0 0 0 48.3328 56.6272 357.2736 357.2736 0 0 1 96.8704 121.856 338.6368 338.6368 0 0 1 34.6112 151.3472 348.16 348.16 0 0 1-34.816 153.6z m-25.7024-153.6A278.6304 278.6304 0 0 0 699.392 268.1856a239.8208 239.8208 0 0 1-62.2592-74.4448 233.0624 233.0624 0 0 1-20.48-56.6272h-209.92a224.1536 224.1536 0 0 1-78.4384 126.464 274.7392 274.7392 0 0 0-94.6176 128.7168 303.3088 303.3088 0 0 0-13.824 158.1056 270.5408 270.5408 0 0 0 78.4384 146.7392 305.152 305.152 0 0 0 147.5584 81.3056c20.48 0 43.8272 2.2528 64.6144 2.2528h-0.512a333.9264 333.9264 0 0 0 66.9696-6.7584 283.3408 283.3408 0 0 0 117.6576-56.6272 294.8096 294.8096 0 0 0 82.944-101.6832A305.5616 305.5616 0 0 0 807.5264 496.64zM385.024 578.56a27.8528 27.8528 0 0 1 0-55.7056 27.8528 27.8528 0 1 1 0 55.7056zM385.024 469.6064a27.8528 27.8528 0 0 1 0-55.7056 27.8528 27.8528 0 1 1 0 55.7056zM456.704 467.456h206.6432v-55.6032H456.704zM456.704 578.6624h206.6432v-55.5008H456.704z" horiz-adv-x="1024" />
<glyph glyph-name="iconfontzhizuobiaozhunbduan3-1" unicode="&#65711;" d="M381.8288 877.098511c42.635029 11.310603 86.403882 17.002232 130.205481 17.002232 68.479651 0 135.072325-13.469779 197.999516-40.101323l-8.362458-369.71439L381.8288 877.098511 381.8288 877.098511zM71.201134 640.609379c22.278399 38.284955 49.218982 73.313749 80.134085 104.090707 48.393173 48.396243 104.980983 85.958744 168.285774 111.666242l255.614725-267.305999L71.201134 640.609379 71.201134 640.609379zM18.900977 253.724934c-11.276834 42.463114-17.000186 86.234013-17.000186 130.276089 0 68.548212 13.502525 135.140886 40.099277 197.933001l369.749182-8.293897L18.900977 253.724934 18.900977 253.724934zM255.39011-56.798355c-38.010709 22.1423-72.968895 49.079812-104.021122 80.134085-48.428989 48.325635-85.993536 104.911398-111.664196 168.283728l267.302929 255.513418L255.39011-56.798355 255.39011-56.798355zM512.034281-126.100744c-68.481697 0-135.072325 13.470803-197.999516 40.031738l8.362458 369.71439 319.843562-392.81348C599.535147-120.411161 555.80211-126.100744 512.034281-126.100744L512.034281-126.100744zM448.830797 178.903855l504.036631-51.54905c-22.107507-37.940101-48.976458-72.900334-80.167854-104.019075-48.327682-48.464805-104.980983-86.029352-168.283728-111.734804L448.830797 178.903855 448.830797 178.903855zM612.320335 194.292334l392.81348 319.915193c11.276834-42.499953 16.966417-86.302575 16.966417-130.206504 0-68.753897-13.502525-135.282103-40.066531-198.002586L612.320335 194.292334 612.320335 194.292334zM768.60989 824.764586c37.975916-22.038946 73.004711-48.942689 104.089683-80.0645 48.464805-48.326659 86.027305-104.980983 111.664196-168.284751l-267.302929-255.580956L768.60989 824.764586 768.60989 824.764586z" horiz-adv-x="1024" /> <glyph glyph-name="iconfontzhizuobiaozhunbduan3-1" unicode="&#65711;" d="M381.8288 877.098511c42.635029 11.310603 86.403882 17.002232 130.205481 17.002232 68.479651 0 135.072325-13.469779 197.999516-40.101323l-8.362458-369.71439L381.8288 877.098511 381.8288 877.098511zM71.201134 640.609379c22.278399 38.284955 49.218982 73.313749 80.134085 104.090707 48.393173 48.396243 104.980983 85.958744 168.285774 111.666242l255.614725-267.305999L71.201134 640.609379 71.201134 640.609379zM18.900977 253.724934c-11.276834 42.463114-17.000186 86.234013-17.000186 130.276089 0 68.548212 13.502525 135.140886 40.099277 197.933001l369.749182-8.293897L18.900977 253.724934 18.900977 253.724934zM255.39011-56.798355c-38.010709 22.1423-72.968895 49.079812-104.021122 80.134085-48.428989 48.325635-85.993536 104.911398-111.664196 168.283728l267.302929 255.513418L255.39011-56.798355 255.39011-56.798355zM512.034281-126.100744c-68.481697 0-135.072325 13.470803-197.999516 40.031738l8.362458 369.71439 319.843562-392.81348C599.535147-120.411161 555.80211-126.100744 512.034281-126.100744L512.034281-126.100744zM448.830797 178.903855l504.036631-51.54905c-22.107507-37.940101-48.976458-72.900334-80.167854-104.019075-48.327682-48.464805-104.980983-86.029352-168.283728-111.734804L448.830797 178.903855 448.830797 178.903855zM612.320335 194.292334l392.81348 319.915193c11.276834-42.499953 16.966417-86.302575 16.966417-130.206504 0-68.753897-13.502525-135.282103-40.066531-198.002586L612.320335 194.292334 612.320335 194.292334zM768.60989 824.764586c37.975916-22.038946 73.004711-48.942689 104.089683-80.0645 48.464805-48.326659 86.027305-104.980983 111.664196-168.284751l-267.302929-255.580956L768.60989 824.764586 768.60989 824.764586z" horiz-adv-x="1024" />

Before

Width:  |  Height:  |  Size: 358 KiB

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -122,7 +122,8 @@ const outerAi = [
title: '教学大模型', title: '教学大模型',
secondTit: '中小学基础教学大模型', secondTit: '中小学基础教学大模型',
img: new URL('../../../src/assets/images/ai-02.png', import.meta.url).href, img: new URL('../../../src/assets/images/ai-02.png', import.meta.url).href,
disabled: true, path: '/ais/aimoss'
}, },
{ {
id: 3, id: 3,

View File

@ -34,7 +34,7 @@ const getFileTypeIcon = () => {
gif: 'icon-gif', gif: 'icon-gif',
txt: 'icon-txt', txt: 'icon-txt',
rar: 'icon-rar', rar: 'icon-rar',
apt: 'icon-lunwen' apt: 'icon-A'
} }
if (iconObj[name]) { if (iconObj[name]) {
return '#' + iconObj[name] return '#' + iconObj[name]

View File

@ -276,6 +276,7 @@ const cloneDialog = (formEl) => {
expandedKeys.value = [] expandedKeys.value = []
formEl.resetFields() formEl.resetFields()
model.value = false model.value = false
emit('on-close')
} }
onMounted(() => { onMounted(() => {

View File

@ -60,10 +60,12 @@
<el-button>{{ type == 'design' ? '形状' : '工具' }}</el-button> <el-button>{{ type == 'design' ? '形状' : '工具' }}</el-button>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item command="square">正方形</el-dropdown-item>
<el-dropdown-item command="rectangle">矩形</el-dropdown-item> <el-dropdown-item command="rectangle">矩形</el-dropdown-item>
<el-dropdown-item command="diamond">菱形</el-dropdown-item> <el-dropdown-item command="diamond">菱形</el-dropdown-item>
<el-dropdown-item command="triangle">三角形</el-dropdown-item> <el-dropdown-item command="triangle">三角形</el-dropdown-item>
<el-dropdown-item command="circle">圆形</el-dropdown-item> <el-dropdown-item command="circle">圆形</el-dropdown-item>
<el-dropdown-item command="elliptic">椭圆形</el-dropdown-item>
<el-dropdown-item command="line">线段</el-dropdown-item> <el-dropdown-item command="line">线段</el-dropdown-item>
<el-dropdown-item command="arrow">箭头</el-dropdown-item> <el-dropdown-item command="arrow">箭头</el-dropdown-item>
<template v-if="type != 'design'"> <template v-if="type != 'design'">
@ -397,7 +399,7 @@ const scroll = reactive({
// //
const showGrid = ref(false) const showGrid = ref(false)
// //
// const readonly = ref(false) const readonly = ref(false)
// //
const elReadonly = ref(false) const elReadonly = ref(false)
@ -675,8 +677,8 @@ const getCanvasBase64 = async () =>{
let base64 = await app.exportImage({ let base64 = await app.exportImage({
type: 'image/jpeg', type: 'image/jpeg',
renderBg: exportRenderBackground.value, renderBg: exportRenderBackground.value,
paddingX: 0, paddingX: 10,
paddingY: 0, paddingY: 10,
onlySelected: exportOnlySelected.value, onlySelected: exportOnlySelected.value,
backgroundColor: '#ffffff' backgroundColor: '#ffffff'
}) })

View File

@ -80,9 +80,7 @@ import { updateUserInfo } from '@/api/system/user'
import logoIco from '@/assets/images/logo.png' import logoIco from '@/assets/images/logo.png'
import { listEvaluation } from '@/api/classManage/index' import { listEvaluation } from '@/api/classManage/index'
import { sessionStore } from '@/utils/store' import { sessionStore } from '@/utils/store'
import { useToolState } from '@/store/modules/tool'
const toolState = useToolState();
let homeTitle = ref(import.meta.env.VITE_APP_TITLE) let homeTitle = ref(import.meta.env.VITE_APP_TITLE)
const { ipcRenderer } = window.electron || {} const { ipcRenderer } = window.electron || {}
const userStore = useUserStore() const userStore = useUserStore()
@ -153,7 +151,8 @@ function handleCommand(command) {
function logout() { function logout() {
const hasClass = sessionStore.has('activeClass.id') const hasClass = sessionStore.has('activeClass.id')
if (hasClass || toolState.isToolWin) return ElMessage.warning('当前正在上课,请先结结束上课') const hasTool = sessionStore.get('isToolWin')
if (hasClass || hasTool) return ElMessage.warning('当前正在上课,请先结束上课')
ElMessageBox.confirm('确认退出系统吗?', '提示', { ElMessageBox.confirm('确认退出系统吗?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',

View File

@ -4,14 +4,7 @@
<Header /> <Header />
</el-header> </el-header>
<el-main> <el-main>
<template v-if="currentRoute.path != '/home'"> <AppMain />
<el-page-header @back="goBack">
<template #content>
<span class="text-large mr-3"> {{ currentRoute.meta.title }} </span>
</template>
</el-page-header>
</template>
<AppMain :style="{ height: currentRoute.path == '/home' ? '100%' : 'calc(100% - 45px)'}" />
</el-main> </el-main>
<Uploader v-if="uploaderStore.uploadList && uploaderStore.uploadList.length > 0" /> <Uploader v-if="uploaderStore.uploadList && uploaderStore.uploadList.length > 0" />
<AiChart/> <AiChart/>
@ -19,32 +12,16 @@
</template> </template>
<script setup> <script setup>
import { watch } from 'vue' import { ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import Header from './components/Header.vue' import Header from './components/Header.vue'
import AppMain from './components/AppMain.vue' import AppMain from './components/AppMain.vue'
import Uploader from './components/Uploader.vue' import Uploader from './components/Uploader.vue'
import AiChart from '@/components/ai-chart/index.vue' import AiChart from '@/components/ai-chart/index.vue'
import uploaderState from '@/store/modules/uploader' import uploaderState from '@/store/modules/uploader'
import { ref } from 'vue'
const router = useRouter()
const currentRoute = ref('')
watch(
() => router.currentRoute.value,
(newValue) => {
currentRoute.value = newValue
},
{ immediate: true }
)
let uploaderStore = ref(uploaderState()) let uploaderStore = ref(uploaderState())
const goBack = () =>{
router.back()
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -10,6 +10,8 @@ import _ from 'lodash'
// import { diff } from 'jsondiffpatch' // import { diff } from 'jsondiffpatch'
// const Remote = isNode?require('@electron/remote'):{} // 远程模块 // const Remote = isNode?require('@electron/remote'):{} // 远程模块
const exArrs = ['subject'] // 不需要同步key-排除
export function shareStorePlugin({store}) { export function shareStorePlugin({store}) {
store.$subscribe((mutation, state) => { // 自动同步 store.$subscribe((mutation, state) => { // 自动同步
// mutation 变量包含了变化前后的状态 // mutation 变量包含了变化前后的状态
@ -54,35 +56,32 @@ function stateSync(storeName, key, value, state) {
// 同步数据-发送给主线程-单独($subscribe-监听使用) // 同步数据-发送给主线程-单独($subscribe-监听使用)
function stateSyncWatch(storeName, newState) { function stateSyncWatch(storeName, newState) {
const oldState = sessionStore.store // 旧数据 const oldState = sessionStore.store // 旧数据
exArrs.forEach(k => Object.keys(oldState).includes(k) && (delete oldState[k]))
const diffData = findDifferences(oldState, newState) const diffData = findDifferences(oldState, newState)
if(!_.keys(diffData).length) return // 没有变化就终止执行 if(!_.keys(diffData).length) return // 没有变化就终止执行
// 数据处理: 找出差异 // 数据处理: 找出差异
console.log('state-change-diffData', diffData) // console.log('state-change-diffData', diffData)
try { try {
let pinaValue = {} // store pina状态管理需要的数据格式 let pinaValue = {} // store pina状态管理需要的数据格式
// 数据转换处理 // 数据转换处理
for(const key in diffData) { for(const key in diffData) {
const value = diffData[key] || null const value = diffData[key]
const newValue = {} // 重新组装pinia需要的数据 {a:{b:1}} 这种 const newValue = {} // 重新组装pinia需要的数据 {a:{b:1}} 这种
const keyArr = key.split('.') || [] const keyArr = key.split('.') || []
keyArr.reduce((o,c,i)=>{o[c] = i === keyArr.length-1 ? value : {};return o[c]}, newValue) keyArr.reduce((o,c,i)=>{o[c] = i === keyArr.length-1 ? value : {};return o[c]}, newValue)
// 合并数据 loadsh _.merge() 函数 // 合并数据 loadsh _.merge() 函数
_.merge(pinaValue, newValue) _.merge(pinaValue, newValue)
} }
const piniaArr = _.toPairs(pinaValue) // 对象转换为数组 {a:1} toPairs [['a',1]]
// 数据处理: electron-store const setData = (key, value) => {
const [key, value] = _.toPairs(pinaValue)[0] // 对象转换为数组 {a:1} toPairs [['a',1]]
// 无数据就终止执行 // 无数据就终止执行
if (!key || !value) return if (!key) return
// 更新本地数据-session // 更新本地数据-session
// 直接获取当前最新值(整体更新)上面获取到value是差异值并不能知道删除还是新增 // 直接获取当前最新值(整体更新)上面获取到value是差异值并不能知道删除还是新增
const newValAll = _.get(newState, key) const newValAll = _.get(newState, key)
const oldValAll = sessionStore.get(key) const oldValAll = sessionStore.get(key)
// 没变化也终止执行 // 没变化也终止执行
if (_.isEqual(oldValAll, newValAll)) return if (_.isEqual(oldValAll, newValAll)) return
// 更新本地数据-session // 更新本地数据-session
sessionStore.set(key, newValAll) sessionStore.set(key, newValAll)
@ -91,6 +90,11 @@ function stateSyncWatch(storeName, newState) {
// 通知主线程更新 // 通知主线程更新
ipcRenderer?.invoke('pinia-state-change', storeName, jsonStr) ipcRenderer?.invoke('pinia-state-change', storeName, jsonStr)
// console.log('======',key, value, jsonStr ) // console.log('======',key, value, jsonStr )
}
// 数据处理: electron-store
for(let [key, value] of piniaArr) {
setData(key, value)
}
} catch (error) { } catch (error) {
console.log('state-change-error', error) console.log('state-change-error', error)
} }
@ -116,7 +120,7 @@ function stateSyncInit(wid, store) {
function sessionWatch(store) { function sessionWatch(store) {
const unsubscribe = sessionStore.onDidAnyChange((newV, oldV) => { const unsubscribe = sessionStore.onDidAnyChange((newV, oldV) => {
if (newV !== oldV) { if (newV !== oldV) {
console.log('session-change', newV, oldV) // console.log('session-change', newV, oldV)
// 通知主线程更新 // 通知主线程更新
// ipcRenderer?.invoke('pinia-state-change', storeName, jsonStr) // ipcRenderer?.invoke('pinia-state-change', storeName, jsonStr)
} }
@ -129,7 +133,7 @@ function stateChange(store) {
const storeName = store.$id const storeName = store.$id
ipcRenderer?.on('pinia-state-set', (e, sName, jsonStr) => { ipcRenderer?.on('pinia-state-set', (e, sName, jsonStr) => {
if (sName == storeName) { // 更新对应数据 if (sName == storeName) { // 更新对应数据
console.log('state-set', jsonStr, sName) // console.log('state-set', jsonStr, sName)
const curJson = circularSafeStringify(store.$state) // 当前数据 const curJson = circularSafeStringify(store.$state) // 当前数据
const isUp = curJson != jsonStr // 不同的时候才写入,不然会导致触发数据变化监听,导致死循环 const isUp = curJson != jsonStr // 不同的时候才写入,不然会导致触发数据变化监听,导致死循环
if (!isUp) return if (!isUp) return

View File

@ -310,3 +310,44 @@ export function timeToStr(time,str = '时分秒', isPad = false) {
if (isPad) return `${h?toStr(h)+arr[0]:''}${m?toStr(m)+arr[1]:''}${toStr(s)}${arr[2]||''}` if (isPad) return `${h?toStr(h)+arr[0]:''}${m?toStr(m)+arr[1]:''}${toStr(s)}${arr[2]||''}`
return `${h?h+arr[0]:''}${m?m+arr[1]:''}${s?s+arr[2]||'':''}` return `${h?h+arr[0]:''}${m?m+arr[1]:''}${s?s+arr[2]||'':''}`
} }
/**
* 防抖一定时间内如果函数被连续调用则只执行最后一次调用
* debounce(() => {
console.log('Input event handled');
}, 300);
* @param {*} func
* @param {*} wait
* @returns
*/
export function debounce(func, wait) {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), wait);
};
}
/**
* 节流一定时间内函数最多只执行一次
* throttle(() => {
console.log('Scroll event handled');
}, 300);
* @param {*} func
* @param {*} wait
* @returns
*/
export function throttle(func, wait) {
let lastTime = 0;
return function() {
const context = this;
const args = arguments;
const now = new Date();
if (now - lastTime >= wait) {
func.apply(context, args);
lastTime = now;
}
};
}

View File

@ -100,6 +100,17 @@ export const getCurrentTime = (format)=> {
if(format == 'MMDD'){ if(format == 'MMDD'){
return `${month}${day}`; return `${month}${day}`;
} }
if(format == 'HH'){
return `${hours}`;
}
if(format == 'HH+3'){
//往后延时3个小时
const hours = (now.getHours()+3).toString().padStart(2, '0');
return `${hours}`
}
if(format == 'mm'){
return `${minutes}`;
}
} }
/** /**
* *

View File

@ -138,7 +138,7 @@ export const createWindow = async (type, data) => {
wins_tool.setIgnoreMouseEvents(true, {forward: true}) // 忽略鼠标事件但是事件继续传递给窗口 wins_tool.setIgnoreMouseEvents(true, {forward: true}) // 忽略鼠标事件但是事件继续传递给窗口
wins_tool.setAlwaysOnTop(true,'screen-saver') // 将窗口设置为顶层窗口 wins_tool.setAlwaysOnTop(true,'screen-saver') // 将窗口设置为顶层窗口
wins_tool.setVisibleOnAllWorkspaces(true) // 如果窗口在所有工作区都可见 wins_tool.setVisibleOnAllWorkspaces(true) // 如果窗口在所有工作区都可见
// wins_tool.webContents.openDevTools() // 打开调试工具 wins_tool.webContents.openDevTools() // 打开调试工具
eventHandles(type, wins_tool) // 事件监听处理 eventHandles(type, wins_tool) // 事件监听处理
return wins_tool return wins_tool
} }
@ -165,7 +165,7 @@ export const createWindow = async (type, data) => {
win.type = type // 唯一标识 win.type = type // 唯一标识
win.show() win.show()
win.setFullScreen(true) // 设置窗口为全屏 win.setFullScreen(true) // 设置窗口为全屏
// win.webContents.openDevTools() // 打开调试工具 win.webContents.openDevTools() // 打开调试工具
eventHandles(type, win) // 事件监听处理 eventHandles(type, win) // 事件监听处理
winPdf=win winPdf=win
break break

View File

@ -1,25 +1,25 @@
<template> <template>
<el-container class="class-reserv-wrap"> <el-container class="class-reserv-wrap">
<div class="class-reserv-tabs"> <!-- <div class="class-reserv-tabs">
<el-segmented v-model="tabActive" block :options="tabOptions" size="large" /> <el-segmented v-model="tabActive" block :options="tabOptions" size="large" />
</div> </div>-->
<div class="class-reserv-body"> <div class="class-reserv-body">
<template v-for="(item, index) in dataList" :key="index">
<reserv-item <reserv-item
v-for="(item, index) in activeDataList" :style="{'background-color': index%2==0?'#f5f5f5':''}"
v-show="tabActive === '进行中'"
:key="index"
:item="item" :item="item"
v-if="item.bookImg"
@open-edit="reservDialog.openDialog(item)" @open-edit="reservDialog.openDialog(item)"
@delete-reserv="deleteReserv(item)" @delete-reserv="deleteReserv(item)"
></reserv-item> ></reserv-item>
<reserv-item <reserv-item-apt
v-for="(item, index) in doneDataList" v-if="!item.bookImg"
v-show="tabActive === '已结束'" :style="{'background-color': index%2==0?'#f5f5f5':''}"
:key="index"
:item="item" :item="item"
@open-edit="reservDialog.openDialog(item)" @open-edit="reservDialog.openDialog(item)"
@delete-reserv="deleteReserv(item)" @delete-reserv="deleteReserv(item)"
></reserv-item> ></reserv-item-apt>
</template>
</div> </div>
<reserv ref="reservDialog"></reserv> <reserv ref="reservDialog"></reserv>
</el-container> </el-container>
@ -28,44 +28,62 @@
<script setup> <script setup>
import { ref, onMounted, computed, watch } from 'vue' import { ref, onMounted, computed, watch } from 'vue'
import { getSelfReserv } from '@/api/classManage' import { getSelfReserv } from '@/api/classManage'
import { listClasscourseNew } from '@/api/teaching/classcourse' // api
import ReservItem from '@/views/classManage/reserv-item.vue' import ReservItem from '@/views/classManage/reserv-item.vue'
import Reserv from '@/views/prepare/container/reserv.vue' import Reserv from '@/views/prepare/container/reserv.vue'
import { useToolState } from '@/store/modules/tool' import { useToolState } from '@/store/modules/tool'
import { sessionStore } from '@/utils/tool' import useUserStore from '@/store/modules/user'
import ReservItemApt from '@/views/classManage/reserv-item-apt.vue'
const reservDialog = ref(null) const reservDialog = ref(null)
const tabOptions = ref(['进行中', '已结束']) const tabOptions = ref(['进行中', '已结束'])
const tabActive = ref('进行中') const tabActive = ref('进行中')
const dataList = ref([]) const dataList = ref([])
const activeDataList = computed(() => { const toolStore = useToolState()
const userStore = useUserStore()
/*const activeDataList = computed(() => {
return dataList.value.filter((item) => { return dataList.value.filter((item) => {
return item.status !== '已结束' return item.status !== '已结束'
}) })
})*/
const props = defineProps({
curNode: {
type: Object,
default: () => {}
}
}) })
const deleteReserv = (item) => { const deleteReserv = (item) => {
dataList.value = dataList.value.filter((is) => { dataList.value = dataList.value.filter((is) => {
return is.id !== item.id return is.id !== item.id
}) })
} }
const doneDataList = computed(() => { /*const doneDataList = computed(() => {
return dataList.value.filter((item) => { return dataList.value.filter((item) => {
return item.status === '已结束' return item.status === '已结束'
}) })
}) })*/
// //
const getData = () => { const getData = () => {
getSelfReserv().then((res) => { Promise.all([listClasscourseNew({teacherid: userStore.id,evalid: props.curNode.id,pageSize:1000}), getSelfReserv({ex2:props.curNode.id})]).then(([res1,res2])=>{
let list = res2.data || []
let list2 = res1.rows || []
// list.sort((a,b) => { if(a.status=='') return -1; else return 0 })
list = list.concat(list2)
list.sort((a,b) => { return new Date(b.createTime) - new Date(a.createTime) })
dataList.value = list
})
/*getSelfReserv().then((res) => {
const list = res.data || [] const list = res.data || []
list.sort((a,b) => { if(a.status=='上课中') return -1; else return 0 }) list.sort((a,b) => { if(a.status=='上课中') return -1; else return 0 })
dataList.value = list dataList.value = list
}) })*/
} }
const toolStore = useToolState()
watch( watch(
() => [dataList,toolStore.isToolWin], () => [dataList,toolStore.isToolWin,props.curNode],
() => { () => {
console.log('====',toolStore)
setTimeout(()=>{ setTimeout(()=>{
getData() // getData() //
},300) },300)
@ -81,13 +99,14 @@ onMounted(() => {
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 15px 30px; //padding: 15px 10px;
.class-reserv-tabs { .class-reserv-tabs {
width: 30%; width: 30%;
text-align: left; text-align: left;
} }
.class-reserv-body { .class-reserv-body {
height: 100%; height: 100%;
font-size: 12px;
flex: 1; flex: 1;
overflow: auto; overflow: auto;
padding: 10px 0; padding: 10px 0;

View File

@ -0,0 +1,127 @@
<template>
<div class="class-reserv-item">
<div class="class-reserv-item-body">
{{ item.openDate }}&nbsp;{{ item.openTime }}
</div>
<div style="flex: 1;max-width: 400px">
<span>{{item.caption}}</span>
</div>
<div class="class-reserv-item-tool" style="width: 200px;max-width: 300px">
<el-tag v-if="item.status === 'close'" style="margin-right: 5px" type="success">已结束</el-tag>
<el-tag v-if="item.status === 'open'" style="margin-right: 5px" type="danger">上课中</el-tag>
<el-button v-if="item.status === 'open'" :disabled="toolStore.isToolWin" size="small" type="primary" @click="startClassR(item)"
>继续上课</el-button
>
<!-- <el-button v-if="item.status === '未开始'" @click="openEdit">编辑</el-button>-->
<el-button v-if="item.status === 'open'" size="small" type="info" @click="endClassR(item)"
>下课</el-button
>
</div>
<div class="class-reserv-item-tool" style="width: 50px;">
<!-- <el-button v-if="item.status!='open'" size="small" type="danger" @click="deleteReserv">删除</el-button>-->
<el-tag>APT</el-tag>
</div>
<div style="min-width: 150px;"><span> 浏览25955 点赞26605</span></div>
</div>
</template>
<script setup>
import { useToolState } from '@/store/modules/tool'
import useUserStore from '@/store/modules/user'
import { createWindow } from '@/utils/tool'
import { deleteSmartReserv, startClass, endClass } from '@/api/classManage'
import { ElMessage } from 'element-plus'
import { listEntpcourse } from '@/api/teaching/classwork'
const emit = defineEmits(['openEdit', 'deleteReserv'])
const props = defineProps({
item: {
type: Object,
default: () => {}
}
})
const basePath = import.meta.env.VITE_APP_BUILD_BASE_PATH
const toolStore = useToolState() // -tool
const openEdit = () => {
emit('openEdit', props.item)
}
const deleteReserv = () => {
deleteSmartReserv([props.item.id]).then((res) => {
if (res.data === true) {
ElMessage({
message: '删除成功',
type: 'success'
})
emit('deleteReserv', props.item)
}
})
}
const startClassR = (item) => {
// startClass(item.id).then((res) => {
// if (res.data === true) {
// item.status = ''
// openLesson()
// }
// })
// item.status = ''
openLesson()
}
const endClassR = (item) => {
/*endClass(item.id).then((res) => {
if (res.data === true) {
ElMessage({
message: '下课成功',
type: 'success'
})
item.status = '已结束'
}
})*/
}
// const toolStore = useToolState()
let wins = null;
// -
const openLesson = () => {
// startClass(props.item.id)
/*listEntpcourse({
evalid: props.item.ex2,
edituserid: useUserStore().user.userId,
pageSize: 500
}).then(async res=>{
if (res.rows[0].id) {
wins = await createWindow('tool-sphere', { url: '/tool/sphere?entpcourseid=' + res.rows[0].id + "&reservId=" + props.item.id })
}
})*/
}
</script>
<style scoped lang="scss">
.class-reserv-item {
display: flex;
background-color: white;
border-radius: 10px;
padding: 5px;
margin-bottom: 10px;
.class-reserv-item-img {
width: 60px;
img {
width: 100%;
}
}
.class-reserv-item-body {
display: flex;
align-items: center;
text-align: left;
padding-left: 5px;
width: 120px;
.class-reserv-item-title1 {
flex: 1;
label {
font-size: 20px;
font-weight: bold;
}
}
}
.class-reserv-item-tool {
margin-left: 15px;
display: flex;
align-items: center;
}
}
</style>

View File

@ -1,34 +1,27 @@
<template> <template>
<div class="class-reserv-item"> <div class="class-reserv-item">
<div class="class-reserv-item-img">
<img :src="basePath + item.bookImg" alt="封面" />
</div>
<div class="class-reserv-item-body"> <div class="class-reserv-item-body">
<div class="class-reserv-item-title1"> {{ item.classDay }}&nbsp;{{ item.startTime }}
<label>{{ item.className }}</label>
<el-tag style="margin-left: 5px" type="primary"> {{ item.classType }}</el-tag>
<el-tag style="margin-left: 5px" type="primary"> {{ item.classSubject }}</el-tag>
</div> </div>
<div class="class-reserv-item-title2"> <div style="flex: 1;max-width: 400px">
{{ item.classDay }}&nbsp;{{ item.startTime }} ~ {{ item.classDay }}&nbsp;{{ item.endTime }} <span v-for="(tag, index) in item.classItemList" :key="index">{{ index === 0 ? tag.name : '' + tag.name }}</span>
{{ item.createUserName }}老师
</div> </div>
<div class="class-reserv-item-title3"> <div class="class-reserv-item-tool" style="width: 200px;max-width: 300px">
<span v-for="(tag, index) in item.classItemList" :key="index" style="margin-left: 5px"> <el-tag v-if="item.status === '已结束'" style="margin-right: 5px" type="success">已结束</el-tag>
{{ index === 0 ? tag.name : '、' + tag.name }}</span <el-tag v-if="item.status === '上课中'" style="margin-right: 5px" type="danger">上课中</el-tag>
<el-button v-if="item.status === '上课中'" :disabled="toolStore.isToolWin" size="small" type="primary" @click="startClassR(item)"
>继续上课</el-button
> >
</div> <!-- <el-button v-if="item.status === '未开始'" @click="openEdit">编辑</el-button>-->
</div> <el-button v-if="item.status === '上课中'" size="small" type="info" @click="endClassR(item)"
<div class="class-reserv-item-tool">
<el-button v-if="item.status !== '已结束'" :disabled="toolStore.isToolWin" type="primary" @click="startClassR(item)"
>{{item.status == '上课中'?'上课中':'上课'}}</el-button
>
<el-button v-if="item.status === '未开始'" @click="openEdit">编辑</el-button>
<!-- <el-button v-if="item.status === '上课中'" type="info" @click="endClassR(item)"
>下课</el-button >下课</el-button
>--> >
<el-button v-if="item.status!='上课中'" type="danger" @click="deleteReserv">删除</el-button>
</div> </div>
<div class="class-reserv-item-tool" style="width: 50px;">
<!-- <el-button v-if="item.status!='上课中'" size="small" type="danger" @click="deleteReserv">删除</el-button>-->
<el-tag type="success">PPT</el-tag>
</div>
<div style="min-width: 150px;"></div>
</div> </div>
</template> </template>
<script setup> <script setup>
@ -100,25 +93,24 @@ const endClassR = (item) => {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.class-reserv-item { .class-reserv-item {
font-size: 13px;
display: flex; display: flex;
background-color: white; background-color: white;
border-radius: 10px; border-radius: 10px;
padding: 5px; padding: 5px;
margin-bottom: 10px; margin-bottom: 10px;
.class-reserv-item-img { .class-reserv-item-img {
width: 80px; width: 60px;
padding-left: 20px;
img { img {
width: 100%; width: 100%;
} }
} }
.class-reserv-item-body { .class-reserv-item-body {
flex: 1;
display: flex; display: flex;
flex-direction: column; align-items: center;
text-align: left; text-align: left;
padding-left: 30px; padding-left: 5px;
font-size: 14px; width: 120px;
.class-reserv-item-title1 { .class-reserv-item-title1 {
flex: 1; flex: 1;
label { label {

View File

@ -63,7 +63,7 @@
<script setup> <script setup>
import { ref, onMounted, onUnmounted, computed, watch } from 'vue' import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
import { listByDeadDate, listClassworkdata } from '@/api/classTask' import { listByDeadDate, listClassworkdata, listClassworkdataNew } from '@/api/classTask'
import TaskItem from '@/views/classTask/container/task-item.vue' import TaskItem from '@/views/classTask/container/task-item.vue'
// import ItemDialog from '@/views/classTask/container/item-dialog.vue' // import ItemDialog from '@/views/classTask/container/item-dialog.vue'
@ -72,6 +72,7 @@ import { getCurrentTime, getTomorrow } from '@/utils/date'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import useClassTaskStore from "@/store/modules/classTask"; import useClassTaskStore from "@/store/modules/classTask";
import {sessionStore, createWindow} from '@/utils/tool' import {sessionStore, createWindow} from '@/utils/tool'
import {throttle,debounce } from '@/utils/comm'
const toolState = useToolState(); const toolState = useToolState();
@ -119,7 +120,7 @@ const getData = async () => {
classWorkList.value = [] classWorkList.value = []
loading.value = true loading.value = true
// 1 // 1
getClassList() //getClassList()
// 2 // 2
await getClassWorkList() await getClassWorkList()
// 3 // 3
@ -140,10 +141,11 @@ const getClassList = () => {
* 2获取班级作业 * 2获取班级作业
*/ */
const getClassWorkList = async () => { const getClassWorkList = async () => {
if(classTaskStore.classListIds.length>0){ //if(classTaskStore.classListIds.length>0){
{
// homeworklist // homeworklist
const response = await listByDeadDate({ const response = await listByDeadDate({
classidarray: classTaskStore.classListIds.join(','), //classidarray: classTaskStore.classListIds.join(','),
edituserid: userStore.userId, // id edituserid: userStore.userId, // id
edustage: userStore.edustage, // edustage: userStore.edustage, //
edusubject: userStore.edusubject,// edusubject: userStore.edusubject,//
@ -218,7 +220,7 @@ const getClassWorkList = async () => {
const getStudentClassWorkData = async() => { const getStudentClassWorkData = async() => {
// const { chapterId } = await useGetHomework(props.bookobj.node) // const { chapterId } = await useGetHomework(props.bookobj.node)
// this.entpcourseid = chapterId // this.entpcourseid = chapterId
if(classTaskStore.classListIds.length>0){ //if(classTaskStore.classListIds.length>0){
// listClassworkdataByDeadDate({ // listClassworkdataByDeadDate({
// edituserid: userStore.userId, // id // edituserid: userStore.userId, // id
// classids: classTaskStore.classListIds.join(','), // classids: classTaskStore.classListIds.join(','),
@ -228,7 +230,21 @@ const getStudentClassWorkData = async() => {
// orderby: "deaddate DESC",// TODO deaddate // orderby: "deaddate DESC",// TODO deaddate
// pageSize: 1000, // pageSize: 1000,
// }) // })
// listClassworkdataNew({
// classworkids: ids, // id
// edituserid: userStore.userId, // id
// edusubject: userStore.edusubject,//
// evalStatus: 1,
// pageSize: 1000,
// })
{
const ids = classWorkList.value.map((item) => item.id).join(','); const ids = classWorkList.value.map((item) => item.id).join(',');
if (ids == '') {
return;
}
listClassworkdata({ listClassworkdata({
classworkids: ids, classworkids: ids,
pageSize: 1000, pageSize: 1000,
@ -362,6 +378,10 @@ const closeDialog = () => {
getStudentClassWorkDataPolling() getStudentClassWorkDataPolling()
} }
const debounceOpenWin = debounce(() => {
toolState.isTaskWin=true; //
createWindow('open-taskwin',{url:'/teachClassTask'}); //
}, 1000);
/** /**
* 开启新批改弹窗 * 开启新批改弹窗
* @param item 作业对象 * @param item 作业对象
@ -369,14 +389,10 @@ const closeDialog = () => {
const onClickItem = (item) => { const onClickItem = (item) => {
console.log('开启弹窗,关闭作业进度轮询') console.log('开启弹窗,关闭作业进度轮询')
clearInterval(pollingST.value) clearInterval(pollingST.value)
// itemDialogRef.value.openDialog(item)
// console.log('防抖开启弹窗')
// 1item2 3item sessionStore.set('teachClassWorkItem', item); // item
// localStorage.setItem('teachClassWorkItem', JSON.stringify(item)) debounceOpenWin();
sessionStore.set('teachClassWorkItem', item)
toolState.isTaskWin=true //
createWindow('open-taskwin',{url:'/teachClassTask'})
} }

View File

@ -92,7 +92,7 @@
<el-table-column v-if="props.initDataProps.queryType!=='single'" label="推送配置" align="left" min-width="16%"> <el-table-column v-if="props.initDataProps.queryType!=='single'" label="推送配置" align="left" min-width="16%">
<template #default="scope"> <template #default="scope">
<div style="display: flex"> <div style="display: flex">
<el-button link icon="Setting" @click="scope.row.status == '10' ? openClassWorkConfigDialog(scope.row, -1,'item') : ''" :style="formatStyle(scope.row)" v-hasPermi="['teaching:classwork:edit']">{{scope.row.status == '10'? '推送' : '已推送'}}</el-button> <el-button v-hasPermi="['teaching:classwork:edit']" link icon="Setting" :style="formatStyle(scope.row)" @click="scope.row.status == '10' ? openClassWorkConfigDialog(scope.row, -1,'item') : ''">{{scope.row.status == '10'? '推送' : '已推送'}}</el-button>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@ -149,21 +149,103 @@
@click="submitWorkTitle('submit')"> </el-button> @click="submitWorkTitle('submit')"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
<!-- 推送作业的配置对话框 -->
<el-dialog v-model="workConfDialogOpen" title="作业布置推送配置" width="60%" append-to-body>
<el-row>
<el-col :span="24">
<el-form ref="classWorkConfigFormRef" :model="classWorkConfigForm" label-width="100px">
<el-row>
<el-col :span="24">
<el-form-item label="班级" prop="grade">
<el-scrollbar max-height="300px" style="width: 100%">
<el-tree
ref="treeRef" :props="defaultProps" :load="getLoad" node-key="id" highlight-current show-checkbox
lazy @check="handleCheckChange" />
</el-scrollbar>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="选中学生">
<div style="max-height: 150px; overflow: auto">
<template v-for="(item, index) in classWorkConfigForm.studentlist" :key="item" >
<el-tag :label="item.studentid" size="large" closable style="margin: 3px" @close="handleClassDialogClassStudentRemove(item, index)">{{ item.name }}</el-tag>
</template>
</div>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="完成要求">
<el-radio-group v-model="classWorkConfigForm.feedtype">
<el-radio label="必做">必做</el-radio>
<el-radio label="选做">选做</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="截止日期">
<el-date-picker v-model="classWorkConfigForm.deaddate" type="date" placeholder="选择日期"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="截止时间">
<el-input-number v-model="classWorkConfigForm.deadhour" :min="8" :max="22"></el-input-number>
<el-input-number v-model="classWorkConfigForm.deadmin" :min="0" :max="60" :step="15" style="margin-left: 10px"></el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="推荐用时">
<el-input-number v-model="classWorkConfigForm.timelength" :min="1"></el-input-number>分钟
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="分值" v-show="false">
<el-input-number v-model="classWorkConfigForm.weights" :min="1"></el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-row>
</el-row>
</el-form>
</el-col>
</el-row>
<div slot="footer" class="dialog-footer" style="text-align: right">
<el-button @click="handleWorkConfigUpdate('cancel')">取消</el-button>
<!-- <el-button type="primary" @click="handleTaskAssignToAllClassType()" :loading="classWorkToStudent_Loading">{{classWorkToStudent_Loading?'推送中……':'推送'}}</el-button> -->
<el-button type="primary" @click="handleTaskAssignToAllClassType()" >{{'推送'}}</el-button>
</div>
</el-dialog>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { onMounted, ref, toRaw,watch, reactive, getCurrentInstance } from 'vue' import { onMounted, ref,watch, reactive, getCurrentInstance,nextTick } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import ChooseTextbook from '@/components/choose-textbook/index.vue' import ChooseTextbook from '@/components/choose-textbook/index.vue'
import { homeworklist, delClasswork } from '@/api/teaching/classwork' import { homeworklist, delClasswork } from '@/api/teaching/classwork'
import { listEntpcoursework, listClassworkeval,updateClasswork } from '@/api/classTask' import { listEntpcoursework, listClassworkeval,updateClasswork,getEvaluationclue } from '@/api/classTask'
import { listClassmain, listClassgroup } from '@/api/classManage/index'
import { saveByClassWorkArray } from '@/api/teaching/classwork'
import { useGetHomework } from '@/hooks/useGetHomework' import { useGetHomework } from '@/hooks/useGetHomework'
import { processList } from '@/hooks/useProcessList' import { processList } from '@/hooks/useProcessList'
import { uniqBy, groupBy } from 'lodash'
import { getCurrentTime } from '@/utils/date' import { getCurrentTime } from '@/utils/date'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
const userStore = useUserStore().user const userStore = useUserStore().user
@ -210,6 +292,22 @@ const workConfObj = reactive({
quizlist: [], // list quizlist: [], // list
}); });
//
const defaultProps = ref({
children: 'children',
label: 'label',
isLeaf: 'leaf'
});
const gradeList = ref([]);//
const workConfDialogOpen = ref(false);//
const classWorkConfigForm = reactive({
formRowsType: '',//
formRowsList: null,
//
feedtype: '必做',
studentlist: [], //list
}); //
// --------------------------------------------------- // ---------------------------------------------------
@ -454,13 +552,17 @@ const handleWorkEdit = (row, index) =>{
// -- // --
let classtaskObj = reactive({ let classtaskObj = reactive({
id: '', // id: '', //
bookName: '', //
uniquekey: '', // uniquekey: '', //
title: '', // title: '', //
worktype: '', // worktype: '', //
quizlist: [], // quizlist: [], //
chooseWorkLists: [],// list
fileHomeworkList: [],// list
whiteboardObj: '',//
}) })
// - // -
const newHandleWorkEdit2ClassWorkQuizAdd =(row, index) =>{ const newHandleWorkEdit2ClassWorkQuizAdd = async (row, index) =>{
// this.newWorkSpace = true; // this.newWorkSpace = true;
// this.newWorkSpaceEdit = true; // this.newWorkSpaceEdit = true;
// this.currentTask = row; // this.currentTask = row;
@ -485,10 +587,15 @@ const newHandleWorkEdit2ClassWorkQuizAdd =(row, index) =>{
if (listCourseWork.length > 0) { if (listCourseWork.length > 0) {
classtaskObj.id= row.id; // classtaskObj.id= row.id; //
classtaskObj.bookObj = courseObj; //
classtaskObj.bookName = row.evaltitle? row.evalparenttitle+'/'+row.evaltitle: row.evalparenttitle// :/
classtaskObj.uniquekey= row.uniquekey; // classtaskObj.uniquekey= row.uniquekey; //
classtaskObj.title= row.title; // classtaskObj.title= row.title; //
classtaskObj.worktype= row.worktype; // classtaskObj.worktype= row.worktype; //
classtaskObj.quizlist= []; // classtaskObj.quizlist= []; //
classtaskObj.chooseWorkLists = []; // list
classtaskObj.fileHomeworkList = []; // list
classtaskObj.whiteboardObj = ''; //
if (row.worktype == '框架梳理') { if (row.worktype == '框架梳理') {
@ -498,14 +605,16 @@ const newHandleWorkEdit2ClassWorkQuizAdd =(row, index) =>{
// queryParams.ppttype = ''; // queryParams.ppttype = '';
// queryParams.title = ''; // queryParams.title = '';
// queryParams.filetype = 'draw'; // queryParams.filetype = 'draw';
// const res = await getEvaluationclue(listCourseWork[0].id); const res = await getEvaluationclue(listCourseWork[0].id);
// if ( res.data==null || res.data==undefined ) { if ( res.data==null || res.data==undefined ) {
// return; return;
// } }
console.log('res.data', res.data);
// this.chooseWorkLists = []; // this.chooseWorkLists = [];
// res.data.worktype = ''; res.data.worktype = '框架梳理';
// res.data.score = listCourseWork[0].score; res.data.score = listCourseWork[0].score;
// this.chooseWorkLists.push(res.data); classtaskObj.chooseWorkLists.push(res.data);
//
} }
else if (row.worktype == '习题训练') { else if (row.worktype == '习题训练') {
const ids = listCourseWork.map(item => item.id).join(","); const ids = listCourseWork.map(item => item.id).join(",");
@ -513,7 +622,6 @@ const newHandleWorkEdit2ClassWorkQuizAdd =(row, index) =>{
// for (var i=0; i<idres.rows.length; i++) { // for (var i=0; i<idres.rows.length; i++) {
// idres.rows[i].titletext = idres.rows[i].title.replace(/<[^>]+>/g, ''); // idres.rows[i].titletext = idres.rows[i].title.replace(/<[^>]+>/g, '');
// } // }
// //
if(idres.rows&&idres.rows.length > 0){ if(idres.rows&&idres.rows.length > 0){
processList(idres.rows); processList(idres.rows);
@ -527,43 +635,417 @@ const newHandleWorkEdit2ClassWorkQuizAdd =(row, index) =>{
}); });
classtaskObj.quizlist = idres.rows; classtaskObj.quizlist = idres.rows;
// //
}
})
}
else if (row.worktype == '课堂展示') {
console.log('row.课堂展示', row.workcodes);
const workcodes = JSON.parse(row.workcodes);
classtaskObj.whiteboardObj = JSON.stringify(workcodes.json);
//
}
else if (row.worktype == '常规作业') {
if(isJson(row.workcodes)){
classtaskObj.fileHomeworkList = JSON.parse(row.workcodes);
//
}
}
//
router.push({ router.push({
path: '/newClassTask', path: '/newClassTask',
query: { query: {
classtaskObj: JSON.stringify(classtaskObj), classtaskObj: JSON.stringify(classtaskObj),
} }
}) })
}
};
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
}
}
}
//
const getGradeList = async() => {
let { rows } = await listClassmain({
classuserid: userStore.userId,
pageSize: 100,
status: 'open'
})
rows.forEach((item) => {
item.label = item.caption
item.level = 0
item.leaf = false
item.children = []
item.classstudentlist = JSON.parse('[' + item.classstudentlist + ']')
item.classstudentlist.forEach((el) => {
el.classid = item.id
})
})
return rows
};
//
const getLoad = async (node, resolve) =>{
//
if (node.level == 0) {
gradeList.value = await getGradeList()
resolve(gradeList.value)
}
//
if (node.level == 1) {
listClassgroup({ classid: node.key, orderby: 'orderidx', pageSize: 100 }).then((res) => {
if (res.rows.length > 0) {
let ary = []
res.rows.forEach((item) => {
if (item.parentid === 0) {
//studentGroup
let studentGroup = JSON.parse('[' + item.studentlist + ']')
studentGroup.forEach((el) => {
el.label = el.name
el.leaf = true
el.level = 2
el.id = el.studentid
el.classid = item.classid
})
ary.push({
label: item.groupname,
leaf: false,
...item,
level: 1,
// children
children: studentGroup
})
}
})
resolve(ary)
} else {
//
let students = node.data.classstudentlist
students.forEach((item) => {
item.label = item.name
item.level = 2
item.leaf = true
})
resolve(students)
} }
}) })
} }
else if (this.classWorkForm.worktype == '课堂展示') { //
if (node.level == 2) {
// const workcodes = JSON.parse(this.currentTask.workcodes); resolve(node.data.children)
// const jsonString = JSON.stringify(workcodes.json);
// await this.$nextTick();
// this.isShowBoard = true
// this.whiteboardObj = jsonString;
} }
else if (this.classWorkForm.worktype == '常规作业') { }
// this.fileHomeworkList = [];
// if(isJson(this.currentTask.workcodes)){ //
// this.fileHomeworkList = JSON.parse(this.currentTask.workcodes); const handleCheckChange = (data, checked) => {
classWorkConfigForm.studentlist = [];
//
let checkNodes = checked.checkedNodes
let ary = []
checkNodes.forEach((item) => {
//
if (item.level == 0) {
ary = [...ary, ...item.classstudentlist]
}
//
if (item.level == 1) {
ary = [...ary, ...item.children]
}
//
if (item.level == 2) {
ary = [...ary, item]
}
})
classWorkConfigForm.studentlist = uniqBy(ary, 'studentid')
};
//
const handleClassDialogClassStudentRemove = (item,index) => {
classWorkConfigForm.studentlist.splice(index, 1);
// []]
proxy.$refs.treeRef.setChecked(item.id, false, true);
//TODO
// const ids = this.$refs.treeRef.getCheckedKeys();
// console.log(ids)
// console.log(ids.filter((_item)=>_item == item.id),'???????')
// if(ids&&ids.filter((_item)=>_item == item.id).length>0){
// console.log(ids,'?====?')
// console.log(item.id,'?=item.id===?')
// // ?
// this.$refs.treeRef.setChecked(item.id, false, true);
// // setCheckedKeys
// } // }
};
/**
* 处理在作业推送前的任务配置
*/
const openClassWorkConfigDialog = (row, configindex, type) => {
//
workConfDialogOpen.value = true;
classWorkConfigForm.formRowsType = '';//
classWorkConfigForm.formRowsList = null;
if(type == 'list'){
classWorkConfigForm.formRowsType = 'list';
classWorkConfigForm.formRowsList = row;
}else{
classWorkConfigForm.formRowsType = 'item';
classWorkConfigForm.formRowsList = [row];
} }
// TODO
// if (configindex > -1) {
// this.handleClassDialogConfigShow(configindex, 0)
// }
classWorkConfigForm.deaddate = getCurrentTime('YYYY-MM-DD');
classWorkConfigForm.deadhour = getCurrentTime('HH+3');// 3
classWorkConfigForm.deadmin = getCurrentTime('mm');
classWorkConfigForm.timelength = 1;
}
}; };
/**
* 推送配置保存配置
* @param key 'cancel' or 'submit'
*/
const handleWorkConfigUpdate = (key,row) => {
if (key == 'cancel') {
workConfDialogOpen.value = false;
} else if (key == 'submit') {
// 2024-04-08, by jackyshen
// this.classWorkConfigForm.classlist
var clist = [];
var cidlist = [];
for (var i=0; i< classWorkConfigForm.studentlist.length; i++) {
if (cidlist.indexOf(classWorkConfigForm.studentlist[i].classid) == -1) {
// UI
var clsname = '';
for (var d = 0; d<gradeList.value.length; d++) {
if (gradeList.value[d].id == classWorkConfigForm.studentlist[i].classid) {
clsname = gradeList.value[d].caption;
}
}
clist.push({id: classWorkConfigForm.studentlist[i].classid, caption: clsname});
cidlist.push(classWorkConfigForm.studentlist[i].classid);
}
}
// 20240408207
// index > -1
//
//
//
// if (classWorkConfigForm.index > -1) {
// classWorkConfigForm.classWorkConfigList.splice(classWorkConfigForm.activeClassWorkIndex);
// }
//
var hh = classWorkConfigForm.deadhour;
hh = "0"+hh;
hh = hh.substr(hh.length-2, 2);
var mm = classWorkConfigForm.deadmin;
mm = "0"+mm;
mm = mm.substr(mm.length-2, 2);
//
classWorkConfigForm.deaddate = '' + classWorkConfigForm.deaddate;
if (isNaN(classWorkConfigForm.deaddate.substring(0,4))) {
var dd = new Date(classWorkConfigForm.deaddate);
var year = dd.getFullYear(); //
var month = dd.getMonth() + 1; //0-11
month = "0"+month;
month = month.substr(month.length-2,2);
var day = dd.getDate(); //131
day = "0"+day;
day = day.substr(day.length-2,2);
classWorkConfigForm.deaddate = year+'-'+month+'-'+day;
}
classWorkConfigForm.classWorkConfigList = [];
//
for (var i=0; i<clist.length; i++) {
classWorkConfigForm.classWorkConfigList.push({
id: 0,
classid: clist[i].id,
classcaption: clist[i].caption, //
parentid: 0,
worktype: '',
workkey: classWorkConfigForm.workkey,
worktag: '',
entpcourseid: 0,
evalid: 0,
edusubject: '',
edudegree: '',
workdate: '',
title: '',
workcodes: '',
studentlist: classWorkConfigForm.studentlist,
timelength: classWorkConfigForm.timelength,
weights: classWorkConfigForm.weights,
feedtype: classWorkConfigForm.feedtype,
deaddate: classWorkConfigForm.deaddate+' '+hh+":"+mm,
});
}
if(classWorkConfigForm.formRowsType == 'list'){
// list
for(var d=0;d<classWorkConfigForm.formRowsList.length;d++){
classWorkConfigForm.rowid = classWorkConfigForm.formRowsList[d].id;
// 20240308by jackyshen
// classWorkConfigForm.classWorkConfigListtaskList[i]
// classWorkConfigForm.classWorkConfigList
for (var i=0; i<taskList.value.length; i++) {
if (taskList.value[i].id == classWorkConfigForm.rowid) {
taskList.value[i].taskconfig = classWorkConfigForm.classWorkConfigList;
break;
}
}
}
}else{
// item
classWorkConfigForm.rowid = classWorkConfigForm.formRowsList[0].id;
// 20240308by jackyshen
// classWorkConfigForm.classWorkConfigListtaskList[i]
// classWorkConfigForm.classWorkConfigList
for (var i=0; i<taskList.value.length; i++) {
if (taskList.value[i].id == classWorkConfigForm.rowid) {
taskList.value[i].taskconfig = classWorkConfigForm.classWorkConfigList;
break;
}
}
}
//
classWorkConfigForm.id = 0;
classWorkConfigForm.index = -1;
classWorkConfigForm.selclassid = 0;
classWorkConfigForm.classlist = [];
classWorkConfigForm.studentlist = [];
classWorkConfigForm.feedtype = '必做';
classWorkConfigForm.workkey = '';
classWorkConfigForm.selgroupid = 0;
classWorkConfigForm.classGroups = [];
classWorkConfigForm.availableStudents = [];
classWorkConfigForm.deaddate = getCurrentTime('YYYY-MM-DD');
classWorkConfigForm.deadhour = getCurrentTime('HH+3');
classWorkConfigForm.deadmin = getCurrentTime('mm');
classWorkConfigForm.timelength = 1;
classWorkConfigForm.weights = 1;
}
};
/**
* 推送
*/
const handleTaskAssignToAllClassType = async() => {
if(classWorkConfigForm.studentlist.length == 0){
return proxy.$modal.msgWarning('请选择需要推送的学生!');
}
// this.classWorkToStudent_Loading = true;
//
handleWorkConfigUpdate('submit', '')
const { chapterId } = await useGetHomework(courseObj.node)
// this.entpcourseid = chapterId
console.log(taskList.value,'===============this.taskListthis.taskList')
var ttt = [];
for (var i=0; i<taskList.value.length; i++) {
// 20240408, by jackyshen
// taskconfig.classWorkList
for (var t=0; t<taskList.value[i].taskconfig.length; t++) {
if (taskList.value[i].taskconfig[t].id == 0) {
ttt.push({
id: 0,
parentid: taskList.value[i].id,
classid: taskList.value[i].taskconfig[t].classid,
classcourseid: 0,
entpcourseid: chapterId,
studentlist: JSON.stringify(taskList.value[i].taskconfig[t].studentlist),
feedback: taskList.value[i].taskconfig[t].feedtype,
workkey: taskList.value[i].taskconfig[t].workkey,
timelength: taskList.value[i].taskconfig[t].timelength,
weights: taskList.value[i].taskconfig[t].weights,
deaddate: taskList.value[i].taskconfig[t].deaddate,
workdate: getCurrentTime('YYYY-MM-DD'),
uniquekey: taskList.value[i].uniquekey,
entpcourseworklist: '['+taskList.value[i].entpcourseworklist+']', // JSON
needMsgNotifine: 'false',
msgkey: 'newclasswork',
title: taskList.value[i].title,
status:'1',
msgcontent: '', // classworkjson
teachername: userStore.nickName,
unixstamp: new Date().getTime(),
});
}
}
}
console.log(ttt,'===============ttt')
if(ttt.length == 0){
proxy.$modal.msgError('您还未进行作业配置,请配置后再推送');
return;
}
var wForm = {};
wForm.classworkarray = JSON.stringify(ttt);
saveByClassWorkArray(wForm).then(response => {
console.log(response,'===============response');
// this.classWorkToStudent_Loading = false;
workConfDialogOpen.value = false;
proxy.$modal.msgSuccess("作业推送成功");
//
proxy.$refs.treeRef.setCheckedKeys([]);
//
nextTick(() => {
getTaskList();
})
}).catch((error) =>{
// this.classWorkToStudent_Loading = false;
workConfDialogOpen.value = false;
});
};
/**
* 一键推送
*/
const handleTaskAssignToAllClass = () => {
let rows = proxy.$refs.taskTable.getSelectionRows();
if (rows.length > 0) {
proxy.$modal.confirm('是否确认推送选中的学习任务?').then(()=> {
}).then(() => {
//
openClassWorkConfigDialog(rows, -1,'list')
}).catch(() => {})
}else{
return proxy.$modal.alertWarning("请选择需要推送的任务!");
}
}
/**
* 设计作业
*/
const handleNewClassWorkDialog = () => {
//
router.push({ path: '/newClassTask' });
}
// - // -
const submitWorkTitle = () => { const submitWorkTitle = () => {

View File

@ -121,9 +121,7 @@
:max="classWorkFormScore.teacherRating[sIndex].maxScore" :max="classWorkFormScore.teacherRating[sIndex].maxScore"
size="small" size="small"
:disabled=" :disabled="
(quItem.worktype == '单选题' || quItem.worktype == '多选题') && (quItem.worktype == '单选题' || quItem.worktype == '多选题' || quItem.worktype == '判断题')
stuItem.feedcontent == stuItem.rightanswer &&
stuItem.feedcontent != ''
? true ? true
: false : false
" "

View File

@ -33,13 +33,13 @@
v-if="classWorkAnalysis.row.worktype == '习题训练'" v-if="classWorkAnalysis.row.worktype == '习题训练'"
:type="classWorkAnalysis.view == 'quizStats' ? 'success' : ''" :type="classWorkAnalysis.view == 'quizStats' ? 'success' : ''"
@click="workHandle('quizStats')" @click="workHandle('quizStats')"
>作业概况</el-button >逐题分析</el-button
> >
<el-button <el-button
v-if="classWorkAnalysis.row.worktype == '习题训练'" v-if="classWorkAnalysis.row.worktype == '习题训练'"
:type="classWorkAnalysis.view == 'report' ? 'success' : ''" :type="classWorkAnalysis.view == 'report' ? 'success' : ''"
@click="handleClassOverviewOpen('report')" @click="handleClassOverviewOpen('report')"
>作业报告</el-button >整体分析</el-button
> >
</el-button-group> </el-button-group>
</el-row> </el-row>
@ -81,12 +81,17 @@
> >
<el-table-column type="index" label="序号" width="52" reserve-selection align="center" /> <el-table-column type="index" label="序号" width="52" reserve-selection align="center" />
<el-table-column label="姓名" prop="studentname" width="100" align="center" /> <el-table-column label="姓名" prop="studentname" width="100" align="center" />
<el-table-column label="提交时间" prop="updatedate" width="170" align="center" /> <el-table-column :label="tableRadio.value==0?'提交状态':'提交时间'" prop="updatedate" width="170" align="center">
<template #default="scope">
<span v-if="tableRadio.value==0" style="color: #2196f3">未提交</span>
<span v-if="tableRadio.value==1">{{ scope.row.updatedate }}</span>
</template>
</el-table-column>
<el-table-column label="批阅状态" prop="teacherRating" align="center" width="120" sortable> <el-table-column label="批阅状态" prop="teacherRating" align="center" width="120" sortable>
<template #default="scope"> <template #default="scope">
<template v-if="scope.row.teacherRating == 0" <template v-if="scope.row.teacherRating == 0">
><span style="color: #2196f3">待批阅</span></template <span v-if="tableRadio.value==1" style="color: #2196f3">待批阅</span>
> </template>
<!-- 1- 2-优减 3- 4-良减 5- --> <!-- 1- 2-优减 3- 4-良减 5- -->
<template v-if="scope.row.teacherRating == 1" <template v-if="scope.row.teacherRating == 1"
><el-tag type="danger"></el-tag></template ><el-tag type="danger"></el-tag></template
@ -136,12 +141,12 @@
</div> </div>
</div> </div>
<!-- 作业概况 --> <!-- 逐题分析 -->
<div v-else-if="classWorkAnalysis.view == 'quizStats'"> <div v-else-if="classWorkAnalysis.view == 'quizStats'">
<quiz-stats :active-data="classWorkActiveData" /> <quiz-stats :active-data="classWorkActiveData" />
</div> </div>
<!-- 作业报告--> <!-- 整体分析-->
<div v-else-if="classWorkAnalysis.view == 'report'" style="overflow-y: scroll"> <div v-else-if="classWorkAnalysis.view == 'report'" style="overflow-y: scroll">
<!-- <ClassOverview :table-list="overviewData" :eval-id="courseObj.evalid"></ClassOverview> --> <!-- <ClassOverview :table-list="overviewData" :eval-id="courseObj.evalid"></ClassOverview> -->
<ClassOverview :table-list="overviewData"></ClassOverview> <ClassOverview :table-list="overviewData"></ClassOverview>
@ -188,7 +193,7 @@ const tableRadio = reactive({
const loading_dt_table = ref(false) const loading_dt_table = ref(false)
const isopen_dtwk_table = ref(false) const isopen_dtwk_table = ref(false)
// zdg: // zdg:
const classWorkActiveData = reactive({ const classWorkActiveData = reactive({
quizlist: [], // quizlist: [], //
studentList: [], // - studentList: [], // -
@ -349,7 +354,7 @@ const getClassWorkStudentList = (rowId) => {
// .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: """" // json .replace(/""/g, '"') eg: """"
response.rows[i].classworkevallist = escapeHtmlQuotes(response.rows[i].classworkevallist) response.rows[i].classworkevallist = escapeHtmlQuotes(response.rows[i].classworkevallist)
console.log('学生完成情况分析classworkevallist', response.rows[i].classworkevallist) //console.log('classworkevallist', response.rows[i].classworkevallist)
const evalarray = JSON.parse('[' + response.rows[i].classworkevallist + ']') const evalarray = JSON.parse('[' + response.rows[i].classworkevallist + ']')
var scoingCount = 0 var scoingCount = 0
var feedcount = 0 var feedcount = 0
@ -362,7 +367,7 @@ const getClassWorkStudentList = (rowId) => {
} }
} }
} }
console.log(evalarray, 'evalarray------------------------------------') //console.log(evalarray, 'evalarray------------------------------------')
if (feedcount > 0) { if (feedcount > 0) {
// : /*100 // : /*100
response.rows[i].scoingRate = ((scoingCount / feedcount) * 100).toFixed(0) + '%' response.rows[i].scoingRate = ((scoingCount / feedcount) * 100).toFixed(0) + '%'
@ -531,7 +536,7 @@ const escapeHtmlQuotes = (str) => {
return result; return result;
} }
//#region //#region
// - // -
const workHandle = (type) => { const workHandle = (type) => {
// ui // ui
@ -566,11 +571,11 @@ const getWorkFeedList = async() =>{
//#endregion //#endregion
//#regin //#regin
/* /*
author: yangws author: yangws
time: 2024-8-06 16:35:33 time: 2024-8-06 16:35:33
function:作业报告的处理 function: 整体分析的处理
*/ */
const handleClassOverviewOpen = (type) =>{ const handleClassOverviewOpen = (type) =>{
// ui // ui
@ -638,12 +643,12 @@ const closeDialog = () => {
watch(classWorkAnalysis, (newVal, oldVal) => { watch(classWorkAnalysis, (newVal, oldVal) => {
if(newVal.view != 'quizStats'){ if(newVal.view != 'quizStats'){
console.log('关闭zdg: 定时执行') console.log('关闭zdg: 定时执行')
clearInterval(classWorkActiveData.timerId) // clearInterval(classWorkActiveData.timerId) //
} }
}) })
onUnmounted(() => { onUnmounted(() => {
clearInterval(classWorkActiveData.timerId) // clearInterval(classWorkActiveData.timerId) //
}) })
defineExpose({ defineExpose({

View File

@ -7,9 +7,9 @@
<el-row class="top"> <el-row class="top">
<el-col :span="24"> <el-col :span="24">
<el-form-item label="作业类型:"> <el-form-item label="作业类型:">
<el-radio-group v-model="formType" @change="changeFormType"> <el-radio-group v-model="classWorkForm.worktype" @change="changeFormType">
<template v-for="(item) in listWorkType" :key="item"> <template v-for="(item) in listWorkType" :key="item">
<el-radio :value="item" >{{ item }}</el-radio> <el-radio :value="item" :disabled="props.isedit">{{ item }}</el-radio>
</template> </template>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
@ -21,12 +21,12 @@
<div v-if="classWorkForm.worktype == '课堂展示'" style="height: 100%; display: flex; flex-direction: column;"> <div v-if="classWorkForm.worktype == '课堂展示'" style="height: 100%; display: flex; flex-direction: column;">
<div style="flex: 0 0 auto;"> <div style="flex: 0 0 auto;">
<el-form-item label="问题"> <el-form-item label="问题">
<el-input v-model="question" type="text" placeholder="请输入问题" /> <el-input v-model="classWorkForm.title" type="text" placeholder="请输入问题" />
</el-form-item> </el-form-item>
</div> </div>
<div v-loading="boardLoading" class="board-wrap" style="height: 100%; flex: 1; overflow: hidden;"> <div v-loading="boardLoading" class="board-wrap" style="height: 100%; flex: 1; overflow: hidden;">
<!-- <whiteboard v-if="isShowBoard" ref="boardref" :height="mainHeight - 150" :isShowSave="false" :data="whiteboardObj"/> --> <!-- <whiteboard v-if="isShowBoard" ref="boardref" :height="mainHeight - 150" :isShowSave="false" :data="whiteboardObj"/> -->
<whiteboard ref="boardref" :height="mainHeight - 150" :isShowSave="false" :data="whiteboardObj"/> <whiteboard ref="boardref" :height="mainHeight - 150" :isShowSave="false" :data="classWorkForm.whiteboardObj"/>
</div> </div>
</div> </div>
<div v-else class="el-form-work-list"> <div v-else class="el-form-work-list">
@ -154,7 +154,7 @@
</template> </template>
<template v-if="classWorkForm.worktype =='常规作业'"> <template v-if="classWorkForm.worktype =='常规作业'">
<div v-loading="fileLoading" class="upload-homework"> <div v-loading="fileLoading" class="upload-homework">
<FileUpload v-model="fileHomeworkList" :fileSize="800" :fileType="['mp3','mp4','doc','docx','xlsx','xls','pdf','ppt','pptx','jpg','jpeg','gif','png','txt']"/> <FileUpload v-model="classWorkForm.fileHomeworkList" :fileSize="800" :fileType="['mp3','mp4','doc','docx','xlsx','xls','pdf','ppt','pptx','jpg','jpeg','gif','png','txt']"/>
</div> </div>
</template> </template>
</div> </div>
@ -180,7 +180,7 @@
<div v-if="classWorkForm.worktype!='习题训练'" :style="{'overflow': 'auto', 'border':'1px dotted blue','border-radius':'5px', 'background-color': '#f7f7f7'}"> <div v-if="classWorkForm.worktype!='习题训练'" :style="{'overflow': 'auto', 'border':'1px dotted blue','border-radius':'5px', 'background-color': '#f7f7f7'}">
<div style="margin: 5px; background-color: white"> <div style="margin: 5px; background-color: white">
<template v-for="(item) in chooseWorkLists" :key="item.id"> <template v-for="(item) in classWorkForm.chooseWorkLists" :key="item.id">
<div v-if="item.worktype==classWorkForm.worktype"> <div v-if="item.worktype==classWorkForm.worktype">
<div class="choose-work"> <div class="choose-work">
<div class="choose-work-title">{{ item.worktype }}</div> <div class="choose-work-title">{{ item.worktype }}</div>
@ -252,7 +252,7 @@ import { useRouter } from 'vue-router'
import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork' import {listEntpcoursework, listEntpcourseworkNew, getEntpcoursework} from '@/api/education/entpCourseWork'
import { addClassworkReturnId } from '@/api/teaching/classwork' import { addClassworkReturnId } from '@/api/teaching/classwork'
import { updateClasswork, listEvaluationclue,readFile, listClassworkeval,delClassworkeval,addClassworkeval } from '@/api/classTask' import { updateClasswork, listEvaluationclue,readFile, listClassworkeval,delClassworkeval,addClassworkeval,updateClassworkeval } from '@/api/classTask'
import { listEvaluation } from '@/api/subject' import { listEvaluation } from '@/api/subject'
import { listEntpcoursefile } from '@/api/education/entpcoursefile' import { listEntpcoursefile } from '@/api/education/entpcoursefile'
import { listKnowledgePoint } from "@/api/knowledge/knowledgePoint"; import { listKnowledgePoint } from "@/api/knowledge/knowledgePoint";
@ -279,6 +279,10 @@ const props = defineProps({
propsformobj: { propsformobj: {
type: Object, type: Object,
default: () =>({}) default: () =>({})
},
isedit: {
type: Boolean,
default: false
} }
}) })
@ -289,11 +293,6 @@ const openDialog = () => {
isDialogOpen.value = true isDialogOpen.value = true
} }
const classWorkFormRef = ref(null); const classWorkFormRef = ref(null);
const formType = ref('习题训练')
const newWorkSpaceEdit = ref(false); //
// ---------------------------------------------------
const listWorkType = ref(['习题训练', '框架梳理', '课堂展示', '常规作业']); //
const entpCourseWorkTypeList = ref([ const entpCourseWorkTypeList = ref([
{value: 0, label: "不限"}, {value: 0, label: "不限"},
{value: 1, label: "单选题"}, {value: 1, label: "单选题"},
@ -360,17 +359,19 @@ const workResource = reactive({
}); // }); //
let classWorkForm = reactive({ let classWorkForm = reactive({
id: cloneDeep(props.propsformobj.id), id: cloneDeep(props.propsformobj.id),
uniquekey: cloneDeep(props.propsformobj.uniquekey), // uniquekey: props.propsformobj.uniquekey?cloneDeep(props.propsformobj.uniquekey):'', //
worktype: props.propsformobj.worktype?cloneDeep(props.propsformobj.worktype): '习题训练', // worktype: props.propsformobj.worktype?cloneDeep(props.propsformobj.worktype): '习题训练', //
title: props.propsformobj.title?cloneDeep(props.propsformobj.title):'',// title: props.propsformobj.title?cloneDeep(props.propsformobj.title):'',//
quizlist: props.propsformobj.quizlist?cloneDeep(props.propsformobj.quizlist):[] // quizlist: props.propsformobj.quizlist?cloneDeep(props.propsformobj.quizlist):[], //
chooseWorkLists: props.propsformobj.chooseWorkLists?cloneDeep(props.propsformobj.chooseWorkLists):[], // list
fileHomeworkList: props.propsformobj.fileHomeworkList?cloneDeep(props.propsformobj.fileHomeworkList):[], //
whiteboardObj: props.propsformobj.whiteboardObj?cloneDeep(props.propsformobj.whiteboardObj):'', // -
}); // }); //
const chooseWorkLists = ref([]); // // ---------------------------------------------------
const whiteboardObj = ref(''); // - const listWorkType = ref(['习题训练', '框架梳理', '课堂展示', '常规作业']); //
// ------- // -------
const boardLoading = ref(false); const boardLoading = ref(false);
const isShowBoard = ref(false); //
const question = ref(''); // --
const prevReadMsg = reactive({ const prevReadMsg = reactive({
visible: false, visible: false,
type: "" type: ""
@ -379,13 +380,11 @@ const prevReadMsg = reactive({
const flowData = ref({})// const flowData = ref({})//
//---------- //----------
const fileLoading = ref(false); // loading const fileLoading = ref(false); // loading
const fileHomeworkList = ref([]);//
/*** /***
* 作业类型切换 * 作业类型切换
*/ */
const changeFormType = (val) => { const changeFormType = (val) => {
console.log(val)
classWorkForm.worktype = val; classWorkForm.worktype = val;
} }
@ -628,7 +627,7 @@ const prevRead = async (item) => {
// //
const handleClassWorkAddOfResource = (work) => { const handleClassWorkAddOfResource = (work) => {
// //
let arrSole = chooseWorkLists.value.filter((item) => { let arrSole = classWorkForm.chooseWorkLists.filter((item) => {
return item.worktype === classWorkForm.worktype return item.worktype === classWorkForm.worktype
}) })
// //
@ -637,25 +636,29 @@ const handleClassWorkAddOfResource = (work) => {
return; return;
} }
// //
let arr = chooseWorkLists.value.filter((item) => { let arr = classWorkForm.chooseWorkLists.filter((item) => {
return item.id === work.id return item.id === work.id
}) })
if (arr.length===0) { if (arr.length===0) {
work.score = 1; work.score = 1;
chooseWorkLists.value.push(work); classWorkForm.chooseWorkLists.push(work);
} }
}; };
/** /**
* 删除作业 * 右侧资源删除作业 非习题list
*/ */
const deleteClassWorkAddOfResource = (work) => { const deleteClassWorkAddOfResource = (work) => {
chooseWorkLists.value.filter((item, index) => { classWorkForm.chooseWorkLists.filter((item, index) => {
if (item.id === work.id) { if (item.id === work.id) {
chooseWorkLists.value.splice(index, 1); classWorkForm.chooseWorkLists.splice(index, 1);
return; return;
} }
}) })
} }
/** 右侧资源删除按钮 习题list */
const handleClassWorkFormQuizRemove = (index) =>{
classWorkForm.quizlist.splice(index, 1);
}
@ -713,8 +716,7 @@ const handleClassWorkSave = async () => {
let canvasJson = proxy.$refs.boardref.getCanvasJson() let canvasJson = proxy.$refs.boardref.getCanvasJson()
let canvasBase64 = await proxy.$refs.boardref.getCanvasBase64() let canvasBase64 = await proxy.$refs.boardref.getCanvasBase64()
// //
// cform.worktag = question.value; cform.title = classWorkForm.title;
cform.title = question.value;
cform.workcodes = JSON.stringify({json: canvasJson, base64: canvasBase64}); cform.workcodes = JSON.stringify({json: canvasJson, base64: canvasBase64});
cform.entpcourseworklist = JSON.stringify([{'id':-1, 'score': '10'}]); cform.entpcourseworklist = JSON.stringify([{'id':-1, 'score': '10'}]);
try { try {
@ -727,8 +729,8 @@ const handleClassWorkSave = async () => {
classWorkForm.quizlist = [], // classWorkForm.quizlist = [], //
// //
chooseWorkLists.value = []; classWorkForm.chooseWorkLists = []; // list
whiteboardObj.value = ''; // ? // classWorkForm.whiteboardObj = ''; // ? //
// refresh the list // refresh the list
// //
// this.getClassWorkAllList(); // this.getClassWorkAllList();
@ -747,7 +749,7 @@ const handleClassWorkSave = async () => {
} }
else if(classWorkForm.worktype === "常规作业"){ else if(classWorkForm.worktype === "常规作业"){
fileLoading.value = true fileLoading.value = true
cform.workcodes = JSON.stringify(fileHomeworkList.value); cform.workcodes = JSON.stringify(classWorkForm.fileHomeworkList);
cform.entpcourseworklist = JSON.stringify([{'id':-2, 'score': '10'}]); cform.entpcourseworklist = JSON.stringify([{'id':-2, 'score': '10'}]);
try { try {
addClassworkReturnId(cform).then(() => { addClassworkReturnId(cform).then(() => {
@ -759,9 +761,9 @@ const handleClassWorkSave = async () => {
classWorkForm.quizlist = [], // classWorkForm.quizlist = [], //
// //
chooseWorkLists.value = []; classWorkForm.chooseWorkLists = []; // list
whiteboardObj.value = ''; // ? // classWorkForm.whiteboardObj = ''; // ? //
fileHomeworkList.value = []; // list classWorkForm.fileHomeworkList = []; // list
// refresh the list // refresh the list
// //
// this.getClassWorkAllList(); // this.getClassWorkAllList();
@ -788,7 +790,7 @@ const handleClassWorkSave = async () => {
ll.push({'id': classWorkForm.quizlist[i].id, 'score': classWorkForm.quizlist[i].score}); ll.push({'id': classWorkForm.quizlist[i].id, 'score': classWorkForm.quizlist[i].score});
} }
}else if( classWorkForm.worktype === "框架梳理") { }else if( classWorkForm.worktype === "框架梳理") {
chooseWorkLists.value.filter((item) => { classWorkForm.chooseWorkLists.filter((item) => {
if (item.worktype === classWorkForm.worktype) { if (item.worktype === classWorkForm.worktype) {
ll.push({'id':item.id, 'score': item.score}); ll.push({'id':item.id, 'score': item.score});
} }
@ -812,8 +814,8 @@ const handleClassWorkSave = async () => {
classWorkForm.quizlist = [], // classWorkForm.quizlist = [], //
// //
chooseWorkLists.value = []; classWorkForm.chooseWorkLists = [];
whiteboardObj.value = ''; // ? // classWorkForm.whiteboardObj = ''; // ? //
// refresh the list // refresh the list
// //
// this.getClassWorkAllList(); // this.getClassWorkAllList();
@ -844,7 +846,7 @@ const editWork = async (cform) =>{
// //
}else { }else {
if (chooseWorkLists.value.length == 0) { if (classWorkForm.chooseWorkLists.length == 0) {
// //
ElMessage.error('请先添加作业资源!'); ElMessage.error('请先添加作业资源!');
return; return;
@ -893,74 +895,55 @@ const editWork = async (cform) =>{
} }
} }
// 3. // 3.-
// const evalid = this.homeworkLesson.length==0 ? '' : this.homeworkLesson.length==1 ? this.homeworkLesson[0] : this.homeworkLesson[1]; }
// const formObj = { else if (classWorkForm.worktype=='框架梳理') {
// id: this.currentTask.id, // 1.workidid
// uniquekey: this.classWorkForm.uniquekey, // [] const wevalres = await listClassworkeval({'workid': classWorkForm.id});
// // warn: if (wevalres.rows.length == 0) {
// //evalid = evalid, // [] ElMessage.error('未找到原框架梳理任务,请或退出重试');
// } return;
// let res = await updateClasswork(cform); }
// 2.
let needUplEval = false;
if (classWorkForm.chooseWorkLists.length !== props.propsformobj.chooseWorkLists.length) {
needUplEval = true;
}else {
//
needUplEval = classWorkForm.chooseWorkLists.some(cur =>
!props.propsformobj.chooseWorkLists.some(last =>
last.id === cur.id && last.score === cur.score
)
);
}
if (needUplEval) {
const uplParams = {
id: wevalres.rows[0].id,
entpcourseworkid: classWorkForm.chooseWorkLists[0].id,
score: classWorkForm.chooseWorkLists[0].score,
}
//
let res = await updateClassworkeval(uplParams);
}
}
else if (classWorkForm.worktype=='课堂展示') {
let canvasJson = proxy.$refs.boardref.getCanvasJson()
let canvasBase64 = await proxy.$refs.boardref.getCanvasBase64()
cform.workcodes = JSON.stringify({json: canvasJson, base64: canvasBase64});
}
else if (classWorkForm.worktype=='常规作业') {
// 1. (, )
cform.workcodes = JSON.stringify(classWorkForm.fileHomeworkList);
}
// 3.
let res = await updateClasswork(cform); let res = await updateClasswork(cform);
if (res.code == 200) { if (res.code == 200) {
ElMessage.success('更新成功'); ElMessage.success('更新成功');
// //
router.back() router.back()
} }
}
// else if (classWorkForm.worktype=='') {
// // 1.workidid
// const wevalres = await listClassworkeval({'workid': this.currentTask.id});
// if (wevalres.rows.length == 0) {
// ElMessage.error('退');
// return;
// }
// // 2.
// let needUplEval = false;
// if (this.chooseWorkLists.length !== this.currentTask.entpcourseworklistarray.length) {
// needUplEval = true;
// }else {
// //
// needUplEval = this.chooseWorkLists.some(cur =>
// !this.currentTask.entpcourseworklistarray.some(last =>
// last.id === cur.id && last.score === cur.score
// )
// );
// }
// if (needUplEval) {
// const uplParams = {
// id: wevalres.rows[0].id,
// entpcourseworkid: this.chooseWorkLists[0].id,
// score: this.chooseWorkLists[0].score,
// }
// let res = await updateClassworkeval(uplParams);
// }
// }else if (classWorkForm.worktype=='') {
// }else if (classWorkForm.worktype=='') {
// // 1. (, )
// classWorkParams.workcodes = JSON.stringify(this.fileHomeworkList);
// }
// // 3.
// let res = await updateClasswork(cform);
// this.fileHomeworkList = [];
// this.chooseWorkLists = [];
// // 4.
// //
// // this.getClassWorkAllList();
// this.classWorkForm.worktype = "";
// this.newWorkSpace = false;
// this.newWorkSpaceEdit = false;
// this.workEdit = false;
} }
@ -968,7 +951,12 @@ const editWork = async (cform) =>{
onMounted(() => { onMounted(() => {
}) })
watch(() => props.propsformobj.uniquekey, (newVal) => {
console.log(props.propsformobj,'propsformobj')
if(props.propsformobj.uniquekey){
classWorkForm.uniquekey = props.propsformobj.uniquekey?cloneDeep(props.propsformobj.uniquekey):''; //
}
})
watch(() => props.bookobj.levelSecondId, (newVal) => { watch(() => props.bookobj.levelSecondId, (newVal) => {
console.log(props.bookobj,'课程选择') console.log(props.bookobj,'课程选择')
// //

View File

@ -1,6 +1,6 @@
<template> <template>
<el-row class="c-warp" :gutter="10"> <el-row class="c-warp" :gutter="10">
<el-col class="left" :span="12"> <el-col class="left" :span="14">
<el-collapse class="c-item" v-model="activeTopic" accordion> <el-collapse class="c-item" v-model="activeTopic" accordion>
<template v-for="(item, index) in dataList"> <template v-for="(item, index) in dataList">
<el-collapse-item class="collapse-item" :name="index+1" :id="'collapse-'+(index+1)"> <el-collapse-item class="collapse-item" :name="index+1" :id="'collapse-'+(index+1)">
@ -54,9 +54,9 @@
</template> </template>
</el-collapse> </el-collapse>
</el-col> </el-col>
<el-col class="right" :span="12"> <el-col class="right" :span="10">
<div class="c-item"> <div class="c-item">
<div class="title">答题情况</div> <div class="title">提交情况</div>
<div class="respond"> <div class="respond">
<el-space wrap> <el-space wrap>
<!-- <template v-for="it in 11"> --> <!-- <template v-for="it in 11"> -->
@ -114,7 +114,9 @@ colorArr = [
] ]
// === === // === ===
onMounted(() => {}) onMounted(() => {
activeTopic.value = dataList.value.map((_, index) => index + 1);
})
// === (methods) === // === (methods) ===
@ -311,7 +313,7 @@ watchEffect(() => { initData() })
background: #F2F3F5; background: #F2F3F5;
height: 100%; height: 100%;
margin: 0 !important; margin: 0 !important;
.left{padding-left: 0 !important;} .left{padding-left: 0 !important; height: 100%;}
.right{padding-right: 0 !important;} .right{padding-right: 0 !important;}
.c-item{ .c-item{
padding: 10px; padding: 10px;
@ -345,6 +347,7 @@ watchEffect(() => { initData() })
} }
.t-left{width: 160px;text-align: left;} .t-left{width: 160px;text-align: left;}
.c-respond{ .c-respond{
text-align: left;
.el-tag{margin: 0 5px;} .el-tag{margin: 0 5px;}
} }
} }
@ -359,7 +362,7 @@ watchEffect(() => { initData() })
margin-bottom: 10px; margin-bottom: 10px;
} }
.respond{ .respond{
height: calc(70vh - 65px); height: calc(100% - 65px);
overflow: auto; overflow: auto;
.el-space{padding: 5px;} .el-space{padding: 5px;}
.card-warp{ .card-warp{

View File

@ -77,6 +77,7 @@ const props = defineProps({
border-radius: 10px; border-radius: 10px;
padding: 10px 5px; padding: 10px 5px;
margin-bottom: 10px; margin-bottom: 10px;
cursor: pointer;
.class-reserv-item-body { .class-reserv-item-body {
flex: 1; flex: 1;

View File

@ -15,11 +15,16 @@
<!-- 标题 --> <!-- 标题 -->
<el-row style="align-items: center; margin-bottom: 0px; flex: 0 0 auto"> <el-row style="align-items: center; margin-bottom: 0px; flex: 0 0 auto">
<el-col :span="12" style="padding-left: 20px; text-align: left;"> <el-col :span="12" style="padding-left: 20px; text-align: left;">
<div class="unit-top-left" @click="isCollapse = !isCollapse"> <div v-if="!isOpenLeftBook" class="unit-top-left cursor-pointer" @click="onOpenLeftBook">
<i v-if="!isCollapse" class="iconfont icon-xiangzuo" style="color: blue;"></i> <i v-if="!isCollapse" class="iconfont icon-xiangzuo" style="color: blue;"></i>
<span>课程目录</span> <span>课程目录</span>
<i v-if="isCollapse" class="iconfont icon-xiangyou" style="color: blue;"></i> <i v-if="isCollapse" class="iconfont icon-xiangyou" style="color: blue;"></i>
</div> </div>
<div v-else class="unit-top-left">
<i class="iconfont icon-xiangzuo cursor-pointer" style="color: blue;" @click="goBack">返回上页</i>
<span>课程</span>
<span>{{bookTitle}}</span>
</div>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<div class="classtype-right"> <div class="classtype-right">
@ -30,13 +35,13 @@
</el-col> </el-col>
</el-row> </el-row>
<!-- 作业类型:内容 --> <!-- 作业类型:内容 -->
<task-type-view :bookobj="courseObj" :propsformobj="classWorkForm" style="flex: 1; overflow: hidden;"/> <task-type-view :bookobj="courseObj" :propsformobj="classWorkForm" :isedit="isOpenLeftBook" style="flex: 1; overflow: hidden;"/>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { onMounted, ref, toRaw,watch, reactive } from 'vue' import { onMounted, ref, toRaw,watch, reactive, getCurrentInstance } from 'vue'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import ChooseTextbook from '@/components/choose-textbook/index.vue' import ChooseTextbook from '@/components/choose-textbook/index.vue'
@ -45,8 +50,13 @@ import { getCurrentTime } from '@/utils/date'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
const userStore = useUserStore().user const userStore = useUserStore().user
const route = useRoute(); const route = useRoute();
const router = useRouter()
const { proxy } = getCurrentInstance()
const classtaskObj = route.query.classtaskObj;// const classtaskObj = route.query.classtaskObj;//
const bookTitle = ref(classtaskObj? JSON.parse(classtaskObj).bookName: '');//
const isOpenLeftBook = ref(classtaskObj? JSON.parse(classtaskObj).id ? true : false: false ); //
const isCollapse = ref(isOpenLeftBook.value?true:false); // : false
// --------------------------------------------------- // ---------------------------------------------------
const classWorkForm = reactive({ const classWorkForm = reactive({
id: classtaskObj? JSON.parse(classtaskObj).id : '', // id id: classtaskObj? JSON.parse(classtaskObj).id : '', // id
@ -54,9 +64,11 @@ const classWorkForm = reactive({
title: classtaskObj? JSON.parse(classtaskObj).title : '', // title: classtaskObj? JSON.parse(classtaskObj).title : '', //
worktype: classtaskObj? JSON.parse(classtaskObj).worktype : '', // worktype: classtaskObj? JSON.parse(classtaskObj).worktype : '', //
quizlist: classtaskObj? JSON.parse(classtaskObj).quizlist : [], // quizlist: classtaskObj? JSON.parse(classtaskObj).quizlist : [], //
chooseWorkLists: classtaskObj? JSON.parse(classtaskObj).chooseWorkLists : [],// list
fileHomeworkList: classtaskObj? JSON.parse(classtaskObj).fileHomeworkList : [],// list
whiteboardObj: classtaskObj? JSON.parse(classtaskObj).whiteboardObj : '',//
}) })
const isCollapse = ref(false)
const courseObj = reactive({ const courseObj = reactive({
// : id,id,id, // : id,id,id,
@ -67,7 +79,6 @@ const courseObj = reactive({
node: null, // node: null, //
// //
}) })
// --------------------------------------------------- // ---------------------------------------------------
@ -94,16 +105,32 @@ const getData = (data) => {
localStorage.setItem('unitId', JSON.stringify({ levelFirstId, levelSecondId})) localStorage.setItem('unitId', JSON.stringify({ levelFirstId, levelSecondId}))
} }
const onOpenLeftBook = () => {
if(isOpenLeftBook.value){
//
proxy.$modal.msgError(`当前为编辑状态不可选择课程!`);
}else{
//
isCollapse.value = !isCollapse.value
}
}
// ---
const goBack = () =>{
router.back()
}
onMounted(() => { onMounted(() => {
// init() //
// sourceStore.getCreate() if(classtaskObj&&JSON.parse(classtaskObj).bookObj){
const bookobj = JSON.parse(classtaskObj).bookObj;
courseObj.textbookId = bookobj.bookObj //
courseObj.levelFirstId = bookobj.levelFirstId //
courseObj.levelSecondId = bookobj.levelSecondId //
courseObj.coursetitle = bookobj.node.itemtitle // (/)
courseObj.node = bookobj.node; //
}
}) })
// const init = () => {
// classWorkForm.uniquekey = userStore.edusubject+'-' + getCurrentTime('MMDD')+'-'+(1);
// }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -120,8 +147,10 @@ onMounted(() => {
width: 300px; width: 300px;
min-height: 100%; min-height: 100%;
} }
.cursor-pointer {
cursor: pointer;//
}
.unit-top-left { .unit-top-left {
cursor: pointer;
.icon-xiangzuo { .icon-xiangzuo {
margin-right: 5px; margin-right: 5px;

View File

@ -23,13 +23,13 @@
v-if="classWorkAnalysis.row.worktype == '习题训练'" v-if="classWorkAnalysis.row.worktype == '习题训练'"
:type="classWorkAnalysis.view == 'quizStats' ? 'success' : ''" :type="classWorkAnalysis.view == 'quizStats' ? 'success' : ''"
@click="workHandle('quizStats')" @click="workHandle('quizStats')"
>作业概况</el-button >逐题分析</el-button
> >
<el-button <el-button
v-if="classWorkAnalysis.row.worktype == '习题训练'" v-if="classWorkAnalysis.row.worktype == '习题训练'"
:type="classWorkAnalysis.view == 'report' ? 'success' : ''" :type="classWorkAnalysis.view == 'report' ? 'success' : ''"
@click="handleClassOverviewOpen('report')" @click="handleClassOverviewOpen('report')"
>作业报告</el-button >整体分析</el-button
> >
</el-button-group> </el-button-group>
</div> </div>
@ -71,12 +71,17 @@
> >
<el-table-column type="index" label="序号" width="52" reserve-selection align="center" /> <el-table-column type="index" label="序号" width="52" reserve-selection align="center" />
<el-table-column label="姓名" prop="studentname" width="100" align="center" /> <el-table-column label="姓名" prop="studentname" width="100" align="center" />
<el-table-column label="提交时间" prop="updatedate" width="170" align="center" /> <el-table-column :label="tableRadio.value==0?'提交状态':'提交时间'" prop="updatedate" width="170" align="center">
<template #default="scope">
<span v-if="tableRadio.value==0" style="color: #2196f3">未提交</span>
<span v-if="tableRadio.value==1">{{ scope.row.updatedate }}</span>
</template>
</el-table-column>
<el-table-column label="批阅状态" prop="teacherRating" align="center" width="120" sortable> <el-table-column label="批阅状态" prop="teacherRating" align="center" width="120" sortable>
<template #default="scope"> <template #default="scope">
<template v-if="scope.row.teacherRating == 0" <template v-if="scope.row.teacherRating == 0">
><span style="color: #2196f3">待批阅</span></template <span v-if="tableRadio.value==1" style="color: #2196f3">待批阅</span>
> </template>
<!-- 1- 2-优减 3- 4-良减 5- --> <!-- 1- 2-优减 3- 4-良减 5- -->
<template v-if="scope.row.teacherRating == 1" <template v-if="scope.row.teacherRating == 1"
><el-tag type="danger"></el-tag></template ><el-tag type="danger"></el-tag></template
@ -126,12 +131,12 @@
</div> </div>
</div> </div>
<!-- 作业概况 --> <!-- 逐题分析 -->
<div v-else-if="classWorkAnalysis.view == 'quizStats'" style="width: 100%;"> <div v-else-if="classWorkAnalysis.view == 'quizStats'" style="width: 100%;">
<quiz-stats :active-data="classWorkActiveData" style="width: 100%;height: 100%;"/> <quiz-stats :active-data="classWorkActiveData" style="width: 100%;height: 100%;"/>
</div> </div>
<!-- 作业报告--> <!-- 整体分析-->
<div v-else-if="classWorkAnalysis.view == 'report'" style="width: 100%;overflow-y: scroll"> <div v-else-if="classWorkAnalysis.view == 'report'" style="width: 100%;overflow-y: scroll">
<!-- <ClassOverview :table-list="overviewData" :eval-id="courseObj.evalid"></ClassOverview> --> <!-- <ClassOverview :table-list="overviewData" :eval-id="courseObj.evalid"></ClassOverview> -->
<ClassOverview :table-list="overviewData" style="width: 100%;"></ClassOverview> <ClassOverview :table-list="overviewData" style="width: 100%;"></ClassOverview>
@ -175,7 +180,7 @@ const tableRadio = reactive({
const loading_dt_table = ref(false) const loading_dt_table = ref(false)
const isopen_dtwk_table = ref(false) const isopen_dtwk_table = ref(false)
// zdg: // zdg:
const classWorkActiveData = reactive({ const classWorkActiveData = reactive({
quizlist: [], // quizlist: [], //
studentList: [], // - studentList: [], // -
@ -341,7 +346,7 @@ const getClassWorkStudentList = (rowId) => {
// .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: """" // json .replace(/""/g, '"') eg: """"
response.rows[i].classworkevallist = escapeHtmlQuotes(response.rows[i].classworkevallist) response.rows[i].classworkevallist = escapeHtmlQuotes(response.rows[i].classworkevallist)
console.log('学生完成情况分析classworkevallist', response.rows[i].classworkevallist) //console.log('classworkevallist', response.rows[i].classworkevallist)
const evalarray = JSON.parse('[' + response.rows[i].classworkevallist + ']') const evalarray = JSON.parse('[' + response.rows[i].classworkevallist + ']')
var scoingCount = 0 var scoingCount = 0
var feedcount = 0 var feedcount = 0
@ -354,7 +359,7 @@ const getClassWorkStudentList = (rowId) => {
} }
} }
} }
console.log(evalarray, 'evalarray------------------------------------') //console.log(evalarray, 'evalarray------------------------------------')
if (feedcount > 0) { if (feedcount > 0) {
// : /*100 // : /*100
response.rows[i].scoingRate = ((scoingCount / feedcount) * 100).toFixed(0) + '%' response.rows[i].scoingRate = ((scoingCount / feedcount) * 100).toFixed(0) + '%'
@ -523,7 +528,7 @@ const escapeHtmlQuotes = (str) => {
return result; return result;
} }
//#region //#region
// - // -
const workHandle = (type) => { const workHandle = (type) => {
// ui // ui
@ -531,6 +536,7 @@ const workHandle = (type) => {
classWorkAnalysis.view = type classWorkAnalysis.view = type
const isClose = type != 'quizStats' && !! classWorkActiveData.timerId const isClose = type != 'quizStats' && !! classWorkActiveData.timerId
const isOpen = type == 'quizStats' && !classWorkActiveData.timerId const isOpen = type == 'quizStats' && !classWorkActiveData.timerId
//
if(type == 'quizStats') { if(type == 'quizStats') {
getWorkFeedList(); getWorkFeedList();
} }
@ -557,11 +563,11 @@ const getWorkFeedList = async() =>{
//#endregion //#endregion
//#regin //#regin
/* /*
author: yangws author: yangws
time: 2024-8-06 16:35:33 time: 2024-8-06 16:35:33
function:作业报告的处理 function: 整体分析的处理
*/ */
const handleClassOverviewOpen = (type) =>{ const handleClassOverviewOpen = (type) =>{
// ui // ui
@ -639,12 +645,12 @@ onMounted(() => {
watch(classWorkAnalysis, (newVal, oldVal) => { watch(classWorkAnalysis, (newVal, oldVal) => {
if(newVal.view != 'quizStats'){ if(newVal.view != 'quizStats'){
console.log('关闭zdg: 定时执行') console.log('关闭zdg: 定时执行')
clearInterval(classWorkActiveData.timerId) // clearInterval(classWorkActiveData.timerId) //
} }
}) })
onUnmounted(() => { onUnmounted(() => {
clearInterval(classWorkActiveData.timerId) // clearInterval(classWorkActiveData.timerId) //
}) })
// defineExpose({ // defineExpose({

View File

@ -37,6 +37,7 @@ import { homeworklist } from '@/api/teaching/classwork'
import { getCurrentTime, getTomorrow } from '@/utils/date' import { getCurrentTime, getTomorrow } from '@/utils/date'
import {sessionStore, createWindow} from '@/utils/tool' import {sessionStore, createWindow} from '@/utils/tool'
import { useToolState } from '@/store/modules/tool' import { useToolState } from '@/store/modules/tool'
import {throttle,debounce } from '@/utils/comm'
const user = useUserStore().user const user = useUserStore().user
const toolState = useToolState(); const toolState = useToolState();
@ -67,14 +68,18 @@ const getHomework = async () => {
loading.value = false loading.value = false
} }
} }
const debounceOpenWin = debounce(() => {
toolState.isTaskWin=true; //
createWindow('open-taskwin',{url:'/teachClassTask'}); //
}, 1000);
// //
const onClickItem = (item) => { const onClickItem = (item) => {
console.log('开启弹窗') console.log('防抖开启弹窗')
// itemDialogRef.value.openDialog(item) sessionStore.set('teachClassWorkItem', item); // item
// debounceOpenWin();
sessionStore.set('teachClassWorkItem', item)
toolState.isTaskWin=true //
createWindow('open-taskwin',{url:'/teachClassTask'})
} }
const tagType = (time) => { const tagType = (time) => {
@ -130,6 +135,7 @@ watch(
border-radius: 5px; border-radius: 5px;
margin-bottom: 10px; margin-bottom: 10px;
padding: 10px; padding: 10px;
cursor: pointer;
.class-left { .class-left {
flex-direction: column; flex-direction: column;

View File

@ -183,10 +183,10 @@ const clickMenu = ({isOuter, path, disabled, id}) =>{
// ID // ID
const { id, rootid } = sessionStore.get('subject.curNode') const { id, rootid } = sessionStore.get('subject.curNode')
if(fullPath.indexOf('?') == -1){ if(fullPath.indexOf('?') == -1){
fullPath += `?unitId=${id}&bookeId=${rootid}` fullPath += `?unitId=${id}&bookId=${rootid}`
} }
else{ else{
fullPath += `&unitId=${id}&bookeId=${rootid}` fullPath += `&unitId=${id}&bookId=${rootid}`
} }
} }
fullPath = fullPath.replaceAll('//', '/') fullPath = fullPath.replaceAll('//', '/')

View File

@ -2,7 +2,7 @@
<div class="login-container"> <div class="login-container">
<div class="box-item desc"> <div class="box-item desc">
<div class="welcome"> <div class="welcome">
<p>欢迎登录 {{homeTitle}}</p> <p>欢迎登录 {{ homeTitle }}</p>
</div> </div>
<img class="welcome-img" :src="leftBg2" /> <img class="welcome-img" :src="leftBg2" />
</div> </div>
@ -14,22 +14,15 @@
<el-input v-model.trim="loginForm.username" placeholder="请输入用户名" /> <el-input v-model.trim="loginForm.username" placeholder="请输入用户名" />
</el-form-item> </el-form-item>
<el-form-item prop="password" style="margin-bottom: 15px"> <el-form-item prop="password" style="margin-bottom: 15px">
<el-input <el-input v-model="loginForm.password" autocomplete="on" type="password" placeholder="请输入密码" />
v-model="loginForm.password"
autocomplete="on"
type="password"
placeholder="请输入密码"
/>
</el-form-item> </el-form-item>
<div class="flex mb-5"> <div class="flex mb-5">
<el-checkbox v-model="loginForm.rememberMe" >记住密码</el-checkbox> <el-checkbox v-model="loginForm.rememberMe">记住密码</el-checkbox>
<!-- <el-checkbox >阅读并同意xxx</el-checkbox> --> <!-- <el-checkbox >阅读并同意xxx</el-checkbox> -->
</div> </div>
<el-form-item> <el-form-item>
<el-button :loading="btnLoading" class="btn" type="primary" @click="submitForm(formRef)" <el-button :loading="btnLoading" class="btn" type="primary" @click="submitForm(formRef)">登录</el-button>
>登录</el-button
>
</el-form-item> </el-form-item>
<div class="flex mb-4" style="display: flex;justify-content: center;color: #ccc;cursor: pointer;"> <div class="flex mb-4" style="display: flex;justify-content: center;color: #ccc;cursor: pointer;">
<a class="hover:text-sky-500" style="margin-right: 10px;" @click="RegisterModel(1)">注册账号</a> <a class="hover:text-sky-500" style="margin-right: 10px;" @click="RegisterModel(1)">注册账号</a>
@ -39,21 +32,10 @@
</el-form> </el-form>
</div> </div>
</div> </div>
<el-dialog <el-dialog v-model="showDownLoading" width="500" :show-close="false" :close-on-click-modal="false"
v-model="showDownLoading" :close-on-press-escape="false" align-center>
width="500" <el-progress :text-inside="true" :stroke-width="22" :percentage="downloadProp" :show-text="false"
:show-close="false" status="success" />
:close-on-click-modal="false"
:close-on-press-escape="false"
align-center
>
<el-progress
:text-inside="true"
:stroke-width="22"
:percentage="downloadProp"
:show-text="false"
status="success"
/>
</el-dialog> </el-dialog>
<!--选择学科--> <!--选择学科-->
<SelectSubject v-model="isSubject" :login-data="loginForm" /> <SelectSubject v-model="isSubject" :login-data="loginForm" />
@ -69,6 +51,7 @@ import leftBg2 from '@/assets/images/login/left-bg2.png'
import WindowTools from '@/components/window-tools/index.vue' import WindowTools from '@/components/window-tools/index.vue'
import SelectSubject from '@/components/select-subject/index.vue' import SelectSubject from '@/components/select-subject/index.vue'
import Register from './components/Register.vue' import Register from './components/Register.vue'
import { sessionStore } from '@/utils/store'
const { session } = require('@electron/remote') const { session } = require('@electron/remote')
const downloadProp = ref(0) const downloadProp = ref(0)
@ -99,7 +82,7 @@ ipcRenderer.on('update-app-progress', (e, prop) => {
showDownLoading.value = prop !== 100 showDownLoading.value = prop !== 100
}) })
// //
const RegisterModel = type =>{ const RegisterModel = type => {
RegModel.value.OpenModel(type) RegModel.value.OpenModel(type)
} }
// //
@ -168,6 +151,13 @@ const setCookie = (name, value) => {
onMounted(() => { onMounted(() => {
localStorage.clear() localStorage.clear()
sessionStore.set('subject', {
bookList: null,
curBook: null,
curNode: null,
defaultExpandedKeys: [],
subjectTree: []
})
getCookie() getCookie()
}) })
</script> </script>
@ -179,6 +169,7 @@ onMounted(() => {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
-webkit-app-region: drag; -webkit-app-region: drag;
.box-item { .box-item {
width: 444px; width: 444px;
height: 520px; height: 520px;

View File

@ -52,6 +52,7 @@
<div :title="value" v-if="!!value"> <div :title="value" v-if="!!value">
<vue-qr :text="value" :size="200" :margin="10" colorDark="green" colorLight="white" :logoSrc="getStaticUrl('/img/logo.png')" :logoScale="0.2" :dotScale="0.7"></vue-qr> <vue-qr :text="value" :size="200" :margin="10" colorDark="green" colorLight="white" :logoSrc="getStaticUrl('/img/logo.png')" :logoScale="0.2" :dotScale="0.7"></vue-qr>
</div> </div>
<el-button type="primary" :icon="Refresh" round title="刷新" @click="getQrUrl()" />
<!-- <el-button type="warning" :loading="dt.loadingDel" @click="removeClasscourse()">删除记录</el-button>--> <!-- <el-button type="warning" :loading="dt.loadingDel" @click="removeClasscourse()">删除记录</el-button>-->
</template> </template>
<!-- 手机登录 --> <!-- 手机登录 -->
@ -80,19 +81,22 @@
<script setup> <script setup>
// //
import { onMounted, reactive, ref, watchEffect, watch, nextTick } from 'vue' // vue import { onMounted, reactive, ref, watchEffect, watch, nextTick } from 'vue' // vue
import { Refresh } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus' // ui: import { ElMessage, ElMessageBox } from 'element-plus' // ui:
import vueQr from 'vue-qr/src/packages/vue-qr.vue' // : import vueQr from 'vue-qr/src/packages/vue-qr.vue' // :
import imChat from '@/views/tool/components/imChat.vue' // im-chat- import imChat from '@/views/tool/components/imChat.vue' // im-chat-
import MsgEnum from '@/plugins/imChat/msgEnum' // -(nuem) import MsgEnum from '@/plugins/imChat/msgEnum' // -(nuem)
import * as commUtil from '@/utils/comm' // - import * as commUtil from '@/utils/comm' // -
import { toLinkWeb, getStaticUrl } from '@/utils/tool' import { toLinkWeb, getStaticUrl } from '@/utils/tool' // -
import * as Http_ClassManage from '@/api/classManage' // api import * as Http_ClassManage from '@/api/classManage' // api
import * as Http_Classcourse from '@/api/teaching/classcourse' // api import * as Http_Classcourse from '@/api/teaching/classcourse' // api
import * as Http_Entpcoursefile from '@/api/education/entpcoursefile' // api import * as Http_Entpcoursefile from '@/api/education/entpcoursefile' // api
import * as Http_api from '@/api/apiService' // api
import useUserStore from "@/store/modules/user" // user import useUserStore from "@/store/modules/user" // user
import CryptoJS from 'crypto-js'
const baseUrl = import.meta.env.VITE_APP_BUILD_BASE_PATH let baseUrl = import.meta.env.VITE_APP_BUILD_BASE_PATH
const userStore = useUserStore() const userStore = useUserStore()
const visible = ref(false) // const visible = ref(false) //
const myClassActive = ref({}) // APT const myClassActive = ref({}) // APT
@ -189,9 +193,9 @@ const getClassList = async () => {
}) })
if (res.code == 200) { if (res.code == 200) {
listData.classList = (res.rows || []).map(o => { listData.classList = (res.rows || []).map(o => {
if(!!o.classstudentlist) { // // if(!!o.classstudentlist) { //
o.classstudentlist = JSON.parse('[' + o.classstudentlist + ']') // o.classstudentlist = JSON.parse('[' + o.classstudentlist + ']')
} // }
return o return o
}); });
// //
@ -277,13 +281,37 @@ const classTeachingStart = async () => {
} }
} }
// //
const getQrUrl = () => { const getQrUrl = async() => {
const { classcourseid:id } = teacherForm.form const { classcourseid:id } = teacherForm.form
const { userName } = userStore.user const { userName, userId } = userStore.user
if (!id||!userName) return if (!id||!userName) return
const qrCodeUrl = `wxlogin?username=${userName}&nextaction=classteaching&id=${id}` // (wx)
// const qrCodeUrl = `wxlogin?username=${userName}&nextaction=classteaching&id=${id}`
// teacherForm.form.qrUrl = baseUrl + qrCodeUrl
// baseUrl = 'https://localhost:7860'
// token
let url = `teaching/classteachingonmobile?classcourseid=${id}` // -
let qrCodeUrl = '' // -
try {
// url
const res = await Http_api.toLink.setLink('/' + url) // -
if (res.code == 200) {
const redisKey = res.data
const base64Key = CryptoJS.enc.Utf8.parse(redisKey).toString(CryptoJS.enc.Base64) // base64
const enStrUrl = encodeURIComponent(base64Key) // url
qrCodeUrl = `${url}&_server=${enStrUrl}`
teacherForm.form.qrUrl = baseUrl + qrCodeUrl
}
} catch (error) { // , token
const jsonStr = JSON.stringify({ url, token: userStore.token }) // json{url, token}
const key = `Ax19i14Ga6qEDOkGTo` // AES-key
const enStr = CryptoJS.AES.encrypt(jsonStr, key).toString() // AES-
const enStrUrl = encodeURIComponent(enStr) // url
qrCodeUrl = `${url}&?_web=${enStrUrl}`
}
teacherForm.form.qrUrl = baseUrl + qrCodeUrl teacherForm.form.qrUrl = baseUrl + qrCodeUrl
} }
//
// ================== ======================= // ================== =======================
// im-chat: {type, data} // im-chat: {type, data}

View File

@ -86,10 +86,16 @@
<span>布置</span> <span>布置</span>
</el-button> </el-button>
</div> </div>
<div class="item-popover-item">
<el-button text @click="reSetHomeWork(item, index)">
<i class="iconfont icon-bianji"></i>
<span>编辑</span>
</el-button>
</div>
<div class="item-popover-item"> <div class="item-popover-item">
<el-button text @click="deleteHomework(item)"> <el-button text @click="deleteHomework(item)">
<i class="iconfont icon-shanchu"></i> <i class="iconfont icon-shanchu"></i>
<span>删除</span> <span style="color: red;">删除</span>
</el-button> </el-button>
</div> </div>
</template> </template>
@ -110,7 +116,7 @@
<div class="item-popover-item" v-if="userInfo.userId === Number(item.createUserId)"> <div class="item-popover-item" v-if="userInfo.userId === Number(item.createUserId)">
<el-button text @click="deleteTalk(item)"> <el-button text @click="deleteTalk(item)">
<i class="iconfont icon-shanchu"></i> <i class="iconfont icon-shanchu"></i>
<span>删除</span> <span style="color: red;">删除</span>
</el-button> </el-button>
</div> </div>
<div class="item-popover-item"> <div class="item-popover-item">
@ -168,7 +174,7 @@ export default {
} }
} }
}, },
emits: { 'on-move': null, 'on-delete': null, 'on-set': null, 'on-delhomework': null,'on-filearg': null }, emits: { 'on-move': null, 'on-delete': null, 'on-set': null, 'on-reSet': null, 'on-delhomework': null,'on-filearg': null },
data() { data() {
return { return {
listenList: [], listenList: [],
@ -275,6 +281,10 @@ export default {
setHomeWork(item) { setHomeWork(item) {
this.$emit('on-set', item) this.$emit('on-set', item)
}, },
//
reSetHomeWork(item) {
this.$emit('on-reSet', item)
},
// //
deleteHomework(item){ deleteHomework(item){
this.$emit('on-delhomework', item) this.$emit('on-delhomework', item)

View File

@ -76,7 +76,7 @@
<div class="item-popover-item"> <div class="item-popover-item">
<el-button text @click="deleteTalk(item)"> <el-button text @click="deleteTalk(item)">
<i class="iconfont icon-shanchu"></i> <i class="iconfont icon-shanchu"></i>
<span>删除</span> <span style="color: red;">删除</span>
</el-button> </el-button>
</div> </div>
</template> </template>
@ -102,6 +102,11 @@ import { deleteSmarttalk, updateSmarttalk, getPrepareById } from '@/api/file'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import outLink from '@/utils/linkConfig' import outLink from '@/utils/linkConfig'
import { sessionStore } from '@/utils/store' import { sessionStore } from '@/utils/store'
import { listClasscourseNew } from '@/api/teaching/classcourse'
import { endClass, getSelfReserv } from '@/api/classManage'
import { listEntpcourse } from '@/api/teaching/classwork'
import { createWindow } from '@/utils/tool'
import { defineExpose } from 'vue'
const { ipcRenderer } = window.electron || {} const { ipcRenderer } = window.electron || {}
export default { export default {
@ -131,6 +136,7 @@ export default {
default: '' default: ''
} }
}, },
expose: ['openFileWin'],
emits: { 'on-start-class': null, 'on-delete': null, 'on-set': null, 'on-delhomework': null,'on-filearg': null }, emits: { 'on-start-class': null, 'on-delete': null, 'on-set': null, 'on-delhomework': null,'on-filearg': null },
data() { data() {
return { return {
@ -142,8 +148,87 @@ export default {
this.userInfo = useUserStore().user this.userInfo = useUserStore().user
}, },
methods: { methods: {
getOpenCourse() {
return Promise.all([listClasscourseNew({teacherid: this.userInfo.userId,status:"open",evalid: this.curNode.id,pageSize:1000}), getSelfReserv({ex2:this.curNode.id})]).then(([res1,res2])=>{
let list2 = res1.rows || []
let list = res2.data || []
let one = list.find(item1 => {
if (item1.status === "上课中") {
return true
}
})
if (one) {
return one
}
if (list2.length>0) {
one = list2[0]
}
return one
})
},
clickStartClass(item) { clickStartClass(item) {
this.getOpenCourse().then(res=>{
if(!res){
this.$emit('on-start-class', item) this.$emit('on-start-class', item)
}else{
ElMessageBox.alert('<strong>上次课程尚未结束,是否继续上课?</strong>', '', {
// if you want to disable its autofocus
// autofocus: false,
confirmButtonText: '下课  ',
cancelButtonText: '继续上课',
showCancelButton: true,
showClose: false,
closeOnClickModal: true,
distinguishCancelAndClose: true,
dangerouslyUseHTMLString: true,
cancelButtonClass: "el-button--primary",
confirmButtonClass: "el-button--danger",
center: true,
beforeClose: (action, instance, done) => {
if (action === 'confirm'){
//
if (res.bookImg) {
//PPT
endClass(res.id).then((res1) => {
if (res1.data === true) {
ElMessage({
message: '下课成功',
type: 'success'
})
res.status = '已结束'
done()
}
})
}else {
//APT
}
}
if (action === 'cancel'){
//
if (res.bookImg) {
//PPT
listEntpcourse({
evalid: res.ex2,
edituserid: useUserStore().user.userId,
pageSize: 500
}).then(async res1=>{
if (res1.rows[0].id) {
createWindow('tool-sphere', { url: '/tool/sphere?entpcourseid=' + res1.rows[0].id + "&reservId=" + res.id })
done()
}
})
}else {
//APT
}
}
if (action === 'close') {
done()
}
},
})
}
})
// this.$emit('on-start-class', item)
}, },
editTalk(item) { editTalk(item) {
ElMessageBox.prompt('请输入新的标签', '添加标签', { ElMessageBox.prompt('请输入新的标签', '添加标签', {

View File

@ -18,6 +18,7 @@
<kj-list-item <kj-list-item
v-for="(item, index) in currentKJFileList" v-for="(item, index) in currentKJFileList"
:key="index" :key="index"
:ref="'kjItemRef'+item.id"
:item="item" :item="item"
:index="index" :index="index"
:curNode="currentNode" :curNode="currentNode"
@ -28,42 +29,11 @@
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="教学实录" name="教学实录" class="prepare-center-jxsl"> <el-tab-pane label="教学实录" name="教学实录" class="prepare-center-jxsl">
<class-reserv></class-reserv> <class-reserv v-if="activeAptTab==='教学实录'" :curNode="currentNode"></class-reserv>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
<div class="page-right"> <div class="page-right">
<!-- <div class="header-top flex">
<div class="textbook-img" @click="navtoPdf">
<el-image style="width: 80px; height: 110px" :src="curBookImg" />
<el-progress
v-if="downloadNum > 0 && downloadNum < 100"
style="position: absolute; left: 0; z-index: 999"
type="circle"
:percentage="downloadNum"
/>
</div>
<div class="top-item">
<el-button class="btn" @click="handleOutLink('standard')">课标研读</el-button>
<el-button class="btn" @click="openReserv">预约课程</el-button>
<el-button class="btn" @click="handleOutLink('gk')">高考研读</el-button>
<el-button class="btn" @click="handleOutLink('aiModel')">教学大模型</el-button>
</div>
<el-button
:type="!curClassReserv.id ? 'info' : 'primary'"
:disabled="!curClassReserv.id || toolStore.isToolWin"
class="to-class-btn"
@click="openLesson"
>
<label
><i class="iconfont icon-lingdang"></i
>{{ curClassReserv.status == '上课中' ? '上课中' : '上课' }}</label
>
<label>{{ curClassReserv.classDay }} {{ getWeekday1(curClassReserv.classDay) }}</label>
<label>{{ curClassReserv.startTime }}-{{ curClassReserv.endTime }}</label>
</el-button>
<div class="top-zoom-style"></div>
</div>-->
<div style="padding: 0 20px;height: 100%;"> <div style="padding: 0 20px;height: 100%;">
<el-tabs v-model="activeTab" class="prepare-tabs" > <el-tabs v-model="activeTab" class="prepare-tabs" >
<el-tab-pane label="素材" name="素材"> <el-tab-pane label="素材" name="素材">
@ -116,22 +86,20 @@
</el-checkbox-group> </el-checkbox-group>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="作业" name="作业"> <el-tab-pane label="作业" name="作业">
<!-- <div class="prepare-body-header"> <div class="prepare-body-header">
<div> <div>
<label style="font-size: 15px">{{ currentWorkList.length }}个作业</label>&nbsp; <label style="font-size: 15px">{{ currentWorkList.length }}个作业</label>&nbsp;
<el-button size="small" @click="handleOutLink('feedback')">作业反馈</el-button> <el-button size="small" @click="handleOutLink('homeWork')">作业设计</el-button>
<el-button size="small" @click="handleOutLink('homeWork')">布置作业</el-button> </div>
</div> </div>
</div>-->
<div class="prepare-work-wrap"> <div class="prepare-work-wrap">
<file-list-item <file-list-item
v-for="(item, index) in currentWorkList" v-for="(item, index) in currentWorkList"
:key="index" :key="index"
:item="item" :item="item"
:index="index" :index="index"
@on-move="onMoveSingleFile"
@on-delete="deleteTalk"
@on-set="openSet" @on-set="openSet"
@on-reSet="openReSet"
@on-delhomework="delhomework" @on-delhomework="delhomework"
> >
</file-list-item> </file-list-item>
@ -305,29 +273,29 @@ export default {
// }, // },
methods: { methods: {
startClass(item) { startClass(item) {
// console.log(item, sessionStore)
// () // ()
const id = sessionStore.has('activeClass.id') ? sessionStore.get('activeClass.id') : null const id = sessionStore.has('activeClass.id') ? sessionStore.get('activeClass.id') : null
if (id && id == item.id) return ElMessage.warning('当前正在上课,请勿重复操作') if (id && id == item.id) return ElMessage.warning('当前正在上课,请勿重复操作')
// -store
sessionStore.set('activeClass', item)
this.activeClass = item
if(item.fileFlag === '课件') { if(item.fileFlag === '课件') {
this.openReserv() this.openReserv()
} }
if(item.fileFlag === 'apt') { if(item.fileFlag === 'apt') {
this.$refs.calssRef.open(item.fileId) this.$refs.calssRef.open(item.fileId)
} }
// -store
sessionStore.set('activeClass', item)
this.activeClass = item
}, },
closeChange() { // - closeChange() { // -
console.log('关闭上课弹窗') console.log('关闭上课弹窗')
this.activeClass = null // this.activeClass = null
sessionStore.delete('activeClass') sessionStore.delete('activeClass')
}, },
initReserv(id) { initReserv(id) {
getClassInfo(id).then((res) => { getClassInfo(id).then((res) => {
this.curClassReserv = res.data this.curClassReserv = res.data
this.openLesson(res.data.id); this.openLesson(res.data.id);
this.$refs['kjItemRef'+this.activeClass.id][0].openFileWin(this.activeClass);
}) })
}, },
getBookPathFromServer() { getBookPathFromServer() {
@ -370,6 +338,9 @@ export default {
createFile() { createFile() {
creatPPT(this.currentNode.itemtitle + '.pptx', this.uploadData).then((res) => { creatPPT(this.currentNode.itemtitle + '.pptx', this.uploadData).then((res) => {
this.currentFileList.unshift(res.resData) this.currentFileList.unshift(res.resData)
setTimeout(()=>{
this.$refs['kjItemRef'+res.resData.id][0].openFileWin(res.resData);
},500)
}) })
}, },
createAptFile() { createAptFile() {
@ -451,6 +422,9 @@ export default {
fileShowName: this.currentNode.itemtitle + '.apt' fileShowName: this.currentNode.itemtitle + '.apt'
}).then((res) => { }).then((res) => {
this.currentFileList.unshift(res.resData) this.currentFileList.unshift(res.resData)
setTimeout(()=>{
this.$refs['kjItemRef'+res.resData.id][0].openFileWin(res.resData);
},500)
}) })
}) })
}) })
@ -596,6 +570,7 @@ export default {
openReserv() { openReserv() {
this.$refs['reservDialog'].openDialog() this.$refs['reservDialog'].openDialog()
}, },
// //
handleOutLink(key) { handleOutLink(key) {
if (key == 'homeWork') { if (key == 'homeWork') {
@ -609,12 +584,15 @@ export default {
let unitId = this.uploadData.levelSecondId let unitId = this.uploadData.levelSecondId
? this.uploadData.levelSecondId ? this.uploadData.levelSecondId
: this.uploadData.levelFirstId : this.uploadData.levelFirstId
if (key == 'gk') { let bookId = this.uploadData.textbookId;
fullPath += `?unitId=${unitId}` if(fullPath.indexOf('?') == -1){
} else { fullPath += `?unitId=${unitId}&bookId=${bookId}&openDialog=newClassTask`
fullPath += `&unitId=${unitId}` }
else{
fullPath += `&unitId=${unitId}&bookId=${bookId}&openDialog=newClassTask`
} }
} }
// //
ipcRenderer.send('openWindow', { ipcRenderer.send('openWindow', {
key, key,
@ -632,6 +610,27 @@ export default {
this.row = row this.row = row
this.setDialog = true this.setDialog = true
}, },
//
openReSet(row) {
//
this.isOpenHomework = true;
// key linkConfig.js
let configObj = outLink()['homeWork']
let fullPath = configObj.fullPath
let unitId = this.uploadData.levelSecondId
? this.uploadData.levelSecondId
: this.uploadData.levelFirstId
let bookId = this.uploadData.textbookId;
fullPath += `&unitId=${unitId}&bookId=${bookId}&courseWorkId=${row.id}`
//
ipcRenderer.send('openWindow', {
key: 'homeWork',
fullPath: fullPath,
cookieData: { ...configObj.data }
})
},
// //
delhomework(item) { delhomework(item) {
this.isLoading = true this.isLoading = true
@ -874,6 +873,7 @@ export default {
width: 100%; width: 100%;
flex: 1; flex: 1;
overflow: auto; overflow: auto;
margin-top: 10px;
} }
.prepare-body-main { .prepare-body-main {
flex: 1; flex: 1;

View File

@ -57,6 +57,13 @@
</div> </div>
<div class="right-align">{{ state.user.createTime }}</div> <div class="right-align">{{ state.user.createTime }}</div>
</li> </li>
<li class="list-group-item">
<div class="left-align">
<Paperclip class="Calendar"/>
<span>版本编号</span>
</div>
<div class="right-align">v{{version}}</div>
</li>
</ul> </ul>
</div> </div>
</el-card> </el-card>
@ -83,13 +90,15 @@
</template> </template>
<script setup name="Profile"> <script setup name="Profile">
import { UserFilled, Cellphone, Message, Suitcase, Avatar, Calendar } from '@element-plus/icons-vue' import { UserFilled, Cellphone, Message, Suitcase, Avatar, Calendar, Paperclip } from '@element-plus/icons-vue'
import { ref, reactive } from 'vue' import { ref, reactive } from 'vue'
import userAvatar from './userAvatar.vue' import userAvatar from './userAvatar.vue'
import userInfo from './userInfo.vue' import userInfo from './userInfo.vue'
import resetPwd from './resetPwd.vue' import resetPwd from './resetPwd.vue'
import { getUserProfile } from '@/api/system/user' import { getUserProfile } from '@/api/system/user'
import pkc from "../../../../../package.json"
const version = ref(pkc.version)
const activeTab = ref('userinfo') const activeTab = ref('userinfo')
const state = reactive({ const state = reactive({
user: {}, user: {},

View File

@ -61,7 +61,7 @@
@click="delRow(item)" @click="delRow(item)"
> >
<i class="iconfont icon-shanchu"></i> <i class="iconfont icon-shanchu"></i>
<span>删除</span> <span style="color: red;">删除</span>
</div> </div>
<div class="item-popover-item" @click="downloadFile(item)"> <div class="item-popover-item" @click="downloadFile(item)">
<i class="iconfont icon-xiazai"></i> <i class="iconfont icon-xiazai"></i>

View File

@ -8,14 +8,19 @@
<h3 class="title">{{ lesson }}</h3> <h3 class="title">{{ lesson }}</h3>
<div class="grade">{{ usertore.edusubject }}</div> <div class="grade">{{ usertore.edusubject }}</div>
</div> </div>
<i class="iconfont icon-xiangyou" @click="showLeft = !showLeft"></i> <!-- <i class="iconfont icon-xiangyou" @click="showLeft = !showLeft"></i> -->
</div> </div>
<div class="homework-list" v-loading="loading"> <div class="homework-list" v-loading="loading">
<el-scrollbar height="360px"> <el-scrollbar height="360px">
<ul> <ul>
<!--资源--> <!--资源-->
<li class="item flex" v-for="item in resourceList" :key="item.id"> <template v-for="item in resourceList" :key="item.id">
<div class="item-left flex"> <!--
apt pptx 暂时不显示
2024-10-10
-->
<li class="item flex" v-if="item.fileFlag != 'apt' && item.fileSuffix != 'pptx' && item.fileSuffix != 'ppt'">
<div class="item-left flex" >
<FileImage :size="50" :file-name="item.fileShowName" /> <FileImage :size="50" :file-name="item.fileShowName" />
<div class="item-info flex"> <div class="item-info flex">
<span class="item-name">{{ item.fileShowName }}</span> <span class="item-name">{{ item.fileShowName }}</span>
@ -27,6 +32,7 @@
</div> </div>
<el-button color="#349d44" @click="openFileLink(item)">推送</el-button> <el-button color="#349d44" @click="openFileLink(item)">推送</el-button>
</li> </li>
</template>
<!--作业--> <!--作业-->
<li class="item flex" v-for="item in dataList" :key="item.id"> <li class="item flex" v-for="item in dataList" :key="item.id">
<div class="item-left flex"> <div class="item-left flex">
@ -170,7 +176,6 @@ const openFileLink = async (item) =>{
// //
const getResource = () => { const getResource = () => {
let querySearch = toRaw(toolStore.curSubjectNode).querySearch let querySearch = toRaw(toolStore.curSubjectNode).querySearch
querySearch.orderByColumn = 'uploadTime' querySearch.orderByColumn = 'uploadTime'
querySearch.isAsc = 'desc' querySearch.isAsc = 'desc'
querySearch.pageSize = 500 querySearch.pageSize = 500
@ -217,8 +222,6 @@ onMounted(async () => {
curNode.data = sessionStore.get('subject.curNode') curNode.data = sessionStore.get('subject.curNode')
getHomework() getHomework()
getResource() getResource()
}) })
</script> </script>

View File

@ -48,9 +48,9 @@ const props = defineProps({
data: { // data: { //
type: Array, type: Array,
default: () => [ default: () => [
{ label: '资源', prop: 'resource', icon: 'icon-kechengziyuan1' }, { label: '活动', prop: 'resource', icon: 'icon-kechengziyuan1' },
{ label: '互动', prop: 'interact', icon: 'icon-hudong' }, // { label: '', prop: 'interact', icon: 'icon-hudong' },
{ label: '窗口', prop: 'win', icon: 'icon-tubiaozhizuomobanyihuifu-' }, // { label: '', prop: 'win', icon: 'icon-tubiaozhizuomobanyihuifu-' },
{ label: '下课', prop: 'over', isExtra: true, icon: 'icon-a-lujing13357' }, { label: '下课', prop: 'over', isExtra: true, icon: 'icon-a-lujing13357' },
] ]
} }
@ -103,7 +103,7 @@ const clickHandel = (o, e) => {
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
right: 10px; right: 10px;
min-height: 40vh; //min-height: 40vh;
min-width: 4em; min-width: 4em;
border-radius: 4em; border-radius: 4em;
background-color: #121212; background-color: #121212;

View File

@ -220,13 +220,13 @@ const sideChange = async o => {
await imChatRef.value?.imChatObj?.imChat?.sendMsgClosed() // await imChatRef.value?.imChatObj?.imChat?.sendMsgClosed() //
// const elMsg = ElMessage.warning({duration:0,message:'...'}) // const elMsg = ElMessage.warning({duration:0,message:'...'})
const elMsg = ElLoading.service({lock: true, text: '正在下课...', background: 'rgba(0, 0, 0, 0.7)'}) const elMsg = ElLoading.service({lock: true, text: '正在下课...', background: 'rgba(0, 0, 0, 0.7)'})
// 2
setTimeout(async() => {
// toolStore.isToolWin = false // toolStore.isToolWin = false
toolStore.resetDef() // toolStore.resetDef() //
await classManageApi.endClass(route.query.reservId)
// 2
setTimeout(async() => {
await imChatRef.value?.deleteGroup() // await imChatRef.value?.deleteGroup() //
await imChatRef.value?.logout() // 退im await imChatRef.value?.logout() // 退im
await classManageApi.endClass(route.query.reservId)
elMsg.close() elMsg.close()
ipcMsgSend('tool-sphere:close') // ipcMsgSend('tool-sphere:close') //
}, 500); }, 500);