Compare commits
45 Commits
cdf12cf213
...
53f43019e9
Author | SHA1 | Date |
---|---|---|
朱浩 | 53f43019e9 | |
zouyf | d896209948 | |
“zouyf” | c618ec04c7 | |
朱浩 | 280313e638 | |
朱浩 | ed7a8a124e | |
zouyf | 4b71008bee | |
“zouyf” | aab477999e | |
“zouyf” | d1b7101ba5 | |
lyc | 47f3202444 | |
lyc | 3cd8c51aae | |
lyc | be187e1a2d | |
lyc | 119e07bcea | |
“zouyf” | 555960b8bd | |
“zouyf” | d709753534 | |
朱浩 | 78ac6e5ca6 | |
朱浩 | acc29b02e4 | |
zhengdegang | 12da4ac2c0 | |
zdg | 5ecba3fb62 | |
zdg | f5f33eaa63 | |
zhengdegang | 090bc5997c | |
zdg | 1c69d10263 | |
zdg | b794d55cd7 | |
zdg | 28b5a131fd | |
zdg | e740cb0c7e | |
zdg | 3a83a31970 | |
zhangxuelin | 30f7b9d5b3 | |
zhangxuelin | 37810586b7 | |
zhangxuelin | e31858a3fe | |
zdg | 3a6b78bc76 | |
zhengdegang | 10a1342b95 | |
zdg | 70e99e69ba | |
lyc | 3171c0b3f9 | |
lyc | 33e84ca006 | |
lyc | 28a815169d | |
zhengdegang | eace8b56d8 | |
zdg | e03e385dbc | |
zdg | 2aaa15230a | |
zdg | 7894214859 | |
朱浩 | fe41a63b2d | |
yangws | 7bb8d2afeb | |
yangws | cfac2086e6 | |
zdg | b6504e114f | |
lyc | 931ed531ab | |
lyc | a6bda302af | |
lyc | eb481e265b |
|
@ -10,6 +10,7 @@ VITE_APP_BASE_API = '/dev-api'
|
|||
VITE_APP_DOMAIN = 'file.ysaix.com'
|
||||
|
||||
VITE_APP_UPLOAD_API = 'https://file.ysaix.com:7868/prod-api'
|
||||
#VITE_APP_UPLOAD_API = 'http://192.168.2.52:7863'
|
||||
|
||||
VITE_APP_RES_FILE_PATH = 'https://file.ysaix.com:7868/src/assets/textbook/booktxt/'
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "aix-win",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.8",
|
||||
"description": "An Electron application with Vue",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "example.com",
|
||||
|
@ -28,16 +28,17 @@
|
|||
"@vueuse/core": "^10.11.0",
|
||||
"cropperjs": "^1.6.2",
|
||||
"crypto-js": "^4.2.0",
|
||||
"echarts": "^5.5.1",
|
||||
"electron-dl-manager": "^3.0.0",
|
||||
"electron-log": "^5.1.7",
|
||||
"electron-store": "8.0.0",
|
||||
"electron-updater": "^6.1.7",
|
||||
"element-plus": "^2.7.6",
|
||||
"fabric": "^5.3.0",
|
||||
"im_electron_sdk": "^8.0.5904",
|
||||
"js-cookie": "^3.0.5",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"jsondiffpatch": "0.6.0",
|
||||
"im_electron_sdk": "^8.0.5904",
|
||||
"lodash": "^4.17.21",
|
||||
"pdfjs-dist": "4.4.168",
|
||||
"pinia": "^2.1.7",
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询entpcoursework列表
|
||||
export function listEntpcoursework(query) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询entpcoursework详细
|
||||
export function getEntpcoursework(id) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增entpcoursework
|
||||
export function addEntpcoursework(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursework',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改entpcoursework
|
||||
export function updateEntpcoursework(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursework',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除entpcoursework
|
||||
export function delEntpcoursework(id) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// xuekubaoapi
|
||||
export function xuekubaoAPI(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/xuekubaoapi',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// PPT文件上传
|
||||
export function uploadEntpcourseworkFile(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/uploadWord',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 查询entpcoursework列表
|
||||
export function listEntpcourseworkNew(query) {
|
||||
return request({
|
||||
url: '/education/entpcoursework/new/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @desc: 学科网接口api
|
||||
* @return: {*}
|
||||
* @param {*} path 请求路径 /xopqbm/questions(无需全拼, 后端学科网sdk自动处理)
|
||||
* @param {*} method 请求方式 post/get
|
||||
* @param {*} params 请求参数 {key: value,}
|
||||
*/
|
||||
export function xkwAPI(path, method, isPostBody, params) {
|
||||
return request({
|
||||
url: '/xkw/post',
|
||||
method: 'post',
|
||||
data: {
|
||||
path: path,
|
||||
method: method,
|
||||
isPostBody: isPostBody,
|
||||
params: params,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc: 图文识别接口 python_OCR_api
|
||||
* @return: {*}
|
||||
* @param {*} path 请求路径 /ocrApi/data
|
||||
* @param {*} method 请求方式 post
|
||||
* @param {*} params 请求参数 {key: value,}
|
||||
*/
|
||||
export function pyOCRAPI(path) {
|
||||
return request({
|
||||
url: '/ocrApi/data',
|
||||
method: 'post',
|
||||
data: {
|
||||
imageBas64: path,
|
||||
}
|
||||
})
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 查询entpcoursefile列表
|
||||
export function listEntpcoursefile(query) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// zdg:查询entpcoursefile列表-新
|
||||
export function listEntpcoursefileNew(query) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/new/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
// 查询entpcoursefile详细
|
||||
export function getEntpcoursefile(id) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增entpcoursefile
|
||||
export function addEntpcoursefile(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增entpcoursefile
|
||||
export function addEntpcoursefileReturnId(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/addReturnId',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// addFromId
|
||||
export function addFromId(fromid, toid, entpid, entpcourseid, edituserid) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/addFromId/'+fromid+'/'+toid+'/'+entpid+'/'+entpcourseid+'/'+edituserid,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 修改entpcoursefile
|
||||
export function updateEntpcoursefile(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 新增 修改接口
|
||||
export function updateEntpcoursefileNew(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/newUpdateFile',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// updateFileByIds
|
||||
export function updateFileByIds(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/updateFileByIds',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// updateFileByArray
|
||||
export function updateFileByArray(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/updateFileByArray',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改entpcoursefile
|
||||
export function updateFile2Redis(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/updateFile2Redis',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除entpcoursefile
|
||||
export function delEntpcoursefile(id) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存base64图片,返回url
|
||||
export function saveEntpCourseBase64File(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/saveBase64File',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 文件上传
|
||||
export function saveEntpCourseBase64File2(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/saveBase64File2',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 保存PPT页面预览base64图片,返回url
|
||||
export function savePPTPreviewBase64File(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/savePreviewBase64',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// PPT文件上传
|
||||
export function saveEntpCoursePPT(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/importPPT',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// PPT文件解析
|
||||
export function parsePPT(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/parsePPT',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 修改ppt.slide.index
|
||||
export function updateSlideIndex(data) {
|
||||
return request({
|
||||
url: '/education/entpcoursefile/saveSlideOrder',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
|
@ -9,6 +9,14 @@ export const getSmarttalkPage = (params) => {
|
|||
})
|
||||
}
|
||||
|
||||
export const creatAPT = (params) => {
|
||||
return request({
|
||||
url: '/smarttalk/file/createApt',
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export const getPrepareById = (id) => {
|
||||
return request({
|
||||
url: '/smarttalk/file/' + id,
|
||||
|
|
|
@ -42,4 +42,13 @@ export function delClasswork(id) {
|
|||
url: '/education/classwork/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增classwork
|
||||
export function addClassworkReturnId(data) {
|
||||
return request({
|
||||
url: '/education/classwork/saveAndReturnId',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2794390 */
|
||||
src: url('iconfont.woff2?t=1724212790213') format('woff2'),
|
||||
url('iconfont.woff?t=1724212790213') format('woff'),
|
||||
url('iconfont.ttf?t=1724212790213') format('truetype'),
|
||||
url('iconfont.svg?t=1724212790213#iconfont') format('svg');
|
||||
src: url('iconfont.woff2?t=1725691484835') format('woff2'),
|
||||
url('iconfont.woff?t=1725691484835') format('woff'),
|
||||
url('iconfont.ttf?t=1725691484835') format('truetype'),
|
||||
url('iconfont.svg?t=1725691484835#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -14,6 +14,34 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-saoyisao:before {
|
||||
content: "\e691";
|
||||
}
|
||||
|
||||
.icon-jiaoxuezhiliangfenxi:before {
|
||||
content: "\e690";
|
||||
}
|
||||
|
||||
.icon-jiaoxuejihua:before {
|
||||
content: "\e7e9";
|
||||
}
|
||||
|
||||
.icon-tongji:before {
|
||||
content: "\e68f";
|
||||
}
|
||||
|
||||
.icon-pigai:before {
|
||||
content: "\e68d";
|
||||
}
|
||||
|
||||
.icon-jiaoxuefansi:before {
|
||||
content: "\e6b2";
|
||||
}
|
||||
|
||||
.icon-kaoshi:before {
|
||||
content: "\e68a";
|
||||
}
|
||||
|
||||
.icon-yiwen:before {
|
||||
content: "\e687";
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5,6 +5,55 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "12657402",
|
||||
"name": "资源库",
|
||||
"font_class": "saoyisao",
|
||||
"unicode": "e691",
|
||||
"unicode_decimal": 59025
|
||||
},
|
||||
{
|
||||
"icon_id": "6513175",
|
||||
"name": "教学质量分析",
|
||||
"font_class": "jiaoxuezhiliangfenxi",
|
||||
"unicode": "e690",
|
||||
"unicode_decimal": 59024
|
||||
},
|
||||
{
|
||||
"icon_id": "38447338",
|
||||
"name": "教学计划",
|
||||
"font_class": "jiaoxuejihua",
|
||||
"unicode": "e7e9",
|
||||
"unicode_decimal": 59369
|
||||
},
|
||||
{
|
||||
"icon_id": "8455509",
|
||||
"name": "统计",
|
||||
"font_class": "tongji",
|
||||
"unicode": "e68f",
|
||||
"unicode_decimal": 59023
|
||||
},
|
||||
{
|
||||
"icon_id": "5969226",
|
||||
"name": "批改",
|
||||
"font_class": "pigai",
|
||||
"unicode": "e68d",
|
||||
"unicode_decimal": 59021
|
||||
},
|
||||
{
|
||||
"icon_id": "36295514",
|
||||
"name": "教学反思",
|
||||
"font_class": "jiaoxuefansi",
|
||||
"unicode": "e6b2",
|
||||
"unicode_decimal": 59058
|
||||
},
|
||||
{
|
||||
"icon_id": "21088705",
|
||||
"name": "考试",
|
||||
"font_class": "kaoshi",
|
||||
"unicode": "e68a",
|
||||
"unicode_decimal": 59018
|
||||
},
|
||||
{
|
||||
"icon_id": "20574719",
|
||||
"name": "疑问",
|
||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 337 KiB After Width: | Height: | Size: 352 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
|
@ -0,0 +1,99 @@
|
|||
body{font-family: "微软雅黑", Arial,"宋体"; color: #333;}
|
||||
a{ text-decoration: none; color: #2489f6;}
|
||||
dl, ul, ol, ul { list-style: none; padding: 0; margin: 0; }
|
||||
.wrapper{ width: 1200px; margin: 0 auto; }
|
||||
.ques-detail{}
|
||||
.ques-detail ul li{margin-bottom: 20px;border: 1px solid #dadada;background: #fff;border-radius: 10px;}
|
||||
.ques-detail ul li:last-child{ margin-bottom: 0; }
|
||||
|
||||
table.edittable{ border-collapse: collapse; text-align: center; margin: 2px; }
|
||||
table.edittable th, table.edittable td{ line-height: 30px; padding: 5px; white-space: normal; word-break: break-all; border: 1px solid #000; vertical-align: middle; }
|
||||
table.composition{ border-collapse: collapse; text-align: left; margin: 2px; width: 98%; }
|
||||
table.composition th, table.composition td{ line-height: 30px; white-space: normal; word-break: break-all; border-width: 0px; vertical-align: middle; }
|
||||
table.composition2{ border-collapse: collapse;width:auto }
|
||||
table.composition2 th, table.composition2 td{text-align:left;line-height:30px; white-space:normal;word-break:break-all;border:none;border-width: 0px;vertical-align: middle; }
|
||||
.MathJye{ border: 0 none; direction: ltr; line-height: normal; display: inline-block; float: none; font-family: 'Times New Roman','宋体'; font-size: 15px; font-style: normal; font-weight: normal; letter-spacing: 1px; line-height: normal; margin: 0; padding: 0; text-align: left; text-indent: 0; text-transform: none; white-space: nowrap; word-spacing: normal; word-wrap: normal; -webkit-text-size-adjust: none; }
|
||||
.MathJye div, .MathJye span{ border: 0 none; margin: 0; padding: 0; line-height: normal; text-align: left; height: auto; _height: auto; white-space: normal; }
|
||||
.MathJye table{ border-collapse: collapse; margin: 0; padding: 0; text-align: center; vertical-align: middle; line-height: normal; font-size: inherit; *font-size: 100%; _font-size: 100%; font-style: normal; font-weight: normal; border: 0; float: none; display: inline-block; *display: inline; zoom: 0; }
|
||||
.MathJye table td{ padding: 0; font-size: inherit; line-height: normal; white-space: nowrap; border: 0 none; width: auto; _height: auto; }
|
||||
.MathJye_mi{ font-style: italic; }
|
||||
.flipv{-ms-transform: scaleX(-1);-moz-transform: scaleX(-1);-webkit-transform: scaleX(-1);-o-transform: scaleX(-1);transform: scaleX(-1);filter: FlipH;}
|
||||
.fliph{-ms-transform: scaleY(-1);-moz-transform: scaleY(-1);-webkit-transform: scaleY(-1);-o-transform: scaleY(-1);transform: scaleY(-1);filter: FlipV;}
|
||||
.mathjye-bold{font-weight:800}
|
||||
.mathjye-del{text-decoration:line-through}
|
||||
.mathjye-underline{border-bottom:1px solid #000;padding-bottom:2px;}
|
||||
@-moz-document url-prefix() {.mathjye-underline{padding-bottom:0px;}}
|
||||
.mathjye-underpline{border-bottom:2px dotted #000; padding-bottom:3px;}
|
||||
@-moz-document url-prefix() {.mathjye-underpline {padding-bottom:1px;}}
|
||||
.mathjye-underpoint{background: url(http://img.jyeoo.net/images/formula/point.png) no-repeat center bottom; padding-bottom:4px;}
|
||||
.mathjye-underpoint2{border-bottom:2px dotted #000; padding-bottom:3px;}
|
||||
@-moz-document url-prefix() {.mathjye-underpoint{padding-bottom:1px;}}
|
||||
.mathjye-underwave{background: url(http://img.jyeoo.net/images/formula/wave.png) bottom repeat-x; padding-bottom:4px;}
|
||||
@-moz-document url-prefix() {.mathjye-underwave {padding-bottom:1px;}}
|
||||
.mathjye-alignleft{display:block;text-align:left;}
|
||||
.mathjye-aligncenter{display:block;text-align:center;}
|
||||
.mathjye-alignright{display:block;text-align:right;}
|
||||
|
||||
|
||||
/*试题*/
|
||||
.artpreview fieldset { padding-top: 10px; font-size: 14px; clear: both; overflow: hidden; zoom: 1; line-height: 24px; font-family: 'Times New Roman',宋体,sans-serif; position: relative; }
|
||||
.artpreview fieldset legend { padding: 5px 0; display: block; margin: 5px; background: #f1f1f1; color: #000; overflow: hidden; zoom: 1; }
|
||||
.queserror { border: 1px dotted #f00; padding: 2px; }
|
||||
fieldset.quesborder {display: block;padding: 0;line-height: 25px;letter-spacing: 1px;word-break: break-all;margin: 0;}
|
||||
fieldset.queserror { border: 1px solid #f00; font-size: 12px; padding: 2px; margin-bottom: 1px; }
|
||||
fieldset.quesborder td, fieldset.queserror td { line-height: 16px; }
|
||||
fieldset.quesborder em, fieldset.queserror em { font-style: normal; font-weight: bold; position: absolute; left: 20px; }
|
||||
fieldset.thiserror1 { border: 1px solid #f00; }
|
||||
fieldset.thiserror1 legend { border: 4px solid #f00; }
|
||||
fieldset.thiserror2 { border: 1px solid #ADCD3C; }
|
||||
fieldset.thiserror2 legend { border: 4px solid #ADCD3C; }
|
||||
fieldset.thisques { border: 1px solid blue; }
|
||||
fieldset.thison { border: 1px solid #A9C9E2; }
|
||||
fieldset.thison div.border { border: 1px solid #ADCD3C; background-color: #F2FDDB; }
|
||||
fieldset, img { border: 0 none; }
|
||||
table.thison { border: 1px solid #00F; }
|
||||
table.thiserr { border: 1px solid #F00; }
|
||||
fieldset.thisvip1 { border: 1px solid #00F; }
|
||||
fieldset.thisvip1 legend { border: 4px solid #00F; }
|
||||
fieldset.status17 { border: 1px solid #ff00ff; }
|
||||
fieldset.status17 legend { border: 4px solid #ff00ff; }
|
||||
.selectoption { vertical-align: middle; font-size: 14px; padding: 2px; }
|
||||
.selectoption:hover { color: #EA8511; }
|
||||
.selectoption label { padding: 4px; line-height: 24px; }
|
||||
fieldset.quesbordere { border: 2px dotted #f00; }
|
||||
.answer { border: 1px dotted #ffffff; }
|
||||
ol.answer li, ul.answer li { padding: 1px; font-size: 14px; }
|
||||
ol.answer li:hover { background: #f2f2f2; }
|
||||
.collapseContainerPanel { border: 0; }
|
||||
.collapsePanelHeader { height: 30px; font-weight: bold; padding: 6px 0 0 0; }
|
||||
.collapseHeaderContent { float: left; padding-left: 5px; }
|
||||
.collapseContent { margin: 0; padding: 0; border: 1px solid #ccc; border-top: 0; }
|
||||
.pt0 { padding: 2px 0 5px 0; font-size: 14px; font-family: "黑体",sans-serif; font-weight: 700; }
|
||||
.pt1 {overflow: hidden;zoom: 1;clear: both;line-height: 25px;font-size: 14px;padding: 20px;position: relative;word-break: break-word;}
|
||||
fieldset.quesborder .pt1 em { position: static; }
|
||||
.pt1 img { position: relative; }
|
||||
.pt2 {padding: 20px;padding-top: 0;}
|
||||
.pt3, .pt4, .pt5, .pt6, .pt7 { clear: both; zoom: 1; position: relative; padding: 0px 20px 20px 80px; }
|
||||
.pt8 a:link, .pt8 a:visited { margin-right: 10px; padding: 2px 5px; }
|
||||
.pt8 a:hover { background: #fc0; }
|
||||
.pt9 { padding: 20px; border: 0 none; color: #999999; font-size: 12px; }
|
||||
.fieldtip {height: 36px;line-height: 36px;background-color: #f4f4f4;border-top: 1px solid #dadada;padding: 0 20px;color: #666666;position: relative;font-size: 12px;border-radius: 0 0 10px 10px;}
|
||||
.newFieldtip .pt1, .newFieldtip .pt2, .newFieldtip .pt3, .newFieldtip .pt4, .newFieldtip .pt5, .newFieldtip .pt6, .newFieldtip .pt7, .newFieldtip .pt8, .newFieldtip.pt9, .newFieldtip + .fieldtip { padding: 0; }
|
||||
fieldset img { max-width: 100%; }
|
||||
|
||||
.fieldtip-left {float: left;}
|
||||
.fieldtip-left >* {margin-right: 20px;}
|
||||
.fieldtip-right { float: right; }
|
||||
.fieldtip-right>* { margin-left: 20px; display: inline-block; color: #666666; }
|
||||
.fieldtip .btn {display: inline-block;margin-bottom: 0;font-weight: normal;text-align: center;vertical-align: middle;-ms-touch-action: manipulation;touch-action: manipulation;cursor: pointer;background-image: none;border: 1px solid transparent;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;font-size: 14px;border-radius: 4px;color: #ffffff;background-color: #ff8a00;line-height: 18px;min-width: 28px;padding: 0 5px;}
|
||||
.fieldtip .btn:hover, .fieldtip .btn:active, .fieldtip .btn:active:hover, .fieldtip .btn:hover { color: #ffffff; background-color: #faad4a; }
|
||||
|
||||
/*填空题*/
|
||||
div.quizPutTag { display: inline-block; *display: inline; padding: 3px 10px 1px 10px; margin: 0 3px; font-size: 14px; min-width: 1em; min-height: 16px; line-height: 18px; height: auto; border-bottom: 1px solid #0033FF; text-decoration: none; zoom: 1; color: #127176; word-break: break-all; }
|
||||
div.quizPutTag:hover { color: #f60; }
|
||||
div.quizPutTag img { cursor: pointer; width: 200px; margin-left: 10px; }
|
||||
.sanwser { padding: 4px 10px; margin: 0px; border: 1px solid #ADCD3C; background-color: #F2FDDB; color: #000; display: none; }
|
||||
/*答案*/
|
||||
.selectoption label.s, div.s { border: 1px solid #91cbed; background-color: #deeeff; display: inline-block; }
|
||||
.selectoption label.s.sh, div.s.sh { margin: 1px; border: none; background: none; }
|
||||
del { text-decoration: none; color: #f00; font-style: normal; font-weight: normal; }
|
|
@ -75,6 +75,8 @@ const curBookImg = ref('')
|
|||
const curBookPath = ref('')
|
||||
// 上册
|
||||
const volumeOne = ref([])
|
||||
//
|
||||
const volumeTwo = ref([])
|
||||
|
||||
// 当前节点
|
||||
const currentNode = reactive({
|
||||
|
@ -90,14 +92,15 @@ const defaultExpandedKeys = ref([])
|
|||
const refTree = ref(null)
|
||||
|
||||
|
||||
//获取教材下面的单元内容
|
||||
//获取教材下面的单元 + 章节
|
||||
const getSubjectContent = async () => {
|
||||
treeLoading.value = true
|
||||
const params = {
|
||||
edusubject,
|
||||
edustage,
|
||||
entpcourseedituserid: userId,
|
||||
pageSize: 500
|
||||
// entpcourseedituserid: userId,
|
||||
itemgroup: 'textbook',
|
||||
pageSize: 10000
|
||||
}
|
||||
|
||||
let data;
|
||||
|
@ -114,7 +117,8 @@ const getSubjectContent = async () => {
|
|||
* 不区分上下册
|
||||
* 2024/08/20调整
|
||||
*/
|
||||
volumeOne.value = data.filter(item => item.level == 1)
|
||||
// volumeOne.value = data.filter(item => item.level == 1 && item.semester == '上册')
|
||||
// volumeTwo.value = data.filter(item => item.level == 1 && item.semester == '下册')
|
||||
getTreeData()
|
||||
}
|
||||
|
||||
|
@ -132,7 +136,9 @@ const changeBook = ({ id, itemtitle, avartar, fileurl }) => {
|
|||
|
||||
const getTreeData = () => {
|
||||
//数据过滤
|
||||
let upData = transData(volumeOne.value)
|
||||
let upData = transData(evaluationList.value)
|
||||
|
||||
|
||||
if(upData.length){
|
||||
treeData.value = [...upData]
|
||||
}
|
||||
|
@ -222,30 +228,33 @@ const transData = (data) => {
|
|||
let ary = []
|
||||
data.forEach(item => {
|
||||
let obj = {}
|
||||
// 根据当前教材ID 过滤出对应的单元、章节
|
||||
if (item.rootid == curBookId.value) {
|
||||
obj.label = item.itemtitle
|
||||
obj.id = item.id
|
||||
obj.itemtitle = item.itemtitle
|
||||
obj.edudegree = item.edudegree
|
||||
obj.edustage = item.edustage
|
||||
obj.edusubject = item.edusubject
|
||||
let ary2 = []
|
||||
evaluationList.value.forEach(el => {
|
||||
let obj2 = {}
|
||||
if (item.id == el.parentid) {
|
||||
obj2 = {
|
||||
label: el.itemtitle,
|
||||
id: el.id,
|
||||
itemtitle : el.itemtitle,
|
||||
edudegree : el.edudegree,
|
||||
edustage : el.edustage,
|
||||
edusubject : el.edusubject,
|
||||
if(item.level == 1){
|
||||
obj.label = item.itemtitle
|
||||
obj.id = item.id
|
||||
obj.itemtitle = item.itemtitle
|
||||
obj.edudegree = item.edudegree
|
||||
obj.edustage = item.edustage
|
||||
obj.edusubject = item.edusubject
|
||||
let ary2 = []
|
||||
evaluationList.value.forEach(el => {
|
||||
let obj2 = {}
|
||||
if (item.id == el.parentid) {
|
||||
obj2 = {
|
||||
label: el.itemtitle,
|
||||
id: el.id,
|
||||
itemtitle : el.itemtitle,
|
||||
edudegree : el.edudegree,
|
||||
edustage : el.edustage,
|
||||
edusubject : el.edusubject,
|
||||
}
|
||||
ary2.push(obj2)
|
||||
}
|
||||
ary2.push(obj2)
|
||||
}
|
||||
obj.children = ary2
|
||||
})
|
||||
ary.push(obj)
|
||||
obj.children = ary2
|
||||
})
|
||||
ary.push(obj)
|
||||
}
|
||||
}
|
||||
})
|
||||
return ary
|
||||
|
@ -254,8 +263,10 @@ const transData = (data) => {
|
|||
//获取教材
|
||||
const getSubject = async () => {
|
||||
|
||||
const { rows } = await listEvaluation({ itemkey: "version", pageSize: 500 })
|
||||
subjectList.value = rows.filter(item => item.edustage == edustage && item.edusubject == edusubject && isHaveUnit(item.id))
|
||||
const { rows } = await listEvaluation({ itemkey: "version", edusubject, edustage, pageSize: 10000 })
|
||||
|
||||
// subjectList.value = rows.filter(item => item.edustage == edustage && item.edusubject == edusubject)
|
||||
subjectList.value = rows
|
||||
localStorage.setItem('subjectList', JSON.stringify(subjectList.value))
|
||||
|
||||
// 默认第一个
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-drawer v-model="model" class="preview-drawer" title="title" :modal="false" :with-header="false" append-to-body
|
||||
<el-drawer v-model="model" class="preview-drawer" title="title" :modal="true" :destroy-on-close="true" :with-header="false" :append-to-body="true"
|
||||
size="50%">
|
||||
<div class="flex drawer-header">
|
||||
<div>
|
||||
|
@ -16,19 +16,23 @@
|
|||
</div>
|
||||
<div class="drawer-content">
|
||||
<!-- <iframe src="./aaa.pdf" width="600px" height="600px"></iframe> -->
|
||||
<!-- <div ref="playerRef" class="video-box"></div> -->
|
||||
<!-- <video src="" controls autoplay></video> -->
|
||||
<el-image style="width: 100%;" src="https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg" />
|
||||
<!--<div ref="playerRef" class="video-box"></div> -->
|
||||
<video v-if="showPrev(row) === 'video'" :src="row.fileFullPath" controls autoplay></video>
|
||||
<el-image v-if="showPrev(row) === 'img'" style="width: 100%;" :src="row.fileFullPath" />
|
||||
<template v-if="showPrev(row) === 'office'">
|
||||
<template v-for="item in row.prevImgList">
|
||||
<el-image :key="item.targetFileId" v-if="item.targetFileType === '预览图'" style="width: 100%;" :src="item.targetFilePath" />
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
<script setup>
|
||||
import { watch, ref, nextTick } from 'vue'
|
||||
import { watch, ref, nextTick, onMounted } from 'vue'
|
||||
import Player from 'xgplayer'
|
||||
import 'xgplayer/dist/index.min.css'
|
||||
import FileImage from '@/components/file-image/index.vue'
|
||||
|
||||
|
||||
const model = defineModel()
|
||||
const props = defineProps({
|
||||
row: {
|
||||
|
@ -42,11 +46,26 @@ const playerRef = ref();
|
|||
const handleClose = () => {
|
||||
|
||||
}
|
||||
|
||||
onMounted(()=>{
|
||||
})
|
||||
// 关闭
|
||||
const onClose = () => {
|
||||
model.value = false
|
||||
}
|
||||
|
||||
const showPrev = (row)=>{
|
||||
if(row.fileSuffix === 'mp4' || row.fileSuffix === 'mp3'){
|
||||
return 'video'
|
||||
}else if(row.fileType.indexOf('image') !== -1){
|
||||
return 'img'
|
||||
}else if(row.fileSuffix === 'doc' || row.fileSuffix === 'docx'|| row.fileSuffix === 'ppt'|| row.fileSuffix === 'pptx'|| row.fileSuffix === 'xls'|| row.fileSuffix === 'xlsx'){
|
||||
return 'office'
|
||||
}else {
|
||||
return 'other'
|
||||
}
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
nextTick(() => {
|
||||
// 播放器 基础用法
|
||||
|
@ -63,7 +82,7 @@ const init = () => {
|
|||
commonStyle:{
|
||||
progressColor: '#cccccce6',//进度条底色
|
||||
},
|
||||
|
||||
|
||||
});
|
||||
})
|
||||
}
|
||||
|
@ -121,4 +140,4 @@ watch(model, (newVal) => {
|
|||
width: 100%;
|
||||
height: 300px
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
|
|
@ -113,7 +113,8 @@ const getSubjectContent = async () => {
|
|||
const params = {
|
||||
edusubject,
|
||||
edustage,
|
||||
entpcourseedituserid: userId,
|
||||
// entpcourseedituserid: userId,
|
||||
itemgroup: 'textbook',
|
||||
pageSize: 500
|
||||
}
|
||||
let data;
|
||||
|
@ -129,7 +130,7 @@ const getSubjectContent = async () => {
|
|||
* 不区分上下册
|
||||
* 2024/08/20调整
|
||||
*/
|
||||
volumeOne.value = data.filter(item => item.level == 1)
|
||||
// volumeOne.value = data.filter(item => item.level == 1)
|
||||
|
||||
getTreeData()
|
||||
}
|
||||
|
@ -141,8 +142,8 @@ const getSubject = async () => {
|
|||
subjectList.value = JSON.parse(localStorage.getItem('subjectList'))
|
||||
}
|
||||
else {
|
||||
const { rows } = await listEvaluation({ itemkey: "version", pageSize: 500 })
|
||||
subjectList.value = rows.filter(item => item.edustage == edustage && item.edusubject == edusubject && isHaveUnit(item.id))
|
||||
const { rows } = await listEvaluation({ itemkey: "version", edusubject, edustage, pageSize: 500 })
|
||||
subjectList.value = rows
|
||||
localStorage.setItem('subjectList', JSON.stringify(subjectList.value))
|
||||
}
|
||||
|
||||
|
@ -160,7 +161,7 @@ const isHaveUnit = (id) => {
|
|||
|
||||
const getTreeData = () => {
|
||||
//数据过滤
|
||||
let upData = transData(volumeOne.value)
|
||||
let upData = transData(evaluationList.value)
|
||||
if(upData.length){
|
||||
treeData.value = [...upData]
|
||||
}
|
||||
|
@ -248,26 +249,35 @@ const handleNodeClick = (data, node) => {
|
|||
|
||||
const transData = (data) => {
|
||||
let ary = []
|
||||
|
||||
data.forEach(item => {
|
||||
let obj = {}
|
||||
|
||||
// 根据当前教材ID 过滤出对应的单元、章节
|
||||
if (item.rootid == curBookId.value) {
|
||||
obj.label = item.itemtitle
|
||||
obj.id = item.id
|
||||
let ary2 = []
|
||||
evaluationList.value.forEach(el => {
|
||||
let obj2 = {}
|
||||
if (item.id == el.parentid) {
|
||||
obj2 = {
|
||||
label: el.itemtitle,
|
||||
id: el.id
|
||||
if(item.level == 1){
|
||||
obj.label = item.itemtitle
|
||||
obj.id = item.id
|
||||
obj.itemtitle = item.itemtitle
|
||||
obj.edudegree = item.edudegree
|
||||
obj.edustage = item.edustage
|
||||
obj.edusubject = item.edusubject
|
||||
let ary2 = []
|
||||
evaluationList.value.forEach(el => {
|
||||
let obj2 = {}
|
||||
if (item.id == el.parentid) {
|
||||
obj2 = {
|
||||
label: el.itemtitle,
|
||||
id: el.id,
|
||||
itemtitle : el.itemtitle,
|
||||
edudegree : el.edudegree,
|
||||
edustage : el.edustage,
|
||||
edusubject : el.edusubject,
|
||||
}
|
||||
ary2.push(obj2)
|
||||
}
|
||||
ary2.push(obj2)
|
||||
}
|
||||
obj.children = ary2
|
||||
})
|
||||
ary.push(obj)
|
||||
obj.children = ary2
|
||||
})
|
||||
ary.push(obj)
|
||||
}
|
||||
}
|
||||
})
|
||||
return ary
|
||||
|
|
|
@ -110,7 +110,7 @@ const savaDataStore = () => {
|
|||
if(!toolState.isToolWin){
|
||||
toolState.isPdfWin=false
|
||||
toolState.showBoardAll=true //恢复默认值
|
||||
ipcRenderer.invoke('tool-sphere:reset') //重置tool状态
|
||||
// ipcRenderer.invoke('tool-sphere:reset') //重置tool状态
|
||||
ipcRenderer.send('open-PDF:minimize')
|
||||
return
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ const savaDataStore = () => {
|
|||
Promise.all(promises).then(res=>{
|
||||
toolState.isPdfWin=false
|
||||
toolState.showBoardAll=true //恢复默认值
|
||||
ipcRenderer.invoke('tool-sphere:reset') //重置tool状态
|
||||
// ipcRenderer.invoke('tool-sphere:reset') //重置tool状态
|
||||
ipcRenderer.send('open-PDF:minimize')
|
||||
})
|
||||
}
|
||||
|
|
|
@ -100,12 +100,14 @@ const renderPage = async (canvasobj) => {
|
|||
})
|
||||
}
|
||||
// 保存数据
|
||||
const savaDataStore = (type) => {
|
||||
const savaDataStore = async (type) => {
|
||||
if(!toolState.isToolWin){
|
||||
toolState.isPdfWin=false
|
||||
toolState.showBoardAll=true //恢复默认值
|
||||
toolState.isPdfWin = false
|
||||
await sleep(20) // 延时
|
||||
toolState.showBoardAll = true //恢复默认值
|
||||
await sleep(50) // 延时
|
||||
if(type=='rest'){
|
||||
ipcRenderer.invoke('tool-sphere:reset') //重置tool状态
|
||||
// ipcRenderer.invoke('tool-sphere:reset') //重置tool状态-废弃
|
||||
ipcRenderer.send('open-PDF:close')
|
||||
}else{
|
||||
ipcRenderer.invoke('open-PDF:minimize')
|
||||
|
@ -141,20 +143,24 @@ const savaDataStore = (type) => {
|
|||
|
||||
}
|
||||
})
|
||||
Promise.all(promises).then(res=>{
|
||||
Promise.all(promises).then(async res=>{
|
||||
toolState.isPdfWin=false
|
||||
await sleep(20) // 延时
|
||||
toolState.showBoardAll=true //恢复默认值
|
||||
await sleep(50) // 延时
|
||||
// ipcRenderer.send('open-PDF:minimize')
|
||||
if(type=='rest'){
|
||||
ipcRenderer.invoke('tool-sphere:reset') //重置tool状态
|
||||
// ipcRenderer.invoke('tool-sphere:reset') //重置tool状态-废弃
|
||||
ipcRenderer.send('open-PDF:close')
|
||||
}else{
|
||||
ipcRenderer.send('open-PDF:minimize')
|
||||
ipcRenderer.invoke('open-PDF:minimize')
|
||||
}
|
||||
// ipcRenderer.send('open-PDF:close')
|
||||
|
||||
})
|
||||
}
|
||||
// 延时
|
||||
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
|
||||
const updatePage = (canvasobj) => {
|
||||
renderPage(canvasobj)
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<template>
|
||||
<section class="app-main">
|
||||
<div class="app-main-left no-select">
|
||||
<!-- <div class="app-main-left no-select">
|
||||
<div v-for="(item, index) in title" :key="index" :class="item.active?'active':''" class="app-main-left-item" @click="active(index)">
|
||||
<div class="app-main-left-item-icon">
|
||||
<i :class="item.img"></i>
|
||||
</div>
|
||||
<div class="app-main-left-item-text">{{item.name}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<transition mode="out-in" name="fade-transform">
|
||||
<div v-show="$route != null" style="height: 100%; flex: 1">
|
||||
<router-view v-slot="{ Component, route }">
|
||||
|
@ -72,8 +72,9 @@ const title = reactive([
|
|||
child1: []
|
||||
},
|
||||
{
|
||||
name: '高考研究',
|
||||
url: '/education/colentrance',
|
||||
name: '考试分析',
|
||||
url: '/examReport',
|
||||
type: 'hash',
|
||||
img: 'iconfont icon-icon_kaoshifenxi',
|
||||
child1: []
|
||||
}
|
||||
|
@ -120,7 +121,7 @@ const active = (index) => {
|
|||
})
|
||||
}
|
||||
onMounted(()=>{
|
||||
active(0)
|
||||
// active(0)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
<template>
|
||||
<div class="title-bar flex">
|
||||
<div class="left-section">
|
||||
<h3 class="title" @click="changeTab">AIX智慧课堂</h3>
|
||||
<div class="flex title-box">
|
||||
<el-image style="width: 23px; height: 23px" :src="logoIco" />
|
||||
<span class="title" @click="changeTab">AIX智慧课堂</span>
|
||||
</div>
|
||||
<div class="change-tab">
|
||||
<ul class="flex">
|
||||
<li
|
||||
<li class="flex" :class="[activeId == menu.path ? 'active-li' : '', menu.disabled ? 'disabled' : '']"
|
||||
v-for="menu in headerMenus" :key="menu.id" @click="clickMenu(menu)">
|
||||
<i class="iconfont" :class="menu.icon"></i>
|
||||
<span class="text">{{ menu.name }}</span>
|
||||
</li>
|
||||
|
||||
<!-- <li
|
||||
v-for="(item, index) in routeHeader.nowRouter"
|
||||
:key="index"
|
||||
class="flex"
|
||||
|
@ -14,7 +23,7 @@
|
|||
>
|
||||
<i :class="item.img"></i>
|
||||
<span class="text">{{ item.name }}</span>
|
||||
</li>
|
||||
</li> -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -58,6 +67,8 @@ import useUserStore from '@/store/modules/user'
|
|||
import routerStore from '@/store/modules/route'
|
||||
import outLink from '@/utils/linkConfig'
|
||||
|
||||
import logoIco from '@/assets/images/logo.png'
|
||||
|
||||
const routeHeader = routerStore()
|
||||
const { ipcRenderer } = window.electron || {}
|
||||
const userStore = useUserStore()
|
||||
|
@ -76,7 +87,7 @@ const handleOutLink = (path, type, name) => {
|
|||
fullPath = fullPath.replaceAll('//', '/')
|
||||
const { levelFirstId, levelSecondId } = JSON.parse(localStorage.getItem('unitId'))
|
||||
let unitId = levelSecondId ? levelSecondId :levelFirstId
|
||||
if(name == '教材分析' || name == '高考研究'){
|
||||
if(name == '教材分析' || name == '考试分析'){
|
||||
fullPath += `?unitId=${unitId}`
|
||||
}
|
||||
// 通知主进程
|
||||
|
@ -87,6 +98,41 @@ const handleOutLink = (path, type, name) => {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
const activeId = ref('/home')
|
||||
const headerMenus = [
|
||||
{
|
||||
name: '工作台',
|
||||
id: 1,
|
||||
icon: 'icon-gongzuotai',
|
||||
path: '/home'
|
||||
},
|
||||
{
|
||||
name: '研究室',
|
||||
id: 2,
|
||||
icon: 'icon-yanjiushi',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
name: '资源库',
|
||||
id: 3,
|
||||
icon: 'icon-saoyisao',
|
||||
path: '/resource'
|
||||
},
|
||||
{
|
||||
name: '朋友圈',
|
||||
id: 4,
|
||||
icon: 'icon-pengyouquan1',
|
||||
disabled: true
|
||||
}
|
||||
]
|
||||
|
||||
const clickMenu = ({ id, disabled, path }) =>{
|
||||
if(disabled) return
|
||||
activeId.value = id
|
||||
router.push(path)
|
||||
}
|
||||
|
||||
/*const menus = ref([
|
||||
{
|
||||
icon: 'icon-zhuye2 icon-homepage',
|
||||
|
@ -114,7 +160,8 @@ const handleOutLink = (path, type, name) => {
|
|||
watch(
|
||||
() => router.currentRoute.value,
|
||||
(newValue) => {
|
||||
currentRoute.value = newValue.path
|
||||
currentRoute.value = newValue
|
||||
activeId.value = newValue.path
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
@ -165,8 +212,6 @@ function setLayout() {
|
|||
<style lang="scss" scoped>
|
||||
.title-bar {
|
||||
height: 80px;
|
||||
background: #ebf0f9;
|
||||
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
-webkit-app-region: drag;
|
||||
|
@ -174,27 +219,38 @@ function setLayout() {
|
|||
|
||||
.left-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
width: 50%;
|
||||
|
||||
.title-box{
|
||||
padding-top: 8px;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
padding-left: 20px;
|
||||
.title {
|
||||
color: #4b73df;
|
||||
font-size: 13px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
.change-tab {
|
||||
-webkit-app-region: no-drag;
|
||||
margin-left: 20px;
|
||||
|
||||
ul {
|
||||
li {
|
||||
padding: 3px 13px;
|
||||
cursor: pointer;
|
||||
flex-direction: column;
|
||||
border-radius: 8px;
|
||||
margin: 0 5px;
|
||||
margin: 0 10px;
|
||||
|
||||
.text {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-size: 22px;
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
.icon-resource {
|
||||
|
@ -214,12 +270,17 @@ function setLayout() {
|
|||
}
|
||||
|
||||
&:hover {
|
||||
background: #d3e3fb;
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
.disabled{
|
||||
cursor: not-allowed;
|
||||
color: #bfbfbf;
|
||||
&:hover{
|
||||
color: #bfbfbf;
|
||||
}
|
||||
}
|
||||
|
||||
.active-li {
|
||||
background: #d3e3fb;
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
@ -229,11 +290,7 @@ function setLayout() {
|
|||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #4b73df;
|
||||
font-size: 18px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.right-section {
|
||||
|
|
|
@ -4,20 +4,45 @@
|
|||
<Header />
|
||||
</el-header>
|
||||
<el-main>
|
||||
<AppMain />
|
||||
<template v-if="currentRoute.path != '/home'">
|
||||
<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>
|
||||
<Uploader v-if="uploaderStore.uploadList && uploaderStore.uploadList.length > 0" />
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import Header from './components/Header.vue'
|
||||
import AppMain from './components/AppMain.vue'
|
||||
import Uploader from './components/Uploader.vue'
|
||||
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())
|
||||
|
||||
const goBack = () =>{
|
||||
router.back()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -32,6 +57,15 @@ let uploaderStore = ref(uploaderState())
|
|||
height: 80px;
|
||||
}
|
||||
.el-main {
|
||||
--el-main-padding: 0 20px 0 0;
|
||||
--el-main-padding: 0 20px 20px 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-page-header{
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.text-large{
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -8,6 +8,7 @@ import 'element-plus/dist/index.css'
|
|||
import './assets/iconfont/iconfont.css'
|
||||
import './assets/iconfont/iconfont'
|
||||
import 'virtual:windi.css'
|
||||
import request from "@/utils/request";
|
||||
|
||||
import { store } from '@/store'
|
||||
import App from './App.vue'
|
||||
|
@ -20,6 +21,20 @@ if(process.env.NODE_ENV != 'development') { // 非开发环境,将日志打印
|
|||
|
||||
const app = createApp(App)
|
||||
|
||||
|
||||
//专为菁优网配置的请求转发
|
||||
app.config.globalProperties.$requestGetJYW = (url,config)=>{
|
||||
config.params = config.params?config.params:{}
|
||||
config.params["getjypath"] = url;
|
||||
return request({
|
||||
url: "/jy/proxy",
|
||||
method: config.method||"get",
|
||||
params: config.params
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
app.use(router)
|
||||
.use(store)
|
||||
.use(ElementPlus, { locale: zhLocale }).mount('#app')
|
|
@ -13,6 +13,7 @@ import IMListeners from './imLiseners' // im消息-监听器
|
|||
const API = window.api
|
||||
// TIM生成签名
|
||||
// import * as GenerateUserSig from './userSig' // 引入签名生成器
|
||||
const isDev = process.env.NODE_ENV == 'development' // 环境
|
||||
export class ImChat {
|
||||
timChat // imChat对象
|
||||
SDKAppID // sdkID
|
||||
|
@ -48,10 +49,11 @@ export class ImChat {
|
|||
}
|
||||
// 设置配置
|
||||
async setConfig() {
|
||||
const log_level = TYPES.TIMLogLevel.kTIMLog_Error
|
||||
await this.timChat.TIMSetConfig({ // TIMSetConfigParam
|
||||
json_config: { // JSONCongfig
|
||||
set_config_log_level: TYPES.TIMLogLevel.kTIMLog_Test,
|
||||
set_config_callback_log_level: TYPES.TIMLogLevel.kTIMLog_Error,
|
||||
set_config_log_level: log_level,
|
||||
set_config_callback_log_level: log_level,
|
||||
set_config_is_log_output_console: true,
|
||||
// set_config_user_config: { // 用户配置
|
||||
// user_config_is_read_receipt: true, // true表示要收已读回执事件
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
const isNode = typeof require !== 'undefined' // 是否支持node函数
|
||||
const { ipcRenderer } = isNode?require('electron'):{} // app使用
|
||||
import { sessionStore } from '@/utils/store'
|
||||
// import { diff } from 'jsondiffpatch'
|
||||
// const Remote = isNode?require('@electron/remote'):{} // 远程模块
|
||||
|
||||
export function shareStorePlugin({store}) {
|
||||
store.$subscribe((mutation, state) => { // 自动同步
|
||||
// mutation 变量包含了变化前后的状态
|
||||
|
@ -19,8 +21,8 @@ export function shareStorePlugin({store}) {
|
|||
if (names.includes(storeName)) {
|
||||
const { storeId: storeName, payload, events, type } = mutation // direct
|
||||
// if (!Object.keys(payload).length) return
|
||||
if (type != 'direct' || !events || Array.isArray(events) || !events.key) return
|
||||
stateSync(storeName, events.key, events.newValue, state) // 需要同步
|
||||
// if (type != 'direct' || !events || Array.isArray(events) || !events.key) return
|
||||
stateSyncWatch(storeName, state) // 需要同步
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -51,6 +53,28 @@ function stateSync(storeName, key, value, state) {
|
|||
console.log('state-change-error', error)
|
||||
}
|
||||
}
|
||||
// 同步数据-发送给主线程-单独($subscribe-监听使用)
|
||||
function stateSyncWatch(storeName, newState) {
|
||||
const oldState = sessionStore.store // 旧数据
|
||||
const diffData = findDifferences(oldState, newState)
|
||||
// console.log('state-change-diffData', diffData)
|
||||
try {
|
||||
for(const key in diffData) {
|
||||
const value = diffData[key]
|
||||
const newValue = {} // 重新组装pinia需要的数据 {a:{b:1}} 这种
|
||||
const keyArr = key.split('.') || []
|
||||
keyArr.reduce((o,c,i)=>{o[c] = i === keyArr.length-1 ? value : {};return o[c]}, newValue)
|
||||
const jsonStr = JSON.stringify(newValue) // 从新组装-json数据
|
||||
// // 更新本地数据-session
|
||||
sessionStore.set(key, value)
|
||||
// // 通知主线程更新
|
||||
ipcRenderer?.invoke('pinia-state-change', storeName, jsonStr)
|
||||
// console.log('======',key, value, jsonStr )
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('state-change-error', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 同步数据-发送给主线程-全量更新
|
||||
function stateSyncAll(store) {
|
||||
|
@ -68,12 +92,24 @@ function stateSyncInit(wid, store) {
|
|||
ipcRenderer.invoke('pinia-state-init', wid, storeName, curJson)
|
||||
}
|
||||
|
||||
// 监听session数据变化
|
||||
function sessionWatch(store) {
|
||||
const unsubscribe = sessionStore.onDidAnyChange((newV, oldV) => {
|
||||
if (newV !== oldV) {
|
||||
console.log('session-change', newV, oldV)
|
||||
// 通知主线程更新
|
||||
// ipcRenderer?.invoke('pinia-state-change', storeName, jsonStr)
|
||||
}
|
||||
})
|
||||
// unsubscribe() 取消监听
|
||||
}
|
||||
|
||||
// 同步数据-接收主线程消息
|
||||
function stateChange(store) {
|
||||
const storeName = store.$id
|
||||
ipcRenderer?.on('pinia-state-set', (e, sName, jsonStr) => {
|
||||
if (sName == storeName) { // 更新对应数据
|
||||
// console.log('state-set', jsonStr, sName)
|
||||
console.log('state-set', jsonStr, sName)
|
||||
const curJson = circularSafeStringify(store.$state) // 当前数据
|
||||
const isUp = curJson != jsonStr // 不同的时候才写入,不然会导致触发数据变化监听,导致死循环
|
||||
if (!isUp) return
|
||||
|
@ -124,5 +160,48 @@ const filterByKey = (obj, key, value) => {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// 获取对象值
|
||||
const getObjValue = (obj, key) => {
|
||||
|
||||
}
|
||||
|
||||
// 找出两个对象之间的差异
|
||||
const findDifferences = (obj1, obj2) => {
|
||||
const differences = {};
|
||||
function compareObjects(o1, o2, path = '') {
|
||||
for (const key in o1) {
|
||||
if (o1.hasOwnProperty(key)) {
|
||||
const newPath = path ? `${path}.${key}` : key;
|
||||
if (o2.hasOwnProperty(key)) {
|
||||
const v1 = toJsonStr(o1[key])
|
||||
const v2 = toJsonStr(o2[key])
|
||||
if (typeof o1[key] === 'object' && typeof o2[key] === 'object' && !Array.isArray(o1[key])) {
|
||||
compareObjects(o1[key], o2[key], newPath);
|
||||
} else if (v1 !== v2) {
|
||||
differences[newPath] = o2[key];
|
||||
}
|
||||
} else {
|
||||
differences[newPath] = o2[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in o2) {
|
||||
if (o2.hasOwnProperty(key) && !o1.hasOwnProperty(key)) {
|
||||
const newPath = path ? `${path}.${key}` : key;
|
||||
differences[newPath] = o2[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compareObjects(objClone(obj1), objClone(obj2));
|
||||
// 特殊处理
|
||||
|
||||
|
||||
return differences;
|
||||
}
|
||||
// 对象克隆
|
||||
const objClone = (obj) => JSON.parse(JSON.stringify(obj))
|
||||
// 转换为json
|
||||
const toJsonStr = (obj) => JSON.stringify(obj)
|
||||
|
|
|
@ -13,8 +13,14 @@ export const constantRoutes = [
|
|||
{
|
||||
path: '/',
|
||||
component: Layout,
|
||||
redirect: '/homepage',
|
||||
redirect: '/home',
|
||||
children: [
|
||||
{
|
||||
path: '/home',
|
||||
component: () => import('@/views/desktop/index.vue'),
|
||||
name: 'desktop',
|
||||
meta: {title: '主页'}
|
||||
},
|
||||
{
|
||||
path: '/homepage',
|
||||
component: () => import('@/views/homePage/index.vue'),
|
||||
|
@ -57,6 +63,12 @@ export const constantRoutes = [
|
|||
name: 'class',
|
||||
meta: {title: '班级中心'},
|
||||
},
|
||||
{
|
||||
path: '/examReport',
|
||||
component: () => import('@/views/examReport/index.vue'),
|
||||
name: 'examReport',
|
||||
meta: {title: '考试分析'}
|
||||
},
|
||||
]
|
||||
},
|
||||
...toolRouters
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
* 工具类-窗口-状态管理
|
||||
*/
|
||||
import { defineStore } from 'pinia'
|
||||
import { sessionStore } from '@/utils/tool'
|
||||
import { sessionStore } from '@/utils/store'
|
||||
|
||||
// 默认数据
|
||||
const defData = sessionStore.store || {}
|
||||
// 延时
|
||||
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
|
||||
|
||||
export const useToolState = defineStore('tool', {
|
||||
state: () => ({
|
||||
|
@ -20,5 +22,12 @@ export const useToolState = defineStore('tool', {
|
|||
...defData // 默认数据-覆盖上面的配置(不要删除, 会导致新窗口-获取状态失败)
|
||||
}),
|
||||
actions: {
|
||||
async resetDef() { // 重置数据-下课
|
||||
this.model = 'select' // 悬浮球-当前模式
|
||||
await sleep(20) // 休眠20ms
|
||||
this.showBoardAll = false // 全屏画板-是否显示
|
||||
await sleep(20) // 休眠20ms
|
||||
this.isToolWin = false // 工具窗口是否打开
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
const JY_TOKEN = 'CA82641DA86072DEFD39E287335E035FDA6AEEC0549B58F54F4408734C8683FFAF0585CFA3B25091E588A03A65C66A80F5FF613F539D600954007A35DFFBFDC3C7BB982771C5E13F0918642CFD7596CE3718F06E5579238D92EC809AC6F4C82A9FE4B0E232A67DD3594D4DAC1C219CCBC4A7A093344446107EB11DC317526D0594249DEBBD82B740C794CF5A7065E1982B7779AF16AD25D7';
|
||||
const JY_SUBJECT = [
|
||||
{id: 10, subject: 'math3', name: '小学数学'},
|
||||
{id: 11, subject: 'chinese3', name: '小学语文'},
|
||||
{id: 12, subject: 'english3', name: '小学英语'},
|
||||
{id: 14, subject: 'science3', name: '小学科学'},
|
||||
{id: 15, subject: 'politics3', name: '小学道德与法治'},
|
||||
{id: 20, subject: 'math', name: '初中数学'},
|
||||
{id: 21, subject: 'physics', name: '初中物理'},
|
||||
{id: 22, subject: 'chemistry', name: '初中化学'},
|
||||
{id: 23, subject: 'bio', name: '初中生物'},
|
||||
{id: 24, subject: 'science', name: '初中科学'},
|
||||
{id: 25, subject: 'geography', name: '初中地理'},
|
||||
{id: 26, subject: 'chinese', name: '初中语文'},
|
||||
{id: 27, subject: 'english', name: '初中英语'},
|
||||
{id: 28, subject: 'politics', name: '初中道德与法治'},
|
||||
{id: 29, subject: 'history', name: '初中历史'},
|
||||
{id: 30, subject: 'math2', name: '高中数学'},
|
||||
{id: 31, subject: 'physics2', name: '高中物理'},
|
||||
{id: 32, subject: 'chemistry2', name: '高中化学'},
|
||||
{id: 33, subject: 'bio2', name: '高中生物'},
|
||||
{id: 35, subject: 'geography2', name: '高中地理'},
|
||||
{id: 36, subject: 'chinese2', name: '高中语文'},
|
||||
{id: 37, subject: 'english2', name: '高中英语'},
|
||||
{id: 38, subject: 'politics2', name: '高中政治'},
|
||||
{id: 39, subject: 'history2', name: '高中历史'},
|
||||
];
|
||||
|
||||
|
||||
export const JYApiListCT = async (_this, name = '高中历史') => {
|
||||
if (name === '初中政治') {
|
||||
name = '初中道德与法治';
|
||||
}
|
||||
const obj = JY_SUBJECT.filter(item => item.name == name);
|
||||
if(obj.length < 1) {
|
||||
return [];
|
||||
}
|
||||
const res = await _this.$requestGetJYW(`/${obj[0].subject}/common`, {
|
||||
headers: {
|
||||
authorization: `Token ${JY_TOKEN}`
|
||||
},
|
||||
params: {
|
||||
tp: 1,
|
||||
},
|
||||
});
|
||||
if (res.code !== 200) {
|
||||
return [];
|
||||
}
|
||||
let arrCT = [{
|
||||
label: "不限",
|
||||
value: 0
|
||||
}]
|
||||
res.data.forEach(item=> {
|
||||
if (item.Value === '选择题') {
|
||||
item.Value = '单选题';
|
||||
}
|
||||
const tmp = {
|
||||
label: item.Value,
|
||||
value: item.Key,
|
||||
}
|
||||
arrCT.push(tmp);
|
||||
})
|
||||
return arrCT;
|
||||
}
|
||||
|
||||
export const JYApiListOriginYear = () => {
|
||||
const arrYear = [{label: '不限', value: '-1'}];
|
||||
let i = 0;
|
||||
for( ; i < 10; i++) {
|
||||
const year = new Date().getFullYear();
|
||||
const s ={
|
||||
label: `${year - i}`,
|
||||
value: `${year - i}`,
|
||||
}
|
||||
arrYear.push(s);
|
||||
};
|
||||
//arrYear.push({label: '更早', value: '0'})
|
||||
return arrYear;
|
||||
}
|
||||
|
||||
export const JYApiListSO = async (_this, name = '高中历史') => {
|
||||
if (name === '初中政治') {
|
||||
name = '初中道德与法治';
|
||||
}
|
||||
|
||||
const obj = JY_SUBJECT.filter(item => item.name == name);
|
||||
if(obj.length < 1) {
|
||||
return [];
|
||||
}
|
||||
const res = await _this.$requestGetJYW(`/${obj[0].subject}/common`, {
|
||||
headers: {
|
||||
authorization: `Token ${JY_TOKEN}`
|
||||
},
|
||||
params: {
|
||||
tp: 2,
|
||||
},
|
||||
});
|
||||
if (res.code !== 200) {
|
||||
return [];
|
||||
}
|
||||
const arrSO = [{"Value": "不限", "Key": 0}, ...res.data];
|
||||
return arrSO;
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const JYApiListPoint = async (_this, name = '高中历史') => {
|
||||
if (name === '初中政治') {
|
||||
name = '初中道德与法治';
|
||||
}
|
||||
|
||||
const obj = JY_SUBJECT.filter(item => item.name == name);
|
||||
if(obj.length < 1) {
|
||||
return [];
|
||||
}
|
||||
const res = await _this.$requestGetJYW(`/${obj[0].subject}/point`, {
|
||||
headers: {
|
||||
authorization: `Token ${JY_TOKEN}`
|
||||
},
|
||||
});
|
||||
if (res.code !== 200) {
|
||||
return [];
|
||||
}
|
||||
return res.data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @desc: 获取菁优网的版本内容
|
||||
* @return: {*}
|
||||
*/
|
||||
export const JYApiListVersion = async (_this, query, hasPoints=true) => {
|
||||
const listVersion = {
|
||||
status: 0,
|
||||
msg: '',
|
||||
data: [],
|
||||
};
|
||||
if (query.stage === '' || query.subject === '') {
|
||||
listVersion.msg = '未选中学段或学科!';
|
||||
return listVersion;
|
||||
}
|
||||
let name = `${query.stage}${query.subject}`;
|
||||
if (name === '初中政治') {
|
||||
name = '初中道德与法治';
|
||||
}
|
||||
const result = JY_SUBJECT.filter( item => item.name===name);
|
||||
if (result.length === 0) {
|
||||
listVersion.msg = `[${name}]未找到对应菁优网教材版本, 请检查学段或学科是否匹配!`;
|
||||
return listVersion;
|
||||
}
|
||||
const JYBook = await _this.$requestGetJYW(`/${result[0].subject}/book2`, {
|
||||
headers: {
|
||||
// JYToken仅占位, 实际后续已未使用该token
|
||||
authorization: `Token ${JY_TOKEN}`
|
||||
},
|
||||
});
|
||||
if (JYBook.code !== 200) {
|
||||
listVersion.msg = `[${name}]获取菁优网教材版本失败!`;
|
||||
return listVersion;
|
||||
}
|
||||
query.list.forEach(ele => {
|
||||
if (ele.thirdkey == null) {
|
||||
listVersion.msg = `[${name}-${ele.itemtitle}]菁优网教材字段标识未设置!`;
|
||||
return;
|
||||
}
|
||||
let nPos = ele.thirdkey.indexOf('-');
|
||||
if (nPos === -1) {
|
||||
listVersion.msg = `[${name}-${ele.itemtitle}-${ele.thirdkey}]菁优网教材字段标识设置有误!`;
|
||||
return;
|
||||
}
|
||||
let editionName = ele.thirdkey.substring(0, nPos);
|
||||
let typeName = ele.thirdkey.substring(nPos+1);
|
||||
const resVersion = JYBook.data.filter( item => {
|
||||
// 高中以typeName为标识, 而小学/初中以Name为标识
|
||||
const JYTypeName = query.stage=='高中' ? item.TypeName : item.Name;
|
||||
if (item.EditionName.trim() === editionName.trim() && JYTypeName.trim() === typeName.trim()) {
|
||||
return true;
|
||||
}
|
||||
})
|
||||
|
||||
if (resVersion.length === 0) {
|
||||
listVersion.msg = `[${name}-${ele.thirdkey}]菁优网教材字段标识查询不存在!`;
|
||||
return;
|
||||
}
|
||||
if (resVersion[0].Children.length === 0) {
|
||||
listVersion.msg = `[${name}]菁优网教材字段标识查询单元内容为空!`;
|
||||
return;
|
||||
}
|
||||
const children = JYApiListLession(resVersion[0], hasPoints);
|
||||
// 高中以typeName为标识, 而小学/初中以Name为标识
|
||||
let JYTypeName = query.stage=='高中' ? resVersion[0].TypeName : resVersion[0].Name;
|
||||
JYTypeName = JYTypeName.trim();
|
||||
const reset = {
|
||||
id: resVersion[0].ID,
|
||||
label: resVersion[0].Name.trim(),
|
||||
nodeType: 'version',
|
||||
children: children,
|
||||
editionName: resVersion[0].EditionName.trim(),
|
||||
typeName: JYTypeName,
|
||||
}
|
||||
listVersion.data.push(reset);
|
||||
})
|
||||
|
||||
if(listVersion.data.length > 0){
|
||||
listVersion.status = 1;
|
||||
}
|
||||
return listVersion;
|
||||
}
|
||||
|
||||
|
||||
const JYApiListLession = (item, hasPoints) => {
|
||||
const list = [];
|
||||
item.Children.forEach(element => {
|
||||
const tempList = formatCurJYLession(element, hasPoints);
|
||||
list.push(tempList);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
const formatCurJYLession = (item, hasPoints) => {
|
||||
const obj = {
|
||||
id: item.ID,
|
||||
label: item.Name.trim(),
|
||||
nodeType: 'unit',
|
||||
children: [],
|
||||
}
|
||||
if(hasPoints) {
|
||||
if (item.Children.length === 0 && !item.hasOwnProperty('Points')) {
|
||||
obj.nodeType = 'points';
|
||||
obj.id = item.No;
|
||||
return obj;
|
||||
}
|
||||
else if (item.Children.length > 0 ){
|
||||
for(let i=0; i<item.Children.length; i++){
|
||||
const child = formatCurJYLession(item.Children[i], hasPoints);
|
||||
obj.children.push(child);
|
||||
}
|
||||
}
|
||||
else if (item.Children.length === 0 && item.Points.length > 0){
|
||||
obj.nodeType = 'lession';
|
||||
for(let i=0; i<item.Points.length; i++){
|
||||
const child = formatCurJYLession(item.Points[i], hasPoints);
|
||||
obj.children.push(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (item.Children.length === 0) {
|
||||
obj.nodeType = 'lession';
|
||||
obj.id = item.ID;
|
||||
return obj;
|
||||
}
|
||||
else if (item.Children.length > 0 ){
|
||||
for(let i=0; i<item.Children.length; i++){
|
||||
const child = formatCurJYLession(item.Children[i], hasPoints);
|
||||
obj.children.push(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
|
@ -0,0 +1,310 @@
|
|||
export const isJson = (str) =>{
|
||||
if (typeof str == 'string') {
|
||||
try {
|
||||
let obj=JSON.parse(str);
|
||||
if(typeof obj == 'object' && obj ){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @description processExamQuestion 格式化试题
|
||||
* @param {*} row
|
||||
*/
|
||||
export const processExamQuestion = (row) => {
|
||||
for (var i=0; i<row.length; i++) {
|
||||
if (isJson(row[i].workanalysis)) {
|
||||
//1、先默认格式化 格式化各项内容(待优化, 后续界面显示的为format的值)
|
||||
row[i].titleFormat = row[i].title; // 题目
|
||||
row[i].examdateFormat = row[i].examdate; // ?考试日期 eg: 2024-07-11 14:39:27"
|
||||
row[i].workdescFormat = row[i].workdesc; // 题目选项
|
||||
row[i].workanswerFormat = row[i].workanswer; // 题目正确答案
|
||||
if (row[i].workanswerFormat == null || row[i].workanswerFormat == '') {
|
||||
row[i].workanswerFormat = '见试题解答内容';
|
||||
}
|
||||
|
||||
// workanalysis 解析内容(analyse:解答; method:分析; discuss:点评; )
|
||||
var jjj = JSON.parse(row[i].workanalysis);
|
||||
row[i].analyse = jjj.analyse;
|
||||
row[i].method = jjj.method;
|
||||
row[i].discuss = jjj.discuss;
|
||||
//row[i].discusscollapse = false;
|
||||
if(row[i].examdate !== null && row[i].examdate !== undefined ){
|
||||
row[i].examdate = row[i].examdate.substring(0, 10);
|
||||
}
|
||||
|
||||
// 具体题型数据结构处理
|
||||
if (row[i].worktype == '复合题') {
|
||||
// 旧类型
|
||||
if(row[i].title.indexOf('!@#$%') !== -1) {
|
||||
// 1.选项解析替换
|
||||
const options = JSON.parse(row[i].workdesc);
|
||||
// 题目(背景材料+复合题目)
|
||||
const bjTitle = row[i].title.split('!@#$%')[0];
|
||||
const tmTitles = row[i].title.split('!@#$%').filter((it,ix)=>ix>0);
|
||||
// console.log(bjTitle,'背景标题');
|
||||
// console.log(tmTitles,'复合题目');
|
||||
let titls = [];
|
||||
options.forEach((element,index1) => {
|
||||
const workDescArr = element.split('#&');
|
||||
let tmp = '';
|
||||
let j=0;
|
||||
for(; j<workDescArr.length; j++){
|
||||
if(j%2 == 0){
|
||||
tmp += `<div style='width:80%;display:flex;'>`;
|
||||
}
|
||||
const char = String.fromCharCode(65+j);
|
||||
tmp += `<div style='display:flex;margin-left:2%;width:35%;overflow:hidden;text-overflow:ellipsis;font-size:0.9em;'>${char}.${workDescArr[j]}</div>`;
|
||||
if(j%2 == 1){
|
||||
tmp += '</div>';
|
||||
}
|
||||
|
||||
}
|
||||
// j此刻已自增1, 故当选项为单数时, 需要补充结束标签
|
||||
if(j%2 == 1){
|
||||
tmp += '</div>';
|
||||
}
|
||||
|
||||
// workDescArr为 [''] 表示为 判断题或者填空题,这里不需要选项
|
||||
if(workDescArr[0] != ''){
|
||||
titls.splice(index1, 1, tmp);
|
||||
}else{
|
||||
titls.splice(index1, 1, '');
|
||||
}
|
||||
});
|
||||
const s = [];
|
||||
tmTitles.map((it,ix)=>{
|
||||
s.push(it);
|
||||
titls.map((it2,ix2)=>{
|
||||
if(ix == ix2){
|
||||
s.push(it2);
|
||||
}
|
||||
})
|
||||
})
|
||||
// console.log(s,'?????????????????')
|
||||
|
||||
row[i].titleFormat = bjTitle + s.join('');
|
||||
row[i].workdescFormat = '';
|
||||
|
||||
|
||||
//2.答案 - 数字转为ABCD
|
||||
const answerArr = JSON.parse(row[i].workanswer);
|
||||
let indexLabel = 1;
|
||||
let arr = [];
|
||||
answerArr.forEach(item => {
|
||||
const arrTmp = item.answer.split('#&');
|
||||
let value = `(${indexLabel})`;
|
||||
arrTmp.forEach((element,i) => {
|
||||
if(item.type == '单选题' || item.type == '多选题'){
|
||||
value += `${String.fromCharCode(65+Number(element))}`;
|
||||
}
|
||||
if(item.type == '判断题' || item.type == '填空题'){
|
||||
// 去除下 html标签
|
||||
value += `${element.replace(/<[^>]+>/g, '')}`+ (i==arrTmp.length-1?'':'、');
|
||||
}
|
||||
if(item.type == '主观题') {
|
||||
if(element){
|
||||
console.log(element,'element')
|
||||
value += item.answer;
|
||||
}else{
|
||||
value += '答案不唯一,请参考分析解答点评!';
|
||||
}
|
||||
}
|
||||
})
|
||||
arr.push(value);
|
||||
indexLabel++;
|
||||
})
|
||||
const answer = arr.join('<br />');
|
||||
|
||||
row[i].workanswerFormat = answer;
|
||||
}
|
||||
else {
|
||||
// 处理[题干显示] - 不再需要处理
|
||||
// row[i].titleFormat = row[i].title; // 仅占位提示
|
||||
|
||||
/**
|
||||
* 处理[选项显示] - 特殊结构
|
||||
* [
|
||||
* {type: '单选题', title: '题目1', options: ['ABC123','ABC123']},
|
||||
* {type: '多选题', title: '题目1', options: ['ABC123','ABC123']},
|
||||
* {type: '填空题', title: '题目1', options: []},
|
||||
* {type: '判断题', title: '题目1', options: []},
|
||||
* {type: '主观题', title: '题目1', options: []},
|
||||
* ]
|
||||
*/
|
||||
let workDescArr = JSON.parse(row[i].workdesc);
|
||||
let workDescHtml = `<div style='width:80%;display:flex;>`;
|
||||
workDescArr.map( (item, index) => {
|
||||
if(item.type == '单选题' || item.type == '多选题'){
|
||||
workDescHtml += `<div style='width:80%;display:flex;'>${index+1}. ${item.title}</div>`;
|
||||
let tmp = '';
|
||||
let j=0;
|
||||
let optionsArr = item.options;
|
||||
for(; j<optionsArr.length; j++){
|
||||
if(j%2 == 0){
|
||||
tmp += `<div style='width:80%;display:flex;'>`;
|
||||
}
|
||||
const char = String.fromCharCode(65+j);
|
||||
tmp += `<div style='display:flex;margin-left: 2%; width: 36%'>${char}.${optionsArr[j]}</div>`;
|
||||
if(j%2 == 1){
|
||||
tmp += '</div>';
|
||||
}
|
||||
}
|
||||
// j此刻已自增1, 故当选项为单数时, 需要补充结束标签
|
||||
if(j%2 == 1){
|
||||
tmp += '</div>';
|
||||
}
|
||||
|
||||
workDescHtml += tmp;
|
||||
}
|
||||
else if(item.type == '填空题' || item.type == '判断题' || item.type == '主观题'){
|
||||
workDescHtml += `<div style='width:80%;display:flex;'>${index+1}. ${item.title}</div>`;
|
||||
}
|
||||
})
|
||||
workDescHtml += '</div>';
|
||||
row[i].workdescFormat = workDescHtml;
|
||||
|
||||
/**
|
||||
* 处理[答案显示] - 特殊结构
|
||||
* [
|
||||
* {type: '单选题', answer: ['0']},
|
||||
* {type: '多选题', answer: ['0','1']},
|
||||
* {type: '填空题', answer: ['填空1','填空2']},
|
||||
* {type: '判断题', answer: ['0'/'1']},
|
||||
* {type: '主观题', answer: [xxxx]},
|
||||
* ]
|
||||
*/
|
||||
let workAnswerArr = JSON.parse(row[i].workanswer);
|
||||
let workAnswerHtml = ``;
|
||||
workAnswerArr.map( (item, index) => {
|
||||
const answerArr = item.answer; //JSON.parse(item.answer);
|
||||
if(item.type == '单选题' || item.type == '多选题'){
|
||||
const answer = answerArr.map( (item) => {
|
||||
return String.fromCharCode(65+Number(item))
|
||||
}).join('');
|
||||
workAnswerHtml += `<div style='display:flex;'>${index+1}. ${answer}</div>`;
|
||||
}
|
||||
else if(item.type == '填空题' ){
|
||||
const answer = answerArr.join('、');
|
||||
workAnswerHtml += `<div style='display:flex;'>${index+1}. ${answer}</div>`;
|
||||
}
|
||||
else if(item.type == '判断题' ){
|
||||
const answer = answerArr.map( (item) => {
|
||||
return item === '1' ? '正确' : '错误'
|
||||
}).join('、');
|
||||
workAnswerHtml += `<div style='display:flex;'>${index+1}. ${answer}</div>`;
|
||||
}
|
||||
else if(item.type == '主观题' ){
|
||||
// 复合题里面的主观题只有一个答案,或没填
|
||||
const answer = answerArr.join('、');
|
||||
if(answerArr[0]){
|
||||
workAnswerHtml += `<div style='display:flex;'>${index+1}. ${answer}</div>`;
|
||||
}else{
|
||||
workAnswerHtml += `<div style='display:flex;'>${index+1}. ${answer}答案不唯一,请参考分析解答点评!</div>`;
|
||||
}
|
||||
}
|
||||
})
|
||||
row[i].workanswerFormat = workAnswerHtml;
|
||||
}
|
||||
|
||||
}
|
||||
else if(row[i].worktype == '主观题' || (row[i].worktype!=='单选题' && row[i].worktype!=='多选题' && row[i].worktype!=='填空题' && row[i].worktype!=='判断题')) {
|
||||
// 处理[选项显示] - 主观题中无选项, 故置空
|
||||
row[i].workdescFormat = '';
|
||||
row[i].workanswerFormat = '';
|
||||
// 答案处理- eg: "\"不唯一的答案,参考\""
|
||||
if (row[i].workanswer && row[i].workanswer != '') {
|
||||
row[i].workanswerFormat = JSON.parse(row[i].workanswer);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 单选题|多选题|填空题|判断题|主观题?(待确认是否归在这里)
|
||||
// 通用选项结构 ['ABC123','ABC123'] | ['ABC123','ABC123'] | [](填空题无选项) | [](判断题无选项)
|
||||
let workDescArr = [];
|
||||
if (row[i].workdesc.charAt(0) === '[' && row[i].workdesc.charAt(row[i].workdesc.length - 1) === ']') {
|
||||
//123会直接被转换, 且不是数组对象, 故手动判断是否有[和]两个字符
|
||||
workDescArr = JSON.parse(row[i].workdesc);
|
||||
}
|
||||
else if(row[i].workdesc.indexOf('#&') !== -1) {
|
||||
workDescArr = row[i].workdesc.split('#&');
|
||||
}
|
||||
else if(row[i].workdesc.indexOf(',') !== -1){
|
||||
workDescArr = row[i].workdesc.split(',');
|
||||
}
|
||||
else {
|
||||
// 单字符串直接添加至空数组(待考虑确认)
|
||||
workDescArr.push(row[i].workdesc);
|
||||
}
|
||||
|
||||
// 单选题|多选题|填空题|判断题|主观题?(待确认是否归在这里)
|
||||
// 通用答案结构 ['0'] | ['0','1'] | ['填空1','填空2'] | ['0'/'1']
|
||||
let workAnswerArr = [];
|
||||
if (row[i].workanswer.charAt(0) === '[' && row[i].workanswer.charAt(row[i].workanswer.length - 1) === ']') {
|
||||
// 123会直接被转换, 且不是数组对象, 故手动判断是否有[和]两个字符
|
||||
workAnswerArr = JSON.parse(row[i].workanswer);
|
||||
}
|
||||
else if(row[i].workanswer.indexOf('#&') !== -1) {
|
||||
workAnswerArr = row[i].workanswer.split('#&');
|
||||
}
|
||||
else if(row[i].workanswer.indexOf(',') !== -1){
|
||||
workAnswerArr = row[i].workanswer.split(',');
|
||||
}
|
||||
else {
|
||||
// 单字符串直接添加至空数组(待考虑确认)
|
||||
workAnswerArr.push(row[i].workanswer);
|
||||
}
|
||||
|
||||
// 具体题型处理
|
||||
if(row[i].worktype == '单选题' || row[i].worktype == '多选题' ){
|
||||
// 处理[选项显示] - 拼接ABCD首序号
|
||||
let tmp = '';
|
||||
let j=0;
|
||||
for(; j<workDescArr.length; j++){
|
||||
if(j%2 == 0){
|
||||
tmp += `<div style='width:80%;display:flex;'>`;
|
||||
}
|
||||
const char = String.fromCharCode(65+j);
|
||||
tmp += `<div style='display:flex;margin-left: 2%; width: 36%'>${char}.${workDescArr[j]}</div>`;
|
||||
if(j%2 == 1){
|
||||
tmp += '</div>';
|
||||
}
|
||||
}
|
||||
if(j%2== 0){
|
||||
tmp += '</div>';
|
||||
}
|
||||
row[i].workdescFormat = tmp;
|
||||
|
||||
// 处理[答案显示] - 转换ABCD
|
||||
let arr2Char = workAnswerArr.map( (item) => {
|
||||
return String.fromCharCode(65+Number(item))
|
||||
}).join('');
|
||||
row[i].workanswerFormat = arr2Char;
|
||||
}
|
||||
else if(row[i].worktype == '填空题'){
|
||||
// 处理[选项显示] - 填空题中无选项, 故置空
|
||||
row[i].workdescFormat = '';
|
||||
|
||||
// 处理[答案显示] - 逗号连接
|
||||
row[i].workanswerFormat = workAnswerArr.join('、');
|
||||
}
|
||||
else if(row[i].worktype == '判断题'){
|
||||
// 处理[选项显示] - 判断题中无选项, 故置空
|
||||
row[i].workdescFormat = '';
|
||||
|
||||
// 处理[答案显示] - 1-正常 0-错误
|
||||
const answer = workAnswerArr.map( (item) => {
|
||||
return item === '1' ? '正确' : '错误'
|
||||
}).join('、');
|
||||
row[i].workanswerFormat = answer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,14 +11,14 @@ const path = isNode?require('path'):{}
|
|||
const Remote = isNode?require('@electron/remote'):{}
|
||||
const { ipcRenderer } = isNode?require('electron'):window.electron || {}
|
||||
const API = isNode?window.api:{} // preload-api
|
||||
// import { useToolState } from '@/store/modules/tool' // 获取store状态
|
||||
import { useToolState } from '@/store/modules/tool' // 获取store状态
|
||||
// const Store = isNode?require('electron-store'):null // 持久化存储
|
||||
import store from './store'
|
||||
|
||||
// 常用变量
|
||||
const BaseUrl = isNode?process.env['ELECTRON_RENDERER_URL']+'/#':''
|
||||
const isDev = isNode?process.env.NODE_ENV !== 'production':''
|
||||
// const toolState = useToolState() // 获取store状态
|
||||
|
||||
const appPath = isNode?Remote.app.getAppPath():'' // 应用目录
|
||||
|
||||
// 暴露Remote中的属性
|
||||
export const ipcMain = Remote?.ipcMain || {}
|
||||
|
@ -31,7 +31,8 @@ export const localStore = store.localStore
|
|||
|
||||
// 暴露Store存储对象
|
||||
export const Store = store
|
||||
|
||||
// 延时
|
||||
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
|
||||
/**
|
||||
* 获取静态资源,开发和生产环境
|
||||
* @param {*} url
|
||||
|
@ -110,6 +111,7 @@ export const createWindow = async (type, data) => {
|
|||
resizable: false, // 禁止窗口大小缩放
|
||||
transparent: true, // 设置透明
|
||||
alwaysOnTop: true, // 窗口是否总是显示在其他窗口之前
|
||||
type: 'toolbar', // 创建的窗口类型为工具栏窗口
|
||||
// parent: mainWin, // 父窗口
|
||||
// autoClose: true, // 关闭窗口后自动关闭
|
||||
}
|
||||
|
@ -141,8 +143,8 @@ export const createWindow = async (type, data) => {
|
|||
const option = data.option||{}
|
||||
const defOption = {
|
||||
frame: false, // 要创建无边框窗口
|
||||
resizable: true, // 禁止窗口大小缩放
|
||||
alwaysOnTop: false, // 窗口是否总是显示在其他窗口之前
|
||||
resizable: true, // 禁止窗口大小缩放
|
||||
alwaysOnTop: false, // 窗口是否总是显示在其他窗口之前
|
||||
}
|
||||
data.isConsole = true // 是否开启控制台
|
||||
data.option = {...defOption, ...option}
|
||||
|
@ -179,13 +181,13 @@ export function toolWindow({url, isConsole, isWeb=true, option={}}) {
|
|||
return new Promise((resolve) => {
|
||||
const config = {
|
||||
width, height,
|
||||
type: 'toolbar', // 创建的窗口类型为工具栏窗口
|
||||
// icon: path.join(__dirname, '../../resources/logo2.ico'),
|
||||
icon: path.join(appPath, '/resources/logo2.ico'),
|
||||
webPreferences: {
|
||||
preload: path.join(API.preloadPath, '/index.js'),
|
||||
sandbox: false,
|
||||
nodeIntegration: true, // nodeApi调用
|
||||
contextIsolation: false, // 沙箱取消
|
||||
devTools: true
|
||||
},
|
||||
...option
|
||||
}
|
||||
|
@ -221,6 +223,7 @@ export function toolWindow({url, isConsole, isWeb=true, option={}}) {
|
|||
* @param {*} win 窗口对象
|
||||
*/
|
||||
const eventHandles = (type, win) => {
|
||||
const toolState = useToolState() // 获取store状态
|
||||
const winAll = Remote.BrowserWindow.getAllWindows()
|
||||
const mainWin = winAll.find(o => o.type == 'main') // 主窗口对象
|
||||
// 公共方法
|
||||
|
@ -248,8 +251,11 @@ const eventHandles = (type, win) => {
|
|||
const on = {
|
||||
onClosed: () => {
|
||||
Remote.ipcMain.removeHandler('tool-sphere:set:ignore', setIgnore)
|
||||
Remote.ipcMain.removeHandler('tool-sphere:reset')
|
||||
// Remote.ipcMain.removeHandler('tool-sphere:reset')
|
||||
// Remote.ipcMain.removeAllListeners() // 移除所有监听事件
|
||||
// 设置状态(再次设置-防止未设置到)
|
||||
if(toolState.isToolWin) toolState.isToolWin = false
|
||||
// sessionStore.set('isToolWin', false)
|
||||
}
|
||||
}
|
||||
publicMethods(on) // 加载公共方法
|
||||
|
@ -266,9 +272,22 @@ const eventHandles = (type, win) => {
|
|||
winPdf=null
|
||||
win&&win.destroy()
|
||||
})
|
||||
|
||||
// 监听窗口的激活事件
|
||||
win.on('focus', async () => {
|
||||
console.log('激活窗口')
|
||||
toolState.isPdfWin=true
|
||||
await sleep(20) // 延时
|
||||
toolState.showBoardAll=false //恢复默认值
|
||||
// await sleep(50) // 延时
|
||||
// 穿透开启
|
||||
if (toolState.isToolWin) ipcRenderer.invoke('tool-sphere:set:ignore', true)
|
||||
});
|
||||
const on = {
|
||||
onClosed: () => {
|
||||
Remote.ipcMain.removeHandler('open-PDF:minimize')
|
||||
// 设置状态(再次设置-防止未设置到)
|
||||
if(toolState.isPdfWin) toolState.isPdfWin = false
|
||||
}
|
||||
}
|
||||
publicMethods(on) // 加载公共方法
|
||||
|
|
|
@ -105,6 +105,7 @@ const switchPageMode = () => {
|
|||
}
|
||||
onMounted(async () => {
|
||||
const isDev = process.env.NODE_ENV == 'development'
|
||||
// toolState.showBoardAll = false // 隐藏画板
|
||||
toolState.isPdfWin=true //设置打开pdf窗口
|
||||
if (isDev)
|
||||
pdfObj.pdfUrl = getStaticUrl('aaa.pdf', 'user', 'selfFile', true) //本地
|
||||
|
|
|
@ -31,6 +31,7 @@ import { getSelfReserv } from '@/api/classManage'
|
|||
import ReservItem from '@/views/classManage/reserv-item.vue'
|
||||
import Reserv from '@/views/prepare/container/reserv.vue'
|
||||
import { useToolState } from '@/store/modules/tool'
|
||||
import { sessionStore } from '@/utils/tool'
|
||||
const reservDialog = ref(null)
|
||||
const tabOptions = ref(['进行中', '已结束'])
|
||||
const tabActive = ref('进行中')
|
||||
|
@ -51,21 +52,27 @@ const doneDataList = computed(() => {
|
|||
return item.status === '已结束'
|
||||
})
|
||||
})
|
||||
// 获取数据
|
||||
const getData = () => {
|
||||
getSelfReserv().then((res) => {
|
||||
const list = res.data || []
|
||||
list.sort((a,b) => { if(a.status=='上课中') return -1; else return 0 })
|
||||
dataList.value = list
|
||||
})
|
||||
}
|
||||
const toolStore = useToolState()
|
||||
|
||||
watch(
|
||||
() => [dataList,toolStore.isToolWin],
|
||||
() => {
|
||||
console.log('====',toolStore)
|
||||
setTimeout(()=>{
|
||||
getSelfReserv().then((res) => {
|
||||
dataList.value = [...res.data]
|
||||
})
|
||||
getData() // 加载数据
|
||||
},300)
|
||||
}
|
||||
)
|
||||
onMounted(() => {
|
||||
getSelfReserv().then((res) => {
|
||||
dataList.value = res.data
|
||||
})
|
||||
getData() // 加载数据
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
|
@ -20,14 +20,14 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="class-reserv-item-tool">
|
||||
<el-button v-if="item.status !== '已结束'" type="primary" @click="startClassR(item)"
|
||||
>上课</el-button
|
||||
<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 type="danger" @click="deleteReserv">删除</el-button>
|
||||
<el-button v-if="item.status!='上课中'" type="danger" @click="deleteReserv">删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -46,6 +46,7 @@ const props = defineProps({
|
|||
}
|
||||
})
|
||||
const basePath = import.meta.env.VITE_APP_BUILD_BASE_PATH
|
||||
const toolStore = useToolState() // 获取状态管理-tool
|
||||
const openEdit = () => {
|
||||
emit('openEdit', props.item)
|
||||
}
|
||||
|
@ -61,18 +62,20 @@ const deleteReserv = () => {
|
|||
})
|
||||
}
|
||||
const startClassR = (item) => {
|
||||
startClass(item.id).then((res) => {
|
||||
if (res.data === true) {
|
||||
item.status = '上课中'
|
||||
openLesson()
|
||||
}
|
||||
})
|
||||
// startClass(item.id).then((res) => {
|
||||
// if (res.data === true) {
|
||||
// item.status = '上课中'
|
||||
// openLesson()
|
||||
// }
|
||||
// })
|
||||
item.status = '上课中'
|
||||
openLesson()
|
||||
}
|
||||
// const toolStore = useToolState()
|
||||
let wins = null;
|
||||
// 上课-工具类悬浮
|
||||
const openLesson = () => {
|
||||
startClass(props.item.id)
|
||||
// startClass(props.item.id)
|
||||
listEntpcourse({
|
||||
evalid: props.item.ex2,
|
||||
edituserid: useUserStore().user.userId,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<div>
|
||||
<div class="studentContent">
|
||||
<template v-if="studentList.length > 0">
|
||||
<div v-for="(item,index) in studentList" :key="index" style="width: 10%" @click="addStudent(item.studentid)">
|
||||
<div v-for="(item,index) in studentList" :key="index" style="width: 10%">
|
||||
<div>
|
||||
<el-avatar
|
||||
src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
<template>
|
||||
<div class="desktop-item">
|
||||
<div class="item-title flex">
|
||||
<span>工作动态</span>
|
||||
<el-radio-group v-model="type">
|
||||
<el-radio-button label="全部" :value="-1" />
|
||||
<el-radio-button label="备课" :value="1" />
|
||||
<el-radio-button label="上课" :value="2" />
|
||||
<el-radio-button label="作业" :value="3" />
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="item-content">
|
||||
<ul>
|
||||
<li class="flex class-item" v-for="item in classList" :key="item.id">
|
||||
<div class="class-left flex">
|
||||
<div class="class-name flex">
|
||||
<span>{{ item.className }}</span>
|
||||
</div>
|
||||
<div class="class-time"> {{ item.classDay }} {{ item.startTime }} ~ {{ item.classDay }} {{ item.endTime }}</div>
|
||||
<div class="class-grade">
|
||||
<span v-for="(tag, index) in item.classItemList" :key="index" style="margin-left: 5px">
|
||||
{{ index === 0 ? tag.name : '、' + tag.name }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="class-right">
|
||||
<el-button type="primary" size="small">上课</el-button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getSelfReserv } from '@/api/classManage'
|
||||
|
||||
const type = ref(-1)
|
||||
const classList = ref([])
|
||||
|
||||
// 获取上课
|
||||
const getClass = () =>{
|
||||
getSelfReserv().then((res) => {
|
||||
let list = res.data || []
|
||||
list.sort((a,b) => { if(a.status=='上课中') return -1; else return 0 })
|
||||
classList.value = list.filter(item => item.status !== '已结束')
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(()=>{
|
||||
getClass()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.desktop-item{
|
||||
margin-bottom: 20px;
|
||||
align-items: center;
|
||||
.item-title{
|
||||
height: 32px;
|
||||
text-align: left;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.item-content{
|
||||
background-color: #fff;
|
||||
border-radius: 5px;
|
||||
padding: 10px 15px;
|
||||
font-size: 13px;
|
||||
.class-item{
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #e2e4f4;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
.class-left{
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
.class-time{
|
||||
font-size: 13px;
|
||||
color: #bfbfbf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,286 @@
|
|||
<template>
|
||||
<div class="page-desktop">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="17">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12" v-for="item in menuList">
|
||||
<div class="desktop-item">
|
||||
<div class="item-title">{{ item.name }}</div>
|
||||
<div class="item-content">
|
||||
<ul class="flex con-ul">
|
||||
<li v-for="menu in item.list" @click="clickMenu(menu)" class="flex item-menu" :class="menu.disabled ? 'menu-disabled' : ''">
|
||||
<i class="iconfont" :class="menu.icon"></i>
|
||||
<span>{{ menu.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="desktop-item">
|
||||
<div class="item-title flex">
|
||||
<span>教学进度</span>
|
||||
</div>
|
||||
<div class="item-content">
|
||||
<div ref="chartDom" class="chart-box"></div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<!--工作动态-->
|
||||
<workTrend/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, nextTick } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import workTrend from './container/work-trend.vue'
|
||||
import outLink from '@/utils/linkConfig'
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
const router = useRouter()
|
||||
const { ipcRenderer } = window.electron || {}
|
||||
const type = ref(-1)
|
||||
const chartDom = ref(null);
|
||||
let chartInstance = null
|
||||
|
||||
const menuList = [{
|
||||
name: '教学分析',
|
||||
list: [
|
||||
{
|
||||
name: '课标分析',
|
||||
icon: 'icon-kecheng',
|
||||
isOuter: true,
|
||||
path: '/teaching/chatwithstandard'
|
||||
},
|
||||
{
|
||||
name: '教材分析',
|
||||
icon: 'icon-jiaocaixuanze',
|
||||
isOuter: true,
|
||||
path: '/teaching/chatwithtextbook'
|
||||
},
|
||||
{
|
||||
name: '考试分析',
|
||||
icon: 'icon-kaoshi',
|
||||
path: '/examReport'
|
||||
},
|
||||
{
|
||||
name: '学情分析',
|
||||
icon: 'icon-xueqingfenxi',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
name: '资源分析',
|
||||
icon: 'icon-ziyuanfenxi',
|
||||
disabled: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '课程教学',
|
||||
list: [
|
||||
{
|
||||
name: '教学设计',
|
||||
icon: 'icon-jiaoxuesheji',
|
||||
path: '/prepare'
|
||||
},
|
||||
{
|
||||
name: '教学实施',
|
||||
icon: 'icon-jiaoxuefenxi',
|
||||
path: '/classReserv'
|
||||
},
|
||||
{
|
||||
name: '教学反思',
|
||||
icon: 'icon-jiaoxuefansi',
|
||||
disabled: true
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '作业管理',
|
||||
list: [
|
||||
{
|
||||
name: '作业设计',
|
||||
icon: 'icon-jiaoxuefansi',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
name: '作业布置',
|
||||
icon: 'icon-xiezuo1',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
name: '作业批改',
|
||||
icon: 'icon-pigai'
|
||||
},
|
||||
{
|
||||
name: '作业统计',
|
||||
icon: 'icon-tongji',
|
||||
disabled: true
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '教学管控',
|
||||
list: [
|
||||
{
|
||||
name: '教学计划',
|
||||
icon: 'icon-jiaoxuejihua',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
name: '教学组织',
|
||||
icon: 'icon-organization-framework-line',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
name: '教学质量',
|
||||
icon: 'icon-jiaoxuezhiliangfenxi',
|
||||
disabled: true
|
||||
},
|
||||
{
|
||||
name: '教学反馈',
|
||||
icon: 'icon-fankui',
|
||||
disabled: true
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
const clickMenu = ({isOuter, path, disabled}) =>{
|
||||
if(disabled) return
|
||||
// 弹窗
|
||||
if(isOuter){
|
||||
let configObj = outLink().getBaseData()
|
||||
let fullPath = configObj.fullPath + path
|
||||
fullPath = fullPath.replaceAll('//', '/')
|
||||
// 通知主进程
|
||||
ipcRenderer.send('openWindow', {
|
||||
key: path,
|
||||
fullPath: fullPath,
|
||||
cookieData: { ...configObj.data }
|
||||
})
|
||||
} else{
|
||||
router.push(path)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async ()=>{
|
||||
// 确保DOM 渲染完成
|
||||
await nextTick()
|
||||
chartInstance = echarts.init(chartDom.value)
|
||||
const option = {
|
||||
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '2%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
// boundaryGap: [0, 0.01]
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data: ['周一', '周二', '周三', '周四', '周五','周六','周日']
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '一班',
|
||||
type: 'bar',
|
||||
data: [18, 24, 10, 13, 23, 15, 12]
|
||||
},
|
||||
{
|
||||
name: '二班',
|
||||
type: 'bar',
|
||||
data: [25, 21, 14, 13, 20, 17,13]
|
||||
},
|
||||
{
|
||||
name: '三班',
|
||||
type: 'bar',
|
||||
data: [15, 16, 16, 18, 20, 16, 10]
|
||||
}
|
||||
]
|
||||
}
|
||||
chartInstance.setOption(option);
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-desktop{
|
||||
height: 100%;
|
||||
padding-top: 20px;
|
||||
|
||||
.desktop-item{
|
||||
margin-bottom: 20px;
|
||||
.item-title{
|
||||
height: 32px;
|
||||
text-align: left;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.item-content{
|
||||
background-color: #fff;
|
||||
border-radius: 5px;
|
||||
padding: 10px 0;
|
||||
.con-ul{
|
||||
justify-content: space-around;
|
||||
.item-menu{
|
||||
cursor: pointer;
|
||||
flex-direction: column;
|
||||
font-size: 14px;
|
||||
.iconfont{
|
||||
font-size: 28px;
|
||||
color: #707070;
|
||||
}
|
||||
&:hover{
|
||||
color: #409EFF;
|
||||
.iconfont{
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
.menu-disabled{
|
||||
cursor: not-allowed;
|
||||
color: #bfbfbf;
|
||||
.iconfont{
|
||||
color: #bfbfbf;
|
||||
}
|
||||
&:hover{
|
||||
color: #bfbfbf;
|
||||
.iconfont{
|
||||
color: #bfbfbf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.chart-box{
|
||||
height: 220px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<div>模拟命题</div>
|
||||
</template>
|
|
@ -0,0 +1,101 @@
|
|||
<template>
|
||||
<el-table ref="table" v-loading="loading" :data="listExamQuestion" class="table-main">
|
||||
<el-table-column type="index" fixed="left" width="60" />
|
||||
<el-table-column align="left" fixed="left" min-width="60%">
|
||||
<template #default="scope">
|
||||
<div @click="showExamAnalyseDrawer(scope.row)">
|
||||
<div v-html="scope.row.titleFormat" class="main-title" ></div>
|
||||
<div v-html="scope.row.workdescFormat" class="main-work-desc" ></div>
|
||||
<el-col :span="24" style="display: flex">
|
||||
<div class="main-user-info" style="">{{ scope.row.entpname }} {{ scope.row.editusername }}</div>
|
||||
<div class="main-upl-time" style="">{{ scope.row.timestamp }}</div>
|
||||
</el-col>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="worktype" width="100"></el-table-column>
|
||||
<el-table-column align="center" prop="worktag" width="120"></el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 试题详情 -->
|
||||
<el-drawer v-model="activeExamInfoDrawer" title="题目详情" :with-header="false" direction="rtl" size="60%">
|
||||
<el-row class="drawer-main">
|
||||
<el-col :span="24">
|
||||
<span>{{activeExam.worktag}}</span>
|
||||
<span style="margin-left: 4px" v-html="activeExam.titleFormat" ></span>
|
||||
</el-col>
|
||||
<el-col :span="24" style="padding: 4px" v-html="activeExam.workdescFormat">
|
||||
</el-col>
|
||||
<el-col :span="3" class="drawer-main-col"><em>【答案】</em></el-col>
|
||||
<el-col :span="20" class="drawer-main-col" v-html="activeExam.workanswerFormat"></el-col>
|
||||
<el-col :span="3" class="drawer-main-col"><em>【分析】</em></el-col>
|
||||
<el-col :span="20" class="drawer-main-col" v-html="activeExam.method"></el-col>
|
||||
<el-col :span="3" class="drawer-main-col"><em>【解答】</em></el-col>
|
||||
<el-col :span="20" class="drawer-main-col" v-html="activeExam.analyse"></el-col>
|
||||
<el-col :span="3" class="drawer-main-col" ><em>【点评】</em></el-col>
|
||||
<el-col :span="20" class="drawer-main-col" v-html="activeExam.discuss"></el-col>
|
||||
</el-row>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref, reactive} from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
listExamQuestion: {type: Array},
|
||||
loading: {type: Boolean}
|
||||
})
|
||||
|
||||
const activeExamInfoDrawer = ref(false);
|
||||
const activeExam = ref({});
|
||||
|
||||
const showExamAnalyseDrawer = (row) => {
|
||||
activeExam.value = row;
|
||||
activeExamInfoDrawer.value = true;
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table-main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: left;
|
||||
|
||||
.main-title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-weight:700
|
||||
}
|
||||
.main-work-desc{
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 0.9em;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.main-user-info{
|
||||
font-size: 0.8em;
|
||||
color: silver;
|
||||
padding-top: 5px
|
||||
}
|
||||
.main-upl-time{
|
||||
margin-left: 30px;
|
||||
font-size: 0.8em;
|
||||
color: silver;
|
||||
padding-top: 7px
|
||||
}
|
||||
}
|
||||
|
||||
.drawer-main{
|
||||
margin: 1%;
|
||||
padding: 1% 2%;
|
||||
border: 2px dotted;
|
||||
display: flex;
|
||||
text-align: left;
|
||||
|
||||
.drawer-main-col{
|
||||
padding: 10px 0px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<div>考点分析</div>
|
||||
</template>
|
|
@ -0,0 +1,292 @@
|
|||
<template>
|
||||
<div class="page-resource flex">
|
||||
<!--左侧 教材 目录-->
|
||||
<ChooseTextbook @change-book="getData" @node-click="getData" />
|
||||
<!--右侧 习题 列表 -->
|
||||
<div class="page-right">
|
||||
<div class="page-right-top">
|
||||
<el-popover placement="top-start" title="真题回顾" trigger="hover" content="勾画、圈点,添加标记等,整理出本课的重点与难点,用于老师讲解和学生自主预习">
|
||||
<template #reference>
|
||||
<el-button-group>
|
||||
<el-button @click="changeTaskView('真题回顾', index)" :type="curTask.viewkey=='真题回顾'?'primary':'default'" round>真题回顾</el-button>
|
||||
<el-button disabled :type="'default'" plain round ></el-button>
|
||||
</el-button-group>
|
||||
</template>
|
||||
</el-popover>
|
||||
<div style="margin-top: 7px"> <el-icon><ArrowRight /></el-icon> </div>
|
||||
|
||||
<el-popover disabled placement="top-start" title="考点分析" trigger="hover" content="勾画、圈点,添加标记等,整理出本课的重点与难点,用于老师讲解和学生自主预习">
|
||||
<template #reference>
|
||||
<el-button-group>
|
||||
<el-button disabled @click="changeTaskView('考点分析', index)" :type="curTask.viewkey=='考点分析'?'primary':'default'" round>考点分析</el-button>
|
||||
<el-button disabled :type="'default'" plain round ></el-button>
|
||||
</el-button-group>
|
||||
</template>
|
||||
</el-popover>
|
||||
<div style="margin-top: 7px"> <el-icon><ArrowRight /></el-icon> </div>
|
||||
|
||||
<el-popover disabled placement="top-start" title="模拟命题" trigger="hover" content="勾画、圈点,添加标记等,整理出本课的重点与难点,用于老师讲解和学生自主预习">
|
||||
<template #reference>
|
||||
<el-button-group>
|
||||
<el-button disabled @click="changeTaskView('模拟命题', index)" :type="curTask.viewkey=='模拟命题'?'primary':'default'" round>模拟命题</el-button>
|
||||
<el-button disabled :type="'default'" plain round ></el-button>
|
||||
</el-button-group>
|
||||
</template>
|
||||
</el-popover>
|
||||
|
||||
<el-select
|
||||
v-model="queryParams.workType"
|
||||
placeholder="题型"
|
||||
size="small"
|
||||
class="work-type"
|
||||
@change="queryExamQuestionByParams"
|
||||
>
|
||||
<template v-for="(item, index) in listWorkType" :key="index">
|
||||
<el-option :label="item.label" :value="item" />
|
||||
</template>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div :style="{'width': (viewportWidth - 400) + 'px','height': (viewportHeight-38) + 'px','overflow-y': 'auto'}">
|
||||
<examReview
|
||||
:loading="loading"
|
||||
:listExamQuestion="listExamQuestion"
|
||||
v-if="curTask.viewkey=='真题回顾'"
|
||||
/>
|
||||
|
||||
<pointAnalysis
|
||||
v-else-if="curTask.viewkey=='考点分析'"
|
||||
/>
|
||||
|
||||
<examMocks v-else
|
||||
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<script setup>
|
||||
import {ref, onMounted, reactive, watch, nextTick, getCurrentInstance} from 'vue'
|
||||
import { ArrowRight } from '@element-plus/icons-vue'
|
||||
|
||||
import useResoureStore from '@/views/resource/store'
|
||||
import ChooseTextbook from '@/components/choose-textbook/index.vue'
|
||||
import {listEntpcoursework, listEntpcourseworkNew} from '@/api/education/entpCourseWork'
|
||||
import {processExamQuestion} from '@/utils/examQuestion/tool'
|
||||
import { JYApiListCT} from "@/utils/examQuestion/jyeoo"
|
||||
|
||||
import examReview from './container/examReview.vue'
|
||||
import pointAnalysis from './container/pointAnalysis.vue'
|
||||
import examMocks from './container/examMocks.vue'
|
||||
|
||||
const {proxy} = getCurrentInstance();
|
||||
const sourceStore = useResoureStore();
|
||||
const viewportHeight = ref(0);
|
||||
const viewportWidth = ref(0);
|
||||
// 当前选中的章节或单元
|
||||
const curNode = ref({});
|
||||
// 试题集合
|
||||
const listExamQuestion = ref([]);
|
||||
const loading = ref(false);
|
||||
const curTask = reactive({
|
||||
viewkey: '真题回顾',
|
||||
});
|
||||
const queryParams = reactive({
|
||||
workType: {
|
||||
label: '不限',
|
||||
value: 0,
|
||||
},
|
||||
total: 0,
|
||||
});
|
||||
const listWorkType = ref([{
|
||||
label: '不限',
|
||||
value: 0,
|
||||
}]);
|
||||
|
||||
/**
|
||||
* @desc: 选中单元章节后的回调, 获取单元章节信息
|
||||
* @return: {*}
|
||||
* @param {*} data
|
||||
*/
|
||||
const getData = async (data) => {
|
||||
if (curNode.value.id == data.node.id) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
|
||||
// 1.获取题型
|
||||
getWorkType(data.node);
|
||||
|
||||
// 2.获取试题集合
|
||||
curNode.value = data.node;
|
||||
// 查询本地
|
||||
// const params = {
|
||||
// pageNum: 1,
|
||||
// pageSize: 100,
|
||||
// workgroup: '1',
|
||||
// edusubject: curNode.value.edusubject,
|
||||
// evalid: curNode.value.id,
|
||||
// orderby: 'concat(worktype,worktag) DESC',
|
||||
// }
|
||||
// const res = await listEntpcoursework(params);
|
||||
// listExamQuestion.value = res.rows;
|
||||
|
||||
// 查询本地+菁优网(后端处理)
|
||||
const params = {
|
||||
eid: curNode.value.id,
|
||||
workgroup: '1',
|
||||
worktype: '不限',
|
||||
workTypeId: '0',
|
||||
edusubject: curNode.value.edusubject,
|
||||
edustage: curNode.value.edustage,
|
||||
sectionName: curNode.value.itemtitle,
|
||||
}
|
||||
const res = await listEntpcourseworkNew(params);
|
||||
if(res.data == null) {
|
||||
listExamQuestion.value = [];
|
||||
// queryParams.total = 0
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
listExamQuestion.value = res.data;
|
||||
// queryParams.total = res.total;
|
||||
// 格式化试题
|
||||
processExamQuestion(listExamQuestion.value);
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc: 切换节点
|
||||
* @return: {*}
|
||||
* @param {*} item
|
||||
* @param {*} key
|
||||
*/
|
||||
const changeTaskView = (item, key) => {
|
||||
curTask.viewkey = item;
|
||||
}
|
||||
|
||||
const getWorkType = async (data) => {
|
||||
const selName = `${data.edustage}${data.edusubject}`
|
||||
const curName = `${curNode.value.edustage}${curNode.value.edusubject}`
|
||||
if (selName === curName) {
|
||||
return;
|
||||
}
|
||||
const jyCT = await JYApiListCT(proxy, selName);
|
||||
if (jyCT.length == 0) {
|
||||
ElMessage.error('获取题型失败!');
|
||||
return;
|
||||
}
|
||||
listWorkType.value = jyCT;
|
||||
}
|
||||
|
||||
const queryExamQuestionByParams = async () => {
|
||||
loading.value = true;
|
||||
|
||||
// 查询本地
|
||||
// const params = {
|
||||
// pageNum: 1,
|
||||
// pageSize: 100,
|
||||
// workgroup: '1',
|
||||
// edusubject: curNode.value.edusubject,
|
||||
// evalid: curNode.value.id,
|
||||
// worktype: queryParams.workType.Value,
|
||||
// orderby: 'concat(worktype,worktag) DESC',
|
||||
// }
|
||||
// if (queryParams.workType == '不限') {
|
||||
// delete params.worktype;
|
||||
// }
|
||||
|
||||
// const res = await listEntpcoursework(params);
|
||||
// listExamQuestion.value = res.rows;
|
||||
|
||||
// 查询本地+菁优网(后端处理)
|
||||
const params = {
|
||||
eid: curNode.value.id,
|
||||
workgroup: '1',
|
||||
worktype: queryParams.workType.label,
|
||||
workTypeId: queryParams.workType.value,
|
||||
edusubject: curNode.value.edusubject,
|
||||
edustage: curNode.value.edustage,
|
||||
sectionName: curNode.value.itemtitle,
|
||||
}
|
||||
const res = await listEntpcourseworkNew(params);
|
||||
if(res.data == null) {
|
||||
listExamQuestion.value = [];
|
||||
// queryParams.total = 0
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
listExamQuestion.value = res.data;
|
||||
// queryParams.total = res.total;
|
||||
// 格式化试题
|
||||
processExamQuestion(listExamQuestion.value);
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
//获取视口高度
|
||||
const getViewportHeight = () => {
|
||||
return Math.max(
|
||||
document.documentElement.clientHeight,
|
||||
window.innerHeight || 0
|
||||
);
|
||||
}
|
||||
|
||||
const getViewportWidth = () => {
|
||||
return Math.max(
|
||||
document.documentElement.clientWidth,
|
||||
window.innerWidth || 0
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
viewportHeight.value = getViewportHeight();
|
||||
viewportWidth.value = getViewportWidth();
|
||||
})
|
||||
window.addEventListener('resize', () => {
|
||||
viewportHeight.value = getViewportHeight();
|
||||
viewportWidth.value = getViewportWidth();
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-resource {
|
||||
padding-top: 20px;
|
||||
height: 100%;
|
||||
|
||||
//右侧栏
|
||||
.page-right {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
margin-left: 20px;
|
||||
height: 100%;
|
||||
background: #ffffff;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0px 0px 20px 0px rgba(99, 99, 99, 0.06);
|
||||
|
||||
.page-right-top {
|
||||
display: flex;
|
||||
margin-top: 6px;
|
||||
margin-left: 6px;
|
||||
|
||||
.work-type {
|
||||
width: 100px;
|
||||
margin: 0 6px 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style src="@/assets/styles/JYStyle.css"></style>
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-card style="overflow: auto; height: 100%">
|
||||
<el-card style="overflow: auto; height: 100%;">
|
||||
<div class="common-layout" style="overflow-y: auto">
|
||||
<el-container>
|
||||
<el-main style="--el-main-padding: 0">
|
||||
|
@ -112,8 +112,8 @@ const title = reactive([
|
|||
]
|
||||
},
|
||||
{
|
||||
name: '高考研究',
|
||||
url: '/education/colentrance',
|
||||
name: '考试分析',
|
||||
url: '/examReport',
|
||||
img: 'iconfont icon-icon_kaoshifenxi',
|
||||
child1: []
|
||||
},
|
||||
|
|
|
@ -230,6 +230,10 @@ export default {
|
|||
}
|
||||
},
|
||||
openFileWin(items) {
|
||||
if (items.fileFlag === 'apt') {
|
||||
console.log(items);
|
||||
return
|
||||
}
|
||||
if (!items||!items.fileSuffix) return;
|
||||
getPrepareById(items.id).then((item) => {
|
||||
Object.assign(items, item)
|
||||
|
|
|
@ -20,11 +20,14 @@
|
|||
</div>
|
||||
<el-button
|
||||
:type="!curClassReserv.id ? 'info' : 'primary'"
|
||||
:disabled="!curClassReserv.id"
|
||||
:disabled="!curClassReserv.id || toolStore.isToolWin"
|
||||
class="to-class-btn"
|
||||
@click="openLesson"
|
||||
>
|
||||
<label><i class="iconfont icon-lingdang"></i>上课</label>
|
||||
<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>
|
||||
|
@ -60,9 +63,21 @@
|
|||
<el-button @click="handleOutLink('feedback')">作业反馈</el-button>
|
||||
<el-button @click="handleOutLink('homeWork')">布置作业</el-button>
|
||||
<el-button @click="isDialogOpen = true">上传资料</el-button>
|
||||
<el-button type="primary" style="margin-left: 10px" @click="createFile"
|
||||
>新建课件</el-button
|
||||
>
|
||||
<el-dropdown trigger="click" style="margin-left: 12px">
|
||||
<el-button type="primary">
|
||||
新建课件<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item style="padding: 0">
|
||||
<el-button type="default" style="" @click="createFile">PPT课件</el-button>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item style="padding: 0">
|
||||
<el-button type="default" style="" @click="createAptFile">APT课件</el-button>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<el-checkbox-group
|
||||
|
@ -92,7 +107,6 @@
|
|||
@on-delete="deleteTalk"
|
||||
@on-set="openSet"
|
||||
@on-delhomework="delhomework"
|
||||
|
||||
>
|
||||
<el-checkbox v-if="!item.uniquekey" label="" :value="item" />
|
||||
</file-list-item>
|
||||
|
@ -110,11 +124,7 @@
|
|||
</div>
|
||||
<MoveFile v-model="isMoveDialogOpen" @on-submit="chooseMoveCata" />
|
||||
<uploadDialog v-model="isDialogOpen" @submit-file="submitFile" />
|
||||
<SetHomework
|
||||
v-model="setDialog"
|
||||
:entpcourseid="entpcourseid"
|
||||
:row="row"
|
||||
/>
|
||||
<SetHomework v-model="setDialog" :entpcourseid="entpcourseid" :row="row" />
|
||||
</div>
|
||||
<reserv
|
||||
ref="reservDialog"
|
||||
|
@ -127,6 +137,7 @@
|
|||
<script setup>
|
||||
import { Check } from '@element-plus/icons-vue'
|
||||
import Reserv from '@/views/prepare/container/reserv.vue'
|
||||
import { ArrowDown } from '@element-plus/icons-vue'
|
||||
</script>
|
||||
<script>
|
||||
const Remote = require('@electron/remote')
|
||||
|
@ -138,18 +149,20 @@ import useUserStore from '@/store/modules/user'
|
|||
import { useToolState } from '@/store/modules/tool'
|
||||
import MoveFile from '@/components/move-file/index.vue'
|
||||
import FileListItem from '@/views/prepare/container/file-list-item.vue'
|
||||
import { getSmarttalkPage, moveSmarttalk } from '@/api/file'
|
||||
import { getSmarttalkPage, moveSmarttalk, creatAPT } from '@/api/file'
|
||||
import { toTimeText } from '@/utils/date'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { parseCataByNode, creatPPT, asyncLocalFile } from '@/utils/talkFile'
|
||||
import FileOperBatch from '@/views/prepare/container/file-oper-batch.vue'
|
||||
import SetHomework from '@/components/set-homework/index.vue'
|
||||
import outLink from '@/utils/linkConfig'
|
||||
import { createWindow, ipcMsgSend } from '@/utils/tool'
|
||||
import { createWindow, sessionStore } from '@/utils/tool'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { delClasswork } from '@/api/teaching/classwork'
|
||||
import { getSelfReserv, startClass } from '@/api/classManage'
|
||||
import { delClasswork, listEntpcourse } from '@/api/teaching/classwork'
|
||||
import { getSelfReserv } from '@/api/classManage'
|
||||
import { useGetHomework } from '@/hooks/useGetHomework'
|
||||
import { addEntpcoursefileReturnId } from '@/api/education/entpcoursefile'
|
||||
|
||||
const toolStore = useToolState()
|
||||
|
||||
const fs = require('fs')
|
||||
|
@ -228,14 +241,12 @@ export default {
|
|||
)
|
||||
// electron 当前窗口
|
||||
const curWin = Remote.getCurrentWindow()
|
||||
curWin.on('focus', ()=>{
|
||||
if(!this.isOpenHomework) return
|
||||
curWin.on('focus', () => {
|
||||
if (!this.isOpenHomework) return
|
||||
this.initHomeWork()
|
||||
this.asyncAllFile()
|
||||
this.isOpenHomework = false
|
||||
})
|
||||
|
||||
|
||||
},
|
||||
// activated() {
|
||||
// if (this.uploadData.textbookId !== null) {
|
||||
|
@ -299,6 +310,90 @@ export default {
|
|||
this.currentFileList.unshift(res.resData)
|
||||
})
|
||||
},
|
||||
createAptFile() {
|
||||
listEntpcourse({
|
||||
evalid: this.uploadData.levelSecondId,
|
||||
edituserid: this.userStore.userId,
|
||||
pageSize: 500
|
||||
}).then((response) => {
|
||||
if (response.rows.length <= 0) return
|
||||
let resCourse = response.rows[0]
|
||||
// 添加
|
||||
let form = {
|
||||
parentid: 0,
|
||||
entpid: this.userStore.deptId,
|
||||
entpcourseid: resCourse.id,
|
||||
ppttype: 'file',
|
||||
title: resCourse.coursetitle,
|
||||
fileurl: '',
|
||||
filetype: 'ppt',
|
||||
datacontent: '',
|
||||
filekey: '',
|
||||
filetag: '',
|
||||
fileidx: 0,
|
||||
dflag: 0,
|
||||
status: '',
|
||||
edituserid: this.userStore.userId
|
||||
}
|
||||
addEntpcoursefileReturnId(form).then((slideid) => {
|
||||
let pagearray = []
|
||||
// 公屏
|
||||
pagearray.push({
|
||||
key: '公屏',
|
||||
title: '公屏页',
|
||||
slidedata: {
|
||||
attrs: { width: 1333, height: 749.8125 },
|
||||
className: 'Stage',
|
||||
children: [
|
||||
{
|
||||
attrs: {},
|
||||
className: 'Layer',
|
||||
children: [
|
||||
{
|
||||
attrs: {
|
||||
width: 1333,
|
||||
height: 749.8125,
|
||||
fill: 'white',
|
||||
name: 'fixedbackground',
|
||||
listening: true
|
||||
},
|
||||
className: 'Rect'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
// 添加
|
||||
var form = {
|
||||
parentid: slideid,
|
||||
entpid: resCourse.entpid,
|
||||
entpcourseid: resCourse.id,
|
||||
ppttype: 'file',
|
||||
title: '第一页',
|
||||
fileurl: '',
|
||||
filetype: 'slide',
|
||||
datacontent: JSON.stringify(pagearray),
|
||||
filekey: '',
|
||||
filetag: '',
|
||||
fileidx: 0,
|
||||
dflag: 0,
|
||||
status: '',
|
||||
edituserid: this.userStore.userId
|
||||
}
|
||||
addEntpcoursefileReturnId(form).then((res) => {
|
||||
creatAPT({
|
||||
...this.uploadData,
|
||||
fileId: res,
|
||||
fileShowName: this.currentNode.label + '.apt'
|
||||
}).then((res) => {
|
||||
this.currentFileList.unshift(res.resData)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
onMoveSingleFile(item) {
|
||||
this.moveFile = [item]
|
||||
this.isMoveDialogOpen = true
|
||||
|
@ -402,6 +497,7 @@ export default {
|
|||
this.asyncAllFileVisiable = true
|
||||
for (let i = 0; i < this.currentFileList.length; i++) {
|
||||
let item = this.currentFileList[i]
|
||||
if (item.fileFlag === 'apt') continue;
|
||||
await asyncLocalFile(item)
|
||||
}
|
||||
this.asyncAllFileVisiable = false
|
||||
|
@ -426,7 +522,9 @@ export default {
|
|||
this.uploadData.textbookId = data.textBook.curBookId
|
||||
toolStore.curSubjectNode.data = data
|
||||
// 不要同时修改共享数据,这样只会触发一次
|
||||
this.$nextTick(() =>{ toolStore.curSubjectNode.querySearch = this.uploadData })
|
||||
this.$nextTick(() => {
|
||||
toolStore.curSubjectNode.querySearch = this.uploadData
|
||||
})
|
||||
this.initHomeWork()
|
||||
await this.asyncAllFile()
|
||||
},
|
||||
|
@ -441,19 +539,20 @@ export default {
|
|||
},
|
||||
// 打开外部链接
|
||||
handleOutLink(key) {
|
||||
if(key == 'homeWork'){
|
||||
if (key == 'homeWork') {
|
||||
this.isOpenHomework = true
|
||||
}
|
||||
// key 对应的 linkConfig.js 外部链接配置
|
||||
let configObj = outLink()[key]
|
||||
let fullPath = configObj.fullPath
|
||||
//打开作业 高考 url增加unitId 章节ID
|
||||
if(key != 'standard' && key != 'aiModel'){
|
||||
let unitId = this.uploadData.levelSecondId ? this.uploadData.levelSecondId : this.uploadData.levelFirstId
|
||||
if(key == 'gk'){
|
||||
if (key != 'standard' && key != 'aiModel') {
|
||||
let unitId = this.uploadData.levelSecondId
|
||||
? this.uploadData.levelSecondId
|
||||
: this.uploadData.levelFirstId
|
||||
if (key == 'gk') {
|
||||
fullPath += `?unitId=${unitId}`
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
fullPath += `&unitId=${unitId}`
|
||||
}
|
||||
}
|
||||
|
@ -542,7 +641,7 @@ export default {
|
|||
<style scoped lang="scss">
|
||||
.page-resource {
|
||||
user-select: none;
|
||||
padding-top: 20px;
|
||||
padding-top: 10px;
|
||||
height: 100%;
|
||||
|
||||
.page-right {
|
||||
|
@ -630,6 +729,7 @@ export default {
|
|||
cursor: pointer !important;
|
||||
}
|
||||
& > :deep(span) {
|
||||
pointer-events: none;
|
||||
flex-direction: column !important;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-loading="sourceStore.loading" class="resource-list">
|
||||
<div v-loading="loading" class="resource-list">
|
||||
<el-scrollbar>
|
||||
<el-empty v-if="!sourceStore.result.list.length" description="暂无数据" />
|
||||
<ul>
|
||||
|
@ -7,7 +7,7 @@
|
|||
v-for="item in sourceStore.result.list"
|
||||
:key="item.id"
|
||||
class="list-item"
|
||||
@click="handleRow"
|
||||
@click="handleRow(item)"
|
||||
>
|
||||
<div class="item-left flex">
|
||||
<FileImage :file-name="item.fileShowName" :size="50" />
|
||||
|
@ -91,10 +91,11 @@
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<FilePreview v-model="isShow" :row="curRow"></FilePreview>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { toRaw } from 'vue'
|
||||
import { toRaw, ref, computed } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import FileImage from '@/components/file-image/index.vue'
|
||||
import { deleteSmarttalk, updateSmarttalk } from '@/api/file'
|
||||
|
@ -102,13 +103,14 @@ import { addFileToPrepare } from '@/api/subject'
|
|||
import { getFileSuffix } from '@/utils/ruoyi'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import useResoureStore from '../store'
|
||||
|
||||
import FilePreview from '@/components/file-preview/index.vue'
|
||||
const { ipcRenderer } = window.electron || {}
|
||||
const userstore = useUserStore()
|
||||
const sourceStore = useResoureStore()
|
||||
|
||||
const loading = computed(() => sourceStore.loading)
|
||||
const userInfo = userstore.user
|
||||
|
||||
const isShow = ref(false)
|
||||
const curRow = ref({})
|
||||
// 分页change
|
||||
const handleSizeChange = (limit) => {
|
||||
sourceStore.query.pageSize = limit
|
||||
|
@ -182,8 +184,12 @@ const addLesson = ({ id }) => {
|
|||
}
|
||||
}
|
||||
//
|
||||
const handleRow = () => {
|
||||
ElMessage.warning('请先加入备课,在备课里面进行预览!')
|
||||
const handleRow = (item) => {
|
||||
item.prevImgList.sort((a,b)=>{
|
||||
return a.targetPrevIndex - b.targetPrevIndex
|
||||
})
|
||||
curRow.value = item
|
||||
isShow.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ watch(() => sourceStore.query.fileSource,() => {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.page-resource {
|
||||
padding-top: 20px;
|
||||
padding-top: 10px;
|
||||
height: 100%;
|
||||
|
||||
.page-right {
|
||||
|
|
|
@ -94,6 +94,7 @@ export default defineStore('resource', {
|
|||
getSmarttalkPage(data).then((res) => {
|
||||
this.result.total = res.total
|
||||
this.result.list = res.rows
|
||||
this.loading = false
|
||||
})
|
||||
}else{
|
||||
let data = JSON.parse(JSON.stringify(this.thirdQuery))
|
||||
|
@ -107,12 +108,13 @@ export default defineStore('resource', {
|
|||
if(res.data.code === 0){
|
||||
this.thirdResult.total = res.data.page.totalCount
|
||||
this.thirdResult.list = [...res.data.data]
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
} finally {
|
||||
this.loading = false
|
||||
// this.loading = false
|
||||
}
|
||||
},
|
||||
changeTab(val) {
|
||||
|
|
|
@ -81,8 +81,8 @@ import { ipcMsgSend, ipcMsgSend2, ipcMsgInvoke } from '@/utils/tool'
|
|||
import { useToolState } from '@/store/modules/tool'
|
||||
import Lesson from './lesson.vue';
|
||||
import { parseCataByNode } from '@/utils/talkFile'
|
||||
import outLink from '@/utils/linkConfig'
|
||||
import MsgEnum from '@/plugins/imChat/msgEnum' // 消息枚举
|
||||
import { createHomework } from '../createHomework'
|
||||
|
||||
const route = useRoute();
|
||||
const usertore = useUserStore().user
|
||||
|
@ -129,16 +129,35 @@ const changeChapter = async (data)=>{
|
|||
getResource()
|
||||
}
|
||||
|
||||
// 文件资源打开web AIX 布置作业
|
||||
const openFileLink = (item) =>{
|
||||
// key 对应的 linkConfig.js 外部链接配置
|
||||
let key = 'filehomework'
|
||||
let configObj = outLink()[key]
|
||||
ipcMsgSend2('openWindow', {
|
||||
key,
|
||||
fullPath: configObj.fullPath + `&fileShowName=${item.fileShowName}&fileFullPath=${item.fileFullPath}`,
|
||||
cookieData: { ...configObj.data }
|
||||
})
|
||||
// 资源推送
|
||||
const openFileLink = async (item) =>{
|
||||
/**
|
||||
* 资源推送
|
||||
* 1:先生成作业
|
||||
* 2:再进行推送
|
||||
*/
|
||||
|
||||
// 根据当前月份日期 生成一个作业编号
|
||||
const today = new Date();
|
||||
// 获取月份
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0');
|
||||
// 获取当前日
|
||||
const day = String(today.getDate()).padStart(2, '0');
|
||||
// 生成一个作业编号
|
||||
const uniquekey = `${usertore.edusubject}-${month}${day}-${dataList.value.length + 1}`
|
||||
|
||||
// 章节ID
|
||||
const querySearch = toolStore.curSubjectNode.querySearch
|
||||
const evalid = querySearch.levelSecondId ? querySearch.levelSecondId : querySearch.levelFirstId
|
||||
|
||||
// 资源数据
|
||||
const data = [{name: item.fileShowName, ulr: item.fileFullPath}]
|
||||
// 生成作业
|
||||
await createHomework({ uniquekey, evalid, data, entpcourseid: entpcourseid.value })
|
||||
// 查询作业
|
||||
getHomework()
|
||||
let row = dataList.value.at(-1)
|
||||
sendHomework(row)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
import useUserStore from '@/store/modules/user'
|
||||
import { addClassworkReturnId } from '@/api/teaching/classwork'
|
||||
|
||||
export const createHomework = ({ uniquekey, evalid, data, entpcourseid }) =>{
|
||||
const usertore = useUserStore().user
|
||||
|
||||
var formObj = {};
|
||||
formObj.id = 0;
|
||||
|
||||
formObj.deaddate = '';
|
||||
formObj.entpid = usertore.deptId;
|
||||
formObj.level = 1;
|
||||
formObj.parentid = 0;
|
||||
formObj.worktype = '常规作业';
|
||||
formObj.workkey = '';
|
||||
formObj.worktag = '';
|
||||
|
||||
formObj.uniquekey = uniquekey;
|
||||
|
||||
formObj.classid = 0;
|
||||
formObj.classcourseid = 0;
|
||||
|
||||
formObj.entpcourseid = entpcourseid;
|
||||
|
||||
formObj.slideid = 0;
|
||||
|
||||
formObj.workcodes = JSON.stringify(data);
|
||||
|
||||
formObj.edusubject = usertore.edusubject;
|
||||
formObj.evalid = evalid
|
||||
|
||||
formObj.edustage = usertore.edustage;
|
||||
formObj.status = '';
|
||||
formObj.edituserid = usertore.userId;
|
||||
formObj.entpcourseworklist = JSON.stringify([{'id':-2, 'score': '10'}]);
|
||||
return addClassworkReturnId(formObj)
|
||||
}
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
<script setup>
|
||||
// 功能说明:electron 悬浮球
|
||||
import { onMounted, ref, reactive, watchEffect } from 'vue'
|
||||
import { onMounted, ref, reactive, watchEffect, nextTick } from 'vue'
|
||||
import { useRoute } from 'vue-router';
|
||||
import { ElMessageBox, ElMessage, ElLoading } from 'element-plus'
|
||||
import * as classManageApi from '@/api/classManage'
|
||||
|
@ -83,9 +83,8 @@ const btnList = [ // 工具栏按钮列表
|
|||
// === 页面加载完毕 ===
|
||||
onMounted(async() => {
|
||||
if (!electron) return // 浏览器端
|
||||
// console.log(sessionStore)
|
||||
// window.test = sessionStore
|
||||
// window.test1 = toolStore
|
||||
window.test = sessionStore
|
||||
window.test1 = toolStore
|
||||
getClassInfo() // 获取课堂详情 ex3
|
||||
resetStatus() // 开启重置状态-监听
|
||||
})
|
||||
|
@ -100,12 +99,14 @@ const getClassInfo = async () => {
|
|||
console.log('获取群ID:', timGroupId)
|
||||
const chat = await imChatRef.value?.initImChat(timGroupId) // 初始化im-chat
|
||||
if (!timGroupId) timGroupId = chat?.timGroupId
|
||||
if (!timGroupId) return ElMessage.error('房间创建-失败')
|
||||
classManageApi.startClass(classObj.id, timGroupId) // 开始上课
|
||||
}
|
||||
// 切换tab-change
|
||||
const tabChange = (val) => {
|
||||
const bool = !toolStore.isPdfWin && !toolStore.showBoardAll
|
||||
if(bool) toolStore.showBoardAll = true
|
||||
console.log('tabChange:', val, bool)
|
||||
toolStore.model = val // 存储当前tab
|
||||
}
|
||||
// logo 点击-事件 折叠|展开
|
||||
|
@ -134,8 +135,15 @@ const logoHandle = (e,t) => {
|
|||
// 底部工具栏:移入移出-是否穿透
|
||||
const mouseChange = (bool) => {
|
||||
let resBool = false
|
||||
if (bool == 0) return setIgnore(resBool) // 移入不穿透
|
||||
if (tabActive.value == 'select') resBool = !!bool
|
||||
if (!isShow.value) resBool = !!bool
|
||||
else {
|
||||
if (!isShow.value) resBool = !!bool
|
||||
// pdf强行穿透
|
||||
const isPdf = !resBool && toolStore.isPdfWin
|
||||
if (isPdf) resBool = true
|
||||
}
|
||||
// console.log('mouseChange:', bool, resBool)
|
||||
setIgnore(resBool)
|
||||
}
|
||||
// im-chat: 聊天事件 {type, data}
|
||||
|
@ -169,15 +177,15 @@ const setIgnore = (bool) => {ipcMsgSend('tool-sphere:set:ignore', bool)}
|
|||
// 重置状态: 鼠标|画板
|
||||
const resetStatus = () => {
|
||||
if (toolStore.isToolWin) return // 已经打开过-忽略
|
||||
ipcMain?.removeHandler('tool-sphere:reset') // 避免已绑定,先移除在绑定
|
||||
ipcMain?.handle?.('tool-sphere:reset', () => {
|
||||
setTimeout(() => {
|
||||
boardVueRef.value.handleMode(tabActive.value)
|
||||
mouseChange(1)
|
||||
}, 500)
|
||||
})
|
||||
// 以下代码废弃-暂时无用
|
||||
// ipcMain?.removeHandler('tool-sphere:reset') // 避免已绑定,先移除在绑定
|
||||
// ipcMain?.handle?.('tool-sphere:reset', () => {
|
||||
// setTimeout(() => {
|
||||
// boardVueRef.value.handleMode(tabActive.value)
|
||||
// mouseChange(1)
|
||||
// }, 500)
|
||||
// })
|
||||
toolStore.isToolWin = true // 标记状态
|
||||
|
||||
}
|
||||
// 侧边工具栏: 移入移出
|
||||
const sideMouse = e => {
|
||||
|
@ -211,7 +219,8 @@ const sideChange = async o => {
|
|||
// 延迟2秒后关闭窗口,如果马上解散群,会导致群组不存在
|
||||
setTimeout(async() => {
|
||||
// elMsg.close()
|
||||
toolStore.isToolWin = false
|
||||
// toolStore.isToolWin = false
|
||||
toolStore.resetDef() // 重置状态
|
||||
await imChatRef.value?.deleteGroup() // 解散群
|
||||
await imChatRef.value?.logout() // 退出im
|
||||
await classManageApi.endClass(route.query.reservId)
|
||||
|
@ -233,6 +242,12 @@ watchEffect(() => {
|
|||
// 不同的时候, 更新值: 是否显示-画板
|
||||
const show = !toolStore.isPdfWin && toolStore.showBoardAll
|
||||
if (show != isShow.value) isShow.value = show
|
||||
if (isShow.value) {
|
||||
nextTick(() => {
|
||||
mouseChange(1) // 移除工具栏
|
||||
boardVueRef.value.handleMode(tabActive.value)
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Reference in New Issue