From 32f3f1df5a08f6d88c73ad380d9295f0942b7b52 Mon Sep 17 00:00:00 2001 From: ddcat666 <26564566+ddcat666@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:47:49 +0800 Subject: [PATCH] =?UTF-8?q?fix(image):=20=E8=A1=A5=E5=85=85=E5=88=86?= =?UTF-8?q?=E8=BE=A8=E7=8E=87=E6=A1=A3=E4=BD=8D=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/image-parameter-fields.tsx | 72 ++++++++++++++----- web/test/image-parameters.test.tsx | 9 +++ 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/web/src/components/image-parameter-fields.tsx b/web/src/components/image-parameter-fields.tsx index f0349d5c5..4683729fa 100644 --- a/web/src/components/image-parameter-fields.tsx +++ b/web/src/components/image-parameter-fields.tsx @@ -2,7 +2,7 @@ import { Input, InputNumber, Switch } from "antd"; import { useEffect, useRef, useState } from "react"; import { ImageSizePresetsEditor } from "./image-size-presets-editor"; import { ImageSizePicker } from "./image-size-picker"; -import { imageSingleSizeTier, imageSizeConfigWithPresets, imageSizePresets } from "@/lib/image-size-presets"; +import { IMAGE_RESOLUTIONS, imageSingleSizeTier, imageSizeConfigWithPresets, imageSizePresets } from "@/lib/image-size-presets"; import { Select } from "@/components/ui/base/select"; import { imageHostControls, imageParameterAccepts, imageParameterRequest, parseImageParameters, projectImageParameters, updateImageParameterSize, type ImageParameter, type ImageParameterValue } from "@/lib/image-parameters"; import type { ImageCapabilityConfig } from "@/lib/model-capabilities"; @@ -189,6 +189,18 @@ export function ImageParameterSchemaEditor({ definitions, parameters, disabled,

选择此模型支持的参数和范围。生成界面同步显示启用项,标记“可计价”的参数可用于规格价格。

{parameters.map((field) => { const definition = definitions.find((p) => p.name === field.name) || field; + const isResolution = field.name === "imageResolution" && field.type === "string"; + const resolutionChoices = isResolution ? (definition.values?.length ? definition.values : IMAGE_RESOLUTIONS.filter((tier) => imageParameterAccepts(definition, tier))) : []; + const quickResolutionChoices = isResolution && (!definition.values?.length || definition.values.some((value) => IMAGE_RESOLUTIONS.includes(String(value).toLowerCase()))) ? resolutionChoices : []; + const updateValues = (items: string[]) => { + const values = [...new Set(items.map((item) => { + const declared = definition.values?.find((v) => String(v) === item); + if (declared !== undefined) return declared; + return isResolution && !definition.values?.length && /^\d+(?:\.\d+)?k$/i.test(item.trim()) ? item.trim().toLowerCase() : item; + }))]; + const next = { ...field, values }; + update(field.name, { values, default: isResolution && !values.length ? undefined : imageParameterAccepts(next, field.default) ? field.default : values[0] }); + }; return (
@@ -202,23 +214,43 @@ export function ImageParameterSchemaEditor({ definitions, parameters, disabled, {field.enabled !== false ? (
{definition.values?.length || field.type === "string" ? ( - + {quickResolutionChoices.length ? ( +
+
+ {quickResolutionChoices.map((tier) => { + const selected = (field.values || []).includes(tier); + return ( + + ); + })} +
+

点选模型支持的档位,再次点击可移除。{!definition.values?.length ? "其他档位可在上方输入后按回车添加。" : ""}

+
+ ) : null} +
) : null} {(field.type === "number" || field.type === "integer") && !definition.values?.length ? (
@@ -316,7 +348,9 @@ export function ImageParameterSizeEditor({ profile, definition, disabled, onChan

) : null} {field.enabled !== false ? ( - grouped || pixelSize ? ( + grouped && !tiers.length ? ( +

请先在上方分辨率中选择支持的档位,再配置各档位的比例和尺寸。

+ ) : grouped || pixelSize ? ( { + const field: ImageParameter = { name: "imageResolution", label: "分辨率", type: "string", default: "1k", pricing: true }; + const html = renderToStaticMarkup( {}} />); + expect(html).toContain("1K"); + expect(html).toContain("2K"); + expect(html).toContain("4K"); + expect(html).toContain("分辨率快捷选择"); + expect(html).toContain("输入后按回车,或点击下方档位"); + }); test("resolution-only contract renders no invented quality or pixel-tier controls", () => { const { image, config } = fixture([parameters[0]]); const html = renderToStaticMarkup( {}} />);