From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/components/Map/index.vue |  268 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 268 insertions(+), 0 deletions(-)

diff --git a/src/components/Map/index.vue b/src/components/Map/index.vue
new file mode 100644
index 0000000..7b9ae1c
--- /dev/null
+++ b/src/components/Map/index.vue
@@ -0,0 +1,268 @@
+<!-- 鍦板浘缁勪欢锛氬熀浜庣櫨搴﹀湴鍥綠L瀹炵幇 -->
+<!-- TODO @super锛氳繕瀛樺湪涓や釜娌¤В鍐崇殑灏廱ug,涓�涓槸淇敼鎵嬪姩瀹氫綅鏃朵竴娆″姞杞� 涓嶇煡閬撲负浣曞畾浣嶇偣鍦ㄥ湴鍥惧乏涓婅 璋冧簡鍗婂ぉ娌¤В鍐� 绗簩涓槸妫�绱㈠湴鍧�纭畾瀹氫綅鐨勫姛鑳藉弬鐓х櫨搴︾殑鏂囨。娌′篃鎼炲ソ 鍥炲ご鍐嶈В鍐充竴涓� -->
+<template>
+  <div v-if="props.isWrite">
+    <el-form ref="form" label-width="120px">
+      <el-form-item label="瀹氫綅浣嶇疆:">
+        <el-select
+          class="w-full"
+          v-model="state.address"
+          clearable
+          filterable
+          remote
+          reserve-keyword
+          placeholder="鍙緭鍏ュ湴鍧�鏌ヨ缁忕含搴�"
+          :remote-method="autoSearch"
+          @change="handleAddressSelect"
+          :loading="state.loading"
+        >
+          <el-option
+            v-for="item in state.mapAddrOptions"
+            :key="item.value"
+            :label="item.name"
+            :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="璁惧鍦板浘:">
+        <!-- TODO @super锛氳繖閲岀湅鐪� unocss 鍝� -->
+        <div id="bdMap" class="mapContainer"></div>
+      </el-form-item>
+    </el-form>
+  </div>
+  <div v-else>
+    <el-descriptions :column="2" border :labelStyle="{ 'font-weight': 'bold' }">
+      <el-descriptions-item label="璁惧浣嶇疆:">{{ state.address }}</el-descriptions-item>
+    </el-descriptions>
+    <div id="bdMap" class="mapContainer"></div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { reactive, onMounted } from 'vue'
+import { propTypes } from '@/utils/propTypes'
+
+// 鎵╁睍 Window 鎺ュ彛浠ュ寘鍚櫨搴﹀湴鍥� GL API
+declare global {
+  interface Window {
+    BMapGL: any
+    initBaiduMap: () => void
+  }
+}
+
+const emits = defineEmits(['locateChange', 'update:center'])
+const state = reactive({
+  lonLat: '', // 缁忓害,绾害
+  address: '',
+  loading: false,
+  latitude: '', // 绾害
+  longitude: '', // 缁忓害
+  map: null as any, // 鍦板浘瀵硅薄
+  mapAddrOptions: [] as any[],
+  mapMarker: null as any, // 鏍囪瀵硅薄
+  geocoder: null as any,
+  autoComplete: null as any,
+  tips: [] // 鎼滅储鎻愮ず
+})
+
+const props = defineProps({
+  clickMap: propTypes.bool.def(false),
+  isWrite: propTypes.bool.def(false),
+  center: propTypes.string.def('')
+})
+
+/** 鍔犺浇鐧惧害鍦板浘 */
+const loadMap = () => {
+  state.address = ''
+  state.latitude = ''
+  state.longitude = ''
+
+  // 鍒涘缓鐧惧害鍦板浘 API 鑴氭湰锛屽姩鎬佸姞杞�
+  const script = document.createElement('script')
+  script.src = `https://api.map.baidu.com/api?v=1.0&type=webgl&ak=${
+    import.meta.env.VITE_BAIDU_MAP_KEY
+  }&callback=initBaiduMap`
+  document.body.appendChild(script)
+
+  // 瀹氫箟鍏ㄥ眬鍥炶皟鍑芥暟
+  window.initBaiduMap = () => {
+    initMap()
+    initGeocoder()
+    initAutoComplete()
+
+    // TODO @super锛氳繖閲屽姞涓�琛屾敞閲�
+    if (props.clickMap) {
+      state.map.addEventListener('click', (e: any) => {
+        console.log(e)
+        const point = e.latlng
+        console.log(point)
+        state.lonLat = point.lng + ',' + point.lat
+        console.log(state.lonLat)
+        regeoCode(state.lonLat)
+      })
+    }
+
+    // TODO @super锛氳繖閲屽姞涓�琛屾敞閲�
+    if (props.center) {
+      regeoCode(props.center)
+    }
+  }
+}
+
+/** 鍒濆鍖栧湴鍥� */
+const initMap = () => {
+  const mapId = 'bdMap'
+  state.map = new window.BMapGL.Map(mapId)
+  // TODO @super锛氳繖涓槸榛樿鐨勫搰锛�
+  state.map.centerAndZoom(new window.BMapGL.Point(116.404, 39.915), 11)
+  state.map.enableScrollWheelZoom()
+  state.map.disableDoubleClickZoom()
+
+  // 娣诲姞鍦板浘鎺т欢
+  state.map.addControl(new window.BMapGL.NavigationControl())
+  state.map.addControl(new window.BMapGL.ScaleControl())
+  state.map.addControl(new window.BMapGL.ZoomControl())
+}
+
+/** 鍒濆鍖栧湴鐞嗙紪鐮佸櫒 */
+const initGeocoder = () => {
+  state.geocoder = new window.BMapGL.Geocoder()
+}
+
+/** 鍒濆鍖栬嚜鍔ㄥ畬鎴� */
+const initAutoComplete = () => {
+  state.autoComplete = new window.BMapGL.Autocomplete({
+    input: 'searchInput',
+    location: state.map
+  })
+}
+
+/**
+ * 鎼滅储鍦板潃
+ * @param queryValue 鎼滅储鍏抽敭璇�
+ */
+const autoSearch = (queryValue: string) => {
+  if (!queryValue) {
+    state.mapAddrOptions = []
+    return
+  }
+
+  state.loading = true
+
+  // 浣跨敤鐧惧害鍦板浘鍦扮偣妫�绱㈡湇鍔�
+  const localSearch = new window.BMapGL.LocalSearch(state.map, {
+    onSearchComplete: (results: any) => {
+      state.loading = false
+      const temp: any[] = []
+
+      if (results && results.getPoi) {
+        const pois = results.getPoi()
+        pois.forEach((p: any) => {
+          const point = p.point
+          if (point && point.lng && point.lat) {
+            temp.push({
+              name: p.title,
+              value: point.lng + ',' + point.lat
+            })
+          }
+        })
+      }
+
+      state.mapAddrOptions = temp
+    }
+  })
+
+  localSearch.search(queryValue)
+}
+
+/**
+ * 澶勭悊鍦板潃閫夋嫨
+ * @param value 閫変腑鐨勫湴鍧�鍊�
+ */
+const handleAddressSelect = (value: string) => {
+  if (value) {
+    regeoCode(value)
+  }
+}
+
+/**
+ * 娣诲姞鏍囪鐐�
+ * @param lnglat 缁忕含搴︽暟缁�
+ */
+// TODO @super锛氭嫾鍐欙紱灏介噺涓嶈鏈� idea 缁胯壊鎻愰啋鍝�
+const setMarker = (lnglat: any) => {
+  if (!lnglat) return
+
+  // 濡傛灉鐐规爣璁板凡瀛樺湪鍒欏厛绉婚櫎鍘熺偣
+  if (state.mapMarker !== null) {
+    state.map.removeOverlay(state.mapMarker)
+    state.lonLat = ''
+  }
+
+  // 鍒涘缓鏂扮殑鏍囪鐐�
+  const point = new window.BMapGL.Point(lnglat[0], lnglat[1])
+  state.mapMarker = new window.BMapGL.Marker(point)
+
+  // 娣诲姞鐐规爣璁板埌鍦板浘
+  state.map.addOverlay(state.mapMarker)
+  state.map.centerAndZoom(point, 16)
+}
+
+/**
+ * 缁忕含搴﹁浆鍖栦负鍦板潃銆佹坊鍔犳爣璁扮偣
+ * @param lonLat 缁忓害,绾害瀛楃涓�
+ */
+// TODO @super锛氭嫾鍐欙紱灏介噺涓嶈鏈� idea 缁胯壊鎻愰啋鍝�
+const regeoCode = (lonLat: string) => {
+  if (!lonLat) return
+
+  // TODO @super锛氭嫾鍐欙紱灏介噺涓嶈鏈� idea 缁胯壊鎻愰啋鍝�
+  const lnglat = lonLat.split(',')
+  if (lnglat.length !== 2) return
+
+  state.longitude = lnglat[0]
+  state.latitude = lnglat[1]
+
+  // 閫氱煡鐖剁粍浠朵綅缃彉鏇�
+  emits('locateChange', lnglat)
+  emits('update:center', lonLat)
+
+  // 鍏堝皢鍦板浘涓績鐐硅缃埌鐩爣浣嶇疆
+  const point = new window.BMapGL.Point(lnglat[0], lnglat[1])
+  state.map.centerAndZoom(point, 16)
+
+  // 鍐嶈缃爣璁板苟鑾峰彇鍦板潃
+  setMarker(lnglat)
+  getAddress(lnglat)
+}
+
+// TODO @super锛歭nglat 鎷煎啓
+/**
+ * 鏍规嵁缁忕含搴﹁幏鍙栧湴鍧�淇℃伅
+ *
+ * @param lnglat 缁忕含搴︽暟缁�
+ */
+const getAddress = (lnglat: any) => {
+  const point = new window.BMapGL.Point(lnglat[0], lnglat[1])
+
+  state.geocoder.getLocation(point, (result: any) => {
+    if (result && result.address) {
+      state.address = result.address
+    }
+  })
+}
+
+/** 鏄惧紡鏆撮湶鏂规硶锛屼娇鍏跺彲浠ヨ鐖剁粍浠惰闂� */
+defineExpose({ regeoCode })
+
+onMounted(() => {
+  loadMap()
+})
+</script>
+
+<style scoped>
+.mapContainer {
+  width: 100%;
+  height: 400px;
+}
+</style>

--
Gitblit v1.8.0