import { useEffect, useState } from 'react' import { Table, Tag, Card, Row, Col, Statistic, Button, Modal, Space, Descriptions } from 'antd' import { AlertOutlined, InfoCircleOutlined, ReloadOutlined } from '@ant-design/icons' import { useAuthStore } from '../../stores/auth' interface Alert { id: number severity: 'critical' | 'warning' | 'info' status: 'active' | 'acknowledged' | 'resolved' datasource_name: string message: string created_at: string acknowledged_at?: string resolved_at?: string } function Alerts() { const { token } = useAuthStore() const [alerts, setAlerts] = useState([]) const [loading, setLoading] = useState(false) const [selectedAlert, setSelectedAlert] = useState(null) const [detailVisible, setDetailVisible] = useState(false) const fetchAlerts = async () => { setLoading(true) try { const res = await fetch('/api/v1/alerts', { headers: { Authorization: `Bearer ${token}` }, }) const data = await res.json() setAlerts(data.data || []) } catch (error) { console.error('Failed to fetch alerts:', error) } finally { setLoading(false) } } useEffect(() => { fetchAlerts() }, [token]) const handleAcknowledge = async (alertId: number) => { try { await fetch(`/api/v1/alerts/${alertId}/acknowledge`, { method: 'POST', headers: { Authorization: `Bearer ${token}` }, }) fetchAlerts() } catch (error) { console.error('Failed to acknowledge alert:', error) } } const handleResolve = async (alertId: number) => { try { await fetch(`/api/v1/alerts/${alertId}/resolve`, { method: 'POST', headers: { Authorization: `Bearer ${token}` }, body: JSON.stringify({ resolution: '已处理' }), }) fetchAlerts() } catch (error) { console.error('Failed to resolve alert:', error) } } const columns = [ { title: 'ID', dataIndex: 'id', key: 'id', width: 60 }, { title: '级别', dataIndex: 'severity', key: 'severity', render: (s: string) => { const colors: Record = { critical: 'error', warning: 'warning', info: 'blue' } const icons: Record = { critical: , warning: , info: , } return ( {s === 'critical' ? '严重' : s === 'warning' ? '警告' : '信息'} ) }, }, { title: '状态', dataIndex: 'status', key: 'status', render: (s: string) => { const colors: Record = { active: 'red', acknowledged: 'orange', resolved: 'green' } return ( {s === 'active' ? '待处理' : s === 'acknowledged' ? '已确认' : '已解决'} ) }, }, { title: '数据源', dataIndex: 'datasource_name', key: 'datasource_name' }, { title: '消息', dataIndex: 'message', key: 'message', ellipsis: true }, { title: '时间', dataIndex: 'created_at', key: 'created_at', render: (t: string) => new Date(t).toLocaleString('zh-CN'), }, { title: '操作', key: 'action', render: (_: unknown, record: Alert) => ( {record.status === 'active' && ( )} {record.status !== 'resolved' && ( )} ), }, ] const stats = alerts.reduce( (acc, alert) => { if (alert.status === 'active') { acc[alert.severity]++ } return acc }, { critical: 0, warning: 0, info: 0 } as Record ) return (
} /> } /> } /> } onClick={fetchAlerts}>刷新} > setDetailVisible(false)} footer={null} width={600} > {selectedAlert && ( {selectedAlert.id} {selectedAlert.severity} {selectedAlert.status} {selectedAlert.datasource_name} {selectedAlert.message} {new Date(selectedAlert.created_at).toLocaleString('zh-CN')} {selectedAlert.acknowledged_at && ( {new Date(selectedAlert.acknowledged_at).toLocaleString('zh-CN')} )} {selectedAlert.resolved_at && ( {new Date(selectedAlert.resolved_at).toLocaleString('zh-CN')} )} )} ) } export default Alerts