mirror of
https://github.com/hi2shark/nazhua.git
synced 2026-01-11 22:50:42 +08:00
✨ 添加服务器状态进度组件,优化样式和交互,调整背景位置,更新状态计算逻辑
This commit is contained in:
parent
5b1a54beeb
commit
5532d48ffb
@ -3,6 +3,8 @@ window.$$nazhuaConfig = {
|
||||
// freeAmount: '白嫖', // 免费服务的费用名称
|
||||
// infinityCycle: '无限', // 无限周期名称
|
||||
// buyBtnText: '购买', // 购买按钮文案
|
||||
// listServerStatusType: 'progress', // 服务器状态类型--列表
|
||||
// detailServerStatusType: 'progress', // 服务器状态类型--详情页
|
||||
// hideNavbarServerCount: false, // 隐藏服务器数量
|
||||
// hideNavbarServerStat: false, // 隐藏服务器统计
|
||||
// hideListItemStatusDonut: true, // 隐藏列表项的饼图
|
||||
|
||||
@ -39,7 +39,7 @@ import LayoutFooter from './components/footer.vue';
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
background: var(--layout-bg-color) url('~@/assets/images/bg.webp') no-repeat 50% 0%;
|
||||
background: var(--layout-bg-color) url('~@/assets/images/bg.webp') no-repeat 50% 100%;
|
||||
background-size: 100% auto;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,9 +2,10 @@
|
||||
<div class="server-status-and-real-time">
|
||||
<div
|
||||
class="server-status-group"
|
||||
:class="'status-list--' + serverStatusList.length"
|
||||
:class="'type--' + componentName + ' status-list--' + serverStatusList.length"
|
||||
>
|
||||
<server-status-item
|
||||
<component
|
||||
:is="componentMaps[componentName]"
|
||||
v-for="item in serverStatusList"
|
||||
:key="item.type"
|
||||
:type="item.type"
|
||||
@ -23,10 +24,14 @@
|
||||
/**
|
||||
* 服务器状态组
|
||||
*/
|
||||
|
||||
import config from '@/config';
|
||||
|
||||
import handleServerStatus from '@/views/composable/server-status';
|
||||
|
||||
import ServerStatusItem from '@/views/components/server/server-status.vue';
|
||||
import ServerListItemRealTime from '@/views/components/server/server-real-time.vue';
|
||||
import ServerStatusDonut from '@/views/components/server/server-status-donut.vue';
|
||||
import ServerStatusProgress from '@/views/components/server/server-status-progress.vue';
|
||||
|
||||
const props = defineProps({
|
||||
info: {
|
||||
@ -35,6 +40,16 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const componentMaps = {
|
||||
donut: ServerStatusDonut,
|
||||
progress: ServerStatusProgress,
|
||||
};
|
||||
|
||||
const componentName = [
|
||||
'donut',
|
||||
'progress',
|
||||
].includes(config.nazhua.detailServerStatusType) ? config.nazhua.detailServerStatusType : 'donut';
|
||||
|
||||
const {
|
||||
serverStatusList,
|
||||
} = handleServerStatus({
|
||||
@ -87,72 +102,85 @@ const {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&.status-list--3 {
|
||||
--server-status-size: 200px;
|
||||
--server-status-val-text-font-size: 32px;
|
||||
--server-status-label-font-size: 18px;
|
||||
--server-status-content-font-size: 16px;
|
||||
}
|
||||
|
||||
&.status-list--4 {
|
||||
--server-status-size: 180px;
|
||||
--server-status-val-text-font-size: 28px;
|
||||
--server-status-label-font-size: 16px;
|
||||
--server-status-content-font-size: 16px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
// gap: 10px 20px;
|
||||
|
||||
&.status-list--4 {
|
||||
--server-status-size: 160px;
|
||||
--server-status-val-text-font-size: 26px;
|
||||
--server-status-label-font-size: 15px;
|
||||
--server-status-content-font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 720px) {
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
&.type--donut {
|
||||
&.status-list--3 {
|
||||
--server-status-size: 100px;
|
||||
--server-status-val-text-font-size: 14px;
|
||||
--server-status-label-font-size: 12px;
|
||||
--server-status-content-font-size: 12px;
|
||||
--server-status-size: 200px;
|
||||
--server-status-val-text-font-size: 32px;
|
||||
--server-status-label-font-size: 18px;
|
||||
--server-status-content-font-size: 16px;
|
||||
}
|
||||
|
||||
&.status-list--4 {
|
||||
padding: 0 10px;
|
||||
gap: 10px 0;
|
||||
--server-status-size: 120px;
|
||||
--server-status-val-text-font-size: 16px;
|
||||
--server-status-label-font-size: 14px;
|
||||
--server-status-content-font-size: 14px;
|
||||
--server-status-size: 180px;
|
||||
--server-status-val-text-font-size: 28px;
|
||||
--server-status-label-font-size: 16px;
|
||||
--server-status-content-font-size: 16px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
// gap: 10px 20px;
|
||||
|
||||
&.status-list--4 {
|
||||
--server-status-size: 160px;
|
||||
--server-status-val-text-font-size: 26px;
|
||||
--server-status-label-font-size: 15px;
|
||||
--server-status-content-font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 720px) {
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
&.status-list--3 {
|
||||
--server-status-size: 100px;
|
||||
--server-status-val-text-font-size: 14px;
|
||||
--server-status-label-font-size: 12px;
|
||||
--server-status-content-font-size: 12px;
|
||||
}
|
||||
|
||||
&.status-list--4 {
|
||||
padding: 0 10px;
|
||||
gap: 10px 0;
|
||||
--server-status-size: 120px;
|
||||
--server-status-val-text-font-size: 16px;
|
||||
--server-status-label-font-size: 14px;
|
||||
--server-status-content-font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 400px) {
|
||||
&.status-list--3 {
|
||||
--server-status-size: 90px;
|
||||
--server-status-val-text-font-size: 12px;
|
||||
--server-status-label-font-size: 12px;
|
||||
--server-status-content-font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 320px) {
|
||||
&.status-list--3 {
|
||||
--server-status-size: 90px;
|
||||
}
|
||||
&.status-list--4 {
|
||||
padding: 0;
|
||||
--server-status-size: 100px;
|
||||
--server-status-val-text-font-size: 14px;
|
||||
--server-status-label-font-size: 12px;
|
||||
--server-status-content-font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 400px) {
|
||||
&.status-list--3 {
|
||||
--server-status-size: 90px;
|
||||
--server-status-val-text-font-size: 12px;
|
||||
--server-status-label-font-size: 12px;
|
||||
--server-status-content-font-size: 12px;
|
||||
}
|
||||
}
|
||||
&.type--progress {
|
||||
padding: 0 5px;
|
||||
gap: 10px;
|
||||
|
||||
@media screen and (max-width: 320px) {
|
||||
&.status-list--3 {
|
||||
--server-status-size: 90px;
|
||||
}
|
||||
&.status-list--4 {
|
||||
padding: 0;
|
||||
--server-status-size: 100px;
|
||||
--server-status-val-text-font-size: 14px;
|
||||
--server-status-label-font-size: 12px;
|
||||
--server-status-content-font-size: 12px;
|
||||
--progress-bar-height: 24px;
|
||||
|
||||
@media screen and (max-width: 350px) {
|
||||
--progress-bar-height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<div class="server-list-item-bill">
|
||||
<div class="remaining-time-info">
|
||||
<template
|
||||
<div class="left-box">
|
||||
<div
|
||||
v-if="billAndPlan.remainingTime"
|
||||
class="remaining-time-info"
|
||||
>
|
||||
<span class="icon">
|
||||
<span class="ri-hourglass-fill" />
|
||||
@ -20,7 +21,7 @@
|
||||
>
|
||||
<span class="text-item value-text">{{ billAndPlan.remainingTime.value }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="tagList"
|
||||
class="tag-list"
|
||||
@ -116,6 +117,10 @@ const tagList = computed(() => {
|
||||
background: rgba(#000, 0.3);
|
||||
box-shadow: 0 -2px 4px rgba(#000, 0.5);
|
||||
|
||||
.left-box {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.remaining-time-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -147,6 +152,7 @@ const tagList = computed(() => {
|
||||
.tag-list {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
padding-left: 15px;
|
||||
// 折行隐藏
|
||||
height: 18px;
|
||||
overflow: hidden;
|
||||
@ -166,7 +172,7 @@ const tagList = computed(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
padding: 0 15px;
|
||||
padding-right: 15px;
|
||||
gap: 10px;
|
||||
|
||||
.billing-info {
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
<template>
|
||||
<div class="server-list-item-status">
|
||||
<server-status-item
|
||||
<div
|
||||
class="server-list-item-status"
|
||||
:class="'type--' + componentName"
|
||||
>
|
||||
<component
|
||||
:is="componentMaps[componentName]"
|
||||
v-for="item in serverStatusList"
|
||||
:key="item.type"
|
||||
:type="item.type"
|
||||
@ -16,8 +20,12 @@
|
||||
/**
|
||||
* 服务器状态盒子
|
||||
*/
|
||||
|
||||
import config from '@/config';
|
||||
|
||||
import handleServerStatus from '@/views/composable/server-status';
|
||||
import ServerStatusItem from '@/views/components/server/server-status.vue';
|
||||
import ServerStatusDonut from '@/views/components/server/server-status-donut.vue';
|
||||
import ServerStatusProgress from '@/views/components/server/server-status-progress.vue';
|
||||
|
||||
const props = defineProps({
|
||||
info: {
|
||||
@ -26,6 +34,16 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const componentMaps = {
|
||||
donut: ServerStatusDonut,
|
||||
progress: ServerStatusProgress,
|
||||
};
|
||||
|
||||
const componentName = [
|
||||
'donut',
|
||||
'progress',
|
||||
].includes(config.nazhua.listServerStatusType) ? config.nazhua.listServerStatusType : 'donut';
|
||||
|
||||
const {
|
||||
serverStatusList,
|
||||
} = handleServerStatus({
|
||||
@ -41,41 +59,55 @@ const {
|
||||
justify-content: space-between;
|
||||
padding: 0 5px;
|
||||
|
||||
--server-status-size: 120px;
|
||||
--server-status-val-text-font-size: 20px;
|
||||
--server-status-label-font-size: 14px;
|
||||
// 针对1440px以下的屏幕(新Mac笔记本或者windows缩放)
|
||||
@media screen and (max-width: 1440px) {
|
||||
padding: 0;
|
||||
--server-status-size: 110px;
|
||||
--server-status-val-text-font-size: 18px;
|
||||
--server-status-label-font-size: 14px;
|
||||
&.type--progress {
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
|
||||
--progress-bar-height: 20px;
|
||||
|
||||
@media screen and (max-width: 350px) {
|
||||
--progress-bar-height: 16px;
|
||||
padding: 0 15px;
|
||||
}
|
||||
}
|
||||
// 针对1280px以下的屏幕(Mac居多)
|
||||
@media screen and (max-width: 1280px) {
|
||||
padding: 0 8px;
|
||||
--server-status-size: 100px;
|
||||
--server-status-val-text-font-size: 16px;
|
||||
--server-status-label-font-size: 12px;
|
||||
}
|
||||
// 针对1024px以下的屏幕(平板居多)
|
||||
@media screen and (max-width: 1024px) {
|
||||
// padding: 0 8px;
|
||||
|
||||
&.type--donut {
|
||||
--server-status-size: 120px;
|
||||
--server-status-val-text-font-size: 20px;
|
||||
--server-status-label-font-size: 16px;
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
padding: 0 8px;
|
||||
--server-status-size: 100px;
|
||||
--server-status-val-text-font-size: 16px;
|
||||
--server-status-label-font-size: 12px;
|
||||
}
|
||||
@media screen and (max-width: 375px) {
|
||||
padding: 0;
|
||||
--server-status-size: 90px;
|
||||
--server-status-val-text-font-size: 14px;
|
||||
--server-status-label-font-size: 12px;
|
||||
--server-status-label-font-size: 14px;
|
||||
// 针对1440px以下的屏幕(新Mac笔记本或者windows缩放)
|
||||
@media screen and (max-width: 1440px) {
|
||||
padding: 0;
|
||||
--server-status-size: 110px;
|
||||
--server-status-val-text-font-size: 18px;
|
||||
--server-status-label-font-size: 14px;
|
||||
}
|
||||
// 针对1280px以下的屏幕(Mac居多)
|
||||
@media screen and (max-width: 1280px) {
|
||||
padding: 0 8px;
|
||||
--server-status-size: 100px;
|
||||
--server-status-val-text-font-size: 16px;
|
||||
--server-status-label-font-size: 12px;
|
||||
}
|
||||
// 针对1024px以下的屏幕(平板居多)
|
||||
@media screen and (max-width: 1024px) {
|
||||
// padding: 0 8px;
|
||||
--server-status-size: 120px;
|
||||
--server-status-val-text-font-size: 20px;
|
||||
--server-status-label-font-size: 16px;
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
padding: 0 8px;
|
||||
--server-status-size: 100px;
|
||||
--server-status-val-text-font-size: 16px;
|
||||
--server-status-label-font-size: 12px;
|
||||
}
|
||||
@media screen and (max-width: 375px) {
|
||||
padding: 0;
|
||||
--server-status-size: 90px;
|
||||
--server-status-val-text-font-size: 14px;
|
||||
--server-status-label-font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -4,9 +4,11 @@
|
||||
:class="{
|
||||
'server-list-item--offline': info.online === -1,
|
||||
}"
|
||||
@click="openDetail"
|
||||
>
|
||||
<div class="server-info-group server-list-item-head">
|
||||
<div
|
||||
class="server-info-group server-list-item-head"
|
||||
@click="openDetail"
|
||||
>
|
||||
<div class="server-name-group left-box">
|
||||
<span
|
||||
class="server-flag"
|
||||
@ -36,6 +38,7 @@
|
||||
<div
|
||||
v-if="showStatus || showStatus"
|
||||
class="server-list-item-main"
|
||||
@click="openDetail"
|
||||
>
|
||||
<server-list-item-status
|
||||
v-if="showStatus"
|
||||
@ -128,6 +131,11 @@ const showBill = config.nazhua.hideListItemBill !== true;
|
||||
border-top-right-radius: var(--list-item-border-radius);
|
||||
background: rgba(#000, 0.3);
|
||||
box-shadow: 0 2px 4px rgba(#000, 0.5);
|
||||
cursor: pointer;
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&.server-list-item-head {
|
||||
flex-wrap: wrap;
|
||||
|
||||
@ -54,6 +54,7 @@ const {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: default;
|
||||
|
||||
.item-value {
|
||||
line-height: 1em;
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
<div class="server-status-donut">
|
||||
<chart-donut
|
||||
:size="size"
|
||||
:used="used"
|
||||
:used="Math.min(Math.max(used, 1), 100)"
|
||||
:item-colors="colors"
|
||||
>
|
||||
<template #default>
|
||||
149
src/views/components/server/server-status-progress.vue
Normal file
149
src/views/components/server/server-status-progress.vue
Normal file
@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<div
|
||||
class="server-status-progress"
|
||||
:class="'server-status--' + type"
|
||||
>
|
||||
<div class="progress-bar-box">
|
||||
<div
|
||||
class="progress-bar-inner"
|
||||
:style="progressStyle"
|
||||
/>
|
||||
<div
|
||||
class="progress-bar-label"
|
||||
:title="label + '使用' + used + '%'"
|
||||
>
|
||||
<span class="server-status-label">
|
||||
{{ label }}:
|
||||
</span>
|
||||
<span class="server-status-val-text">
|
||||
{{ valText }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="content"
|
||||
class="server-status-progress-content"
|
||||
>
|
||||
<span>{{ content?.default }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
/**
|
||||
* 服务器状态进度调单项
|
||||
*/
|
||||
|
||||
import {
|
||||
computed,
|
||||
} from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 100,
|
||||
},
|
||||
used: {
|
||||
type: [Number, String],
|
||||
default: 1,
|
||||
},
|
||||
colors: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
valText: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
content: {
|
||||
type: [String, Object],
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const progressStyle = computed(() => {
|
||||
const style = {};
|
||||
style.width = `${Math.min(props.used, 100)}%`;
|
||||
const color = typeof props.colors === 'string' ? props.colors : props.colors?.used;
|
||||
if (color) {
|
||||
style.backgroundColor = color;
|
||||
}
|
||||
return style;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.server-status-progress {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
flex: none;
|
||||
width: calc(50% - 5px);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 350px) {
|
||||
flex: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.progress-bar-box {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: var(--progress-bar-height);
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-radius: var(--progress-bar-height);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress-bar-inner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background-color: #08f;
|
||||
border-radius: var(--progress-bar-height);
|
||||
}
|
||||
|
||||
.progress-bar-label {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
line-height: var(--progress-bar-height);
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
text-shadow: 1px 1px 2px rgba(#000, 0.8), 0 0 1px rgba(#fff, 0.5);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.server-status-val-text {
|
||||
color: #a1eafb;
|
||||
}
|
||||
.server-status-label {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.server-status-progress-content {
|
||||
color: #eee;
|
||||
@media screen and (max-width: 480px) {
|
||||
line-height: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -63,7 +63,7 @@ export default (params) => {
|
||||
case 'cpu':
|
||||
return {
|
||||
type: 'cpu',
|
||||
used: Math.max(props.info.State.CPU, 1),
|
||||
used: (props.info.State.CPU).toFixed(1) * 1,
|
||||
colors: {
|
||||
used: '#0088ff',
|
||||
total: 'rgba(255, 255, 255, 0.2)',
|
||||
@ -85,7 +85,7 @@ export default (params) => {
|
||||
}
|
||||
return {
|
||||
type: 'mem',
|
||||
used: Math.max(useMemAndTotalMem.value.usePercent, 1),
|
||||
used: useMemAndTotalMem.value.usePercent,
|
||||
colors: {
|
||||
used: '#0aa344',
|
||||
total: 'rgba(255, 255, 255, 0.2)',
|
||||
@ -111,7 +111,7 @@ export default (params) => {
|
||||
}
|
||||
return {
|
||||
type: 'swap',
|
||||
used: Math.max(useSwapAndTotalSwap.value.usePercent, 1),
|
||||
used: useSwapAndTotalSwap.value.usePercent,
|
||||
colors: {
|
||||
used: '#ff8c00',
|
||||
total: 'rgba(255, 255, 255, 0.2)',
|
||||
@ -134,7 +134,7 @@ export default (params) => {
|
||||
}
|
||||
return {
|
||||
type: 'disk',
|
||||
used: Math.max(useDiskAndTotalDisk.value.usePercent, 1),
|
||||
used: useDiskAndTotalDisk.value.usePercent,
|
||||
colors: {
|
||||
used: '#70f3ff',
|
||||
total: 'rgba(255, 255, 255, 0.2)',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user