Files
aiops/frontend/src/pages/host-monitor/SystemInfoSection.tsx
T
Logan.Li 0b404b4611 refactor(frontend): API 子模块化、大组件拆分与 TanStack Query hooks
P1: kubernetes/system API 拆为子目录模块,导出工具下沉到 lib/export-utils,
    http 统一 buildApiUrl/getWsBase;HostMonitor、DeploymentEdit* 拆至子组件。

P2: 新增 hooks/api(queryKeys、useTerminalSessions、useHostMonitor),
    TerminalSessionsTab 与 HostMonitor 接入 TanStack Query。

P3: 保留 services/api 路径,未迁移至 api/ 目录。
2026-06-26 00:02:29 +08:00

86 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 系统信息 Tab 内容 // Logan.Li
import { Activity, HardDrive } from 'lucide-react';
import { Card, CardContent } from '@/components/ui/card';
import { TabsContent } from '@/components/ui/tabs';
import { parseJSON } from './utils';
interface SystemInfoSectionProps {
selectedHost: string;
serverInfo: any;
latest: any;
heartbeatInfo: any;
portInfoCount: number;
}
export function SystemInfoSection({
selectedHost, serverInfo, latest, heartbeatInfo, portInfoCount,
}: SystemInfoSectionProps) {
const disk = latest?.disk_info ? parseJSON(latest.disk_info) : null;
const parts = disk ? (Array.isArray(disk) ? disk : (disk.partitions || [])) : [];
return (
<TabsContent value="system" className="mt-3 space-y-3">
<Card className="bg-[var(--dg-bg-secondary)] border-[var(--dg-border)]">
<CardContent className="p-4">
<div className="grid grid-cols-2 md:grid-cols-4 gap-x-6 gap-y-3 text-xs">
{[
['主机名', serverInfo?.hostname || selectedHost],
['IP 地址', serverInfo?.ip || '—'],
['操作系统', serverInfo?.os || '—'],
['内核版本', serverInfo?.kernel || '—'],
['CPU 核心数', serverInfo?.cpu_cores || '—'],
['总内存', serverInfo?.mem_total ? `${serverInfo.mem_total.toFixed(0)} GB` : '—'],
['已用内存', serverInfo?.mem_used ? `${serverInfo.mem_used.toFixed(1)} GB` : '—'],
['运行时长', serverInfo?.uptime ? `${Math.floor(serverInfo.uptime / 86400)}天 ${Math.floor((serverInfo.uptime % 86400) / 3600)}时` : '—'],
['Agent 版本', heartbeatInfo?.version || serverInfo?.agent_version || '—'],
['Agent 序列号', heartbeatInfo?.report_seq != null ? String(heartbeatInfo.report_seq) : '—'],
['监听端口数', portInfoCount > 0 ? `${portInfoCount}` : '—'],
['Agent RSS', heartbeatInfo?.self_rss_mb ? `${heartbeatInfo.self_rss_mb.toFixed(1)} MB` : '—'],
].map(([label, val]) => (
<div key={label as string}>
<span className="text-[var(--dg-text-muted)]">{label}:</span>
<span className="text-[var(--dg-text-primary)] font-mono">{val}</span>
</div>
))}
</div>
</CardContent>
</Card>
{latest && (
<Card className="bg-[var(--dg-bg-secondary)] border-[var(--dg-border)]">
<CardContent className="p-4">
<div className="flex items-center gap-2 mb-2">
<Activity className="h-4 w-4 text-[var(--dg-text-muted)]" />
<h3 className="text-xs font-medium text-[var(--dg-text-primary)]">系统负载 (Load Average)</h3>
</div>
<div className="flex items-center gap-6 text-xs">
<div><span className="text-[var(--dg-text-muted)]">1min </span><span className="text-sm font-bold text-slate-200">{latest.load1 ?? '--'}</span></div>
<div><span className="text-[var(--dg-text-muted)]">5min </span><span className="text-sm font-bold text-slate-200">{latest.load5 ?? '--'}</span></div>
<div><span className="text-[var(--dg-text-muted)]">15min </span><span className="text-sm font-bold text-slate-200">{latest.load15 ?? '--'}</span></div>
</div>
</CardContent>
</Card>
)}
{parts.length > 0 && (
<Card className="bg-[var(--dg-bg-secondary)] border-[var(--dg-border)]">
<CardContent className="p-4">
<h3 className="text-xs font-medium text-[var(--dg-text-primary)] mb-2 flex items-center gap-2"><HardDrive className="h-4 w-4" />磁盘分区</h3>
<div className="space-y-1.5">
{parts.map((p: any, i: number) => (
<div key={i} className="flex items-center gap-2 text-xs">
<span className="text-[var(--dg-text-muted)] w-24 font-mono truncate">{p.mount || p.mountpoint || p.device || `disk${i}`}</span>
<div className="flex-1 h-1.5 bg-slate-700 rounded-full overflow-hidden">
<div className="h-full rounded-full bg-blue-500" style={{ width: `${Math.min(p.usage_percent || p.used_percent || 0, 100)}%` }} />
</div>
<span className="text-[var(--dg-text-primary)] w-28 text-right tabular-nums whitespace-nowrap">{(p.used_gb ?? 0).toFixed(1)}/{(p.total_gb ?? 0).toFixed(0)}GB</span>
<span className="text-blue-400 w-14 text-right tabular-nums whitespace-nowrap">{(p.usage_percent ?? p.used_percent ?? 0).toFixed(1)}%</span>
</div>
))}
</div>
</CardContent>
</Card>
)}
</TabsContent>
);
}