import React, { useEffect } from "react"; import { Card, Input, Slider, InputNumber, Switch, Select, Row, Col, Button, message, Space, Typography, Spin, Alert, } from "antd"; import { SettingOutlined, SaveOutlined, DatabaseOutlined, ClockCircleOutlined, BellOutlined, FilterOutlined, CloudUploadOutlined, SyncOutlined, } from "@ant-design/icons"; import useAdvancedSettings from "../hooks/useAdvancedSettings"; const { Option } = Select; const { Title, Text } = Typography; const AdvancedSettings = ({ onLogout }) => { // 使用高级配置 Hook const { settings, loading, isConnected, isReady, fetchAllSettings, saveAllSettings, resetSettings, updateLocalSettings, } = useAdvancedSettings(); // 只在首次 isReady 变为 true 时自动拉取配置 const hasFetchedRef = React.useRef(false); useEffect(() => { if (isReady && !hasFetchedRef.current) { fetchAllSettings(); hasFetchedRef.current = true; } }, [isReady, fetchAllSettings]); // IP 地址验证函数 const validateIP = (ip) => { if (!ip) return true; // 允许空值 const ipRegex = /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; // 如果匹配 IP 格式(包含点分十进制),则严格按 IP 验证 if (/^\d+\.\d+\.\d+\.\d+$/.test(ip)) { return ipRegex.test(ip); } // 否则按域名验证 const domainRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; return domainRegex.test(ip); }; // 端口验证函数 const validatePort = (port) => { const portNum = Number(port); return !isNaN(portNum) && portNum >= 1 && portNum <= 65535; }; // 从 settings 中提取配置 const deviceId = settings.deviceId; const fps = settings.dataFps; const enableOfflineAlert = settings.alertConfig?.enable ?? false; const offlineThreshold = settings.alertConfig?.intervalSec ?? 60; const enableFiltering = settings.filterConfig?.enable ?? true; const filterMethod = settings.filterConfig?.method ?? 'median'; const windowSize = settings.filterConfig?.size ?? 5; const filterThreshold = settings.filterConfig?.threshold ?? 0.1; const flowThreshold = settings.filterConfig?.imgThreshold ?? 10.0; const enableMqtt = settings.mqttConfig?.enable ?? true; const brokerAddress = settings.mqttConfig?.mqtt?.broker ?? ''; const mqttPort = settings.mqttConfig?.mqtt?.port ?? 1883; const mqttTopic = settings.mqttConfig?.mqtt?.topic ?? ''; const mqttClientId = settings.mqttConfig?.mqtt?.client_id ?? ''; const mqttUsername = settings.mqttConfig?.mqtt?.username ?? ''; const mqttPassword = settings.mqttConfig?.mqtt?.password ?? ''; // 更新本地状态的辅助函数 const setDeviceId = (value) => updateLocalSettings({ deviceId: value }); const setFps = (value) => updateLocalSettings({ dataFps: value }); const setEnableOfflineAlert = (value) => updateLocalSettings({ alertConfig: { enable: value, intervalSec: settings.alertConfig?.intervalSec ?? 60 }, }); const setOfflineThreshold = (value) => updateLocalSettings({ alertConfig: { enable: settings.alertConfig?.enable ?? false, intervalSec: value }, }); const setEnableFiltering = (value) => updateLocalSettings({ filterConfig: { ...settings.filterConfig, enable: value }, }); const setFilterMethod = (value) => updateLocalSettings({ filterConfig: { ...settings.filterConfig, method: value }, }); const setWindowSize = (value) => updateLocalSettings({ filterConfig: { ...settings.filterConfig, size: value }, }); const setFilterThreshold = (value) => updateLocalSettings({ filterConfig: { ...settings.filterConfig, threshold: -Math.abs(value) }, }); const setFlowThreshold = (value) => updateLocalSettings({ filterConfig: { ...settings.filterConfig, imgThreshold: value }, }); const setEnableMqtt = (value) => updateLocalSettings({ mqttConfig: { enable: value, mqtt: settings.mqttConfig?.mqtt ?? { broker: '', port: 1883, topic: '', username: '', password: '', client_id: '' } }, }); const setBrokerAddress = (value) => updateLocalSettings({ mqttConfig: { ...settings.mqttConfig, mqtt: { ...(settings.mqttConfig?.mqtt ?? {}), broker: value }, }, }); const setMqttPort = (value) => updateLocalSettings({ mqttConfig: { ...settings.mqttConfig, mqtt: { ...(settings.mqttConfig?.mqtt ?? {}), port: value }, }, }); const setMqttTopic = (value) => updateLocalSettings({ mqttConfig: { ...settings.mqttConfig, mqtt: { ...(settings.mqttConfig?.mqtt ?? {}), topic: value }, }, }); const setMqttClientId = (value) => updateLocalSettings({ mqttConfig: { ...settings.mqttConfig, mqtt: { ...(settings.mqttConfig?.mqtt ?? {}), client_id: value }, }, }); const setMqttUsername = (value) => updateLocalSettings({ mqttConfig: { ...settings.mqttConfig, mqtt: { ...(settings.mqttConfig?.mqtt ?? {}), username: value }, }, }); const setMqttPassword = (value) => updateLocalSettings({ mqttConfig: { ...settings.mqttConfig, mqtt: { ...(settings.mqttConfig?.mqtt ?? {}), password: value }, }, }); const [saving, setSaving] = React.useState(false); const handleSave = async () => { if (enableMqtt) { if (brokerAddress && !validateIP(brokerAddress)) { message.error('Broker 地址格式不正确,请检查后重试'); return; } if (mqttPort && !validatePort(mqttPort)) { message.error('端口号格式不正确,请检查后重试'); return; } if (!brokerAddress) { message.warning('启用 MQTT 时请填写 Broker 地址'); return; } } try { setSaving(true); const success = await saveAllSettings(); if (!success) { console.log('保存操作未完全成功'); } } catch (error) { console.error('保存配置时发生异常:', error); message.error('保存配置时发生异常,请重试'); } finally { setSaving(false); } }; const handleReset = () => { fetchAllSettings(); }; return (
{/* WebSocket 连接状态提示 */} {!isConnected && ( )} <SettingOutlined /> 高级参数配置 针对下位机运行的参数配置,修改后请及时保存(慎用) 基础设备信息 } style={{ marginBottom: 12, borderRadius: 12, paddingLeft: 24, paddingRight: 24, }} >
设备编码
setDeviceId(e.target.value)} placeholder="请输入设备编码" size="large" style={{ borderRadius: 8 }} />
数据帧率 (FPS) } style={{ marginBottom: 12, borderRadius: 12, paddingLeft: 24, paddingRight: 24, }} >
数据帧率
有效范围 1~30 Hz
异常监控与报警 } style={{ marginBottom: 12, borderRadius: 12, paddingLeft: 24, paddingRight: 24, }} >
启用离线超时告警
系统将按您设置的间隔周期持续检测:若连续离线时长达到整个周期,则会触发告警
超时阈值
数据滤波与异常记录 } style={{ marginBottom: 12, borderRadius: 12, paddingLeft: 24, paddingRight: 24, }} >
滤波配置
启用数据滤波算法
滤波方法
窗口大小
滤波阈值
波动阈值
数据上报 (MQTT)
} style={{ borderRadius: 12, paddingLeft: 24, paddingRight: 24, }} >
Broker Address *
setBrokerAddress(e.target.value)} placeholder="例如: 218.3.126.49 或 mqtt.example.com" size="large" disabled={!enableMqtt} style={{ borderRadius: 8, borderColor: brokerAddress && !validateIP(brokerAddress) ? '#ff4d4f' : undefined }} status={brokerAddress && !validateIP(brokerAddress) ? 'error' : undefined} /> {brokerAddress && !validateIP(brokerAddress) && ( 请输入有效的 IPv4 地址 )}
Port *
setMqttPort(e.target.value)} placeholder="1883" size="large" disabled={!enableMqtt} style={{ borderRadius: 8, borderColor: mqttPort && !validatePort(mqttPort) ? '#ff4d4f' : undefined }} status={mqttPort && !validatePort(mqttPort) ? 'error' : undefined} /> {mqttPort && !validatePort(mqttPort) && ( 端口范围: 1-65535 )}
Topic
setMqttTopic(e.target.value)} placeholder="例如: wybb/z/mqtt179" size="large" disabled={!enableMqtt} style={{ borderRadius: 8 }} />
Client ID
setMqttClientId(e.target.value)} placeholder="wybb_z1_123" size="large" disabled={!enableMqtt} style={{ borderRadius: 8 }} />
Username
setMqttUsername(e.target.value)} placeholder="用户名" size="large" disabled={!enableMqtt} style={{ borderRadius: 8 }} />
Password
setMqttPassword(e.target.value)} placeholder="密码" size="large" disabled={!enableMqtt} style={{ borderRadius: 8 }} />
); }; export default AdvancedSettings;