diff --git a/app/(auth)/auth.ts b/app/(auth)/auth.ts index ce2b00d7e..cd907a049 100644 --- a/app/(auth)/auth.ts +++ b/app/(auth)/auth.ts @@ -3,6 +3,7 @@ import NextAuth, { type DefaultSession } from "next-auth"; import type { DefaultJWT } from "next-auth/jwt"; import Credentials from "next-auth/providers/credentials"; import Google from "next-auth/providers/google"; +import { headers } from "next/headers"; import { DUMMY_PASSWORD } from "@/lib/constants"; import { createGuestUser, getAuthSettings, getUser } from "@/lib/db/queries"; import { buildAuthConfig } from "./auth.config"; @@ -159,6 +160,37 @@ function createBaseProviders(googleClientId?: string, googleClientSecret?: strin return providers; } +function normalizeBaseUrl(input?: string | null) { + if (!input) return ""; + + try { + const parsed = new URL(input); + return `${parsed.protocol}//${parsed.host}`; + } catch { + return ""; + } +} + +async function resolveRuntimeAuthUrl(settingsAuthUrl?: string | null) { + const fromEnv = + normalizeBaseUrl(process.env.AUTH_URL) || + normalizeBaseUrl(process.env.NEXTAUTH_URL); + if (fromEnv) return fromEnv; + + const fromSettings = normalizeBaseUrl(settingsAuthUrl); + if (fromSettings) return fromSettings; + + const requestHeaders = await headers(); + const forwardedHost = requestHeaders.get("x-forwarded-host"); + const host = requestHeaders.get("host"); + const resolvedHost = forwardedHost || host || ""; + if (!resolvedHost) return ""; + + const forwardedProto = requestHeaders.get("x-forwarded-proto"); + const protocol = forwardedProto || "https"; + return `${protocol}://${resolvedHost}`; +} + export const { handlers: { GET, POST }, auth, @@ -167,7 +199,7 @@ export const { } = NextAuth(async () => { const runtimeAuthSettings = await getAuthSettings().catch(() => null as any); const resolvedAuthUrl = - runtimeAuthSettings?.authUrl || process.env.AUTH_URL || undefined; + (await resolveRuntimeAuthUrl(runtimeAuthSettings?.authUrl)) || undefined; const googleClientId = runtimeAuthSettings?.googleClientId || process.env.GOOGLE_CLIENT_ID || ""; const googleClientSecret = diff --git a/app/(chat)/api/chat/route.ts b/app/(chat)/api/chat/route.ts index 1f8b78335..6f1547656 100644 --- a/app/(chat)/api/chat/route.ts +++ b/app/(chat)/api/chat/route.ts @@ -1930,6 +1930,9 @@ export async function POST(request: Request) { const explicitFollowLatestResult = /(上一张|上一轮|刚生成|最新生成|这个结果|该结果|按这个结果|继续在这张|基于这张结果|延续上一次结果)/i.test( textContent ); + const explicitUseOriginalUpload = /(原图|上传图|参考图|最初那张|第一张图|素材图)/i.test( + textContent + ); const latestAssistantImages: string[] = []; const latestUserImages: string[] = []; @@ -1982,22 +1985,24 @@ export async function POST(request: Request) { } } - if (explicitFollowLatestResult && latestAssistantImages.length > 0) { - smartAutoHistoryImages = latestAssistantImages.slice(0, 4); - console.log( - "[Smart Auto Mode] 🖼️ Using latest generated image(s) by explicit instruction:", - smartAutoHistoryImages.length - ); - } else if (latestUserImages.length > 0) { + if (explicitUseOriginalUpload && latestUserImages.length > 0) { smartAutoHistoryImages = latestUserImages.slice(0, 4); console.log( - "[Smart Auto Mode] 🖼️ Using latest user-uploaded image(s) to avoid iterative blur:", + "[Smart Auto Mode] 🖼️ Using latest user-uploaded image(s) by explicit instruction:", smartAutoHistoryImages.length ); } else if (latestAssistantImages.length > 0) { smartAutoHistoryImages = latestAssistantImages.slice(0, 4); console.log( - "[Smart Auto Mode] 🖼️ Fallback to latest generated image(s):", + explicitFollowLatestResult + ? "[Smart Auto Mode] 🖼️ Using latest generated image(s) by explicit instruction:" + : "[Smart Auto Mode] 🖼️ Using latest generated image(s) for continuous edit:", + smartAutoHistoryImages.length + ); + } else if (latestUserImages.length > 0) { + smartAutoHistoryImages = latestUserImages.slice(0, 4); + console.log( + "[Smart Auto Mode] 🖼️ Fallback to latest user-uploaded image(s):", smartAutoHistoryImages.length ); } diff --git a/app/canvas/[id]/model3d/page.tsx b/app/canvas/[id]/model3d/page.tsx index 25ab37d3b..892b29dd1 100644 --- a/app/canvas/[id]/model3d/page.tsx +++ b/app/canvas/[id]/model3d/page.tsx @@ -12,7 +12,6 @@ import { Download, Eye, EyeOff, - FileBox, Grid3X3, History, ImagePlus, @@ -20,12 +19,14 @@ import { Layers3, Loader2, Maximize, + Package, Palette, PenLine, Play, PlusCircle, RefreshCw, RotateCw, + Scissors, Settings2, Sparkles, Sun, @@ -414,6 +415,7 @@ export default function CanvasModel3DPage() { // Effect hooks for data loading and cleanup useEffect(() => { + console.log("CanvasModel3DPage mounted - v2.0"); const loadBalance = async () => { const result = await model3DGenerationService.getBalance(); if (!result.success) return; @@ -1301,7 +1303,10 @@ export default function CanvasModel3DPage() {
- 3D 工作台 + 3D 工作台{" "} + + v2.0 + Tripo3D 驱动 diff --git a/app/canvas/[id]/page.tsx b/app/canvas/[id]/page.tsx index 477fe25ba..1209a1f2e 100644 --- a/app/canvas/[id]/page.tsx +++ b/app/canvas/[id]/page.tsx @@ -561,7 +561,7 @@ export default function CanvasEditorPage({ params }: PageProps) { {/* 1. Canvas Layer (Full Screen) - 使用 key 强制在 id 变化时重新挂载 */}
- +
{/* Brand Entry (Top Left) */} @@ -663,7 +663,7 @@ export default function CanvasEditorPage({ params }: PageProps) { "absolute top-4 right-4 bottom-4 z-10 w-[460px] max-w-[calc(100vw-1rem)] transition-all duration-300 ease-in-out", isPanelOpen ? "translate-x-0 opacity-100" : "translate-x-[120%] opacity-0 pointer-events-none" )}> -
+
{panelMode === 'chat' ? ( // AI 对话内容 - 使用 key 强制在 id 变化时重新挂载
diff --git a/components/home/lovart-home.tsx b/components/home/lovart-home.tsx index f3ddcb8f5..302067c9d 100644 --- a/components/home/lovart-home.tsx +++ b/components/home/lovart-home.tsx @@ -1138,7 +1138,7 @@ export function LovartHome({ }, [accountCenterData?.profile, currentPlan?.monthlyCredits, currentPlan?.name, membershipData?.summary?.currentCredits, membershipData?.summary?.dailyFreeCredits, user?.email, userDisplayName]); return ( -
+