'use client'; import Link from 'next/link'; import { useQuery } from '@tanstack/react-query'; import { TrendChart } from '@/components/data/trend-chart'; import { EmptyState } from '@/components/feedback/empty-state'; import { ErrorState } from '@/components/feedback/error-state'; import { LoadingState } from '@/components/feedback/loading-state'; import { AppCard } from '@/components/ui/app-card'; import { StatusBadge } from '@/components/ui/status-badge'; import { getDashboardOverview } from '@/features/dashboard/api/overview'; import type { DashboardAlert, DashboardNodeHealth, } from '@/features/dashboard/types'; import { getNodeStatusLabel, getNodeStatusVariant, getOpenrestyStatusLabel, getOpenrestyStatusVariant, } from '@/features/nodes/utils'; import { formatDateTime, formatRelativeTime } from '@/lib/utils/date'; function formatPercent(value?: number | null) { if (value === undefined || value === null || Number.isNaN(value)) { return '—'; } return `${value.toFixed(1)}%`; } function getErrorMessage(error: unknown) { return error instanceof Error ? error.message : '请求失败,请稍后重试。'; } function formatTrendHour(value: string) { const date = new Date(value); if (Number.isNaN(date.getTime())) { return '—'; } return `${date.getHours().toString().padStart(2, '0')}:00`; } function getAlertVariant( alert: DashboardAlert, ): 'success' | 'warning' | 'danger' | 'info' { if (alert.status === 'resolved') { return 'success'; } if (alert.severity === 'critical') { return 'danger'; } if (alert.severity === 'warning') { return 'warning'; } return 'info'; } function OverviewMetric({ label, value, hint, }: { label: string; value: string | number; hint?: string; }) { return (
{label}
{value}
{hint ? ({hint}
) : null}{node.name}
{node.node_id}
CPU
{formatPercent(node.cpu_usage_percent)}
内存
{formatPercent(node.memory_usage_percent)}
最近窗口请求
{node.request_count}
活动异常
{node.active_event_count}
当前版本:{node.current_version || '未应用'}
最近心跳: {node.last_seen_at ? ` ${formatRelativeTime(node.last_seen_at)} · ${formatDateTime(node.last_seen_at)}` : ' 暂无'}
{alert.node_name}
{alert.message || '暂无详细消息'}
{formatRelativeTime(alert.last_triggered_at)} ·{' '} {formatDateTime(alert.last_triggered_at)}