Files
task-board/public/index.html
T
work-1 da6ff6a51b 初始提交:多智能体任务管理系统
- 完整的 RESTful API(智能体注册、任务管理)
- Web 管理界面(实时统计、任务列表)
- SQLite 数据库存储
- Python 客户端示例
- 完整的 API 文档
2026-02-15 13:41:49 +08:00

460 lines
12 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多智能体任务管理系统</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1400px;
margin: 0 auto;
}
header {
text-align: center;
color: white;
margin-bottom: 30px;
}
h1 {
font-size: 2.5em;
margin-bottom: 10px;
}
.stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
margin-bottom: 30px;
}
.stat-card {
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
text-align: center;
}
.stat-card h3 {
color: #666;
font-size: 0.9em;
margin-bottom: 10px;
}
.stat-card .number {
font-size: 2em;
font-weight: bold;
color: #667eea;
}
.main-content {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 20px;
}
.panel {
background: white;
border-radius: 10px;
padding: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.panel h2 {
color: #333;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid #667eea;
}
.agent-item, .task-item {
padding: 15px;
margin-bottom: 10px;
border-radius: 8px;
background: #f8f9fa;
border-left: 4px solid #667eea;
}
.agent-item.busy {
border-left-color: #f39c12;
background: #fff9e6;
}
.agent-item.offline {
border-left-color: #95a5a6;
background: #ecf0f1;
}
.task-item.pending {
border-left-color: #3498db;
}
.task-item.in_progress {
border-left-color: #f39c12;
background: #fff9e6;
}
.task-item.completed {
border-left-color: #27ae60;
background: #e8f8f5;
}
.badge {
display: inline-block;
padding: 4px 12px;
border-radius: 20px;
font-size: 0.85em;
font-weight: bold;
margin-left: 10px;
}
.badge.idle {
background: #3498db;
color: white;
}
.badge.busy {
background: #f39c12;
color: white;
}
.badge.pending {
background: #3498db;
color: white;
}
.badge.in_progress {
background: #f39c12;
color: white;
}
.badge.completed {
background: #27ae60;
color: white;
}
.badge.high {
background: #e74c3c;
color: white;
}
.badge.normal {
background: #3498db;
color: white;
}
.badge.low {
background: #95a5a6;
color: white;
}
button {
padding: 10px 20px;
border: none;
border-radius: 5px;
background: #667eea;
color: white;
font-weight: bold;
cursor: pointer;
transition: all 0.3s;
}
button:hover {
background: #764ba2;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
color: #333;
font-weight: bold;
}
.form-group input, .form-group textarea, .form-group select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 1em;
}
.form-group textarea {
resize: vertical;
min-height: 80px;
}
.task-meta {
font-size: 0.85em;
color: #666;
margin-top: 8px;
}
.empty-state {
text-align: center;
color: #999;
padding: 40px;
}
#createTaskForm {
margin-top: 20px;
}
.refresh-btn {
float: right;
padding: 5px 15px;
font-size: 0.9em;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>🤖 多智能体任务管理系统</h1>
<p>Multi-Agent Task Management System</p>
</header>
<div class="stats" id="stats">
<!-- 统计数据将动态加载 -->
</div>
<div class="main-content">
<div class="panel">
<h2>
智能体列表
<button class="refresh-btn" onclick="loadAgents()">刷新</button>
</h2>
<div id="agentList">
<div class="empty-state">加载中...</div>
</div>
</div>
<div class="panel">
<h2>
任务列表
<button class="refresh-btn" onclick="loadTasks()">刷新</button>
</h2>
<div id="taskList">
<div class="empty-state">加载中...</div>
</div>
<form id="createTaskForm">
<h3 style="margin-top: 30px; margin-bottom: 15px;">创建新任务</h3>
<div class="form-group">
<label>任务标题 *</label>
<input type="text" id="taskTitle" required placeholder="输入任务标题">
</div>
<div class="form-group">
<label>任务描述</label>
<textarea id="taskDescription" placeholder="详细描述任务内容"></textarea>
</div>
<div class="form-group">
<label>优先级</label>
<select id="taskPriority">
<option value="low"></option>
<option value="normal" selected>普通</option>
<option value="high"></option>
</select>
</div>
<button type="submit">创建任务</button>
</form>
</div>
</div>
</div>
<script>
const API_BASE = '';
// 加载统计数据
async function loadStats() {
try {
const response = await fetch(`${API_BASE}/api/stats`);
const stats = await response.json();
document.getElementById('stats').innerHTML = `
<div class="stat-card">
<h3>智能体总数</h3>
<div class="number">${stats.total_agents || 0}</div>
</div>
<div class="stat-card">
<h3>活跃智能体</h3>
<div class="number">${stats.active_agents || 0}</div>
</div>
<div class="stat-card">
<h3>待处理任务</h3>
<div class="number">${stats.pending_tasks || 0}</div>
</div>
<div class="stat-card">
<h3>进行中任务</h3>
<div class="number">${stats.in_progress_tasks || 0}</div>
</div>
<div class="stat-card">
<h3>已完成任务</h3>
<div class="number">${stats.completed_tasks || 0}</div>
</div>
<div class="stat-card">
<h3>任务总数</h3>
<div class="number">${stats.total_tasks || 0}</div>
</div>
`;
} catch (error) {
console.error('加载统计数据失败:', error);
}
}
// 加载智能体列表
async function loadAgents() {
try {
const response = await fetch(`${API_BASE}/api/agents`);
const agents = await response.json();
const agentList = document.getElementById('agentList');
if (agents.length === 0) {
agentList.innerHTML = '<div class="empty-state">暂无智能体注册</div>';
return;
}
agentList.innerHTML = agents.map(agent => {
const statusClass = agent.status === 'busy' ? 'busy' : 'idle';
const lastHeartbeat = new Date(agent.last_heartbeat).toLocaleString('zh-CN');
return `
<div class="agent-item ${statusClass}">
<strong>${agent.name}</strong>
<span class="badge ${agent.status}">${agent.status === 'idle' ? '空闲' : '忙碌'}</span>
<div class="task-meta">
类型: ${agent.type || '通用'} |
注册时间: ${new Date(agent.registered_at).toLocaleString('zh-CN')} |
最后心跳: ${lastHeartbeat}
</div>
</div>
`;
}).join('');
} catch (error) {
console.error('加载智能体列表失败:', error);
document.getElementById('agentList').innerHTML =
'<div class="empty-state">加载失败</div>';
}
}
// 加载任务列表
async function loadTasks() {
try {
const response = await fetch(`${API_BASE}/api/tasks`);
const tasks = await response.json();
const taskList = document.getElementById('taskList');
if (tasks.length === 0) {
taskList.innerHTML = '<div class="empty-state">暂无任务</div>';
return;
}
taskList.innerHTML = tasks.map(task => {
const statusText = {
'pending': '待处理',
'in_progress': '进行中',
'completed': '已完成'
}[task.status] || task.status;
const priorityText = {
'low': '低',
'normal': '普通',
'high': '高'
}[task.priority] || task.priority;
return `
<div class="task-item ${task.status}">
<strong>${task.title}</strong>
<span class="badge ${task.status}">${statusText}</span>
<span class="badge ${task.priority}">${priorityText}</span>
${task.description ? `<div style="margin-top: 8px; color: #666;">${task.description}</div>` : ''}
<div class="task-meta">
创建时间: ${new Date(task.created_at).toLocaleString('zh-CN')} |
${task.assigned_to ? `执行者: ${task.assigned_to}` : '未分配'} |
${task.completed_at ? `完成时间: ${new Date(task.completed_at).toLocaleString('zh-CN')}` : ''}
</div>
${task.result ? `<div style="margin-top: 8px; padding: 8px; background: #e8f4f8; border-radius: 4px;"><strong>结果:</strong> ${task.result}</div>` : ''}
</div>
`;
}).join('');
} catch (error) {
console.error('加载任务列表失败:', error);
document.getElementById('taskList').innerHTML =
'<div class="empty-state">加载失败</div>';
}
}
// 创建任务表单提交
document.getElementById('createTaskForm').addEventListener('submit', async (e) => {
e.preventDefault();
const title = document.getElementById('taskTitle').value;
const description = document.getElementById('taskDescription').value;
const priority = document.getElementById('taskPriority').value;
try {
const response = await fetch(`${API_BASE}/api/tasks`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
title,
description,
priority,
created_by: 'human'
})
});
const result = await response.json();
if (response.ok) {
alert('✅ 任务创建成功!');
document.getElementById('createTaskForm').reset();
loadTasks();
loadStats();
} else {
alert('❌ 创建失败: ' + result.error);
}
} catch (error) {
alert('❌ 创建失败: ' + error.message);
}
});
// 初始加载
loadStats();
loadAgents();
loadTasks();
// 自动刷新(每10秒)
setInterval(() => {
loadStats();
loadAgents();
loadTasks();
}, 10000);
</script>
</body>
</html>