mirror of
https://github.com/EasyTierMC/ETMC.Web.git
synced 2025-12-07 21:15:48 +08:00
chore:monitorview more concise code and add pagination
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="p-6 min-h-screen bg-base-200">
|
<div class="p-6 min-h-screen bg-base-200">
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
@@ -9,60 +9,32 @@
|
|||||||
<!-- 搜索和筛选栏 -->
|
<!-- 搜索和筛选栏 -->
|
||||||
<div class="bg-base-100 rounded-lg p-4 mb-6 mx-4 border border-base-300">
|
<div class="bg-base-100 rounded-lg p-4 mb-6 mx-4 border border-base-300">
|
||||||
<div class="flex flex-col lg:flex-row gap-4">
|
<div class="flex flex-col lg:flex-row gap-4">
|
||||||
<!-- 搜索框 -->
|
<input
|
||||||
<div class="flex-1">
|
v-model="searchQuery"
|
||||||
<input
|
type="text"
|
||||||
v-model="searchQuery"
|
placeholder="搜索节点名称..."
|
||||||
type="text"
|
class="input input-bordered w-full text-sm"
|
||||||
placeholder="搜索节点名称..."
|
/>
|
||||||
class="input input-bordered w-full text-sm"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 状态筛选 -->
|
<select v-model="statusFilter" class="select select-bordered text-sm">
|
||||||
<div class="flex gap-2">
|
<option value="all">全部状态</option>
|
||||||
<select
|
<option value="online">在线</option>
|
||||||
v-model="statusFilter"
|
<option value="offline">离线</option>
|
||||||
class="select select-bordered text-sm"
|
</select>
|
||||||
>
|
|
||||||
<option value="all">全部状态</option>
|
|
||||||
<option value="online">在线</option>
|
|
||||||
<option value="offline">离线</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 标签筛选 -->
|
<select v-model="tagFilter" class="select select-bordered text-sm min-w-[120px]">
|
||||||
<div class="flex gap-2">
|
<option value="">全部标签</option>
|
||||||
<select
|
<option v-for="tag in availableTags" :key="tag" :value="tag">{{ tag }}</option>
|
||||||
v-model="tagFilter"
|
</select>
|
||||||
class="select select-bordered text-sm min-w-[120px]"
|
|
||||||
>
|
|
||||||
<option value="">全部标签</option>
|
|
||||||
<option
|
|
||||||
v-for="tag in availableTags"
|
|
||||||
:key="tag"
|
|
||||||
:value="tag"
|
|
||||||
>
|
|
||||||
{{ tag }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 排序选择 -->
|
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<select
|
<select v-model="sortBy" class="select select-bordered text-sm min-w-[120px]">
|
||||||
v-model="sortBy"
|
|
||||||
class="select select-bordered text-sm"
|
|
||||||
>
|
|
||||||
<option value="name">按名称排序</option>
|
<option value="name">按名称排序</option>
|
||||||
<option value="id">按ID排序</option>
|
<option value="id">按ID排序</option>
|
||||||
<option value="load">按负载排序</option>
|
<option value="load">按负载排序</option>
|
||||||
<option value="connections">按连接数排序</option>
|
<option value="connections">按连接数排序</option>
|
||||||
</select>
|
</select>
|
||||||
<button
|
<button @click="toggleSortOrder" class="btn btn-outline btn-sm">
|
||||||
@click="toggleSortOrder"
|
|
||||||
class="btn btn-outline btn-sm"
|
|
||||||
>
|
|
||||||
{{ sortOrder === 'asc' ? '↑' : '↓' }}
|
{{ sortOrder === 'asc' ? '↑' : '↓' }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -105,7 +77,7 @@
|
|||||||
|
|
||||||
<div class="space-y-3 px-4">
|
<div class="space-y-3 px-4">
|
||||||
<div
|
<div
|
||||||
v-for="node in filteredAndSortedNodes"
|
v-for="node in paginatedNodes"
|
||||||
:key="node.id"
|
:key="node.id"
|
||||||
class="w-full border border-base-300 bg-base-100 rounded-lg px-4 py-3 hover:shadow-lg transition-all duration-300"
|
class="w-full border border-base-300 bg-base-100 rounded-lg px-4 py-3 hover:shadow-lg transition-all duration-300"
|
||||||
>
|
>
|
||||||
@@ -170,6 +142,82 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 分页控件 -->
|
||||||
|
<div class="bg-base-100 rounded-lg px-4 py-4 mx-4 mt-6 border border-base-300">
|
||||||
|
<div class="flex flex-col sm:flex-row justify-between items-center gap-4">
|
||||||
|
<!-- 分页信息 -->
|
||||||
|
<div class="text-sm text-base-content/70">
|
||||||
|
显示 {{ ((currentPage - 1) * pageSize) + 1 }} - {{ Math.min(currentPage * pageSize, totalNodes) }}
|
||||||
|
共 {{ totalNodes }} 条记录
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 每页显示数量选择 -->
|
||||||
|
<div class="flex items-center gap-2 whitespace-nowrap">
|
||||||
|
<span class="text-sm text-base-content/70">每页</span>
|
||||||
|
<select v-model="pageSize" @change="changePageSize" class="select select-bordered select-sm">
|
||||||
|
<option v-for="size in pageSizeOptions" :key="size" :value="size">{{ size }}</option>
|
||||||
|
</select>
|
||||||
|
<span class="text-sm text-base-content/70">条</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 分页按钮 -->
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<!-- 首页 -->
|
||||||
|
<button
|
||||||
|
@click="goToPage(1)"
|
||||||
|
:disabled="currentPage === 1"
|
||||||
|
class="btn btn-outline btn-sm"
|
||||||
|
:class="{ 'btn-disabled': currentPage === 1 }"
|
||||||
|
>
|
||||||
|
首页
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- 上一页 -->
|
||||||
|
<button
|
||||||
|
@click="goToPage(currentPage - 1)"
|
||||||
|
:disabled="currentPage === 1"
|
||||||
|
class="btn btn-outline btn-sm"
|
||||||
|
:class="{ 'btn-disabled': currentPage === 1 }"
|
||||||
|
>
|
||||||
|
上一页
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- 页码 -->
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<button
|
||||||
|
v-for="page in getPageNumbers()"
|
||||||
|
:key="page"
|
||||||
|
@click="goToPage(page)"
|
||||||
|
class="btn btn-sm"
|
||||||
|
:class="page === currentPage ? 'btn-primary' : 'btn-outline'"
|
||||||
|
>
|
||||||
|
{{ page }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 下一页 -->
|
||||||
|
<button
|
||||||
|
@click="goToPage(currentPage + 1)"
|
||||||
|
:disabled="currentPage === totalPages"
|
||||||
|
class="btn btn-outline btn-sm"
|
||||||
|
:class="{ 'btn-disabled': currentPage === totalPages }"
|
||||||
|
>
|
||||||
|
下一页
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- 末页 -->
|
||||||
|
<button
|
||||||
|
@click="goToPage(totalPages)"
|
||||||
|
:disabled="currentPage === totalPages"
|
||||||
|
class="btn btn-outline btn-sm"
|
||||||
|
:class="{ 'btn-disabled': currentPage === totalPages }"
|
||||||
|
>
|
||||||
|
末页
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -179,7 +227,7 @@ import { ref, computed } from 'vue'
|
|||||||
|
|
||||||
// 节点接口定义
|
// 节点接口定义
|
||||||
interface Node {
|
interface Node {
|
||||||
id: string
|
id: number
|
||||||
name: string
|
name: string
|
||||||
isOnline: boolean
|
isOnline: boolean
|
||||||
maxConnections: number
|
maxConnections: number
|
||||||
@@ -194,13 +242,18 @@ interface Node {
|
|||||||
const searchQuery = ref('')
|
const searchQuery = ref('')
|
||||||
const statusFilter = ref('all')
|
const statusFilter = ref('all')
|
||||||
const tagFilter = ref('')
|
const tagFilter = ref('')
|
||||||
const sortBy = ref('name')
|
const sortBy = ref('id')
|
||||||
const sortOrder = ref<'asc' | 'desc'>('asc')
|
const sortOrder = ref<'asc' | 'desc'>('asc')
|
||||||
|
|
||||||
|
// 分页状态
|
||||||
|
const currentPage = ref(1)
|
||||||
|
const pageSize = ref(10)
|
||||||
|
const pageSizeOptions = [10, 30, 50, 100, 200]
|
||||||
|
|
||||||
// 示例节点数据
|
// 示例节点数据
|
||||||
const nodes = ref<Node[]>([
|
const nodes = ref<Node[]>([
|
||||||
{
|
{
|
||||||
id: 'NODE-001',
|
id: 1,
|
||||||
name: '主控节点',
|
name: '主控节点',
|
||||||
isOnline: true,
|
isOnline: true,
|
||||||
maxConnections: 100,
|
maxConnections: 100,
|
||||||
@@ -211,7 +264,7 @@ const nodes = ref<Node[]>([
|
|||||||
tags: ['核心', '主控', '高可用']
|
tags: ['核心', '主控', '高可用']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'NODE-002',
|
id: 2,
|
||||||
name: '数据处理节点',
|
name: '数据处理节点',
|
||||||
isOnline: true,
|
isOnline: true,
|
||||||
maxConnections: 80,
|
maxConnections: 80,
|
||||||
@@ -222,7 +275,7 @@ const nodes = ref<Node[]>([
|
|||||||
tags: ['计算', '数据分析', '高性能']
|
tags: ['计算', '数据分析', '高性能']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'NODE-003',
|
id: 3,
|
||||||
name: '边缘服务节点',
|
name: '边缘服务节点',
|
||||||
isOnline: false,
|
isOnline: false,
|
||||||
maxConnections: 50,
|
maxConnections: 50,
|
||||||
@@ -231,102 +284,234 @@ const nodes = ref<Node[]>([
|
|||||||
createdAt: new Date('2024-03-10T09:45:00'),
|
createdAt: new Date('2024-03-10T09:45:00'),
|
||||||
description: '部署在网络边缘的服务节点,提供低延迟的本地化服务。',
|
description: '部署在网络边缘的服务节点,提供低延迟的本地化服务。',
|
||||||
tags: ['边缘', '低延迟', '本地服务']
|
tags: ['边缘', '低延迟', '本地服务']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: '缓存服务节点',
|
||||||
|
isOnline: true,
|
||||||
|
maxConnections: 200,
|
||||||
|
currentConnections: 120,
|
||||||
|
loadScore: 0,
|
||||||
|
createdAt: new Date('2024-01-20T08:00:00'),
|
||||||
|
description: '提供高速缓存服务,支持分布式缓存和内存数据库功能。',
|
||||||
|
tags: ['缓存', '高性能', '分布式']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
name: 'API网关节点',
|
||||||
|
isOnline: true,
|
||||||
|
maxConnections: 150,
|
||||||
|
currentConnections: 85,
|
||||||
|
loadScore: 0,
|
||||||
|
createdAt: new Date('2024-02-01T12:00:00'),
|
||||||
|
description: '统一API入口,负责请求路由、负载均衡和安全认证。',
|
||||||
|
tags: ['API', '网关', '安全']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
name: '文件存储节点',
|
||||||
|
isOnline: true,
|
||||||
|
maxConnections: 75,
|
||||||
|
currentConnections: 30,
|
||||||
|
loadScore: 0,
|
||||||
|
createdAt: new Date('2024-01-25T16:30:00'),
|
||||||
|
description: '提供分布式文件存储服务,支持大文件上传和下载。',
|
||||||
|
tags: ['存储', '文件', '分布式']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
name: '消息队列节点',
|
||||||
|
isOnline: false,
|
||||||
|
maxConnections: 90,
|
||||||
|
currentConnections: 0,
|
||||||
|
loadScore: 0,
|
||||||
|
createdAt: new Date('2024-03-05T11:20:00'),
|
||||||
|
description: '处理异步消息传递,支持发布订阅模式和消息持久化。',
|
||||||
|
tags: ['消息', '队列', '异步']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 8,
|
||||||
|
name: '监控收集节点',
|
||||||
|
isOnline: true,
|
||||||
|
maxConnections: 60,
|
||||||
|
currentConnections: 45,
|
||||||
|
loadScore: 0,
|
||||||
|
createdAt: new Date('2024-02-10T09:15:00'),
|
||||||
|
description: '收集和聚合系统监控数据,提供实时监控和告警功能。',
|
||||||
|
tags: ['监控', '数据收集', '告警']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 9,
|
||||||
|
name: '日志处理节点',
|
||||||
|
isOnline: true,
|
||||||
|
maxConnections: 120,
|
||||||
|
currentConnections: 95,
|
||||||
|
loadScore: 0,
|
||||||
|
createdAt: new Date('2024-01-18T14:45:00'),
|
||||||
|
description: '处理和存储系统日志,支持日志搜索和分析功能。',
|
||||||
|
tags: ['日志', '处理', '存储']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10,
|
||||||
|
name: '认证服务节点',
|
||||||
|
isOnline: true,
|
||||||
|
maxConnections: 80,
|
||||||
|
currentConnections: 35,
|
||||||
|
loadScore: 0,
|
||||||
|
createdAt: new Date('2024-02-15T10:00:00'),
|
||||||
|
description: '提供用户认证和授权服务,支持多种认证方式。',
|
||||||
|
tags: ['认证', '安全', '授权']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 11,
|
||||||
|
name: '配置管理节点',
|
||||||
|
isOnline: true,
|
||||||
|
maxConnections: 50,
|
||||||
|
currentConnections: 20,
|
||||||
|
loadScore: 0,
|
||||||
|
createdAt: new Date('2024-01-22T13:30:00'),
|
||||||
|
description: '集中管理应用配置,支持动态配置更新和版本控制。',
|
||||||
|
tags: ['配置', '管理', '动态']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 12,
|
||||||
|
name: '任务调度节点',
|
||||||
|
isOnline: false,
|
||||||
|
maxConnections: 70,
|
||||||
|
currentConnections: 0,
|
||||||
|
loadScore: 0,
|
||||||
|
createdAt: new Date('2024-03-08T15:00:00'),
|
||||||
|
description: '负责任务调度和执行,支持定时任务和分布式任务处理。',
|
||||||
|
tags: ['任务', '调度', '分布式']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 13,
|
||||||
|
name: '搜索服务节点',
|
||||||
|
isOnline: true,
|
||||||
|
maxConnections: 100,
|
||||||
|
currentConnections: 78,
|
||||||
|
loadScore: 0,
|
||||||
|
createdAt: new Date('2024-02-05T08:45:00'),
|
||||||
|
description: '提供全文搜索和索引服务,支持复杂查询和实时搜索。',
|
||||||
|
tags: ['搜索', '索引', '查询']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 14,
|
||||||
|
name: '图像处理节点',
|
||||||
|
isOnline: true,
|
||||||
|
maxConnections: 60,
|
||||||
|
currentConnections: 42,
|
||||||
|
loadScore: 0,
|
||||||
|
createdAt: new Date('2024-01-28T11:15:00'),
|
||||||
|
description: '专门处理图像相关任务,包括压缩、裁剪和格式转换。',
|
||||||
|
tags: ['图像', '处理', '媒体']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 15,
|
||||||
|
name: '机器学习节点',
|
||||||
|
isOnline: true,
|
||||||
|
maxConnections: 40,
|
||||||
|
currentConnections: 28,
|
||||||
|
loadScore: 0,
|
||||||
|
createdAt: new Date('2024-02-18T16:00:00'),
|
||||||
|
description: '提供机器学习模型训练和推理服务,支持多种算法框架。',
|
||||||
|
tags: ['AI', '机器学习', '推理']
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
// 获取所有可用标签
|
// 获取所有可用标签
|
||||||
const availableTags = computed(() => {
|
const availableTags = computed(() =>
|
||||||
const tags = new Set<string>()
|
[...new Set(nodes.value.flatMap(node => node.tags))].sort()
|
||||||
nodes.value.forEach(node => {
|
)
|
||||||
node.tags.forEach(tag => tags.add(tag))
|
|
||||||
})
|
|
||||||
return Array.from(tags).sort()
|
|
||||||
})
|
|
||||||
|
|
||||||
// 过滤和排序后的节点
|
// 过滤和排序后的节点
|
||||||
const filteredAndSortedNodes = computed(() => {
|
const filteredAndSortedNodes = computed(() => {
|
||||||
let filtered = nodes.value.filter(node => {
|
const sortMethods = {
|
||||||
// 搜索过滤
|
name: (a: Node, b: Node) => a.name.localeCompare(b.name, 'zh-CN'),
|
||||||
const matchesSearch = node.name.toLowerCase().includes(searchQuery.value.toLowerCase())
|
id: (a: Node, b: Node) => a.id - b.id,
|
||||||
|
load: (a: Node, b: Node) => a.loadScore - b.loadScore,
|
||||||
// 状态过滤
|
connections: (a: Node, b: Node) => a.currentConnections - b.currentConnections
|
||||||
const matchesStatus = statusFilter.value === 'all' ||
|
}
|
||||||
(statusFilter.value === 'online' && node.isOnline) ||
|
|
||||||
(statusFilter.value === 'offline' && !node.isOnline)
|
|
||||||
|
|
||||||
// 标签过滤
|
|
||||||
const matchesTag = !tagFilter.value || node.tags.includes(tagFilter.value)
|
|
||||||
|
|
||||||
return matchesSearch && matchesStatus && matchesTag
|
|
||||||
})
|
|
||||||
|
|
||||||
// 排序
|
return nodes.value
|
||||||
filtered.sort((a, b) => {
|
.filter(node =>
|
||||||
let comparison = 0
|
node.name.toLowerCase().includes(searchQuery.value.toLowerCase()) &&
|
||||||
|
(statusFilter.value === 'all' ||
|
||||||
switch (sortBy.value) {
|
(statusFilter.value === 'online' && node.isOnline) ||
|
||||||
case 'name':
|
(statusFilter.value === 'offline' && !node.isOnline)) &&
|
||||||
comparison = a.name.localeCompare(b.name, 'zh-CN')
|
(!tagFilter.value || node.tags.includes(tagFilter.value))
|
||||||
break
|
)
|
||||||
case 'id':
|
.sort((a, b) => {
|
||||||
comparison = a.id.localeCompare(b.id)
|
const comparison = sortMethods[sortBy.value as keyof typeof sortMethods](a, b)
|
||||||
break
|
return sortOrder.value === 'asc' ? comparison : -comparison
|
||||||
case 'load':
|
})
|
||||||
comparison = a.loadScore - b.loadScore
|
|
||||||
break
|
|
||||||
case 'connections':
|
|
||||||
comparison = a.currentConnections - b.currentConnections
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortOrder.value === 'asc' ? comparison : -comparison
|
|
||||||
})
|
|
||||||
|
|
||||||
return filtered
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 分页相关计算属性
|
||||||
|
const totalNodes = computed(() => filteredAndSortedNodes.value.length)
|
||||||
|
const totalPages = computed(() => Math.ceil(totalNodes.value / pageSize.value))
|
||||||
|
const paginatedNodes = computed(() => {
|
||||||
|
const start = (currentPage.value - 1) * pageSize.value
|
||||||
|
const end = start + pageSize.value
|
||||||
|
return filteredAndSortedNodes.value.slice(start, end)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 分页方法
|
||||||
|
const goToPage = (page: number) => {
|
||||||
|
if (page >= 1 && page <= totalPages.value) {
|
||||||
|
currentPage.value = page
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const changePageSize = () => {
|
||||||
|
currentPage.value = 1 // 重置到第一页
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取要显示的页码数组
|
||||||
|
const getPageNumbers = () => {
|
||||||
|
const current = currentPage.value
|
||||||
|
const total = totalPages.value
|
||||||
|
|
||||||
|
if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1)
|
||||||
|
|
||||||
|
if (current <= 4) return [...Array.from({ length: 5 }, (_, i) => i + 1), total]
|
||||||
|
if (current >= total - 3) return [1, ...Array.from({ length: 5 }, (_, i) => total - 4 + i)]
|
||||||
|
|
||||||
|
return [1, current - 1, current, current + 1, total]
|
||||||
|
}
|
||||||
|
|
||||||
// 切换排序顺序
|
// 切换排序顺序
|
||||||
const toggleSortOrder = () => {
|
const toggleSortOrder = () => {
|
||||||
sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc'
|
sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算负载分数
|
// 计算负载分数
|
||||||
const calculateLoadScore = (maxConnections: number, currentConnections: number): number => {
|
const calculateLoadScore = (max: number, current: number) =>
|
||||||
if (maxConnections === 0) return 0
|
max === 0 ? 0 : Math.min((current / max) * 100, 100)
|
||||||
return Math.min((currentConnections / maxConnections) * 100, 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新所有节点的负载分数
|
// 更新所有节点的负载分数
|
||||||
const updateLoadScores = () => {
|
const updateLoadScores = () =>
|
||||||
nodes.value.forEach(node => {
|
nodes.value.forEach(node => {
|
||||||
node.loadScore = calculateLoadScore(node.maxConnections, node.currentConnections)
|
node.loadScore = calculateLoadScore(node.maxConnections, node.currentConnections)
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
// 获取负载分数颜色
|
// 获取负载分数颜色
|
||||||
const getLoadScoreColor = (score: number): string => {
|
const getLoadScoreColor = (score: number) =>
|
||||||
if (score < 30) return 'text-success'
|
score < 30 ? 'text-success' : score < 70 ? 'text-warning' : 'text-error'
|
||||||
if (score < 70) return 'text-warning'
|
|
||||||
return 'text-error'
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取负载分数条颜色
|
// 获取负载分数条颜色
|
||||||
const getLoadScoreBarColor = (score: number): string => {
|
const getLoadScoreBarColor = (score: number) =>
|
||||||
if (score < 30) return 'bg-success'
|
score < 30 ? 'bg-success' : score < 70 ? 'bg-warning' : 'bg-error'
|
||||||
if (score < 70) return 'bg-warning'
|
|
||||||
return 'bg-error'
|
|
||||||
}
|
|
||||||
|
|
||||||
// 格式化日期
|
// 格式化日期
|
||||||
const formatDate = (date: Date): string => {
|
const formatDate = (date: Date) =>
|
||||||
return date.toLocaleString('zh-CN', {
|
date.toLocaleString('zh-CN', {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
month: '2-digit',
|
month: '2-digit',
|
||||||
day: '2-digit',
|
day: '2-digit',
|
||||||
hour: '2-digit',
|
hour: '2-digit',
|
||||||
minute: '2-digit'
|
minute: '2-digit'
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化负载分数
|
// 初始化负载分数
|
||||||
updateLoadScores()
|
updateLoadScores()
|
||||||
|
|||||||
Reference in New Issue
Block a user