diff --git a/app/(auth)/login/page.tsx b/app/(auth)/login/page.tsx index 0e36d960a..6809ad7ad 100644 --- a/app/(auth)/login/page.tsx +++ b/app/(auth)/login/page.tsx @@ -217,7 +217,7 @@ export default function Page() { console.log("=".repeat(50)); // 获取网站设置(添加时间戳防止缓存) - fetch(`/api/site-settings?t=${Date.now()}`) + fetch(`/api/site-settings?scope=auth&t=${Date.now()}`) .then((res) => res.json()) .then((data) => { console.log("[Login] Site settings data:", data); diff --git a/app/(auth)/register/page.tsx b/app/(auth)/register/page.tsx index 900d90c0b..29bd06b21 100644 --- a/app/(auth)/register/page.tsx +++ b/app/(auth)/register/page.tsx @@ -41,7 +41,7 @@ export default function Page() { .catch(console.error); // 获取网站设置(添加时间戳防止缓存) - fetch(`/api/site-settings?t=${Date.now()}`) + fetch(`/api/site-settings?scope=branding&t=${Date.now()}`) .then((res) => res.json()) .then((data) => { if (data.siteName) { diff --git a/app/api/site-settings/route.ts b/app/api/site-settings/route.ts index 5546e6ddd..0b29662aa 100644 --- a/app/api/site-settings/route.ts +++ b/app/api/site-settings/route.ts @@ -440,9 +440,338 @@ function normalizeAgentCategoryTreeConfig(value: unknown): AgentCategoryTreeConf }; } +type PublicSiteSettingsScope = + | "agent-brand-model" + | "agent-canvas" + | "agent-presets" + | "auth" + | "branding" + | "canvas" + | "canvas-chat" + | "chat" + | "home"; + +const PUBLIC_SITE_SETTINGS_SCOPES = new Set([ + "agent-brand-model", + "agent-canvas", + "agent-presets", + "auth", + "branding", + "canvas", + "canvas-chat", + "chat", + "home", +]); + +function createScopedSiteSettingsResponse(data: Record) { + const response = NextResponse.json(data); + // Lightweight public settings change rarely; keep them browser-local briefly + // so page opens do not repeatedly wait on the large full settings endpoint. + response.headers.set( + "Cache-Control", + "private, max-age=30, stale-while-revalidate=120" + ); + return response; +} + +async function readScopedSiteSettings(keys: string[]) { + const [settings, settingRows] = await Promise.all([ + db + .select() + .from(siteSettings) + .limit(1) + .then((rows) => rows[0]), + keys.length > 0 + ? db + .select() + .from(systemSettings) + .where(inArray(systemSettings.key, keys)) + : Promise.resolve([]), + ]); + + return { + settings, + valueByKey: new Map(settingRows.map((row) => [row.key, row.value])), + }; +} + +function createBrandingSettings(settings: Record | undefined) { + return { + siteName: String(settings?.siteName || "AI Chatbot"), + siteLogo: settings?.siteLogo || null, + siteLogoDark: settings?.siteLogoDark || null, + favicon: settings?.favicon || null, + }; +} + +async function getScopedPublicSiteSettings(scope: PublicSiteSettingsScope) { + if (scope === "auth") { + const { settings, valueByKey } = await readScopedSiteSettings([ + "login_notification", + ]); + return createScopedSiteSettingsResponse({ + ...createBrandingSettings(settings as Record | undefined), + notification: valueByKey.get("login_notification") || { + enabled: false, + title: "", + content: "", + }, + }); + } + + if (scope === "agent-brand-model") { + const { valueByKey } = await readScopedSiteSettings([ + AGENT_WORKFLOW_BRAND_MODEL_CONFIG_KEY, + ]); + return createScopedSiteSettingsResponse({ + agentWorkflowBrandModelConfig: normalizeAgentWorkflowBrandModelConfig( + valueByKey.get(AGENT_WORKFLOW_BRAND_MODEL_CONFIG_KEY) + ), + }); + } + + if (scope === "agent-presets") { + const { valueByKey } = await readScopedSiteSettings([ + AGENT_PRESET_LIBRARY_CONFIG_KEY, + AGENT_WORKFLOW_SHOWCASE_CONFIG_KEY, + ]); + return createScopedSiteSettingsResponse({ + agentPresetLibraryConfig: normalizeAgentPresetLibraryConfig( + valueByKey.get(AGENT_PRESET_LIBRARY_CONFIG_KEY) + ), + agentWorkflowShowcaseConfig: normalizeAgentWorkflowShowcaseConfig( + valueByKey.get(AGENT_WORKFLOW_SHOWCASE_CONFIG_KEY) + ), + }); + } + + if (scope === "agent-canvas") { + const [{ settings, valueByKey }, agentPsdTemplates] = await Promise.all([ + readScopedSiteSettings([ + REALTIME_CANVAS_CONFIG_KEY, + REALTIME_CANVAS_MODE_ICON_CONFIG_KEY, + CANVAS_TOOLBAR_CONFIG_SETTING_KEY, + LAYER_SPLIT_CONFIG_KEY, + CANVAS_AGENT_MODE_ENABLED_KEY, + VIDEO_CANVAS_ENABLED_KEY, + VIDEO_CANVAS_SIDEBAR_ENABLED_KEY, + AGENT_WORKFLOW_UI_CONFIG_KEY, + AGENT_WORKFLOW_BRAND_MODEL_CONFIG_KEY, + AGENT_WORKFLOW_SHOWCASE_CONFIG_KEY, + AGENT_PSD_TEMPLATE_CATEGORY_TAG_CONFIG_KEY, + ]), + readAgentPsdTemplates().catch(() => []), + ]); + const typedSettings = settings as Record | undefined; + const videoCanvasSidebarEnabled = normalizeVideoCanvasSidebarEnabled( + valueByKey.get(VIDEO_CANVAS_SIDEBAR_ENABLED_KEY) + ); + const agentPsdTemplateCategoryTagConfig = + normalizeAgentPsdTemplateCategoryTagConfig( + valueByKey.get(AGENT_PSD_TEMPLATE_CATEGORY_TAG_CONFIG_KEY) + ); + + return createScopedSiteSettingsResponse({ + ...createBrandingSettings(typedSettings), + agentEnabled: typedSettings?.agentEnabled ?? true, + canvasAgentModeEnabled: normalizeCanvasAgentModeEnabled( + valueByKey.get(CANVAS_AGENT_MODE_ENABLED_KEY) + ), + videoCanvasEnabled: normalizeVideoCanvasEnabled( + valueByKey.get(VIDEO_CANVAS_ENABLED_KEY), + valueByKey.get(VIDEO_CANVAS_SIDEBAR_ENABLED_KEY) + ), + videoCanvasSidebarEnabled, + realtimeCanvasEnabled: true, + realtimeCanvasServiceEnabled: + (valueByKey.get(REALTIME_CANVAS_CONFIG_KEY) as + | { enabled?: boolean } + | undefined)?.enabled !== false, + realtimeCanvasModeIconConfig: normalizeRealtimeCanvasModeIconConfig( + valueByKey.get(REALTIME_CANVAS_MODE_ICON_CONFIG_KEY) + ), + canvasToolbarConfig: normalizeCanvasToolbarConfig( + valueByKey.get(CANVAS_TOOLBAR_CONFIG_SETTING_KEY) + ), + layerSplitEnabled: normalizeLayerSplitEnabled( + valueByKey.get(LAYER_SPLIT_CONFIG_KEY) + ), + agentWorkflowUiConfig: normalizeAgentWorkflowUiConfig( + valueByKey.get(AGENT_WORKFLOW_UI_CONFIG_KEY) + ), + agentWorkflowBrandModelConfig: normalizeAgentWorkflowBrandModelConfig( + valueByKey.get(AGENT_WORKFLOW_BRAND_MODEL_CONFIG_KEY) + ), + agentWorkflowShowcaseConfig: normalizeAgentWorkflowShowcaseConfig( + valueByKey.get(AGENT_WORKFLOW_SHOWCASE_CONFIG_KEY) + ), + agentPsdTemplateCategoryTagIndex: buildAgentPsdTemplateCategoryTagIndex({ + templates: agentPsdTemplates, + config: agentPsdTemplateCategoryTagConfig, + }), + }); + } + + if (scope === "branding") { + const { settings } = await readScopedSiteSettings([]); + return createScopedSiteSettingsResponse( + createBrandingSettings(settings as Record | undefined) + ); + } + + if (scope === "chat") { + const { settings } = await readScopedSiteSettings([]); + const typedSettings = settings as Record | undefined; + return createScopedSiteSettingsResponse({ + ...createBrandingSettings(typedSettings), + showAutoModel: typedSettings?.showAutoModel ?? true, + usageTimeEnabled: typedSettings?.usageTimeEnabled ?? false, + usageTimeStart: typedSettings?.usageTimeStart || "08:00", + usageTimeEnd: typedSettings?.usageTimeEnd || "20:00", + usageTimeMessage: + typedSettings?.usageTimeMessage || "由壹点累了也是需要休息的", + }); + } + + if (scope === "canvas") { + const { settings, valueByKey } = await readScopedSiteSettings([ + REALTIME_CANVAS_CONFIG_KEY, + REALTIME_CANVAS_MODE_ICON_CONFIG_KEY, + CANVAS_TOOLBAR_CONFIG_SETTING_KEY, + LAYER_SPLIT_CONFIG_KEY, + CANVAS_AGENT_MODE_ENABLED_KEY, + VIDEO_CANVAS_ENABLED_KEY, + VIDEO_CANVAS_SIDEBAR_ENABLED_KEY, + ]); + const typedSettings = settings as Record | undefined; + const videoCanvasSidebarEnabled = normalizeVideoCanvasSidebarEnabled( + valueByKey.get(VIDEO_CANVAS_SIDEBAR_ENABLED_KEY) + ); + + return createScopedSiteSettingsResponse({ + ...createBrandingSettings(typedSettings), + agentEnabled: typedSettings?.agentEnabled ?? true, + canvasAgentModeEnabled: normalizeCanvasAgentModeEnabled( + valueByKey.get(CANVAS_AGENT_MODE_ENABLED_KEY) + ), + videoCanvasEnabled: normalizeVideoCanvasEnabled( + valueByKey.get(VIDEO_CANVAS_ENABLED_KEY), + valueByKey.get(VIDEO_CANVAS_SIDEBAR_ENABLED_KEY) + ), + videoCanvasSidebarEnabled, + realtimeCanvasEnabled: true, + realtimeCanvasServiceEnabled: + (valueByKey.get(REALTIME_CANVAS_CONFIG_KEY) as + | { enabled?: boolean } + | undefined)?.enabled !== false, + realtimeCanvasModeIconConfig: normalizeRealtimeCanvasModeIconConfig( + valueByKey.get(REALTIME_CANVAS_MODE_ICON_CONFIG_KEY) + ), + canvasToolbarConfig: normalizeCanvasToolbarConfig( + valueByKey.get(CANVAS_TOOLBAR_CONFIG_SETTING_KEY) + ), + layerSplitEnabled: normalizeLayerSplitEnabled( + valueByKey.get(LAYER_SPLIT_CONFIG_KEY) + ), + }); + } + + if (scope === "canvas-chat") { + const { settings, valueByKey } = await readScopedSiteSettings([ + AI_DETAIL_GENERATOR_ENABLED_KEY, + LOVART_COMPOSER_PREVIEW_TEXTS_KEY, + LOVART_COMPOSER_PREFIX_KEY, + CANVAS_TOOLBAR_CONFIG_SETTING_KEY, + ]); + const typedSettings = settings as Record | undefined; + + return createScopedSiteSettingsResponse({ + ...createBrandingSettings(typedSettings), + bannerEnabled: typedSettings?.bannerEnabled ?? true, + bannerText: + typedSettings?.bannerText || "升级会员, Nano Banana Pro 免费365天!", + bannerLink: typedSettings?.bannerLink || null, + lovartComposerPrefix: normalizeLovartComposerPrefix( + valueByKey.get(LOVART_COMPOSER_PREFIX_KEY) + ), + lovartComposerPreviewTexts: normalizeLovartComposerPreviewTexts( + valueByKey.get(LOVART_COMPOSER_PREVIEW_TEXTS_KEY) + ), + canvasEnabled: typedSettings?.canvasEnabled ?? true, + aiDetailGenerationEnabled: Boolean( + valueByKey.get(AI_DETAIL_GENERATOR_ENABLED_KEY) + ), + canvasDefaultModelId: typedSettings?.canvasDefaultModelId || null, + canvasAutoModeDefaultModelId: + typedSettings?.canvasAutoModeDefaultModelId || null, + canvasDetailDefaultModelId: + typedSettings?.canvasDetailDefaultModelId || null, + canvasToolbarConfig: normalizeCanvasToolbarConfig( + valueByKey.get(CANVAS_TOOLBAR_CONFIG_SETTING_KEY) + ), + }); + } + + const { settings, valueByKey } = await readScopedSiteSettings([ + LOVART_COMPOSER_PREVIEW_TEXTS_KEY, + LOVART_COMPOSER_PREFIX_KEY, + LOVART_PROMPT_TAG_VISIBILITY_KEY, + CONTACT_CONFIG_KEY, + MEMBERSHIP_CONFIG_KEY, + POINTS_PACKAGES_KEY, + DULUPAY_CONFIG_KEY, + LOVART_HOME_SIDEBAR_CONFIG_KEY, + VIDEO_CANVAS_ENABLED_KEY, + VIDEO_CANVAS_SIDEBAR_ENABLED_KEY, + ]); + const typedSettings = settings as Record | undefined; + + return createScopedSiteSettingsResponse({ + ...createBrandingSettings(typedSettings), + canvasDefaultModelId: typedSettings?.canvasDefaultModelId || null, + lovartComposerPrefix: normalizeLovartComposerPrefix( + valueByKey.get(LOVART_COMPOSER_PREFIX_KEY) + ), + lovartComposerPreviewTexts: normalizeLovartComposerPreviewTexts( + valueByKey.get(LOVART_COMPOSER_PREVIEW_TEXTS_KEY) + ), + lovartPromptTagVisibility: normalizeLovartPromptTagVisibility( + valueByKey.get(LOVART_PROMPT_TAG_VISIBILITY_KEY) + ), + contactConfig: normalizeContactConfig(valueByKey.get(CONTACT_CONFIG_KEY)), + membershipConfig: normalizeMembershipConfig( + valueByKey.get(MEMBERSHIP_CONFIG_KEY) + ), + toolbox1Name: typedSettings?.toolbox1Name || "工具箱", + toolbox1Enabled: typedSettings?.toolbox1Enabled ?? true, + toolbox2Name: typedSettings?.toolbox2Name || "工具箱2", + toolbox2Enabled: typedSettings?.toolbox2Enabled ?? false, + productPlanningEnabled: typedSettings?.productPlanningEnabled ?? true, + agentEnabled: typedSettings?.agentEnabled ?? true, + videoCanvasEnabled: normalizeVideoCanvasEnabled( + valueByKey.get(VIDEO_CANVAS_ENABLED_KEY), + valueByKey.get(VIDEO_CANVAS_SIDEBAR_ENABLED_KEY) + ), + tutorialEnabled: typedSettings?.tutorialEnabled ?? false, + tutorialVideoUrl: typedSettings?.tutorialVideoUrl || null, + pointsPackages: normalizePointsPackages( + valueByKey.get(POINTS_PACKAGES_KEY) + ), + dulupayConfig: normalizeDulupayForPublic(valueByKey.get(DULUPAY_CONFIG_KEY)), + lovartHomeSidebarConfig: normalizeLovartHomeSidebarConfig( + valueByKey.get(LOVART_HOME_SIDEBAR_CONFIG_KEY) + ), + }); +} + // GET /api/site-settings - 获取网站设置 (公开) -export async function GET() { +export async function GET(request: NextRequest) { try { + const scope = request.nextUrl.searchParams.get("scope") || ""; + if (PUBLIC_SITE_SETTINGS_SCOPES.has(scope)) { + return getScopedPublicSiteSettings(scope as PublicSiteSettingsScope); + } + const session = await auth().catch(() => null); const isAdmin = isSiteAdminType(session?.user?.type); const canManageAgentWorkflow = isAgentWorkflowAdminType(session?.user?.type); diff --git a/app/canvas/[id]/CanvasEditorLegacyPageClient.tsx b/app/canvas/[id]/CanvasEditorLegacyPageClient.tsx index 5d7a4b4fd..eba279453 100644 --- a/app/canvas/[id]/CanvasEditorLegacyPageClient.tsx +++ b/app/canvas/[id]/CanvasEditorLegacyPageClient.tsx @@ -1790,7 +1790,12 @@ export default function CanvasEditorLegacyPage({ params }: PageProps) { }>; }>; }; - }>("/api/site-settings", fetcher); + }>( + requestedAgentMode + ? "/api/site-settings?scope=agent-canvas" + : "/api/site-settings?scope=canvas", + fetcher + ); const { data: sceneFusionConfigData } = useSWR<{ enabled?: boolean; }>("/api/scene-fusion/config", fetcher); diff --git a/app/canvas/[id]/CanvasPageClientRouter.tsx b/app/canvas/[id]/CanvasPageClientRouter.tsx index 2ab577fc7..575ce88af 100644 --- a/app/canvas/[id]/CanvasPageClientRouter.tsx +++ b/app/canvas/[id]/CanvasPageClientRouter.tsx @@ -18,13 +18,22 @@ const LiblibVideoCanvasReplica = dynamic( } ); -export function CanvasPageClientRouter({ initialId }: { initialId: string }) { +export function CanvasPageClientRouter({ + initialId, + initialMode = "", + initialWorkspaceType = "", +}: { + initialId: string; + initialMode?: string; + initialWorkspaceType?: string; +}) { const routeParams = useParams(); const searchParams = useSearchParams(); const routeId = routeParams?.id; const id = Array.isArray(routeId) ? routeId[0] || initialId : typeof routeId === "string" ? routeId : initialId; - const mode = searchParams.get("mode"); - const requestedWorkspaceType = searchParams.get("workspaceType"); + const mode = searchParams.get("mode") || initialMode; + const requestedWorkspaceType = + searchParams.get("workspaceType") || initialWorkspaceType; const requestedAgentMode = mode === "agent"; const isVideoMode = !requestedAgentMode && (mode === "video" || requestedWorkspaceType === "video"); const legacyParams = useMemo(() => Promise.resolve({ id }), [id]); diff --git a/app/canvas/[id]/model3d/page.tsx b/app/canvas/[id]/model3d/page.tsx index 1cc13cc23..0224ccbf7 100644 --- a/app/canvas/[id]/model3d/page.tsx +++ b/app/canvas/[id]/model3d/page.tsx @@ -784,7 +784,10 @@ export default function CanvasModel3DPage() { const batchImageSlotsRef = useRef([]); // Fetch site settings for Logo - const { data: siteSettingsData } = useSWR("/api/site-settings", fetcher); + const { data: siteSettingsData } = useSWR( + "/api/site-settings?scope=branding", + fetcher + ); const { data: modelAliasConfigResponse } = useSWR<{ success?: boolean; data?: PublicThreeDModelAliasConfig; diff --git a/app/canvas/[id]/page.tsx b/app/canvas/[id]/page.tsx index 2f24e9fb0..694f53b64 100644 --- a/app/canvas/[id]/page.tsx +++ b/app/canvas/[id]/page.tsx @@ -2,10 +2,34 @@ import { Loader2 } from "lucide-react"; import { Suspense } from "react"; import { CanvasPageClientRouter } from "./CanvasPageClientRouter"; -export default function CanvasEditorPage() { +type CanvasEditorPageProps = { + params: Promise<{ id: string }>; + searchParams?: Promise<{ + mode?: string | string[]; + workspaceType?: string | string[]; + }>; +}; + +function getFirstParamValue(value: string | string[] | undefined) { + return Array.isArray(value) ? value[0] || "" : value || ""; +} + +export default async function CanvasEditorPage({ + params, + searchParams, +}: CanvasEditorPageProps) { + const { id } = await params; + const resolvedSearchParams = searchParams ? await searchParams : {}; + return ( }> - + ); } diff --git a/components/agents/AgentPresetDialog.tsx b/components/agents/AgentPresetDialog.tsx index 6d162e7cd..80998645a 100644 --- a/components/agents/AgentPresetDialog.tsx +++ b/components/agents/AgentPresetDialog.tsx @@ -150,7 +150,7 @@ export function AgentPresetDialog({ }>("/api/models", fetcher); const { data: siteSettingsData } = useSWR<{ agentPresetLibraryConfig?: AgentPresetLibraryConfig; - }>("/api/site-settings", fetcher); + }>("/api/site-settings?scope=agent-presets", fetcher); const [name, setName] = useState(""); const [type, setType] = useState<"image" | "video" | "text">("image"); diff --git a/components/agents/AgentPresetPanelDarkV2.tsx b/components/agents/AgentPresetPanelDarkV2.tsx index d2092a575..cc2637309 100644 --- a/components/agents/AgentPresetPanelDarkV2.tsx +++ b/components/agents/AgentPresetPanelDarkV2.tsx @@ -63,7 +63,7 @@ export function AgentPresetPanelDarkV2({ agentWorkflowShowcaseConfig?: unknown; agentPresetLibraryConfig?: AgentPresetLibraryConfig; }>( - "/api/site-settings", + "/api/site-settings?scope=agent-presets", (url: string) => fetch(url, { cache: "no-store" }).then((res) => res.json()) ); diff --git a/components/agents/AgentWorkflowBrandModelPicker.tsx b/components/agents/AgentWorkflowBrandModelPicker.tsx index dc3de43ed..4ab268e73 100644 --- a/components/agents/AgentWorkflowBrandModelPicker.tsx +++ b/components/agents/AgentWorkflowBrandModelPicker.tsx @@ -25,7 +25,7 @@ export function AgentWorkflowBrandModelPicker({ theme = "light", }: AgentWorkflowBrandModelPickerProps) { const { data } = useSWR<{ agentWorkflowBrandModelConfig?: AgentWorkflowBrandModelConfig }>( - "/api/site-settings", + "/api/site-settings?scope=agent-brand-model", fetcher ); diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index 5afef8612..47a1b3325 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -3011,7 +3011,7 @@ export function CanvasChatPanel({ canvasAutoModeDefaultModelId?: string | null; canvasDetailDefaultModelId?: string | null; canvasToolbarConfig?: CanvasToolbarConfig; - }>("/api/site-settings", fetcher); + }>("/api/site-settings?scope=canvas-chat", fetcher); const { data: canvasSkillTagsData } = useSWR<{ enabled?: boolean; title?: string; diff --git a/components/canvas/LiblibVideoCanvasReplica.tsx b/components/canvas/LiblibVideoCanvasReplica.tsx index f7821f6b2..89454ada5 100644 --- a/components/canvas/LiblibVideoCanvasReplica.tsx +++ b/components/canvas/LiblibVideoCanvasReplica.tsx @@ -2685,7 +2685,10 @@ export function LiblibVideoCanvasReplica({ canvasId, isLoading = false }: Liblib const router = useRouter(); const canvasRef = useRef(null); const dragRef = useRef(null); - const { data: siteBrandSettings } = useSWR("/api/site-settings", fetcher); + const { data: siteBrandSettings } = useSWR( + "/api/site-settings?scope=branding", + fetcher + ); const { data: videoCanvasFunctionSettings } = useSWR<{ config?: VideoCanvasFunctionConfig }>( "/api/video-canvas/config", fetcher @@ -11146,7 +11149,10 @@ function MemberStoreModal({ onClose }: { onClose: () => void }) { const [activeTab, setActiveTab] = useState("credits"); const [billingCycle, setBillingCycle] = useState<"monthly" | "annual">("monthly"); const [creatingPaymentPackageId, setCreatingPaymentPackageId] = useState(null); - const { data: siteSettingsData } = useSWR("/api/site-settings", fetcher); + const { data: siteSettingsData } = useSWR( + "/api/site-settings?scope=home", + fetcher + ); const { data: membershipSummary } = useSWR("/api/user/membership-summary", fetcher); const { data: accountCenterData } = useSWR("/api/user/account-center", fetcher); diff --git a/components/canvas/RealtimeCanvasDialog.tsx b/components/canvas/RealtimeCanvasDialog.tsx index e8ddc734e..2b658c806 100644 --- a/components/canvas/RealtimeCanvasDialog.tsx +++ b/components/canvas/RealtimeCanvasDialog.tsx @@ -1019,7 +1019,7 @@ export function RealtimeCanvasDialog({ useEffect(() => { let cancelled = false; - fetch(`/api/site-settings?t=${Date.now()}`, { cache: "no-store" }) + fetch(`/api/site-settings?scope=canvas&t=${Date.now()}`) .then((res) => (res.ok ? res.json() : null)) .then((data) => { if (!data || cancelled) return; diff --git a/components/home/lovart-home.tsx b/components/home/lovart-home.tsx index 48d650b35..5fb5aca19 100644 --- a/components/home/lovart-home.tsx +++ b/components/home/lovart-home.tsx @@ -595,7 +595,7 @@ export function LovartHome({ defaultType?: string; }; lovartHomeSidebarConfig?: unknown; - }>("/api/site-settings", fetcher); + }>("/api/site-settings?scope=home", fetcher); const { data: tutorialVideosData } = useSWR<{ videos: TutorialVideo[] }>( isSecondaryDataReady && siteSettingsData?.tutorialEnabled diff --git a/components/image-annotator.tsx b/components/image-annotator.tsx index a5c740fcd..c2231cf82 100644 --- a/components/image-annotator.tsx +++ b/components/image-annotator.tsx @@ -419,7 +419,7 @@ export function ImageAnnotator({ setMounted(true); // 获取网站设置 - fetch(`/api/site-settings?t=${Date.now()}`) + fetch(`/api/site-settings?scope=branding&t=${Date.now()}`) .then((res) => res.json()) .then((data) => { if (data.siteName) setSiteName(data.siteName); diff --git a/components/multimodal-input.tsx b/components/multimodal-input.tsx index 14d8efeb5..e86e5f3a3 100644 --- a/components/multimodal-input.tsx +++ b/components/multimodal-input.tsx @@ -234,7 +234,7 @@ function PureMultimodalInput({ } | null>(null); // 获取网站设置(用于时间限制检查) - const { data: siteSettings } = useSWR("/api/site-settings", fetcher); + const { data: siteSettings } = useSWR("/api/site-settings?scope=chat", fetcher); const { data: modelCatalog } = useSWR<{ models: DynamicModel[]; }>("/api/models", fetcher); @@ -1565,7 +1565,7 @@ function PureModelSelectorCompact({ // 获取站点设置 const { data: siteSettings } = useSWR<{ showAutoModel: boolean; - }>("/api/site-settings", fetcher); + }>("/api/site-settings?scope=chat", fetcher); const allModels = useMemo( () =>