| | |
| | | <template> |
| | | <el-container class="layout-container"> |
| | | <!-- 侧边栏 --> |
| | | <el-aside width="200px" class="sidebar"> |
| | | <div class="logo"> |
| | | <h2>蓉易创</h2> |
| | | <!-- 顶部栏 --> |
| | | <el-header class="layout-header"> |
| | | <div class="header-content"> |
| | | <div class="title-container"> |
| | | <img src="/logo.jpg" alt="蓉易创" class="logo-icon" /> |
| | | <span class="system-title">蓉易创比赛管理</span> |
| | | </div> |
| | | <el-dropdown @command="handleCommand"> |
| | | <span class="el-dropdown-link"> |
| | | {{ currentUserName }} |
| | | <el-icon class="el-icon--right"> |
| | | <arrow-down /> |
| | | </el-icon> |
| | | </span> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item command="profile">个人信息</el-dropdown-item> |
| | | <el-dropdown-item command="logout">退出登录</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </div> |
| | | <el-menu |
| | | :default-active="$route.path" |
| | | class="sidebar-menu" |
| | | router |
| | | unique-opened |
| | | > |
| | | <el-menu-item |
| | | v-for="item in menuItems" |
| | | :key="item.path" |
| | | :index="item.path" |
| | | </el-header> |
| | | |
| | | <!-- 下方容器:左侧菜单 + 右侧内容 --> |
| | | <el-container class="main-container"> |
| | | <el-aside width="200px" class="layout-aside"> |
| | | <el-menu |
| | | :default-active="$route.path" |
| | | router |
| | | background-color="transparent" |
| | | text-color="#666666" |
| | | active-text-color="#1E3A8A" |
| | | > |
| | | <el-icon><component :is="item.icon" /></el-icon> |
| | | <span>{{ item.title }}</span> |
| | | </el-menu-item> |
| | | </el-menu> |
| | | </el-aside> |
| | | > |
| | | <el-menu-item index="/dashboard"> |
| | | <el-icon><House /></el-icon> |
| | | <span>工作台</span> |
| | | </el-menu-item> |
| | | |
| | | <!-- 主内容区 --> |
| | | <el-container> |
| | | <!-- 顶部导航 --> |
| | | <el-header class="header"> |
| | | <div class="header-left"> |
| | | <h3>{{ currentPageTitle }}</h3> |
| | | </div> |
| | | <div class="header-right"> |
| | | <el-dropdown @command="handleCommand"> |
| | | <span class="user-info"> |
| | | <el-icon><User /></el-icon> |
| | | <span>{{ currentUserName }}</span> |
| | | <el-tag size="small" style="margin-left: 8px">{{ currentUserRole }}</el-tag> |
| | | <el-icon><ArrowDown /></el-icon> |
| | | </span> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item command="profile">个人信息</el-dropdown-item> |
| | | <el-dropdown-item command="logout" divided>退出登录</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | </div> |
| | | </el-header> |
| | | |
| | | <!-- 主内容 --> |
| | | <el-main class="main-content"> |
| | | <el-menu-item index="/activity"> |
| | | <el-icon><Calendar /></el-icon> |
| | | <span>比赛信息</span> |
| | | </el-menu-item> |
| | | <el-menu-item index="/judge"> |
| | | <el-icon><User /></el-icon> |
| | | <span>评委管理</span> |
| | | </el-menu-item> |
| | | <el-menu-item index="/rating-scheme"> |
| | | <el-icon><Document /></el-icon> |
| | | <span>评分模板</span> |
| | | </el-menu-item> |
| | | <el-menu-item index="/player"> |
| | | <el-icon><UserFilled /></el-icon> |
| | | <span>报名审核</span> |
| | | </el-menu-item> |
| | | <el-menu-item index="/project-review"> |
| | | <el-icon><Files /></el-icon> |
| | | <span>项目评审</span> |
| | | </el-menu-item> |
| | | <el-menu-item index="/competition-promotion"> |
| | | <el-icon><TrendCharts /></el-icon> |
| | | <span>比赛晋级</span> |
| | | </el-menu-item> |
| | | <el-menu-item index="/carousel"> |
| | | <el-icon><Picture /></el-icon> |
| | | <span>新闻与推广</span> |
| | | </el-menu-item> |
| | | <el-menu-item index="/region"> |
| | | <el-icon><Location /></el-icon> |
| | | <span>区域管理</span> |
| | | </el-menu-item> |
| | | <el-menu-item index="/employee"> |
| | | <el-icon><Avatar /></el-icon> |
| | | <span>员工管理</span> |
| | | </el-menu-item> |
| | | </el-menu> |
| | | </el-aside> |
| | | |
| | | <el-main class="layout-main"> |
| | | <router-view /> |
| | | </el-main> |
| | | </el-container> |
| | |
| | | |
| | | <script setup lang="ts"> |
| | | import { computed } from 'vue' |
| | | import { useRoute, useRouter } from 'vue-router' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | import { getCurrentUserDisplayName, getCurrentUserRoleText, clearAuth } from '@/utils/auth' |
| | | import { useRouter } from 'vue-router' |
| | | import { House, Calendar, User, Document, UserFilled, Files, TrendCharts, Picture, Location, Avatar, ArrowDown } from '@element-plus/icons-vue' |
| | | |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | |
| | | // 当前用户信息 |
| | | const currentUserName = computed(() => getCurrentUserDisplayName()) |
| | | const currentUserRole = computed(() => getCurrentUserRoleText()) |
| | | const userInfo = computed(() => ({ |
| | | name: '管理员' |
| | | })) |
| | | |
| | | // 菜单项 |
| | | const menuItems = [ |
| | | { path: '/dashboard', title: '工作台', icon: 'House' }, |
| | | { path: '/activity', title: '比赛管理', icon: 'Trophy' }, |
| | | { path: '/judge', title: '评委管理', icon: 'User' }, |
| | | { path: '/rating-scheme', title: '评分模板', icon: 'Document' }, |
| | | { path: '/player', title: '报名审核', icon: 'UserFilled' }, |
| | | { path: '/project-review', title: '项目评审', icon: 'View' }, |
| | | { path: '/competition-promotion', title: '比赛晋级', icon: 'Promotion' }, |
| | | { path: '/carousel', title: '新闻与推广', icon: 'Picture' }, |
| | | { path: '/region', title: '区域管理', icon: 'Location' }, |
| | | { path: '/employee', title: '员工管理', icon: 'Avatar' } |
| | | ] |
| | | const currentUserName = computed(() => userInfo.value.name || '用户') |
| | | |
| | | // 当前页面标题 |
| | | const currentPageTitle = computed(() => { |
| | | const currentItem = menuItems.find(item => item.path === route.path) |
| | | return currentItem?.title || '蓉易创管理系统' |
| | | }) |
| | | |
| | | // 处理用户操作 |
| | | const handleCommand = async (command: string) => { |
| | | if (command === 'logout') { |
| | | try { |
| | | await ElMessageBox.confirm('确定要退出登录吗?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }) |
| | | |
| | | clearAuth() |
| | | ElMessage.success('退出登录成功') |
| | | const handleCommand = (command: string) => { |
| | | switch (command) { |
| | | case 'profile': |
| | | router.push('/profile') |
| | | break |
| | | case 'logout': |
| | | localStorage.removeItem('token') |
| | | router.push('/login') |
| | | } catch { |
| | | // 用户取消 |
| | | } |
| | | } else if (command === 'profile') { |
| | | ElMessage.info('个人信息功能待开发') |
| | | break |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | <style scoped> |
| | | /* 整体布局容器 */ |
| | | .layout-container { |
| | | height: 100vh; |
| | | width: 100vw; |
| | | } |
| | | |
| | | .sidebar { |
| | | background-color: #304156; |
| | | color: white; |
| | | |
| | | .logo { |
| | | height: 60px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | border-bottom: 1px solid #434a50; |
| | | |
| | | h2 { |
| | | color: white; |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | |
| | | .sidebar-menu { |
| | | background-color: #304156; |
| | | border-right: none; |
| | | |
| | | :deep(.el-menu-item) { |
| | | color: #bfcbd9; |
| | | |
| | | &:hover { |
| | | background-color: #434a50; |
| | | color: white; |
| | | } |
| | | |
| | | &.is-active { |
| | | background-color: #409eff; |
| | | color: white; |
| | | } |
| | | } |
| | | } |
| | | /* 顶部栏样式 */ |
| | | .layout-header { |
| | | background-color: #FFFFFF; |
| | | color: #333; |
| | | line-height: 60px; |
| | | padding: 0 20px; |
| | | border-bottom: 1px solid #E5E7EB; |
| | | } |
| | | |
| | | .header { |
| | | background-color: white; |
| | | border-bottom: 1px solid #e4e7ed; |
| | | .header-content { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | height: 100%; |
| | | } |
| | | |
| | | .title-container { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | padding: 0 20px; |
| | | |
| | | .header-left { |
| | | h3 { |
| | | color: #303133; |
| | | font-size: 16px; |
| | | font-weight: 500; |
| | | } |
| | | } |
| | | |
| | | .header-right { |
| | | .user-info { |
| | | display: flex; |
| | | align-items: center; |
| | | cursor: pointer; |
| | | color: #606266; |
| | | |
| | | .el-icon { |
| | | margin: 0 4px; |
| | | } |
| | | |
| | | &:hover { |
| | | color: #409eff; |
| | | } |
| | | } |
| | | } |
| | | gap: 8px; |
| | | } |
| | | |
| | | .main-content { |
| | | background-color: #f5f5f5; |
| | | min-height: calc(100vh - 60px); |
| | | .logo-icon { |
| | | width: 48px; |
| | | height: 48px; |
| | | } |
| | | |
| | | .system-title { |
| | | font-size: 20px; |
| | | font-weight: bold; |
| | | color: #333; |
| | | } |
| | | |
| | | /* 主要容器 */ |
| | | .main-container { |
| | | height: calc(100vh - 60px); |
| | | } |
| | | |
| | | /* 侧边栏样式 */ |
| | | .layout-aside { |
| | | background-color: #FFFFFF; |
| | | height: 100%; |
| | | border-right: 1px solid #E5E7EB; |
| | | } |
| | | |
| | | .sidebar-menu { |
| | | height: 100%; |
| | | border-right: none; |
| | | } |
| | | |
| | | /* 菜单项样式 */ |
| | | .el-menu-item.is-active { |
| | | background-color: #3B82F6 !important; |
| | | color: #FFFFFF !important; |
| | | border-radius: 6px; |
| | | margin: 2px 8px; |
| | | } |
| | | |
| | | .el-menu-item:hover { |
| | | background-color: #EBF4FF !important; |
| | | color: #1E3A8A !important; |
| | | border-radius: 6px; |
| | | margin: 2px 8px; |
| | | } |
| | | |
| | | /* 主内容区域 */ |
| | | .layout-main { |
| | | background-color: #FFFFFF; |
| | | padding: 20px; |
| | | } |
| | | |
| | | /* 下拉菜单样式 */ |
| | | .el-dropdown-link { |
| | | cursor: pointer; |
| | | color: #333; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .el-dropdown-link:hover { |
| | | color: #409eff; |
| | | } |
| | | </style> |