mirror of
https://gitee.com/ccnetcore/Yi
synced 2026-04-08 18:26:36 +08:00
289 lines
5.8 KiB
Vue
289 lines
5.8 KiB
Vue
<!-- 移动端布局 -->
|
|
<script setup lang="ts">
|
|
import { ref } from 'vue';
|
|
import { useRouter } from 'vue-router';
|
|
import { useUserStore } from '@/stores';
|
|
|
|
const router = useRouter();
|
|
const userStore = useUserStore();
|
|
|
|
// 侧边栏抽屉状态
|
|
const drawerVisible = ref(false);
|
|
|
|
// 底部导航菜单
|
|
const bottomMenus = [
|
|
{
|
|
key: 'chat',
|
|
label: '对话',
|
|
icon: 'ChatDotRound',
|
|
path: '/chat/conversation',
|
|
},
|
|
{
|
|
key: 'image',
|
|
label: '图片',
|
|
icon: 'Picture',
|
|
path: '/chat/image',
|
|
},
|
|
{
|
|
key: 'video',
|
|
label: '视频',
|
|
icon: 'VideoCamera',
|
|
path: '/chat/video',
|
|
},
|
|
{
|
|
key: 'console',
|
|
label: '我的',
|
|
icon: 'User',
|
|
path: '/console',
|
|
},
|
|
];
|
|
|
|
// 侧边栏菜单
|
|
const sidebarMenus = [
|
|
{
|
|
key: 'model-library',
|
|
label: '模型库',
|
|
icon: 'Box',
|
|
path: '/model-library',
|
|
},
|
|
{
|
|
key: 'pricing',
|
|
label: '购买',
|
|
icon: 'ShoppingCart',
|
|
path: '/pricing',
|
|
},
|
|
{
|
|
key: 'logout',
|
|
label: '退出登录',
|
|
icon: 'SwitchButton',
|
|
action: 'logout',
|
|
},
|
|
];
|
|
|
|
// 当前路由
|
|
const currentPath = computed(() => router.currentRoute.value.path);
|
|
|
|
// 当前激活的底部菜单
|
|
const activeBottomMenu = computed(() => {
|
|
const path = currentPath.value;
|
|
if (path.includes('/chat/conversation')) return 'chat';
|
|
if (path.includes('/chat/image')) return 'image';
|
|
if (path.includes('/chat/video')) return 'video';
|
|
if (path.includes('/console')) return 'console';
|
|
return 'chat';
|
|
});
|
|
|
|
// 打开抽屉
|
|
function openDrawer() {
|
|
drawerVisible.value = true;
|
|
}
|
|
|
|
// 底部菜单点击
|
|
function handleBottomMenuClick(menu: typeof bottomMenus[0]) {
|
|
router.push(menu.path);
|
|
}
|
|
|
|
// 侧边栏菜单点击
|
|
function handleSidebarMenuClick(menu: typeof sidebarMenus[0]) {
|
|
if (menu.action === 'logout') {
|
|
userStore.logout();
|
|
drawerVisible.value = false;
|
|
}
|
|
else if (menu.path) {
|
|
router.push(menu.path);
|
|
drawerVisible.value = false;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="mobile-layout">
|
|
<!-- 顶部栏 -->
|
|
<div class="mobile-header">
|
|
<el-button circle @click="openDrawer">
|
|
<el-icon><i-ep-menu /></el-icon>
|
|
</el-button>
|
|
<div class="header-title">意心AI</div>
|
|
<div class="header-avatar">
|
|
<el-avatar v-if="userStore.userInfo" :size="32" :src="userStore.userInfo.avatar">
|
|
{{ userStore.userInfo.name?.charAt(0) }}
|
|
</el-avatar>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 主内容区 -->
|
|
<div class="mobile-main">
|
|
<router-view />
|
|
</div>
|
|
|
|
<!-- 底部导航 -->
|
|
<div class="mobile-bottom-nav">
|
|
<div
|
|
v-for="menu in bottomMenus"
|
|
:key="menu.key"
|
|
class="nav-item"
|
|
:class="{ active: activeBottomMenu === menu.key }"
|
|
@click="handleBottomMenuClick(menu)"
|
|
>
|
|
<el-icon class="nav-icon">
|
|
<component :is="`i-ep-${menu.icon}`" />
|
|
</el-icon>
|
|
<div class="nav-label">
|
|
{{ menu.label }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 侧边栏抽屉 -->
|
|
<el-drawer
|
|
v-model="drawerVisible"
|
|
title="菜单"
|
|
direction="ltr"
|
|
size="280px"
|
|
>
|
|
<!-- 用户信息 -->
|
|
<div v-if="userStore.userInfo" class="drawer-user">
|
|
<el-avatar :size="60" :src="userStore.userInfo.avatar">
|
|
{{ userStore.userInfo.name?.charAt(0) }}
|
|
</el-avatar>
|
|
<div class="user-info">
|
|
<div class="user-name">{{ userStore.userInfo.name }}</div>
|
|
<div class="user-email">{{ userStore.userInfo.email }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 菜单列表 -->
|
|
<el-menu class="drawer-menu">
|
|
<el-menu-item
|
|
v-for="menu in sidebarMenus"
|
|
:key="menu.key"
|
|
@click="handleSidebarMenuClick(menu)"
|
|
>
|
|
<el-icon>
|
|
<component :is="`i-ep-${menu.icon}`" />
|
|
</el-icon>
|
|
<span>{{ menu.label }}</span>
|
|
</el-menu-item>
|
|
</el-menu>
|
|
</el-drawer>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.mobile-layout {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
height: 100vh;
|
|
overflow: hidden;
|
|
background-color: var(--el-bg-color);
|
|
}
|
|
|
|
.mobile-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
height: 56px;
|
|
padding: 0 16px;
|
|
background-color: var(--el-bg-color);
|
|
border-bottom: 1px solid var(--el-border-color);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.header-title {
|
|
flex: 1;
|
|
text-align: center;
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
color: var(--el-text-color-primary);
|
|
}
|
|
|
|
.header-avatar {
|
|
width: 40px;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.mobile-main {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
-webkit-overflow-scrolling: touch;
|
|
}
|
|
|
|
.mobile-bottom-nav {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-around;
|
|
height: 56px;
|
|
padding-bottom: env(safe-area-inset-bottom);
|
|
background-color: var(--el-bg-color);
|
|
border-top: 1px solid var(--el-border-color);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.nav-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 8px 12px;
|
|
cursor: pointer;
|
|
color: var(--el-text-color-secondary);
|
|
transition: all 0.2s;
|
|
|
|
&.active {
|
|
color: var(--el-color-primary);
|
|
|
|
.nav-icon {
|
|
transform: scale(1.1);
|
|
}
|
|
}
|
|
|
|
&:active {
|
|
opacity: 0.7;
|
|
}
|
|
}
|
|
|
|
.nav-icon {
|
|
font-size: 24px;
|
|
margin-bottom: 2px;
|
|
transition: transform 0.2s;
|
|
}
|
|
|
|
.nav-label {
|
|
font-size: 12px;
|
|
}
|
|
|
|
// 抽屉样式
|
|
.drawer-user {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
padding: 24px 16px;
|
|
border-bottom: 1px solid var(--el-border-color);
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.user-info {
|
|
margin-top: 12px;
|
|
text-align: center;
|
|
}
|
|
|
|
.user-name {
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
color: var(--el-text-color-primary);
|
|
}
|
|
|
|
.user-email {
|
|
font-size: 12px;
|
|
color: var(--el-text-color-secondary);
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.drawer-menu {
|
|
border-right: none;
|
|
}
|
|
</style>
|