Procházet zdrojové kódy

feat: 添加新的系统监控 new

zhaifanhua před 10 měsíci
rodič
revize
8d00f6280a

+ 1 - 1
Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj

@@ -70,7 +70,7 @@
     <PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="9.0.6" />
     <PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="9.0.6" />
 	<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.5.1" />
-	<PackageReference Include="XiHan.Framework.Utils" Version="0.9.12" />
+	<PackageReference Include="XiHan.Framework.Utils" Version="0.9.13-preview.6" />
   </ItemGroup>
 
 </Project>

+ 46 - 0
Admin.NET/Admin.NET.Core/Service/Server/SysServerService.cs

@@ -4,6 +4,15 @@
 //
 // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
 
+#if NET9_0_OR_GREATER
+
+using XiHan.Framework.Utils.HardwareInfos;
+using XiHan.Framework.Utils.Reflections;
+using XiHan.Framework.Utils.Runtime;
+using ReflectionHelper = XiHan.Framework.Utils.Reflections.ReflectionHelper;
+
+#endif // NET9_0_OR_GREATER
+
 namespace Admin.NET.Core.Service;
 
 /// <summary>
@@ -16,6 +25,43 @@ public class SysServerService : IDynamicApiController, ITransient
     {
     }
 
+#if NET9_0_OR_GREATER
+
+    /// <summary>
+    /// 获取服务器硬件信息
+    /// </summary>
+    /// <returns></returns>
+    [DisplayName("获取服务器硬件信息")]
+    public SystemHardwareInfo HardwareInfo()
+    {
+        var hardwareInfo = HardwareInfoManager.GetSystemHardwareInfo();
+        return hardwareInfo;
+    }
+
+    /// <summary>
+    /// 获取服务器运行时信息
+    /// </summary>
+    /// <returns></returns>
+    [DisplayName("获取服务器运行时信息")]
+    public SystemRuntimeInfo RuntimeInfo()
+    {
+        var systemRuntimeInfo = RuntimeInfoManger.GetSystemRuntimeInfo();
+        return systemRuntimeInfo;
+    }
+
+    /// <summary>
+    /// 获取框架主要程序集
+    /// </summary>
+    /// <returns></returns>
+    [DisplayName("获取框架主要程序集")]
+    public List<NuGetPackage> NuGetPackagesInfo()
+    {
+        var nuGetPackages = ReflectionHelper.GetNuGetPackages("Admin.NET");
+        return nuGetPackages;
+    }
+
+#endif // NET9_0_OR_GREATER
+
     /// <summary>
     /// 获取服务器配置信息 🔖
     /// </summary>

+ 25 - 0
Web/src/api/system/admin.ts

@@ -2,6 +2,9 @@ import request from '/@/utils/request';
 enum Api {
 	DictTypeDataList = '/api/sysDictData/DataList',
 	AllDictList = '/api/sysDictType/AllDictList',
+	HardwareInfo = '/api/sysServer/hardwareInfo',
+	RuntimeInfo = '/api/sysServer/runtimeInfo',
+	NuGetPackagesInfo = '/api/sysServer/nuGetPackagesInfo',
 }
 
 // 根据字典类型编码获取字典值集合
@@ -17,3 +20,25 @@ export const getAllDictList = () =>
 		url: `${Api.AllDictList}`,
 		method: 'get',
 	});
+
+	// 获取硬件信息
+export const getHardwareInfo = () =>
+	request({
+		url: `${Api.HardwareInfo}`,
+		method: 'post',
+	});
+
+// 获取运行时信息
+export const getRuntimeInfo = () =>
+	request({
+		url: `${Api.RuntimeInfo}`,
+		method: 'post',
+	});
+
+// 获取NuGet包信息
+export const getNuGetPackagesInfo = () =>
+	request({
+		url: `${Api.NuGetPackagesInfo}`,
+		method: 'post',
+	});
+

+ 1194 - 0
Web/src/views/system/server/new.vue

