'use client'; import { useState, useEffect, useRef, useCallback } from 'react'; import { getRandomMockData, STEP_MESSAGES, MOCK_DELAY_TIME, MOCK_DATA } from '@/components/work-flow/constants'; // 当前选择的mock数据 let selectedMockData: any = null; export function useWorkflowData() { const [taskObject, setTaskObject] = useState(null); const [taskSketch, setTaskSketch] = useState([]); const [taskRoles, setTaskRoles] = useState([]); const [taskVideos, setTaskVideos] = useState([]); const [sketchCount, setSketchCount] = useState(0); const [isLoading, setIsLoading] = useState(true); const [currentStep, setCurrentStep] = useState('0'); const [currentSketchIndex, setCurrentSketchIndex] = useState(0); const [isGeneratingSketch, setIsGeneratingSketch] = useState(false); const [isGeneratingVideo, setIsGeneratingVideo] = useState(false); const [currentLoadingText, setCurrentLoadingText] = useState('正在加载项目数据...'); const [dataLoadError, setDataLoadError] = useState(null); const [isLoadingData, setIsLoadingData] = useState(false); // 异步加载数据 - 改进错误处理和fallback机制 const loadMockData = async () => { try { setIsLoadingData(true); setDataLoadError(null); setCurrentLoadingText('正在从服务器获取项目数据...'); // 尝试从接口获取数据 selectedMockData = await getRandomMockData(); console.log('成功从接口获取数据:', selectedMockData); setCurrentLoadingText('项目数据加载完成'); } catch (error) { // 报错 } finally { setIsLoadingData(false); } }; // 重试加载数据 const retryLoadData = async () => { console.log('用户点击重试,重新加载数据...'); selectedMockData = null; // 重置数据 setDataLoadError(null); setIsLoading(true); setCurrentStep('0'); // 重新初始化整个流程 await initializeWorkflow(); }; // 模拟接口请求 获取任务详情 const getTaskDetail = async (taskId: string) => { // 确保已经加载了数据 if (!selectedMockData) { console.warn('selectedMockData为空,重新加载数据'); await loadMockData(); } // 确保数据结构正确 if (!selectedMockData || !selectedMockData.detail) { throw new Error('数据结构不正确'); } const data = { projectId: selectedMockData.detail.projectId, projectName: selectedMockData.detail.projectName, taskId: taskId, taskName: selectedMockData.detail.taskName, taskDescription: selectedMockData.detail.taskDescription, taskStatus: selectedMockData.detail.taskStatus, taskProgress: 0, mode: selectedMockData.detail.mode, resolution: selectedMockData.detail.resolution.toString(), }; return data; }; // 模拟接口请求 每次获取一个分镜草图 轮询获取 const getTaskSketch = async (taskId: string) => { if (isGeneratingSketch || taskSketch.length > 0) return; setIsGeneratingSketch(true); setTaskSketch([]); const sketchData = selectedMockData.sketch; const totalSketches = sketchData.length; // 模拟分批获取分镜草图 for (let i = 0; i < totalSketches; i++) { await new Promise(resolve => setTimeout(resolve, MOCK_DELAY_TIME.sketch)); // 10s const newSketch = { id: `sketch-${i}`, url: sketchData[i].url, script: sketchData[i].script, bg_rgb: sketchData[i].bg_rgb, status: 'done' }; setTaskSketch(prev => { if (prev.find(sketch => sketch.id === newSketch.id)) { return prev; } return [...prev, newSketch]; }); setCurrentSketchIndex(i); setSketchCount(i + 1); } // 等待最后一个动画完成再设置生成状态为false await new Promise(resolve => setTimeout(resolve, 1500)); setIsGeneratingSketch(false); }; // 模拟接口请求 每次获取一个角色 轮询获取 const getTaskRole = async (taskId: string) => { setTaskRoles([]); const roleData = selectedMockData.roles; const totalRoles = roleData.length; for (let i = 0; i < totalRoles; i++) { // 先更新loading文字显示当前正在生成的角色 setCurrentLoadingText(STEP_MESSAGES.newCharacter(i, totalRoles)); await new Promise(resolve => setTimeout(resolve, MOCK_DELAY_TIME.character)); // 2s 一个角色 // 添加角色到列表 setTaskRoles(prev => [...prev, roleData[i]]); // 更新loading文字显示已完成的角色数量 setCurrentLoadingText(STEP_MESSAGES.newCharacter(i + 1, totalRoles)); // 如果不是最后一个角色,稍微延迟一下让用户看到更新 if (i < totalRoles - 1) { await new Promise(resolve => setTimeout(resolve, 500)); } } }; // 模拟接口请求 获取背景音 const getTaskBackgroundAudio = async (taskId: string) => { await new Promise(resolve => setTimeout(resolve, MOCK_DELAY_TIME.audio)); // 10s }; // 模拟接口请求 获取最终成品 const getTaskFinalProduct = async (taskId: string) => { await new Promise(resolve => setTimeout(resolve, MOCK_DELAY_TIME.final)); // 50s }; // 模拟接口请求 每次获取一个分镜视频 轮询获取 const getTaskVideo = async (taskId: string) => { setIsGeneratingVideo(true); setTaskVideos([]); const videoData = selectedMockData.video; const totalVideos = videoData.length; // 模拟分批获取分镜视频 for (let i = 0; i < totalVideos; i++) { await new Promise(resolve => setTimeout(resolve, MOCK_DELAY_TIME.video)); // 60s const newVideo = { id: `video-${i}`, url: videoData[i].url, script: videoData[i].script, status: 'done' }; setTaskVideos(prev => { if (prev.find(video => video.id === newVideo.id)) { return prev; } return [...prev, newVideo]; }); setCurrentSketchIndex(i); } // 等待最后一个动画完成再设置生成状态为false await new Promise(resolve => setTimeout(resolve, 1500)); setIsGeneratingVideo(false); }; // 更新加载文字 useEffect(() => { if (isLoading) { // 在初始加载阶段,保持当前loading文字不变 return; } const totalSketches = selectedMockData?.sketch?.length || 0; const totalVideos = selectedMockData?.video?.length || 0; const totalCharacters = selectedMockData?.roles?.length || 0; if (currentStep === '1') { if (isGeneratingSketch) { setCurrentLoadingText(STEP_MESSAGES.sketch(sketchCount, totalSketches)); } else { setCurrentLoadingText(STEP_MESSAGES.sketchComplete); } } else if (currentStep === '2') { // 在角色生成阶段,loading文字已经在 getTaskRole 函数中直接管理 // 这里不需要额外设置,避免覆盖 if (taskRoles.length === totalCharacters) { setCurrentLoadingText(STEP_MESSAGES.newCharacter(totalCharacters, totalCharacters)); } } else if (currentStep === '3') { if (isGeneratingVideo) { setCurrentLoadingText(STEP_MESSAGES.video(taskVideos.length, totalVideos)); } else { setCurrentLoadingText(STEP_MESSAGES.videoComplete); } } else if (currentStep === '4') { setCurrentLoadingText(STEP_MESSAGES.audio); } else if (currentStep === '5') { setCurrentLoadingText(STEP_MESSAGES.final); } else { setCurrentLoadingText(STEP_MESSAGES.complete); } }, [isLoading, currentStep, isGeneratingSketch, sketchCount, isGeneratingVideo, taskVideos.length, taskSketch.length, taskRoles.length]); // 工作流初始化函数 const initializeWorkflow = async () => { try { setIsLoading(true); setCurrentLoadingText('正在初始化工作流...'); const taskId = (typeof window !== 'undefined' ? localStorage.getItem("taskId") : null) || "taskId-123"; // 首先加载数据 await loadMockData(); // 然后获取任务详情 setCurrentLoadingText('正在加载任务详情...'); const data = await getTaskDetail(taskId); setTaskObject(data); // 数据加载完成,进入工作流 setIsLoading(false); setCurrentStep('1'); // 只在任务详情加载完成后获取分镜草图 await getTaskSketch(taskId); // 修改 taskObject 下的 taskStatus 为 '2' setTaskObject((prev: any) => ({ ...prev, taskStatus: '2' })); setCurrentStep('2'); // 获取分镜草图后,开始绘制角色 await getTaskRole(taskId); // 修改 taskObject 下的 taskStatus 为 '3' setTaskObject((prev: any) => ({ ...prev, taskStatus: '3' })); setCurrentStep('3'); // 获取绘制角色后,开始获取分镜视频 await getTaskVideo(taskId); // 修改 taskObject 下的 taskStatus 为 '4' setTaskObject((prev: any) => ({ ...prev, taskStatus: '4' })); setCurrentStep('4'); // 获取分镜视频后,开始获取背景音 await getTaskBackgroundAudio(taskId); // 后期制作:抽卡中 对口型中 配音中 一致性处理中 setCurrentLoadingText(STEP_MESSAGES.postProduction('Selecting optimal frames')); await new Promise(resolve => setTimeout(resolve, MOCK_DELAY_TIME.postProduction)); setCurrentLoadingText(STEP_MESSAGES.postProduction('Aligning lip sync')); await new Promise(resolve => setTimeout(resolve, MOCK_DELAY_TIME.postProduction)); setCurrentLoadingText(STEP_MESSAGES.postProduction('Adding background audio')); await new Promise(resolve => setTimeout(resolve, MOCK_DELAY_TIME.postProduction)); setCurrentLoadingText(STEP_MESSAGES.postProduction('Consistency processing')); await new Promise(resolve => setTimeout(resolve, MOCK_DELAY_TIME.postProduction)); // 修改 taskObject 下的 taskStatus 为 '5' setTaskObject((prev: any) => ({ ...prev, taskStatus: '5' })); setCurrentStep('5'); // 获取背景音后,开始获取最终成品 await getTaskFinalProduct(taskId); await new Promise(resolve => setTimeout(resolve, 2000)); // 修改 taskObject 下的 taskStatus 为 '6' setTaskObject((prev: any) => ({ ...prev, taskStatus: '6' })); setCurrentStep('6'); } catch (error) { console.error('工作流初始化失败:', error); setDataLoadError('工作流初始化失败,请刷新页面重试'); setIsLoading(false); } }; // 初始化数据 useEffect(() => { initializeWorkflow(); }, []); return { // 状态数据 taskObject, taskSketch, taskVideos, sketchCount, isLoading: isLoading || isLoadingData, // 合并loading状态 currentStep, currentSketchIndex, isGeneratingSketch, isGeneratingVideo, currentLoadingText, totalSketchCount: selectedMockData?.sketch?.length || 0, roles: selectedMockData?.roles || [], music: selectedMockData?.music || {}, final: selectedMockData?.final || {}, dataLoadError, // 操作方法 setCurrentSketchIndex, retryLoadData, }; }