教学工作台面包屑

This commit is contained in:
lyc 2024-10-31 14:05:24 +08:00
parent da1390a0df
commit 8bc0ab460c
13 changed files with 134 additions and 298 deletions

View File

@ -88,7 +88,7 @@ function createLoginWindow() {
function createMainWindow() { function createMainWindow() {
mainWindow = new BrowserWindow({ mainWindow = new BrowserWindow({
width: 1350, width: 1350,
minWidth: 1200, minWidth: 1370,
height: 700, height: 700,
minHeight: 700, minHeight: 700,
show: false, show: false,

View File

@ -1,8 +1,8 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 4723712 */ font-family: "iconfont"; /* Project id 4723712 */
src: url('iconfont.woff2?t=1730256542457') format('woff2'), src: url('iconfont.woff2?t=1730343912063') format('woff2'),
url('iconfont.woff?t=1730256542457') format('woff'), url('iconfont.woff?t=1730343912063') format('woff'),
url('iconfont.ttf?t=1730256542457') format('truetype'); url('iconfont.ttf?t=1730343912063') format('truetype');
} }
.iconfont { .iconfont {
@ -13,6 +13,18 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-fanhui:before {
content: "\e604";
}
.icon-tianchongxing-:before {
content: "\e641";
}
.icon-daishenhe:before {
content: "\e64c";
}
.icon-A:before { .icon-A:before {
content: "\e6ef"; content: "\e6ef";
} }

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,27 @@
"css_prefix_text": "icon-", "css_prefix_text": "icon-",
"description": "", "description": "",
"glyphs": [ "glyphs": [
{
"icon_id": "26283779",
"name": "返回",
"font_class": "fanhui",
"unicode": "e604",
"unicode_decimal": 58884
},
{
"icon_id": "6446310",
"name": "博士",
"font_class": "tianchongxing-",
"unicode": "e641",
"unicode_decimal": 58945
},
{
"icon_id": "8651682",
"name": "待审核",
"font_class": "daishenhe",
"unicode": "e64c",
"unicode_decimal": 58956
},
{ {
"icon_id": "12688893", "icon_id": "12688893",
"name": "A", "name": "A",

View File

@ -8,8 +8,19 @@
<el-header> <el-header>
<Header/> <Header/>
</el-header> </el-header>
<el-main> <el-main :style="{ 'padding-top' : isShowBread ? 0 : '20px'}">
<AppMain /> <template v-if="isShowBread">
<div class="bread-row">
<div class="back" @click="onBack">
<i class="iconfont icon-fanhui"></i>
<span>返回</span>
</div>
<el-breadcrumb :separator-icon="ArrowRight">
<el-breadcrumb-item v-for="item in breadList"> {{ item.title }} </el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
<AppMain :style="{ height: isShowBread ? 'calc(100% - 45px)' : '100%' }" />
</el-main> </el-main>
</el-container> </el-container>
<Uploader v-if="uploaderStore.uploadList && uploaderStore.uploadList.length > 0" /> <Uploader v-if="uploaderStore.uploadList && uploaderStore.uploadList.length > 0" />
@ -19,7 +30,9 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref, watch } from 'vue'
import { ArrowRight } from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'
import Header from './components/Header.vue' import Header from './components/Header.vue'
import Aside from './components/Aside.vue' import Aside from './components/Aside.vue'
import AppMain from './components/AppMain.vue' import AppMain from './components/AppMain.vue'
@ -29,6 +42,33 @@ import uploaderState from '@/store/modules/uploader'
let uploaderStore = ref(uploaderState()) let uploaderStore = ref(uploaderState())
//
const router = useRouter()
//
const isShowBread = ref(false)
const breadList = ref([])
//
watch(
() => router.currentRoute.value,
(newValue) => {
let ary = newValue.matched.map( item => item.meta)
// ()
if(ary.some(item => item.hasOwnProperty('showBread'))){
isShowBread.value = true
breadList.value = ary
}
else{
isShowBread.value = false
}
},
{ immediate: true }
)
const onBack = () =>{
router.go(-1)
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -45,7 +85,7 @@ let uploaderStore = ref(uploaderState())
height: 45px; height: 45px;
} }
.el-main { .el-main {
--el-main-padding: 20px; --el-main-padding: 0 20px 20px 20px;
box-sizing: border-box; box-sizing: border-box;
} }
.el-page-header{ .el-page-header{
@ -56,4 +96,26 @@ let uploaderStore = ref(uploaderState())
font-size: 16px; font-size: 16px;
} }
} }
.bread-row{
display: flex;
align-items: center;
height: 45px;
padding-top: 5px;
font-size: 14px;
color: #606266;
.back{
display: flex;
align-items: center;
margin-right: 20px;
cursor: pointer;
color: #409EFF;
font-weight: bold;
.icon-fanhui{
margin-top: -3px;
margin-right: 3px;
}
}
}
</style> </style>

View File

@ -19,7 +19,7 @@ export const constantRoutes = [
path: '/fullscreenpdf', path: '/fullscreenpdf',
component: () => import('@/views/fullScreenPdf/index.vue'), component: () => import('@/views/fullScreenPdf/index.vue'),
name: 'fullscreenpdf', name: 'fullscreenpdf',
meta: {title: '全屏显示PDF'} meta: { title: '全屏显示PDF' }
}, },
{ {
path: '/teachClassTask', path: '/teachClassTask',
@ -30,116 +30,111 @@ export const constantRoutes = [
path: '/', path: '/',
component: Layout, component: Layout,
redirect: '/home', redirect: '/home',
meta: { title: '教学工作台' },
children: [ children: [
{ {
path: '/index', path: '/index',
component: () => import('@/views/index/index.vue'), component: () => import('@/views/index/index.vue'),
name: 'index', name: 'index',
meta: {title: '首页'} meta: { title: '首页' }
}, },
{ {
path: '/home', path: '/home',
component: () => import('@/views/desktop/index.vue'), component: () => import('@/views/desktop/index.vue'),
name: 'desktop', name: 'desktop',
meta: {title: '主页'} meta: { title: '教学工作台' }
},
{
path: '/homepage',
component: () => import('@/views/homePage/index.vue'),
name: 'homepage',
meta: {title: '主页'}
}, },
{ {
path: '/resource', path: '/resource',
component: () => import('@/views/resource/index.vue'), component: () => import('@/views/resource/index.vue'),
name: 'resource', name: 'resource',
meta: {title: '资源库'} meta: { title: '资源库' }
}, },
{ {
path: '/prepare', path: 'prepare',
component: () => import('@/views/prepare/index.vue'), component: () => import('@/views/prepare/index.vue'),
name: 'prepare', name: 'prepare',
meta: {title: '教学实践'} meta: { title: '教学实践', showBread: true }
}, },
{ {
path: '/teach', path: '/teach',
component: () => import('@/views/teach/index.vue'), component: () => import('@/views/teach/index.vue'),
name: 'teach', name: 'teach',
meta: {title: '授课'} meta: { title: '授课' }
}, },
{ {
path: '/standardanalysis', path: '/standardanalysis',
component: () => import('@/views/teach/standardAnalysis/index.vue'), component: () => import('@/views/teach/standardAnalysis/index.vue'),
name: 'standardanalysis', name: 'standardanalysis',
meta: {title: '课标分析'} meta: { title: '课标分析', showBread: true }
}, },
{ {
path: '/textbookAnalysis', path: '/textbookAnalysis',
component: () => import('@/views/textbookAnalysis/index.vue'), component: () => import('@/views/textbookAnalysis/index.vue'),
name: 'textbookAnalysis', name: 'textbookAnalysis',
meta: {title: '教材分析'} meta: { title: '教材分析', showBread: true }
}, },
{ {
path: '/profile', path: '/profile',
component: () => import('@/views/profile/index.vue'), component: () => import('@/views/profile/index.vue'),
name: 'profile', name: 'profile',
meta: {title: '个人中心'} meta: { title: '个人中心' }
}, },
{ {
path: '/testpdf', path: '/testpdf',
component: () => import('@/views/testPdf/index.vue'), component: () => import('@/views/testPdf/index.vue'),
name: 'testpdf', name: 'testpdf',
meta: {title: '测试PDF'} meta: { title: '测试PDF' }
}, },
{ {
path: '/classReserv', path: '/classReserv',
component: () => import('@/views/classManage/classReserv.vue'), component: () => import('@/views/classManage/classReserv.vue'),
name: 'classReserv', name: 'classReserv',
meta: {title: '课程预约'} meta: { title: '课程预约' }
}, },
{ {
path: '/class', path: '/class',
component: () => import('@/views/classManage/index.vue'), component: () => import('@/views/classManage/index.vue'),
name: 'class', name: 'class',
meta: {title: '班级中心'}, meta: { title: '班级中心' }
}, },
{ {
path: '/classTaskAssign', path: '/classTaskAssign',
component: () => import('@/views/classTask/classTaskAssign.vue'), component: () => import('@/views/classTask/classTaskAssign.vue'),
name: 'classTaskAssign', name: 'classTaskAssign',
meta: {title: '作业布置'}, meta: { title: '作业布置', showBread: true }
}, },
{ {
path: '/classTask', path: '/classTask',
component: () => import('@/views/classTask/classTask.vue'), component: () => import('@/views/classTask/classTask.vue'),
name: 'classCorrect', name: 'classCorrect',
meta: {title: '作业批改'}, meta: { title: '作业批改', showBread: true }
}, },
{ {
path: '/newClassTask', path: '/newClassTask',
component: () => import('@/views/classTask/newClassTask.vue'), component: () => import('@/views/classTask/newClassTask.vue'),
name: 'newClassCorrect', name: 'newClassCorrect',
meta: {title: '作业设计'}, meta: { title: '作业设计', showBread: true }
}, },
{ {
path: '/examReport', path: '/examReport',
component: () => import('@/views/examReport/index.vue'), component: () => import('@/views/examReport/index.vue'),
name: 'examReport', name: 'examReport',
meta: {title: '考试分析'} meta: { title: '考试分析', showBread: true }
}, },
{ {
path: '/hashrate', path: '/hashrate',
component: () => import('@/views/hashrate/index.vue'), component: () => import('@/views/hashrate/index.vue'),
name: 'hashrate', name: 'hashrate',
meta: {title: '算力'} meta: { title: '算力' }
}, },
{ {
path: '/setting', path: '/setting',
component: () => import('@/views/setting/index.vue'), component: () => import('@/views/setting/index.vue'),
name: 'setting', name: 'setting',
meta: {title: '设置'} meta: { title: '设置' }
}, }
] ]
}, },
...toolRouters ...toolRouters

View File

@ -1,15 +1,10 @@
<template> <template>
<div class="page-classTaskAssign flex"> <div class="page-classTaskAssign flex">
<el-menu
default-active="1" <!--左侧 教材 目录-->
class="el-menu-vertical-demo" <div v-if="!isCollapse" style="height: 100%;overflow: hidden;">
:collapse="isCollapse" <ChooseTextbook @change-book="getData" @node-click="getData" />
> </div>
<!--左侧 教材 目录-->
<div v-if="!isCollapse" style="height: 100%;overflow: hidden;">
<ChooseTextbook @change-book="getData" @node-click="getData" />
</div>
</el-menu>
<div class="page-right" :style="{'margin-left': isCollapse ? '0' : '20px'}"> <div class="page-right" :style="{'margin-left': isCollapse ? '0' : '20px'}">
<!-- 标题 --> <!-- 标题 -->

View File

@ -1,15 +1,11 @@
<template> <template>
<div class="page-newcalsetask flex"> <div class="page-newcalsetask flex">
<el-menu
default-active="1"
class="el-menu-vertical-demo"
:collapse="isCollapse"
>
<!--左侧 教材 目录--> <!--左侧 教材 目录-->
<div v-if="!isCollapse" style="height: 100%;overflow: hidden;"> <div v-if="!isCollapse" style="height: 100%;overflow: hidden;">
<ChooseTextbook @change-book="getData" @node-click="getData" /> <ChooseTextbook @change-book="getData" @node-click="getData" />
</div> </div>
</el-menu>
<div class="page-right" :style="{'margin-left': isCollapse ? '0' : '20px'}"> <div class="page-right" :style="{'margin-left': isCollapse ? '0' : '20px'}">
<!-- 标题 --> <!-- 标题 -->

View File

@ -94,7 +94,7 @@ const menuList = [{
{ {
name: '教学实践', name: '教学实践',
icon: '#icon-jiaoxueshijian', icon: '#icon-jiaoxueshijian',
path: '/prepare', path: 'prepare',
id: '1-5' id: '1-5'
}, },
{ {

View File

@ -1,245 +0,0 @@
<template>
<el-card style="overflow: auto; height: 100%;">
<div class="common-layout" style="overflow-y: auto">
<el-container>
<el-main style="--el-main-padding: 0">
<template v-for="(itemFirst, indexFirst) in title" :key="indexFirst">
<el-card style="margin-bottom: 10px">
<template #header>
<div style="text-align: left">{{ itemFirst.name }}</div>
</template>
<div :class="itemFirst.id === 1 || itemFirst.id === 2 ? 'six' : 'three'">
<template v-for="(itemSec, indexSec) in itemFirst.child" :key="indexSec">
<el-popover :disabled="itemSec.child1.length === 0" width="auto" trigger="hover">
<div style="display: flex; justify-content: space-between">
<!-- 鼠标移上去的一列为三级菜单-->
<template v-for="(itemThird, indexThird) in itemSec.child1" :key="indexThird">
<div
style="width: 120px"
:class="[
itemFirst.id == 1
? 'a1'
: itemFirst.id == 2
? 'a2'
: itemFirst.id == 3
? 'a3'
: 'a4',
'CustomBox'
]"
@click="handleOutLink(itemThird.url)"
>
<span :class="itemThird.img"></span>
<span>{{ itemThird.name }}</span>
</div>
</template>
</div>
<!-- 最外层的一列为二级菜单-->
<template #reference>
<div
:class="[
itemFirst.id == 1
? 'a1'
: itemFirst.id == 2
? 'a2'
: itemFirst.id == 3
? 'a3'
: 'a4',
'CustomBox'
]"
@click="handleOutLink(itemSec.url, itemSec.type)"
>
<span :class="itemSec.img"></span>
<span>{{ itemSec.name }}</span>
</div>
</template>
</el-popover>
</template>
</div>
</el-card>
</template>
</el-main>
</el-container>
</div>
</el-card>
</template>
<script setup>
import { reactive } from 'vue'
import { useRouter } from 'vue-router'
import outLink from '@/utils/linkConfig'
const { ipcRenderer } = window.electron || {}
const router = useRouter()
const title = reactive([
{
name: '教学工作台',
img: 'iconfont icon-gongzuotai',
id: 1,
child: [
{
name: '课程教学',
img: 'iconfont icon-PPT',
type: 'hash',
url: '/prepare',
child1: []
},
{
name: '作业管理',
img: 'iconfont icon-36zuoyepingtai',
url: '/teaching/classtaskassign?titleName=作业布置',
child1: []
}
]
},
{
name: '教学研究室',
img: 'iconfont icon-yanjiushi',
id: 2,
child: [
{
name: '课程研究',
img: 'iconfont icon-shuyi_jiaoxueguanli',
child1: [
{
name: '课标分析',
url: '/teaching/chatwithstandard',
img: 'iconfont icon-kecheng'
},
{
name: '教材分析',
url: '/teaching/chatwithtextbook',
img: 'iconfont icon-yanjiushi'
}
]
},
{
name: '考试分析',
url: '/examReport',
img: 'iconfont icon-icon_kaoshifenxi',
child1: []
},
{
name: '资源研究',
url: '/resource',
type: 'hash',
img: 'iconfont icon-business-report',
child1: []
}
]
},
{
name: '教学资源库',
img: 'iconfont icon-zhuanyeziyuanku',
id: 3,
child: [
{
name: '教学素材',
img: 'iconfont icon-sucai',
url: '/teaching/materialbank',
child1: []
},
{
name: '课程资源',
img: 'iconfont icon-kechengziyuan',
url: '/teaching/coursewareresource',
child1: []
},
{
name: '习题资源',
img: 'iconfont icon-iconku-zhuanqu-',
url: '/teaching/quesbank',
child1: []
}
]
}
])
const handleOutLink = (path, type) => {
if (!path) return
if (type === 'hash') {
router.push(path)
} else {
// key linkConfig.js
let configObj = outLink.getBaseData()
let fullPath = configObj.fullPath + path
fullPath = fullPath.replaceAll('//', '/')
//
ipcRenderer.send('openWindow', {
fullPath: fullPath,
cookieData: { ...configObj.data }
})
}
}
</script>
<style scoped>
.CustomTitle {
margin-bottom: 8px;
font-weight: 600;
display: flex;
align-items: center;
white-space: nowrap;
margin-right: 10px;
cursor: pointer;
}
.CustomTitle span:nth-child(1) {
font-size: 24px;
margin-right: 8px;
color: #7b7a7a;
display: none;
}
.six {
display: flex;
& > div {
width: 20%;
}
}
.three {
display: flex;
& > div {
width: 20%;
}
}
.CustomBox span:nth-child(1) {
display: flex;
width: 60px;
justify-content: center;
height: 60px;
background-color: #ebe9e9;
border-radius: 50%;
align-items: center;
font-size: 32px;
margin-bottom: 6px;
}
.CustomBox {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: pointer;
}
.CustomBox span:nth-child(2) {
font-size: 18px;
}
.CustomBox div {
display: flex;
flex-direction: column;
align-items: center;
}
.a1 span:nth-child(1) {
color: #1296db;
}
.a2 span:nth-child(1) {
color: #f56c6c;
}
.a3 span:nth-child(1) {
color: #e6a23a;
}
.a4 span:nth-child(1) {
color: #67c23a;
}
.ac span:nth-child(1) {
background-color: #1296db;
color: #ffffff;
}
</style>