diff --git a/package-lock.json b/package-lock.json index 50b7c7c..831d253 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,6 +47,7 @@ "jest": "^27.4.3", "jest-resolve": "^27.4.2", "jest-watch-typeahead": "^1.0.0", + "konva": "^8.3.5", "mini-css-extract-plugin": "^2.4.5", "postcss-flexbugs-fixes": "^5.0.2", "postcss-loader": "^6.2.1", @@ -58,6 +59,7 @@ "react-app-polyfill": "^3.0.0", "react-dev-utils": "^12.0.1", "react-dom": "^18.3.1", + "react-konva": "^18.0.0", "react-redux": "^9.2.0", "react-refresh": "^0.11.0", "react-router": "^6.30.0", @@ -4557,6 +4559,15 @@ "@types/react": "^19.0.0" } }, + "node_modules/@types/react-reconciler": { + "version": "0.28.9", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz", + "integrity": "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmmirror.com/@types/resolve/-/resolve-1.17.1.tgz", @@ -10874,6 +10885,18 @@ "node": ">= 0.4" } }, + "node_modules/its-fine": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.2.5.tgz", + "integrity": "sha512-fXtDA0X0t0eBYAGLVM5YsgJGsJ5jEmqZEPrGbzdf5awjv0xE7nqv3TVnvtUF060Tkes15DbDAKW/I48vsb6SyA==", + "license": "MIT", + "dependencies": { + "@types/react-reconciler": "^0.28.0" + }, + "peerDependencies": { + "react": ">=18.0" + } + }, "node_modules/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmmirror.com/jackspeak/-/jackspeak-3.4.3.tgz", @@ -12036,6 +12059,26 @@ "node": ">= 8" } }, + "node_modules/konva": { + "version": "8.4.3", + "resolved": "https://registry.npmjs.org/konva/-/konva-8.4.3.tgz", + "integrity": "sha512-ARqdgAbdNIougRlOKvkQwHlGhXPRBV4KvhCP+qoPpGoVQwwiJe4Hkdu4HHdRPb9rGUp04jDTAxBzEwBsE272pg==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/lavrton" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/konva" + }, + { + "type": "github", + "url": "https://github.com/sponsors/lavrton" + } + ], + "license": "MIT" + }, "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmmirror.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", @@ -15532,6 +15575,53 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "license": "MIT" }, + "node_modules/react-konva": { + "version": "18.2.10", + "resolved": "https://registry.npmjs.org/react-konva/-/react-konva-18.2.10.tgz", + "integrity": "sha512-ohcX1BJINL43m4ynjZ24MxFI1syjBdrXhqVxYVDw2rKgr3yuS0x/6m1Y2Z4sl4T/gKhfreBx8KHisd0XC6OT1g==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/lavrton" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/konva" + }, + { + "type": "github", + "url": "https://github.com/sponsors/lavrton" + } + ], + "license": "MIT", + "dependencies": { + "@types/react-reconciler": "^0.28.2", + "its-fine": "^1.1.1", + "react-reconciler": "~0.29.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "konva": "^8.0.1 || ^7.2.5 || ^9.0.0", + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } + }, + "node_modules/react-reconciler": { + "version": "0.29.2", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.2.tgz", + "integrity": "sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, "node_modules/react-redux": { "version": "9.2.0", "resolved": "https://registry.npmmirror.com/react-redux/-/react-redux-9.2.0.tgz", diff --git a/package.json b/package.json index 2af872c..d787bc8 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "outline", "version": "0.1.0", "private": true, - "proxy":"http://192.168.1.200:80", + "proxy": "http://192.168.1.200:80", "dependencies": { "@babel/core": "^7.16.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", @@ -54,6 +54,8 @@ "react-app-polyfill": "^3.0.0", "react-dev-utils": "^12.0.1", "react-dom": "^18.3.1", + "konva": "^8.3.5", + "react-konva": "^18.0.0", "react-redux": "^9.2.0", "react-refresh": "^0.11.0", "react-router": "^6.30.0", diff --git a/src/components/SideMenu.tsx b/src/components/SideMenu.tsx index 1c74dcd..5050302 100644 --- a/src/components/SideMenu.tsx +++ b/src/components/SideMenu.tsx @@ -2,7 +2,7 @@ import type { MenuProps } from "antd"; import { Menu } from "antd"; import icon_logo from "../assets/icon_logo.svg"; import icon_measure from "../assets/menu/icon_measure.svg"; -import { useNavigate, useLocation } from 'react-router-dom'; +import { useNavigate, useLocation } from "react-router-dom"; import "./SideMenu.scss"; type MenuItem = Required["items"][number]; @@ -28,9 +28,14 @@ const items: MenuItem[] = [ export default function SideMenu() { const navigate = useNavigate(); const location = useLocation(); + const key = + location.pathname === "/measure/detail" + ? "/measure/detail" + : location.pathname.startsWith("/measure") + ? "/measure/config" + : location.pathname; const onClick: MenuProps["onClick"] = e => { - console.log("click menu----", e); - navigate(e.key) + navigate(e.key); }; return (
@@ -39,13 +44,12 @@ export default function SideMenu() { className="side-menu" onClick={onClick} style={{ width: "100%", backgroundColor: "transparent", color: "#fff" }} - defaultSelectedKeys={["1"]} - defaultOpenKeys={["sub1"]} - selectedKeys={[location.pathname]} + defaultOpenKeys={["measure"]} + selectedKeys={[key]} mode="inline" items={items} /> -

V1.0

+

V1.0

); } diff --git a/src/index.tsx b/src/index.tsx index 6f781af..0b5f9f5 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,7 +1,7 @@ import React from "react"; import ReactDOM from "react-dom/client"; import "./index.css"; -import { createBrowserRouter, RouterProvider } from "react-router-dom"; +import {createBrowserRouter, RouterProvider} from "react-router-dom"; import Login from "./pages/login/Login"; import Measure from "./pages/measure/Measure"; import MeasureConfig from "./pages/measure/components/MeasureConfig"; @@ -11,48 +11,48 @@ import App from "./App"; import reportWebVitals from "./reportWebVitals"; // redux toolkit -import { Provider } from "react-redux"; +import {Provider} from "react-redux"; import store from "./store/index"; const router = createBrowserRouter([ - { - path: "/", - element: , - children: [ - { - path: "measure", - element: , - children: [ - { - path: "config", - element: , - }, - { - path: "detail", - element: , - }, - { - path: "action", - element: , - }, - ], - }, - ], - }, - { - path: "/login", - element: , - }, - + { + path: "/", + element: , + children: [ + { + path: "measure", + element: , + children: [ + { + path: "config", + element: , + }, + { + path: "detail", + element: , + }, + { + path: "action", + element: , + } + ], + }, + ], + }, + { + path: "/login", + element: , + }, + ]); const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement); root.render( - // - - - - // + // + + + + // ); console.log(process.env.REACT_APP_WS_URL); diff --git a/src/pages/measure/components/MeasureAction.tsx b/src/pages/measure/components/MeasureAction.tsx index 08c1e1c..892bfe9 100644 --- a/src/pages/measure/components/MeasureAction.tsx +++ b/src/pages/measure/components/MeasureAction.tsx @@ -1,335 +1,454 @@ -import { Button, Checkbox, CheckboxProps, Switch, message } from "antd"; -import { useState, useEffect } from "react"; +import React from 'react'; +import { Button, Checkbox, CheckboxProps, message, Switch } from "antd"; +import { useEffect, useRef, useState } from "react"; import { useNavigate } from "react-router"; -import { analyzeMeasurement, saveMeasurement, startMeasurement, analysisReport } from "../../../services/measure/analysis"; +import { + fetchAnalysisReport, + getBaseRecordPointSetByCode, + saveMeasurement, + startMeasurement, +} from "../../../services/measure/analysis"; import { createWebSocket, sharedWsUrl } from "../../../services/socket"; -import GridLayer from "./graph/GridLayer"; -import StandardLayer from "./graph/StandardLayer"; -import ResultLayer from "./graph/ResultLayer"; -import MarkLayer from "./graph/MarkLayer"; import { switchMeasureAfterSave } from "../../../store/features/contextSlice"; -import { AnalyzeAngle } from "../../../services/measure/type"; +import { AnalysisReport, AnalyzeAngle } from "../../../services/measure/type"; import { MeasureState, taskStatusDescMap } from "../../../services/wsTypes"; import { useAppDispatch, useAppSelector } from "../../../utils/hooks"; -import Gr_round from '../../../assets/green_round.svg' -import Bl_round from '../../../assets/blue_round.svg' +import Gr_round from '../../../assets/green_round.svg'; +import Bl_round from '../../../assets/blue_round.svg'; +import MeasurementCanvas, { + AnalysisData, + BenchmarkShape, + MeasurementCanvasRef, +} from "./konva/MeasurementCanvas"; + const wsClient = createWebSocket(sharedWsUrl); export default function MeasureAction() { - const dispatch = useAppDispatch(); + 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 [showGrid, setShowGrid] = useState(true); - const [showStandard, setShowStandard] = useState(true); - const [showResult, setShowResult] = useState(true); - const [showMark, setShowMark] = useState(true); + 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", + }, + ]; + const [statusList, setStatusList] = useState(initialStatusList); - const afterSave = useAppSelector(store => store.context.newMeasureAfterSave); + const onAfterSaveChange: CheckboxProps["onChange"] = (e) => { + dispatch(switchMeasureAfterSave(e.target.checked)); + }; - const navigate = useNavigate(); + const onAnalysisBtnClick = () => { + // 分析按钮只允许点击一次 + setAnalysisClicked(true); + fetchAnalysisReport("6001").then((res) => { + if (res.success) { + const report: AnalysisReport = res.data; + console.log(res.data); + // 更新 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), + describe: item.describe, + })); + canvasRef.current?.setAnalysisData(analysisData); + } + // 保存返回数据,并显示分析表格(右侧区域切换) + setAnalysisReport(report); + setShowAnalysisTable(true); + } else { + message.error("分析报告请求失败: " + res.data.info); + } + }); + }; - const [angles, setAngles] = useState([]); - const [taskStatus, setTaskStatus] = useState("IDLE"); + const onStart = () => { + // 如果按钮文本为“新测量”,则直接跳转到新测量页面 + if (startBtnText === "新测量") { + navigate("../newMeasure"); + return; + } + // 进入测量流程时恢复右侧区域为测量步骤 + setShowAnalysisTable(false); + setMeasurementFinished(false); + setAnalysisClicked(false); + setSaveClicked(false); + 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); + } else { + const newStatusList = [...initialStatusList]; + newStatusList[0].color = "b"; + setStatusList(newStatusList); + message.success("已通知设备开始测量"); + let name = taskStatusDescMap["IDLE"]; + setTaskStatusName(name); + // 测量启动成功后,按钮文本变为“重新测量” + setStartBtnText("重新测量"); + } + }); + }; - const onAfterSaveChange: CheckboxProps["onChange"] = e => { - dispatch(switchMeasureAfterSave(e.target.checked)); - }; - const onAnalysisBtnClick = () => { - // navigate("../detail"); - // if(taskStatus !== 'FINISHED'){ - // message.error('测量还未结束') - // return; - // } - const params = {//静态数据 TODO - code: 6001 - } - analysisReport(params).then(res => { - console.log('res===', res) - if (res.success) { - const angleAnalysisList = res.data.angleAnalysisList; - let angles:any = [] - angleAnalysisList && angleAnalysisList.map(item => { - const pointA = item.pointA; - angles.push({ - x: pointA.x, - y: pointA.y, - degree: item.describe, - describe: item.describe - }) - }) - setAngles(angles); - }else{ + const onSaveBtnClick = () => { + // 保存按钮只允许点击一次 + setSaveClicked(true); + saveMeasurement().then((res) => { + if (res.status !== 0) { + message.error(res.data.info); + } else { + message.success("保存成功"); + if (afterSave) { + // 勾选了保存后自动开始新测量则直接跳转 + navigate("../config"); + } else { + // 否则修改按钮文本为“新测量” + setStartBtnText("新测量"); + } + } + }); + }; - } - }) - // analyzeMeasurement().then(res => { - // if (res.success) { - // setAngles(res.data.angles); - // } else { - // message.error(res.data.info); - // } - // }); - }; + const [taskStatusName, setTaskStatusName] = useState(""); + 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 onStart = () => { - startMeasurement().then(res => { - if (res.status !== 0) { - message.error(res.data.info); - let name = taskStatusDescMap['IDLE'] - setTaskStatusName(name) - } else { - statusList[0].color = 'b'; - setStatusList(statusList) - message.success("已通知设备开始测量"); - let name = taskStatusDescMap['IDLE'] - setTaskStatusName(name) - } - }); - }; + // 处理状态变化事件 + 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); + } + setStatusList([...statusList]); + } - const onSaveBtnClick = () => { - saveMeasurement().then(res => { - if (res.status !== 0) { - message.error(res.data.info); - } else { - message.success("保存成功"); - if (afterSave) { - navigate("../config"); - } - } - }); - }; + 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]); + } + } + }); + wsClient.connect(); + return () => subscription.unsubscribe(); + }, [statusList]); - let [taskStatusName, setTaskStatusName] = useState('') - 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.isMeasuringLeftEnd && !data.data.isMeasuringRightEnd){ - console.log('这是右侧的状态===', data.data.isMeasuringRightEnd) - } - 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){//左边为true, 右边是false时表示左边已完成,右边准备 - setTaskStatusName('右侧正在测量') - }else{ - let name = taskStatusDescMap[data.data.taskStatus] - setTaskStatusName(name) - } - 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'; - }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'; - } - setStatusList(statusList) - } - }); - wsClient.connect(); - return () => subscription.unsubscribe(); - }); + // 页面加载时获取基础图形数据,并传入 MeasurementCanvas + useEffect(() => { + getBaseRecordPointSetByCode("6001").then((res) => { + if (res.success) { + const benchmarkShapes = JSON.parse(res.data.points) as BenchmarkShape[]; + if (canvasRef.current) { + console.log("解析后的基础图形数据:", benchmarkShapes); + canvasRef.current.setBenchmarkData(benchmarkShapes); + } + } + }); + }, []); - 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; - } + type StatusCodeData = { + statusCode: string; + name: string; + background: string; + isReady: boolean; + color: string; + }; - const onHandleIcon =(item:StatusCodeData, index:number)=>{ - if(item.color === 'g'){ - return - }else if(item.color === 'b'){//index > 0 && statusList[index-1].isReady - return - }else if(item.color === 'h'){ - return
- } - } + const onHandleChangeStatus = (item: StatusCodeData) => { + let backgroundColor = ""; + if (item.statusCode === "START_RECORD_LEFT") { + backgroundColor = item.background; + } + return backgroundColor; + }; - let [statusList,setStatusList] = useState([{ - 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 onHandleIcon = (item: StatusCodeData, index: number) => { + if (item.color === "g") { + return ; + } else if (item.color === "b") { + return ; + } else if (item.color === "h") { + return ( +
+ ); + } + }; - return ( -
-
-
-
- setShowGrid(checked)} /> - 参考线 -
-
- setShowStandard(checked)} /> - 标准线 -
-
- setShowResult(checked)} /> - 对比线 -
- {angles.length > 0 && ( -
- setShowMark(checked)} /> - 角度线 -
- )} -
-
- -
- -
-
- -
- {angles.length > 0 && ( -
- -
- )} -
-
-
-

