8 changed files with 384 additions and 24 deletions
@ -0,0 +1,68 @@ |
|||
# V1.2.0 更新日志 |
|||
|
|||
- **更新日期**: 2025年12月3日 |
|||
- **版本号**: 1.2.0 |
|||
|
|||
## 新增功能 |
|||
|
|||
### 1. 中值滤波算法配置 |
|||
- **新增中值滤波算法配置界面**:在系统设置中新增"中值滤波算法配置"功能模块 |
|||
- **按需加载机制**:优化数据加载逻辑,仅在打开配置弹窗时才加载算法配置数据,提升性能 |
|||
- **可视化配置**:支持对每个测点进行独立的中值滤波参数配置 |
|||
- X方向窗口大小配置 |
|||
- Y方向窗口大小配置 |
|||
- 算法启用/禁用开关 |
|||
- **实时同步**:配置数据可实时同步到设备端 |
|||
- **数据持久化**:配置保存到设备后自动加载,支持配置的读取和设置 |
|||
|
|||
## Bug 修复 |
|||
|
|||
### 1. 算法配置加载优化 |
|||
- **修复数据加载时机问题**:避免组件加载时不必要的数据请求 |
|||
- **优化 Modal 打开逻辑**:确保只在用户主动打开配置界面时才触发数据加载 |
|||
|
|||
## 🔧 优化改进 |
|||
|
|||
### 1. 组件架构优化 |
|||
- **解耦组件职责**:将算法设置按钮移至父组件,优化组件结构 |
|||
- **受控组件模式**:AlgorithmSettings 改为完全受控的 Modal 组件 |
|||
- **状态管理优化**:通过 props 传递控制状态,提升代码可维护性 |
|||
|
|||
### 2. 用户体验提升 |
|||
- **设备连接状态检测**:按钮在设备未连接时自动禁用,避免无效操作 |
|||
- **加载状态反馈**:添加加载动画,提供更好的用户反馈 |
|||
- **错误提示优化**:完善错误提示信息,帮助用户快速定位问题 |
|||
|
|||
## 技术细节 |
|||
|
|||
### IPC 通信 |
|||
- 新增 IPC 事件: |
|||
- `MEDIAN_FILTER_CONFIG_GET (win:get)`:获取中值滤波算法配置 |
|||
- `MEDIAN_FILTER_CONFIG_SET (win:set)`:设置中值滤波算法配置 |
|||
|
|||
### 数据格式 |
|||
```json |
|||
{ |
|||
"type": "median", |
|||
"sensors": [ |
|||
{ |
|||
"enable": false, |
|||
"pos": "1", |
|||
"xLen": 0, |
|||
"yLen": 0 |
|||
} |
|||
] |
|||
} |
|||
``` |
|||
|
|||
## 依赖更新 |
|||
- 无依赖包更新 |
|||
|
|||
## 注意事项 |
|||
1. 确保设备固件版本支持中值滤波算法配置功能 |
|||
2. 配置参数的有效范围请参考设备手册 |
|||
3. 建议在修改配置前备份当前配置 |
|||
|
|||
--- |
|||
|
|||
**完整更新内容请查看项目 Git 提交记录** |
|||
@ -0,0 +1,173 @@ |
|||
import styles from './AlgorithmSettings.module.css' |
|||
import { Button, Flex, Input, Switch, Modal, List, message } from 'antd' |
|||
import { useState, useEffect } from 'react' |
|||
import useDeviceStore from '../../stores/deviceStore' |
|||
import { IPC_EVENT } from '../../common/ipcEvents' |
|||
|
|||
function AlgorithmSettings({ visible, onClose }) { |
|||
const [loading, setLoading] = useState(false) |
|||
|
|||
const connectedDevice = useDeviceStore((state) => state.connectedDevice) |
|||
console.log('当前连接的设备:', connectedDevice) |
|||
// 点位配置列表数据 |
|||
const [pointSettings, setPointSettings] = useState([]) |
|||
|
|||
// 只在 Modal 打开时获取中值滤波算法配置 |
|||
useEffect(() => { |
|||
const loadMedianFilterConfig = async () => { |
|||
if (!visible) { |
|||
// Modal 未打开,不加载数据 |
|||
return |
|||
} |
|||
|
|||
if (!connectedDevice) { |
|||
console.log('未连接设备,跳过加载中值滤波配置') |
|||
return |
|||
} |
|||
|
|||
setLoading(true) |
|||
try { |
|||
const result = await window.electron.ipcRenderer.invoke(IPC_EVENT.MEDIAN_FILTER_CONFIG_GET, { |
|||
ip: connectedDevice |
|||
}) |
|||
|
|||
if (result.success && result.data) { |
|||
console.log('中值滤波算法配置加载成功:', result.data) |
|||
const data = result.data.values |
|||
|
|||
// 根据返回的数据更新 pointSettings |
|||
if (data && data.sensors && Array.isArray(data.sensors)) { |
|||
const updatedSettings = data.sensors.map((sensor, index) => ({ |
|||
id: index + 1, |
|||
pos: `点位${sensor.pos}`, |
|||
xLen: sensor.xLen || null, |
|||
yLen: sensor.yLen || null, |
|||
enable: sensor.enable || false |
|||
})) |
|||
setPointSettings(updatedSettings) |
|||
message.success('算法配置加载成功') |
|||
} else { |
|||
message.warning('配置数据格式异常') |
|||
} |
|||
} else { |
|||
console.error('加载中值滤波配置失败:', result.error) |
|||
message.error(result.error || '加载配置失败') |
|||
} |
|||
} catch (error) { |
|||
console.error('加载中值滤波配置异常:', error) |
|||
message.error('加载配置异常') |
|||
} finally { |
|||
setLoading(false) |
|||
} |
|||
} |
|||
loadMedianFilterConfig() |
|||
}, [visible, connectedDevice]) // 依赖 visible,当 Modal 打开时触发加载 |
|||
|
|||
// 更新点位配置 |
|||
const updatePointSetting = (id, field, value) => { |
|||
setPointSettings((prev) => |
|||
prev.map((item) => (item.id === id ? { ...item, [field]: value } : item)) |
|||
) |
|||
} |
|||
|
|||
// 保存配置 |
|||
const handleSave = async () => { |
|||
if (!connectedDevice) { |
|||
message.error('设备未连接') |
|||
return |
|||
} |
|||
|
|||
try { |
|||
// 转换为设备需要的数据格式 |
|||
const values = { |
|||
type: 'median', |
|||
sensors: pointSettings.map((setting) => ({ |
|||
enable: setting.enable, |
|||
pos: setting.pos.replace('点位', ''), // 从"点位1"中提取"1" |
|||
xLen: setting.xLen, |
|||
yLen: setting.yLen |
|||
})) |
|||
} |
|||
|
|||
console.log('保存配置:', values) |
|||
|
|||
const result = await window.electron.ipcRenderer.invoke(IPC_EVENT.MEDIAN_FILTER_CONFIG_SET, { |
|||
ip: connectedDevice, |
|||
values: values |
|||
}) |
|||
|
|||
if (result.success) { |
|||
message.success('配置保存成功!') |
|||
onClose && onClose() |
|||
} else { |
|||
message.error(result.error || '配置保存失败') |
|||
} |
|||
} catch (error) { |
|||
console.error('保存配置异常:', error) |
|||
message.error('配置保存异常') |
|||
} |
|||
} |
|||
|
|||
return ( |
|||
<Modal |
|||
title="算法设置详情" |
|||
open={visible} |
|||
onCancel={onClose} |
|||
onOk={onClose} |
|||
width={700} |
|||
footer={[ |
|||
<Button key="save" type="primary" onClick={handleSave}> |
|||
保存 |
|||
</Button>, |
|||
<Button key="close" onClick={onClose}> |
|||
关闭 |
|||
</Button> |
|||
]} |
|||
> |
|||
<List |
|||
itemLayout="vertical" |
|||
dataSource={pointSettings} |
|||
renderItem={(item) => ( |
|||
<List.Item> |
|||
<div style={{ width: '100%' }}> |
|||
<div style={{ fontWeight: 'bold', marginBottom: 12 }}>{item.pos}</div> |
|||
<Flex vertical gap={12}> |
|||
<Flex align="center" gap={8}> |
|||
<span style={{ minWidth: 100 }}>X方向:</span> |
|||
<Input |
|||
type="number" |
|||
value={item.xLen} |
|||
onChange={(e) => |
|||
updatePointSetting(item.id, 'xLen', Number(e.target.value)) |
|||
} |
|||
style={{ width: 150 }} |
|||
/> |
|||
</Flex> |
|||
<Flex align="center" gap={8}> |
|||
<span style={{ minWidth: 100 }}>Y方向:</span> |
|||
<Input |
|||
type="number" |
|||
value={item.yLen} |
|||
onChange={(e) => |
|||
updatePointSetting(item.id, 'yLen', Number(e.target.value)) |
|||
} |
|||
style={{ width: 150 }} |
|||
/> |
|||
</Flex> |
|||
<Flex align="center" gap={8} justify="space-between"> |
|||
<span>是否启用中值滤波算法:</span> |
|||
<Switch |
|||
checked={item.enable} |
|||
onChange={(checked) => updatePointSetting(item.id, 'enable', checked)} |
|||
/> |
|||
</Flex> |
|||
</Flex> |
|||
</div> |
|||
</List.Item> |
|||
)} |
|||
/> |
|||
</Modal> |
|||
) |
|||
} |
|||
|
|||
export default AlgorithmSettings |
|||
@ -0,0 +1,10 @@ |
|||
.subSection { |
|||
margin-bottom: 6px; |
|||
border: 1px solid #eee; |
|||
padding: 4px; |
|||
} |
|||
|
|||
.subSectionTitle { |
|||
font-weight: bold; |
|||
margin-bottom: 6px; |
|||
} |
|||
Loading…
Reference in new issue