From 708928ab267aa06a11fae9d0458f8346467cd811 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sat, 19 Apr 2025 22:07:39 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20App=20=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0=E5=85=A8=E5=B1=80=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E6=B3=A8=E5=85=A5=EF=BC=8C=E6=9B=B4=E6=96=B0=E4=B8=BB=E9=A2=98?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E8=83=8C=E6=99=AF=E5=9B=BE=E7=89=87=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=B9=B6=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=9B=BE=E7=89=87=E5=9C=B0=E5=9D=80=E7=9A=84=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E3=80=82=E9=87=8D=E6=9E=84=20Footer=20?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=EF=BC=8C=E7=AE=80=E5=8C=96=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E7=AE=A1=E7=90=86=EF=BC=8C=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E5=AF=BC=E8=88=AA=E4=BD=93=E9=AA=8C=E3=80=82=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E4=B8=AD=E5=BF=83=E9=A1=B5=E9=9D=A2=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=88=86=E7=BB=84=E6=A0=87=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=88=97=E8=A1=A8=E9=A1=B9=E7=9A=84=E5=86=85?= =?UTF-8?q?=E8=BE=B9=E8=B7=9D=EF=BC=8C=E6=8F=90=E5=8D=87=E6=95=B4=E4=BD=93?= =?UTF-8?q?=E5=8F=AF=E7=94=A8=E6=80=A7=E5=92=8C=E8=A7=86=E8=A7=89=E6=95=88?= =?UTF-8?q?=E6=9E=9C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 21 +++++-- src/layouts/components/Footer.vue | 94 ++++++++----------------------- src/pages/appcenter.vue | 5 +- 3 files changed, 45 insertions(+), 75 deletions(-) diff --git a/src/App.vue b/src/App.vue index 58f02c65..9e39fd63 100644 --- a/src/App.vue +++ b/src/App.vue @@ -10,8 +10,11 @@ let themeValue = localStorage.getItem('theme') || 'light' const autoTheme = checkPrefersColorSchemeIsDark() ? 'dark' : 'light' globalTheme.name.value = themeValue === 'auto' ? autoTheme : themeValue +// 从 provide 中获取全局设置 +const globalSettings: any = inject('globalSettings') + // 更新data-theme属性以便CSS选择器能正确匹配 -function updateHtmlThemeAttribute(themeName) { +function updateHtmlThemeAttribute(themeName: string) { document.documentElement.setAttribute('data-theme', themeName) // 确保body元素也有相同的主题属性,以便更好地选择弹出窗口 document.body.setAttribute('data-theme', themeName) @@ -30,9 +33,8 @@ let backgroundRotationTimer: NodeJS.Timeout | null = null async function fetchBackgroundImages() { try { backgroundImages.value = await api.get('/login/wallpapers') - console.log('获取背景图片成功:', backgroundImages.value) } catch (e) { - console.error('获取背景图片失败:', e) + console.error(e) } } @@ -47,6 +49,17 @@ function startBackgroundRotation() { } } +// 计算图片地址 +function getImgUrl(url: string) { + // 使用图片缓存 + if (globalSettings.GLOBAL_IMAGE_CACHE) + return `${import.meta.env.VITE_API_BASE_URL}system/cache/image?url=${encodeURIComponent(url)}` + // 如果地址中包含douban则使用中转代理 + if (url.includes('doubanio.com')) + return `${import.meta.env.VITE_API_BASE_URL}system/img/0?imgurl=${encodeURIComponent(url)}` + return url +} + // 监听主题变化 watch( () => globalTheme.name.value, @@ -131,7 +144,7 @@ onUnmounted(() => { :key="index" class="background-image" :class="{ 'active': index === activeImageIndex }" - :style="{ backgroundImage: `url(${imageUrl})` }" + :style="{ backgroundImage: `url(${getImgUrl(imageUrl)})` }" >
diff --git a/src/layouts/components/Footer.vue b/src/layouts/components/Footer.vue index 71afb9a1..476c2d61 100644 --- a/src/layouts/components/Footer.vue +++ b/src/layouts/components/Footer.vue @@ -7,86 +7,50 @@ const appMode = inject('pwaMode') && display.mdAndDown.value const route = useRoute() -// 过滤出底部菜单项(排除电影和电视剧,因为我们会合并它们) +// 根据当前路径获取匹配的菜单路径 +function getMenuPathFromRoute(path: string): string { + const matchedMenu = SystemNavMenus.find(menu => menu.footer === true && path.startsWith(menu.to)) + return matchedMenu ? matchedMenu.to : '/apps' +} + +// 当前选中的菜单,初始值基于当前路由 +const currentMenu = ref(getMenuPathFromRoute(route.path)) + +// 过滤出底部菜单项 const footerMenus = computed(() => { return SystemNavMenus.filter(menu => menu.footer === true) }) -// 为每个底部菜单创建激活状态 -const activeState = computed(() => { - const activeStates: Record = {} - - footerMenus.value.forEach(menu => { - const pathKey = menu.to.replace(/\//g, '_') - activeStates[pathKey] = route.path.startsWith(menu.to) - }) - - return activeStates -}) - -// 更多按钮的激活状态 -const moreActiveState = computed(() => { - return !Object.values(activeState.value).some(v => v) -}) - -// 用于动画的状态和方法 -const indicator = ref(null) -const activeButton = ref(null) - -// 更新指示器位置的方法 -const updateIndicatorPosition = async () => { - await nextTick() - const activeEl = document.querySelector('.footer-nav-btn-active') as HTMLElement - if (activeEl && indicator.value) { - // 获取按钮的完整尺寸和位置信息 - const rect = activeEl.getBoundingClientRect() - const parentRect = indicator.value.parentElement!.getBoundingClientRect() - - // 计算相对于父容器的位置 - const relativeLeft = rect.left - parentRect.left - - // 设置指示器宽度和位置 - indicator.value.style.width = `${rect.width}px` - indicator.value.style.left = `${relativeLeft}px` - - activeButton.value = activeEl - } -} - -// 监听路由变化 +// 监听路由变化来更新currentMenu watch( () => route.path, - async () => { - updateIndicatorPosition() + newPath => { + currentMenu.value = getMenuPathFromRoute(newPath) }, { immediate: false }, ) - -// 在组件挂载后初始化指示器位置 -onMounted(() => { - updateIndicatorPosition() -})