|
|
<script setup> // 导航栏在这
import { computed, ref } from 'vue' import { useRoute, useRouter } from 'vue-router' import { ElMessage } from 'element-plus' import dmmn from '../assets/link.png' import ChangePassword from '@/components/changePassword.vue' import { useAdminStore } from '@/store' import { storeToRefs } from 'pinia' import { filterMenu, getRoutePath } from "@/utils/menuUtils.js";
// 存储接口返回的菜单数据
const menuList = ref([])
// 获取仓库实例
const adminStore = useAdminStore() // 解构状态(保持响应式) 获得 adminData(用户信息) 和 menuTree(菜单树)
const { adminData, menuTree } = storeToRefs(adminStore)
// 筛选权限菜单 ,menuTree 是组件通信拿的
menuList.value = filterMenu(menuTree.value)
console.log("menuList", menuList.value) // 获取当前路由
const route = useRoute()
// 通用函数:从菜单树中递归找出最匹配的 index
function findBestMatch(menuList, path) { let bestMatch = ''
function traverse(menus) { for (const item of menus) { const itemPath = getRoutePath(item) // 如果当前菜单的 path 是当前路径的前缀,可能是候选项
if (path.startsWith(itemPath) && itemPath.length > bestMatch.length) { bestMatch = itemPath }
if (item.children && item.children.length > 0) { traverse(item.children) } } }
traverse(menuList) return bestMatch || path // fallback 到当前路径
}
// 响应式高亮菜单
const activeMenu = computed(() => { return findBestMatch(menuList.value, route.path) }) const router = useRouter() const imgrule1 = dmmn const messageVisible = ref(false)
// 查看个人信息弹出框
const openMessage = function () { messageVisible.value = true } // 关闭个人信息
const closeMessage = function () { messageVisible.value = false } const message = function () { openMessage() }
// 显示修改密码弹窗
const showPasswordDialog = ref(false) const pwdRef = ref()
//打开修改密码弹窗
const openChangePassword = () => { showPasswordDialog.value = true } //关闭后清空密码表单
function onPwdDialogClosed() { // 调用子组件暴露的 resetFields
pwdRef.value?.resetFields() }
function logout() { const machineId = localStorage.getItem('machineId') localStorage.removeItem('token') adminStore.clearState() router.push('/login?machineId=' + machineId) ElMessage.success('退出成功') }
</script>
<template> <div class="main-container"> <!-- 背景毛玻璃层(作为内容容器) --> <div class="background-glass"> <!-- 侧边栏 --> <div class="sidebar-container"> <el-aside> <div class="logo"> <img src="../assets/新logo.png" alt="logo" style="width: 9vh; height: 9vh" /> </div> <el-menu :router="true" :default-active="activeMenu" style="min-height: 80vh;border:none;"> <!-- 递归渲染菜单层级 --> <template v-for="menu in menuList" :key="menu.id"> <!-- 有子菜单的父级菜单(menuType=2 且存在children) --> <el-sub-menu v-if="menu.children && menu.children.length > 0" :index="menu.id.toString()"> <template #title> <el-icon> <Folder /> </el-icon> <span>{{ menu.menuName }}</span> </template> <!-- 子菜单 --> <template v-for="child in menu.children" :key="child.id"> <!-- 子菜单为叶子节点(无children) --> <el-menu-item v-if="!child.children || child.children.length === 0" :index="getRoutePath(child)"> <span>{{ child.menuName }}</span> </el-menu-item>
<!-- 子菜单有下级 --> <el-sub-menu v-else :index="child.id.toString()"> <template #title> <span>{{ child.menuName }}</span> </template> <!-- 递归 下一级--> <template v-for="grandChild in child.children" :key="grandChild.id"> <el-menu-item :index="getRoutePath(grandChild)"> <span>{{ grandChild.menuName }}</span> </el-menu-item> </template> </el-sub-menu> </template> </el-sub-menu>
<!-- 无子菜单的一级菜单 --> <el-menu-item v-else :index="getRoutePath(menu)"> <el-icon> <Folder /> </el-icon> <span>{{ menu.menuName }}</span> </el-menu-item> </template> </el-menu> </el-aside> </div> <!-- 右侧内容区域 --> <div class="content-container"> <!-- 头部 --> <el-header class="header"> <el-menu class="el-menu-demo" mode="horizontal" :ellipsis="false"> <el-sub-menu index="1"> <template #title> <el-image :src="imgrule1" style="width: 53px; height: 53px" /> <span style="margin-left: 10px">{{ adminData.name }}</span> </template> <el-menu-item @click="message()">查看个人信息</el-menu-item> <el-menu-item @click="openChangePassword">修改密码</el-menu-item> <el-menu-item @click="logout">退出登录</el-menu-item> </el-sub-menu> </el-menu> </el-header> <!-- 主内容区域 --> <div class="main-area"> <el-main> <router-view></router-view> </el-main> </div> </div> </div>
<!-- 查看个人信息 --> <el-dialog v-model="messageVisible" title="查看个人信息" width="500px"> <el-form :model="adminData"> <el-form-item label="用户姓名" label-width="100px" label-position="left"> <span class="message-font">{{ adminData.adminName }}</span> </el-form-item> <el-form-item label="精网号" label-width="100px" label-position="left"> <span class="message-font">{{ adminData.account }}</span> </el-form-item> <el-form-item label="地区" label-width="100px" label-position="left"> <span class="message-font">{{ adminData.markets }}</span> </el-form-item> <el-form-item label="注册时间" label-width="100px" label-position="left"> <span class="message-font">{{ adminData.createTime }}</span> </el-form-item> </el-form> <template #footer> <div> <el-button text @click="closeMessage()">关闭</el-button> </div> </template> </el-dialog>
<!-- 自定义密码修改弹窗组件 --> <el-dialog v-model="showPasswordDialog" :center="true" width="470px" @closed="onPwdDialogClosed"> <ChangePassword ref="pwdRef" @confirm="showPasswordDialog = false" /> </el-dialog> </div> </template>
<style scoped> /* 主容器,设置背景图并居中 */ .main-container { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-image: url('@/assets/background.jpg'); background-size: cover; background-position: center center; background-repeat: no-repeat; overflow: hidden; }
/* 背景毛玻璃层(作为内容容器) */ .background-glass { position: absolute; top: 1vh; left: 1vh; right: 1vh; bottom: 1vh; background: rgba(255, 255, 255, 0.3); /* 更透明的背景 */ backdrop-filter: blur(10px); /* 毛玻璃效果 */ z-index: 1; display: flex; flex-direction: row; padding: 20px; border-radius: 12px; }
/* 侧边栏容器 */ .sidebar-container { flex-shrink: 0; }
.el-aside { width: 15vw; height: 100%; background: rgba(255, 255, 255, 0.85); /* 半透明白色背景 */ backdrop-filter: blur(5px); /* 毛玻璃效果 */ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); /* 添加阴影增强层次感 */ border-radius: 12px; overflow-y: auto; /* 应用自定义滚动条 */ }
/* 内容区域容器 */ .content-container { flex: 1; display: flex; flex-direction: column; margin-left: 5px; gap: 5px; height: 100%; overflow: hidden; }
/* 头部样式 */ .header { background: rgba(255, 255, 255, 0.9); /* 半透明白色背景 */ backdrop-filter: blur(5px); /* 毛玻璃效果 */ height: 8vh; border-radius: 12px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); /* 添加阴影增强层次感 */ z-index: 80; }
/* 主内容区域容器 */ .main-area { flex: 1; background: rgba(255, 255, 255, 0.9); /* 半透明白色背景 */ backdrop-filter: blur(5px); /* 毛玻璃效果 */ border-radius: 12px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); /* 添加阴影增强层次感 */ overflow: hidden; display: flex; flex-direction: column; }
/* 主内容区域样式 */ .el-main { height: 100%; padding: 20px; background: transparent; overflow-y: auto; /* 应用自定义滚动条 */ }
.logo { display: flex; align-items: center; justify-content: center; height: 12vh; }
.el-menu-demo { border: none; padding: 0; float: right; background: transparent !important; /* 最高优先级的透明 */ }
/* 侧边栏菜单样式优化 */ .el-menu { background: transparent !important; }
::v-deep(.el-sub-menu__title:hover) { background: transparent !important; }
.message-font { /* 个人信息字体样式 */ font-size: 16px; font-weight: bold; }
/* 确保全局el-container适应容器 */ :deep(.el-container) { /* vue3的深度选择器,用于覆盖element-plus的默认样式 */ min-height: 100%; width: 100%; background: transparent; }
/* 为侧边栏和主内容区域添加滚动条样式 */ .el-aside, .el-main { scrollbar-width: thin; /* Firefox */ scrollbar-color: rgba(0, 0, 0, 0.3) rgba(255, 255, 255, 0.2); /* Firefox滑块和轨道颜色 */ } </style>
|