吉安感知网项目-前端
shuishen
2026-02-03 89380e6260a75d1d3b94de687ebcc2f50d50659d
applications/drone-command/src/views/areaManage/precinctInfo/FormDiaLog.vue
@@ -111,15 +111,17 @@
</template>
<script setup>
import { computed, nextTick, ref } from 'vue'
import { computed, nextTick, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { fwPoliceStationDetailApi, fwPoliceStationSubmitApi } from './precinctInfoApi'
import { fieldRules } from '@ztzf/utils'
import { contactPhoneRules, fieldRules } from '@ztzf/utils'
import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue'
import * as Cesium from 'cesium'
import axios from 'axios'
import { saveOperationLog } from '@ztzf/apis'
import { useRoute } from 'vue-router'
import positionIcon from '@/assets/images/areaManage/positionIcon.png'
import { MapTooltip } from '@ztzf/utils'
const initForm = () => ({
   address: '', // 位置
@@ -145,7 +147,7 @@
   address: fieldRules(true, 50),
   stationName: fieldRules(true, 50),
   contactPerson: fieldRules(true, 50),
   contactPhone: fieldRules(true, 50),
   contactPhone: contactPhoneRules(true, 50),
   longitude: fieldRules(true),
}
@@ -184,8 +186,12 @@
let viewer
let redPointEntity
let leftClickBound = false
let mouseMoveBound = false
let mapTooltip
let publicCesium
const tooltipEventKey = 'precinct-info-point-tip'
const labelParams = {
   font: '16px',
   font: '18px',
   fillColor: Cesium.Color.WHITE, // 文字颜色:白色
   backgroundColor: Cesium.Color.BLACK, //背景颜色
   backgroundPadding: new Cesium.Cartesian2(5, 5), // 水平/垂直内边距(像素)
@@ -200,17 +206,17 @@
}
function LeftClickEvent(click) {
   const pos = click.position // Cartesian2 屏幕坐标
   // 屏幕坐标 -> 椭球面坐标(不考虑地形/模型)
   const cartesian3 = viewer.camera.pickEllipsoid(pos, viewer.scene.globe.ellipsoid)
   if (!cartesian3) {
      return { longitude: 112, latitude: 23 }
   const pos = click.position
   // 优先使用 pickPosition 获取贴地坐标(包含地形高度)
   let cartesian3 = viewer.scene.pickPosition(pos)
   // 如果 pickPosition 失败,回退到 pickEllipsoid
   if (!cartesian3 || !Cesium.defined(cartesian3)) {
      cartesian3 = viewer.camera.pickEllipsoid(pos, viewer.scene.globe.ellipsoid)
   }
   // 椭球面坐标 -> 经纬度
   if (!cartesian3) return
   const carto = Cesium.Cartographic.fromCartesian(cartesian3)
   const longitude = Cesium.Math.toDegrees(carto.longitude)
   const latitude = Cesium.Math.toDegrees(carto.latitude)
   // 直接更新 formData
   formData.value.longitude = _.round(longitude, 6)
   formData.value.latitude = _.round(latitude, 6)
   getLocationName(longitude, latitude)
@@ -219,14 +225,16 @@
   if (!redPointEntity) {
      redPointEntity = viewer.entities.add({
         position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
         point: {
            color: Cesium.Color.RED,
            pixelSize: 10,
         billboard: {
            image: positionIcon,
            width: 20,
            height: 20,
            verticalOrigin: Cesium.VerticalOrigin.CENTER,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
         },
         label: {
            text: `${longitude.toFixed(6)}, ${latitude.toFixed(6)}`,
            ...labelParams
            ...labelParams,
         },
      })
   } else {
@@ -240,14 +248,16 @@
   if (!redPointEntity) {
      redPointEntity = viewer.entities.add({
         position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
         point: {
            color: Cesium.Color.RED,
            pixelSize: 10,
         billboard: {
            image: positionIcon,
            width: 20,
            height: 20,
            verticalOrigin: Cesium.VerticalOrigin.CENTER,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
         },
         label: {
            text: `${longitude.toFixed(6)}, ${latitude.toFixed(6)}`,
            ...labelParams
            ...labelParams,
         },
      })
   } else {
@@ -266,12 +276,38 @@
   await nextTick()
   const map = inlineMapRef.value?.getMap()
   viewer = map?.viewer || null
   publicCesium = map?.publicCesium || null
   if (viewer && !leftClickBound) {
      map.publicCesium?.addLeftClickEvent?.(null, LeftClickEvent)
      leftClickBound = true
   }
   if (viewer && !readonly.value) {
      ensurePointTooltip()
   }
   if (formData.value.longitude != null && formData.value.latitude != null) {
      setMapPoint(formData.value.longitude, formData.value.latitude)
   }
}
function ensurePointTooltip() {
   if (!viewer || !publicCesium || mouseMoveBound) return
   mapTooltip ||= new MapTooltip(viewer, { offset: { x: 16, y: 24 } })
   publicCesium.addMouseHandler?.(
      null,
      movement => {
         if (!visible.value || readonly.value) return
         mapTooltip?.show('点击地图选择派出所位置', movement.endPosition)
      },
      tooltipEventKey
   )
   mouseMoveBound = true
}
function clearPointTooltip() {
   mapTooltip?.hide()
   if (publicCesium && mouseMoveBound) {
      publicCesium.removeMouseHandler?.(tooltipEventKey)
      mouseMoveBound = false
   }
}
@@ -291,6 +327,7 @@
   formData.value = dialogMode.value === 'add' ? initForm() : row
   redPointEntity = null
   leftClickBound = false
   clearPointTooltip()
   if (dialogMode.value !== 'add') {
      await loadDetail()
   }
@@ -300,6 +337,15 @@
   }, 500)
}
watch(
   () => visible.value,
   val => {
      if (!val) {
         clearPointTooltip()
      }
   }
)
defineExpose({ open })
</script>
<style scoped lang="scss">