From b0530ed9211230227a8f94e394eda779d5ae5fc1 Mon Sep 17 00:00:00 2001 From: birt <2499248221@qq.com> Date: 星期日, 13 四月 2025 01:51:52 +0800 Subject: [PATCH] birtzhang --- zhitan-vue/src/layout/components/Sidebar/index.vue | 350 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 346 insertions(+), 4 deletions(-) diff --git a/zhitan-vue/src/layout/components/Sidebar/index.vue b/zhitan-vue/src/layout/components/Sidebar/index.vue index 2fe645a..603f4f2 100644 --- a/zhitan-vue/src/layout/components/Sidebar/index.vue +++ b/zhitan-vue/src/layout/components/Sidebar/index.vue @@ -3,17 +3,19 @@ :class="{ 'has-logo': showLogo }" :style="{ backgroundColor: sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground }" > - <logo v-if="showLogo" :collapse="isCollapse" /> <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper"> + <!-- 棣栭〉鏃朵笉鏄剧ず浠讳綍鑿滃崟椤� --> <el-menu + v-if="!isHomePage" :default-active="activeMenu" :collapse="isCollapse" - :background-color="sideTheme === 'theme-dark' ? '#232D70' : '#fff'" + :background-color="'transparent'" :text-color="sideTheme === 'theme-dark' ? '#fff' : '#000'" :unique-opened="true" :active-text-color="theme" :collapse-transition="false" mode="vertical" + class="custom-menu" > <sidebar-item v-for="(route, index) in sidebarRouters" @@ -22,24 +24,91 @@ :base-path="route.path" /> </el-menu> + <!-- 棣栭〉鏃剁殑绌虹櫧鍖哄煙 --> + <div v-else class="home-empty-menu"></div> </el-scrollbar> + + <!-- 搴曢儴鐢ㄦ埛鍖哄煙 --> + <div class="sidebar-footer" :class="{ 'collapsed': isCollapse, 'theme-light': sideTheme === 'theme-light' }"> + <div class="user-avatar-container"> + <img :src="userStore.avatar" class="user-avatar" /> + </div> + + <!-- 灞曞紑鐘舵�佷笅鏄剧ず瀹屾暣鍐呭 --> + <div class="user-info" v-if="!isCollapse"> + <div class="username">{{ userStore.name || 'admin' }}</div> + + <div class="action-buttons"> + <div class="action-button" :class="{'theme-light': sideTheme === 'theme-light'}" @click="toUserProfile"> + <el-icon><User /></el-icon> + <span>涓汉涓績</span> + </div> + + <div class="action-button" :class="{'theme-light': sideTheme === 'theme-light'}" @click="toggleTheme"> + <el-icon><Brush /></el-icon> + <span>鍒囨崲涓婚</span> + </div> + + <div class="action-button" :class="{'theme-light': sideTheme === 'theme-light'}" @click="handleLogout"> + <el-icon><SwitchButton /></el-icon> + <span>閫�鍑虹櫥褰�</span> + </div> + </div> + </div> + + <!-- 鎶樺彔鐘舵�佷笅鍙樉绀哄浘鏍囨寜閽� --> + <div class="collapsed-actions" v-if="isCollapse"> + <div class="action-icon" :class="{'theme-light': sideTheme === 'theme-light'}" @click="toUserProfile" title="涓汉涓績"> + <el-icon><User /></el-icon> + </div> + + <div class="action-icon" :class="{'theme-light': sideTheme === 'theme-light'}" @click="toggleTheme" title="鍒囨崲涓婚"> + <el-icon><Brush /></el-icon> + </div> + + <div class="action-icon" :class="{'theme-light': sideTheme === 'theme-light'}" @click="handleLogout" title="閫�鍑虹櫥褰�"> + <el-icon><SwitchButton /></el-icon> + </div> + </div> + </div> </div> </template> <script setup> -import Logo from "./Logo" import SidebarItem from "./SidebarItem" import variables from "@/assets/styles/variables.module.scss" import useAppStore from "@/store/modules/app" import useSettingsStore from "@/store/modules/settings" import usePermissionStore from "@/store/modules/permission" +import useUserStore from "@/store/modules/user" +import { User, Brush, SwitchButton } from '@element-plus/icons-vue' +import { ElMessageBox } from 'element-plus' +import { useRouter } from 'vue-router' +const router = useRouter() const route = useRoute() const appStore = useAppStore() const settingsStore = useSettingsStore() const permissionStore = usePermissionStore() +const userStore = useUserStore() const sidebarRouters = computed(() => permissionStore.sidebarRouters) + +// 鍒ゆ柇褰撳墠鏄惁涓洪椤� +const isHomePage = computed(() => { + return route.path === '/index' || route.path === '/' || route.fullPath.startsWith('/index') +}) + +// 棣栭〉涓撶敤璺敱锛屽彧鏈夐椤典竴涓彍鍗曢」 +const homePageRouters = computed(() => { + // 浠庡師濮嬭矾鐢变腑绛涢�夊嚭棣栭〉璺敱 + const homeRoute = sidebarRouters.value.find(route => { + return route.children && route.children.find(child => child.path === '/index') + }) + + return homeRoute ? [homeRoute] : [] +}) + const showLogo = computed(() => settingsStore.sidebarLogo) const sideTheme = computed(() => settingsStore.sideTheme) const theme = computed(() => settingsStore.theme) @@ -53,5 +122,278 @@ } return path }) + +function toUserProfile() { + router.push('/user/profile') +} + +function toggleTheme() { + if (settingsStore.sideTheme == "theme-dark") { + settingsStore.sideTheme = "theme-light" + document.querySelector("body").className = "themeLight" + } else { + settingsStore.sideTheme = "theme-dark" + document.querySelector("body").className = "themeDark" + } +} + +function handleLogout() { + ElMessageBox.confirm("纭畾娉ㄩ攢骞堕��鍑虹郴缁熷悧锛�", "鎻愮ず", { + confirmButtonText: "纭畾", + cancelButtonText: "鍙栨秷", + type: "warning", + }) + .then(() => { + userStore.logOut().then(() => { + location.href = "/index" + }) + }) + .catch(() => {}) +} </script> -<style lang="scss" scoped></style> +<style lang="scss" scoped> +:deep(.custom-menu) { + padding: 6px 0; + height: calc(100% - 150px); // 鐣欏嚭搴曢儴鐢ㄦ埛鍖哄煙鐨勭┖闂� + + // Override Element Plus default menu styles + .el-menu-item { + height: 38px !important; + line-height: 38px !important; + border-radius: 4px; + margin: 4px 10px; + width: calc(100% - 20px); + + &.is-active { + background-color: #3883FA !important; + color: #fff !important; + } + + &:hover { + background-color: rgba(56, 131, 250, 0.1) !important; + } + } + + .el-sub-menu { + .el-sub-menu__title { + height: 38px !important; + line-height: 38px !important; + border-radius: 4px; + margin: 4px 10px; + width: calc(100% - 20px); + + &:hover { + background-color: rgba(56, 131, 250, 0.1) !important; + } + } + + .el-menu-item { + padding-left: 45px !important; + min-width: auto !important; + + &.is-active { + padding-left: 45px !important; + } + } + + // For nested submenus + .el-menu { + .el-menu-item, + .el-sub-menu__title { + height: 38px !important; + line-height: 38px !important; + } + } + } +} + +// 棣栭〉绌虹櫧鑿滃崟鍖哄煙鏍峰紡 +.home-empty-menu { + height: calc(100% - 150px); +} + +// 搴曢儴鐢ㄦ埛鍖哄煙鏍峰紡 +.sidebar-footer { + position: absolute; + bottom: 72px; + left: 0; + width: 100%; + border-top: 1px solid rgba(255, 255, 255, 0.1); + padding: 16px; + display: flex; + flex-direction: column; + align-items: center; + + &.collapsed { + padding: 10px; + + .user-avatar-container { + margin-bottom: 10px; + } + } + + &.theme-light { + background-color: rgba(255, 255, 255, 0.6); + border-top: 1px solid rgba(0, 0, 0, 0.1); + + .user-avatar-container { + border-color: rgba(0, 0, 0, 0.1); + } + + .user-info { + .username { + color: #333; + } + } + } + + .user-avatar-container { + margin-bottom: 10px; + border: 2px dashed rgba(255, 255, 255, 0.3); + border-radius: 4px; + width: 54px; + height: 54px; + display: flex; + align-items: center; + justify-content: center; + + .user-avatar { + width: 38px; + height: 38px; + border-radius: 4px; + } + } + + .user-info { + width: 100%; + text-align: center; + + .username { + color: #fff; + font-size: 16px; + font-weight: 500; + margin-bottom: 16px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .action-buttons { + .action-button { + display: flex; + align-items: center; + justify-content: center; + background: rgba(56, 131, 250, 0.11); + border-radius: 9px; + border: 1px solid rgba(255, 255, 255, 0.3); + color: #fff; + padding: 10px; + margin-bottom: 10px; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s; + + &:hover { + background: rgba(56, 131, 250, 0.2); + } + + .el-icon { + margin-right: 8px; + font-size: 16px; + } + + span { + font-size: 14px; + } + + &.theme-light { + background-color: rgba(56, 131, 250, 1); + color: #fff; + border: 1px solid rgba(56, 131, 250, 0.8); + + &:hover { + background-color: rgba(56, 131, 250, 0.9); + } + + .el-icon { + color: #fff; + } + } + } + } + } + + .collapsed-actions { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + + .action-icon { + width: 40px; + height: 40px; + margin-bottom: 8px; + background: rgba(56, 131, 250, 0.11); + border: 1px solid rgba(255, 255, 255, 0.3); + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + + &:hover { + background: rgba(56, 131, 250, 0.2); + } + + .el-icon { + font-size: 20px; + color: #fff; + } + + &.theme-light { + background: rgba(56, 131, 250, 1); + border: 1px solid rgba(56, 131, 250, 0.8); + + &:hover { + background: rgba(56, 131, 250, 0.9); + } + + .el-icon { + color: #fff; + } + } + } + } +} + +.theme-light { + :deep(.custom-menu) { + // Override Element Plus menu styles for light theme + .el-menu-item { + &.is-active { + background-color: #3883FA !important; + color: #fff !important; + } + + &:hover { + background-color: rgba(56, 131, 250, 0.1) !important; + } + } + + .el-sub-menu { + .el-sub-menu__title { + &:hover { + background-color: rgba(56, 131, 250, 0.1) !important; + } + } + } + } +} + +// Add global style to override Element Plus defaults +:global(.el-menu--vertical .el-menu-item), +:global(.el-menu--vertical .el-sub-menu__title) { + height: 38px !important; + line-height: 38px !important; +} +</style> -- Gitblit v1.9.3