Browse Source

feat: 增强 IPC 事件并实现传感器数据处理

- 在 ipcEvents.js 中添加了用于获取和设置各种传感器参数的新 IPC 事件。
- 更新了 DeflectionCollection 组件以处理传入的传感器数据,保留最近 10 个数据点的历史记录并在图表中显示。
- 改进了 MeasurementPointSetting 组件,支持加载和设置传感器数据,并添加了加载状态以提升用户体验。
- 重构了 SystemSettings 组件,通过适当的 IPC 事件读取和设置参数,包括加载状态和验证功能。
- 调整了 MeasurementPointSetting.module.css 中的样式,以获得更好的 UI 一致性。
master
cles 2 weeks ago
parent
commit
d703d3b58a
  1. 834
      src/main/ipcRouter.js
  2. 21
      src/renderer/src/common/ipcEvents.js
  3. 175
      src/renderer/src/components/DeflectionCollection/DeflectionCollection.jsx
  4. 98
      src/renderer/src/components/MeasurementPointSetting/MeasurementPointSetting.jsx
  5. 2
      src/renderer/src/components/MeasurementPointSetting/MeasurementPointSetting.module.css
  6. 166
      src/renderer/src/components/SystemSettings/SystemSettings.jsx

834
src/main/ipcRouter.js

