334 lines
10 KiB
Vue

<template>
<div class="course-editor">
<!-- 左侧导航菜单 -->
<div class="sidebar" v-if="!hideSidebar">
<router-link :to="`/teacher/course-editor/${courseId}/courseware`" class="menu-item"
:class="{ active: $route.path.includes('courseware') }">
<img :src="$route.path.includes('courseware') ? '/images/teacher/课件-选中.png' : '/images/teacher/课件.png'"
alt="资源库" />
<span>资源库</span>
</router-link>
<router-link :to="`/teacher/course-editor/${courseId}/chapters`" class="menu-item"
:class="{ active: $route.path.includes('chapters') }">
<img :src="$route.path.includes('chapters') ? '/images/teacher/章节-选中.png' : '/images/teacher/章节.png'"
alt="章节" />
<span>章节</span>
</router-link>
<!-- 作业二级导航 -->
<div class="menu-group">
<div class="menu-header" @click="toggleHomework">
<img src="/images/teacher/作业.png" alt="作业" />
<span>作业</span>
<i class="n-base-icon" :class="{ expanded: homeworkExpanded || shouldExpandHomework }">
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M5.64645 3.14645C5.45118 3.34171 5.45118 3.65829 5.64645 3.85355L9.79289 8L5.64645 12.1464C5.45118 12.3417 5.45118 12.6583 5.64645 12.8536C5.84171 13.0488 6.15829 13.0488 6.35355 12.8536L10.8536 8.35355C11.0488 8.15829 11.0488 7.84171 10.8536 7.64645L6.35355 3.14645C6.15829 2.95118 5.84171 2.95118 5.64645 3.14645Z"
fill="#C2C2C2" />
</svg>
</i>
</div>
<div class="submenu" v-show="homeworkExpanded || shouldExpandHomework">
<router-link :to="`/teacher/course-editor/${courseId}/homework/library`" class="submenu-item"
:class="{ active: $route.path.includes('/homework/library') || $route.path.includes('/homework/add-homework') }">
<span>作业库</span>
</router-link>
<router-link :to="`/teacher/course-editor/${courseId}/homework/review`" class="submenu-item"
:class="{ active: $route.path.includes('/homework/review') }">
<span>批阅作业</span>
</router-link>
</div>
</div>
<!-- 练考通二级导航 -->
<div class="menu-group">
<div class="menu-header" @click="togglePractice">
<img src="/images/teacher/练考通.png" alt="练考通" />
<span>考试管理</span>
<i class="n-base-icon" :class="{ expanded: practiceExpanded }">
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M5.64645 3.14645C5.45118 3.34171 5.45118 3.65829 5.64645 3.85355L9.79289 8L5.64645 12.1464C5.45118 12.3417 5.45118 12.6583 5.64645 12.8536C5.84171 13.0488 6.15829 13.0488 6.35355 12.8536L10.8536 8.35355C11.0488 8.15829 11.0488 7.84171 10.8536 7.64645L6.35355 3.14645C6.15829 2.95118 5.84171 2.95118 5.64645 3.14645Z"
fill="#C2C2C2" />
</svg>
</i>
</div>
<div class="submenu" v-show="practiceExpanded">
<router-link :to="`/teacher/course-editor/${courseId}/practice/exam`" class="submenu-item"
:class="{ active: $route.path.includes('/practice/exam') }">
<span>试卷管理</span>
</router-link>
<router-link :to="`/teacher/course-editor/${courseId}/practice/review`" class="submenu-item"
:class="{ active: $route.path.includes('/practice/review') }">
<span>阅卷中心</span>
</router-link>
</div>
</div>
<!-- <router-link :to="`/teacher/course-editor/${courseId}/question-bank`" class="menu-item"
:class="{ active: $route.path.includes('question-bank') }">
<img :src="$route.path.includes('question-bank') ? '/images/teacher/题库-选中.png' : '/images/teacher/题库.png'"
alt="题库" />
<span>题库</span>
</router-link> -->
<router-link :to="`/teacher/course-editor/${courseId}/certificate`" class="menu-item"
:class="{ active: $route.path.includes('certificate') }">
<img :src="$route.path.includes('certificate') ? '/images/teacher/证书-选中.png' : '/images/teacher/证书.png'"
alt="证书" />
<span>证书</span>
</router-link>
<router-link :to="`/teacher/course-editor/${courseId}/discussion`" class="menu-item"
:class="{ active: $route.path.includes('discussion') }">
<img :src="$route.path.includes('discussion') ? '/images/teacher/讨论-选中.png' : '/images/teacher/讨论.png'"
alt="讨论" />
<span>讨论</span>
</router-link>
<router-link :to="`/teacher/course-editor/${courseId}/statistics`" class="menu-item"
:class="{ active: $route.path.includes('statistics') }">
<img :src="$route.path.includes('statistics') ? '/images/teacher/统计-选中.png' : '/images/teacher/统计.png'"
alt="统计" />
<span>统计</span>
</router-link>
<!-- <router-link :to="`/teacher/course-editor/${courseId}/notification`" class="menu-item"
:class="{ active: $route.path.includes('notification') }">
<img :src="$route.path.includes('notification') ? '/images/teacher/通知-选中.png' : '/images/teacher/通知.png'"
alt="通知" />
<span>通知</span>
</router-link> -->
<router-link :to="`/teacher/course-editor/${courseId}/management`" class="menu-item"
:class="{ active: $route.path.includes('management') }">
<img :src="$route.path.includes('management') ? '/images/teacher/管理-选中.png' : '/images/teacher/管理.png'"
alt="管理" />
<span>管理</span>
</router-link>
</div>
<!-- 右侧内容区域 -->
<div class="content-area" :class="{ 'full-width': hideSidebar }">
<router-view v-slot="{ Component, route }">
<transition name="content-transition" mode="out-in" appear>
<component :is="Component" :key="route.path" class="content-component" />
</transition>
</router-view>
</div>
</div>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router'
import { ref, computed } from 'vue'
const route = useRoute()
// 获取课程ID
const courseId = route.params.id
// 作业菜单展开状态
const homeworkExpanded = ref(false)
// 根据当前路由自动展开作业菜单
const shouldExpandHomework = computed(() => {
return route.path.includes('/homework/')
})
// 切换作业菜单展开/收起
const toggleHomework = () => {
homeworkExpanded.value = !homeworkExpanded.value
}
// 练考通菜单展开状态
const practiceExpanded = ref(false)
// 切换练考通菜单展开/收起
const togglePractice = () => {
practiceExpanded.value = !practiceExpanded.value
}
// 判断是否隐藏左侧导航
const hideSidebar = computed(() => {
const currentPath = route.path
// 定义需要隐藏侧边栏的页面路径
const hideSidebarPaths = [
'add-question', // 新增试题页面
'add-homework', // 添加作业页面
'template-import',
'review/',
'certificate/detail/',
'certificate/add'
]
// 检查当前路径是否包含需要隐藏侧边栏的路径
return hideSidebarPaths.some(path => currentPath.includes(path))
})
</script>
<style scoped>
.course-editor {
display: flex;
margin-top: 5px;
height: 100vh;
background: #f5f5f5;
}
/* 左侧导航 */
.sidebar {
width: 220px;
background: #fff;
border-right: 1px solid #e8e8e8;
padding: 20px 15px;
margin-right: 5px;
}
/* 右侧内容区域 */
.content-area {
flex: 1;
overflow: auto;
}
/* 全宽显示(隐藏侧边栏的页面) */
.content-area.full-width {
width: 100%;
margin-left: 0;
}
.menu-item {
display: flex;
align-items: center;
padding: 12px 15px;
margin-bottom: 5px;
cursor: pointer;
transition: all 0.3s ease;
border-left: 3px solid transparent;
text-decoration: none;
color: inherit;
font-size: 16px;
color: #666;
border-radius: 5px;
}
.menu-item:hover {
background: #f5f5f5;
}
.menu-item.active {
background: #F5F8FB;
color: #0288D1;
}
.menu-item.active span {
color: #0288D1;
}
.menu-item img {
margin-left: 30px;
margin-top: 1px;
width: 16px;
height: 16px;
margin-right: 14px;
}
.menu-item span {
font-size: 16px;
color: #666;
}
/* 作业二级导航样式 */
.menu-group {
margin-bottom: 5px;
}
.menu-header {
display: flex;
align-items: center;
padding: 12px 15px;
margin-bottom: 5px;
cursor: pointer;
transition: all 0.3s ease;
border-left: 3px solid transparent;
font-size: 16px;
color: #666;
border-radius: 5px;
}
.menu-header:hover {
background: #f5f5f5;
}
.menu-header img {
margin-left: 30px;
margin-top: 1px;
width: 16px;
height: 16px;
margin-right: 14px;
}
.menu-header span {
font-size: 16px;
color: #666;
}
.menu-header .n-base-icon {
margin-left: auto;
transition: transform 0.3s ease;
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
}
.menu-header .n-base-icon svg {
width: 16px;
height: 16px;
transition: transform 0.3s ease;
}
.menu-header .n-base-icon.expanded svg {
transform: rotate(90deg);
}
.submenu-item {
display: block;
padding: 12px 15px;
margin-bottom: 3px;
text-decoration: none;
color: #666;
font-size: 14px;
border-radius: 3px;
transition: all 0.3s ease;
text-align: center;
}
.submenu-item:hover {
background: #f0f8ff;
color: #0288D1;
}
.submenu-item.active {
background: #e6f7ff;
color: #0288D1;
}
/* 内容区域过渡动画 */
.content-transition-enter-active,
.content-transition-leave-active {
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.content-transition-enter-from {
opacity: 0;
transform: translateX(20px);
}
.content-transition-leave-to {
opacity: 0;
transform: translateX(-20px);
}
.content-transition-enter-to,
.content-transition-leave-from {
opacity: 1;
transform: translateX(0);
}
.content-component {
width: 100%;
}
</style>