import { memo, useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { Activity, AlertTriangle, CheckCircle2, RefreshCw, XCircle } from 'lucide-react' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { systemApi, type SelfCheckResult } from '@/api/system' /** 单项状态 → 图标与配色 */ function StatusIcon({ status }: { status: 'ok' | 'warn' | 'error' }) { if (status === 'ok') return if (status === 'warn') return return } /** * 一键自检 — 仪表盘顶部。 * * 为什么放在仪表盘:新人接手/故障时第一眼看这里,不必在 * 「集群/主机/存储/部署/采集器」五个页面之间来回跳着判断"到底哪坏了"。 * 后端 /system/self-check 会真正探活(Loki /ready、集群凭证解密、磁盘空间), * 不是只读配置推断。 */ export const SelfCheckCard = memo(function SelfCheckCard() { const { t } = useTranslation('dashboard') const [data, setData] = useState(null) const [loading, setLoading] = useState(true) const [failed, setFailed] = useState(false) const load = useCallback(async () => { setLoading(true) setFailed(false) try { setData(await systemApi.selfCheck()) } catch { // 自检失败本身不代表平台坏了(可能是权限或接口异常), // 这里静默降级,不打断仪表盘其它内容 setFailed(true) } finally { setLoading(false) } }, []) useEffect(() => { void load() }, [load]) if (loading && !data) { return ( {t('selfCheck.loading')} ) } if (failed || !data) return null const borderClass = data.overall === 'ok' ? 'border-success/30' : data.overall === 'warn' ? 'border-warning/40' : 'border-destructive/40' return ( {/* 按使用反馈去掉「平台自检 / N 项需关注」这两段文字: 卡片本身就是自检结果,标题重复一遍没有信息量。 只保留状态图标着色(边框颜色已经能表达 overall)+ 时间 + 刷新。 */} {new Date(data.checkedAt).toLocaleTimeString()} {data.items.map(item => (
{item.name} {item.message}
))}
) })