diff --git a/env.js b/env.js index 17630ec..465aa70 100644 --- a/env.js +++ b/env.js @@ -9,17 +9,23 @@ 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://192.168.2.59: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://192.168.2.59: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', //WS_URL: 'ws://1.95.137.212:9002/ws/', //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', diff --git a/src/api/device.ts b/src/api/device.ts index 75ace55..e4bda2b 100644 --- a/src/api/device.ts +++ b/src/api/device.ts @@ -402,6 +402,25 @@ export function getRouteByTask(params) { }) } +//增加预设路径iot/workRecord/add + +export function addRoute(data) { + const config = { + url: '/iot/workRecord/add', // 修正为正确的添加接口 + method: 'post', + data + }; + + // 如果是 FormData,不需要设置 Content-Type,axios 会自动设置 + if (!(data instanceof FormData)) { + config.headers = { + 'Content-Type': 'application/json' + }; + } + + return request(config); +} + diff --git a/src/components/Map.jsx b/src/components/Map.jsx index 4af2a91..7ee055b 100644 --- a/src/components/Map.jsx +++ b/src/components/Map.jsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useState, useMemo } from 'react'; +import React, { useEffect, useRef, useState, useMemo, useImperativeHandle, forwardRef, useCallback } from 'react'; import carImg from '../assets/images/car.png'; import inspectImg from "../assets/images/inspectCar.png" import planeImg from '../assets/images/plane.png'; @@ -26,7 +26,7 @@ const CYAN_GLOW_COLOR = new window.Cesium.Color( ); window.Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNjk0NjI1MC0wZGYyLTQ1YzItYjJmZi0wY2M5ODEwODllYzIiLCJpZCI6Mzk3MTQxLCJpYXQiOjE3NzI1MjkwMjV9.U6qmakhDgXJVXwLFyWzSxAUOFZRrDkIsRUPP6CCdnKg"; -export default function CesiumMap({ ifClear, ifClearPlanLine, ifClearNavLine, finishPoint, drawRealTime, realtimePosition, realtimeType, pathPoints = [], devices = [], onCameraClick, focusLocation, points = [], onPathChange, from, onClearDraw }) { +const CesiumMap = React.forwardRef(({ ifClear, ifClearPlanLine, ifClearNavLine, finishPoint, drawRealTime, realtimePosition, realtimeType, pathPoints = [], devices = [], onCameraClick, focusLocation, points = [], markedPoints = [], onPathChange, from, onClearDraw }, ref) => { const containerRef = useRef(null); const viewerRef = useRef(null); const tooltipRef = useRef(null); @@ -37,6 +37,7 @@ export default function CesiumMap({ ifClear, ifClearPlanLine, ifClearNavLine, fi const iotMapRef = useRef(new Map()); const planLineRef = useRef(null); // points 规划航线 const navLineRef = useRef(null); // 完成点实时轨迹 + const markedPointsRef = useRef([]); // 标记点实体 const realtimeEntityRef = useRef(null); const realtimeLineRef = useRef(null); @@ -295,6 +296,49 @@ export default function CesiumMap({ ifClear, ifClearPlanLine, ifClearNavLine, fi } }, [points]); + // 渲染绿色标记点 + const drawMarkedPoints = (points) => { + const viewer = viewerRef.current; + if (!viewer) return; + + // 先清空之前的标记点 + markedPointsRef.current.forEach(id => { + viewer.entities.removeById(id); + }); + markedPointsRef.current = []; + + if (!points || points.length === 0) return; + + points.forEach((p, i) => { + const id = `marked-point-${i}`; + viewer.entities.add({ + id, + position: window.Cesium.Cartesian3.fromDegrees(p.lon, p.lat), + point: { + color: window.Cesium.Color.GREEN, + pixelSize: 15, + disableDepthTestDistance: Number.POSITIVE_INFINITY, + }, + label: { + text: `${i + 1}`, + font: '14px sans-serif', + pixelOffset: new window.Cesium.Cartesian2(0, -20), + fillColor: window.Cesium.Color.WHITE, + outlineColor: window.Cesium.Color.BLACK, + outlineWidth: 2, + style: window.Cesium.LabelStyle.FILL_AND_OUTLINE, + } + }); + markedPointsRef.current.push(id); + }); + }; + + useEffect(() => { + if (viewerRef.current) { + drawMarkedPoints(markedPoints); + } + }, [markedPoints]); + function showRobotTooltip(tooltip, robot, position) { const statusMap = { 1: { text: "工作中", color: "#10b981" }, @@ -1753,6 +1797,29 @@ export default function CesiumMap({ ifClear, ifClearPlanLine, ifClearNavLine, fi viewer.scene.requestRender(); }, [realtimePosition]); + // 截图功能 + const captureScreenshot = useCallback(() => { + return new Promise((resolve) => { + const viewer = viewerRef.current; + if (!viewer) { + resolve(null); + return; + } + + // 使用 Cesium 的截图功能 + viewer.scene.render(); + + const canvas = viewer.scene.canvas; + const dataUrl = canvas.toDataURL('image/jpeg', 0.8); + resolve(dataUrl); + }); + }, []); + + // 暴露 ref 方法 + useImperativeHandle(ref, () => ({ + captureScreenshot + })); + return <>
>; -} +}); + +export default CesiumMap; diff --git a/src/components/devices/DeviceStatusPage.tsx b/src/components/devices/DeviceStatusPage.tsx index d860ce2..b5c57ff 100644 --- a/src/components/devices/DeviceStatusPage.tsx +++ b/src/components/devices/DeviceStatusPage.tsx @@ -41,6 +41,7 @@ import { getUAVState, getSiteDevice, getSiteUAVList, + addRoute, } from '../../api/device.ts'; import XboxController from './XboxController'; @@ -312,6 +313,14 @@ export default function DeviceStatusPage({ const [clearNavLine, setClearNavLine] = useState(0); const [clearPlanLine, setClearPlanLine] = useState(0); const timerRef = useRef{modalContent.content}
+ + {/* 保存路径模态框 */} +