From 1f078d5b371885e41eeadc6c4f10ee786dfc45e0 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 18 Mar 2026 01:18:58 +0800 Subject: [PATCH] feat: polish agent workflow showcase and layout --- .../agent-workflow-settings-client.tsx | 295 ++++++++++ app/api/site-settings/route.ts | 79 +++ app/canvas/[id]/page.tsx | 28 + components/agents/AgentCanvasTopNavDark.tsx | 123 ++++ .../agents/AgentGenerationWorkspaceDarkV2.tsx | 557 ++++++++++++------ components/agents/AgentPresetPanelDarkV2.tsx | 79 +-- .../agents/AgentWorkflowBrandModelPicker.tsx | 94 ++- .../agents/AgentWorkflowMaterialPicker.tsx | 105 +++- .../AgentWorkflowMaterialSelectionPanel.tsx | 31 +- .../agents/AgentWorkflowPanelDarkV2.tsx | 268 ++++----- .../agents/AgentWorkflowShowcaseBanner.tsx | 126 ++++ components/ui/searchable-select.tsx | 53 +- lib/agents/workflow-showcase-config.ts | 47 ++ types/agent.ts | 11 + 14 files changed, 1472 insertions(+), 424 deletions(-) create mode 100644 components/agents/AgentCanvasTopNavDark.tsx create mode 100644 components/agents/AgentWorkflowShowcaseBanner.tsx create mode 100644 lib/agents/workflow-showcase-config.ts diff --git a/app/(admin)/settings/agent-workflow/agent-workflow-settings-client.tsx b/app/(admin)/settings/agent-workflow/agent-workflow-settings-client.tsx index 03e6560f3..7240c3016 100644 --- a/app/(admin)/settings/agent-workflow/agent-workflow-settings-client.tsx +++ b/app/(admin)/settings/agent-workflow/agent-workflow-settings-client.tsx @@ -22,6 +22,10 @@ import { defaultAgentWorkflowBrandModelConfig, normalizeAgentWorkflowBrandModelConfig, } from "@/lib/agents/workflow-brand-model-config"; +import { + defaultAgentWorkflowShowcaseConfig, + normalizeAgentWorkflowShowcaseConfig, +} from "@/lib/agents/workflow-showcase-config"; import { defaultAgentWorkflowMaterialApiConfig, normalizeAgentWorkflowMaterialApiConfig, @@ -37,6 +41,7 @@ import type { AgentWorkflowBrandModelConfig, AgentWorkflowMaterialApiConfig, AgentWorkflowOptionUiConfig, + AgentWorkflowShowcaseConfig, AgentWorkflowStepUiConfig, AgentWorkflowUiConfig, } from "@/types/agent"; @@ -132,11 +137,15 @@ export function AgentWorkflowSettingsClient({ agentWorkflowUiConfig?: AgentWorkflowUiConfig; agentWorkflowMaterialApiConfig?: AgentWorkflowMaterialApiConfig; agentWorkflowBrandModelConfig?: AgentWorkflowBrandModelConfig; + agentWorkflowShowcaseConfig?: AgentWorkflowShowcaseConfig; }>("/api/site-settings", fetcher); const [config, setConfig] = useState(defaultAgentWorkflowUiConfig); const [materialApiConfig, setMaterialApiConfig] = useState( defaultAgentWorkflowMaterialApiConfig ); + const [showcaseConfig, setShowcaseConfig] = useState( + defaultAgentWorkflowShowcaseConfig + ); const [brandModelConfig, setBrandModelConfig] = useState( defaultAgentWorkflowBrandModelConfig ); @@ -150,6 +159,9 @@ export function AgentWorkflowSettingsClient({ setMaterialApiConfig( normalizeAgentWorkflowMaterialApiConfig(data.agentWorkflowMaterialApiConfig) ); + setShowcaseConfig( + normalizeAgentWorkflowShowcaseConfig(data.agentWorkflowShowcaseConfig) + ); setBrandModelConfig( normalizeAgentWorkflowBrandModelConfig(data.agentWorkflowBrandModelConfig) ); @@ -279,6 +291,7 @@ export function AgentWorkflowSettingsClient({ agentWorkflowUiConfig: config, agentWorkflowMaterialApiConfig: materialApiConfig, agentWorkflowBrandModelConfig: brandModelConfig, + agentWorkflowShowcaseConfig: showcaseConfig, }), }); @@ -395,6 +408,43 @@ export function AgentWorkflowSettingsClient({ })); }; + const handleUploadShowcaseAsset = async ( + target: "video" | "poster", + file: File + ) => { + const isVideo = target === "video"; + const expectedPrefix = isVideo ? "video/" : "image/"; + + if (!file.type.startsWith(expectedPrefix)) { + toast.error(isVideo ? "请上传视频文件" : "请上传图片文件"); + return; + } + + const refKey = `showcase:${target}`; + try { + setUploadingKey(refKey); + const formData = new FormData(); + formData.append("file", file); + + const response = await fetchUploadWithRetry(formData); + const result = await response.json(); + + if (!response.ok || !result?.url) { + throw new Error(result?.error || "上传失败"); + } + + setShowcaseConfig((prev) => ({ + ...prev, + [target === "video" ? "videoUrl" : "posterUrl"]: result.url, + })); + toast.success(isVideo ? "视频海报上传成功" : "视频封面上传成功"); + } catch (error) { + toast.error(error instanceof Error ? error.message : "上传失败"); + } finally { + setUploadingKey(null); + } + }; + return (
@@ -440,6 +490,251 @@ export function AgentWorkflowSettingsClient({ ) : (
+ + + 顶部视频海报 + + 配置第一步顶部展示区的视频海报。前台会按固定 21:9 比例自动循环播放,并同步显示可自定义标题、按钮文案和海报叠加文字。 + + + +
+
+
启用顶部视频海报
+
+ 关闭后前台会隐藏视频海报展示区,但保留下方工作流内容。 +
+
+ + setShowcaseConfig((prev) => ({ + ...prev, + enabled: checked, + })) + } + /> +
+ +
+
+ + + setShowcaseConfig((prev) => ({ + ...prev, + title: event.target.value, + })) + } + placeholder="三倍速出片,电影级质感" + /> +
+
+ + + setShowcaseConfig((prev) => ({ + ...prev, + subtitle: event.target.value, + })) + } + placeholder="第一步:风格选择 第二步:生图模式" + /> +
+
+ + + setShowcaseConfig((prev) => ({ + ...prev, + actionText: event.target.value, + })) + } + placeholder="我要创作" + /> +
+
+ + + setShowcaseConfig((prev) => ({ + ...prev, + footerText: event.target.value, + })) + } + placeholder="用户作品" + /> +
+
+ +
+ +