diff --git a/src/api/device.ts b/src/api/device.ts index bd79a5f..c7c26f8 100644 --- a/src/api/device.ts +++ b/src/api/device.ts @@ -10,7 +10,7 @@ export function getDeviceListApi(data) { export function getPlaneDeviceList() { return request({ - url: '/iot/UAV/getProjectDeviceList', + url: '/iot/UAV/getUAVList', method: 'get', }) } diff --git a/src/components/Map.jsx b/src/components/Map.jsx index 85b24c3..7638b66 100644 --- a/src/components/Map.jsx +++ b/src/components/Map.jsx @@ -776,7 +776,6 @@ export default function CesiumMap({ realtimePosition, pathPoints = [], devices = devices.forEach((device, index) => { - console.log(device, "devicedd") const raw = device?.lastRunningStatus || {}; const parsed = parseLngLat(raw.longitude, raw.latitude); diff --git a/src/components/devices/DeviceOverviewPage.tsx b/src/components/devices/DeviceOverviewPage.tsx index 923b0f4..bad6148 100644 --- a/src/components/devices/DeviceOverviewPage.tsx +++ b/src/components/devices/DeviceOverviewPage.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect, useRef } from 'react'; import { Layout, Card, Row, Col, Statistic, Tag, Button, Table, Typography, Space, Progress, Badge, Timeline, message, - Select, Modal + Select, Modal, Space as AntSpace } from 'antd'; import { EnvironmentOutlined, RobotOutlined, BranchesOutlined, @@ -16,7 +16,7 @@ import { } from '@ant-design/icons'; import { useSelector } from 'react-redux'; -import { changeCameragateway, getDeviceListApi, getLiveStream, getPlaneDeviceList } from '../../api/device.ts'; +import { changeCameragateway, changeCameraPlane, getDeviceListApi, getLiveStream, getPlaneDeviceList } from '../../api/device.ts'; import { RootState } from '@/src/store'; import DroneLivePlayer from '../VolcRtcPlayer.jsx'; import AgoraTextTest from '../AgoraRtc.tsx'; @@ -46,10 +46,13 @@ const logs = [ ]; export default function DeviceOverviewPage({ devices, planedevices, devicesAll, onViewStatus, selectedSn, onDeviceSelect }) { - const [planeVideo, setPlaneVideo] = useState([]); + const [planeVideo, setPlaneVideo] = useState(null); const [zoomedVideo, setZoomedVideo] = useState(null); const [mowerView, setMowerView] = useState('front'); - const videoTypeRef = useRef('drone'); // drone → 无人机镜头 station → 机场镜头 + const [videoSource, setVideoSource] = useState('station'); // station / drone + const videoTypeRef = useRef('station'); + const [selectedCamera, setSelectedCamera] = useState('outdoor'); // 机场默认室外 + const [selectedLens, setSelectedLens] = useState('wide'); // 飞机默认广角 const selectedDevice = React.useMemo(() => { const sn = selectedSn || (devicesAll?.[0]?.device_sn || devicesAll?.[0]?.serialNumber); @@ -100,35 +103,71 @@ export default function DeviceOverviewPage({ devices, planedevices, devicesAll, const handleRecharge = () => message.info('回充指令已下发'); const handleEmergencyStop = () => message.error('已触发急停!'); - // ====================== ✅ 核心:无人机视频获取逻辑(优先无人机 → 无则机场) ====================== - const getDroneLiveStream = async () => { + // 加载机场摄像头 + const loadStationCamera = async (cameraPosition) => { + console.log(cameraPosition, "cameraPosition") if (!selectedDevice?.gateway_sn) return; - console.log(selectedDevice, "selectedDevice") + console.log(selectedDevice, "selectedDevice", cameraPosition) try { - if (selectedDevice.gateway_camera_list && selectedDevice.gateway_camera_list.length > 0) { - const droneData = { - sn: selectedDevice.gateway_sn, - cameraIndex: selectedDevice.gateway_camera_list.filter(item => item.camera_position - == "indoor")[0]?.camera_index || "", - - cameraPosition: "indoor", - qualityType: "adaptive", - videoExpire: 7200, - }; - changeCameragateway(droneData).then(res => { - if (res.code == 200) { - setPlaneVideo(res.data) - } - }) + const cameraIndex = selectedDevice.gateway_camera_list?.find( + item => item.camera_position == cameraPosition + )?.camera_index || ""; + console.log(cameraIndex, "cameraIndex") + if (!cameraIndex) { + setPlaneVideo({}); + return + } + const res = await changeCameragateway({ + sn: selectedDevice.gateway_sn, + cameraIndex, + cameraPosition, + qualityType: "adaptive", + videoExpire: 7200, + }); + if (res.code == 200) { + setPlaneVideo(res.data); + videoTypeRef.current = 'station'; } - - setPlaneVideo({}); } catch (err) { - console.error('视频拉流失败', err); - setPlaneVideo({}); + console.error('切换机场摄像头失败', err); } }; + // 加载无人机镜头 + const loadDroneLens = async (lensType) => { + console.log(lensType, "lensType") + if (!selectedDevice?.gateway_sn || !selectedDevice?.device_sn) return; + const cameraIndex = selectedDevice.drone_camera_list + ?.find(item => item.drone_camera_list == cameraPosition + )?.camera_index || ""; + console.log(cameraIndex, "cameraIndex") + if (!cameraIndex) return; + try { + const res = await changeCameraPlane({ + drone_sn: selectedDevice.device_sn, + lensType, + }); + if (res.code === 200) { + setPlaneVideo(res.data); + videoTypeRef.current = 'drone'; + } + } catch (err) { + console.error('切换无人机镜头失败', err); + } + }; + + // 自动加载默认画面 + useEffect(() => { + if (isUAV) { + setPlaneVideo(null); + if (videoSource === 'station') { + loadStationCamera('outdoor'); + } else { + loadDroneLens('wide'); + } + } + }, [selectedDevice, videoSource]); + const fix2 = (val) => { if (val === null || val === undefined || isNaN(val)) return '-'; return Number(val).toFixed(2); @@ -136,13 +175,6 @@ export default function DeviceOverviewPage({ devices, planedevices, devicesAll, const getVal = (val) => val == "no_rain" ? "无" : (val || '-'); - useEffect(() => { - if (isUAV) { - setPlaneVideo({}); - getDroneLiveStream(); - } - }, [selectedDevice]); - const handleDeviceChange = (id) => { if (onDeviceSelect) onDeviceSelect(id); }; @@ -312,32 +344,84 @@ export default function DeviceOverviewPage({ devices, planedevices, devicesAll,
- - - - + + + +
-
+
实时画面 - {!isUAV && ( - )}
+ {/* 视频容器 */}
+ + {/* 右上角摄像头切换按钮 */} + {isUAV && ( +
+ {videoSource === 'station' ? ( + <> + + + + + ) : ( + <> + + + + + + + )} +
+ )} + + {/* 视频内容 */} {isUAV ? ( planeVideo ? ( @@ -381,7 +465,6 @@ export default function DeviceOverviewPage({ devices, planedevices, devicesAll, )} - {/* 下面的卡片逻辑保持不变 */} AI分析与操作建议} bordered={false} style={{ borderRadius: 12, marginBottom: 16 }}>
🔥
热斑疑似
2 处
diff --git a/src/index.css b/src/index.css index 9550352..124a25e 100644 --- a/src/index.css +++ b/src/index.css @@ -119,7 +119,7 @@ h4, .ant-typography h4 { font-size: clamp(1rem, 1.5vw, 1.25rem) !important; } border-radius:4px !important; /* 更小的圆角看起来更紧凑 */ } .ant-btn{ - height: 32px !important; + /*height: 32px !important;*/ padding: 4px 12px !important; border-radius: 4px !important; }