@ -3,7 +3,8 @@ import dgram from 'dgram'
import net from 'net' import net from 'net'
import { IPC_EVENT } from '../renderer/src/common/ipcEvents.js' import { IPC_EVENT } from '../renderer/src/common/ipcEvents.js'
import fs from 'fs' import fs from 'fs'
const TIMEOUT = 10000 // 10秒超时
const END_SEQUENCE = '\n\n' // 消息结束标志
// 全局保存所有TCP连接和相关信息 // 全局保存所有TCP连接和相关信息
const tcpClients = new Map() const tcpClients = new Map()
// 保存待处理的请求,用于关联响应 // 保存待处理的请求,用于关联响应
@ -13,7 +14,24 @@ export function registerIpRouter() {
ipcMain.on(IPC_EVENT.DEVICE_SEARCH, searchDevice) ipcMain.on(IPC_EVENT.DEVICE_SEARCH, searchDevice)
ipcMain.on(IPC_EVENT.DEVICE_CONNECT, connectDevice) ipcMain.on(IPC_EVENT.DEVICE_CONNECT, connectDevice)
ipcMain.on(IPC_EVENT.DEVICE_DISCONNECT, disconnectDevice) ipcMain.on(IPC_EVENT.DEVICE_DISCONNECT, disconnectDevice)
ipcMain.handle(IPC_EVENT.SENSORS_GET, sensorLoad) // 改为handle,支持异步返回 ipcMain.handle(IPC_EVENT.SENSORS_GET, sensorLoad) // 获取传感器
ipcMain.handle(IPC_EVENT.SENSORS_SET, sensorSet) // 传感器设置处理
ipcMain.handle(IPC_EVENT.IMAGE_SEND_TIME_GET, imageSendTimeGet)
ipcMain.handle(IPC_EVENT.IMAGE_SEND_TIME_SET, imageSendTimeSet)
// 其他基本参数GET处理
ipcMain.handle(IPC_EVENT.ZERO_COUNT_GET, zeroCountGet)
ipcMain.handle(IPC_EVENT.RESULT_COUNT_GET, resultCountGet)
ipcMain.handle(IPC_EVENT.DATA_FPS_GET, dataFpsGet)
ipcMain.handle(IPC_EVENT.VIDEO_FPS_GET, videoFpsGet)
ipcMain.handle(IPC_EVENT.THRESHOLD_GET, thresholdGet)
ipcMain.handle(IPC_EVENT.INVALID_DATA_COUNT_GET, invalidDataCountGet)
// 其他基本参数SET处理
ipcMain.handle(IPC_EVENT.ZERO_COUNT_SET, zeroCountSet)
ipcMain.handle(IPC_EVENT.RESULT_COUNT_SET, resultCountSet)
ipcMain.handle(IPC_EVENT.DATA_FPS_SET, dataFpsSet)
ipcMain.handle(IPC_EVENT.VIDEO_FPS_SET, videoFpsSet)
ipcMain.handle(IPC_EVENT.THRESHOLD_SET, thresholdSet)
ipcMain.handle(IPC_EVENT.INVALID_DATA_COUNT_SET, invalidDataCountSet)
} }
const searchDevice = (event) => { const searchDevice = (event) => {
@ -143,7 +161,7 @@ const disconnectDevice = (event, { ip }) => {
} }
// 处理TCP响应 // 处理TCP响应
const handleTcpResponse = (ip, msg) => { const handleTcpResponse = async (ip, msg) => {
const connectionInfo = tcpClients.get(ip) const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) return if (!connectionInfo) return
@ -159,11 +177,182 @@ const handleTcpResponse = (ip, msg) => {
const sensorRequest = pendingRequests.get(`${ip}${IPC_EVENT.SENSORS_GET}`) const sensorRequest = pendingRequests.get(`${ip}${IPC_EVENT.SENSORS_GET}`)
if (sensorRequest) { if (sensorRequest) {
// 响应传感器加载请求 // 响应传感器加载请求
await delay()
sensorRequest.resolve({ success: true, data: msg }) sensorRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.SENSORS_GET}`) pendingRequests.delete(`${ip}${IPC_EVENT.SENSORS_GET}`)
} }
} }
break break
case IPC_EVENT.SENSORS_SET:
{
const sensorSetRequest = pendingRequests.get(`${ip}${IPC_EVENT.SENSORS_SET}`)
if (sensorSetRequest) {
// 响应传感器设置请求
await delay()
sensorSetRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.SENSORS_SET}`)
}
}
break
case IPC_EVENT.IMAGE_SEND_TIME_GET:
{
const imageTimeRequest = pendingRequests.get(`${ip}${IPC_EVENT.IMAGE_SEND_TIME_GET}`)
if (imageTimeRequest) {
// 响应图像发送间隔获取请求
await delay()
console.log(msg)
imageTimeRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.IMAGE_SEND_TIME_GET}`)
}
}
break
case IPC_EVENT.IMAGE_SEND_TIME_SET:
{
const imageTimeRequest = pendingRequests.get(`${ip}${IPC_EVENT.IMAGE_SEND_TIME_SET}`)
if (imageTimeRequest) {
// 响应图像发送间隔设置请求
await delay()
console.log(msg)
imageTimeRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.IMAGE_SEND_TIME_SET}`)
}
}
break
// 其他基本参数GET响应处理
case IPC_EVENT.ZERO_COUNT_GET:
{
const paramRequest = pendingRequests.get(`${ip}${IPC_EVENT.ZERO_COUNT_GET}`)
if (paramRequest) {
await delay()
console.log(msg)
paramRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.ZERO_COUNT_GET}`)
}
}
break
case IPC_EVENT.RESULT_COUNT_GET:
{
const paramRequest = pendingRequests.get(`${ip}${IPC_EVENT.RESULT_COUNT_GET}`)
if (paramRequest) {
await delay()
console.log(msg)
paramRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.RESULT_COUNT_GET}`)
}
}
break
case IPC_EVENT.DATA_FPS_GET:
{
const paramRequest = pendingRequests.get(`${ip}${IPC_EVENT.DATA_FPS_GET}`)
if (paramRequest) {
await delay()
console.log(msg)
paramRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.DATA_FPS_GET}`)
}
}
break
case IPC_EVENT.VIDEO_FPS_GET:
{
const paramRequest = pendingRequests.get(`${ip}${IPC_EVENT.VIDEO_FPS_GET}`)
if (paramRequest) {
await delay()
console.log(msg)
paramRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.VIDEO_FPS_GET}`)
}
}
break
case IPC_EVENT.THRESHOLD_GET:
{
const paramRequest = pendingRequests.get(`${ip}${IPC_EVENT.THRESHOLD_GET}`)
if (paramRequest) {
await delay()
console.log(msg)
paramRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.THRESHOLD_GET}`)
}
}
break
case IPC_EVENT.INVALID_DATA_COUNT_GET:
{
const paramRequest = pendingRequests.get(`${ip}${IPC_EVENT.INVALID_DATA_COUNT_GET}`)
if (paramRequest) {
await delay()
console.log(msg)
paramRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.INVALID_DATA_COUNT_GET}`)
}
}
break
// 其他基本参数SET响应处理
case IPC_EVENT.ZERO_COUNT_SET:
{
const paramRequest = pendingRequests.get(`${ip}${IPC_EVENT.ZERO_COUNT_SET}`)
if (paramRequest) {
await delay()
console.log(msg)
paramRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.ZERO_COUNT_SET}`)
}
}
break
case IPC_EVENT.RESULT_COUNT_SET:
{
const paramRequest = pendingRequests.get(`${ip}${IPC_EVENT.RESULT_COUNT_SET}`)
if (paramRequest) {
await delay()
console.log(msg)
paramRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.RESULT_COUNT_SET}`)
}
}
break
case IPC_EVENT.DATA_FPS_SET:
{
const paramRequest = pendingRequests.get(`${ip}${IPC_EVENT.DATA_FPS_SET}`)
if (paramRequest) {
await delay()
console.log(msg)
paramRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.DATA_FPS_SET}`)
}
}
break
case IPC_EVENT.VIDEO_FPS_SET:
{
const paramRequest = pendingRequests.get(`${ip}${IPC_EVENT.VIDEO_FPS_SET}`)
if (paramRequest) {
await delay()
console.log(msg)
paramRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.VIDEO_FPS_SET}`)
}
}
break
case IPC_EVENT.THRESHOLD_SET:
{
const paramRequest = pendingRequests.get(`${ip}${IPC_EVENT.THRESHOLD_SET}`)
if (paramRequest) {
await delay()
console.log(msg)
paramRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.THRESHOLD_SET}`)
}
}
break
case IPC_EVENT.INVALID_DATA_COUNT_SET:
{
const paramRequest = pendingRequests.get(`${ip}${IPC_EVENT.INVALID_DATA_COUNT_SET}`)
if (paramRequest) {
await delay()
console.log(msg)
paramRequest.resolve({ success: true, data: msg })
pendingRequests.delete(`${ip}${IPC_EVENT.INVALID_DATA_COUNT_SET}`)
}
}
break
case IPC_EVENT.HEARTBEAT_REPLY: case IPC_EVENT.HEARTBEAT_REPLY:
// 心跳处理 // 心跳处理
break break
@ -173,7 +362,7 @@ const handleTcpResponse = (ip, msg) => {
} }
} }
// 传感器加载 - 改为异步处理 // 传感器加载
const sensorLoad = async (event, { ip }) => { const sensorLoad = async (event, { ip }) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip) const connectionInfo = tcpClients.get(ip)
@ -189,7 +378,7 @@ const sensorLoad = async (event, { ip }) => {
const timeout = setTimeout(() => { const timeout = setTimeout(() => {
pendingRequests.delete(requestKey) pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' }) resolve({ success: false, error: '请求超时' })
}, 10000) // 10秒超时 }, TIMEOUT) // 10秒超时
// 保存请求信息 // 保存请求信息
pendingRequests.set(requestKey, { pendingRequests.set(requestKey, {
@ -206,7 +395,7 @@ const sensorLoad = async (event, { ip }) => {
// 发送传感器加载命令 // 发送传感器加载命令
const command = { command: 'sensors', type: 'get', values: '' } const command = { command: 'sensors', type: 'get', values: '' }
const message = JSON.stringify(command) + '\n\n' const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => { connectionInfo.client.write(message, (err) => {
if (err) { if (err) {
@ -217,15 +406,632 @@ const sensorLoad = async (event, { ip }) => {
}) })
}) })
} }
// 传感器设置
const sensorSet = async (event, { ip, sensors }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
// 清理指定IP的所有待处理请求 // 生成请求ID并保存待处理请求
const clearPendingRequestsByIp = (ip) => { const requestKey = `${ip}${IPC_EVENT.SENSORS_SET}`
const keysToDelete = []
for (const [key, request] of pendingRequests) { // 设置超时
if (key.startsWith(`${ip}_`)) { const timeout = setTimeout(() => {
request.resolve({ success: false, error: '连接已断开' }) pendingRequests.delete(requestKey)
keysToDelete.push(key) resolve({ success: false, error: '请求超时' })
}, TIMEOUT) // 10秒超时
// 保存请求信息
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
// 发送传感器设置命令
const command = { command: 'sensors', type: 'set', values: sensors }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
} }
})
})
} }
keysToDelete.forEach((key) => pendingRequests.delete(key)) // 图像发送间隔获取
const imageSendTimeGet = async (event, { ip }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
// 生成请求ID并保存待处理请求
const requestKey = `${ip}${IPC_EVENT.IMAGE_SEND_TIME_GET}`
// 设置超时
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT) // 10秒超时
// 保存请求信息
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
// 发送图像发送间隔获取命令
const command = { command: 'imageSendTime', type: 'get', values: '' }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// 图像发送间隔设置
const imageSendTimeSet = async (event, { ip, value }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
// 生成请求ID并保存待处理请求
const requestKey = `${ip}${IPC_EVENT.IMAGE_SEND_TIME_SET}`
// 设置超时
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT) // 10秒超时
// 保存请求信息
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
// 发送图像发送间隔设置命令
const command = { command: 'imageSendTime', type: 'set', values: value }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// zeroCount获取
const zeroCountGet = async (event, { ip }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
const requestKey = `${ip}${IPC_EVENT.ZERO_COUNT_GET}`
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT)
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
const command = { command: 'zeroCount', type: 'get', values: '' }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// zeroCount设置
const zeroCountSet = async (event, { ip, value }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
const requestKey = `${ip}${IPC_EVENT.ZERO_COUNT_SET}`
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT)
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
const command = { command: 'zeroCount', type: 'set', values: value }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// resultCount获取
const resultCountGet = async (event, { ip }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
const requestKey = `${ip}${IPC_EVENT.RESULT_COUNT_GET}`
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT)
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
const command = { command: 'resultCount', type: 'get', values: '' }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// resultCount设置
const resultCountSet = async (event, { ip, value }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
const requestKey = `${ip}${IPC_EVENT.RESULT_COUNT_SET}`
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT)
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
const command = { command: 'resultCount', type: 'set', values: value }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// dataFps获取
const dataFpsGet = async (event, { ip }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
const requestKey = `${ip}${IPC_EVENT.DATA_FPS_GET}`
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT)
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
const command = { command: 'dataFps', type: 'get', values: '' }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// dataFps设置
const dataFpsSet = async (event, { ip, value }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
const requestKey = `${ip}${IPC_EVENT.DATA_FPS_SET}`
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT)
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
const command = { command: 'dataFps', type: 'set', values: value }
const message = JSON.stringify(command) + END_SEQUENCE
console.log('Sending command:', message)
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// videoFps获取
const videoFpsGet = async (event, { ip }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
const requestKey = `${ip}${IPC_EVENT.VIDEO_FPS_GET}`
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT)
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
const command = { command: 'videoFps', type: 'get', values: '' }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// videoFps设置
const videoFpsSet = async (event, { ip, value }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
const requestKey = `${ip}${IPC_EVENT.VIDEO_FPS_SET}`
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT)
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
const command = { command: 'videoFps', type: 'set', values: value }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// threshold获取
const thresholdGet = async (event, { ip }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
const requestKey = `${ip}${IPC_EVENT.THRESHOLD_GET}`
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT)
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
const command = { command: 'threshold', type: 'get', values: '' }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// threshold设置
const thresholdSet = async (event, { ip, value }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
const requestKey = `${ip}${IPC_EVENT.THRESHOLD_SET}`
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT)
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
const command = { command: 'threshold', type: 'set', values: value }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// invalidDataCount获取
const invalidDataCountGet = async (event, { ip }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
const requestKey = `${ip}${IPC_EVENT.INVALID_DATA_COUNT_GET}`
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT)
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
const command = { command: 'invalidDataCount', type: 'get', values: '' }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// invalidDataCount设置
const invalidDataCountSet = async (event, { ip, value }) => {
return new Promise((resolve, reject) => {
const connectionInfo = tcpClients.get(ip)
if (!connectionInfo) {
resolve({ success: false, error: '设备未连接' })
return
}
const requestKey = `${ip}${IPC_EVENT.INVALID_DATA_COUNT_SET}`
const timeout = setTimeout(() => {
pendingRequests.delete(requestKey)
resolve({ success: false, error: '请求超时' })
}, TIMEOUT)
pendingRequests.set(requestKey, {
resolve: (result) => {
clearTimeout(timeout)
resolve(result)
},
reject: (error) => {
clearTimeout(timeout)
reject(error)
},
timestamp: Date.now()
})
const command = { command: 'invalidDataCount', type: 'set', values: value }
const message = JSON.stringify(command) + END_SEQUENCE
connectionInfo.client.write(message, (err) => {
if (err) {
pendingRequests.delete(requestKey)
clearTimeout(timeout)
resolve({ success: false, error: err.message })
}
})
})
}
// 清理指定IP的所有待处理请求
const clearPendingRequestsByIp = (ip) => {
const keysToDelete = []
for (const [key, request] of pendingRequests) {
if (key.startsWith(`${ip}_`)) {
request.resolve({ success: false, error: '连接已断开' })
keysToDelete.push(key)
}
}
keysToDelete.forEach((key) => pendingRequests.delete(key))
}
//模拟延迟函数
const delay = () => {
return new Promise((resolve) => setTimeout(resolve, 1000))
} }

21
src/renderer/src/common/ipcEvents.js

@ -10,5 +10,24 @@ export const IPC_EVENT = {
RESULT_REPLY: 'result:reply', // 传感器数据 RESULT_REPLY: 'result:reply', // 传感器数据
IMAGE_REPLY: 'image:reply', // 图像数据 IMAGE_REPLY: 'image:reply', // 图像数据
HEARTBEAT_REPLY: 'heartbeat:reply', // 心跳包 HEARTBEAT_REPLY: 'heartbeat:reply', // 心跳包
SENSORS_GET: 'sensors:get' // 加载传感器配置 SENSORS_GET: 'sensors:get', // 加载传感器配置
SENSORS_SET: 'sensors:set', // 加载传感器配置
// 基本参数相关,GET
IMAGE_SEND_TIME_GET: 'imageSendTime:get',
ZERO_COUNT_GET: 'zeroCount:get',
RESULT_COUNT_GET: 'resultCount:get',
DATA_FPS_GET: 'dataFps:get',
VIDEO_FPS_GET: 'videoFps:get',
THRESHOLD_GET: 'threshold:get',
INVALID_DATA_COUNT_GET: 'invalidDataCount:get',
// 基本参数相关,SET
IMAGE_SEND_TIME_SET: 'imageSendTime:set',
ZERO_COUNT_SET: 'zeroCount:set',
RESULT_COUNT_SET: 'resultCount:set',
DATA_FPS_SET: 'dataFps:set',
VIDEO_FPS_SET: 'videoFps:set',
THRESHOLD_SET: 'threshold:set',
INVALID_DATA_COUNT_SET: 'invalidDataCount:set'
} }

175
src/renderer/src/components/DeflectionCollection/DeflectionCollection.jsx

@ -1,3 +1,6 @@
import { useEffect, useState } from 'react'
import { IPC_EVENT } from '../../common/ipcEvents'
import useDeviceStore from '../../stores/deviceStore'
import { Line } from 'react-chartjs-2' import { Line } from 'react-chartjs-2'
import { import {
Chart as ChartJS, Chart as ChartJS,
@ -13,65 +16,111 @@ import { FileTextOutlined, ClockCircleOutlined, EyeOutlined } from '@ant-design/
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend) ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend)
function randomAround(base, delta) {
return base + Math.round((Math.random() * 2 - 1) * delta)
}
function getTimeLabels(count) {
const now = new Date()
return Array.from({ length: count }).map((_, i) => {
const d = new Date(now.getTime() - (count - 1 - i) * 2 * 1000)
return d.toTimeString().slice(0, 8)
})
}
function DeflectionCollection() { function DeflectionCollection() {
const count = 10 // - 10
const targetCount = 5 // target const [sensorDataHistory, setSensorDataHistory] = useState([])
//
const connectedDevice = useDeviceStore((state) => state.connectedDevice)
// target //
const targetColors = [ const targetColors = [
'rgba(75,192,192,1)', // 'rgba(75,192,192,1)', //
'rgba(255,99,132,1)', // 'rgba(255,99,132,1)', //
'rgba(54,162,235,1)', // 'rgba(54,162,235,1)', //
'rgba(255,206,86,1)', // 'rgba(255,206,86,1)', //
'rgba(153,102,255,1)' // 'rgba(153,102,255,1)', //
'rgba(255,159,64,1)', //
'rgba(199,199,199,1)', //
'rgba(83,102,255,1)' //
] ]
// target //
const targetsData = Array.from({ length: targetCount }).map((_, targetIndex) => ({ useEffect(() => {
name: `Target ${targetIndex + 1}`, if (connectedDevice) {
color: targetColors[targetIndex % targetColors.length], console.log('设备连接,清空历史数据:', connectedDevice)
data: Array.from({ length: count }).map((_, i) => ({ setSensorDataHistory([])
x: 350 + targetIndex * 50 + Math.sin(i * 0.5 + targetIndex) * 20 + randomAround(0, 3), }
y: 50 + targetIndex * 20 + Math.cos(i * 0.3 + targetIndex) * 15 + randomAround(0, 2), }, [connectedDevice])
w: randomAround(125, 5),
h: randomAround(115, 5) useEffect(() => {
})) if (window?.electron?.ipcRenderer?.on && IPC_EVENT?.RESULT_REPLY) {
})) const handler = (event, data) => {
console.log('收到主进程RESULT_REPLY:', data)
const timeLabels = getTimeLabels(count) //
if (data && data.values && data.values.sensors && Array.isArray(data.values.sensors)) {
const newDataPoint = {
timestamp: data.values.timestamp || new Date().toISOString(),
sensors: data.values.sensors
}
setSensorDataHistory((prev) => {
const newHistory = [...prev, newDataPoint]
// 10
return newHistory.slice(-10)
})
}
}
window.electron.ipcRenderer.on(IPC_EVENT.RESULT_REPLY, handler)
return () => {
window.electron.ipcRenderer.removeListener(IPC_EVENT.RESULT_REPLY, handler)
}
}
}, [])
// -
const timeLabels = sensorDataHistory.map((dataPoint) => {
const timestamp = new Date(dataPoint.timestamp)
// HH:MM:SS.mmm
const hours = timestamp.getHours().toString().padStart(2, '0')
const minutes = timestamp.getMinutes().toString().padStart(2, '0')
const seconds = timestamp.getSeconds().toString().padStart(2, '0')
const milliseconds = timestamp.getMilliseconds().toString().padStart(3, '0')
return `${hours}:${minutes}:${seconds}.${milliseconds}`
})
//
const allSensors = sensorDataHistory.reduce((acc, dataPoint) => {
dataPoint.sensors.forEach((sensor) => {
if (!acc.some((s) => s.pos === sensor.pos)) {
acc.push({
pos: sensor.pos,
des: sensor.des,
color: targetColors[acc.length % targetColors.length]
})
}
})
return acc
}, [])
// Y
const dataY = { const dataY = {
labels: timeLabels, labels: timeLabels,
datasets: targetsData.map((target) => ({ datasets: allSensors.map((sensor) => ({
label: `${target.name}`, label: `测点${sensor.pos}`,
data: target.data.map((d) => d.y), data: sensorDataHistory.map((dataPoint) => {
borderColor: target.color, const sensorData = dataPoint.sensors.find((s) => s.pos === sensor.pos)
backgroundColor: target.color.replace('1)', '0.2)'), return sensorData ? Number(sensorData.yReal) : null
}),
borderColor: sensor.color,
backgroundColor: sensor.color.replace('1)', '0.2)'),
tension: 0.3, tension: 0.3,
pointRadius: 3, pointRadius: 3,
pointHoverRadius: 5 pointHoverRadius: 5
})) }))
} }
// X
const dataX = { const dataX = {
labels: timeLabels, labels: timeLabels,
datasets: targetsData.map((target) => ({ datasets: allSensors.map((sensor) => ({
label: `${target.name}`, label: `测点${sensor.pos}`,
data: target.data.map((d) => d.x), data: sensorDataHistory.map((dataPoint) => {
borderColor: target.color, const sensorData = dataPoint.sensors.find((s) => s.pos === sensor.pos)
backgroundColor: target.color.replace('1)', '0.2)'), return sensorData ? Number(sensorData.xReal) : null
}),
borderColor: sensor.color,
backgroundColor: sensor.color.replace('1)', '0.2)'),
tension: 0.3, tension: 0.3,
pointRadius: 3, pointRadius: 3,
pointHoverRadius: 5 pointHoverRadius: 5
@ -108,6 +157,10 @@ function DeflectionCollection() {
} }
} }
//
const latestData =
sensorDataHistory.length > 0 ? sensorDataHistory[sensorDataHistory.length - 1] : null
return ( return (
<div <div
style={{ style={{
@ -184,13 +237,25 @@ function DeflectionCollection() {
实时数据 实时数据
</div> </div>
{targetsData.map((target, index) => { {latestData ? (
const latestData = target.data[target.data.length - 1] latestData.sensors.map((sensor, index) => {
const latestTime = timeLabels[timeLabels.length - 1] const sensorConfig = allSensors.find((s) => s.pos === sensor.pos) || {
color: targetColors[index % targetColors.length]
}
const latestTime =
timeLabels[timeLabels.length - 1] ||
(() => {
const now = new Date()
const hours = now.getHours().toString().padStart(2, '0')
const minutes = now.getMinutes().toString().padStart(2, '0')
const seconds = now.getSeconds().toString().padStart(2, '0')
const milliseconds = now.getMilliseconds().toString().padStart(3, '0')
return `${hours}:${minutes}:${seconds}.${milliseconds}`
})()
return ( return (
<div <div
key={index} key={sensor.pos}
style={{ style={{
marginBottom: '15px', marginBottom: '15px',
padding: '10px', padding: '10px',
@ -210,7 +275,7 @@ function DeflectionCollection() {
style={{ style={{
width: '8px', width: '8px',
height: '8px', height: '8px',
backgroundColor: target.color, backgroundColor: sensorConfig.color,
borderRadius: '50%', borderRadius: '50%',
marginRight: '8px' marginRight: '8px'
}} }}
@ -222,7 +287,7 @@ function DeflectionCollection() {
color: '#333' color: '#333'
}} }}
> >
测点位置{index + 1} 测点位置{sensor.pos}
</span> </span>
</div> </div>
@ -241,7 +306,7 @@ function DeflectionCollection() {
marginLeft: '5px' marginLeft: '5px'
}} }}
> >
测点描述 测点描述{sensor.des || '无'}
</span> </span>
</div> </div>
@ -260,7 +325,7 @@ function DeflectionCollection() {
marginLeft: '5px' marginLeft: '5px'
}} }}
> >
采集时间{new Date().toLocaleDateString()} {latestTime} 采集时间{new Date(latestData.timestamp).toLocaleDateString()} {latestTime}
</span> </span>
</div> </div>
@ -279,7 +344,7 @@ function DeflectionCollection() {
marginLeft: '5px' marginLeft: '5px'
}} }}
> >
X {latestData.x.toFixed(3)} X {Number(sensor.xReal).toFixed(3)}
</span> </span>
</div> </div>
@ -297,12 +362,24 @@ function DeflectionCollection() {
marginLeft: '5px' marginLeft: '5px'
}} }}
> >
Y {latestData.y.toFixed(3)} Y {Number(sensor.yReal).toFixed(3)}
</span> </span>
</div> </div>
</div> </div>
) )
})} })
) : (
<div
style={{
textAlign: 'center',
color: '#999',
fontSize: '12px',
marginTop: '20px'
}}
>
等待数据...
</div>
)}
</div> </div>
</div> </div>
) )

98
src/renderer/src/components/MeasurementPointSetting/MeasurementPointSetting.jsx

@ -35,6 +35,10 @@ function MeasurementPointSetting() {
// //
const [selectedSensorKey, setSelectedSensorKey] = useState(null) const [selectedSensorKey, setSelectedSensorKey] = useState(null)
// loading
const [loadingSensors, setLoadingSensors] = useState(false)
const [settingSensors, setSettingSensors] = useState(false)
// //
const updateRectangleFromSensor = (sensorKey) => { const updateRectangleFromSensor = (sensorKey) => {
if (!sensorKey) { if (!sensorKey) {
@ -243,7 +247,36 @@ function MeasurementPointSetting() {
}) })
} }
//
const convertSensorDataToInternalFormat = (sensorValues) => {
return sensorValues.map((sensor, index) => {
const sensorKey = String(index + 1)
return {
key: sensorKey,
name: '传感器',
value: '',
children: [
{ key: `${sensorKey}-1`, name: '测点位置', value: Number(sensor.pos) || 0 },
{ key: `${sensorKey}-2`, name: '测点描述', value: sensor.des || '' },
{ key: `${sensorKey}-3`, name: '计算系数', value: Number(sensor.arg) || 0 },
{
key: `${sensorKey}-4`,
name: '基准标靶',
value: sensor.tar || 'n',
children: [
{ key: `${sensorKey}-4-1`, name: 'x', value: Number(sensor.x) || 0 },
{ key: `${sensorKey}-4-2`, name: 'y', value: Number(sensor.y) || 0 },
{ key: `${sensorKey}-4-3`, name: 'w', value: Number(sensor.w) || 0 },
{ key: `${sensorKey}-4-4`, name: 'h', value: Number(sensor.h) || 0 }
]
}
]
}
})
}
const handleLoad = async () => { const handleLoad = async () => {
setLoadingSensors(true)
try { try {
// storeIP // storeIP
if (!connectedDevice || !connectedDevice.ip) { if (!connectedDevice || !connectedDevice.ip) {
@ -260,7 +293,21 @@ function MeasurementPointSetting() {
if (result.success) { if (result.success) {
console.log('传感器数据加载成功:', result.data) console.log('传感器数据加载成功:', result.data)
message.success('传感器数据已成功加载!')
//
if (result.data && result.data.values && Array.isArray(result.data.values)) {
//
const convertedData = convertSensorDataToInternalFormat(result.data.values)
setSensorList(convertedData)
//
setSelectedSensorKey(null)
setRectangleData(null)
message.success(`传感器数据已成功加载!`)
} else {
message.warning('传感器数据格式不正确')
}
} else { } else {
console.error('传感器数据加载失败:', result.error) console.error('传感器数据加载失败:', result.error)
message.error(`传感器数据加载失败:${result.error}`) message.error(`传感器数据加载失败:${result.error}`)
@ -268,16 +315,14 @@ function MeasurementPointSetting() {
} catch (error) { } catch (error) {
console.error('调用传感器加载失败:', error) console.error('调用传感器加载失败:', error)
message.error(`调用传感器加载失败:${error.message}`) message.error(`调用传感器加载失败:${error.message}`)
} finally {
setLoadingSensors(false)
} }
} }
const handleSet = () => { const handleSet = async () => {
// setSettingSensors(true)
if (!sensorList || sensorList.length === 0) { try {
message.warning('没有传感器数据,请先添加传感器!')
return
}
// //
if (!connectedDevice || !connectedDevice.ip) { if (!connectedDevice || !connectedDevice.ip) {
message.warning('请先连接设备后再设置传感器!') message.warning('请先连接设备后再设置传感器!')
@ -314,8 +359,23 @@ function MeasurementPointSetting() {
} }
}) })
console.log('收集到的传感器数据:', collectedData) //
console.log('格式化后的JSON:', JSON.stringify(collectedData, null, 2)) const result = await window.electron.ipcRenderer.invoke(IPC_EVENT.SENSORS_SET, {
ip: connectedDevice.ip,
sensors: collectedData
})
if (result.success) {
message.success('传感器数据已成功设置!')
} else {
console.error('传感器数据设置失败:', result.error)
message.error(`传感器数据设置失败:${result.error}`)
}
} catch (error) {
console.error('调用传感器设置失败:', error)
message.error(`调用传感器设置失败:${error.message}`)
} finally {
setSettingSensors(false)
}
} }
return ( return (
@ -462,7 +522,7 @@ function MeasurementPointSetting() {
childrenColumnName: 'children', childrenColumnName: 'children',
indentSize: '2em' indentSize: '2em'
}} }}
scroll={{ y: 220 }} scroll={{ y: 200 }}
rowSelection={{ rowSelection={{
type: 'radio', type: 'radio',
selectedRowKeys: selectedSensorKey ? [selectedSensorKey] : [], selectedRowKeys: selectedSensorKey ? [selectedSensorKey] : [],
@ -512,10 +572,22 @@ function MeasurementPointSetting() {
<Button icon={<DeleteOutlined />} shape="circle" onClick={handleClear} /> <Button icon={<DeleteOutlined />} shape="circle" onClick={handleClear} />
</Tooltip> </Tooltip>
<Tooltip title="加载传感器"> <Tooltip title="加载传感器">
<Button icon={<ReloadOutlined />} shape="circle" onClick={handleLoad} /> <Button
icon={<ReloadOutlined />}
shape="circle"
onClick={handleLoad}
loading={loadingSensors}
disabled={loadingSensors || settingSensors}
/>
</Tooltip> </Tooltip>
<Tooltip title="设置传感器"> <Tooltip title="设置传感器">
<Button icon={<SendOutlined />} shape="circle" onClick={handleSet} /> <Button
icon={<SendOutlined />}
shape="circle"
onClick={handleSet}
loading={settingSensors}
disabled={loadingSensors || settingSensors}
/>
</Tooltip> </Tooltip>
</Flex> </Flex>
</div> </div>

2
src/renderer/src/components/MeasurementPointSetting/MeasurementPointSetting.module.css

@ -53,7 +53,7 @@
.numberInput { .numberInput {
font-size: 12px; font-size: 12px;
height: 26px; /* height: 26px; */
} }
.tableSection { .tableSection {

166
src/renderer/src/components/SystemSettings/SystemSettings.jsx

@ -1,5 +1,5 @@
import styles from './SystemSettings.module.css' import styles from './SystemSettings.module.css'
import { Flex, InputNumber, Select, Button, Input, Checkbox } from 'antd' import { Flex, InputNumber, Select, Button, Input, Checkbox, message } from 'antd'
import { import {
SettingFilled, SettingFilled,
InfoCircleFilled, InfoCircleFilled,
@ -8,8 +8,147 @@ import {
EyeOutlined, EyeOutlined,
EditOutlined EditOutlined
} from '@ant-design/icons' } from '@ant-design/icons'
import { useState } from 'react'
import { IPC_EVENT } from '../../common/ipcEvents'
import useDeviceStore from '../../stores/deviceStore'
function SystemSettings() { function SystemSettings() {
//
const [selectedParam, setSelectedParam] = useState('')
const [paramValue, setParamValue] = useState('')
const [loading, setLoading] = useState(false)
const [settingLoading, setSettingLoading] = useState(false)
//
const connectedDevice = useDeviceStore((state) => state.connectedDevice)
//
const handleReadParam = async () => {
if (!selectedParam) {
message.warning('请先选择要读取的参数!')
return
}
if (!connectedDevice || !connectedDevice.ip) {
message.warning('请先连接设备!')
return
}
setLoading(true)
try {
let eventName = ''
switch (selectedParam) {
case 'imageSendTime':
eventName = IPC_EVENT.IMAGE_SEND_TIME_GET
break
case 'zeroCount':
eventName = IPC_EVENT.ZERO_COUNT_GET
break
case 'resultCount':
eventName = IPC_EVENT.RESULT_COUNT_GET
break
case 'dataFps':
eventName = IPC_EVENT.DATA_FPS_GET
break
case 'videoFps':
eventName = IPC_EVENT.VIDEO_FPS_GET
break
case 'threshold':
eventName = IPC_EVENT.THRESHOLD_GET
break
case 'invalidDataCount':
eventName = IPC_EVENT.INVALID_DATA_COUNT_GET
break
default:
message.error('不支持的参数类型')
return
}
const result = await window.electron.ipcRenderer.invoke(eventName, {
ip: connectedDevice.ip
})
if (result.success) {
setParamValue(result.data.values || '')
console.log(result.data, eventName)
message.success(`${selectedParam} 读取成功!`)
} else {
message.error(`读取失败:${result.error}`)
}
} catch (error) {
console.error('参数读取失败:', error)
message.error(`参数读取失败:${error.message}`)
} finally {
setLoading(false)
}
}
//
const handleSetParam = async () => {
if (!selectedParam) {
message.warning('请先选择要设置的参数!')
return
}
if (!paramValue) {
message.warning('请输入参数值!')
return
}
if (!connectedDevice || !connectedDevice.ip) {
message.warning('请先连接设备!')
return
}
setSettingLoading(true)
try {
let eventName
// SET
switch (selectedParam) {
case 'imageSendTime':
eventName = IPC_EVENT.IMAGE_SEND_TIME_SET
break
case 'zeroCount':
eventName = IPC_EVENT.ZERO_COUNT_SET
break
case 'resultCount':
eventName = IPC_EVENT.RESULT_COUNT_SET
break
case 'dataFps':
eventName = IPC_EVENT.DATA_FPS_SET
break
case 'videoFps':
eventName = IPC_EVENT.VIDEO_FPS_SET
break
case 'threshold':
eventName = IPC_EVENT.THRESHOLD_SET
break
case 'invalidDataCount':
eventName = IPC_EVENT.INVALID_DATA_COUNT_SET
break
default:
message.error('不支持的参数类型')
return
}
const result = await window.electron.ipcRenderer.invoke(eventName, {
ip: connectedDevice.ip,
value: Number(paramValue) // 使value
})
if (result.success) {
message.success(`${selectedParam} 设置成功!`)
} else {
message.error(`设置失败:${result.error}`)
}
} catch (error) {
console.error('参数设置失败:', error)
message.error(`参数设置失败:${error.message}`)
} finally {
setSettingLoading(false)
}
}
return ( return (
<Flex vertical gap={4} className={styles.container}> <Flex vertical gap={4} className={styles.container}>
<div className={styles.header}> <div className={styles.header}>
@ -25,6 +164,8 @@ function SystemSettings() {
<Select <Select
className={styles.paramSelect} className={styles.paramSelect}
placeholder="请选择基本参数" placeholder="请选择基本参数"
value={selectedParam}
onChange={setSelectedParam}
options={[ options={[
{ value: 'imageSendTime', label: 'imageSendTime' }, { value: 'imageSendTime', label: 'imageSendTime' },
{ value: 'zeroCount', label: 'zeroCount' }, { value: 'zeroCount', label: 'zeroCount' },
@ -35,12 +176,29 @@ function SystemSettings() {
{ value: 'invalidDataCount', label: 'invalidDataCount' } { value: 'invalidDataCount', label: 'invalidDataCount' }
]} ]}
/> />
<Input className={styles.paramInput} /> <Input
className={styles.paramInput}
value={paramValue}
onChange={(e) => setParamValue(e.target.value)}
placeholder="参数值"
/>
<Flex gap={12}> <Flex gap={12}>
<Button icon={<InfoCircleFilled />} className={styles.paramButton}> <Button
icon={<InfoCircleFilled />}
className={styles.paramButton}
onClick={handleReadParam}
loading={loading}
disabled={!selectedParam || !connectedDevice}
>
读取 读取
</Button> </Button>
<Button icon={<ControlFilled />} className={styles.paramButton}> <Button
icon={<ControlFilled />}
className={styles.paramButton}
onClick={handleSetParam}
loading={settingLoading}
disabled={!paramValue || !connectedDevice}
>
设置 设置
</Button> </Button>
</Flex> </Flex>

Loading…
Cancel
Save