This commit is contained in:
2025-07-15 18:02:29 +08:00
parent 2038ddc617
commit d636050aac
65 changed files with 17885 additions and 103 deletions
+282
View File
@@ -0,0 +1,282 @@
<template>
<div class="admin-layout">
<!-- 侧边栏 -->
<div class="sidebar">
<div class="logo-container">
<h1 class="title">零零七云计算后台控制面板</h1>
</div>
<el-scrollbar>
<el-menu
:default-active="activeMenu"
class="sidebar-menu"
background-color="#ffffff"
text-color="#333333"
active-text-color="#1890ff"
:unique-opened="true"
router
>
<sidebar-menu-item v-for="menu in menus" :key="menu.path" :menu="menu" />
</el-menu>
</el-scrollbar>
</div>
<!-- 主区域 -->
<div class="main-container">
<!-- 顶部导航 -->
<div class="navbar">
<div class="navbar-left">
<breadcrumb />
</div>
<div class="navbar-right">
<div class="navbar-item">
<el-tooltip content="全屏" placement="bottom">
<el-button type="text" class="header-btn" @click="toggleFullScreen">
<el-icon :size="18"><full-screen /></el-icon>
</el-button>
</el-tooltip>
</div>
<div class="navbar-item">
<el-dropdown trigger="click">
<div class="avatar-container">
<el-avatar :size="32" src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" />
<span class="username">{{ userStore.userInfo.user_name }}</span>
<el-icon class="el-icon--right"><arrow-down /></el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="router.push('/profile')">
<el-icon><user /></el-icon>个人信息
</el-dropdown-item>
<el-dropdown-item @click="router.push('/change-password')">
<el-icon><key /></el-icon>修改密码
</el-dropdown-item>
<el-dropdown-item divided @click="handleLogout">
<el-icon><switch-button /></el-icon>退出登录
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</div>
<!-- 标签页 -->
<tags-view />
<!-- 内容区域 -->
<div class="content-container">
<el-config-provider :locale="zhCn">
<router-view v-slot="{ Component }">
<transition name="fade" mode="out-in">
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
</el-config-provider>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import SidebarMenuItem from './SidebarMenuItem.vue'
import Breadcrumb from './Breadcrumb.vue'
import TagsView from './TagsView.vue'
import { menus as menuConfig } from '@/config/menus'
import {
FullScreen,
ArrowDown,
User,
Key,
SwitchButton
} from '@element-plus/icons-vue'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { ElMessageBox } from 'element-plus'
import {useUserStore} from "@/store/userStore.js";
const userStore = useUserStore()
const route = useRoute()
const router = useRouter()
// 侧边栏菜单数据
const menus = ref(menuConfig)
// 获取当前激活的菜单项
const activeMenu = computed(() => {
return route.path
})
// 切换全屏
const toggleFullScreen = () => {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen()
} else {
if (document.exitFullscreen) {
document.exitFullscreen()
}
}
}
// 退出登录
const handleLogout = () => {
ElMessageBox.confirm('确定要退出登录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
localStorage.removeItem('token')
router.push('/login')
}).catch(() => {})
}
</script>
<style scoped>
.admin-layout {
display: flex;
height: 100vh;
width: 100%;
}
/* 侧边栏样式 */
.sidebar {
width: 240px;
height: 100%;
background-color: #ffffff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
z-index: 20;
}
.logo-container {
height: 60px;
display: flex;
align-items: center;
padding: 0 16px;
color: #333;
background-color: #ffffff;
border-bottom: 1px solid #f0f0f0;
overflow: hidden;
}
.logo {
width: 32px;
height: 32px;
margin-right: 10px;
}
.title {
font-size: 18px;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
color: #1890ff;
}
.sidebar-menu {
border-right: none;
height: calc(100vh - 60px);
}
/* 主容器样式 */
.main-container {
flex: 1;
display: flex;
flex-direction: column;
background-color: #f0f2f5;
overflow: hidden;
}
/* 顶部导航栏样式 */
.navbar {
height: 60px;
padding: 0 15px;
background-color: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
display: flex;
align-items: center;
justify-content: space-between;
z-index: 10;
}
.navbar-left {
display: flex;
align-items: center;
}
.navbar-right {
display: flex;
align-items: center;
}
.navbar-item {
padding: 0 10px;
height: 60px;
display: flex;
align-items: center;
}
.header-btn {
height: 40px;
width: 40px;
display: flex;
align-items: center;
justify-content: center;
color: #606266;
}
.header-btn:hover {
background-color: #f5f7fa;
border-radius: 4px;
}
.avatar-container {
display: flex;
align-items: center;
cursor: pointer;
padding: 0 12px;
height: 60px;
}
.avatar-container:hover {
background-color: rgba(0, 0, 0, 0.025);
}
.username {
margin: 0 8px;
font-size: 14px;
color: #606266;
}
/* 内容区域样式 */
.content-container {
flex: 1;
padding: 16px;
overflow-y: auto;
background-color: #f0f2f5;
position: relative;
}
/* 过渡动画 */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
:deep(.el-dropdown-menu__item) {
display: flex;
align-items: center;
}
:deep(.el-dropdown-menu__item i) {
margin-right: 8px;
}
</style>