diff --git a/app/api/site-settings/route.ts b/app/api/site-settings/route.ts index 338dae1a1..0f7542bb9 100644 --- a/app/api/site-settings/route.ts +++ b/app/api/site-settings/route.ts @@ -642,7 +642,7 @@ const updateSchema = z.object({ subtitle: z.string().max(300).optional(), actionText: z.string().max(48).optional(), videoUrl: z.string().max(2000).optional(), - posterUrl: z.string().max(2000).optional(), + posterUrl: z.string().max(2000).nullable().optional(), overlayText: z.string().max(200).optional(), footerText: z.string().max(64).optional(), }) diff --git a/app/canvas/[id]/page.tsx b/app/canvas/[id]/page.tsx index 08697f49d..421b46b3a 100644 --- a/app/canvas/[id]/page.tsx +++ b/app/canvas/[id]/page.tsx @@ -127,6 +127,7 @@ export default function CanvasEditorPage({ params }: PageProps) { const id = (routeParams?.id as string) || use(params).id; const router = useRouter(); const mode = searchParams.get("mode"); + const shouldOpenBatchProcessing = searchParams.get("batch") === "1"; const goHome = useCallback(() => { if (typeof window !== "undefined") { window.location.assign("/"); @@ -386,6 +387,12 @@ export default function CanvasEditorPage({ params }: PageProps) { } }, [isAgentMode]); + useEffect(() => { + if (shouldOpenBatchProcessing) { + setSceneFusionDialogOpen(true); + } + }, [shouldOpenBatchProcessing]); + const workflowStorageKey = useMemo(() => `canvas-workflow-state:${id}`, [id]); const buildPersistedCanvasData = useCallback(() => { const workflowState: AgentWorkflowPersistedState = { diff --git a/components/agents/AgentCanvasTopNavDark.tsx b/components/agents/AgentCanvasTopNavDark.tsx index 3dc298e1a..62756080b 100644 --- a/components/agents/AgentCanvasTopNavDark.tsx +++ b/components/agents/AgentCanvasTopNavDark.tsx @@ -1,7 +1,7 @@ "use client"; import type { ReactNode } from "react"; -import { ArrowLeft, Images, LayoutGrid, Sparkles, Wand2 } from "lucide-react"; +import { ArrowLeft, Images, Layers, LayoutGrid, Wand2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; @@ -17,9 +17,9 @@ interface AgentCanvasTopNavDarkProps { const NAV_ITEMS = [ { key: "featured" as const, - label: "AI精选", - icon: Sparkles, - onClick: () => window.location.assign("/featured"), + label: "批量处理", + icon: Layers, + onClick: () => window.location.assign(`/canvas/${crypto.randomUUID()}?batch=1`), }, { key: "agent" as const, @@ -92,30 +92,32 @@ export function AgentCanvasTopNavDark({ - +
+ -
{rightSlot}
+ {rightSlot ?
{rightSlot}
: null} +
diff --git a/components/agents/AgentGenerationWorkspaceDarkV2.tsx b/components/agents/AgentGenerationWorkspaceDarkV2.tsx index bde13a10f..0e4606e3e 100644 --- a/components/agents/AgentGenerationWorkspaceDarkV2.tsx +++ b/components/agents/AgentGenerationWorkspaceDarkV2.tsx @@ -614,7 +614,7 @@ export function AgentGenerationWorkspaceDarkV2({ )} - {selectedAgentPresetId && brandModelPanel ? ( + {brandModelPanel ? ( {/* 搜索栏 */} -
-
+
+
+
{/* 导航标签(简化版) */} @@ -209,8 +221,20 @@ export function AgentPresetPanelDarkV2({ ))} ) : ( -
- 暂无{embeddedEntityLabel} +
+
暂无{embeddedEntityLabel}
+
)}
diff --git a/components/agents/AgentWorkflowPanelDarkV2.tsx b/components/agents/AgentWorkflowPanelDarkV2.tsx index 878f639fc..2b65d5c88 100644 --- a/components/agents/AgentWorkflowPanelDarkV2.tsx +++ b/components/agents/AgentWorkflowPanelDarkV2.tsx @@ -2,14 +2,13 @@ import { useMemo } from "react"; import { motion } from "framer-motion"; -import { ArrowRight, Check, Copy, RotateCcw, Sparkles, ChevronRight } from "lucide-react"; +import { ArrowRight, Check, Copy, Sparkles, ChevronRight } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { SearchableSelect } from "@/components/ui/searchable-select"; import { Textarea } from "@/components/ui/textarea"; import { cn } from "@/lib/utils"; import { defaultAgentWorkflowUiConfig } from "@/lib/agents/workflow-ui-config"; -import { createEmptyAgentWorkflowMaterialSelection } from "@/lib/agents/workflow-material-config"; import { AgentCanvasTopNavDark } from "@/components/agents/AgentCanvasTopNavDark"; import { AgentWorkflowShowcaseBanner } from "@/components/agents/AgentWorkflowShowcaseBanner"; import { @@ -164,7 +163,6 @@ export function AgentWorkflowPanelDarkV2({ onMaterialsChange, selections, onSelectionsChange, - onReset, onNextStep, onSkipStep, siteName, @@ -239,28 +237,6 @@ export function AgentWorkflowPanelDarkV2({ siteLogo={siteLogo} siteLogoDark={siteLogoDark} activeKey="agent" - rightSlot={ - - } />
@@ -269,11 +245,14 @@ export function AgentWorkflowPanelDarkV2({
{ const target = document.getElementById("agent-workflow-content"); if (!target) return; target.scrollIntoView({ behavior: "smooth", block: "start" }); }} + onSecondaryActionClick={onSkipStep} />
diff --git a/components/agents/AgentWorkflowShowcaseBanner.tsx b/components/agents/AgentWorkflowShowcaseBanner.tsx index eab1da5b5..1e8b8b832 100644 --- a/components/agents/AgentWorkflowShowcaseBanner.tsx +++ b/components/agents/AgentWorkflowShowcaseBanner.tsx @@ -10,18 +10,25 @@ import type { AgentWorkflowShowcaseConfig } from "@/types/agent"; interface AgentWorkflowShowcaseBannerProps { config?: AgentWorkflowShowcaseConfig | null; onActionClick?: () => void; + actionLabel?: string; + secondaryActionLabel?: string; + onSecondaryActionClick?: () => void; className?: string; } export function AgentWorkflowShowcaseBanner({ config, onActionClick, + actionLabel, + secondaryActionLabel, + onSecondaryActionClick, className, }: AgentWorkflowShowcaseBannerProps) { const resolved = config || defaultAgentWorkflowShowcaseConfig; const hasVideo = Boolean(resolved.videoUrl); const hasPoster = Boolean(resolved.posterUrl); const shouldRenderMedia = resolved.enabled !== false; + const resolvedActionLabel = actionLabel || resolved.actionText; return (
@@ -33,22 +40,36 @@ export function AgentWorkflowShowcaseBanner({ >

{resolved.title}

{resolved.subtitle}

- {resolved.actionText ? ( - + {resolvedActionLabel || secondaryActionLabel ? ( +
+ {resolvedActionLabel ? ( + + ) : null} + {secondaryActionLabel ? ( + + ) : null} +
) : null}