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