feat: add admin operations war room

This commit is contained in:
boos
2026-06-06 21:50:23 +08:00
parent f7916a42e5
commit 3b3292b934
2 changed files with 269 additions and 0 deletions
+106
View File
@@ -547,6 +547,72 @@ export default function Dashboard({
const latency = site.averageLatencyMs ?? 0;
return availability < 99 || latency > 1800 || site.failedCount > 0;
}).length;
const riskySites = activeSites
.filter((site) => {
const availability = site.availabilityPercent ?? 100;
const latency = site.averageLatencyMs ?? 0;
return availability < 99 || latency > 1800 || site.failedCount > 0;
})
.sort((a, b) => {
const aScore =
(100 - (a.availabilityPercent ?? 100)) * 100 +
(a.failedCount || 0) * 8 +
Math.max(0, (a.averageLatencyMs || 0) - 1200) / 10;
const bScore =
(100 - (b.availabilityPercent ?? 100)) * 100 +
(b.failedCount || 0) * 8 +
Math.max(0, (b.averageLatencyMs || 0) - 1200) / 10;
return bScore - aScore;
})
.slice(0, 3);
const overallHealthTone =
proxySuccessRate >= 99 && siteRiskCount === 0
? "success"
: proxySuccessRate >= 95 && siteRiskCount <= 2
? "warning"
: "danger";
const overallHealthLabel =
overallHealthTone === "success"
? "稳定"
: overallHealthTone === "warning"
? "需关注"
: "异常";
const spendTone =
todaySpend <= todayReward
? "success"
: todaySpend <= Math.max(1, todayReward * 2)
? "warning"
: "danger";
const throughputLabel =
requestsPerMinute > 0
? `${Math.round(requestsPerMinute).toLocaleString()} RPM`
: "暂无流量";
const operationsPulse = [
{
label: "整体状态",
value: overallHealthLabel,
note: `${proxySuccessRate.toFixed(1)}% 成功率`,
tone: overallHealthTone,
},
{
label: "站点风险",
value: `${siteRiskCount}`,
note: `${activeSites.length}/${rawSiteAvailability.length} 活跃站点`,
tone: siteRiskCount > 0 ? "warning" : "success",
},
{
label: "今日成本",
value: `$${todaySpend.toFixed(2)}`,
note: `奖励 $${todayReward.toFixed(2)}`,
tone: spendTone,
},
{
label: "当前吞吐",
value: throughputLabel,
note: `${formatCompactTokenMetric(tokensPerMinute)} TPM`,
tone: requestsPerMinute > 0 ? "primary" : "muted",
},
];
const dashboardCommandLinks = [
{
to: "/routes",
@@ -681,6 +747,46 @@ export default function Dashboard({
</div>
</section>
<section className="dashboard-war-room" aria-label="运营战情室">
<div className="dashboard-pulse-grid">
{operationsPulse.map((item) => (
<div className="dashboard-pulse-card" data-tone={item.tone} key={item.label}>
<span>{item.label}</span>
<strong>{item.value}</strong>
<em>{item.note}</em>
</div>
))}
</div>
<div className="dashboard-risk-panel">
<div className="dashboard-risk-head">
<div>
<span>风险雷达</span>
<strong>{riskySites.length > 0 ? "优先检查这些站点" : "暂无明显站点风险"}</strong>
</div>
<Link to="/sites" className="btn btn-ghost">站点管理</Link>
</div>
{riskySites.length > 0 ? (
<div className="dashboard-risk-list">
{riskySites.map((site) => (
<Link
key={site.siteId}
to={buildSiteLast24hLogsRoute(site.siteId)}
className="dashboard-risk-row"
>
<strong>{site.siteName}</strong>
<span>{formatAvailabilityPercent(site.availabilityPercent)}</span>
<em>{site.averageLatencyMs != null ? `${site.averageLatencyMs}ms` : "暂无延迟"}</em>
</Link>
))}
</div>
) : (
<div className="dashboard-risk-empty">
站点可用性、平均延迟和失败数都处于可接受范围。
</div>
)}
</div>
</section>
<nav className="dashboard-command-strip" aria-label="运营快捷入口">
{dashboardCommandLinks.map((item) => (
<Link