refactor: overhaul system navigation based on 5 HTML docs
Reorganize modules, add AI Agent smart interaction, include prompt settings, enhance data output with subscriptions, and separate system monitoring. Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
This commit is contained in:
346
app/system/alerts/page.tsx
Normal file
346
app/system/alerts/page.tsx
Normal file
@@ -0,0 +1,346 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
||||
import { Switch } from "@/components/ui/switch"
|
||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
|
||||
import {
|
||||
Bell, Plus, Settings, CheckCircle2, AlertTriangle,
|
||||
XCircle, Clock, Eye, Trash2, BellOff
|
||||
} from "lucide-react"
|
||||
|
||||
const alerts = [
|
||||
{
|
||||
id: "1",
|
||||
title: "磁盘使用率超过70%",
|
||||
description: "服务器磁盘使用率达到72%,建议清理或扩容",
|
||||
severity: "warning",
|
||||
source: "系统监控",
|
||||
time: "2024-01-15 14:30:00",
|
||||
status: "active",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
title: "AI推理服务延迟升高",
|
||||
description: "AI推理服务平均延迟达到230ms,超过预设阈值200ms",
|
||||
severity: "warning",
|
||||
source: "AI Agent",
|
||||
time: "2024-01-15 13:45:00",
|
||||
status: "active",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
title: "数据同步任务失败",
|
||||
description: "用户行为数据同步任务执行失败,已自动重试",
|
||||
severity: "error",
|
||||
source: "数据接入",
|
||||
time: "2024-01-15 10:20:00",
|
||||
status: "resolved",
|
||||
},
|
||||
]
|
||||
|
||||
const alertRules = [
|
||||
{ id: "1", name: "CPU使用率告警", condition: "CPU > 80%", severity: "critical", enabled: true },
|
||||
{ id: "2", name: "内存使用率告警", condition: "内存 > 85%", severity: "critical", enabled: true },
|
||||
{ id: "3", name: "磁盘使用率告警", condition: "磁盘 > 70%", severity: "warning", enabled: true },
|
||||
{ id: "4", name: "API延迟告警", condition: "延迟 > 500ms", severity: "warning", enabled: true },
|
||||
{ id: "5", name: "任务失败告警", condition: "失败次数 > 3", severity: "error", enabled: false },
|
||||
]
|
||||
|
||||
export default function AlertsPage() {
|
||||
const [activeTab, setActiveTab] = useState("active")
|
||||
const [showCreateDialog, setShowCreateDialog] = useState(false)
|
||||
|
||||
const getSeverityBadge = (severity: string) => {
|
||||
switch (severity) {
|
||||
case "critical":
|
||||
return <Badge className="bg-red-100 text-red-700">严重</Badge>
|
||||
case "error":
|
||||
return <Badge className="bg-red-100 text-red-700">错误</Badge>
|
||||
case "warning":
|
||||
return <Badge className="bg-yellow-100 text-yellow-700">警告</Badge>
|
||||
case "info":
|
||||
return <Badge className="bg-blue-100 text-blue-700">信息</Badge>
|
||||
default:
|
||||
return <Badge variant="secondary">未知</Badge>
|
||||
}
|
||||
}
|
||||
|
||||
const getSeverityIcon = (severity: string) => {
|
||||
switch (severity) {
|
||||
case "critical":
|
||||
case "error":
|
||||
return <XCircle className="h-5 w-5 text-red-500" />
|
||||
case "warning":
|
||||
return <AlertTriangle className="h-5 w-5 text-yellow-500" />
|
||||
default:
|
||||
return <Bell className="h-5 w-5 text-blue-500" />
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* 页面标题 */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-foreground">告警中心</h1>
|
||||
<p className="text-muted-foreground">查看和管理系统告警</p>
|
||||
</div>
|
||||
<Button onClick={() => setShowCreateDialog(true)}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
新建告警规则
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* 统计卡片 */}
|
||||
<div className="grid gap-4 md:grid-cols-4">
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">活跃告警</p>
|
||||
<p className="text-2xl font-bold text-yellow-600">2</p>
|
||||
</div>
|
||||
<AlertTriangle className="h-8 w-8 text-yellow-500" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">今日告警</p>
|
||||
<p className="text-2xl font-bold">5</p>
|
||||
</div>
|
||||
<Bell className="h-8 w-8 text-blue-500" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">已解决</p>
|
||||
<p className="text-2xl font-bold text-green-600">3</p>
|
||||
</div>
|
||||
<CheckCircle2 className="h-8 w-8 text-green-500" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">告警规则</p>
|
||||
<p className="text-2xl font-bold">5</p>
|
||||
</div>
|
||||
<Settings className="h-8 w-8 text-purple-500" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* 主内容区 */}
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab}>
|
||||
<TabsList>
|
||||
<TabsTrigger value="active">
|
||||
活跃告警
|
||||
<Badge className="ml-2 bg-yellow-100 text-yellow-700">2</Badge>
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="history">历史告警</TabsTrigger>
|
||||
<TabsTrigger value="rules">告警规则</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="active" className="space-y-4">
|
||||
{alerts.filter(a => a.status === "active").map((alert) => (
|
||||
<Card key={alert.id}>
|
||||
<CardContent className="pt-6">
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex items-start gap-4">
|
||||
{getSeverityIcon(alert.severity)}
|
||||
<div>
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<h3 className="font-semibold">{alert.title}</h3>
|
||||
{getSeverityBadge(alert.severity)}
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground mb-2">{alert.description}</p>
|
||||
<div className="flex items-center gap-4 text-xs text-muted-foreground">
|
||||
<span>来源: {alert.source}</span>
|
||||
<span>时间: {alert.time}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button variant="outline" size="sm">
|
||||
<Eye className="h-4 w-4 mr-1" />
|
||||
详情
|
||||
</Button>
|
||||
<Button size="sm">
|
||||
<CheckCircle2 className="h-4 w-4 mr-1" />
|
||||
确认
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="history" className="space-y-4">
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>告警标题</TableHead>
|
||||
<TableHead>严重程度</TableHead>
|
||||
<TableHead>来源</TableHead>
|
||||
<TableHead>时间</TableHead>
|
||||
<TableHead>状态</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{alerts.map((alert) => (
|
||||
<TableRow key={alert.id}>
|
||||
<TableCell className="font-medium">{alert.title}</TableCell>
|
||||
<TableCell>{getSeverityBadge(alert.severity)}</TableCell>
|
||||
<TableCell>{alert.source}</TableCell>
|
||||
<TableCell>{alert.time}</TableCell>
|
||||
<TableCell>
|
||||
{alert.status === "resolved" ? (
|
||||
<Badge className="bg-green-100 text-green-700">已解决</Badge>
|
||||
) : (
|
||||
<Badge className="bg-yellow-100 text-yellow-700">活跃</Badge>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="rules" className="space-y-4">
|
||||
<Card>
|
||||
<CardContent className="pt-6">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>规则名称</TableHead>
|
||||
<TableHead>触发条件</TableHead>
|
||||
<TableHead>严重程度</TableHead>
|
||||
<TableHead>状态</TableHead>
|
||||
<TableHead className="text-right">操作</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{alertRules.map((rule) => (
|
||||
<TableRow key={rule.id}>
|
||||
<TableCell className="font-medium">{rule.name}</TableCell>
|
||||
<TableCell>
|
||||
<code className="text-sm bg-muted px-2 py-1 rounded">{rule.condition}</code>
|
||||
</TableCell>
|
||||
<TableCell>{getSeverityBadge(rule.severity)}</TableCell>
|
||||
<TableCell>
|
||||
<Switch checked={rule.enabled} />
|
||||
</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<div className="flex items-center justify-end gap-1">
|
||||
<Button variant="ghost" size="sm">
|
||||
<Settings className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" className="text-red-600">
|
||||
<Trash2 className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
{/* 创建告警规则弹窗 */}
|
||||
<Dialog open={showCreateDialog} onOpenChange={setShowCreateDialog}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>新建告警规则</DialogTitle>
|
||||
<DialogDescription>配置系统告警触发条件和通知方式</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label>规则名称</Label>
|
||||
<Input placeholder="输入规则名称" />
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label>监控指标</Label>
|
||||
<Select>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="选择指标" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="cpu">CPU使用率</SelectItem>
|
||||
<SelectItem value="memory">内存使用率</SelectItem>
|
||||
<SelectItem value="disk">磁盘使用率</SelectItem>
|
||||
<SelectItem value="latency">API延迟</SelectItem>
|
||||
<SelectItem value="error_rate">错误率</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>阈值</Label>
|
||||
<Input placeholder="输入阈值" type="number" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>严重程度</Label>
|
||||
<Select>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="选择严重程度" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="critical">严重</SelectItem>
|
||||
<SelectItem value="warning">警告</SelectItem>
|
||||
<SelectItem value="info">信息</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>通知方式</Label>
|
||||
<div className="grid grid-cols-3 gap-2">
|
||||
<label className="flex items-center gap-2 p-3 border rounded-lg cursor-pointer hover:bg-muted">
|
||||
<input type="checkbox" defaultChecked />
|
||||
<span>站内通知</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-2 p-3 border rounded-lg cursor-pointer hover:bg-muted">
|
||||
<input type="checkbox" />
|
||||
<span>邮件</span>
|
||||
</label>
|
||||
<label className="flex items-center gap-2 p-3 border rounded-lg cursor-pointer hover:bg-muted">
|
||||
<input type="checkbox" />
|
||||
<span>短信</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => setShowCreateDialog(false)}>取消</Button>
|
||||
<Button>创建规则</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user