添加服务器状态进度组件,优化样式和交互,调整背景位置,更新状态计算逻辑

This commit is contained in:
hi2hi 2024-12-04 11:05:27 +00:00
parent 5b1a54beeb
commit 5532d48ffb
10 changed files with 334 additions and 108 deletions

View File

@ -3,6 +3,8 @@ window.$$nazhuaConfig = {
// freeAmount: '白嫖', // 免费服务的费用名称
// infinityCycle: '无限', // 无限周期名称
// buyBtnText: '购买', // 购买按钮文案
// listServerStatusType: 'progress', // 服务器状态类型--列表
// detailServerStatusType: 'progress', // 服务器状态类型--详情页
// hideNavbarServerCount: false, // 隐藏服务器数量
// hideNavbarServerStat: false, // 隐藏服务器统计
// hideListItemStatusDonut: true, // 隐藏列表项的饼图

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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 {

View File

@ -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(Macwindows)
@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(Macwindows)
@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>

View File

@ -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;

View File

@ -54,6 +54,7 @@ const {
flex-direction: column;
align-items: center;
justify-content: center;
cursor: default;
.item-value {
line-height: 1em;

View File

@ -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>

View 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>

View File

@ -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)',