| | |
| | | <template> |
| | | <div class="sidebar-logo-container" :class="{ collapse }"> |
| | | <div class="sidebar-logo-container" |
| | | :class="{ collapse }"> |
| | | <transition name="sidebarLogoFade"> |
| | | <router-link style="display: flex;" v-if="collapse" key="collapse" class="sidebar-logo-link" to="/"> |
| | | <img :src="faviconUrl" class="sidebar-logo sidebar-favicon" alt="站点图标" /> |
| | | <router-link style="display: flex;" |
| | | v-if="collapse" |
| | | key="collapse" |
| | | class="sidebar-logo-link" |
| | | to="/"> |
| | | <img :src="faviconUrl" |
| | | class="sidebar-logo sidebar-favicon" |
| | | alt="站点图标" /> |
| | | </router-link> |
| | | <router-link v-else key="expand" class="sidebar-logo-link" :style="expandLogoLinkStyle" to="/"> |
| | | <img v-if="logoUrl" :src="logoUrl" class="sidebar-logo" @error="handleImageError" alt="公司Logo" /> |
| | | <h1 v-if="!logoUrl" class="sidebar-title">{{ title }}</h1> |
| | | <router-link v-else |
| | | key="expand" |
| | | class="sidebar-logo-link" |
| | | :style="expandLogoLinkStyle" |
| | | to="/"> |
| | | <img v-if="logoUrl" |
| | | :src="logoUrl" |
| | | class="sidebar-logo" |
| | | @error="handleImageError" |
| | | alt="公司Logo" /> |
| | | <h1 v-if="!logoUrl" |
| | | class="sidebar-title">{{ title }}</h1> |
| | | </router-link> |
| | | </transition> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, onMounted, watch } from 'vue' |
| | | import useUserStore from '@/store/modules/user' |
| | | import defaultLogo from '@/assets/logo/logo.png' |
| | | import { ref, computed, onMounted, watch } from "vue"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import defaultLogo from "@/assets/logo/芯导软件(江苏)有限公司.png"; |
| | | |
| | | defineProps({ |
| | | collapse: { |
| | | type: Boolean, |
| | | required: true |
| | | } |
| | | }) |
| | | defineProps({ |
| | | collapse: { |
| | | type: Boolean, |
| | | required: true, |
| | | }, |
| | | }); |
| | | |
| | | 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 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() |
| | | }) |
| | | const cleanFactoryName = computed(() => { |
| | | if (!userStore.currentFactoryName) return ""; |
| | | return userStore.currentFactoryName.trim(); |
| | | }); |
| | | |
| | | const logoUrl = ref('') |
| | | const logoUrl = ref(""); |
| | | |
| | | const expandLogoLinkStyle = computed(() => { |
| | | if (!logoUrl.value) { |
| | | return { '--logo-bg-image': 'none' } |
| | | } |
| | | const escaped = String(logoUrl.value).replace(/"/g, '\\"') |
| | | return { '--logo-bg-image': `url("${escaped}")` } |
| | | }) |
| | | |
| | | const updateLogoUrl = () => { |
| | | if (!cleanFactoryName.value) { |
| | | logoUrl.value = defaultLogo |
| | | return |
| | | } |
| | | |
| | | try { |
| | | const dynamicLogo = import.meta.glob('/src/assets/logo/*.png', { eager: true }) |
| | | const logoPath = `/src/assets/logo/${cleanFactoryName.value}.png` |
| | | |
| | | if (dynamicLogo[logoPath]) { |
| | | logoUrl.value = dynamicLogo[logoPath].default |
| | | } else { |
| | | logoUrl.value = defaultLogo |
| | | const expandLogoLinkStyle = computed(() => { |
| | | if (!logoUrl.value) { |
| | | return { "--logo-bg-image": "none" }; |
| | | } |
| | | } catch (error) { |
| | | console.error('加载工厂 Logo 失败:', error) |
| | | logoUrl.value = defaultLogo |
| | | } |
| | | } |
| | | const escaped = String(logoUrl.value).replace(/"/g, '\\"'); |
| | | return { "--logo-bg-image": `url("${escaped}")` }; |
| | | }); |
| | | |
| | | onMounted(() => { |
| | | updateLogoUrl() |
| | | watch(() => userStore.currentFactoryName, updateLogoUrl) |
| | | }) |
| | | const updateLogoUrl = () => { |
| | | if (!cleanFactoryName.value) { |
| | | logoUrl.value = defaultLogo; |
| | | return; |
| | | } |
| | | |
| | | const handleImageError = () => { |
| | | logoUrl.value = defaultLogo |
| | | } |
| | | try { |
| | | const dynamicLogo = import.meta.glob("/src/assets/logo/*.png", { |
| | | eager: true, |
| | | }); |
| | | const logoPath = `/src/assets/logo/${cleanFactoryName.value}.png`; |
| | | |
| | | if (dynamicLogo[logoPath]) { |
| | | logoUrl.value = dynamicLogo[logoPath].default; |
| | | } else { |
| | | logoUrl.value = defaultLogo; |
| | | } |
| | | } catch (error) { |
| | | console.error("加载工厂 Logo 失败:", error); |
| | | logoUrl.value = defaultLogo; |
| | | } |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | updateLogoUrl(); |
| | | watch(() => userStore.currentFactoryName, updateLogoUrl); |
| | | }); |
| | | |
| | | const handleImageError = () => { |
| | | logoUrl.value = defaultLogo; |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import '@/assets/styles/variables.module.scss'; |
| | | @import "@/assets/styles/variables.module.scss"; |
| | | |
| | | .sidebarLogoFade-enter-active { |
| | | transition: opacity 1.5s; |
| | | } |
| | | |
| | | .sidebarLogoFade-enter, |
| | | .sidebarLogoFade-leave-to { |
| | | opacity: 0; |
| | | } |
| | | |
| | | .sidebar-logo-container { |
| | | position: relative; |
| | | width: 100% !important; |
| | | height: 64px !important; |
| | | line-height: 64px; |
| | | background: transparent; |
| | | border-bottom: 1px solid rgba(255, 255, 255, 0.08); |
| | | text-align: left; |
| | | overflow: hidden; |
| | | transition: all 0.3s ease; |
| | | |
| | | .sidebar-logo-link { |
| | | height: 100%; |
| | | width: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: flex-start; // 默认展开时靠左 |
| | | padding: 0 16px; |
| | | .sidebarLogoFade-enter-active { |
| | | transition: opacity 1.5s; |
| | | } |
| | | |
| | | .sidebar-logo { |
| | | height:100%; |
| | | width:100%; |
| | | width: auto; |
| | | max-width: 100%; |
| | | vertical-align: middle; |
| | | object-fit: contain; |
| | | display: block; |
| | | .sidebarLogoFade-enter, |
| | | .sidebarLogoFade-leave-to { |
| | | opacity: 0; |
| | | } |
| | | |
| | | .sidebar-title { |
| | | display: inline-block; |
| | | margin: 0; |
| | | color: #fff; |
| | | font-weight: 600; |
| | | line-height: 64px; |
| | | font-size: 16px; |
| | | vertical-align: middle; |
| | | margin-left: 12px; |
| | | white-space: nowrap; |
| | | } |
| | | .sidebar-logo-container { |
| | | position: relative; |
| | | width: 100% !important; |
| | | height: 100% !important; |
| | | line-height: var(--topbar-height, 64px); |
| | | background: transparent; |
| | | text-align: left; |
| | | overflow: hidden; |
| | | transition: all 0.3s ease; |
| | | |
| | | &.collapse { |
| | | .sidebar-logo-link { |
| | | padding: 0; |
| | | justify-content: center; // 折叠时绝对居中 |
| | | height: 100%; |
| | | width: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; // 始终居中 |
| | | padding: 0; // 移除两边间距,让图片能撑满 |
| | | } |
| | | |
| | | .sidebar-logo { |
| | | width: 32px; |
| | | height: 32px; |
| | | width: 100%; // 宽度始终和侧边栏一致 |
| | | height: auto; // 高度自适应 |
| | | vertical-align: middle; |
| | | object-fit: contain; |
| | | display: block; |
| | | } |
| | | |
| | | .sidebar-title { |
| | | display: inline-block; |
| | | margin: 0; |
| | | color: #333; // 白色背景下需要深色字体 |
| | | font-weight: 600; |
| | | line-height: var(--topbar-height, 64px); |
| | | font-size: 16px; |
| | | vertical-align: middle; |
| | | margin-left: 12px; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | &.collapse { |
| | | .sidebar-logo-link { |
| | | padding: 0; |
| | | justify-content: center; // 折叠时绝对居中 |
| | | } |
| | | |
| | | .sidebar-logo { |
| | | width: 32px; |
| | | height: 32px; |
| | | margin: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |