Files
new-cashier/jeepay-ui-manager/src/components/JeepayUIComponents/JeepayAmap/JeepayAmap.vue
2024-05-23 14:39:33 +08:00

256 lines
7.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!--
封装高德地图选址组件
initMapData: { areacode:[], areacodeNames:[], address: '', lnglat: '' } //areacode 位置、 省市县名称字符串数组、 详细地址, 经纬度(中间,分割)
@author terrfly
@site https://www.jeequan.com
@date 2022/05/07 11:34
-->
<template>
<a-row>
<a-col :span="isMobile ? 24 : 12">
<a-form-item label="选址省/市/区" name="areacode">
<JeepayAreaSelect
ref="jeepayAreaSelect"
v-model:value="vdata.mapData.areacode"
@change="changeAreaCodeFunc"
:getPopupContainer="(triggerNode) => (triggerNode.parentElement)"
/>
</a-form-item>
</a-col>
<a-col :span="isMobile ? 24 : 12">
<a-form-item label="具体位置" name="address">
<a-input
id="amap-search-input"
v-model:value="vdata.mapData.address"
autoComplete="off"
/>
</a-form-item>
</a-col>
<a-col :span="isMobile ? 24 : 12">
<a-form-item label="经纬度" name="lnglat">
<a-input v-model:value="vdata.mapData.lnglat" autoComplete="off" />
</a-form-item>
</a-col>
</a-row>
<a-collapse v-model:activeKey="vdata.showKey" @change="changeMap">
<a-collapse-panel key="map" header="地图选址">
<div :id="vdata.mapDivId" :style="{width: '100%', height: isMobile?'300px':'600px'}">MAP</div>
</a-collapse-panel>
</a-collapse>
</template>
<script lang="ts" setup>
import { $getMapConfig } from '@/api/manage'
import { reactive, ref, inject } from 'vue'
import AMapLoader from '@amap/amap-jsapi-loader'
// emit 父组件使用: v-model="val" 进行双向绑定。
const emit = defineEmits(['update:value', 'change'])
// 参数注入: 是否手机端
let isMobile : any = inject('isMobile')
const vdata: any = reactive({
showKey: 'map',
mapData: { areacode: [], areacodeNames: [], address: '', lnglat: '' }, //areacode 位置、 省市县、
mapDivId: 'mapDIV_' + new Date().getTime()
})
const jeepayAreaSelect = ref()
// 地图对象
let AMapInstantiate = null as any // 地图实例
let AMapDefine = null as any // 地图定义,初始成功返回的定义对象, 可以通过 AMapDefine.map等获取
let AMapDistrictSearch = null as any // 区域搜索插件
let AMapMarker = null as any //标记点
let AutoComplete = null as any //自动录入组件
/** 初始化 */
function init(initMapData) {
// 清空数据
vdata.mapData.areacode = initMapData.areacode || []
// vdata.mapData.areacodeNames = initMapData.areacodeNames || []
vdata.mapData.lnglat = initMapData.lnglat
vdata.mapData.address = initMapData.address
AMapInstantiate = null as any // 地图实例
AMapDefine = null as any // 地图定义,初始成功返回的定义对象, 可以通过 AMapDefine.map等获取
AMapDistrictSearch = null as any // 区域搜索插件
AMapMarker = null as any //标记点
AutoComplete = null as any //自动录入组件
// 获取地图配置参数
$getMapConfig()
.then((res) => {
// @ts-ignore window._AMapSecurityConfig
window._AMapSecurityConfig = { securityJsCode: res.apiMapWebSecret }
return AMapLoader.load({
// 申请好的Web端开发者Key首次调用 load 时必填
key: res.apiMapWebKey,
// 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
version: '2.0',
// 同步加载插件
plugins: [
'AMap.ToolBar',
'AMap.Scale',
'AMap.Marker',
'AMap.PlaceSearch',
'AMap.AutoComplete',
'AMap.Geocoder',
'AMap.DistrictSearch',
],
})
})
.then((AMap) => {
// 定义
AMapDefine = AMap
// 实例化
AMapInstantiate = new AMapDefine.Map(vdata.mapDivId, {
viewMode: '3D',
})
AMapInstantiate.addControl(new AMapDefine.ToolBar()) // 工具栏
AMapInstantiate.addControl(new AMapDefine.Scale()) // 比例尺
// geocoder 地理位置查询插件
var geocoder = new AMap.Geocoder()
AMapDistrictSearch = new AMapDefine.DistrictSearch()
// 输入提示插件
AutoComplete = new AMapDefine.AutoComplete({
input: 'amap-search-input',
citylimit: true,
})
// 搜索到内容后的回调函数
AutoComplete.on('select', function (e) {
let name = e.poi.name // 搜索到的名称
selectLocationFunc(e.poi.location.lng, e.poi.location.lat, name)
})
// 地图的选中后的回调函数
AMapInstantiate.on('click', (e) => {
// 查询省市县、 位置信息
geocoder.getAddress(
new AMapDefine.LngLat(e.lnglat.getLng(), e.lnglat.getLat()),
function (state, result) {
// 查找失败
if (state != 'complete') {
return false
}
// 限制城市搜索
AutoComplete.setCity(result.regeocode.addressComponent.citycode)
// 更改省市县 --> 组件调用change事件
jeepayAreaSelect.value.changeByAreacode(
result.regeocode.addressComponent.adcode
)
// 选中的点
selectLocationFunc(
e.lnglat.getLng(),
e.lnglat.getLat(),
result.regeocode.formattedAddress
)
}
)
})
// 存在数据
if (initMapData.lnglat) {
AMapInstantiate.setCenter(
new AMapDefine.LngLat(
initMapData.lnglat.split(',')[0],
initMapData.lnglat.split(',')[1]
)
)
selectLocationFunc(
initMapData.lnglat.split(',')[0],
initMapData.lnglat.split(',')[1],
initMapData.address
)
// 查询省市县、 位置信息 ( 限制城市搜索 )
geocoder.getAddress(new AMapDefine.LngLat(initMapData.lnglat.split(',')[0], initMapData.lnglat.split(',')[1]), function (state, result) {
// 查找失败
if (state != 'complete') {
return false
}
// 限制城市搜索
AutoComplete.setCity(result.regeocode.addressComponent.citycode)
})
}
})
}
// 选中某个点的事件: 定位到当前地点
function selectLocationFunc(lng, lat, name = null) {
if (name) {
vdata.mapData.address = name
}
if (!lng || !lat) {
return false
}
// 更改经纬度坐标
changeInputLnglat(lng, lat)
if (AMapMarker == null) {
// 创建地图标点中心点
AMapMarker = new AMapDefine.Marker({
position: new AMapDefine.LngLat(lng, lat), // 经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
})
AMapInstantiate.add([AMapMarker])
} else {
AMapMarker.setPosition(new AMapDefine.LngLat(lng, lat))
}
}
// 选择省市县的回调函数
function changeAreaCodeFunc(areacode, val) {
// 无无变化
if (vdata.mapData.areacode && vdata.mapData.areacode[2] == val[2]) {
return
}
// 设置地图的city
AMapInstantiate.setCity(val[2])
// 限制城市搜索
AutoComplete.setCity(val[2])
//
vdata.mapData.areacode = val
vdata.mapData.areacodeNames = [
areacode[0].label,
areacode[1].label,
areacode[2].label,
]
}
// 更改输入框的 经纬度
function changeInputLnglat(lng, lat) {
vdata.mapData.lnglat = lng + ',' + lat
}
function getMapData() {
return vdata.mapData
}
// 在移动端收起展开后地图组件未能加载 所以要重新初始化
const changeMap=(key)=>{
if(isMobile && key[0] == 'map'){
init(vdata.mapData)
}
}
defineExpose({ init, getMapData })
</script>