2026-10-15 17:59:34 +08:00

346 lines
10 KiB
Vue

<template>
<div class="left">
<!-- 可滚动菜单区域 -->
<div class="sidebar-scroll">
<!-- 主导航 -->
<div class="main-navigation mb-6">
<el-menu
:default-active="activeIndex"
class="custom-menu"
background-color="transparent"
text-color="#fff"
active-text-color="#00FFCC"
@select="handleSelect"
>
<el-menu-item index="index">
<div class="menu-item-content">
<i class="iconfont icon-shouye"></i>
<span class="menu-text">首页</span>
</div>
</el-menu-item>
</el-menu>
</div>
<!-- AI 创作分组 -->
<div class="ai-creation-menu mb-8">
<div class="menu-title">AI 创作</div>
<el-menu
:default-active="activeIndex"
class="custom-menu"
background-color="transparent"
text-color="#fff"
active-text-color="#00FFCC"
@select="handleSelect"
>
<el-menu-item index="/videoGenerate">
<div class="menu-item-content">
<i class="iconfont icon-img2video"></i>
<span class="menu-text">视频生成</span>
</div>
</el-menu-item>
<el-menu-item index="/ImgGenerate">
<div class="menu-item-content">
<i class="iconfont icon-tupianshengcheng"></i>
<span class="menu-text">图片生成</span>
</div>
</el-menu-item>
<el-menu-item index="/TextGenerate">
<div class="menu-item-content">
<i class="iconfont icon-xiaoxi"></i>
<span class="menu-text">文本生成</span>
</div>
</el-menu-item>
</el-menu>
</div>
<!-- 我的分组 -->
<div class="tool-navigation mb-8">
<div class="menu-title">我的</div>
<el-menu
:default-active="activeIndex"
class="custom-menu"
background-color="transparent"
text-color="#fff"
active-text-color="#00FFCC"
@select="handleSelect"
>
<!-- <el-menu-item index="bill">
<div class="menu-item-content">
<i class="iconfont icon-xiaofeijilu"></i>
<span class="menu-text">消费记录</span>
</div>
</el-menu-item> -->
<el-menu-item index="history-creation">
<div class="menu-item-content">
<i class="iconfont icon-wodechuangzuo"></i>
<span class="menu-text">历史创作</span>
</div>
</el-menu-item>
<el-menu-item index="apikey">
<div class="menu-item-content">
<i class="iconfont icon-apikey"></i>
<span class="menu-text">令牌管理</span>
</div>
</el-menu-item>
<el-menu-item index="redeem">
<div class="menu-item-content">
<i class="iconfont icon-yue"></i>
<span class="menu-text">兑换码</span>
</div>
</el-menu-item>
</el-menu>
</div>
<!-- 底部占位空白 -->
<div class="pb-20"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
// 路由实例
const router = useRouter()
const route = useRoute()
// 根据当前路由计算激活的菜单项索引
const activeIndex = ref('index')
// 菜单项点击事件
const handleSelect = (index: string) => {
activeIndex.value = index
// 处理路由跳转
switch (index) {
case 'index':
router.push('/index');
break;
case 'bill':
router.push('/bill');
break;
case 'history-creation':
router.push('/history-creation');
break;
case 'discover':
router.push('/discover');
break;
case 'profile':
router.push('/profile');
break;
case 'infinite-canvas':
router.push('/infinite-canvas');
break;
case '/videoGenerate':
router.push('/videoGenerate');
break;
case '/ImgGenerate':
router.push('/ImgGenerate');
break;
case '/TextGenerate':
router.push('/TextGenerate');
break;
case 'digital-human':
router.push('/digital-human');
break;
case 'material-square':
router.push('/material-square');
break;
case 'apikey':
router.push('/apikey');
break;
case 'redeem':
router.push('/redeem');
break;
default:
break;
}
}
// 监听路由变化,更新激活状态
const updateActiveIndex = () => {
const path = route.path
if (path.includes('/index')) {
activeIndex.value = 'index';
} else if (path.includes('/history-creation')) {
activeIndex.value = 'history-creation';
} else if (path.includes('/bill')) {
activeIndex.value = 'bill';
} else if (path.includes('/discover')) {
activeIndex.value = 'discover';
} else if (path.includes('/profile')) {
activeIndex.value = 'profile';
} else if (path.includes('/infinite-canvas')) {
activeIndex.value = 'infinite-canvas';
} else if (path.includes('/videoGenerate')) {
activeIndex.value = '/videoGenerate';
} else if (path.includes('/ImgGenerate')) {
activeIndex.value = '/ImgGenerate';
} else if (path.includes('/TextGenerate')) {
activeIndex.value = '/TextGenerate';
} else if (path.includes('/digital-human')) {
activeIndex.value = 'digital-human';
} else if (path.includes('/material-square')) {
activeIndex.value = 'material-square';
} else if (path.includes('/apikey')) {
activeIndex.value = 'apikey';
} else if (path.includes('/redeem')) {
activeIndex.value = 'redeem';
}
else {
activeIndex.value = 'index';
}
}
// 组件挂载时更新激活状态
onMounted(() => {
updateActiveIndex()
// 监听路由变化
router.afterEach(() => {
updateActiveIndex()
})
})
</script>
<style scoped lang="less">
.left {
height: calc(100vh - 80px);
padding: 0 24px;
color: #fff;
display: flex;
flex-direction: column;
overflow: hidden;
.sidebar-scroll {
flex: 1;
min-height: 0;
overflow-y: auto;
scrollbar-width: none;
-ms-overflow-style: none;
&::-webkit-scrollbar {
display: none;
}
}
// 菜单标题
.menu-title {
margin-bottom: 16px;
padding-left: 16px;
font-size: 14px;
color: rgba(255, 255, 255, 0.5);
}
// 自定义菜单样式覆盖
:deep(.custom-menu) {
border-right: none;
background-color: transparent;
.el-menu-item {
height: auto;
line-height: normal;
padding: 10px 12px;
margin-bottom: 4px;
border-radius: 8px;
transition: background-color 0.2s ease;
&:last-child {
margin-bottom: 0;
}
&:hover {
background-color: rgba(255, 255, 255, 0.12);
}
&.is-active {
background: linear-gradient(90deg, #2cfff84d, #2c68ff4d);
.menu-text {
color: #00FFCC;
}
.iconfont {
color: #00FFCC;
}
}
&.is-disabled {
cursor: not-allowed;
opacity: 0.6;
&:hover {
background-color: transparent;
}
.menu-text {
color: rgba(255, 255, 255, 0.4);
}
.iconfont {
opacity: 0.4;
}
}
}
}
// 菜单项内容布局
.menu-item-content {
display: flex;
align-items: center;
width: 100%;
.iconfont {
font-size: 20px;
margin-right: 12px;
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
}
.menu-text {
flex: 1;
font-size: 14px;
}
}
// 标签样式
.menu-tag {
margin-left: 8px;
padding: 2px 8px;
font-size: 10px;
border-radius: 12px;
background-color: #2563eb;
color: #fff;
white-space: nowrap;
&.new {
background-color: #2563eb;
}
&.disabled {
background-color: rgba(255, 255, 255, 0.2);
color: rgba(255, 255, 255, 0.6);
}
}
// 底部空白
.pb-20 {
padding-bottom: 80px;
}
// 辅助类
.mb-6 {
margin-bottom: 24px;
}
.mb-8 {
margin-bottom: 32px;
}
}
</style>