Files
pig-farm-controller-fe/src/layouts/MainLayout.vue
2025-09-30 22:35:36 +08:00

229 lines
5.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-container class="layout-container">
<!-- 侧边栏菜单 -->
<el-aside :width="isCollapse ? '64px' : '200px'" class="sidebar">
<div class="logo" @click="toggleCollapse">
<h2 v-if="!isCollapse" class="logo-text">猪场管理系统</h2>
<el-icon v-else class="logo-icon"><Menu /></el-icon>
</div>
<el-menu
:default-active="activeMenu"
class="sidebar-menu"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
:collapse="isCollapse"
:collapse-transition="false"
router
>
<el-menu-item index="/">
<el-icon><House /></el-icon>
<template #title>首页</template>
</el-menu-item>
<el-menu-item index="/devices">
<el-icon><Monitor /></el-icon>
<template #title>设备管理</template>
</el-menu-item>
<el-menu-item index="/plans">
<el-icon><Calendar /></el-icon>
<template #title>计划管理</template>
</el-menu-item>
</el-menu>
</el-aside>
<!-- 主区域 -->
<el-container>
<!-- 头部 -->
<el-header class="header">
<div class="header-content">
<div class="header-left">
<el-button link @click="toggleCollapse">
<el-icon><Expand v-if="isCollapse" /><Fold v-else /></el-icon>
</el-button>
<h3 class="page-title">{{ currentPageTitle }}</h3>
</div>
<div class="user-info">
<el-dropdown>
<span class="el-dropdown-link">
{{ username }} <el-icon><ArrowDown /></el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>个人信息</el-dropdown-item>
<el-dropdown-item @click="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</el-header>
<!-- 主内容区 -->
<el-main class="main-content">
<router-view />
</el-main>
<!-- 底部 -->
<el-footer class="footer">
<p>© 2025 猪场管理系统. All rights reserved.</p>
</el-footer>
</el-container>
</el-container>
</template>
<script>
import { ref, computed, onMounted, onUnmounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { House, Monitor, Calendar, ArrowDown, Menu, Fold, Expand } from '@element-plus/icons-vue';
export default {
name: 'MainLayout',
components: {
House,
Monitor,
Calendar,
ArrowDown,
Menu,
Fold,
Expand
},
setup() {
const route = useRoute();
const router = useRouter();
const isCollapse = ref(false);
const username = ref(localStorage.getItem('username') || '管理员');
// 监听localStorage变化实时更新用户名
const handleStorageChange = () => {
username.value = localStorage.getItem('username') || '管理员';
};
onMounted(() => {
window.addEventListener('storage', handleStorageChange);
});
onUnmounted(() => {
window.removeEventListener('storage', handleStorageChange);
});
const toggleCollapse = () => {
isCollapse.value = !isCollapse.value;
};
const activeMenu = computed(() => {
return route.path;
});
const currentPageTitle = computed(() => {
const routeMap = {
'/': '系统首页',
'/devices': '设备管理',
'/plans': '计划管理'
};
return routeMap[route.path] || '猪场管理系统';
});
const logout = () => {
localStorage.removeItem('jwt_token');
localStorage.removeItem('username'); // 清除用户名
username.value = '管理员'; // 重置显示
router.push('/login');
};
return {
isCollapse,
activeMenu,
currentPageTitle,
toggleCollapse,
logout,
username
};
}
};
</script>
<style scoped>
.layout-container {
min-height: 100vh;
}
.sidebar {
background-color: #545c64;
box-shadow: 2px 0 6px rgba(0, 21, 18, 0.1);
transition: width 0.3s ease;
overflow: hidden;
}
.logo {
height: 60px;
display: flex;
align-items: center;
justify-content: center;
color: white;
background-color: #454d54;
cursor: pointer;
transition: all 0.3s ease;
}
.logo-text {
margin: 0;
font-size: 18px;
white-space: nowrap;
}
.logo-icon {
font-size: 24px;
}
.sidebar-menu {
border-right: none;
height: calc(100% - 60px);
}
.sidebar-menu:not(.el-menu--collapse) {
width: 200px;
}
.header {
background-color: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 18, 0.1);
padding: 0;
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
padding: 0 20px;
}
.header-left {
display: flex;
align-items: center;
gap: 15px;
}
.page-title {
margin: 0;
font-size: 18px;
font-weight: 500;
}
.user-info {
margin-right: 10px;
}
.main-content {
background-color: #f5f5f5;
padding: 20px;
}
.footer {
background-color: #fff;
color: #666;
text-align: center;
font-size: 14px;
border-top: 1px solid #eee;
}
</style>