1.18升级
This commit is contained in:
parent
8b66e7d100
commit
38b6e873c8
@ -66,6 +66,8 @@
|
||||
"cmdk": "^1.1.1",
|
||||
"dagre": "^0.8.5",
|
||||
"dayjs": "^1.11.13",
|
||||
"echarts": "^6.0.0",
|
||||
"echarts-for-react": "^3.0.5",
|
||||
"form-render": "^2.5.6",
|
||||
"less": "^4.2.1",
|
||||
"monaco-editor": "^0.52.2",
|
||||
|
||||
@ -173,6 +173,12 @@ importers:
|
||||
dayjs:
|
||||
specifier: ^1.11.13
|
||||
version: 1.11.13
|
||||
echarts:
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0
|
||||
echarts-for-react:
|
||||
specifier: ^3.0.5
|
||||
version: 3.0.5(echarts@6.0.0)(react@18.3.1)
|
||||
form-render:
|
||||
specifier: ^2.5.6
|
||||
version: 2.5.6(@types/react@18.3.18)(antd@5.27.5(date-fns@2.30.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(immer@10.1.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@ -2752,6 +2758,15 @@ packages:
|
||||
eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||
|
||||
echarts-for-react@3.0.5:
|
||||
resolution: {integrity: sha512-YpEI5Ty7O/2nvCfQ7ybNa+S90DwE8KYZWacGvJW4luUqywP7qStQ+pxDlYOmr4jGDu10mhEkiAuMKcUlT4W5vg==}
|
||||
peerDependencies:
|
||||
echarts: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0
|
||||
react: ^15.0.0 || >=16.0.0
|
||||
|
||||
echarts@6.0.0:
|
||||
resolution: {integrity: sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==}
|
||||
|
||||
electron-to-chromium@1.5.73:
|
||||
resolution: {integrity: sha512-8wGNxG9tAG5KhGd3eeA0o6ixhiNdgr0DcHWm85XPCphwZgD1lIEoi6t3VERayWao7SF7AAZTw6oARGJeVjH8Kg==}
|
||||
|
||||
@ -4106,6 +4121,9 @@ packages:
|
||||
simple-swizzle@0.2.4:
|
||||
resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==}
|
||||
|
||||
size-sensor@1.0.2:
|
||||
resolution: {integrity: sha512-2NCmWxY7A9pYKGXNBfteo4hy14gWu47rg5692peVMst6lQLPKrVjhY+UTEsPI5ceFRJSl3gVgMYaUi/hKuaiKw==}
|
||||
|
||||
slash@3.0.0:
|
||||
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
||||
engines: {node: '>=8'}
|
||||
@ -4242,6 +4260,9 @@ packages:
|
||||
ts-interface-checker@0.1.13:
|
||||
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
|
||||
|
||||
tslib@2.3.0:
|
||||
resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==}
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
@ -4411,6 +4432,9 @@ packages:
|
||||
zod@3.24.1:
|
||||
resolution: {integrity: sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==}
|
||||
|
||||
zrender@6.0.0:
|
||||
resolution: {integrity: sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==}
|
||||
|
||||
zustand@4.5.5:
|
||||
resolution: {integrity: sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q==}
|
||||
engines: {node: '>=12.7.0'}
|
||||
@ -7272,6 +7296,18 @@ snapshots:
|
||||
|
||||
eastasianwidth@0.2.0: {}
|
||||
|
||||
echarts-for-react@3.0.5(echarts@6.0.0)(react@18.3.1):
|
||||
dependencies:
|
||||
echarts: 6.0.0
|
||||
fast-deep-equal: 3.1.3
|
||||
react: 18.3.1
|
||||
size-sensor: 1.0.2
|
||||
|
||||
echarts@6.0.0:
|
||||
dependencies:
|
||||
tslib: 2.3.0
|
||||
zrender: 6.0.0
|
||||
|
||||
electron-to-chromium@1.5.73: {}
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
@ -8777,6 +8813,8 @@ snapshots:
|
||||
dependencies:
|
||||
is-arrayish: 0.3.4
|
||||
|
||||
size-sensor@1.0.2: {}
|
||||
|
||||
slash@3.0.0: {}
|
||||
|
||||
source-map-js@1.2.1: {}
|
||||
@ -8923,6 +8961,8 @@ snapshots:
|
||||
|
||||
ts-interface-checker@0.1.13: {}
|
||||
|
||||
tslib@2.3.0: {}
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
type-check@0.4.0:
|
||||
@ -9052,6 +9092,10 @@ snapshots:
|
||||
|
||||
zod@3.24.1: {}
|
||||
|
||||
zrender@6.0.0:
|
||||
dependencies:
|
||||
tslib: 2.3.0
|
||||
|
||||
zustand@4.5.5(@types/react@18.3.18)(immer@10.1.1)(react@18.3.1):
|
||||
dependencies:
|
||||
use-sync-external-store: 1.2.2(react@18.3.1)
|
||||
|
||||
@ -16,6 +16,7 @@ import {
|
||||
Tag,
|
||||
FileText,
|
||||
RefreshCw,
|
||||
BarChart3,
|
||||
} from 'lucide-react';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
@ -38,12 +39,13 @@ interface ServerCardProps {
|
||||
onDelete: (server: ServerResponse) => void;
|
||||
onSSHConnect: (server: ServerResponse) => void;
|
||||
onCollectHardware: (server: ServerResponse) => void;
|
||||
onMonitor: (server: ServerResponse) => void;
|
||||
isTesting?: boolean;
|
||||
isCollecting?: boolean;
|
||||
getOsIcon: (osType?: string) => React.ReactNode;
|
||||
}
|
||||
|
||||
export const ServerCard: React.FC<ServerCardProps> = ({ server, onTest, onEdit, onDelete, onSSHConnect, onCollectHardware, isTesting, isCollecting, getOsIcon }) => {
|
||||
export const ServerCard: React.FC<ServerCardProps> = ({ server, onTest, onEdit, onDelete, onSSHConnect, onCollectHardware, onMonitor, isTesting, isCollecting, getOsIcon }) => {
|
||||
const [expanded, setExpanded] = React.useState(false);
|
||||
|
||||
const formatTime = (time?: string) => {
|
||||
@ -73,6 +75,11 @@ export const ServerCard: React.FC<ServerCardProps> = ({ server, onTest, onEdit,
|
||||
<Card className={`group relative flex h-full flex-col justify-between overflow-visible border transition-all duration-200 hover:border-primary/40 hover:shadow-lg ${
|
||||
expanded ? 'rounded-b-none border-b-0' : ''
|
||||
}`}>
|
||||
{/* ID Badge - 悬浮在左上角,类似通知样式 */}
|
||||
<div className="absolute -left-2 -top-2 z-10 flex h-6 w-6 items-center justify-center rounded-full bg-primary text-[10px] font-bold text-primary-foreground shadow-md">
|
||||
{server.id}
|
||||
</div>
|
||||
|
||||
<CardContent className="flex flex-1 flex-col gap-3 p-3">
|
||||
{/* 基础信息 */}
|
||||
<div className="flex items-start gap-3">
|
||||
@ -233,6 +240,20 @@ export const ServerCard: React.FC<ServerCardProps> = ({ server, onTest, onEdit,
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7 text-primary"
|
||||
onClick={() => onMonitor(server)}
|
||||
>
|
||||
<BarChart3 className="h-3.5 w-3.5" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>监控数据</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
|
||||
@ -9,6 +9,7 @@ import {
|
||||
HelpCircle,
|
||||
Terminal,
|
||||
RefreshCw,
|
||||
BarChart3,
|
||||
} from 'lucide-react';
|
||||
import {
|
||||
Table,
|
||||
@ -38,6 +39,7 @@ interface ServerTableProps {
|
||||
onDelete: (server: ServerResponse) => void;
|
||||
onSSHConnect: (server: ServerResponse) => void;
|
||||
onCollectHardware: (server: ServerResponse) => void;
|
||||
onMonitor: (server: ServerResponse) => void;
|
||||
isTesting?: (serverId: number) => boolean;
|
||||
isCollecting?: (serverId: number) => boolean;
|
||||
getOsIcon: (osType?: string) => React.ReactNode;
|
||||
@ -50,6 +52,7 @@ export const ServerTable: React.FC<ServerTableProps> = ({
|
||||
onDelete,
|
||||
onSSHConnect,
|
||||
onCollectHardware,
|
||||
onMonitor,
|
||||
isTesting,
|
||||
isCollecting,
|
||||
getOsIcon,
|
||||
@ -74,6 +77,7 @@ export const ServerTable: React.FC<ServerTableProps> = ({
|
||||
<Table minWidth="1200px">
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead width="80px">ID</TableHead>
|
||||
<TableHead width="180px">服务器名称</TableHead>
|
||||
<TableHead width="150px">IP地址</TableHead>
|
||||
<TableHead width="120px">状态</TableHead>
|
||||
@ -89,13 +93,16 @@ export const ServerTable: React.FC<ServerTableProps> = ({
|
||||
<TableBody>
|
||||
{servers.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={10} className="text-center py-8">
|
||||
<TableCell colSpan={11} className="text-center py-8">
|
||||
<span className="text-muted-foreground">暂无服务器数据</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
servers.map((server) => (
|
||||
<TableRow key={server.id}>
|
||||
<TableCell>
|
||||
<span className="font-mono text-sm text-muted-foreground">{server.id}</span>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium text-foreground">{server.serverName}</span>
|
||||
@ -141,6 +148,19 @@ export const ServerTable: React.FC<ServerTableProps> = ({
|
||||
</TableCell>
|
||||
<TableCell sticky className="text-right">
|
||||
<div className="flex items-center justify-end gap-1">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => onMonitor(server)}
|
||||
className="h-8 w-8 p-0"
|
||||
>
|
||||
<BarChart3 className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>监控数据</TooltipContent>
|
||||
</Tooltip>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
|
||||
@ -44,6 +44,7 @@ import { ServerCard } from './components/ServerCard';
|
||||
import { ServerTable } from './components/ServerTable';
|
||||
import { SSHWindowManager } from './components/SSHWindowManager';
|
||||
import { FileManagerWindowManager } from '@/components/FileManager';
|
||||
import { ServerMonitorDialog } from './components/ServerMonitorDialog';
|
||||
|
||||
const ServerList: React.FC = () => {
|
||||
const { toast } = useToast();
|
||||
@ -81,6 +82,8 @@ const ServerList: React.FC = () => {
|
||||
const [serverToDelete, setServerToDelete] = useState<ServerResponse | null>(null);
|
||||
const [testingServerId, setTestingServerId] = useState<number | null>(null);
|
||||
const [collectingServerId, setCollectingServerId] = useState<number | null>(null);
|
||||
const [monitorDialogOpen, setMonitorDialogOpen] = useState(false);
|
||||
const [monitoringServer, setMonitoringServer] = useState<ServerResponse | null>(null);
|
||||
const [statsData, setStatsData] = useState<{
|
||||
total: number;
|
||||
online: number;
|
||||
@ -103,10 +106,10 @@ const ServerList: React.FC = () => {
|
||||
try {
|
||||
// 并行请求各个状态的数量
|
||||
const [totalResult, onlineResult, offlineResult, unknownResult] = await Promise.all([
|
||||
getServers({ categoryId: selectedCategoryId, osType: selectedOsType, pageNum: 0, size: 1 }),
|
||||
getServers({ categoryId: selectedCategoryId, status: 'ONLINE', osType: selectedOsType, pageNum: 0, size: 1 }),
|
||||
getServers({ categoryId: selectedCategoryId, status: 'OFFLINE', osType: selectedOsType, pageNum: 0, size: 1 }),
|
||||
getServers({ categoryId: selectedCategoryId, status: 'UNKNOWN', osType: selectedOsType, pageNum: 0, size: 1 }),
|
||||
getServers({ categoryId: selectedCategoryId, osType: selectedOsType, pageNum: 0, pageSize: 1 }),
|
||||
getServers({ categoryId: selectedCategoryId, status: 'ONLINE', osType: selectedOsType, pageNum: 0, pageSize: 1 }),
|
||||
getServers({ categoryId: selectedCategoryId, status: 'OFFLINE', osType: selectedOsType, pageNum: 0, pageSize: 1 }),
|
||||
getServers({ categoryId: selectedCategoryId, status: 'UNKNOWN', osType: selectedOsType, pageNum: 0, pageSize: 1 }),
|
||||
]);
|
||||
|
||||
setStatsData({
|
||||
@ -173,7 +176,7 @@ const ServerList: React.FC = () => {
|
||||
const result = await getServers({
|
||||
...params,
|
||||
pageNum: pageIndex,
|
||||
size: pageSize,
|
||||
pageSize: pageSize,
|
||||
});
|
||||
if (result) {
|
||||
setServers(result.content || []);
|
||||
@ -280,6 +283,12 @@ const ServerList: React.FC = () => {
|
||||
setDeleteDialogOpen(true);
|
||||
};
|
||||
|
||||
// 监控数据
|
||||
const handleMonitor = (server: ServerResponse) => {
|
||||
setMonitoringServer(server);
|
||||
setMonitorDialogOpen(true);
|
||||
};
|
||||
|
||||
// SSH连接 - 使用多窗口系统
|
||||
const handleSSHConnect = (server: ServerResponse) => {
|
||||
// 调用全局方法打开新的SSH窗口
|
||||
@ -345,15 +354,12 @@ const ServerList: React.FC = () => {
|
||||
// 监听筛选条件和视图模式变化(使用全局loading)
|
||||
useEffect(() => {
|
||||
loadServers(false, false); // 筛选加载,使用全局loading
|
||||
// 筛选条件变化时重置分页到第一页
|
||||
setPageIndex(0);
|
||||
}, [pageSize, selectedCategoryId, selectedStatus, selectedOsType, viewMode]);
|
||||
|
||||
// 监听分页变化(单独处理,使用pageLoading)
|
||||
// 注意:这个useEffect只处理用户主动翻页的情况
|
||||
useEffect(() => {
|
||||
if (viewMode === 'table' && pageIndex > 0) {
|
||||
// pageIndex > 0 说明是用户翻页操作,使用pageLoading
|
||||
if (viewMode === 'table') {
|
||||
// 表格模式下,分页变化时加载数据
|
||||
loadServers(false, true);
|
||||
}
|
||||
}, [pageIndex]);
|
||||
@ -615,6 +621,7 @@ const ServerList: React.FC = () => {
|
||||
onDelete={handleDelete}
|
||||
onSSHConnect={handleSSHConnect}
|
||||
onCollectHardware={handleCollectHardware}
|
||||
onMonitor={handleMonitor}
|
||||
isTesting={testingServerId === server.id}
|
||||
isCollecting={collectingServerId === server.id}
|
||||
getOsIcon={getOsIcon}
|
||||
@ -642,6 +649,7 @@ const ServerList: React.FC = () => {
|
||||
onDelete={handleDelete}
|
||||
onSSHConnect={handleSSHConnect}
|
||||
onCollectHardware={handleCollectHardware}
|
||||
onMonitor={handleMonitor}
|
||||
isTesting={(serverId) => testingServerId === serverId}
|
||||
isCollecting={(serverId) => collectingServerId === serverId}
|
||||
getOsIcon={getOsIcon}
|
||||
@ -726,6 +734,13 @@ const ServerList: React.FC = () => {
|
||||
confirmText="确定"
|
||||
/>
|
||||
|
||||
{/* 监控数据对话框 */}
|
||||
<ServerMonitorDialog
|
||||
open={monitorDialogOpen}
|
||||
onOpenChange={setMonitorDialogOpen}
|
||||
server={monitoringServer}
|
||||
/>
|
||||
|
||||
{/* SSH多窗口管理器 */}
|
||||
<SSHWindowManager />
|
||||
|
||||
|
||||
@ -10,6 +10,9 @@ import type {
|
||||
AlertRuleResponse,
|
||||
AlertRuleQuery,
|
||||
AlertRuleRequest,
|
||||
ServerMonitorResponse,
|
||||
TimeRange,
|
||||
MetricType,
|
||||
} from './types';
|
||||
import type { ServerFormValues } from './schema';
|
||||
import type { Page } from '@/types/base';
|
||||
@ -18,6 +21,7 @@ import type { Page } from '@/types/base';
|
||||
const CATEGORY_URL = '/api/v1/server-category';
|
||||
const SERVER_URL = '/api/v1/server';
|
||||
const ALERT_RULE_URL = '/api/v1/server/alert-rule';
|
||||
const MONITOR_URL = '/api/v1/server/monitor';
|
||||
|
||||
// ==================== 服务器分类 ====================
|
||||
|
||||
@ -78,22 +82,14 @@ export const getServerList = (params?: {
|
||||
/**
|
||||
* 获取服务器分页列表
|
||||
*/
|
||||
export const getServers = (params: {
|
||||
export const getServers = (params?: {
|
||||
categoryId?: number;
|
||||
status?: string;
|
||||
osType?: string;
|
||||
pageNum?: number;
|
||||
size?: number;
|
||||
pageSize?: number;
|
||||
}) =>
|
||||
request.get<Page<ServerResponse>>(`${SERVER_URL}/page`, {
|
||||
params: {
|
||||
pageNum: params.pageNum ?? 0,
|
||||
size: params.size ?? 20,
|
||||
categoryId: params.categoryId,
|
||||
status: params.status,
|
||||
osType: params.osType,
|
||||
},
|
||||
});
|
||||
request.get<Page<ServerResponse>>(`${SERVER_URL}/page`, { params });
|
||||
|
||||
/**
|
||||
* 获取服务器详情
|
||||
@ -177,3 +173,22 @@ export const updateAlertRule = (id: number, data: AlertRuleRequest) =>
|
||||
export const deleteAlertRule = (id: number) =>
|
||||
request.delete<void>(`${ALERT_RULE_URL}/${id}`);
|
||||
|
||||
// ==================== 服务器监控 ====================
|
||||
|
||||
/**
|
||||
* 获取服务器监控数据
|
||||
* @param serverId 服务器ID
|
||||
* @param timeRange 时间范围
|
||||
* @param metrics 指标类型列表(可选,为空则查询所有)
|
||||
*/
|
||||
export const getServerMonitorMetrics = (
|
||||
serverId: number,
|
||||
timeRange: TimeRange,
|
||||
metrics?: MetricType[]
|
||||
) =>
|
||||
request.get<ServerMonitorResponse>(`${MONITOR_URL}/${serverId}/metrics`, {
|
||||
params: {
|
||||
timeRange,
|
||||
metrics: metrics?.join(','),
|
||||
},
|
||||
});
|
||||
|
||||
@ -371,3 +371,233 @@ export const AlertTypeLabels: Record<AlertType, { label: string; unit: string; d
|
||||
[AlertType.SERVER_STATUS]: { label: '服务器状态', unit: '次', description: '服务器连接状态告警' },
|
||||
};
|
||||
|
||||
// ==================== 服务器监控 ====================
|
||||
|
||||
/**
|
||||
* 时间范围枚举
|
||||
*/
|
||||
export enum TimeRange {
|
||||
/** 最近1小时 */
|
||||
LAST_1_HOUR = 'LAST_1_HOUR',
|
||||
/** 最近6小时 */
|
||||
LAST_6_HOURS = 'LAST_6_HOURS',
|
||||
/** 最近24小时 */
|
||||
LAST_24_HOURS = 'LAST_24_HOURS',
|
||||
/** 最近7天 */
|
||||
LAST_7_DAYS = 'LAST_7_DAYS',
|
||||
/** 最近30天 */
|
||||
LAST_30_DAYS = 'LAST_30_DAYS',
|
||||
}
|
||||
|
||||
/**
|
||||
* 监控指标类型枚举
|
||||
*/
|
||||
export enum MetricType {
|
||||
/** CPU */
|
||||
CPU = 'CPU',
|
||||
/** 内存 */
|
||||
MEMORY = 'MEMORY',
|
||||
/** 磁盘 */
|
||||
DISK = 'DISK',
|
||||
/** 网络 */
|
||||
NETWORK = 'NETWORK',
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间范围标签映射
|
||||
*/
|
||||
export const TimeRangeLabels: Record<TimeRange, { label: string; interval: string; description: string }> = {
|
||||
[TimeRange.LAST_1_HOUR]: { label: '最近1小时', interval: '5分钟', description: '最近1小时的监控数据' },
|
||||
[TimeRange.LAST_6_HOURS]: { label: '最近6小时', interval: '5分钟', description: '最近6小时的监控数据' },
|
||||
[TimeRange.LAST_24_HOURS]: { label: '最近24小时', interval: '15分钟', description: '最近24小时的监控数据' },
|
||||
[TimeRange.LAST_7_DAYS]: { label: '最近7天', interval: '1小时', description: '最近7天的监控数据' },
|
||||
[TimeRange.LAST_30_DAYS]: { label: '最近30天', interval: '4小时', description: '最近30天的监控数据' },
|
||||
};
|
||||
|
||||
/**
|
||||
* 指标类型标签映射
|
||||
*/
|
||||
export const MetricTypeLabels: Record<MetricType, { label: string; unit: string; color: string }> = {
|
||||
[MetricType.CPU]: { label: 'CPU使用率', unit: '%', color: '#3b82f6' },
|
||||
[MetricType.MEMORY]: { label: '内存使用率', unit: '%', color: '#10b981' },
|
||||
[MetricType.DISK]: { label: '磁盘使用率', unit: '%', color: '#f59e0b' },
|
||||
[MetricType.NETWORK]: { label: '网络流量', unit: 'MB/s', color: '#8b5cf6' },
|
||||
};
|
||||
|
||||
/**
|
||||
* CPU监控数据点
|
||||
*/
|
||||
export interface CpuMetricData {
|
||||
/** 时间点 */
|
||||
time: string;
|
||||
/** CPU使用率(%) */
|
||||
value: number;
|
||||
/** 采集状态 */
|
||||
status: 'SUCCESS' | 'FAILURE';
|
||||
}
|
||||
|
||||
/**
|
||||
* 内存监控数据点
|
||||
*/
|
||||
export interface MemoryMetricData {
|
||||
/** 时间点 */
|
||||
time: string;
|
||||
/** 内存使用率(%) */
|
||||
usagePercent: number;
|
||||
/** 已用内存(GB) */
|
||||
usedGB: number;
|
||||
/** 采集状态 */
|
||||
status: 'SUCCESS' | 'FAILURE';
|
||||
}
|
||||
|
||||
/**
|
||||
* 网络监控数据点
|
||||
*/
|
||||
export interface NetworkMetricData {
|
||||
/** 时间点 */
|
||||
time: string;
|
||||
/** 接收字节数(累计) */
|
||||
rxBytes: number;
|
||||
/** 发送字节数(累计) */
|
||||
txBytes: number;
|
||||
/** 接收速率(MB/s) */
|
||||
rxMBps: number;
|
||||
/** 发送速率(MB/s) */
|
||||
txMBps: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 磁盘分区信息
|
||||
*/
|
||||
export interface DiskPartitionData {
|
||||
/** 挂载点 */
|
||||
mountPoint: string;
|
||||
/** 文件系统 */
|
||||
fileSystem: string;
|
||||
/** 总容量(GB) */
|
||||
totalSizeGB: number;
|
||||
/** 已用容量(GB) */
|
||||
usedSizeGB: number;
|
||||
/** 使用率(%) */
|
||||
usagePercent: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 磁盘监控数据
|
||||
*/
|
||||
export interface DiskMetricData {
|
||||
/** 最新采集时间 */
|
||||
latestTime: string;
|
||||
/** 分区信息列表 */
|
||||
partitions: DiskPartitionData[];
|
||||
/** 时间范围内最大使用率(%) */
|
||||
maxUsagePercent: number;
|
||||
/** 最大使用率的分区 */
|
||||
maxUsagePartition: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* CPU统计信息
|
||||
*/
|
||||
export interface CpuStatistics {
|
||||
/** 平均值(%) */
|
||||
avg: number;
|
||||
/** 最大值(%) */
|
||||
max: number;
|
||||
/** 最小值(%) */
|
||||
min: number;
|
||||
/** 峰值时间 */
|
||||
maxTime: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 内存统计信息
|
||||
*/
|
||||
export interface MemoryStatistics {
|
||||
/** 平均使用率(%) */
|
||||
avgPercent: number;
|
||||
/** 最大使用率(%) */
|
||||
maxPercent: number;
|
||||
/** 最小使用率(%) */
|
||||
minPercent: number;
|
||||
/** 峰值时间 */
|
||||
maxTime: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 网络统计信息
|
||||
*/
|
||||
export interface NetworkStatistics {
|
||||
/** 总接收字节数 */
|
||||
totalRxBytes: number;
|
||||
/** 总发送字节数 */
|
||||
totalTxBytes: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务器信息
|
||||
*/
|
||||
export interface MonitorServerInfo {
|
||||
/** 服务器ID */
|
||||
serverId: number;
|
||||
/** 服务器名称 */
|
||||
serverName: string;
|
||||
/** 主机IP */
|
||||
hostIp: string;
|
||||
/** 服务器状态 */
|
||||
status: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间范围信息
|
||||
*/
|
||||
export interface MonitorTimeRangeInfo {
|
||||
/** 开始时间 */
|
||||
startTime: string;
|
||||
/** 结束时间 */
|
||||
endTime: string;
|
||||
/** 数据聚合间隔 */
|
||||
interval: string;
|
||||
/** 实际返回的数据点数量 */
|
||||
dataPoints: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 监控指标数据
|
||||
*/
|
||||
export interface MonitorMetrics {
|
||||
/** CPU数据 */
|
||||
cpu: CpuMetricData[] | null;
|
||||
/** 内存数据 */
|
||||
memory: MemoryMetricData[] | null;
|
||||
/** 网络数据 */
|
||||
network: NetworkMetricData[] | null;
|
||||
/** 磁盘数据 */
|
||||
disk: DiskMetricData | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 监控统计信息
|
||||
*/
|
||||
export interface MonitorStatistics {
|
||||
/** CPU统计 */
|
||||
cpu: CpuStatistics | null;
|
||||
/** 内存统计 */
|
||||
memory: MemoryStatistics | null;
|
||||
/** 网络统计 */
|
||||
network: NetworkStatistics | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 服务器监控数据响应
|
||||
*/
|
||||
export interface ServerMonitorResponse {
|
||||
/** 服务器信息 */
|
||||
server: MonitorServerInfo;
|
||||
/** 时间范围信息 */
|
||||
timeRange: MonitorTimeRangeInfo;
|
||||
/** 指标数据 */
|
||||
metrics: MonitorMetrics;
|
||||
/** 统计信息 */
|
||||
statistics: MonitorStatistics;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user