From f2986264876e17afba88b60440704ea54249017d Mon Sep 17 00:00:00 2001 From: Momentry Studio Date: Wed, 14 Oct 2026 20:23:42 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=E5=9B=9B=E9=98=B6?= =?UTF-8?q?=E6=AE=B5=E8=BF=9B=E5=BA=A6=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: - 当前进度显示使用旧的处理器列表 - 显示了所有独立的处理步骤,而不是分阶段 解决方案: - 将处理步骤聚合到四个主要阶段 - 实现阶段级进度计算 - 更新阶段名称显示 四阶段结构: 1. Processors (30%) - 包含所有处理器 (ASR, FACE, OCR, etc.) 2. Knowledge Graph (35%) - tkg_nodes - tkg_edges 3. Moment Extraction (6%) - vlm_summary - scene_vlm - moment_chunks 4. Integration (29%) - rule1_ingestion - rule2_ingestion - face_tracing - face_dedup 实现细节: - loadPipelineStats() 中添加阶段聚合逻辑 - 根据步骤权重计算阶段进度 - 根据步骤状态确定阶段状态 - formatStageName() 更新阶段名称映射 进度计算: - 阶段进度 = 加权平均步骤进度 - 阶段状态 = 优先级: failed > completed > running > pending - 总体进度 = 加权阶段进度之和 显示效果: - ✗ Processors: 0% - ✓ Knowledge Graph: 100% - ✗ Moment Extraction: 33% - ✗ Integration: 50% 优势: - 更清晰的阶段划分 - 更好的进度概览 - 更符合实际处理流程 --- src/store.ts | 76 +++++++++++++++++++++++++++++---------- src/views/LibraryView.vue | 4 +++ 2 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/store.ts b/src/store.ts index 19663c5..e25467c 100644 --- a/src/store.ts +++ b/src/store.ts @@ -1112,31 +1112,69 @@ export async function loadPipelineStats(fileUuid: string, force = false): Promis const stages = data.stages || [] - const WEIGHT_MAP: Record = { - processors: 0.30, - rule1_ingestion: 0.05, - face_tracing: 0.05, - face_dedup: 0.10, - tkg_nodes: 0.20, - tkg_edges: 0.15, - rule2_ingestion: 0.10, - vlm_summary: 0.03, - scene_vlm: 0.03, - moment_chunks: 0.01 + // Map individual steps to phases + const phaseMap: Record = { + processors: { + weight: 0.30, + steps: ['processors'] + }, + knowledge_graph: { + weight: 0.35, + steps: ['tkg_nodes', 'tkg_edges'] + }, + moment_extraction: { + weight: 0.06, + steps: ['vlm_summary', 'scene_vlm', 'moment_chunks'] + }, + integration: { + weight: 0.29, + steps: ['rule1_ingestion', 'rule2_ingestion', 'face_tracing', 'face_dedup'] + } } - const mappedStages = stages.map((s: any) => ({ - name: s.name, - weight: WEIGHT_MAP[s.name] ?? s.weight ?? 0, - progress: s.progress || 0, - status: s.status || 'pending' - })) + // Aggregate steps into phases + const aggregatedStages: PipelineStage[] = [] - const calculatedProgress = mappedStages.reduce((sum, s) => sum + s.weight * s.progress, 0) + for (const [phaseName, phaseConfig] of Object.entries(phaseMap)) { + const phaseSteps = stages.filter((s: any) => phaseConfig.steps.includes(s.name)) + + if (phaseSteps.length > 0) { + // Calculate phase progress from steps + const totalWeight = phaseSteps.reduce((sum: number, s: any) => sum + (s.weight || 0), 0) + const weightedProgress = phaseSteps.reduce((sum: number, s: any) => { + const stepWeight = s.weight || 0 + return sum + stepWeight * (s.progress || 0) + }, 0) + + const phaseProgress = totalWeight > 0 ? weightedProgress / totalWeight : 0 + + // Determine phase status + const allCompleted = phaseSteps.every((s: any) => s.status === 'completed') + const anyRunning = phaseSteps.some((s: any) => s.status === 'running') + const anyFailed = phaseSteps.some((s: any) => s.status === 'failed') + + let phaseStatus: 'pending' | 'running' | 'completed' | 'failed' = 'pending' + if (anyFailed) phaseStatus = 'failed' + else if (allCompleted) phaseStatus = 'completed' + else if (anyRunning) phaseStatus = 'running' + + aggregatedStages.push({ + name: phaseName, + weight: phaseConfig.weight, + progress: phaseProgress, + status: phaseStatus + }) + } + } + + const calculatedProgress = aggregatedStages.reduce((sum, s) => sum + s.weight * s.progress, 0) const pipelineStats: PipelineStats = { overall_progress: calculatedProgress, - stages: mappedStages + stages: aggregatedStages } console.log('[loadPipelineStats]', fileUuid, pipelineStats) diff --git a/src/views/LibraryView.vue b/src/views/LibraryView.vue index cf9b51f..7c50135 100644 --- a/src/views/LibraryView.vue +++ b/src/views/LibraryView.vue @@ -1179,6 +1179,10 @@ function getStageIcon(status: string): string { function formatStageName(name: string): string { const names: Record = { processors: 'Processors', + knowledge_graph: 'Knowledge Graph', + moment_extraction: 'Moment Extraction', + integration: 'Integration', + // Keep old names for backward compatibility rule1_ingestion: 'Rule1 Ingestion', face_tracing: 'Face Tracing', face_dedup: 'Face Dedup',