import { Avatar, Card, Spinner } from '@heroui/react'
import { useConnection } from '../../connection'
import { fmtBytes, fmtRate, fmtUptime } from '../../lib/format'
interface BotInfo {
self_id: string
adapter: string
nick: string
avatar: string
ws_connected: boolean
online: boolean | null
msg_recv: number | null
msg_sent: number | null
}
interface SystemInfo {
hostname: string
os: string
python: string
nonebot: string
boot_time: number
system_uptime_seconds: number
bot_uptime_seconds: number
}
interface CpuInfo {
percent: number
per_core: number[]
logical: number | null
physical: number | null
brand: string
load_avg: number[] | null
}
interface MemInfo {
percent: number
used: number
total: number
available: number
process_rss: number
process_percent: number
}
interface ProcessInfo {
pid: number
name: string
rss: number
cpu_percent: number
memory_percent: number
create_time: number
}
interface DiskInfo {
mount: string
device: string
percent: number
used: number
total: number
}
interface NicInfo {
name: string
up: boolean
sent: number
recv: number
ip: string
}
interface NetworkInfo {
sent: number
recv: number
sent_rate: number
recv_rate: number
packets_sent: number
packets_recv: number
interfaces: NicInfo[]
}
interface BackendInfo {
nonebot_version: string
plugin_count: number
python: string
driver: string
driver_type: string
}
interface DashboardData {
ok: boolean
bots: BotInfo[]
system: SystemInfo
cpu: CpuInfo
memory: MemInfo
process: ProcessInfo
disk: DiskInfo[]
network: NetworkInfo
backend: BackendInfo
}
function Bar({ value, color }: { value: number; color?: string }) {
const v = Math.max(0, Math.min(100, value))
const c = color || (v >= 80 ? 'bg-rose-500' : v >= 60 ? 'bg-amber-500' : 'bg-indigo-500')
return (
)
}
function coreColor(v: number): string {
if (v >= 80) return 'bg-rose-500'
if (v >= 60) return 'bg-amber-500'
if (v >= 30) return 'bg-indigo-500'
return 'bg-emerald-500'
}
function InfoRow({ label, value }: { label: string; value: string }) {
return (
{label}
{value || '—'}
)
}
function SectionTitle({ title, desc }: { title: string; desc: string }) {
return (
)
}
export default function HomePage() {
// 数据与连接状态来自全局 ConnectionProvider(顶栏已显示状态徽章)
const { data: rawData, error } = useConnection()
const data = rawData as DashboardData | null
const cpu = data?.cpu
const mem = data?.memory
const proc = data?.process
const sys = data?.system
const net = data?.network
const backend = data?.backend
return (
{error && !data &&
{error}
}
{/* 顶部:BOT 协议端信息 + BOT 后端信息 一行两列 */}
{/* BOT 协议端信息:登录账号昵称 / 账号 / 适配器类型 */}
{!data ? (
) : !data.bots.length ? (
暂无在线 QQ 账号
) : (
{data.bots.map(bot => (
{(bot.nick || bot.self_id).charAt(0).toUpperCase()}
{bot.nick}
{bot.self_id} · {bot.adapter}
{bot.msg_recv != null && 收 {bot.msg_recv}}
{bot.msg_sent != null && 发 {bot.msg_sent}}
{bot.online != null && {bot.online ? '在线' : '离线'}}
{bot.ws_connected ? '已连接' : '未连接'}
))}
)}
{/* BOT 后端信息:NoneBot 版本 / 驱动方式 / 装载插件数 */}
NoneBot 版本
{backend?.nonebot_version || '—'}
驱动方式
{backend?.driver || '—'}
{backend?.driver_type || ''}
装载插件数
{backend?.plugin_count ?? '—'} 个
Python
{backend?.python || '—'}
bot 运行 {sys ? fmtUptime(sys.bot_uptime_seconds) : '—'}
{/* 1. 主机规格信息:系统 / 处理器 / 内存 / 硬盘 */}
硬盘
{!data ? (
) : !data.disk.length ? (
未获取到磁盘信息
) : (
{data.disk.map((d) => (
{d.mount}
{d.percent}%
{fmtBytes(d.used)} / {fmtBytes(d.total)}
))}
)}
{/* 2. 资源占用信息:CPU / 内存 / 网络 */}
{/* CPU */}
CPU 使用率{cpu?.logical ? ' ' + cpu.logical + ' 核' : ''}
{cpu ? cpu.percent + '%' : '—'}
负载: {cpu?.load_avg ? cpu.load_avg.join(' / ') : '—'}
{cpu?.per_core?.length ? (
{cpu.per_core.map((v, i) => (
))}
) : null}
{/* 内存 */}
内存使用
{mem ? mem.percent + '%' : '—'}
已用 {mem ? fmtBytes(mem.used) : '—'} · 可用 {mem ? fmtBytes(mem.available) : '—'}
共 {mem ? fmtBytes(mem.total) : '—'}
{/* 网络 */}
网络流量
{net?.interfaces?.length ? {net.interfaces.length} 网卡 : null}
↓ 下行速率{net ? fmtRate(net.recv_rate) : '—'}
↑ 上行速率{net ? fmtRate(net.sent_rate) : '—'}
累计下行{net ? fmtBytes(net.recv) : '—'}
累计上行{net ? fmtBytes(net.sent) : '—'}
{/* 本进程 */}
运行进程(bot)
- PID
- {proc?.pid ?? '—'}
- 进程名
- {proc?.name || '—'}
- CPU
- {proc?.cpu_percent != null ? proc.cpu_percent + '%' : '—'}
- 内存占用
- {proc?.memory_percent != null ? proc.memory_percent + '%' : '—'}
- RSS
- {proc ? fmtBytes(proc.rss) : '—'}
)
}