mirror of
https://gitee.com/dromara/mayfly-go
synced 2026-05-25 12:25:19 +08:00
153 lines
6.8 KiB
Vue
153 lines
6.8 KiB
Vue
<template>
|
|
<Base
|
|
:resource-label="$t('home.myMachines')"
|
|
:resource-icon="ResourceTypeEnum.Machine.extra.icon"
|
|
:resource-color="ResourceTypeEnum.Machine.extra.iconColor"
|
|
:api-method="machineApi.list"
|
|
ref="baseRef"
|
|
>
|
|
<!-- 自定义列表项 -->
|
|
<template #item="{ resource }">
|
|
<div class="flex flex-col gap-2 p-2.5 border border-[var(--el-border-color-lighter)] rounded-md bg-[var(--el-bg-color)] cursor-pointer transition-all duration-200 min-w-0 max-w-full box-border hover:border-[var(--el-color-primary-light-7)] hover:bg-[var(--el-fill-color-light)] hover:shadow-[0_2px_8px_rgba(0,0,0,0.08)]">
|
|
<div class="flex items-center justify-between gap-2">
|
|
<div class="flex items-center gap-1.5 font-medium text-[13px] text-[var(--el-text-color-primary)] flex-1 min-w-0">
|
|
<SvgIcon :name="ResourceTypeEnum.Machine.extra.icon" :size="16" />
|
|
<span class="overflow-hidden text-ellipsis whitespace-nowrap">{{ resource.name || resource.code }}</span>
|
|
</div>
|
|
<el-tag v-if="resource.stat" size="small" type="success">{{ $t('common.online') }}</el-tag>
|
|
<el-tag v-else size="small" type="danger">{{ $t('common.offline') }}</el-tag>
|
|
</div>
|
|
<div class="flex flex-col gap-1.5 text-[12px] text-[var(--el-text-color-secondary)]">
|
|
<div class="font-['Courier_New',monospace]">{{ resource.ip }}:{{ resource.port }}</div>
|
|
<div v-if="resource.stat" class="flex flex-col gap-1">
|
|
<div class="flex gap-2">
|
|
<span class="text-[11px] font-medium" :class="getCpuUsageClass(100 - resource.stat.cpuIdle) === 'stat-danger' ? 'text-[var(--el-color-danger)]' : getCpuUsageClass(100 - resource.stat.cpuIdle) === 'stat-warning' ? 'text-[var(--el-color-warning)]' : 'text-[var(--el-color-success)]'">
|
|
CPU: {{ (100 - resource.stat.cpuIdle).toFixed(0) }}%
|
|
</span>
|
|
</div>
|
|
<div class="flex gap-2">
|
|
<span
|
|
class="text-[11px] font-medium"
|
|
:class="getMemUsageClass(resource.stat.memTotal - resource.stat.memAvailable, resource.stat.memTotal) === 'stat-danger' ? 'text-[var(--el-color-danger)]' : getMemUsageClass(resource.stat.memTotal - resource.stat.memAvailable, resource.stat.memTotal) === 'stat-warning' ? 'text-[var(--el-color-warning)]' : 'text-[var(--el-color-success)]'"
|
|
>
|
|
MEM: {{ formatByteSize(resource.stat.memTotal - resource.stat.memAvailable) }} /
|
|
{{ formatByteSize(resource.stat.memTotal) }} ({{
|
|
(((resource.stat.memTotal - resource.stat.memAvailable) / resource.stat.memTotal) * 100).toFixed(0)
|
|
}}%)
|
|
</span>
|
|
</div>
|
|
<div v-if="resource.stat.fsInfos && resource.stat.fsInfos.length > 0" class="flex gap-2">
|
|
<span class="text-[11px] font-medium" :class="getDiskUsageClass(resource.stat.fsInfos) === 'stat-danger' ? 'text-[var(--el-color-danger)]' : getDiskUsageClass(resource.stat.fsInfos) === 'stat-warning' ? 'text-[var(--el-color-warning)]' : 'text-[var(--el-color-success)]'">
|
|
DISK: {{ getDiskUsed(resource.stat.fsInfos) }} / {{ getDiskTotal(resource.stat.fsInfos) }} ({{
|
|
getDiskUsage(resource.stat.fsInfos)
|
|
}})
|
|
</span>
|
|
</div>
|
|
<div v-else-if="resource.stat" class="flex gap-2">
|
|
<span class="text-[11px] text-[var(--el-text-color-secondary)]"> DISK: N/A </span>
|
|
</div>
|
|
</div>
|
|
<div v-else class="text-[11px] text-[var(--el-text-color-secondary)]">{{ $t('common.offline') }}</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</Base>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ResourceTypeEnum } from '@/common/commonEnum';
|
|
import SvgIcon from '@/components/svgIcon/index.vue';
|
|
import { machineApi } from '@/views/ops/machine/api';
|
|
import Base from './Base.vue';
|
|
const formatByteSize = (bytes: number): string => {
|
|
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 (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i];
|
|
};
|
|
|
|
// 计算磁盘使用率
|
|
const getDiskUsage = (fSInfos: any[]) => {
|
|
if (!fSInfos || fSInfos.length === 0) return '0%';
|
|
|
|
let totalUsed = 0;
|
|
let totalFree = 0;
|
|
|
|
fSInfos.forEach((fs: any) => {
|
|
totalUsed += fs.used || 0;
|
|
totalFree += fs.free || 0;
|
|
});
|
|
|
|
const total = totalUsed + totalFree;
|
|
if (total === 0) return '0%';
|
|
|
|
const usage = (totalUsed / total) * 100;
|
|
return usage.toFixed(0) + '%';
|
|
};
|
|
|
|
// 获取CPU使用率颜色类
|
|
const getCpuUsageClass = (cpuUsage: number) => {
|
|
if (cpuUsage > 90) return 'stat-danger';
|
|
if (cpuUsage > 70) return 'stat-warning';
|
|
return 'stat-success';
|
|
};
|
|
|
|
// 获取内存使用率颜色类
|
|
const getMemUsageClass = (memUsed: number, memTotal: number) => {
|
|
if (memTotal === 0) return 'stat-success';
|
|
const usage = (memUsed / memTotal) * 100;
|
|
if (usage > 90) return 'stat-danger';
|
|
if (usage > 70) return 'stat-warning';
|
|
return 'stat-success';
|
|
};
|
|
|
|
// 获取磁盘使用率颜色类
|
|
const getDiskUsageClass = (fSInfos: any[]) => {
|
|
if (!fSInfos || fSInfos.length === 0) return 'stat-success';
|
|
|
|
let totalUsed = 0;
|
|
let totalFree = 0;
|
|
|
|
fSInfos.forEach((fs: any) => {
|
|
totalUsed += fs.used || 0;
|
|
totalFree += fs.free || 0;
|
|
});
|
|
|
|
const total = totalUsed + totalFree;
|
|
if (total === 0) return 'stat-success';
|
|
|
|
const usage = (totalUsed / total) * 100;
|
|
if (usage > 90) return 'stat-danger';
|
|
if (usage > 70) return 'stat-warning';
|
|
return 'stat-success';
|
|
};
|
|
|
|
// 计算磁盘已用空间
|
|
const getDiskUsed = (fSInfos: any[]) => {
|
|
if (!fSInfos || fSInfos.length === 0) return '0 B';
|
|
|
|
let totalUsed = 0;
|
|
fSInfos.forEach((fs: any) => {
|
|
totalUsed += fs.used || 0;
|
|
});
|
|
|
|
return formatByteSize(totalUsed);
|
|
};
|
|
|
|
// 计算磁盘总空间
|
|
const getDiskTotal = (fSInfos: any[]) => {
|
|
if (!fSInfos || fSInfos.length === 0) return '0 B';
|
|
|
|
let totalUsed = 0;
|
|
let totalFree = 0;
|
|
|
|
fSInfos.forEach((fs: any) => {
|
|
totalUsed += fs.used || 0;
|
|
totalFree += fs.free || 0;
|
|
});
|
|
|
|
return formatByteSize(totalUsed + totalFree);
|
|
};
|
|
</script>
|