优化任务完成之后 的显示 优化实时监控界面的显示逻辑

This commit is contained in:
mmc
2026-09-11 08:48:27 +08:00
parent cb00ed4a9e
commit 4a47177e47
5 changed files with 216 additions and 185 deletions

View File

@@ -1677,14 +1677,37 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine,
handler.setInputAction((movement) => {
const picked = viewer.scene.pick(movement.position);
if (window.Cesium.defined(picked) && picked.id?.properties?.robot) {
const robot = picked.id.properties.robot.getValue();
robot.feStatus == 1 && onCameraClickRef.current?.(robot);
}
}, window.Cesium.ScreenSpaceEventType.LEFT_CLICK);
// ========= 增加防护,直接拦截 movement.position undefined =========
if (!movement || !movement.position) return;
handler.setInputAction((movement) => {
const picked = viewer.scene.pick(movement.position);
let robot = null;
if (window.Cesium.defined(picked) && picked.id) {
const robotProp = picked.id.properties?.robot;
robot = robotProp ? (typeof robotProp.getValue === "function" ? robotProp.getValue() : robotProp) : (picked.id.robotData || null);
if (!robot) {
const pickedCarto = viewer.scene.globe.pick(movement.position, viewer.scene);
if (window.Cesium.defined(pickedCarto)) {
const clon = window.Cesium.Math.toDegrees(pickedCarto.longitude);
const clat = window.Cesium.Math.toDegrees(pickedCarto.latitude);
let best = null;
let bestDist = 0.002;
devices.forEach(d => {
const raw = d?.locationMessage || d?.lastRunningStatus || {};
const dlon = Number(raw.longitude);
const dlat = Number(raw.latitude);
if (!isFinite(dlon) || !isFinite(dlat)) return;
const dist = Math.hypot(dlon - clon, dlat - clat);
if (dist < bestDist) { bestDist = dist; best = d; }
});
robot = best;
}
}
}
console.log('点击地图,拾取到设备', robot);
if (robot) {
onCameraClickRef.current?.(robot);
}
if (from !== "deviceStatus")
return;
const cartesian = viewer.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
@@ -1696,6 +1719,9 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine,
onMarkPointRef.current?.({ lon, lat });
}, window.Cesium.ScreenSpaceEventType.LEFT_CLICK);
if (onClearDraw) {
onClearDraw(clearDrawingPath);
}
@@ -1703,7 +1729,7 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine,
return () => {
handler.destroy();
};
}, [drawPoints, from]);
}, [drawPoints, from, devices]);
//useEffect(() => {
// const viewer = viewerRef.current;
@@ -1875,6 +1901,7 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine,
if (realtimePosition?.heading !== undefined && !isNaN(Number(realtimePosition.heading))) {
let headingDeg = Number(realtimePosition.heading);
rotation = Cesium.Math.toRadians(headingDeg);

View File

@@ -158,7 +158,7 @@ export default function Organization() {
<AntdCard style={{ borderRadius: 8 }}>
<div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between' }}>
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>{t('systemSetting.fixed2AddNew2')}</Button>
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>{t('systemSetting.addOrganization')}</Button>
</div>
{/* 表格 + 统一分页 */}

View File

@@ -6,7 +6,8 @@ import {
TimePicker,
Popconfirm,
App,
Radio
Radio,
Empty
} from 'antd';
import {
PlusOutlined, ImportOutlined, NodeIndexOutlined,
@@ -93,6 +94,7 @@ export default function RobotTaskPage() {
const [runningPoolTask, setRunningPoolTask] = useState(null);//正在执行的任务
const [proPoints, setProPoints] = useState({});//规划点
// 当前执行任务的机器人
@@ -160,6 +162,7 @@ export default function RobotTaskPage() {
const handleFinish = (data) => {
console.log('任务完成回调', data);
setExecute(false);
setShowVideo(false); // 任务完成关闭视频
utils.message.success(t('devices.fixed2TaskSuspended2Fixed2CompletedFixed2'));
@@ -274,42 +277,7 @@ export default function RobotTaskPage() {
// 处理路线点回调:taskId必须和当前选中任务一致
controller.onRoutePost = (msg) => {
console.log('收到 route_post 消息:', msg);
const { taskId, data } = msg;
// 1. 先在任务池中查找该taskId对应的任务
const matchedTask = taskPoolList.find(task => String(task.id) === String(taskId));
// 2. 两种情况处理:
// a) 当前没有选中任务,且匹配到了任务池中的任务 → 自动选中该任务
// b) 当前已选中任务,且选中任务的id === 传来的taskId → 更新数据
const isSameAsSelected = runningPoolTask && String(runningPoolTask.id) === String(taskId);
const shouldSelectNewTask = !runningPoolTask && matchedTask;
if (isSameAsSelected || shouldSelectNewTask) {
console.log('taskId匹配成功,处理路线数据', {
taskId,
runningPoolTaskId: runningPoolTask?.id,
matchedTask
});
// 如果是匹配到新任务就设置选中状态
if (shouldSelectNewTask) {
setRunningPoolTask(matchedTask);
}
// 先直接用推送的data设置点(实时性)
if (data) {
setPoints(data);
}
} else {
console.log('taskId不匹配,忽略本次推送', {
receivedTaskId: taskId,
currentSelectedTaskId: runningPoolTask?.id,
matchedTaskFound: !!matchedTask
});
}
setProPoints(msg);
};
@@ -322,6 +290,8 @@ export default function RobotTaskPage() {
if (controllerRef.current) {
controllerRef.current.destroy?.();
}
setExecute(false);
controllerRef.current = null;
};
@@ -349,6 +319,10 @@ export default function RobotTaskPage() {
// 找到对应的设备
const targetDevice = devices.find(d => d.serialNumber === runningTask.deviceId);
setRunningPoolTask(runningTask); // 设置当前任务
setExecute(true);
setExecutingRobot(targetDevice);
setClearNavLine(v => v + 1); // 清空地图轨迹
if (!targetDevice) return;
@@ -359,14 +333,20 @@ export default function RobotTaskPage() {
// 切换设备
console.log('🔄 检测到正在执行任务的新设备,开始连接', targetDevice);
setRunningPoolTask(runningTask); // 设置当前任务
setExecute(true);
setExecutingRobot(targetDevice);
setClearNavLine(v => v + 1); // 清空地图轨迹
if (isFirstConnect.current) { isFirstConnect.current = false; controllerRef.current?.connectDevice(targetDevice); } else { controllerRef.current?.switchDevice(targetDevice); }
setShowVideo(true);
}, [devices, taskPoolList, executingRobot, runningPoolTask]);
useEffect(() => {
console.log('runningPoolTask, proPoints', runningPoolTask, proPoints);
if (!runningPoolTask?.id || !proPoints?.taskId) return;
if (runningPoolTask?.id == proPoints?.taskId) {
setPoints(proPoints?.data || []);
}
}, [runningPoolTask, proPoints]);
const realtimePosition = useMemo(() => {
@@ -471,6 +451,7 @@ export default function RobotTaskPage() {
}, [taskPoolList]);
const getRouteOut = async () => {
try {
if (!selectedPathWork?.id) return;
const res = await getSingleRouteList({ id: selectedPathWork?.id });
// coverage(区域覆盖)绘制为多边形,其余为折线/单点
@@ -508,7 +489,6 @@ export default function RobotTaskPage() {
}, [selectedPathWork?.id])
// 调用接口获取路线详情
const fetchRouteDetail = async (id) => {
console.log(id, "获取正在执行任务的id")
try {
const params = {
taskId: id,
@@ -1578,15 +1558,14 @@ export default function RobotTaskPage() {
style={cardStyle}
>
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
{routeList
//.filter(item => {
// if (!routeSearch) return true;
// const name = (item.workName || item.name || '').toLowerCase();
// const id = String(item.id || '').toLowerCase();
// const key = routeSearch.toLowerCase();
// return name.includes(key) || id.includes(key);
//})
.map(route => (
{
// 判断有无数据
(!routeList || routeList.length === 0) ? (
<div style={{ padding: '40px 0', textAlign: 'center', color: '#86909C' }}>
<Empty></Empty>
</div>
) : (
routeList.map(route => (
<div
key={route.id}
style={{
@@ -1649,7 +1628,6 @@ export default function RobotTaskPage() {
</div>
)}
</div>
{/* 路线信息 */}
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{ fontWeight: 600, fontSize: 14, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
@@ -1683,7 +1661,6 @@ export default function RobotTaskPage() {
}}
/>
</Tooltip>
{/* 执行按钮 */}
<Tooltip title={t('devices.executeRoute')}>
<Button
@@ -1696,10 +1673,12 @@ export default function RobotTaskPage() {
}}
/>
</Tooltip>
</div>
))
)
}
</div>
</div>
))}
</div>
</Card>
</Col>

View File

@@ -1273,7 +1273,7 @@ const en = {
videoFixed2: ' Airport video',
fixed2TaskSuspended2Fixed2CompletedFixed2: 'Fixed2 Task Suspended2 Fixed2 Completed Fixed2',
fixed2TaskSuspended2Fixed2CompletedFixed2: 'Task Completed ',
deletedSuccessfullyFixed2: '航线 Deleted successfully Fixed2',
@@ -2578,7 +2578,7 @@ const en = {
addMenu: 'Add Menu',
editSite: 'Edit Station',
addSite: 'Add Station',
selectsite:'Select Station',
selectsite: 'Select Station',

View File

@@ -39,6 +39,7 @@ import {
getSiteUAVList, getWayLine, createWaylineTask, getUAVState,
postFlightCommmand, getFlightTaskDetail
} from '../api/device';
import utils from '../lib/utils';
const { Option } = Select;
const { Search } = Input;
@@ -142,6 +143,7 @@ const RealTimeMonitorPage = () => {
};
}, [robotRealtimePosition]);
const [runningPoolTask, setRunningPoolTask] = useState(null);
const [proPoints, setProPoints] = useState({});//规划点
// ========= UI 状态 =========
const [selectedDevice, setSelectedDevice] = useState(null);
@@ -175,17 +177,18 @@ const RealTimeMonitorPage = () => {
controller.onLocationInfoUpdate = (pos) => {
setRobotRealtimePosition(pos);
};
controller.onIsFinished = handleFinish;
controller.onRoutePost = (msg) => {
console.log('[RTMonitor] route_post:', msg);
const { taskId, data } = msg;
const matchedTask = taskPoolList.find(task => String(task.id) === String(taskId));
const sameAsSelected = runningPoolTask && String(runningPoolTask.id) === String(taskId);
if ((!runningPoolTask && matchedTask) || sameAsSelected) {
if (!runningPoolTask && matchedTask) setRunningPoolTask(matchedTask);
if (data) setPoints(data);
loadTaskPath(taskId);
}
//const matchedTask = taskPoolList.find(task => String(task.id) === String(taskId));
//const sameAsSelected = runningPoolTask && String(runningPoolTask.id) === String(taskId);
//if ((!runningPoolTask && matchedTask) || sameAsSelected) {
// if (!runningPoolTask && matchedTask) setRunningPoolTask(matchedTask);
console.log('[RTMonitor] route_post:', data)
setProPoints(msg);
//}
};
controller.init();
@@ -199,6 +202,28 @@ const RealTimeMonitorPage = () => {
};
// eslint-disable-next-line
}, []);
useEffect(() => {
//console.log('runningPoolTask?.id, proPoints?.taskId', proPoints)
if (!runningPoolTask?.id || !proPoints?.taskId) return;
if (runningPoolTask?.id == proPoints?.taskId) {
console.log('1111111111', proPoints?.data);
setPoints(proPoints?.data);
}
}, [runningPoolTask, proPoints]);
const handleFinish = (data) => {
setExecute(false);
utils.message.success(t('devices.fixed2TaskSuspended2Fixed2CompletedFixed2'));
setPoints([]);
setPolyPoints([]);
setRunningPoolTask(null);
setExcuteStatus('stop');
};
// ============================================================
// WebSocket 连接
// ============================================================
// 拉取基础数据
@@ -298,7 +323,7 @@ const RealTimeMonitorPage = () => {
.filter(p => !isNaN(p.lng) && !isNaN(p.lat) && Math.abs(p.lng) < 180 && Math.abs(p.lat) < 90 && p.lng !== 0 && p.lat !== 0);
console.log('[RTMonitor] fetchRouteDetailAndShow:', routeId, mapPoints);
if (mapPoints.length) {
setPoints(mapPoints);
setPolyPoints(mapPoints);
setRouteMode(mode || '');
@@ -796,7 +821,6 @@ const RealTimeMonitorPage = () => {
if (newTask) {
setRunningPoolTask(newTask);
await loadTaskPath(newTask.id);
await fetchDetailTaskPath(newTask.id);
setExcuteStatus('running');
}
} else {
@@ -980,6 +1004,8 @@ const RealTimeMonitorPage = () => {
<div>📡 {t('devices.realtimePosition')}</div>
<div>Lng: {Number(robotRealtimePosition.longitude || robotRealtimePosition.lng || 0).toFixed(5)}</div>
<div>Lat: {Number(robotRealtimePosition.latitude || robotRealtimePosition.lat || 0).toFixed(5)}</div>
<div>yaw: {Number(robotRealtimePosition.heading || 0).toFixed(5)}</div>
</div>
)}
</div>
@@ -1312,7 +1338,6 @@ const RealTimeMonitorPage = () => {
{(runningPoolTask || deviceTasks.current) ? (
(() => {
const task = runningPoolTask || deviceTasks.current;
console.log(task, " dsada")
return (
<Space direction="vertical" size={6} style={{ width: '100%' }}>
<Space wrap>
@@ -1433,7 +1458,7 @@ const RealTimeMonitorPage = () => {
type="text"
size="small"
icon={<SendOutlined />}
disabled={!selectedDevice || selectedDevice.onlineStatus !== 1}
//disabled={!selectedDevice || selectedDevice.onlineStatus !== 1}
onClick={(e) => {
e.stopPropagation();
handleRouteExecute(route);