"use client" import { useEffect, useState, useRef } from "react"; import { Play, ChevronUp, Loader2 } from "lucide-react"; import "./style/work-flow.css"; import LiquidGlass from '@/plugins/liquid-glass'; import { Skeleton } from "@/components/ui/skeleton"; import { AISuggestionBar } from "@/components/ai-suggestion-bar"; import { motion, AnimatePresence } from "framer-motion"; import { debounce } from "lodash"; const MOCK_SKETCH_URLS = [ 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-1.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-2.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-3.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-4.jpg', ]; const MOCK_SKETCH_SCRIPT = [ 'script-123', 'script-123', 'script-123', 'script-123', ]; const MOCK_SKETCH_COUNT = 8; export default function WorkFlow() { const [taskObject, setTaskObject] = useState(null); const [projectObject, setProjectObject] = useState(null); const [taskSketch, setTaskSketch] = useState([]); const [sketchCount, setSketchCount] = useState(0); const containerRef = useRef(null); const [isLoading, setIsLoading] = useState(true); const [isAIBarVisible, setIsAIBarVisible] = useState(true); const [currentStep, setCurrentStep] = useState('0'); const [currentSketchIndex, setCurrentSketchIndex] = useState(0); const [isGeneratingSketch, setIsGeneratingSketch] = useState(false); const thumbnailsRef = useRef(null); const [isDragging, setIsDragging] = useState(false); const [startX, setStartX] = useState(0); const [scrollLeft, setScrollLeft] = useState(0); // 模拟 AI 建议 const mockSuggestions = [ "优化场景转场效果", "调整画面构图", "改进角色动作设计", "增加环境氛围", "调整镜头语言" ]; useEffect(() => { const taskId = localStorage.getItem("taskId") || "taskId-123"; getTaskDetail(taskId).then((data) => { setTaskObject(data); setIsLoading(false); setCurrentStep('1'); }); // 轮询获取分镜草图 防抖 1000ms const debouncedGetTaskSketch = debounce(() => { getTaskSketch(taskId); }, 1000); debouncedGetTaskSketch(); }, []); // 监听当前选中索引变化,自动滚动到对应位置 useEffect(() => { if (thumbnailsRef.current && taskSketch.length > 0) { const container = thumbnailsRef.current; const thumbnailWidth = container.offsetWidth / 4; // 每个缩略图宽度(包含间距) const scrollPosition = currentSketchIndex * thumbnailWidth; container.scrollTo({ left: scrollPosition, behavior: 'smooth' }); } }, [currentSketchIndex, taskSketch.length]); // 处理鼠标/触摸拖动事件 const handleMouseDown = (e: React.MouseEvent) => { setIsDragging(true); setStartX(e.pageX - thumbnailsRef.current!.offsetLeft); setScrollLeft(thumbnailsRef.current!.scrollLeft); }; const handleMouseMove = (e: React.MouseEvent) => { if (!isDragging) return; e.preventDefault(); const x = e.pageX - thumbnailsRef.current!.offsetLeft; const walk = (x - startX) * 2; thumbnailsRef.current!.scrollLeft = scrollLeft - walk; }; const handleMouseUp = (e: React.MouseEvent) => { setIsDragging(false); if (!isDragging) return; const container = thumbnailsRef.current!; const thumbnailWidth = container.offsetWidth / 4; const currentScroll = container.scrollLeft; const nearestIndex = Math.round(currentScroll / thumbnailWidth); // 只有在拖动距离较小时才触发选中 const x = e.pageX - container.offsetLeft; const walk = Math.abs(x - startX); if (walk < 10) { return; // 如果拖动距离太小,保持原有的点击选中逻辑 } setCurrentSketchIndex(Math.min(Math.max(0, nearestIndex), taskSketch.length - 1)); }; // 模拟接口请求 获取任务详情 const getTaskDetail = async (taskId: string) => { // const response = await fetch(`/api/task/${taskId}`); // const data = await response.json(); // mock data const data = { projectId: 'projectId-123', projectName: "Project 1", taskId: taskId, taskName: "Task 1", taskDescription: "Task 1 Description", taskStatus: "1", // '1' 绘制分镜、'2' 绘制角色、'3' 生成分镜视频、'4' 视频后期制作、'5' 最终成品 taskProgress: 0, taskCreatedAt: new Date().toISOString(), taskUpdatedAt: new Date().toISOString(), }; return data; } // 模拟接口请求 每次获取一个分镜草图 轮询获取 const getTaskSketch = async (taskId: string) => { setIsGeneratingSketch(true); setTaskSketch([]); // 模拟分批获取分镜草图 for (let i = 0; i < MOCK_SKETCH_COUNT; i++) { await new Promise(resolve => setTimeout(resolve, 2000)); // 模拟2秒延迟 const newSketch = { id: `sketch-${i}`, url: MOCK_SKETCH_URLS[i % MOCK_SKETCH_URLS.length], script: MOCK_SKETCH_SCRIPT[i % MOCK_SKETCH_SCRIPT.length], status: 'done' }; setTaskSketch(prev => [...prev, newSketch]); setCurrentSketchIndex(i); setSketchCount(i + 1); } setIsGeneratingSketch(false); } const handleSuggestionClick = (suggestion: string) => { console.log('Selected suggestion:', suggestion); }; const handleSubmit = (text: string) => { console.log('Submitted text:', text); }; // 渲染分镜草图或加载动画 const renderSketchContent = () => { if (!taskSketch[currentSketchIndex]) { return (

正在生成分镜草图 {sketchCount + 1}/{MOCK_SKETCH_COUNT}

); } return ( ); }; return (
{isLoading ? ( <> ) : ( <>
{taskObject?.projectName}:{taskObject?.taskName}

{taskObject?.taskDescription}

)}
{isLoading ? ( ) : ( <> { currentStep === '1' ? (
{renderSketchContent()}
) : ( ) } )}
{isLoading ? ( <> ) : (
setIsDragging(false)} > {currentStep === '1' ? ( <> {taskSketch.map((sketch, index) => ( !isDragging && setCurrentSketchIndex(index)} initial={false} animate={{ scale: currentSketchIndex === index ? 1.05 : 1, rotateY: currentSketchIndex === index ? 5 : 0, rotateX: currentSketchIndex === index ? -5 : 0, translateZ: currentSketchIndex === index ? '20px' : '0px', transition: { type: "spring", stiffness: 300, damping: 20 } }} style={{ transformStyle: 'preserve-3d', perspective: '1000px' }} >
场景 {index + 1}
))} {isGeneratingSketch && sketchCount < MOCK_SKETCH_COUNT && (
)} ) : ( <> )}
)}
{/* AI 建议栏 */}
) }