<template>
|
<el-container class="main-layout">
|
<el-aside :width="collapsed ? '64px' : '200px'">
|
<div class="logo" @click="collapsed = !collapsed">
|
<span v-if="!collapsed">WMS管理系统</span>
|
<span v-else>W</span>
|
</div>
|
<el-scrollbar>
|
<el-menu
|
:default-active="activeMenu"
|
class="el-menu-vertical"
|
:collapse="collapsed"
|
:router="true"
|
@select="handleMenuSelect"
|
>
|
<template v-for="item in menuList" :key="item.id">
|
<el-sub-menu v-if="item.children?.length" :index="String(item.id)">
|
<template #title>
|
<span>{{ item.name || item.text }}</span>
|
</template>
|
<el-menu-item
|
v-for="child in item.children"
|
:key="child.id"
|
:index="child.path || String(child.id)"
|
>
|
<span>{{ child.name || child.text }}</span>
|
</el-menu-item>
|
</el-sub-menu>
|
<el-menu-item v-else :index="item.path || String(item.id)">
|
<span>{{ item.name || item.text }}</span>
|
</el-menu-item>
|
</template>
|
</el-menu>
|
</el-scrollbar>
|
</el-aside>
|
<el-container>
|
<el-header>
|
<div class="header-left">
|
<span class="project-title">WIDESEA WMS</span>
|
</div>
|
<div class="header-right">
|
<span class="username">{{ username }}</span>
|
<el-button link @click="handleLogout">退出</el-button>
|
</div>
|
</el-header>
|
<el-main>
|
<router-view />
|
</el-main>
|
</el-container>
|
</el-container>
|
</template>
|
|
<script setup lang="ts">
|
import { ref, computed, onMounted } from 'vue';
|
import { useRoute, useRouter } from 'vue-router';
|
import { useMenuStore } from '@/store/modules/menu';
|
import { ElMessage } from 'element-plus';
|
|
const route = useRoute();
|
const router = useRouter();
|
const menuStore = useMenuStore();
|
|
const collapsed = ref(false);
|
const menuList = ref<any[]>([]);
|
|
const username = computed(() => {
|
const userStr = localStorage.getItem('user');
|
if (userStr) {
|
try {
|
const user = JSON.parse(userStr);
|
return user.userTrueName || user.userName || '未登录';
|
} catch {}
|
}
|
return '未登录';
|
});
|
|
const activeMenu = computed(() => route.path);
|
|
function handleMenuSelect(index: string) {
|
const menu = menuStore.findMenuByPath(index);
|
if (menu?.path) {
|
router.push(menu.path);
|
}
|
}
|
|
async function loadMenus() {
|
try {
|
const menus = await menuStore.loadMenus();
|
menuList.value = menus || [];
|
} catch (error) {
|
console.error('加载菜单失败:', error);
|
ElMessage.error('加载菜单失败');
|
}
|
}
|
|
function handleLogout() {
|
localStorage.removeItem('user');
|
menuStore.resetMenus();
|
router.push('/login');
|
}
|
|
onMounted(() => {
|
loadMenus();
|
});
|
</script>
|
|
<style scoped>
|
.main-layout {
|
height: 100%;
|
}
|
.el-aside {
|
background-color: #304156;
|
color: #fff;
|
transition: width 0.3s;
|
}
|
.logo {
|
height: 60px;
|
line-height: 60px;
|
text-align: center;
|
font-size: 18px;
|
color: #fff;
|
cursor: pointer;
|
background-color: #263445;
|
}
|
.el-menu-vertical {
|
border-right: none;
|
background-color: transparent;
|
}
|
.el-menu-vertical:not(.el-menu--collapse) {
|
width: 200px;
|
}
|
.el-header {
|
background-color: #fff;
|
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
line-height: 60px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 0 20px;
|
}
|
.project-title {
|
font-weight: 600;
|
font-size: 16px;
|
color: #333;
|
}
|
.header-right {
|
display: flex;
|
align-items: center;
|
gap: 12px;
|
}
|
.username {
|
color: #666;
|
}
|
.el-main {
|
background-color: #f0f2f5;
|
padding: 16px;
|
}
|
</style>
|