diff --git a/src/components/image-editor/ImageCanvasExportModel.ts b/src/components/image-editor/ImageCanvasExportModel.ts index 48a203845..b31f5d87c 100644 --- a/src/components/image-editor/ImageCanvasExportModel.ts +++ b/src/components/image-editor/ImageCanvasExportModel.ts @@ -7,6 +7,7 @@ import type { } from './ImageCanvasEditorTypes'; import { DEFAULT_ICON_DESCRIPTIONS, + formatEditorGenerationInputFieldValue, formatLayerImageType, getEditorLayerModelDisplayName, isEditorUserVisibleGenerationInputField, @@ -540,7 +541,7 @@ function buildVisibleGenerationInputs(layer: CanvasLayer) { .filter((field) => !isBuiltInGenerationInputField(field)) .map((field) => ({ title: field.title, - value: field.value, + value: formatEditorGenerationInputFieldValue(field), })) ?? []; const references = layer.generationInputs?.references.map((reference) => ({ diff --git a/src/components/image-editor/ImageCanvasGenerationModel.test.ts b/src/components/image-editor/ImageCanvasGenerationModel.test.ts index c71601aff..a461ac5f6 100644 --- a/src/components/image-editor/ImageCanvasGenerationModel.test.ts +++ b/src/components/image-editor/ImageCanvasGenerationModel.test.ts @@ -39,6 +39,7 @@ import { EDITOR_SOUND_EFFECT_MODEL_OPTIONS, EDITOR_VIDEO_MODEL_MUD_POINT_CONFIG, EDITOR_VIDEO_MODEL_OPTIONS, + formatEditorGenerationInputFieldValue, getGenerationFrameAriaLabel, getGenerationFrameLabel, IMAGE_MODEL_GPT_IMAGE_2, @@ -61,6 +62,23 @@ describe('ImageCanvasGenerationModel', () => { }); }); + it('展示时长时收敛到两位小数且不改动其他字段', () => { + const format = (title: string, value: string) => + formatEditorGenerationInputFieldValue({ title, value }); + + expect(format('时长', '8.306938775510204秒')).toBe('8.31秒'); + expect(format('时长', '3.4512秒')).toBe('3.45秒'); + // 整数与一位小数不补零,"自动"这类无数字取值原样保留。 + expect(format('时长', '5秒')).toBe('5秒'); + expect(format('时长', '2.5秒')).toBe('2.5秒'); + expect(format('时长', '自动')).toBe('自动'); + expect(format('duration', '8.306938775510204s')).toBe('8.31s'); + // 非时长字段一律原样返回,不能误伤提示词里的数字。 + expect(format('用户描述', '持续 8.306938775510204 秒的低鸣')).toBe( + '持续 8.306938775510204 秒的低鸣', + ); + }); + it('为所有编辑器生成模型提供显式定价配置', () => { expect( EDITOR_IMAGE_MODEL_OPTIONS.map((option) => option.value).filter( diff --git a/src/components/image-editor/ImageCanvasGenerationModel.ts b/src/components/image-editor/ImageCanvasGenerationModel.ts index a47fa33d9..80f1d15d9 100644 --- a/src/components/image-editor/ImageCanvasGenerationModel.ts +++ b/src/components/image-editor/ImageCanvasGenerationModel.ts @@ -637,6 +637,30 @@ export function isEditorUserVisibleGenerationInputField( return field.title.trim() !== '处理模型'; } +const GENERATION_INPUT_DURATION_TITLES = new Set(['时长', 'duration']); +const GENERATION_INPUT_DURATION_DECIMALS = 2; + +/** + * 时长字段落库的是模型返回的全精度秒数(例如 8.306938775510204 秒),展示时收敛到两位 + * 小数。只作用于渲染:底层字段保持原值,重绘默认时长与作品时长推断仍按原精度解析。 + */ +export function formatEditorGenerationInputFieldValue( + field: CanvasGenerationInputField, +) { + if (!GENERATION_INPUT_DURATION_TITLES.has(field.title.trim().toLowerCase())) { + return field.value; + } + // 只改写首个数字,"自动"这类无数字取值和"秒"后缀都原样保留。 + return field.value.replace(/\d+(?:\.\d+)?/u, (matched) => { + const parsed = Number.parseFloat(matched); + if (!Number.isFinite(parsed)) { + return matched; + } + const factor = 10 ** GENERATION_INPUT_DURATION_DECIMALS; + return String(Math.round(parsed * factor) / factor); + }); +} + export function getEditorLayerModelDisplayName( model: string | null | undefined, ) { diff --git a/src/components/image-editor/ImageCanvasMetadataModalView.tsx b/src/components/image-editor/ImageCanvasMetadataModalView.tsx index 779157413..7ca69a0c1 100644 --- a/src/components/image-editor/ImageCanvasMetadataModalView.tsx +++ b/src/components/image-editor/ImageCanvasMetadataModalView.tsx @@ -2,6 +2,7 @@ import { UnifiedModal } from '../common/UnifiedModal'; import type { CanvasLayer } from './ImageCanvasEditorTypes'; import { formatTaskIdForDisplay } from './ImageCanvasExportModel'; import { + formatEditorGenerationInputFieldValue, formatLayerImageType, getEditorLayerModelDisplayName, isEditorUserVisibleGenerationInputField, @@ -63,7 +64,7 @@ export function ImageCanvasMetadataModalView({ {field.title} - {field.value} + {formatEditorGenerationInputFieldValue(field)} ))} {generationInputReferences.length ? (