forked from drone/command-center-dashboard

罗广辉
2025-04-18 55e74685fe3a27bf061a2451b2a730ddb0bc7e9c
feat: 抽出WS逻辑
2 files modified
1 files added
166 ■■■■ changed files
src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue 2 ●●● patch | view | raw | blame | history
src/components/CurrentTaskDetails/CurrentTaskDetails.vue 120 ●●●● patch | view | raw | blame | history
src/components/CurrentTaskDetails/useDroneWS.js 44 ●●●●● patch | view | raw | blame | history
src/components/CurrentTaskDetails/ControlPanel/ControlPanel.vue
@@ -398,7 +398,7 @@
watch(
    () => workspace_id.value,
    async () => {
        if (workspace_id.value) {
        if (workspace_id.value && mqttState === null && client_id.value === '') {
            await createConnect()
            // 使用控制
            manualControl = useManualControl(mqttState, deviceTopicInfo.value, flightController, paramsRef)
src/components/CurrentTaskDetails/CurrentTaskDetails.vue
@@ -22,7 +22,7 @@
            </template>
            <!--    控制面板,里面有方法需要立即执行,不可用v-if        -->
<!--            <ControlPanel />-->
            <!--            <ControlPanel />-->
            <ControlPanel v-show="!isAutoControl" />
            <img alt="" :src="amplifyImg" class="amplify" @click="isMaxMap = !isMaxMap" />
        </div>
@@ -49,40 +49,42 @@
import { updateDroneQualityApi } from '@/api/drc'
import { getLiveAiLinkApi } from '@/api/payload'
import { CURRENT_CONFIG } from '@/utils/http/config'
import { useDroneWS } from '@/components/CurrentTaskDetails/useDroneWS'
const isAutoControl = ref(true)
const isAutoControl = ref(true) //是否自动控制
const lineQuality = ref(1) //1流畅,2标清
provide('isAutoControl', isAutoControl)
provide('lineQuality', lineQuality)
const taskDetailsViewer = ref(null)
provide('taskDetailsViewer', taskDetailsViewer)
let taskDetails = ref({})
provide('taskDetails', taskDetails)
const deviceOsdInfo = ref({})
provide('deviceOsdInfo', deviceOsdInfo)
const taskDetailsViewer = ref(null) //地图实例
let taskDetails = ref({}) //任务详情
const deviceOsdInfo = computed(() => wsInfo.value?.device_osd)
const dockSn = computed(() => taskDetails?.value?.device_sns?.[0])
const droneSn = computed(() => deviceOsdInfo?.value?.data?.sn)
const trueAltitude = ref('') // 真实高度
const isAiLive = ref(false) // 是ai直播
const video_id = ref('') // 直播视频id
const workspace_id = ref('')
const isShow = defineModel('show') // 是否显示当前任务详情
const props = defineProps(['id'])
const currentLiveUrl = ref('') // 当前直播地址
const isTakeOff = ref(false) // 是在飞行中
const isMaxMap = ref(false) //是大地图
provide('isAutoControl', isAutoControl)
provide('lineQuality', lineQuality)
provide('taskDetailsViewer', taskDetailsViewer)
provide('taskDetails', taskDetails)
provide('deviceOsdInfo', deviceOsdInfo)
provide('dockOsdInfo', wsInfo?.value?.dock_osd)
provide('dockSn', dockSn)
provide('droneSn', droneSn)
const trueAltitude = ref('')
provide('trueAltitude', trueAltitude)
const isAiLive = ref(false)
provide('isAiLive', isAiLive)
const isShow = defineModel('show')
const props = defineProps(['id'])
const currentLiveUrl = ref('')
const isTakeOff = ref(false)
const isMaxMap = ref(false)
let droneWebSocket //WS实例
const video_id = ref('')
provide('video_id', video_id)
let wsInfo = useDroneWS(workspace_id)
watch(wsInfo, () => {
    setCurrentLiveUrl()
}, { deep: true })
provide('wsInfo', wsInfo)
// 获取机巢直播
const getDeviceLiveUrl = async () => {
@@ -90,10 +92,10 @@
    currentLiveUrl.value = res.data.data.rtcs_url
}
const getAiLiveUrl = async ()=>{
    const res =await getLiveAiLinkApi({
const getAiLiveUrl = async () => {
    const res = await getLiveAiLinkApi({
        original_stream_url: `${CURRENT_CONFIG.rtmpURL}${video_id.value.replace(/\//g, '-')}`,
        video_id:video_id.value
        video_id: video_id.value,
    })
    currentLiveUrl.value = res.data.data.rtcs_url
    ElMessage.success('开启成功')
@@ -116,15 +118,13 @@
// 设置当前直播地址
const setCurrentLiveUrl = async () => {
    const data = deviceOsdInfo.value?.data
    const deviceInfo = data?.host
    const deviceInfo = deviceOsdInfo.value?.data?.host
    const currentIsTakeOff = ![14, 0].includes(deviceInfo.mode_code)
    // 如果还是之前的状态,不切换
    if (isTakeOff.value === currentIsTakeOff) return
    isTakeOff.value = currentIsTakeOff
    isTakeOff.value ? await getDroneLiveUrl() : await getDeviceLiveUrl()
}
// 获取任务详情获取航线文件
const getTaskDetails = () => {
    if (!props.id) ElMessage.warning('请检查是否传入id')
@@ -132,59 +132,8 @@
        taskDetails.value = res.data.data
        await getDeviceLiveUrl()
        taskDetails.value.workspace_id = taskDetails.value.way_lines[0]?.workspace_id
        createWsConnect()
        workspace_id.value = taskDetails.value.workspace_id
    })
}
const dockOsdInfo = ref({})
provide('dockOsdInfo', dockOsdInfo)
const wsInfo = ref({})
provide('wsInfo', wsInfo)
// websocket 的消息回调
const messageHandler = result => {
    let payload = JSON.parse(result)
    wsInfo.value[payload.biz_code] = payload
    switch (payload.biz_code) {
        // 无人机
        case EBizCode.DeviceOsd: {
            deviceOsdInfo.value = payload
            setCurrentLiveUrl()
            console.log(payload, 'DeviceOsd--信息')
            break
        }
        // 遥控器
        case EBizCode.GatewayOsd: {
            console.log(payload, 'GatewayOsd--信息')
            break
        }
        // 机巢
        case EBizCode.DockOsd: {
            console.log(payload, 'DockOsd--信息')
            break
        }
        // PsdkWidgetValues
        case EBizCode.PsdkWidgetValues: {
            console.log(payload, 'PsdkWidgetValues--信息')
            break
        }
        // VideoSurveillance
        case EBizCode.VideoSurveillance: {
            console.log(payload, 'VideoSurveillance--信息')
            break
        }
        default:
            break
    }
}
// 创建ws连接
const createWsConnect = () => {
    const workspaceId = taskDetails.value.workspace_id
    if (!workspaceId) return
    let webSocketUrl = getWebsocketUrl() + '&workspace-id=' + workspaceId
    // 监听ws 消息
    droneWebSocket = useConnectWebSocket(messageHandler, webSocketUrl)
}
onMounted(() => {
@@ -195,9 +144,6 @@
})
onBeforeUnmount(() => {
    droneWebSocket?.close()
    deviceOsdInfo.value = {}
    droneWebSocket = null
    EventBus.off('CurrentTaskDetails-timeStop', changeLineQuality)
    EventBus.off('CurrentTaskDetails-getAiLiveUrl', getAiLiveUrl)
    EventBus.off('CurrentTaskDetails-getDroneLiveUrl', getDroneLiveUrl)
src/components/CurrentTaskDetails/useDroneWS.js
New file
@@ -0,0 +1,44 @@
import { getWebsocketUrl } from '@/websocket/util/config'
import { useConnectWebSocket } from '@/utils/websocket/connect-websocket'
/**
 * 使用无人机WebSocket连接,根据工作区ID动态管理WebSocket连接。
 *
 * @param {Ref<string>} workspaceIdRef - 工作区ID的引用,用于动态更新WebSocket连接。
 * @returns {Ref<Object>} - 返回一个包含WebSocket消息的响应式对象,键为业务代码,值为对应的消息负载。
 */
export const useDroneWS = workspaceIdRef => {
    const wsInfo = ref({})
    let droneWebSocket = null
    const messageHandler = result => {
        let payload = JSON.parse(result)
        if (payload.biz_code) {
            wsInfo.value[payload.biz_code] = payload
        }
    }
    function init() {
        let webSocketUrl = getWebsocketUrl() + '&workspace-id=' + workspaceIdRef.value
        // 监听ws 消息
        droneWebSocket = useConnectWebSocket(messageHandler, webSocketUrl)
    }
    watch(workspaceIdRef, (newValue, oldValue) => {
        removeEvent()
        if (workspaceIdRef.value) {
            init()
        }
    })
    function removeEvent() {
        droneWebSocket?.close()
        droneWebSocket = null
        wsInfo.value = {}
    }
    onBeforeUnmount(() => {
        removeEvent()
    })
    return wsInfo
}