3 changed files with 497 additions and 16 deletions
@ -0,0 +1,493 @@ |
|||||
|
import React, { useState } from "react"; |
||||
|
import { |
||||
|
Card, |
||||
|
Input, |
||||
|
Slider, |
||||
|
InputNumber, |
||||
|
Switch, |
||||
|
Select, |
||||
|
Row, |
||||
|
Col, |
||||
|
Button, |
||||
|
message, |
||||
|
Space, |
||||
|
Typography, |
||||
|
} from "antd"; |
||||
|
import { |
||||
|
SettingOutlined, |
||||
|
SaveOutlined, |
||||
|
ReloadOutlined, |
||||
|
DatabaseOutlined, |
||||
|
ClockCircleOutlined, |
||||
|
BellOutlined, |
||||
|
FilterOutlined, |
||||
|
CloudUploadOutlined, |
||||
|
} from "@ant-design/icons"; |
||||
|
|
||||
|
const { Option } = Select; |
||||
|
const { Title, Text } = Typography; |
||||
|
|
||||
|
const AdvancedSettings = ({ onLogout }) => { |
||||
|
const [deviceId, setDeviceId] = useState(""); |
||||
|
const [fps, setFps] = useState(5); |
||||
|
const [enableOfflineAlert, setEnableOfflineAlert] = useState(false); |
||||
|
const [offlineThreshold, setOfflineThreshold] = useState(60); |
||||
|
const [enableFiltering, setEnableFiltering] = useState(true); |
||||
|
const [filterMethod, setFilterMethod] = useState("median"); |
||||
|
const [windowSize, setWindowSize] = useState(5); |
||||
|
const [filterThreshold, setFilterThreshold] = useState(0.1); |
||||
|
const [flowThreshold, setFlowThreshold] = useState(10.0); |
||||
|
const [enableMqtt, setEnableMqtt] = useState(true); |
||||
|
const [brokerAddress, setBrokerAddress] = useState(""); |
||||
|
const [mqttPort, setMqttPort] = useState(""); |
||||
|
const [mqttTopic, setMqttTopic] = useState(""); |
||||
|
const [mqttClientId, setMqttClientId] = useState(""); |
||||
|
const [mqttUsername, setMqttUsername] = useState(""); |
||||
|
const [mqttPassword, setMqttPassword] = useState(""); |
||||
|
|
||||
|
const handleSave = () => message.success("配置已保存"); |
||||
|
const handleReset = () => { |
||||
|
setDeviceId(""); |
||||
|
setFps(5); |
||||
|
setEnableOfflineAlert(false); |
||||
|
setOfflineThreshold(60); |
||||
|
setEnableFiltering(true); |
||||
|
setFilterMethod("median"); |
||||
|
setWindowSize(5); |
||||
|
setFilterThreshold(0.1); |
||||
|
setFlowThreshold(10.0); |
||||
|
setEnableMqtt(true); |
||||
|
setBrokerAddress(""); |
||||
|
setMqttPort(""); |
||||
|
setMqttTopic(""); |
||||
|
setMqttClientId(""); |
||||
|
setMqttUsername(""); |
||||
|
setMqttPassword(""); |
||||
|
message.info("配置已重置"); |
||||
|
}; |
||||
|
|
||||
|
return ( |
||||
|
<div |
||||
|
style={{ |
||||
|
padding: "12px", |
||||
|
backgroundColor: "#f5f7fa", |
||||
|
minHeight: "calc(100vh - 92px)", |
||||
|
}} |
||||
|
> |
||||
|
<Card |
||||
|
style={{ |
||||
|
marginBottom: 12, |
||||
|
background: |
||||
|
"linear-gradient(135deg, #01152cff 0%, #063b77ff 100%)", |
||||
|
borderRadius: 12, |
||||
|
}} |
||||
|
styles={{ padding: 12 }} |
||||
|
> |
||||
|
<Row justify="space-between" align="middle"> |
||||
|
<Col> |
||||
|
<Space direction="vertical" size={4}> |
||||
|
<Title |
||||
|
level={2} |
||||
|
style={{ |
||||
|
margin: 0, |
||||
|
color: "white", |
||||
|
display: "flex", |
||||
|
alignItems: "center", |
||||
|
gap: 12, |
||||
|
}} |
||||
|
> |
||||
|
<SettingOutlined /> |
||||
|
高级参数配置 |
||||
|
</Title> |
||||
|
<Text |
||||
|
style={{ |
||||
|
color: "rgba(255,255,255,0.85)", |
||||
|
fontSize: 14, |
||||
|
}} |
||||
|
> |
||||
|
针对下位机运行的参数配置,修改后请及时保存(慎用) |
||||
|
</Text> |
||||
|
</Space> |
||||
|
</Col> |
||||
|
<Col> |
||||
|
<Space size="middle"> |
||||
|
<Button |
||||
|
icon={<ReloadOutlined />} |
||||
|
onClick={handleReset} |
||||
|
size="large" |
||||
|
style={{ height: 42, borderRadius: 8 }} |
||||
|
> |
||||
|
重置/刷新 |
||||
|
</Button> |
||||
|
<Button |
||||
|
type="primary" |
||||
|
icon={<SaveOutlined />} |
||||
|
onClick={handleSave} |
||||
|
size="large" |
||||
|
style={{ |
||||
|
height: 42, |
||||
|
borderRadius: 8, |
||||
|
background: "white", |
||||
|
color: "#667eea", |
||||
|
borderColor: "white", |
||||
|
}} |
||||
|
> |
||||
|
保存更改 |
||||
|
</Button> |
||||
|
</Space> |
||||
|
</Col> |
||||
|
</Row> |
||||
|
</Card> |
||||
|
|
||||
|
<Row gutter={12}> |
||||
|
<Col xs={12} lg={12}> |
||||
|
<Card |
||||
|
title={ |
||||
|
<Space> |
||||
|
<DatabaseOutlined style={{ color: "#667eea" }} /> |
||||
|
<span>基础设备信息</span> |
||||
|
</Space> |
||||
|
} |
||||
|
|
||||
|
style={{ |
||||
|
marginBottom: 12, |
||||
|
borderRadius: 12, |
||||
|
paddingLeft: 24, |
||||
|
paddingRight: 24, |
||||
|
}} |
||||
|
> |
||||
|
<div style={{ marginBottom: 4, fontWeight: 500 }}> |
||||
|
设备编码 |
||||
|
</div> |
||||
|
<Input |
||||
|
value={deviceId} |
||||
|
onChange={(e) => setDeviceId(e.target.value)} |
||||
|
placeholder="请输入设备编码" |
||||
|
size="large" |
||||
|
style={{ borderRadius: 8 }} |
||||
|
/> |
||||
|
</Card> |
||||
|
|
||||
|
<Card |
||||
|
title={ |
||||
|
<Space> |
||||
|
<ClockCircleOutlined style={{ color: "#667eea" }} /> |
||||
|
<span>数据帧率 (FPS)</span> |
||||
|
</Space> |
||||
|
} |
||||
|
|
||||
|
style={{ |
||||
|
marginBottom: 12, |
||||
|
borderRadius: 12, |
||||
|
paddingLeft: 24, |
||||
|
paddingRight: 24, |
||||
|
}} |
||||
|
> |
||||
|
<div style={{ marginBottom: 12, fontWeight: 500 }}> |
||||
|
数据帧率 |
||||
|
</div> |
||||
|
<Row gutter={12} align="middle"> |
||||
|
<Col span={18}> |
||||
|
<Slider |
||||
|
min={1} |
||||
|
max={30} |
||||
|
value={fps} |
||||
|
onChange={setFps} |
||||
|
marks={{ 1: "1 Hz", 30: "30 Hz" }} |
||||
|
/> |
||||
|
</Col> |
||||
|
<Col span={6}> |
||||
|
<InputNumber |
||||
|
min={1} |
||||
|
max={30} |
||||
|
value={fps} |
||||
|
onChange={setFps} |
||||
|
style={{ width: "100%", borderRadius: 8 }} |
||||
|
size="large" |
||||
|
/> |
||||
|
</Col> |
||||
|
</Row> |
||||
|
<Text type="secondary" style={{ fontSize: 12 }}> |
||||
|
有效范围 1~30 Hz |
||||
|
</Text> |
||||
|
</Card> |
||||
|
|
||||
|
<Card |
||||
|
title={ |
||||
|
<Space> |
||||
|
<BellOutlined style={{ color: "#667eea" }} /> |
||||
|
<span>异常监控与报警</span> |
||||
|
</Space> |
||||
|
} |
||||
|
|
||||
|
style={{ |
||||
|
marginBottom: 12, |
||||
|
borderRadius: 12, |
||||
|
paddingLeft: 24, |
||||
|
paddingRight: 24, |
||||
|
}} |
||||
|
> |
||||
|
<div |
||||
|
style={{ |
||||
|
background: |
||||
|
"linear-gradient(135deg, #f5f7fa 0%, #e8eef5 100%)", |
||||
|
padding: 20, |
||||
|
borderRadius: 12, |
||||
|
marginBottom: 12, |
||||
|
}} |
||||
|
> |
||||
|
<Row justify="space-between" align="middle"> |
||||
|
<Col> |
||||
|
<Text strong>启用离线超时告警</Text> |
||||
|
<br /> |
||||
|
<Text type="secondary" style={{ fontSize: 12 }}> |
||||
|
超过此时长未接收到新数据则触发报警 |
||||
|
</Text> |
||||
|
</Col> |
||||
|
<Col> |
||||
|
<Switch |
||||
|
checked={enableOfflineAlert} |
||||
|
onChange={setEnableOfflineAlert} |
||||
|
/> |
||||
|
</Col> |
||||
|
</Row> |
||||
|
</div> |
||||
|
<div style={{ marginBottom: 4, fontWeight: 500 }}> |
||||
|
超时阈值 |
||||
|
</div> |
||||
|
<InputNumber |
||||
|
min={10} |
||||
|
max={300} |
||||
|
value={offlineThreshold} |
||||
|
onChange={setOfflineThreshold} |
||||
|
size="large" |
||||
|
addonAfter="秒" |
||||
|
style={{ width: "100%", borderRadius: 8 }} |
||||
|
/> |
||||
|
</Card> |
||||
|
</Col> |
||||
|
|
||||
|
<Col xs={12} lg={12}> |
||||
|
<Card |
||||
|
title={ |
||||
|
<Space> |
||||
|
<FilterOutlined style={{ color: "#667eea" }} /> |
||||
|
<span>数据滤波与异常记录</span> |
||||
|
</Space> |
||||
|
} |
||||
|
|
||||
|
style={{ |
||||
|
marginBottom: 12, |
||||
|
borderRadius: 12, |
||||
|
paddingLeft: 24, |
||||
|
paddingRight: 24, |
||||
|
}} |
||||
|
> |
||||
|
<div |
||||
|
style={{ |
||||
|
background: |
||||
|
"linear-gradient(135deg, #f5f7fa 0%, #e8eef5 100%)", |
||||
|
padding: 20, |
||||
|
borderRadius: 12, |
||||
|
marginBottom: 20, |
||||
|
}} |
||||
|
> |
||||
|
<Row justify="space-between" align="middle"> |
||||
|
<Col> |
||||
|
<Text strong>滤波配置</Text> |
||||
|
<br /> |
||||
|
<Text type="secondary" style={{ fontSize: 12 }}> |
||||
|
启用数据滤波算法 |
||||
|
</Text> |
||||
|
</Col> |
||||
|
<Col> |
||||
|
<Switch |
||||
|
checked={enableFiltering} |
||||
|
onChange={setEnableFiltering} |
||||
|
checkedChildren="已启用" |
||||
|
unCheckedChildren="已停用" |
||||
|
/> |
||||
|
</Col> |
||||
|
</Row> |
||||
|
</div> |
||||
|
<Row gutter={[12, 12]}> |
||||
|
<Col span={12}> |
||||
|
<div style={{ marginBottom: 4, fontWeight: 500 }}> |
||||
|
滤波方法 |
||||
|
</div> |
||||
|
<Select |
||||
|
value={filterMethod} |
||||
|
onChange={setFilterMethod} |
||||
|
size="large" |
||||
|
disabled={!enableFiltering} |
||||
|
style={{ width: "100%", borderRadius: 8 }} |
||||
|
> |
||||
|
<Option value="median">中值滤波</Option> |
||||
|
</Select> |
||||
|
</Col> |
||||
|
<Col span={12}> |
||||
|
<div style={{ marginBottom: 4, fontWeight: 500 }}> |
||||
|
窗口大小 |
||||
|
</div> |
||||
|
<InputNumber |
||||
|
min={3} |
||||
|
max={21} |
||||
|
step={2} |
||||
|
value={windowSize} |
||||
|
onChange={setWindowSize} |
||||
|
size="large" |
||||
|
disabled={!enableFiltering} |
||||
|
style={{ width: "100%", borderRadius: 8 }} |
||||
|
/> |
||||
|
</Col> |
||||
|
<Col span={12}> |
||||
|
<div style={{ marginBottom: 4, fontWeight: 500 }}> |
||||
|
滤波阈值 |
||||
|
</div> |
||||
|
<InputNumber |
||||
|
min={0} |
||||
|
max={100} |
||||
|
step={0.1} |
||||
|
value={filterThreshold} |
||||
|
onChange={setFilterThreshold} |
||||
|
addonAfter="mm" |
||||
|
size="large" |
||||
|
disabled={!enableFiltering} |
||||
|
style={{ width: "100%", borderRadius: 8 }} |
||||
|
/> |
||||
|
</Col> |
||||
|
<Col span={12}> |
||||
|
<div style={{ marginBottom: 4, fontWeight: 500 }}> |
||||
|
波动阈值 |
||||
|
</div> |
||||
|
<InputNumber |
||||
|
min={0} |
||||
|
max={100} |
||||
|
step={0.1} |
||||
|
value={flowThreshold} |
||||
|
onChange={setFlowThreshold} |
||||
|
addonAfter="mm" |
||||
|
size="large" |
||||
|
disabled={!enableFiltering} |
||||
|
style={{ width: "100%", borderRadius: 8 }} |
||||
|
/> |
||||
|
</Col> |
||||
|
</Row> |
||||
|
</Card> |
||||
|
|
||||
|
<Card |
||||
|
title={ |
||||
|
<div |
||||
|
style={{ |
||||
|
display: "flex", |
||||
|
justifyContent: "space-between", |
||||
|
alignItems: "center", |
||||
|
}} |
||||
|
> |
||||
|
<Space> |
||||
|
<CloudUploadOutlined style={{ color: "#667eea" }} /> |
||||
|
<span>数据上报 (MQTT)</span> |
||||
|
</Space> |
||||
|
<Switch |
||||
|
checked={enableMqtt} |
||||
|
onChange={setEnableMqtt} |
||||
|
checkedChildren="启用" |
||||
|
unCheckedChildren="禁用" |
||||
|
/> |
||||
|
</div> |
||||
|
} |
||||
|
|
||||
|
style={{ |
||||
|
borderRadius: 12, |
||||
|
paddingLeft: 24, |
||||
|
paddingRight: 24, |
||||
|
}} |
||||
|
> |
||||
|
<Row gutter={[12, 12]}> |
||||
|
<Col span={12}> |
||||
|
<div style={{ marginBottom: 4, fontWeight: 500 }}> |
||||
|
Broker Address |
||||
|
</div> |
||||
|
<Input |
||||
|
value={brokerAddress} |
||||
|
onChange={(e) => setBrokerAddress(e.target.value)} |
||||
|
placeholder="例如: 218.3.126.49" |
||||
|
size="large" |
||||
|
disabled={!enableMqtt} |
||||
|
style={{ borderRadius: 8 }} |
||||
|
/> |
||||
|
</Col> |
||||
|
<Col span={8}> |
||||
|
<div style={{ marginBottom: 4, fontWeight: 500 }}> |
||||
|
Port |
||||
|
</div> |
||||
|
<Input |
||||
|
value={mqttPort} |
||||
|
onChange={(e) => setMqttPort(e.target.value)} |
||||
|
placeholder="1883" |
||||
|
size="large" |
||||
|
disabled={!enableMqtt} |
||||
|
style={{ borderRadius: 8 }} |
||||
|
/> |
||||
|
</Col> |
||||
|
<Col span={12}> |
||||
|
<div style={{ marginBottom: 4, fontWeight: 500 }}> |
||||
|
Topic |
||||
|
</div> |
||||
|
<Input |
||||
|
value={mqttTopic} |
||||
|
onChange={(e) => setMqttTopic(e.target.value)} |
||||
|
placeholder="例如: wybb/z/mqtt179" |
||||
|
size="large" |
||||
|
disabled={!enableMqtt} |
||||
|
style={{ borderRadius: 8 }} |
||||
|
/> |
||||
|
</Col> |
||||
|
<Col span={8}> |
||||
|
<div style={{ marginBottom: 4, fontWeight: 500 }}> |
||||
|
Client ID |
||||
|
</div> |
||||
|
<Input |
||||
|
value={mqttClientId} |
||||
|
onChange={(e) => setMqttClientId(e.target.value)} |
||||
|
placeholder="wybb_z1_123" |
||||
|
size="large" |
||||
|
disabled={!enableMqtt} |
||||
|
style={{ borderRadius: 8 }} |
||||
|
/> |
||||
|
</Col> |
||||
|
<Col span={8}> |
||||
|
<div style={{ marginBottom: 4, fontWeight: 500 }}> |
||||
|
Username |
||||
|
</div> |
||||
|
<Input |
||||
|
value={mqttUsername} |
||||
|
onChange={(e) => setMqttUsername(e.target.value)} |
||||
|
placeholder="用户名" |
||||
|
size="large" |
||||
|
disabled={!enableMqtt} |
||||
|
style={{ borderRadius: 8 }} |
||||
|
/> |
||||
|
</Col> |
||||
|
<Col span={8}> |
||||
|
<div style={{ marginBottom: 4, fontWeight: 500 }}> |
||||
|
Password |
||||
|
</div> |
||||
|
<Input.Password |
||||
|
value={mqttPassword} |
||||
|
onChange={(e) => setMqttPassword(e.target.value)} |
||||
|
placeholder="密码" |
||||
|
size="large" |
||||
|
disabled={!enableMqtt} |
||||
|
style={{ borderRadius: 8 }} |
||||
|
/> |
||||
|
</Col> |
||||
|
</Row> |
||||
|
</Card> |
||||
|
</Col> |
||||
|
</Row> |
||||
|
</div> |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
export default AdvancedSettings; |
||||
Loading…
Reference in new issue