@@ -0,0 +1,1194 @@
+<template>
+	<div class="device-info-container">
+		<!-- 系统概览卡片 -->
+		<el-row :gutter="16" style="margin-bottom: 16px">
+			<el-col :span="24">
+				<el-card class="overview-card" shadow="hover">
+					<template #header>
+						<div class="card-header">
+							<i class="el-icon-monitor"></i>
+							<span>系统概览</span>
+							<span class="status-text">运行正常</span>
+						</div>
+					</template>
+					<div class="overview-content">
+						<div class="overview-item">
+							<div class="overview-icon cpu-icon">
+								<i class="el-icon-cpu"></i>
+							</div>
+							<div class="overview-text">
+								<div class="overview-title">处理器</div>
+								<div class="overview-value">{{ deviceInfo.cpuInfo.processorName }}</div>
+								<div class="overview-subtitle">{{ deviceInfo.cpuInfo.physicalCoreCount }}核 {{ deviceInfo.cpuInfo.logicalCoreCount }}线程</div>
+							</div>
+						</div>
+						<div class="overview-item">
+							<div class="overview-icon ram-icon">
+								<i class="el-icon-film"></i>
+							</div>
+							<div class="overview-text">
+								<div class="overview-title">内存</div>
+								<div class="overview-value">{{ deviceInfo.ramInfo.totalSpace }}</div>
+								<div class="overview-subtitle">使用率 {{ deviceInfo.ramInfo.usagePercentage }}%</div>
+							</div>
+						</div>
+						<div class="overview-item">
+							<div class="overview-icon os-icon">
+								<i class="el-icon-monitor"></i>
+							</div>
+							<div class="overview-text">
+								<div class="overview-title">操作系统</div>
+								<div class="overview-value">{{ deviceInfo.systemInfo.osDescription }}</div>
+								<div class="overview-subtitle">{{ deviceInfo.systemInfo.osArchitecture }} 架构</div>
+							</div>
+						</div>
+						<div class="overview-item">
+							<div class="overview-icon framework-icon">
+								<i class="el-icon-guide"></i>
+							</div>
+							<div class="overview-text">
+								<div class="overview-title">运行框架</div>
+								<div class="overview-value">{{ deviceInfo.systemInfo.frameworkDescription }}</div>
+								<div class="overview-subtitle">{{ deviceInfo.systemInfo.machineName }}</div>
+							</div>
+						</div>
+						<div class="overview-item">
+							<div class="overview-icon time-icon">
+								<i class="el-icon-time"></i>
+							</div>
+							<div class="overview-text">
+								<div class="overview-title">运行时间</div>
+								<div class="overview-value">{{ deviceInfo.systemUptime }}</div>
+								<div class="overview-subtitle">系统稳定运行</div>
+							</div>
+						</div>
+					</div>
+				</el-card>
+			</el-col>
+		</el-row>
+
+		<!-- CPU和内存性能 -->
+		<el-row :gutter="16" style="margin-bottom: 16px">
+			<el-col :md="12" :sm="24">
+				<el-card class="performance-card cpu-card" shadow="hover">
+					<template #header>
+						<div class="card-header">
+							<i class="el-icon-cpu"></i>
+							<span>CPU 性能</span>
+						</div>
+					</template>
+					<div class="performance-content">
+						<div class="performance-chart">
+							<el-progress type="dashboard" :percentage="deviceInfo.cpuInfo.usagePercentage" :color="getCpuColor(deviceInfo.cpuInfo.usagePercentage)" :width="180" :stroke-width="12">
+								<template #default>
+									<div class="progress-content">
+										<div class="progress-value">{{ deviceInfo.cpuInfo.usagePercentage }}%</div>
+										<div class="progress-label">CPU使用率</div>
+									</div>
+								</template>
+							</el-progress>
+						</div>
+						<div class="performance-details">
+							<div class="detail-item">
+								<span class="detail-label">处理器架构:</span>
+								<span class="detail-value">{{ deviceInfo.cpuInfo.processorArchitecture }}</span>
+							</div>
+							<div class="detail-item">
+								<span class="detail-label">基础频率:</span>
+								<span class="detail-value">{{ deviceInfo.cpuInfo.baseClockSpeed }} GHz</span>
+							</div>
+							<div class="detail-item">
+								<span class="detail-label">缓存大小:</span>
+								<span class="detail-value">{{ deviceInfo.cpuInfo.cacheSize }}</span>
+							</div>
+						</div>
+					</div>
+				</el-card>
+			</el-col>
+			<el-col :md="12" :sm="24">
+				<el-card class="performance-card ram-card" shadow="hover">
+					<template #header>
+						<div class="card-header">
+							<i class="el-icon-memory-card"></i>
+							<span>内存使用</span>
+						</div>
+					</template>
+					<div class="performance-content">
+						<div class="performance-chart">
+							<el-progress type="dashboard" :percentage="deviceInfo.ramInfo.usagePercentage" :color="getRamColor(deviceInfo.ramInfo.usagePercentage)" :width="180" :stroke-width="12">
+								<template #default>
+									<div class="progress-content">
+										<div class="progress-value">{{ deviceInfo.ramInfo.usagePercentage.toFixed(1) }}%</div>
+										<div class="progress-label">内存使用</div>
+									</div>
+								</template>
+							</el-progress>
+						</div>
+						<div class="performance-details">
+							<div class="detail-item">
+								<span class="detail-label">总内存:</span>
+								<span class="detail-value">{{ deviceInfo.ramInfo.totalSpace }}</span>
+							</div>
+							<div class="detail-item">
+								<span class="detail-label">已使用:</span>
+								<span class="detail-value">{{ deviceInfo.ramInfo.usedSpace }}</span>
+							</div>
+							<div class="detail-item">
+								<span class="detail-label">可用:</span>
+								<span class="detail-value">{{ deviceInfo.ramInfo.freeSpace }}</span>
+							</div>
+						</div>
+					</div>
+				</el-card>
+			</el-col>
+		</el-row>
+
+		<!-- 磁盘信息 -->
+		<el-row :gutter="16" style="margin-bottom: 16px">
+			<el-col :span="24">
+				<el-card class="disk-card" shadow="hover">
+					<template #header>
+						<div class="card-header">
+							<i class="el-icon-files"></i>
+							<span>磁盘使用情况</span>
+						</div>
+					</template>
+					<el-row :gutter="16">
+						<el-col :md="12" :sm="24" v-for="disk in deviceInfo.diskInfos" :key="disk.diskName">
+							<div class="disk-item">
+								<div class="disk-header">
+									<div class="disk-name">{{ disk.diskName }}</div>
+									<div class="disk-type">{{ disk.typeName }}</div>
+								</div>
+								<div class="disk-content">
+									<div class="disk-chart">
+										<el-progress type="circle" :percentage="parseFloat(disk.usedPercentage)" :color="getDiskColor(disk.availableRate)" :width="120" :stroke-width="8">
+											<template #default>
+												<div class="disk-progress-content">
+													<div class="disk-usage">{{ disk.usedPercentage }}%</div>
+													<div class="disk-label">已使用</div>
+												</div>
+											</template>
+										</el-progress>
+									</div>
+									<div class="disk-details">
+										<div class="disk-detail-item">
+											<span class="detail-label">总容量:</span>
+											<span class="detail-value">{{ disk.totalSpace }}</span>
+										</div>
+										<div class="disk-detail-item">
+											<span class="detail-label">已使用:</span>
+											<span class="detail-value">{{ disk.usedSpace }}</span>
+										</div>
+										<div class="disk-detail-item">
+											<span class="detail-label">可用空间:</span>
+											<span class="detail-value">{{ disk.freeSpace }}</span>
+										</div>
+									</div>
+								</div>
+							</div>
+						</el-col>
+					</el-row>
+				</el-card>
+			</el-col>
+		</el-row>
+
+		<!-- GPU信息 -->
+		<el-row :gutter="16" style="margin-bottom: 16px">
+			<el-col :span="24">
+				<el-card class="gpu-card" shadow="hover">
+					<template #header>
+						<div class="card-header">
+							<i class="el-icon-view"></i>
+							<span>显卡信息</span>
+						</div>
+					</template>
+					<el-row :gutter="16">
+						<el-col :md="12" :sm="24" v-for="(gpu, index) in deviceInfo.gpuInfos" :key="index">
+							<div class="gpu-item">
+								<div class="gpu-header">
+									<div class="gpu-name">{{ gpu.name }}</div>
+									<el-tag :type="gpu.status === 'OK' ? 'success' : 'danger'" size="small">
+										{{ gpu.status }}
+									</el-tag>
+								</div>
+								<div class="gpu-details">
+									<div class="gpu-detail-item">
+										<span class="detail-label">显存:</span>
+										<span class="detail-value">{{ gpu.memorySize }}</span>
+									</div>
+									<div class="gpu-detail-item">
+										<span class="detail-label">驱动版本:</span>
+										<span class="detail-value">{{ gpu.driverVersion || 'N/A' }}</span>
+									</div>
+									<div class="gpu-detail-item">
+										<span class="detail-label">分辨率:</span>
+										<span class="detail-value">{{ gpu.videoModeDescription }}</span>
+									</div>
+								</div>
+							</div>
+						</el-col>
+					</el-row>
+				</el-card>
+			</el-col>
+		</el-row>
+
+		<!-- 网络信息 -->
+		<el-row :gutter="16" style="margin-bottom: 16px">
+			<el-col :span="24">
+				<el-card class="network-card" shadow="hover">
+					<template #header>
+						<div class="card-header">
+							<i class="el-icon-connection"></i>
+							<span>网络适配器</span>
+							<span class="status-text">{{ getActiveNetworks().length }} 个活跃</span>
+						</div>
+					</template>
+					<div class="network-content">
+						<el-collapse v-model="activeNetworkNames" accordion>
+							<el-collapse-item v-for="network in getActiveNetworks()" :key="network.name" :name="network.name">
+								<template #title>
+									<div class="network-title">
+										<div class="network-status">
+											<i :class="getNetworkStatusIcon(network.operationalStatus)"></i>
+											<span class="network-name">{{ network.name }}</span>
+										</div>
+										<div class="network-type">
+											<el-tag size="small" :type="getNetworkTypeColor(network.type)">
+												{{ network.type }}
+											</el-tag>
+										</div>
+									</div>
+								</template>
+								<div class="network-details">
+									<el-row :gutter="16">
+										<el-col :md="12" :sm="24">
+											<div class="network-info">
+												<div class="network-detail-item">
+													<span class="detail-label">描述:</span>
+													<span class="detail-value">{{ network.description }}</span>
+												</div>
+												<div class="network-detail-item">
+													<span class="detail-label">物理地址:</span>
+													<span class="detail-value">{{ network.physicalAddress || 'N/A' }}</span>
+												</div>
+												<div class="network-detail-item">
+													<span class="detail-label">速度:</span>
+													<span class="detail-value">{{ network.speed }}</span>
+												</div>
+												<div class="network-detail-item" v-if="network.iPv4Addresses && network.iPv4Addresses.length > 0">
+													<span class="detail-label">IPv4地址:</span>
+													<div class="ip-addresses">
+														<el-tag v-for="ip in network.iPv4Addresses" :key="ip.address" size="small" class="ip-tag">
+															{{ ip.address }}
+														</el-tag>
+													</div>
+												</div>
+											</div>
+										</el-col>
+										<el-col :md="12" :sm="24" v-if="network.statistics">
+											<div class="network-statistics">
+												<h4>网络统计</h4>
+												<div class="stats-grid">
+													<div class="stat-item">
+														<div class="stat-label">接收字节</div>
+														<div class="stat-value">{{ formatBytes(network.statistics.bytesReceived) }}</div>
+													</div>
+													<div class="stat-item">
+														<div class="stat-label">发送字节</div>
+														<div class="stat-value">{{ formatBytes(network.statistics.bytesSent) }}</div>
+													</div>
+													<div class="stat-item">
+														<div class="stat-label">接收包数</div>
+														<div class="stat-value">{{ network.statistics.packetsReceived.toLocaleString() }}</div>
+													</div>
+													<div class="stat-item">
+														<div class="stat-label">发送包数</div>
+														<div class="stat-value">{{ network.statistics.packetsSent.toLocaleString() }}</div>
+													</div>
+												</div>
+											</div>
+										</el-col>
+									</el-row>
+								</div>
+							</el-collapse-item>
+						</el-collapse>
+					</div>
+				</el-card>
+			</el-col>
+		</el-row>
+
+		<!-- 主板信息 -->
+		<el-row :gutter="16" style="margin-bottom: 16px">
+			<el-col :span="24">
+				<el-card class="board-card" shadow="hover">
+					<template #header>
+						<div class="card-header">
+							<i class="el-icon-cpu"></i>
+							<span>主板信息</span>
+						</div>
+					</template>
+					<div class="board-content">
+						<div class="board-item">
+							<span class="detail-label">制造商:</span>
+							<span class="detail-value">{{ deviceInfo.boardInfo.manufacturer }}</span>
+						</div>
+						<div class="board-item">
+							<span class="detail-label">产品型号:</span>
+							<span class="detail-value">{{ deviceInfo.boardInfo.product }}</span>
+						</div>
+						<div class="board-item">
+							<span class="detail-label">版本:</span>
+							<span class="detail-value">{{ deviceInfo.boardInfo.version }}</span>
+						</div>
+						<div class="board-item">
+							<span class="detail-label">序列号:</span>
+							<span class="detail-value">{{ deviceInfo.boardInfo.serialNumber }}</span>
+						</div>
+					</div>
+				</el-card>
+			</el-col>
+		</el-row>
+
+		<!-- 系统信息 -->
+		<el-row :gutter="16">
+			<el-col :span="24">
+				<el-card class="system-card" shadow="hover">
+					<template #header>
+						<div class="card-header">
+							<i class="el-icon-setting"></i>
+							<span>系统信息</span>
+						</div>
+					</template>
+					<div class="system-content">
+						<div class="system-item">
+							<span class="detail-label">操作系统:</span>
+							<span class="detail-value">{{ deviceInfo.systemInfo.osDescription }}</span>
+						</div>
+						<div class="system-item">
+							<span class="detail-label">系统版本:</span>
+							<span class="detail-value">{{ deviceInfo.systemInfo.osVersion }}</span>
+						</div>
+						<div class="system-item">
+							<span class="detail-label">系统架构:</span>
+							<span class="detail-value">{{ deviceInfo.systemInfo.osArchitecture }}</span>
+						</div>
+						<div class="system-item">
+							<span class="detail-label">运行框架:</span>
+							<span class="detail-value">{{ deviceInfo.systemInfo.frameworkDescription }}</span>
+						</div>
+						<div class="system-item">
+							<span class="detail-label">机器名称:</span>
+							<span class="detail-value">{{ deviceInfo.systemInfo.machineName }}</span>
+						</div>
+						<div class="system-item">
+							<span class="detail-label">当前用户:</span>
+							<span class="detail-value">{{ deviceInfo.systemInfo.userName }}</span>
+						</div>
+						<div class="system-item">
+							<span class="detail-label">系统启动时间:</span>
+							<span class="detail-value">{{ deviceInfo.systemInfo.systemStartTime }}</span>
+						</div>
+						<div class="system-item">
+							<span class="detail-label">进程启动时间:</span>
+							<span class="detail-value">{{ deviceInfo.systemInfo.processStartTime }}</span>
+						</div>
+					</div>
+				</el-card>
+			</el-col>
+		</el-row>
+
+		<!-- NuGet包信息 -->
+		<el-row :gutter="16">
+			<el-col :span="24">
+				<el-card class="nuget-card" shadow="hover">
+					<template #header>
+						<div class="card-header">
+							<i class="el-icon-collection"></i>
+							<span>NuGet 包信息</span>
+							<span class="status-text">{{ deviceInfo.nugetPackages.length }} 个包</span>
+						</div>
+					</template>
+					<div class="nuget-content">
+						<div v-for="pkg in deviceInfo.nugetPackages" :key="pkg.packageName" class="package-item">
+							<el-tag round>
+								<div class="package-info">
+									<div class="package-name">{{ pkg.packageName }}</div>
+									<div class="package-version">v{{ pkg.packageVersion }}</div>
+								</div>
+							</el-tag>
+						</div>
+					</div>
+				</el-card>
+			</el-col>
+		</el-row>
+	</div>
+</template>
+
+<script lang="ts" setup name="deviceInfo">
+import { ref, reactive, onMounted } from 'vue';
+import { getHardwareInfo, getRuntimeInfo, getNuGetPackagesInfo } from '/@/api/system/admin';
+
+// 网络接口类型定义
+interface NetworkInfo {
+	name: string;
+	description: string;
+	type: string;
+	operationalStatus: string;
+	speed: string;
+	physicalAddress: string;
+	supportsMulticast: boolean;
+	isReceiveOnly: boolean;
+	dnsAddresses: string[];
+	gatewayAddresses: string[];
+	dhcpServerAddresses: string[];
+	iPv4Addresses: Array<{
+		address: string;
+		subnetMask: string;
+		prefixLength: number;
+	}>;
+	iPv6Addresses: Array<{
+		address: string;
+		subnetMask: string;
+		prefixLength: number;
+	}>;
+	statistics?: {
+		bytesReceived: number;
+		bytesSent: number;
+		packetsReceived: number;
+		packetsSent: number;
+		incomingPacketsDiscarded: number;
+		outgoingPacketsDiscarded: number;
+		incomingPacketsWithErrors: number;
+		outgoingPacketsWithErrors: number;
+	};
+}
+
+// 设备信息数据
+const deviceInfo = reactive<any>({
+	cpuInfo: {
+		processorName: '',
+		processorArchitecture: '',
+		physicalCoreCount: 0,
+		logicalCoreCount: 0,
+		baseClockSpeed: 0,
+		cacheSize: '',
+		usagePercentage: 0,
+	},
+	ramInfo: {
+		totalSpace: '',
+		usedSpace: '',
+		freeSpace: '',
+		usagePercentage: 0,
+	},
+	diskInfos: [],
+	networkInfos: [],
+	gpuInfos: [],
+	boardInfo: {
+		manufacturer: '',
+		product: '',
+		version: '',
+		serialNumber: '',
+	},
+	systemUptime: '',
+	systemInfo: {
+		osDescription: '',
+		osVersion: '',
+		osArchitecture: '',
+		frameworkDescription: '',
+		machineName: '',
+		userName: '',
+		systemStartTime: '',
+		processStartTime: '',
+	},
+	nugetPackages: [],
+});
+
+const activeNetworkNames = ref('');
+
+// 格式化字节数为可读格式
+const formatBytes = (bytes: number) => {
+	if (bytes === 0) return '0 B';
+	const k = 1024;
+	const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
+	const i = Math.floor(Math.log(bytes) / Math.log(k));
+	return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
+};
+
+// 获取硬件信息
+const getHardwareInfoData = async () => {
+	try {
+		// 并行获取硬件信息、运行时信息和 NuGet 包信息
+		const [hardwareRes, runtimeRes, nugetRes] = await Promise.all([getHardwareInfo(), getRuntimeInfo(), getNuGetPackagesInfo()]);
+
+		const hardwareData = hardwareRes.data.result;
+		const runtimeData = runtimeRes.data.result;
+		const nugetPackages = nugetRes.data.result;
+
+		// 处理CPU信息
+		Object.assign(deviceInfo.cpuInfo, {
+			processorName: hardwareData.cpuInfo.processorName,
+			processorArchitecture: hardwareData.cpuInfo.processorArchitecture,
+			physicalCoreCount: hardwareData.cpuInfo.physicalCoreCount,
+			logicalCoreCount: hardwareData.cpuInfo.logicalCoreCount,
+			baseClockSpeed: hardwareData.cpuInfo.baseClockSpeed,
+			cacheSize: formatBytes(hardwareData.cpuInfo.cacheBytes || 0),
+			usagePercentage: hardwareData.cpuInfo.usagePercentage,
+		});
+
+		// 处理内存信息
+		Object.assign(deviceInfo.ramInfo, {
+			totalSpace: formatBytes(hardwareData.ramInfo.totalBytes),
+			usedSpace: formatBytes(hardwareData.ramInfo.usedBytes),
+			freeSpace: formatBytes(hardwareData.ramInfo.freeBytes),
+			usagePercentage: hardwareData.ramInfo.usagePercentage,
+		});
+
+		// 处理磁盘信息
+		deviceInfo.diskInfos = hardwareData.diskInfos.map((disk: any) => ({
+			diskName: disk.diskName,
+			typeName: disk.typeName,
+			totalSpace: formatBytes(disk.totalSpace),
+			usedSpace: formatBytes(disk.usedSpace),
+			freeSpace: formatBytes(disk.freeSpace),
+			availableRate: disk.availableRate,
+			usedPercentage: ((disk.usedSpace / disk.totalSpace) * 100).toFixed(1),
+		}));
+
+		// 处理网络信息
+		deviceInfo.networkInfos = hardwareData.networkInfos;
+
+		// 处理GPU信息
+		deviceInfo.gpuInfos = hardwareData.gpuInfos.map((gpu: any) => ({
+			name: gpu.name,
+			description: gpu.description,
+			vendor: gpu.vendor,
+			deviceId: gpu.deviceId,
+			busInfo: gpu.busInfo,
+			driverVersion: gpu.driverVersion,
+			memorySize: gpu.memoryBytes ? formatBytes(gpu.memoryBytes) : 'N/A',
+			videoModeDescription: gpu.videoModeDescription,
+			status: gpu.status,
+		}));
+
+		// 处理主板信息
+		Object.assign(deviceInfo.boardInfo, {
+			manufacturer: hardwareData.boardInfo.manufacturer,
+			product: hardwareData.boardInfo.product,
+			version: hardwareData.boardInfo.version,
+			serialNumber: hardwareData.boardInfo.serialNumber,
+		});
+
+		// 处理系统运行时间和其他系统信息
+		deviceInfo.systemUptime = runtimeData.runningTime || runtimeData.runtimeInfo.systemUptime;
+
+		// 添加系统信息到deviceInfo(可选)
+		deviceInfo.systemInfo = {
+			osDescription: runtimeData.runtimeInfo.osDescription,
+			osVersion: runtimeData.runtimeInfo.osVersion,
+			osArchitecture: runtimeData.runtimeInfo.osArchitecture,
+			frameworkDescription: runtimeData.runtimeInfo.frameworkDescription,
+			machineName: runtimeData.runtimeInfo.machineName,
+			userName: runtimeData.runtimeInfo.userName,
+			systemStartTime: runtimeData.runtimeInfo.systemStartTime,
+			processStartTime: runtimeData.runtimeInfo.processStartTime,
+		};
+
+		// 处理 NuGet 包信息
+		deviceInfo.nugetPackages = nugetPackages.map((pkg: any) => ({
+			packageName: pkg.packageName,
+			packageVersion: pkg.packageVersion,
+		}));
+	} catch (error) {
+		console.error('获取硬件信息失败:', error);
+		// 设置默认值,避免页面崩溃
+		deviceInfo.systemUptime = '获取失败';
+	}
+};
+
+// 获取活跃网络
+const getActiveNetworks = () => {
+	return deviceInfo.networkInfos.filter(
+		(network: NetworkInfo) =>
+			network.operationalStatus === 'Up' && !network.name.includes('WFP') && !network.name.includes('QoS') && !network.name.includes('Filter') && !network.name.includes('vSwitch')
+	);
+};
+
+// 获取网络状态图标
+const getNetworkStatusIcon = (status: string) => {
+	switch (status) {
+		case 'Up':
+			return 'el-icon-success network-status-up';
+		case 'Down':
+			return 'el-icon-error network-status-down';
+		default:
+			return 'el-icon-warning network-status-unknown';
+	}
+};
+
+// 获取网络类型颜色
+const getNetworkTypeColor = (type: string) => {
+	switch (type) {
+		case 'Ethernet':
+			return 'primary';
+		case 'Wireless80211':
+			return 'success';
+		case 'Loopback':
+			return 'info';
+		default:
+			return 'warning';
+	}
+};
+
+// 获取CPU使用率颜色
+const getCpuColor = (percentage: number) => {
+	if (percentage < 50) return '#67c23a';
+	if (percentage < 80) return '#e6a23c';
+	return '#f56c6c';
+};
+
+// 获取内存使用率颜色
+const getRamColor = (percentage: number) => {
+	if (percentage < 60) return '#409eff';
+	if (percentage < 80) return '#e6a23c';
+	return '#f56c6c';
+};
+
+// 获取磁盘使用率颜色
+const getDiskColor = (availablePercentage: number) => {
+	const usedPercentage = 100 - availablePercentage;
+	if (usedPercentage < 70) return '#67c23a';
+	if (usedPercentage < 90) return '#e6a23c';
+	return '#f56c6c';
+};
+
+onMounted(() => {
+	console.log('设备信息页面已加载');
+	getHardwareInfoData();
+});
+</script>
+
+<style lang="scss" scoped>
+.device-info-container {
+	padding: 16px;
+	background: #f5f7fa;
+	min-height: 100vh;
+}
+
+.card-header {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	font-weight: 600;
+
+	i {
+		margin-right: 8px;
+		font-size: 18px;
+	}
+
+	> span:first-of-type {
+		flex: 1;
+	}
+}
+
+.status-text {
+	font-size: 12px;
+	color: #67c23a;
+	flex-shrink: 0;
+}
+
+// 概览卡片
+.overview-card {
+	background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+	color: white;
+
+	:deep(.el-card__header) {
+		background: rgba(255, 255, 255, 0.1);
+		border-bottom: 1px solid rgba(255, 255, 255, 0.2);
+		color: white;
+	}
+}
+
+.overview-content {
+	display: flex;
+	justify-content: space-around;
+	flex-wrap: wrap;
+	gap: 20px;
+}
+
+.overview-item {
+	display: flex;
+	align-items: center;
+	gap: 16px;
+	min-width: 200px;
+	flex: 1;
+	min-height: 80px;
+	max-height: 103px;
+}
+
+.overview-icon {
+	width: 60px;
+	height: 60px;
+	border-radius: 50%;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 24px;
+	background: rgba(255, 255, 255, 0.2);
+	flex-shrink: 0;
+}
+
+.overview-text {
+	flex: 1;
+	min-width: 0;
+	display: flex;
+	flex-direction: column;
+	justify-content: center;
+	min-height: 72px;
+	max-height: 95px;
+
+	.overview-title {
+		font-size: 14px;
+		opacity: 0.8;
+		margin-bottom: 4px;
+		line-height: 1.2;
+		height: 17px;
+		display: flex;
+		align-items: center;
+	}
+
+	.overview-value {
+		font-size: 18px;
+		font-weight: 600;
+		margin-bottom: 4px;
+		word-break: break-word;
+		line-height: 1.3;
+		min-height: 23px;
+		max-height: 46px;
+		display: -webkit-box;
+		-webkit-line-clamp: 2;
+		-webkit-box-orient: vertical;
+		overflow: hidden;
+		text-overflow: ellipsis;
+	}
+
+	.overview-subtitle {
+		font-size: 12px;
+		opacity: 0.7;
+		line-height: 1.2;
+		height: 15px;
+		display: flex;
+		align-items: center;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+}
+
+// 性能卡片
+.performance-card {
+	&.cpu-card {
+		border-left: 4px solid #e6a23c;
+	}
+
+	&.ram-card {
+		border-left: 4px solid #409eff;
+	}
+}
+
+.performance-content {
+	display: flex;
+	align-items: center;
+	gap: 24px;
+}
+
+.performance-chart {
+	flex-shrink: 0;
+}
+
+.progress-content {
+	text-align: center;
+
+	.progress-value {
+		font-size: 24px;
+		font-weight: 600;
+		color: #303133;
+	}
+
+	.progress-label {
+		font-size: 12px;
+		color: #909399;
+		margin-top: 4px;
+	}
+}
+
+.performance-details {
+	flex: 1;
+}
+
+.detail-item {
+	display: flex;
+	justify-content: space-between;
+	padding: 8px 0;
+	border-bottom: 1px solid #f0f0f0;
+
+	&:last-child {
+		border-bottom: none;
+	}
+}
+
+.detail-label {
+	color: #606266;
+	font-size: 14px;
+}
+
+.detail-value {
+	color: #303133;
+	font-weight: 500;
+	font-size: 14px;
+}
+
+// 磁盘卡片
+.disk-card {
+	border-left: 4px solid #67c23a;
+}
+
+.disk-item {
+	background: #f8f9fa;
+	border-radius: 8px;
+	padding: 16px;
+	margin-bottom: 16px;
+
+	&:last-child {
+		margin-bottom: 0;
+	}
+}
+
+.disk-header {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	margin-bottom: 16px;
+}
+
+.disk-name {
+	font-size: 18px;
+	font-weight: 600;
+	color: #303133;
+}
+
+.disk-type {
+	color: #909399;
+	font-size: 14px;
+}
+
+.disk-content {
+	display: flex;
+	align-items: center;
+	gap: 24px;
+}
+
+.disk-chart {
+	flex-shrink: 0;
+}
+
+.disk-progress-content {
+	text-align: center;
+
+	.disk-usage {
+		font-size: 16px;
+		font-weight: 600;
+		color: #303133;
+	}
+
+	.disk-label {
+		font-size: 12px;
+		color: #909399;
+	}
+}
+
+.disk-details {
+	flex: 1;
+}
+
+.disk-detail-item {
+	display: flex;
+	justify-content: space-between;
+	padding: 6px 0;
+	border-bottom: 1px solid #e4e7ed;
+
+	&:last-child {
+		border-bottom: none;
+	}
+}
+
+// GPU卡片
+.gpu-card {
+	border-left: 4px solid #f56c6c;
+}
+
+.gpu-item {
+	background: #f8f9fa;
+	border-radius: 8px;
+	padding: 16px;
+	margin-bottom: 16px;
+
+	&:last-child {
+		margin-bottom: 0;
+	}
+}
+
+.gpu-header {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	margin-bottom: 12px;
+}
+
+.gpu-name {
+	font-size: 16px;
+	font-weight: 600;
+	color: #303133;
+	flex: 1;
+	margin-right: 12px;
+}
+
+.gpu-details {
+	display: grid;
+	gap: 8px;
+}
+
+.gpu-detail-item {
+	display: flex;
+	justify-content: space-between;
+	padding: 4px 0;
+}
+
+// 网络卡片
+.network-card {
+	border-left: 4px solid #909399;
+}
+
+.network-title {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	width: 100%;
+	padding-right: 16px;
+}
+
+.network-status {
+	display: flex;
+	align-items: center;
+	gap: 8px;
+}
+
+.network-name {
+	font-weight: 500;
+}
+
+.network-status-up {
+	color: #67c23a;
+}
+
+.network-status-down {
+	color: #f56c6c;
+}
+
+.network-status-unknown {
+	color: #e6a23c;
+}
+
+.network-details {
+	padding: 16px 0;
+}
+
+.network-info {
+	.network-detail-item {
+		margin-bottom: 12px;
+
+		&:last-child {
+			margin-bottom: 0;
+		}
+	}
+}
+
+.ip-addresses {
+	margin-top: 4px;
+}
+
+.ip-tag {
+	margin-right: 8px;
+	margin-bottom: 4px;
+}
+
+.network-statistics {
+	h4 {
+		margin: 0 0 16px 0;
+		color: #303133;
+	}
+}
+
+.stats-grid {
+	display: grid;
+	grid-template-columns: 1fr 1fr;
+	gap: 12px;
+}
+
+.stat-item {
+	background: #f0f2f5;
+	padding: 12px;
+	border-radius: 6px;
+	text-align: center;
+}
+
+.stat-label {
+	font-size: 12px;
+	color: #909399;
+	margin-bottom: 4px;
+}
+
+.stat-value {
+	font-size: 14px;
+	font-weight: 600;
+	color: #303133;
+}
+
+// 主板卡片
+.board-card {
+	border-left: 4px solid #973399;
+}
+
+.board-content {
+	display: grid;
+	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+	gap: 16px;
+}
+
+.board-item {
+	display: flex;
+	justify-content: space-between;
+	padding: 12px;
+	background: #f8f9fa;
+	border-radius: 6px;
+}
+
+// 系统信息卡片
+.system-card {
+	border-left: 4px solid #409eff;
+}
+
+.system-content {
+	display: grid;
+	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+	gap: 16px;
+}
+
+.system-item {
+	display: flex;
+	justify-content: space-between;
+	padding: 12px;
+	background: #f8f9fa;
+	border-radius: 6px;
+}
+
+// 响应式设计
+@media (max-width: 768px) {
+	.overview-content {
+		flex-direction: column;
+	}
+
+	.overview-item {
+		min-width: 100%;
+	}
+
+	.performance-content {
+		flex-direction: column;
+		text-align: center;
+	}
+
+	.disk-content {
+		flex-direction: column;
+		text-align: center;
+	}
+
+	.stats-grid {
+		grid-template-columns: 1fr;
+	}
+
+	.board-content {
+		grid-template-columns: 1fr;
+	}
+}
+
+// 动画效果
+.el-card {
+	transition:
+		transform 0.3s ease,
+		box-shadow 0.3s ease;
+
+	&:hover {
+		transform: translateY(-2px);
+		box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
+	}
+}
+
+.el-progress {
+	:deep(.el-progress__text) {
+		color: inherit !important;
+	}
+}
+
+:deep(.el-collapse-item__header) {
+	padding-left: 0;
+	padding-right: 16px;
+}
+
+:deep(.el-collapse-item__content) {
+	padding-bottom: 16px;
+}
+
+// NuGet包信息卡片样式
+.nuget-card {
+	border-left: 4px solid #409eff;
+	margin-top: 16px;
+}
+
+.nuget-content {
+	padding: 8px;
+	display: flex;
+	flex-wrap: wrap;
+	gap: 8px;
+}
+
+.package-item {
+	display: inline-block;
+	margin: 4px;
+	text-align: left;
+}
+
+.package-info {
+	display: inline-flex;
+	align-items: center;
+	gap: 4px;
+}
+
+.package-name {
+	font-family: 'Consolas', monospace;
+}
+
+.package-version {
+	color: #909399;
+	font-size: 9px;
+}
+
+:deep(.el-tag) {
+	--el-tag-bg-color: var(--el-color-primary-light-9);
+	--el-tag-border-color: var(--el-color-primary-light-8);
+	--el-tag-hover-color: var(--el-color-primary);
+
+	&:hover {
+		background-color: var(--el-color-primary-light-8);
+	}
+}
+</style>