音频信息的时长展示收敛到两位小数
Project CI / Repository checks (pull_request) Failing after 7s
Project CI / Backend tests (pull_request) Failing after 8s
Project CI / Frontend tests (pull_request) Successful in 3m17s
Project CI / Native shell tests (pull_request) Has been cancelled

模型返回的时长是全精度秒数,落库后信息面板会直出 8.306938775510204秒
这类无意义尾数。

- 新增 formatEditorGenerationInputFieldValue,只改写标题为「时长」或
  duration 的字段中的首个数字,四舍五入到两位小数
- 接入音频信息弹窗与导出的可见元数据两处用户可见出口
- 不补零,"自动"这类无数字取值与其他字段原样保留

只作用于展示:generationInputs 落库值不变,重绘默认时长与作品时长推断
仍按原精度解析,已有素材也一并生效。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-07 12:28:41 +00:00
parent 97de29a58f
commit 87c0e167c4
4 changed files with 46 additions and 2 deletions
@@ -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) => ({
@@ -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(
@@ -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,
) {
@@ -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({
<span className="image-canvas-editor__metadata-input-title">
{field.title}
</span>
<span>{field.value}</span>
<span>{formatEditorGenerationInputFieldValue(field)}</span>
</div>
))}
{generationInputReferences.length ? (