'use client'; import React from 'react'; import { TaskStatistics } from '@/api/video_flow'; import { cn } from '@/public/lib/utils'; interface TaskStatisticsCardsProps { statistics: TaskStatistics[]; } export default function TaskStatisticsCards({ statistics }: TaskStatisticsCardsProps) { // 聚合多个项目的统计数据 const aggregatedStats = React.useMemo(() => { if (statistics.length === 0) { return { total_tasks: 0, status_stats: { completed: 0, in_progress: 0, pending: 0, failed: 0, blocked: 0, }, success_rate: 0, avg_execution_time: 0, project_count: 0, }; } const totals = statistics.reduce( (acc, stat) => ({ total_tasks: acc.total_tasks + stat.total_tasks, completed: acc.completed + stat.status_stats.completed, in_progress: acc.in_progress + stat.status_stats.in_progress, pending: acc.pending + stat.status_stats.pending, failed: acc.failed + stat.status_stats.failed, blocked: acc.blocked + stat.status_stats.blocked, total_execution_time: acc.total_execution_time + (stat.avg_execution_time * stat.total_tasks), }), { total_tasks: 0, completed: 0, in_progress: 0, pending: 0, failed: 0, blocked: 0, total_execution_time: 0, } ); const success_rate = totals.total_tasks > 0 ? (totals.completed / totals.total_tasks) * 100 : 0; const avg_execution_time = totals.total_tasks > 0 ? totals.total_execution_time / totals.total_tasks : 0; return { total_tasks: totals.total_tasks, status_stats: { completed: totals.completed, in_progress: totals.in_progress, pending: totals.pending, failed: totals.failed, blocked: totals.blocked, }, success_rate, avg_execution_time, project_count: statistics.length, }; }, [statistics]); const cards = [ { title: '总任务数', value: aggregatedStats.total_tasks.toLocaleString(), icon: '📊', color: 'blue', subtitle: `${aggregatedStats.project_count} 个项目`, }, { title: '成功率', value: `${aggregatedStats.success_rate.toFixed(1)}%`, icon: '✅', color: aggregatedStats.success_rate >= 90 ? 'green' : aggregatedStats.success_rate >= 70 ? 'yellow' : 'red', subtitle: `${aggregatedStats.status_stats.completed} 个成功`, }, { title: '进行中', value: aggregatedStats.status_stats.in_progress.toLocaleString(), icon: '⚡', color: 'blue', subtitle: '正在执行', }, { title: '失败任务', value: aggregatedStats.status_stats.failed.toLocaleString(), icon: '❌', color: 'red', subtitle: '需要处理', }, { title: '平均耗时', value: `${(aggregatedStats.avg_execution_time / 60).toFixed(1)}分`, icon: '⏱️', color: 'purple', subtitle: '执行时间', }, { title: '阻塞任务', value: aggregatedStats.status_stats.blocked.toLocaleString(), icon: '🚫', color: 'orange', subtitle: '等待处理', }, ]; const getColorClasses = (color: string) => { switch (color) { case 'green': return 'bg-emerald-500/10 border-emerald-500/20 text-emerald-400'; case 'red': return 'bg-red-500/10 border-red-500/20 text-red-400'; case 'yellow': return 'bg-yellow-500/10 border-yellow-500/20 text-yellow-400'; case 'blue': return 'bg-blue-500/10 border-blue-500/20 text-blue-400'; case 'purple': return 'bg-purple-500/10 border-purple-500/20 text-purple-400'; case 'orange': return 'bg-orange-500/10 border-orange-500/20 text-orange-400'; default: return 'bg-gray-500/10 border-gray-500/20 text-gray-400'; } }; return (
{cards.map((card, index) => (
{card.icon}
{card.title}
{card.value}
{card.subtitle}
))}
); } // 单个项目的详细统计卡片 export function ProjectStatisticsCard({ statistics }: { statistics: TaskStatistics }) { const statusItems = [ { label: '已完成', value: statistics.status_stats.completed, color: 'text-emerald-400' }, { label: '进行中', value: statistics.status_stats.in_progress, color: 'text-blue-400' }, { label: '等待中', value: statistics.status_stats.pending, color: 'text-yellow-400' }, { label: '失败', value: statistics.status_stats.failed, color: 'text-red-400' }, { label: '阻塞', value: statistics.status_stats.blocked, color: 'text-orange-400' }, ]; return (

{statistics.project_name || statistics.project_id}

项目ID: {statistics.project_id}

{statistics.total_tasks}
总任务数
{statusItems.map((item, index) => (
{item.value}
{item.label}
))}
成功率: {statistics.success_rate.toFixed(1)}% 平均耗时: {(statistics.avg_execution_time / 60).toFixed(1)}分
更新于 {new Date(statistics.last_updated).toLocaleTimeString()}
); }