Files
Agent-n8n/web_frontend/web_result/app.js
Yep_Q 0d96ffd429 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>
2025-09-29 20:12:57 +08:00

273 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const express = require('express');
const path = require('path');
const fs = require('fs');
const yaml = require('js-yaml');
// 加载路由配置
function loadRoutes() {
try {
const fileContents = fs.readFileSync('routes.yaml', 'utf8');
return yaml.load(fileContents);
} catch (e) {
console.error('加载路由配置失败:', e);
process.exit(1);
}
}
const config = loadRoutes();
const app = express();
const PORT = config.server.port || 4155;
// 静态文件服务
app.use('/css', express.static('css'));
app.use('/js', express.static('js'));
app.use('/data', express.static('data'));
app.use('/order-classes', express.static('order-classes'));
// 日志中间件
app.use((req, res, next) => {
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
next();
});
// 主路由 - 显示订单班选择页面
app.get('/', (req, res) => {
const orderClass = req.query.class;
if (orderClass) {
// 如果指定了订单班,重定向到对应路由
res.redirect(`/order-class/${orderClass}`);
} else {
// 显示选择页面
res.send(generateIndexPage());
}
});
// 订单班路由
app.get('/order-class/:className', (req, res) => {
const className = req.params.className;
const classConfig = config.order_classes[className];
if (!classConfig) {
res.status(404).send(generate404Page(className));
return;
}
// 如果订单班已完成,返回其页面
if (classConfig.status === 'completed') {
const filePath = path.join(__dirname, classConfig.path, classConfig.entry);
if (fs.existsSync(filePath)) {
// 读取文件并修改相对路径
let html = fs.readFileSync(filePath, 'utf8');
// 修正资源路径
html = html.replace(/href="css\//g, 'href="/css/');
html = html.replace(/src="js\//g, 'src="/js/');
html = html.replace(/href="pages\//g, `href="${classConfig.path}`);
html = html.replace(/src="\/data\//g, 'src="/data/');
html = html.replace(/href="\/pages\//g, `href="${classConfig.path}`);
res.send(html);
} else {
res.send(generateComingSoonPage(classConfig));
}
} else {
res.send(generateComingSoonPage(classConfig));
}
});
// 处理订单班内部页面如文旅的overview.html等
app.get('/order-classes/:className/:page', (req, res) => {
const { className, page } = req.params;
const filePath = path.join(__dirname, 'order-classes', className, page);
if (fs.existsSync(filePath)) {
let html = fs.readFileSync(filePath, 'utf8');
// 修正资源路径
html = html.replace(/href="\.\.\/css\//g, 'href="/css/');
html = html.replace(/src="\.\.\/js\//g, 'src="/js/');
html = html.replace(/src="\/data\//g, 'src="/data/');
res.send(html);
} else {
res.status(404).send(generate404Page(`${className}/${page}`));
}
});
// 生成首页(选择页面)
function generateIndexPage() {
const orderClasses = Object.entries(config.order_classes);
const completedClasses = orderClasses.filter(([_, c]) => c.status === 'completed');
const pendingClasses = orderClasses.filter(([_, c]) => c.status === 'pending');
return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>订单班AI生成方案展示系统</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
body { font-family: 'Inter', 'Noto Sans SC', sans-serif; }
.order-card {
transition: all 0.3s ease;
cursor: pointer;
}
.order-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0,0,0,0.15);
}
.gradient-bg {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
</style>
</head>
<body class="bg-gray-50">
<div class="gradient-bg text-white py-12">
<div class="container mx-auto px-4 text-center">
<h1 class="text-4xl font-bold mb-4">订单班AI生成方案展示系统</h1>
<p class="text-xl opacity-90">基于多Agent协作的智能方案生成平台</p>
</div>
</div>
<div class="container mx-auto px-4 py-12">
<h2 class="text-2xl font-bold mb-6">已完成的订单班方案</h2>
<div class="grid md:grid-cols-3 lg:grid-cols-4 gap-6 mb-12">
${completedClasses.map(([key, config]) => `
<div class="order-card bg-white rounded-lg p-6 shadow-md" onclick="location.href='/order-class/${key}'">
<div class="text-3xl mb-3">${getClassIcon(key)}</div>
<h3 class="font-bold text-lg mb-2">${config.name}</h3>
<p class="text-sm text-gray-600 mb-3">${config.description}</p>
<div class="text-sm text-gray-500">
<i class="fas fa-users"></i> ${config.agents.length || 0} 位AI专家
</div>
<div class="mt-4 text-blue-600 font-semibold">
查看方案 <i class="fas fa-arrow-right"></i>
</div>
</div>
`).join('')}
</div>
<h2 class="text-2xl font-bold mb-6 text-gray-500">即将推出</h2>
<div class="grid md:grid-cols-3 lg:grid-cols-4 gap-6">
${pendingClasses.map(([key, config]) => `
<div class="bg-gray-100 rounded-lg p-6 opacity-60">
<div class="text-3xl mb-3 text-gray-400">${getClassIcon(key)}</div>
<h3 class="font-bold text-lg mb-2 text-gray-500">${config.name}</h3>
<p class="text-sm text-gray-400">${config.description}</p>
<div class="mt-4 text-gray-400">
开发中...
</div>
</div>
`).join('')}
</div>
</div>
<script>
// 可以添加一些交互效果
</script>
</body>
</html>`;
}
// 生成404页面
function generate404Page(resource) {
return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面未找到</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 flex items-center justify-center min-h-screen">
<div class="text-center">
<h1 class="text-6xl font-bold text-gray-300 mb-4">404</h1>
<p class="text-xl text-gray-600 mb-2">页面未找到</p>
<p class="text-gray-500 mb-6">资源 "${resource}" 不存在</p>
<a href="/" class="bg-blue-600 text-white px-6 py-3 rounded-lg hover:bg-blue-700">
返回首页
</a>
</div>
</body>
</html>`;
}
// 生成即将推出页面
function generateComingSoonPage(classConfig) {
return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${classConfig.name} - 即将推出</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gradient-to-br from-purple-600 to-blue-600 text-white min-h-screen flex items-center justify-center">
<div class="text-center">
<div class="text-6xl mb-6">${getClassIcon(classConfig.name)}</div>
<h1 class="text-4xl font-bold mb-4">${classConfig.name}</h1>
<p class="text-xl mb-2">${classConfig.title}</p>
<p class="opacity-80 mb-8">${classConfig.description}</p>
<div class="bg-white/20 backdrop-blur rounded-lg p-6 max-w-md mx-auto">
<p class="text-lg font-semibold mb-2">🚀 正在开发中</p>
<p>我们的AI专家团队正在为您准备专业的解决方案</p>
</div>
<a href="/" class="mt-8 inline-block bg-white text-purple-600 px-6 py-3 rounded-lg hover:bg-gray-100">
返回首页
</a>
</div>
</body>
</html>`;
}
// 获取订单班图标
function getClassIcon(key) {
const icons = {
'wenlu': '🚗',
'food': '🍽️',
'caijing': '💰',
'jiankang': '🏥',
'huagong': '⚗️',
'huanbao': '🌱',
'jiaotong': '🚚',
'nengyuan': '⚡',
'shijue': '🎨',
'tumu': '🏗️',
'zhineng-dev': '💻',
'zhineng-mfg': '🏭'
};
return icons[key] || '📦';
}
// 启动服务器
app.listen(PORT, () => {
console.log(`
╔═══════════════════════════════════════════════════════╗
║ 订单班AI生成方案展示系统 - 服务器已启动 ║
╠═══════════════════════════════════════════════════════╣
║ ║
║ 访问地址: ║
║ • http://localhost:${PORT}
║ ║
║ 路由示例: ║
║ • 首页: http://localhost:${PORT}/ ║
║ • 文旅: http://localhost:${PORT}/order-class/wenlu ║
║ • 食品: http://localhost:${PORT}/order-class/food ║
║ ║
║ 快捷访问: ║
║ • http://localhost:${PORT}/?class=wenlu ║
║ • http://localhost:${PORT}/?class=food ║
║ ║
╚═══════════════════════════════════════════════════════╝
`);
});
// 优雅关闭
process.on('SIGINT', () => {
console.log('\n正在关闭服务器...');
process.exit(0);
});