device.jsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import React, { useState, useRef, useEffect } from 'react'
  2. import './device.scss'
  3. import UpdateBtn from './update-btn/update-btn.jsx'
  4. import ConnectItem from './connect-item/connect-item.jsx'
  5. import { DeviceClass, setSelectedDevicesStore, setExecutionStatusCallback, getExecutionStatus } from './device.js'
  6. function Device({ show }) {
  7. const [deviceList, setDeviceList] = useState([])
  8. const deviceClass = useRef(null)
  9. const [inputValue, setInputValue] = useState('192.168.')
  10. const [portValue, setPortValue] = useState('5555')
  11. const [selectedDevices, setSelectedDevices] = useState([]) // 数组,记录所有选中的 device IP
  12. const [executionStatus, setExecutionStatus] = useState(getExecutionStatus())
  13. if (!show) {
  14. return null
  15. }
  16. useEffect(() => {
  17. setExecutionStatusCallback((status) => setExecutionStatus(status))
  18. return () => setExecutionStatusCallback(null)
  19. }, [])
  20. // 每次显示时同步一次执行状态,确保停止后切回设备列表时灯色为灰
  21. useEffect(() => {
  22. if (show) setExecutionStatus(getExecutionStatus())
  23. }, [show])
  24. useEffect(() => {
  25. if (!deviceClass.current) {
  26. deviceClass.current = new DeviceClass()
  27. deviceClass.current.init(setDeviceList, inputValue, portValue, setSelectedDevices, setInputValue, setPortValue)
  28. }
  29. }, [])
  30. useEffect(() => {
  31. if (deviceClass.current) deviceClass.current.inputValue = inputValue
  32. }, [inputValue])
  33. useEffect(() => {
  34. if (deviceClass.current) deviceClass.current.portValue = portValue
  35. }, [portValue])
  36. useEffect(() => {
  37. if (deviceClass.current) deviceClass.current.currentDeviceList = deviceList
  38. }, [deviceList])
  39. useEffect(() => {
  40. setSelectedDevicesStore(selectedDevices)
  41. }, [selectedDevices])
  42. return (
  43. <>
  44. <div className="device-container">
  45. {/* 更新设备列表 */}
  46. <div className="device-update">
  47. <div className="device-update-title">设备列表</div>
  48. <div className="enable-wirless-connect-btn" onClick={() => deviceClass.current?.onEnableWirlessConnect()}>激活</div>
  49. </div>
  50. {/* 设备列表 */}
  51. <div className="device-list">
  52. {deviceList.map((device, index) => (
  53. <ConnectItem
  54. key={index}
  55. ipAddress={deviceList[index]}
  56. selected={selectedDevices.includes(deviceList[index])}
  57. executionStatus={executionStatus}
  58. onSelect={(ip) => setSelectedDevices(prev => prev.includes(ip) ? prev.filter(x => x !== ip) : [...prev, ip])}
  59. onRemove={(ip) => deviceClass.current?.onRemoveDevice(ip)}
  60. />
  61. ))}
  62. </div>
  63. {/* 添加设备 */}
  64. <div className="device-add">
  65. <div className="ip-input">
  66. <input
  67. type="text"
  68. placeholder="请输入设备IP"
  69. value={inputValue}
  70. onChange={(e) => setInputValue(e.target.value)}
  71. onKeyDown={(e) => { if (e.key === 'Enter') { deviceClass.current?.onAddDevice() } }}
  72. />
  73. </div>
  74. <div className="port-input">
  75. <input
  76. type="text"
  77. placeholder="请输入设备端口"
  78. value={portValue}
  79. onChange={(e) => setPortValue(e.target.value)}
  80. onKeyDown={(e) => { if (e.key === 'Enter') { deviceClass.current?.onAddDevice() } }}
  81. />
  82. </div>
  83. <div className="add-btn" onClick={() => deviceClass.current?.onAddDevice()}>
  84. <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  85. <path d="M12 5V19M5 12H19" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
  86. </svg>
  87. </div>
  88. </div>
  89. </div>
  90. </>
  91. )
  92. }
  93. export default Device