8
0
duy 3 месяцев назад
Родитель
Сommit
e5f9790bf4
5 измененных файлов с 324 добавлено и 34 удалено
  1. 17 15
      src/components/index.js
  2. 281 0
      src/components/map/info-map1.vue
  3. 3 0
      src/main.js
  4. 14 1
      src/views/project/detail/info.vue
  5. 9 18
      yarn.lock

+ 17 - 15
src/components/index.js

@@ -1,21 +1,23 @@
-import { setupDirective } from "./directive/index";
-import HcMenuIcon from "./menu-icon/menu-icon.vue";
-import HcIconInput from "./icon-input/icon-input.vue";
-import HcRelatedProject from "./related-project/related-project.vue";
-import HcTableForm from "./table-form/table-form.vue";
-import HcInfoTable from "./info-table/info-table.vue";
-import HcInfoTableTd from "./info-table/info-table-td.vue";
+import { setupDirective } from './directive/index'
+import HcMenuIcon from './menu-icon/menu-icon.vue'
+import HcIconInput from './icon-input/icon-input.vue'
+import HcRelatedProject from './related-project/related-project.vue'
+import HcTableForm from './table-form/table-form.vue'
+import HcInfoTable from './info-table/info-table.vue'
+import HcInfoTableTd from './info-table/info-table-td.vue'
+
 
 //注册全局组件
 export const setupComponents = (App) => {
     //自定义指令
-    setupDirective(App);
+    setupDirective(App)
 
     //自定义组件
-    App.component("HcMenuIcon", HcMenuIcon);
-    App.component("HcIconInput", HcIconInput);
-    App.component("HcRelatedProject", HcRelatedProject);
-    App.component("HcTableForm", HcTableForm);
-    App.component("HcInfoTable", HcInfoTable);
-    App.component("HcInfoTableTd", HcInfoTableTd);
-};
+    App.component('HcMenuIcon', HcMenuIcon)
+    App.component('HcIconInput', HcIconInput)
+    App.component('HcRelatedProject', HcRelatedProject)
+    App.component('HcTableForm', HcTableForm)
+    App.component('HcInfoTable', HcInfoTable)
+    App.component('HcInfoTableTd', HcInfoTableTd)
+   
+}

+ 281 - 0
src/components/map/info-map1.vue

