160 lines
4.2 KiB
Vue
160 lines
4.2 KiB
Vue
<script setup>
|
|
import {fitToRightByteUnit, percentageToStatus} from "@/tools";
|
|
import {useClipboard} from "@vueuse/core";
|
|
import {ElMessage, ElMessageBox} from "element-plus";
|
|
import {post} from "@/net";
|
|
|
|
const props = defineProps({
|
|
data: Object,
|
|
update: Function
|
|
})
|
|
|
|
const { copy } = useClipboard()
|
|
const copyIp = () => {
|
|
copy(props.data.ip).then(() => ElMessage.success('成功复制IP地址到剪贴板'))
|
|
}
|
|
|
|
const rename = () => ElMessageBox.prompt('请输入新的服务器主机名称', '修改名称', {
|
|
confirmButtonText: '确认',
|
|
cancelButtonText: '取消',
|
|
inputValue: props.data.name,
|
|
inputPattern:
|
|
/^[a-zA-Z0-9_\u4e00-\u9fa5]{1,10}$/,
|
|
inputErrorMessage: '名称只能包含中英文字符、数字和下划线',
|
|
}).then(({ value }) => post('/api/monitor/rename', {
|
|
id: props.data.id,
|
|
name: value
|
|
}, () => {
|
|
ElMessage.success('主机名称已更新')
|
|
props.update()
|
|
})
|
|
).catch(() => {})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="instance-card">
|
|
<div style="display: flex;justify-content: space-between">
|
|
<div>
|
|
<div class="title">
|
|
<span :class="`flag-icon flag-icon-${data.location}`"></span>
|
|
<span style="margin: 0 10px">{{ data.name }}</span>
|
|
<i @click.stop="rename" class="fa-solid fa-pen-to-square interact-item"></i>
|
|
</div>
|
|
<div class="os">
|
|
操作系统: {{`${data.osName} ${data.osVersion}`}}
|
|
</div>
|
|
</div>
|
|
<div class="status" v-if="data.online">
|
|
<i style="color: #18cb18" class="fa-solid fa-circle-play"></i>
|
|
<span style="margin-left: 5px">运行中</span>
|
|
</div>
|
|
<div class="status" v-else>
|
|
<i style="color: #8a8a8a" class="fa-solid fa-circle-stop"></i>
|
|
<span style="margin-left: 5px">离线</span>
|
|
</div>
|
|
</div>
|
|
<el-divider style="margin: 10px 0"/>
|
|
<div class="network">
|
|
<span style="margin-right: 10px">公网IP: {{data.ip}}</span>
|
|
<i class="fa-solid fa-copy interact-item" style="color: dodgerblue" @click.stop="copyIp"></i>
|
|
</div>
|
|
<div class="cpu">
|
|
<span style="margin-right: 10px">处理器: {{data.cpuName}}</span>
|
|
</div>
|
|
<div class="hardware">
|
|
<i class="fa-solid fa-microchip"></i>
|
|
<span style="margin-right: 10px">{{` ${data.cpuCore} CPU`}}</span>
|
|
<i class="fa-solid fa-memory"></i>
|
|
<span>{{` ${data.memory.toFixed(1)} GB`}}</span>
|
|
</div>
|
|
<div class="progress">
|
|
<span>{{ `CPU: ${(data.cpuUsage * 100).toFixed(1)} %` }}</span>
|
|
<el-progress :percentage="data.cpuUsage * 100" :stroke-width="5" :show-text="false"
|
|
:status="percentageToStatus(data.cpuUsage * 100)"/>
|
|
</div>
|
|
<div class="progress" style="margin-top: 7px">
|
|
<span>内存: <b>{{ data.memoryUsage.toFixed(1) }}</b> GB</span>
|
|
<el-progress :percentage="data.memoryUsage/data.memory * 100" :stroke-width="5" :show-text="false"
|
|
:status="percentageToStatus(data.memoryUsage/data.memory * 100)"/>
|
|
</div>
|
|
<div class="network-flow">
|
|
<div>网络流量</div>
|
|
<div>
|
|
<i class="fa-solid fa-arrow-up"></i>
|
|
<span>{{` ${fitToRightByteUnit(data.networkUpload, 'KB')}/s`}}</span>
|
|
<el-divider direction="vertical"/>
|
|
<i class="fa-solid fa-arrow-down"></i>
|
|
<span>{{` ${fitToRightByteUnit(data.networkDownload, 'KB')}/s`}}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.dark .instance-card { color: #d9d9d9
|
|
}
|
|
.instance-card {
|
|
width: 320px;
|
|
background-color: var(--el-bg-color);
|
|
border-radius: 5px;
|
|
padding: 15px;
|
|
box-sizing: border-box;
|
|
color: #6b6b6b;
|
|
transition: scale .3s;
|
|
|
|
&:hover {
|
|
cursor: pointer;
|
|
scale: 1.02;
|
|
}
|
|
|
|
.interact-item {
|
|
transition: .3s;
|
|
|
|
&:hover {
|
|
cursor: pointer;
|
|
scale: 1.1;
|
|
opacity: 0.8;
|
|
}
|
|
}
|
|
|
|
.os {
|
|
font-size: 13px;
|
|
color: grey;
|
|
}
|
|
|
|
.status {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.title {
|
|
font-size: 15px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.network {
|
|
font-size: 13px;
|
|
}
|
|
|
|
.cpu {
|
|
font-size: 13px;
|
|
}
|
|
|
|
.hardware {
|
|
margin-top: 5px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.progress {
|
|
margin-top: 15px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.network-flow {
|
|
margin-top: 10px;
|
|
font-size: 12px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
}
|
|
</style>
|