const mapConfig = require('../../../utils/map-config.js'); const config = require('../../../config/config.js'); Page({ data: { poiList: [], markers: [], latitude: '', longitude: '', originalLatitude: '', // 保存原始位置信息 originalLongitude: '', originalLocationName: '', // 保存原始位置名称 originalAddress: '', // 保存原始详细地址 hasMovedMap: false, isHideLocationSelected: false, // "不显示地点"是否被选中 currentPage: 1, // 当前页码 totalCount: 0, // 总地点数量 hasMore: true, // 是否有更多数据 loadingMore: false // 是否正在加载更多数据 }, onLoad(options) { const latitude = parseFloat(options.latitude); const longitude = parseFloat(options.longitude); // 获取原始位置名称和详细地址 const originalLocationName = options.locationName ? decodeURIComponent(options.locationName) : ''; const originalAddress = options.address ? decodeURIComponent(options.address) : ''; const isHideLocationSelected = false; wx.getLocation({ type: 'gcj02', success: (res) => { wx.request({ url: 'https://restapi.amap.com/v3/geocode/regeo', method: 'GET', data: { key: config.amapKey || mapConfig.MAP_CONFIG.amapKey, location: `${res.longitude},${res.latitude}`, extensions: 'all' }, success: (geoRes) => { let city = ''; if (geoRes.data.status === '1' && geoRes.data.regeocode) { if (geoRes.data.regeocode.addressComponent.city) { city = geoRes.data.regeocode.addressComponent.city; } else if (geoRes.data.regeocode.addressComponent.province) { city = geoRes.data.regeocode.addressComponent.province; } } // 设置导航栏标题 let title = '所在地点'; if (city) { title = `所在地点-${city}`; } else if (originalLocationName) { title = `所在地点-${originalLocationName}`; } wx.setNavigationBarTitle({ title: title }); }, fail: () => { let city = '所在地点'; if (originalAddress) { let cityMatch = originalAddress.match(/[^省]+省([^市]+市)/); if (cityMatch && cityMatch[1]) { city = cityMatch[1]; } else { cityMatch = originalAddress.match(/([^区镇街道市]+市)/); if (cityMatch && cityMatch[1]) { city = cityMatch[1]; } } } let title = '所在地点'; if (city && city !== '所在地点') { title = `所在地点-${city}`; } else if (originalLocationName) { title = `所在地点-${originalLocationName}`; } wx.setNavigationBarTitle({ title: title }); } }); }, fail: () => { // 获取位置失败 let city = '所在地点'; if (originalAddress) { let cityMatch = originalAddress.match(/[^省]+省([^市]+市)/); if (cityMatch && cityMatch[1]) { city = cityMatch[1]; } else { cityMatch = originalAddress.match(/([^区镇街道市]+市)/); if (cityMatch && cityMatch[1]) { city = cityMatch[1]; } } } let title = '所在地点'; if (city && city !== '所在地点') { title = `所在地点-${city}`; } else if (originalLocationName) { title = `所在地点-${originalLocationName}`; } wx.setNavigationBarTitle({ title: title }); } }); this.setData({ latitude, longitude, originalLatitude: latitude, originalLongitude: longitude, originalLocationName: originalLocationName, originalAddress: originalAddress, isHideLocationSelected: isHideLocationSelected, markers: [{ id: 0, latitude, longitude, iconPath: '/images/map/marker_position.png', width: 50, height: 50, zIndex: 10 }] }); // 显示加载提示 wx.showLoading({ title: '获取附近点位中...', mask: true }); // 初始化地图并获取附近地点 this.getNearbyPois(latitude, longitude); }, // 获取附近1公里内的地点 getNearbyPois(latitude, longitude, isLoadMore = false) { if (isLoadMore && (!this.data.hasMore || this.data.loadingMore)) { return; } // 设置加载状态 if (isLoadMore) { this.setData({ loadingMore: true }); } else { // 显示加载提示 wx.showLoading({ title: '获取附近点位中...', mask: true }); // 重置页面状态 this.setData({ currentPage: 1, hasMore: true, poiList: [] }); } const page = isLoadMore ? this.data.currentPage + 1 : 1; const offset = 20; wx.request({ url: 'https://restapi.amap.com/v3/place/around', method: 'GET', data: { key: config.amapKey || mapConfig.MAP_CONFIG.amapKey, location: `${longitude},${latitude}`, radius: 1000, offset: offset, page: page, extensions: 'all', types: '050000|060000|070000|080000|090000|100000|110000|120000|130000|140000|150000|160000|170000|180000|190000|200000|210000|220000|230000|240000|250000|260000|270000|280000|290000|300000|310000|320000|330000', sortrule: 'distance' }, success: (res) => { // 隐藏加载提示 if (!isLoadMore) { wx.hideLoading(); } // 记录API调用状态 if (res.data.status === '0') { console.error('高德API返回错误:', res.data.info, '错误码:', res.data.infocode); } if (res.data.status === '1' && res.data.pois && res.data.pois.length > 0) { const poiList = res.data.pois; // 更新总数量 const totalCount = parseInt(res.data.count) || 0; const enhancedPoiList = poiList.map(poi => { let distance = poi.distance ? parseInt(poi.distance) : 0; if (!distance && poi.location && poi.location.split(',').length === 2) { const [poiLon, poiLat] = poi.location.split(',').map(coord => parseFloat(coord)); const latDiff = poiLat - latitude; const lonDiff = poiLon - longitude; distance = Math.round(Math.sqrt(latDiff * latDiff + lonDiff * lonDiff) * 111000); } let isSameAsPublishAddress = false; // 提取分类信息 const category = poi.type ? poi.type.split(';').filter(t => t.trim()) : []; const mainCategory = category.length > 0 ? category[0] : '未知分类'; const subCategory = category.length > 1 ? category[1] : ''; const phone = poi.tel || ''; const email = poi.email || ''; const website = poi.website || ''; const shopHours = poi.biz_time || ''; return { ...poi, isSameAsPublishAddress: isSameAsPublishAddress, distance: distance, address: poi.address || '', displayAddress: typeof poi.address === 'string' && poi.address.trim() !== '' ? poi.address : '地址未知', mainCategory: mainCategory, subCategory: subCategory, phone: phone, email: email, website: website, shopHours: shopHours, typecode: poi.typecode || '', pname: poi.pname || '', cityname: poi.cityname || '', adname: poi.adname || '' }; }); const markers = this.createMarkers(enhancedPoiList, latitude, longitude); if (isLoadMore) { this.setData({ poiList: [...this.data.poiList, ...enhancedPoiList], markers: [...this.data.markers, ...markers], currentPage: page, totalCount: totalCount, hasMore: this.data.poiList.length + enhancedPoiList.length < totalCount, loadingMore: false }); } else { this.setData({ poiList: enhancedPoiList, markers: markers, currentPage: page, totalCount: totalCount, hasMore: enhancedPoiList.length < totalCount }); } this.restoreSelectedState(); } else { if (isLoadMore) { this.setData({ loadingMore: false, hasMore: false }); } else { wx.showToast({ title: '该位置1公里内无地点', icon: 'none', duration: 2000 }); } } }, fail: (error) => { console.error('获取附近地点失败:', error); // 隐藏加载提示 wx.hideLoading(); wx.showToast({ title: '获取真实地点数据失败', icon: 'none', duration: 2000 }); if (!config.mockData) { return; } const mockPoiList = [ { id: 'mock_1', name: '附近咖啡厅', address: '', location: `${longitude},${latitude + 0.001}`, type: '餐饮服务;咖啡厅', typecode: '050101', distance: 120, pname: '北京市', cityname: '北京市', adname: '朝阳区', tel: '010-12345678', biz_time: '09:00-22:00' }, { id: 'mock_2', name: '示例餐厅', address: '和平路123号', location: `${longitude + 0.003},${latitude}`, type: '餐饮服务;中餐厅', typecode: '050105', distance: 330, pname: '北京市', cityname: '北京市', adname: '朝阳区', tel: '010-87654321', biz_time: '10:00-21:30' }, { id: 'mock_3', name: '购物中心', address: '', location: `${longitude},${latitude - 0.005}`, type: '购物服务;购物中心', typecode: '060101', distance: 550, pname: '北京市', cityname: '北京市', adname: '朝阳区', tel: '010-11223344', biz_time: '10:00-22:00' }, { id: 'mock_4', name: '城市公园', address: '文化街56号', location: `${longitude - 0.007},${latitude}`, type: '风景名胜;公园', typecode: '110101', distance: 770, pname: '北京市', cityname: '北京市', adname: '朝阳区', biz_time: '06:00-22:00' }, { id: 'mock_5', name: '便利店', address: '幸福路78号', location: `${longitude + 0.0005},${latitude + 0.0005}`, type: '购物服务;便利店', typecode: '060203', distance: 80, pname: '北京市', cityname: '北京市', adname: '朝阳区', tel: '010-55667788', biz_time: '24小时' }, { id: 'mock_6', name: '健身房', address: '体育路12号', location: `${longitude + 0.009},${latitude + 0.003}`, type: '体育休闲服务;健身中心', typecode: '140100', distance: 950, pname: '北京市', cityname: '北京市', adname: '朝阳区', tel: '010-99887766', biz_time: '06:00-23:00' } ]; const enhancedMockList = mockPoiList.map(poi => { // 计算距离 let distance = 0; if (poi.location && poi.location.split(',').length === 2) { const [poiLon, poiLat] = poi.location.split(',').map(coord => parseFloat(coord)); const latDiff = poiLat - latitude; const lonDiff = poiLon - longitude; distance = Math.round(Math.sqrt(latDiff * latDiff + lonDiff * lonDiff) * 111000); } // 提取分类信息 const category = poi.type ? poi.type.split(';').filter(t => t.trim()) : []; const mainCategory = category.length > 0 ? category[0] : '未知分类'; const subCategory = category.length > 1 ? category[1] : ''; return { ...poi, isSameAsPublishAddress: false, distance: distance, address: poi.address || '', displayAddress: typeof poi.address === 'string' && poi.address.trim() !== '' ? poi.address : '地址未知', mainCategory: mainCategory, subCategory: subCategory, phone: poi.tel || '', email: poi.email || '', website: poi.website || '', shopHours: poi.biz_time || '' }; }); const markers = this.createMarkers(enhancedMockList, latitude, longitude); if (isLoadMore) { this.setData({ poiList: [...this.data.poiList, ...enhancedMockList], markers: [...this.data.markers, ...markers], loadingMore: false }); } else { this.setData({ poiList: enhancedMockList, markers: markers, totalCount: enhancedMockList.length }); } this.restoreSelectedState(); wx.showToast({ title: '显示1公里范围内模拟地点', icon: 'none' }); } }); }, // 恢复选中状态的方法 restoreSelectedState() { try { const poiList = this.data.poiList; if (!poiList || poiList.length === 0) { return; } let selectedPoi; let isLocationHidden; try { selectedPoi = wx.getStorageSync('selectedPoi'); isLocationHidden = wx.getStorageSync('isLocationHidden'); } catch (storageError) { console.error('从本地存储获取选中状态失败:', storageError); selectedPoi = null; isLocationHidden = false; } const isHideLocationSelected = isLocationHidden === true; console.log('从本地存储获取的选中状态:', { selectedPoi: selectedPoi ? JSON.stringify(selectedPoi) : 'null', isLocationHidden: isLocationHidden, isHideLocationSelected: isHideLocationSelected }); this.setData({ isHideLocationSelected: isHideLocationSelected }); if (isHideLocationSelected) { const finalPoiList = poiList.map(poi => ({ ...poi, isSameAsPublishAddress: false })); this.setData({ poiList: finalPoiList }); return; } if (!selectedPoi || typeof selectedPoi !== 'object') { return; } let finalPoiList = poiList.map(poi => ({ ...poi, isSameAsPublishAddress: false })); // 定义匹配函数 const findMatchingPoi = (poiList, targetPoi) => { // 位置精确匹配 const exactMatch = poiList.find(poi => { return poi.location && targetPoi.location && poi.location === targetPoi.location; }); if (exactMatch) { return exactMatch; } // 名称和地址组合匹配 const looseMatch = poiList.find(poi => { const poiName = poi.name && poi.name.toLowerCase(); const poiAddress = poi.address && poi.address.toLowerCase(); const targetName = targetPoi.name && targetPoi.name.toLowerCase(); const targetAddress = targetPoi.address && targetPoi.address.toLowerCase(); return (poiName && targetName && (poiName.includes(targetName) || targetName.includes(poiName))) || (poiAddress && targetAddress && (poiAddress.includes(targetAddress) || targetAddress.includes(poiAddress))); }); if (looseMatch) { return looseMatch; } // 名称模糊匹配 const fuzzyMatch = poiList.find(poi => { const poiName = poi.name && poi.name.toLowerCase(); const targetName = targetPoi.name && targetPoi.name.toLowerCase(); // 检查名称是否有包含关系 return poiName && targetName && (poiName.includes(targetName) || targetName.includes(poiName)); }); if (fuzzyMatch) { return fuzzyMatch; } return null; }; const matchedPoi = findMatchingPoi(finalPoiList, selectedPoi); if (matchedPoi) { finalPoiList = finalPoiList.map(poi => ({ ...poi, isSameAsPublishAddress: poi.id === matchedPoi.id })); } else { } // 更新地点列表 this.setData({ poiList: finalPoiList }); } catch (error) { console.error('恢复选中状态时发生错误:', error); try { if (this.data.poiList && this.data.poiList.length > 0) { const clearedPoiList = this.data.poiList.map(poi => ({ ...poi, isSameAsPublishAddress: false })); this.setData({ poiList: clearedPoiList }); } } catch (setDataError) { console.error('设置清除选中状态失败:', setDataError); } } }, createMarkers(poiList, userLat, userLon) { const markers = [{ id: 0, latitude: userLat, longitude: userLon, iconPath: '/images/map/marker_position.png', width: 50, height: 50, zIndex: 10 }]; poiList.forEach((poi, index) => { if (poi.location && poi.location.split(',').length === 2) { const [lon, lat] = poi.location.split(',').map(coord => parseFloat(coord)); let markerIcon = '/images/map/marker_hong.png'; if (index % 3 === 1) markerIcon = '/images/map/marker_lan.png'; if (index % 3 === 2) markerIcon = '/images/map/marker_yinliao.png'; markers.push({ id: index + 1, latitude: lat, longitude: lon, title: poi.name, iconPath: markerIcon, width: 40, height: 40, zIndex: 5, callout: { content: poi.name, color: '#333', fontSize: 24, borderRadius: 4, padding: 8, bgColor: 'rgba(255, 255, 255, 0.9)', display: 'BYCLICK' } }); } }); return markers; }, autoSelectFirstLocation(poiList) { return; }, // 选择地点 selectPoi(e) { const { id } = e.currentTarget.dataset; const poiIndex = parseInt(id); if (this.data.poiList[poiIndex]) { const selectedPoi = this.data.poiList[poiIndex]; // 获取当前保存的状态 const savedPoi = wx.getStorageSync('selectedPoi'); wx.removeStorageSync('isLocationHidden'); if (savedPoi === null) { wx.removeStorageSync('selectedPoi'); } const locationData = { name: selectedPoi.name || '', address: (typeof selectedPoi.address === 'string' && selectedPoi.address.trim() !== '') ? selectedPoi.address : '地址未知', distance: Array.isArray(selectedPoi.distance) ? (selectedPoi.distance.length > 0 ? selectedPoi.distance[0] : '') : (selectedPoi.distance || ''), location: selectedPoi.location || '', type: selectedPoi.type || '', typecode: selectedPoi.typecode || '' }; if (!locationData.name && locationData.address) { locationData.name = locationData.address; } if (!locationData.address && locationData.name) { locationData.address = locationData.name; } wx.setStorageSync('selectedPoi', locationData); let storedData = wx.getStorageSync('selectedPoi'); if (JSON.stringify(storedData) !== JSON.stringify(locationData)) { wx.setStorageSync('selectedPoi', locationData); storedData = wx.getStorageSync('selectedPoi'); } const updatedPoiList = this.data.poiList.map((poi, index) => ({ ...poi, isSameAsPublishAddress: index === poiIndex })); this.setData({ poiList: updatedPoiList, isHideLocationSelected: false }); setTimeout(() => { const finalStoredData = wx.getStorageSync('selectedPoi'); const pages = getCurrentPages(); let publishPage = null; for (let i = pages.length - 1; i >= 0; i--) { if (pages[i].route === 'subpackages/media/edits/edits') { publishPage = pages[i]; break; } } if (publishPage) { if (publishPage.receiveLocationData && typeof publishPage.receiveLocationData === 'function') { publishPage.receiveLocationData(locationData); } else { publishPage.setData({ currentLocation: locationData.address || locationData.name || locationData.toString(), locationName: locationData.name || locationData.address || locationData.toString(), distance: locationData.distance || '', fullAddress: locationData.address && locationData.address !== locationData.name ? locationData.address : '' }); console.log('发布页数据:', { currentLocation: locationData.address || locationData.name || locationData.toString(), locationName: locationData.name || locationData.address || locationData.toString(), distance: locationData.distance || '', fullAddress: locationData.address && locationData.address !== locationData.name ? locationData.address : '' }); } } else { } let delta = 1; for (let i = pages.length - 1; i >= 0; i--) { if (pages[i].route === 'subpackages/media/edits/edits') { delta = pages.length - 1 - i; break; } } // 返回到发布页 wx.navigateBack({ delta: delta }); }, 100); } }, onMarkerTap(e) { const markerId = e.markerId; if (markerId > 0) { const poiIndex = markerId - 1; if (this.data.poiList[poiIndex]) { const selectedPoi = this.data.poiList[poiIndex]; wx.removeStorageSync('isLocationHidden'); const locationData = { name: selectedPoi.name || '', address: (typeof selectedPoi.address === 'string' && selectedPoi.address.trim() !== '') ? selectedPoi.address : '地址未知', distance: Array.isArray(selectedPoi.distance) ? (selectedPoi.distance.length > 0 ? selectedPoi.distance[0] : '') : (selectedPoi.distance || ''), location: selectedPoi.location || '', type: selectedPoi.type || '', typecode: selectedPoi.typecode || '' }; if (!locationData.name && locationData.address) { locationData.name = locationData.address; } if (!locationData.address && locationData.name) { locationData.address = locationData.name; } wx.setStorageSync('selectedPoi', locationData); let storedData = wx.getStorageSync('selectedPoi'); if (JSON.stringify(storedData) !== JSON.stringify(locationData)) { wx.setStorageSync('selectedPoi', locationData); storedData = wx.getStorageSync('selectedPoi'); } setTimeout(() => { const finalStoredData = wx.getStorageSync('selectedPoi'); const pages = getCurrentPages(); let publishPage = null; for (let i = pages.length - 1; i >= 0; i--) { if (pages[i].route === 'subpackages/media/edits/edits') { publishPage = pages[i]; break; } } if (publishPage) { if (publishPage.receiveLocationData && typeof publishPage.receiveLocationData === 'function') { publishPage.receiveLocationData(locationData); } else { publishPage.setData({ currentLocation: locationData.address || locationData.name || locationData.toString(), locationName: locationData.name || locationData.address || locationData.toString(), distance: locationData.distance || '', fullAddress: locationData.address && locationData.address !== locationData.name ? locationData.address : '' }); console.log('发布页数据:', { currentLocation: locationData.address || locationData.name || locationData.toString(), locationName: locationData.name || locationData.address || locationData.toString(), distance: locationData.distance || '', fullAddress: locationData.address && locationData.address !== locationData.name ? locationData.address : '' }); } } else { } let delta = 1; for (let i = pages.length - 1; i >= 0; i--) { if (pages[i].route === 'subpackages/media/edits/edits') { delta = pages.length - 1 - i; break; } } // 返回到发布页 wx.navigateBack({ delta: delta }); }, 100); } } }, // 选择不显示地点 selectNoLocation() { wx.setStorageSync('selectedPoi', null); wx.setStorageSync('isLocationHidden', true); let storedData = wx.getStorageSync('selectedPoi'); const updatedPoiList = this.data.poiList.map(poi => ({ ...poi, isSameAsPublishAddress: false })); this.setData({ hasSelectedLocation: true, isHideLocationSelected: true, poiList: updatedPoiList }, () => { setTimeout(() => { const pages = getCurrentPages(); let publishPage = null; for (let i = pages.length - 1; i >= 0; i--) { if (pages[i].route === 'subpackages/media/edits/edits') { publishPage = pages[i]; break; } } if (publishPage) { if (publishPage.receiveLocationData && typeof publishPage.receiveLocationData === 'function') { publishPage.receiveLocationData(null); } else { publishPage.setData({ currentLocation: '', locationName: '', distance: '', fullAddress: '' }); } } else { } let delta = 1; for (let i = pages.length - 1; i >= 0; i--) { if (pages[i].route === 'subpackages/media/edits/edits') { delta = pages.length - 1 - i; break; } } // 返回到发布页 wx.navigateBack({ delta: delta }); }, 100); }); }, // 生命周期函数 onShow() { this.restoreSelectedState(); }, // 生命周期函数 onUnload() { }, onRegionChange(e) { if (e.type === 'end' && e.causedBy === 'drag') { this.setData({ hasMovedMap: true }); // 获取地图中心坐标 this.mapCtx = wx.createMapContext('map'); this.mapCtx.getCenterLocation({ success: (res) => { this.setData({ latitude: res.latitude, longitude: res.longitude }); // 重新获取附近地点 this.getNearbyPois(res.latitude, res.longitude); } }); } }, // 地图点击事件 onMapTap(e) { // 获取点击位置的经纬度 const { latitude, longitude } = e.detail; // 更新地图中心坐标 this.setData({ latitude, longitude }); // 显示加载提示 wx.showLoading({ title: '获取附近点位中...', mask: true }); // 获取点击位置附近的点位 this.getNearbyPois(latitude, longitude); }, // 跳转到搜索页面 navigateToSearchPage() { wx.navigateTo({ url: '/subpackages/map-extras/searchLocation/searchLocation' }); }, // 加载更多地点数据 loadMorePois() { const { latitude, longitude } = this.data; this.getNearbyPois(latitude, longitude, true); } });