@@ -0,0 +1,281 @@
+<template>
+    <hc-dialog
+        v-model="isShow" is-table widths="1200px" title="选择地图" @close="cancel"
+    >
+        <div class="amap-box">
+            <el-input id="keyword" v-model="tipInput" clearable placeholder="关键词搜索" />
+            <div id="custom-amap" />
+            <div id="my-panel" />
+            <div v-if="address" class="info-list">
+                <div class="info-item">已选择地点:{{ address }}</div>
+                <div class="info-item">地点经纬度:{{ point }}</div>
+            </div>
+        </div>
+        <template #footer>
+            <el-button hc-btn type="primary" @click="save">确定</el-button>
+        </template>
+    </hc-dialog>
+</template>
+  
+  <script setup>
+  import { onUnmounted, ref, watch } from 'vue'
+  import AMapLoader from '@amap/amap-jsapi-loader'
+
+
+
+  
+  const props = defineProps({
+    defaultAddress: {
+      type: String,
+      default: '',
+    },
+    defaultPoint: {
+      type: Array,
+      default:[],
+    },
+    isShow: {
+      type: Boolean,
+      default: false,
+    },
+  }) 
+  const emit = defineEmits(['finish', 'close'])
+  const map = ref(null) // 地图对象
+  const address = ref('') // 地址
+  const point = ref([]) // 地址对应的经纬度信息
+  
+  const marker = ref('') // 地图标记
+  const geocoder = ref('') // 地址解析(正向)
+  
+  const tipInput = ref(props.defaultAddress) // 检索关键字
+  const autoComplete = ref(null)
+  const placeSearch = ref(null)
+  
+  const isShow = defineModel('modelValue', {
+    default: false,
+})
+  window._AMapSecurityConfig = {
+  securityJsCode: 'dfd9c521e218fb29772123a488e68c80', //申请key时的安全密钥
+}
+
+
+watch(() => props.defaultAddress, (data) => {
+    tipInput.value = data
+}, { immediate: true, deep: true })
+//监听显示
+watch(isShow, (val) => {
+    if (val) {
+        initMap()
+    }
+})
+  
+  //   初始化地图页面
+  const initMap = () => {
+    AMapLoader.load({
+      key: 'dfd9c521e218fb29772123a488e68c80', // 申请好的Web端开发者Key,首次调用 load 时必填
+      version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
+      plugins: [
+        'AMap.ToolBar',
+        'AMap.Scale',
+        'AMap.HawkEye',
+        'AMap.MapType',
+        'AMap.Geolocation',
+        'AMap.AutoComplete',
+        'AMap.PlaceSearch',
+        'AMap.Geocoder',
+      ], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
+    })
+      .then((AMap) => {
+        const tempCenter = props.defaultPoint[0]
+          ? props.defaultPoint
+          : [118.784136, 32.041806]
+        map.value = new AMap.Map('custom-amap', {
+          // 设置地图容器id
+          viewMode: '2D', // 是否为3D地图模式
+          zoom: 12, // 初始化地图级别
+          showLabel: true, // 是否展示地图文字和 POI 信息。
+          resizeEnable: true,
+          center: tempCenter, // 初始化地图中心点位置
+        })
+        // 如果父组件传入了有效值 回显一个icon
+        if (props.defaultPoint.length > 0) {
+          address.value = props.defaultAddress
+          point.value = props.defaultPoint
+          addMarker()
+        }
+        // 地图点击事件
+        map.value.on('click', clickMapHandler)
+  
+        // 引入高德地图的空间绑定使用
+        map.value.addControl(new AMap.Scale())
+        map.value.addControl(new AMap.ToolBar())
+        map.value.addControl(new AMap.HawkEye())
+        map.value.addControl(new AMap.MapType())
+        map.value.addControl(new AMap.Geolocation())
+  
+        // 搜索框自动完成类
+        autoComplete.value = new AMap.AutoComplete({
+          input: 'keyword', // input 为绑定输入提示功能的input的DOM ID
+        })
+        // 构造地点查询类
+        placeSearch.value = new AMap.PlaceSearch({
+          map: map.value,
+          panel: 'my-panel', //结果列表将在此容器中进行展示。
+          autoFitView: true, //是否自动调整地图视野使绘制的 Marker 点都处于视口的可见范围
+          pageSize: 5, //单页显示结果条数
+          pageIndex: 1, //页码
+        })
+        // 当选中某条搜索记录时触发
+        autoComplete.value.on('select', selectHandler)
+        // poi覆盖物点击事件
+        placeSearch.value.on('markerClick', clickMarkerHandler)
+
+      
+      })
+      .catch((e) => {
+        console.log(e)
+      })
+  }
+  
+  
+  const clickMapHandler = (e) => {
+    const lng = e.lnglat.lng
+    const lat = e.lnglat.lat
+    point.value = [lng, lat]
+    // 增加点标记
+    addMarker()
+    // 获取地址
+    getAddress()
+  }
+  
+  // 增加点标记
+  const addMarker = () => {
+    
+    // 清除其他icon
+    if (marker.value) {
+      marker.value.setMap(null)
+      marker.value = null
+    }
+    // 重新渲染icon
+    marker.value = new AMap.Marker({
+      position: point.value, // icon经纬度
+      offset: new AMap.Pixel(-13, -30), // icon中心点的偏移量
+      icon: new AMap.Icon({
+        image:
+          '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',
+        size: new AMap.Size(30, 40), // 图标大小
+        imageSize: new AMap.Size(30, 40),
+      }),
+    })
+    marker.value.setMap(map.value) // 设置icon
+  }
+  
+  // 将经纬度转换为地址
+  const getAddress = () => {
+    // 获取地址,这里通过高德 SDK 完成。
+    geocoder.value = new AMap.Geocoder()
+    // 调用逆解析方法, 个人开发者调用量上限5000(次/日)
+    geocoder.value.getAddress(point.value, (status, result) => {
+      if (status === 'complete' && result.info === 'OK') {
+        if (result && result.regeocode) {
+          address.value = result.regeocode.formattedAddress
+          tipInput.value = result.regeocode.formattedAddress
+        }
+      }
+    })
+  }
+  // 当选中某条记录时会触发
+  const selectHandler = (e) => {
+    
+    placeSearch.value.setCity(e.poi.adcode)
+    // placeSearch.value.search(e.poi.name) // 关键字查询查询
+    //在回调函数中使用插件功能
+    placeSearch.value.search(e.poi.name, function (status, result) {
+
+            const panelElement = document.getElementById('my-panel')
+            panelElement.addEventListener('click', function (event) {
+            // 判断点击的目标是否是搜索结果项
+            const clickedItem = event.target.closest('.poibox')
+            if (clickedItem) {
+                let index = clickedItem.getAttribute('data-idx')
+                const poi = result.poiList.pois[index] // 获取对应索引的POI(兴趣点)信息
+
+                // 这里你可以执行相关操作,比如在地图上标记点击的点,或显示详细信息
+                console.log('点击的 POI 信息:', poi)
+                tipInput.value = poi.name
+                address.value = poi.name
+                point.value = [poi.location.lng, poi.location.lat]
+                map.value.setCenter(poi.location) // 跳转到点击的地点
+                // 如果需要,还可以在地图上添加 Marker 或显示信息窗口等
+            }
+            })
+
+    })
+  }
+  
+  
+  
+  // 点击poi覆盖物事件
+  const clickMarkerHandler = (e) => {
+    point.value = [e.data.location.lng, e.data.location.lat]
+    getAddress()
+  }
+  
+
+  const cancel = () => {
+    emit('close')
+  }
+  const save = () => {
+    emit('finish', tipInput.value)
+  }
+  onUnmounted(() => {
+    map.value && map.value.destroy()
+  })
+  </script>
+  
+  <style lang="scss" scoped>
+  #my-panel{
+    position: absolute;
+    top: 10px;
+    right: 10px;
+    z-index: 99;
+    width: 400px !important;
+
+
+
+}
+  .amap-box {
+    padding: 5px 0 0;
+    #custom-amap {
+      width: 100%;
+      height: 600px;
+      margin-top: 10px;
+      border: 1px solid #ccc;
+    }
+  
+    .input-with {
+      width: 580px;
+      z-index: 1;
+    }
+  
+    .address {
+      color: #373737;
+    }
+    .info-list {
+      padding: 5px 5px 0;
+      line-height: 24px;
+    }
+  }
+  </style>
+  
+  <style lang="scss">
+  .select-map-dialog {
+    .el-dialog__body {
+      padding-top: 3px;
+      padding-bottom: 3px;
+    }
+  }
+  .amap-sug-result {
+    z-index: 2024;
+  }
+  </style>
+  

