forked from drone/command-center-dashboard

罗广辉
2025-04-21 2800fa4f32f3900509cb4d6eefaf2bfaf54efdd7
src/hooks/components/useMapHandlerClick.js
@@ -2,33 +2,72 @@
 * @Author: shuishen 1109946754@qq.com
 * @Date: 2025-04-15 22:41:40
 * @LastEditors: shuishen 1109946754@qq.com
 * @LastEditTime: 2025-04-16 19:02:39
 * @LastEditTime: 2025-04-17 19:43:36
 * @FilePath: \command-center-dashboard\src\hooks\components\useMapHandlerClick.js
 * @Description: 
 * 
 * Copyright (c) 2025 by shuishen, All Rights Reserved. 
 */
import * as Cesium from 'cesium'
import { render } from 'vue'
import { useStore } from 'vuex'
import DevicePopUpBox from '@/hooks/components/DevicePopUpBox.vue'
import EventPopUpBox from '@/hooks/components/EventPopUpBox.vue'
/**
 * 
 * @param {Object} options - 配置选项
 */
export function useMapHandlerClick (viewer, options = {
  type: 'single-drone-event',
  customDom: EventPopUpBox
}) {
  const { type } = options
export function useMapHandlerClick (options = {}) {
  const {
    popupType = 'event-popup',
    eventType = 'single-drone-event',
    styleTransform = 'translate(-50%,-110%)',
    getViewer
  } = options
  const currentClickEntity = ref(null)
  const store = useStore()
  const popupData = {
    'event-popup': EventPopUpBox,
    'device-popup': DevicePopUpBox
  }
  const MapPopUpBox = popupData[popupType]
  let viewer = null
  let handler = null
  let currentClickEntity = null
  // 查找特定类型的实体
  const findEntityByType = (entities, type) => {
    return entities.find(entity =>
      entity?.properties?.customData?._value?.data?.type === type
    )
    let types = []
    Array.isArray(type) ? types = type : types = [type]
    return types.reduce((pre, curType) => {
      let entity = entities.find(entity => entity?.properties?.customData?._value?.data?.type === curType)
      return entity ? (pre.push({
        type: curType,
        entity
      }), pre) : pre
    }, [])
  }
  const publicEvent = (entity) => {
    viewer.scene.postRender.addEventListener(labelBoxRender)
  }
  const typeEvent = {
    'deviceAggregation': publicEvent,
    'single-drone-event': publicEvent,
    'event': publicEvent,
    'device': (entity) => {
      const device = entity.properties.customData._value.data
      store.commit('setSingleUavHome', device)
    }
  }
  // 左键单机事件
@@ -36,17 +75,21 @@
    let clickedEntities = viewer?.scene.drillPick(click.position).map(item => item.id)
    if (!clickedEntities.length) return
    currentClickEntity.value = findEntityByType(clickedEntities, type)
    let curClick = findEntityByType(clickedEntities, eventType)
    removeLabel()
    if (currentClickEntity.value) {
      viewer?.scene.postRender.addEventListener(labelBoxRender)
    if (curClick.length > 0 && typeEvent[curClick[0].type]) {
      currentClickEntity = curClick[0].entity
      typeEvent[curClick[0].type](currentClickEntity)
    }
  }
  // 事件初始化
  const handlerInit = () => {
    !viewer && (viewer = getViewer())
    if (handler) return
    handler = new Cesium.ScreenSpaceEventHandler(viewer?.scene.canvas)
@@ -62,7 +105,7 @@
  // 获取弹框box
  const getLabelDom = data => {
    const vNode = h(customDom, { data, removeLabel })
    const vNode = h(MapPopUpBox, { data, removeLabel })
    const tooltipContainer = document.createElement('div')
    tooltipContainer.id = 'mapPopUpBox'
    tooltipContainer.style.position = 'absolute'
@@ -75,12 +118,12 @@
  // 弹框位置刷新
  const labelBoxRender = () => {
    if (!currentEntity) return
    if (!currentClickEntity) return
    let dom = document.querySelector('#mapPopUpBox')
    if (!dom) {
      dom = getLabelDom(currentEntity.properties.customData._value.data)
      dom = getLabelDom(currentClickEntity.properties.customData._value.data)
    }
    const screenPosition = viewer?.scene.cartesianToCanvasCoordinates(currentEntity?.position?._value)
    const screenPosition = viewer?.scene.cartesianToCanvasCoordinates(currentClickEntity?.position?._value)
    if (screenPosition) {
      dom.style.left = `${screenPosition.x}px`
      dom.style.top = `${screenPosition.y}px`
@@ -101,15 +144,19 @@
    removeDom()
  }
  // 自动清理
  onUnmounted(() => {
  const removeAll = () => {
    removeHandler()
    removeLabel()
  }
  // 自动清理
  onUnmounted(() => {
    removeAll()
  })
  return {
    currentClickEntity,
    handlerInit,
    removeHandler
    removeAll,
    removeLabel
  }
}