You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
735 lines
23 KiB
735 lines
23 KiB
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,
|
|
updateMeasureStatus,
|
|
updateMeasureFinish,
|
|
updateShowCalibration
|
|
} 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<MeasurementCanvasRef>(null);
|
|
const [railSize, setRailSize] = useState<number | string | null>();
|
|
const iconWidth = 40;
|
|
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(() => {
|
|
// // setTimeout(() => {
|
|
// // setShowStandard(false)
|
|
// // setMeasurementCanvasKey(measurementCanvasKey + 1)
|
|
// // }, 1000)
|
|
//
|
|
// return () =>{
|
|
// console.log(111)
|
|
// setMeasurementCanvasKey(measurementCanvasKey + 1)
|
|
// }
|
|
// }, []);
|
|
|
|
|
|
|
|
// 检查轨型有没有坐标,如果有,绘制轨型基准线,如果没,拉取再绘制其线
|
|
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!);
|
|
console.log(r.points)
|
|
} else {
|
|
Toast.show(res.message);
|
|
}
|
|
});
|
|
}
|
|
}, [baseState.railTypes, dispatch, railId, measureState.measureFinishData]);
|
|
|
|
useEffect(() => {
|
|
if (canvasRef.current && measureState.measureFinishData.length) {
|
|
setTimeout(() => {
|
|
setShowStandard(true)
|
|
}, 100);
|
|
canvasRef.current?.setMeasurementCalibrationData(measureState.measureFinishData);
|
|
setShowMeasureFinish(true)
|
|
}
|
|
}, [baseState.railTypes, measureState.measureFinishData, railId]);
|
|
|
|
// 绘制测量坐标线
|
|
useEffect(() => {
|
|
if (canvasRef.current) {
|
|
canvasRef.current.setMeasurementDataLeft(measureState.leftPoints);
|
|
}
|
|
}, [measureState.leftPoints]);
|
|
|
|
useEffect(() => {
|
|
if (canvasRef.current) {
|
|
canvasRef.current.setMeasurementDataRight(measureState.rightPoints);
|
|
}
|
|
}, [measureState.rightPoints]);
|
|
|
|
// 左右两测量完成,转换后的测量线(两线合一线)
|
|
// useEffect(() => {
|
|
// const points = baseState.railTypes.find((r) => r.id === railId[0])
|
|
// console.log(1111, points)
|
|
//
|
|
// if (canvasRef.current && measureState.measureFinishData.length) {
|
|
// setTimeout(() => {
|
|
// const points = baseState.railTypes.find((r) => r.code === railId[0])?.points
|
|
// drawRailBaseLine(points || '[]')
|
|
// setShowStandard(true)
|
|
// }, 100);
|
|
// canvasRef.current?.setMeasurementCalibrationData(measureState.measureFinishData);
|
|
// // setShowCalibration(true);
|
|
// setShowMeasureFinish(true)
|
|
// setLoading(false)
|
|
//
|
|
//
|
|
// }
|
|
// }, [measureState.measureFinishData])
|
|
|
|
useEffect(() => {
|
|
if(measureState.measureStatus === 'FINISH_RECORD'){
|
|
setLoading(true)
|
|
Bridge.record().then((res) => {
|
|
if (res.success) {
|
|
dispatch(updateMeasureFinish(res.data));
|
|
} else {
|
|
dispatch(updateMeasureFinish([]));
|
|
setState({
|
|
left_ready: 'none',
|
|
right_ready: 'none',
|
|
left_begin: 'none',
|
|
right_begin: 'none',
|
|
left_end: 'none',
|
|
right_end: 'none',
|
|
});
|
|
Toast.show(res.message);
|
|
}
|
|
}).finally(() => {
|
|
setLoading(false)
|
|
})
|
|
}
|
|
}, [dispatch, measureState.measureStatus])
|
|
|
|
|
|
useEffect(() => {
|
|
return () => {
|
|
dispatch(updateMeasureStatus(''))
|
|
}
|
|
}, [dispatch])
|
|
|
|
const onSaveClick = () => {
|
|
if (!contextState.currOrgCode || !orgTextArr) {
|
|
Dialog.alert({
|
|
content: '请选择铁路局/工务段/线路',
|
|
onConfirm: () => {
|
|
onOrgBarClick();
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
dispatch(updateMeasureData(newMeasureData));
|
|
navigate('/measure/save');
|
|
};
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
const [showMeasureFinish, setShowMeasureFinish] = useState(false);
|
|
const onCalibrationBtnClick = () => {
|
|
setLoading(true);
|
|
Bridge.alignPoints({ railSize: railSize || 'GX-60' })
|
|
.then((res) => {
|
|
if (res.success) {
|
|
// setShowCalibration(true);
|
|
dispatch(updateShowCalibration(true))
|
|
canvasRef.current?.setMeasurementCalibrationData(res.data);
|
|
dispatch(updateMeasureFinish(res.data))
|
|
} else {
|
|
}
|
|
setLoading(false);
|
|
})
|
|
.catch((e) => {
|
|
setLoading(false);
|
|
Toast.show({
|
|
content: <span>服务器异常</span>,
|
|
position: 'top',
|
|
});
|
|
});
|
|
};
|
|
|
|
const [initStart, setInitStart] = useState(false);
|
|
|
|
const [measurementCanvasKey, setMeasurementCanvasKey] = useState(0);
|
|
|
|
|
|
const [state, setState] = useState({
|
|
left_ready: 'none',
|
|
right_ready: 'none',
|
|
left_begin: 'none',
|
|
right_begin: 'none',
|
|
left_end: 'none',
|
|
right_end: 'none',
|
|
});
|
|
|
|
|
|
const onStartClick = () => {
|
|
setMeasurementCanvasKey(measurementCanvasKey+1)
|
|
// setShowCalibration(false);
|
|
dispatch(updateShowCalibration(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 || !orgTextArr) {
|
|
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: '请选择',
|
|
});
|
|
console.log(value)
|
|
// Toast.show(value ? `你选择了 ${value.join(' - ')}` : '你没有进行选择');
|
|
if (value?.length) {
|
|
dispatch(updateOrg(value as string[]));
|
|
}else {
|
|
Toast.show('请选择组织机构');
|
|
}
|
|
};
|
|
|
|
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',
|
|
});
|
|
// 测量完成,显示基线
|
|
|
|
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 [style, setStyle] = useState({
|
|
left: 'none',
|
|
right: 'none',
|
|
up: 'none',
|
|
down: 'none',
|
|
left_rotation:'none',
|
|
right_rotation:'none',
|
|
});
|
|
//上下移动
|
|
let timerRef = useRef<any>(null);
|
|
const handlePressStart = (type: string) => {
|
|
setStyle({...style, [type]: 'active'})
|
|
console.log('你进行了长按操作!');
|
|
if (timerRef.current) {
|
|
return
|
|
}
|
|
timerRef.current = setInterval(() => {
|
|
console.log('111!');
|
|
onHandleMove(type);
|
|
}, 100);
|
|
console.log(timerRef.current)
|
|
};
|
|
|
|
const handlePressEnd = () => {
|
|
setStyle({
|
|
left: 'none',
|
|
right: 'none',
|
|
up: 'none',
|
|
down: 'none',
|
|
left_rotation:'none',
|
|
right_rotation:'none',
|
|
})
|
|
clearInterval(timerRef.current);
|
|
timerRef.current = null;
|
|
};
|
|
|
|
const onMoveLine = (type: string) => {
|
|
console.log('这是点击');
|
|
onHandleMove(type);
|
|
};
|
|
|
|
const onHandleMove = (type: string) => {
|
|
let list = canvasRef.current?.getMeasurementCalibrationData();
|
|
console.log(list)
|
|
if (list && list.length) {
|
|
const updatedList = list.map((item) => {
|
|
const mutableItem = { ...item }; // 创建副本
|
|
if (type === 'up') {
|
|
mutableItem.y -= distance / 1000;
|
|
} else if (type === 'down') {
|
|
mutableItem.y += distance / 1000;
|
|
} else if (type === 'left') {
|
|
mutableItem.x -= distance / 1000;
|
|
} else if (type === 'right') {
|
|
mutableItem.x += distance / 1000;
|
|
}
|
|
return mutableItem;
|
|
});
|
|
|
|
canvasRef.current?.setMeasurementCalibrationData(updatedList);
|
|
dispatch(updateMeasureFinish(list));
|
|
setNewMeasureData(updatedList);
|
|
}
|
|
};
|
|
|
|
const handleRotationPressStart = (type: string) => {
|
|
setStyle({...style, [type === 'left' ? 'left_rotation' : 'right_rotation']: 'active'})
|
|
timerRef.current = setInterval(() => {
|
|
onRotationLine(type);
|
|
}, 500);
|
|
};
|
|
|
|
//旋转
|
|
let [measurementRotation] = useState<number>(0);
|
|
let [newMeasureData, setNewMeasureData] = useState<Point[]>();
|
|
let [angle] = useState<number>(5); //角度单位 分
|
|
let [distance] = useState<number>(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) {
|
|
const updatedList = list.map((item) => {
|
|
const mutableItem = { ...item }; // 创建副本
|
|
let cloneItem = rotatePoint(mutableItem, mrValue);
|
|
mutableItem.x = cloneItem.x;
|
|
mutableItem.y = cloneItem.y;
|
|
return mutableItem;
|
|
});
|
|
|
|
canvasRef.current?.setMeasurementCalibrationData(updatedList);
|
|
dispatch(updateMeasureFinish(list));
|
|
setNewMeasureData(updatedList);
|
|
}
|
|
};
|
|
|
|
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 (
|
|
<>
|
|
<div className="relative pt-[--navBarHeight]">
|
|
<div className="absolute top-0 w-full z-10">
|
|
<CustomNavBar title={'测量'}></CustomNavBar>
|
|
</div>
|
|
|
|
<main className="home-page-content overflow-x-hidden overflow-y-auto">
|
|
<div className="relative h-0 p-0 pb-[70%]">
|
|
{/**正在校准时的loading */}
|
|
{/*loading*/}
|
|
{loading && (
|
|
<Mask opacity='thick' className="h-[100vh] flex justify-center items-center">
|
|
<div style={{ margin: '45%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
|
|
<SpinLoading color="#5c92b4" />
|
|
<span className="whitespace-nowrap mt-5 text-[#5c92b4]" style={{fontSize: '16px'}}>请稍候...</span>
|
|
</div>
|
|
</Mask>
|
|
)}
|
|
|
|
{/**测量区 */}
|
|
<div className="absolute left-0 right-0 top-0 bottom-0 bg-title">
|
|
<MeasurementCanvas
|
|
width={window.innerWidth}
|
|
height={window.innerWidth * 0.7}
|
|
logicalExtent={{ minX: -45, maxX: 45, minY: -18, maxY: 52 }}
|
|
gridStep={3}
|
|
origin={{ x: 0, y: 20 }}
|
|
pixelPerMm={window.innerWidth / 90}
|
|
maxZoom={8}
|
|
showGrid={true}
|
|
showBenchmark={showStandard}
|
|
showAnalysis={false}
|
|
showScale={false}
|
|
scaleInterval={1}
|
|
showCoordinates={false}
|
|
showCalibration={measureState.showCalibration || showMeasureFinish}
|
|
ref={canvasRef}
|
|
key={measurementCanvasKey}
|
|
/>
|
|
|
|
{/**选择轨型区 */}
|
|
{railId.length > 0 && (
|
|
<div className="absolute left-1 bottom-1">
|
|
<RailTypeBtn text={railName()} onClick={() => setRailPickerVisible(true)} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/**局段线区 */}
|
|
<section
|
|
className="h-10 bg-[#e3e8f5] flex justify-between items-center px-4"
|
|
onClick={onOrgBarClick}
|
|
>
|
|
<p className="text-text" style={{ color: contextState.currOrgCode ? '#333' : 'red' }}>
|
|
{contextState.currOrgCode && orgTextArr ? orgTextArr.join('/') : '点击此处选择铁路局和工务段'}
|
|
</p>
|
|
<span className="text-primary underline">修改</span>
|
|
</section>
|
|
{/**手动校准区 */}
|
|
{(measureState.showCalibration && measureState.measureFinishData.length>0) && (
|
|
<section className="h-10 bg-[#e3e8f5] flex justify-between items-center px-4">
|
|
<img
|
|
width={iconWidth}
|
|
src={icon_left}
|
|
onClick={() => onMoveLine('left')}
|
|
onTouchStart={() => handlePressStart('left')}
|
|
onTouchEnd={handlePressEnd}
|
|
onTouchCancel={handlePressEnd}
|
|
onContextMenu={handleContextMenu}
|
|
className={
|
|
style.left === 'active'
|
|
? 'text-[20px] ml-[5px] icon-button active-icon-button'
|
|
: 'text-[20px] ml-[5px] icon-button'
|
|
}
|
|
alt="左移"
|
|
/>
|
|
|
|
<img
|
|
width={iconWidth}
|
|
src={icon_right}
|
|
onClick={() => onMoveLine('right')}
|
|
onTouchStart={() => handlePressStart('right')}
|
|
onTouchEnd={handlePressEnd}
|
|
onTouchCancel={handlePressEnd}
|
|
onContextMenu={handleContextMenu}
|
|
className={
|
|
style.right === 'active'
|
|
? 'text-[20px] ml-[5px] icon-button active-icon-button'
|
|
: 'text-[20px] ml-[5px] icon-button'
|
|
}
|
|
alt="右移"
|
|
/>
|
|
|
|
<img
|
|
width={iconWidth}
|
|
src={icon_up}
|
|
onClick={() => onMoveLine('up')}
|
|
onTouchStart={() => handlePressStart('up')}
|
|
onTouchEnd={handlePressEnd}
|
|
onTouchCancel={handlePressEnd}
|
|
onContextMenu={handleContextMenu}
|
|
className={
|
|
style.up === 'active'
|
|
? 'text-[20px] ml-[5px] icon-button active-icon-button'
|
|
: 'text-[20px] ml-[5px] icon-button'
|
|
}
|
|
alt="上移"
|
|
/>
|
|
|
|
<img
|
|
width={iconWidth}
|
|
src={icon_down}
|
|
onClick={() => onMoveLine('down')}
|
|
onTouchStart={() => handlePressStart('down')}
|
|
onTouchEnd={handlePressEnd}
|
|
onTouchCancel={handlePressEnd}
|
|
onContextMenu={handleContextMenu}
|
|
className={
|
|
style.down === 'active'
|
|
? 'text-[20px] ml-[5px] icon-button active-icon-button'
|
|
: 'text-[20px] ml-[5px] icon-button'
|
|
}
|
|
alt="下移"
|
|
/>
|
|
|
|
<img
|
|
width={iconWidth}
|
|
src={icon_leftR}
|
|
onClick={() => onRotationLine('left')}
|
|
onTouchStart={() => handleRotationPressStart('left')}
|
|
onTouchEnd={handlePressEnd}
|
|
onTouchCancel={handlePressEnd}
|
|
onContextMenu={handleContextMenu}
|
|
className={
|
|
style.left_rotation === 'active'
|
|
? 'text-[20px] ml-[5px] icon-button active-icon-button'
|
|
: 'text-[20px] ml-[5px] icon-button'
|
|
}
|
|
alt="逆时针旋转"
|
|
/>
|
|
|
|
<img
|
|
width={iconWidth}
|
|
src={icon_rightR}
|
|
onClick={() => onRotationLine('right')}
|
|
onTouchStart={() => handleRotationPressStart('right')}
|
|
onTouchEnd={handlePressEnd}
|
|
onTouchCancel={handlePressEnd}
|
|
onContextMenu={handleContextMenu}
|
|
className={
|
|
style.right_rotation === 'active'
|
|
? 'text-[20px] ml-[5px] icon-button active-icon-button'
|
|
: 'text-[20px] ml-[5px] icon-button'
|
|
}
|
|
alt="顺时针旋转"
|
|
/>
|
|
</section>
|
|
)}
|
|
|
|
{/**按钮操作区 */}
|
|
<section className="flex items-center gap-4 px-4 my-4">
|
|
<button className="btn-contained rounded-md text-sm h-10 flex-1" onClick={onStartClick}>
|
|
{!initStart ||
|
|
(measureState.leftPoints.length > 0 && measureState.rightPoints.length > 0)
|
|
? '开始测量'
|
|
: '重新测量'}
|
|
</button>
|
|
<button
|
|
className="btn-contained rounded-md text-sm h-10 flex-1"
|
|
disabled={!measureState.measureFinishData.length}
|
|
onClick={onSaveClick}
|
|
>
|
|
保存
|
|
</button>
|
|
<button
|
|
className="btn-contained rounded-md text-sm h-10 flex-1"
|
|
disabled={!measureState.measureFinishData.length}
|
|
onClick={onCalibrationBtnClick}
|
|
>
|
|
校准
|
|
</button>
|
|
</section>
|
|
|
|
{/**测量状态区 */}
|
|
<section className="grid grid-cols-2 gap-[10px]">
|
|
<StepItem state={state.left_ready} text={'等待测量'} />
|
|
<StepItem state={state.right_ready} text={'等待测量另一侧'} />
|
|
<StepItem state={state.left_begin} text={'正在进行测量'} />
|
|
<StepItem state={state.right_begin} text={'正在进行测量'} />
|
|
<StepItem state={state.left_end} text={'一侧测量完成'} />
|
|
<StepItem state={state.right_end} text={'测量已完成'} />
|
|
</section>
|
|
</main>
|
|
</div>
|
|
<Picker
|
|
columns={[baseState.railTypes.map((t) => ({ label: t.name, value: t.id }))]}
|
|
visible={railPickerVisible}
|
|
onClose={() => {
|
|
setRailPickerVisible(false);
|
|
}}
|
|
value={railId}
|
|
onConfirm={(v) => {
|
|
onRailSizeChange(v);
|
|
}}
|
|
/>
|
|
</>
|
|
);
|
|
}
|