import StepItem from '../components/StepItem'; import { useNavigate } from 'react-router-dom'; import CustomNavBar from '../components/CustomNavBar'; import MeasurementCanvas, { BenchmarkShape, MeasurementCanvasRef, Point, } from '../components/konva/MeasurementCanvas'; import { useEffect, useRef, useState } from 'react'; import RailTypeBtn from '../components/RailTypeBtn'; import { Cascader, Dialog, Mask, Picker, SpinLoading, Toast } from 'antd-mobile'; import { useAppDispatch, useAppSelector } from '../utils/hooks'; import { updateMeasureData, updateTaskState } from '../store/features/measureSlice'; import Bridge from '../utils/bridge'; import { selectLabeledKtjOrgs, updateRailPoints } from '../store/features/baseData'; import { updateOrg } from '../store/features/contextSlice'; import { selectOrgTextArr } from '../store'; import icon_left from '../assets/icon_left.svg'; import icon_right from '../assets/icon_right.svg'; import icon_up from '../assets/icon_up.svg'; import icon_down from '../assets/icon_down.svg'; import icon_leftR from '../assets/icon_leftR.svg'; import icon_rightR from '../assets/icon_rightR.svg'; export default function Measure() { const navigate = useNavigate(); const dispatch = useAppDispatch(); const labeledKtjOrgs = useAppSelector(selectLabeledKtjOrgs); const orgTextArr = useAppSelector(selectOrgTextArr); const measureState = useAppSelector((state) => state.measure); const contextState = useAppSelector((state) => state.context); const baseState = useAppSelector((state) => state.baseData); const [railPickerVisible, setRailPickerVisible] = useState(false); const [railId, setRailId] = useState<(number | string | null)[]>([]); const canvasRef = useRef(null); const [railSize, setRailSize] = useState(); const iconWidth = 35; const [showStandard, setShowStandard] = useState(false); // 默认选中第一个轨型 useEffect(() => { if (baseState.railTypes.length > 0) { let railData = baseState.railTypes[0]; setRailId([railData.id]); setRailSize(railData.code); } }, [baseState.railTypes]); function drawRailBaseLine(points: string) { const benchmarkShapes = JSON.parse(points) as BenchmarkShape[]; if (canvasRef.current) { canvasRef.current.setBenchmarkData(benchmarkShapes); } } // 检查轨型有没有坐标,如果有,绘制轨型基准线,如果没,拉取再绘制其线 useEffect(() => { if (railId.length > 0) { const r = baseState.railTypes.find((rail) => rail.id === railId[0]); if (!r) return; if (!!r.points) { drawRailBaseLine(r.points); return; } Bridge.getTrackPoint({ code: r.code }).then((res) => { if (res.success) { dispatch(updateRailPoints(res.data)); drawRailBaseLine(res.data.points!); } else { Toast.show(res.message); } }); } }, [baseState.railTypes, dispatch, railId]); // 绘制测量坐标线 useEffect(() => { if (canvasRef.current) { canvasRef.current.setMeasurementDataLeft(measureState.leftPoints); } }, [measureState.leftPoints]); useEffect(() => { if (canvasRef.current) { canvasRef.current.setMeasurementDataRight(measureState.rightPoints); } }, [measureState.rightPoints]); // 左右两测量完成,转换后的测量线(两线合一线) useEffect(() => { if (canvasRef.current && measureState.measureFinishData.length) { canvasRef.current?.setMeasurementCalibrationData(measureState.measureFinishData); // setshowCalibration(true); setShowMeasureFinish(true) setCaloading(false) } }, [measureState.measureFinishData]) useEffect(() => { if(measureState.measureStatus === 'FINISH_RECORD'){ setCaloading(true) } else { setCaloading(false) } }, [measureState.measureStatus]) const onSaveClick = () => { dispatch(updateMeasureData(newMeasureData)); navigate('/measure/save'); }; const [caloading, setCaloading] = useState(false); const [showCalibration, setshowCalibration] = useState(false); const [showMeasureFinish, setShowMeasureFinish] = useState(false); const onCalibrationBtnClick = () => { setCaloading(true); Bridge.alignPoints({ railSize: railSize || 'GX-60' }) .then((res) => { if (res.success) { setshowCalibration(true); canvasRef.current?.setMeasurementCalibrationData(res.data); } else { } setCaloading(false); }) .catch((e) => { setCaloading(false); Toast.show({ content: 服务器异常, position: 'top', }); }); }; const [initStart, setInitStart] = useState(false); const onStartClick = () => { setshowCalibration(false); setShowMeasureFinish(false) dispatch(updateMeasureData([])); if (!contextState.device.connected) { Dialog.alert({ content: '蓝牙未连接,请先连接蓝牙', onConfirm: () => { navigate('/home/bluetooth'); }, }); return; } if (baseState.ktjOrgs.length === 0) { Dialog.alert({ content: '请在基础数据同步完成后重试', onConfirm: () => { navigate('/home/mine'); }, }); return; } if (!contextState.currOrgCode) { Dialog.alert({ content: '请选择铁路局/工务段/线路', onConfirm: () => { onOrgBarClick(); }, }); return; } // if (contextState.device.power < 20) { // Toast.show("电量低于20%,请充电后测量"); // return; // } Bridge.startMeasure().then((res) => { if (res.success) { dispatch(updateTaskState('START_RECORD_SIG')); } else { Toast.show(res.message); } setInitStart(true); setShowStandard(false) }); }; const onOrgBarClick = async () => { if (baseState.ktjOrgs.length === 0) { Dialog.alert({ content: '请在基础数据同步完成后重试', onConfirm: () => { navigate('/home/mine'); }, }); return; } const value = await Cascader.prompt({ options: labeledKtjOrgs, placeholder: '请选择', }); // Toast.show(value ? `你选择了 ${value.join(' - ')}` : '你没有进行选择'); if (value) { dispatch(updateOrg(value as string[])); } }; const [state, setState] = useState({ left_ready: 'none', right_ready: 'none', left_begin: 'none', right_begin: 'none', left_end: 'none', right_end: 'none', }); const [status, setStatus] = useState(0) useEffect(() => { console.log(measureState.taskState) switch (measureState.taskState) { case 'WAITING_FOR_RECORD_THE_1ST_SIDE': setStatus(1); setState({ left_ready: 'ongoing', right_ready: 'none', left_begin: 'none', right_begin: 'none', left_end: 'none', right_end: 'none', }); break; case 'WAITING_FOR_RECORD_THE_2ND_SIDE': setStatus(2) break; case 'START_RECORD_SIG': setState({ left_ready: 'ongoing', right_ready: 'none', left_begin: 'none', right_begin: 'none', left_end: 'none', right_end: 'none', }); break; case 'START_RECORD_LEFT': case 'START_RECORD_RIGHT': if (status === 1) { setState({ left_ready: 'done', right_ready: 'none', left_begin: 'ongoing', right_begin: 'none', left_end: 'none', right_end: 'none', }); } else if (status === 2) { setState({ left_ready: 'done', right_ready: 'done', left_begin: 'done', right_begin: 'ongoing', left_end: 'done', right_end: 'none', }); } break; case 'FINISH_RECORD_LEFT': case 'FINISH_RECORD_RIGHT': if (status === 1) { setState({ left_ready: 'done', right_ready: 'none', left_begin: 'done', right_begin: 'none', left_end: 'done', right_end: 'none', }); } else if (status === 2) { setState({ left_ready: 'done', right_ready: 'done', left_begin: 'done', right_begin: 'done', left_end: 'done', right_end: 'done', }); } break; case 'FINISH_RECORD': setState({ left_ready: 'done', right_ready: 'done', left_begin: 'done', right_begin: 'done', left_end: 'done', right_end: 'done', }); // 测量完成,显示基线 setShowStandard(true) break; default: setState({ left_ready: 'none', right_ready: 'none', left_begin: 'none', right_begin: 'none', left_end: 'none', right_end: 'none', }); } }, [measureState.taskState, status]); function railName() { return baseState.railTypes.find((r) => r.id === railId[0])?.name || ''; } function onRailSizeChange(ids: (number | string | null)[]) { if (ids && ids.length) { setRailId(ids); let id = ids[0]; const codes = baseState.railTypes.map((item) => { if (item.id === id) { return item.code; } return item.code; }); if (codes && codes.length) { setRailSize(codes[0]); } } } //上下移动 const timerRef = useRef(null); const handlePressStart = (type: string) => { timerRef.current = setInterval(() => { console.log('你进行了长按操作!'); onHandleMove(type); }, 500); }; const handlePressEnd = () => { if (timerRef.current) { clearInterval(timerRef.current); timerRef.current = null; } }; const onMoveLine = (type: string) => { console.log('这是点击'); onHandleMove(type); }; const onHandleMove = (type: string) => { let list = canvasRef.current?.getMeasurementCalibrationData(); if (list && list.length) { list.forEach((item) => { if (type === 'up') { //向上移动,原数据减y X轴不动 item.y = item.y - distance / 1000; } if (type === 'down') { //向上移动,原数据加y X轴不动 item.y = item.y + distance / 1000; } if (type === 'left') { //向左移动,原数据减x Y轴不动 item.x = item.x - distance / 1000; } if (type === 'right') { //向右移动,原数据加x Y轴不动 item.x = item.x + distance / 1000; } }); canvasRef.current?.setMeasurementCalibrationData(list); setNewMeasureData(list); } }; const handleRotationPressStart = (type: string) => { timerRef.current = setInterval(() => { onRotationLine(type); }, 500); }; //旋转 let [measurementRotation] = useState(0); let [newMeasureData, setNewMeasureData] = useState(); let [angle] = useState(5); //角度单位 分 let [distance] = useState(100); const onRotationLine = (type: string) => { let mrValue = 0; if (type === 'left') { //逆时针 mrValue = measurementRotation - ((angle / 60) * Math.PI) / 180; } if (type === 'right') { //顺时针 mrValue = measurementRotation + ((angle / 60) * Math.PI) / 180; } let list = canvasRef.current?.getMeasurementCalibrationData(); if (list && list.length) { list.forEach((item, index) => { let cloneItem = rotatePoint(item, mrValue); item.x = cloneItem.x; item.y = cloneItem.y; }); canvasRef.current?.setMeasurementCalibrationData(list); setNewMeasureData(list); } }; const rotatePoint = (pt: { x: number; y: number }, angle: number) => { const item = { x: pt.x * Math.cos(angle) - pt.y * Math.sin(angle), y: pt.x * Math.sin(angle) + pt.y * Math.cos(angle), }; return item; }; const handleContextMenu = (e: any) => { e.preventDefault(); }; return ( <>
{/**正在校准时的loading */} {caloading && (
正在转换...
)} {/**测量区 */}
{/**选择轨型区 */} {railId.length > 0 && (
setRailPickerVisible(true)} />
)}
{/**局段线区 */}

