| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- <template>
- <div class="user-layout">
- <el-container>
- <el-header class="header">
- <div class="header-left" @click="router.push('/problems')">
- <img :src="metaStore.logo" alt="logo" class="logo">
- <h2 class="title">{{metaStore.title}}</h2>
- </div>
- <nav class="nav">
- <router-link
- v-for="menu in menus"
- :key="menu.path"
- :to="menu.path"
- class="nav-link"
- :class="{ active: currentPath.startsWith(menu.path) }"
- >
- <el-icon><component :is="menu.meta?.icon"/></el-icon>
- <span>{{ menu.meta?.title }}</span>
- </router-link>
- <router-link
- v-if="isStaff"
- to="/admin"
- class="nav-link"
- :class="{ active: currentPath.startsWith('/admin') }"
- >
- <el-icon><Tools/></el-icon>
- <span>后台管理</span>
- </router-link>
- </nav>
- <div class="header-right">
- <template v-if="login">
- <el-dropdown placement="bottom">
- <el-button class="user-btn" text>
- <el-icon class="user-avatar"><UserFilled /></el-icon>
- <span class="username">{{ loginUserStore.loginUser?.user?.name }}</span>
- </el-button>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item @click="handleProfile">个人信息</el-dropdown-item>
- <el-dropdown-item divided @click="logoutHandler">退出登录</el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- </template>
- <template v-else>
- <el-button type="primary" size="small" @click="loginHandler">登录</el-button>
- <el-button size="small" @click="router.push({ path: '/login', query: { tab: 'register' } })">注册</el-button>
- </template>
- </div>
- </el-header>
- <el-main>
- <router-view/>
- </el-main>
- <el-footer>Footer</el-footer>
- </el-container>
- </div>
- </template>
- <script setup lang="ts">
- import {computed} from 'vue'
- import {useRoute} from 'vue-router'
- import {ElMessage} from 'element-plus'
- import {useLoginUserStore, useMetaStore} from "../store";
- import router, {userRoutes} from "../router";
- import {
- Tools,
- UserFilled
- } from '@element-plus/icons-vue'
- const route = useRoute()
- const metaStore = useMetaStore()
- const loginUserStore = useLoginUserStore()
- const login = computed(() => loginUserStore.loginUser.isLogin)
- const isStaff = computed(() => {
- const role = loginUserStore.loginUser.user?.role
- return role === 'admin' || role === 'coach'
- })
- const loginHandler = () => {
- router.push('/login')
- }
- const currentPath = computed(() => route.path)
- const menus = computed(()=>{
- return userRoutes[0].children?.filter((child) => !String(child.path).includes(':') && child.path !== '/');
- })
- const logoutHandler = () => {
- loginUserStore.logoutUser()
- router.push('/problems')
- }
- const handleProfile = () => {
- ElMessage.info('功能开发中,敬请期待')
- }
- </script>
- <style scoped>
- .user-layout {
- display: flex;
- flex-direction: column;
- min-height: 100vh;
- }
- el-main{
- flex: 1;
- }
- .header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 20px;
- border-bottom: 1px solid var(--el-border-color);
- }
- .header-left {
- display: flex;
- align-items: center;
- gap: 10px;
- }
- .logo {
- width: 40px;
- height: 40px;
- }
- .title {
- margin: 0;
- font-size: 20px;
- }
- .nav {
- flex: 1;
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 28px;
- }
- .nav-link {
- display: flex;
- align-items: center;
- gap: 6px;
- height: auto;
- padding: 2px 4px;
- font-size: 14px;
- color: var(--el-text-color-regular);
- text-decoration: none;
- border-bottom: 2px solid transparent;
- transition: color 0.2s, border-color 0.2s;
- }
- .nav-link:hover {
- color: var(--el-color-primary);
- }
- .nav-link.active {
- color: var(--el-color-primary);
- border-bottom-color: var(--el-color-primary);
- }
- .header-right {
- display: flex;
- align-items: center;
- gap: 10px;
- }
- .username {
- font-size: 14px;
- color: var(--el-text-color-regular);
- }
- .user-btn {
- display: flex;
- align-items: center;
- gap: 6px;
- cursor: pointer;
- transition: color 0.2s;
- }
- .user-btn:hover {
- color: var(--el-color-primary);
- }
- .user-avatar {
- font-size: 20px;
- color: var(--el-color-primary);
- }
- </style>
|