+ 3 - 0
src/main.js

@@ -5,10 +5,13 @@ import setupPinia from './store/init'
 import router, { setupRouter } from './router'
 import App from './App.vue'
 
+
 //挂载全局
 import { setupComponents } from '~com'
 import { setupInstall } from '~com/install'
 
+
+  
 //创建实例
 async function bootstrap() {
     const app = createApp(App)

+ 14 - 1
src/views/project/detail/info.vue

@@ -193,7 +193,7 @@
                 <el-row :gutter="20">
                     <el-col :span="24">
                         <el-form-item label="项目地址:" prop="projectPlace">
-                            <el-input v-model="contractForm.projectPlace" clearable />
+                            <el-input v-model="contractForm.projectPlace" clearable @click="handleMapDialog" />
                         </el-form-item>
                     </el-col>
                     <el-col :span="8">
@@ -223,6 +223,8 @@
             <el-button hc-btn class="mr-4" :loading="submitLoading" @click="saveAndExit">保存并退出</el-button>
             <el-button hc-btn type="primary" :loading="submitLoading" @click="saveAndNextStep">保存并进入下一步</el-button>
         </div>
+        <!-- <HcInfoMap v-model="showMap" :address-text="contractForm.projectPlace" @close="mapClose" /> -->
+        <amap v-model="showMap" :default-address="contractForm.projectPlace" @finish="mapClose" />
     </div>
 </template>
 
@@ -231,6 +233,7 @@ import { onMounted, ref, watch } from 'vue'
 import { deepClone, formValidate, getArrValue, getObjValue, isNullES } from 'js-fast-way'
 import { getDictionaryData } from '~uti/tools'
 import HcMeterTable from './table.vue'
+import amap from '../../../components/map/info-map1.vue'
 
 //请求接口
 import mainApi from '~api/project/contract'
@@ -442,6 +445,16 @@ const saveDataApi = async () => {
     submitLoading.value = false
     return code === 200
 }
+const showMap = ref(false)
+const handleMapDialog = ()=>{
+    showMap.value = true
+}
+const mapClose = (val)=>{
+    console.log(val, 'val')
+    
+    showMap.value = false
+    contractForm.value.projectPlace = val
+}
 </script>
 
 <style scoped lang="scss">

+ 9 - 18
yarn.lock

@@ -7,6 +7,11 @@
   resolved "http://39.108.216.210:9000/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf"
   integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==
 
+"@amap/amap-jsapi-loader@^1.0.1":
+  version "1.0.1"
+  resolved "http://39.108.216.210:9000/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz#9ec4b4d5d2467eac451f6c852e35db69e9f9f0c0"
+  integrity sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw==
+
 "@ampproject/remapping@^2.2.0":
   version "2.2.1"
   resolved "http://39.108.216.210:9000/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630"
@@ -3010,16 +3015,8 @@ streamx@^2.15.0:
   optionalDependencies:
     bare-events "^2.2.0"
 
-"string-width-cjs@npm:string-width@^4.2.0":
-  version "4.2.3"
-  resolved "http://39.108.216.210:9000/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
-  integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
-  dependencies:
-    emoji-regex "^8.0.0"
-    is-fullwidth-code-point "^3.0.0"
-    strip-ansi "^6.0.1"
-
-string-width@^4.1.0:
+"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
+  name string-width-cjs
   version "4.2.3"
   resolved "http://39.108.216.210:9000/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
   integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -3051,14 +3048,8 @@ string_decoder@~1.1.1:
   dependencies:
     safe-buffer "~5.1.0"
 
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
-  version "6.0.1"
-  resolved "http://39.108.216.210:9000/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
-  integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
-  dependencies:
-    ansi-regex "^5.0.1"
-
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+  name strip-ansi-cjs
   version "6.0.1"
   resolved "http://39.108.216.210:9000/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
   integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==