dashboar数据面板优化

This commit is contained in:
qikongjian 2025-09-05 21:04:24 +08:00
parent 38dc25123a
commit f7fbb3ef9b
2 changed files with 57 additions and 208 deletions

View File

@ -1166,17 +1166,18 @@ export function NetworkTimeline({
{/* 主内容区域 */}
<div className="flex-1 flex min-h-0">
{/* 左侧任务列表 */}
<div className="w-1/2 border-r border-gray-800 flex flex-col min-h-0">
{/* 任务列表 - 全宽显示,包含时间线 */}
<div className="w-full flex flex-col min-h-0">
{/* 列表头部 */}
<div className="flex items-center px-4 py-1.5 bg-gray-800/50 text-xs font-medium text-gray-400 border-b border-gray-800 flex-shrink-0">
<div className="w-8"></div>
<div className="w-6"></div> {/* 展开/折叠按钮列 */}
<div className="flex-1"></div>
<div className="w-56"></div>
<div className="w-24 text-center"></div>
<div className="w-16 text-center"></div>
<div className="w-20 text-center"></div>
<div className="w-32 text-center"></div>
<div className="w-48 text-center"></div>
<div className="flex-1 text-center">线</div>
</div>
{/* 任务列表 */}
@ -1239,7 +1240,7 @@ export function NetworkTimeline({
{/* 任务名称 */}
<div className={cn(
"flex-1 flex items-center gap-2",
"w-56 flex items-center gap-2",
task.level === 1 && "pl-4"
)}>
<span className={cn(
@ -1384,29 +1385,36 @@ export function NetworkTimeline({
</div>
{/* 时间信息 */}
<div className="w-32 text-center">
<div className="w-48 text-center">
<div className="flex flex-col items-center">
<span className={cn("text-sm font-medium", getTimeDisplayColor(task.executionTime))}>
{formatTime(task.executionTime)}
</span>
{/* 显示开始时间 */}
{(() => {
const taskTimes = getTaskTimes(task);
return taskTimes.startTime ? (
<span className="text-xs text-green-400" title={`开始时间: ${formatDateTime(taskTimes.startTime)}`}>
{new Date(taskTimes.startTime).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}
</span>
) : null;
})()}
{/* 显示结束时间 */}
{(() => {
const taskTimes = getTaskTimes(task);
return taskTimes.endTime ? (
<span className="text-xs text-blue-400" title={`结束时间: ${formatDateTime(taskTimes.endTime)}`}>
{new Date(taskTimes.endTime).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}
</span>
) : null;
})()}
{/* 开始和结束时间一行显示 */}
<div className="flex items-center gap-1 text-xs">
{(() => {
const taskTimes = getTaskTimes(task);
return taskTimes.startTime ? (
<span className="text-green-400" title={`开始时间: ${formatDateTime(taskTimes.startTime)}`}>
{new Date(taskTimes.startTime).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}
</span>
) : null;
})()}
{(() => {
const taskTimes = getTaskTimes(task);
return taskTimes.startTime && taskTimes.endTime ? (
<span className="text-gray-500">-</span>
) : null;
})()}
{(() => {
const taskTimes = getTaskTimes(task);
return taskTimes.endTime ? (
<span className="text-blue-400" title={`结束时间: ${formatDateTime(taskTimes.endTime)}`}>
{new Date(taskTimes.endTime).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}
</span>
) : null;
})()}
</div>
{/* 剩余时间估算 */}
{task.level === 0 && (() => {
const originalTask = tasks.find((t: any) => t.task_id === task.id);
@ -1419,146 +1427,32 @@ export function NetworkTimeline({
})()}
</div>
</div>
</div>
))
)}
</div>
</div>
{/* 右侧时间线 */}
<div className="w-1/2 flex flex-col min-h-0">
<div className="px-4 py-2.5 bg-gray-900/50 border-b border-gray-800 flex-shrink-0">
<div className="text-sm font-medium text-gray-300 text-center">
线 (: {formatTime(projectDurationMs)})
</div>
</div>
<div className="flex-1 p-3.5 overflow-y-auto min-h-0">
{/* 时间刻度 */}
<div className="relative mb-6">
<div className="flex justify-between text-xs mb-3">
{Array.from({ length: 6 }, (_, i) => {
const timeValue = (maxTime / 5) * i;
return (
<span
key={i}
className={cn("font-medium", getTimeDisplayColor(timeValue))}
title={`${formatTime(timeValue)} (${Math.round(timeValue)}ms)`}
>
{formatTime(timeValue)}
</span>
);
})}
</div>
<div className="h-px bg-gradient-to-r from-gray-700 via-gray-600 to-gray-700"></div>
{/* 时间刻度线 */}
<div className="absolute top-8 left-0 right-0 flex justify-between">
{Array.from({ length: 6 }, (_, i) => (
<div key={i} className="w-px h-2 bg-gray-600"></div>
))}
</div>
</div>
{/* 瀑布图 */}
<div className="space-y-1">
{filteredTaskExecutions.length === 0 ? (
<div className="flex items-center justify-center py-8 text-gray-400">
<div className="text-center">
<Activity className="w-8 h-8 mx-auto mb-2 opacity-50" />
<p className="text-sm"></p>
</div>
</div>
) : (
filteredTaskExecutions.map((task) => (
<div key={task.id} className={cn(
"relative",
task.level === 0 ? "h-5" : "h-3.5"
)}>
{/* 任务条 */}
{/* 时间线进度条 */}
<div className="flex-1 px-2">
<div className="relative h-6 bg-gray-800/50 rounded border border-gray-700/50 overflow-hidden">
{/* 时间线背景 */}
<div className="absolute inset-0 bg-gradient-to-r from-gray-700 via-gray-600 to-gray-700 opacity-30"></div>
{/* 任务进度条 */}
<div
className={cn(
"absolute rounded-sm cursor-pointer transition-all duration-200",
task.level === 0 ? "top-0.5 h-3.5" : "top-0.5 h-2.5",
"absolute top-0 h-full rounded-sm transition-all duration-200",
task.statusCode === 200 ? "bg-emerald-500" :
task.statusCode === 202 ? "bg-cyan-500" :
task.statusCode >= 400 ? "bg-rose-500" : "bg-amber-500",
// 选中时明显高亮提高不透明度、描边、阴影与z-index
selectedTask === task.id
? "opacity-100 ring-2 ring-cyan-300/90 shadow-[0_0_10px_rgba(34,211,238,0.6)] z-10"
: "opacity-80 hover:opacity-95",
task.level === 1 && "opacity-70"
selectedTask === task.id && "ring-2 ring-cyan-300/90 shadow-[0_0_8px_rgba(34,211,238,0.6)]"
)}
style={{
left: `${(task.startTime / maxTime) * 100}%`,
width: `${Math.max((task.executionTime / maxTime) * 100, 0.5)}%`
}}
onClick={() => setSelectedTask(task.id)}
title={(() => {
const taskTimes = getTaskTimes(task);
return `${task.displayName}
执行时间: ${formatTime(task.executionTime)}
状态: ${getTaskStatusText(task.status)}
${task.status === 'IN_PROGRESS' ? `进度: ${task.progress}%` : ''}
开始时间: ${formatDateTime(taskTimes.startTime)}
结束时间: ${formatDateTime(taskTimes.endTime)}`;
})()}
>
{/* 基于状态的单色进度条 */}
<div className="w-full h-full rounded-sm overflow-hidden relative">
{/* 背景条 */}
<div className="w-full h-full bg-gray-700/30"></div>
{/* 进度条 - 根据任务状态和进度显示 */}
{task.status === 'IN_PROGRESS' && (
<div
className={cn(
"absolute top-0 left-0 h-full transition-all duration-500 ease-out",
getProgressBarColor(task.status)
)}
style={{ width: `${task.progress}%` }}
title={`进度: ${task.progress}%`}
/>
)}
{/* 完成状态显示满进度 */}
{task.status === 'COMPLETED' && (
<div
className={cn(
"absolute top-0 left-0 h-full w-full",
getProgressBarColor(task.status)
)}
title="已完成"
/>
)}
{/* 失败状态显示部分进度 */}
{task.status === 'FAILED' && (
<div
className={cn(
"absolute top-0 left-0 h-full opacity-70",
getProgressBarColor(task.status)
)}
style={{ width: `${Math.max(task.progress, 15)}%` }}
title={`失败于 ${task.progress}%`}
/>
)}
{/* 等待状态显示微弱指示 */}
{task.status === 'PENDING' && (
<div
className={cn(
"absolute top-0 left-0 h-full opacity-40",
getProgressBarColor(task.status)
)}
style={{ width: '8%' }}
title="等待开始"
/>
)}
{/* 智能百分比文字显示 - 只在主任务且有足够空间时显示 */}
title={`${task.displayName} - ${formatTime(task.executionTime)}`}
>
{/* 进度百分比显示 */}
{(() => {
const barWidth = (task.executionTime / maxTime) * 100;
const showPercentage = task.level === 0 && barWidth > 6; // 主任务且宽度足够
const showPercentage = barWidth > 8; // 只在有足够空间时显示
if (!showPercentage) return null;
@ -1580,37 +1474,13 @@ ${task.status === 'IN_PROGRESS' ? `进度: ${task.progress}%` : ''}
const percentageText = getPercentageText();
if (!percentageText) return null;
// 根据进度条宽度和进度值决定文字位置
const progressWidth = task.status === 'IN_PROGRESS' ? task.progress :
task.status === 'COMPLETED' ? 100 :
task.status === 'FAILED' ? Math.max(task.progress, 15) : 8;
const shouldCenterInProgress = task.status === 'IN_PROGRESS' && progressWidth > 30;
const shouldCenterInBar = (task.status === 'COMPLETED') ||
(task.status === 'FAILED' && progressWidth > 25);
return (
<div
className={cn(
"absolute top-0 flex items-center pointer-events-none h-full",
shouldCenterInProgress || shouldCenterInBar ? "justify-center inset-0" : "justify-end right-1"
)}
>
<div className="absolute inset-0 flex items-center justify-center pointer-events-none">
<span
className={cn(
"font-semibold transition-all duration-300 select-none",
// 智能颜色选择
task.status === 'COMPLETED' ? "text-white" :
task.status === 'IN_PROGRESS' && shouldCenterInProgress ? "text-white" :
task.status === 'IN_PROGRESS' && !shouldCenterInProgress ? "text-cyan-200" :
task.status === 'FAILED' && shouldCenterInBar ? "text-white" :
task.status === 'FAILED' && !shouldCenterInBar ? "text-rose-200" :
"text-amber-200"
)}
className="text-xs font-semibold text-white"
style={{
textShadow: '0 1px 3px rgba(0,0,0,0.9), 0 0 8px rgba(0,0,0,0.5)',
fontSize: barWidth > 12 ? '11px' : '10px',
fontWeight: '600'
textShadow: '0 1px 2px rgba(0,0,0,0.8)',
fontSize: '10px'
}}
>
{percentageText}
@ -1620,41 +1490,20 @@ ${task.status === 'IN_PROGRESS' ? `进度: ${task.progress}%` : ''}
})()}
</div>
{/* 子任务进度指示器和百分比 */}
{task.level === 1 && task.status === 'IN_PROGRESS' && (
<>
<div
className="absolute top-0 left-0 h-full bg-white/30 rounded-sm"
style={{ width: `${task.progress}%` }}
/>
{/* 子任务百分比 - 只在有足够空间时显示 */}
{(() => {
const barWidth = (task.executionTime / maxTime) * 100;
if (barWidth < 4) return null; // 子任务条太窄不显示
return (
<div className="absolute inset-0 flex items-center justify-end pr-1 pointer-events-none">
<span
className="text-white font-medium"
style={{
textShadow: '0 1px 2px rgba(0,0,0,0.8)',
fontSize: '9px'
}}
>
{task.progress}%
</span>
{/* 时间刻度标记 */}
<div className="absolute top-0 left-0 right-0 h-full flex justify-between items-end pb-1">
{Array.from({ length: 5 }, (_, i) => (
<div key={i} className="w-px h-2 bg-gray-500/50"></div>
))}
</div>
);
})()}
</>
)}
</div>
</div>
</div>
))
)}
</div>
</div>
</div>
</div>
{/* 详细信息面板 */}

View File

@ -164,7 +164,7 @@ const WorkFlow = React.memo(function WorkFlow() {
// iframe智能剪辑回调函数
const handleIframeAIEditingComplete = useCallback((result: any) => {
console.log('🎉 iframe AI剪辑完成结果:', result);
console.log('🎉 iframe AI剪辑完成结果:', result);
// 保存剪辑结果
setAiEditingResult(result);