2.5init #1
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "aix-win",
|
||||
"version": "2.5.0",
|
||||
"version": "2.1.21",
|
||||
"description": "",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "上海交大重庆人工智能研究院",
|
||||
|
|
|
@ -137,7 +137,7 @@ function createMainWindow() {
|
|||
|
||||
// mainWindow.setAlwaysOnTop(true, "screen-saver") // 将窗口设置为顶层窗口
|
||||
// mainWindow.setVisibleOnAllWorkspaces(true) // 如果窗口在所有工作区都可见
|
||||
mainWindow.maximize();
|
||||
// mainWindow.maximize();
|
||||
// 第三步: 开启remote服务
|
||||
remote.enable(mainWindow.webContents)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,6 @@ const size = ref('default')
|
|||
text-align: center;
|
||||
color: #2c3e50;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
/* height: 100vh; */
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2794390 */
|
||||
src: url('iconfont.woff2?t=1728543886557') format('woff2'),
|
||||
url('iconfont.woff?t=1728543886557') format('woff'),
|
||||
url('iconfont.ttf?t=1728543886557') format('truetype'),
|
||||
url('iconfont.svg?t=1728543886557#iconfont') format('svg');
|
||||
src: url('iconfont.woff2?t=1729838168701') format('woff2'),
|
||||
url('iconfont.woff?t=1729838168701') format('woff'),
|
||||
url('iconfont.ttf?t=1729838168701') format('truetype'),
|
||||
url('iconfont.svg?t=1729838168701#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
@ -14,6 +14,22 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-banji2:before {
|
||||
content: "\e6c0";
|
||||
}
|
||||
|
||||
.icon-set:before {
|
||||
content: "\e691";
|
||||
}
|
||||
|
||||
.icon-shouye:before {
|
||||
content: "\e637";
|
||||
}
|
||||
|
||||
.icon-gongzuotai:before {
|
||||
content: "\e690";
|
||||
}
|
||||
|
||||
.icon-A1:before {
|
||||
content: "\e635";
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5,6 +5,34 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "1017928",
|
||||
"name": "班级",
|
||||
"font_class": "banji2",
|
||||
"unicode": "e6c0",
|
||||
"unicode_decimal": 59072
|
||||
},
|
||||
{
|
||||
"icon_id": "376364",
|
||||
"name": "设置",
|
||||
"font_class": "set",
|
||||
"unicode": "e691",
|
||||
"unicode_decimal": 59025
|
||||
},
|
||||
{
|
||||
"icon_id": "5835474",
|
||||
"name": "首页",
|
||||
"font_class": "shouye",
|
||||
"unicode": "e637",
|
||||
"unicode_decimal": 58935
|
||||
},
|
||||
{
|
||||
"icon_id": "19108133",
|
||||
"name": "工作台",
|
||||
"font_class": "gongzuotai",
|
||||
"unicode": "e690",
|
||||
"unicode_decimal": 59024
|
||||
},
|
||||
{
|
||||
"icon_id": "11657531",
|
||||
"name": "A",
|
||||
|
|
|
@ -14,6 +14,14 @@
|
|||
/>
|
||||
<missing-glyph />
|
||||
|
||||
<glyph glyph-name="banji2" unicode="" d="M865.793707 531.61984c0 12.357973-10.03008 22.386347-22.386347 22.386347-12.357973 0-22.386347-10.03008-22.386347-22.386347 0-61.743787-50.19136-111.93344-111.935147-111.93344s-111.935147 50.19136-111.935147 111.93344c0 12.357973-10.03008 22.386347-22.386347 22.386347-12.357973 0-22.386347-10.03008-22.386347-22.386347 0-86.413653 70.294187-156.70784 156.70784-156.70784S865.793707 445.206187 865.793707 531.61984zM1059.054933 208.631467c58.876587 23.237973 99.48672 81.08544 99.48672 145.916587 0 71.637333-47.684267 132.082347-115.24608 150.528 0.67072 8.820053 1.611093 17.55136 1.611093 26.550613 0 185.183573-150.662827 335.802027-335.802027 335.802027-185.183573 0-335.802027-150.618453-335.802027-335.802027 0-9.043627 1.477973-17.73056 2.194773-26.594987-67.428693-18.536107-115.024213-78.93504-115.024213-150.483627 0-64.832853 40.564053-122.68032 99.442347-145.916587L287.470933 1.59744c-4.118187-11.685547 2.059947-24.446293 13.70112-28.520107 2.46272-0.84992 4.969813-1.252693 7.386453-1.252693 9.222827 0 17.90976 5.77536 21.133653 14.999893l80.413013 229.643947c0.402773 1.02912 0.67072 2.148693 0.940373 3.268267 2.46272 11.55072-4.432213 23.058773-15.849813 26.238293-2.776747 0.807253-5.59616 0.896-8.193707 0.761173-47.72864 13.298347-81.75616 57.623893-81.75616 107.815253 0 49.206613 31.43168 91.24864 76.741973 106.069333 25.879893-117.306027 113.322667-215.048533 230.137173-250.374827l-72.174933-206.226773c-4.118187-11.685547 2.059947-24.446293 13.745493-28.520107 2.46272-0.896 4.92544-1.252693 7.386453-1.252693 9.268907 0 17.865387 5.77536 21.133653 14.999893l80.18944 229.15072c2.10432 6.045013 1.56672 12.670293-1.611093 18.26816-3.089067 5.59616-8.46336 9.581227-14.73024 10.970453-132.125013 29.146453-227.985067 148.60288-227.985067 283.997867 0 160.469333 130.56 291.027627 291.027627 291.027627s291.027627-130.56 291.027627-291.027627c0-12.043947-0.761173-23.86432-2.148693-35.551573-14.327467-116.993707-97.158827-213.03296-211.10784-244.642133-5.95456-1.657173-10.970453-5.686613-13.88032-11.19232-2.82112-5.46304-3.31264-11.910827-1.252693-17.73056l81.62304-233.270613c3.268267-9.222827 11.864747-14.999893 21.133653-14.999893 2.46272 0 4.92544 0.3584 7.386453 1.252693 11.685547 4.07552 17.819307 16.83456 13.745493 28.520107l-74.011307 211.46624c110.052693 38.99904 190.55616 131.76832 214.95808 245.225813 45.535573-14.685867 77.190827-56.818347 77.190827-106.15808 0-50.773333-34.833067-95.501653-83.457707-108.30848-2.194773 0-4.522667-0.31232-6.760107-1.02912-11.461973-3.403093-18.044587-15.849813-15.179093-27.446613 0.402773-1.431893 0.896-2.776747 1.477973-4.118187l79.428267-226.822827c3.223893-9.222827 11.820373-14.999893 21.087573-14.999893 2.46272 0 4.969813 0.402773 7.432533 1.252693 11.641173 4.07552 17.819307 16.83456 13.70112 28.520107L1059.054933 208.631467z" horiz-adv-x="1366" />
|
||||
|
||||
<glyph glyph-name="set" unicode="" d="M512 558.182c-115.665 0-209.455-93.789-209.455-209.455 0-115.665 93.789-209.455 209.455-209.455s209.455 93.789 209.455 209.455c0 115.665-93.789 209.455-209.455 209.455zM512 185.818c-89.972 0-162.909 72.937-162.909 162.909 0 89.972 72.937 162.909 162.909 162.909s162.909-72.937 162.909-162.909c0-89.972-72.937-162.909-162.909-162.909zM907.636 465.091l-66.746 0c-4.143 11.59-8.797 22.9-14.057 33.932l47.197 47.197c18.199 18.199 18.199 47.663 0 65.815l-98.723 98.723c-18.199 18.199-47.663 18.199-65.815 0l-47.43-47.43c-10.938 5.213-22.109 10.1-33.652 14.196l0 66.839c0 25.693-20.852 46.545-46.545 46.545l-139.636 0c-25.693 0-46.545-20.852-46.545-46.545l0-66.839c-11.59-4.096-22.807-8.89-33.792-14.15l-47.383 47.383c-18.153 18.199-47.663 18.199-65.815 0l-98.723-98.723c-18.199-18.199-18.199-47.663 0-65.815l47.29-47.29c-5.26-10.985-10.1-22.249-14.196-33.839l-66.7 0c-25.693 0-46.545-20.852-46.545-46.545l0-139.636c0-25.693 20.852-46.545 46.545-46.545l66.746 0c4.143-11.59 8.797-22.9 14.057-33.885l-47.197-47.197c-18.199-18.153-18.199-47.663 0-65.815l98.723-98.723c18.199-18.199 47.663-18.199 65.815 0l47.43 47.43c10.938-5.213 22.109-10.1 33.652-14.196l0-66.886c0-25.693 20.852-46.545 46.545-46.545l139.636 0c25.693 0 46.545 20.852 46.545 46.545l0 66.746c11.59 4.143 22.9 8.797 33.885 14.057l47.197-47.197c18.199-18.199 47.663-18.199 65.815 0l98.723 98.723c18.199 18.199 18.199 47.663 0 65.815l-47.43 47.43c5.213 10.938 10.1 22.109 14.196 33.652l66.932 0c25.693 0 46.545 20.852 46.545 46.545l0 139.636c0 25.74-20.852 46.592-46.545 46.592zM907.636 302.182c0-12.847-10.426-23.273-23.273-23.273l-78.243 0c-7.54-31.837-20.108-61.673-36.817-88.762l55.343-55.389c9.076-9.076 9.076-23.831 0-32.908l-65.815-65.815c-9.076-9.076-23.831-9.076-32.908 0l-55.343 55.343c-27.089-16.71-56.925-29.277-88.762-36.817l0-78.196c0-12.847-10.426-23.273-23.273-23.273l-93.091 0c-12.847 0-23.273 10.426-23.273 23.273l0 78.243c-31.837 7.54-61.673 20.108-88.762 36.817l-55.343-55.343c-9.076-9.076-23.831-9.076-32.908 0l-65.815 65.815c-9.076 9.076-9.076 23.831 0 32.908l55.343 55.389c-16.71 27.043-29.277 56.879-36.817 88.716l-78.243 0c-12.847 0-23.273 10.426-23.273 23.273l0 93.091c0 12.847 10.426 23.273 23.273 23.273l78.243 0c7.54 31.837 20.108 61.673 36.817 88.762l-55.389 55.343c-9.076 9.076-9.076 23.831 0 32.908l65.815 65.815c9.076 9.076 23.831 9.076 32.908 0l55.343-55.343c27.136 16.71 56.972 29.277 88.809 36.817l0 78.243c0 12.847 10.426 23.273 23.273 23.273l93.091 0c12.847 0 23.273-10.426 23.273-23.273l0-78.243c31.837-7.54 61.673-20.108 88.762-36.817l55.343 55.343c9.076 9.076 23.831 9.076 32.908 0l65.815-65.815c9.076-9.076 9.076-23.831 0-32.908l-55.343-55.343c16.71-27.089 29.277-56.879 36.817-88.762l78.243 0c12.847 0 23.273-10.426 23.273-23.273l0-93.091z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="shouye" unicode="" d="M960 448c-6.4 0-12.9 1.9-18.6 6L512 760.7 82.6 454c-14.4-10.2-34.4-6.9-44.6 7.5-10.3 14.4-6.9 34.4 7.5 44.6l448 320c11.1 7.9 26.1 7.9 37.2 0l448-320c14.4-10.3 17.7-30.3 7.5-44.6-6.4-8.8-16.2-13.5-26.2-13.5zM608-64H416c-17.7 0-32 14.3-32 32V256c0 17.7 14.3 32 32 32h192c17.7 0 32-14.3 32-32v-288c0-17.7-14.3-32-32-32z m-160 64h128V224H448v-224zM832-64H192c-52.9 0-96 43.1-96 96V512c0 17.7 14.3 32 32 32s32-14.3 32-32v-480c0-17.6 14.4-32 32-32h640c17.6 0 32 14.4 32 32V512c0 17.7 14.3 32 32 32s32-14.3 32-32v-480c0-52.9-43.1-96-96-96z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="gongzuotai" unicode="" d="M320.284444 810.666667a85.333333 85.333333 0 0 0 85.333334-85.333334v-234.951111H170.666667a85.333333 85.333333 0 0 0-85.333334 85.333334V725.333333a85.333333 85.333333 0 0 0 85.333334 85.333334h149.617777m0 85.333333H170.666667a170.666667 170.666667 0 0 1-170.666667-170.666667v-149.617777a170.666667 170.666667 0 0 1 170.666667-170.666667h320.284444V725.333333a170.666667 170.666667 0 0 1-170.666667 170.666667zM405.617778 277.617778V42.666667a85.333333 85.333333 0 0 0-85.333334-85.333334H170.666667a85.333333 85.333333 0 0 0-85.333334 85.333334v149.617777a85.333333 85.333333 0 0 0 85.333334 85.333334h234.951111m85.333333 85.333333H170.666667a170.666667 170.666667 0 0 1-170.666667-170.666667V42.666667a170.666667 170.666667 0 0 1 170.666667-170.666667h149.617777a170.666667 170.666667 0 0 1 170.666667 170.666667V362.951111zM853.333333 277.617778a85.333333 85.333333 0 0 0 85.333334-85.333334V42.666667a85.333333 85.333333 0 0 0-85.333334-85.333334h-149.617777a85.333333 85.333333 0 0 0-85.333334 85.333334v234.951111H853.333333m0 85.333333H533.048889V42.666667a170.666667 170.666667 0 0 1 170.666667-170.666667H853.333333a170.666667 170.666667 0 0 1 170.666667 170.666667v149.617777a170.666667 170.666667 0 0 1-170.666667 170.666667zM853.333333 810.666667a85.333333 85.333333 0 0 0 85.333334-85.333334v-149.617777a85.333333 85.333333 0 0 0-85.333334-85.333334h-234.951111V725.333333a85.333333 85.333333 0 0 0 85.333334 85.333334H853.333333m0 85.333333h-149.617777a170.666667 170.666667 0 0 1-170.666667-170.666667v-320.284444H853.333333a170.666667 170.666667 0 0 1 170.666667 170.666667V725.333333a170.666667 170.666667 0 0 1-170.666667 170.666667z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="A1" unicode="" d="M449 339h121.5L507.5 505.5zM782 834H242C143 834 62 753 62 654v-540c0-99 81-180 180-180h540c99 0 180 81 180 180V654c0 99-81 180-180 180z m-139.5-675l-40.5 103.5H422L381.5 159H287L462.5 609H557l180-450h-94.5z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="A" unicode="" d="M841.589844 779.507813a65.917969 65.917969 0 0 0 65.917969-65.917969v-659.179688a65.917969 65.917969 0 0 0-65.917969-65.917969H182.410156a65.917969 65.917969 0 0 0-65.917969 65.917969V713.589844a65.917969 65.917969 0 0 0 65.917969 65.917969h659.179688z m0-49.438477H182.410156a16.479492 16.479492 0 0 1-16.21582-13.513183L165.930664 713.589844v-659.179688a16.479492 16.479492 0 0 1 13.513183-16.21582L182.410156 37.930664h659.179688a16.479492 16.479492 0 0 1 16.21582 13.513183L858.069336 54.410156V713.589844a16.479492 16.479492 0 0 1-13.513183 16.21582L841.589844 730.069336zM539.059326 614.712891l188.85498-461.425782h-69.543456l-53.822022 139.746094H411.606933L360.916016 153.287109H296.118652l177.1875 461.425782h65.786133z m-34.277344-48.449707c-5.899658-29.597168-14.172364-58.996582-24.884033-88.165284L429.207031 342.80127h156.456299l-48.153076 127.781982-4.779053 12.689209a1170.900879 1170.900879 0 0 0-27.982178 82.990723z" horiz-adv-x="1024" />
|
||||
|
|
Before Width: | Height: | Size: 362 KiB After Width: | Height: | Size: 369 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -244,7 +244,8 @@ const onSubmit = (formEl) => {
|
|||
entpcourseworklist: '[' + props.rows[i].entpcourseworklist + ']',
|
||||
needMsgNotifine: 'false',
|
||||
msgkey: 'newclasswork',
|
||||
title: '作业任务',
|
||||
//title: '作业任务',
|
||||
title: props.rows[i].title,
|
||||
msgcontent: '',
|
||||
teachername: userInfo.nickName,
|
||||
unixstamp: new Date().getTime(),
|
||||
|
@ -254,6 +255,7 @@ const onSubmit = (formEl) => {
|
|||
ary.push(obj)
|
||||
}
|
||||
}
|
||||
console.log('ary->', ary)
|
||||
setLoading.value = true
|
||||
saveByClassWorkArray({
|
||||
classworkarray: JSON.stringify(ary)
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
<template>
|
||||
<div class="page-aside">
|
||||
<div>
|
||||
<div>
|
||||
<el-popover placement="right" trigger="hover" :width="120" popper-class="popoverStyle">
|
||||
<template #reference>
|
||||
<el-image class="user-img" :src="dev_api + userStore.user.avatar" />
|
||||
</template>
|
||||
<div class="head-aside">
|
||||
<span>11</span>
|
||||
<el-button type="primary" @click="logout">退出登录</el-button>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="aside-tab">
|
||||
<ul class="flex">
|
||||
<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>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="side-bottom">
|
||||
<div class="aside-tab">
|
||||
<ul class="flex">
|
||||
<li class="flex" :class="[activeId == menu.path ? 'active-li' : '', menu.disabled ? 'disabled' : '']"
|
||||
v-for="menu in sideBottomMenu" :key="menu.id" @click="clickMenu(menu)">
|
||||
<i class="iconfont" :class="menu.icon"></i>
|
||||
<span class="text">{{ menu.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import { sessionStore } from '@/utils/store'
|
||||
|
||||
const { ipcRenderer } = window.electron || {}
|
||||
const dev_api = ref(import.meta.env.VITE_APP_BASE_API)
|
||||
const userStore = useUserStore()
|
||||
const router = useRouter()
|
||||
const currentRoute = ref('')
|
||||
const activeId = ref('/home')
|
||||
|
||||
const headerMenus = [
|
||||
{
|
||||
name: '教学大模型',
|
||||
id: 1,
|
||||
icon: 'icon-shouye',
|
||||
path: '/index'
|
||||
},
|
||||
{
|
||||
name: '班级中心',
|
||||
id: 2,
|
||||
icon: 'icon-banji2',
|
||||
path: '/class'
|
||||
},
|
||||
{
|
||||
name: '教学工作台',
|
||||
id: 3,
|
||||
icon: 'icon-gongzuotai',
|
||||
path: '/home'
|
||||
},
|
||||
{
|
||||
name: '资源中心',
|
||||
id: 4,
|
||||
icon: 'icon-kechengziyuan1',
|
||||
path: '/resource'
|
||||
},
|
||||
]
|
||||
|
||||
const sideBottomMenu = [
|
||||
{
|
||||
name: '设置',
|
||||
id: 5,
|
||||
icon: 'icon-set',
|
||||
path: '/setting'
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
const clickMenu = ({ id, disabled, path }) => {
|
||||
if (disabled) return
|
||||
activeId.value = id
|
||||
router.push(path)
|
||||
}
|
||||
|
||||
// 监听当前路由
|
||||
watch(
|
||||
() => router.currentRoute.value,
|
||||
(newValue) => {
|
||||
currentRoute.value = newValue
|
||||
activeId.value = newValue.path
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
|
||||
const logout = () => {
|
||||
const hasClass = sessionStore.has('activeClass.id')
|
||||
const hasTool = sessionStore.get('isToolWin')
|
||||
if (hasClass || hasTool) return ElMessage.warning('当前正在上课,请先结束上课')
|
||||
ElMessageBox.confirm('确认退出系统吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async () => {
|
||||
const Chat = (await import('@/utils/chat')).default
|
||||
if (!!Chat.imChat) Chat.logout()
|
||||
userStore
|
||||
.logOut()
|
||||
.then(() => {
|
||||
// router.replace('/login')
|
||||
ipcRenderer && ipcRenderer.send('openLoginWindow')
|
||||
})
|
||||
.catch(() => {
|
||||
// router.replace('/login')
|
||||
ipcRenderer && ipcRenderer.send('openLoginWindow')
|
||||
})
|
||||
}).catch(()=>{})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.el-popover.popoverStyle{
|
||||
min-width:120px
|
||||
}
|
||||
.popoverStyle .head-aside{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.page-aside {
|
||||
height: 100%;
|
||||
background-color: #3A3A3A;
|
||||
padding: 20px 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
.user-img{
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.aside-tab {
|
||||
margin-top: 25px;
|
||||
-webkit-app-region: no-drag;
|
||||
|
||||
ul {
|
||||
flex-direction: column;
|
||||
li {
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
flex-direction: column;
|
||||
padding: 5px 0;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
|
||||
.text {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-size: 22px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
background-color: #7D7D7D
|
||||
}
|
||||
}
|
||||
|
||||
.disabled {
|
||||
cursor: not-allowed;
|
||||
color: #bfbfbf;
|
||||
|
||||
&:hover {
|
||||
color: #bfbfbf;
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.active-li {
|
||||
color: #fff;
|
||||
background-color: #7D7D7D
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
|
@ -1,5 +1,11 @@
|
|||
<template>
|
||||
<div class="title-bar flex">
|
||||
<div class="page-header">
|
||||
<div class="header-center">文枢2.5</div>
|
||||
<div class="header-right">
|
||||
<WindowTools />
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="title-bar flex">
|
||||
<div class="left-section">
|
||||
<div class="flex title-box">
|
||||
<el-image style="width: 23px; height: 23px" :src="logoIco" />
|
||||
|
@ -21,9 +27,9 @@
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="right-section flex">
|
||||
<!-- <div class="right-section flex">
|
||||
<WindowTools />
|
||||
<div class="user flex">
|
||||
<div class="avatar-container">
|
||||
|
@ -33,7 +39,6 @@
|
|||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item @click="changePage('/profile')">个人中心</el-dropdown-item>
|
||||
<!-- <el-dropdown-item @click="changePage('/classReserv')">课程预约</el-dropdown-item>-->
|
||||
<el-dropdown-item @click="changePage('/class')">班级中心</el-dropdown-item>
|
||||
<el-dropdown-item divided command="logout">
|
||||
<span>退出登录</span>
|
||||
|
@ -65,8 +70,8 @@
|
|||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- </div> -->
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
@ -221,6 +226,23 @@ onMounted(() => {
|
|||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-header{
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
.header-center{
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.header-right{
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.title-bar {
|
||||
height: 80px;
|
||||
justify-content: space-between;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-container>
|
||||
<!-- <el-container>
|
||||
<el-header>
|
||||
<Header />
|
||||
</el-header>
|
||||
|
@ -8,13 +8,31 @@
|
|||
</el-main>
|
||||
<Uploader v-if="uploaderStore.uploadList && uploaderStore.uploadList.length > 0" />
|
||||
<AiChart/>
|
||||
</el-container>
|
||||
</el-container> -->
|
||||
<div class="common-layout">
|
||||
<el-container>
|
||||
<el-aside width="70px">
|
||||
<Aside/>
|
||||
</el-aside>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<Header/>
|
||||
</el-header>
|
||||
<el-main>
|
||||
<AppMain />
|
||||
</el-main>
|
||||
</el-container>
|
||||
<Uploader v-if="uploaderStore.uploadList && uploaderStore.uploadList.length > 0" />
|
||||
<AiChart/>
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import Header from './components/Header.vue'
|
||||
import Aside from './components/Aside.vue'
|
||||
import AppMain from './components/AppMain.vue'
|
||||
import Uploader from './components/Uploader.vue'
|
||||
import AiChart from '@/components/ai-chart/index.vue'
|
||||
|
@ -31,18 +49,19 @@ let uploaderStore = ref(uploaderState())
|
|||
.el-container {
|
||||
height: 100%;
|
||||
// background: url(@/assets/images/login/login-bg.png) no-repeat center;
|
||||
// background: #EAEFF8;
|
||||
// background: #fff;
|
||||
background: linear-gradient(to bottom right, #cce6ff 0%, #79d0fc 100%);
|
||||
// background: linear-gradient(to top, #a6e3e9, #e3fdfd);
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.common-layout{
|
||||
height: 100%;
|
||||
}
|
||||
.el-header {
|
||||
padding: 0;
|
||||
height: 80px;
|
||||
height: 45px;
|
||||
}
|
||||
.el-main {
|
||||
--el-main-padding: 0 20px 20px 20px;
|
||||
--el-main-padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.el-page-header{
|
||||
|
|
|
@ -31,6 +31,12 @@ export const constantRoutes = [
|
|||
component: Layout,
|
||||
redirect: '/home',
|
||||
children: [
|
||||
{
|
||||
path: '/index',
|
||||
component: () => import('@/views/index/index.vue'),
|
||||
name: 'index',
|
||||
meta: {title: '首页'}
|
||||
},
|
||||
{
|
||||
path: '/home',
|
||||
component: () => import('@/views/desktop/index.vue'),
|
||||
|
@ -122,6 +128,12 @@ export const constantRoutes = [
|
|||
name: 'examReport',
|
||||
meta: {title: '考试分析'}
|
||||
},
|
||||
{
|
||||
path: '/setting',
|
||||
component: () => import('@/views/setting/index.vue'),
|
||||
name: 'setting',
|
||||
meta: {title: '设置'}
|
||||
},
|
||||
]
|
||||
},
|
||||
...toolRouters
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div class="common-layout">
|
||||
<el-container>
|
||||
<el-aside style="width: 200px;margin-top: 20px">
|
||||
<el-card style="width: 200px" class="el-card-demo" :style="{'min-height': (viewportHeight - 164) + 'px','max-height': (viewportHeight - 164) + 'px'}">
|
||||
<el-aside style="width: 200px;">
|
||||
<el-card style="width: 200px" class="el-card-demo">
|
||||
<div >
|
||||
<Aside :menuItems="menuItems" :classList="classList" @handleSelect="handleSelect"></Aside>
|
||||
</div>
|
||||
|
@ -13,9 +13,9 @@
|
|||
</template>
|
||||
</el-card>
|
||||
</el-aside>
|
||||
<el-main :style="{'min-height': (viewportHeight - 204) + 'px'}">
|
||||
|
||||
<!-- <router-view :style="{'height': (viewportHeight - 120) + 'px','overflow-y': 'auto'}" :key="route.path"></router-view>-->
|
||||
<div :style="{'height': (viewportHeight - 164) + 'px','overflow-y': 'auto'}">
|
||||
<div class="page-right">
|
||||
<!-- 班级概况-->
|
||||
<ClassInfo v-if="currentIndex==0" :classId="classId"></ClassInfo>
|
||||
<!-- 学生列表-->
|
||||
|
@ -24,7 +24,7 @@
|
|||
<BasicGroup v-else-if="currentIndex==2" :classId="classId"></BasicGroup>
|
||||
</div>
|
||||
|
||||
</el-main>
|
||||
|
||||
</el-container>
|
||||
</div>
|
||||
<el-dialog v-model="dialogVisible" title="新增班级" width="50%" append-to-body>
|
||||
|
@ -306,13 +306,27 @@
|
|||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.common-layout{
|
||||
height: 100%;
|
||||
.el-container{
|
||||
height: 100%;
|
||||
.el-aside{
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-card-demo{
|
||||
width: 200px;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
height: 100%
|
||||
}
|
||||
.page-right{
|
||||
flex: 1;
|
||||
margin-left: 20px
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -75,12 +75,12 @@ let studentList = ref([]) // 学生数据
|
|||
|
||||
// 初始-数据处理
|
||||
const initData = () => {
|
||||
console.log('xxx', props)
|
||||
// window.test = activeCourse
|
||||
studentList.value = props.activeData.studentList || []
|
||||
const activeWorkFeedList = props.activeData.workFeedList || []
|
||||
const quizlist = props.activeData.quizlist || []
|
||||
const timeArr = groupByField(props.activeData.workFeedList,'entpcourseworkid')
|
||||
console.log(quizlist,'quizlist');
|
||||
|
||||
// 习题特殊处理
|
||||
let data = quizlist.map(o => {
|
||||
// 解析题选项
|
||||
|
@ -90,14 +90,9 @@ const initData = () => {
|
|||
let rightIds = [] // 正确学生
|
||||
let hasAnswers= [] // 答过题的学生
|
||||
let timeAnalyse = [] // 平均时长和编号
|
||||
// let subjectCourese = [] // 题目编号
|
||||
const quizFeedList = activeWorkFeedList.filter(f => f.entpcourseworkid == o.id) // 做该题的列表
|
||||
// 获取所有的做题时间
|
||||
timeArr.forEach((item,index) => {
|
||||
const arr = item.reduce((acc, cur) => {
|
||||
return acc + (cur.timelength ? Number(cur.timelength) : 0);
|
||||
},0)
|
||||
timeAnalyse.push(arr)
|
||||
})
|
||||
|
||||
let children = []
|
||||
const allStudents = [];
|
||||
if (o.worktype == '单选题') { // '单选题','多选题'
|
||||
|
@ -108,6 +103,11 @@ const initData = () => {
|
|||
// 改选项的学生id
|
||||
const studentIds = quizFeedList.filter(f => f.feedcontent==v&&f.finishtimelength!='0').map(f => f.studentid)||[];
|
||||
accSum += studentIds.length;
|
||||
// 该到题的用时时间
|
||||
timeAnalyse = quizFeedList.reduce((acc, cur) => {
|
||||
return acc + (cur.timelength ? Number(cur.timelength) : 0);
|
||||
},0)
|
||||
|
||||
if (isOk) {
|
||||
activeIds.push(...studentIds)
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ const initData = () => {
|
|||
const res = isSame((f.feedcontent||'').split(','), workanswer);
|
||||
return f.entpcourseworkid == o.id && f.finishtimelength!='0' && res;
|
||||
});
|
||||
|
||||
|
||||
const list = workdesc.includes('#&') ? workdesc.split('#&') : isJson(workdesc)?JSON.parse(workdesc):[];
|
||||
children = list.map((v,i) => {
|
||||
const isOne = o.worktype == '单选题'
|
||||
|
@ -135,6 +135,10 @@ const initData = () => {
|
|||
if (studentIds.length>0) {
|
||||
allStudents.push(...studentIds);
|
||||
}
|
||||
// 该到题的用时时间
|
||||
timeAnalyse = quizFeedList.reduce((acc, cur) => {
|
||||
return acc + (cur.timelength ? Number(cur.timelength) : 0);
|
||||
},0)
|
||||
if(isOk) {
|
||||
activeIds=[...new Set(activeIds.concat(studentIds))] // 多选去重
|
||||
}
|
||||
|
@ -153,6 +157,10 @@ const initData = () => {
|
|||
activeIds=[...new Set(activeIds.concat(studentIds))] // 多选去重
|
||||
hasAnswers=[...new Set(hasAnswers.concat(studentIds))]
|
||||
accSum = activeIds.length
|
||||
// 该到题的用时时间
|
||||
timeAnalyse = quizFeedList.reduce((acc, cur) => {
|
||||
return acc + (cur.timelength ? Number(cur.timelength) : 0);
|
||||
},0)
|
||||
return { def, code, txt, isOk:true, studentIds }
|
||||
})
|
||||
} else if (o.worktype == '判断题') { // 判断题
|
||||
|
@ -194,6 +202,10 @@ const initData = () => {
|
|||
accSum += studentIds.length;
|
||||
if(isOk) activeIds.push(...studentIds)
|
||||
hasAnswers.push(...studentIds)
|
||||
// 该到题的用时时间
|
||||
timeAnalyse = quizFeedList.reduce((acc, cur) => {
|
||||
return acc + (cur.timelength ? Number(cur.timelength) : 0);
|
||||
},0)
|
||||
return { def: v, code: v, isOk, studentIds }
|
||||
})
|
||||
} else { // 论述题
|
||||
|
@ -203,6 +215,10 @@ const initData = () => {
|
|||
activeIds=[...new Set(activeIds.concat(studentIds))] // 多选去重
|
||||
hasAnswers=[...new Set(hasAnswers.concat(studentIds))]
|
||||
accSum = activeIds.length
|
||||
// 该到题的用时时间
|
||||
timeAnalyse = quizFeedList.reduce((acc, cur) => {
|
||||
return acc + (cur.timelength ? Number(cur.timelength) : 0);
|
||||
},0)
|
||||
children = [{ def, code, isOk:true, studentIds }]
|
||||
}
|
||||
|
||||
|
@ -222,7 +238,7 @@ const initData = () => {
|
|||
}
|
||||
|
||||
// def: 原始题数据 type 类型 active: 选中 points: 得分率, accSum 题解答人数
|
||||
return { def: o, id: o.id, type: o.worktype, active: [], points, accSum, rightSum, children,hasAnswers,timeAnalyse }
|
||||
return { def: o, id: o.id, type: o.worktype, active: [], points, accSum, rightSum, children,hasAnswers,timeAnalyse,score:o.score }
|
||||
})
|
||||
if (data.length === 0) return
|
||||
useOverview.getAllData([...data])
|
||||
|
|
|
@ -24,6 +24,7 @@ const dataList = ref([
|
|||
// 答过题的学生才进行统计
|
||||
const hasStudents = ref([])
|
||||
|
||||
|
||||
// 根据数据生成不同的颜色
|
||||
function getColor(name) {
|
||||
const colorMap = {
|
||||
|
@ -104,7 +105,18 @@ const showEcharts = () => {
|
|||
}
|
||||
//执行
|
||||
watch(() => useOverview.tableList, () => {
|
||||
hasStudents.value = useOverview.tableList.filter(item => useOverview.allData[0].hasAnswers.includes(item.studentid)).map(item => item);
|
||||
// 判断是不是客观题
|
||||
const subType = useOverview.allData.map(item => item.type)
|
||||
const objectiveQuestion = ['单选题','多选题','判断题']
|
||||
if( !subType.every(item => objectiveQuestion.includes(item)) ){
|
||||
hasStudents.value = useOverview.tableList.filter(item => {
|
||||
if(item.rating > 0 && useOverview.allData[0].hasAnswers.includes(item.studentid)){
|
||||
return item
|
||||
}
|
||||
})
|
||||
}else{
|
||||
hasStudents.value = useOverview.tableList.filter(item => useOverview.allData[0].hasAnswers.includes(item.studentid)).map(item => item);
|
||||
}
|
||||
showEcharts();
|
||||
nextTick(() => {
|
||||
initChart();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<el-tab-pane :label="item.label" style="text-align:left" stretch="true">
|
||||
<template v-if="item.stuList.length > 0">
|
||||
<template v-for="(stuItem,stuIndex) in item.stuList" :key="stuIndex">
|
||||
<el-tag style="margin:5px 10px 0 0" type="primary">{{stuItem.studentname}}</el-tag>
|
||||
<el-tag style="margin:5px 10px 0 0" type="primary">{{ stuItem.studentname }}:{{ stuItem.getScore }}分</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
|
@ -81,7 +81,18 @@ const showStudents = (index) => {
|
|||
})
|
||||
}
|
||||
watch(() => useOverview.tableList, () => {
|
||||
hasStudents.value = useOverview.tableList.filter(item => useOverview.allData[0].hasAnswers.includes(item.studentid)).map(item => item);
|
||||
// 判断是不是客观题
|
||||
const subType = useOverview.allData.map(item => item.type)
|
||||
const objectiveQuestion = ['单选题','多选题','判断题']
|
||||
if( !subType.every(item => objectiveQuestion.includes(item)) ){
|
||||
hasStudents.value = useOverview.tableList.filter(item => {
|
||||
if(item.rating > 0 && useOverview.allData[0].hasAnswers.includes(item.studentid)){
|
||||
return item
|
||||
}
|
||||
})
|
||||
}else{
|
||||
hasStudents.value = useOverview.tableList.filter(item => useOverview.allData[0].hasAnswers.includes(item.studentid)).map(item => item);
|
||||
}
|
||||
showStudents(0)
|
||||
},{deep: true})
|
||||
</script>
|
||||
|
|
|
@ -20,82 +20,80 @@
|
|||
<script setup>
|
||||
import {ref, watch} from 'vue'
|
||||
import overviewStore from '@/store/modules/overview'
|
||||
import {listEntpcoursework} from '@/api/education/entpCourseWork'
|
||||
|
||||
const useOverview = overviewStore()
|
||||
const tableData = ref([])
|
||||
//获取题目id
|
||||
const ids = ref('')
|
||||
//总分
|
||||
const allScore = ref(0)
|
||||
//用来获取所有知识点
|
||||
const konwledge = ref([])
|
||||
const hasStudents = ref([])
|
||||
// 获取的所有得分
|
||||
const allScore = ref([])
|
||||
//所有题目的知识点
|
||||
const getKonwledge = () => {
|
||||
useOverview.tableList.forEach(item => {
|
||||
const getScoreRate = []
|
||||
// 获取知识点的种数
|
||||
const ledges = []
|
||||
hasStudents.value.forEach((item,index) => {
|
||||
//判断是否存在知识点
|
||||
if(item.knowledgePoint){
|
||||
konwledge.value.push({...JSON.parse(item.knowledgePoint),...{scoingRate:Number(item.scoingRate),point:item.point,allPoint:allScore.value}})
|
||||
const title = JSON.parse(item.knowledgePoint)
|
||||
//判断知识点是否重复
|
||||
if(!ledges.includes(title.id)){
|
||||
ledges.push(title.id)
|
||||
// 假如分数是0 或者 得分率为空
|
||||
konwledge.value.push({title:title.title,allPoint:allScore.value,id:title.id})
|
||||
}
|
||||
// 判断学生是否答过题
|
||||
if(useOverview.allData[0].hasAnswers.includes(item.studentid))
|
||||
getScoreRate.push({rate:item.scoingRate,id:title.id})
|
||||
}
|
||||
})
|
||||
tableData.value = getTableList(konwledge.value)
|
||||
tableData.value = tableData.value.map(item => {
|
||||
return{
|
||||
|
||||
// 看看有几个知识点
|
||||
konwledge.value.forEach(item => {
|
||||
let sunRate = 0
|
||||
let num = 0
|
||||
if(getScoreRate.length === 0) return
|
||||
|
||||
getScoreRate.forEach(item2 => {
|
||||
if(item.id === item2.id){
|
||||
sunRate += extractedNumber(item2.rate)
|
||||
num ++
|
||||
}
|
||||
})
|
||||
const scoreRate = sunRate / num
|
||||
tableData.value.push({
|
||||
scoingRate:scoreRate.toFixed(2),
|
||||
...item,
|
||||
allPoint: allScore.value
|
||||
}
|
||||
point:(item.allPoint * scoreRate / 100).toFixed(2)
|
||||
})
|
||||
})
|
||||
console.log(tableData.value,'tableData.value')
|
||||
}
|
||||
//获取总分
|
||||
const getScore = async () => {
|
||||
const scoreId = useOverview.tableList[0].entpcourseworklist
|
||||
const fixedJsonString = `[${scoreId}]`;
|
||||
const objects = JSON.parse(fixedJsonString);
|
||||
const id = objects.map(obj => obj.id);
|
||||
ids.value = id.join(',')
|
||||
const res = await listEntpcoursework({ids: ids.value, pageSize: 500})
|
||||
if(res.code === 200){
|
||||
allScore.value = res.rows.reduce((acc, cur) => acc + cur.workScore, 0);
|
||||
getKonwledge()
|
||||
}
|
||||
// 获取百分比的数字
|
||||
const extractedNumber = (score) => {
|
||||
const match = score.match(/\d+/);
|
||||
return match ? parseInt(match[0], 10) : null;
|
||||
}
|
||||
//组装tableList表格
|
||||
const getTableList = (data) => {
|
||||
const result = [];
|
||||
data.forEach(item => {
|
||||
const existingItem = result.find(i => i.id === item.id);
|
||||
if (existingItem) {
|
||||
// 累加point和scoingRate
|
||||
existingItem.pointTotal += parseInt(item.point);
|
||||
existingItem.scoingRateTotal += parseFloat(item.scoingRate);
|
||||
existingItem.count++;
|
||||
} else {
|
||||
// 新的对象
|
||||
result.push({
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
pointTotal: item.point,
|
||||
scoingRateTotal: parseFloat(item.scoingRate),
|
||||
count: 1
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 计算平均值
|
||||
result.forEach(item => {
|
||||
item.point = Math.round(item.pointTotal / item.count);
|
||||
// item.scoingRate = Math.round((item.scoingRateTotal / item.count) * 100) / 100;
|
||||
item.scoingRate = Math.round((item.point / allScore.value) * 100);
|
||||
delete item.pointTotal;
|
||||
delete item.scoingRateTotal;
|
||||
delete item.count;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
watch(() => useOverview.tableList,() => {
|
||||
console.log(useOverview.tableList,'useOverview.tableList')
|
||||
getScore()
|
||||
watch(() => useOverview.tableList,() => {
|
||||
// 判断是不是客观题
|
||||
const subType = useOverview.allData.map(item => item.type)
|
||||
const objectiveQuestion = ['单选题','多选题','判断题']
|
||||
if( !subType.every(item => objectiveQuestion.includes(item)) ){
|
||||
hasStudents.value = useOverview.tableList.filter(item => {
|
||||
if(item.rating > 0 && useOverview.allData[0].hasAnswers.includes(item.studentid)){
|
||||
return item
|
||||
}
|
||||
})
|
||||
}else{
|
||||
hasStudents.value = useOverview.tableList.filter(item => useOverview.allData[0].hasAnswers.includes(item.studentid)).map(item => item);
|
||||
}
|
||||
// 这里获取所有知识点的总分
|
||||
allScore.value = useOverview.allData.reduce((acc, cur) => {
|
||||
return acc + Number(cur.score)
|
||||
},0)
|
||||
getKonwledge()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
|
@ -9,134 +9,155 @@ import * as echarts from 'echarts';
|
|||
import {ref, nextTick, watch} from 'vue'
|
||||
import overviewStore from '@/store/modules/overview'
|
||||
|
||||
const useOverview = overviewStore()
|
||||
const useOverview = overviewStore();
|
||||
|
||||
// 获取图表容器的引用
|
||||
const chartRef = ref(null);
|
||||
// 预计用时
|
||||
const expectedDuration = ref([]);
|
||||
|
||||
// 初始化图表
|
||||
function initChart() {
|
||||
const myChart = echarts.init(chartRef.value);
|
||||
// 指定图表的配置项和数据
|
||||
let option = {
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||
},
|
||||
formatter: function(parms) {
|
||||
let str =
|
||||
parms[0].axisValue +
|
||||
"</br>" +
|
||||
parms[0].marker +
|
||||
"平均用时:" +
|
||||
parms[0].value + 's'
|
||||
return str;
|
||||
},
|
||||
|
||||
},
|
||||
textStyle: {
|
||||
|
||||
// 指定图表的配置项和数据
|
||||
let option = {
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
|
||||
},
|
||||
formatter: function (parms) {
|
||||
let str = "";
|
||||
parms.forEach(param => {
|
||||
if (param.seriesType === 'bar') {
|
||||
str += param.axisValue + "</br>" + param.marker + "平均用时:" + param.value + 's' + "</br>";
|
||||
} else if (param.seriesType === 'line') {
|
||||
str += param.marker + "预计用时:" + param.value + 's';
|
||||
}
|
||||
});
|
||||
return str;
|
||||
},
|
||||
},
|
||||
textStyle: {
|
||||
color: "#333",
|
||||
},
|
||||
color: ["#7BA9FA", "#4690FA"],
|
||||
grid: {
|
||||
containLabel: true,
|
||||
left: "10%",
|
||||
top: "20%",
|
||||
bottom: "10%",
|
||||
right: "10%",
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: getXValue(),
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#333",
|
||||
},
|
||||
color: ["#7BA9FA", "#4690FA"],
|
||||
grid: {
|
||||
containLabel: true,
|
||||
left: "10%",
|
||||
top: "20%",
|
||||
bottom: "10%",
|
||||
right: "10%",
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
margin: 20, //刻度标签与轴线之间的距离。
|
||||
textStyle: {
|
||||
color: "#000",
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: getXValue(),
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#333",
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
margin: 20, //刻度标签与轴线之间的距离。
|
||||
textStyle: {
|
||||
color: "#000",
|
||||
},
|
||||
},
|
||||
name:'题目编号'
|
||||
},
|
||||
name: '题目编号'
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#B5B5B5",
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: "#B5B5B5",
|
||||
},
|
||||
},
|
||||
name:'平均时长',
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
// 使用深浅的间隔色
|
||||
color: ["#B5B5B5"],
|
||||
type: "dashed",
|
||||
opacity: 0.5,
|
||||
},
|
||||
},
|
||||
axisLabel: {},
|
||||
},
|
||||
name: '平均时长',
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
// 使用深浅的间隔色
|
||||
color: ["#B5B5B5"],
|
||||
type: "dashed",
|
||||
opacity: 0.5,
|
||||
},
|
||||
series: [{
|
||||
data: getYValue(),
|
||||
stack: "zs",
|
||||
type: "bar",
|
||||
barMaxWidth: "auto",
|
||||
barWidth: 60,
|
||||
itemStyle: {
|
||||
color: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
type: "linear",
|
||||
global: false,
|
||||
colorStops: [{
|
||||
offset: 0,
|
||||
color: "#5EA1FF",
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: "#90BEFF",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
axisLabel: {},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: getYValue(),
|
||||
stack: "zs",
|
||||
type: "bar",
|
||||
barMaxWidth: "auto",
|
||||
barWidth: 60,
|
||||
itemStyle: {
|
||||
color: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
type: "linear",
|
||||
global: false,
|
||||
colorStops: [
|
||||
{ offset: 0, color: "#5EA1FF" },
|
||||
{ offset: 1, color: "#90BEFF" },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: '{c}s',
|
||||
color: '#333',
|
||||
},
|
||||
},
|
||||
//折线的加入
|
||||
{
|
||||
data: expectedDuration.value,
|
||||
type: "line",
|
||||
smooth: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
lineStyle: {
|
||||
color: '#FF7F50',
|
||||
width: 2,
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#FF7F50',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
myChart.setOption(option);
|
||||
}
|
||||
//获取平均时长纵坐标
|
||||
|
||||
// 获取平均时长纵坐标
|
||||
const getYValue = () => {
|
||||
const arr = [...useOverview.allData[0].timeAnalyse]
|
||||
const num = useOverview.allData[0].hasAnswers.length
|
||||
|
||||
return arr.map(item => {
|
||||
return item ? (item / num).toFixed(2) : 0
|
||||
})
|
||||
}
|
||||
// 获取横纵轴坐标数据
|
||||
const arr = useOverview.allData.map(item => item.timeAnalyse)
|
||||
const num = useOverview.allData[0].hasAnswers.length;
|
||||
if (arr.length === 0) return [];
|
||||
return arr.map(item => (item ? (item / num).toFixed(2) : 0));
|
||||
};
|
||||
|
||||
// 获取横纵轴坐标数据
|
||||
const getXValue = () => {
|
||||
return useOverview.allData.map(item => item.id)
|
||||
}
|
||||
return useOverview.allData.map((item, index) => `第${index + 1}题`);
|
||||
};
|
||||
|
||||
watch(() => useOverview.tableList, () => {
|
||||
expectedDuration.value = useOverview.tableList.map(item => (Number(item.timelength) * 60 / useOverview.allData.length).toFixed(2));
|
||||
|
||||
|
||||
watch(() => useOverview.tableList,() => {
|
||||
//获取横纵坐标
|
||||
// 获取横纵坐标
|
||||
nextTick(() => {
|
||||
initChart();
|
||||
})
|
||||
})
|
||||
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
<span>学生答案:
|
||||
<span
|
||||
v-if="stuItem.feedcontent !=''"
|
||||
style="background-color: red; color: white; padding: 0 5px; border-radius: 5px;"
|
||||
:style="{backgroundColor: `${formatWorkAnswer(quItem) == formatFeedContent(stuItem, quItem)? '#0ed116' : 'red'}`,color: 'white', padding: '0 5px', borderRadius: '5px'}"
|
||||
v-html="formatFeedContent(stuItem, quItem)"
|
||||
>
|
||||
</span>
|
||||
|
|
|
@ -87,6 +87,11 @@
|
|||
<span v-if="tableRadio.value==1">{{ scope.row.updatedate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="tableRadio.value==0?'':'得分'" prop="score" width="80" align="center" >
|
||||
<template #default="scope" v-if="tableRadio.value==1">
|
||||
<span style="color: #2196f3">{{scope.row.getScore || 0}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="批阅状态" prop="teacherRating" align="center" width="120" sortable>
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.teacherRating == 0">
|
||||
|
@ -359,21 +364,27 @@ const getClassWorkStudentList = (rowId) => {
|
|||
const evalarray = JSON.parse('[' + response.rows[i].classworkevallist + ']')
|
||||
var scoingCount = 0
|
||||
var feedcount = 0
|
||||
let score = 0
|
||||
for (var e = 0; e < evalarray.length; e++) {
|
||||
if (evalarray[e].feedcontent != '') {
|
||||
feedcount++
|
||||
// 与答案对比正误。注意注意,这里仅限单选题
|
||||
if (evalarray[e].feedcontent == evalarray[e].rightanswer) {
|
||||
scoingCount++
|
||||
score += evalarray[e].score;
|
||||
evalarray[e].teacherRating = evalarray[e].score
|
||||
}
|
||||
}
|
||||
}
|
||||
const allScore = evalarray.reduce((acc, cur) => acc + cur.score, 0)
|
||||
//console.log(evalarray, 'evalarray------------------------------------')
|
||||
if (feedcount > 0) {
|
||||
// 多个题目的总得分率: 正确题数/(题目数*100)
|
||||
response.rows[i].scoingRate = ((scoingCount / feedcount) * 100).toFixed(0) + '%'
|
||||
response.rows[i].scoingRate = ((score / allScore) * 100).toFixed(0) + '%'
|
||||
response.rows[i].getScore = score
|
||||
} else {
|
||||
response.rows[i].scoingRate = '0%'
|
||||
response.rows[i].getScore = 0
|
||||
}
|
||||
// 批阅状态 优良类 :注意:这里题目中的评价都是一样的,所以取第一个
|
||||
if (evalarray[0].rating != '') {
|
||||
|
@ -381,6 +392,7 @@ const getClassWorkStudentList = (rowId) => {
|
|||
}
|
||||
} else {
|
||||
response.rows[i].scoingRate = '0%'
|
||||
response.rows[i].getScore = 0
|
||||
}
|
||||
}
|
||||
classWorkAnalysis.classworkdata = response.rows
|
||||
|
@ -624,6 +636,7 @@ const handleClassOverviewOpen = (type) =>{
|
|||
response.rows.forEach(item => {
|
||||
let rightAnswer = 0
|
||||
let answers = 0
|
||||
let score = 0
|
||||
if(!item.classworkevallist) return
|
||||
// 使用正则表达式替换字符串值中的双引号为单引号
|
||||
let replacedString = item.classworkevallist.replace(/""/g, "\"");
|
||||
|
@ -642,12 +655,18 @@ const handleClassOverviewOpen = (type) =>{
|
|||
//正确答案,仅限单选题
|
||||
if(itemTopic.feedcontent === itemTopic.rightanswer){
|
||||
rightAnswer ++
|
||||
score += itemTopic.score
|
||||
itemTopic.teacherRating = itemTopic.score
|
||||
}
|
||||
}
|
||||
})
|
||||
rightAnswer > 0?item.scoingRate = (rightAnswer/answers * 100).toFixed(0):item.scoingRate = ''
|
||||
const allScore = allTopic.reduce((acc, cur) => {
|
||||
return acc + cur.score;
|
||||
},0)
|
||||
rightAnswer > 0?item.scoingRate = (score/allScore * 100).toFixed(0):item.scoingRate = ''
|
||||
}else{
|
||||
item.scoingRate = ''
|
||||
item.getScore = 0
|
||||
}
|
||||
//获得总分
|
||||
const point = allTopic.reduce((acc, cur) => {
|
||||
|
|
|
@ -77,6 +77,11 @@
|
|||
<span v-if="tableRadio.value==1">{{ scope.row.updatedate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="tableRadio.value==0?'':'得分'" prop="score" width="80" align="center" >
|
||||
<template #default="scope" v-if="tableRadio.value==1">
|
||||
<span style="color: #2196f3">{{scope.row.getScore || 0}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="批阅状态" prop="teacherRating" align="center" width="120" sortable>
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.teacherRating == 0">
|
||||
|
@ -356,21 +361,27 @@ const getClassWorkStudentList = (rowId) => {
|
|||
const evalarray = JSON.parse('[' + response.rows[i].classworkevallist + ']')
|
||||
var scoingCount = 0
|
||||
var feedcount = 0
|
||||
let score = 0
|
||||
for (var e = 0; e < evalarray.length; e++) {
|
||||
if (evalarray[e].feedcontent != '') {
|
||||
feedcount++
|
||||
// 与答案对比正误。注意注意,这里仅限单选题
|
||||
if (evalarray[e].feedcontent == evalarray[e].rightanswer) {
|
||||
scoingCount++
|
||||
score += evalarray[e].score;
|
||||
evalarray[e].teacherRating = evalarray[e].score
|
||||
}
|
||||
}
|
||||
}
|
||||
const allScore = evalarray.reduce((acc, cur) => acc + cur.score, 0)
|
||||
//console.log(evalarray, 'evalarray------------------------------------')
|
||||
if (feedcount > 0) {
|
||||
// 多个题目的总得分率: 正确题数/(题目数*100)
|
||||
response.rows[i].scoingRate = ((scoingCount / feedcount) * 100).toFixed(0) + '%'
|
||||
response.rows[i].scoingRate = ((score / allScore) * 100).toFixed(0) + '%'
|
||||
response.rows[i].getScore = score
|
||||
} else {
|
||||
response.rows[i].scoingRate = '0%'
|
||||
response.rows[i].getScore = 0
|
||||
}
|
||||
// 批阅状态 优良类 :注意:这里题目中的评价都是一样的,所以取第一个
|
||||
if (evalarray[0].rating != '') {
|
||||
|
@ -378,6 +389,7 @@ const getClassWorkStudentList = (rowId) => {
|
|||
}
|
||||
} else {
|
||||
response.rows[i].scoingRate = '0%'
|
||||
response.rows[i].getScore = 0
|
||||
}
|
||||
}
|
||||
classWorkAnalysis.classworkdata = response.rows
|
||||
|
@ -390,17 +402,29 @@ const getClassWorkStudentList = (rowId) => {
|
|||
tableRadio.value = '1'
|
||||
tableRadio.num0 = classWorkAnalysis.classworkdata.length - tableRadio.list.length
|
||||
tableRadio.num1 = tableRadio.list.length
|
||||
tableRadio.list = tableRadio.list.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
teacherRating : checkWorkType(item)
|
||||
}
|
||||
})
|
||||
// 自动批阅判断
|
||||
teacherCriticism();
|
||||
})
|
||||
.catch(() => {
|
||||
loading_dt_table.value = false
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 自动批阅判断:
|
||||
* 已交 并 作业类型为习题训练
|
||||
*/
|
||||
const teacherCriticism = ()=>{
|
||||
// 已交的list才自动批阅判断
|
||||
if(tableRadio.value == '1'&& classWorkAnalysis.worktype == '习题训练'){
|
||||
// 只有习题训练才会自动批阅
|
||||
tableRadio.list = tableRadio.list.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
teacherRating : item.teacherRating || checkWorkType(item)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
const checkWorkType = (item) => {
|
||||
//这里判断题目类型
|
||||
const subType = classWorkActiveData.quizlist.map(item => item.worktype)
|
||||
|
@ -408,7 +432,7 @@ const checkWorkType = (item) => {
|
|||
let rating = 0
|
||||
//判断题目是不是客观题
|
||||
if(subType.every(item => objectiveQuestion.includes(item))){
|
||||
// 获取学生答题列表
|
||||
// 获取学生答题列表 scoingRate 得分率
|
||||
const score = extractedNumber(item.scoingRate)
|
||||
if(0<=score && score<=59){
|
||||
rating = 5
|
||||
|
@ -551,6 +575,8 @@ const tableRadioChange = (e) => {
|
|||
tableRadio.value = '1';
|
||||
tableRadio.num0 = classWorkAnalysis.classworkdata.length - tableRadio.list.length;
|
||||
tableRadio.num1 = tableRadio.list.length;
|
||||
// 自动批阅判断
|
||||
teacherCriticism();
|
||||
}else if(e=='0'){
|
||||
tableRadio.list = classWorkAnalysis.classworkdata.filter(item => item.finishtimelength == '0')
|
||||
tableRadio.value = '0';
|
||||
|
@ -625,6 +651,7 @@ const handleClassOverviewOpen = (type) =>{
|
|||
response.rows.forEach(item => {
|
||||
let rightAnswer = 0
|
||||
let answers = 0
|
||||
let score = 0
|
||||
if(!item.classworkevallist) return
|
||||
// 使用正则表达式替换字符串值中的双引号为单引号
|
||||
let replacedString = item.classworkevallist.replace(/""/g, "\"");
|
||||
|
@ -643,12 +670,19 @@ const handleClassOverviewOpen = (type) =>{
|
|||
//正确答案,仅限单选题
|
||||
if(itemTopic.feedcontent === itemTopic.rightanswer){
|
||||
rightAnswer ++
|
||||
score += itemTopic.score
|
||||
itemTopic.teacherRating = itemTopic.score
|
||||
}
|
||||
}
|
||||
})
|
||||
rightAnswer > 0?item.scoingRate = (rightAnswer/answers * 100).toFixed(0):item.scoingRate = ''
|
||||
const allScore = allTopic.reduce((acc, cur) => {
|
||||
return acc + cur.score;
|
||||
},0)
|
||||
rightAnswer > 0?item.scoingRate = (score/allScore * 100).toFixed(0):item.scoingRate = ''
|
||||
item.getScore = score
|
||||
}else{
|
||||
item.scoingRate = ''
|
||||
item.getScore = 0
|
||||
}
|
||||
//获得总分
|
||||
const point = allTopic.reduce((acc, cur) => {
|
||||
|
|
|
@ -263,7 +263,6 @@ onMounted(async ()=>{
|
|||
<style lang="scss" scoped>
|
||||
.page-desktop{
|
||||
height: 100%;
|
||||
padding-top: 20px;
|
||||
.desktop-left{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
|
@ -270,7 +270,6 @@ onMounted(() => {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.page-resource {
|
||||
padding-top: 10px;
|
||||
height: 100%;
|
||||
|
||||
//右侧栏
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<template>
|
||||
<div>
|
||||
教学大模型
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
|
@ -818,7 +818,6 @@ export default {
|
|||
<style scoped lang="scss">
|
||||
.page-resource {
|
||||
user-select: none;
|
||||
padding-top: 10px;
|
||||
height: 100%;
|
||||
:deep(.el-tabs__nav) {
|
||||
.el-tabs__item{
|
||||
|
|
|
@ -112,7 +112,6 @@ watch(() => sourceStore.query.fileSource,() => {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.page-resource {
|
||||
padding-top: 10px;
|
||||
height: 100%;
|
||||
|
||||
.page-right {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<template>
|
||||
<div>
|
||||
设置
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
|
@ -73,9 +73,8 @@ const list = computed(() => props.data.map((o,i) => {
|
|||
}))
|
||||
onMounted(() => {
|
||||
posBtnAll = btnRef.value.getBoundingClientRect()
|
||||
hPost.value = posBtnAll.height
|
||||
|
||||
curNode = sessionStore.get('subject.curNode')
|
||||
hPost.value = Math.round(posBtnAll.height)
|
||||
curNode = sessionStore?.get?.('subject.curNode')
|
||||
})
|
||||
// === 方法 ===
|
||||
// 获取颜色索引
|
||||
|
@ -97,7 +96,7 @@ const clickHandel = (o, e) => {
|
|||
isVisible.value = !isColse // 相同的按钮且打开状态,点击关闭
|
||||
activeObj.value = o
|
||||
const nodeH = parseInt(node.height / 2) // 高度的一半
|
||||
topPos.value = parseInt(node.top) - posBtnAll.top + nodeH
|
||||
topPos.value = Math.round(parseInt(node.top) - posBtnAll.top + nodeH)
|
||||
}
|
||||
emit('change', o)
|
||||
}
|
||||
|
@ -149,8 +148,8 @@ const closeActive = () =>{
|
|||
--top: 30px;
|
||||
--height: 40vh;
|
||||
position: fixed;
|
||||
inset: 50% 75px auto auto;
|
||||
transform: translateY(-50%);
|
||||
inset: 0 75px auto auto;
|
||||
// transform: translateY(-50%);
|
||||
background-color: #121212;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div v-if="props.test">
|
||||
<el-button type="primary" @click="trigger" v-tap:trigger="">点赞</el-button>
|
||||
<el-button type="primary" @click="trigger(1)" v-tap:trigger="[1,'']">点赞</el-button>
|
||||
<el-button type="primary" @click="trigger(2, '学生A')" v-tap:trigger="[2,'学生A']">疑惑</el-button>
|
||||
</div>
|
||||
<!-- 温度计-模式 -->
|
||||
|
@ -258,11 +258,11 @@ defineExpose({ trigger })
|
|||
min-width: 15px;
|
||||
// height: 500px;
|
||||
&.like{
|
||||
background-image: linear-gradient(to top, #fef0f0, #f56c6c);
|
||||
background-image: linear-gradient(to top, #d2f0cb, #2f9e44);
|
||||
// animation: striped-flow 5s linear infinite;
|
||||
}
|
||||
&.doubt{
|
||||
background-image: linear-gradient(to top, #fdf6ec, #e6a23c);
|
||||
background-image: linear-gradient(to top, #ebc6c6, #ff0000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue