mirror of
https://github.com/woodchen-ink/nezha-dash-v1.git
synced 2025-07-18 09:31:55 +08:00
更新 ServerCard 组件,优化 CPU 和内存信息的显示,增加 SWAP 使用率的提示功能,提升信息展示的清晰度和可读性。同时调整字节格式化函数,简化单位显示。
This commit is contained in:
parent
56812a52c3
commit
8eec93aff4
@ -9,7 +9,6 @@ import { useNavigate } from "react-router-dom"
|
|||||||
|
|
||||||
import PlanInfo from "./PlanInfo"
|
import PlanInfo from "./PlanInfo"
|
||||||
import BillingInfo from "./billingInfo"
|
import BillingInfo from "./billingInfo"
|
||||||
import { Badge } from "./ui/badge"
|
|
||||||
import { Card, CardContent, CardHeader, CardFooter } from "./ui/card"
|
import { Card, CardContent, CardHeader, CardFooter } from "./ui/card"
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip"
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip"
|
||||||
import { ArrowDown, ArrowUp, Clock, Cpu, HardDrive, Server, Activity, BarChart3, Calendar } from "lucide-react"
|
import { ArrowDown, ArrowUp, Clock, Cpu, HardDrive, Server, Activity, BarChart3, Calendar } from "lucide-react"
|
||||||
@ -45,7 +44,10 @@ export default function ServerCard({ now, serverInfo, cycleStats }: ServerCardPr
|
|||||||
udp,
|
udp,
|
||||||
process,
|
process,
|
||||||
uptime,
|
uptime,
|
||||||
last_active_time_string
|
last_active_time_string,
|
||||||
|
arch,
|
||||||
|
swap,
|
||||||
|
swap_total
|
||||||
} = formatNezhaInfo(
|
} = formatNezhaInfo(
|
||||||
now,
|
now,
|
||||||
serverInfo,
|
serverInfo,
|
||||||
@ -60,8 +62,6 @@ export default function ServerCard({ now, serverInfo, cycleStats }: ServerCardPr
|
|||||||
const customBackgroundImage = (window.CustomBackgroundImage as string) !== "" ? window.CustomBackgroundImage : undefined
|
const customBackgroundImage = (window.CustomBackgroundImage as string) !== "" ? window.CustomBackgroundImage : undefined
|
||||||
// @ts-expect-error ShowNetTransfer is a global variable
|
// @ts-expect-error ShowNetTransfer is a global variable
|
||||||
const showNetTransfer = window.ShowNetTransfer as boolean
|
const showNetTransfer = window.ShowNetTransfer as boolean
|
||||||
// @ts-expect-error ShowServerDetails is a global variable
|
|
||||||
const showServerDetails = window.ShowServerDetails !== undefined ? window.ShowServerDetails as boolean : true
|
|
||||||
|
|
||||||
const parsedData = parsePublicNote(public_note)
|
const parsedData = parsePublicNote(public_note)
|
||||||
|
|
||||||
@ -379,6 +379,29 @@ export default function ServerCard({ now, serverInfo, cycleStats }: ServerCardPr
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ServerUsageBar value={cpu} />
|
<ServerUsageBar value={cpu} />
|
||||||
|
{/* CPU信息 */}
|
||||||
|
{cpu_info && cpu_info.length > 0 && (
|
||||||
|
<div className="mt-1.5 flex flex-col gap-1 text-[10px]">
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div className="bg-blue-500/10 text-blue-600 dark:text-blue-400 rounded px-1.5 py-0.5 text-center">
|
||||||
|
{cpu_info[0].includes("Physical") ? "pCPU: " : "vCPU: "}
|
||||||
|
{cpu_info[0].match(/(\d+)\s+(?:Physical|Virtual)\s+Core/)?.[1] || "-"}
|
||||||
|
</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent className="max-w-[250px] text-xs whitespace-pre-wrap p-2">
|
||||||
|
{cpu_info.join("\n")}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
{arch && (
|
||||||
|
<div className="bg-green-500/10 text-green-600 dark:text-green-400 rounded px-1.5 py-0.5 text-center">
|
||||||
|
{arch}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 内存使用率 */}
|
{/* 内存使用率 */}
|
||||||
@ -401,6 +424,41 @@ export default function ServerCard({ now, serverInfo, cycleStats }: ServerCardPr
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ServerUsageBar value={mem} />
|
<ServerUsageBar value={mem} />
|
||||||
|
{/* 内存信息 */}
|
||||||
|
<div className="mt-1.5 flex flex-col gap-1 text-[10px]">
|
||||||
|
<div className="bg-purple-500/10 text-purple-600 dark:text-purple-400 rounded px-1.5 py-0.5 text-center">
|
||||||
|
{mem_total > 0 ? formatBytes(mem_total) : "-"}
|
||||||
|
</div>
|
||||||
|
{swap_total > 0 ? (
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div className={cn("bg-indigo-500/10 text-indigo-600 dark:text-indigo-400 rounded px-1.5 py-0.5 text-center",
|
||||||
|
Number(swap) > 90 ? "bg-red-500/10 text-red-600 dark:text-red-400" :
|
||||||
|
Number(swap) > 70 ? "bg-orange-500/10 text-orange-600 dark:text-orange-400" : "")}>
|
||||||
|
SWAP:{swap.toFixed(0)}%
|
||||||
|
</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent className="text-xs">
|
||||||
|
<div className="flex flex-col gap-1 p-2">
|
||||||
|
<div className="flex justify-between items-center gap-3">
|
||||||
|
<span>总容量:</span>
|
||||||
|
<span>{formatBytes(swap_total)}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between items-center gap-3">
|
||||||
|
<span>使用率:</span>
|
||||||
|
<span className={getColorClass(Number(swap))}>{swap.toFixed(1)}%</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
):(
|
||||||
|
<div className="bg-amber-500/10 text-amber-600 dark:text-amber-400 rounded px-1.5 py-0.5 text-center">
|
||||||
|
-
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 存储使用率 */}
|
{/* 存储使用率 */}
|
||||||
@ -415,6 +473,10 @@ export default function ServerCard({ now, serverInfo, cycleStats }: ServerCardPr
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ServerUsageBar value={stg} />
|
<ServerUsageBar value={stg} />
|
||||||
|
{/* 存储信息 */}
|
||||||
|
<div className="mt-1.5 bg-amber-500/10 text-amber-600 dark:text-amber-400 rounded px-1.5 py-0.5 text-center text-[10px]">
|
||||||
|
{disk_total > 0 ? formatBytes(disk_total) : "-"}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -440,64 +502,20 @@ export default function ServerCard({ now, serverInfo, cycleStats }: ServerCardPr
|
|||||||
|
|
||||||
{/* 连接数与进程数 */}
|
{/* 连接数与进程数 */}
|
||||||
<div className="bg-muted/40 rounded-lg p-2 grid grid-cols-2 gap-2">
|
<div className="bg-muted/40 rounded-lg p-2 grid grid-cols-2 gap-2">
|
||||||
<div className="flex items-center min-w-0">
|
<div className="flex items-center min-w-0">
|
||||||
<Server className="size-[14px] text-indigo-500 mr-1 flex-shrink-0" />
|
<Server className="size-[14px] text-indigo-500 mr-1 flex-shrink-0" />
|
||||||
<span className="text-xs truncate" title={`TCP连接: ${tcp}`}>T: {formatLargeNumber(tcp)}</span>
|
<span className="text-xs truncate" title={`TCP连接: ${tcp}`}>T: {formatLargeNumber(tcp)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center min-w-0">
|
<div className="flex items-center min-w-0">
|
||||||
<Server className="size-[14px] text-pink-500 mr-1 flex-shrink-0" />
|
<Server className="size-[14px] text-pink-500 mr-1 flex-shrink-0" />
|
||||||
<span className="text-xs truncate" title={`UDP连接: ${udp}`}>U: {formatLargeNumber(udp)}</span>
|
<span className="text-xs truncate" title={`UDP连接: ${udp}`}>U: {formatLargeNumber(udp)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center min-w-0 col-span-2">
|
<div className="flex items-center min-w-0 col-span-2">
|
||||||
<Activity className="size-[14px] text-orange-500 mr-1 flex-shrink-0" />
|
<Activity className="size-[14px] text-orange-500 mr-1 flex-shrink-0" />
|
||||||
<span className="text-xs truncate" title={`进程数: ${process}`}>P: {formatLargeNumber(process)}</span>
|
<span className="text-xs truncate" title={`进程数: ${process}`}>P: {formatLargeNumber(process)}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 服务器详细信息区域 */}
|
|
||||||
{showServerDetails && (
|
|
||||||
<div className="mt-3 flex items-center flex-wrap gap-1.5">
|
|
||||||
{/* CPU信息 */}
|
|
||||||
{cpu_info && cpu_info.length > 0 && (
|
|
||||||
<TooltipProvider>
|
|
||||||
<Tooltip>
|
|
||||||
<TooltipTrigger asChild>
|
|
||||||
<Badge variant="outline" className="text-[10px] py-0 h-5 bg-blue-500/10 hover:bg-blue-500/20">
|
|
||||||
{cpu_info[0].includes("Physical") ? "pCPU: " : "vCPU: "}
|
|
||||||
{cpu_info[0].match(/(\d+)\s+(?:Physical|Virtual)\s+Core/)?.[1] || "-"}
|
|
||||||
</Badge>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent className="text-xs">
|
|
||||||
{cpu_info.join(", ")}
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 内存大小 */}
|
|
||||||
{mem_total > 0 ? (
|
|
||||||
<Badge variant="outline" className="text-[10px] py-0 h-5 bg-purple-500/10 hover:bg-purple-500/20">
|
|
||||||
RAM: {formatBytes(mem_total)}
|
|
||||||
</Badge>
|
|
||||||
) : (
|
|
||||||
<Badge variant="outline" className="text-[10px] py-0 h-5 bg-purple-500/10 hover:bg-purple-500/20">
|
|
||||||
RAM: -
|
|
||||||
</Badge>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 存储大小 */}
|
|
||||||
{disk_total > 0 ? (
|
|
||||||
<Badge variant="outline" className="text-[10px] py-0 h-5 bg-amber-500/10 hover:bg-amber-500/20">
|
|
||||||
DISK: {formatBytes(disk_total)}
|
|
||||||
</Badge>
|
|
||||||
) : (
|
|
||||||
<Badge variant="outline" className="text-[10px] py-0 h-5 bg-amber-500/10 hover:bg-amber-500/20">
|
|
||||||
DISK: -
|
|
||||||
</Badge>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|
||||||
<CardFooter className="p-4 pt-0 flex flex-col gap-2 pb-3">
|
<CardFooter className="p-4 pt-0 flex flex-col gap-2 pb-3">
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
export function formatBytes(bytes: number, decimals: number = 2) {
|
export function formatBytes(bytes: number, decimals: number = 2) {
|
||||||
if (!+bytes) return "0 Bytes"
|
if (!+bytes) return "0 B"
|
||||||
|
|
||||||
const k = 1024
|
const k = 1024
|
||||||
const dm = decimals < 0 ? 0 : decimals
|
const dm = decimals < 0 ? 0 : decimals
|
||||||
const sizes = ["Bytes", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]
|
const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
|
||||||
|
|
||||||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user