| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- import React, { useState, useEffect } from 'react';
- import {
- useNavigate,
- } from 'react-router';
- import {
- Button, Table, Space,
- Form, Select, message,
- Card, Tag, DatePicker
- } from 'antd';
- import dayjs from 'dayjs';
- import 'dayjs/locale/zh-cn';
- // 从share/types.ts导入所有类型,包括MapMode
- import type {
- ZichanInfo, DeviceAlert
- } from '../share/monitorTypes.ts';
- import {
- AlertLevel, AlertStatus, MetricType,
- AlertLevelNameMap, AlertStatusNameMap,
- MetricTypeNameMap
- } from '../share/monitorTypes.ts';
- import { getEnumOptions } from './utils.ts';
- import { DeviceInstanceAPI, AlertAPI} from './api/index.ts';
- // 告警记录页面
- export const AlertRecordsPage = () => {
- const [loading, setLoading] = useState(false);
- const [alertData, setAlertData] = useState<DeviceAlert[]>([]);
- const [pagination, setPagination] = useState({
- current: 1,
- pageSize: 10,
- total: 0,
- });
- const [deviceOptions, setDeviceOptions] = useState<{label: string, value: number}[]>([]);
- const [formRef] = Form.useForm();
-
- useEffect(() => {
- fetchDeviceOptions();
- fetchAlertData();
- }, [pagination.current, pagination.pageSize]);
-
- const fetchDeviceOptions = async () => {
- try {
- const response = await DeviceInstanceAPI.getDeviceInstances();
- if (response && response.data) {
- const options = response.data.map((device: ZichanInfo) => ({
- label: device.asset_name || `设备${device.id}`,
- value: device.id
- }));
- setDeviceOptions(options);
- }
- } catch (error) {
- console.error('获取设备列表失败:', error);
- message.error('获取设备列表失败');
- }
- };
-
- const fetchAlertData = async () => {
- setLoading(true);
- try {
- const values = formRef.getFieldsValue();
- const params = {
- page: pagination.current,
- pageSize: pagination.pageSize,
- device_id: values.device_id,
- metric_type: values.metric_type,
- alert_level: values.alert_level,
- status: values.status,
- start_time: values.time?.[0]?.format('YYYY-MM-DD HH:mm:ss'),
- end_time: values.time?.[1]?.format('YYYY-MM-DD HH:mm:ss'),
- };
-
- const response = await AlertAPI.getAlertData(params);
-
- if (response) {
- setAlertData(response.data || []);
- setPagination({
- ...pagination,
- total: response.total || 0,
- });
- }
- } catch (error) {
- console.error('获取告警数据失败:', error);
- message.error('获取告警数据失败');
- } finally {
- setLoading(false);
- }
- };
-
- const handleSearch = (values: any) => {
- setPagination({
- ...pagination,
- current: 1,
- });
- fetchAlertData();
- };
-
- const handleTableChange = (newPagination: any) => {
- setPagination({
- ...pagination,
- current: newPagination.current,
- pageSize: newPagination.pageSize,
- });
- };
-
- const handleAlertHandle = async (record: DeviceAlert, mode: 'view' | 'edit' = 'edit') => {
- try {
- navigate(`/admin/alert-handle/${record.id}?mode=${mode}`);
- } catch (error) {
- console.error('处理告警失败:', error);
- message.error('处理告警失败');
- }
- };
-
- const metricTypeOptions = getEnumOptions(MetricType, MetricTypeNameMap);
-
- const alertLevelOptions = getEnumOptions(AlertLevel, AlertLevelNameMap);
-
- const alertStatusOptions = getEnumOptions(AlertStatus, AlertStatusNameMap);
-
- const getAlertLevelTag = (level: AlertLevel) => {
- switch (level) {
- case AlertLevel.MINOR:
- return <Tag color="blue">次要</Tag>;
- case AlertLevel.NORMAL:
- return <Tag color="green">一般</Tag>;
- case AlertLevel.IMPORTANT:
- return <Tag color="orange">重要</Tag>;
- case AlertLevel.URGENT:
- return <Tag color="red">紧急</Tag>;
- default:
- return <Tag>未知</Tag>;
- }
- };
-
- const getAlertStatusTag = (status: AlertStatus) => {
- switch (status) {
- case AlertStatus.PENDING:
- return <Tag color="red">待处理</Tag>;
- case AlertStatus.HANDLING:
- return <Tag color="orange">处理中</Tag>;
- case AlertStatus.RESOLVED:
- return <Tag color="green">已解决</Tag>;
- case AlertStatus.IGNORED:
- return <Tag color="default">已忽略</Tag>;
- default:
- return <Tag>未知</Tag>;
- }
- };
-
- const navigate = useNavigate();
-
- const columns = [
- {
- title: '告警ID',
- dataIndex: 'id',
- key: 'id',
- width: 80,
- },
- {
- title: '设备名称',
- dataIndex: 'device_name',
- key: 'device_name',
- },
- {
- title: '监控指标',
- dataIndex: 'metric_type',
- key: 'metric_type',
- render: (text: string) => {
- const option = metricTypeOptions.find(opt => opt.value === text);
- return option ? option.label : text;
- },
- },
- {
- title: '触发值',
- dataIndex: 'metric_value',
- key: 'metric_value',
- },
- {
- title: '告警等级',
- dataIndex: 'alert_level',
- key: 'alert_level',
- render: (level: AlertLevel) => getAlertLevelTag(level),
- },
- {
- title: '告警消息',
- dataIndex: 'alert_message',
- key: 'alert_message',
- ellipsis: true,
- },
- {
- title: '状态',
- dataIndex: 'status',
- key: 'status',
- render: (status: AlertStatus) => getAlertStatusTag(status),
- },
- {
- title: '告警时间',
- dataIndex: 'created_at',
- key: 'created_at',
- render: (text: Date) => dayjs(text).format('YYYY-MM-DD HH:mm:ss'),
- },
- {
- title: '操作',
- key: 'action',
- render: (_: any, record: DeviceAlert) => (
- <Space size="middle">
- {record.status === AlertStatus.PENDING && (
- <Button size="small" type="primary" onClick={() => handleAlertHandle(record, 'edit')}>
- 处理
- </Button>
- )}
- {record.status === AlertStatus.HANDLING && (
- <Button size="small" type="primary" onClick={() => handleAlertHandle(record, 'edit')}>
- 继续处理
- </Button>
- )}
- <Button size="small" onClick={() => handleAlertHandle(record, 'view')}>
- 查看
- </Button>
- </Space>
- ),
- },
- ];
-
- return (
- <div>
- <Card title="告警记录" style={{ marginBottom: 16 }}>
- <Form
- form={formRef}
- layout="inline"
- onFinish={handleSearch}
- style={{ marginBottom: 16 }}
- >
- <Form.Item name="device_id" label="设备">
- <Select
- placeholder="选择设备"
- style={{ width: 200 }}
- allowClear
- options={deviceOptions}
- />
- </Form.Item>
- <Form.Item name="metric_type" label="监控指标">
- <Select
- placeholder="选择监控指标"
- style={{ width: 150 }}
- allowClear
- options={metricTypeOptions}
- />
- </Form.Item>
- <Form.Item name="alert_level" label="告警等级">
- <Select
- placeholder="选择告警等级"
- style={{ width: 120 }}
- allowClear
- options={alertLevelOptions}
- />
- </Form.Item>
- <Form.Item name="status" label="状态">
- <Select
- placeholder="选择状态"
- style={{ width: 120 }}
- allowClear
- options={alertStatusOptions}
- />
- </Form.Item>
- <Form.Item name="time" label="时间范围">
- <DatePicker.RangePicker
- showTime
- style={{ width: 380 }}
- />
- </Form.Item>
- <Form.Item>
- <Button type="primary" htmlType="submit">
- 查询
- </Button>
- </Form.Item>
- </Form>
-
- <Table
- columns={columns}
- dataSource={alertData}
- rowKey="id"
- pagination={pagination}
- loading={loading}
- onChange={handleTableChange}
- />
- </Card>
- </div>
- );
- };
|