From 0547ab2cc2007a1123d5fa43ea216d1f139f89d3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 18 Jan 2026 17:04:47 +0800 Subject: [PATCH] feat: add model selection for scene fusion - allow choosing between Alibaba and Gemini models --- .../settings/admin-settings-client.tsx | 41 ++++++++++++++++++- app/api/scene-fusion/route.ts | 36 ++++++++++++---- 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/app/(admin)/settings/admin-settings-client.tsx b/app/(admin)/settings/admin-settings-client.tsx index 155c9ec81..814b702be 100644 --- a/app/(admin)/settings/admin-settings-client.tsx +++ b/app/(admin)/settings/admin-settings-client.tsx @@ -404,6 +404,7 @@ export function AdminSettingsClient() { enabled: true, defaultPrompt: "将图1的产品替换到图2的场景中,保持图1产品的外观、颜色和细节不变,自然融合到图2的环境中。", maxScenes: 10, + modelId: "", // 使用的生图模型ID }); // 加载抠图API配置 @@ -497,11 +498,13 @@ export function AdminSettingsClient() { enabled?: boolean; defaultPrompt?: string; maxScenes?: number; + modelId?: string; }; setSceneFusionConfig({ enabled: config.enabled ?? true, defaultPrompt: config.defaultPrompt || "将图1的产品替换到图2的场景中,保持图1产品的外观、颜色和细节不变,自然融合到图2的环境中。", maxScenes: config.maxScenes ?? 10, + modelId: config.modelId ?? "", }); } }, [sceneFusionConfigData]); @@ -966,6 +969,7 @@ export function AdminSettingsClient() { enabled: sceneFusionConfig.enabled, defaultPrompt: sceneFusionConfig.defaultPrompt.trim(), maxScenes: sceneFusionConfig.maxScenes, + modelId: sceneFusionConfig.modelId, }, }), }); @@ -3898,12 +3902,47 @@ export function AdminSettingsClient() { + {/* 生图模型选择 */} +
+ + +
+ 选择用于场景裂变的生图模型,支持阿里生图和Gemini图片编辑模型 +
+
+
功能说明

• 用户上传1张产品图和多张场景参考图

• 系统自动将产品图融合到每个场景中

-

• 使用已配置的阿里生图模型进行处理

+

• 支持选择阿里生图或Gemini图片模型

• 生成的图片会自动保存到用户相册

diff --git a/app/api/scene-fusion/route.ts b/app/api/scene-fusion/route.ts index 1c18d2521..31f96cec3 100644 --- a/app/api/scene-fusion/route.ts +++ b/app/api/scene-fusion/route.ts @@ -42,11 +42,13 @@ async function getSceneFusionConfig() { enabled?: boolean; defaultPrompt?: string; maxScenes?: number; + modelId?: string; }; return { enabled: config.enabled ?? true, defaultPrompt: config.defaultPrompt || FALLBACK_PROMPT, maxScenes: config.maxScenes ?? 10, + modelId: config.modelId || "", }; } } catch (error) { @@ -57,6 +59,7 @@ async function getSceneFusionConfig() { enabled: true, defaultPrompt: FALLBACK_PROMPT, maxScenes: 10, + modelId: "", }; } @@ -418,22 +421,39 @@ export async function POST(request: Request) { console.log(`[SceneFusion] Processing ${scenes.length} scenes for user ${session.user.id}`); console.log(`[SceneFusion] Product name: ${productName || '(not specified)'}`); console.log(`[SceneFusion] Using default prompt: ${config.defaultPrompt.substring(0, 50)}...`); + console.log(`[SceneFusion] Configured model ID: ${config.modelId || '(auto - default alibaba)'}`); - // 4. 获取阿里生图模型配置 + // 4. 获取生图模型配置 const allModels = await getEnabledAiModelsWithProvider(); - const alibabaModel = allModels.find( - (m) => m.provider.type === "alibaba-image" && m.model.isEnabled - ); - if (!alibabaModel) { + let selectedModel: typeof allModels[0] | undefined; + + // 如果配置了指定的模型ID,优先使用 + if (config.modelId) { + selectedModel = allModels.find( + (m) => m.model.id === config.modelId && m.model.isEnabled + ); + if (!selectedModel) { + console.warn(`[SceneFusion] Configured model ${config.modelId} not found or disabled, falling back to default`); + } + } + + // 如果没有配置或配置的模型不可用,使用默认的阿里生图模型 + if (!selectedModel) { + selectedModel = allModels.find( + (m) => m.provider.type === "alibaba-image" && m.model.isEnabled + ); + } + + if (!selectedModel) { return NextResponse.json( - { error: "未配置阿里生图模型,请联系管理员" }, + { error: "未配置可用的生图模型,请联系管理员" }, { status: 500 } ); } - const { provider, model } = alibabaModel; - console.log(`[SceneFusion] Using model: ${model.displayName} (${model.modelId})`); + const { provider, model } = selectedModel; + console.log(`[SceneFusion] Using model: ${model.displayName} (${model.modelId}) - Provider: ${provider.type}`); // 4. 预处理:将 Base64 图片上传到 S3 let productImageUrl = productImage;