From 79048a8c1638ebc9e47a299ecb7731fdf32661ac Mon Sep 17 00:00:00 2001 From: kdletters Date: Sun, 26 Apr 2026 16:14:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=88=9B=E4=BD=9C=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E8=80=97=E6=97=B6=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customWorldAgentGenerationProgress.test.ts | 13 +++++++++++++ .../customWorldAgentGenerationProgress.ts | 16 +++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/services/customWorldAgentGenerationProgress.test.ts b/src/services/customWorldAgentGenerationProgress.test.ts index 712db293..0a0f9a8d 100644 --- a/src/services/customWorldAgentGenerationProgress.test.ts +++ b/src/services/customWorldAgentGenerationProgress.test.ts @@ -128,6 +128,19 @@ test('maps running draft_foundation operation to refined generation progress ste expect(isDraftFoundationOperationRunning(baseOperation)).toBe(true); }); +test('calculates elapsed time from operation startedAt before local fallback', () => { + const progress = buildAgentDraftFoundationGenerationProgress( + { + ...baseOperation, + startedAt: '1970-01-01T00:00:01.000Z', + }, + 4_000, + 6_000, + ); + + expect(progress?.elapsedMs).toBe(5_000); +}); + test('maps auto asset phases to refined generation progress steps', () => { const progress = buildAgentDraftFoundationGenerationProgress( { diff --git a/src/services/customWorldAgentGenerationProgress.ts b/src/services/customWorldAgentGenerationProgress.ts index 5b10231d..bf1d6f0a 100644 --- a/src/services/customWorldAgentGenerationProgress.ts +++ b/src/services/customWorldAgentGenerationProgress.ts @@ -380,6 +380,18 @@ function parseOperationUpdatedAtMs( return Number.isFinite(parsedMs) ? parsedMs : null; } +function parseOperationStartedAtMs( + operation: CustomWorldAgentOperationRecord, +) { + const rawStartedAt = operation.startedAt?.trim(); + if (!rawStartedAt) { + return null; + } + + const parsedMs = Date.parse(rawStartedAt); + return Number.isFinite(parsedMs) ? parsedMs : null; +} + function resolveAgentDraftFoundationStepIndex( operation: CustomWorldAgentOperationRecord, ) { @@ -517,7 +529,7 @@ export function isDraftFoundationOperationRunning( export function buildAgentDraftFoundationGenerationProgress( operation: CustomWorldAgentOperationRecord | null | undefined, - startedAtMs: number | null, + fallbackStartedAtMs: number | null, nowMs = Date.now(), ): CustomWorldGenerationProgress | null { if (!isDraftFoundationOperation(operation)) { @@ -526,6 +538,8 @@ export function buildAgentDraftFoundationGenerationProgress( const activeStepIndex = resolveAgentDraftFoundationStepIndex(operation); const overallProgress = resolveFailedProgress(operation, activeStepIndex); + // 中文注释:总耗时必须绑定服务端 operation 创建时间,避免刷新或前端重挂载后重新计时。 + const startedAtMs = parseOperationStartedAtMs(operation) ?? fallbackStartedAtMs; const elapsedMs = startedAtMs ? Math.max(0, nowMs - startedAtMs) : 0; const estimatedRemainingMs = resolveEstimatedRemainingMs( overallProgress,