页面样式,svg

This commit is contained in:
2025-11-14 15:29:02 +08:00
parent 46003a646e
commit 6be3cc6abd
27 changed files with 585 additions and 180 deletions

View File

@@ -4,29 +4,50 @@
<div class="layout-content">
<!-- 侧边栏和内容 -->
<div class="content-wrapper" v-if="hasSidebarMenus">
<!-- 侧边栏 -->
<aside class="sidebar">
<!-- Logo区域 -->
<div class="sidebar-header">
<div class="logo-container">
<img src="@/assets/imgs/logo-icon.svg" alt="Logo" class="logo-icon" />
<div class="logo-text">
<div class="logo-title">管理后台</div>
<div class="logo-subtitle">红色思政平台</div>
<!-- 侧边栏 -->
<aside class="sidebar">
<!-- Logo区域 -->
<div class="sidebar-header">
<div class="logo-container">
<img src="@/assets/imgs/logo-icon.svg" alt="Logo" class="logo-icon" />
<div class="logo-text">
<div class="logo-title">管理后台</div>
<div class="logo-subtitle">红色思政平台</div>
</div>
</div>
</div>
</div>
<!-- 导航菜单 -->
<nav class="sidebar-nav">
<ChangeHome />
<MenuSidebar
:menus="sidebarMenus"
:collapsed="false"
@menu-click="handleMenuClick"
/>
</nav>
</aside>
<!-- 导航菜单 -->
<nav class="sidebar-nav">
<MenuSidebar :menus="sidebarMenus" :collapsed="false" @menu-click="handleMenuClick" />
</nav>
<div class="sidebar-footer">
<div class="sidebar-footer-contain">
<!-- 用户头像+名称 -->
<div class="user-info">
<img :src="getUserAvatar()" alt="用户头像" class="user-avatar" />
<span>{{ user?.username }}</span>
</div>
<div class="dropdown-item" @click="toggleDropdown">
<img src="@/assets/imgs/else.svg" alt="其他" class="dropdown-icon" />
</div>
</div>
<transition name="dropdown-up">
<div v-if="showDropdown" class="dropdown-menu" @mouseleave="showDropdown = false">
<div class="dropdown-item">
<img src="@/assets/imgs/home.svg" alt="用户界面" class="dropdown-icon" />
<ChangeHome />
</div>
<div class="dropdown-item" @click="handleLogout">
<img src="@/assets/imgs/logout.svg" alt="退出登录" class="dropdown-icon" />
<span>退出登录</span>
</div>
</div>
</transition>
</div>
</aside>
<!-- 页面内容 -->
<main class="main-content">
@@ -45,26 +66,32 @@
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { computed, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useStore } from 'vuex';
import type { SysMenu } from '@/types';
import { MenuType } from '@/types/enums';
import { MenuSidebar, ChangeHome } from '@/components';
import { FILE_DOWNLOAD_URL } from '@/config';
import defaultAvatar from '@/assets/imgs/default-avatar.png';
const route = useRoute();
const router = useRouter();
const store = useStore();
const user = computed(() => store.getters['auth/user']);
const showDropdown = ref(false);
// 获取所有菜单
const allMenus = computed(() => store.getters['auth/menuTree']);
// 获取所有顶层SIDEBAR菜单作为侧边栏
const sidebarMenus = computed(() => {
// 严格过滤type=SIDEBAR 且 layout='SidebarLayout' 的顶层菜单
return allMenus.value.filter((menu: SysMenu) =>
menu.type === MenuType.SIDEBAR &&
!menu.parentID &&
return allMenus.value.filter((menu: SysMenu) =>
menu.type === MenuType.SIDEBAR &&
!menu.parentID &&
(menu as any).layout === 'SidebarLayout'
);
});
@@ -78,6 +105,18 @@ function handleMenuClick(menu: SysMenu) {
router.push(menu.url);
}
}
function getUserAvatar() {
return user.value?.avatar ? `${FILE_DOWNLOAD_URL}/${user.value?.avatar}` : defaultAvatar;
}
function handleLogout() {
store.dispatch('auth/logout');
}
function toggleDropdown() {
showDropdown.value = !showDropdown.value;
}
</script>
<style lang="scss" scoped>
@@ -116,7 +155,7 @@ function handleMenuClick(menu: SysMenu) {
.sidebar-header {
padding: 24px 24px 1px;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
height: 97px;
height: 100px;
}
.logo-container {
@@ -155,27 +194,135 @@ function handleMenuClick(menu: SysMenu) {
flex: 1;
overflow-y: auto;
padding: 16px 16px 0;
// 美化滚动条(深色,适配白色背景)
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 3px;
&:hover {
background: #a8a8a8;
}
}
}
.sidebar-footer {
height: 50px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.sidebar-footer-contain {
display: flex;
align-items: center;
justify-content: space-between;
width: 80%;
height: 80%;
border-radius: 8px;
background-color: #F6F6F6;
.user-info {
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
color: #1f2933;
height: 100%;
}
.user-avatar {
/* width: 20px; */
height: 80%;
border-radius: 50%;
object-fit: cover;
flex-shrink: 0;
}
.dropdown-item {
display: flex;
align-items: center;
justify-content: center;
padding: 4px;
cursor: pointer;
border-radius: 6px;
&:hover {
background-color: #f5f5f5;
}
.dropdown-icon {
width: 16px;
height: 16px;
flex-shrink: 0;
object-fit: contain;
}
}
}
}
.dropdown-menu {
position: absolute;
bottom: 52px;
left: 50%;
transform: translateX(-50%);
background: #ffffff;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
border-radius: 6px;
padding: 8px 0;
min-width: 180px;
z-index: 10;
.dropdown-item {
padding: 8px 16px;
display: flex;
align-items: center;
cursor: pointer;
span,
.change-home-text {
font-size: 14px;
}
.dropdown-icon {
width: 16px;
height: 16px;
margin-right: 8px;
flex-shrink: 0;
object-fit: contain;
}
&:hover {
background-color: #f5f5f5;
}
}
}
.dropdown-up-enter-active,
.dropdown-up-leave-active {
transition: all 0.15s ease-out;
}
.dropdown-up-enter-from,
.dropdown-up-leave-to {
opacity: 0;
transform: translate(-50%, 6px);
}
.dropdown-up-enter-to,
.dropdown-up-leave-from {
opacity: 1;
transform: translate(-50%, 0);
}
.main-content {
flex: 1;
background: #F9FAFB;
@@ -184,21 +331,21 @@ function handleMenuClick(menu: SysMenu) {
padding: 20px;
box-sizing: border-box;
height: 100vh;
// 美化滚动条
&::-webkit-scrollbar {
width: 8px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
&::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 4px;
&:hover {
background: #a8a8a8;
}
@@ -216,24 +363,24 @@ function handleMenuClick(menu: SysMenu) {
padding: 20px;
box-sizing: border-box;
widows: 100vw;
// 美化滚动条
&::-webkit-scrollbar {
width: 8px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
&::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 4px;
&:hover {
background: #a8a8a8;
}
}
}
</style>