chore: 清理macOS同步产生的重复文件

详细说明:
- 删除了352个带数字后缀的重复文件
- 更新.gitignore防止未来产生此类文件
- 这些文件是由iCloud或其他同步服务冲突产生的
- 不影响项目功能,仅清理冗余文件
This commit is contained in:
Yep_Q
2025-09-08 12:06:01 +08:00
parent 1564396449
commit d6f48d6d14
365 changed files with 2039 additions and 68301 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

View File

@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import LandingPage from './pages/LandingPage';
import WorkflowPageV2 from './pages/WorkflowPageV2';
import WorkflowPageV4 from './pages/WorkflowPageV4';
import ResultPageV2 from './pages/ResultPageV2';
import { useDemoStore } from './store/demoStore';
@@ -45,7 +45,7 @@ function App() {
exit={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
<WorkflowPageV2 />
<WorkflowPageV4 />
</motion.div>
)}

View File

@@ -0,0 +1,170 @@
import React, { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { X, Sparkles, FileText, Zap, Building2 } from 'lucide-react';
interface RequirementModalProps {
isOpen: boolean;
onClose: () => void;
onSubmit: (requirement: string) => void;
}
const requirementTemplates = [
{
id: 1,
title: '新能源汽车展',
icon: <Zap className="w-5 h-5" />,
content: `展会名称2024长三角国际新能源汽车与智能交通产业博览会
地点:上海国家会展中心
时间2024年10月18日-20日
规模50,000平方米预计350家展商50,000人次观众
主题:双碳目标下的新能源汽车产业创新与发展
特色:整车展示、核心零部件、充电设施、智能交通解决方案`
}
];
const RequirementModal: React.FC<RequirementModalProps> = ({ isOpen, onClose, onSubmit }) => {
const [requirement, setRequirement] = useState('');
const [selectedTemplate, setSelectedTemplate] = useState<number | null>(null);
const handleTemplateSelect = (template: typeof requirementTemplates[0]) => {
setRequirement(template.content);
setSelectedTemplate(template.id);
};
const handleSubmit = () => {
if (requirement.trim()) {
onSubmit(requirement);
setRequirement('');
setSelectedTemplate(null);
}
};
return (
<AnimatePresence>
{isOpen && (
<>
{/* 背景遮罩 */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 bg-black/60 backdrop-blur-sm z-50"
onClick={onClose}
/>
{/* 弹窗内容 */}
<motion.div
initial={{ opacity: 0, scale: 0.9, y: 20 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.9, y: 20 }}
transition={{ type: 'spring', damping: 25, stiffness: 300 }}
className="fixed inset-0 flex items-center justify-center z-50 p-4"
onClick={(e) => e.stopPropagation()}
>
<div className="bg-white rounded-2xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden">
{/* 头部 */}
<div className="bg-gradient-to-r from-blue-600 to-purple-600 p-6 text-white">
<div className="flex items-center justify-between">
<div>
<h2 className="text-2xl font-bold mb-2"></h2>
<p className="text-blue-100">AI将为您生成完整方案</p>
</div>
<button
onClick={onClose}
className="p-2 hover:bg-white/20 rounded-lg transition-colors"
>
<X className="w-6 h-6" />
</button>
</div>
</div>
<div className="p-6">
{/* 需求模板 */}
<div className="mb-6">
<h3 className="text-sm font-semibold text-gray-700 mb-3 flex items-center gap-2">
<FileText className="w-4 h-4" />
</h3>
<div className="grid grid-cols-1 gap-3">
{requirementTemplates.map((template) => (
<button
key={template.id}
onClick={() => handleTemplateSelect(template)}
className={`p-4 rounded-xl border-2 transition-all hover:shadow-lg ${
selectedTemplate === template.id
? 'border-blue-500 bg-blue-50'
: 'border-gray-200 hover:border-gray-300'
}`}
>
<div className="flex items-center gap-3 mb-2">
<div className={`p-2 rounded-lg ${
selectedTemplate === template.id
? 'bg-blue-500 text-white'
: 'bg-gray-100 text-gray-600'
}`}>
{template.icon}
</div>
<span className="font-medium text-gray-900">{template.title}</span>
</div>
<p className="text-xs text-gray-500 text-left"></p>
</button>
))}
</div>
</div>
{/* 输入区域 */}
<div className="mb-6">
<label className="block text-sm font-semibold text-gray-700 mb-2">
</label>
<textarea
value={requirement}
onChange={(e) => setRequirement(e.target.value)}
placeholder="请输入展会的名称、规模、时间、地点、主题等信息..."
className="w-full h-48 px-4 py-3 border border-gray-300 rounded-xl text-gray-900 placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none transition-all"
style={{ fontFamily: 'system-ui, -apple-system, sans-serif' }}
/>
<div className="mt-2 text-right">
<span className="text-xs text-gray-500">{requirement.length} </span>
</div>
</div>
{/* 底部按钮 */}
<div className="flex items-center justify-between">
<div className="text-sm text-gray-500">
<span className="inline-flex items-center gap-1">
<Sparkles className="w-4 h-4 text-yellow-500" />
AI将基于您的需求生成专业的展会策划方案
</span>
</div>
<div className="flex gap-3">
<button
onClick={onClose}
className="px-6 py-2.5 text-gray-700 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors font-medium"
>
</button>
<button
onClick={handleSubmit}
disabled={!requirement.trim()}
className={`px-6 py-2.5 rounded-lg font-medium transition-all flex items-center gap-2 ${
requirement.trim()
? 'bg-gradient-to-r from-blue-600 to-purple-600 text-white hover:shadow-lg transform hover:scale-105'
: 'bg-gray-300 text-gray-500 cursor-not-allowed'
}`}
>
<Zap className="w-4 h-4" />
</button>
</div>
</div>
</div>
</div>
</motion.div>
</>
)}
</AnimatePresence>
);
};
export default RequirementModal;

View File

@@ -0,0 +1,167 @@
import React from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { X, Download, Eye, CheckCircle, FileText, TrendingUp, Calendar } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
interface ResultModalProps {
isOpen: boolean;
onClose: () => void;
onViewDetails: () => void;
}
const ResultModal: React.FC<ResultModalProps> = ({ isOpen, onClose, onViewDetails }) => {
const stats = [
{ label: '生成时间', value: '3分钟', icon: <Calendar className="w-5 h-5" /> },
{ label: '文档页数', value: '68页', icon: <FileText className="w-5 h-5" /> },
{ label: '预期ROI', value: '30%', icon: <TrendingUp className="w-5 h-5" /> },
];
const sections = [
{ name: '策划案概述', status: 'completed', pages: 8 },
{ name: '展会介绍', status: 'completed', pages: 12 },
{ name: '营销方案', status: 'completed', pages: 15 },
{ name: '现场运营', status: 'completed', pages: 10 },
{ name: '预算分析', status: 'completed', pages: 13 },
{ name: '风险评估', status: 'completed', pages: 10 },
];
return (
<AnimatePresence>
{isOpen && (
<>
{/* 背景遮罩 */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 bg-black/60 backdrop-blur-sm z-50"
onClick={onClose}
/>
{/* 弹窗内容 */}
<motion.div
initial={{ opacity: 0, scale: 0.9, y: 20 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.9, y: 20 }}
transition={{ type: 'spring', damping: 25, stiffness: 300 }}
className="fixed inset-0 flex items-center justify-center z-50 p-4"
onClick={(e) => e.stopPropagation()}
>
<div className="bg-white rounded-2xl shadow-2xl max-w-2xl w-full max-h-[90vh] overflow-hidden">
{/* 头部 */}
<div className="relative bg-gradient-to-br from-green-500 to-emerald-600 p-8 text-white">
<button
onClick={onClose}
className="absolute top-4 right-4 p-2 hover:bg-white/20 rounded-lg transition-colors"
>
<X className="w-6 h-6" />
</button>
<div className="flex items-center justify-center mb-4">
<motion.div
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{ delay: 0.2, type: 'spring', stiffness: 200 }}
className="p-4 bg-white/20 rounded-full"
>
<CheckCircle className="w-12 h-12" />
</motion.div>
</div>
<h2 className="text-3xl font-bold text-center mb-2"></h2>
<p className="text-center text-green-100">
AI已成功为您生成完整的展会策划方案
</p>
</div>
<div className="p-6">
{/* 统计信息 */}
<div className="grid grid-cols-3 gap-4 mb-6">
{stats.map((stat, index) => (
<motion.div
key={stat.label}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.3 + index * 0.1 }}
className="bg-gray-50 rounded-xl p-4"
>
<div className="flex items-center gap-3 mb-2">
<div className="p-2 bg-white rounded-lg text-gray-600">
{stat.icon}
</div>
<div>
<p className="text-2xl font-bold text-gray-900">{stat.value}</p>
<p className="text-xs text-gray-500">{stat.label}</p>
</div>
</div>
</motion.div>
))}
</div>
{/* 内容章节 */}
<div className="mb-6">
<h3 className="text-sm font-semibold text-gray-700 mb-3"></h3>
<div className="space-y-2">
{sections.map((section, index) => (
<motion.div
key={section.name}
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.4 + index * 0.05 }}
className="flex items-center justify-between p-3 bg-gray-50 rounded-lg"
>
<div className="flex items-center gap-3">
<div className="w-8 h-8 bg-green-100 text-green-600 rounded-full flex items-center justify-center">
<CheckCircle className="w-5 h-5" />
</div>
<span className="font-medium text-gray-900">{section.name}</span>
</div>
<span className="text-sm text-gray-500">{section.pages}</span>
</motion.div>
))}
</div>
</div>
{/* 生成信息 */}
<div className="p-4 bg-blue-50 rounded-xl mb-6">
<div className="flex items-start gap-3">
<div className="p-2 bg-blue-100 rounded-lg">
<FileText className="w-5 h-5 text-blue-600" />
</div>
<div className="flex-1">
<h4 className="font-semibold text-gray-900 mb-1">
2024
</h4>
<p className="text-sm text-gray-600">
</p>
</div>
</div>
</div>
{/* 操作按钮 */}
<div className="flex gap-3">
<button
onClick={onViewDetails}
className="flex-1 px-6 py-3 bg-gradient-to-r from-blue-600 to-purple-600 text-white rounded-xl font-medium hover:shadow-lg transform hover:scale-105 transition-all flex items-center justify-center gap-2"
>
<Eye className="w-5 h-5" />
</button>
<button
className="flex-1 px-6 py-3 bg-gray-100 text-gray-700 rounded-xl font-medium hover:bg-gray-200 transition-colors flex items-center justify-center gap-2"
>
<Download className="w-5 h-5" />
PDF
</button>
</div>
</div>
</div>
</motion.div>
</>
)}
</AnimatePresence>
);
};
export default ResultModal;

