"use client"; import { useState, useEffect } from "react"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Check, Image, Ratio, Maximize2, Images, Sparkles, Ban } from "lucide-react"; import { cn } from "@/lib/utils"; import { Input } from "@/components/ui/input"; import { Switch } from "@/components/ui/switch"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Label } from "@/components/ui/label"; // 图片生成参数接口 export interface ImageGenerationParams { aspectRatio: string; imageSize: string; imageCount?: number; // 生成图片数量 // 🆕 阿里生图专用参数 size?: string; // 自定义分辨率,如 "1024*1024" negativePrompt?: string; // 反向提示词 promptExtend?: boolean; // 提示词智能优化 watermark?: boolean; // 水印 seed?: number; // 随机种子 } interface ImageParamsBarProps { modelName?: string; initialParams?: Partial; onParamsChange?: (params: ImageGenerationParams) => void; inline?: boolean; // 内联模式:只显示参数按钮,不显示外层容器 providerType?: string; // 模型类型:gemini, volcano-vision, alibaba-image 等 // 🆕 图片生成模型特性配置(从模型配置中读取) imageGenConfig?: { maxImages?: number; supportsSize?: boolean; supportsPromptExtend?: boolean; supportsNegativePrompt?: boolean; supportsWatermark?: boolean; supportsSeed?: boolean; }; } // 图片比例选项(根据 Nano Banana 文档) const ASPECT_RATIO_OPTIONS = [ { value: "auto", label: "自动" }, { value: "1:1", label: "1:1" }, { value: "16:9", label: "16:9" }, { value: "9:16", label: "9:16" }, { value: "4:3", label: "4:3" }, { value: "3:4", label: "3:4" }, { value: "3:2", label: "3:2" }, { value: "2:3", label: "2:3" }, { value: "5:4", label: "5:4" }, { value: "4:5", label: "4:5" }, { value: "21:9", label: "21:9" }, ] as const; // 图片大小选项(仅支持 nano-banana-pro) const IMAGE_SIZE_OPTIONS = [ { value: "1K", label: "1K", disabled: false }, { value: "2K", label: "2K ⚡", disabled: false }, // 默认推荐 { value: "4K", label: "4K 🐌", disabled: false }, // 4K较慢 ] as const; export function ImageParamsBar({ modelName = "Gemini 图片生成", initialParams, onParamsChange, inline = false, providerType = "gemini", // 默认 gemini imageGenConfig, }: ImageParamsBarProps) { const [params, setParams] = useState({ aspectRatio: "auto", imageSize: "2K", // 默认 2K imageCount: 1, // 默认 1 张 promptExtend: true, // 阿里生图默认开启提示词优化 watermark: false, ...initialParams, }); // 根据模型类型和配置确定可选的图片数量 const getImageCountOptions = () => { // 优先使用模型配置中的 maxImages if (imageGenConfig?.maxImages) { return Array.from({ length: imageGenConfig.maxImages }, (_, i) => i + 1); } // 否则根据 providerType 判断 if (providerType === "alibaba-image") { // 阿里生图:1~6 张(qwen-image-edit-plus) return [1, 2, 3, 4, 5, 6]; } if (providerType === "volcano-vision") { // 即梦4.5(豆包):1~3 张 return [1, 2, 3]; } // Gemini:1~2 张 return [1, 2]; }; const imageCountOptions = getImageCountOptions(); // 是否显示阿里生图专用参数 const isAlibabaImage = providerType === "alibaba-image"; const showPromptExtend = isAlibabaImage || imageGenConfig?.supportsPromptExtend; const showNegativePrompt = isAlibabaImage || imageGenConfig?.supportsNegativePrompt; // 🆕 监听 initialParams 变化,确保状态同步 useEffect(() => { console.log("[ImageParamsBar] Mount/Update - initialParams:", initialParams); // 如果 initialParams 存在,更新参数 // 如果 initialParams 是 undefined,保持当前参数不变(使用 useState 的初始值) if (initialParams !== undefined) { setParams((prevParams) => ({ // 先使用默认值 aspectRatio: "auto", imageSize: "2K", imageCount: 1, // 然后应用 initialParams(会覆盖默认值) ...initialParams, })); } }, [initialParams]); const updateParam = ( key: K, value: ImageGenerationParams[K] ) => { const newParams = { ...params, [key]: value }; console.log("[ImageParamsBar] Updating param:", key, "=", value); console.log("[ImageParamsBar] New params:", newParams); setParams(newParams); onParamsChange?.(newParams); }; // 内联模式:只返回参数按钮,嵌入工具栏 if (inline) { return (
{/* 图片比例 */}
{ASPECT_RATIO_OPTIONS.map((option) => ( ))}
{/* 分辨率 */} {IMAGE_SIZE_OPTIONS.map((option) => ( updateParam("imageSize", option.value)} className="focus-visible:ring-0 focus-visible:ring-offset-0 focus:outline-none focus:ring-0" > {option.label} ))} {/* 图片数量 */} {imageCountOptions.map((count) => ( updateParam("imageCount", count)} className="focus-visible:ring-0 focus-visible:ring-offset-0 focus:outline-none focus:ring-0" > {count}张 ))} {/* 🆕 阿里生图专用:提示词优化 & 反向提示词 */} {(showPromptExtend || showNegativePrompt) && (
高级选项
{/* 提示词智能优化 */} {showPromptExtend && (

AI 自动优化您的描述

updateParam("promptExtend", checked)} />
)} {/* 反向提示词 */} {showNegativePrompt && (
updateParam("negativePrompt", e.target.value)} className="h-8 text-xs" />
)}
)}
); } // 非内联模式(暂时不实现,因为只需要内联模式) return null; }