184 lines
6.0 KiB
Vue
184 lines
6.0 KiB
Vue
<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> |