fix: 修复Agent头像显示和结果弹窗问题

主要修复:
- 恢复Agent真实头像显示(替换emoji为实际图片)
- 删除自动跳转到ResultPageV2的逻辑
- 修改ResultModal支持动态内容显示
- 根据不同订单班显示对应的方案信息

优化内容:
- 重构Agent系统,每个订单班独立管理Agent配置
- 删除不需要的ResultPageV2组件
- handleViewDetails改为在新标签页打开

影响模块:
- web_frontend/exhibition-demo/src/components/ResultModal.tsx
- web_frontend/exhibition-demo/src/pages/WorkflowPageV4.tsx
- web_frontend/exhibition-demo/src/App.tsx
- web_frontend/exhibition-demo/src/data/terminalSimulations/*.ts

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Yep_Q
2025-09-29 20:12:57 +08:00
parent a884afc494
commit 0d96ffd429
991 changed files with 113654 additions and 1303 deletions

View File

@@ -2,20 +2,20 @@ import React, { useState } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import LandingPage from './pages/LandingPage';
import WorkflowPageV4 from './pages/WorkflowPageV4';
import ResultPageV2 from './pages/ResultPageV2';
import { useDemoStore } from './store/demoStore';
type PageType = 'landing' | 'workflow' | 'result';
type PageType = 'landing' | 'workflow';
function App() {
const [currentPage, setCurrentPage] = useState<PageType>('landing');
const { status } = useDemoStore();
React.useEffect(() => {
if (status === 'completed') {
setCurrentPage('result');
}
}, [status]);
// 注释掉自动跳转逻辑,让用户通过弹窗选择是否查看结果
// React.useEffect(() => {
// if (status === 'completed') {
// setCurrentPage('result');
// }
// }, [status]);
const handleStartDemo = () => {
setCurrentPage('workflow');
@@ -49,17 +49,6 @@ function App() {
</motion.div>
)}
{currentPage === 'result' && (
<motion.div
key="result"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
<ResultPageV2 />
</motion.div>
)}
</AnimatePresence>
</div>
);

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { X, Sparkles, FileText, Zap } from 'lucide-react';
import { X, Sparkles, FileText, Zap, PenTool } from 'lucide-react';
import orderClassesData from '../data/orderClasses.json';
import { OrderClassIconMap } from './OrderClassIcons';
@@ -147,7 +147,7 @@ const RequirementModal: React.FC<RequirementModalProps> = ({ isOpen, onClose, on
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-5xl w-full max-h-[90vh] overflow-hidden">
<div className="bg-white rounded-3xl shadow-2xl max-w-5xl w-full overflow-hidden">
{/* 头部 - 苹果风格设计 */}
<div className="relative">
{/* 渐变背景 */}
@@ -198,52 +198,77 @@ const RequirementModal: React.FC<RequirementModalProps> = ({ isOpen, onClose, on
<div className="h-px bg-gradient-to-r from-transparent via-gray-200 to-transparent" />
</div>
<div className="p-6 max-h-[calc(90vh-120px)] overflow-y-auto">
<div className="p-6 bg-white/50 backdrop-blur-sm">
{/* 订单班选择 */}
<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" />
<div className="mb-6 p-5 bg-white rounded-xl shadow-sm">
<h3 className="text-base font-semibold text-gray-800 mb-4 flex items-center gap-2">
<FileText className="w-5 h-5" />
</h3>
<div className="grid grid-cols-3 gap-3">
<div className="grid grid-cols-3 gap-4">
{orderClassesData.orderClasses.map((orderClass) => (
<button
key={orderClass.id}
onClick={() => handleTemplateSelect(orderClass)}
className={`p-4 rounded-xl border-2 transition-all hover:shadow-lg ${
className={`group relative p-5 rounded-2xl border-2 transition-all duration-300 transform hover:-translate-y-1 ${
selectedTemplate === orderClass.id
? 'border-blue-500 bg-blue-50'
: 'border-gray-200 hover:border-gray-300'
? 'border-blue-500 bg-gradient-to-br from-blue-50 to-white shadow-xl scale-[1.02]'
: 'border-gray-200 hover:border-gray-300 hover:shadow-lg bg-white'
}`}
>
<div className="flex items-center gap-3 mb-2">
<div className={`p-2 rounded-lg transition-all ${
{/* 选中时的光晕效果 */}
{selectedTemplate === orderClass.id && (
<div className="absolute inset-0 rounded-2xl bg-blue-400 opacity-10 blur-xl animate-pulse" />
)}
<div className="relative flex items-center gap-3">
<div className={`p-3 rounded-xl transition-all duration-300 ${
selectedTemplate === orderClass.id
? 'bg-gradient-to-br from-blue-500 to-blue-600 text-white shadow-md scale-110'
: 'text-white hover:scale-105'
? 'bg-gradient-to-br from-blue-500 to-blue-600 text-white shadow-lg scale-110 rotate-3'
: 'text-white group-hover:scale-110 group-hover:rotate-3'
}`}
style={{
backgroundColor: selectedTemplate === orderClass.id ? undefined : orderClass.color,
boxShadow: selectedTemplate === orderClass.id ? '0 4px 12px rgba(59, 130, 246, 0.4)' : undefined
boxShadow: selectedTemplate === orderClass.id
? '0 8px 20px rgba(59, 130, 246, 0.4)'
: '0 4px 12px rgba(0, 0, 0, 0.1)'
}}>
{(() => {
const IconComponent = OrderClassIconMap[orderClass.id];
return IconComponent ? <IconComponent size={20} /> : <FileText className="w-5 h-5" />;
return IconComponent ? <IconComponent size={24} /> : <FileText className="w-6 h-6" />;
})()}
</div>
<div className="text-left flex-1">
<div className="font-medium text-gray-900">{orderClass.name}</div>
<div className="text-xs text-gray-500 truncate">{orderClass.template?.title || orderClass.description}</div>
<div className={`font-semibold transition-colors duration-300 ${
selectedTemplate === orderClass.id ? 'text-blue-900' : 'text-gray-900'
}`}>
{orderClass.name}
</div>
<div className={`text-xs mt-0.5 line-clamp-2 transition-colors duration-300 ${
selectedTemplate === orderClass.id ? 'text-blue-600' : 'text-gray-500'
}`}>
{orderClass.template?.title || orderClass.description}
</div>
</div>
</div>
{/* 选中标记 */}
{selectedTemplate === orderClass.id && (
<div className="absolute -top-2 -right-2 w-6 h-6 bg-blue-500 rounded-full flex items-center justify-center shadow-lg animate-bounce">
<svg className="w-3.5 h-3.5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
</svg>
</div>
)}
</button>
))}
</div>
</div>
{/* 输入区域 */}
<div className="mb-6">
<label className="block text-sm font-semibold text-gray-700 mb-2">
<div className="mb-6 p-5 bg-white rounded-xl shadow-sm">
<label className="text-base font-semibold text-gray-800 mb-3 flex items-center gap-2">
<PenTool className="w-5 h-5" />
</label>
<textarea

View File

@@ -5,9 +5,20 @@ import { X, Eye, CheckCircle, FileText, TrendingUp, Calendar } from 'lucide-reac
interface ResultModalProps {
isOpen: boolean;
onClose: () => void;
onViewDetails?: () => void;
projectTitle?: string;
projectSubtitle?: string;
orderClassName?: string;
}
const ResultModal: React.FC<ResultModalProps> = ({ isOpen, onClose }) => {
const ResultModal: React.FC<ResultModalProps> = ({
isOpen,
onClose,
onViewDetails,
projectTitle = '项目方案',
projectSubtitle = '包含完整的分析、设计、预算、执行计划等内容',
orderClassName = '通用'
}) => {
const stats = [
{ label: '生成时间', value: '3分钟', icon: <Calendar className="w-5 h-5" /> },
{ label: '文档页数', value: '68页', icon: <FileText className="w-5 h-5" /> },
@@ -68,7 +79,7 @@ const ResultModal: React.FC<ResultModalProps> = ({ isOpen, onClose }) => {
<h2 className="text-3xl font-bold text-center mb-2"></h2>
<p className="text-center text-green-100">
AI已成功为您生成完整的展会策划方
AI已成功为您生成完整的{orderClassName}
</p>
</div>
@@ -128,10 +139,10 @@ const ResultModal: React.FC<ResultModalProps> = ({ isOpen, onClose }) => {
</div>
<div className="flex-1">
<h4 className="font-semibold text-gray-900 mb-1">
2024
{projectTitle}
</h4>
<p className="text-sm text-gray-600">
{projectSubtitle}
</p>
</div>
</div>
@@ -142,7 +153,7 @@ const ResultModal: React.FC<ResultModalProps> = ({ isOpen, onClose }) => {
<div className="p-6 bg-gray-50 border-t border-gray-200 flex-shrink-0">
<div className="flex justify-center">
<button
onClick={() => window.open('http://localhost:4155/', '_blank')}
onClick={onViewDetails}
className="px-8 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" />

View File

@@ -0,0 +1,60 @@
// 食品订单班专属Agent配置
export interface FoodAgent {
id: string;
name: string;
icon: string;
avatar?: string;
description: string;
}
export const foodAgents: FoodAgent[] = [
{
id: 'market-research',
name: '餐饮市场调研专家',
icon: '🔍',
avatar: '/data/订单班文档资料/食品/agent头像/餐饮市场调研专家.jpeg',
description: '负责市场分析、竞品调研、消费者画像'
},
{
id: 'brand-design',
name: '餐饮品牌设计专家',
icon: '🎨',
avatar: '/data/订单班文档资料/食品/agent头像/餐饮品牌设计专家.jpeg',
description: '负责品牌定位、视觉设计、空间设计'
},
{
id: 'menu-development',
name: '菜品研发专家',
icon: '👨‍🍳',
avatar: '/data/订单班文档资料/食品/agent头像/菜品研发专家.jpeg',
description: '负责菜单设计、营养搭配、口味调试'
},
{
id: 'location-design',
name: '餐厅选址装修专家',
icon: '🏪',
avatar: '/data/订单班文档资料/食品/agent头像/餐厅选址装修专家.jpeg',
description: '负责选址分析、装修设计、空间规划'
},
{
id: 'team-management',
name: '餐饮团队人员管理专家',
icon: '👥',
avatar: '/data/订单班文档资料/食品/agent头像/餐饮团队人员管理专家.jpeg',
description: '负责团队组建、培训体系、绩效管理'
},
{
id: 'budget',
name: '财务预算专家',
icon: '💰',
avatar: '/data/订单班文档资料/食品/agent头像/财务预算专家.jpeg',
description: '负责投资预算、成本核算、财务规划'
},
{
id: 'operation',
name: '轻食店经营管理专家',
icon: '📊',
avatar: '/data/订单班文档资料/食品/agent头像/轻食店经营管理专家.jpeg',
description: '负责运营策略、流程优化、质量管理'
}
];

View File

@@ -0,0 +1,93 @@
import { LucideIcon, Search, Palette, Calculator, FileText, Zap, Megaphone, Calendar } from 'lucide-react';
export interface WenluAgent {
id: string;
name: string;
icon: string;
IconComponent?: LucideIcon;
role: string;
description: string;
skills: string[];
experience: string;
avatar: string;
}
export const wenluAgents: WenluAgent[] = [
{
id: 'info-retrieval',
name: '信息检索专家',
icon: '🔍',
IconComponent: Search,
role: '展会信息收集与分析',
description: '专注于展会行业信息检索、市场调研、竞品分析、行业报告整理。擅长从海量数据中提取关键信息,为展会策划提供数据支撑。',
skills: ['市场调研', '数据分析', '竞品研究', '趋势预测'],
experience: '10年展会行业研究经验',
avatar: '/data/订单班文档资料/文旅/agent头像/信息检索专家.jpg'
},
{
id: 'design-expert',
name: '设计师专家',
icon: '🎨',
IconComponent: Palette,
role: '展会视觉设计与空间规划',
description: '负责展会整体视觉设计、展台布局、空间规划、品牌VI系统。精通展览设计原理能创造独特的参展体验。',
skills: ['展台设计', '空间规划', 'VI设计', '3D建模'],
experience: '8年展览设计经验',
avatar: '/data/订单班文档资料/文旅/agent头像/设计专家.jpg'
},
{
id: 'budget-expert',
name: '财务预算专家',
icon: '💰',
IconComponent: Calculator,
role: '展会成本控制与财务规划',
description: '精通展会预算编制、成本控制、投资回报分析。确保展会在预算范围内实现最大价值,优化资源配置。',
skills: ['预算编制', '成本控制', 'ROI分析', '财务规划'],
experience: '12年展会财务管理经验',
avatar: '/data/订单班文档资料/文旅/agent头像/预算编辑专家.jpg'
},
{
id: 'format-editor',
name: '格式编辑专家',
icon: '📝',
IconComponent: FileText,
role: '展会文档标准化与内容编辑',
description: '负责展会方案文档编写、格式规范、内容校对。确保所有文档专业、清晰、符合行业标准。',
skills: ['文档编写', '内容编辑', '格式规范', '多语言翻译'],
experience: '6年展会文案策划经验',
avatar: '/data/订单班文档资料/文旅/agent头像/结构编辑专家.jpg'
},
{
id: 'event-executor',
name: '活动执行专家',
icon: '⚡',
IconComponent: Zap,
role: '展会现场执行与协调',
description: '负责展会现场执行、供应商管理、突发事件处理。确保展会顺利进行,各环节无缝衔接。',
skills: ['现场管理', '供应商协调', '危机处理', '流程优化'],
experience: '15年大型展会执行经验',
avatar: '/data/订单班文档资料/文旅/agent头像/会展执行专家.jpg'
},
{
id: 'marketing-expert',
name: '营销宣传专家',
icon: '📢',
IconComponent: Megaphone,
role: '展会推广与品牌传播',
description: '制定展会营销策略、媒体推广计划、观众招募方案。通过多渠道营销提升展会影响力和参与度。',
skills: ['营销策划', '媒体公关', '社交媒体', '观众招募'],
experience: '9年展会营销推广经验',
avatar: '/data/订单班文档资料/文旅/agent头像/营销策划专家.jpg'
},
{
id: 'exhibition-planner',
name: '会展策划专家',
icon: '🎯',
IconComponent: Calendar,
role: '展会整体策划与统筹',
description: '负责展会整体策划、主题设计、流程规划、资源整合。确保展会目标明确、执行有序、效果卓越。',
skills: ['策略规划', '主题策划', '资源整合', '项目管理'],
experience: '18年国际展会策划经验',
avatar: '/data/订单班文档资料/文旅/agent头像/会展策划专家.jpg'
}
];

View File

@@ -1,70 +0,0 @@
{
"orderClass": "食品",
"orderClassId": "food",
"title": "2024国际健康食品与轻食产业博览会",
"templateConfig": {
"id": "food",
"title": "食品产业展",
"icon": "UtensilsCrossed",
"content": "展会名称2024国际健康食品与轻食产业博览会\n地点北京国家会议中心\n时间2024年11月15日-17日\n规模30,000平方米预计200家展商30,000人次观众\n主题健康饮食新风尚轻食产业新机遇\n特色健康食品展示、轻食品牌推广、营养科技创新、餐饮连锁加盟"
},
"sections": [
{
"title": "项目概述",
"content": [
{
"type": "text",
"text": "随着国民健康意识提升,'低卡、营养、便捷'的轻食需求持续增长。据艾瑞咨询2024年报告显示中国轻食市场规模已突破1200亿元年增长率达18%。本展会聚焦健康食品与轻食产业,为品牌商、投资者、消费者搭建交流平台。"
}
]
},
{
"title": "展会亮点",
"content": [
{
"type": "list",
"items": [
"青莳轻食等中高端轻食品牌现场展示",
"营养科学讲座与健康饮食体验",
"轻食加盟项目对接会",
"食材供应链解决方案展示"
]
}
]
},
{
"title": "参展品牌",
"content": [
{
"type": "brands",
"items": ["青莳轻食", "Wagas", "Element Fresh", "Moka Bros", "Hunter Gatherer", "沙野轻食", "超能鹿战队", "田园主义"]
}
]
},
{
"title": "商业机会",
"content": [
{
"type": "text",
"text": "展会特设轻食加盟专区青莳轻食等品牌提供完整的加盟方案初始投资85万元预计8个月回本年化收益率35%。现场签约享受优惠政策。"
}
]
}
],
"images": {
"basePath": "../../data/订单班文档资料/食品/notion文稿/image/",
"list": [
"设计图_01.jpg",
"设计图_02.jpg",
"设计图_03.jpg",
"展示图_01.jpg",
"展示图_02.jpg",
"展示图_03.jpg"
]
},
"metadata": {
"createTime": "2024-09-28",
"updateTime": "2024-09-28",
"status": "completed"
}
}

View File

@@ -1,10 +1,60 @@
import { Agent } from '@/store/demoStore';
import { SimulationData, TerminalLine } from './index';
export const foodSimulation = (agents: Agent[]): SimulationData => ({
// 食品订单班专属Agent配置
const foodAgents: Agent[] = [
{
id: 'food_market_analyst',
name: '餐饮市场分析师',
icon: '📊',
avatar: '/data/订单班文档资料/食品/agent头像/餐饮市场调研专家.jpeg',
model: 'DeepSeek V2',
role: '市场调研、竞品分析、消费趋势',
status: 'waiting',
},
{
id: 'food_brand_designer',
name: '品牌设计师',
icon: '🎨',
avatar: '/data/订单班文档资料/食品/agent头像/餐饮品牌设计专家.jpeg',
model: 'Google Gemini',
role: '品牌形象、VI设计、门店装修',
status: 'waiting',
},
{
id: 'food_operation_expert',
name: '餐饮运营专家',
icon: '🍽️',
avatar: '/data/订单班文档资料/食品/agent头像/轻食店经营管理专家.jpeg',
model: 'DeepSeek Chat',
role: '运营流程、供应链管理、质量控制',
status: 'waiting',
},
{
id: 'food_finance_advisor',
name: '财务顾问',
icon: '💰',
avatar: '/data/订单班文档资料/食品/agent头像/财务预算专家.jpeg',
model: 'GPT-4',
role: '成本核算、投资回报、财务规划',
status: 'waiting',
},
{
id: 'food_marketing_strategist',
name: '营销策略师',
icon: '📱',
avatar: '/data/订单班文档资料/食品/agent头像/餐饮团队人员管理专家.jpeg',
model: 'Claude 3',
role: '营销推广、社媒运营、会员体系',
status: 'waiting',
},
];
export const foodSimulation = (): SimulationData => ({
orderClassId: 'food',
orderClassName: '食品',
projectTitle: '青莳轻食连锁品牌创业方案',
agents: foodAgents,
startupSequence: [
{ type: 'info', content: '🚀 启动食品行业轻食品牌创业方案生成系统...' },
@@ -24,9 +74,9 @@ export const foodSimulation = (agents: Agent[]): SimulationData => ({
agentSequence: [
{
agent: () => agents[0], // 信息检索专家
agent: () => foodAgents[0], // 餐饮市场分析师
outputs: [
{ type: 'system', content: '🔍 信息检索专家 正在分析...' },
{ type: 'system', content: '📊 餐饮市场分析师 正在分析...' },
{ type: 'info', content: '检索关键词: 轻食市场 + 国贸商圈 + 白领消费' },
{ type: 'progress', content: '分析市场数据...', duration: 800 },
{ type: 'success', content: '✓ 发现目标区域日均白领流量: 15,000人' },
@@ -44,145 +94,111 @@ export const foodSimulation = (agents: Agent[]): SimulationData => ({
]
},
{
agent: () => agents[1], // 设计专家
agent: () => foodAgents[1], // 品牌设计师
outputs: [
{ type: 'system', content: '🎨 设计专家 开始创作...' },
{ type: 'system', content: '🎨 品牌设计师 开始创作...' },
{ type: 'info', content: '设计理念: 透明厨房 + 自然简约' },
{ type: 'progress', content: '生成空间布局方案...', duration: 1000 },
{
type: 'image',
content: '🏪 店面设计效果图',
imageSrc: '/data/订单班文档资料/食品/notion文稿/image/图片_02.jpg',
imageAlt: '青莳轻食店面3D效果图'
},
{ type: 'success', content: '✓ 110㎡空间优化完成' },
{ type: 'info', content: '功能分区:' },
{ type: 'system', content: '├─ 堂食区: 65㎡ (26座)' },
{ type: 'system', content: '├─ 透明厨房: 30㎡' },
{ type: 'system', content: '└─ 营养咨询区: 15㎡' },
{ type: 'progress', content: '生成品牌视觉方案...', duration: 1000 },
{
type: 'image',
content: '🎨 品牌VI设计',
imageSrc: '/data/订单班文档资料/食品/notion文稿/image/图片_02.jpg',
imageAlt: '青莳品牌Logo设计'
},
{ type: 'success', content: '✓ Logo设计: 青莳标识(绿叶+汉字组合)' },
{ type: 'success', content: '✓ 主色调: 莫兰迪绿 + 暖白' },
{ type: 'success', content: '✓ 门店效果图已生成' },
{
type: 'image',
content: '🏪 门店设计效果图',
imageSrc: '/data/订单班文档资料/食品/notion文稿/image/图片_03.jpg',
imageAlt: '青莳品牌视觉识别系统'
imageAlt: '门店3D效果图'
},
{ type: 'success', content: '✓ 品牌色: 青莳绿 #4CAF50' },
]
},
{
agent: () => agents[2], // 财务预算专家
agent: () => foodAgents[2], // 餐饮运营专家
outputs: [
{ type: 'system', content: '💰 财务预算专家 正在核算...' },
{ type: 'info', content: '总投资预算: 60万元' },
{ type: 'progress', content: '详细成本分解...', duration: 800 },
{ type: 'system', content: '📊 投资明细:' },
{ type: 'system', content: '├─ 装修费用: 30万 (2727元/㎡)' },
{ type: 'system', content: '├─ 设备采购: 15万' },
{ type: 'system', content: '├─ 首批原料: 5万' },
{ type: 'system', content: '├─ 营销推广: 3万' },
{ type: 'system', content: '└─ 流动资金: 7万' },
{ type: 'system', content: '🍽️ 餐饮运营专家 正在规划...' },
{ type: 'info', content: '制定标准化运营流程' },
{ type: 'progress', content: '优化供应链体系...', duration: 800 },
{ type: 'success', content: '✓ 建立中央厨房配送模式' },
{ type: 'success', content: '✓ 制定食材采购标准' },
{ type: 'info', content: '设计产品矩阵...' },
{
type: 'image',
content: '📈 财务预测模型',
imageSrc: '/data/订单班文档资料/食品/notion文稿/image/图片_08.jpg',
imageAlt: '12个月财务预测图表'
content: '📋 产品矩阵图',
imageSrc: '/data/订单班文档资料/食品/notion文稿/image/图片_04.jpg',
imageAlt: '产品SKU矩阵'
},
{ type: 'success', content: '✓ 预计回本周期: 14个月' },
{ type: 'success', content: '✓ 毛利率: 65%' },
{ type: 'warning', content: '💡 日均营业额需达: 15,000元' },
{ type: 'success', content: '✓ 核心SKU: 20款健康轻食' },
{ type: 'success', content: '✓ 季节性新品: 每季度4款' },
{ type: 'success', content: '✓ 运营SOP手册已完成' },
]
},
{
agent: () => agents[3], // 格式编辑专家
agent: () => foodAgents[3], // 财务顾问
outputs: [
{ type: 'system', content: '📝 格式编辑专家 整理方案...' },
{ type: 'info', content: '生成标准化商业计划书' },
{ type: 'progress', content: '格式化文档...', duration: 600 },
{ type: 'success', content: '✓ 执行摘要完成' },
{ type: 'success', content: '✓ 产品菜单设计完成' },
{ type: 'info', content: '核心产品线:' },
{ type: 'system', content: '├─ 能量碗系列: 12款' },
{ type: 'system', content: '├─ 轻食沙拉: 8款' },
{ type: 'system', content: '├─ 低卡主食: 6款' },
{ type: 'system', content: '└─ 营养饮品: 6款' },
{ type: 'success', content: '✓ 32款SKU定价策略完成' },
{ type: 'info', content: '客单价区间: 45-68元' },
]
},
{
agent: () => agents[4], // 活动执行专家
outputs: [
{ type: 'system', content: '⚡ 活动执行专家 制定开业计划...' },
{ type: 'info', content: '开业倒计时: 45天' },
{ type: 'progress', content: '生成执行时间线...', duration: 800 },
{ type: 'system', content: '💰 财务顾问 正在核算...' },
{ type: 'info', content: '编制投资预算方案' },
{ type: 'progress', content: '计算投资回报率...', duration: 1200 },
{
type: 'image',
content: '📅 开业执行计划',
imageSrc: '/data/订单班文档资料/食品/notion文稿/image/图片_10.jpg',
imageAlt: '45天开业准备甘特图'
content: '💹 财务模型',
imageSrc: '/data/订单班文档资料/食品/notion文稿/image/图片_05.jpg',
imageAlt: '投资回报分析'
},
{ type: 'system', content: '关键里程碑:' },
{ type: 'system', content: '├─ D-45: 签约装修团队' },
{ type: 'system', content: '├─ D-30: 设备进场安装' },
{ type: 'system', content: '├─ D-15: 团队培训启动' },
{ type: 'system', content: '├─ D-7: 试营业' },
{ type: 'system', content: '└─ D-Day: 正式开业' },
{ type: 'success', content: '✓ 供应链对接完成' },
{ type: 'warning', content: '⚠️ 关键风险: 食材供应稳定性' },
{ type: 'success', content: '✓ 初始投资: 120万元' },
{ type: 'success', content: '✓ 月均营收预测: 45万元' },
{ type: 'success', content: '✓ 投资回收期: 14个月' },
{ type: 'success', content: '✓ 年化收益率: 35%' },
{ type: 'info', content: '成本结构分析完成' },
{ type: 'success', content: '✓ 食材成本: 35%' },
{ type: 'success', content: '✓ 人工成本: 25%' },
{ type: 'success', content: '✓ 租金成本: 15%' },
]
},
{
agent: () => agents[5], // 营销宣传专家
agent: () => foodAgents[4], // 营销策略师
outputs: [
{ type: 'system', content: '📢 营销宣传专家 策划推广...' },
{ type: 'info', content: '目标: 开业首月获客3000人' },
{ type: 'progress', content: '制定营销策略...', duration: 1000 },
{ type: 'system', content: '📱 营销策略师 制定策略...' },
{ type: 'info', content: '构建全渠道营销体系' },
{ type: 'progress', content: '设计推广方案...', duration: 900 },
{
type: 'image',
content: '📱 社交媒体营销',
imageSrc: '/data/订单班文档资料/食品/notion文稿/image/图片_12.jpg',
imageAlt: '小红书/抖音营销方案'
content: '📣 营销策略图',
imageSrc: '/data/订单班文档资料/食品/notion文稿/image/图片_06.jpg',
imageAlt: '全渠道营销布局'
},
{ type: 'system', content: '营销渠道矩阵:' },
{ type: 'system', content: '├─ 小红书: KOL种草计划' },
{ type: 'system', content: '├─ 美团: 新店扶持活动' },
{ type: 'system', content: '├─ 企业团餐: B端拓展' },
{ type: 'system', content: '└─ 会员体系: 储值优惠' },
{ type: 'success', content: '✓ 开业活动: 买一送一(前500名)' },
{ type: 'success', content: '✓ 预计转化率: 15%' },
{ type: 'info', content: '月度营销预算: 15,000元' },
{ type: 'success', content: '✓ 线上渠道: 美团/饿了么/抖音团购' },
{ type: 'success', content: '✓ 私域运营: 企业微信社群运营' },
{ type: 'success', content: '✓ 会员体系: 积分+储值双轨制' },
{ type: 'info', content: '开业营销活动策划' },
{ type: 'success', content: '✓ 开业3天: 全场6.8折' },
{ type: 'success', content: '✓ 首月会员: 储值送30%' },
{ type: 'success', content: '✓ 企业团餐: 满20单8.5折' },
]
},
{
agent: () => agents[6], // 会展策划专家(总协调)
outputs: [
{ type: 'system', content: '🎯 策划专家 整合最终方案...' },
{ type: 'info', content: '方案评分: 92/100' },
{ type: 'progress', content: '生成完整商业计划书...', duration: 1200 },
{
type: 'image',
content: '📊 项目总览',
imageSrc: '/data/订单班文档资料/食品/notion文稿/image/图片_15.jpg',
imageAlt: '青莳轻食项目一页纸总览'
},
{ type: 'success', content: '✅ 商业模式: 透明化健康轻食' },
{ type: 'success', content: '✅ 核心优势: 食材可溯源+营养可视化' },
{ type: 'success', content: '✅ 目标营收: 首年600万' },
{ type: 'success', content: '✅ 扩张计划: 18个月开设3家店' },
{ type: 'warning', content: '💡 成功关键: 产品标准化+会员运营' },
{ type: 'system', content: '文档生成完成共68页' },
]
}
],
completionSequence: [
{ type: 'success', content: '🎉 青莳轻食创业方案生成完成!' },
{ type: 'info', content: '生成耗时: 3分12秒' },
{ type: 'system', content: '方案亮点:' },
{ type: 'system', content: '• 精准定位国贸白领健康餐饮需求' },
{ type: 'system', content: '• 透明厨房打造信任感' },
{ type: 'system', content: '• 营养师驻店提供专业咨询' },
{ type: 'system', content: '• 数字化会员管理系统' },
{ type: 'success', content: '✨ 方案已保存至: /projects/food/青莳轻食_BP_v1.0.pdf' },
{ type: 'system', content: '=' .repeat(60) },
{ type: 'success', content: '🎉 青莳轻食品牌创业方案生成完成!' },
{ type: 'system', content: '=' .repeat(60) },
{ type: 'info', content: '📊 方案亮点:' },
{ type: 'success', content: '✓ 精准定位国贸白领健康餐饮需求' },
{ type: 'success', content: '✓ 差异化品牌形象和产品矩阵' },
{ type: 'success', content: '✓ 标准化运营确保品质稳定' },
{ type: 'success', content: '✓ 全渠道营销快速获客' },
{ type: 'success', content: '✓ 14个月回本年化收益35%' },
{ type: 'info', content: '' },
{ type: 'info', content: '💼 下一步行动:' },
{ type: 'output', content: '1. 选址考察建议3-5个备选点位' },
{ type: 'output', content: '2. 团队组建(店长、厨师、服务员)' },
{ type: 'output', content: '3. 供应商洽谈(食材、包装、设备)' },
{ type: 'output', content: '4. 装修施工预计45天' },
{ type: 'output', content: '5. 试营业调整7-10天' },
{ type: 'info', content: '' },
{ type: 'success', content: '✅ 方案已保存至: /projects/food/青莳轻食_创业方案_v1.0.pdf' },
]
});

View File

@@ -32,13 +32,14 @@ export interface SimulationData {
orderClassId: string;
orderClassName: string;
projectTitle: string;
agents: Agent[]; // 添加agents字段
startupSequence: TerminalLine[];
agentSequence: AgentOutput[];
completionSequence: TerminalLine[];
}
// 生成函数类型
export type SimulationGenerator = (agents: Agent[]) => SimulationData;
// 生成函数类型 - 不再需要传入agents参数
export type SimulationGenerator = () => SimulationData;
// 订单班模拟数据映射表 - 目前只有文旅和食品
export const simulationMap: Record<string, SimulationGenerator> = {
@@ -48,32 +49,29 @@ export const simulationMap: Record<string, SimulationGenerator> = {
};
// 获取指定订单班的模拟数据
export const getSimulationData = (orderClassId: string, agents: Agent[]): SimulationData | null => {
console.log('[getSimulationData] Called with:', {
orderClassId,
agentsCount: agents.length,
agentsNames: agents.map(a => a.name)
});
export const getSimulationData = (orderClassId: string): SimulationData | null => {
console.log('[getSimulationData] Called with orderClassId:', orderClassId);
const generator = simulationMap[orderClassId];
console.log('[getSimulationData] Available keys:', Object.keys(simulationMap));
console.log('[getSimulationData] Generator found:', !!generator);
if (!generator) {
console.warn(`No simulation data found for order class: ${orderClassId}`);
return null;
}
const data = generator(agents);
const data = generator();
console.log('[getSimulationData] Data generated:', {
hasData: !!data,
orderClassName: data?.orderClassName,
projectTitle: data?.projectTitle,
agentsCount: data?.agents?.length,
startupSequenceLength: data?.startupSequence?.length,
agentSequenceLength: data?.agentSequence?.length,
completionSequenceLength: data?.completionSequence?.length
});
return data;
};

View File

@@ -6,7 +6,74 @@
import { Agent } from '@/store/demoStore';
import { SimulationData, TerminalLine } from './index';
export const wenluSimulation = (agents: Agent[]): SimulationData => {
// 文旅订单班专属Agent配置
const wenluAgents: Agent[] = [
{
id: 'wenlu_info_retrieval',
name: '信息检索专家',
icon: '🔍',
avatar: '/data/订单班文档资料/文旅/agent头像/信息检索专家.jpg',
model: 'DeepSeek V2',
role: '市场调研、数据分析、趋势洞察',
status: 'waiting',
},
{
id: 'wenlu_design_expert',
name: '设计创意专家',
icon: '🎨',
avatar: '/data/订单班文档资料/文旅/agent头像/设计专家.jpg',
model: 'Google Gemini',
role: '展览设计、视觉创作、空间规划',
status: 'waiting',
},
{
id: 'wenlu_budget_expert',
name: '财务预算专家',
icon: '💰',
avatar: '/data/订单班文档资料/文旅/agent头像/预算编辑专家.jpg',
model: 'DeepSeek Math',
role: '成本核算、预算规划、财务分析',
status: 'waiting',
},
{
id: 'wenlu_doc_formatter',
name: '格式编辑专家',
icon: '📄',
avatar: '/data/订单班文档资料/文旅/agent头像/结构编辑专家.jpg',
model: 'DeepSeek Chat',
role: '文档编排、格式优化、内容整合',
status: 'waiting',
},
{
id: 'wenlu_execution_expert',
name: '活动执行专家',
icon: '📅',
avatar: '/data/订单班文档资料/文旅/agent头像/会展执行专家.jpg',
model: 'DeepSeek Chat',
role: '执行规划、时间管理、资源调度',
status: 'waiting',
},
{
id: 'wenlu_marketing_expert',
name: '营销宣传专家',
icon: '📱',
avatar: '/data/订单班文档资料/文旅/agent头像/营销策划专家.jpg',
model: 'DeepSeek Chat',
role: '品牌推广、媒体策略、用户增长',
status: 'waiting',
},
{
id: 'wenlu_coordinator',
name: '会展策划专家',
icon: '🎯',
avatar: '/data/订单班文档资料/文旅/agent头像/会展策划专家.jpg',
model: 'Chat Models',
role: '整体协调、质量把控、方案整合',
status: 'waiting',
},
];
export const wenluSimulation = (): SimulationData => {
const startupSequence: TerminalLine[] = [
{ type: 'system', content: '>>> AI Exhibition Planning System v2.0.0' },
{ type: 'system', content: '>>> Copyright (c) 2024 DeepSeek AI. All rights reserved.' },
@@ -41,7 +108,7 @@ export const wenluSimulation = (agents: Agent[]): SimulationData => {
const agentSequence = [
{
agent: () => agents[0], // 信息检索专家
agent: () => wenluAgents[0], // 信息检索专家
outputs: [
{ type: 'system', content: '>>> [Agent-1] Information Retrieval Expert Activated' },
{ type: 'info', content: 'Model: DeepSeek-V2 Chat (Temperature: 0.7)' },
@@ -92,7 +159,7 @@ export const wenluSimulation = (agents: Agent[]): SimulationData => {
]
},
{
agent: () => agents[1], // 设计专家
agent: () => wenluAgents[1], // 设计创意专家
outputs: [
{ type: 'system', content: '>>> [Agent-2] Design & Creative Expert Activated' },
{ type: 'info', content: 'Model: Google Gemini Pro Vision (Temperature: 0.8)' },
@@ -182,7 +249,7 @@ export const wenluSimulation = (agents: Agent[]): SimulationData => {
]
},
{
agent: () => agents[2], // 财务预算专家
agent: () => wenluAgents[2], // 财务预算专家
outputs: [
{ type: 'system', content: '>>> [Agent-3] Financial & Budget Expert Activated' },
{ type: 'info', content: 'Model: DeepSeek-Math-7B (Temperature: 0.3)' },
@@ -221,7 +288,7 @@ export const wenluSimulation = (agents: Agent[]): SimulationData => {
]
},
{
agent: () => agents[3], // 格式编辑专家
agent: () => wenluAgents[3], // 格式编辑专家
outputs: [
{ type: 'system', content: '>>> [Agent-4] Document Formatting Expert Activated' },
{ type: 'info', content: 'Model: DeepSeek-V2 Chat (Temperature: 0.5)' },
@@ -251,7 +318,7 @@ export const wenluSimulation = (agents: Agent[]): SimulationData => {
]
},
{
agent: () => agents[4], // 活动执行专家
agent: () => wenluAgents[4], // 活动执行专家
outputs: [
{ type: 'system', content: '>>> [Agent-5] Event Execution Expert Activated' },
{ type: 'info', content: 'Model: DeepSeek-V2 Chat (Temperature: 0.6)' },
@@ -291,7 +358,7 @@ export const wenluSimulation = (agents: Agent[]): SimulationData => {
]
},
{
agent: () => agents[5], // 营销宣传专家
agent: () => wenluAgents[5], // 营销宣传专家
outputs: [
{ type: 'system', content: '>>> [Agent-6] Marketing & PR Expert Activated' },
{ type: 'info', content: 'Model: DeepSeek-V2 Chat (Temperature: 0.7)' },
@@ -339,7 +406,7 @@ export const wenluSimulation = (agents: Agent[]): SimulationData => {
]
},
{
agent: () => agents[6], // 会展策划专家(协调者)
agent: () => wenluAgents[6], // 会展策划专家(协调者)
outputs: [
{ type: 'system', content: '>>> [Agent-7] Exhibition Planning Coordinator Activated' },
{ type: 'info', content: 'Model: Chat Models + Memories (Multi-Modal)' },
@@ -401,6 +468,7 @@ export const wenluSimulation = (agents: Agent[]): SimulationData => {
orderClassId: 'wenlu',
orderClassName: '文旅',
projectTitle: '2024长三角国际新能源汽车展会策划案',
agents: wenluAgents,
startupSequence,
agentSequence,
completionSequence

View File

@@ -1,61 +0,0 @@
{
"orderClass": "文旅",
"orderClassId": "wenlu",
"title": "2024长三角国际新能源汽车与智能交通产业博览会",
"templateConfig": {
"id": "wenlu",
"title": "新能源汽车展",
"icon": "Zap",
"content": "展会名称2024长三角国际新能源汽车与智能交通产业博览会\n地点上海国家会展中心\n时间2024年10月18日-20日\n规模50,000平方米预计350家展商50,000人次观众\n主题双碳目标下的新能源汽车产业创新与发展\n特色整车展示、核心零部件、充电设施、智能交通解决方案"
},
"sections": [
{
"title": "展会概览",
"content": [
{
"type": "text",
"text": "2024长三角国际新能源汽车与智能交通产业博览会是长三角地区最具影响力的新能源汽车产业盛会展示最新的电动汽车技术、智能驾驶解决方案和绿色出行理念。"
}
]
},
{
"title": "展会亮点",
"content": [
{
"type": "list",
"items": [
"国内外知名品牌新能源整车展示",
"智能驾驶技术演示与体验",
"充电基础设施完整解决方案",
"产业链上下游对接洽谈会"
]
}
]
},
{
"title": "参展品牌",
"content": [
{
"type": "brands",
"items": ["特斯拉", "比亚迪", "蔚来", "小鹏", "理想", "宝马", "奔驰", "奥迪"]
}
]
}
],
"images": {
"basePath": "../../data/订单班文档资料/文旅/notion文稿/image/",
"list": [
"设计图_01.jpg",
"设计图_02.jpg",
"设计图_03.jpg",
"场景图_01.jpg",
"场景图_02.jpg",
"场景图_03.jpg"
]
},
"metadata": {
"createTime": "2024-09-28",
"updateTime": "2024-09-28",
"status": "completed"
}
}

View File

@@ -1,307 +0,0 @@
import { useState } from 'react';
import { motion } from 'framer-motion';
import {
FileText,
Target,
Megaphone,
Users,
DollarSign,
Shield,
ChevronRight,
Download,
Maximize2,
X
} from 'lucide-react';
interface Section {
id: string;
title: string;
icon: React.ReactNode;
content: {
title: string;
subtitle?: string;
items?: string[];
description?: string;
}[];
}
const ResultPageV2 = () => {
const [activeSection, setActiveSection] = useState('overview');
const [isFullscreen, setIsFullscreen] = useState(false);
const sections: Section[] = [
{
id: 'overview',
title: '策划案概述',
icon: <FileText className="w-4 h-4" />,
content: [
{
title: '展会背景',
description: '在全球碳中和目标推动下,新能源汽车产业迎来前所未有的发展机遇。长三角地区作为中国经济最发达、产业链最完善的区域之一,已成为新能源汽车产业的核心聚集地。'
},
{
title: '展会定位',
description: '打造长三角地区最具影响力的新能源汽车产业交流平台,聚焦"双碳"目标下的产业创新与发展,推动产业链上下游深度合作。'
},
{
title: '核心价值',
items: [
'展示最新技术成果和产品创新',
'促进产业链上下游深度对接',
'推动国际技术交流与合作',
'引领行业发展趋势'
]
}
]
},
{
id: 'exhibition',
title: '展会介绍',
icon: <Target className="w-4 h-4" />,
content: [
{
title: '基本信息',
items: [
'展会名称2024长三角国际新能源汽车与智能交通产业博览会',
'举办时间2024年10月18日-20日',
'举办地点:上海国家会展中心',
'展览面积50,000平方米',
'预计展商350家',
'预计观众50,000人次'
]
},
{
title: '展区规划',
items: [
'A区 - 整车展示区15,000㎡新能源乘用车、商用车展示',
'B区 - 零部件展区10,000㎡电池、电机、电控系统',
'C区 - 充电设施展区8,000㎡充电桩、换电站、储能系统',
'D区 - 智能交通展区12,000㎡自动驾驶、车联网、智慧交通',
'E区 - 论坛会议区5,000㎡主论坛、分论坛、商务洽谈'
]
}
]
},
{
id: 'marketing',
title: '营销方案',
icon: <Megaphone className="w-4 h-4" />,
content: [
{
title: '线上推广',
items: [
'官方网站:建设响应式展会官网,提供在线注册、展位预订功能',
'社交媒体微信、微博、抖音、LinkedIn多平台运营',
'KOL合作邀请行业大V、汽车测评博主参与宣传',
'搜索引擎SEM投放、SEO优化提升展会曝光度'
]
},
{
title: '线下推广',
items: [
'行业展会:参加相关展会进行推介',
'路演活动:在长三角主要城市举办巡回推介会',
'户外广告:高速公路、地铁、机场广告投放',
'定向邀请:精准邀请目标客户群体'
]
},
{
title: '媒体合作',
items: [
'主流媒体:央视、新华社、人民日报等',
'行业媒体:汽车之家、易车网、电车资源网等',
'国际媒体:路透社、彭博社驻华机构'
]
}
]
},
{
id: 'operation',
title: '现场运营',
icon: <Users className="w-4 h-4" />,
content: [
{
title: '人员配置',
items: [
'总指挥中心1名总指挥 + 3名副总指挥',
'展务组20人负责展位管理和现场协调',
'接待组30人负责VIP接待和观众服务',
'安保组50人负责现场安全保障',
'技术组15人负责设备调试和技术支持',
'媒体组10人负责媒体接待和新闻发布'
]
},
{
title: '服务设施',
items: [
'智能导览系统AR导航、展位查询、活动提醒',
'商务配套商务洽谈室、VIP休息室、餐饮服务',
'交通接驳:地铁站、机场、高铁站免费班车',
'停车服务5000个车位新能源车免费充电'
]
}
]
},
{
id: 'budget',
title: '预算分析',
icon: <DollarSign className="w-4 h-4" />,
content: [
{
title: '支出预算',
items: [
'场地租赁300万元',
'展台搭建450万元',
'营销推广120万元',
'人员费用80万元',
'应急储备50万元',
'总计1,000万元'
]
},
{
title: '收入预测',
items: [
'展位销售850万元标准展位500个×1.5万特装100个×10万',
'门票收入150万元专业观众票3万张×50元',
'赞助收入300万元钻石赞助1家、金牌赞助3家、银牌赞助5家',
'总计1,300万元'
]
},
{
title: '盈利分析',
description: '预计净利润300万元投资回报率30%,达到预期收益目标。'
}
]
},
{
id: 'risk',
title: '风险评估',
icon: <Shield className="w-4 h-4" />,
content: [
{
title: '潜在风险',
items: [
'疫情风险:可能导致展会延期或取消',
'市场风险:行业波动影响展商参展意愿',
'竞争风险:同期其他展会分流',
'天气风险:极端天气影响观众出行'
]
},
{
title: '应对措施',
items: [
'制定完善的疫情防控方案,购买展会取消险',
'提前锁定核心展商,签订参展协议',
'差异化定位,突出展会特色优势',
'制定恶劣天气应急预案,提供线上参展选项'
]
}
]
}
];
const currentSection = sections.find(s => s.id === activeSection);
return (
<div className={`${isFullscreen ? 'fixed inset-0 z-50' : 'min-h-screen'} bg-gray-50 flex flex-col`}>
{/* 顶部标题栏 */}
<div className="bg-white border-b border-gray-200 px-6 py-4">
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold text-gray-900">2024 - </h1>
<p className="text-sm text-gray-600 mt-1">AI多Agent协同生成 | 3</p>
</div>
<div className="flex items-center gap-3">
<button className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors flex items-center gap-2">
<Download className="w-4 h-4" />
<span>PDF</span>
</button>
<button
onClick={() => setIsFullscreen(!isFullscreen)}
className="p-2 hover:bg-gray-100 rounded-lg transition-colors"
>
{isFullscreen ? <X className="w-5 h-5" /> : <Maximize2 className="w-5 h-5" />}
</button>
</div>
</div>
</div>
{/* 导航标签 */}
<div className="bg-white border-b border-gray-200">
<div className="flex overflow-x-auto">
{sections.map((section) => (
<button
key={section.id}
onClick={() => setActiveSection(section.id)}
className={`flex items-center gap-2 px-6 py-3 border-b-2 transition-all whitespace-nowrap ${
activeSection === section.id
? 'border-blue-600 text-blue-600 bg-blue-50'
: 'border-transparent text-gray-600 hover:text-gray-900 hover:bg-gray-50'
}`}
>
{section.icon}
<span className="font-medium">{section.title}</span>
</button>
))}
</div>
</div>
{/* 内容区域 */}
<div className="flex-1 overflow-y-auto">
<div className="max-w-5xl mx-auto p-8">
<motion.div
key={activeSection}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3 }}
>
{currentSection?.content.map((block, index) => (
<div key={index} className="mb-8 bg-white rounded-lg shadow-sm border border-gray-200 p-6">
<h2 className="text-xl font-bold text-gray-900 mb-4 flex items-center gap-2">
<ChevronRight className="w-5 h-5 text-blue-600" />
{block.title}
</h2>
{block.subtitle && (
<p className="text-gray-600 mb-4">{block.subtitle}</p>
)}
{block.description && (
<p className="text-gray-700 leading-relaxed">{block.description}</p>
)}
{block.items && (
<ul className="space-y-2">
{block.items.map((item, i) => (
<li key={i} className="flex items-start gap-2">
<span className="text-blue-600 mt-1"></span>
<span className="text-gray-700">{item}</span>
</li>
))}
</ul>
)}
</div>
))}
</motion.div>
</div>
</div>
{/* 底部状态栏 */}
<div className="bg-white border-t border-gray-200 px-6 py-3">
<div className="flex items-center justify-between text-sm text-gray-600">
<div className="flex items-center gap-4">
<span>文档完整度: 100%</span>
<span>总字数: 12,847</span>
<span>生成用时: 2分48秒</span>
</div>
<div className="flex items-center gap-2">
<div className="w-2 h-2 rounded-full bg-green-500"></div>
<span></span>
</div>
</div>
</div>
</div>
);
};
export default ResultPageV2;

View File

@@ -55,6 +55,13 @@ const WorkflowPageV4 = () => {
const intervalRef = useRef<number | null>(null);
const progressLineIdRef = useRef<string | null>(null);
const logoClickTimerRef = useRef<number | null>(null);
const statusRef = useRef(status);
const abortControllerRef = useRef<AbortController | null>(null);
// 更新 statusRef
useEffect(() => {
statusRef.current = status;
}, [status]);
// 启动序列
const startupSequence = [
@@ -568,7 +575,16 @@ const WorkflowPageV4 = () => {
// 进度动画
let progress = 0;
while (progress < 100) {
if (status !== 'running') return;
// 暂停时等待,而不是返回
while (statusRef.current === 'paused') {
await new Promise(resolve => setTimeout(resolve, 100));
}
// 如果是 idle重置或其他状态才真正停止
if (statusRef.current === 'idle' || statusRef.current === 'completed') {
console.log('🛑 Progress animation stopped, status:', statusRef.current);
return;
}
// 检查是否需要卡顿
if (stutters.includes(progress)) {
@@ -592,7 +608,7 @@ const WorkflowPageV4 = () => {
// 完成后清除引用
progressLineIdRef.current = null;
}, [updateProgressLine]);
}, [updateProgressLine, statusRef]);
// 执行启动序列
const executeStartupSequence = useCallback(async () => {
@@ -605,7 +621,16 @@ const WorkflowPageV4 = () => {
console.log(' - using sequence length:', sequence?.length);
for (const line of sequence) {
if (status !== 'running') return;
// 暂停时等待,而不是返回
while (statusRef.current === 'paused') {
await new Promise(resolve => setTimeout(resolve, 100));
}
// 如果是 idle重置或其他状态才真正停止
if (statusRef.current === 'idle' || statusRef.current === 'completed') {
console.log('🛑 Execution stopped, status:', statusRef.current);
return;
}
if (line.type === 'progress') {
// 进度条动画
@@ -621,17 +646,23 @@ const WorkflowPageV4 = () => {
// 开始执行Agent
setCurrentAgentIndex(0);
}, [terminalData, status, addTerminalLine, executeProgress]);
}, [terminalData, statusRef, addTerminalLine, executeProgress]);
// 执行Agent
const executeAgent = useCallback(async (agentIndex: number) => {
// 使用加载的数据或默认数据
const currentTerminalData = terminalData;
const sequence = currentTerminalData?.agents || agentSequence;
const sequence = currentTerminalData?.agentSequence || agentSequence;
if (agentIndex >= sequence.length) {
// 所有Agent执行完成
setIsExecuting(false);
setCurrentAgentIndex(-1); // 重置索引,防止重复执行
// 重要:将 store 状态设置为 completed防止重新执行
const store = useDemoStore.getState();
store.completeDemo(); // 设置状态为 completed
store.setProgress(100); // 设置进度为100%
// 使用加载的完成序列或默认序列
const completionSeq = currentTerminalData?.completionSequence || [
@@ -640,28 +671,33 @@ const WorkflowPageV4 = () => {
{ type: 'system', content: `Total execution time: 3m 00s | Peak memory: 512MB` },
{ type: 'system', content: '=' .repeat(60) }
];
for (const line of completionSeq) {
addTerminalLine(line);
}
// 更新store状态为完成
const store = useDemoStore.getState();
store.setProgress(100);
// 显示结果弹窗
setTimeout(() => {
setShowResultModal(true);
setShowFloatingButton(true);
}, 2000);
return;
}
const agentData = sequence[agentIndex];
for (const output of agentData.outputs) {
if (status !== 'running') return;
// 暂停时等待,而不是返回
while (statusRef.current === 'paused') {
await new Promise(resolve => setTimeout(resolve, 100));
}
// 如果是 idle重置或其他状态才真正停止
if (statusRef.current === 'idle' || statusRef.current === 'completed') {
console.log('🛑 Agent execution stopped, status:', statusRef.current);
return;
}
if (output.type === 'progress') {
// 进度条动画(带卡顿)
@@ -693,7 +729,7 @@ const WorkflowPageV4 = () => {
// 执行下一个Agent
await new Promise(resolve => setTimeout(resolve, 500));
setCurrentAgentIndex(agentIndex + 1);
}, [terminalData, status, addTerminalLine]);
}, [terminalData, statusRef, addTerminalLine]);
// 开始演示
useEffect(() => {
@@ -705,10 +741,10 @@ const WorkflowPageV4 = () => {
// 监听Agent变化
useEffect(() => {
if (status === 'running' && currentAgentIndex >= 0) {
if (status === 'running' && currentAgentIndex >= 0 && isExecuting) {
executeAgent(currentAgentIndex);
}
}, [currentAgentIndex, executeAgent, status]);
}, [currentAgentIndex, executeAgent, status, isExecuting]);
// 计时器
useEffect(() => {
@@ -724,7 +760,10 @@ const WorkflowPageV4 = () => {
// 加载终端数据 - 使用新的TSX模拟系统
const loadTerminalData = async (orderClassId: string) => {
console.log('🔍 loadTerminalData called with:', orderClassId);
console.log('🔍 Current agents:', agents);
// 获取最新的 agents 状态
const currentAgents = useDemoStore.getState().agents;
console.log('🔍 Current agents from store:', currentAgents);
setLoadingData(true);
setDataLoadError(null);
@@ -735,7 +774,7 @@ const WorkflowPageV4 = () => {
const { getSimulationData } = await import('@/data/terminalSimulations');
console.log('🔍 getSimulationData imported successfully');
const simulationData = getSimulationData(orderClassId, agents);
const simulationData = getSimulationData(orderClassId);
console.log('🔍 simulationData result:', simulationData);
if (!simulationData) {
@@ -754,7 +793,8 @@ const WorkflowPageV4 = () => {
const terminalData = {
startupSequence: simulationData.startupSequence,
agents: simulationData.agentSequence.map((seq, index) => {
agents: simulationData.agents, // 直接使用agents数组
agentSequence: simulationData.agentSequence.map((seq, index) => {
const agent = seq.agent();
console.log(` - Agent ${index}:`, agent?.name || 'undefined');
return {
@@ -790,6 +830,12 @@ const WorkflowPageV4 = () => {
setSelectedOrderClass(orderClass);
setShowRequirementModal(false);
// 先加载对应订单班的 Agent 专家
useDemoStore.getState().loadOrderClassAgents(orderClass);
// 等待状态更新完成
await new Promise(resolve => setTimeout(resolve, 100));
// 加载对应订单班的数据
console.log('🔄 Loading terminal data for order class:', orderClass);
const dataLoaded = await loadTerminalData(orderClass);
@@ -811,32 +857,59 @@ const WorkflowPageV4 = () => {
}
};
// 获取项目信息
const getProjectInfo = () => {
const simulationData = currentTerminalData || getSimulationData(selectedOrderClass || 'wenlu');
// 根据订单班返回不同的描述
const projectSubtitles: Record<string, string> = {
wenlu: '包含完整的市场分析、设计方案、预算规划、执行计划、营销策略等内容',
food: '包含市场调研、品牌设计、运营规划、财务预测、营销推广等完整方案',
// 可以添加更多订单班的描述
};
return {
projectTitle: simulationData?.projectTitle || '项目方案',
projectSubtitle: projectSubtitles[selectedOrderClass || ''] || '包含完整的分析、设计、预算、执行计划等内容',
orderClassName: simulationData?.orderClassName || '订单班'
};
};
// 处理查看详情
const handleViewDetails = () => {
setShowResultModal(false);
// 导航到对应订单班的结果页面
// 不关闭弹窗,让用户可以继续查看
// setShowResultModal(false);
// 在新标签页中打开,而不是当前页面跳转
const baseUrl = 'http://localhost:4155'; // 假设 web_result 运行在 4155 端口
if (selectedOrderClass) {
window.location.href = `/web_result/index.html?orderClass=${selectedOrderClass}`;
window.open(`${baseUrl}/index.html?orderClass=${selectedOrderClass}`, '_blank');
} else {
// 默认跳转到文旅
window.location.href = '/web_result/index.html?orderClass=tourism';
window.open(`${baseUrl}/index.html?orderClass=tourism`, '_blank');
}
};
// 重置
const handleReset = () => {
console.log('🔄 Reset button clicked');
reset();
setTerminalLines([]);
setCurrentAgentIndex(-1);
setElapsedTime(0);
setIsExecuting(false);
setUserRequirement('');
setSelectedOrderClass('');
setTerminalData(null); // 清除加载的数据
setShowResultModal(false);
setShowFloatingButton(false);
console.log('✅ Reset completed');
// 立即停止所有执行
reset(); // 这会将 status 设置为 'idle'
// 等待一下让 statusRef 更新
setTimeout(() => {
setTerminalLines([]);
setCurrentAgentIndex(-1);
setElapsedTime(0);
setIsExecuting(false);
setUserRequirement('');
setSelectedOrderClass('');
setTerminalData(null); // 清除加载的数据
setShowResultModal(false);
setShowFloatingButton(false);
console.log('✅ Reset completed');
}, 100);
};
// Logo三击处理
@@ -1207,6 +1280,7 @@ const WorkflowPageV4 = () => {
isOpen={showResultModal}
onClose={() => setShowResultModal(false)}
onViewDetails={handleViewDetails}
{...getProjectInfo()}
/>
{/* 右下角浮动按钮 - 只在完成后显示 */}

View File

@@ -1,4 +1,6 @@
import { create } from 'zustand';
import { foodAgents } from '../data/agents/foodAgents';
import { wenluAgents } from '../data/agents/wenluAgents';
export interface Agent {
id: string;
@@ -47,78 +49,18 @@ export interface DemoState {
resumeDemo: () => void;
setCurrentAgent: (agentId: string) => void;
setSelectedOrderClass: (orderClass: string) => void;
loadOrderClassAgents: (orderClass: string) => void;
updateAgentStatus: (agentId: string, status: Agent['status']) => void;
updateAgentOutput: (agentId: string, output: string) => void;
addGeneratedContent: (section: string, content: any) => void;
setProgress: (progress: number) => void;
completeDemo: () => void;
reset: () => void;
}
const initialAgents: Agent[] = [
{
id: 'retrieval',
name: '信息检索专家',
icon: '🔍',
avatar: '/agents/信息检索专家.jpg',
model: 'DeepSeek Chat Model5',
role: '市场调研、数据收集、竞品分析',
status: 'waiting',
},
{
id: 'design',
name: '设计专家',
icon: '🎨',
avatar: '/agents/设计专家.jpg',
model: 'Google Gemini Chat Model2',
role: '视觉设计、空间布局、品牌形象',
status: 'waiting',
},
{
id: 'budget',
name: '财务预算专家',
icon: '💰',
avatar: '/agents/预算编辑专家.jpg',
model: 'DeepSeek Chat Model2',
role: '成本核算、预算规划、ROI分析',
status: 'waiting',
},
{
id: 'format',
name: '格式编辑专家',
icon: '📝',
avatar: '/agents/结构编辑专家.jpg',
model: 'DeepSeek Chat Model4',
role: '文档格式化、内容结构优化',
status: 'waiting',
},
{
id: 'execution',
name: '活动执行专家',
icon: '⚡',
avatar: '/agents/会展执行专家.jpg',
model: 'DeepSeek Chat Model1',
role: '执行计划、时间线管理、任务分配',
status: 'waiting',
},
{
id: 'marketing',
name: '营销宣传专家',
icon: '📢',
avatar: '/agents/营销策划专家.jpg',
model: 'DeepSeek Chat Model3',
role: '推广策略、媒体规划、品牌传播',
status: 'waiting',
},
{
id: 'coordinator',
name: '会展策划专家',
icon: '🎯',
avatar: '/agents/会展策划专家.jpg',
model: 'Chat Models + Memories',
role: '中央协调、方案整合、决策支持',
status: 'waiting',
},
];
// 默认agents已移除 - 每个订单班有自己的Agent配置
// 参见 src/data/terminalSimulations/[orderClass].ts
const initialAgents: Agent[] = [];
export const useDemoStore = create<DemoState>((set) => ({
status: 'idle',
@@ -142,6 +84,43 @@ export const useDemoStore = create<DemoState>((set) => ({
setSelectedOrderClass: (orderClass) => set({ selectedOrderClass: orderClass }),
loadOrderClassAgents: (orderClass) => {
let newAgents: Agent[] = [];
switch(orderClass) {
case 'food':
newAgents = foodAgents.map(agent => ({
id: agent.id,
name: agent.name,
icon: agent.icon,
avatar: agent.avatar,
model: `DeepSeek Chat Model${Math.floor(Math.random() * 5) + 1}`,
role: agent.role,
status: 'waiting' as const,
}));
break;
case 'wenlu':
newAgents = wenluAgents.map(agent => ({
id: agent.id,
name: agent.name,
icon: agent.icon,
avatar: agent.avatar,
model: `DeepSeek Chat Model${Math.floor(Math.random() * 5) + 1}`,
role: agent.role,
status: 'waiting' as const,
}));
break;
default:
// 使用默认的 initialAgents
newAgents = initialAgents;
break;
}
set({ agents: newAgents });
},
updateAgentStatus: (agentId, status) =>
set((state) => ({
agents: state.agents.map((agent) =>
@@ -166,6 +145,8 @@ export const useDemoStore = create<DemoState>((set) => ({
setProgress: (progress) => set({ progress }),
completeDemo: () => set({ status: 'completed' }),
reset: () =>
set({
status: 'idle',