继续优化调整代码
This commit is contained in:
1 parent
f5dc875755
commit
3016121cc4
10 files changed
+137
-110
No files matched your search
@@ -12,6 +12,46 @@ import (
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Paging 探针分页查询
|
||||
func (h *AgentHandler) Paging(c echo.Context) error {
|
||||
status := c.QueryParam("status")
|
||||
|
||||
pr := orz.GetPageRequest(c, "name")
|
||||
|
||||
builder := orz.NewPageBuilder(h.agentService.AgentRepo.Repository).
|
||||
PageRequest(pr).
|
||||
Contains("name", c.QueryParam("name")).
|
||||
Contains("hostname", c.QueryParam("hostname")).
|
||||
Contains("ip", c.QueryParam("ip"))
|
||||
|
||||
// 处理状态筛选
|
||||
if status == "online" {
|
||||
builder.Equal("status", "1")
|
||||
} else if status == "offline" {
|
||||
builder.Equal("status", "0")
|
||||
}
|
||||
|
||||
ctx := c.Request().Context()
|
||||
page, err := builder.Execute(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return orz.Ok(c, page)
|
||||
}
|
||||
|
||||
// GetForAdmin 获取探针详情(管理员接口,显示完整信息)
|
||||
func (h *AgentHandler) GetForAdmin(c echo.Context) error {
|
||||
id := c.Param("id")
|
||||
ctx := c.Request().Context()
|
||||
|
||||
agent, err := h.agentService.GetAgent(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return orz.Ok(c, agent)
|
||||
}
|
||||
|
||||
// SendCommand 向探针发送指令
|
||||
func (h *AgentHandler) SendCommand(c echo.Context) error {
|
||||
agentID := c.Param("id")
|
||||
|
||||
@@ -11,33 +11,6 @@ import (
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
// Paging 探针分页查询
|
||||
func (h *AgentHandler) Paging(c echo.Context) error {
|
||||
status := c.QueryParam("status")
|
||||
|
||||
pr := orz.GetPageRequest(c, "name")
|
||||
|
||||
builder := orz.NewPageBuilder(h.agentService.AgentRepo.Repository).
|
||||
PageRequest(pr).
|
||||
Contains("name", c.QueryParam("name")).
|
||||
Contains("hostname", c.QueryParam("hostname")).
|
||||
Contains("ip", c.QueryParam("ip"))
|
||||
|
||||
// 处理状态筛选
|
||||
if status == "online" {
|
||||
builder.Equal("status", "1")
|
||||
} else if status == "offline" {
|
||||
builder.Equal("status", "0")
|
||||
}
|
||||
|
||||
ctx := c.Request().Context()
|
||||
page, err := builder.Execute(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return orz.Ok(c, page)
|
||||
}
|
||||
|
||||
// Get 获取探针详情(公开接口,已登录返回全部,未登录返回公开可见)
|
||||
func (h *AgentHandler) Get(c echo.Context) error {
|
||||
id := c.Param("id")
|
||||
@@ -59,19 +32,6 @@ func (h *AgentHandler) Get(c echo.Context) error {
|
||||
return orz.Ok(c, agent)
|
||||
}
|
||||
|
||||
// GetForAdmin 获取探针详情(管理员接口,显示完整信息)
|
||||
func (h *AgentHandler) GetForAdmin(c echo.Context) error {
|
||||
id := c.Param("id")
|
||||
ctx := c.Request().Context()
|
||||
|
||||
agent, err := h.agentService.GetAgent(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return orz.Ok(c, agent)
|
||||
}
|
||||
|
||||
// GetAgents 获取探针列表(公开接口,已登录返回全部,未登录返回公开可见)
|
||||
func (h *AgentHandler) GetAgents(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
@@ -101,7 +61,7 @@ func (h *AgentHandler) GetAgents(c echo.Context) error {
|
||||
}
|
||||
|
||||
func (h *AgentHandler) buildAgentListItem(agent models.Agent) map[string]interface{} {
|
||||
item := map[string]interface{}{
|
||||
item := map[string]any{
|
||||
"id": agent.ID,
|
||||
"name": agent.Name,
|
||||
"os": agent.OS,
|
||||
@@ -115,14 +75,14 @@ func (h *AgentHandler) buildAgentListItem(agent models.Agent) map[string]interfa
|
||||
}
|
||||
|
||||
trafficStats := agent.TrafficStats.Data()
|
||||
item["trafficLimit"] = trafficStats.Limit
|
||||
item["trafficUsed"] = trafficStats.Used
|
||||
item["trafficResetDay"] = trafficStats.ResetDay
|
||||
item["trafficPeriodStart"] = trafficStats.PeriodStart
|
||||
item["trafficBaselineRecv"] = trafficStats.BaselineRecv
|
||||
item["trafficAlertSent80"] = trafficStats.AlertSent80
|
||||
item["trafficAlertSent90"] = trafficStats.AlertSent90
|
||||
item["trafficAlertSent100"] = trafficStats.AlertSent100
|
||||
if trafficStats.Limit > 0 {
|
||||
item["traffic"] = map[string]any{
|
||||
"limit": trafficStats.Limit,
|
||||
"used": trafficStats.Used,
|
||||
}
|
||||
} else {
|
||||
item["traffic"] = map[string]any{}
|
||||
}
|
||||
|
||||
metrics, ok := h.metricService.GetLatestMetrics(agent.ID)
|
||||
if ok {
|
||||
|
||||
@@ -17,6 +17,8 @@ import CompactResourceBar from '@portal/components/CompactResourceBar';
|
||||
import {formatBytes, formatSpeed, formatUptime} from '@portal/utils/util';
|
||||
import CyberCard from "@portal/components/CyberCard.tsx";
|
||||
import {Link} from "react-router-dom";
|
||||
import {isExpired} from "@portal/utils/server.ts";
|
||||
import {cn} from "@/lib/utils.ts";
|
||||
|
||||
interface AgentWithMetrics extends Agent {
|
||||
metrics?: LatestMetrics;
|
||||
@@ -71,7 +73,10 @@ const ServerCard: FC<ServerCardProps> = ({server}) => {
|
||||
{/* 顶部:名称和状态 */}
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="font-bold text-slate-800 dark:text-cyan-100 font-mono text-base truncate">
|
||||
<div className={cn(
|
||||
'font-bold text-slate-800 dark:text-cyan-100 font-mono text-base truncate',
|
||||
isExpired(server.expireTime) ? 'text-red-600 dark:text-red-400' : ''
|
||||
)}>
|
||||
{server.name || server.hostname}
|
||||
</div>
|
||||
<div
|
||||
@@ -175,7 +180,11 @@ const ServerCard: FC<ServerCardProps> = ({server}) => {
|
||||
</div>
|
||||
{server.expireTime > 0 && (
|
||||
<div
|
||||
className="text-xs font-mono text-cyan-600 dark:text-cyan-500 flex items-center gap-1">
|
||||
className={cn(
|
||||
`text-xs font-mono flex items-center gap-1 text-gray-600 dark:text-cyan-500`,
|
||||
// 剩余时间小于 30 天时显示为红色
|
||||
isExpired(server.expireTime) ? 'text-red-600 dark:text-red-400' : ''
|
||||
)}>
|
||||
<Calendar className="w-3 h-3"/>
|
||||
{new Date(server.expireTime).toLocaleDateString('zh-CN')}
|
||||
</div>
|
||||
@@ -204,16 +213,16 @@ const ServerCard: FC<ServerCardProps> = ({server}) => {
|
||||
</div>
|
||||
|
||||
{/* 流量限制 */}
|
||||
{server.trafficLimit > 0 && (
|
||||
{server.traffic?.limit > 0 && (
|
||||
<div className="pt-2 border-t border-slate-200 dark:border-cyan-900/30">
|
||||
<div className="flex justify-between text-xs text-gray-600 dark:text-cyan-500 mb-1">
|
||||
<span>流量使用</span>
|
||||
<span>{Math.round((server.trafficUsed || 0) / server.trafficLimit * 100)}%</span>
|
||||
<span>{Math.round((server.traffic?.used || 0) / server.traffic?.limit * 100)}%</span>
|
||||
</div>
|
||||
<div className="h-1.5 bg-slate-200 dark:bg-cyan-900/50 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-gray-500 dark:bg-cyan-400 transition-all"
|
||||
style={{width: `${((server.trafficUsed || 0) / server.trafficLimit) * 100}%`}}
|
||||
style={{width: `${((server.traffic?.used || 0) / server.traffic?.limit) * 100}%`}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+5
-5
@@ -2,11 +2,11 @@ import {useNavigate, useParams} from 'react-router-dom';
|
||||
import {useQuery} from '@tanstack/react-query';
|
||||
import {getMonitorAgentStats, getMonitorStatsById} from '@/api/monitor.ts';
|
||||
import type {AgentMonitorStat, PublicMonitor} from '@/types';
|
||||
import {MonitorHero} from '@portal/components/monitor/MonitorHero';
|
||||
import {ResponseTimeChart} from '@portal/components/monitor/ResponseTimeChart';
|
||||
import {AgentStatsTable} from '@portal/components/monitor/AgentStatsTable';
|
||||
import {EmptyState} from '@portal/components/EmptyState';
|
||||
import {LoadingSpinner} from '@portal/components/LoadingSpinner';
|
||||
import {MonitorHero} from '@portal/components/monitor/MonitorHero.tsx';
|
||||
import {ResponseTimeChart} from '@portal/components/monitor/ResponseTimeChart.tsx';
|
||||
import {AgentStatsTable} from '@portal/components/monitor/AgentStatsTable.tsx';
|
||||
import {EmptyState} from '@portal/components/EmptyState.tsx';
|
||||
import {LoadingSpinner} from '@portal/components/LoadingSpinner.tsx';
|
||||
|
||||
/**
|
||||
* 监控详情页面
|
||||
@@ -4,9 +4,9 @@ import {useQuery} from '@tanstack/react-query';
|
||||
import {AlertTriangle, BarChart3, CheckCircle2, Globe, Loader2, Maximize2, Search, Shield, Zap} from 'lucide-react';
|
||||
import {getPublicMonitors} from '@/api/monitor.ts';
|
||||
import type {PublicMonitor} from '@/types';
|
||||
import {cn} from '@/lib/utils';
|
||||
import {cn} from '@/lib/utils.ts';
|
||||
import StatBlock from "@portal/components/StatBlock.tsx";
|
||||
import MonitorCard, {type DisplayMode} from "@portal/components/monitor/MonitorCard";
|
||||
import MonitorCard, {type DisplayMode} from "@portal/components/monitor/MonitorCard.tsx";
|
||||
|
||||
const LoadingSpinner = () => (
|
||||
<div className="flex min-h-[400px] w-full items-center justify-center">
|
||||
+19
-19
@@ -1,24 +1,24 @@
|
||||
import {useState} from 'react';
|
||||
import {useNavigate, useParams} from 'react-router-dom';
|
||||
import {Card} from '@portal/components/Card';
|
||||
import {EmptyState} from '@portal/components/EmptyState';
|
||||
import {LoadingSpinner} from '@portal/components/LoadingSpinner';
|
||||
import {TimeRangeSelector} from '@portal/components/TimeRangeSelector';
|
||||
import {GpuMonitorSection} from '@portal/components/server/GpuMonitorSection';
|
||||
import {NetworkConnectionSection} from '@portal/components/server/NetworkConnectionSection';
|
||||
import {ServerHero} from '@portal/components/server/ServerHero';
|
||||
import {SystemInfoSection} from '@portal/components/server/SystemInfoSection';
|
||||
import {TemperatureMonitorSection} from '@portal/components/server/TemperatureMonitorSection';
|
||||
import {CpuChart} from '@portal/components/server/CpuChart';
|
||||
import {DiskIOChart} from '@portal/components/server/DiskIOChart';
|
||||
import {GpuChart} from '@portal/components/server/GpuChart';
|
||||
import {MemoryChart} from '@portal/components/server/MemoryChart';
|
||||
import {MonitorChart} from '@portal/components/server/MonitorChart';
|
||||
import {NetworkChart} from '@portal/components/server/NetworkChart';
|
||||
import {NetworkConnectionChart} from '@portal/components/server/NetworkConnectionChart';
|
||||
import {TemperatureChart} from '@portal/components/server/TemperatureChart';
|
||||
import {useAgentQuery, useLatestMetricsQuery} from '@portal/hooks/server';
|
||||
import {SERVER_TIME_RANGE_OPTIONS} from '@portal/constants/time';
|
||||
import {Card} from '@portal/components/Card.tsx';
|
||||
import {EmptyState} from '@portal/components/EmptyState.tsx';
|
||||
import {LoadingSpinner} from '@portal/components/LoadingSpinner.tsx';
|
||||
import {TimeRangeSelector} from '@portal/components/TimeRangeSelector.tsx';
|
||||
import {GpuMonitorSection} from '@portal/components/server/GpuMonitorSection.tsx';
|
||||
import {NetworkConnectionSection} from '@portal/components/server/NetworkConnectionSection.tsx';
|
||||
import {ServerHero} from '@portal/components/server/ServerHero.tsx';
|
||||
import {SystemInfoSection} from '@portal/components/server/SystemInfoSection.tsx';
|
||||
import {TemperatureMonitorSection} from '@portal/components/server/TemperatureMonitorSection.tsx';
|
||||
import {CpuChart} from '@portal/components/server/CpuChart.tsx';
|
||||
import {DiskIOChart} from '@portal/components/server/DiskIOChart.tsx';
|
||||
import {GpuChart} from '@portal/components/server/GpuChart.tsx';
|
||||
import {MemoryChart} from '@portal/components/server/MemoryChart.tsx';
|
||||
import {MonitorChart} from '@portal/components/server/MonitorChart.tsx';
|
||||
import {NetworkChart} from '@portal/components/server/NetworkChart.tsx';
|
||||
import {NetworkConnectionChart} from '@portal/components/server/NetworkConnectionChart.tsx';
|
||||
import {TemperatureChart} from '@portal/components/server/TemperatureChart.tsx';
|
||||
import {useAgentQuery, useLatestMetricsQuery} from '@portal/hooks/server.ts';
|
||||
import {SERVER_TIME_RANGE_OPTIONS} from '@portal/constants/time.ts';
|
||||
|
||||
/**
|
||||
* 服务器详情页面
|
||||
@@ -8,7 +8,8 @@ import {
|
||||
ArrowUp,
|
||||
Clock,
|
||||
Cpu,
|
||||
Filter, Globe,
|
||||
Filter,
|
||||
Globe,
|
||||
HardDrive,
|
||||
LinkIcon,
|
||||
Loader2,
|
||||
@@ -19,12 +20,13 @@ import {
|
||||
} from 'lucide-react';
|
||||
import {getPublicTags, listAgents} from '@/api/agent.ts';
|
||||
import type {Agent, LatestMetrics} from '@/types';
|
||||
import {cn} from '@/lib/utils';
|
||||
import {cn} from '@/lib/utils.ts';
|
||||
import CompactResourceBar from "@portal/components/CompactResourceBar.tsx";
|
||||
import StatBlock from "@portal/components/StatBlock.tsx";
|
||||
import ServerCard from "@portal/components/ServerCard.tsx";
|
||||
import NetworkStatCard from "@portal/components/NetworkStatCard.tsx";
|
||||
import {formatBytes, formatSpeed, formatUptime} from "@portal/utils/util.ts";
|
||||
import {isExpired} from "@portal/utils/server.ts";
|
||||
|
||||
interface AgentWithMetrics extends Agent {
|
||||
metrics?: LatestMetrics;
|
||||
@@ -289,7 +291,10 @@ const ServerList = () => {
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="space-y-1">
|
||||
<div
|
||||
className="font-bold text-slate-800 dark:text-cyan-100 font-mono text-sm transition-colors">
|
||||
className={cn(
|
||||
'font-bold text-slate-800 dark:text-cyan-100 font-mono text-sm transition-colors',
|
||||
isExpired(server.expireTime) ? 'text-red-600 dark:text-red-400' : ''
|
||||
)}>
|
||||
{server.name}
|
||||
</div>
|
||||
<div
|
||||
@@ -300,11 +305,13 @@ const ServerList = () => {
|
||||
</div>
|
||||
{isOnline && server.metrics?.host && (
|
||||
<div className="flex items-center gap-3 text-xs font-mono mt-1">
|
||||
<div className="flex items-center gap-1 text-gray-500 dark:text-cyan-600">
|
||||
<div
|
||||
className="flex items-center gap-1 text-gray-500 dark:text-cyan-600">
|
||||
<Clock className="w-3 h-3"/>
|
||||
<span>{formatUptime(server.metrics.host.uptime)}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1 text-gray-500 dark:text-cyan-600">
|
||||
<div
|
||||
className="flex items-center gap-1 text-gray-500 dark:text-cyan-600">
|
||||
<Activity className="w-3 h-3"/>
|
||||
<span>{server.metrics.host.procs} 进程</span>
|
||||
</div>
|
||||
@@ -347,7 +354,8 @@ const ServerList = () => {
|
||||
<span key={index} className="flex items-center gap-1">
|
||||
<span
|
||||
className="text-orange-400">{temp.temperature?.toFixed(1)}°C</span>
|
||||
<span className="text-gray-500 dark:text-cyan-500">{temp.type}</span>
|
||||
<span
|
||||
className="text-gray-500 dark:text-cyan-500">{temp.type}</span>
|
||||
{index < temperatures.length - 1 &&
|
||||
<span className="text-cyan-900">|</span>}
|
||||
</span>
|
||||
@@ -367,25 +375,28 @@ const ServerList = () => {
|
||||
{/* Network */}
|
||||
<td className="p-4 font-mono text-xs align-top">
|
||||
<div className="flex flex-col gap-1.5 mb-1.5">
|
||||
<span className="flex items-center gap-2 text-emerald-600 dark:text-emerald-400/80">
|
||||
<span
|
||||
className="flex items-center gap-2 text-emerald-600 dark:text-emerald-400/80">
|
||||
<ArrowDown className="w-3 h-3"/>
|
||||
<span>{formatSpeed(download)}</span>
|
||||
</span>
|
||||
<span className="flex items-center gap-2 text-blue-600 dark:text-blue-400/80">
|
||||
<span
|
||||
className="flex items-center gap-2 text-blue-600 dark:text-blue-400/80">
|
||||
<ArrowUp className="w-3 h-3"/>
|
||||
<span>{formatSpeed(upload)}</span>
|
||||
</span>
|
||||
</div>
|
||||
{server.trafficLimit > 0 && (
|
||||
{server.traffic?.limit > 0 && (
|
||||
<div className="w-32 text-xs">
|
||||
<div
|
||||
className="flex justify-between text-gray-600 dark:text-cyan-500 mb-0.5">
|
||||
<span className={''}>流量使用</span>
|
||||
<span>{Math.round((server.trafficUsed || 0) / server.trafficLimit * 100)}%</span>
|
||||
<span>{Math.round((server.traffic?.used || 0) / server.traffic?.limit * 100)}%</span>
|
||||
</div>
|
||||
<div className="h-1 bg-slate-200 dark:bg-cyan-900/50 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-1 bg-slate-200 dark:bg-cyan-900/50 rounded-full overflow-hidden">
|
||||
<div className="h-full bg-gray-500 dark:bg-cyan-400"
|
||||
style={{width: `${((server.trafficUsed || 0) / server.trafficLimit) * 100}%`}}></div>
|
||||
style={{width: `${((server.traffic?.used || 0) / server.traffic?.limit) * 100}%`}}></div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -396,20 +407,25 @@ const ServerList = () => {
|
||||
{isOnline && netConn ? (
|
||||
<div className="flex flex-col gap-1.5">
|
||||
<div className="flex items-center gap-2">
|
||||
<Network className="w-3 h-3 text-emerald-600 dark:text-emerald-400"/>
|
||||
<Network
|
||||
className="w-3 h-3 text-emerald-600 dark:text-emerald-400"/>
|
||||
<span
|
||||
className="text-emerald-600 dark:text-emerald-400">{netConn.established || 0}</span>
|
||||
<span className="text-gray-600 dark:text-cyan-500">ESTABLISHED</span>
|
||||
<span
|
||||
className="text-gray-600 dark:text-cyan-500">ESTABLISHED</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Network className="w-3 h-3 text-blue-600 dark:text-blue-400"/>
|
||||
<span className="text-blue-600 dark:text-blue-400">{netConn.listen || 0}</span>
|
||||
<span
|
||||
className="text-blue-600 dark:text-blue-400">{netConn.listen || 0}</span>
|
||||
<span className="text-gray-600 dark:text-cyan-500">LISTEN</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Network className="w-3 h-3 text-rose-600 dark:text-rose-400"/>
|
||||
<span className="text-rose-600 dark:text-rose-400">{netConn.closeWait || 0}</span>
|
||||
<span className="text-gray-600 dark:text-cyan-500">CLOSE_WAIT</span>
|
||||
<span
|
||||
className="text-rose-600 dark:text-rose-400">{netConn.closeWait || 0}</span>
|
||||
<span
|
||||
className="text-gray-600 dark:text-cyan-500">CLOSE_WAIT</span>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
@@ -432,7 +448,7 @@ const ServerList = () => {
|
||||
className={cn(
|
||||
`text-xs font-mono flex items-center gap-1 text-gray-600 dark:text-cyan-500`,
|
||||
// 剩余时间小于 30 天时显示为红色
|
||||
server.expireTime && server.expireTime > 0 && server.expireTime - Date.now() < 30 * 24 * 60 * 60 * 1000 ? 'text-red-600 dark:text-red-400' : ''
|
||||
isExpired(server.expireTime) ? 'text-red-600 dark:text-red-400' : ''
|
||||
)}>
|
||||
|
||||
{server.expireTime > 0 &&
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
export const isExpired = (expireTime?: number) => {
|
||||
return expireTime && expireTime > 0 && expireTime - Date.now() < 30 * 24 * 60 * 60 * 1000
|
||||
}
|
||||
@@ -12,10 +12,10 @@ const AgentDetailPage = lazy(() => import('@admin/pages/Agents/AgentDetail'));
|
||||
const AgentInstallPage = lazy(() => import('@admin/pages/Agents/AgentInstall'));
|
||||
const ApiKeyListPage = lazy(() => import('@admin/pages/ApiKeys/ApiKeyList'));
|
||||
const SettingsPage = lazy(() => import('@admin/pages/Settings'));
|
||||
const ServerListPage = lazy(() => import('@portal/pages/Public/ServerList'));
|
||||
const ServerDetailPage = lazy(() => import('@portal/pages/Public/ServerDetail'));
|
||||
const PublicMonitorListPage = lazy(() => import('@portal/pages/Public/MonitorList'));
|
||||
const PublicMonitorDetailPage = lazy(() => import('@portal/pages/Public/MonitorDetail'));
|
||||
const ServerListPage = lazy(() => import('@portal/pages/ServerList.tsx'));
|
||||
const ServerDetailPage = lazy(() => import('@portal/pages/ServerDetail.tsx'));
|
||||
const PublicMonitorListPage = lazy(() => import('@portal/pages/MonitorList.tsx'));
|
||||
const PublicMonitorDetailPage = lazy(() => import('@portal/pages/MonitorDetail.tsx'));
|
||||
const MonitorListPage = lazy(() => import('@admin/pages/Monitors/MonitorList'));
|
||||
const DDNSPage = lazy(() => import('@admin/pages/DDNS'));
|
||||
const AlertRecordListPage = lazy(() => import('@admin/pages/AlertRecords'));
|
||||
|
||||
@@ -30,14 +30,12 @@ export interface Agent {
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
// 流量统计相关字段
|
||||
trafficLimit?: number; // 流量限额(字节), 0表示不限制
|
||||
trafficUsed?: number; // 当前周期已使用流量(字节)
|
||||
trafficResetDay?: number; // 流量重置日期(1-31), 0表示不自动重置
|
||||
trafficPeriodStart?: number; // 当前周期开始时间(时间戳毫秒)
|
||||
trafficBaselineRecv?: number; // 当前周期流量基线(BytesRecvTotal)
|
||||
trafficAlertSent80?: boolean; // 是否已发送80%告警
|
||||
trafficAlertSent90?: boolean; // 是否已发送90%告警
|
||||
trafficAlertSent100?: boolean;// 是否已发送100%告警
|
||||
traffic?: TrafficData; // 流量
|
||||
}
|
||||
|
||||
export interface TrafficData {
|
||||
limit?: number;
|
||||
used?: number;
|
||||
}
|
||||
|
||||
// 聚合指标数据(所有图表查询只返回聚合数据)
|
||||
|
||||
Reference in new issue
Block a user