'use client'; import React, { useState, useEffect, useRef } from 'react'; import NetworkTimeline from '@/components/dashboard/network-timeline'; import { useSearchParams } from 'next/navigation'; import { getProjectTaskList } from '@/api/video_flow'; import { mockDashboardData } from '@/components/dashboard/demo-data'; import { cn } from '@/public/lib/utils'; export default function DashboardPage() { const searchParams = useSearchParams(); // 使用真实项目ID,如果URL没有提供则使用默认的真实项目ID const projectId = searchParams.get('project_id') || 'bc43bc81-c781-4caa-8256-9710fd5bee80'; const [dashboardData, setDashboardData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [isUsingMockData, setIsUsingMockData] = useState(false); const [isBackgroundRefreshing, setIsBackgroundRefreshing] = useState(false); const [lastUpdateTime, setLastUpdateTime] = useState(null); const [connectionStatus, setConnectionStatus] = useState<'connected' | 'disconnected' | 'checking'>('checking'); // 使用 ref 来存储最新的状态,避免定时器闭包问题 const stateRef = useRef({ isUsingMockData, dashboardData }); // 初始加载数据 const fetchInitialData = async () => { try { setLoading(true); setError(null); setConnectionStatus('checking'); console.log('正在获取项目数据,项目ID:', projectId); // 调用新的任务列表API const response = await getProjectTaskList({ project_id: projectId }); console.log('API响应:', response); if (response.code === 0 && response.data) { // 直接使用新API数据,不进行格式转换 setDashboardData(response.data); setIsUsingMockData(false); setLastUpdateTime(new Date()); setConnectionStatus('connected'); console.log('成功获取真实数据:', response.data); } else { console.warn('API返回错误或无数据,使用演示数据'); setDashboardData(mockDashboardData); setIsUsingMockData(true); setLastUpdateTime(new Date()); setConnectionStatus('disconnected'); setError(`API返回: ${response.message || '无数据'} (已切换到演示模式)`); } } catch (err: any) { console.error('获取数据失败:', err); // 详细的错误分析 let errorMessage = '未知错误'; if (err.code === 'NETWORK_ERROR' || err.message?.includes('Network Error')) { errorMessage = '网络连接失败,请检查网络连接'; } else if (err.code === 'ECONNABORTED' || err.message?.includes('timeout')) { errorMessage = '请求超时,服务器响应缓慢'; } else if (err.response?.status === 404) { errorMessage = 'API接口不存在'; } else if (err.response?.status === 500) { errorMessage = '服务器内部错误'; } else if (err.response?.status === 403) { errorMessage = '访问被拒绝,请检查权限'; } else if (err.message) { errorMessage = err.message; } // 如果API调用失败,回退到演示数据 console.log('API调用失败,使用演示数据'); setDashboardData(mockDashboardData); setIsUsingMockData(true); setLastUpdateTime(new Date()); setConnectionStatus('disconnected'); setError(`${errorMessage} (已切换到演示模式)`); } finally { setLoading(false); } }; // 深度比较数据是否发生变化 const hasDataChanged = (newData: any, oldData: any) => { if (!oldData || !newData) return true; try { return JSON.stringify(newData) !== JSON.stringify(oldData); } catch { return true; // 如果比较失败,认为数据已变化 } }; // 后台静默刷新数据 const refreshDataSilently = async () => { try { setIsBackgroundRefreshing(true); console.log('后台刷新数据...'); // 调用新的任务列表API const response = await getProjectTaskList({ project_id: projectId }); if (response.code === 0 && response.data) { // 直接使用新API数据,检查数据是否真正发生变化 if (hasDataChanged(response.data, dashboardData)) { // 只有数据变化时才更新UI setDashboardData(response.data); setIsUsingMockData(false); setLastUpdateTime(new Date()); setConnectionStatus('connected'); setError(null); // 清除之前的错误 console.log('后台数据更新成功 - 数据已变化'); } else { // 数据未变化,只更新时间戳 setLastUpdateTime(new Date()); setConnectionStatus('connected'); console.log('后台数据检查完成 - 数据无变化'); } } else { console.warn('后台刷新失败,保持当前数据'); setConnectionStatus('disconnected'); } } catch (err: any) { console.error('后台刷新失败:', err); setConnectionStatus('disconnected'); // 后台刷新失败时不影响当前显示,只记录日志和更新连接状态 } finally { setIsBackgroundRefreshing(false); } }; // 智能刷新频率:根据任务状态决定刷新间隔 const getRefreshInterval = React.useCallback(() => { if (!dashboardData || isUsingMockData) return 60000; // mock数据时60秒刷新一次 // 检查是否有正在运行的任务 - 基于接口实际返回的状态 const hasRunningTasks = Array.isArray(dashboardData) && dashboardData.some((task: any) => // 接口实际返回的活跃状态 task.task_status === 'IN_PROGRESS' || task.task_status === 'INIT' || // 检查子任务状态 (task.sub_tasks && Array.isArray(task.sub_tasks) && task.sub_tasks.some((subTask: any) => subTask.task_status === 'IN_PROGRESS' || subTask.task_status === 'INIT' )) ); return hasRunningTasks ? 10000 : 30000; // 有运行任务时10秒,否则30秒 }, [dashboardData, isUsingMockData]); // 初始加载数据 - 只在 projectId 变化时执行 useEffect(() => { fetchInitialData(); }, [projectId]); // 只依赖 projectId // 更新 ref 中的状态 useEffect(() => { stateRef.current = { isUsingMockData, dashboardData }; }, [isUsingMockData, dashboardData]); // 智能定时刷新 - 根据数据状态动态调整刷新间隔 useEffect(() => { if (!dashboardData) return; // 没有数据时不设置定时器 const refreshInterval = getRefreshInterval(); console.log(`设置刷新间隔: ${refreshInterval / 1000}秒`); const interval = setInterval(() => { // 使用 ref 中的最新状态 if (!stateRef.current.isUsingMockData) { refreshDataSilently(); } }, refreshInterval); return () => clearInterval(interval); }, [getRefreshInterval]); // 只依赖 getRefreshInterval if (loading) { return (

加载数据面板...

); } if (error && !dashboardData) { return (
⚠️

连接失败

{error}

如果问题持续存在,请检查:

  • • 网络连接是否正常
  • • 服务器是否可访问
  • • 项目ID是否正确
); } return (
{/* 后台刷新指示器 */} {isBackgroundRefreshing && (
数据更新中...
)} {/* 手动刷新按钮和状态指示器 */}
{/* 手动刷新按钮 */} {/* 连接状态和最后更新时间指示器 */}
{/* 连接状态指示器 */}
{connectionStatus === 'connected' ? '已连接' : connectionStatus === 'disconnected' ? '离线模式' : '连接中...'}
{/* 分隔符 */} {lastUpdateTime && |} {/* 最后更新时间 */} {lastUpdateTime && ( 最后更新: {lastUpdateTime.toLocaleTimeString()} )}
{/* 顶部状态栏 */}
{/* 项目信息 */}

Video Flow Dashboard

项目ID: {projectId}
{/* 连接状态和统计 */}
{/* 连接状态指示器 */}
{connectionStatus === 'connected' ? '实时连接' : connectionStatus === 'checking' ? '连接中...' : '离线模式'}
{/* 最后更新时间 */} {lastUpdateTime && (
更新于 {lastUpdateTime.toLocaleTimeString()}
)}
{/* 主内容区域 */}
{ console.log('切换轮询状态'); }} onRetryTask={async (taskId: string) => { console.log('重试任务:', taskId); await fetchInitialData(); }} />
); }