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() -})