优化点击任务池中 连接不同设备 并且 清空地图轨迹的逻辑,优化顶部topcard数值的显示

This commit is contained in:
mmc
2026-06-17 20:42:21 +08:00
parent b4288288ba
commit ec4005c1f8
3 changed files with 112 additions and 28 deletions

33
env.js
View File

@@ -9,11 +9,11 @@ const currentEnv = import.meta.env?.MODE || process.env.NODE_ENV;
// 环境配置映射
const envConfig = {
[ENV.DEV]: {
baseURL: 'http://192.168.2.59:8081',//http://192.168.2.56:8081
//baseURL: 'http://1.95.137.212:59015',//http://192.168.2.56:8081
WS_URL: 'ws://192.168.2.59:9002/ws/',
mqtt_url: "ws://1.95.137.212:8083/mqtt",
geoserver_url: "http://192.168.2.59:7000/geoserver"
//baseURL: 'http://192.168.2.59:8081',//http://192.168.2.56:8081
////baseURL: 'http://1.95.137.212:59015',//http://192.168.2.56:8081
//WS_URL: 'ws://192.168.2.59:9002/ws/',
//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: 'https://serviceri.satabot.com',
@@ -21,17 +21,24 @@ const envConfig = {
//mqtt_url: "ws://1.95.137.212:59021/mqtt",
//geoserver_url: "http://1.95.137.212:59018/geoserver"
//baseURL: 'http://1.95.137.212:59015',//http://192.168.2.56:8081
////baseURL: 'https://serviceri.satabot.com',
//WS_URL: 'ws://1.95.137.212:59017/ws/',
//mqtt_url: "ws://1.95.137.212:59021/mqtt",
//geoserver_url: "http://1.95.137.212:59018/geoserver"
},
[ENV.PROD]: {
//baseURL: 'https://pvcloudservice.satabot.com',
baseURL: 'http://1.95.137.212:59015',//http://192.168.2.56:8081
//baseURL: 'https://serviceri.satabot.com',
WS_URL: 'ws://1.95.137.212:59017/ws/',
mqtt_url: "ws://1.95.137.212:59021/mqtt",
geoserver_url: "http://1.95.137.212:59018/geoserver"
},
[ENV.PROD]: {
//baseURL: 'https://pvcloudservice.satabot.com',
//baseURL: 'http://1.95.137.212:59015',//http://192.168.2.56:8081
////baseURL: 'https://serviceri.satabot.com',
//WS_URL: 'ws://1.95.137.212:59017/ws/',
//mqtt_url: "ws://1.95.137.212:8083/mqtt",
//geoserver_url: "http://1.95.137.212:59018/geoserver"
baseURL: 'http://1.95.137.212:8081',//http://192.168.2.56:8081
//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"
},

View File

@@ -401,6 +401,7 @@ const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine,
}
function displayPublishedLayers(publishedLayers, baseUrl) {
console.log('已发布的图层:', publishedLayers)
publishedLayers.forEach((layer, index) => {
const [workspace, layerName] = layer.name.split(':');
if (workspace && layerName) {

View File

@@ -78,6 +78,9 @@ export default function RobotTaskPage() {
const [selectedRobotForExecute, setSelectedRobotForExecute] = useState(null);
const [runningPoolTask, setRunningPoolTask] = useState(null);//正在执行的任务
// 当前执行任务的机器人
const [executingRobot, setExecutingRobot] = useState(null);
const [showVideo, setShowVideo] = useState(false); // 控制视频组件显示
@@ -168,7 +171,32 @@ export default function RobotTaskPage() {
// 任务池项点击事件
const handlePoolTaskClick = (record) => {
setRunningPoolTask(record);
loadTaskPath(record.id);
// 查找对应的设备
const targetDevice = devices?.find(d => d.serialNumber === record.deviceId);
if (!targetDevice) {
console.warn('未找到任务对应的设备');
return;
}
// 判断是否是新设备(避免重复连接)
const isSameDevice = executingRobot?.serialNumber === targetDevice.serialNumber;
if (isSameDevice) {
console.log('✅ 任务使用相同设备,无需重新连接');
return;
}
// 切换设备连接
console.log('🔄 点击任务切换设备连接', targetDevice);
setExecute(true);
setExecutingRobot(targetDevice);
setClearNavLine(v => v + 1); // 清空地图轨迹
controllerRef.current?.connectDevice(targetDevice);
setShowVideo(true);
};
@@ -192,9 +220,19 @@ export default function RobotTaskPage() {
}, []);
// 监听任务列表和设备列表变化,自动连接正在执行中的机器人
// 监听任务列表和设备列表变化,自动连接正在执行中的机器人(仅在没有选择任务时)
useEffect(() => {
if (!taskPoolList || !devices) return;
if (!taskPoolList || taskPoolList.length == 0) {
setClearNavLine(v => v + 1); // 清空地图轨迹
setClearPlanLine(v => v + 1);
setRunningPoolTask(null);
return;
}
if (!devices) return;
// 如果已经有选择的任务(runningPoolTask),则不自动连接,让用户手动选择
if (runningPoolTask) return;
// 查找正在执行中的任务
const runningTask = taskPoolList.find(item => ['EXECUTING', 'PAUSE'].includes(item.taskStaus));
@@ -202,7 +240,7 @@ export default function RobotTaskPage() {
if (!runningTask) return;
// 找到对应的设备
const targetDevice = devices.find(d => d.serialNumber === runningTask.deviceId || d.serialNumber === runningTask.deviceId);
const targetDevice = devices.find(d => d.serialNumber === runningTask.deviceId);
if (!targetDevice) return;
@@ -213,13 +251,14 @@ export default function RobotTaskPage() {
// 切换设备
console.log('🔄 检测到正在执行任务的新设备,开始连接', targetDevice);
setRunningPoolTask(runningTask); // 设置当前任务
setExecute(true);
setExecutingRobot(targetDevice);
setClearNavLine(v => v + 1); // 清空地图轨迹
controllerRef.current?.connectDevice(targetDevice);
setShowVideo(true);
}, [devices, taskPoolList, executingRobot]);
}, [devices, taskPoolList, executingRobot, runningPoolTask]);
const realtimePosition = useMemo(() => {
@@ -348,10 +387,32 @@ export default function RobotTaskPage() {
// 监听任务池列表变化,自动加载第一个任务的路径
useEffect(() => {
if (taskPoolList && taskPoolList.length > 0) {
loadTaskPath(taskPoolList[0].id);
setRunningPoolTask(taskPoolList[0]);
}
}, [taskPoolList]);
useEffect(() => {
if (!runningPoolTask?.id) return;
loadTaskPath(runningPoolTask.id);
// 只有当任务是执行状态,并且没有连接的设备时,才自动连接
if ((runningPoolTask.taskStaus == 'EXECUTING' || runningPoolTask.taskStaus == 'PAUSE') && !executingRobot) {
const targetDevice = devices?.find(d => d.serialNumber === runningPoolTask.deviceId);
if (targetDevice) {
setExecute(true);
setExecutingRobot(targetDevice);
setClearNavLine(v => v + 1); // 清空地图轨迹
controllerRef.current?.connectDevice(targetDevice);
setShowVideo(true);
}
}
}, [runningPoolTask, devices, executingRobot])
// 获取路线列表
const fetchRouteList = async () => {
if (!stationId) return;
@@ -557,6 +618,7 @@ export default function RobotTaskPage() {
//}
setSelectedRobotForExecute(null);
setSelectedRouteForExecute(null);
} else {
utils.message.error('任务取消失败');
}
@@ -798,7 +860,8 @@ export default function RobotTaskPage() {
onConfirm={() => handleCancelTask(record)}
okText="确定" cancelText="取消"
>
<Button type="text" size="small" danger icon={<CloseOutlined />}>取消</Button>
<Button type="text" size="small" danger icon={<CloseOutlined />} onClick={(e) => e.stopPropagation()}
>取消</Button>
</Popconfirm>
{/*//)}*/}
@@ -808,7 +871,8 @@ export default function RobotTaskPage() {
onConfirm={() => handlePauseTask(record)}
okText="确定" cancelText="取消"
>
<Button type="text" size="small" style={{ color: '#FF9500' }}>暂停</Button>
<Button type="text" size="small" style={{ color: '#FF9500' }} onClick={(e) => e.stopPropagation()}
>暂停</Button>
</Popconfirm>
{/*)}/*/}
@@ -818,7 +882,8 @@ export default function RobotTaskPage() {
onConfirm={() => handleRecoverTask(record)}
okText="确定" cancelText="取消"
>
<Button type="text" size="small" style={{ color: '#00B42A' }}>恢复</Button>
<Button type="text" size="small" style={{ color: '#00B42A' }} onClick={(e) => e.stopPropagation()}
>恢复</Button>
</Popconfirm>
)}
</>
@@ -887,14 +952,22 @@ export default function RobotTaskPage() {
const finishList = taskList.filter(item => ['FINISH', 'FAILED'].includes(item.taskStaus));
return { waitList, runList, finishList };
}, [taskList]);
const historyData = useMemo(() => {
const successfulTaskList = taskHistoryList.filter(item => ['FINISH', 'FAILED'].includes(item.taskStaus));
return { successfulTaskList };
}, [taskHistoryList]);
const { waitList, runList, finishList } = groupBoardData;
const { successfulTaskList } = historyData;
const topCards = [
{ title: '今日机器人计划', value: taskList.length, unit: '条', desc: '进行中', icon: <LayoutGrid size={22} />, color: '#165DFF' },
{ title: '作业中机器人', value: runList.length, unit: '台', desc: '作业中', icon: <Car size={22} />, color: '#165DFF' },
{ title: '作业中机器人', value: taskPoolList?.filter(item => ['EXECUTING', 'PAUSE'].includes(item.taskStaus))?.length, unit: '台', desc: '作业中', icon: <Car size={22} />, color: '#165DFF' },
{ title: '累计作业里程', value: '12.5', unit: 'km', trend: '较昨日 +1.2', trendColor: '#00B42A', icon: <TrendingUp size={22} />, color: '#722ED1' },
{ title: '任务完成率', value: taskList.length ? Math.round((finishList.length / taskList.length) * 100) : 0, unit: '%', trend: '较昨日 +5%', trendColor: '#00B42A', icon: <CheckCircle2 size={22} />, color: '#00B42A' },
{ title: '异常告警', value: '2', unit: '次', trend: '较昨日 -1', trendColor: '#00B42A', icon: <AlertCircle size={22} />, color: '#F53F3F' },
{ title: '任务完成率', value: successfulTaskList.length ? Math.round((successfulTaskList.length / taskHistoryList.length) * 100) : 0, unit: '%', trend: '较昨日 +5%', trendColor: '#00B42A', icon: <CheckCircle2 size={22} />, color: '#00B42A' },
{ title: '异常告警', value: '0', unit: '次', trend: '较昨日 -1', trendColor: '#00B42A', icon: <AlertCircle size={22} />, color: '#F53F3F' },
{
title: '在线率',
value: `${devices?.length ? Math.round((devices.filter(d => d.onlineStatus == 1).length / devices.length) * 100) : 0}`,
@@ -1260,7 +1333,10 @@ export default function RobotTaskPage() {
scroll={{ x: 800, y: 150 }}
onRow={(record) => ({
onClick: () => handlePoolTaskClick(record),
style: { cursor: 'pointer' }
style: {
cursor: 'pointer',
backgroundColor: record.id === runningPoolTask?.id ? '#e6f4ff' : 'transparent'
}
})}
/>
</>
@@ -1359,7 +1435,7 @@ export default function RobotTaskPage() {
bodyStyle={{ padding: '16px' }}
style={{ ...cardStyle, flex: 1 }}
>
<Row gutter={[16, 16]}>
<Row gutter={[8, 8]}>
<Col span={12}>
<div style={{ background: '#F7F8FA', padding: 12, borderRadius: 10 }}>
<div style={{ fontSize: 12, color: '#86909C' }}>当前温度</div>
@@ -1385,7 +1461,7 @@ export default function RobotTaskPage() {
</div>
</Col>
</Row>
<div style={{ marginTop: 20, padding: 12, background: 'rgba(255, 125, 0, 0.1)', borderRadius: 8, display: 'flex', alignItems: 'center', gap: 8 }}>
<div style={{ marginTop: 8, padding: 12, background: 'rgba(255, 125, 0, 0.1)', borderRadius: 8, display: 'flex', alignItems: 'center', gap: 8 }}>
<AlertCircle size={16} style={{ color: '#FF7D00' }} />
<span style={{ fontSize: 13, color: '#FF7D00' }}>注意:区域 B 存在积水风险,建议避开</span>
</div>
@@ -1631,7 +1707,7 @@ export default function RobotTaskPage() {
title={`机器人全景视频 - ${executingRobot.deviceAlias || executingRobot.serialNumber}`}
onClose={() => setShowVideo(false)}
>
<div style={{ height: 'clamp(300px, 30vw, 600px)', }}>
<div >
<MowerAllView
serialNumber={executingRobot.serialNumber}
robotVideo={robotVideo}