From 132af3a74b83ff09ef22fd5d76bfaade52d83726 Mon Sep 17 00:00:00 2001 From: liujiangyong Date: Wed, 19 Aug 2026 11:31:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=A0=87=E9=9D=B6=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E9=99=90=E5=88=B6=E6=94=BE=E5=A4=A7=E5=88=B020=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=A0=87=E9=9D=B6=E5=91=BD=E5=90=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wuyuanbiaoba/components/CameraView.jsx | 96 ++++++++++++------- 1 file changed, 60 insertions(+), 36 deletions(-) diff --git a/client/src/sections/wuyuanbiaoba/components/CameraView.jsx b/client/src/sections/wuyuanbiaoba/components/CameraView.jsx index e21cb7e..ac4851b 100644 --- a/client/src/sections/wuyuanbiaoba/components/CameraView.jsx +++ b/client/src/sections/wuyuanbiaoba/components/CameraView.jsx @@ -3,6 +3,31 @@ import { useWebSocket } from "../actions/websocket.jsx"; import { message } from "antd"; // import { useTargetStorage } from "../hooks/useTargetStorage.js"; +const MAX_RECTANGLES = 20; + +const getNextTargetNameIndex = (rectangles) => { + return rectangles.reduce((maxIndex, rectangle) => { + const match = /^T_(\d+)$/i.exec(String(rectangle?.name || "")); + return match ? Math.max(maxIndex, Number(match[1])) : maxIndex; + }, 0) + 1; +}; + +const getNextTargetId = (rectangles) => { + const usedIds = new Set( + rectangles + .map((rectangle) => rectangle?.id ?? rectangle?.key) + .filter((id) => id !== undefined && id !== null && id !== "") + .map((id) => String(id)) + ); + + let sequence = 1; + while (usedIds.has(`10${sequence}`)) { + sequence += 1; + } + + return `10${sequence}`; +}; + const CameraView = ({ selectedTargetId, onClearSelection, @@ -73,7 +98,7 @@ const CameraView = ({ const minScale = 0.2; const maxScale = 4.0; const scaleStep = 0.1; - const maxRectangles = 10; + const maxRectangles = MAX_RECTANGLES; let streamUrl = `http://${window.location.hostname}:2240/video_flow`; // 摄像头流地址 if (window.env && window.env.FS_FLAG === "localdev") { @@ -281,7 +306,7 @@ const CameraView = ({ // 计算鼠标移动距离 const mouseMoveDistance = Math.sqrt( Math.pow(mouseX - mouseDownPos.x, 2) + - Math.pow(mouseY - mouseDownPos.y, 2) + Math.pow(mouseY - mouseDownPos.y, 2) ); // 检查是否是单击操作:时间短且移动距离小 @@ -350,34 +375,33 @@ const CameraView = ({ const videoRect = screenToVideoCoordinates(x, y, w, h); if (videoRect && rectangles.length < maxRectangles) { - const nextIndex = Number(rectangles[rectangles.length - 1]?.id) - ? Number(rectangles[rectangles.length - 1]?.id) - 100 + 1 - : 1; - const fixedId = `10${nextIndex}`; + // 名称序号与设备协议 ID 分开计算,避免第 10 个以后发生拼接错误。 + const nextNameIndex = getNextTargetNameIndex(rectangles); + const fixedId = getNextTargetId(rectangles); // 根据选中的模板预设参数 const templateParams = selectedTemplate ? { - // 从模板中获取参数 - name: `T_${nextIndex}` || selectedTemplate.name, - radius: selectedTemplate.physicalRadius || 40.0, - isReferencePoint: selectedTemplate.isBaseline || false, - gradientThreshold: selectedTemplate.gradientThresholdValue, - anchorThreshold: selectedTemplate.anchorThresholdValue, - gaussianBlurThreshold: selectedTemplate.gaussianBlur || 3, - binaryThreshold: selectedTemplate.binaryThreshold || 120, - hasAdvancedConfig: false, - } + // 从模板中获取参数 + name: `T_${nextNameIndex}`, + radius: selectedTemplate.physicalRadius || 40.0, + isReferencePoint: selectedTemplate.isBaseline || false, + gradientThreshold: selectedTemplate.gradientThresholdValue, + anchorThreshold: selectedTemplate.anchorThresholdValue, + gaussianBlurThreshold: selectedTemplate.gaussianBlur || 3, + binaryThreshold: selectedTemplate.binaryThreshold || 120, + hasAdvancedConfig: false, + } : { - // 默认参数 - name: `T_${nextIndex}`, - radius: 40.0, - isReferencePoint: false, - gradientThreshold: 100, - anchorThreshold: 80, - gaussianBlurThreshold: 3, - binaryThreshold: 120, - hasAdvancedConfig: false, - }; + // 默认参数 + name: `T_${nextNameIndex}`, + radius: 40.0, + isReferencePoint: false, + gradientThreshold: 100, + anchorThreshold: 80, + gaussianBlurThreshold: 3, + binaryThreshold: 120, + hasAdvancedConfig: false, + }; const newRect = { id: fixedId, @@ -707,8 +731,8 @@ const CameraView = ({ index === selectedRectIndex && isDraggingRect ? "lime" : isSelected - ? "lime" - : "blue"; + ? "lime" + : "blue"; ctx.font = `${12 / scale}px Arial`; // ctx.fillText(`#${index + 1}`, displayX + 5 / scale, displayY + 15 / scale); }); @@ -1141,12 +1165,12 @@ const CameraView = ({ cursor: dragging ? "grabbing" : drawing - ? "crosshair" - : isDraggingRect - ? "move" - : hoveredRectIndex !== -1 - ? "move" - : "default", + ? "crosshair" + : isDraggingRect + ? "move" + : hoveredRectIndex !== -1 + ? "move" + : "default", }} onMouseDown={handleMouseDown} onMouseMove={handleMouseMove} @@ -1280,8 +1304,8 @@ const CameraView = ({ {isSaving ? "下发中..." : rectangles.length === 0 - ? "无标靶" - : "一键下发"} + ? "无标靶" + : "一键下发"} {/* 信息显示 */}