mirror of
https://github.com/hi2shark/nazhua.git
synced 2026-01-19 02:30:43 +08:00
Compare commits
5 Commits
dbecdcf379
...
066aaaa088
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
066aaaa088 | ||
|
|
a2b55c5cca | ||
|
|
94f602cbb5 | ||
|
|
dbe5e5fd02 | ||
|
|
e278637525 |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nazhua",
|
"name": "nazhua",
|
||||||
"version": "0.4.19",
|
"version": "0.4.20",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@ -36,10 +36,29 @@ export default (
|
|||||||
},
|
},
|
||||||
formatter: (params) => {
|
formatter: (params) => {
|
||||||
const time = dayjs(parseInt(params[0].axisValue, 10)).format('YYYY.MM.DD HH:mm');
|
const time = dayjs(parseInt(params[0].axisValue, 10)).format('YYYY.MM.DD HH:mm');
|
||||||
let res = `${time}<br>`;
|
let res = `<p style="font-weight: bold; color: #ff6;">${time}</p>`;
|
||||||
|
if (params.length < 10) {
|
||||||
params.forEach((i) => {
|
params.forEach((i) => {
|
||||||
res += `${i.marker} ${i.seriesName}: ${i.value[1]}ms<br>`;
|
res += `${i.marker} ${i.seriesName}: ${i.value[1]}ms<br>`;
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
res += '<table>';
|
||||||
|
let trEnd = false;
|
||||||
|
params.forEach((i, index) => {
|
||||||
|
if (index % 2 === 0) {
|
||||||
|
res += '<tr>';
|
||||||
|
}
|
||||||
|
res += `<td style="padding: 0 4px;">${i.marker} ${i.seriesName}: ${i.value[1]}ms</td>`;
|
||||||
|
if (index % 2 === 1) {
|
||||||
|
res += '</tr>';
|
||||||
|
trEnd = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!trEnd) {
|
||||||
|
res += '</tr>';
|
||||||
|
}
|
||||||
|
res += '</table>';
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
backgroundColor: mode === 'dark' ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 255, 255, 0.7)',
|
backgroundColor: mode === 'dark' ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 255, 255, 0.7)',
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
* V1版数据加载
|
* V1版数据加载
|
||||||
*/
|
*/
|
||||||
import store from '@/store';
|
import store from '@/store';
|
||||||
|
import validate from '@/utils/validate';
|
||||||
import { Mapping } from '@/utils/object-mapping';
|
import { Mapping } from '@/utils/object-mapping';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,6 +98,14 @@ export default function (v1Data) {
|
|||||||
break;
|
break;
|
||||||
case '_$mapping':
|
case '_$mapping':
|
||||||
v0Data[key] = Mapping.each(magics[$magic[1]], v1Data);
|
v0Data[key] = Mapping.each(magics[$magic[1]], v1Data);
|
||||||
|
if (key === 'State') {
|
||||||
|
// 修复Load1、Load5、Load15字段为空时的问题
|
||||||
|
['Load1', 'Load5', 'Load15'].forEach((k) => {
|
||||||
|
if (!validate.isSet(v0Data[key][k])) {
|
||||||
|
v0Data[key][k] = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -166,10 +166,8 @@ const showCates = ref({});
|
|||||||
|
|
||||||
const monitorData = ref([]);
|
const monitorData = ref([]);
|
||||||
|
|
||||||
const accpetShowTime = computed(() => {
|
const now = ref(Date.now());
|
||||||
const now = store.state.serverTime || Date.now();
|
const accpetShowTime = computed(() => now.value - (minute.value * 60 * 1000));
|
||||||
return now - (minute.value * 60 * 1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
const minuteActiveArrowStyle = computed(() => {
|
const minuteActiveArrowStyle = computed(() => {
|
||||||
const index = minutes.findIndex((i) => i.value === minute.value);
|
const index = minutes.findIndex((i) => i.value === minute.value);
|
||||||
@ -308,6 +306,7 @@ function switchRefresh() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toggleMinute(value) {
|
function toggleMinute(value) {
|
||||||
|
now.value = store.state.serverTime || Date.now();
|
||||||
minute.value = value;
|
minute.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,6 +327,7 @@ async function loadMonitor() {
|
|||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
|
now.value = store.state.serverTime || Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
let loadMonitorTimer = null;
|
let loadMonitorTimer = null;
|
||||||
|
|||||||
162
src/views/components/server-list/row/server-list-column.vue
Normal file
162
src/views/components/server-list/row/server-list-column.vue
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="list-column"
|
||||||
|
:class="`list-column--${prop}`"
|
||||||
|
:style="columnStyle"
|
||||||
|
>
|
||||||
|
<div class="list-column-content">
|
||||||
|
<span class="item-label">{{ label }}</span>
|
||||||
|
<div class="item-content">
|
||||||
|
<template v-if="slotContent">
|
||||||
|
<slot />
|
||||||
|
</template>
|
||||||
|
<template v-if="slotValue">
|
||||||
|
<span class="item-text item-value">
|
||||||
|
<slot name="value" />
|
||||||
|
</span>
|
||||||
|
<span class="item-text item-unit">
|
||||||
|
<slot name="unit" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<span class="item-text item-value">{{ value }}</span>
|
||||||
|
<span class="item-text item-unit">{{ unit }}</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
/**
|
||||||
|
* 服务器信息列表列
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
computed,
|
||||||
|
} from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
prop: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
unit: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
slotContent: {
|
||||||
|
type: [String, Boolean],
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
slotValue: {
|
||||||
|
type: [String, Boolean],
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const columnStyle = computed(() => {
|
||||||
|
const style = {};
|
||||||
|
const width = parseInt(props.width, 10);
|
||||||
|
if (Number.isNaN(width) === false) {
|
||||||
|
style.width = `${width}px`;
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.list-column {
|
||||||
|
width: 50px;
|
||||||
|
|
||||||
|
.list-column-content {
|
||||||
|
--list-column-label-height: 16px;
|
||||||
|
--list-column-value-height: 24px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: var(--list-item-height);
|
||||||
|
|
||||||
|
.item-label {
|
||||||
|
padding-top: 6px; // 视觉修正
|
||||||
|
line-height: var(--list-column-label-height);
|
||||||
|
font-size: 12px;
|
||||||
|
color: #bbb;
|
||||||
|
}
|
||||||
|
.item-content {
|
||||||
|
line-height: var(--list-column-value-height);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--duration {
|
||||||
|
.item-value {
|
||||||
|
color: var(--duration-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--load {
|
||||||
|
.item-value {
|
||||||
|
color: var(--load-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--transfer {
|
||||||
|
width: 80px;
|
||||||
|
.item-value {
|
||||||
|
color: var(--transfer-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--inTransfer {
|
||||||
|
.item-value {
|
||||||
|
color: var(--transfer-in-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--outTransfer {
|
||||||
|
.item-value {
|
||||||
|
color: var(--transfer-out-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--inSpeed {
|
||||||
|
.item-value {
|
||||||
|
color: var(--net-speed-in-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--outSpeed {
|
||||||
|
.item-value {
|
||||||
|
color: var(--net-speed-out-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--remaining-time {
|
||||||
|
width: 60px;
|
||||||
|
.value-text {
|
||||||
|
color: #74dbef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--billing {
|
||||||
|
width: 60px;
|
||||||
|
.value-text {
|
||||||
|
color: var(--list-item-price-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,49 +1,32 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<server-list-column
|
||||||
v-if="extraFields?.remainingTime"
|
v-if="extraFields?.remainingTime"
|
||||||
class="list-column-item list-column-item--remaining-time"
|
prop="remaining-time"
|
||||||
>
|
label="剩余"
|
||||||
<div class="list-column-item-content">
|
:value="billAndPlan?.remainingTime?.value || '-'"
|
||||||
<span class="item-label">剩余</span>
|
/>
|
||||||
<div class="item-content">
|
<server-list-column
|
||||||
<span class="text-item value-text">{{ billAndPlan?.remainingTime?.value || '-' }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="extraFields?.billing"
|
v-if="extraFields?.billing"
|
||||||
class="list-column-item list-column-item--billing"
|
prop="billing"
|
||||||
>
|
label="费用"
|
||||||
<div class="list-column-item-content">
|
:value="billAndPlan?.billing?.value || '-'"
|
||||||
<span
|
/>
|
||||||
v-if="!billAndPlan?.billing?.isFree && billAndPlan?.billing?.label"
|
<server-list-column
|
||||||
class="item-label"
|
|
||||||
>
|
|
||||||
{{ billAndPlan.billing.label }}
|
|
||||||
</span>
|
|
||||||
<div class="item-content">
|
|
||||||
<span class="text-item value-text">{{ billAndPlan?.billing?.value || '-' }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="extraFields?.orderLink"
|
v-if="extraFields?.orderLink"
|
||||||
class="list-column-item list-column-item--order-link"
|
prop="order-link"
|
||||||
|
label="链接"
|
||||||
|
wdith="80"
|
||||||
|
:slot-content="true"
|
||||||
>
|
>
|
||||||
<div class="list-column-item-content">
|
|
||||||
<span class="item-label">链接</span>
|
|
||||||
<div class="item-content">
|
|
||||||
<span
|
<span
|
||||||
v-if="showBuyBtn"
|
v-if="showBuyBtn"
|
||||||
class="text-item value-text"
|
class="order-link"
|
||||||
@click="toBuy"
|
@click="toBuy"
|
||||||
>
|
>
|
||||||
{{ buyBtnText }}
|
{{ buyBtnText }}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</div>
|
</server-list-column>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -59,6 +42,8 @@ import config from '@/config';
|
|||||||
|
|
||||||
import handleServerBillAndPlan from '@/views/composable/server-bill-and-plan';
|
import handleServerBillAndPlan from '@/views/composable/server-bill-and-plan';
|
||||||
|
|
||||||
|
import ServerListColumn from './server-list-column.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
info: {
|
info: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -81,60 +66,15 @@ const {
|
|||||||
const buyBtnText = computed(() => config.nazhua.buyBtnText || '购买');
|
const buyBtnText = computed(() => config.nazhua.buyBtnText || '购买');
|
||||||
const showBuyBtn = computed(() => !!props.info?.PublicNote?.customData?.orderLink);
|
const showBuyBtn = computed(() => !!props.info?.PublicNote?.customData?.orderLink);
|
||||||
|
|
||||||
// function toBuy() {
|
function toBuy() {
|
||||||
// const decodeUrl = decodeURIComponent(props.info?.PublicNote?.customData?.orderLink);
|
const decodeUrl = decodeURIComponent(props.info?.PublicNote?.customData?.orderLink);
|
||||||
// window.open(decodeUrl, '_blank');
|
window.open(decodeUrl, '_blank');
|
||||||
// }
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.list-column-item {
|
.order-link {
|
||||||
|
|
||||||
.list-column-item-content {
|
|
||||||
--item-content-label-height: 16px;
|
|
||||||
--item-content-value-height: 24px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
height: var(--list-item-height);
|
|
||||||
|
|
||||||
.item-label {
|
|
||||||
padding-top: 6px; // 视觉修正
|
|
||||||
line-height: var(--item-content-label-height);
|
|
||||||
font-size: 12px;
|
|
||||||
color: #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-content {
|
|
||||||
line-height: var(--item-content-value-height);
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--remaining-time {
|
|
||||||
width: 60px;
|
|
||||||
|
|
||||||
.value-text {
|
|
||||||
color: #74dbef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--billing {
|
|
||||||
width: 60px;
|
|
||||||
|
|
||||||
.value-text {
|
|
||||||
color: var(--list-item-price-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--order-link {
|
|
||||||
width: 60px;
|
|
||||||
|
|
||||||
.value-text {
|
|
||||||
color: var(--list-item-buy-link-color);
|
color: var(--list-item-buy-link-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,18 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<server-list-column
|
||||||
v-for="item in serverRealTimeList"
|
v-for="item in serverRealTimeList"
|
||||||
:key="item.key"
|
:key="item.key"
|
||||||
class="list-column-item list-column-item--real-time"
|
:prop="item.key"
|
||||||
:class="`list-column-item--real-time-${item.key}`"
|
:label="item.label"
|
||||||
>
|
:value="item.show ? item?.value : '-'"
|
||||||
<div class="real-time-content">
|
:unit="item.show ? item?.unit : ''"
|
||||||
<span class="item-label">{{ item.label }}</span>
|
/>
|
||||||
<div class="item-content">
|
|
||||||
<span class="item-value">{{ item.show ? item?.value : '-' }}</span>
|
|
||||||
<span class="item-unit item-text">{{ item.show ? item?.unit : '' }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -24,6 +18,8 @@ import {
|
|||||||
} from 'vue';
|
} from 'vue';
|
||||||
import handleServerRealTime from '@/views/composable/server-real-time';
|
import handleServerRealTime from '@/views/composable/server-real-time';
|
||||||
|
|
||||||
|
import ServerListColumn from './server-list-column.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
info: {
|
info: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -47,59 +43,3 @@ const {
|
|||||||
serverRealTimeListTpls: props.serverRealTimeListTpls,
|
serverRealTimeListTpls: props.serverRealTimeListTpls,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.list-column-item {
|
|
||||||
.real-time-content {
|
|
||||||
--real-time-label-height: 16px;
|
|
||||||
--real-time-value-height: 24px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
height: var(--list-item-height);
|
|
||||||
|
|
||||||
.item-label {
|
|
||||||
padding-top: 6px; // 视觉修正
|
|
||||||
line-height: var(--real-time-label-height);
|
|
||||||
font-size: 12px;
|
|
||||||
color: #ccc;
|
|
||||||
}
|
|
||||||
.item-content {
|
|
||||||
line-height: var(--real-time-value-height);
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--real-time-duration {
|
|
||||||
width: 50px;
|
|
||||||
.item-value {
|
|
||||||
color: var(--duration-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&--real-time-load {
|
|
||||||
width: 50px;
|
|
||||||
.item-value {
|
|
||||||
color: var(--load-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&--real-time-transfer {
|
|
||||||
width: 80px;
|
|
||||||
.item-value {
|
|
||||||
color: var(--transfer-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&--real-time-inSpeed {
|
|
||||||
width: 50px;
|
|
||||||
.item-value {
|
|
||||||
color: var(--net-speed-in-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&--real-time-outSpeed {
|
|
||||||
width: 50px;
|
|
||||||
.item-value {
|
|
||||||
color: var(--net-speed-out-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
}"
|
}"
|
||||||
@click="openDetail"
|
@click="openDetail"
|
||||||
>
|
>
|
||||||
|
<div class="row-left-box">
|
||||||
<div class="list-column-item list-column-item--server-flag">
|
<div class="list-column-item list-column-item--server-flag">
|
||||||
<span
|
<span
|
||||||
class="server-flag"
|
class="server-flag"
|
||||||
@ -26,16 +27,30 @@
|
|||||||
{{ info.Name }}
|
{{ info.Name }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-column-item list-column-item--server-system">
|
<server-list-column
|
||||||
<span :class="platformLogoIconClassName" />
|
prop="server-flag"
|
||||||
</div>
|
label="地区"
|
||||||
<div class="list-column-item list-column-item--cpu-mem">
|
:value="info?.Host?.CountryCode?.toUpperCase() || 'UN'"
|
||||||
<span class="core-mem">{{ cpuAndMemAndDisk || '-' }}</span>
|
/>
|
||||||
|
<server-list-column
|
||||||
|
prop="server-system"
|
||||||
|
label="系统"
|
||||||
|
:value="platformSystemLabel || '-'"
|
||||||
|
/>
|
||||||
|
<server-list-column
|
||||||
|
prop="cpu-mem"
|
||||||
|
label="配置"
|
||||||
|
width="80"
|
||||||
|
:value="cpuAndMemAndDisk || '-'"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row-center-box">
|
||||||
<server-list-item-status
|
<server-list-item-status
|
||||||
v-if="$config.nazhua.hideListItemStatusDonut !== true"
|
v-if="$config.nazhua.hideListItemStatusDonut !== true"
|
||||||
:info="info"
|
:info="info"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="row-right-box">
|
||||||
<server-list-item-real-time
|
<server-list-item-real-time
|
||||||
v-if="$config.nazhua.hideListItemStat !== true"
|
v-if="$config.nazhua.hideListItemStat !== true"
|
||||||
:info="info"
|
:info="info"
|
||||||
@ -45,6 +60,7 @@
|
|||||||
v-if="$config.nazhua.hideListItemBill !== true"
|
v-if="$config.nazhua.hideListItemBill !== true"
|
||||||
:info="info"
|
:info="info"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</dot-dot-box>
|
</dot-dot-box>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -62,6 +78,7 @@ import {
|
|||||||
import * as hostUtils from '@/utils/host';
|
import * as hostUtils from '@/utils/host';
|
||||||
|
|
||||||
import handleServerInfo from '@/views/composable/server-info';
|
import handleServerInfo from '@/views/composable/server-info';
|
||||||
|
import ServerListColumn from './server-list-column.vue';
|
||||||
import ServerListItemStatus from './server-list-item-status.vue';
|
import ServerListItemStatus from './server-list-item-status.vue';
|
||||||
import ServerListItemRealTime from './server-list-item-real-time.vue';
|
import ServerListItemRealTime from './server-list-item-real-time.vue';
|
||||||
import ServerListItemBill from './server-list-item-bill.vue';
|
import ServerListItemBill from './server-list-item-bill.vue';
|
||||||
@ -82,7 +99,7 @@ const { cpuAndMemAndDisk } = handleServerInfo({
|
|||||||
props,
|
props,
|
||||||
});
|
});
|
||||||
|
|
||||||
const platformLogoIconClassName = computed(() => hostUtils.getPlatformLogoIconClassName(props.info?.Host?.Platform));
|
const platformSystemLabel = computed(() => hostUtils.getSystemOSLabel(props.info?.Host?.Platform));
|
||||||
|
|
||||||
function openDetail() {
|
function openDetail() {
|
||||||
router.push({
|
router.push({
|
||||||
@ -99,7 +116,7 @@ function openDetail() {
|
|||||||
--list-item-height: 64px;
|
--list-item-height: 64px;
|
||||||
--list-item-border-radius: 8px;
|
--list-item-border-radius: 8px;
|
||||||
--list-item-gap: 10px;
|
--list-item-gap: 10px;
|
||||||
--list-item-padding: 20px;
|
--list-item-padding: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -110,6 +127,25 @@ function openDetail() {
|
|||||||
&--offline {
|
&--offline {
|
||||||
filter: grayscale(1);
|
filter: grayscale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.row-left-box,
|
||||||
|
.row-center-box,
|
||||||
|
.row-right-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--list-item-gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-left-box,
|
||||||
|
.row-right-box {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.row-right-box {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
.row-center-box {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-column-item {
|
.list-column-item {
|
||||||
@ -120,6 +156,7 @@ function openDetail() {
|
|||||||
&--server-flag {
|
&--server-flag {
|
||||||
--server-flag-size: 24px;
|
--server-flag-size: 24px;
|
||||||
width: calc(var(--server-flag-size) * 1.5);
|
width: calc(var(--server-flag-size) * 1.5);
|
||||||
|
margin-left: 20px;
|
||||||
.server-flag {
|
.server-flag {
|
||||||
width: calc(var(--server-flag-size) * 1.5);
|
width: calc(var(--server-flag-size) * 1.5);
|
||||||
height: var(--server-flag-size);
|
height: var(--server-flag-size);
|
||||||
@ -128,7 +165,7 @@ function openDetail() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&--server-name {
|
&--server-name {
|
||||||
flex: 1;
|
width: 200px;
|
||||||
|
|
||||||
.server-name {
|
.server-name {
|
||||||
height: 32px;
|
height: 32px;
|
||||||
@ -140,27 +177,5 @@ function openDetail() {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&--server-system {
|
|
||||||
width: 24px;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
&--cpu-mem {
|
|
||||||
width: 100px;
|
|
||||||
.core-mem {
|
|
||||||
height: 30px;
|
|
||||||
line-height: 32px;
|
|
||||||
font-size: 16px;
|
|
||||||
width: 100%;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 针对1440px以下的屏幕
|
|
||||||
@media screen and (max-width: 1440px) {
|
|
||||||
width: 80px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -39,9 +39,11 @@ export function getThreshold(data, tolerance = 2) {
|
|||||||
const lineColorMap = {};
|
const lineColorMap = {};
|
||||||
const lineColors = [];
|
const lineColors = [];
|
||||||
const defaultColors = [
|
const defaultColors = [
|
||||||
'#5470c6', '#91cc75', '#fac858',
|
'#5470C6', '#91CC75', '#FAC858', '#EE6666',
|
||||||
'#ee6666', '#73c0de', '#3ba272',
|
'#73C0DE', '#3BA272', '#FC8452', '#9A60B4',
|
||||||
'#fc8452', '#9a60b4', '#ea7ccc',
|
'#EA7CCC', '#C23531', '#2F4554', '#61A0A8',
|
||||||
|
'#D48265', '#91C7AE', '#749F83', '#CA8622',
|
||||||
|
'#BDA29A', '#6E7074', '#546570', '#C4CCD3',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,20 +78,24 @@ function rgbDistance(color1, color2) {
|
|||||||
* 获取一个随机颜色
|
* 获取一个随机颜色
|
||||||
* @returns {string} 返回一个随机颜色的字符串
|
* @returns {string} 返回一个随机颜色的字符串
|
||||||
*/
|
*/
|
||||||
function getColor() {
|
function getColor(count = 0, len = 0) {
|
||||||
|
// 如果尝试次数超过 3 次,返回固定颜色组里面的颜色
|
||||||
|
if (count > 3) {
|
||||||
|
return defaultColors[len % defaultColors.length];
|
||||||
|
}
|
||||||
const { color } = uniqolor.random({
|
const { color } = uniqolor.random({
|
||||||
saturation: [75, 90],
|
saturation: [75, 90],
|
||||||
lightness: [65, 70],
|
lightness: [65, 70],
|
||||||
differencePoint: 100,
|
differencePoint: 100,
|
||||||
});
|
});
|
||||||
if (lineColors.includes(color)) {
|
if (lineColors.includes(color)) {
|
||||||
return getColor();
|
return getColor(count + 1, len);
|
||||||
}
|
}
|
||||||
if (lineColors.some((i) => rgbDistance(
|
if (lineColors.some((i) => rgbDistance(
|
||||||
hexToRgb(i),
|
hexToRgb(i),
|
||||||
hexToRgb(color),
|
hexToRgb(color),
|
||||||
) < 80)) {
|
) < 50)) {
|
||||||
return getColor();
|
return getColor(count + 1, len);
|
||||||
}
|
}
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
@ -104,14 +110,7 @@ export function getLineColor(name) {
|
|||||||
if (lineColorMap[name]) {
|
if (lineColorMap[name]) {
|
||||||
return lineColorMap[name];
|
return lineColorMap[name];
|
||||||
}
|
}
|
||||||
// 如果默认颜色还有剩余,直接使用
|
const color = getColor(0, lineColors.length);
|
||||||
if (defaultColors.length > 0) {
|
|
||||||
const color = defaultColors.shift();
|
|
||||||
lineColorMap[name] = color;
|
|
||||||
lineColors.push(color);
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
const color = getColor();
|
|
||||||
lineColorMap[name] = color;
|
lineColorMap[name] = color;
|
||||||
lineColors.push(color);
|
lineColors.push(color);
|
||||||
return color;
|
return color;
|
||||||
|
|||||||
@ -122,6 +122,44 @@ export default (params) => {
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const inTransfer = computed(() => {
|
||||||
|
const inStats = hostUtils.calcBinary(props.info?.State?.NetInTransfer || 0);
|
||||||
|
const result = {
|
||||||
|
value: 0,
|
||||||
|
unit: '',
|
||||||
|
};
|
||||||
|
if (inStats.g > 1) {
|
||||||
|
result.value = (inStats.g).toFixed(1) * 1;
|
||||||
|
result.unit = 'G';
|
||||||
|
} else if (inStats.m > 1) {
|
||||||
|
result.value = (inStats.m).toFixed(1) * 1;
|
||||||
|
result.unit = 'M';
|
||||||
|
} else {
|
||||||
|
result.value = (inStats.k).toFixed(1) * 1;
|
||||||
|
result.unit = 'K';
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
|
const outTransfer = computed(() => {
|
||||||
|
const outStats = hostUtils.calcBinary(props.info?.State?.NetOutTransfer || 0);
|
||||||
|
const result = {
|
||||||
|
value: 0,
|
||||||
|
unit: '',
|
||||||
|
};
|
||||||
|
if (outStats.g > 1) {
|
||||||
|
result.value = (outStats.g).toFixed(1) * 1;
|
||||||
|
result.unit = 'G';
|
||||||
|
} else if (outStats.m > 1) {
|
||||||
|
result.value = (outStats.m).toFixed(1) * 1;
|
||||||
|
result.unit = 'M';
|
||||||
|
} else {
|
||||||
|
result.value = (outStats.k).toFixed(1) * 1;
|
||||||
|
result.unit = 'K';
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算入向网速
|
* 计算入向网速
|
||||||
*/
|
*/
|
||||||
@ -184,6 +222,22 @@ export default (params) => {
|
|||||||
unit: transfer.value?.unit,
|
unit: transfer.value?.unit,
|
||||||
show: validate.isSet(transfer.value?.value),
|
show: validate.isSet(transfer.value?.value),
|
||||||
};
|
};
|
||||||
|
case 'inTransfer':
|
||||||
|
return {
|
||||||
|
key,
|
||||||
|
label: '入网流量',
|
||||||
|
value: inTransfer.value?.value,
|
||||||
|
unit: inTransfer.value?.unit,
|
||||||
|
show: validate.isSet(inTransfer.value?.value),
|
||||||
|
};
|
||||||
|
case 'outTransfer':
|
||||||
|
return {
|
||||||
|
key,
|
||||||
|
label: '出网流量',
|
||||||
|
value: outTransfer.value?.value,
|
||||||
|
unit: outTransfer.value?.unit,
|
||||||
|
show: validate.isSet(outTransfer.value?.value),
|
||||||
|
};
|
||||||
case 'inSpeed':
|
case 'inSpeed':
|
||||||
return {
|
return {
|
||||||
key,
|
key,
|
||||||
@ -226,7 +280,7 @@ export default (params) => {
|
|||||||
return {
|
return {
|
||||||
key,
|
key,
|
||||||
label: '负载',
|
label: '负载',
|
||||||
value: (props.info.State?.Load1 || 0).toFixed(2) * 1,
|
value: (props.info.State?.Load1 || 0).toFixed(2),
|
||||||
unit: '',
|
unit: '',
|
||||||
show: validate.isSet(props.info.State?.Load1),
|
show: validate.isSet(props.info.State?.Load1),
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user