Browse Source

feat: 更新设备连接逻辑,添加IP地址格式验证和设备选择功能

master
cles 2 weeks ago
parent
commit
881d5edcef
  1. 1
      README.md
  2. 58
      src/renderer/src/components/MeasurementPointSetting/MeasurementPointSetting.jsx
  3. 40
      src/renderer/src/components/SiderHeader/SiderHeader.jsx

1
README.md

@ -2,7 +2,6 @@
> 基于 Electron + React + Vite 开发的传感器监测应用程序 > 基于 Electron + React + Vite 开发的传感器监测应用程序
![License](https://img.shields.io/badge/license-MIT-blue.svg)
![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey.svg) ![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-lightgrey.svg)
![Version](https://img.shields.io/badge/version-1.0.0-green.svg) ![Version](https://img.shields.io/badge/version-1.0.0-green.svg)

58
src/renderer/src/components/MeasurementPointSetting/MeasurementPointSetting.jsx

@ -10,7 +10,7 @@ import {
} from '@ant-design/icons' } from '@ant-design/icons'
import useRectangleStore from '../../stores/rectangleStore' import useRectangleStore from '../../stores/rectangleStore'
import useDeviceStore from '../../stores/deviceStore' import useDeviceStore from '../../stores/deviceStore'
import { useState } from 'react' import { useState, useMemo } from 'react'
import { IPC_EVENT } from '../../common/ipcEvents' import { IPC_EVENT } from '../../common/ipcEvents'
function MeasurementPointSetting() { function MeasurementPointSetting() {
@ -25,10 +25,29 @@ function MeasurementPointSetting() {
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
location: 1, // location: 1, //
description: '', // description: '', //
coefficient: 0, //
baseTarget: 'n' // baseTarget: 'n' //
}) })
//
const [lensDistance, setLensDistance] = useState(50) //
const [measureDistance, setMeasureDistance] = useState(10) //
//
const calculateCoefficient = (measureDist, lensDist) => {
if (!lensDist || lensDist <= 0) return 0
return Number(((measureDist / lensDist) * 2.24).toFixed(6))
}
//
const handleLensDistanceChange = (value) => {
setLensDistance(value)
}
//
const handleMeasureDistanceChange = (value) => {
setMeasureDistance(value)
}
// //
const [sensorList, setSensorList] = useState([]) const [sensorList, setSensorList] = useState([])
@ -39,6 +58,11 @@ function MeasurementPointSetting() {
const [loadingSensors, setLoadingSensors] = useState(false) const [loadingSensors, setLoadingSensors] = useState(false)
const [settingSensors, setSettingSensors] = useState(false) const [settingSensors, setSettingSensors] = useState(false)
// 使useMemo
const calculatedCoefficient = useMemo(() => {
return calculateCoefficient(measureDistance, lensDistance)
}, [measureDistance, lensDistance])
// //
const updateRectangleFromSensor = (sensorKey) => { const updateRectangleFromSensor = (sensorKey) => {
if (!sensorKey) { if (!sensorKey) {
@ -110,7 +134,7 @@ function MeasurementPointSetting() {
children: [ children: [
{ key: `${newSensorKey}-1`, name: '测点位置', value: formData.location }, { key: `${newSensorKey}-1`, name: '测点位置', value: formData.location },
{ key: `${newSensorKey}-2`, name: '测点描述', value: formData.description }, { key: `${newSensorKey}-2`, name: '测点描述', value: formData.description },
{ key: `${newSensorKey}-3`, name: '计算系数', value: formData.coefficient }, { key: `${newSensorKey}-3`, name: '计算系数', value: calculatedCoefficient },
{ {
key: `${newSensorKey}-4`, key: `${newSensorKey}-4`,
name: '基准标靶', name: '基准标靶',
@ -132,7 +156,6 @@ function MeasurementPointSetting() {
setFormData((prev) => ({ setFormData((prev) => ({
location: prev.location + 1, // location: prev.location + 1, //
description: '', description: '',
coefficient: 0,
baseTarget: 'n' baseTarget: 'n'
})) }))
} }
@ -416,10 +439,10 @@ function MeasurementPointSetting() {
<span className={styles.label}>计算系数:</span> <span className={styles.label}>计算系数:</span>
<InputNumber <InputNumber
className={styles.numberInput} className={styles.numberInput}
value={formData.coefficient} value={calculatedCoefficient}
onChange={(value) => handleFormChange('coefficient', value)} readOnly
precision={4} precision={6}
style={{ flex: 1 }} style={{ flex: 1, backgroundColor: '#f5f5f5' }}
/> />
</Flex> </Flex>
@ -486,15 +509,15 @@ function MeasurementPointSetting() {
<Flex className={styles.formRow}> <Flex className={styles.formRow}>
<span className={styles.label}>镜头焦距:</span> <span className={styles.label}>镜头焦距:</span>
<Select <InputNumber
className={styles.select} className={styles.numberInput}
defaultValue="50" value={lensDistance}
onChange={handleLensDistanceChange}
min={0.001}
precision={3}
style={{ flex: 1 }} style={{ flex: 1 }}
options={[ status={!lensDistance || lensDistance <= 0 ? 'error' : ''}
{ value: '50', label: '50' }, placeholder="请输入大于0的数值"
{ value: '125', label: '125' },
{ value: '200', label: '200' }
]}
/> />
</Flex> </Flex>
@ -502,7 +525,8 @@ function MeasurementPointSetting() {
<span className={styles.label}>测点距离:</span> <span className={styles.label}>测点距离:</span>
<InputNumber <InputNumber
className={styles.numberInput} className={styles.numberInput}
defaultValue={10} value={measureDistance}
onChange={handleMeasureDistanceChange}
precision={4} precision={4}
style={{ flex: 1 }} style={{ flex: 1 }}
/> />

40
src/renderer/src/components/SiderHeader/SiderHeader.jsx

@ -1,6 +1,6 @@
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
import styles from './SiderHeader.module.css' import styles from './SiderHeader.module.css'
import { Flex, Select, Button, Input, Spin, message } from 'antd' import { Flex, Button, Input, message, AutoComplete } from 'antd'
import { IPC_EVENT } from '../../common/ipcEvents.js' import { IPC_EVENT } from '../../common/ipcEvents.js'
import useDeviceStore from '../../stores/deviceStore' import useDeviceStore from '../../stores/deviceStore'
import { import {
@ -98,15 +98,27 @@ function SiderHeader({ showSystemSettings = true }) {
// / // /
const handleConnectOrDisconnect = () => { const handleConnectOrDisconnect = () => {
console.log('点击连接,当前selectedDevice:', selectedDevice, '端口:', devicePort)
if (connected) { if (connected) {
// //
window.electron.ipcRenderer.send(IPC_EVENT.DEVICE_DISCONNECT, { ip: connected }) window.electron.ipcRenderer.send(IPC_EVENT.DEVICE_DISCONNECT, { ip: connected })
} else { } else {
// //
if (!selectedDevice || !devicePort) { if (!selectedDevice || !devicePort) {
message.error('请选择设备并填写端口') message.error('请输入或选择设备IP地址并填写端口')
return
}
// IP
const ipPattern =
/^((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]?)$/
if (!ipPattern.test(selectedDevice)) {
message.error('请输入有效的IP地址格式 (例如: 192.168.1.100)')
return return
} }
console.log('发送连接请求:', { ip: selectedDevice, port: devicePort })
window.electron.ipcRenderer.send(IPC_EVENT.DEVICE_CONNECT, { window.electron.ipcRenderer.send(IPC_EVENT.DEVICE_CONNECT, {
ip: selectedDevice, ip: selectedDevice,
port: devicePort port: devicePort
@ -117,9 +129,6 @@ function SiderHeader({ showSystemSettings = true }) {
// UI // UI
const uiDisabled = !!connected const uiDisabled = !!connected
//
console.log('connected:', connected, 'uiDisabled:', uiDisabled)
return ( return (
<Flex vertical> <Flex vertical>
<Flex className={styles.header}> <Flex className={styles.header}>
@ -131,21 +140,29 @@ function SiderHeader({ showSystemSettings = true }) {
<Flex align="center"> <Flex align="center">
<VideoCameraFilled className={styles.icon} /> <VideoCameraFilled className={styles.icon} />
<span className={styles.label}>设备列表:</span> <span className={styles.label}>设备列表:</span>
<Select <AutoComplete
className={styles.deviceSelect} className={styles.deviceSelect}
placeholder="请选择设备" placeholder="搜索设备或输入IP地址"
loading={searching}
value={selectedDevice} value={selectedDevice}
options={deviceList} options={deviceList}
onChange={setSelectedDevice} onChange={(value) => {
setSelectedDevice(value)
}}
onSelect={(value) => {
setSelectedDevice(value)
}}
style={{ minWidth: 120, flex: 1 }} style={{ minWidth: 120, flex: 1 }}
notFoundContent={searching ? <Spin size="small" /> : '无设备'}
disabled={searching || uiDisabled} disabled={searching || uiDisabled}
allowClear
filterOption={(inputValue, option) =>
option?.value?.toLowerCase().indexOf(inputValue.toLowerCase()) !== -1
}
/> />
</Flex> </Flex>
<Flex align="center"> <Flex align="center">
<span className={styles.label}>设备端口:</span>
<GoldFilled className={styles.icon} /> <GoldFilled className={styles.icon} />
<span className={styles.label}>设备端口:</span>
<Input <Input
className={styles.deviceInput} className={styles.deviceInput}
value={devicePort} value={devicePort}
@ -153,6 +170,7 @@ function SiderHeader({ showSystemSettings = true }) {
disabled={uiDisabled} disabled={uiDisabled}
/> />
</Flex> </Flex>
<Flex gap={8}> <Flex gap={8}>
<Button <Button
className={styles.actionButton} className={styles.actionButton}

Loading…
Cancel
Save