import { useCallback, useEffect, useState } from 'react';
import { Button, Form, Input, InputNumber, message, Modal, Result, Select, Space, Switch, Table, Tag } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import {
alertRuleApi,
type AlertRule,
type CreateAlertRuleReq,
type UpdateAlertRuleReq,
} from '../../api/health/alerts';
import { SEVERITY_COLOR, SEVERITY_OPTIONS, DEVICE_TYPE_OPTIONS, CONDITION_TYPE_OPTIONS } from '../../constants/health';
import { usePermission } from '../../hooks/usePermission';
export default function AlertRuleList() {
const { hasPermission } = usePermission('health.alerts.list');
if (!hasPermission) return ;
const [data, setData] = useState([]);
const [total, setTotal] = useState(0);
const [loading, setLoading] = useState(false);
const [page, setPage] = useState(1);
const [modalOpen, setModalOpen] = useState(false);
const [editingRule, setEditingRule] = useState(null);
const [form] = Form.useForm();
const fetchRules = useCallback(async () => {
setLoading(true);
try {
const res = await alertRuleApi.list({ page, page_size: 20 });
setData(res.data);
setTotal(res.total);
} catch {
message.error('加载规则列表失败');
} finally {
setLoading(false);
}
}, [page]);
useEffect(() => {
fetchRules();
}, [fetchRules]);
const openCreateModal = () => {
setEditingRule(null);
form.resetFields();
form.setFieldsValue({
severity: 'warning',
cooldown_minutes: 60,
});
setModalOpen(true);
};
const openEditModal = (rule: AlertRule) => {
setEditingRule(rule);
form.setFieldsValue({
name: rule.name,
description: rule.description,
device_type: rule.device_type,
condition_type: rule.condition_type,
condition_params: JSON.stringify(rule.condition_params, null, 2),
severity: rule.severity,
cooldown_minutes: rule.cooldown_minutes,
});
setModalOpen(true);
};
const handleSubmit = async () => {
try {
const values = await form.validateFields();
const conditionParams = JSON.parse(values.condition_params);
if (editingRule) {
const req: UpdateAlertRuleReq = {
name: values.name,
description: values.description,
condition_params: conditionParams,
severity: values.severity,
cooldown_minutes: values.cooldown_minutes,
version: editingRule.version,
};
await alertRuleApi.update(editingRule.id, req);
message.success('规则已更新');
} else {
const req: CreateAlertRuleReq = {
name: values.name,
description: values.description,
device_type: values.device_type,
condition_type: values.condition_type,
condition_params: conditionParams,
severity: values.severity,
cooldown_minutes: values.cooldown_minutes,
};
await alertRuleApi.create(req);
message.success('规则已创建');
}
setModalOpen(false);
fetchRules();
} catch (e) {
if (e instanceof SyntaxError) {
message.error('条件参数 JSON 格式无效');
}
}
};
const handleToggle = async (rule: AlertRule, active: boolean) => {
try {
if (!active) {
await alertRuleApi.deactivate(rule.id, rule.version);
message.success('规则已禁用');
}
fetchRules();
} catch {
message.error('操作失败');
}
};
const columns: ColumnsType = [
{ title: '规则名称', dataIndex: 'name', width: 180 },
{
title: '指标类型',
dataIndex: 'device_type',
width: 100,
render: (v: string) => DEVICE_TYPE_OPTIONS.find((d) => d.value === v)?.label || v,
},
{
title: '条件类型',
dataIndex: 'condition_type',
width: 120,
render: (v: string) => CONDITION_TYPE_OPTIONS.find((c) => c.value === v)?.label || v,
},
{
title: '严重程度',
dataIndex: 'severity',
width: 90,
render: (v: string) => {v},
},
{
title: '启用',
dataIndex: 'is_active',
width: 80,
render: (v: boolean, record) => (
handleToggle(record, checked)} />
),
},
{
title: '冷却(分)',
dataIndex: 'cooldown_minutes',
width: 90,
},
{
title: '操作',
width: 80,
render: (_, record) => (
),
},
];
return (