{contextState.currOrgCode ? orgTextArr.join('/') : '点击此处选择铁路局和工务段'}

修改
{/**手动校准区 */} {showCalibration && (
onMoveLine('left')} onTouchStart={() => handlePressStart('left')} onTouchEnd={handlePressEnd} onContextMenu={handleContextMenu} className="text-[20px] ml-[5px]" alt="左移" /> onMoveLine('right')} onTouchStart={() => handlePressStart('right')} onTouchEnd={handlePressEnd} onContextMenu={handleContextMenu} className="text-[20px] ml-[5px]" alt="右移" /> onMoveLine('up')} onTouchStart={() => handlePressStart('up')} onTouchEnd={handlePressEnd} onContextMenu={handleContextMenu} className="text-[20px] ml-[5px]" alt="上移" /> onMoveLine('down')} onTouchStart={() => handlePressStart('down')} onTouchEnd={handlePressEnd} onContextMenu={handleContextMenu} className="text-[20px] ml-[5px]" alt="下移" /> onRotationLine('left')} onTouchStart={() => handleRotationPressStart('left')} onTouchEnd={handlePressEnd} onContextMenu={handleContextMenu} className="text-[20px] ml-[5px]" alt="逆时针旋转" /> onRotationLine('right')} onTouchStart={() => handleRotationPressStart('right')} onTouchEnd={handlePressEnd} onContextMenu={handleContextMenu} className="text-[20px] ml-[5px]" alt="顺时针旋转" />
)} {/**按钮操作区 */}
{/**测量状态区 */}
({ label: t.name, value: t.id }))]} visible={railPickerVisible} onClose={() => { setRailPickerVisible(false); }} value={railId} onConfirm={(v) => { onRailSizeChange(v); }} /> ); }