add ServerPartitionsDetail.vue
This commit is contained in:
@@ -82,7 +82,7 @@ defineSlots<{
|
|||||||
.value {
|
.value {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
font-size: .8rem;
|
font-size: 14px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
:note="Text.unit(item.used / item.total * 100, '%')"
|
:note="Text.unit(item.used / item.total * 100, '%')"
|
||||||
/>
|
/>
|
||||||
</t-cell-info>
|
</t-cell-info>
|
||||||
<t-cell title="更多" arrow />
|
<t-cell title="更多" arrow @click="router.push('/server/partitions-detail')" />
|
||||||
</t-cell-group>
|
</t-cell-group>
|
||||||
</template>
|
</template>
|
||||||
<t-empty v-else description="暂无系统状态数据" />
|
<t-empty v-else description="暂无系统状态数据" />
|
||||||
|
|||||||
124
src/pages/dashboard/ServerDashboard/ServerPartitionsDetail.vue
Normal file
124
src/pages/dashboard/ServerDashboard/ServerPartitionsDetail.vue
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<template>
|
||||||
|
<div class="server-partitions-detail">
|
||||||
|
<div v-if="isLoading && partitions.length < 1" class="loading-wrap">
|
||||||
|
<t-loading text="加载磁盘详情..." />
|
||||||
|
</div>
|
||||||
|
<template v-else-if="partitions.length">
|
||||||
|
<t-cell-group
|
||||||
|
v-for="item in partitions"
|
||||||
|
:key="item.uuid"
|
||||||
|
:title="resolvePartitionTitle(item)"
|
||||||
|
theme="card"
|
||||||
|
>
|
||||||
|
<t-cell title="磁盘名称" :note="Text.display(item.diskName)" />
|
||||||
|
<t-cell-info label="磁盘型号" :value="Text.display(item.diskModel)" />
|
||||||
|
<t-cell-info label="磁盘序列号" :value="Text.display(item.diskSerial)" />
|
||||||
|
<t-cell title="分区 ID" :note="Text.display(item.partitionId)" />
|
||||||
|
<t-cell title="分区名称" :note="Text.display(item.partitionName)" />
|
||||||
|
<t-cell title="分区类型" :note="Text.display(item.partitionType)" />
|
||||||
|
<t-cell-info label="UUID" :value="Text.display(item.uuid)" />
|
||||||
|
<t-cell title="总容量" :note="IOSize.format(item.total)" />
|
||||||
|
<t-cell title="已使用" :note="IOSize.format(item.used)" />
|
||||||
|
<t-cell title="可用容量" :note="IOSize.format(resolveAvailableBytes(item))" />
|
||||||
|
<t-cell title="使用率" :note="Text.unit(resolveUsageRate(item) * 100, '%')" />
|
||||||
|
<t-cell
|
||||||
|
v-if="typeof item.transferTimeMs === 'number'"
|
||||||
|
title="传输耗时"
|
||||||
|
:note="Text.unit(item.transferTimeMs, '毫秒')"
|
||||||
|
/>
|
||||||
|
<t-cell v-if="item.healthStatus" title="健康状态" :note="item.healthStatus" />
|
||||||
|
</t-cell-group>
|
||||||
|
</template>
|
||||||
|
<t-empty v-else description="暂无磁盘详情数据" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { Toast } from "tdesign-mobile-vue";
|
||||||
|
import { getSystemStatus, resolveSystemRequestErrorMessage } from "@/api/SystemAPI";
|
||||||
|
import type { SystemStatusSnapshot, SystemStatusSnapshotView } from "@/types/System";
|
||||||
|
import { IOSize, Text } from "timi-web";
|
||||||
|
|
||||||
|
type Partition = NonNullable<SystemStatusSnapshot["storagePartitions"]>[number];
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "ServerPartitionsDetail"
|
||||||
|
});
|
||||||
|
|
||||||
|
const isLoading = ref(false);
|
||||||
|
const snapshotView = ref<SystemStatusSnapshotView | null>(null);
|
||||||
|
const refreshIntervalMs = 3000;
|
||||||
|
let refreshTimer: ReturnType<typeof setInterval> | null = null;
|
||||||
|
|
||||||
|
const partitions = computed<Partition[]>(() => {
|
||||||
|
const list = snapshotView.value?.snapshot?.storagePartitions || [];
|
||||||
|
return list.slice().sort((left, right) => {
|
||||||
|
return (right.used / Math.max(right.total, 1)) - (left.used / Math.max(left.total, 1));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
void refreshDetail();
|
||||||
|
refreshTimer = setInterval(() => {
|
||||||
|
void refreshDetail();
|
||||||
|
}, refreshIntervalMs);
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (!refreshTimer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearInterval(refreshTimer);
|
||||||
|
refreshTimer = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
function resolvePartitionTitle(item: Partition): string {
|
||||||
|
const mountPoint = Text.display(item.mountPoint);
|
||||||
|
const partitionName = Text.display(item.partitionName);
|
||||||
|
if (partitionName !== "-") {
|
||||||
|
return `${mountPoint} (${partitionName})`;
|
||||||
|
}
|
||||||
|
return mountPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveUsageRate(item: Partition): number {
|
||||||
|
if (item.total < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return item.used / item.total;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveAvailableBytes(item: Partition): number {
|
||||||
|
return Math.max(item.total - item.used, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refreshDetail(): Promise<void> {
|
||||||
|
if (isLoading.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isLoading.value = true;
|
||||||
|
try {
|
||||||
|
snapshotView.value = await getSystemStatus("storage");
|
||||||
|
} catch (error) {
|
||||||
|
Toast({
|
||||||
|
theme: "error",
|
||||||
|
message: resolveSystemRequestErrorMessage(error)
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
.server-partitions-detail {
|
||||||
|
padding: var(--app-nav-offset) 0 1rem 0;
|
||||||
|
|
||||||
|
.loading-wrap {
|
||||||
|
display: flex;
|
||||||
|
min-height: 4rem;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -12,6 +12,7 @@ import DashboardSetting from "@/pages/setting/DashboardSetting.vue";
|
|||||||
import ThemeSetting from "@/pages/setting/ThemeSetting.vue";
|
import ThemeSetting from "@/pages/setting/ThemeSetting.vue";
|
||||||
import ServerDetail from "@/pages/dashboard/ServerDashboard/ServerDetail.vue";
|
import ServerDetail from "@/pages/dashboard/ServerDashboard/ServerDetail.vue";
|
||||||
import ServerPerformanceDetail from "@/pages/dashboard/ServerDashboard/ServerPerformanceDetail.vue";
|
import ServerPerformanceDetail from "@/pages/dashboard/ServerDashboard/ServerPerformanceDetail.vue";
|
||||||
|
import ServerPartitionsDetail from "@/pages/dashboard/ServerDashboard/ServerPartitionsDetail.vue";
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory("/"),
|
history: createWebHistory("/"),
|
||||||
@@ -95,6 +96,19 @@ const router = createRouter({
|
|||||||
},
|
},
|
||||||
component: ServerPerformanceDetail
|
component: ServerPerformanceDetail
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/server/partitions-detail",
|
||||||
|
name: "ServerPartitionsDetail",
|
||||||
|
meta: {
|
||||||
|
depth: 3,
|
||||||
|
navBarVisible: true,
|
||||||
|
navBarCanBack: true,
|
||||||
|
navBarTitle: "磁盘详情",
|
||||||
|
tabBarVisible: false,
|
||||||
|
bodyBackground: "#F4F4F4"
|
||||||
|
},
|
||||||
|
component: ServerPartitionsDetail
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/settings/connect",
|
path: "/settings/connect",
|
||||||
name: "ConnectSetting",
|
name: "ConnectSetting",
|
||||||
|
|||||||
Reference in New Issue
Block a user