测量步骤

-
- {/*
测量状态: {taskStatusDescMap[taskStatus]}
*/} - {/*
- {taskStatus !== 'FINISHED' && -
- -
{taskStatusName}
-
- } - { - taskStatus === 'FINISHED' && -
- -
{taskStatusName}
-
- } -
*/} - - - - - 保存后自动开始新测量 - -
-
- {statusList && statusList.map((item,index) => { - return
-
- {onHandleIcon(item, index)} -
{item.name}
-
-
- })} -
-
-
- ); + return ( +
+ {/* 左侧区域:包含开关区域和测量画布 */} +
+
+
+ setShowGrid(checked)} /> + 参考线 +
+
+ { + setShowStandard(checked); + if (!checked) { + // 关闭标准线时,备份当前角度线状态,并关闭角度线 + setAngleMarkBackup(showMark); + setShowMark(false); + } else { + // 打开标准线时,恢复角度线之前的状态 + setShowMark(angleMarkBackup); + } + }} + /> + 标准线 +
+
+ { + setShowMark(checked); + // 当标准线处于开启状态时,允许修改角度线状态,并更新备份状态 + setAngleMarkBackup(checked); + }} + /> + 角度线 +
+
+
+ +
+
+ {/* 右侧区域:根据 showAnalysisTable 状态决定显示测量步骤区域还是分析表格 */} +
+ {showAnalysisTable && analysisReport ? ( +
+ + + + + + + + + + + {analysisReport.angleAnalysisList.map((item, index) => ( + + + + + ))} + + + + +
W1垂直磨耗{analysisReport.w1}
轨头宽度{analysisReport.railHeadWidth}
{item.describe}{item.distance}
+ +
+
+ ) : ( +
+

测量步骤

+
+ {statusList.map((item, index) => { + return ( +
+
+ {onHandleIcon(item, index)} +
{item.name}
+
+
+ ); + })} +
+
+ + + + + 保存后自动开始新测量 + +
+
+ )} +
+
+ ); } diff --git a/src/pages/measure/components/MeasureConfig.tsx b/src/pages/measure/components/MeasureConfig.tsx index 046704b..e1396a7 100644 --- a/src/pages/measure/components/MeasureConfig.tsx +++ b/src/pages/measure/components/MeasureConfig.tsx @@ -51,8 +51,12 @@ export default function MeasureConfig() { onFinish={onFinish} // onFinishFailed={onFinishFailed} autoComplete="off"> - - + + + {/* @@ -68,21 +72,21 @@ export default function MeasureConfig() { + rules={[{ required: true, message: "请输入测量名称" }]}> + rules={[{ required: false, message: "请输入线路名称" }]}> - + - {/* + { - */} + }