GPU_Web/src/views/layout/index.vue
Leo_Ding 45f557c9cb 11
2025-12-03 18:15:10 +08:00

184 lines
6.0 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="gx_layout">
<div :class="isHome ? 'gx_layout_header_home' : 'gx_layout_header_noHome'" class="gx_layout_header">
<div class="logo">GxDL算力云</div>
<div class="menu">
<a-menu v-model:selectedKeys="current" :class="isHome?'custom-menu':''" mode="horizontal" :items="leftRoutes"
@click="({ key }) => handleMenuClick(key)" />
<a-menu v-model:selectedKeys="current" mode="horizontal" :class="isHome?'custom-menu':''" :items="rightRoutes"
@click="({ key }) => handleMenuClick(key)" />
</div>
<div class="user-info">
<a-dropdown>
<div style="display: flex;align-items: center;justify-content: flex-end;">
<a-avatar :size="24" :src="userInfo.avatar">
<!-- <template #icon>
<UserOutlined />
</template> -->
</a-avatar>
<span style="font-size: 14px;padding-left:5px;">{{ userInfo.userName }}</span>
</div>
<template #overlay>
<a-card hoverable style="width: 300px">
<template #cover>
<div style="background:#f5f7fa;padding:10px;line-height: 30px">
<div>{{ userInfo.userName }} <a-tag color="blue" style="margin-left: 10px;">{{ userInfo.accountType==='USER'?'个人认证':'企业认证' }}</a-tag></div>
<div>ID:{{ userInfo.id }}</div>
</div>
<div style="padding: 10px;line-height: 45px;">
<div style="display: flex;justify-content: space-between;align-items: center;"><div>可用余额¥200.00</div> <a-button type="primary" danger ghost size="small">去充值</a-button></div>
<div>实例数量¥{{ userInfo.caseNum }}</div>
<div>冻结余额¥{{ userInfo.freezeBalace }}</div>
<div>未冻结余额¥{{ userInfo.noFreezeBalace }}</div>
</div>
</template>
<template #actions>
<!-- <setting-outlined key="setting" />
<edit-outlined key="edit" />
<ellipsis-outlined key="ellipsis" /> -->
<a-button block type="text" @click="logout">退出登录</a-button>
</template>
</a-card>
</template>
</a-dropdown>
</div>
</div>
<div class="gx_layout_content">
<router-view />
</div>
</div>
</template>
<script setup>
import { ref, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { UserOutlined } from '@ant-design/icons-vue';
import avatar from '@/assets/avator.png'
const router = useRouter()
const route = useRoute()
const isHome = ref(true)
const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}');
// 根据当前路由初始化菜单选中项(去掉 /layout 前缀)
const getActiveKeyFromRoute = () => {
const path = route.path
if (path.startsWith('/layout')) {
const key = path.replace('/layout', '') || '/home'
return [key.startsWith('/') ? key : '/' + key]
}
return ['/home']
}
const current = ref(getActiveKeyFromRoute())
// 监听路由变化(浏览器前进后退时同步菜单)
watch(() => route.path, () => {
current.value = getActiveKeyFromRoute()
if (current.value == '/home') {
isHome.value = true
} else {
isHome.value = true
}
})
// 菜单数据key 使用子路径,如 '/admin'
const leftRoutes = ref([
{ key: '/home', label: '首页' },
{ key: '/market', label: '算力中心' },
{ key: '/yunmain', label: '云主机' }
])
const rightRoutes = ref([
{ key: '/document', label: '用户文档' },
{ key: '/admin/home', label: '控制台' }
])
// 点击菜单跳转
const handleMenuClick = (key) => {
if (key === '/document') {
window.open(key, '_blank');
} else {
// 否则按照正常方式在当前标签页跳转
const fullPath = `/layout${key}`;
router.push(fullPath);
}
}
const logout = () => {
localStorage.clear()
router.replace('/login')
}
</script>
<style lang="scss" scoped>
.gx_layout {
width: 100%;
height: 100vh;
.gx_layout_header_home {
background-color: #cfe7fe;
border-bottom: none;
}
.gx_layout_header_noHome {
border-bottom: 1px solid rgb(216 216 216);
}
.gx_layout_header {
z-index: 999;
width: 100%;
height: 60px;
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
flex: 1;
.logo {
width: 200px;
}
.user-info {
width: 100px;
}
.menu {
flex: 1;
display: flex;
justify-content: space-around;
align-items: center;
&>ul:first-child {
width: 100%;
border-bottom: none;
}
&>ul {
border-bottom: none;
}
}
}
.gx_layout_content {
margin-top: 60px;
min-height: calc(100% - 60px);
background-color: rgba(240, 240, 240, 1);
}
}
/* 自定义菜单主题 */
.custom-menu {
/* 背景色 */
background: #cfe7fe !important;
}
/* 选中项文字颜色 + 左侧竖条horizontal 模式下是底部横线) */
.custom-menu :deep(.ant-menu-item-selected) {
color: #2563eb !important;
}
/* hover 效果 */
.custom-menu :deep(.ant-menu-item:hover) {
color: #2563eb !important;
}
</style>