mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-05-15 21:08:01 +02:00
Add files via upload
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user