From cc76d87649a5ffa851e12975304bc764de48c03d Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 30 Dec 2025 00:15:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dfavicon=E6=9C=AA=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2=E9=97=AE=E9=A2=98=E5=92=8C=E4=BC=98=E5=8C=96=E5=B0=BA?= =?UTF-8?q?=E5=AF=B8=E8=B0=83=E6=95=B4=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 彻底修复favicon未替换问题:改进Metadata配置,添加客户端FaviconUpdater组件 - 添加缓存破坏参数,确保浏览器正确加载新的favicon - 尺寸调整完成后添加下载按钮 - 保持尺寸编辑状态下左右图片虚线框相同尺寸(714x570px) - 优化工具栏布局,宽高设置移动到选择比例工具栏后面 --- app/layout.tsx | 15 +++++++++-- components/favicon-updater.tsx | 47 ++++++++++++++++++++++++++++++++++ components/image-annotator.tsx | 18 +++++++++++-- 3 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 components/favicon-updater.tsx diff --git a/app/layout.tsx b/app/layout.tsx index 6159151..e6af49c 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,6 +2,7 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; import { Toaster } from "sonner"; import { ThemeProvider } from "@/components/theme-provider"; +import { FaviconUpdater } from "@/components/favicon-updater"; import "./globals.css"; import { SessionProvider } from "next-auth/react"; @@ -10,6 +11,11 @@ import { getSiteSettings } from "@/lib/db/queries"; export async function generateMetadata(): Promise { const settings = await getSiteSettings(); + + // 处理 favicon URL,添加缓存破坏参数确保更新 + const faviconUrl = settings.favicon + ? `${settings.favicon}${settings.favicon.includes('?') ? '&' : '?'}v=${Date.now()}` + : "/favicon.ico"; return { title: { @@ -18,8 +24,12 @@ export async function generateMetadata(): Promise { }, description: settings.siteName, icons: { - icon: settings.favicon || "/favicon.ico", - apple: settings.favicon || "/favicon.ico", + icon: [ + { url: faviconUrl, sizes: "any" }, + { url: faviconUrl, type: "image/x-icon" }, + ], + apple: faviconUrl, + shortcut: faviconUrl, }, }; } @@ -145,6 +155,7 @@ export default function RootLayout({ /> + { + // 从 API 获取最新的 favicon 设置 + fetch("/api/site-settings") + .then((res) => res.json()) + .then((settings) => { + if (settings.favicon) { + const faviconUrl = settings.favicon; + const timestamp = Date.now(); + const urlWithCache = `${faviconUrl}${faviconUrl.includes("?") ? "&" : "?"}v=${timestamp}`; + + // 移除所有旧的 favicon link 标签 + const oldLinks = document.querySelectorAll('link[rel*="icon"]'); + oldLinks.forEach((link) => link.remove()); + + // 添加新的 favicon link 标签 + const link = document.createElement("link"); + link.rel = "icon"; + link.type = "image/x-icon"; + link.href = urlWithCache; + document.head.appendChild(link); + + // 添加 Apple touch icon + const appleLink = document.createElement("link"); + appleLink.rel = "apple-touch-icon"; + appleLink.href = urlWithCache; + document.head.appendChild(appleLink); + + // 添加 shortcut icon + const shortcutLink = document.createElement("link"); + shortcutLink.rel = "shortcut icon"; + shortcutLink.href = urlWithCache; + document.head.appendChild(shortcutLink); + } + }) + .catch((error) => { + console.error("[Favicon] Error updating favicon:", error); + }); + }, []); + + return null; +} + diff --git a/components/image-annotator.tsx b/components/image-annotator.tsx index 1662c91..3f4b9f9 100644 --- a/components/image-annotator.tsx +++ b/components/image-annotator.tsx @@ -1253,7 +1253,7 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel }: ImageAnnotator /* 尺寸调整模式 - 左右对比布局 */ <> {/* 左侧:原图 */} -
+
原图
{image && ( @@ -1275,7 +1275,21 @@ export function ImageAnnotator({ imageUrl, onConfirm, onCancel }: ImageAnnotator {/* 右侧:尺寸调整预览画布 */}
-
调整尺寸
+
+ 调整尺寸 + {(processedImageUrl || processedImageBase64) && processType === "resize" && ( + + )} +