View File

@@ -0,0 +1,686 @@
import { useState, useEffect, useRef } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { useDemoStore } from '@/store/demoStore';
import { Play, Pause, RotateCcw, Maximize2, Terminal } from 'lucide-react';
// Terminal line type
interface TerminalLine {
id: string;
timestamp: string;
type: 'info' | 'success' | 'warning' | 'error' | 'system' | 'output' | 'progress' | 'install';
agent?: string;
content: string;
typing?: boolean;
progress?: number;
}
// 生成随机延迟
const getRandomDelay = (min: number, max: number) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
// 生成进度条字符串
const generateProgressBar = (progress: number, width: number = 30) => {
const filled = Math.floor((progress / 100) * width);
const empty = width - filled;
return `[${'█'.repeat(filled)}${'░'.repeat(empty)}] ${progress}%`;
};
const WorkflowPageV3 = () => {
const { agents, startDemo, pauseDemo, reset, status } = useDemoStore();
const [terminalLines, setTerminalLines] = useState<TerminalLine[]>([]);
const [currentAgentIndex, setCurrentAgentIndex] = useState(-1);
const [elapsedTime, setElapsedTime] = useState(0);
const [isExecuting, setIsExecuting] = useState(false);
const terminalRef = useRef<HTMLDivElement>(null);
const intervalRef = useRef<number | null>(null);
const executionTimeoutRef = useRef<number | null>(null);
// 启动序列
const startupSequence = [
{ type: 'system', content: '>>> AI Exhibition Planning System v2.0.0' },
{ type: 'system', content: '>>> Initializing multi-agent workflow...' },
{ type: 'info', content: 'Loading configuration from /etc/agents/config.yaml' },
{ type: 'info', content: 'Checking system requirements...' },
{ type: 'success', content: '✓ Node.js v18.17.0' },
{ type: 'success', content: '✓ Python 3.11.4' },
{ type: 'success', content: '✓ MongoDB 6.0.8' },
{ type: 'info', content: 'Installing dependencies...' },
{ type: 'install', content: 'npm install @ai/core @ai/agents @ai/workflow' },
{ type: 'progress', content: 'Downloading packages...', progress: 0 },
{ type: 'progress', content: 'Extracting files...', progress: 35 },
{ type: 'progress', content: 'Building modules...', progress: 67 },
{ type: 'progress', content: 'Linking dependencies...', progress: 89 },
{ type: 'success', content: '✓ All dependencies installed successfully' },
{ type: 'system', content: '========================================' },
{ type: 'system', content: 'System ready. Starting agent workflow...' },
{ type: 'system', content: '========================================' },
];
// Agent执行序列 - 更丰富的输出
const agentSequence = [
{
agent: agents[0], // 信息检索
outputs: [
{ type: 'system', content: '>>> [Agent-1] Information Retrieval Expert' },
{ type: 'info', content: 'Initializing data connectors...' },
{ type: 'install', content: 'pip install pandas numpy sklearn beautifulsoup4' },
{ type: 'progress', content: 'Installing data analysis packages...', progress: 0 },
{ type: 'progress', content: 'Installing ML libraries...', progress: 45 },
{ type: 'success', content: '✓ Packages installed (12.3s)' },
{ type: 'info', content: 'Connecting to data sources...' },
{ type: 'output', content: '[1/5] MongoDB: mongodb://data-server:27017' },
{ type: 'output', content: '[2/5] ElasticSearch: http://es-cluster:9200' },
{ type: 'output', content: '[3/5] Redis Cache: redis://cache:6379' },
{ type: 'output', content: '[4/5] API Gateway: https://api.exhibition.cn' },
{ type: 'output', content: '[5/5] Web Scraper: Ready' },
{ type: 'success', content: '✓ All connections established' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Executing search queries...' },
{ type: 'output', content: 'db.exhibitions.find({region: "长三角", year: 2024})' },
{ type: 'progress', content: 'Scanning documents...', progress: 0 },
{ type: 'progress', content: 'Processing results...', progress: 62 },
{ type: 'success', content: '> Found 2,847 matching records (342ms)' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Running data analysis pipeline...' },
{ type: 'output', content: 'import pandas as pd' },
{ type: 'output', content: 'df = pd.DataFrame(results)' },
{ type: 'output', content: 'df.groupby("category").agg({' },
{ type: 'output', content: ' "revenue": "sum",' },
{ type: 'output', content: ' "visitors": "mean",' },
{ type: 'output', content: ' "exhibitors": "count"' },
{ type: 'output', content: '})' },
{ type: 'progress', content: 'Analyzing market trends...', progress: 0 },
{ type: 'progress', content: 'Computing statistics...', progress: 78 },
{ type: 'info', content: '' },
{ type: 'success', content: '=== Analysis Results ===' },
{ type: 'output', content: '• Market Size: ¥3.2 Trillion (↑32% YoY)' },
{ type: 'output', content: '• Key Players: 5,832 companies' },
{ type: 'output', content: '• Employment: 1.86M professionals' },
{ type: 'output', content: '• Growth Rate: 28% CAGR' },
{ type: 'output', content: '• Hot Technologies: Solid-state batteries, L4 autonomous driving' },
{ type: 'success', content: '✓ Report generated: market_analysis_2024.json (15.3MB)' },
{ type: 'system', content: '[Agent-1] Completed in 18.7s' },
]
},
{
agent: agents[1], // 设计专家
outputs: [
{ type: 'system', content: '>>> [Agent-2] Design & Creative Expert' },
{ type: 'info', content: 'Loading design engines...' },
{ type: 'install', content: 'npm install three.js @adobe/react-spectrum figma-api' },
{ type: 'progress', content: 'Installing 3D libraries...', progress: 0 },
{ type: 'progress', content: 'Loading design assets...', progress: 56 },
{ type: 'success', content: '✓ Design toolkit ready' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Initializing AI design assistant...' },
{ type: 'output', content: 'const designer = new AIDesigner({' },
{ type: 'output', content: ' model: "stable-diffusion-xl",' },
{ type: 'output', content: ' style: "modern-minimalist",' },
{ type: 'output', content: ' palette: ["#0EA5E9", "#10B981", "#F59E0B"]' },
{ type: 'output', content: '});' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Generating design concepts...' },
{ type: 'progress', content: 'Creating mood board...', progress: 0 },
{ type: 'progress', content: 'Generating color schemes...', progress: 25 },
{ type: 'progress', content: 'Designing layouts...', progress: 50 },
{ type: 'progress', content: 'Optimizing spatial flow...', progress: 75 },
{ type: 'progress', content: 'Rendering 3D preview...', progress: 90 },
{ type: 'success', content: '✓ Design concepts ready' },
{ type: 'info', content: '' },
{ type: 'output', content: '=== Exhibition Layout ===' },
{ type: 'output', content: '┌──────────────────────────────┐' },
{ type: 'output', content: '│ A: Vehicle Display (15000㎡) │' },
{ type: 'output', content: '│ ┌────┬────┬────┬────┐ │' },
{ type: 'output', content: '│ │Tesla│NIO │Li │XPeng│ │' },
{ type: 'output', content: '│ └────┴────┴────┴────┘ │' },
{ type: 'output', content: '├──────────────────────────────┤' },
{ type: 'output', content: '│ B: Components (10000㎡) │' },
{ type: 'output', content: '│ C: Charging (8000㎡) │' },
{ type: 'output', content: '│ D: Smart Traffic (12000㎡) │' },
{ type: 'output', content: '└──────────────────────────────┘' },
{ type: 'success', content: '✓ Exported: design_blueprint.pdf (48.2MB)' },
{ type: 'success', content: '✓ 3D Model: exhibition_layout.glb (126MB)' },
{ type: 'system', content: '[Agent-2] Completed in 22.3s' },
]
},
{
agent: agents[2], // 财务预算
outputs: [
{ type: 'system', content: '>>> [Agent-3] Financial & Budget Expert' },
{ type: 'info', content: 'Initializing financial analysis system...' },
{ type: 'output', content: 'Loading economic models...' },
{ type: 'progress', content: 'Importing financial data...', progress: 0 },
{ type: 'progress', content: 'Building cost models...', progress: 45 },
{ type: 'success', content: '✓ Financial system ready' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Running cost calculations...' },
{ type: 'output', content: 'SELECT * FROM cost_database WHERE type IN' },
{ type: 'output', content: ' ("venue", "construction", "marketing", "operations")' },
{ type: 'output', content: 'ORDER BY priority DESC;' },
{ type: 'info', content: '' },
{ type: 'output', content: '=== Cost Breakdown ===' },
{ type: 'output', content: '• Venue Rental: ¥3,000,000' },
{ type: 'output', content: ' └─ Main Hall: ¥2,500,000' },
{ type: 'output', content: ' └─ Meeting Rooms: ¥500,000' },
{ type: 'output', content: '• Construction: ¥4,500,000' },
{ type: 'output', content: ' └─ Premium Booths: ¥3,000,000' },
{ type: 'output', content: ' └─ Standard Booths: ¥1,500,000' },
{ type: 'output', content: '• Operations: ¥2,000,000' },
{ type: 'output', content: '• Reserve Fund: ¥500,000' },
{ type: 'warning', content: 'Total Budget: ¥10,000,000' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Calculating revenue projections...' },
{ type: 'progress', content: 'Analyzing market data...', progress: 0 },
{ type: 'progress', content: 'Running simulations...', progress: 67 },
{ type: 'output', content: '=== Revenue Forecast ===' },
{ type: 'output', content: '• Booth Sales: ¥8,500,000' },
{ type: 'output', content: '• Sponsorship: ¥3,000,000' },
{ type: 'output', content: '• Tickets: ¥1,500,000' },
{ type: 'success', content: 'Total Revenue: ¥13,000,000' },
{ type: 'success', content: 'Net Profit: ¥3,000,000 (ROI: 30%)' },
{ type: 'system', content: '[Agent-3] Completed in 15.8s' },
]
},
{
agent: agents[3], // 格式编辑
outputs: [
{ type: 'system', content: '>>> [Agent-4] Document Format Expert' },
{ type: 'info', content: 'Loading document processors...' },
{ type: 'output', content: 'const formatter = require("@ai/doc-formatter");' },
{ type: 'output', content: 'const validator = require("@ai/doc-validator");' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Analyzing document structure...' },
{ type: 'progress', content: 'Parsing content...', progress: 0 },
{ type: 'progress', content: 'Checking formatting...', progress: 50 },
{ type: 'progress', content: 'Validating structure...', progress: 100 },
{ type: 'output', content: '> Chapters: 6' },
{ type: 'output', content: '> Sections: 24' },
{ type: 'output', content: '> Words: 12,847' },
{ type: 'output', content: '> Images: 36' },
{ type: 'output', content: '> Tables: 12' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Applying formatting rules...' },
{ type: 'output', content: '• Standardizing headings...' },
{ type: 'output', content: '• Unifying terminology...' },
{ type: 'output', content: '• Optimizing readability...' },
{ type: 'output', content: '• Generating TOC...' },
{ type: 'success', content: '✓ 187 terms unified' },
{ type: 'success', content: '✓ 92 numbers formatted' },
{ type: 'success', content: '✓ Document optimized' },
{ type: 'system', content: '[Agent-4] Completed in 12.1s' },
]
},
{
agent: agents[4], // 活动执行
outputs: [
{ type: 'system', content: '>>> [Agent-5] Event Execution Expert' },
{ type: 'info', content: 'Loading project management tools...' },
{ type: 'install', content: 'npm install gantt-chart timeline-js resource-planner' },
{ type: 'progress', content: 'Setting up PM tools...', progress: 0 },
{ type: 'progress', content: 'Loading templates...', progress: 78 },
{ type: 'success', content: '✓ Project tools ready' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Creating execution timeline...' },
{ type: 'output', content: 'const timeline = new Timeline({' },
{ type: 'output', content: ' start: "2024-04-01",' },
{ type: 'output', content: ' end: "2024-10-20",' },
{ type: 'output', content: ' milestones: 15' },
{ type: 'output', content: '});' },
{ type: 'info', content: '' },
{ type: 'output', content: '=== Critical Milestones ===' },
{ type: 'output', content: 'D-180: Project Kickoff ✓' },
{ type: 'output', content: 'D-150: Exhibitor Recruitment ░░░░' },
{ type: 'output', content: 'D-120: Media Launch ░░░░' },
{ type: 'output', content: 'D-90: Booth Confirmation ░░░░' },
{ type: 'output', content: 'D-60: Construction Plan ░░░░' },
{ type: 'output', content: 'D-30: Site Inspection ░░░░' },
{ type: 'output', content: 'D-7: Setup Begins ░░░░' },
{ type: 'output', content: 'D-0: Grand Opening ░░░░' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Allocating resources...' },
{ type: 'progress', content: 'Assigning teams...', progress: 0 },
{ type: 'progress', content: 'Scheduling tasks...', progress: 100 },
{ type: 'output', content: '• Management: 6 people' },
{ type: 'output', content: '• Exhibition: 30 people' },
{ type: 'output', content: '• Reception: 40 people' },
{ type: 'output', content: '• Technical: 20 people' },
{ type: 'output', content: '• Security: 30 people' },
{ type: 'success', content: '✓ Total Staff: 126 people allocated' },
{ type: 'success', content: '✓ Gantt chart generated' },
{ type: 'system', content: '[Agent-5] Completed in 16.9s' },
]
},
{
agent: agents[5], // 营销宣传
outputs: [
{ type: 'system', content: '>>> [Agent-6] Marketing & PR Expert' },
{ type: 'info', content: 'Initializing marketing automation...' },
{ type: 'output', content: 'Loading campaign tools...' },
{ type: 'progress', content: 'Connecting to ad platforms...', progress: 0 },
{ type: 'progress', content: 'Syncing social media...', progress: 60 },
{ type: 'success', content: '✓ Marketing suite ready' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Analyzing target audience...' },
{ type: 'output', content: 'SELECT demographics, interests, behavior' },
{ type: 'output', content: 'FROM audience_insights' },
{ type: 'output', content: 'WHERE industry = "automotive"' },
{ type: 'output', content: 'AND region = "yangtze_delta";' },
{ type: 'info', content: '' },
{ type: 'output', content: '=== Audience Profile ===' },
{ type: 'output', content: '• Total Reach: 5M+ professionals' },
{ type: 'output', content: '• Decision Makers: 180K' },
{ type: 'output', content: '• Media Contacts: 1,200' },
{ type: 'output', content: '• KOL Network: 89 influencers' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Generating campaign strategy...' },
{ type: 'progress', content: 'Creating content calendar...', progress: 0 },
{ type: 'progress', content: 'Planning ad campaigns...', progress: 40 },
{ type: 'progress', content: 'Scheduling posts...', progress: 80 },
{ type: 'output', content: '=== Marketing Timeline ===' },
{ type: 'output', content: 'Week 1-4: Teaser Campaign' },
{ type: 'output', content: 'Week 5-8: Early Bird Promotion' },
{ type: 'output', content: 'Week 9-12: Media Blitz' },
{ type: 'output', content: 'Week 13-16: Final Push' },
{ type: 'success', content: '✓ 120 social posts scheduled' },
{ type: 'success', content: '✓ 30 press releases drafted' },
{ type: 'success', content: '✓ ¥1.2M ad budget allocated' },
{ type: 'system', content: '[Agent-6] Completed in 19.2s' },
]
},
{
agent: agents[6], // 中央协调
outputs: [
{ type: 'system', content: '>>> [Agent-7] Central Coordinator' },
{ type: 'info', content: 'Collecting all agent outputs...' },
{ type: 'progress', content: 'Aggregating data...', progress: 0 },
{ type: 'progress', content: 'Validating consistency...', progress: 30 },
{ type: 'progress', content: 'Resolving conflicts...', progress: 60 },
{ type: 'progress', content: 'Optimizing plan...', progress: 90 },
{ type: 'success', content: '✓ All data synchronized' },
{ type: 'info', content: '' },
{ type: 'output', content: '=== Final Validation ===' },
{ type: 'success', content: '✓ Market Analysis: Complete' },
{ type: 'success', content: '✓ Design Plan: Complete' },
{ type: 'success', content: '✓ Budget Plan: Complete' },
{ type: 'success', content: '✓ Document Format: Complete' },
{ type: 'success', content: '✓ Execution Plan: Complete' },
{ type: 'success', content: '✓ Marketing Strategy: Complete' },
{ type: 'info', content: '' },
{ type: 'output', content: '=== System Metrics ===' },
{ type: 'output', content: '• Total Processing Time: 2m 48s' },
{ type: 'output', content: '• Documents Generated: 8' },
{ type: 'output', content: '• Total File Size: 238.7MB' },
{ type: 'output', content: '• Quality Score: 94/100' },
{ type: 'info', content: '' },
{ type: 'success', content: '✓ Exhibition plan completed successfully!' },
{ type: 'success', content: '✓ All files exported to /output/exhibition_2024/' },
{ type: 'system', content: '========================================' },
{ type: 'system', content: 'Workflow completed. Total time: 3m 00s' },
{ type: 'system', content: '========================================' },
]
}
];
// 添加终端行
const addTerminalLine = (line: Omit<TerminalLine, 'id' | 'timestamp'>) => {
const now = new Date();
const timestamp = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}.${now.getMilliseconds().toString().padStart(3, '0')}`;
setTerminalLines(prev => [...prev, {
...line,
id: Math.random().toString(36).substr(2, 9),
timestamp
}]);
// 自动滚动到底部
setTimeout(() => {
if (terminalRef.current) {
terminalRef.current.scrollTop = terminalRef.current.scrollHeight;
}
}, 10);
};
// 执行启动序列
const executeStartupSequence = async () => {
for (const line of startupSequence) {
if (status !== 'running') return;
if (line.type === 'progress') {
// 进度条动画
const progress = (line as any).progress || 0;
for (let p = progress; p <= 100; p += 5) {
if (status !== 'running') return;
addTerminalLine({
type: 'output',
content: generateProgressBar(p)
});
await new Promise(resolve => setTimeout(resolve, getRandomDelay(30, 80)));
}
} else {
addTerminalLine(line as any);
await new Promise(resolve => setTimeout(resolve, getRandomDelay(50, 200)));
}
}
// 开始执行Agent
setCurrentAgentIndex(0);
};
// 执行Agent
const executeAgent = async (agentIndex: number) => {
if (agentIndex >= agentSequence.length) {
// 所有Agent执行完成
setIsExecuting(false);
return;
}
const agentData = agentSequence[agentIndex];
for (const output of agentData.outputs) {
if (status !== 'running') return;
if (output.type === 'progress') {
// 进度条动画
const targetProgress = (output as any).progress || 100;
const step = targetProgress === 0 ? 100 : targetProgress;
for (let p = 0; p <= step; p += Math.floor(Math.random() * 10) + 5) {
if (status !== 'running') return;
addTerminalLine({
type: 'output',
agent: agentData.agent.name,
content: `${output.content} ${generateProgressBar(Math.min(p, step))}`
});
await new Promise(resolve => setTimeout(resolve, getRandomDelay(20, 60)));
}
} else {
addTerminalLine({
...output,
agent: output.type === 'system' ? undefined : agentData.agent.name
});
// 随机延迟,模拟真实执行
const delay = output.type === 'system' ? getRandomDelay(100, 300) :
output.type === 'install' ? getRandomDelay(200, 500) :
output.type === 'info' && output.content === '' ? 50 :
getRandomDelay(30, 150);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
// 执行下一个Agent
setCurrentAgentIndex(agentIndex + 1);
};
// 开始演示
useEffect(() => {
if (status === 'running' && !isExecuting) {
setIsExecuting(true);
executeStartupSequence();
}
}, [status]);
// 监听Agent变化
useEffect(() => {
if (status === 'running' && currentAgentIndex >= 0 && currentAgentIndex < agentSequence.length) {
executeAgent(currentAgentIndex);
}
}, [currentAgentIndex]);
// 计时器
useEffect(() => {
if (status === 'running') {
intervalRef.current = window.setInterval(() => {
setElapsedTime(prev => prev + 100);
}, 100);
} else {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
}
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
};
}, [status]);
// 重置
const handleReset = () => {
reset();
setTerminalLines([]);
setCurrentAgentIndex(-1);
setElapsedTime(0);
setIsExecuting(false);
};
// 格式化时间
const formatTime = (ms: number) => {
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const remainingSeconds = seconds % 60;
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
};
// 获取终端行颜色
const getLineColor = (type: string) => {
switch(type) {
case 'success': return 'text-green-400';
case 'error': return 'text-red-400';
case 'warning': return 'text-yellow-400';
case 'system': return 'text-purple-400';
case 'output': return 'text-blue-400';
case 'info': return 'text-gray-300';
case 'install': return 'text-cyan-400';
case 'progress': return 'text-amber-400';
default: return 'text-gray-300';
}
};
return (
<div className="h-screen bg-gray-50 flex flex-col">
{/* 顶部控制栏 */}
<div className="bg-white border-b border-gray-200 px-6 py-3 flex items-center justify-between">
<div className="flex items-center gap-4">
<h1 className="text-lg font-semibold text-gray-900">AI会展策划系统 - Agent协同演示</h1>
<div className="flex items-center gap-2">
<button
onClick={status === 'idle' ? startDemo : pauseDemo}
className="px-3 py-1.5 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors flex items-center gap-1.5"
>
{status === 'idle' || status === 'paused' ? (
<>
<Play className="w-4 h-4" />
<span></span>
</>
) : (
<>
<Pause className="w-4 h-4" />
<span></span>
</>
)}
</button>
<button
onClick={handleReset}
className="px-3 py-1.5 bg-gray-600 text-white rounded-md hover:bg-gray-700 transition-colors flex items-center gap-1.5"
>
<RotateCcw className="w-4 h-4" />
<span></span>
</button>
</div>
</div>
<div className="text-sm text-gray-600">
: {formatTime(elapsedTime)} / 03:00
</div>
</div>
{/* 主内容区 */}
<div className="flex-1 flex overflow-hidden">
{/* 左侧n8n工作流 */}
<div className="w-1/2 border-r border-gray-200 bg-white flex flex-col">
<div className="px-4 py-2 border-b border-gray-200 flex items-center justify-between bg-gray-50">
<div className="flex items-center gap-2">
<div className="w-3 h-3 rounded-full bg-green-500"></div>
<span className="text-sm font-medium text-gray-700"></span>
</div>
<button className="p-1 hover:bg-gray-200 rounded transition-colors">
<Maximize2 className="w-4 h-4 text-gray-600" />
</button>
</div>
<div className="flex-1">
<iframe
src="http://localhost:5678/workflow/XbfF8iRI4a69hmYS"
className="w-full h-full border-0"
title="n8n Workflow"
/>
</div>
</div>
{/* 右侧:终端执行区 */}
<div className="w-1/2 bg-gray-900 flex flex-col">
<div className="px-4 py-2 bg-gray-800 flex items-center justify-between">
<div className="flex items-center gap-2">
<Terminal className="w-4 h-4 text-green-400" />
<span className="text-sm font-mono text-green-400">Agent Execution Terminal</span>
</div>
<div className="flex gap-1">
<div className="w-3 h-3 rounded-full bg-red-500"></div>
<div className="w-3 h-3 rounded-full bg-yellow-500"></div>
<div className="w-3 h-3 rounded-full bg-green-500"></div>
</div>
</div>
<div
ref={terminalRef}
className="flex-1 overflow-y-auto p-4 font-mono text-xs custom-scrollbar"
style={{
backgroundColor: '#0a0a0a',
maxHeight: 'calc(100vh - 200px)'
}}
>
<style jsx>{`
.custom-scrollbar::-webkit-scrollbar {
width: 8px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: #1a1a1a;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: #444;
border-radius: 4px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: #555;
}
`}</style>
<AnimatePresence>
{terminalLines.map((line) => (
<motion.div
key={line.id}
initial={{ opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.1 }}
className="mb-0.5 whitespace-pre-wrap break-all"
>
<span className="text-gray-600">[{line.timestamp}]</span>
{line.agent && (
<span className="text-cyan-400 ml-2">{line.agent}:</span>
)}
<span className={`ml-2 ${getLineColor(line.type)}`}>
{line.content}
</span>
</motion.div>
))}
</AnimatePresence>
{/* 光标 */}
{status === 'running' && (
<motion.span
animate={{ opacity: [1, 0] }}
transition={{ duration: 0.5, repeat: Infinity }}
className="inline-block w-2 h-4 bg-green-400"
/>
)}
</div>
{/* Agent状态栏 */}
<div className="px-4 py-3 bg-gray-800 border-t border-gray-700">
<div className="grid grid-cols-7 gap-2">
{agents.map((agent, index) => (
<div
key={agent.id}
className={`flex flex-col items-center gap-1 px-2 py-2 rounded-lg transition-all ${
index < currentAgentIndex ? 'bg-green-900/50 border border-green-700' :
index === currentAgentIndex ? 'bg-blue-900 border border-blue-500 animate-pulse' :
'bg-gray-800 border border-gray-700'
}`}
>
{/* Agent头像 */}
<div className={`relative w-12 h-12 rounded-full overflow-hidden border-2 ${
index < currentAgentIndex ? 'border-green-400' :
index === currentAgentIndex ? 'border-blue-400 animate-pulse' :
'border-gray-600'
}`}>
{agent.avatar ? (
<img
src={agent.avatar}
alt={agent.name}
className={`w-full h-full object-cover ${
index < currentAgentIndex ? 'brightness-100' :
index === currentAgentIndex ? 'brightness-110' :
'brightness-50 grayscale'
}`}
/>
) : (
<div className="w-full h-full bg-gray-700 flex items-center justify-center">
<span className="text-2xl">{agent.icon}</span>
</div>
)}
{/* 状态指示器 */}
{index === currentAgentIndex && (
<div className="absolute -bottom-1 -right-1 w-3 h-3 bg-blue-400 rounded-full animate-ping"></div>
)}
{index < currentAgentIndex && (
<div className="absolute -bottom-1 -right-1 w-3 h-3 bg-green-400 rounded-full">
<svg className="w-3 h-3 text-white" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
</svg>
</div>
)}
</div>
<span className={`text-xs text-center line-clamp-2 ${
index < currentAgentIndex ? 'text-green-400' :
index === currentAgentIndex ? 'text-blue-400' :
'text-gray-500'
}`}>{agent.name}</span>
<div className={`w-full h-1 rounded-full mt-1 ${
index < currentAgentIndex ? 'bg-green-500' :
index === currentAgentIndex ? 'bg-blue-500' :
'bg-gray-700'
}`}>
{index === currentAgentIndex && (
<div className="h-full bg-blue-400 rounded-full animate-pulse"
style={{width: '50%'}}></div>
)}
</div>
</div>
))}
</div>
<div className="mt-2 text-center text-xs text-gray-400">
: {Math.round(((currentAgentIndex + 1) / agentSequence.length) * 100)}% |
: {currentAgentIndex >= 0 && currentAgentIndex < agentSequence.length ? agentSequence[currentAgentIndex]?.agent.name : '初始化中...'}
</div>
</div>
</div>
</div>
</div>
);
};
export default WorkflowPageV3;

View File

@@ -0,0 +1,992 @@
import { useState, useEffect, useRef } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { useDemoStore } from '@/store/demoStore';
import { Play, Pause, RotateCcw, Maximize2, Terminal, FileInput } from 'lucide-react';
import RequirementModal from '@/components/RequirementModal';
import ResultModal from '@/components/ResultModal';
// Terminal line type
interface TerminalLine {
id: string;
timestamp: string;
type: 'info' | 'success' | 'warning' | 'error' | 'system' | 'output' | 'progress' | 'install' | 'file' | 'image';
agent?: string;
content: string;
typing?: boolean;
isProgressLine?: boolean;
imageSrc?: string;
imageAlt?: string;
}
// 生成随机延迟
const getRandomDelay = (min: number, max: number) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
// 生成进度条字符串
const generateProgressBar = (progress: number, width: number = 40) => {
const filled = Math.floor((progress / 100) * width);
const empty = width - filled;
return `[${'█'.repeat(filled)}${'░'.repeat(empty)}] ${progress.toString().padStart(3, ' ')}%`;
};
// 生成文件大小
const generateFileSize = () => {
const sizes = ['12.3KB', '456KB', '1.2MB', '3.4MB', '15.7MB', '48.2MB', '126MB'];
return sizes[Math.floor(Math.random() * sizes.length)];
};
const WorkflowPageV4 = () => {
const { agents, startDemo, pauseDemo, reset, status } = useDemoStore();
const [terminalLines, setTerminalLines] = useState<TerminalLine[]>([]);
const [currentAgentIndex, setCurrentAgentIndex] = useState(-1);
const [elapsedTime, setElapsedTime] = useState(0);
const [isExecuting, setIsExecuting] = useState(false);
const [showRequirementModal, setShowRequirementModal] = useState(false);
const [showResultModal, setShowResultModal] = useState(false);
const [userRequirement, setUserRequirement] = useState('');
const terminalRef = useRef<HTMLDivElement>(null);
const intervalRef = useRef<number | null>(null);
const progressLineIdRef = useRef<string | null>(null);
// 启动序列
const startupSequence = [
{ type: 'system', content: '>>> AI Exhibition Planning System v2.0.0' },
{ type: 'system', content: '>>> Copyright (c) 2024 DeepSeek AI. All rights reserved.' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Checking system requirements...' },
{ type: 'progress', content: 'System check', target: 100 },
{ type: 'info', content: '' },
{ type: 'info', content: 'Loading configuration...' },
{ type: 'output', content: 'Config path: /etc/agents/config.yaml' },
{ type: 'output', content: 'Loading agents: 7 experts found' },
{ type: 'output', content: 'Workflow engine: n8n v1.109.2' },
{ type: 'success', content: '✓ Configuration loaded successfully' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Installing required packages...' },
{ type: 'install', content: 'npm install @ai/core @ai/agents @ai/workflow --save' },
{ type: 'progress', content: 'npm packages', target: 100 },
{ type: 'install', content: 'pip install pandas numpy tensorflow beautifulsoup4' },
{ type: 'progress', content: 'Python packages', target: 100 },
{ type: 'success', content: '✓ All dependencies installed' },
{ type: 'info', content: '' },
{ type: 'system', content: '=' .repeat(60) },
{ type: 'system', content: 'SYSTEM READY - Starting multi-agent workflow...' },
{ type: 'system', content: '=' .repeat(60) },
];
// Agent执行序列 - 更真实的输出
const agentSequence = [
{
agent: agents[0], // 信息检索
outputs: [
{ type: 'system', content: '>>> [Agent-1] Information Retrieval Expert Activated' },
{ type: 'info', content: 'Model: DeepSeek-V2 Chat (Temperature: 0.7)' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Installing agent dependencies...' },
{ type: 'progress', content: 'pandas==2.0.3', target: 100, stutters: [23, 67, 89] },
{ type: 'progress', content: 'requests==2.31.0', target: 100, stutters: [45, 78] },
{ type: 'progress', content: 'beautifulsoup4==4.12.2', target: 100, stutters: [34] },
{ type: 'info', content: '' },
{ type: 'info', content: 'Connecting to data sources...' },
{ type: 'output', content: 'MongoDB : mongodb://data-server:27017 ... Connected' },
{ type: 'output', content: 'ElasticSearch: http://es-cluster:9200 ... Connected' },
{ type: 'output', content: 'Redis Cache : redis://cache:6379 ... Connected' },
{ type: 'success', content: '✓ All data sources connected' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Executing search queries...' },
{ type: 'output', content: '```sql' },
{ type: 'output', content: 'SELECT * FROM exhibitions' },
{ type: 'output', content: 'WHERE region = "长三角"' },
{ type: 'output', content: ' AND industry = "新能源汽车"' },
{ type: 'output', content: ' AND year >= 2023' },
{ type: 'output', content: 'ORDER BY scale DESC;' },
{ type: 'output', content: '```' },
{ type: 'progress', content: 'Query execution', target: 100, stutters: [12, 45, 78, 92] },
{ type: 'success', content: '✓ Query completed: 2,847 rows in 342ms' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Running data analysis...' },
{ type: 'progress', content: 'Data processing', target: 100, stutters: [15, 38, 65, 88] },
{ type: 'output', content: '' },
{ type: 'output', content: '=== Market Analysis Results ===' },
{ type: 'output', content: '• Market Size : ¥3.2 Trillion (↑32% YoY)' },
{ type: 'output', content: '• Key Players : 5,832 companies' },
{ type: 'output', content: '• Employment : 1.86M professionals' },
{ type: 'output', content: '• Exhibition Count : 126 events/year' },
{ type: 'output', content: '• Avg Scale : 32,000 sqm' },
{ type: 'output', content: '• Growth Rate : 28% CAGR' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Generating report files...' },
{ type: 'progress', content: 'market_analysis_2024.json', target: 100, stutters: [56, 89] },
{ type: 'file', content: '✓ Created: market_analysis_2024.json (15.3MB)' },
{ type: 'progress', content: 'competitor_data.csv', target: 100, stutters: [34] },
{ type: 'file', content: '✓ Created: competitor_data.csv (3.7MB)' },
{ type: 'progress', content: 'industry_trends.pdf', target: 100, stutters: [67, 91] },
{ type: 'file', content: '✓ Created: industry_trends.pdf (28.5MB)' },
{ type: 'info', content: '' },
{ type: 'success', content: '✓ Agent-1 completed successfully' },
{ type: 'system', content: 'Execution time: 18.7s | Memory: 124MB | CPU: 23%' },
]
},
{
agent: agents[1], // 设计专家
outputs: [
{ type: 'system', content: '>>> [Agent-2] Design & Creative Expert Activated' },
{ type: 'info', content: 'Model: Google Gemini Pro Vision (Temperature: 0.8)' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Loading design libraries...' },
{ type: 'progress', content: 'three.js@0.157.0', target: 100, stutters: [45, 78] },
{ type: 'progress', content: '@adobe/react-spectrum', target: 100, stutters: [23, 67, 88] },
{ type: 'progress', content: 'stable-diffusion-xl', target: 100, stutters: [34, 56, 89] },
{ type: 'info', content: '' },
{ type: 'info', content: 'Initializing AI image generator...' },
{ type: 'output', content: 'const imageGen = new StableDiffusion({' },
{ type: 'output', content: ' model: "SDXL 1.0",' },
{ type: 'output', content: ' steps: 50,' },
{ type: 'output', content: ' guidance: 7.5,' },
{ type: 'output', content: ' resolution: "1920x1080"' },
{ type: 'output', content: '});' },
{ type: 'info', content: '' },
{ type: 'info', content: '🎨 Generating exhibition hall visualization...' },
{ type: 'output', content: 'Prompt: "Modern auto expo hall, futuristic design, glass ceiling"' },
{ type: 'progress', content: 'Generating: Whisk_e8f83d1a37.jpg', target: 100, stutters: [23, 45, 67, 89, 95] },
{ type: 'image',
content: '📷 IMAGE PREVIEW: 展馆外观',
imageSrc: '/data/会展策划/image/Whisk_e8f83d1a37.jpg',
imageAlt: '展馆外观效果图'
},
{ type: 'file', content: '✓ Generated: Whisk_e8f83d1a37.jpg (2.4MB)' },
{ type: 'info', content: '' },
{ type: 'info', content: '🎨 Generating interior exhibition view...' },
{ type: 'output', content: 'Prompt: "Car exhibition interior, visitors, modern displays"' },
{ type: 'progress', content: 'Generating: 展会内部参观.jpg', target: 100, stutters: [34, 67, 88] },
{ type: 'image',
content: '📷 IMAGE PREVIEW: 展厅内部布局',
imageSrc: '/data/会展策划/image/展会内部参观.jpg',
imageAlt: '展厅内部参观实景'
},
{ type: 'file', content: '✓ Generated: 展会内部参观.jpg (3.1MB)' },
{ type: 'info', content: '' },
{ type: 'info', content: '🎨 Generating test drive area visualization...' },
{ type: 'output', content: 'Prompt: "EV test drive track, outdoor exhibition area"' },
{ type: 'progress', content: 'Generating: 试驾小景.jpg', target: 100, stutters: [45, 78] },
{ type: 'output', content: '' },
{ type: 'output', content: '╔═══════════════════════════════════════════╗' },
{ type: 'output', content: '║ IMAGE PREVIEW: 试驾体验区 ║' },
{ type: 'output', content: '╠═══════════════════════════════════════════╣' },
{ type: 'output', content: '║ ╭──────────────────────────╮ ║' },
{ type: 'output', content: '║ │ ═══════════════════════ │ ║' },
{ type: 'output', content: '║ │ ║ TEST DRIVE TRACK ║ │ ║' },
{ type: 'output', content: '║ │ ║ ╱╲ 🚗 ➜➜➜ ║ │ ║' },
{ type: 'output', content: '║ │ ║ ╲ ╱──────╲ ║ │ ║' },
{ type: 'output', content: '║ │ ║ ╲ ║ │ ║' },
{ type: 'output', content: '║ │ ═══════════════════════ │ ║' },
{ type: 'output', content: '║ ╰──────────────────────────╯ ║' },
{ type: 'output', content: '╚═══════════════════════════════════════════╝' },
{ type: 'file', content: '✓ Generated: 试驾小景.jpg (2.8MB)' },
{ type: 'info', content: '' },
{ type: 'info', content: '🎨 Generating brand showcase images...' },
{ type: 'progress', content: 'Generating: 小米汽车.jpg', target: 100, stutters: [34, 67] },
{ type: 'file', content: '✓ Generated: 小米汽车.jpg (1.9MB)' },
{ type: 'progress', content: 'Generating: 博览会.jpg', target: 100, stutters: [56, 89] },
{ type: 'file', content: '✓ Generated: 博览会.jpg (3.5MB)' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Creating exhibition hall 3D layout...' },
{ type: 'output', content: '' },
{ type: 'output', content: '┌────────────────────────────────────┐' },
{ type: 'output', content: '│ EXHIBITION HALL LAYOUT │' },
{ type: 'output', content: '├────────────────────────────────────┤' },
{ type: 'output', content: '│ A: Vehicle Display [15,000㎡] │' },
{ type: 'output', content: '│ ┌─────┬─────┬─────┬─────┐ │' },
{ type: 'output', content: '│ │Tesla│ NIO │ Li │XPeng│ │' },
{ type: 'output', content: '│ └─────┴─────┴─────┴─────┘ │' },
{ type: 'output', content: '├────────────────────────────────────┤' },
{ type: 'output', content: '│ B: Components [10,000㎡] │' },
{ type: 'output', content: '│ C: Charging Tech [8,000㎡] │' },
{ type: 'output', content: '│ D: Smart Traffic [12,000㎡] │' },
{ type: 'output', content: '│ E: Conference Hall [5,000㎡] │' },
{ type: 'output', content: '└────────────────────────────────────┘' },
{ type: 'info', content: '' },
{ type: 'output', content: '📊 Image Generation Summary:' },
{ type: 'output', content: '• Total Images: 12 high-res renders' },
{ type: 'output', content: '• Format: JPEG (optimized for web)' },
{ type: 'output', content: '• Resolution: 1920x1080 @ 300dpi' },
{ type: 'output', content: '• Color Profile: sRGB' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Exporting all design assets...' },
{ type: 'progress', content: 'design_blueprint.pdf', target: 100, stutters: [45, 78, 92] },
{ type: 'file', content: '✓ Exported: design_blueprint.pdf (48.2MB)' },
{ type: 'progress', content: 'exhibition_3d_model.glb', target: 100, stutters: [23, 56, 78, 91] },
{ type: 'file', content: '✓ Exported: exhibition_3d_model.glb (126MB)' },
{ type: 'progress', content: 'image_gallery.zip', target: 100, stutters: [34, 67, 89] },
{ type: 'file', content: '✓ Exported: image_gallery.zip (42.8MB) - Contains 12 images' },
{ type: 'info', content: '' },
{ type: 'success', content: '✓ Agent-2 completed successfully' },
{ type: 'system', content: 'Execution time: 28.5s | Memory: 384MB | GPU: 65%' },
]
},
{
agent: agents[2], // 财务预算
outputs: [
{ type: 'system', content: '>>> [Agent-3] Financial & Budget Expert Activated' },
{ type: 'info', content: 'Model: DeepSeek-Math-7B (Temperature: 0.3)' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Loading financial models...' },
{ type: 'progress', content: 'Economic models', target: 100, stutters: [34, 78] },
{ type: 'progress', content: 'Cost database', target: 100, stutters: [56] },
{ type: 'info', content: '' },
{ type: 'info', content: 'Calculating costs...' },
{ type: 'output', content: 'import pandas as pd' },
{ type: 'output', content: 'import numpy as np' },
{ type: 'output', content: '' },
{ type: 'output', content: 'costs = {' },
{ type: 'output', content: ' "venue": calculate_venue_cost(50000, "shanghai"),' },
{ type: 'output', content: ' "construction": calculate_booth_cost(600, "premium"),' },
{ type: 'output', content: ' "marketing": estimate_marketing_budget("large"),' },
{ type: 'output', content: ' "operations": calculate_staff_cost(126, 3)' },
{ type: 'output', content: '}' },
{ type: 'progress', content: 'Cost calculation', target: 100, stutters: [23, 67, 89] },
{ type: 'info', content: '' },
{ type: 'output', content: '╔══════════════════════════════════════╗' },
{ type: 'output', content: '║ BUDGET BREAKDOWN ║' },
{ type: 'output', content: '╠══════════════════════════════════════╣' },
{ type: 'output', content: '║ Venue Rental ¥3,000,000 ║' },
{ type: 'output', content: '║ ├─ Exhibition Hall ¥2,500,000 ║' },
{ type: 'output', content: '║ └─ Meeting Rooms ¥500,000 ║' },
{ type: 'output', content: '║ Construction ¥4,500,000 ║' },
{ type: 'output', content: '║ ├─ Premium Booths ¥3,000,000 ║' },
{ type: 'output', content: '║ └─ Standard Booths ¥1,500,000 ║' },
{ type: 'output', content: '║ Operations ¥2,000,000 ║' },
{ type: 'output', content: '║ Reserve Fund ¥500,000 ║' },
{ type: 'output', content: '╟──────────────────────────────────────╢' },
{ type: 'output', content: '║ TOTAL BUDGET ¥10,000,000 ║' },
{ type: 'output', content: '╚══════════════════════════════════════╝' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Calculating revenue projections...' },
{ type: 'progress', content: 'Revenue modeling', target: 100, stutters: [12, 45, 78, 92] },
{ type: 'output', content: '' },
{ type: 'success', content: 'Revenue Forecast:' },
{ type: 'output', content: '• Booth Sales : ¥8,500,000' },
{ type: 'output', content: '• Sponsorship : ¥3,000,000' },
{ type: 'output', content: '• Ticket Sales : ¥1,500,000' },
{ type: 'output', content: '────────────────────────────' },
{ type: 'success', content: 'Total Revenue : ¥13,000,000' },
{ type: 'success', content: 'Net Profit : ¥3,000,000' },
{ type: 'success', content: 'ROI : 30%' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Generating financial reports...' },
{ type: 'progress', content: 'budget_plan_2024.xlsx', target: 100, stutters: [45, 89] },
{ type: 'file', content: '✓ Created: budget_plan_2024.xlsx (1.2MB)' },
{ type: 'progress', content: 'financial_forecast.pdf', target: 100, stutters: [67] },
{ type: 'file', content: '✓ Created: financial_forecast.pdf (4.8MB)' },
{ type: 'info', content: '' },
{ type: 'success', content: '✓ Agent-3 completed successfully' },
{ type: 'system', content: 'Execution time: 15.8s | Memory: 96MB | CPU: 18%' },
]
},
{
agent: agents[3], // 格式编辑
outputs: [
{ type: 'system', content: '>>> [Agent-4] Format & Structure Expert Activated' },
{ type: 'info', content: 'Model: DeepSeek-V2 Chat (Temperature: 0.5)' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Loading document processors...' },
{ type: 'progress', content: 'markdown-it@13.0.1', target: 100, stutters: [45] },
{ type: 'progress', content: 'pdfkit@0.13.0', target: 100, stutters: [67, 89] },
{ type: 'info', content: '' },
{ type: 'info', content: 'Analyzing document structure...' },
{ type: 'output', content: '📄 Document Structure Analysis' },
{ type: 'output', content: '├── 1. Executive Summary (3 pages)' },
{ type: 'output', content: '├── 2. Market Analysis (12 pages)' },
{ type: 'output', content: '├── 3. Exhibition Design (15 pages)' },
{ type: 'output', content: '├── 4. Budget Planning (10 pages)' },
{ type: 'output', content: '├── 5. Marketing Strategy (8 pages)' },
{ type: 'output', content: '├── 6. Execution Plan (10 pages)' },
{ type: 'output', content: '├── 7. Risk Assessment (5 pages)' },
{ type: 'output', content: '└── 8. Appendices (5 pages)' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Formatting sections...' },
{ type: 'progress', content: 'Document formatting', target: 100, stutters: [34, 67, 88] },
{ type: 'progress', content: 'TOC generation', target: 100, stutters: [56] },
{ type: 'progress', content: 'Page numbering', target: 100, stutters: [78] },
{ type: 'info', content: '' },
{ type: 'output', content: '╔════════════════════════════════════╗' },
{ type: 'output', content: '║ DOCUMENT STATISTICS ║' },
{ type: 'output', content: '╠════════════════════════════════════╣' },
{ type: 'output', content: '║ Total Pages : 68 ║' },
{ type: 'output', content: '║ Word Count : 24,567 ║' },
{ type: 'output', content: '║ Images : 42 ║' },
{ type: 'output', content: '║ Tables : 18 ║' },
{ type: 'output', content: '║ Charts : 23 ║' },
{ type: 'output', content: '╚════════════════════════════════════╝' },
{ type: 'info', content: '' },
{ type: 'progress', content: 'exhibition_plan_formatted.docx', target: 100, stutters: [45, 78] },
{ type: 'file', content: '✓ Created: exhibition_plan_formatted.docx (8.4MB)' },
{ type: 'info', content: '' },
{ type: 'success', content: '✓ Agent-4 completed successfully' },
{ type: 'system', content: 'Execution time: 12.4s | Memory: 72MB | CPU: 15%' },
]
},
{
agent: agents[4], // 活动执行
outputs: [
{ type: 'system', content: '>>> [Agent-5] Event Execution Expert Activated' },
{ type: 'info', content: 'Model: DeepSeek-V2 Chat (Temperature: 0.6)' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Loading project management tools...' },
{ type: 'progress', content: 'gantt-chart-js', target: 100, stutters: [23, 67] },
{ type: 'progress', content: 'resource-planner', target: 100, stutters: [45] },
{ type: 'info', content: '' },
{ type: 'info', content: 'Creating execution timeline...' },
{ type: 'output', content: '' },
{ type: 'output', content: '📅 PROJECT TIMELINE (12 Weeks)' },
{ type: 'output', content: '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━' },
{ type: 'output', content: 'Week 1-2 : [████████] Venue booking & contracts' },
{ type: 'output', content: 'Week 3-4 : [████████] Booth design & production' },
{ type: 'output', content: 'Week 5-6 : [████████] Marketing campaign launch' },
{ type: 'output', content: 'Week 7-8 : [████████] Exhibitor recruitment' },
{ type: 'output', content: 'Week 9-10 : [████████] Logistics & setup' },
{ type: 'output', content: 'Week 11 : [████] Final preparations' },
{ type: 'output', content: 'Week 12 : [████] EXHIBITION DAYS' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Assigning team resources...' },
{ type: 'progress', content: 'Resource allocation', target: 100, stutters: [34, 78, 92] },
{ type: 'output', content: '' },
{ type: 'output', content: '👥 TEAM STRUCTURE' },
{ type: 'output', content: '├── Project Director (1)' },
{ type: 'output', content: '├── Operations Team (8)' },
{ type: 'output', content: '├── Marketing Team (6)' },
{ type: 'output', content: '├── Design Team (4)' },
{ type: 'output', content: '├── Logistics Team (12)' },
{ type: 'output', content: '├── Customer Service (15)' },
{ type: 'output', content: '└── Security & Safety (20)' },
{ type: 'output', content: 'Total Staff: 66 professionals' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Creating task checklists...' },
{ type: 'progress', content: 'Checklist generation', target: 100, stutters: [56, 89] },
{ type: 'output', content: '✅ Generated 247 action items' },
{ type: 'output', content: '📋 Created 18 milestone checkpoints' },
{ type: 'output', content: '⚠️ Identified 12 critical dependencies' },
{ type: 'info', content: '' },
{ type: 'progress', content: 'execution_plan.xlsx', target: 100, stutters: [67] },
{ type: 'file', content: '✓ Created: execution_plan.xlsx (2.3MB)' },
{ type: 'progress', content: 'task_assignments.pdf', target: 100, stutters: [45, 89] },
{ type: 'file', content: '✓ Created: task_assignments.pdf (5.6MB)' },
{ type: 'info', content: '' },
{ type: 'success', content: '✓ Agent-5 completed successfully' },
{ type: 'system', content: 'Execution time: 19.2s | Memory: 108MB | CPU: 22%' },
]
},
{
agent: agents[5], // 营销宣传
outputs: [
{ type: 'system', content: '>>> [Agent-6] Marketing & PR Expert Activated' },
{ type: 'info', content: 'Model: DeepSeek-V2 Chat (Temperature: 0.7)' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Loading marketing analytics...' },
{ type: 'progress', content: 'Social media APIs', target: 100, stutters: [34, 78] },
{ type: 'progress', content: 'Ad platform SDKs', target: 100, stutters: [56] },
{ type: 'info', content: '' },
{ type: 'info', content: 'Designing marketing campaigns...' },
{ type: 'output', content: '' },
{ type: 'output', content: '🎯 MARKETING STRATEGY' },
{ type: 'output', content: '═══════════════════════════════════' },
{ type: 'output', content: '📱 Digital Marketing (40%)' },
{ type: 'output', content: ' • WeChat: 500K+ followers target' },
{ type: 'output', content: ' • Weibo: 300K+ impressions/day' },
{ type: 'output', content: ' • LinkedIn: B2B engagement 25%' },
{ type: 'output', content: ' • TikTok: Short videos 2M views' },
{ type: 'output', content: '' },
{ type: 'output', content: '📺 Traditional Media (30%)' },
{ type: 'output', content: ' • TV Ads: CCTV-2, Dragon TV' },
{ type: 'output', content: ' • Radio: Traffic channels' },
{ type: 'output', content: ' • Print: Industry magazines' },
{ type: 'output', content: '' },
{ type: 'output', content: '🤝 Partnerships (30%)' },
{ type: 'output', content: ' • Industry associations' },
{ type: 'output', content: ' • Government agencies' },
{ type: 'output', content: ' • Media partners' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Creating content calendar...' },
{ type: 'progress', content: 'Content planning', target: 100, stutters: [23, 67, 89] },
{ type: 'output', content: '' },
{ type: 'output', content: '📊 EXPECTED REACH' },
{ type: 'output', content: '┌─────────────────────────────┐' },
{ type: 'output', content: '│ Pre-Event : 2.5M people │' },
{ type: 'output', content: '│ During : 500K visitors │' },
{ type: 'output', content: '│ Post-Event: 1M engagement │' },
{ type: 'output', content: '│ ROI : 320% │' },
{ type: 'output', content: '└─────────────────────────────┘' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Generating marketing materials...' },
{ type: 'progress', content: 'marketing_strategy.pptx', target: 100, stutters: [45, 78] },
{ type: 'file', content: '✓ Created: marketing_strategy.pptx (18.7MB)' },
{ type: 'progress', content: 'social_media_kit.zip', target: 100, stutters: [67, 92] },
{ type: 'file', content: '✓ Created: social_media_kit.zip (156MB)' },
{ type: 'progress', content: 'press_release.docx', target: 100, stutters: [34] },
{ type: 'file', content: '✓ Created: press_release.docx (245KB)' },
{ type: 'info', content: '' },
{ type: 'success', content: '✓ Agent-6 completed successfully' },
{ type: 'system', content: 'Execution time: 21.5s | Memory: 142MB | CPU: 28%' },
]
},
{
agent: agents[6], // 会展策划专家(总协调)
outputs: [
{ type: 'system', content: '>>> [Agent-7] Exhibition Planning Coordinator Activated' },
{ type: 'info', content: 'Model: Chat Models + Memories (Temperature: 0.4)' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Aggregating all agent outputs...' },
{ type: 'progress', content: 'Data aggregation', target: 100, stutters: [34, 67] },
{ type: 'info', content: '' },
{ type: 'info', content: 'Performing final integration...' },
{ type: 'output', content: '' },
{ type: 'output', content: '🎯 FINAL PLAN SUMMARY' },
{ type: 'output', content: '══════════════════════════════════════' },
{ type: 'output', content: '' },
{ type: 'output', content: '📋 PROJECT: 2024长三角新能源汽车展' },
{ type: 'output', content: '📍 VENUE: 上海国家会展中心' },
{ type: 'output', content: '📅 DATE: 2024.10.18-20' },
{ type: 'output', content: '📏 SCALE: 50,000㎡ | 350展商 | 50,000观众' },
{ type: 'output', content: '' },
{ type: 'output', content: '💼 KEY DELIVERABLES' },
{ type: 'output', content: '├── Complete Planning Document (68 pages)' },
{ type: 'output', content: '├── Budget Plan (¥10M total)' },
{ type: 'output', content: '├── Design Blueprint (3D models)' },
{ type: 'output', content: '├── Marketing Strategy (2.5M reach)' },
{ type: 'output', content: '├── Execution Timeline (12 weeks)' },
{ type: 'output', content: '└── Risk Management Plan' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Quality assurance check...' },
{ type: 'progress', content: 'QA validation', target: 100, stutters: [45, 78, 91] },
{ type: 'output', content: '' },
{ type: 'success', content: '✅ All requirements met' },
{ type: 'success', content: '✅ Budget within limits' },
{ type: 'success', content: '✅ Timeline achievable' },
{ type: 'success', content: '✅ Risk factors addressed' },
{ type: 'success', content: '✅ ROI projection: 30%' },
{ type: 'info', content: '' },
{ type: 'info', content: 'Generating final deliverables...' },
{ type: 'progress', content: 'final_plan_complete.pdf', target: 100, stutters: [23, 56, 78, 92] },
{ type: 'file', content: '✓ Created: final_plan_complete.pdf (68 pages, 45.8MB)' },
{ type: 'progress', content: 'executive_summary.pdf', target: 100, stutters: [67] },
{ type: 'file', content: '✓ Created: executive_summary.pdf (3 pages, 1.2MB)' },
{ type: 'info', content: '' },
{ type: 'output', content: '╔═══════════════════════════════════════╗' },
{ type: 'output', content: '║ 🎉 PLAN GENERATION COMPLETE 🎉 ║' },
{ type: 'output', content: '╠═══════════════════════════════════════╣' },
{ type: 'output', content: '║ Total Processing Time : 03:00 ║' },
{ type: 'output', content: '║ Documents Generated : 15 files ║' },
{ type: 'output', content: '║ Total Size : 287MB ║' },
{ type: 'output', content: '║ Quality Score : 98/100 ║' },
{ type: 'output', content: '╚═══════════════════════════════════════╝' },
{ type: 'info', content: '' },
{ type: 'success', content: '✓ Agent-7 completed successfully' },
{ type: 'system', content: 'Execution time: 16.8s | Memory: 186MB | CPU: 31%' },
]
}
];
// 添加终端行
const addTerminalLine = (line: Omit<TerminalLine, 'id' | 'timestamp'>) => {
const now = new Date();
const timestamp = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}.${now.getMilliseconds().toString().padStart(3, '0')}`;
const newLine = {
...line,
id: Math.random().toString(36).substr(2, 9),
timestamp
};
setTerminalLines(prev => [...prev, newLine]);
// 自动滚动到底部
setTimeout(() => {
if (terminalRef.current) {
terminalRef.current.scrollTop = terminalRef.current.scrollHeight;
}
}, 10);
};
// 更新进度条行(覆盖同一行)
const updateProgressLine = (content: string, progressId: string) => {
const now = new Date();
const timestamp = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}.${now.getMilliseconds().toString().padStart(3, '0')}`;
setTerminalLines(prev => {
const existing = prev.findIndex(line => line.id === progressId);
if (existing !== -1) {
const updated = [...prev];
updated[existing] = {
...updated[existing],
content,
timestamp
};
return updated;
}
return prev;
});
};
// 执行进度条动画(带卡顿效果)
const executeProgress = async (label: string, stutters: number[] = [], agent?: string) => {
const progressId = Math.random().toString(36).substr(2, 9);
progressLineIdRef.current = progressId;
// 添加初始进度行
const now = new Date();
const timestamp = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}.${now.getMilliseconds().toString().padStart(3, '0')}`;
setTerminalLines(prev => [...prev, {
id: progressId,
timestamp,
type: 'output',
agent,
content: `${label}: ${generateProgressBar(0)}`,
isProgressLine: true
}]);
// 进度动画
let progress = 0;
while (progress < 100) {
if (status !== 'running') return;
// 检查是否需要卡顿
if (stutters.includes(progress)) {
await new Promise(resolve => setTimeout(resolve, getRandomDelay(1000, 3000)));
}
// 随机增长速度
const increment = Math.min(
100 - progress,
Math.floor(Math.random() * 15) + 1
);
progress = Math.min(100, progress + increment);
// 更新进度条
updateProgressLine(`${label}: ${generateProgressBar(progress)}`, progressId);
// 随机延迟
await new Promise(resolve => setTimeout(resolve, getRandomDelay(30, 150)));
}
// 完成后清除引用
progressLineIdRef.current = null;
};
// 执行启动序列
const executeStartupSequence = async () => {
for (const line of startupSequence) {
if (status !== 'running') return;
if (line.type === 'progress') {
// 进度条动画
const target = (line as any).target || 100;
const label = line.content;
await executeProgress(label, [23, 67, 89]);
} else {
addTerminalLine(line as any);
await new Promise(resolve => setTimeout(resolve, getRandomDelay(50, 200)));
}
}
// 开始执行Agent
setCurrentAgentIndex(0);
};
// 执行Agent
const executeAgent = async (agentIndex: number) => {
if (agentIndex >= agentSequence.length) {
// 所有Agent执行完成
setIsExecuting(false);
addTerminalLine({
type: 'system',
content: '=' .repeat(60)
});
addTerminalLine({
type: 'system',
content: 'ALL AGENTS COMPLETED SUCCESSFULLY'
});
addTerminalLine({
type: 'system',
content: `Total execution time: 3m 00s | Peak memory: 512MB`
});
addTerminalLine({
type: 'system',
content: '=' .repeat(60)
});
// 显示结果弹窗
setTimeout(() => {
setShowResultModal(true);
}, 1000);
return;
}
const agentData = agentSequence[agentIndex];
for (const output of agentData.outputs) {
if (status !== 'running') return;
if (output.type === 'progress') {
// 进度条动画(带卡顿)
const stutters = (output as any).stutters || [];
await executeProgress(output.content, stutters, agentData.agent.name);
} else {
addTerminalLine({
...output,
agent: output.type === 'system' ? undefined : agentData.agent.name
});
// 根据类型设置延迟
const delay =
output.type === 'system' ? getRandomDelay(100, 300) :
output.type === 'install' ? getRandomDelay(200, 400) :
output.type === 'file' ? getRandomDelay(100, 200) :
output.type === 'info' && output.content === '' ? 50 :
getRandomDelay(30, 100);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
// 执行下一个Agent
await new Promise(resolve => setTimeout(resolve, 500));
setCurrentAgentIndex(agentIndex + 1);
};
// 开始演示
useEffect(() => {
if (status === 'running' && !isExecuting) {
setIsExecuting(true);
executeStartupSequence();
}
}, [status]);
// 监听Agent变化
useEffect(() => {
if (status === 'running' && currentAgentIndex >= 0 && currentAgentIndex < agentSequence.length) {
executeAgent(currentAgentIndex);
}
}, [currentAgentIndex]);
// 计时器
useEffect(() => {
if (status === 'running') {
intervalRef.current = window.setInterval(() => {
setElapsedTime(prev => prev + 100);
}, 100);
} else {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
}
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
}
};
}, [status]);
// 处理需求提交
const handleRequirementSubmit = (requirement: string) => {
setUserRequirement(requirement);
setShowRequirementModal(false);
// 开始演示
startDemo();
};
// 处理查看详情
const handleViewDetails = () => {
setShowResultModal(false);
// 这里可以导航到结果页面
window.location.href = '#result';
};
// 重置
const handleReset = () => {
reset();
setTerminalLines([]);
setCurrentAgentIndex(-1);
setElapsedTime(0);
setIsExecuting(false);
setUserRequirement('');
setShowResultModal(false);
};
// 格式化时间
const formatTime = (ms: number) => {
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const remainingSeconds = seconds % 60;
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
};
// 获取终端行颜色
const getLineColor = (type: string) => {
switch(type) {
case 'success': return 'text-green-400';
case 'error': return 'text-red-400';
case 'warning': return 'text-yellow-400';
case 'system': return 'text-purple-400';
case 'output': return 'text-blue-400';
case 'info': return 'text-gray-300';
case 'install': return 'text-cyan-400';
case 'progress': return 'text-amber-400';
case 'file': return 'text-emerald-400';
case 'image': return 'text-pink-400';
default: return 'text-gray-300';
}
};
return (
<div className="h-screen bg-gray-50 flex flex-col">
{/* 顶部控制栏 */}
<div className="bg-white border-b border-gray-200 px-6 py-3 flex items-center justify-between">
<div className="flex items-center gap-4">
<h1 className="text-lg font-semibold text-gray-900">AI会展策划系统 - Agent协同演示</h1>
<div className="flex items-center gap-2">
<button
onClick={status === 'idle' ? () => setShowRequirementModal(true) : pauseDemo}
className="px-3 py-1.5 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors flex items-center gap-1.5"
>
{status === 'idle' ? (
<>
<FileInput className="w-4 h-4" />
<span></span>
</>
) : status === 'paused' ? (
<>
<Play className="w-4 h-4" />
<span></span>
</>
) : (
<>
<Pause className="w-4 h-4" />
<span></span>
</>
)}
</button>
<button
onClick={handleReset}
className="px-3 py-1.5 bg-gray-600 text-white rounded-md hover:bg-gray-700 transition-colors flex items-center gap-1.5"
>
<RotateCcw className="w-4 h-4" />
<span></span>
</button>
</div>
</div>
<div className="text-sm text-gray-600">
: {formatTime(elapsedTime)} / 03:00
</div>
</div>
{/* 主内容区 */}
<div className="flex-1 flex overflow-hidden">
{/* 左侧n8n工作流 */}
<div className="w-1/2 border-r border-gray-200 bg-white flex flex-col">
<div className="px-4 py-2 border-b border-gray-200 flex items-center justify-between bg-gray-50">
<div className="flex items-center gap-2">
<div className="w-3 h-3 rounded-full bg-green-500"></div>
<span className="text-sm font-medium text-gray-700"></span>
</div>
<button className="p-1 hover:bg-gray-200 rounded transition-colors">
<Maximize2 className="w-4 h-4 text-gray-600" />
</button>
</div>
<div className="flex-1">
<iframe
src="http://localhost:5678/workflow/XbfF8iRI4a69hmYS"
className="w-full h-full border-0"
title="n8n Workflow"
/>
</div>
</div>
{/* 右侧:终端执行区 */}
<div className="w-1/2 bg-gray-900 flex flex-col">
<div className="px-4 py-2 bg-gray-800 flex items-center justify-between">
<div className="flex items-center gap-2">
<Terminal className="w-4 h-4 text-green-400" />
<span className="text-sm font-mono text-green-400">Agent Execution Terminal</span>
</div>
<div className="flex gap-1">
<div className="w-3 h-3 rounded-full bg-red-500"></div>
<div className="w-3 h-3 rounded-full bg-yellow-500"></div>
<div className="w-3 h-3 rounded-full bg-green-500"></div>
</div>
</div>
<div
ref={terminalRef}
className="flex-1 overflow-y-auto p-4 font-mono text-xs custom-scrollbar"
style={{
backgroundColor: '#0a0a0a',
maxHeight: 'calc(100vh - 200px)'
}}
>
<style jsx>{`
.custom-scrollbar::-webkit-scrollbar {
width: 8px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: #1a1a1a;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: #444;
border-radius: 4px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: #555;
}
`}</style>
<AnimatePresence>
{terminalLines.map((line) => (
<motion.div
key={line.id}
initial={line.isProgressLine ? false : { opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.05 }}
className="whitespace-pre-wrap break-all leading-5"
>
{line.type === 'image' ? (
<div className="my-2">
<span className="text-gray-600">[{line.timestamp}]</span>
{line.agent && (
<span className="text-cyan-400 ml-2">{line.agent}:</span>
)}
<span className={`ml-2 ${getLineColor(line.type)}`}>
{line.content}
</span>
{line.imageSrc && (
<div className="mt-2 mb-2 inline-block">
<img
src={line.imageSrc}
alt={line.imageAlt || 'Generated image'}
className="max-w-md rounded-lg border-2 border-gray-700 shadow-xl"
style={{ maxHeight: '300px' }}
onError={(e) => {
e.currentTarget.style.display = 'none';
}}
/>
</div>
)}
</div>
) : (
<>
<span className="text-gray-600">[{line.timestamp}]</span>
{line.agent && (
<span className="text-cyan-400 ml-2">{line.agent}:</span>
)}
<span className={`ml-2 ${getLineColor(line.type)}`}>
{line.content}
</span>
</>
)}
</motion.div>
))}
</AnimatePresence>
{/* 光标 */}
{status === 'running' && (
<motion.span
animate={{ opacity: [1, 0] }}
transition={{ duration: 0.5, repeat: Infinity }}
className="inline-block w-2 h-4 bg-green-400"
/>
)}
</div>
{/* Agent状态栏 */}
<div className="px-4 py-3 bg-gray-800 border-t border-gray-700">
<div className="grid grid-cols-7 gap-2">
{agents.map((agent, index) => (
<div
key={agent.id}
className={`flex flex-col items-center gap-1 px-2 py-2 rounded-lg transition-all ${
index < currentAgentIndex ? 'bg-green-900/50 border border-green-700' :
index === currentAgentIndex ? 'bg-blue-900 border border-blue-500 animate-pulse' :
'bg-gray-800 border border-gray-700'
}`}
>
{/* Agent头像 */}
<div className={`relative w-12 h-12 rounded-full overflow-hidden border-2 ${
index < currentAgentIndex ? 'border-green-400' :
index === currentAgentIndex ? 'border-blue-400 animate-pulse' :
'border-gray-600'
}`}>
{agent.avatar ? (
<img
src={agent.avatar}
alt={agent.name}
className={`w-full h-full object-cover ${
index < currentAgentIndex ? 'brightness-100' :
index === currentAgentIndex ? 'brightness-110' :
'brightness-50 grayscale'
}`}
/>
) : (
<div className="w-full h-full bg-gray-700 flex items-center justify-center">
<span className="text-2xl">{agent.icon}</span>
</div>
)}
{/* 状态指示器 */}
{index === currentAgentIndex && (
<div className="absolute -bottom-1 -right-1 w-3 h-3 bg-blue-400 rounded-full animate-ping"></div>
)}
{index < currentAgentIndex && (
<div className="absolute -bottom-1 -right-1 w-3 h-3 bg-green-400 rounded-full">
<svg className="w-3 h-3 text-white" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
</svg>
</div>
)}
</div>
<span className={`text-xs text-center line-clamp-2 ${
index < currentAgentIndex ? 'text-green-400' :
index === currentAgentIndex ? 'text-blue-400' :
'text-gray-500'
}`}>{agent.name}</span>
<div className={`w-full h-1 rounded-full mt-1 ${
index < currentAgentIndex ? 'bg-green-500' :
index === currentAgentIndex ? 'bg-blue-500' :
'bg-gray-700'
}`}>
{index === currentAgentIndex && (
<div className="h-full bg-blue-400 rounded-full animate-pulse"
style={{width: '50%'}}></div>
)}
</div>
</div>
))}
</div>
<div className="mt-2 text-center text-xs text-gray-400">
: {currentAgentIndex === -1 ? 0 : Math.round(((currentAgentIndex) / agentSequence.length) * 100)}% |
: {currentAgentIndex >= 0 && currentAgentIndex < agentSequence.length ? agentSequence[currentAgentIndex]?.agent.name : currentAgentIndex === -1 ? '初始化中...' : '已完成'}
</div>
</div>
</div>
</div>
{/* 弹窗组件 */}
<RequirementModal
isOpen={showRequirementModal}
onClose={() => setShowRequirementModal(false)}
onSubmit={handleRequirementSubmit}
/>
<ResultModal
isOpen={showResultModal}
onClose={() => setShowResultModal(false)}
onViewDetails={handleViewDetails}
/>
</div>
);
};
export default WorkflowPageV4;

View File

@@ -4,6 +4,7 @@ export interface Agent {
id: string;
name: string;
icon: string;
avatar?: string;
model: string;
role: string;
status: 'waiting' | 'thinking' | 'generating' | 'done';
@@ -56,6 +57,7 @@ const initialAgents: Agent[] = [
id: 'retrieval',
name: '信息检索专家',
icon: '🔍',
avatar: '/agents/信息检索专家.jpg',
model: 'DeepSeek Chat Model5',
role: '市场调研、数据收集、竞品分析',
status: 'waiting',
@@ -64,6 +66,7 @@ const initialAgents: Agent[] = [
id: 'design',
name: '设计专家',
icon: '🎨',
avatar: '/agents/设计专家.jpg',
model: 'Google Gemini Chat Model2',
role: '视觉设计、空间布局、品牌形象',
status: 'waiting',
@@ -72,6 +75,7 @@ const initialAgents: Agent[] = [
id: 'budget',
name: '财务预算专家',
icon: '💰',
avatar: '/agents/预算编辑专家.jpg',
model: 'DeepSeek Chat Model2',
role: '成本核算、预算规划、ROI分析',
status: 'waiting',
@@ -80,6 +84,7 @@ const initialAgents: Agent[] = [
id: 'format',
name: '格式编辑专家',
icon: '📝',
avatar: '/agents/结构编辑专家.jpg',
model: 'DeepSeek Chat Model4',
role: '文档格式化、内容结构优化',
status: 'waiting',
@@ -88,6 +93,7 @@ const initialAgents: Agent[] = [
id: 'execution',
name: '活动执行专家',
icon: '⚡',
avatar: '/agents/会展执行专家.jpg',
model: 'DeepSeek Chat Model1',
role: '执行计划、时间线管理、任务分配',
status: 'waiting',
@@ -96,6 +102,7 @@ const initialAgents: Agent[] = [
id: 'marketing',
name: '营销宣传专家',
icon: '📢',
avatar: '/agents/营销策划专家.jpg',
model: 'DeepSeek Chat Model3',
role: '推广策略、媒体规划、品牌传播',
status: 'waiting',
@@ -104,6 +111,7 @@ const initialAgents: Agent[] = [
id: 'coordinator',
name: '会展策划专家',
icon: '🎯',
avatar: '/agents/会展策划专家.jpg',
model: 'Chat Models + Memories',
role: '中央协调、方案整合、决策支持',
status: 'waiting',