From 80479e8c7d1faa4f3eb798c068abd38233416449 Mon Sep 17 00:00:00 2001 From: cles <208023732@qq.com> Date: Tue, 9 Sep 2025 10:29:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20tab=E5=88=87=E6=8D=A2=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/ipcRouter.js | 33 +++++---- src/renderer/src/App.jsx | 67 ++++++++++++++----- .../DeflectionCollection.jsx | 8 +-- .../ImageCollection/ImageCollection.jsx | 1 + .../MeasurementPointSetting.jsx | 17 +++-- .../components/SiderHeader/SiderHeader.jsx | 9 ++- 6 files changed, 90 insertions(+), 45 deletions(-) diff --git a/src/main/ipcRouter.js b/src/main/ipcRouter.js index a7362cc..a303d92 100644 --- a/src/main/ipcRouter.js +++ b/src/main/ipcRouter.js @@ -10,17 +10,11 @@ const END_SEQUENCE = '\n\n' // 消息结束标志 const tcpClients = new Map() // 保存待处理的请求,用于关联响应 const pendingRequests = new Map() -// 重连配置和状态管理 -const reconnectConfig = { - enabled: false, - interval: 5 // 默认5秒 -} // 创建重连管理器实例 const reconnectManager = new ReconnectManager() - -// 配置重连管理器的事件处理 -reconnectManager.on('attempt-reconnect', (ip, callback) => { +// 处理重连尝试的回调函数 +const handleAttemptReconnect = (ip, callback) => { // 获取重连信息 const connectionData = reconnectManager.getReconnectStatus(ip) if (!connectionData.config.enabled) { @@ -40,7 +34,7 @@ reconnectManager.on('attempt-reconnect', (ip, callback) => { `Connection timeout set to ${connectionTimeout}ms (reconnect interval: ${reconnectInterval}ms)` ) - // 需要从某处获取端口和eventSender - 这里需要存储这些信息 + // 需要从某处获取端口和eventSender const storedConnectionData = tcpClients.get(ip) || tcpConnectionData.get(ip) if (!storedConnectionData) { callback(false, 'Connection data not found') @@ -112,10 +106,10 @@ reconnectManager.on('attempt-reconnect', (ip, callback) => { log.debug(`Reconnect attempt connection closed for ${ip}`) // 连接关闭由心跳检测处理 }) -}) +} -// 处理重连状态更新 -reconnectManager.on('reconnect-status', (status) => { +// 处理重连状态更新的回调函数 +const handleReconnectStatus = (status) => { // 通知所有渲染进程重连状态变化 const storedConnectionData = tcpConnectionData.get(status.ip) if (storedConnectionData && storedConnectionData.eventSender) { @@ -147,7 +141,11 @@ reconnectManager.on('reconnect-status', (status) => { }) } } -}) +} + +// 配置重连管理器事件监听 +reconnectManager.on('attempt-reconnect', handleAttemptReconnect) +reconnectManager.on('reconnect-status', handleReconnectStatus) // 存储连接数据以供重连使用 const tcpConnectionData = new Map() // 存储连接参数 @@ -339,6 +337,7 @@ const connectDevice = (event, { ip, port }) => { // 只有在非主动断开的情况下才启动重连 // 主动断开会先调用 disconnectDevice 函数 + const reconnectConfig = reconnectManager.getConfig() if (reconnectConfig.enabled) { log.info(`Connection lost to ${ip}, starting reconnect...`) // 保存连接数据供重连使用 @@ -1355,16 +1354,15 @@ const delay = () => { // 处理重连配置 const handleReconnectConfig = (event, { enabled, interval }) => { - reconnectConfig.enabled = enabled - reconnectConfig.interval = Math.max(4, interval) // 最小4秒 + const validInterval = Math.max(4, interval) // 最小4秒 // 更新重连管理器配置 reconnectManager.updateConfig({ enabled, - interval: reconnectConfig.interval + interval: validInterval }) - log.info('Reconnect config updated:', { enabled, interval: reconnectConfig.interval }) + log.info('Reconnect config updated:', { enabled, interval: validInterval }) } // 启动心跳检测 @@ -1421,6 +1419,7 @@ const checkHeartbeat = (ip) => { }) // 启动重连(如果启用) + const reconnectConfig = reconnectManager.getConfig() if (reconnectConfig.enabled) { log.info(`Connection lost to ${ip} due to heartbeat timeout, starting reconnect...`) // 保存连接数据供重连使用 diff --git a/src/renderer/src/App.jsx b/src/renderer/src/App.jsx index 178b29a..f957396 100644 --- a/src/renderer/src/App.jsx +++ b/src/renderer/src/App.jsx @@ -1,4 +1,4 @@ -import { Layout } from 'antd' +import { Layout, Spin } from 'antd' import styles from './App.module.css' const { Sider, Content } = Layout import SiderHeader from './components/SiderHeader/SiderHeader' @@ -7,6 +7,9 @@ import { FundFilled, CameraFilled } from '@ant-design/icons' import { Tabs } from 'antd' import DeflectionCollection from './components/DeflectionCollection/DeflectionCollection' import ImageCollection from './components/ImageCollection/ImageCollection' +import { useState } from 'react' +import useRectangleStore from './stores/rectangleStore' + const tabItem = [ { key: '1', @@ -22,10 +25,24 @@ const tabItem = [ } ] -import { useState } from 'react' - const App = () => { const [activeKey, setActiveKey] = useState('1') + const [isTabLoading, setIsTabLoading] = useState(false) + const setRectangleData = useRectangleStore((state) => state.setRectangleData) + // 处理Tab切换 + const handleTabChange = (newActiveKey) => { + // 如果切换不同的Tab,显示短暂的loading + if (newActiveKey !== activeKey) { + setIsTabLoading(true) + setRectangleData(null) // 切换Tab时清除矩形数据 + // 延迟切换,给组件一些时间准备 + setTimeout(() => { + setActiveKey(newActiveKey) + setIsTabLoading(false) + }, 500) + } + } + return ( @@ -33,20 +50,36 @@ const App = () => { - ({ - key: item.key, - label: ( - - {item.icon} - {item.label} - - ), - children: item.children - }))} - /> + {isTabLoading ? ( +
+ + {'数据加载中...'} +
+ ) : ( + ({ + key: item.key, + label: ( + + {item.icon} + {item.label} + + ), + children: item.children + }))} + /> + )}
diff --git a/src/renderer/src/components/DeflectionCollection/DeflectionCollection.jsx b/src/renderer/src/components/DeflectionCollection/DeflectionCollection.jsx index bfe1bec..5faa048 100644 --- a/src/renderer/src/components/DeflectionCollection/DeflectionCollection.jsx +++ b/src/renderer/src/components/DeflectionCollection/DeflectionCollection.jsx @@ -121,7 +121,7 @@ function DeflectionCollection() { data: timeLabels.map(() => alarmLimits.yUpper), borderColor: 'rgba(255, 0, 0, 0.8)', backgroundColor: 'rgba(255, 0, 0, 0.1)', - borderDash: [5, 5], // 虚线 + borderDash: [2, 2], // 虚线 pointRadius: 0, tension: 0, fill: false @@ -131,7 +131,7 @@ function DeflectionCollection() { data: timeLabels.map(() => alarmLimits.yLower), borderColor: 'rgba(255, 0, 0, 0.8)', backgroundColor: 'rgba(255, 0, 0, 0.1)', - borderDash: [5, 5], // 虚线 + borderDash: [2, 2], // 虚线 pointRadius: 0, tension: 0, fill: false @@ -167,7 +167,7 @@ function DeflectionCollection() { data: timeLabels.map(() => alarmLimits.xUpper), borderColor: 'rgba(255, 0, 0, 0.8)', backgroundColor: 'rgba(255, 0, 0, 0.1)', - borderDash: [5, 5], // 虚线 + borderDash: [2, 2], // 虚线 pointRadius: 0, tension: 0, fill: false @@ -177,7 +177,7 @@ function DeflectionCollection() { data: timeLabels.map(() => alarmLimits.xLower), borderColor: 'rgba(255, 0, 0, 0.8)', backgroundColor: 'rgba(255, 0, 0, 0.1)', - borderDash: [5, 5], // 虚线 + borderDash: [2, 2], // 虚线 pointRadius: 0, tension: 0, fill: false diff --git a/src/renderer/src/components/ImageCollection/ImageCollection.jsx b/src/renderer/src/components/ImageCollection/ImageCollection.jsx index 564ff44..a443cf2 100644 --- a/src/renderer/src/components/ImageCollection/ImageCollection.jsx +++ b/src/renderer/src/components/ImageCollection/ImageCollection.jsx @@ -22,6 +22,7 @@ function ImagePreview() { // 监听store中的矩形数据变化,转换为显示坐标 useEffect(() => { + console.log(rectangleData, 'rectangleData') if (rectangleData && image && imageScale) { // 将原始图片坐标转换为显示坐标 const displayRect = { diff --git a/src/renderer/src/components/MeasurementPointSetting/MeasurementPointSetting.jsx b/src/renderer/src/components/MeasurementPointSetting/MeasurementPointSetting.jsx index 46f13d1..f0321dd 100644 --- a/src/renderer/src/components/MeasurementPointSetting/MeasurementPointSetting.jsx +++ b/src/renderer/src/components/MeasurementPointSetting/MeasurementPointSetting.jsx @@ -10,7 +10,7 @@ import { } from '@ant-design/icons' import useRectangleStore from '../../stores/rectangleStore' import useDeviceStore from '../../stores/deviceStore' -import { useState, useMemo } from 'react' +import { useState, useMemo, useEffect, useCallback } from 'react' import { IPC_EVENT } from '../../common/ipcEvents' function MeasurementPointSetting() { @@ -298,7 +298,7 @@ function MeasurementPointSetting() { }) } - const handleLoad = async () => { + const handleLoad = useCallback(async () => { setLoadingSensors(true) try { // 从store中获取当前连接的设备IP @@ -341,7 +341,15 @@ function MeasurementPointSetting() { } finally { setLoadingSensors(false) } - } + }, [connectedDevice, setRectangleData]) // 依赖项包括connectedDevice和setRectangleData + + // 组件初始化时加载测点列表数据 + useEffect(() => { + // 如果有连接的设备,则自动加载测点列表 + if (connectedDevice && connectedDevice.ip) { + handleLoad() + } + }, [connectedDevice, handleLoad]) // 依赖connectedDevice和handleLoad const handleSet = async () => { setSettingSensors(true) @@ -398,6 +406,7 @@ function MeasurementPointSetting() { message.error(`调用传感器设置失败:${error.message}`) } finally { setSettingSensors(false) + setRectangleData(null) } } @@ -555,7 +564,7 @@ function MeasurementPointSetting() { childrenColumnName: 'children', indentSize: '2em' }} - scroll={{ y: 200 }} + scroll={{ y: 190 }} rowSelection={{ type: 'radio', selectedRowKeys: selectedSensorKey ? [selectedSensorKey] : [], diff --git a/src/renderer/src/components/SiderHeader/SiderHeader.jsx b/src/renderer/src/components/SiderHeader/SiderHeader.jsx index ac6439d..4943471 100644 --- a/src/renderer/src/components/SiderHeader/SiderHeader.jsx +++ b/src/renderer/src/components/SiderHeader/SiderHeader.jsx @@ -246,9 +246,12 @@ function SiderHeader({ showSystemSettings = true }) { onClick={handleConnectOrDisconnect} > {connecting - ? (connected ? '正在断开...' : '正在连接...') - : (connected ? '断开连接' : '连接设备') - } + ? connected + ? '正在断开...' + : '正在连接...' + : connected + ? '断开连接' + : '连接设备'}