diff --git a/app/(admin)/settings/admin-settings-client.tsx b/app/(admin)/settings/admin-settings-client.tsx index 93c477fec..efe0651a6 100644 --- a/app/(admin)/settings/admin-settings-client.tsx +++ b/app/(admin)/settings/admin-settings-client.tsx @@ -826,7 +826,7 @@ export function AdminSettingsClient() { imageSize: "square" as "square" | "square_hd", }); - // 详情替换配置状态 + // 批量处理配置状态 const [sceneFusionConfig, setSceneFusionConfig] = useState({ enabled: true, defaultPrompt: "将图1的产品替换到图2的场景中,保持图1产品的外观、颜色和细节不变,自然融合到图2的环境中。", @@ -1014,7 +1014,7 @@ export function AdminSettingsClient() { } }, [realtimeCanvasConfigData]); - // 加载详情替换配置 + // 加载批量处理配置 const { data: sceneFusionConfigData } = useSWR("/api/admin/settings?key=scene_fusion_config", fetcher); useEffect(() => { if (sceneFusionConfigData?.setting?.value) { @@ -2102,7 +2102,7 @@ export function AdminSettingsClient() { } }; - // --- 详情替换配置逻辑 --- + // --- 批量处理配置逻辑 --- const handleSaveSceneFusionConfig = async () => { try { if (!sceneFusionConfig.defaultPrompt.trim()) { @@ -2125,9 +2125,9 @@ export function AdminSettingsClient() { }); if (!response.ok) throw new Error("保存失败"); - toast.success("详情替换配置保存成功"); + toast.success("批量处理配置保存成功"); } catch (error) { - toast.error("保存详情替换配置失败"); + toast.error("保存批量处理配置失败"); } }; @@ -8630,24 +8630,24 @@ export function AdminSettingsClient() { - {/* 详情替换配置 */} + {/* 批量处理配置 */} - 详情替换配置 + 批量处理配置 - 配置详情替换功能的默认提示词和参数。详情替换可将产品图批量融合到多个场景中。 + 配置批量处理功能的默认提示词和参数。批量处理可将产品图批量融合到多个场景中。 {/* 功能开关 */}
- +
- 开启后用户可在图片编辑器中使用详情替换功能 + 开启后用户可在图片编辑器中使用批量处理功能
@@ -8673,7 +8673,7 @@ export function AdminSettingsClient() { disabled={!sceneFusionConfig.enabled} />
- 该提示词将作为详情替换的基础指令,用户可以在此基础上添加修改要求 + 该提示词将作为批量处理的基础指令,用户可以在此基础上添加修改要求
diff --git a/app/canvas/[id]/page.tsx b/app/canvas/[id]/page.tsx index 72ea4b513..96023ff1c 100644 --- a/app/canvas/[id]/page.tsx +++ b/app/canvas/[id]/page.tsx @@ -25,6 +25,7 @@ import { Settings, PenTool, Box, + Layers, } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; @@ -60,6 +61,7 @@ import { CanvasWorkspace } from "@/components/canvas"; import { CanvasChatPanel } from "@/components/canvas/CanvasChatPanel"; import { CanvasFileListPanel } from "@/components/canvas/CanvasFileListPanel"; import { ObjectPickerOverlay } from "@/components/canvas/ObjectPickerOverlay"; +import { SceneFusionDialog } from "@/components/scene-fusion-dialog"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { cn, fetcher } from "@/lib/utils"; import { Grid2X2 } from "lucide-react"; @@ -127,6 +129,7 @@ export default function CanvasEditorPage({ params }: PageProps) { const [isEditingTitle, setIsEditingTitle] = useState(false); const [editTitle, setEditTitle] = useState(""); const [isPanelOpen, setIsPanelOpen] = useState(true); + const [sceneFusionDialogOpen, setSceneFusionDialogOpen] = useState(false); // 面板模式: 'chat' 聊天面板, 'fileList' 文件列表 const [panelMode, setPanelMode] = useState<'chat' | 'fileList'>('chat'); const [viewportWidth, setViewportWidth] = useState(0); @@ -769,6 +772,20 @@ export default function CanvasEditorPage({ params }: PageProps) { 平移 (H) + + + + + 批量处理 + +
); diff --git a/components/canvas/nodes/ImageNode.tsx b/components/canvas/nodes/ImageNode.tsx index ea107b31b..d689fecb8 100644 --- a/components/canvas/nodes/ImageNode.tsx +++ b/components/canvas/nodes/ImageNode.tsx @@ -1192,7 +1192,7 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) { 'extend': '扩图', 'resize': '调尺', 'angle': '视角', - 'scene-fusion': '替换', + 'scene-fusion': '批量处理', 'annotate': '标注', 'text-edit': '改字', 'note': '备注', @@ -2006,7 +2006,7 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) { /> )} - {/* 详情替换对话框 */} + {/* 批量处理对话框 */} - 详情替换 + 批量处理
diff --git a/components/scene-fusion-dialog.tsx b/components/scene-fusion-dialog.tsx index a735a3f15..5bc7e96b1 100644 --- a/components/scene-fusion-dialog.tsx +++ b/components/scene-fusion-dialog.tsx @@ -53,7 +53,7 @@ export function SceneFusionDialog({ open, onOpenChange }: SceneFusionDialogProps // 最大自动重试次数 const MAX_AUTO_RETRY = 10; - // 获取详情替换配置(使用公开 API 端点) + // 获取批量处理配置(使用公开 API 端点) const { data: configData } = useSWR( open ? "/api/scene-fusion/config" : null, fetcher @@ -144,7 +144,7 @@ export function SceneFusionDialog({ open, onOpenChange }: SceneFusionDialogProps // 开始裂变 const startFusion = async () => { if (config?.enabled === false) { - toast.error("详情替换功能已被管理员禁用"); + toast.error("批量处理功能已被管理员禁用"); return; } if (!productImage) { @@ -410,7 +410,7 @@ export function SceneFusionDialog({ open, onOpenChange }: SceneFusionDialogProps - 详情替换 + 批量处理 上传1张产品图和多张场景图,AI 自动将产品融合到所有场景中。 diff --git a/components/scene-fusion-view.tsx b/components/scene-fusion-view.tsx index 278a22354..39f950964 100644 --- a/components/scene-fusion-view.tsx +++ b/components/scene-fusion-view.tsx @@ -40,12 +40,12 @@ interface SceneFusionViewProps { onBack: () => void; /** * 可选:从外部(例如图片编辑器当前图片)传入的初始产品图。 - * 这样在「详情替换」中就可以自动带入当前正在编辑的图片, + * 这样在「批量处理」中就可以自动带入当前正在编辑的图片, * 避免用户重复上传。 */ initialProductImage?: string | null; /** - * 可选:初始产品名称,便于在进入详情替换时预填文案。 + * 可选:初始产品名称,便于在进入批量处理时预填文案。 */ initialProductName?: string; } @@ -54,7 +54,7 @@ export function SceneFusionView({ onBack, initialProductImage, initialProductNam // 最大自动重试次数 const MAX_AUTO_RETRY = 10; - // 获取详情替换配置(使用公开 API 端点) + // 获取批量处理配置(使用公开 API 端点) const { data: configData } = useSWR( "/api/scene-fusion/config", fetcher @@ -222,7 +222,7 @@ export function SceneFusionView({ onBack, initialProductImage, initialProductNam // 开始裂变 const startFusion = async () => { if (config?.enabled === false) { - toast.error("详情替换功能已被管理员禁用"); + toast.error("批量处理功能已被管理员禁用"); return; } if (!productImage) { @@ -613,7 +613,7 @@ export function SceneFusionView({ onBack, initialProductImage, initialProductNam
- 详情替换 + 批量处理