// 全局JSONP回调函数 window.geocodeCallback = function(result) { if (window.vueMapComponent) { window.vueMapComponent.handleGeocodeResult(result); } }; window.reverseGeocodeCallback = function(result) { if (window.vueMapComponent) { window.vueMapComponent.handleReverseGeocodeResult(result); } }; Vue.component('get-position-map-tencent', { template: `
`, props: { 'longitude': { type: Number, default: '', },//经度 'latitude': { type: Number, default: '', },//纬度 'address': { type: String, default: '', },//地图中心的地址 'getCountType': { type: Number, default: 1,// 1单个地址 2多个地址 }, }, data() { return { mapLoading: false, mapApp: null, marker: null, mapContent: "", // 地图挂载dom center: { lng: 116.397475, lat: 39.908817, }, keyword: "", key: '', // API key将从后端获取 currentSearchAddress: '', currentReverseLat: 0, currentReverseLng: 0, }; }, methods: { //获取腾讯地图API Key async getTencentMapKey() { try { const response = await fetch('/index.php/Retail/Store/getTencentMapKey', { method: 'POST', headers: { 'Content-Type': 'application/json', } }); const result = await response.json(); if (result.status === 1 && result.key) { this.key = result.key; return true; } else { console.error('获取腾讯地图API Key失败:', result.msg || '未知错误'); this.$message.error('获取地图配置失败,请联系管理员'); return false; } } catch (error) { console.error('获取腾讯地图API Key异常:', error); this.$message.error('获取地图配置异常,请检查网络连接'); return false; } }, //初始化地图 async mapInit() { if (this.mapApp && this.mapApp.destroy) { this.mapApp.destroy(); } else { this.mapContent.innerHTML = ""; } // 如果没有API key,先获取 if (!this.key) { const success = await this.getTencentMapKey(); if (!success) { return; // 获取API key失败,停止初始化 } } this.checkScript(); }, //检查腾讯地图API是否已加载 checkScript() { if (typeof TMap !== 'undefined' && TMap.Map) { this.tencentMapInit(); } else { // 动态加载腾讯地图API GL const script = document.createElement('script'); script.src = `https://map.qq.com/api/gljs?v=1.exp&key=${this.key}`; script.onload = () => { this.waitForTMapLoad().then(() => { this.tencentMapInit(); }).catch(error => { console.error('腾讯地图API加载失败:', error); this.$message.error('地图加载失败,请刷新页面重试'); }); }; script.onerror = () => { console.error('腾讯地图API脚本加载失败'); this.$message.error('地图脚本加载失败,请检查网络连接'); }; document.head.appendChild(script); } }, // 等待腾讯地图API加载完成 waitForTMapLoad() { return new Promise((resolve, reject) => { if (typeof TMap !== 'undefined' && TMap.Map) { resolve(); } else { let attempts = 0; const maxAttempts = 50; const checkInterval = setInterval(() => { attempts++; if (typeof TMap !== 'undefined' && TMap.Map) { clearInterval(checkInterval); resolve(); } else if (attempts >= maxAttempts) { clearInterval(checkInterval); reject(new Error('腾讯地图API加载超时')); } }, 100); } }); }, //初始化腾讯地图 tencentMapInit() { try { // 设置全局引用 window.vueMapComponent = this; // 创建地图实例 this.mapApp = new TMap.Map(this.mapContent, { center: new TMap.LatLng(this.center.lat, this.center.lng), zoom: 15, viewMode: '2D', mapStyleId: 'style1' }); // 地图点击事件 this.mapApp.on('click', (evt) => { const latLng = evt.latLng; this.updateMapMaker(latLng.lat, latLng.lng); this.reverseGeocode(latLng.lat, latLng.lng); }); // 初始化标记点 this.updateMapMaker(this.center.lat, this.center.lng); this.mapLoading = true; console.log('腾讯地图初始化成功'); } catch (error) { console.error('地图初始化失败:', error); this.$message.error('地图初始化失败: ' + error.message); } }, //更新地图标记点 updateMapMaker(lat, lng, address = '', callback = null) { if (!this.mapApp) return; // 清除之前的标记点 if (this.marker) { this.marker.setMap(null); } // 创建新的标记点 this.marker = new TMap.MultiMarker({ map: this.mapApp, styles: { 'marker-style': new TMap.MarkerStyle({ width: 25, height: 35, anchor: { x: 12, y: 35 }, src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/marker.png' }) }, geometries: [{ id: 'location-marker', styleId: 'marker-style', position: new TMap.LatLng(lat, lng), properties: { title: address || '当前位置' } }] }); // 更新地图中心 this.mapApp.setCenter(new TMap.LatLng(lat, lng)); // 更新数据 this.updateData(lat, lng, address); if (callback) callback(); }, // 处理地理编码JSONP回调 handleGeocodeResult(result) { if (result.status === 0 && result.result && result.result.location) { const location = result.result.location; const lat = location.lat; const lng = location.lng; const address = this.currentSearchAddress; this.updateMapMaker(lat, lng, address); this.$message.success(`搜索成功!找到地址: ${address}`); console.log('地址搜索成功:', result); } else { this.$message.error('未找到该地址,请检查地址是否正确'); console.error('地址搜索失败:', result); } }, // 处理反向地理编码JSONP回调 handleReverseGeocodeResult(result) { const lat = this.currentReverseLat; const lng = this.currentReverseLng; if (result.status === 0 && result.result && result.result.address) { const address = result.result.address; this.updateData(lat, lng, address); console.log('反向地理编码成功:', result); } else { this.updateData(lat, lng, '无法获取地址信息'); console.error('反向地理编码失败:', result); } }, // 反向地理编码(根据坐标获取地址) async reverseGeocode(lat, lng) { if (!this.mapApp) { console.log('地图未初始化'); return; } // 确保有API key if (!this.key) { const success = await this.getTencentMapKey(); if (!success) { this.updateData(lat, lng, '获取地址配置失败'); return; } } // 保存当前坐标 this.currentReverseLat = lat; this.currentReverseLng = lng; // 使用JSONP方式调用腾讯地图WebService API const reverseGeocodeUrl = `https://apis.map.qq.com/ws/geocoder/v1/?location=${lat},${lng}&key=${this.key}&output=jsonp&callback=reverseGeocodeCallback`; // 创建script标签进行JSONP请求 const script = document.createElement('script'); script.src = reverseGeocodeUrl; script.onerror = () => { this.updateData(lat, lng, '地址获取失败'); console.error('反向地理编码JSONP请求失败'); }; document.head.appendChild(script); // 清理script标签 setTimeout(() => { if (script.parentNode) { document.head.removeChild(script); } }, 5000); }, //关键词查询 async addressSearch() { const address = this.keyword.trim(); if (!address) { this.$message.error('请输入要搜索的地址'); return; } if (!this.mapApp) { this.$message.error('地图未初始化,请稍后再试'); return; } // 确保有API key if (!this.key) { const success = await this.getTencentMapKey(); if (!success) { return; } } this.$message.info('正在搜索地址...'); // 保存当前搜索的地址 this.currentSearchAddress = address; // 使用JSONP方式调用腾讯地图WebService API const geocodeUrl = `https://apis.map.qq.com/ws/geocoder/v1/?address=${encodeURIComponent(address)}&key=${this.key}&output=jsonp&callback=geocodeCallback`; // 创建script标签进行JSONP请求 const script = document.createElement('script'); script.src = geocodeUrl; script.onerror = () => { this.$message.error('地址搜索失败,请检查网络连接'); console.error('JSONP请求失败'); }; document.head.appendChild(script); // 清理script标签 setTimeout(() => { if (script.parentNode) { document.head.removeChild(script); } }, 5000); }, //更新数据 updateData(lat, lng, address = '') { this.center.lat = lat; this.center.lng = lng; // 更新父组件的数据 this.$emit('update:longitude', lng); this.$emit('update:latitude', lat); if (address) { this.$emit('update:address', address); } }, //获取初始数据 getInitData(callback) { if (this.longitude && this.latitude) { this.center.lng = this.longitude; this.center.lat = this.latitude; } if (this.address) { this.keyword = this.address; } if (callback) callback(); }, }, mounted() { this.mapContent = this.$refs.mapContent; this.getInitData(() => { this.mapInit(); }); }, created() { this.getInitData(); }, beforeDestroy() { // 清理全局引用 if (window.vueMapComponent === this) { window.vueMapComponent = null; } } });