| src/assets/styles/sidebar.scss | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/layout/components/Sidebar/Logo.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/layout/components/Sidebar/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/layout/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/assets/styles/sidebar.scss
@@ -88,7 +88,7 @@ } // menu hover .sub-menu-title-noDropdown, .submenu-title-noDropdown, .el-sub-menu__title { &:hover { background-color: var(--menu-hover) !important; @@ -122,22 +122,45 @@ .hideSidebar { .sidebar-container { width: 54px !important; width: 68px !important; padding-left: 12px; padding-right: 0; } .main-container { margin-left: 54px; margin-left: 84px; } .sub-menu-title-noDropdown { .submenu-title-noDropdown { padding: 0 !important; position: relative; display: flex !important; align-items: center; justify-content: center; .el-tooltip { padding: 0 !important; display: inline-flex !important; align-items: center; justify-content: center; width: 100%; .svg-icon { margin-left: 20px; margin-left: 0; } } .el-menu-tooltip__trigger { width: 100%; display: inline-flex !important; align-items: center; justify-content: center; .svg-icon { width: 18px; height: 18px; margin-right: 0; flex-shrink: 0; } } } @@ -146,16 +169,32 @@ & > .el-sub-menu__title { padding: 0 !important; display: flex !important; align-items: center; justify-content: center; .svg-icon { margin-left: 20px; margin-left: 0; } } } .el-menu--collapse { > .el-menu-item, .el-sub-menu { & > .el-sub-menu__title { & > .el-sub-menu__title, &.el-menu-item { display: flex !important; align-items: center; justify-content: center; .svg-icon { width: 18px; height: 18px; margin-right: 0; flex-shrink: 0; } & > span { height: 0; width: 0; src/layout/components/Sidebar/Logo.vue
@@ -1,9 +1,8 @@ <template> <div class="sidebar-logo-container" :class="{ 'collapse': collapse }"> <div class="sidebar-logo-container" :class="{ collapse }"> <transition name="sidebarLogoFade"> <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/"> <img v-if="logoUrl" :src="logoUrl" class="sidebar-logo" @error="handleImageError" alt="公司Logo" /> <h1 v-if="!logoUrl" class="sidebar-title">{{ title }}</h1> <img :src="faviconUrl" class="sidebar-logo sidebar-favicon" alt="站点图标" /> </router-link> <router-link v-else key="expand" class="sidebar-logo-link" to="/"> <img v-if="logoUrl" :src="logoUrl" class="sidebar-logo" @error="handleImageError" alt="公司Logo" /> @@ -16,7 +15,7 @@ <script setup> import { ref, computed, onMounted, watch } from 'vue' import useUserStore from '@/store/modules/user' import defaultLogo from '@/assets/logo/logo.png' // 导入默认logo import defaultLogo from '@/assets/logo/logo.png' defineProps({ collapse: { @@ -27,24 +26,22 @@ const title = import.meta.env.VITE_APP_TITLE const userStore = useUserStore() const baseUrl = import.meta.env.BASE_URL || '/' const faviconUrl = `${baseUrl.replace(/\/?$/, '/') }favicon.ico`.replace(/([^:]\/)\/+/g, '$1') // 处理工厂名称,生成合法的文件名 const cleanFactoryName = computed(() => { if (!userStore.currentFactoryName) return '' return userStore.currentFactoryName.trim() }) // 动态logo路径 const logoUrl = ref('') // 检查logo是否存在并设置url const updateLogoUrl = () => { if (!cleanFactoryName.value) { logoUrl.value = defaultLogo return } // 使用Vite的动态导入 try { const dynamicLogo = import.meta.glob('/src/assets/logo/*.png', { eager: true }) const logoPath = `/src/assets/logo/${cleanFactoryName.value}.png` @@ -60,17 +57,12 @@ } } // 初始化和监听变化 onMounted(() => { updateLogoUrl() // 监听工厂名称变化 watch(() => userStore.currentFactoryName, updateLogoUrl) }) // 图片加载错误处理 const handleImageError = (event) => { console.warn('Logo加载失败,使用默认Logo') const handleImageError = () => { logoUrl.value = defaultLogo } </script> @@ -99,15 +91,16 @@ overflow: hidden; box-shadow: var(--shadow-sm); & .sidebar-logo-link { .sidebar-logo-link { height: 100%; width: 100%; display: flex; align-items: center; justify-content: center; padding: 0 18px 0 14px; } & .sidebar-logo { .sidebar-logo { width: auto; max-width: 250px; max-height: 50px; @@ -117,7 +110,7 @@ object-position: center; } & .sidebar-title { .sidebar-title { display: inline-block; margin: 0; color: var(--text-primary); @@ -126,7 +119,6 @@ font-size: 14px; font-family: "Segoe UI", "PingFang SC", sans-serif; vertical-align: middle; } } &.collapse { @@ -138,6 +130,13 @@ max-width: 30px; max-height: 30px; } .sidebar-favicon { width: 24px; height: 24px; max-width: 24px; max-height: 24px; } } } </style> src/layout/components/Sidebar/index.vue
@@ -2,11 +2,23 @@ <div :class="{ 'has-logo': showLogo }" class="sidebar-container"> <logo v-if="showLogo" :collapse="isCollapse" /> <el-scrollbar wrap-class="scrollbar-wrapper"> <el-menu :default-active="activeMenu" :collapse="isCollapse" :background-color="getMenuBackground" :text-color="getMenuTextColor" :unique-opened="true" :active-text-color="theme" :collapse-transition="false" mode="vertical" :class="sideTheme"> <sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" /> <el-menu :default-active="activeMenu" :collapse="isCollapse" :background-color="getMenuBackground" :text-color="getMenuTextColor" :unique-opened="true" :active-text-color="theme" :collapse-transition="false" mode="vertical" :class="sideTheme" > <sidebar-item v-for="(route, index) in sidebarRouters" :key="route.path + index" :item="route" :base-path="route.path" /> </el-menu> </el-scrollbar> </div> @@ -31,16 +43,8 @@ const theme = computed(() => settingsStore.theme) const isCollapse = computed(() => !appStore.sidebar.opened) // 获取菜单背景色 const getMenuBackground = computed(() => { if (settingsStore.isDark) { return 'var(--sidebar-bg)' } // 浅色主题时,直接用主题色 return sideTheme.value === 'theme-dark' ? variables.menuBg : settingsStore.theme }) const getMenuBackground = computed(() => 'var(--sidebar-bg)') // 获取菜单文字颜色 const getMenuTextColor = computed(() => { if (settingsStore.isDark) { return 'var(--sidebar-text)' src/layout/index.vue
@@ -105,7 +105,7 @@ } .hideSidebar .fixed-header { width: calc(100% - 70px); width: calc(100% - 100px); } .sidebarHide .fixed-header {