Add files via upload

This commit is contained in:
公明
2026-02-08 20:46:51 +08:00
committed by GitHub
parent 9a52ec25ea
commit 0d617ebd66
3 changed files with 121 additions and 3 deletions
+41
View File
@@ -8072,6 +8072,47 @@ header {
border: 1px solid rgba(0,0,0,0.05);
}
.dashboard-section-overview {
background: var(--bg-primary);
border-radius: 16px;
padding: 22px 24px;
box-shadow: 0 2px 12px rgba(0,0,0,0.04);
border: 1px solid rgba(0,0,0,0.05);
}
.dashboard-overview-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 16px;
}
.dashboard-overview-item {
padding: 14px 18px;
background: var(--bg-secondary);
border-radius: 12px;
border: 1px solid var(--border-color);
cursor: pointer;
transition: border-color 0.2s, background 0.2s;
}
.dashboard-overview-item:hover {
border-color: var(--accent-color);
background: rgba(0, 102, 255, 0.04);
}
.dashboard-overview-label {
display: block;
font-size: 0.8rem;
font-weight: 600;
color: var(--text-secondary);
margin-bottom: 6px;
}
.dashboard-overview-value {
font-size: 0.9rem;
color: var(--text-primary);
}
.dashboard-section-title {
display: flex;
align-items: center;
+63 -3
View File
@@ -1,4 +1,4 @@
// 仪表盘页面:拉取运行中任务、漏洞统计并渲染
// 仪表盘页面:拉取运行中任务、漏洞统计、批量任务、工具与 Skills 统计并渲染
async function refreshDashboard() {
const runningEl = document.getElementById('dashboard-running-tasks');
@@ -13,17 +13,22 @@ async function refreshDashboard() {
const barEl = document.getElementById('dashboard-bar-' + s);
if (barEl) barEl.style.width = '0%';
});
setDashboardOverviewPlaceholder('…');
if (typeof apiFetch === 'undefined') {
if (runningEl) runningEl.textContent = '-';
if (vulnTotalEl) vulnTotalEl.textContent = '-';
setDashboardOverviewPlaceholder('-');
return;
}
try {
const [tasksRes, vulnRes] = await Promise.all([
const [tasksRes, vulnRes, batchRes, monitorRes, skillsRes] = await Promise.all([
apiFetch('/api/agent-loop/tasks').then(r => r.ok ? r.json() : null).catch(() => null),
apiFetch('/api/vulnerabilities/stats').then(r => r.ok ? r.json() : null).catch(() => null)
apiFetch('/api/vulnerabilities/stats').then(r => r.ok ? r.json() : null).catch(() => null),
apiFetch('/api/batch-tasks?limit=500&page=1').then(r => r.ok ? r.json() : null).catch(() => null),
apiFetch('/api/monitor/stats').then(r => r.ok ? r.json() : null).catch(() => null),
apiFetch('/api/skills/stats').then(r => r.ok ? r.json() : null).catch(() => null)
]);
if (tasksRes && Array.isArray(tasksRes.tasks)) {
@@ -50,9 +55,64 @@ async function refreshDashboard() {
if (barEl) barEl.style.width = '0%';
});
}
// 批量任务队列:按状态统计
if (batchRes && Array.isArray(batchRes.queues)) {
const queues = batchRes.queues;
let pending = 0, running = 0, done = 0;
queues.forEach(q => {
const s = (q.status || '').toLowerCase();
if (s === 'pending' || s === 'paused') pending++;
else if (s === 'running') running++;
else if (s === 'completed' || s === 'cancelled') done++;
});
setEl('dashboard-batch-pending', String(pending));
setEl('dashboard-batch-running', String(running));
setEl('dashboard-batch-done', String(done));
} else {
setEl('dashboard-batch-pending', '-');
setEl('dashboard-batch-running', '-');
setEl('dashboard-batch-done', '-');
}
// 工具调用:monitor/stats 为 { toolName: { TotalCalls, ... } }
if (monitorRes && typeof monitorRes === 'object') {
const names = Object.keys(monitorRes);
let totalCalls = 0;
names.forEach(k => {
const v = monitorRes[k];
const n = v && (v.totalCalls ?? v.TotalCalls);
if (typeof n === 'number') totalCalls += n;
});
setEl('dashboard-tools-count', String(names.length));
setEl('dashboard-tools-calls', String(totalCalls));
} else {
setEl('dashboard-tools-count', '-');
setEl('dashboard-tools-calls', '-');
}
// Skills{ total_skills, total_calls, ... }
if (skillsRes && typeof skillsRes === 'object') {
setEl('dashboard-skills-count', String(skillsRes.total_skills ?? '-'));
setEl('dashboard-skills-calls', String(skillsRes.total_calls ?? '-'));
} else {
setEl('dashboard-skills-count', '-');
setEl('dashboard-skills-calls', '-');
}
} catch (e) {
console.warn('仪表盘拉取统计失败', e);
if (runningEl) runningEl.textContent = '-';
if (vulnTotalEl) vulnTotalEl.textContent = '-';
setDashboardOverviewPlaceholder('-');
}
}
function setEl(id, text) {
const el = document.getElementById(id);
if (el) el.textContent = text;
}
function setDashboardOverviewPlaceholder(t) {
['dashboard-batch-pending', 'dashboard-batch-running', 'dashboard-batch-done',
'dashboard-tools-count', 'dashboard-tools-calls', 'dashboard-skills-count', 'dashboard-skills-calls'].forEach(id => setEl(id, t));
}
+17
View File
@@ -267,6 +267,23 @@
</div>
</div>
</div>
<div class="dashboard-section dashboard-section-overview">
<h3 class="dashboard-section-title"><span class="dashboard-section-dot"></span>运行概览</h3>
<div class="dashboard-overview-grid">
<div class="dashboard-overview-item" onclick="switchPage('tasks')">
<span class="dashboard-overview-label">批量任务队列</span>
<span class="dashboard-overview-value"><span id="dashboard-batch-pending">-</span> 待执行 / <span id="dashboard-batch-running">-</span> 执行中 / <span id="dashboard-batch-done">-</span> 已完成</span>
</div>
<div class="dashboard-overview-item" onclick="switchPage('mcp-monitor')">
<span class="dashboard-overview-label">工具调用</span>
<span class="dashboard-overview-value"><span id="dashboard-tools-count">-</span> 个工具,共 <span id="dashboard-tools-calls">-</span> 次调用</span>
</div>
<div class="dashboard-overview-item" onclick="switchPage('skills-monitor')">
<span class="dashboard-overview-label">Skills</span>
<span class="dashboard-overview-value"><span id="dashboard-skills-count">-</span> 个 Skill,共 <span id="dashboard-skills-calls">-</span> 次调用</span>
</div>
</div>
</div>
<div class="dashboard-section">
<h3 class="dashboard-section-title"><span class="dashboard-section-dot"></span>快捷入口</h3>
<div class="dashboard-quick-links">