Compare commits

...

2 Commits

Author SHA1 Message Date
qinjian af4741fb39 fix & feat: 4 days ago
qinjian 071320bfd1 refactor: 清除调试日志,只保留错误日志 4 days ago
  1. 174
      client/src/sections/wuyuanbiaoba/components/CameraView.jsx
  2. 79
      client/src/sections/wuyuanbiaoba/components/RealtimeCharts.jsx
  3. 32
      client/src/sections/wuyuanbiaoba/container/index.jsx
  4. 4
      client/src/sections/wuyuanbiaoba/hooks/useTargetStorage.js
  5. 38
      server/tcpProxy/index.js

174
client/src/sections/wuyuanbiaoba/components/CameraView.jsx

@ -16,8 +16,8 @@ const CameraView = ({
const [scale, setScale] = useState(1.0); const [scale, setScale] = useState(1.0);
const [translateX, setTranslateX] = useState(0); const [translateX, setTranslateX] = useState(0);
const [translateY, setTranslateY] = useState(0); const [translateY, setTranslateY] = useState(0);
const [videoNaturalWidth, setVideoNaturalWidth] = useState(1920); const [videoNaturalWidth, setVideoNaturalWidth] = useState(0);
const [videoNaturalHeight, setVideoNaturalHeight] = useState(1080); const [videoNaturalHeight, setVideoNaturalHeight] = useState(0);
const [mousePos, setMousePos] = useState({ x: 0, y: 0 }); const [mousePos, setMousePos] = useState({ x: 0, y: 0 });
// //
@ -37,6 +37,7 @@ const CameraView = ({
const [currentDrawingRect, setCurrentDrawingRect] = useState(null); const [currentDrawingRect, setCurrentDrawingRect] = useState(null);
const [hoveredRectIndex, setHoveredRectIndex] = useState(-1); const [hoveredRectIndex, setHoveredRectIndex] = useState(-1);
const [isSaving, setIsSaving] = useState(false); // const [isSaving, setIsSaving] = useState(false); //
const [streamError, setStreamError] = useState(false); //
// 使WebSocket // 使WebSocket
const { isConnected, sendMessage } = useWebSocket(); const { isConnected, sendMessage } = useWebSocket();
@ -76,10 +77,7 @@ const CameraView = ({
canvas.style.width = rect.width + "px"; canvas.style.width = rect.width + "px";
canvas.style.height = rect.height + "px"; canvas.style.height = rect.height + "px";
console.log("resizeCanvas: 画布大小已调整", { // console.log("resizeCanvas: ", { width: rect.width, height: rect.height });
width: rect.width,
height: rect.height,
});
// applyTransform // applyTransform
setTimeout(() => { setTimeout(() => {
@ -90,24 +88,35 @@ const CameraView = ({
// //
const handleImageLoad = () => { const handleImageLoad = () => {
setStreamError(false); //
if (imgRef.current) { if (imgRef.current) {
const img = imgRef.current; const img = imgRef.current;
if (img.naturalWidth && img.naturalHeight) { if (img.naturalWidth && img.naturalHeight) {
setVideoNaturalWidth(img.naturalWidth); setVideoNaturalWidth(img.naturalWidth);
setVideoNaturalHeight(img.naturalHeight); setVideoNaturalHeight(img.naturalHeight);
console.log( // console.log(`handleImageLoad: : ${img.naturalWidth}x${img.naturalHeight}`);
`handleImageLoad: 视频原始分辨率: ${img.naturalWidth}x${img.naturalHeight}`
);
} }
resizeCanvas(); resizeCanvas();
// //
setTimeout(() => { setTimeout(() => {
console.log("handleImageLoad: 延迟重绘矩形框"); // console.log("handleImageLoad: ");
redrawAllRectangles(); redrawAllRectangles();
}, 200); }, 200);
} }
}; };
//
const handleImageError = () => {
setStreamError(true);
// 3src
setTimeout(() => {
setStreamError(false);
if (imgRef.current) {
imgRef.current.src = streamUrl + "?t=" + Date.now();
}
}, 3000);
};
// //
const handleMouseDown = (e) => { const handleMouseDown = (e) => {
const container = containerRef.current; const container = containerRef.current;
@ -229,7 +238,7 @@ const CameraView = ({
(target) => target.id === clickedRectangle.id (target) => target.id === clickedRectangle.id
); );
if (targetData) { if (targetData) {
console.log("点击矩形框,弹出标靶详情:", targetData); // console.log(":", targetData);
onRectangleClick(targetData); onRectangleClick(targetData);
} }
} }
@ -277,7 +286,8 @@ const CameraView = ({
const templateParams = selectedTemplate const templateParams = selectedTemplate
? { ? {
// //
name: selectedTemplate.name || `target${rectangles.length + 1}`, name:
selectedTemplate.name || `target${rectangles.length + 1}`,
radius: selectedTemplate.physicalRadius || 40.0, radius: selectedTemplate.physicalRadius || 40.0,
isReferencePoint: selectedTemplate.isBaseline || false, isReferencePoint: selectedTemplate.isBaseline || false,
gradientThreshold: gradientThreshold:
@ -317,13 +327,13 @@ const CameraView = ({
setRectangles((prev) => [...prev, newRect]); setRectangles((prev) => [...prev, newRect]);
console.log("新建矩形:", newRect); // console.log(":", newRect);
if (selectedTemplate) { if (selectedTemplate) {
console.log("使用模板参数:", selectedTemplate); // console.log("使:", selectedTemplate);
} else { } else {
console.log("使用默认参数"); // console.log("使");
} }
logRectangleData(); // logRectangleData();
} }
}; // }; //
const dragExistingRectangle = (mouseX, mouseY) => { const dragExistingRectangle = (mouseX, mouseY) => {
@ -547,11 +557,15 @@ const CameraView = ({
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
// //
if (!videoNaturalWidth || !videoNaturalHeight) { if (
console.log("redrawAllRectangles: 视频尺寸未准备好", { !videoNaturalWidth ||
videoNaturalWidth, !videoNaturalHeight ||
videoNaturalHeight, videoNaturalWidth < 100 ||
}); videoNaturalHeight < 100
) {
//
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
return; return;
} }
@ -703,15 +717,15 @@ const CameraView = ({
const handleSave = useCallback(async () => { const handleSave = useCallback(async () => {
// //
if (isSaving) { if (isSaving) {
console.log("正在保存中,忽略重复请求"); // console.log("");
return; return;
} }
console.log("=== 保存矩形信息 ==="); // console.log("=== ===");
console.log("矩形总数:", rectangles.length); // console.log(":", rectangles.length);
if (rectangles.length === 0) { if (rectangles.length === 0) {
console.log("没有创建任何矩形"); // console.log("");
return; return;
} }
@ -720,7 +734,7 @@ const CameraView = ({
try { try {
// //
const targets = {}; const targets = {};
console.log(rectangles, "当前矩形数据"); // console.log(rectangles, "");
rectangles.forEach((rect, index) => { rectangles.forEach((rect, index) => {
targets[index.toString()] = { targets[index.toString()] = {
@ -758,7 +772,7 @@ const CameraView = ({
}, },
}; };
console.log("格式化数据:"); // console.log(":");
// //
const jsonString = JSON.stringify(outputData, null, 2).replace( const jsonString = JSON.stringify(outputData, null, 2).replace(
@ -770,7 +784,7 @@ const CameraView = ({
const success = sendMessage(jsonString); const success = sendMessage(jsonString);
if (success) { if (success) {
console.log("数据已发送到服务器"); // console.log("");
// //
setTimeout(() => { setTimeout(() => {
@ -795,7 +809,14 @@ const CameraView = ({
setIsSaving(false); setIsSaving(false);
}, 1000); }, 1000);
} }
}, [rectangles, isConnected, sendMessage, refreshTargets, onClearSelection, isSaving]); }, [
rectangles,
isConnected,
sendMessage,
refreshTargets,
onClearSelection,
isSaving,
]);
// alt+ // alt+
useEffect(() => { useEffect(() => {
@ -832,14 +853,14 @@ const CameraView = ({
// //
useEffect(() => { useEffect(() => {
if (videoNaturalWidth && videoNaturalHeight) { if (videoNaturalWidth && videoNaturalHeight) {
console.log("视频尺寸已更新,重新绘制矩形框"); // console.log("");
redrawAllRectangles(); redrawAllRectangles();
} }
}, [videoNaturalWidth, videoNaturalHeight]); }, [videoNaturalWidth, videoNaturalHeight]);
// //
useEffect(() => { useEffect(() => {
console.log("矩形列表发生变化,重新绘制:", rectangles); // console.log(":", rectangles);
// 使requestAnimationFrame // 使requestAnimationFrame
const rafId = requestAnimationFrame(() => { const rafId = requestAnimationFrame(() => {
redrawAllRectangles(); redrawAllRectangles();
@ -848,27 +869,27 @@ const CameraView = ({
return () => cancelAnimationFrame(rafId); return () => cancelAnimationFrame(rafId);
}, [rectangles]); }, [rectangles]);
//
const forceRefreshRectangles = useCallback(() => {
console.log("强制刷新矩形框");
redrawAllRectangles();
}, []);
// //
useEffect(() => { useEffect(() => {
console.log("targets 或 loading 状态变化:", { // console.log("targets loading :", {
targets, // targets,
loading, // loading,
targetsLength: targets?.length, // targetsLength: targets?.length,
}); // });
if (!loading && targets && targets.length > 0) { if (
console.log("从标靶数据初始化矩形框:", targets); !loading &&
targets &&
targets.length > 0 &&
videoNaturalWidth > 0 &&
videoNaturalHeight > 0
) {
// console.log(":", targets);
const initialRectangles = targets const initialRectangles = targets
.map((target) => { .map((target) => {
const rectangleArea = target.rectangleArea; const rectangleArea = target.rectangleArea;
console.log("处理标靶:", target.id, "矩形区域:", rectangleArea); // console.log(":", target.id, ":", rectangleArea);
if ( if (
rectangleArea && rectangleArea &&
rectangleArea.x !== undefined && rectangleArea.x !== undefined &&
@ -896,17 +917,17 @@ const CameraView = ({
}) })
.filter((rect) => rect !== null); // .filter((rect) => rect !== null); //
console.log("生成的矩形框数据:", initialRectangles); // console.log(":", initialRectangles);
console.log("当前矩形框数据:", rectangles); // console.log(":", rectangles);
console.log( // console.log(
"标靶数据详情:", // ":",
targets.map((t) => ({ id: t.id, rectangleArea: t.rectangleArea })) // targets.map((t) => ({ id: t.id, rectangleArea: t.rectangleArea }))
); // );
// targetsrectangles // targetsrectangles
console.log("强制更新矩形框数据以确保与targets同步"); // console.log("targets");
setRectangles(initialRectangles); setRectangles(initialRectangles);
console.log("已从标靶数据强制更新矩形框:", initialRectangles); // console.log(":", initialRectangles);
// //
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
@ -915,18 +936,18 @@ const CameraView = ({
return () => clearTimeout(timeoutId); return () => clearTimeout(timeoutId);
} else if (!loading && (!targets || targets.length === 0)) { } else if (!loading && (!targets || targets.length === 0)) {
// //
console.log( // console.log(
"标靶数据为空,准备清空矩形框,当前矩形框数量:", // ":",
rectangles.length // rectangles.length
); // );
setRectangles([]); setRectangles([]);
console.log("标靶数据为空,已清空矩形框"); // console.log("");
} }
}, [targets, loading]); // targetsloading }, [targets, loading, videoNaturalWidth, videoNaturalHeight]); // targetsloading
// rectangles // rectangles
useEffect(() => { useEffect(() => {
console.log("rectangles状态变化:", rectangles); // console.log("rectangles:", rectangles);
// //
if (videoNaturalWidth && videoNaturalHeight) { if (videoNaturalWidth && videoNaturalHeight) {
// //
@ -935,7 +956,7 @@ const CameraView = ({
if (canvas) { if (canvas) {
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
console.log("强制清除画布,因为矩形数组为空"); // console.log("");
} }
} else { } else {
redrawAllRectangles(); redrawAllRectangles();
@ -958,7 +979,7 @@ const CameraView = ({
// //
useEffect(() => { useEffect(() => {
console.log("选中标靶ID变化:", selectedTargetId); // console.log("ID:", selectedTargetId);
// 使requestAnimationFrame // 使requestAnimationFrame
if (rectangles.length > 0) { if (rectangles.length > 0) {
const rafId = requestAnimationFrame(() => { const rafId = requestAnimationFrame(() => {
@ -1068,7 +1089,7 @@ const CameraView = ({
src={streamUrl} src={streamUrl}
alt="MJPEG 视频流" alt="MJPEG 视频流"
onLoad={handleImageLoad} onLoad={handleImageLoad}
onError={() => console.error("视频流加载失败")} onError={handleImageError}
style={{ style={{
position: "absolute", position: "absolute",
left: 0, left: 0,
@ -1080,6 +1101,27 @@ const CameraView = ({
pointerEvents: "none", pointerEvents: "none",
}} }}
/> />
{/* 视频流断开提示 */}
{streamError && (
<div
style={{
position: "absolute",
left: 0,
top: 0,
width: "100%",
height: "100%",
background: "rgba(0,0,0,0.7)",
color: "#fff",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: 24,
zIndex: 100,
}}
>
视频流断开正在尝试重连...
</div>
)}
</div> </div>
{/* 绘制画布 */} {/* 绘制画布 */}
@ -1131,7 +1173,9 @@ const CameraView = ({
position: "absolute", position: "absolute",
top: "10px", top: "10px",
right: "10px", right: "10px",
backgroundColor: isSaving ? "rgba(128, 128, 128, 0.7)" : "rgba(0, 100, 0, 0.7)", backgroundColor: isSaving
? "rgba(128, 128, 128, 0.7)"
: "rgba(0, 100, 0, 0.7)",
color: "white", color: "white",
border: "1px solid rgba(255, 255, 255, 0.3)", border: "1px solid rgba(255, 255, 255, 0.3)",
borderRadius: "4px", borderRadius: "4px",
@ -1172,7 +1216,7 @@ const CameraView = ({
}} }}
> >
<div> <div>
分辨率: {videoNaturalWidth} × {videoNaturalHeight} 摄像头分辨率: {videoNaturalWidth} × {videoNaturalHeight}
</div> </div>
<div>缩放: {Math.round(scale * 100)}%</div> <div>缩放: {Math.round(scale * 100)}%</div>
<div> <div>

79
client/src/sections/wuyuanbiaoba/components/RealtimeCharts.jsx

@ -31,7 +31,7 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
// //
if (!Array.isArray(tableData)) { if (!Array.isArray(tableData)) {
console.warn('tableData is not an array:', tableData); // console.warn('tableData is not an array:', tableData);
return <div>数据格式错误</div>; return <div>数据格式错误</div>;
} }
@ -60,7 +60,7 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
labels: [], labels: [],
deviceIds: [], deviceIds: [],
timeGroups: {}, timeGroups: {},
sortedTimes: [] sortedTimes: [],
}; };
} }
@ -70,7 +70,9 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
data.forEach((item) => { data.forEach((item) => {
if (!item || !item.updateTime) return; if (!item || !item.updateTime) return;
const timeKey = Math.floor(new Date(item.updateTime).getTime() / 1000); // const timeKey = Math.floor(
new Date(item.updateTime).getTime() / 1000
); //
if (!timeGroups[timeKey]) { if (!timeGroups[timeKey]) {
timeGroups[timeKey] = []; timeGroups[timeKey] = [];
} }
@ -84,25 +86,30 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
.reverse(); .reverse();
// ID // ID
const deviceIds = [...new Set(data.map((item) => item?.deviceId).filter(Boolean))].sort(); const deviceIds = [
...new Set(data.map((item) => item?.deviceId).filter(Boolean)),
].sort();
// //
const labels = sortedTimes.map((timeKey) => { const labels = sortedTimes.map((timeKey) => {
return new Date(Number(timeKey) * 1000).toLocaleTimeString("zh-CN", { return new Date(Number(timeKey) * 1000).toLocaleTimeString(
hour: "2-digit", "zh-CN",
minute: "2-digit", {
second: "2-digit", hour: "2-digit",
}); minute: "2-digit",
second: "2-digit",
}
);
}); });
return { labels, deviceIds, timeGroups, sortedTimes }; return { labels, deviceIds, timeGroups, sortedTimes };
} catch (error) { } catch (error) {
console.error('数据采样出错:', error); console.error("数据采样出错:", error);
return { return {
labels: [], labels: [],
deviceIds: [], deviceIds: [],
timeGroups: {}, timeGroups: {},
sortedTimes: [] sortedTimes: [],
}; };
} }
}; };
@ -110,7 +117,8 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
// X // X
const xChartData = useMemo(() => { const xChartData = useMemo(() => {
try { try {
const { labels, deviceIds, timeGroups, sortedTimes } = sampleData(tableData); const { labels, deviceIds, timeGroups, sortedTimes } =
sampleData(tableData);
if (!deviceIds || deviceIds.length === 0) { if (!deviceIds || deviceIds.length === 0) {
return { labels: [], datasets: [] }; return { labels: [], datasets: [] };
@ -122,7 +130,9 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
const deviceData = timeData.find( const deviceData = timeData.find(
(item) => item.deviceId === deviceId (item) => item.deviceId === deviceId
); );
return deviceData && deviceData.xValue !== undefined ? parseFloat(deviceData.xValue) : null; return deviceData && deviceData.xValue !== undefined
? parseFloat(deviceData.xValue)
: null;
}); });
return { return {
@ -140,7 +150,7 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
return { labels, datasets }; return { labels, datasets };
} catch (error) { } catch (error) {
console.error('准备X轴图表数据出错:', error); console.error("准备X轴图表数据出错:", error);
return { labels: [], datasets: [] }; return { labels: [], datasets: [] };
} }
}, [tableData]); }, [tableData]);
@ -148,7 +158,8 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
// Y // Y
const yChartData = useMemo(() => { const yChartData = useMemo(() => {
try { try {
const { labels, deviceIds, timeGroups, sortedTimes } = sampleData(tableData); const { labels, deviceIds, timeGroups, sortedTimes } =
sampleData(tableData);
if (!deviceIds || deviceIds.length === 0) { if (!deviceIds || deviceIds.length === 0) {
return { labels: [], datasets: [] }; return { labels: [], datasets: [] };
@ -160,7 +171,9 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
const deviceData = timeData.find( const deviceData = timeData.find(
(item) => item.deviceId === deviceId (item) => item.deviceId === deviceId
); );
return deviceData && deviceData.yValue !== undefined ? parseFloat(deviceData.yValue) : null; return deviceData && deviceData.yValue !== undefined
? parseFloat(deviceData.yValue)
: null;
}); });
return { return {
@ -178,7 +191,7 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
return { labels, datasets }; return { labels, datasets };
} catch (error) { } catch (error) {
console.error('准备Y轴图表数据出错:', error); console.error("准备Y轴图表数据出错:", error);
return { labels: [], datasets: [] }; return { labels: [], datasets: [] };
} }
}, [tableData]); }, [tableData]);
@ -300,11 +313,11 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
}; };
// //
useEffect(() => { // useEffect(() => {
console.log('RealtimeCharts - tableData:', tableData); // console.log('RealtimeCharts - tableData:', tableData);
console.log('RealtimeCharts - xChartData:', xChartData); // console.log('RealtimeCharts - xChartData:', xChartData);
console.log('RealtimeCharts - yChartData:', yChartData); // console.log('RealtimeCharts - yChartData:', yChartData);
}, [tableData, xChartData, yChartData]); // }, [tableData, xChartData, yChartData]);
// //
if (!tableData || tableData.length === 0) { if (!tableData || tableData.length === 0) {
@ -325,13 +338,15 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
style={{ marginLeft: "16px", fontSize: "12px" }} style={{ marginLeft: "16px", fontSize: "12px" }}
/> />
</Title> </Title>
<div style={{ <div
flex: 1, style={{
display: "flex", flex: 1,
alignItems: "center", display: "flex",
justifyContent: "center", alignItems: "center",
minHeight: "500px" justifyContent: "center",
}}> minHeight: "500px",
}}
>
<div style={{ textAlign: "center", color: "#999" }}> <div style={{ textAlign: "center", color: "#999" }}>
<p>等待实时数据...</p> <p>等待实时数据...</p>
</div> </div>
@ -356,7 +371,13 @@ const RealtimeCharts = ({ tableData, lastUpdateTime }) => {
text={`实时更新 - 最后更新: ${lastUpdateTime.toLocaleTimeString()}`} text={`实时更新 - 最后更新: ${lastUpdateTime.toLocaleTimeString()}`}
style={{ marginLeft: "16px", fontSize: "12px" }} style={{ marginLeft: "16px", fontSize: "12px" }}
/> />
<Badge
status="default"
text={`图表数据采样频率:1Hz`}
style={{ marginLeft: "16px", fontSize: "12px" }}
/>
</Title> </Title>
<div <div
style={{ style={{
flex: 1, flex: 1,

32
client/src/sections/wuyuanbiaoba/container/index.jsx

@ -86,7 +86,7 @@ const WuyuanbiaobaContent = () => {
// //
setRealtimeData([]); setRealtimeData([]);
setTableData([]); setTableData([]);
console.log("数据已初始化,等待实时数据...", import.meta.env.MODE); // console.log("...", import.meta.env.MODE);
}, []); }, []);
// //
@ -98,11 +98,11 @@ const WuyuanbiaobaContent = () => {
); );
if (builtinTemplate) { if (builtinTemplate) {
setSelectedTemplate("builtin_1"); setSelectedTemplate("builtin_1");
console.log("默认选中内置模板:", builtinTemplate.name); // console.log(":", builtinTemplate.name);
} else { } else {
// //
setSelectedTemplate(tempListData[0].key); setSelectedTemplate(tempListData[0].key);
console.log("默认选中第一个模板:", tempListData[0].name); // console.log(":", tempListData[0].name);
} }
} }
}, [templatesLoading, tempListData, selectedTemplate]); }, [templatesLoading, tempListData, selectedTemplate]);
@ -110,15 +110,15 @@ const WuyuanbiaobaContent = () => {
// WebSocket // WebSocket
useEffect(() => { useEffect(() => {
if (isConnected) { if (isConnected) {
console.log("WebSocket已连接,等待实时数据..."); // console.log("WebSocket...");
} else { } else {
console.log("WebSocket未连接"); // console.log("WebSocket");
} }
}, [isConnected]); }, [isConnected]);
// //
useEffect(() => { useEffect(() => {
// console.log(':', { // console.log(':', {
// hasData: !!realtimeDataSubscription.latest, // hasData: !!realtimeDataSubscription.latest,
// dataCount: realtimeDataSubscription.data?.length || 0, // dataCount: realtimeDataSubscription.data?.length || 0,
// latestTimestamp: realtimeDataSubscription.latest?.timestamp, // latestTimestamp: realtimeDataSubscription.latest?.timestamp,
@ -177,24 +177,24 @@ const WuyuanbiaobaContent = () => {
setCurrentEditTarget(target); setCurrentEditTarget(target);
setTargetDetailModalMode("edit"); setTargetDetailModalMode("edit");
setTargetDetailModalVisible(true); setTargetDetailModalVisible(true);
console.log("编辑标靶:", target); // console.log(":", target);
}; };
// //
const handleSelectTarget = (target) => { const handleSelectTarget = (target) => {
setSelectedTargetId(target.id); setSelectedTargetId(target.id);
console.log("选中标靶:", target); // console.log(":", target);
}; };
// //
const handleClearSelection = () => { const handleClearSelection = () => {
setSelectedTargetId(null); setSelectedTargetId(null);
console.log("清除标靶选中状态"); // console.log("");
}; };
// //
const handleRectangleClick = (targetData) => { const handleRectangleClick = (targetData) => {
console.log("矩形框被点击,打开标靶详情:", targetData); // console.log(":", targetData);
setCurrentEditTarget(targetData); setCurrentEditTarget(targetData);
setTargetDetailModalMode("edit"); setTargetDetailModalMode("edit");
setTargetDetailModalVisible(true); setTargetDetailModalVisible(true);
@ -203,7 +203,7 @@ const WuyuanbiaobaContent = () => {
// //
const handleTemplateSelect = (templateKey) => { const handleTemplateSelect = (templateKey) => {
setSelectedTemplate(templateKey); setSelectedTemplate(templateKey);
console.log("选中模板:", templateKey); // console.log(":", templateKey);
}; };
// //
@ -222,7 +222,7 @@ const WuyuanbiaobaContent = () => {
// //
const handleTemplateModalOk = (templateInfo) => { const handleTemplateModalOk = (templateInfo) => {
console.log(templateInfo, "templateInfo"); // console.log(templateInfo, "templateInfo");
let success = false; let success = false;
if (templateModalMode === "add") { if (templateModalMode === "add") {
@ -269,7 +269,7 @@ const WuyuanbiaobaContent = () => {
if (success) { if (success) {
setTargetDetailModalVisible(false); setTargetDetailModalVisible(false);
setCurrentEditTarget(null); setCurrentEditTarget(null);
console.log("更新标靶信息:", targetInfo); // console.log(":", targetInfo);
} else { } else {
console.error("更新标靶失败"); console.error("更新标靶失败");
// //
@ -284,7 +284,7 @@ const WuyuanbiaobaContent = () => {
// //
const handleDeleteTarget = (targetKey) => { const handleDeleteTarget = (targetKey) => {
console.log("开始删除标靶:", targetKey); // console.log(":", targetKey);
const success = deleteTarget(targetKey); const success = deleteTarget(targetKey);
if (success) { if (success) {
@ -294,7 +294,7 @@ const WuyuanbiaobaContent = () => {
if (selectedTargetId === targetKey) { if (selectedTargetId === targetKey) {
setSelectedTargetId(null); setSelectedTargetId(null);
} }
console.log("删除标靶成功:", targetKey); // console.log(":", targetKey);
// UI // UI
setTimeout(() => { setTimeout(() => {
@ -307,7 +307,7 @@ const WuyuanbiaobaContent = () => {
}; };
// - // -
const onClickClearAll = () => { const onClickClearAll = () => {
console.log("一键清零操作"); // console.log("");
sendMessage( sendMessage(
JSON.stringify({ JSON.stringify({
_from: "setup", _from: "setup",

4
client/src/sections/wuyuanbiaoba/hooks/useTargetStorage.js

@ -59,7 +59,7 @@ export const useTargetStorage = () => {
if (targetDataResponse && targetDataResponse.values) { if (targetDataResponse && targetDataResponse.values) {
try { try {
const responseValues = targetDataResponse.values; const responseValues = targetDataResponse.values;
console.log('收到标靶数据:', responseValues); // console.log('收到标靶数据:', responseValues);
// 检查是否为空对象 // 检查是否为空对象
if (!responseValues || Object.keys(responseValues).length === 0) { if (!responseValues || Object.keys(responseValues).length === 0) {
@ -101,7 +101,7 @@ export const useTargetStorage = () => {
setTargets(formattedTargets); setTargets(formattedTargets);
setError(null); setError(null);
console.log('解析到标靶数据:', formattedTargets); // console.log('解析到标靶数据:', formattedTargets);
} catch (err) { } catch (err) {
console.error('处理标靶数据失败:', err); console.error('处理标靶数据失败:', err);
setError('处理标靶数据失败'); setError('处理标靶数据失败');

38
server/tcpProxy/index.js

@ -10,7 +10,7 @@ function setupTcpProxy(conf) {
// 从配置中获取端口,如果没有则使用默认端口 // 从配置中获取端口,如果没有则使用默认端口
const wsPort = (conf && conf.port) ? Number(conf.port) + 1 : 5001; // WebSocket端口比HTTP端口大1 const wsPort = (conf && conf.port) ? Number(conf.port) + 1 : 5001; // WebSocket端口比HTTP端口大1
console.log(`准备在端口 ${wsPort} 启动WebSocket服务器`); // console.log(`准备在端口 ${wsPort} 启动WebSocket服务器`);
const wss = new WebSocket.Server({ const wss = new WebSocket.Server({
port: wsPort, port: wsPort,
@ -19,7 +19,7 @@ function setupTcpProxy(conf) {
}); });
wss.on('connection', (ws, request) => { wss.on('connection', (ws, request) => {
console.log(`WebSocket连接建立,来自: ${request.socket.remoteAddress}`); // console.log(`WebSocket连接建立,来自: ${request.socket.remoteAddress}`);
// 创建TCP连接 // 创建TCP连接
const tcpClient = new net.Socket(); const tcpClient = new net.Socket();
@ -28,8 +28,8 @@ function setupTcpProxy(conf) {
// TCP连接成功 // TCP连接成功
tcpClient.connect(process.env.TCP_PORT || TCP_PORT, process.env.TCP_HOST || TCP_HOST, () => { tcpClient.connect(process.env.TCP_PORT || TCP_PORT, process.env.TCP_HOST || TCP_HOST, () => {
console.log(process.env); // console.log(process.env);
console.log(`TCP连接已建立到 ${TCP_HOST}:${TCP_PORT}`); // console.log(`TCP连接已建立到 ${TCP_HOST}:${TCP_PORT}`);
}); });
// TCP接收数据,转发到WebSocket // TCP接收数据,转发到WebSocket
@ -40,7 +40,7 @@ function setupTcpProxy(conf) {
textData = data.toString('utf8'); textData = data.toString('utf8');
// console.log('收到TCP数据片段:', textData.length, '字节'); // console.log('收到TCP数据片段:', textData.length, '字节');
} catch (e) { } catch (e) {
console.log('TCP数据无法解析为文本'); // console.log('TCP数据无法解析为文本');
return; return;
} }
@ -55,7 +55,7 @@ function setupTcpProxy(conf) {
// 从缓冲区移除已处理的消息 // 从缓冲区移除已处理的消息
tcpDataBuffer = tcpDataBuffer.substring(endIndex + 2); tcpDataBuffer = tcpDataBuffer.substring(endIndex + 2);
console.log('提取到完整消息:', completeMessage.length, '字节'); // console.log('提取到完整消息:', completeMessage.length, '字节');
// 转发完整消息到WebSocket // 转发完整消息到WebSocket
if (ws.readyState === WebSocket.OPEN) { if (ws.readyState === WebSocket.OPEN) {
@ -65,13 +65,13 @@ function setupTcpProxy(conf) {
if (err) { if (err) {
console.error('WebSocket发送数据错误:', err); console.error('WebSocket发送数据错误:', err);
} else { } else {
console.log('完整消息已转发到WebSocket客户端'); // console.log('完整消息已转发到WebSocket客户端');
} }
}); });
} }
} }
console.log('缓冲区剩余数据:', tcpDataBuffer.length, '字节'); // console.log('缓冲区剩余数据:', tcpDataBuffer.length, '字节');
}); });
// WebSocket接收数据,转发到TCP // WebSocket接收数据,转发到TCP
@ -86,28 +86,28 @@ function setupTcpProxy(conf) {
messageStr = data; messageStr = data;
// console.log('WebSocket数据(字符串):', messageStr); // console.log('WebSocket数据(字符串):', messageStr);
} else { } else {
console.warn('收到未知类型数据,已忽略:', typeof data); // console.warn('收到未知类型数据,已忽略:', typeof data);
return; return;
} }
// 转发字符串数据到TCP服务器 // 转发字符串数据到TCP服务器
if (tcpClient.writable) { if (tcpClient.writable) {
console.log('准备发送数据到TCP服务器:', messageStr); // console.log('准备发送数据到TCP服务器:', messageStr);
// 检查数据大小 // 检查数据大小
const dataSize = Buffer.byteLength(messageStr, 'utf8'); const dataSize = Buffer.byteLength(messageStr, 'utf8');
console.log(`数据大小: ${dataSize} bytes`); // console.log(`数据大小: ${dataSize} bytes`);
// 直接发送完整数据 // 直接发送完整数据
tcpClient.write(messageStr + '\n\n', (err) => { tcpClient.write(messageStr + '\n\n', (err) => {
if (err) { if (err) {
console.error('TCP发送数据错误:', err); console.error('TCP发送数据错误:', err);
} else { } else {
console.log('数据已发送到TCP服务器'); // console.log('数据已发送到TCP服务器');
} }
}); });
} else { } else {
console.warn('TCP连接不可写,无法发送数据'); // console.warn('TCP连接不可写,无法发送数据');
} }
}); });
@ -122,7 +122,7 @@ function setupTcpProxy(conf) {
// TCP连接关闭 // TCP连接关闭
tcpClient.on('close', () => { tcpClient.on('close', () => {
console.log('TCP连接已关闭'); // console.log('TCP连接已关闭');
tcpDataBuffer = ''; // 清理缓冲区 tcpDataBuffer = ''; // 清理缓冲区
if (ws.readyState === WebSocket.OPEN) { if (ws.readyState === WebSocket.OPEN) {
ws.close(); ws.close();
@ -131,7 +131,7 @@ function setupTcpProxy(conf) {
// WebSocket连接关闭 // WebSocket连接关闭
ws.on('close', () => { ws.on('close', () => {
console.log('WebSocket连接已关闭'); // console.log('WebSocket连接已关闭');
tcpDataBuffer = ''; // 清理缓冲区 tcpDataBuffer = ''; // 清理缓冲区
if (tcpClient.writable) { if (tcpClient.writable) {
tcpClient.destroy(); tcpClient.destroy();
@ -148,10 +148,10 @@ function setupTcpProxy(conf) {
}); });
wss.on('listening', () => { wss.on('listening', () => {
console.log(`TCP代理WebSocket服务器已启动在端口 ${wsPort},路径: /tcp-proxy`); // console.log(`TCP代理WebSocket服务器已启动在端口 ${wsPort},路径: /tcp-proxy`);
console.log(`局域网连接地址: ws://[本机IP]:${wsPort}/tcp-proxy`); // console.log(`局域网连接地址: ws://[本机IP]:${wsPort}/tcp-proxy`);
console.log(`本地连接地址: ws://localhost:${wsPort}/tcp-proxy`); // console.log(`本地连接地址: ws://localhost:${wsPort}/tcp-proxy`);
console.log(`注意:请确保防火墙允许端口 ${wsPort} 的访问`); // console.log(`注意:请确保防火墙允许端口 ${wsPort} 的访问`);
}); });
wss.on('error', (err) => { wss.on('error', (err) => {

Loading…
Cancel
Save