252 lines
7.0 KiB
TypeScript
252 lines
7.0 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import {
|
|
Button, Table, Form, Input, Select, message, Card, Badge,
|
|
} from 'antd';
|
|
import dayjs from 'dayjs';
|
|
import 'dayjs/locale/zh-cn';
|
|
import type {
|
|
DeviceMonitorData,
|
|
} from '@/share/monitorTypes';
|
|
|
|
import {
|
|
DeviceStatus, DeviceProtocolType, MetricType, DeviceStatusNameMap, DeviceProtocolTypeNameMap,
|
|
MetricTypeNameMap
|
|
} from '@/share/monitorTypes';
|
|
|
|
import { getEnumOptions } from '../utils';
|
|
import { DeviceInstanceAPI, MonitorAPI } from '../api/index';
|
|
|
|
|
|
// Modbus RTU设备监控页面
|
|
export const ModbusRtuDevicePage = () => {
|
|
const [loading, setLoading] = useState(false);
|
|
const [monitorData, setMonitorData] = useState<DeviceMonitorData[]>([]);
|
|
const [pagination, setPagination] = useState({
|
|
current: 1,
|
|
pageSize: 10,
|
|
total: 0,
|
|
});
|
|
const [deviceOptions, setDeviceOptions] = useState<{label: string, value: number}[]>([]);
|
|
const [formRef] = Form.useForm();
|
|
|
|
// 监控数据刷新间隔(毫秒)
|
|
const REFRESH_INTERVAL = 30000;
|
|
|
|
useEffect(() => {
|
|
fetchDeviceOptions();
|
|
fetchMonitorData();
|
|
|
|
// 设置定时刷新
|
|
const intervalId = setInterval(() => {
|
|
fetchMonitorData();
|
|
}, REFRESH_INTERVAL);
|
|
|
|
return () => clearInterval(intervalId);
|
|
}, [pagination.current, pagination.pageSize]);
|
|
|
|
const fetchDeviceOptions = async () => {
|
|
try {
|
|
const response = await DeviceInstanceAPI.getDeviceInstances();
|
|
if (response && response.data) {
|
|
const options = response.data.map((device) => ({
|
|
label: device.asset_name || `设备${device.id}`,
|
|
value: device.id
|
|
}));
|
|
setDeviceOptions(options);
|
|
}
|
|
} catch (error) {
|
|
console.error('获取设备列表失败:', error);
|
|
message.error('获取设备列表失败');
|
|
}
|
|
};
|
|
|
|
const fetchMonitorData = async () => {
|
|
setLoading(true);
|
|
try {
|
|
const values = formRef.getFieldsValue();
|
|
const params = {
|
|
page: pagination.current,
|
|
pageSize: pagination.pageSize,
|
|
device_id: values.device_id,
|
|
device_name: values.device_name,
|
|
protocol: values.protocol,
|
|
address: values.address,
|
|
metric_type: values.metric_type,
|
|
status: values.status,
|
|
};
|
|
|
|
const response = await MonitorAPI.getMonitorData(params);
|
|
|
|
if (response) {
|
|
setMonitorData(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,
|
|
});
|
|
fetchMonitorData();
|
|
};
|
|
|
|
const handleTableChange = (newPagination: any) => {
|
|
setPagination({
|
|
...pagination,
|
|
current: newPagination.current,
|
|
pageSize: newPagination.pageSize,
|
|
});
|
|
};
|
|
|
|
const metricTypeOptions = getEnumOptions(MetricType, MetricTypeNameMap);
|
|
const statusOptions = getEnumOptions(DeviceStatus, DeviceStatusNameMap);
|
|
const protocolOptions = getEnumOptions(DeviceProtocolType, DeviceProtocolTypeNameMap);
|
|
|
|
const getStatusBadge = (status?: DeviceStatus) => {
|
|
switch (status) {
|
|
case DeviceStatus.NORMAL:
|
|
return <Badge status="success" text="正常" />;
|
|
case DeviceStatus.MAINTAIN:
|
|
return <Badge status="processing" text="维护中" />;
|
|
case DeviceStatus.FAULT:
|
|
return <Badge status="error" text="故障" />;
|
|
case DeviceStatus.OFFLINE:
|
|
return <Badge status="default" text="下线" />;
|
|
default:
|
|
return <Badge status="default" text="未知" />;
|
|
}
|
|
};
|
|
|
|
const columns = [
|
|
{
|
|
title: '设备ID',
|
|
dataIndex: 'device_id',
|
|
key: 'device_id',
|
|
width: 80,
|
|
},
|
|
{
|
|
title: '设备名称',
|
|
dataIndex: 'device_name',
|
|
key: 'device_name',
|
|
},
|
|
{
|
|
title: '通信协议',
|
|
dataIndex: 'protocol',
|
|
key: 'protocol',
|
|
render: (text: string) => {
|
|
const option = protocolOptions.find(opt => opt.value === text);
|
|
return option ? option.label : text;
|
|
},
|
|
},
|
|
{
|
|
title: '通信地址',
|
|
dataIndex: 'address',
|
|
key: 'address',
|
|
},
|
|
{
|
|
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',
|
|
render: (value: number, record: DeviceMonitorData) => {
|
|
return `${value} ${record.unit || ''}`;
|
|
},
|
|
},
|
|
{
|
|
title: '状态',
|
|
dataIndex: 'status',
|
|
key: 'status',
|
|
render: (status: DeviceStatus) => getStatusBadge(status),
|
|
},
|
|
{
|
|
title: '采集时间',
|
|
dataIndex: 'collect_time',
|
|
key: 'collect_time',
|
|
render: (text: Date) => dayjs(text).format('YYYY-MM-DD HH:mm:ss'),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div>
|
|
<Card title="Modbus RTU设备监控" 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="device_name" label="设备名称">
|
|
<Input placeholder="输入设备名称" style={{ width: 200 }} />
|
|
</Form.Item>
|
|
<Form.Item name="protocol" label="通信协议">
|
|
<Select
|
|
placeholder="选择通信协议"
|
|
style={{ width: 200 }}
|
|
allowClear
|
|
options={protocolOptions}
|
|
/>
|
|
</Form.Item>
|
|
<Form.Item name="address" label="通信地址">
|
|
<Input placeholder="输入通信地址" style={{ width: 200 }} />
|
|
</Form.Item>
|
|
<Form.Item name="metric_type" label="监控指标">
|
|
<Select
|
|
placeholder="选择监控指标"
|
|
style={{ width: 200 }}
|
|
allowClear
|
|
options={metricTypeOptions}
|
|
/>
|
|
</Form.Item>
|
|
<Form.Item name="status" label="状态">
|
|
<Select
|
|
placeholder="选择状态"
|
|
style={{ width: 120 }}
|
|
allowClear
|
|
options={statusOptions}
|
|
/>
|
|
</Form.Item>
|
|
<Form.Item>
|
|
<Button type="primary" htmlType="submit">
|
|
查询
|
|
</Button>
|
|
</Form.Item>
|
|
</Form>
|
|
|
|
<Table
|
|
columns={columns}
|
|
dataSource={monitorData}
|
|
rowKey="id"
|
|
pagination={pagination}
|
|
loading={loading}
|
|
onChange={handleTableChange}
|
|
/>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}; |