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}