big-event-frontend/src/views/LayoutView.vue
2025-01-21 10:09:12 +08:00

290 lines
9.5 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.

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import {
Management,
Promotion,
UserFilled,
User,
Crop,
EditPen,
SwitchButton,
CaretBottom
} from '@element-plus/icons-vue';
import avatar from '@/assets/default.png';
import { userInfoService } from '@/api/user.js';
import useUserInfoStore from '@/stores/userInfo.js';
import { useTokenStore } from '@/stores/token.js';
import { useRouter } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
const tokenStore = useTokenStore();
const userInfoStore = useUserInfoStore();
const router = useRouter();
const isPortrait = ref(false);
const getUserInfo = async () => {
let result = await userInfoService();
userInfoStore.setInfo(result.data);
};
const handleCommand = (command) => {
if (command === 'logout') {
ElMessageBox.confirm(
'您确认要退出吗?',
'温馨提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(async () => {
tokenStore.removeToken();
userInfoStore.removeInfo();
router.push('/login');
ElMessage({
type: 'success',
message: '退出登录成功',
});
})
.catch(() => {
ElMessage({
type: 'info',
message: '用户取消了退出登录',
});
});
} else {
router.push('/user/' + command);
}
};
const checkIsPortrait = () => {
isPortrait.value = window.innerWidth / window.innerHeight < 1;
};
onMounted(() => {
checkIsPortrait();
window.addEventListener('resize', checkIsPortrait);
});
onUnmounted(() => {
window.removeEventListener('resize', checkIsPortrait);
});
getUserInfo();
</script>
<template>
<el-container class="layout-container">
<!-- 左侧菜单宽高比大于1时显示 -->
<el-aside v-if="!isPortrait" width="200px">
<div class="el-aside__logo"></div>
<el-menu active-text-color="#ffd04b" background-color="#232323" text-color="#fff" router>
<el-menu-item index="/article/category">
<el-icon>
<Management />
</el-icon>
<span>文章分类</span>
</el-menu-item>
<el-menu-item index="/article/manage">
<el-icon>
<Promotion />
</el-icon>
<span>文章管理</span>
</el-menu-item>
<el-sub-menu>
<template #title>
<el-icon>
<UserFilled />
</el-icon>
<span>个人中心</span>
</template>
<el-menu-item index="/user/info">
<el-icon>
<User />
</el-icon>
<span>基本资料</span>
</el-menu-item>
<el-menu-item index="/user/avatar">
<el-icon>
<Crop />
</el-icon>
<span>更换头像</span>
</el-menu-item>
<el-menu-item index="/user/resetPassword">
<el-icon>
<EditPen />
</el-icon>
<span>重置密码</span>
</el-menu-item>
</el-sub-menu>
</el-menu>
</el-aside>
<!-- 顶部菜单宽高比小于1时显示 -->
<el-header v-if="isPortrait" class="mobile-header">
<el-menu mode="horizontal" active-text-color="#ffd04b" background-color="#232323" text-color="#fff" router>
<el-menu-item index="/article/category">
<el-icon>
<Management />
</el-icon>
<span>文章分类</span>
</el-menu-item>
<el-menu-item index="/article/manage">
<el-icon>
<Promotion />
</el-icon>
<span>文章管理</span>
</el-menu-item>
<el-sub-menu>
<template #title>
<el-icon>
<UserFilled />
</el-icon>
<span>个人中心</span>
</template>
<el-menu-item index="/user/info">
<el-icon>
<User />
</el-icon>
<span>基本资料</span>
</el-menu-item>
<el-menu-item index="/user/avatar">
<el-icon>
<Crop />
</el-icon>
<span>更换头像</span>
</el-menu-item>
<el-menu-item index="/user/resetPassword">
<el-icon>
<EditPen />
</el-icon>
<span>重置密码</span>
</el-menu-item>
</el-sub-menu>
</el-menu>
<el-dropdown placement="bottom-end" @command="handleCommand">
<span class="el-dropdown__box">
<el-avatar :src="userInfoStore.info.userPic ? userInfoStore.info.userPic : avatar" />
<el-icon>
<CaretBottom />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="info" :icon="User">基本资料</el-dropdown-item>
<el-dropdown-item command="avatar" :icon="Crop">更换头像</el-dropdown-item>
<el-dropdown-item command="resetPassword" :icon="EditPen">重置密码</el-dropdown-item>
<el-dropdown-item command="logout" :icon="SwitchButton">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-header>
<!-- 右侧主区域 -->
<el-container>
<!-- 头部区域 -->
<el-header v-if="!isPortrait">
<div>程序员:<strong>{{ userInfoStore.info.nickname }}</strong></div>
<el-dropdown placement="bottom-end" @command="handleCommand">
<span class="el-dropdown__box">
<el-avatar :src="userInfoStore.info.userPic ? userInfoStore.info.userPic : avatar" />
<el-icon>
<CaretBottom />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="info" :icon="User">基本资料</el-dropdown-item>
<el-dropdown-item command="avatar" :icon="Crop">更换头像</el-dropdown-item>
<el-dropdown-item command="resetPassword" :icon="EditPen">重置密码</el-dropdown-item>
<el-dropdown-item command="logout" :icon="SwitchButton">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-header>
<!-- 中间区域 -->
<el-main>
<router-view></router-view>
</el-main>
<!-- 底部区域 -->
<el-footer>大事件 ©2025 Created by xclele</el-footer>
</el-container>
</el-container>
</template>
<style lang="scss" scoped>
.layout-container {
height: 100vh;
.el-aside {
background-color: #232323;
&__logo {
height: 120px;
background: url('@/assets/logo.png') no-repeat center / 120px auto;
}
.el-menu {
border-right: none;
}
}
.el-header {
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
.el-dropdown__box {
display: flex;
align-items: center;
.el-icon {
color: #999;
margin-left: 10px;
}
&:active,
&:focus {
outline: none;
}
}
}
.el-footer {
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: #666;
}
@media (orientation: portrait) {
.el-aside {
display: none;
}
.mobile-header {
display: flex;
background-color: #232323;
.el-menu {
width: 100%;
}
.el-dropdown__box {
display: flex;
align-items: center;
.el-icon {
color: #999;
margin-left: 10px;
}
&:active,
&:focus {
outline: none;
}
}
}
}
}
</style>