feat: monitor page redesign and node card cleanup (#340)

This commit is contained in:
sagit
2026-03-18 18:57:23 +08:00
committed by GitHub
parent 7134253b2c
commit 555039e028
4 changed files with 172 additions and 358 deletions
-247
View File
@@ -683,15 +683,7 @@ export default function NodePage() {
};
// 格式化流量
const formatTraffic = (bytes: number): string => {
if (bytes === 0) return "0 B";
const k = 1024;
const sizes = ["B", "KB", "MB", "GB", "TB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};
const formatFlow = (bytes: number): string => {
if (!Number.isFinite(bytes) || bytes <= 0) {
@@ -719,17 +711,6 @@ export default function NodePage() {
return "未知链路";
};
// 获取进度条颜色
const getProgressColor = (
value: number,
offline = false,
): "default" | "primary" | "secondary" | "success" | "warning" | "danger" => {
if (offline) return "default";
if (value <= 50) return "success";
if (value <= 80) return "warning";
return "danger";
};
// IPv4/IPv6 格式验证(仅用于判定地址族)
const ipv4Regex =
@@ -2162,235 +2143,7 @@ export default function NodePage() {
</div>
)}
{!isRemoteNode && (
<>
{/* 系统监控 */}
<div className="space-y-3 mb-4">
<div className="grid grid-cols-2 gap-3">
<div>
<div className="flex justify-between text-xs mb-1">
<span>CPU</span>
<span className="font-mono">
{node.connectionStatus === "online" &&
node.systemInfo
? `${node.systemInfo.cpuUsage.toFixed(1)}%`
: "-"}
</span>
</div>
<Progress
aria-label="CPU使用率"
color={getProgressColor(
node.connectionStatus === "online" &&
node.systemInfo
? node.systemInfo.cpuUsage
: 0,
node.connectionStatus !== "online",
)}
size="sm"
value={
node.connectionStatus === "online" &&
node.systemInfo
? node.systemInfo.cpuUsage
: 0
}
/>
</div>
<div>
<div className="flex justify-between text-xs mb-1">
<span>内存</span>
<span className="font-mono">
{node.connectionStatus === "online" &&
node.systemInfo
? `${node.systemInfo.memoryUsage.toFixed(1)}%`
: "-"}
</span>
</div>
<Progress
aria-label="内存使用率"
color={getProgressColor(
node.connectionStatus === "online" &&
node.systemInfo
? node.systemInfo.memoryUsage
: 0,
node.connectionStatus !== "online",
)}
size="sm"
value={
node.connectionStatus === "online" &&
node.systemInfo
? node.systemInfo.memoryUsage
: 0
}
/>
</div>
</div>
<div className="grid grid-cols-2 gap-2 text-xs">
<div className="text-center p-2 bg-default-50 dark:bg-default-100 rounded">
<div className="text-default-600 mb-0.5">
上传
</div>
<div className="font-mono">
{node.connectionStatus === "online" &&
node.systemInfo
? formatSpeed(
node.systemInfo.uploadSpeed,
)
: "-"}
</div>
</div>
<div className="text-center p-2 bg-default-50 dark:bg-default-100 rounded">
<div className="text-default-600 mb-0.5">
下载
</div>
<div className="font-mono">
{node.connectionStatus === "online" &&
node.systemInfo
? formatSpeed(
node.systemInfo.downloadSpeed,
)
: "-"}
</div>
</div>
</div>
{/* 流量统计 */}
<div className="grid grid-cols-2 gap-2 text-xs">
<div className="text-center p-2 bg-primary-50 dark:bg-primary-100/20 rounded border border-primary-200 dark:border-primary-300/20">
<div className="text-primary-600 dark:text-primary-400 mb-0.5">
↑ 上行流量
</div>
<div className="font-mono text-primary-700 dark:text-primary-300">
{node.connectionStatus === "online" &&
node.systemInfo
? formatTraffic(
node.systemInfo.uploadTraffic,
)
: "-"}
</div>
</div>
<div className="text-center p-2 bg-success-50 dark:bg-success-100/20 rounded border border-success-200 dark:border-success-300/20">
<div className="text-success-600 dark:text-success-400 mb-0.5">
↓ 下行流量
</div>
<div className="font-mono text-success-700 dark:text-success-300">
{node.connectionStatus === "online" &&
node.systemInfo
? formatTraffic(
node.systemInfo.downloadTraffic,
)
: "-"}
</div>
</div>
</div>
{/* 扩展指标:磁盘/负载/连接 */}
{node.connectionStatus === "online" &&
node.systemInfo && (
<div className="space-y-2">
{node.systemInfo.diskUsage !==
undefined && (
<div>
<div className="flex justify-between text-xs mb-1">
<span>磁盘</span>
<span className="font-mono">
{node.systemInfo.diskUsage.toFixed(
1,
)}
%
</span>
</div>
<Progress
aria-label="磁盘使用率"
color={getProgressColor(
node.systemInfo.diskUsage,
false,
)}
size="sm"
value={node.systemInfo.diskUsage}
/>
</div>
)}
{(node.systemInfo.load1 !== undefined ||
node.systemInfo.load5 !== undefined ||
node.systemInfo.load15 !==
undefined) && (
<div className="grid grid-cols-3 gap-1 text-xs">
{node.systemInfo.load1 !==
undefined && (
<div className="text-center p-1.5 bg-default-50 dark:bg-default-100 rounded">
<div className="text-default-500 text-[10px]">
负载 1m
</div>
<div className="font-mono">
{node.systemInfo.load1.toFixed(
2,
)}
</div>
</div>
)}
{node.systemInfo.load5 !==
undefined && (
<div className="text-center p-1.5 bg-default-50 dark:bg-default-100 rounded">
<div className="text-default-500 text-[10px]">
负载 5m
</div>
<div className="font-mono">
{node.systemInfo.load5.toFixed(
2,
)}
</div>
</div>
)}
{node.systemInfo.load15 !==
undefined && (
<div className="text-center p-1.5 bg-default-50 dark:bg-default-100 rounded">
<div className="text-default-500 text-[10px]">
负载 15m
</div>
<div className="font-mono">
{node.systemInfo.load15.toFixed(
2,
)}
</div>
</div>
)}
</div>
)}
{(node.systemInfo.tcpConns !==
undefined ||
node.systemInfo.udpConns !==
undefined) && (
<div className="grid grid-cols-2 gap-2 text-xs">
{node.systemInfo.tcpConns !==
undefined && (
<div className="text-center p-1.5 bg-default-50 dark:bg-default-100 rounded">
<div className="text-default-500 text-[10px]">
TCP 连接
</div>
<div className="font-mono">
{node.systemInfo.tcpConns}
</div>
</div>
)}
{node.systemInfo.udpConns !==
undefined && (
<div className="text-center p-1.5 bg-default-50 dark:bg-default-100 rounded">
<div className="text-default-500 text-[10px]">
UDP 连接
</div>
<div className="font-mono">
{node.systemInfo.udpConns}
</div>
</div>
)}
</div>
)}
</div>
)}
</div>
</>
)}
<div className="mt-auto space-y-3">
{/* 操作按钮 */}