diff --git a/frontend/web/src/components/intelligent_eval/ExecutionProcess.tsx b/frontend/web/src/components/intelligent_eval/ExecutionProcess.tsx index 586662b..36f1f15 100644 --- a/frontend/web/src/components/intelligent_eval/ExecutionProcess.tsx +++ b/frontend/web/src/components/intelligent_eval/ExecutionProcess.tsx @@ -97,11 +97,19 @@ function decisionEvents(logs: DecisionLog[]): ActivityEvent[] { })) } -function LifecycleTimeline({ currentStage, abnormal }: { currentStage: string; abnormal: boolean }) { +function LifecycleTimeline({ ev, currentStage, abnormal }: { ev: IntelligentEval; currentStage: string; abnormal: boolean }) { const currentIndex = STAGE_CONFIG.findIndex((s) => s.key === currentStage) + // Map stages to timestamps + const stageTimes: Record = { + planning: ev.created_at, + approval: ev.started_at, // Approval completed when execution started + executing: ev.started_at, + done: ev.completed_at, + } + return ( -
+
{STAGE_CONFIG.map((stage, idx) => { const Icon = stage.icon const isCompleted = idx < currentIndex @@ -117,10 +125,11 @@ function LifecycleTimeline({ currentStage, abnormal }: { currentStage: string; a : colors.bgSubtle const textColor = isCompleted || isCurrent ? '#fff' : colors.textSecondary + const time = stageTimes[stage.key] return ( -
-
+
+
{isCompleted ? : }
-
+
{stage.title} {isCurrent &&
当前阶段
}
+ {time && ( +
+ {formatDateTime(time).split(' ')[1] || formatDateTime(time)} +
+ )}
{idx < STAGE_CONFIG.length - 1 && (
@@ -162,67 +175,82 @@ function LifecycleTimeline({ currentStage, abnormal }: { currentStage: string; a ) } -function TimeDistributionCards({ slots }: { slots: ExecutionProgress['slots'] }) { +function TimeDistributionTable({ slots }: { slots: ExecutionProgress['slots'] }) { return ( -
- {slots.map((slot) => { - const plannedPct = slot.planned > 0 ? 100 : 0 - const createdPct = slot.planned > 0 ? (slot.created / slot.planned) * 100 : 0 - const completedPct = slot.planned > 0 ? (slot.completed / slot.planned) * 100 : 0 +
+ + + + + + + + + + + + + {slots.map((slot) => { + const pct = slot.planned > 0 ? Math.round((slot.completed / slot.planned) * 100) : 0 + const isComplete = slot.completed >= slot.planned && slot.planned > 0 + const isPast = slot.is_past - return ( - -
-
{slot.time_slot}
- {slot.is_current && ( - - - 当前 - - )} -
- -
-
-
- 计划 - {slot.planned} -
-
-
-
-
- -
-
- 已创建 - {slot.created}/{slot.planned} -
-
-
-
-
- -
-
- 已完成 - {slot.completed}/{slot.planned} -
-
-
-
-
-
- - ) - })} + return ( +
+ + + + + + + + ) + })} + +
时段计划已创建已完成进度状态
+ {slot.time_slot} + {slot.is_current && ( + + + 当前 + + )} + {slot.planned} 0 ? colors.text : colors.textMuted }}> + {slot.created} + 0 ? statusColors.completed : colors.textMuted }}> + {slot.completed} + +
+
+
+
+ {pct}% +
+
+ {isComplete ? ( + 已完成 + ) : isPast ? ( + 未达标 + ) : slot.is_current ? ( + 进行中 + ) : ( + 待执行 + )} +
) } @@ -273,7 +301,7 @@ export default function ExecutionProcess({ ev }: { ev: IntelligentEval }) { return (
- + {progress.blocker != null && ( ) : ( - + )}