feat: support multiple disks in host info panel
This commit is contained in:
parent
d7da96c0c5
commit
2387e6e5f4
@ -47,11 +47,11 @@ function HostInfoPanel({ hostId, connectionId, isConnected, onOpenSFTP, onClose
|
||||
echo "===CPU_CORES===$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null)"
|
||||
echo "===MEMORY===$(free -h 2>/dev/null | awk '/^Mem:/ {print $2}' || echo 'N/A')"
|
||||
echo "===MEMORY_USED===$(free -h 2>/dev/null | awk '/^Mem:/ {print $3}' || echo 'N/A')"
|
||||
echo "===DISK===$(df -h / | awk 'NR==2 {print $2}')"
|
||||
echo "===DISK_USED===$(df -h / | awk 'NR==2 {print $3}')"
|
||||
echo "===DISK_PERCENT===$(df -h / | awk 'NR==2 {print $5}')"
|
||||
echo "===LOAD===$(cat /proc/loadavg 2>/dev/null | awk '{print $1, $2, $3}' || uptime | awk -F'load average:' '{print $2}' | xargs)"
|
||||
echo "===IP===$(hostname -I 2>/dev/null | awk '{print $1}' || ifconfig 2>/dev/null | grep 'inet ' | grep -v 127.0.0.1 | head -1 | awk '{print $2}')"
|
||||
echo "===DISKS_START==="
|
||||
df -h -T 2>/dev/null | grep -E '^/dev/' | grep -v 'tmpfs\|devtmpfs\|squashfs\|overlay\|loop' | awk '{print $1"|"$2"|"$3"|"$4"|"$6"|"$7}' || df -h 2>/dev/null | grep -E '^/dev/' | awk '{print $1"|unknown|"$2"|"$3"|"$5"|"$6}'
|
||||
echo "===DISKS_END==="
|
||||
`
|
||||
);
|
||||
|
||||
@ -61,6 +61,26 @@ function HostInfoPanel({ hostId, connectionId, isConnected, onOpenSFTP, onClose
|
||||
return match ? match[1].trim() : 'N/A';
|
||||
};
|
||||
|
||||
// 解析多硬盘信息
|
||||
const disksMatch = result.stdout.match(/===DISKS_START===([\s\S]*?)===DISKS_END===/);
|
||||
const disks = [];
|
||||
if (disksMatch && disksMatch[1]) {
|
||||
const diskLines = disksMatch[1].trim().split('\n').filter(line => line.trim());
|
||||
for (const line of diskLines) {
|
||||
const parts = line.split('|');
|
||||
if (parts.length >= 6) {
|
||||
disks.push({
|
||||
device: parts[0],
|
||||
type: parts[1],
|
||||
total: parts[2],
|
||||
used: parts[3],
|
||||
percent: parts[4],
|
||||
mount: parts[5],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setSystemInfo({
|
||||
hostname: parseValue('HOSTNAME'),
|
||||
os: parseValue('OS'),
|
||||
@ -70,11 +90,9 @@ function HostInfoPanel({ hostId, connectionId, isConnected, onOpenSFTP, onClose
|
||||
cpuCores: parseValue('CPU_CORES'),
|
||||
memory: parseValue('MEMORY'),
|
||||
memoryUsed: parseValue('MEMORY_USED'),
|
||||
disk: parseValue('DISK'),
|
||||
diskUsed: parseValue('DISK_USED'),
|
||||
diskPercent: parseValue('DISK_PERCENT'),
|
||||
load: parseValue('LOAD'),
|
||||
ip: parseValue('IP'),
|
||||
disks: disks.length > 0 ? disks : [{ device: '/dev/sda1', type: 'unknown', total: 'N/A', used: 'N/A', percent: '0%', mount: '/' }],
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
@ -340,18 +358,45 @@ function HostInfoPanel({ hostId, connectionId, isConnected, onOpenSFTP, onClose
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 磁盘使用 */}
|
||||
{/* 磁盘使用 - 支持多硬盘 */}
|
||||
<div className="bg-shell-surface/50 rounded-lg p-3 border border-shell-border/50">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<div className="flex items-center gap-2 mb-3">
|
||||
<FiHardDrive size={14} className="text-shell-orange" />
|
||||
<span className="text-shell-text-dim text-xs">磁盘 (/)</span>
|
||||
<span className="text-shell-text-dim text-xs">磁盘</span>
|
||||
<span className="text-shell-text-dim text-xs ml-auto">
|
||||
共 {systemInfo.disks?.length || 0} 个分区
|
||||
</span>
|
||||
</div>
|
||||
<div className="space-y-3 max-h-48 overflow-y-auto custom-scrollbar pr-1">
|
||||
{systemInfo.disks?.map((disk, index) => (
|
||||
<div key={index} className="bg-shell-bg/30 rounded-lg p-2">
|
||||
<div className="flex items-center justify-between text-xs mb-1">
|
||||
<span className="text-shell-accent font-mono truncate max-w-[120px]" title={disk.mount}>
|
||||
{disk.mount}
|
||||
</span>
|
||||
<span className="text-shell-text-dim text-[10px]" title={disk.device}>
|
||||
{disk.type !== 'unknown' ? disk.type : disk.device.split('/').pop()}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between text-xs mb-1">
|
||||
<span className="text-shell-text-dim">使用</span>
|
||||
<span className="text-shell-text">{disk.used} / {disk.total}</span>
|
||||
</div>
|
||||
<div className="h-1.5 bg-shell-border/50 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full rounded-full transition-all duration-300"
|
||||
style={{
|
||||
width: `${parseInt(disk.percent) || 0}%`,
|
||||
backgroundColor: parseInt(disk.percent) > 80 ? '#f85149' : parseInt(disk.percent) > 60 ? '#d29922' : '#58a6ff'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-right text-[10px] text-shell-text-dim mt-0.5">
|
||||
{disk.percent}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<UsageBar
|
||||
label="使用率"
|
||||
used={systemInfo.diskUsed}
|
||||
total={systemInfo.disk}
|
||||
percent={parseInt(systemInfo.diskPercent) || 0}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user