和算法测试成功第一步 状态界面看到经纬度信息和保存可以成功
This commit is contained in:
10
env.js
10
env.js
@@ -15,11 +15,13 @@ const envConfig = {
|
||||
//mqtt_url: "ws://1.95.137.212:8083/mqtt",
|
||||
//geoserver_url: "http://192.168.2.59:7000/geoserver"
|
||||
|
||||
baseURL: 'http://1.95.137.212:8081',//http://192.168.2.56:8081
|
||||
//baseURL: 'http://1.95.137.212:8081',//http://192.168.2.56:8081
|
||||
baseURL: 'http://192.168.2.34:8081',//http://192.168.2.56:8081
|
||||
//baseURL: 'https://serviceri.satabot.com',
|
||||
WS_URL: 'ws://1.95.137.212:9002/ws/',
|
||||
//WS_URL: 'ws://1.95.137.212:9002/ws/',
|
||||
WS_URL: 'ws://192.168.2.34:9002/ws/',
|
||||
mqtt_url: "ws://1.95.137.212:8083/mqtt",
|
||||
geoserver_url: "http://1.95.137.212:59018/geoserver"
|
||||
geoserver_url: "http://1.95.137.212:7900/geoserver"
|
||||
|
||||
//baseURL: 'http://1.95.137.212:59015',//http://192.168.2.56:8081
|
||||
////baseURL: 'https://serviceri.satabot.com',
|
||||
@@ -40,7 +42,7 @@ const envConfig = {
|
||||
//baseURL: 'https://serviceri.satabot.com',
|
||||
WS_URL: 'ws://1.95.137.212:9002/ws/',
|
||||
mqtt_url: "ws://1.95.137.212:8083/mqtt",
|
||||
geoserver_url: "http://1.95.137.212:59018/geoserver"
|
||||
geoserver_url: "http://1.95.137.212:7900/geoserver"
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -455,6 +455,15 @@ export function hasPermission(params) {
|
||||
})
|
||||
}
|
||||
|
||||
///iot/workRecord/getTaskPath?taskId=74 get 获取算法回传的路径
|
||||
export function getTaskPath(params) {
|
||||
return request({
|
||||
url: '/iot/workRecord/getTaskPath',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -344,7 +344,7 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine,
|
||||
}, [markedPoints]);
|
||||
|
||||
function showRobotTooltip(tooltip, robot, position) {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useTranslation();
|
||||
const statusMap = {
|
||||
1: { text: t('common.working'), color: "#10b981" },
|
||||
2: { text: t('devices.idle'), color: "#f59e0b" },
|
||||
@@ -498,6 +498,9 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine,
|
||||
if (index == 2 && from == "other") {
|
||||
flyToLayer(layerIdentifier, baseUrl, 100);
|
||||
}
|
||||
//if (index == 0 && from == "other") {
|
||||
// flyToLayer(layerIdentifier, baseUrl, 100);
|
||||
//}
|
||||
//getLayerBoundsAndFit(wmsUrl, layerName);
|
||||
|
||||
if (baseUrl.includes('/gwc/service/wms')) {
|
||||
@@ -1599,7 +1602,6 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine,
|
||||
|
||||
// 如果有航向角,设置旋转
|
||||
let rotation = 0;
|
||||
console.log('realtimePosition.heading:', realtimePosition.heading);
|
||||
|
||||
|
||||
if (realtimePosition?.heading !== undefined && !isNaN(Number(realtimePosition.heading))) {
|
||||
|
||||
@@ -484,7 +484,7 @@ export default function SmartDeviceManagement({
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item label={t('systemSetting.leader')} name="userId" rules={[{ required: true, message: t('systemSetting.fixed2PleaseSelectFixed2LeaderFixed2') }]}>
|
||||
<Form.Item label={t('systemSetting.leader')} name="userId" >
|
||||
<Select
|
||||
placeholder={t('systemSetting.leaderFixed2')}
|
||||
allowClear
|
||||
|
||||
@@ -95,6 +95,7 @@ export default function DeviceStatusPage() {
|
||||
const [connecting, setConnecting] = useState(false);
|
||||
const [wsStatus, setWsStatus] = useState('disconnected');
|
||||
const [wsDeviceInfo, setWsDeviceInfo] = useState({});
|
||||
const [locationInfo, setLocationInfo] = useState({});
|
||||
|
||||
|
||||
// 👇 加上这两个
|
||||
@@ -387,8 +388,9 @@ export default function DeviceStatusPage() {
|
||||
|
||||
|
||||
const runningStatus = useMemo(() => {
|
||||
console.log(locationInfo, "locationInfo")
|
||||
// 判断对象是否为空
|
||||
if ((!wsDeviceInfo || Object.keys(wsDeviceInfo).length === 0) && !isUAV) {
|
||||
if ((!wsDeviceInfo || Object.keys(wsDeviceInfo).length === 0) && (!locationInfo || Object.keys(locationInfo).length === 0) && !isUAV) {
|
||||
return {};
|
||||
}
|
||||
if (isUAV) {
|
||||
@@ -403,8 +405,10 @@ export default function DeviceStatusPage() {
|
||||
: {
|
||||
...base,
|
||||
...wsDeviceInfo,
|
||||
...locationInfo
|
||||
};
|
||||
}, [device, wsDeviceInfo, isUAV]);
|
||||
}, [device, wsDeviceInfo, isUAV, locationInfo]);
|
||||
console.log(runningStatus, "runningStatus")
|
||||
|
||||
const { video: robotVideo, error, ready } = useWebRTCPlayer(
|
||||
(!isUAV && isVideoPlaying) ? (device?.serialNumber || '') : '',
|
||||
@@ -433,8 +437,8 @@ export default function DeviceStatusPage() {
|
||||
}
|
||||
|
||||
// 2. 机器人:从 wsDeviceInfo / runningStatus 取实时经纬度
|
||||
const robotLon = runningStatus.longitude || wsDeviceInfo.longitude;
|
||||
const robotLat = runningStatus.latitude || wsDeviceInfo.latitude;
|
||||
const robotLon = runningStatus.longitude || locationInfo.longitude;
|
||||
const robotLat = runningStatus.latitude || locationInfo.latitude;
|
||||
|
||||
if (robotLon && robotLat) {
|
||||
return {
|
||||
@@ -453,6 +457,7 @@ export default function DeviceStatusPage() {
|
||||
const controller = new DeviceController(userInfo, messageApi);
|
||||
|
||||
controller.onDeviceInfoUpdate = setWsDeviceInfo;
|
||||
controller.onLocationInfoUpdate = setLocationInfo;
|
||||
controller.onControlStatusChange = setIsControlled;
|
||||
controller.onHasControlRightChange = setHasControlRight;
|
||||
controller.onRequestControlStatusChange = setConnecting;
|
||||
@@ -485,6 +490,7 @@ export default function DeviceStatusPage() {
|
||||
return;
|
||||
}
|
||||
setWsDeviceInfo({});
|
||||
setLocationInfo({});
|
||||
|
||||
controllerRef.current.connectDevice(device);
|
||||
|
||||
@@ -656,103 +662,6 @@ export default function DeviceStatusPage() {
|
||||
};
|
||||
|
||||
// 完成功能 - 调用路径规划接口
|
||||
const handleComplete = async () => {
|
||||
//如果时弓子模式
|
||||
if (isLoopMode) {
|
||||
if (markedPoints.length < 3) {
|
||||
messageApi.warning(t('devices.minThreePoints'));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 准备路径规划请求参数
|
||||
const positionPoints = [...markedPoints];
|
||||
|
||||
|
||||
const requestParams = {
|
||||
reference: {
|
||||
lat: positionPoints[0].lat,
|
||||
lon: positionPoints[0].lon,
|
||||
},
|
||||
heading: 0,
|
||||
outer: {
|
||||
position: positionPoints.map(point => ({
|
||||
lat: point.lat,
|
||||
lon: point.lon,
|
||||
})),
|
||||
sideWidth: 0.0,
|
||||
},
|
||||
holes: [],
|
||||
workType: 0,
|
||||
};
|
||||
|
||||
const response = await fetch('https://servicepathplan.satabot.com/api/path', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(requestParams),
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result) {
|
||||
const path = result?.data?.path?.map(p => {
|
||||
return {
|
||||
lng: p.lon,
|
||||
lat: p.lat
|
||||
}
|
||||
})
|
||||
setPoints(path);
|
||||
setSavePath({
|
||||
path: path, // 存储返回的路径结果
|
||||
outer: requestParams?.outer?.position?.map(p => {
|
||||
return {
|
||||
lng: p.lon,
|
||||
lat: p.lat
|
||||
}
|
||||
}
|
||||
),
|
||||
planModel: 0,
|
||||
});
|
||||
setCompleteFlag(true);
|
||||
messageApi.success(t('devices.pathPlanDone'));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('路径规划失败:', error);
|
||||
messageApi.error(t('devices.pathPlanFailRetry'));
|
||||
}
|
||||
} else {
|
||||
const positionPoints = [...markedPoints].map(item => {
|
||||
return {
|
||||
lng: item.lon,
|
||||
lat: item.lat
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
setPoints(positionPoints);
|
||||
setSavePath({
|
||||
path: positionPoints, // 存储返回的路径结果
|
||||
outer: [],
|
||||
planModel: 2,
|
||||
});
|
||||
setCompleteFlag(true);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// 打开保存模态框
|
||||
const handleOpenSaveModal = () => {
|
||||
if (!completeFlag) {
|
||||
messageApi.warning(t('devices.completePathFirst'));
|
||||
return;
|
||||
}
|
||||
setPlotName('');
|
||||
setIsSaveModalVisible(true);
|
||||
};
|
||||
|
||||
// 保存功能
|
||||
const handleSave = async () => {
|
||||
if (!plotName.trim()) {
|
||||
messageApi.warning(t('devices.inputPlotName'));
|
||||
@@ -761,6 +670,15 @@ export default function DeviceStatusPage() {
|
||||
|
||||
setIsSaving(true);
|
||||
try {
|
||||
// ✅重点:接收handleComplete返回的path数据,不再读组件savePath state
|
||||
const pathResult = await handleComplete();
|
||||
if (!pathResult) {
|
||||
messageApi.warning(t('devices.saveFail'));
|
||||
|
||||
// 路径规划失败/校验不通过直接终止
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 获取地图截图
|
||||
let screenshotDataUrl = null;
|
||||
if (mapRef.current) {
|
||||
@@ -776,18 +694,20 @@ export default function DeviceStatusPage() {
|
||||
const file = dataUrlToFile(screenshotDataUrl, "screenshot.jpg");
|
||||
console.log("blob", file)
|
||||
|
||||
|
||||
if (file instanceof File) {
|
||||
formData.append('file', file);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 添加 workRecord
|
||||
// 4. 添加 workRecord,直接使用函数返回的 pathResult,不读取state savePath
|
||||
const workRecord = {
|
||||
workName: plotName,
|
||||
siteId: stationId,
|
||||
jsonData: savePath,
|
||||
orgId: currentStation?.orgId,
|
||||
jsonData: pathResult, // 直接用返回值,彻底规避state异步延迟
|
||||
mode: isLoopMode ? "coverage" : "single_point",//"区域还是单点"
|
||||
};
|
||||
console.log("workRecord", workRecord)
|
||||
formData.append(
|
||||
"workRecord",
|
||||
new Blob([JSON.stringify(workRecord)], {
|
||||
@@ -795,8 +715,6 @@ export default function DeviceStatusPage() {
|
||||
})
|
||||
);
|
||||
|
||||
//formData.append('workRecord', JSON.stringify(workRecord));
|
||||
|
||||
// 5. 调用保存接口
|
||||
const res = await addRoute(formData);
|
||||
|
||||
@@ -818,6 +736,95 @@ export default function DeviceStatusPage() {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 修改handleComplete:计算完成后 return路径对象;失败返回null
|
||||
*/
|
||||
const handleComplete = async () => {
|
||||
//如果是闭环模式
|
||||
if (isLoopMode) {
|
||||
if (markedPoints.length < 3) {
|
||||
messageApi.warning(t('devices.minThreePoints'));
|
||||
return null; //校验失败返回null
|
||||
}
|
||||
|
||||
try {
|
||||
// 准备路径规划请求参数
|
||||
let positionPoints = [...markedPoints];
|
||||
|
||||
// =========新增:保证闭环,第一个点和最后一个点一致=========
|
||||
const firstPt = positionPoints[0];
|
||||
const lastPt = positionPoints[positionPoints.length - 1];
|
||||
// 判断经纬度是否相等,不相等就把首点追加到末尾
|
||||
if (!(firstPt.lat === lastPt.lat && firstPt.lon === lastPt.lon)) {
|
||||
positionPoints.push({ ...firstPt });
|
||||
}
|
||||
|
||||
const requestParams = {
|
||||
outer: {
|
||||
position: positionPoints.map(point => ({
|
||||
lat: point.lat,
|
||||
lng: point.lon,
|
||||
})),
|
||||
},
|
||||
};
|
||||
|
||||
const path = requestParams?.outer?.position
|
||||
setPoints(path);
|
||||
|
||||
const resultObj = {
|
||||
path: path,
|
||||
outer: requestParams?.outer?.position?.map(p => {
|
||||
return {
|
||||
lng: p.lon,
|
||||
lat: p.lat
|
||||
}
|
||||
}),
|
||||
};
|
||||
|
||||
setSavePath(resultObj);
|
||||
setCompleteFlag(true);
|
||||
messageApi.success(t('devices.pathPlanDone'));
|
||||
return resultObj; // ✅返回计算好的数据给上层调用
|
||||
} catch (error) {
|
||||
console.error('路径规划失败:', error);
|
||||
messageApi.error(t('devices.pathPlanFailRetry'));
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// 单点模式
|
||||
const positionPoints = [...markedPoints].map(item => {
|
||||
return {
|
||||
lng: item.lon,
|
||||
lat: item.lat
|
||||
}
|
||||
});
|
||||
|
||||
setPoints(positionPoints);
|
||||
|
||||
const resultObj = {
|
||||
path: positionPoints,
|
||||
outer: [],
|
||||
};
|
||||
setSavePath(resultObj);
|
||||
setCompleteFlag(true);
|
||||
|
||||
return resultObj; // ✅返回
|
||||
}
|
||||
};
|
||||
|
||||
// 打开保存模态框
|
||||
const handleOpenSaveModal = () => {
|
||||
//if (!completeFlag) {
|
||||
// messageApi.warning(t('devices.completePathFirst'));
|
||||
// return;
|
||||
//}
|
||||
setPlotName('');
|
||||
setIsSaveModalVisible(true);
|
||||
};
|
||||
|
||||
|
||||
|
||||
const realtimeType = useMemo(() => {
|
||||
return isUAV ? 'plane' : 'car';
|
||||
}, [isUAV]);
|
||||
@@ -856,8 +863,8 @@ export default function DeviceStatusPage() {
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||
<Text strong>{t('devices.pathPlanning')}:</Text>
|
||||
<Text type="secondary">{t('devices.markedPointsCount', { count: markedPoints.length })}</Text>
|
||||
<Text strong>{t('devices.pathPlanning')}:</Text>
|
||||
<Text type="secondary">{t('devices.markedPointsCount', { count: markedPoints.length })}</Text>
|
||||
</div>
|
||||
<Space size="middle">
|
||||
<Space>
|
||||
@@ -882,18 +889,18 @@ export default function DeviceStatusPage() {
|
||||
>
|
||||
{t('devices.clearMarks')}
|
||||
</Button>
|
||||
<Button
|
||||
{/*<Button
|
||||
type="primary"
|
||||
ghost
|
||||
onClick={handleComplete}
|
||||
disabled={markedPoints.length < 2}
|
||||
>
|
||||
{t('devices.complete')}
|
||||
</Button>
|
||||
</Button>*/}
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={handleOpenSaveModal}
|
||||
disabled={!completeFlag}
|
||||
//disabled={!completeFlag}
|
||||
>
|
||||
{t('common.save')}
|
||||
</Button>
|
||||
@@ -961,7 +968,7 @@ export default function DeviceStatusPage() {
|
||||
title={
|
||||
<>
|
||||
<VideoCameraOutlined />
|
||||
{t('devices.stationVideo')}
|
||||
{t('devices.stationVideo')}
|
||||
</>
|
||||
}
|
||||
bordered={false}
|
||||
@@ -1039,7 +1046,7 @@ export default function DeviceStatusPage() {
|
||||
title={
|
||||
<>
|
||||
<VideoCameraOutlined />
|
||||
{t('devices.droneVideo')}
|
||||
{t('devices.droneVideo')}
|
||||
</>
|
||||
}
|
||||
bordered={false}
|
||||
@@ -1103,33 +1110,33 @@ export default function DeviceStatusPage() {
|
||||
}}>
|
||||
<div style={{ marginBottom: 6, fontWeight: 600, color: '#1890ff' }}>{t('devices.robotStatus')}</div>
|
||||
<div style={{ display: 'flex', gap: '3px 10px', flexWrap: 'wrap' }}>
|
||||
<span>{t('devices.rtBattery')}</span>
|
||||
<span>{t('devices.rtBattery')}:</span>
|
||||
<span style={{ color: (runningStatus.battery || 0) < 20 ? '#ff4d4f' : '#52c41a' }}>
|
||||
{runningStatus.battery !== undefined ? `${runningStatus.battery}%` : '-'}
|
||||
</span>
|
||||
<span>{t('devices.rtVoltage')}</span>
|
||||
<span>{t('devices.rtVoltage')}:</span>
|
||||
<span>{runningStatus.voltage !== undefined ? `${Number(runningStatus.voltage).toFixed(2)}V` : '-'}</span>
|
||||
<span>{t('devices.rtLeftMotor')}</span>
|
||||
<span>{t('devices.rtLeftMotor')}:</span>
|
||||
<span>{runningStatus.leftCurrent !== undefined ? `${Number(runningStatus.leftCurrent).toFixed(2)}A` : '-'}</span>
|
||||
<span>{t('devices.rtRightMotor')}</span>
|
||||
<span>{t('devices.rtRightMotor')}:</span>
|
||||
<span>{runningStatus.rightCurrent !== undefined ? `${Number(runningStatus.rightCurrent).toFixed(2)}A` : '-'}</span>
|
||||
<span>{t('devices.rtLeftSpeed')}</span>
|
||||
<span>{t('devices.rtLeftSpeed')}:</span>
|
||||
<span>{runningStatus.leftMeasureSpeed !== undefined ? `${Number(runningStatus.leftMeasureSpeed).toFixed(1)}rpm` : '-'}</span>
|
||||
<span>{t('devices.rtRightSpeed')}</span>
|
||||
<span>{t('devices.rtRightSpeed')}:</span>
|
||||
<span>{runningStatus.rightMeasureSpeed !== undefined ? `${Number(runningStatus.rightMeasureSpeed).toFixed(1)}rpm` : '-'}</span>
|
||||
<span>{t('devices.rtLeftTemp')}</span>
|
||||
<span>{t('devices.rtLeftTemp')}:</span>
|
||||
<span>{runningStatus.leftMotorTemp !== undefined ? `${Number(runningStatus.leftMotorTemp).toFixed(1)}℃` : '-'}</span>
|
||||
<span>{t('devices.rtRightTemp')}</span>
|
||||
<span>{t('devices.rtRightTemp')}:</span>
|
||||
<span>{runningStatus.rightMotorTemp !== undefined ? `${Number(runningStatus.rightMotorTemp).toFixed(1)}℃` : '-'}</span>
|
||||
<span>{t('devices.rtMainTemp')}</span>
|
||||
<span>{t('devices.rtMainTemp')}:</span>
|
||||
<span>{runningStatus.chipTemp !== undefined ? `${Number(runningStatus.chipTemp).toFixed(1)}℃` : '-'}</span>
|
||||
<span>{t('devices.rtHeadingAngle')}</span>
|
||||
<span>{t('devices.rtHeadingAngle')}:</span>
|
||||
<span>{runningStatus.yaw !== undefined ? `${Number(runningStatus.yaw).toFixed(1)}°` : '-'}</span>
|
||||
<span>{t('devices.rtPitchAngle')}</span>
|
||||
<span>{t('devices.rtPitchAngle')}:</span>
|
||||
<span>{runningStatus.pitch !== undefined ? `${Number(runningStatus.pitch).toFixed(1)}°` : '-'}</span>
|
||||
<span>{t('devices.rtHeadingStatus')}</span>
|
||||
<span>{t('devices.rtHeadingStatus')}:</span>
|
||||
<span>{runningStatus.headingStatus !== undefined ? `${runningStatus.headingStatus == 1 ? t('devices.rtInitialized') : t('devices.uninitialized')}` : '-'}</span>
|
||||
<span>{t('devices.rtPositioning')}</span>
|
||||
<span>{t('devices.rtPositioning')}:</span>
|
||||
<span>
|
||||
{runningStatus.qual == 0 ? t('constants.locationInvalid') :
|
||||
runningStatus.qual == 1 ? t('devices.gpsSingle') :
|
||||
@@ -1137,9 +1144,9 @@ export default function DeviceStatusPage() {
|
||||
runningStatus.qual == 4 ? t('devices.rtkFixed2') :
|
||||
runningStatus.qual == 5 ? t('devices.rtkFloat') : t('constants.locationUnknown')}
|
||||
</span>
|
||||
<span>{t('devices.rtSatellites')}</span>
|
||||
<span>{t('devices.rtSatellites')}:</span>
|
||||
<span>{t('devices.satelliteCount', { count: runningStatus.satelliteCnt || 0 })}</span>
|
||||
<span>{t('devices.rtMode')}</span>
|
||||
<span>{t('devices.rtMode')}:</span>
|
||||
<span>
|
||||
{runningStatus.controlMode == 1 ? t('devices.localMode') :
|
||||
runningStatus.controlMode == 3 ? t('devices.remoteMode') : t('constants.locationUnknown')}
|
||||
@@ -1322,7 +1329,7 @@ export default function DeviceStatusPage() {
|
||||
title={
|
||||
<>
|
||||
<ControlOutlined />
|
||||
{t('devices.remoteControl')}
|
||||
{t('devices.remoteControl')}
|
||||
</>
|
||||
}
|
||||
bordered={false}
|
||||
|
||||
@@ -5,7 +5,8 @@ import {
|
||||
Modal, InputNumber,
|
||||
TimePicker,
|
||||
Popconfirm,
|
||||
App
|
||||
App,
|
||||
Radio
|
||||
} from 'antd';
|
||||
import {
|
||||
PlusOutlined, ImportOutlined, NodeIndexOutlined,
|
||||
@@ -35,6 +36,7 @@ import {
|
||||
getSiteDeviceTaskHistory,
|
||||
getRouteByTask,
|
||||
deleteRoute,
|
||||
getTaskPath,
|
||||
} from '../../api/device';
|
||||
import dayjs from 'dayjs';
|
||||
import DraggableBox from '../Draggable';
|
||||
@@ -116,6 +118,8 @@ export default function RobotTaskPage() {
|
||||
robot: null,
|
||||
dateRange: null,
|
||||
});
|
||||
// 取消任务模式 normal普通取消 force强制取消
|
||||
const [cancelMode, setCancelMode] = useState<'normal' | 'force'>('normal');
|
||||
|
||||
|
||||
|
||||
@@ -244,7 +248,7 @@ export default function RobotTaskPage() {
|
||||
useEffect(() => {
|
||||
const controller = new DeviceController(userInfo, messageApi);
|
||||
|
||||
controller.onDeviceInfoUpdate = setRobotRealtimePosition;
|
||||
controller.onLocationInfoUpdate = setRobotRealtimePosition;
|
||||
controller.onIsFinished = handleFinish;
|
||||
controller.handleArrivedPoint = handleFinishEdPoint;
|
||||
|
||||
@@ -394,22 +398,14 @@ export default function RobotTaskPage() {
|
||||
// 调用接口获取路线详情
|
||||
const fetchRouteDetail = async () => {
|
||||
try {
|
||||
const res = await getSingleRouteList({ id: selectedPathWork.id });
|
||||
const res = await getTaskPath({ taskId: selectedPathWork.id })
|
||||
//const res = await getSingleRouteList({ id: selectedPathWork.id });
|
||||
if (res?.code === 200 && res?.data) {
|
||||
let pathPoints = [];
|
||||
let outerPoints = [];
|
||||
let method = '';//0弓子 2 回子
|
||||
|
||||
try {
|
||||
// 尝试解析 JSON
|
||||
if (res.data.jsonData) {
|
||||
const data = typeof res.data.jsonData === 'string'
|
||||
? JSON.parse(res.data.jsonData)
|
||||
: res.data.jsonData;
|
||||
pathPoints = data?.path || [];
|
||||
outerPoints = data?.outer || [];
|
||||
method = data?.planModel;
|
||||
|
||||
}
|
||||
pathPoints = res.data || [];
|
||||
} catch (err) {
|
||||
console.error('解析路线数据失败:', err);
|
||||
}
|
||||
@@ -417,15 +413,9 @@ export default function RobotTaskPage() {
|
||||
if (pathPoints.length === 0) {
|
||||
utils.message.warning(t('devices.route2'));
|
||||
}
|
||||
//if (outerPoints.length === 0 && method == 2) {
|
||||
// utils.message.warning(t('devices.route2'));
|
||||
//}
|
||||
//if (method == 0) {
|
||||
setPoints(pathPoints);
|
||||
//} else {
|
||||
// setPoints(outerPoints);
|
||||
|
||||
//}
|
||||
setPoints(pathPoints);
|
||||
|
||||
} else {
|
||||
setPoints([]);
|
||||
}
|
||||
@@ -653,13 +643,14 @@ export default function RobotTaskPage() {
|
||||
};
|
||||
|
||||
// 取消任务
|
||||
const handleCancelTask = async (task) => {
|
||||
const handleCancelTask = async (task, mode) => {
|
||||
try {
|
||||
const params = {
|
||||
taskId: task.id,
|
||||
//deviceId: task.deviceId,
|
||||
siteId: stationId,
|
||||
orgId: task.orgId,
|
||||
forceCancel: mode === 'force' ? true : false,
|
||||
};
|
||||
const res = await cancelRoute(params);
|
||||
if (res.code === 200 && res.data == true) {
|
||||
@@ -832,15 +823,17 @@ export default function RobotTaskPage() {
|
||||
dataIndex: 'taskStaus',
|
||||
width: 100,
|
||||
render: (status, record) => {
|
||||
console.log('status', status, record);
|
||||
const statusMap = {
|
||||
'NEW': { color: 'default', text: t('devices.statusNew') },
|
||||
'EXECUTING': { color: 'processing', text: t('workOrder.inProgress') },
|
||||
'PAUSE': { color: 'warning', text: t('devices.statusPaused') },
|
||||
'FINISH': { color: 'success', text: t('devices.statusFinished') },
|
||||
'FAILED': { color: 'error', text: t('devices.statusFailed') }
|
||||
'FAILED': { color: 'error', text: t('devices.statusFailed') },
|
||||
"CANCELING": { color: 'warning', text: t('devices.statusCanceling') },
|
||||
};
|
||||
const item = statusMap[status] || { color: 'default', text: record.taskStausTranslate || t('constants.locationUnknown') };
|
||||
return <Tag color={item.color}>{item.text}</Tag>;
|
||||
return <Tag color={item.color}>{record.taskStausTranslate}</Tag>;
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -889,7 +882,8 @@ export default function RobotTaskPage() {
|
||||
'EXECUTING': { color: 'processing', text: t('workOrder.inProgress') },
|
||||
'PAUSE': { color: 'warning', text: t('devices.statusPaused') },
|
||||
'FINISH': { color: 'success', text: t('devices.statusFinished') },
|
||||
'FAILED': { color: 'error', text: t('devices.statusFailed') }
|
||||
'FAILED': { color: 'error', text: t('devices.statusFailed') },
|
||||
"CANCELING": { color: 'warning', text: t('devices.statusCanceling') },
|
||||
};
|
||||
const item = statusMap[status] || { color: 'default', text: t('constants.locationUnknown') };
|
||||
return <Tag color={item.color}>{item.text}</Tag>;
|
||||
@@ -909,27 +903,46 @@ export default function RobotTaskPage() {
|
||||
|
||||
<>
|
||||
{/*{record.taskStaus === 'NEW' && (*/}
|
||||
<Popconfirm
|
||||
title={t('devices.confirmCancelTask')}
|
||||
onConfirm={() => handleCancelTask(record)}
|
||||
okText={t('common.ok')} cancelText={t('common.cancel')}
|
||||
>
|
||||
<Button type="text" size="small" danger icon={<CloseOutlined />} onClick={(e) => e.stopPropagation()}>
|
||||
{t('common.cancel')}
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
<Popconfirm
|
||||
title={t('devices.confirmCancelTask')}
|
||||
description={
|
||||
<Radio.Group
|
||||
value={cancelMode}
|
||||
onChange={(e) => setCancelMode(e.target.value)}
|
||||
style={{ marginTop: 8 }}
|
||||
>
|
||||
<Space direction="vertical">
|
||||
<Radio value="normal">{t('devices.normalCancel')}</Radio>
|
||||
<Radio value="force">{t('devices.forceCancel')}</Radio>
|
||||
</Space>
|
||||
</Radio.Group>
|
||||
}
|
||||
onConfirm={() => handleCancelTask(record, cancelMode)}
|
||||
okText={t('common.ok')}
|
||||
cancelText={t('common.cancel')}
|
||||
>
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
danger
|
||||
icon={<CloseOutlined />}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{t('common.cancel')}
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
{/*//)}*/}
|
||||
|
||||
{/*{record.taskStaus === 'EXECUTING' && (*/}
|
||||
<Popconfirm
|
||||
title={t('devices.confirmPauseTask')}
|
||||
onConfirm={() => handlePauseTask(record)}
|
||||
okText={t('common.ok')} cancelText={t('common.cancel')}
|
||||
>
|
||||
<Button type="text" size="small" style={{ color: '#FF9500' }} onClick={(e) => e.stopPropagation()}>
|
||||
{t('video.pause')}
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
<Popconfirm
|
||||
title={t('devices.confirmPauseTask')}
|
||||
onConfirm={() => handlePauseTask(record)}
|
||||
okText={t('common.ok')} cancelText={t('common.cancel')}
|
||||
>
|
||||
<Button type="text" size="small" style={{ color: '#FF9500' }} onClick={(e) => e.stopPropagation()}>
|
||||
{t('video.pause')}
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
{/*)}/*/}
|
||||
|
||||
{record.taskStaus === 'PAUSE' && (
|
||||
|
||||
@@ -27,11 +27,14 @@ export default class DeviceController {
|
||||
|
||||
this.wsStatus = 'disconnected';
|
||||
this.wsDeviceInfo = {};
|
||||
this.locationInfo = {};
|
||||
|
||||
this.controlTimeout = null;
|
||||
this.keepAliveInterval = null; // 后台保活定时器
|
||||
|
||||
this.onDeviceInfoUpdate = null;
|
||||
this.onLocationInfoUpdate = null;
|
||||
|
||||
this.onControlStatusChange = null;
|
||||
this.onWsStatusChange = null;
|
||||
this.onHasControlRightChange = null;
|
||||
@@ -156,6 +159,7 @@ export default class DeviceController {
|
||||
|
||||
this.connectedDeviceSn = null;
|
||||
this.wsDeviceInfo = {};
|
||||
this.locationInfo = {};
|
||||
this.isControlled = false;
|
||||
this.onControlStatusChange?.(false);
|
||||
|
||||
@@ -263,6 +267,15 @@ export default class DeviceController {
|
||||
this.onDeviceInfoUpdate?.(data);
|
||||
break;
|
||||
}
|
||||
case 'locationInfo': {
|
||||
const data = {};
|
||||
msg.data.forEach((item) => {
|
||||
data[item.name] = item.value;
|
||||
});
|
||||
this.locationInfo = data;
|
||||
this.onLocationInfoUpdate?.(data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'AUTH': {
|
||||
if (msg.isAuth) {
|
||||
|
||||
@@ -989,6 +989,10 @@ const en = {
|
||||
working: 'Working',
|
||||
workingCurrent: 'Working Current',
|
||||
zoomLens: 'Zoom Lens',
|
||||
controllerNotConnected: "controllerNotConnected",
|
||||
otherWebConnected: "otherWebConnected",
|
||||
clickToRequestControl: "clickToRequestControl",
|
||||
control2: "connecting",
|
||||
|
||||
fixed2TaskSuspended2: 'Fixed2 Task Suspended2 态势',
|
||||
|
||||
|
||||
@@ -558,6 +558,13 @@ const zh = {
|
||||
fillRequiredFields: '填写必填字段',
|
||||
firmwareVersion: '固件版本',
|
||||
fixed: '固定',
|
||||
controllerNotConnected: "控制器未连接",
|
||||
otherWebConnected: "其他网页已连接",
|
||||
clickToRequestControl: "点击请求控制",
|
||||
control2: "已连接",
|
||||
|
||||
controlling: "控制中",
|
||||
|
||||
fixed2: '',
|
||||
fixedEnv: '固定环境',
|
||||
flightAltitude: '飞行高度',
|
||||
|
||||
Reference in New Issue
Block a user