From 841fe37df5c83b684caf007a4278798c1a09e8e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=87=A4=E5=90=89?= Date: Mon, 10 Mar 2025 10:58:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E6=9E=90=E5=AE=8C=E6=AF=95=E5=90=8E?= =?UTF-8?q?=E5=88=86=E6=9E=90=E5=88=87=E6=8D=A2=E6=8C=89=E9=92=AE=E6=89=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=87=BA=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/measure/components/MeasureAction.tsx | 316 +++++++++++-------------- 1 file changed, 134 insertions(+), 182 deletions(-) diff --git a/src/pages/measure/components/MeasureAction.tsx b/src/pages/measure/components/MeasureAction.tsx index c97607d..79e6da9 100644 --- a/src/pages/measure/components/MeasureAction.tsx +++ b/src/pages/measure/components/MeasureAction.tsx @@ -1,6 +1,5 @@ -import React from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { Button, Checkbox, CheckboxProps, message, Switch } from "antd"; -import { useEffect, useRef, useState } from "react"; import { useNavigate } from "react-router"; import { fetchAnalysisReport, @@ -21,105 +20,64 @@ import MeasurementCanvas, { MeasurementCanvasRef, } from "./konva/MeasurementCanvas"; +// 创建 websocket 客户端 const wsClient = createWebSocket(sharedWsUrl); export default function MeasureAction() { const dispatch = useAppDispatch(); const navigate = useNavigate(); - // MeasurementCanvas 的 ref + /** ----------------------- 引用 ----------------------- **/ const canvasRef = useRef(null); - - // 用于累计点数据 const leftPoints = useRef<{ x: number; y: number }[]>([]); const rightPoints = useRef<{ x: number; y: number }[]>([]); - // 标志左侧数据是否结束 const isLeftFinished = useRef(false); + /** ----------------------- 状态 ----------------------- **/ const [showGrid, setShowGrid] = useState(true); const [showStandard, setShowStandard] = useState(true); const [showMark, setShowMark] = useState(true); - // 用于保存角度线的备份状态,当标准线关闭时记住原先角度线是否开启 const [angleMarkBackup, setAngleMarkBackup] = useState(true); const afterSave = useAppSelector((store) => store.context.newMeasureAfterSave); - const [angles, setAngles] = useState([]); const [taskStatus, setTaskStatus] = useState("IDLE"); - // 初始按钮文本为“开始测量” const [startBtnText, setStartBtnText] = useState("开始测量"); - // 测量是否完成的状态 const [measurementFinished, setMeasurementFinished] = useState(false); - // 本次测量周期内按钮是否已点击过(只能点击一次) const [analysisClicked, setAnalysisClicked] = useState(false); const [saveClicked, setSaveClicked] = useState(false); - - // 新增:保存接口返回的分析报告数据和是否显示分析表格(右侧区域切换) const [analysisReport, setAnalysisReport] = useState(null); const [showAnalysisTable, setShowAnalysisTable] = useState(false); + const [taskStatusName, setTaskStatusName] = useState(""); + // 初始状态列表 const initialStatusList = [ - { - statusCode: "START_RECORD_LEFT", - name: "请移动到顶部,停顿2秒", - background: "#ececec", - isReady: false, - color: "h", - }, - { - statusCode: "START_RECORD_LEFT", - name: "开始测量左侧", - background: "#ececec", - isReady: false, - color: "h", - }, - { - statusCode: "START_RECORD_LEFT", - name: "左侧测量完成", - background: "#ececec", - isReady: false, - color: "h", - }, - { - statusCode: "START_RECORD_LEFT", - name: "请移动到顶部,停顿2秒", - background: "#ececec", - isReady: false, - color: "h", - }, - { - statusCode: "START_RECORD_LEFT", - name: "开始测量右侧", - background: "#ececec", - isReady: false, - color: "h", - }, - { - statusCode: "START_RECORD_LEFT", - name: "右侧测量完成", - background: "#ececec", - isReady: false, - color: "h", - }, + { statusCode: "START_RECORD_LEFT", name: "请移动到顶部,停顿2秒", background: "#ececec", isReady: false, color: "h" }, + { statusCode: "START_RECORD_LEFT", name: "开始测量左侧", background: "#ececec", isReady: false, color: "h" }, + { statusCode: "START_RECORD_LEFT", name: "左侧测量完成", background: "#ececec", isReady: false, color: "h" }, + { statusCode: "START_RECORD_LEFT", name: "请移动到顶部,停顿2秒", background: "#ececec", isReady: false, color: "h" }, + { statusCode: "START_RECORD_LEFT", name: "开始测量右侧", background: "#ececec", isReady: false, color: "h" }, + { statusCode: "START_RECORD_LEFT", name: "右侧测量完成", background: "#ececec", isReady: false, color: "h" }, ]; const [statusList, setStatusList] = useState(initialStatusList); + /** ----------------------- 事件处理函数 ----------------------- **/ + // 切换保存后自动开始新测量 const onAfterSaveChange: CheckboxProps["onChange"] = (e) => { - dispatch(switchMeasureAfterSave(e.target.checked)); - }; + dispatch(switchMeasureAfterSave(e.target.checked)); + }; + // 分析按钮点击事件 const onAnalysisBtnClick = () => { - // 分析按钮只允许点击一次 setAnalysisClicked(true); fetchAnalysisReport("6001").then((res) => { if (res.success) { const report: AnalysisReport = res.data; - console.log(res.data); - // 更新 canvas 分析数据(如有需要) + console.log(report); + // 更新 canvas 的分析数据 if (report && report.angleAnalysisList) { const analysisData: AnalysisData[] = report.angleAnalysisList.map((item) => ({ pointA: { x: parseFloat(item.pointA.x), y: parseFloat(item.pointA.y) }, pointB: { x: parseFloat(item.pointB.x), y: parseFloat(item.pointB.y) }, - // 默认将 base 与 measure 分别设置为 pointA 与 pointB base: { x: parseFloat(item.pointA.x), y: parseFloat(item.pointA.y) }, measure: { x: parseFloat(item.pointB.x), y: parseFloat(item.pointB.y) }, distance: parseFloat(item.distance), @@ -127,7 +85,6 @@ export default function MeasureAction() { })); canvasRef.current?.setAnalysisData(analysisData); } - // 保存返回数据,并显示分析表格(右侧区域切换) setAnalysisReport(report); setShowAnalysisTable(true); } else { @@ -136,13 +93,13 @@ export default function MeasureAction() { }); }; + // 开始/重新测量按钮点击事件 const onStart = () => { - // 如果按钮文本为“新测量”,则直接跳转到新测量页面 if (startBtnText === "新测量") { navigate("../newMeasure"); return; } - // 进入测量流程时恢复右侧区域为测量步骤 + // 重置测量相关状态 setShowAnalysisTable(false); setMeasurementFinished(false); setAnalysisClicked(false); @@ -150,33 +107,28 @@ export default function MeasureAction() { isLeftFinished.current = false; leftPoints.current = []; rightPoints.current = []; - // 清空绘制的图形,并重置缩放/偏移 canvasRef.current?.clearShapes(); canvasRef.current?.resetCanvas(); - // 如果按钮原来为“重新测量”,则重置状态列表 if (startBtnText === "重新测量") { setStatusList(initialStatusList); } startMeasurement().then((res) => { if (res.status !== 0) { message.error(res.data.info); - let name = taskStatusDescMap["IDLE"]; - setTaskStatusName(name); + setTaskStatusName(taskStatusDescMap["IDLE"]); } else { const newStatusList = [...initialStatusList]; newStatusList[0].color = "b"; setStatusList(newStatusList); message.success("已通知设备开始测量"); - let name = taskStatusDescMap["IDLE"]; - setTaskStatusName(name); - // 测量启动成功后,按钮文本变为“重新测量” + setTaskStatusName(taskStatusDescMap["IDLE"]); setStartBtnText("重新测量"); } }); }; + // 保存按钮点击事件 const onSaveBtnClick = () => { - // 保存按钮只允许点击一次 setSaveClicked(true); saveMeasurement().then((res) => { if (res.status !== 0) { @@ -184,77 +136,120 @@ export default function MeasureAction() { } else { message.success("保存成功"); if (afterSave) { - // 勾选了保存后自动开始新测量则直接跳转 navigate("../config"); } else { - // 否则修改按钮文本为“新测量” setStartBtnText("新测量"); } } }); }; - const [taskStatusName, setTaskStatusName] = useState(""); + // 辅助函数:渲染状态项的背景颜色 + const renderStatusBackground = (item: typeof initialStatusList[0]) => + item.statusCode === "START_RECORD_LEFT" ? item.background : ""; + + // 辅助函数:渲染状态项的图标 + const renderStatusIcon = (item: typeof initialStatusList[0]) => { + if (item.color === "g") { + return green; + } else if (item.color === "b") { + return blue; + } else { + return ( +
+ ); + } + }; + + /** ----------------------- WebSocket 消息处理 ----------------------- **/ useEffect(() => { - const subscription = wsClient.dataOb.subscribe((data) => { - // 处理任务状态消息 - if (data.messageType === "STATE" && data.path === "/measurement-task/get-task-state") { - if (!data.data) return; - if (data.data.taskStatus === "IDLE") { - setTaskStatusName("空闲"); - } else if (!data.data.isMeasuringLeftEnd) { - setTaskStatusName("左侧正在测量"); - statusList[0].isReady = true; - setStatusList([...statusList]); - } else if (data.data.isMeasuringLeftEnd && !data.data.isMeasuringRightEnd) { - setTaskStatusName("右侧正在测量"); - } else { - let name = taskStatusDescMap[data.data.taskStatus]; - setTaskStatusName(name); - } - setTaskStatus(data.data.taskStatus); + // 处理任务状态消息 + const handleStateMessage = (data: any) => { + if (!data.data) return; + if (data.data.taskStatus === "IDLE") { + setTaskStatusName("空闲"); + } else if (!data.data.isMeasuringLeftEnd) { + setTaskStatusName("左侧正在测量"); + setStatusList((prev) => { + const updated = [...prev]; + updated[0].isReady = true; + return updated; + }); + } else if (data.data.isMeasuringLeftEnd && !data.data.isMeasuringRightEnd) { + setTaskStatusName("右侧正在测量"); + } else { + setTaskStatusName(taskStatusDescMap[data.data.taskStatus as keyof typeof taskStatusDescMap]); + } + setTaskStatus(data.data.taskStatus); + }; - // 处理状态变化事件 - if (data.messageType === "EVENT" && data.path === "/measurement-task/event") { - if (data.data === "START_RECORD_LEFT") { - statusList[0].color = "g"; - statusList[1].color = "b"; - } else if (data.data === "FINISH_RECORD_LEFT") { - statusList[1].color = "g"; - statusList[2].color = "g"; - statusList[3].color = "b"; - // 左侧测量结束后,切换到右侧数据累计 - isLeftFinished.current = true; - } else if (data.data === "START_RECORD_RIGHT") { - statusList[3].color = "g"; - statusList[4].color = "b"; - } else if (data.data === "FINISH_RECORD_RIGHT") { - statusList[4].color = "g"; - statusList[5].color = "g"; - // 接收到 FINISH_RECORD_RIGHT 后认为测量完成 - setMeasurementFinished(true); + // 处理事件消息 + const handleEventMessage = (data: any) => { + setStatusList((prev) => { + const updated = [...prev]; + switch (data.data) { + case "START_RECORD_LEFT": + updated[0].color = "g"; + updated[1].color = "b"; + break; + case "FINISH_RECORD_LEFT": + updated[1].color = "g"; + updated[2].color = "g"; + updated[3].color = "b"; + isLeftFinished.current = true; + break; + case "START_RECORD_RIGHT": + updated[3].color = "g"; + updated[4].color = "b"; + break; + case "FINISH_RECORD_RIGHT": + updated[4].color = "g"; + updated[5].color = "g"; + setMeasurementFinished(true); + break; + default: + break; } - setStatusList([...statusList]); + return updated; + }); + }; + + // 处理点数据消息 + const handlePointReport = (data: any) => { + const pointData = data.data as { x: number; y: number }; + console.log(`pointData === ${pointData.x},${pointData.y}`); + if (!isLeftFinished.current) { + leftPoints.current.push(pointData); + canvasRef.current?.setMeasurementDataLeft([...leftPoints.current]); + } else { + rightPoints.current.push(pointData); + canvasRef.current?.setMeasurementDataRight([...rightPoints.current]); } + }; - if (data.messageType === "STATE" && (data as any).path === "/measurement-task/point-report") { - const pointData = ((data as unknown) as { data: { x: number; y: number } }).data; - console.log("pointData ====" + pointData.x + "," + pointData.y); - if (!isLeftFinished.current) { - leftPoints.current.push(pointData); - canvasRef.current?.setMeasurementDataLeft([...leftPoints.current]); - } else { - rightPoints.current.push(pointData); - canvasRef.current?.setMeasurementDataRight([...rightPoints.current]); - } + const subscription = wsClient.dataOb.subscribe((data: any) => { + if (data.messageType === "STATE" && data.path === "/measurement-task/get-task-state") { + handleStateMessage(data); + } else if (data.messageType === "EVENT" && data.path === "/measurement-task/event") { + handleEventMessage(data); + } else if (data.messageType === "STATE" && data.path === "/measurement-task/point-report") { + handlePointReport(data); } }); wsClient.connect(); return () => subscription.unsubscribe(); - }, [statusList]); + }, []); - // 页面加载时获取基础图形数据,并传入 MeasurementCanvas + /** ----------------------- 页面加载获取基础图形数据 ----------------------- **/ useEffect(() => { getBaseRecordPointSetByCode("6001").then((res) => { if (res.success) { @@ -267,42 +262,7 @@ export default function MeasureAction() { }); }, []); - type StatusCodeData = { - statusCode: string; - name: string; - background: string; - isReady: boolean; - color: string; - }; - - const onHandleChangeStatus = (item: StatusCodeData) => { - let backgroundColor = ""; - if (item.statusCode === "START_RECORD_LEFT") { - backgroundColor = item.background; - } - return backgroundColor; - }; - - const onHandleIcon = (item: StatusCodeData, index: number) => { - if (item.color === "g") { - return ; - } else if (item.color === "b") { - return ; - } else if (item.color === "h") { - return ( -
- ); - } - }; - + /** ----------------------- 渲染 ----------------------- **/ return (
{/* 左侧区域:包含开关区域和测量画布 */} @@ -320,18 +280,16 @@ export default function MeasureAction() { onChange={(checked) => { setShowStandard(checked); if (!checked) { - // 关闭标准线时,备份当前角度线状态,并关闭角度线 setAngleMarkBackup(showMark); setShowMark(false); } else { - // 打开标准线时,恢复角度线之前的状态 setShowMark(angleMarkBackup); } }} /> 标准线
- {/* 角度线开关仅在点击分析按钮后显示 */} + {/* 角度线开关,仅在点击分析按钮后显示 */} {analysisClicked && (
{ setShowMark(checked); - // 当标准线处于开启状态时,允许修改角度线状态,并更新备份状态 setAngleMarkBackup(checked); }} /> @@ -366,7 +323,7 @@ export default function MeasureAction() { />
- {/* 右侧区域:根据 showAnalysisTable 状态决定显示测量步骤区域还是分析表格 */} + {/* 右侧区域:根据 showAnalysisTable 状态显示测量步骤或分析表格 */}
{showAnalysisTable && analysisReport ? (
@@ -394,10 +351,7 @@ export default function MeasureAction() { ))} - + @@ -410,20 +364,18 @@ export default function MeasureAction() {

测量步骤

- {statusList.map((item, index) => { - return ( -
-
- {onHandleIcon(item, index)} -
{item.name}
-
+ {statusList.map((item, index) => ( +
+
+ {renderStatusIcon(item)} +
{item.name}
- ); - })} +
+ ))}