1175 lines
31 KiB
Vue
Raw Normal View History

2025-08-20 14:10:48 +08:00
<template>
<div class="admin-dashboard">
<!-- 顶部图片 -->
<div class="top-image-container" v-if="showTopImage">
2025-08-21 19:39:07 +08:00
<img src="/images/teacher/顶部.png" alt="顶部图片" class="top-image">
<button class="close-button" @click="handleClose">关闭</button>
2025-08-21 19:39:07 +08:00
</div>
2025-08-20 14:10:48 +08:00
<div class="main-content">
<!-- 侧边栏 -->
2025-08-25 10:39:24 +08:00
<div class="sidebar-container" v-if="!hideSidebar">
2025-08-21 19:39:07 +08:00
<!-- 头像 -->
<div class="avatar-container">
2025-09-11 14:34:30 +08:00
<img :src="userStore.user?.avatar" :alt="userStore.user?.profile?.realName || userStore.user?.nickname || userStore.user?.username" class="avatar">
2025-08-21 19:39:07 +08:00
<div class="avatar-text">
2025-09-11 14:34:30 +08:00
{{ userStore.user?.profile?.realName || userStore.user?.nickname || userStore.user?.username }}
2025-08-21 19:39:07 +08:00
</div>
</div>
<!-- 导航栏 -->
<div class="nav-container">
<router-link to="/teacher/course-management" class="nav-item" :class="{ active: activeNavItem === 0 }"
@click="setActiveNavItem(0)">
<img :src="activeNavItem === 0 ? '/images/teacher/课程管理(选中).png' : '/images/teacher/课程管理.png'" alt="">
<span>课程管理</span>
</router-link>
<!-- 考试管理 - 可展开菜单 -->
<div class="nav-item" :class="{ active: activeNavItem === 4 }" @click="toggleExamMenu">
<img
:src="activeNavItem === 4 ? '/images/teacher/examination-active.png' : '/images/teacher/examination.png'"
alt="">
<span>考试管理</span>
<n-icon class="expand-icon" :class="{ expanded: examMenuExpanded }">
<ChevronDownOutline />
</n-icon>
</div>
2025-08-25 18:28:46 +08:00
<!-- 考试管理子菜单 -->
<div class="submenu-container" :class="{ expanded: examMenuExpanded }">
<router-link to="/teacher/exam-management/question-bank" class="submenu-item"
:class="{ active: activeSubNavItem === 'question-bank' }" @click="setActiveSubNavItem('question-bank')">
<span>题库管理</span>
</router-link>
2025-08-25 18:28:46 +08:00
<router-link to="/teacher/exam-management/exam-library" class="submenu-item"
:class="{ active: activeSubNavItem === 'exam-library' }" @click="setActiveSubNavItem('exam-library')">
<span>试卷管理</span>
</router-link>
<router-link to="/teacher/exam-management/marking-center/list" class="submenu-item"
2025-08-25 18:28:46 +08:00
:class="{ active: activeSubNavItem === 'marking-center' }" @click="setActiveSubNavItem('marking-center')">
<span>阅卷中心</span>
</router-link>
</div>
<!-- 学员中心 - 可展开菜单 -->
2025-09-11 14:34:30 +08:00
<div class="nav-item" :class="{ active: activeNavItem === 1 }" @click="toggleStudentMenu('/teacher/student-management/student-library')">
2025-08-21 19:39:07 +08:00
<img :src="activeNavItem === 1 ? '/images/teacher/学院管理(选中).png' : '/images/teacher/学员管理.png'" alt="">
<span>学员中心</span>
<n-icon class="expand-icon" :class="{ expanded: studentMenuExpanded }">
<ChevronDownOutline />
</n-icon>
</div>
<!-- 学员中心子菜单 -->
<div class="submenu-container" :class="{ expanded: studentMenuExpanded }">
<router-link to="/teacher/student-management/student-library" class="submenu-item"
:class="{ active: activeSubNavItem === 'student-library' }"
@click="setActiveSubNavItem('student-library')">
<span>学员库</span>
</router-link>
<router-link to="/teacher/student-management/class-management" class="submenu-item"
:class="{ active: activeSubNavItem === 'class-management' }"
@click="setActiveSubNavItem('class-management')">
<span>班级管理</span>
</router-link>
</div>
2025-08-21 19:39:07 +08:00
<router-link to="/teacher/my-resources" class="nav-item" :class="{ active: activeNavItem === 2 }"
@click="setActiveNavItem(2)">
<img :src="activeNavItem === 2 ? '/images/teacher/我的资源(选中).png' : '/images/teacher/我的资源.png'" alt="">
<span>我的资源</span>
</router-link>
<router-link to="/teacher/message-center" class="nav-item" :class="{ active: activeNavItem === 5 }"
@click="setActiveNavItem(5)">
2025-09-11 14:34:30 +08:00
<img :src="activeNavItem === 5 ? '/images/profile/message-active.png' : '/images/profile/message.png'" alt="">
<span>消息中心</span>
</router-link>
2025-08-21 19:39:07 +08:00
<router-link to="/teacher/personal-center" class="nav-item" :class="{ active: activeNavItem === 3 }"
@click="setActiveNavItem(3)">
<img :src="activeNavItem === 3 ? '/images/teacher/个人中心(选中).png' : '/images/teacher/个人中心.png'" alt="">
<span>个人中心</span>
</router-link>
</div>
<!-- ai助教 -->
<div class="ai-container">
<router-link to="/teacher/ai-assistant" class="ai-tab" @mouseenter="isAiHovered = true"
@mouseleave="isAiHovered = false">
<img :src="(isAiActive || isAiHovered) ? '/images/aiAssistant/AI助教1.png' : '/images/aiAssistant/AI助教2.png'"
alt="ai" />
<span>AI助教</span>
</router-link>
</div>
2025-08-20 14:10:48 +08:00
</div>
<!-- 右侧路由视图 -->
2025-08-25 10:39:24 +08:00
<div class="router-view-container" :class="{ 'full-width': hideSidebar }">
2025-08-20 14:10:48 +08:00
<!-- 面包屑 -->
<div class="breadcrumb" v-if="breadcrumbDisplay">
<span class="breadcrumb-side"></span>
2025-08-25 18:28:46 +08:00
<div class="custom-breadcrumb">
<!-- 左侧课程管理 -->
<span class="breadcrumb-item clickable first-item"
@click="handleBreadcrumbClick('/teacher/course-management')">课程管理</span>
<!-- 右侧路径 -->
<div class="breadcrumb-path">
<span v-for="(item, index) in breadcrumbPathItems" :key="index" class="breadcrumb-item" :class="{
'clickable': index < breadcrumbPathItems.length - 1,
'last-item': index === breadcrumbPathItems.length - 1
}" @click="index < breadcrumbPathItems.length - 1 ? handleBreadcrumbClick(item.path) : null">
{{ item.title }}
<span v-if="index < breadcrumbPathItems.length - 1" class="breadcrumb-separator"> > </span>
</span>
</div>
2025-08-25 18:28:46 +08:00
</div>
2025-08-20 14:10:48 +08:00
</div>
<router-view></router-view>
</div>
</div>
</div>
</template>
<script setup lang="ts">
// @ts-nocheck
import { ref, onMounted, computed, watch, nextTick } from 'vue'
2025-08-25 10:39:24 +08:00
import { useRoute, useRouter } from 'vue-router'
import { ChevronDownOutline } from '@vicons/ionicons5'
2025-09-11 14:34:30 +08:00
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
2025-08-20 14:10:48 +08:00
const width = window.innerWidth;
const height = window.innerHeight;
console.log(`当前屏幕宽度: ${width}px, 高度: ${height}px`);
// 添加导航项激活状态管理
const activeNavItem = ref(0); // 0: 课程管理, 1: 学员管理, 2: 我的资源, 3: 个人中心, 4: 考试管理, 5: 消息中心
const activeSubNavItem = ref(''); // 子菜单激活状态
const examMenuExpanded = ref(false); // 考试管理菜单展开状态
const studentMenuExpanded = ref(false); // 学员中心菜单展开状态
const showTopImage = ref(true); // 控制顶部图片显示/隐藏
// 需要隐藏顶部图片的路由路径数组
const hideTopImageRoutes = [
'teacher/chapter-editor-teacher',
'teacher/course-editor'
// 可以在这里添加更多需要隐藏顶部图片的路由
];
2025-08-20 14:10:48 +08:00
const route = useRoute();
2025-08-25 10:39:24 +08:00
const router = useRouter();
const isAiHovered = ref(false);
const isAiActive = computed(() => route.path.includes('/teacher/ai-assistant'));
const breadcrumbDisplay = computed(() => {
const currentPath = route.path;
let arr = ['certificate/new', 'ai-assistant'];
let found = arr.find(item => currentPath.includes(item));
if (found) {
return false;
}
return true;
});
2025-08-20 14:10:48 +08:00
const setActiveNavItem = (index: number) => {
activeNavItem.value = index;
// 如果不是考试管理,关闭考试管理子菜单
if (index !== 4) {
examMenuExpanded.value = false;
}
// 如果不是学员中心,关闭学员中心子菜单
if (index !== 1) {
studentMenuExpanded.value = false;
}
// 如果切换到其他菜单,清空子菜单选中状态
if (index !== 4 && index !== 1) {
activeSubNavItem.value = '';
}
}
// 考试管理菜单切换
const toggleExamMenu = () => {
examMenuExpanded.value = !examMenuExpanded.value;
activeNavItem.value = 4;
2025-08-25 18:28:46 +08:00
// 如果展开且没有选中子菜单,默认选中第一个
if (examMenuExpanded.value && !activeSubNavItem.value) {
activeSubNavItem.value = 'question-management';
}
}
// 学员中心菜单切换
2025-09-11 14:34:30 +08:00
const toggleStudentMenu = (path: string) => {
studentMenuExpanded.value = !studentMenuExpanded.value;
activeNavItem.value = 1;
// 如果展开且没有选中子菜单,默认选中第一个
if (studentMenuExpanded.value && !activeSubNavItem.value) {
activeSubNavItem.value = 'student-library';
2025-09-11 14:34:30 +08:00
router.push(path);
}
}
// 设置子菜单激活状态
const setActiveSubNavItem = (subItem: string) => {
activeSubNavItem.value = subItem;
// 根据子菜单项判断属于哪个主菜单
if (subItem === 'question-bank' || subItem === 'exam-library' || subItem === 'marking-center') {
// 考试管理子菜单
activeNavItem.value = 4;
examMenuExpanded.value = true;
} else if (subItem === 'student-library' || subItem === 'class-management') {
// 学员中心子菜单
activeNavItem.value = 1;
studentMenuExpanded.value = true;
}
2025-08-20 14:10:48 +08:00
}
2025-08-25 10:39:24 +08:00
// 处理面包屑点击
const handleBreadcrumbClick = (path: string) => {
console.log('面包屑点击,跳转到:', path);
router.push(path);
}
// 处理关闭按钮点击
const handleClose = () => {
console.log('关闭按钮被点击');
showTopImage.value = false; // 隐藏顶部图片容器
// 动态更新CSS变量让侧边栏占满全高
nextTick(() => {
document.documentElement.style.setProperty('--top-height', '0px');
});
}
2025-08-25 10:39:24 +08:00
// 判断是否隐藏左侧侧边栏
const hideSidebar = computed(() => {
const currentPath = route.path
2025-08-25 18:28:46 +08:00
// 当进入课程管理相关页面或章节编辑页面时隐藏侧边栏
return currentPath.includes('course-editor') || currentPath.includes('chapter-editor-teacher') || currentPath.includes('certificate')
2025-08-25 10:39:24 +08:00
})
// 动态生成面包屑路径项(右侧部分)
const breadcrumbPathItems = computed(() => {
2025-08-25 10:39:24 +08:00
const currentPath = route.path;
2025-08-21 19:39:07 +08:00
// 证书管理模块的面包屑逻辑(优先处理)
if (currentPath.includes('certificate')) {
console.log('证书页面路径:', currentPath);
let breadcrumbs: Array<{ title: string, path: string }> = [];
// 从路径中提取课程ID如果路径包含course-editor
const courseIdMatch = currentPath.match(/\/course-editor\/(\d+)/);
const courseId = courseIdMatch ? courseIdMatch[1] : '1';
if (currentPath.includes('/certificate/detail/')) {
console.log('匹配到证书详情页面');
// 证书详细页面:课程管理 > 证书 > 证书详情
breadcrumbs = [
{
title: '课程管理',
path: '/teacher/course-management'
},
{
title: '证书管理',
path: `/teacher/course-editor/${courseId}/certificate`
},
{
title: '证书详情',
path: currentPath
}
];
} else if (currentPath.includes('/certificate/add')) {
console.log('匹配到添加证书页面');
// 添加证书页面:课程管理 > 证书 > 添加证书
breadcrumbs = [
{
title: '课程管理',
path: '/teacher/course-management'
},
{
title: '证书管理',
path: `/teacher/course-editor/${courseId}/certificate`
},
{
title: '添加证书',
path: currentPath
}
];
} else if (currentPath.endsWith('/certificate')) {
console.log('匹配到证书管理页面');
// 证书管理页面:课程管理 > 证书
breadcrumbs = [
{
title: '课程管理',
path: '/teacher/course-management'
},
{
title: '证书',
path: `/teacher/course-editor/${courseId}/certificate`
}
];
} else {
console.log('证书页面但未匹配到具体条件');
}
console.log('证书页面面包屑:', breadcrumbs);
return breadcrumbs;
}
// 如果在课程编辑器相关页面
2025-08-25 10:39:24 +08:00
if (currentPath.includes('course-editor')) {
2025-08-25 18:28:46 +08:00
// 从路径中提取课程ID
const courseIdMatch = currentPath.match(/\/course-editor\/(\d+)/);
const courseId = courseIdMatch ? courseIdMatch[1] : '未知';
let breadcrumbs: Array<{ title: string, path: string }> = [];
2025-08-25 10:39:24 +08:00
// 根据当前路径添加子页面标题
if (currentPath.includes('courseware')) {
2025-08-25 18:28:46 +08:00
breadcrumbs.push(
{
title: '课件管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
2025-08-25 10:39:24 +08:00
} else if (currentPath.includes('question-bank')) {
2025-08-25 18:28:46 +08:00
breadcrumbs.push(
{
title: '题库管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
2025-08-25 10:39:24 +08:00
} else if (currentPath.includes('add-question')) {
breadcrumbs.push(
{
title: '题库管理',
path: currentPath.replace('/add-question', '/question-bank')
},
2025-08-25 18:28:46 +08:00
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
},
2025-08-25 10:39:24 +08:00
{
title: '新增试题',
path: currentPath
}
);
} else if (currentPath.includes('chapters')) {
2025-08-25 18:28:46 +08:00
breadcrumbs.push(
{
title: '章节管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
} else if (currentPath.includes('template-import')) {
2025-08-25 18:28:46 +08:00
breadcrumbs.push(
{
title: '课程管理',
path: '/teacher/course-management'
2025-08-25 18:28:46 +08:00
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
},
2025-08-25 18:28:46 +08:00
{
title: '作业管理',
path: `/teacher/course-editor/${courseId}/homework`
2025-08-25 18:28:46 +08:00
},
{
title: '导入',
path: currentPath
2025-08-25 18:28:46 +08:00
}
);
} else if (currentPath.includes('homework')) {
// 检查是否是批阅作业详情页面
if (currentPath.includes('review/') && currentPath.split('/').length > 6) {
// 批阅作业详情页面:课程管理 > 课程名称 > 批阅作业 > 批阅
breadcrumbs.push(
{
title: '课程管理',
path: '/teacher/course-management'
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
},
{
title: '批阅作业',
path: `/teacher/course-editor/${courseId}/homework/review`
},
{
title: '批阅',
path: currentPath
}
);
} else {
// 普通作业页面:作业管理
breadcrumbs.push(
{
title: '作业管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
}
} else if (currentPath.includes('practice/exam')) {
2025-08-25 18:28:46 +08:00
breadcrumbs.push(
{
title: '考试管理',
2025-08-25 18:28:46 +08:00
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
} else if (currentPath.includes('practice/review')) {
2025-08-25 18:28:46 +08:00
breadcrumbs.push(
{
title: '阅卷中心',
2025-08-25 18:28:46 +08:00
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
2025-08-25 10:39:24 +08:00
} else if (currentPath.includes('certificate')) {
2025-08-25 18:28:46 +08:00
breadcrumbs.push(
{
title: '课程管理',
path: '/teacher/course-management'
},
2025-08-25 18:28:46 +08:00
{
title: '证书管理',
path: '/teacher/course-editor/1/certificate'
2025-08-25 18:28:46 +08:00
},
{
title: '证书名称详情',
path: currentPath
2025-08-25 18:28:46 +08:00
}
);
} else if (currentPath.includes('discussion/add')) {
// 添加讨论页面:课程管理 > 讨论 > 添加讨论
breadcrumbs.push(
{
title: '课程管理',
path: '/teacher/course-management'
},
{
title: '讨论',
path: `/teacher/course-editor/${courseId}/discussion`
},
{
title: '添加讨论',
path: currentPath
}
);
2025-08-25 10:39:24 +08:00
} else if (currentPath.includes('discussion')) {
2025-08-25 18:28:46 +08:00
breadcrumbs.push(
{
title: '讨论管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
} else if (currentPath.includes('comment/')) {
// 查看评论页面:课程管理 > 讨论 > 查看讨论
breadcrumbs.push(
{
title: '课程管理',
path: '/teacher/course-management'
},
{
title: '讨论',
path: `/teacher/course-editor/${courseId}/discussion`
},
{
title: '查看讨论',
path: currentPath
}
);
2025-08-25 10:39:24 +08:00
} else if (currentPath.includes('statistics')) {
2025-08-25 18:28:46 +08:00
breadcrumbs.push(
{
title: '统计管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
2025-08-25 10:39:24 +08:00
} else if (currentPath.includes('notification')) {
2025-08-25 18:28:46 +08:00
breadcrumbs.push(
{
title: '通知管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
2025-08-25 10:39:24 +08:00
} else if (currentPath.includes('management')) {
2025-08-25 18:28:46 +08:00
breadcrumbs.push(
{
title: '综合管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
2025-08-25 10:39:24 +08:00
}
console.log('课程编辑器页面面包屑:', breadcrumbs);
return breadcrumbs;
}
2025-08-25 18:28:46 +08:00
// 如果在章节编辑页面,显示课程管理>课程管理>课程名称>章节>章节名称 格式
if (currentPath.includes('chapter-editor-teacher')) {
const courseId = route.params.courseId;
let breadcrumbs = [
{
title: '课程管理',
path: '/teacher/course-management'
},
{
title: '课程管理',
path: '/teacher/course-management'
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
},
{
title: '章节',
path: `/teacher/course-editor/${courseId}/chapters`
},
{
title: '章节名称',
path: currentPath
}
];
console.log('章节编辑页面面包屑:', breadcrumbs);
return breadcrumbs;
}
// 学员管理模块的面包屑逻辑
if (currentPath.includes('student-management')) {
console.log('学员管理页面路径:', currentPath);
let breadcrumbs: Array<{ title: string, path: string }> = [];
if (currentPath.includes('student-library')) {
console.log('匹配到学员库页面');
breadcrumbs = [
{
title: '学员中心',
path: '/teacher/student-management'
},
{
title: '学员库',
path: '/teacher/student-management/student-library'
}
];
} else if (currentPath.includes('class-management')) {
console.log('匹配到班级管理页面');
breadcrumbs = [
{
title: '学员中心',
path: '/teacher/student-management'
},
{
title: '班级管理',
path: '/teacher/student-management/class-management'
}
];
} else if (currentPath.endsWith('/student-management')) {
console.log('匹配到学员管理主页面');
breadcrumbs = [
{
title: '学员中心',
path: '/teacher/student-management'
}
];
}
console.log('学员管理页面面包屑:', breadcrumbs);
return breadcrumbs;
}
// 回收站页面的面包屑逻辑
if (currentPath.includes('recycle-bin')) {
const breadcrumbs = [
{
title: '我的资源',
path: '/teacher/my-resources'
},
{
title: '回收站',
path: currentPath
}
]
return breadcrumbs;
}
2025-08-25 10:39:24 +08:00
// 其他页面的面包屑逻辑
const matchedRoutes = route.matched;
2025-08-24 18:20:16 +08:00
let breadcrumbs = matchedRoutes
2025-08-25 10:39:24 +08:00
.filter((item: any) => item.meta.title !== '管理后台')
.map((item: any) => ({
2025-08-20 14:10:48 +08:00
title: item.meta.title || '未知页面',
path: item.path
}));
2025-08-24 18:20:16 +08:00
2025-08-25 10:39:24 +08:00
console.log('其他页面面包屑:', breadcrumbs);
2025-08-24 18:20:16 +08:00
return breadcrumbs;
2025-08-20 14:10:48 +08:00
});
// 监听路由变化,更新激活的导航项
onMounted(() => {
// 初始设置
updateActiveNavItem();
// 初始化CSS变量
if (showTopImage.value) {
document.documentElement.style.setProperty('--top-height', '130px');
} else {
document.documentElement.style.setProperty('--top-height', '0px');
}
updateTopImageVisibility();
2025-08-20 14:10:48 +08:00
});
// 使用watch监听路由变化
2025-08-20 22:30:37 +08:00
watch(route, () => {
2025-08-20 14:10:48 +08:00
updateActiveNavItem();
updateTopImageVisibility();
2025-08-20 14:10:48 +08:00
});
// 更新顶部图片显示状态
const updateTopImageVisibility = () => {
const currentPath = route.path;
console.log('检查路径是否需要隐藏顶部图片:', currentPath);
// 检查当前路径是否包含需要隐藏顶部图片的路由
const shouldHideTopImage = hideTopImageRoutes.some(routePath =>
currentPath.includes(routePath)
);
showTopImage.value = !shouldHideTopImage;
console.log('顶部图片显示状态:', showTopImage.value);
};
2025-08-20 14:10:48 +08:00
// 更新激活的导航项
const updateActiveNavItem = () => {
const path = route.path;
console.log('当前路径:', path); // 添加调试信息
2025-08-20 14:10:48 +08:00
if (path.includes('course-management')) {
2025-08-21 19:39:07 +08:00
activeNavItem.value = 0; // 课程管理
2025-08-20 14:10:48 +08:00
} else if (path.includes('student-management')) {
2025-08-21 19:39:07 +08:00
activeNavItem.value = 1; // 学员管理
studentMenuExpanded.value = true;
// 根据路径设置子菜单激活状态
if (path.includes('student-library')) {
activeSubNavItem.value = 'student-library';
} else if (path.includes('class-management')) {
activeSubNavItem.value = 'class-management';
}
2025-08-20 14:10:48 +08:00
} else if (path.includes('my-resources')) {
2025-08-21 19:39:07 +08:00
activeNavItem.value = 2; // 我的资源
2025-08-20 14:10:48 +08:00
} else if (path.includes('personal-center')) {
2025-08-21 19:39:07 +08:00
activeNavItem.value = 3; // 个人中心
} else if (path.includes('exam-management')) {
activeNavItem.value = 4; // 考试管理
examMenuExpanded.value = true;
const arr = ['question-bank', 'exam-library', 'marking-center'];
const found = arr.find(item => path.includes(item));
activeSubNavItem.value = found || '';
} else if (path.includes('message-center')) {
activeNavItem.value = 5; // 消息中心
} else if (path.includes('ai-assistant')) {
// AI助教页面清空所有导航项选中状态
console.log('检测到AI助教页面清空导航选中状态');
activeNavItem.value = -1;
activeSubNavItem.value = '';
examMenuExpanded.value = false;
studentMenuExpanded.value = false;
2025-08-20 14:10:48 +08:00
}
}
</script>
<style scoped>
.top-image-container {
position: relative;
width: 100%;
height: 130px;
overflow: hidden;
}
/* 关闭按钮样式 */
.close-button {
position: absolute;
top: 0;
right: 15px;
width: 30px;
height: 20px;
background-color: #7192DC;
color: white;
border: none;
font-size: 10px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
transition: background-color 0.3s ease;
}
.close-button:hover {
background-color: #999999;
}
/* 展开图标样式 */
.expand-icon {
margin-left: auto;
margin-right: 20px;
transition: transform 0.3s ease;
color: #666;
}
.expand-icon.expanded {
transform: rotate(180deg);
}
/* 子菜单容器 */
.submenu-container {
overflow: hidden;
max-height: 0;
transition: max-height 0.3s ease-out;
margin-left: 20px;
}
.submenu-container.expanded {
max-height: 200px;
}
/* 子菜单项样式 */
.submenu-item {
display: flex;
align-items: center;
height: 40px;
margin-bottom: 8px;
margin-left: 10px;
margin-right: 10px;
padding-left: 40px;
border-radius: 8px;
transition: all 0.3s ease;
text-decoration: none;
color: #666;
font-size: 16px;
position: relative;
}
.submenu-item:hover {
background: rgba(102, 183, 227, 0.05);
}
.submenu-item.active {
background: rgba(102, 183, 227, 0.1);
color: #0C99DA;
}
2025-08-22 19:52:05 +08:00
/* 响应式调整 */
@media screen and (max-width: 768px) {
.top-image-container {
height: 100px;
}
}
@media screen and (max-width: 480px) {
.top-image-container {
height: 80px;
}
}
2025-08-20 14:10:48 +08:00
.top-image {
2025-08-22 19:52:05 +08:00
width: 100%;
height: 100%;
2025-08-20 14:10:48 +08:00
position: absolute;
left: 0px;
2025-08-22 19:52:05 +08:00
top: 0px;
2025-08-20 14:10:48 +08:00
opacity: 100%;
object-fit: cover;
}
.main-content {
display: flex;
}
2025-08-22 19:52:05 +08:00
@media screen and (max-width: 768px) {
.main-content {
flex-direction: column;
}
2025-08-25 10:39:24 +08:00
2025-08-22 19:52:05 +08:00
.sidebar-container {
width: 100%;
height: auto;
min-height: 300px;
}
2025-08-25 10:39:24 +08:00
2025-08-22 19:52:05 +08:00
.router-view-container {
height: auto;
min-height: calc(100vh - var(--top-height, 100px) - 300px);
}
}
2025-08-21 19:39:07 +08:00
.sidebar-container {
2025-08-23 19:20:14 +08:00
width: 240px;
2025-08-22 19:52:05 +08:00
height: calc(100vh - var(--top-height, 130px));
2025-08-21 19:39:07 +08:00
background: #FFFFFF;
2025-08-20 14:10:48 +08:00
}
2025-08-21 19:39:07 +08:00
2025-08-22 19:52:05 +08:00
@media screen and (max-width: 768px) {
.sidebar-container {
--top-height: 100px;
}
}
@media screen and (max-width: 480px) {
.sidebar-container {
--top-height: 80px;
2025-08-23 19:20:14 +08:00
width: 200px;
2025-08-22 19:52:05 +08:00
}
}
2025-08-21 19:39:07 +08:00
.avatar-container {
height: 230px;
position: relative;
/* 移除原来的边框 */
2025-08-20 14:10:48 +08:00
}
/* 添加带间距的横线 */
.avatar-container::after {
2025-08-21 19:39:07 +08:00
content: '';
position: absolute;
bottom: 0;
2025-08-23 19:20:14 +08:00
left: 15px;
2025-08-25 10:39:24 +08:00
right: 15px;
height: 1px;
background-color: #E6E6E6;
}
.avatar-container img {
width: 80px;
height: 80px;
/* 圆角 */
border-radius: 50%;
margin-top: 55px;
margin-left: 80px;
margin-right: 80px;
}
.avatar-text {
margin-left: 80px;
height: 31px;
font-family: AppleSystemUIFont;
font-size: 20px;
color: #000000;
line-height: 26px;
text-align: left;
font-style: normal;
text-transform: none;
}
@media screen and (max-width: 768px) {
.avatar-container {
height: 180px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
2025-08-22 19:52:05 +08:00
}
2025-08-25 10:39:24 +08:00
2025-08-22 19:52:05 +08:00
.avatar-container img {
2025-08-25 10:39:24 +08:00
margin: 0 0 15px 0;
2025-08-22 19:52:05 +08:00
}
2025-08-25 10:39:24 +08:00
2025-08-22 19:52:05 +08:00
.avatar-text {
2025-08-25 10:39:24 +08:00
margin: 0;
text-align: center;
2025-08-22 19:52:05 +08:00
}
2025-08-25 10:39:24 +08:00
}
@media screen and (max-width: 480px) {
.avatar-container {
height: 150px;
2025-08-22 19:52:05 +08:00
}
2025-08-25 10:39:24 +08:00
.avatar-container img {
width: 80px;
height: 80px;
2025-08-22 19:52:05 +08:00
}
2025-08-25 10:39:24 +08:00
.avatar-text {
font-size: 18px;
2025-08-22 19:52:05 +08:00
}
2025-08-25 10:39:24 +08:00
}
.nav-container {
margin-top: 30px;
/* 鼠标变小手 */
cursor: pointer;
}
.nav-container .nav-item {
margin-left: 15px;
width: 210px;
height: 50px;
margin-bottom: 15px;
/* 圆角 */
border-radius: 10px;
display: flex;
align-items: center;
transition: all 0.3s ease;
gap: 8px;
}
@media screen and (max-width: 768px) {
.nav-container {
2025-08-23 19:20:14 +08:00
display: flex;
2025-08-25 10:39:24 +08:00
flex-wrap: wrap;
justify-content: center;
margin-top: 15px;
2025-08-22 19:52:05 +08:00
}
2025-08-25 10:39:24 +08:00
.nav-container .nav-item {
width: 200px;
margin: 0 10px 15px;
}
2025-08-25 18:28:46 +08:00
.submenu-container {
width: 200px;
}
2025-08-25 10:39:24 +08:00
}
@media screen and (max-width: 480px) {
.nav-container .nav-item {
width: 150px;
height: 45px;
margin: 0 5px 10px;
}
2025-08-25 10:39:24 +08:00
2025-08-23 19:20:14 +08:00
.nav-container .nav-item img {
2025-08-25 10:39:24 +08:00
margin-left: 20px;
}
2025-08-25 10:39:24 +08:00
}
.nav-container .nav-item:hover {
background: rgba(102, 183, 227, 0.05);
}
/* 添加激活状态样式 */
.nav-container .nav-item.active {
background: rgba(102, 183, 227, 0.1);
}
.nav-container .nav-item.active span {
color: #0C99DA;
}
.nav-container .nav-item img {
height: 18px;
margin-left: 40px;
margin-top: 0;
margin-right: 5px;
}
.nav-container .nav-item span {
height: 26px;
2025-08-21 19:39:07 +08:00
font-family: AppleSystemUIFont;
2025-08-23 19:20:14 +08:00
font-size: 18px;
2025-08-21 19:39:07 +08:00
color: #666666;
line-height: 23px;
text-align: left;
font-style: normal;
text-transform: none;
2025-08-20 14:10:48 +08:00
}
.ai-container {
margin: 0 20px;
border-top: 1.5px solid #E6E6E6;
padding-top: 30px;
}
.ai-tab {
display: flex;
align-items: center;
gap: 8px;
height: 54px;
padding-left: 16px;
color: #666666;
background: transparent;
border-radius: 8px;
text-decoration: none;
font-size: 18px;
}
.ai-tab.router-link-active,
.ai-tab.router-link-exact-active {
background: #E2F5FF;
color: #0088D1;
}
.ai-tab:hover {
background: rgba(2, 136, 209, 0.06);
color: #0088D1;
}
.ai-tab img {
margin-left: 30px;
width: 20px;
height: 20px;
}
2025-08-20 14:10:48 +08:00
.router-view-container {
2025-08-21 19:39:07 +08:00
flex: 1;
2025-08-23 19:20:14 +08:00
padding: 10px 25px;
2025-08-21 19:39:07 +08:00
background: #F5F7FA;
2025-08-22 19:52:05 +08:00
height: calc(100vh - var(--top-height, 130px));
2025-08-23 19:20:14 +08:00
overflow-y: auto;
2025-08-20 14:10:48 +08:00
}
2025-08-25 10:39:24 +08:00
/* 全宽显示(隐藏侧边栏时) */
.router-view-container.full-width {
width: 100%;
margin-left: 0;
}
2025-08-22 19:52:05 +08:00
@media screen and (max-width: 768px) {
.router-view-container {
--top-height: 100px;
padding: 15px;
}
}
@media screen and (max-width: 480px) {
.router-view-container {
--top-height: 80px;
padding: 10px;
}
}
2025-08-20 14:10:48 +08:00
.breadcrumb {
display: flex;
align-items: center;
}
.breadcrumb-separator {
2025-08-21 19:39:07 +08:00
margin-right: 10px;
2025-08-20 14:10:48 +08:00
}
2025-08-25 10:39:24 +08:00
.breadcrumb-side {
width: 4px;
height: 17px;
background-color: #0288D1;
margin-right: 4px;
}
2025-08-25 18:28:46 +08:00
@media screen and (max-width: 480px) {
.nav-container .nav-item {
width: 150px;
height: 45px;
margin: 0 5px 10px;
}
2025-08-25 18:28:46 +08:00
.nav-container .nav-item img {
margin-left: 20px;
}
.submenu-container {
width: 150px;
}
2025-08-25 18:28:46 +08:00
}
/* 面包屑样式 */
.custom-breadcrumb {
display: flex;
align-items: center;
gap: 8px;
}
.breadcrumb-path {
display: flex;
align-items: center;
gap: 8px;
}
2025-08-25 18:28:46 +08:00
.breadcrumb-item {
display: flex;
align-items: center;
font-size: 14px;
color: #000;
2025-08-25 10:39:24 +08:00
cursor: pointer;
2025-08-25 18:28:46 +08:00
transition: color 0.3s ease;
2025-08-25 10:39:24 +08:00
}
2025-08-25 18:28:46 +08:00
.breadcrumb-item.clickable:hover {
color: #0C99DA;
2025-08-25 10:39:24 +08:00
text-decoration: underline;
}
2025-08-25 18:28:46 +08:00
.breadcrumb-item.last-item {
color: #999;
cursor: default;
}
.breadcrumb-item.last-item:hover {
color: #999;
text-decoration: none;
}
.breadcrumb-item.first-item {
font-size: 16px;
font-weight: 500;
color: #333;
margin-right: 10px;
}
2025-08-25 18:28:46 +08:00
.breadcrumb-separator {
color: #666;
margin: 0 4px;
font-weight: normal;
}
2025-08-20 14:10:48 +08:00
</style>