1316 lines
33 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="admin-dashboard">
<!-- 顶部图片 -->
<div class="top-image-container" v-if="showTopImage">
<img src="/images/teacher/顶部.png" alt="顶部图片" class="top-image">
<button class="close-button" @click="handleClose">关闭</button>
</div>
<div class="main-content">
<!-- 侧边栏 -->
<div class="sidebar-container" v-if="!hideSidebar">
<!-- 头像 -->
<div class="avatar-container">
<img :src="userStore.user?.avatar"
:alt="userStore.user?.profile?.realName || userStore.user?.nickname || userStore.user?.username"
class="avatar">
<div class="avatar-text">
{{ userStore.user?.profile?.realName || userStore.user?.nickname || userStore.user?.username }}
</div>
</div>
<!-- 导航栏 -->
<div class="nav-container">
<!-- 动态菜单渲染 -->
<template v-for="menu in menuList" :key="menu.id">
<!-- 有子菜单的父级菜单 -->
<div v-if="menu.children && menu.children.length > 0"
class="nav-item"
:class="{ active: activeNavItem === menu.id }"
@click="toggleMenu(menu)">
<img :src="getMenuIcon(menu)" :alt="menu.name" v-if="menu.icon">
<span>{{ menu.name }}</span>
<n-icon class="expand-icon" :class="{ expanded: isMenuExpanded(menu.id) }">
<ChevronDownOutline />
</n-icon>
</div>
<!-- 子菜单容器 -->
<div v-if="menu.children && menu.children.length > 0"
class="submenu-container"
:class="{ expanded: isMenuExpanded(menu.id) }">
<router-link v-for="subMenu in menu.children"
:key="subMenu.id"
:to="subMenu.path"
class="submenu-item"
:class="{ active: activeSubNavItem === subMenu.id }"
@click="handleSubMenuClick(subMenu, menu)">
<span>{{ subMenu.name }}</span>
</router-link>
</div>
<!-- 没有子菜单的直接链接 -->
<router-link v-else
:to="menu.path"
class="nav-item"
:class="{ active: activeNavItem === menu.id }"
@click="toggleMenu(menu)">
<img :src="getMenuIcon(menu)" :alt="menu.name" v-if="menu.icon">
<span>{{ menu.name }}</span>
</router-link>
</template>
</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> -->
<!-- 智能体编排 - 可展开菜单 - 已注释 -->
<!-- <div class="nav-container orchestration-nav">
<div class="nav-item" :class="{ active: activeNavItem === 6 }" @click="toggleOrchestrationMenu">
<img :src="activeNavItem === 6 ? '/images/aiAssistant/AI助教1.png' : '/images/aiAssistant/AI助教2.png'" alt="">
<span>智能体编排</span>
<n-icon class="expand-icon" :class="{ expanded: orchestrationMenuExpanded }">
<ChevronDownOutline />
</n-icon>
</div>
<div class="submenu-container" :class="{ expanded: orchestrationMenuExpanded }">
<router-link to="/teacher/airag/aiapp" class="submenu-item"
:class="{ active: activeSubNavItem === 'app-management' }" @click="setActiveSubNavItem('app-management')">
<span>AI应用管理</span>
</router-link>
<router-link to="/teacher/airag/aiknowledge" class="submenu-item"
:class="{ active: activeSubNavItem === 'knowledge-base' }" @click="setActiveSubNavItem('knowledge-base')">
<span>AI知识库</span>
</router-link>
<router-link to="/teacher/airag/aiflow" class="submenu-item"
:class="{ active: activeSubNavItem === 'process-design' }" @click="setActiveSubNavItem('process-design')">
<span>AI流程设计</span>
</router-link>
<router-link to="/teacher/airag/aimodel" class="submenu-item"
:class="{ active: activeSubNavItem === 'model-config' }" @click="setActiveSubNavItem('model-config')">
<span>AI模型配置</span>
</router-link>
<router-link to="/teacher/airag/ocr" class="submenu-item"
:class="{ active: activeSubNavItem === 'ocr-recognition' }"
@click="setActiveSubNavItem('ocr-recognition')">
<span>OCR识别</span>
</router-link>
</div>
</div> -->
</div>
<!-- 右侧路由视图 -->
<div class="router-view-container" :class="{ 'full-width': hideSidebar }">
<!-- 面包屑 -->
<div class="breadcrumb" v-if="breadcrumbDisplay">
<span class="breadcrumb-side"></span>
<div class="custom-breadcrumb">
<!-- 左侧课程管理 -->
<div class="breadcrumb-item clickable first-item" v-if="isCourseEditor">
<n-button text @click="handleBreadcrumbClick('/teacher/course-management')">
<template #icon>
<n-icon>
<ChevronBackSharp />
</n-icon>
</template>
课程管理
</n-button>
</div>
<!-- <span class="breadcrumb-item clickable first-item"
@click="handleBreadcrumbClick('/teacher/course-management')" v-else>课程管理</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>
</div>
</div>
<router-view></router-view>
</div>
</div>
</div>
</template>
<script setup lang="ts">
// @ts-nocheck
import { ref, onMounted, computed, watch, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ChevronDownOutline } from '@vicons/ionicons5'
import { useUserStore } from '@/stores/user'
import { ChevronBackSharp } from '@vicons/ionicons5'
import { TeachCourseApi } from '@/api/modules/teachCourse'
const userStore = useUserStore()
const width = window.innerWidth;
const height = window.innerHeight;
console.log(`当前屏幕宽度: ${width}px, 高度: ${height}px`);
// 添加导航项激活状态管理
const activeNavItem = ref(''); // 当前激活的菜单ID
const activeSubNavItem = ref(''); // 子菜单激活状态
const expandedMenus = ref(new Set()); // 展开的菜单ID集合
const showTopImage = ref(false); // 控制顶部图片显示/隐藏
// 需要隐藏顶部图片的路由路径数组
const hideTopImageRoutes = [
'teacher/chapter-editor-teacher',
'teacher/course-editor'
// 可以在这里添加更多需要隐藏顶部图片的路由
];
const route = useRoute();
const router = useRouter();
// const isAiHovered = ref(false); // AI助教悬停状态 - 已注释
// const isAiActive = computed(() => route.path.includes('/teacher/ai-assistant')); // AI助教激活状态 - 已注释
const breadcrumbDisplay = computed(() => {
const currentPath = route.path;
let arr = ['certificate/new']; // 移除 'ai-assistant', 'airag' - 已注释
let found = arr.find(item => currentPath.includes(item));
if (found) {
return false;
}
return true;
});
const isCourseEditor = computed(() => route.path.includes('course-editor') || route.path.includes('chapter-editor-teacher'));
// 检查菜单是否展开
const isMenuExpanded = (menuId) => {
return expandedMenus.value.has(menuId)
}
// 切换菜单展开状态
const toggleMenu = (menu) => {
if (menu.children && menu.children.length > 0) {
if (expandedMenus.value.has(menu.id)) {
expandedMenus.value.delete(menu.id)
} else {
expandedMenus.value.add(menu.id)
}
}
// 设置当前菜单为激活状态
activeNavItem.value = menu.id
// 如果有路径且没有子菜单,则导航
if (menu.path && (!menu.children || menu.children.length === 0)) {
router.push(menu.path)
}
}
// 处理子菜单点击
const handleSubMenuClick = (subMenu, parentMenu) => {
activeSubNavItem.value = subMenu.id
activeNavItem.value = parentMenu.id
if (subMenu.path) {
router.push(subMenu.path)
}
}
// 获取菜单图标,处理激活状态
const getMenuIcon = (menu) => {
if (!menu.icon) return null
// 如果是激活状态且有对应的激活图标
if (activeNavItem.value === menu.id) {
return menu.icon.replace('.png', '-active.png')
}
return menu.icon
}
// 更新激活的导航项
const updateActiveNavItem = () => {
const path = route.path;
console.log('当前路径:', path);
// 遍历菜单找到匹配的路径
const findActiveMenu = (menus, parentId = null) => {
for (const menu of menus) {
if (menu.path && path.includes(menu.path.replace('/teacher/', ''))) {
activeNavItem.value = parentId || menu.id
if (parentId) {
activeSubNavItem.value = menu.id
expandedMenus.value.add(parentId)
}
return true
}
if (menu.children && menu.children.length > 0) {
if (findActiveMenu(menu.children, menu.id)) {
return true
}
}
}
return false
}
findActiveMenu(menuList.value)
}
// 处理面包屑点击
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');
});
}
// 判断是否隐藏左侧侧边栏
const hideSidebar = computed(() => {
const currentPath = route.path
// 当进入课程管理相关页面或章节编辑页面时隐藏侧边栏
return currentPath.includes('course-editor') || currentPath.includes('chapter-editor-teacher') || currentPath.includes('certificate')
})
// 定义菜单数据
const menuList = ref([])
// 处理菜单数据,构建层级关系
const processMenuData = (menuData) => {
const menuMap = new Map()
const rootMenus = []
// 先创建所有菜单项的映射
menuData.forEach(menu => {
menuMap.set(menu.id, {
...menu,
children: []
})
})
// 构建层级关系
menuData.forEach(menu => {
if (menu.parentId === null) {
// 根级菜单
rootMenus.push(menuMap.get(menu.id))
} else {
// 子菜单
const parent = menuMap.get(menu.parentId)
if (parent) {
parent.children.push(menuMap.get(menu.id))
}
}
})
// 按sortOrder排序
const sortMenus = (menus) => {
menus.sort((a, b) => b.sortOrder - a.sortOrder)
menus.forEach(menu => {
if (menu.children.length > 0) {
sortMenus(menu.children)
}
})
}
sortMenus(rootMenus)
return rootMenus
}
// 动态生成面包屑路径项(右侧部分)
const breadcrumbPathItems = computed(() => {
const currentPath = route.path;
// 证书管理模块的面包屑逻辑(优先处理)
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;
}
// 如果在课程编辑器相关页面
if (currentPath.includes('course-editor')) {
// 从路径中提取课程ID
const courseIdMatch = currentPath.match(/\/course-editor\/(\d+)/);
const courseId = courseIdMatch ? courseIdMatch[1] : '未知';
let breadcrumbs: Array<{ title: string, path: string }> = [];
// 根据当前路径添加子页面标题
if (currentPath.includes('courseware')) {
breadcrumbs.push(
{
title: '课件管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
} else if (currentPath.includes('question-bank')) {
breadcrumbs.push(
{
title: '题库管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
} else if (currentPath.includes('add-question')) {
breadcrumbs.push(
{
title: '题库管理',
path: currentPath.replace('/add-question', '/question-bank')
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
},
{
title: '新增试题',
path: currentPath
}
);
} else if (currentPath.includes('chapters')) {
breadcrumbs.push(
{
title: '章节管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
} else if (currentPath.includes('template-import')) {
breadcrumbs.push(
{
title: '课程管理',
path: '/teacher/course-management'
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
},
{
title: '作业管理',
path: `/teacher/course-editor/${courseId}/homework`
},
{
title: '导入',
path: currentPath
}
);
} 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')) {
breadcrumbs.push(
{
title: '考试管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
} else if (currentPath.includes('practice/review')) {
breadcrumbs.push(
{
title: '阅卷中心',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
} else if (currentPath.includes('certificate')) {
breadcrumbs.push(
{
title: '课程管理',
path: '/teacher/course-management'
},
{
title: '证书管理',
path: '/teacher/course-editor/1/certificate'
},
{
title: '证书名称详情',
path: currentPath
}
);
} else if (currentPath.includes('discussion/add')) {
// 添加讨论页面:课程管理 > 讨论 > 添加讨论
breadcrumbs.push(
{
title: '课程管理',
path: '/teacher/course-management'
},
{
title: '讨论',
path: `/teacher/course-editor/${courseId}/discussion`
},
{
title: '添加讨论',
path: currentPath
}
);
} else if (currentPath.includes('discussion')) {
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
}
);
} else if (currentPath.includes('statistics')) {
breadcrumbs.push(
{
title: '统计管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
} else if (currentPath.includes('notification')) {
breadcrumbs.push(
{
title: '通知管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
} else if (currentPath.includes('management')) {
breadcrumbs.push(
{
title: '综合管理',
path: currentPath
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
}
);
}
return breadcrumbs;
}
// 如果在章节编辑页面,显示课程管理>课程名称>新建/编辑章节
if (currentPath.includes('chapter-editor-teacher')) {
const courseId = route.params.courseId;
let breadcrumbs = [
{
title: '课程管理',
path: '/teacher/course-management'
},
{
title: `课程${courseId}`,
path: `/teacher/course-editor/${courseId}`
},
{
title: route.query.mode === 'add' ? '新建章节' : '编辑章节',
path: `/teacher/course-editor/${courseId}/chapters`
},
];
return breadcrumbs;
}
// 学员管理模块的面包屑逻辑
if (currentPath.includes('student-management')) {
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')) {
breadcrumbs = [
{
title: '学员中心',
path: '/teacher/student-management'
},
{
title: '班级管理',
path: '/teacher/student-management/class-management'
}
];
} else if (currentPath.endsWith('/student-management')) {
breadcrumbs = [
{
title: '学员中心',
path: '/teacher/student-management'
}
];
}
return breadcrumbs;
}
// 回收站页面的面包屑逻辑
if (currentPath.includes('recycle-bin')) {
const breadcrumbs = [
{
title: '我的资源',
path: '/teacher/my-resources'
},
{
title: '回收站',
path: currentPath
}
]
return breadcrumbs;
}
// 智能体编排模块的面包屑逻辑
if (currentPath.includes('airag')) {
console.log('智能体编排页面路径:', currentPath);
let breadcrumbs: Array<{ title: string, path: string }> = [];
// 根据具体页面添加子页面标题
if (currentPath.includes('aiapp')) {
breadcrumbs = [
{
title: '智能体编排',
path: '/teacher/airag'
},
{
title: 'AI应用管理',
path: currentPath
}
];
} else if (currentPath.includes('aiknowledge')) {
breadcrumbs = [
{
title: '智能体编排',
path: '/teacher/airag'
},
{
title: 'AI知识库',
path: currentPath
}
];
} else if (currentPath.includes('aiflow')) {
breadcrumbs = [
{
title: '智能体编排',
path: '/teacher/airag'
},
{
title: 'AI流程设计',
path: currentPath
}
];
} else if (currentPath.includes('aimodel')) {
breadcrumbs = [
{
title: '智能体编排',
path: '/teacher/airag'
},
{
title: 'AI模型配置',
path: currentPath
}
];
} else if (currentPath.includes('ocr')) {
breadcrumbs = [
{
title: '智能体编排',
path: '/teacher/airag'
},
{
title: 'OCR识别',
path: currentPath
}
];
} else {
// 智能体编排主页面
breadcrumbs = [
{
title: '智能体编排',
path: currentPath
}
];
}
console.log('智能体编排页面面包屑:', breadcrumbs);
return breadcrumbs;
}
// 其他页面的面包屑逻辑
const matchedRoutes = route.matched;
let breadcrumbs = matchedRoutes
.filter((item: any) => item.meta.title !== '管理后台')
.map((item: any) => ({
title: item.meta.title || '未知页面',
path: item.path
}));
console.log('其他页面面包屑:', breadcrumbs);
return breadcrumbs;
});
// 监听路由变化,更新激活的导航项
onMounted(async () => {
try {
// 获取菜单数据
const menuResponse = await TeachCourseApi.getTeacherMenuList()
const rawMenuData = menuResponse.data.result
console.log('原始菜单数据:', rawMenuData);
// 处理菜单数据
menuList.value = processMenuData(rawMenuData)
console.log('处理后的菜单数据:', menuList.value);
} catch (error) {
console.error('获取菜单数据失败:', error)
}
// 初始设置
updateActiveNavItem();
// 确保广告默认隐藏
showTopImage.value = false;
// 初始化CSS变量
if (showTopImage.value) {
document.documentElement.style.setProperty('--top-height', '130px');
} else {
document.documentElement.style.setProperty('--top-height', '0px');
}
updateTopImageVisibility();
});
// 使用watch监听路由变化
watch(route, () => {
updateActiveNavItem();
updateTopImageVisibility();
});
// 更新顶部图片显示状态
const updateTopImageVisibility = () => {
const currentPath = route.path;
console.log('检查路径是否需要隐藏顶部图片:', currentPath);
// 检查当前路径是否包含需要隐藏顶部图片的路由
const shouldHideTopImage = hideTopImageRoutes.some(routePath =>
currentPath.includes(routePath)
);
// 默认隐藏广告,只在特定路由下显示(如果需要的话)
showTopImage.value = false; // 默认隐藏
console.log('顶部图片显示状态:', showTopImage.value);
};
</script>
<style scoped>
.admin-dashboard {
position: relative;
}
.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;
}
/* 响应式调整 */
@media screen and (max-width: 768px) {
.top-image-container {
height: 100px;
}
}
@media screen and (max-width: 480px) {
.top-image-container {
height: 80px;
}
}
.top-image {
width: 100%;
height: 100%;
position: absolute;
left: 0px;
top: 0px;
opacity: 100%;
object-fit: cover;
}
.main-content {
display: flex;
}
@media screen and (max-width: 768px) {
.main-content {
flex-direction: column;
}
.sidebar-container {
width: 100%;
height: auto;
min-height: 300px;
}
.router-view-container {
height: auto;
min-height: calc(100vh - var(--top-height, 100px) - 300px);
}
}
.sidebar-container {
width: 240px;
height: calc(100vh - var(--top-height, 130px) - 64px);
background: #FFFFFF;
overflow-y: auto;
/* 隐藏滚动条但保持滚动功能 */
scrollbar-width: none;
/* Firefox */
-ms-overflow-style: none;
/* IE and Edge */
}
/* 隐藏Webkit浏览器的滚动条 */
.sidebar-container::-webkit-scrollbar {
display: none;
}
@media screen and (max-width: 768px) {
.sidebar-container {
--top-height: 100px;
}
}
@media screen and (max-width: 480px) {
.sidebar-container {
--top-height: 80px;
width: 200px;
}
}
.avatar-container {
position: relative;
padding: 20px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
/* 移除原来的边框 */
}
/* 添加带间距的横线 */
.avatar-container::after {
content: '';
position: absolute;
bottom: 0;
left: 15px;
right: 15px;
height: 1px;
background-color: #E6E6E6;
}
.avatar-container img {
width: 80px;
height: 80px;
/* 圆角 */
border-radius: 50%;
margin-top: 30px;
}
.avatar-text {
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;
}
.avatar-container img {
margin: 0 0 15px 0;
}
.avatar-text {
margin: 0;
text-align: center;
}
}
@media screen and (max-width: 480px) {
.avatar-container {
height: 150px;
}
.avatar-container img {
width: 80px;
height: 80px;
}
.avatar-text {
font-size: 18px;
}
}
.nav-container {
margin-top: 30px;
/* 鼠标变小手 */
cursor: pointer;
}
/* 智能体编排菜单移除顶部外边距 */
.orchestration-nav {
margin-top: 10px;
}
.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 {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-top: 15px;
}
.nav-container .nav-item {
width: 200px;
margin: 0 10px 15px;
}
.submenu-container {
width: 200px;
}
}
@media screen and (max-width: 480px) {
.nav-container .nav-item {
width: 150px;
height: 45px;
margin: 0 5px 10px;
}
.nav-container .nav-item img {
margin-left: 20px;
}
}
.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;
font-family: AppleSystemUIFont;
font-size: 18px;
color: #666666;
line-height: 23px;
text-align: left;
font-style: normal;
text-transform: none;
}
.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;
}
.router-view-container {
flex: 1;
padding: 10px 25px;
background: #F5F7FA;
height: calc(100vh - var(--top-height, 130px) - 64px);
overflow-y: hidden;
display: flex;
flex-direction: column;
}
/* 全宽显示(隐藏侧边栏时) */
.router-view-container.full-width {
width: 100%;
margin-left: 0;
}
@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;
}
}
.breadcrumb {
display: flex;
align-items: center;
}
.breadcrumb-separator {
margin-right: 10px;
}
.breadcrumb-side {
width: 4px;
height: 17px;
background-color: #0288D1;
margin-right: 4px;
}
@media screen and (max-width: 480px) {
.nav-container .nav-item {
width: 150px;
height: 45px;
margin: 0 5px 10px;
}
.nav-container .nav-item img {
margin-left: 20px;
}
.submenu-container {
width: 150px;
}
}
/* 面包屑样式 */
.custom-breadcrumb {
display: flex;
align-items: center;
gap: 8px;
}
.breadcrumb-path {
display: flex;
align-items: center;
gap: 8px;
padding: 4px 0;
}
.breadcrumb-item {
display: flex;
align-items: center;
font-size: 14px;
color: #000;
cursor: pointer;
transition: color 0.3s ease;
}
.breadcrumb-item.clickable:hover {
color: #0C99DA;
text-decoration: underline;
}
.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;
}
.breadcrumb-separator {
color: #666;
margin: 0 4px;
font-weight: normal;
}
</style>