优化切换生图模型后的参数工具同步逻辑

This commit is contained in:
Your Name 2026-02-07 20:51:10 +08:00
parent 55c41f7b45
commit 79d54f0a92
2 changed files with 93 additions and 35 deletions

View File

@ -37,6 +37,32 @@ import type { VisibilityType } from "@/components/visibility-selector";
import type { VideoGenerationParams } from "@/components/video-params-bar";
import type { ImageGenerationParams } from "@/components/image-params-bar";
function normalizeImageParamsForProvider(
params: ImageGenerationParams,
providerType?: string
): ImageGenerationParams {
const normalized = { ...params };
const currentCount = normalized.imageCount || 1;
if (providerType === "ruxa-image") {
normalized.imageCount = 1;
return normalized;
}
if (providerType === "alibaba-image") {
normalized.imageCount = Math.min(Math.max(currentCount, 1), 6);
return normalized;
}
if (providerType === "volcano-vision") {
normalized.imageCount = Math.min(Math.max(currentCount, 1), 3);
return normalized;
}
normalized.imageCount = Math.min(Math.max(currentCount, 1), 2);
return normalized;
}
export function Chat({
id,
initialMessages,
@ -167,13 +193,14 @@ export function Chat({
// 🆕 保存图片参数到 localStorage
const handleImageParamsChange = (params: ImageGenerationParams) => {
setImageParams(params);
const normalized = normalizeImageParamsForProvider(params, currentModel?.providerType);
setImageParams(normalized);
try {
localStorage.setItem("gemini-image-params", JSON.stringify(params));
localStorage.setItem("gemini-image-params", JSON.stringify(normalized));
} catch (e) {
console.error("Failed to save image params:", e);
}
console.log("[Chat] Image params updated:", params);
console.log("[Chat] Image params updated:", normalized);
};
// 🆕 获取模型列表以检查是否是视频模型/图片模型
@ -247,11 +274,17 @@ export function Chat({
// 🆕 当切换到图片模型时,强制更新 imageParams(确保组件重新渲染)
useEffect(() => {
if (isImageModel) {
// 强制更新一次 imageParams 以触发重新渲染
setImageParams(prev => ({...prev}));
console.log("[Chat] 图片模型已激活,触发参数更新");
setImageParams((prev) => {
const next = normalizeImageParamsForProvider(prev, currentModel?.providerType);
if (JSON.stringify(prev) === JSON.stringify(next)) return prev;
try {
localStorage.setItem("gemini-image-params", JSON.stringify(next));
} catch {}
return next;
});
console.log("[Chat] 图片模型已激活,参数已按当前模型规范化");
}
}, [isImageModel]);
}, [isImageModel, currentModel?.providerType]);
useEffect(() => {
currentModelIdRef.current = currentModelId;

View File

@ -79,17 +79,11 @@ export function ImageParamsBar({
providerType = "gemini", // 默认 gemini
imageGenConfig,
}: ImageParamsBarProps) {
const [params, setParams] = useState<ImageGenerationParams>({
aspectRatio: "auto",
imageSize: "2K", // 默认 2K
imageCount: 1, // 默认 1 张
promptExtend: true, // 阿里生图默认开启提示词优化
watermark: false,
...initialParams,
});
// 根据模型类型和配置确定可选的图片数量
const getImageCountOptions = () => {
// RUXA 当前按单图任务处理(优先级最高)
if (providerType === "ruxa-image") {
return [1];
}
// 优先使用模型配置中的 maxImages
if (imageGenConfig?.maxImages) {
return Array.from({ length: imageGenConfig.maxImages }, (_, i) => i + 1);
@ -99,10 +93,6 @@ export function ImageParamsBar({
// 阿里生图:1~6 张(qwen-image-edit-plus)
return [1, 2, 3, 4, 5, 6];
}
if (providerType === "ruxa-image") {
// RUXA 当前按单图任务处理
return [1];
}
if (providerType === "volcano-vision") {
// 即梦4.5(豆包):1~3 张
return [1, 2, 3];
@ -110,7 +100,41 @@ export function ImageParamsBar({
// Gemini:1~2 张
return [1, 2];
};
const clampParamsByProvider = (raw: ImageGenerationParams): ImageGenerationParams => {
const options = getImageCountOptions();
const fallbackCount = options[0] ?? 1;
const imageCount = options.includes(raw.imageCount || fallbackCount) ? (raw.imageCount || fallbackCount) : fallbackCount;
return {
...raw,
imageCount,
};
};
const isSameParams = (a: ImageGenerationParams, b: ImageGenerationParams) =>
a.aspectRatio === b.aspectRatio &&
a.imageSize === b.imageSize &&
(a.imageCount || 1) === (b.imageCount || 1) &&
a.size === b.size &&
a.negativePrompt === b.negativePrompt &&
a.promptExtend === b.promptExtend &&
a.watermark === b.watermark &&
a.seed === b.seed;
const buildBaseParams = (source?: Partial<ImageGenerationParams>) =>
clampParamsByProvider({
aspectRatio: "auto",
imageSize: "2K",
imageCount: 1,
promptExtend: true,
watermark: false,
...source,
});
const [params, setParams] = useState<ImageGenerationParams>({
...buildBaseParams(initialParams),
});
const imageCountOptions = getImageCountOptions();
// 是否显示阿里生图专用参数
@ -121,25 +145,26 @@ export function ImageParamsBar({
// 🆕 监听 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,
}));
const rawParams = {
aspectRatio: "auto",
imageSize: "2K",
imageCount: 1,
promptExtend: true,
watermark: false,
...(initialParams || {}),
} as ImageGenerationParams;
const nextParams = buildBaseParams(initialParams);
setParams((prevParams) => (isSameParams(prevParams, nextParams) ? prevParams : nextParams));
if (initialParams !== undefined && onParamsChange && !isSameParams(rawParams, nextParams)) {
onParamsChange(nextParams);
}
}, [initialParams]);
}, [initialParams, providerType, imageGenConfig?.maxImages]);
const updateParam = <K extends keyof ImageGenerationParams>(
key: K,
value: ImageGenerationParams[K]
) => {
const newParams = { ...params, [key]: value };
const newParams = clampParamsByProvider({ ...params, [key]: value });
console.log("[ImageParamsBar] Updating param:", key, "=", value);
console.log("[ImageParamsBar] New params:", newParams);
setParams(newParams);