forked from drone/command-center-dashboard

罗广辉
2025-04-21 1f52603ba0dcd62d3ff30e17b2c55101298da5e5
refactor: 重构单机巢状态
7 files modified
308 ■■■■ changed files
src/store/modules/home.js 77 ●●●●● patch | view | raw | blame | history
src/views/SignMachineNest/MachineLeft/MachineData.vue 4 ●●●● patch | view | raw | blame | history
src/views/SignMachineNest/MachineRight/InspectionRaskList.vue 5 ●●●●● patch | view | raw | blame | history
src/views/SignMachineNest/MachineRight/MachineMonitor.vue 22 ●●●● patch | view | raw | blame | history
src/views/SignMachineNest/MachineRight/MachineStatus/MachineStatus.vue 127 ●●●● patch | view | raw | blame | history
src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/MachineTableDetails.vue 2 ●●● patch | view | raw | blame | history
src/views/SignMachineNest/SignMachineNest.vue 71 ●●●● patch | view | raw | blame | history
src/store/modules/home.js
@@ -11,38 +11,10 @@
        currentAreaPosition:getStore({ name: 'currentAreaPosition' }) || {},
    singleUavHome: {},
        footActiveIndex: 0,
    singleTotal: {}, // 统计单个机巢数据
    // 项目id
    selectedWorkSpaceId: window.localStorage.getItem('bs_workspace_id'),
    // 事件 日 周 月 年
    eventTimeType: 'day',
    eventTimeParams: 'CURRENT_WEEK',
    eventTimeRang: '',
    wsMessage: {},
    deviceState: {
      gatewayInfo: {},
      deviceInfo: {},
      timestamp: '',
      dockInfo: {},
      currentSn: '',
      currentType: -1,
      drone_charge_state_new: {},
      psdk_widget_values: {},
      speakerAudioPlayStartProgress: {},
    },
    osdVisible: {
      // osd 显示设备相关信息
      sn: '',
      callsign: '',
      model: '',
      visible: false,
      gateway_sn: '',
      is_dock: false,
      payloads: null,
      device_domain: '',
      device_sub_type: '',
      device_type: '',
    },
  },
  actions: {},
  mutations: {
@@ -69,55 +41,6 @@
    setSingleUavHome: (state, data) => {
      state.singleUavHome = data;
    },
    setSingleTotal: (state, data) => {
      state.singleTotal = data;
    },
    setSelectedWorkSpaceId: (state, id) => {
      state.selectedWorkSpaceId = id
      window.localStorage.setItem('bs_workspace_id', id)
    },
    setOsdVisibleInfo: (state, info) => {
      console.log('存储',info)
      state.osdVisible = Object.assign({}, info)
      window.localStorage.setItem('bs_osd', JSON.stringify(info))
    },
    setWsMessage: (state, data) => {
      state.wsMessage = data.data.host;
    },
    setDeviceInfo: (state, data) => {
      const info = data.data
      state.deviceState.timestamp = data.timestamp
      state.deviceState.deviceInfo[info.sn] = info.host
      state.deviceState.currentSn = info.sn
      state.deviceState.currentType = EDeviceTypeName.Aircraft
    },
    setGatewayInfo: (state, info) => {
      state.deviceState.gatewayInfo[info.sn] = info.host
      state.deviceState.currentSn = info.sn
      state.deviceState.currentType = EDeviceTypeName.Gateway
    },
    setDockOnfo: (state, info) => {
      if (Object.keys(info.host).length === 0) return
            if (!state.deviceState.dockInfo[info.sn]) {
                state.deviceState.dockInfo[info.sn] = {}
            }
            state.deviceState.currentSn = info.sn
            state.deviceState.currentType = EDeviceTypeName.Dock
            const dock = state.deviceState.dockInfo[info.sn]
            if (info.host.mode_code !== undefined) {
                dock.basic_osd = info.host
                state.deviceState.drone_charge_state_new = dock.basic_osd.drone_charge_state
                return
            }
            if (info.host.sdr) {
                dock.link_osd = info.host
                return
            }
            if (info.host.job_number !== undefined) {
                dock.work_osd = info.host
            }
        },
    setEventTimeType: (state, [timeType, timeParams]) => {
      state.eventTimeType = timeType
      state.eventTimeParams = timeParams
src/views/SignMachineNest/MachineLeft/MachineData.vue
@@ -27,9 +27,9 @@
const statisticsList = ref([]);
const singleTotal = inject('singleTotal')
// 添加监听
watch(
  () => store.state.home.singleTotal,
watch(singleTotal,
  (newValue) => {
    if (!newValue) return;
    statisticsList.value = [
src/views/SignMachineNest/MachineRight/InspectionRaskList.vue
@@ -81,8 +81,7 @@
let viewer = null
let { taskDetails, workspace_id, getTaskDetails } = useTaskDetails()
let { wsInfo, removeWS } = useDroneWS(workspace_id) //ws信息,是一个ref对象
const wsInfo = inject('wsInfo')
const store = useStore()
// 设备任务详情
let currentInfoId = ref('')
@@ -200,7 +199,7 @@
const taskClick = item => {
    if (tabIndex.value === 1) {
        // 展示当前任务详情
        if (!item?.device_sns.length) return ElMessage.warning('没有device_sns');
        if (!item?.device_sns?.length) return ElMessage.warning('没有device_sns');
        if (item?.device_sns?.length !== 1) {
            // todo 后续开发
            ElMessage.success('即将跳转到集群调度');
src/views/SignMachineNest/MachineRight/MachineMonitor.vue
@@ -15,13 +15,17 @@
import CommonTitle from '@/components/CommonTitle.vue'
import LiveVideo from '@/components/LiveVideo.vue'
import { liveStart } from '@/api/home/machineNest'
// import { CURRENT_CONFIG as config } from '@/utils/http/config'
import { useStore } from 'vuex'
const store = useStore()
// 单个机巢信息
const singleUavHome = computed(() => store.state.home.singleUavHome);
const osdVisible = computed(() => store.state.home.osdVisible);
const wsInfo = inject('wsInfo')
let device_osd_info = computed(() => wsInfo.value?.device_osd || {});
let device_osd_host = computed(() => device_osd_info?.value?.data?.host || {});
const dockSn = inject('dockSn')
const droneSn = inject('droneSn')
// 直播地址
let airPortUrl = ref('')
// 获取机巢直播地址
@@ -43,17 +47,13 @@
const isTakeOff = ref(false)
// 监听ws消息
watch(() => store.state.home.deviceState, async (newValue) => {
    console.log(osdVisible.value.sn,'333333')
        const deviceInfo = newValue?.deviceInfo[osdVisible.value.sn]
        if (!deviceInfo) return
        const currentIsTakeOff = ![14, 0].includes(deviceInfo?.mode_code)
        console.log(isTakeOff.value, currentIsTakeOff,'8888')
watch(device_osd_host, async () => {
        if (!device_osd_host.value.mode_code) return
      const currentIsTakeOff = ![14, 0].includes(device_osd_host.value?.mode_code)
        // 如果还是之前的状态,不切换
        if (isTakeOff.value === currentIsTakeOff) return
        isTakeOff.value = currentIsTakeOff
        isTakeOff.value ? await getDroneLiveUrl(osdVisible.value.sn, 2) : await getVideoUrl(singleUavHome.value.device_sn, 1)
        isTakeOff.value ? await getDroneLiveUrl(droneSn.value, 2) : await getVideoUrl(dockSn.value, 1)
    },
    {
        immediate: true,
@@ -62,7 +62,7 @@
)
onMounted(() => {
    getVideoUrl(singleUavHome.value.device_sn, 1)
    getVideoUrl(dockSn.value, 2)
})
onUnmounted(() => {
    airPortUrl.value = ''
src/views/SignMachineNest/MachineRight/MachineStatus/MachineStatus.vue
@@ -7,7 +7,7 @@
                <img src="../../../../assets/images/signMachineNest/machineRight/wrj.png" alt="" />
                <div class="info-right">
                    <!-- <div class="name">{{ osdVisible?.callsign || '--' }}</div> -->
                    <div class="name">{{ osdVisible?.nickname || '--' }}</div>
                    <div class="name">{{ dockDetails?.nickname || '--' }}</div>
                    <div class="wz">
                        <span class="left">当前位置:</span>
                        <span class="right">{{ detailInfo.longitude }},{{ detailInfo.latitude }}</span>
@@ -96,16 +96,18 @@
import { useStore } from 'vuex'
import MachineTableDetails from '@/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/MachineTableDetails.vue'
const store = useStore()
// 获取机巢信息
let osdVisible = ref({}) //computed(() => store.state.home.osdVisible);
const singleUavHome = computed(() => store.state.home.singleUavHome)
const wsInfo = inject('wsInfo')
const dockDetails = inject('dockDetails')
let device_osd_info = computed(() => wsInfo.value?.device_osd || {});
let device_osd_host = computed(() => device_osd_info?.value?.data?.host || {});
let dock_osd_info = computed(() => wsInfo.value?.dock_osd || {});
let dock_osd_host = computed(() => dock_osd_info.value?.data?.host || {});
// 单个机巢统计数据
const singleTotal = computed(() => store.state.home.singleTotal)
const singleTotal = inject('singleTotal')
// 是否展示机机巢状态详情
let isShowDetails = ref(false)
let str = '--'
let drone_charge_state = ref({
    capacity_percent: '--',
    state: 0,
@@ -122,55 +124,15 @@
    capacity_percent: '--',
})
let quality = ref(['弱', '较弱', '中等', '较强', '强'])
let deviceInfo = ref({
    gateway: {
        capacity_percent: str,
        transmission_signal_quality: str,
    },
    dock: {},
    device: {
        gear: -1,
        mode_code: EModeCode.Disconnected,
        height: str,
        home_distance: str,
        horizontal_speed: str,
        vertical_speed: str,
        wind_speed: str,
        wind_direction: str,
        elevation: str,
        position_state: {
            gps_number: str,
            is_fixed: 0,
            rtk_number: str,
        },
        battery: {
            capacity_percent: str,
            landing_power: str,
            remain_flight_time: 0,
            return_home_power: str,
        },
        latitude: 0,
        longitude: 0,
    },
})
let mode_code = ref('已断开连接')
watch(
    () => store.state.home.osdVisible,
    newValue => {
        osdVisible.value = newValue
    }
)
// 监听实时信息
watch(
    () => store.state.home.wsMessage,
watch(device_osd_host,
    newValue => {
        if (newValue.mode_code === 14) return
        if (!newValue) return
        if (newValue?.mode_code === 14) return
        if (Object.keys(newValue).length === 0) return
        detailInfo.value.longitude = newValue?.longitude.toFixed(6) || '--'
        detailInfo.value.latitude = newValue?.latitude.toFixed(6) || '--'
        // console.log(window.$viewer)
        getLnglatAltitude(Number(detailInfo.value.longitude), Number(detailInfo.value.latitude), window.$viewer).then(
            res => {
                const height = newValue?.height - res?.height
@@ -191,57 +153,31 @@
    },
    { immediate: true, deep: true }
)
// EDeviceTypeName.Dock
// 获取最新机场状态
watch(
    store.state.home.deviceState,
    newValue => {
        // console.log('newValue', newValue);
        if (newValue.currentType === EDeviceTypeName.Dock && newValue?.dockInfo[newValue.currentSn]) {
            // 机场状态
            mode_code.value = EDockModeText[newValue?.dockInfo[newValue.currentSn]?.basic_osd?.mode_code]
            // this.$emit('updateModeCode', mode_code.value);
            // 舱内状态
            AircraftStatus.value =
                EModeText[
                    newValue.deviceInfo[deviceInfo.value.dock.basic_osd?.sub_device?.device_sn ?? osdVisible.sn]?.mode_code
                ]
            // 舱内关机时显示的电量
            let child_sn = newValue?.dockInfo[newValue.currentSn].basic_osd?.sub_device?.device_sn
watch(wsInfo,
    () => {
        if (dock_osd_host.value?.mode_code){
                AircraftStatus.value = EModeText?.[dock_osd_host.value?.mode_code] || '--'
            }
            // 飞机在线时取飞机中的电量
            if (newValue.deviceInfo[child_sn]) {
            if (device_osd_host.value?.battery) {
                drone_charge_state.value = {
                    capacity_percent: newValue.deviceInfo[child_sn].battery.capacity_percent,
                    state: newValue.deviceInfo[child_sn].battery.landing_power,
                }
            } else {
                // 遥控器这里拿不到值data.drone_charge_state_new == undefined 会一直报错
                if (newValue.drone_charge_state_new) {
                    drone_charge_state.value = newValue.drone_charge_state_new
                    capacity_percent: device_osd_host.value.battery.capacity_percent,
                    state: device_osd_host.value.battery.landing_power,
                }
            }
            if (osdVisible.value.visible && osdVisible.value.is_dock && osdVisible.value.gateway_sn !== '') {
                deviceInfo.value.dock = newValue.dockInfo[osdVisible.value.gateway_sn]
                deviceInfo.value.device =
                    newValue.deviceInfo[deviceInfo.value.dock.basic_osd?.sub_device?.device_sn ?? osdVisible.value.sn]
                // 设备关机即不显示信息
                // 兼容遥控器 关闭无人机 mode_code返回的是14 不是undefined
                if (
                    newValue.deviceInfo[deviceInfo.value.dock.basic_osd?.sub_device?.device_sn ?? osdVisible.value.sn]
                        ?.mode_code === undefined ||
                    newValue.deviceInfo[deviceInfo.value.dock.basic_osd?.sub_device?.device_sn ?? osdVisible.value.sn]
                        ?.mode_code == 14
                ) {
                    detailInfo.value = {
                        longitude: '--',
                        latitude: '--',
                        home_distance: '--',
                        quality: '--',
                        horizontal_speed: '--',
                        remain_flight_time: '--',
                        height: '--',
                        capacity_percent: '--',
                    }
                }
        if (device_osd_host.value?.mode_code === undefined || device_osd_host.value?.mode_code === 14) {
            detailInfo.value = {
                longitude: '--',
                latitude: '--',
                home_distance: '--',
                quality: '--',
                horizontal_speed: '--',
                remain_flight_time: '--',
                height: '--',
                capacity_percent: '--',
            }
        }
    },
@@ -343,7 +279,6 @@
                .close {
                    width: 60px;
                    height: 20px;
                    line-height: 20px;
                    background: rgba(255, 178, 106, 0.2);
                    border-radius: 4px 4px 4px 4px;
                    border: 1px solid #ffb26a;
src/views/SignMachineNest/MachineRight/MachineStatus/MachineTableDetails/MachineTableDetails.vue
@@ -57,7 +57,7 @@
    { name: '机巢状态', value: '', field: 'status' },
])
const store = useStore()
const singleTotal = computed(() => store.state.home.singleTotal)
const singleTotal = inject('singleTotal')
watch(singleTotal, val => {
    if (val?.device_info) {
        infoList.value.forEach(item => {
src/views/SignMachineNest/SignMachineNest.vue
@@ -6,14 +6,11 @@
<script setup>
import MachineLeft from '@/views/SignMachineNest/MachineLeft/MachineLeft.vue'
import MachineRight from '@/views/SignMachineNest/MachineRight/MachineRight.vue'
import { useConnectWebSocket } from '@/utils/websocket/connect-websocket'
import { getWebsocketUrl } from '@/websocket/util/config'
import { EBizCode } from '@/utils/staticData/enums.js'
import { EModeCode } from '@/utils/staticData/device.js'
import { useStore } from 'vuex'
import { getDeviceDetail, getFlightStatistics, getEventList } from '@/api/home/machineNest'
import { useSingleDroneMap } from '@/hooks/useSingleDroneMap/useSingleDroneMap'
import { useDroneWS } from '@/hooks/useDroneWS'
const store = useStore()
let connectWs = ref(null)
@@ -23,34 +20,6 @@
let osdVisible = ref({})
let workspaceId = ref('')
// 进入单个机巢开始连接ws
const createWsConntect = () => {
    let webSorketUrl = getWebsocketUrl() + '&workspace-id=' + workspaceId.value
    // 监听ws 消息
    connectWs.value = useConnectWebSocket(messageHandler, webSorketUrl)
}
const messageHandler = result => {
    let payload = JSON.parse(result) // 为了兼容聊天消息
    if (!payload) return
    switch (payload.biz_code) {
        case EBizCode.GatewayOsd: {
            store.commit('setGatewayInfo', payload.data)
            break
        }
        case EBizCode.DeviceOsd: {
            store.commit('setDeviceInfo', payload)
            store.commit('setWsMessage', payload)
            break
        }
        case EBizCode.DockOsd: {
            store.commit('setDockOnfo', payload.data)
            break
        }
        default:
            break
    }
}
// 单机巢初始化及事件撒点
const { init, initEventLayer, initDroneEntity } = useSingleDroneMap({
@@ -60,46 +29,38 @@
    },
})
let workspace_id = ref('')
let { wsInfo } = useDroneWS(workspace_id) //ws信息,是一个ref对象
const dockSn = computed(() => singleUavHome.value.device_sn) //机巢sn
const droneSn = computed(() => wsInfo.value?.device_osd?.data?.sn) //无人机sn
provide('dockSn', dockSn)
provide('droneSn', droneSn)
provide('wsInfo',wsInfo)
// 获取单个机巢信息
const dockDetails= ref('')
provide('dockDetails', dockDetails)
const getSingleDetails = () => {
    getDeviceDetail(singleUavHome.value.device_sn).then(res => {
        if (res.data.code !== 0) return
        const result = res.data.data
        dockDetails.value = result
        workspace_id.value = result.workspace_id
        initDroneEntity({
            lng: result.longitude,
            lat: result.latitude,
            status: result.status,
        })
        const child = result.children
        // 对应store 里面数据结构
        osdVisible.value.nickname = result.nickname || '--'
        osdVisible.value.sn = child?.device_sn || ''
        osdVisible.value.callsign = child?.nickname || '--'
        osdVisible.value.model = EModeCode.Disconnected || ''
        osdVisible.value.visible = true
        osdVisible.value.gateway_sn = result?.device_sn || ''
        osdVisible.value.is_dock = true
        osdVisible.value.gateway_callsign = result?.callsign || '--'
        osdVisible.value.payloads = child?.payloads_list || []
        osdVisible.value.device_domain = child.domain || 0
        osdVisible.value.device_sub_type = child.sub_type || 1
        osdVisible.value.device_type = child.type || 0
        // osdVisible.value.latest_wayline_job = result?.latest_wayline_job || {}
        store.commit('setOsdVisibleInfo', osdVisible.value)
        store.commit('setSelectedWorkSpaceId', result.workspace_id)
        workspaceId.value = result.workspace_id
        createWsConntect()
    })
}
const singleTotal = ref({})
provide('singleTotal', singleTotal)
// 获取机巢统计数据 提供给左右侧组件使用
const getMachineData = () => {
    getFlightStatistics(singleUavHome.value.device_sn).then(res => {
        if (res.data.code !== 0) return
        const result = res.data.data
        store.commit('setSingleTotal', result)
        singleTotal.value = result
    })
}