2060 lines
60 KiB
JavaScript
2060 lines
60 KiB
JavaScript
|
|
// 地图页面 - 高德地图SDK集成版本
|
|||
|
|
const app = getApp();
|
|||
|
|
const apiClient = require('../../utils/api-client.js');
|
|||
|
|
const { MapUtils, MAP_CONFIG } = require('../../utils/map-config.js');
|
|||
|
|
const { AmapWX } = require('../../libs/amap-wx.js');
|
|||
|
|
const { systemInfoHelper } = require('../../utils/system-info-helper.js');
|
|||
|
|
const config = require('../../config/config.js');
|
|||
|
|
var amapFile = require('../../libs/amap-wx-all.js');
|
|||
|
|
|
|||
|
|
const marker_blank = '/images/map/marker_blank.png';
|
|||
|
|
|
|||
|
|
Page({
|
|||
|
|
data: {
|
|||
|
|
amapFun:null,
|
|||
|
|
poiAroundList:[],
|
|||
|
|
showPoiAroundModal: false,
|
|||
|
|
// 地图配置
|
|||
|
|
longitude: 0,
|
|||
|
|
latitude: 0,
|
|||
|
|
scale: 15, // 初始缩放级别,低于自动切换阈值
|
|||
|
|
markers: [],
|
|||
|
|
|
|||
|
|
//商家信息
|
|||
|
|
merchantMarkers: [],
|
|||
|
|
merchantInfoModalVisible: false,
|
|||
|
|
selectedMerchant: null,
|
|||
|
|
|
|||
|
|
// 位置信息
|
|||
|
|
currentAddress: '获取位置中...',
|
|||
|
|
addressDetail: null,
|
|||
|
|
accuracy: 0,
|
|||
|
|
currentDistrict: '',
|
|||
|
|
currentCity: '',
|
|||
|
|
weatherInfo: null,
|
|||
|
|
|
|||
|
|
// SDK状态
|
|||
|
|
amapReady: false,
|
|||
|
|
amapError: null,
|
|||
|
|
|
|||
|
|
// 好友数据
|
|||
|
|
friendsData: [],
|
|||
|
|
|
|||
|
|
// 用户信息
|
|||
|
|
userInfo: null,
|
|||
|
|
myLocation: null, // 保存自己的位置信息
|
|||
|
|
|
|||
|
|
// 地图样式控制
|
|||
|
|
enableSatellite: false,
|
|||
|
|
currentMapType: 'standard', // standard, satellite
|
|||
|
|
autoSatelliteZoom: 18, // 超过此缩放级别自动切换卫星图
|
|||
|
|
|
|||
|
|
// 系统适配
|
|||
|
|
statusBarHeight: 44,
|
|||
|
|
menuButtonHeight: 32,
|
|||
|
|
navBarHeight: 88,
|
|||
|
|
windowHeight: 667,
|
|||
|
|
safeAreaBottom: 0,
|
|||
|
|
|
|||
|
|
// UI状态
|
|||
|
|
selectedUser: null,
|
|||
|
|
currentFilter: 'friends',
|
|||
|
|
friendsCount: 0,
|
|||
|
|
strangersCount: 0,
|
|||
|
|
|
|||
|
|
// 🔥 浮动UI状态
|
|||
|
|
isOnline: true,
|
|||
|
|
friendRequestCount: 0,
|
|||
|
|
unreadMessageCount: 0,
|
|||
|
|
nearbyCount: 0,
|
|||
|
|
|
|||
|
|
// 地址信息
|
|||
|
|
weather: null,
|
|||
|
|
|
|||
|
|
// 默认位置(如果定位失败)
|
|||
|
|
defaultLocation: {
|
|||
|
|
latitude: 39.908692,
|
|||
|
|
longitude: 116.397979,
|
|||
|
|
address: '北京市'
|
|||
|
|
},
|
|||
|
|
poiDetail: null,
|
|||
|
|
showPoiRemindModal: false,
|
|||
|
|
poiRemindRadius: 300, // 默认300米
|
|||
|
|
poiRemindCircle: null,
|
|||
|
|
poiRemindMode: ['arrive'], // 多选,初始为到达
|
|||
|
|
showFriendSelectModal: false,
|
|||
|
|
lastPoiForRemind: null,
|
|||
|
|
allFriendsList: [], // 新增:用于好友选择弹窗的模拟数据
|
|||
|
|
// 新增
|
|||
|
|
friendSearchText: '',
|
|||
|
|
filteredFriendsList: [],
|
|||
|
|
showLocationMarkModal: false,
|
|||
|
|
locationMarkSearchText: '',
|
|||
|
|
locationMarkList: [],
|
|||
|
|
filteredLocationMarkList: [],
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onLoad() {
|
|||
|
|
console.log('🗺️ 地图页面加载');
|
|||
|
|
this.amapFun = new amapFile.AMapWX({key:config.amapKey});
|
|||
|
|
// 使用已经创建的系统信息辅助实例
|
|||
|
|
this.systemInfoHelper = systemInfoHelper;
|
|||
|
|
|
|||
|
|
// 初始化API客户端
|
|||
|
|
this.apiClient = apiClient;
|
|||
|
|
|
|||
|
|
// 初始化地图上下文
|
|||
|
|
this.mapContext = wx.createMapContext('main-map', this);
|
|||
|
|
this.mapContext.initMarkerCluster({
|
|||
|
|
enableDefaultStyle: true, // 使用默认聚合样式
|
|||
|
|
zoomOnClick: true, // 点击聚合点自动放大
|
|||
|
|
gridSize: 60, // 聚合计算网格大小,单位px
|
|||
|
|
complete(res) {
|
|||
|
|
console.log('initMarkerCluster', res);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
// enableDefaultStyle 为 true 时不会触发改事件
|
|||
|
|
this.mapContext.on('markerClusterCreate', res => {
|
|||
|
|
console.log('clusterCreate', res)
|
|||
|
|
const clusters = res.clusters
|
|||
|
|
const markers = clusters.map(cluster => {
|
|||
|
|
const {
|
|||
|
|
center,
|
|||
|
|
clusterId,
|
|||
|
|
markerIds
|
|||
|
|
} = cluster
|
|||
|
|
return {
|
|||
|
|
...center,
|
|||
|
|
width: 0,
|
|||
|
|
height: 0,
|
|||
|
|
clusterId, // 必须
|
|||
|
|
label: {
|
|||
|
|
content: markerIds.length + '',
|
|||
|
|
fontSize: 20,
|
|||
|
|
width: 60,
|
|||
|
|
height: 60,
|
|||
|
|
bgColor: '#00ff00',
|
|||
|
|
borderRadius: 30,
|
|||
|
|
textAlign: 'center',
|
|||
|
|
anchorX: 0,
|
|||
|
|
anchorY: -30,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
});
|
|||
|
|
this.initSystemInfo();
|
|||
|
|
this.initUserInfo();
|
|||
|
|
this.initAMapSDK();
|
|||
|
|
this.requestLocationPermission();
|
|||
|
|
|
|||
|
|
// 🔥 加载浮动UI相关数据
|
|||
|
|
this.loadFloatingUIData();
|
|||
|
|
|
|||
|
|
// 注入模拟好友数据
|
|||
|
|
const mockFriends = [
|
|||
|
|
{ userId: 'u1', nickname: '小明', avatarUrl: '' },
|
|||
|
|
{ userId: 'u2', nickname: '小红', avatarUrl: '' },
|
|||
|
|
{ userId: 'u3', nickname: '小刚', avatarUrl: '' },
|
|||
|
|
{ userId: 'u4', nickname: '小美', avatarUrl: '' },
|
|||
|
|
{ userId: 'u5', nickname: '小强', avatarUrl: '' }
|
|||
|
|
];
|
|||
|
|
this.setData({ allFriendsList: mockFriends, filteredFriendsList: mockFriends });
|
|||
|
|
|
|||
|
|
// 模拟收藏地址数据
|
|||
|
|
const mockLocationMarkList = [
|
|||
|
|
{
|
|||
|
|
id: 'loc1',
|
|||
|
|
lat: 44.897383746906186,
|
|||
|
|
lng: 82.07800276534772,
|
|||
|
|
name: "博尔塔拉长城医院",
|
|||
|
|
remindFriends: [
|
|||
|
|
{ userId: 'u1', avatarUrl: '' },
|
|||
|
|
{ userId: 'u2', avatarUrl: '' }
|
|||
|
|
],
|
|||
|
|
remindType: 'arrive',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'loc2',
|
|||
|
|
lat: 44.90334720165053,
|
|||
|
|
lng: 82.06464725905994,
|
|||
|
|
name: "博乐市第八中学",
|
|||
|
|
remindFriends: [
|
|||
|
|
{ userId: 'u3', avatarUrl: '' }
|
|||
|
|
],
|
|||
|
|
remindType: 'leave',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'loc3',
|
|||
|
|
lat: 44.899198022190106,
|
|||
|
|
lng: 82.06220180027526,
|
|||
|
|
name: "博乐大巴扎商业公园",
|
|||
|
|
remindFriends: [
|
|||
|
|
{ userId: 'u3', avatarUrl: '' }
|
|||
|
|
],
|
|||
|
|
remindType: 'leave',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'loc4',
|
|||
|
|
lat: 44.899198022190106,
|
|||
|
|
lng: 82.06220180027526,
|
|||
|
|
name: "博乐大巴扎商业公园",
|
|||
|
|
remindFriends: [
|
|||
|
|
{ userId: 'u3', avatarUrl: '' }
|
|||
|
|
],
|
|||
|
|
remindType: 'leave',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'loc5',
|
|||
|
|
lat: 44.899198022190106,
|
|||
|
|
lng: 82.06220180027526,
|
|||
|
|
name: "博乐大巴扎商业公园",
|
|||
|
|
remindFriends: [
|
|||
|
|
{ userId: 'u3', avatarUrl: '' }
|
|||
|
|
],
|
|||
|
|
remindType: 'leave',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'loc6',
|
|||
|
|
lat: 44.899198022190106,
|
|||
|
|
lng: 82.06220180027526,
|
|||
|
|
name: "博乐大巴扎商业公园",
|
|||
|
|
remindFriends: [
|
|||
|
|
{ userId: 'u3', avatarUrl: '' }
|
|||
|
|
],
|
|||
|
|
remindType: 'leave',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'loc7',
|
|||
|
|
lat: 44.899198022190106,
|
|||
|
|
lng: 82.06220180027526,
|
|||
|
|
name: "博乐大巴扎商业公园",
|
|||
|
|
remindFriends: [
|
|||
|
|
{ userId: 'u3', avatarUrl: '' }
|
|||
|
|
],
|
|||
|
|
remindType: 'leave',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'loc8',
|
|||
|
|
lat: 44.899198022190106,
|
|||
|
|
lng: 82.06220180027526,
|
|||
|
|
name: "博乐大巴扎商业公园",
|
|||
|
|
remindFriends: [
|
|||
|
|
{ userId: 'u3', avatarUrl: '' }
|
|||
|
|
],
|
|||
|
|
remindType: 'leave',
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 'loc9',
|
|||
|
|
lat: 44.899198022190106,
|
|||
|
|
lng: 82.06220180027526,
|
|||
|
|
name: "博乐大巴扎商业公园",
|
|||
|
|
remindFriends: [
|
|||
|
|
{ userId: 'u3', avatarUrl: '' }
|
|||
|
|
],
|
|||
|
|
remindType: 'leave',
|
|||
|
|
}
|
|||
|
|
];
|
|||
|
|
this.setData({
|
|||
|
|
locationMarkList: mockLocationMarkList,
|
|||
|
|
filteredLocationMarkList: mockLocationMarkList
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onShow() {
|
|||
|
|
console.log('地图页面显示');
|
|||
|
|
|
|||
|
|
if (this.data.amapReady) {
|
|||
|
|
this.startLocationService();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onHide() {
|
|||
|
|
console.log('地图页面隐藏');
|
|||
|
|
this.stopLocationService();
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onUnload() {
|
|||
|
|
console.log('地图页面卸载');
|
|||
|
|
this.stopLocationService();
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 初始化高德地图SDK
|
|||
|
|
initAMapSDK() {
|
|||
|
|
try {
|
|||
|
|
console.log('🚀 初始化高德定位SDK');
|
|||
|
|
|
|||
|
|
// 只用于GPS定位,不需要API Key
|
|||
|
|
this.amap = AmapWX.getInstance({
|
|||
|
|
key: config.amapKey || '' // 可选,仅用于标识
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
amapReady: true,
|
|||
|
|
amapError: null
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
console.log('✅ 高德定位SDK初始化成功');
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 高德定位SDK初始化失败:', error);
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
amapReady: false,
|
|||
|
|
amapError: error.message || '高德定位SDK初始化失败'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '定位服务异常',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 初始化系统信息
|
|||
|
|
initSystemInfo() {
|
|||
|
|
try {
|
|||
|
|
const systemInfo = this.systemInfoHelper.getSystemInfoSync();
|
|||
|
|
const menuButtonInfo = wx.getMenuButtonBoundingClientRect();
|
|||
|
|
|
|||
|
|
const statusBarHeight = systemInfo.statusBarHeight || 44;
|
|||
|
|
const menuButtonHeight = menuButtonInfo.height || 32;
|
|||
|
|
const menuButtonTop = menuButtonInfo.top || statusBarHeight + 6;
|
|||
|
|
const navBarHeight = statusBarHeight + menuButtonHeight + 10;
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
statusBarHeight: statusBarHeight,
|
|||
|
|
menuButtonHeight: menuButtonHeight,
|
|||
|
|
navBarHeight: navBarHeight,
|
|||
|
|
windowHeight: systemInfo.windowHeight || 667,
|
|||
|
|
safeAreaBottom: systemInfo.safeArea ? systemInfo.windowHeight - systemInfo.safeArea.bottom : 0
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
console.log('地图页面系统适配信息:', {
|
|||
|
|
statusBarHeight,
|
|||
|
|
menuButtonHeight,
|
|||
|
|
menuButtonTop,
|
|||
|
|
navBarHeight,
|
|||
|
|
windowHeight: systemInfo.windowHeight,
|
|||
|
|
safeAreaBottom: this.data.safeAreaBottom
|
|||
|
|
});
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('获取系统信息失败:', error);
|
|||
|
|
// 设置默认值
|
|||
|
|
this.setData({
|
|||
|
|
statusBarHeight: 44,
|
|||
|
|
menuButtonHeight: 32,
|
|||
|
|
menuButtonTop: 50,
|
|||
|
|
navBarHeight: 88,
|
|||
|
|
windowHeight: 667,
|
|||
|
|
safeAreaBottom: 0
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 初始化用户信息
|
|||
|
|
initUserInfo() {
|
|||
|
|
try {
|
|||
|
|
const userInfo = app.globalData.userInfo;
|
|||
|
|
if (userInfo) {
|
|||
|
|
this.setData({ userInfo });
|
|||
|
|
console.log('用户信息已设置:', userInfo.nickname || userInfo.customID);
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('初始化用户信息失败:', error);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 请求位置权限
|
|||
|
|
requestLocationPermission() {
|
|||
|
|
console.log('🎯 开始获取位置...');
|
|||
|
|
|
|||
|
|
// 直接尝试获取位置,如果失败会自动触发权限请求
|
|||
|
|
this.getCurrentLocation();
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 获取当前位置 - 添加降级方案
|
|||
|
|
getCurrentLocation() {
|
|||
|
|
if (!this.data.amapReady) {
|
|||
|
|
console.warn('高德地图SDK尚未准备就绪,使用微信原生定位');
|
|||
|
|
this.getWxLocation();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('📍 使用高德SDK获取定位');
|
|||
|
|
|
|||
|
|
this.amap.getWxLocation((location, error) => {
|
|||
|
|
if (error) {
|
|||
|
|
console.error('高德SDK获取位置失败:', error);
|
|||
|
|
console.log('🔄 降级使用微信原生定位');
|
|||
|
|
this.getWxLocation();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('✅ 高德SDK位置获取成功,原始数据:', JSON.stringify(location, null, 2));
|
|||
|
|
|
|||
|
|
// 🔥 打印关键字段用于调试
|
|||
|
|
console.log('🔍 关键地址字段检查:', {
|
|||
|
|
address: location.address,
|
|||
|
|
formattedAddress: location.formattedAddress,
|
|||
|
|
province: location.province,
|
|||
|
|
city: location.city,
|
|||
|
|
district: location.district,
|
|||
|
|
street: location.street,
|
|||
|
|
description: location.description
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
this.processLocationResult(location);
|
|||
|
|
}, {
|
|||
|
|
type: 'gcj02',
|
|||
|
|
isHighAccuracy: true,
|
|||
|
|
highAccuracyExpireTime: 4000
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 🔥 新增:微信原生定位降级方案
|
|||
|
|
getWxLocation() {
|
|||
|
|
console.log('📱 使用微信原生定位API');
|
|||
|
|
|
|||
|
|
wx.getLocation({
|
|||
|
|
type: 'gcj02',
|
|||
|
|
isHighAccuracy: true,
|
|||
|
|
highAccuracyExpireTime: 4000,
|
|||
|
|
success: (location) => {
|
|||
|
|
console.log('✅ 微信原生定位成功:', location);
|
|||
|
|
|
|||
|
|
// 模拟高德地图数据格式,添加简单的地址信息
|
|||
|
|
const enhancedLocation = {
|
|||
|
|
...location,
|
|||
|
|
address: `位置 ${location.latitude.toFixed(6)}, ${location.longitude.toFixed(6)}`,
|
|||
|
|
// 微信原生定位不返回地址信息,我们设置为空,让解析逻辑处理
|
|||
|
|
formattedAddress: '',
|
|||
|
|
province: '',
|
|||
|
|
city: '',
|
|||
|
|
district: '',
|
|||
|
|
street: ''
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
console.log('📍 微信定位增强数据:', enhancedLocation);
|
|||
|
|
this.processLocationResult(enhancedLocation);
|
|||
|
|
|
|||
|
|
// 尝试通过第三方服务获取地址信息
|
|||
|
|
this.reverseGeocode(location.latitude, location.longitude);
|
|||
|
|
},
|
|||
|
|
fail: (error) => {
|
|||
|
|
console.error('微信原生定位也失败:', error);
|
|||
|
|
this.handleLocationError(error);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 🔥 新增:逆地理编码获取地址信息
|
|||
|
|
async reverseGeocode(latitude, longitude) {
|
|||
|
|
try {
|
|||
|
|
console.log('🔍 尝试逆地理编码获取地址信息');
|
|||
|
|
|
|||
|
|
// 这里可以调用第三方地理编码服务,或者使用简化版本
|
|||
|
|
// 暂时使用一个基于坐标推断的简化版本
|
|||
|
|
const location = this.getLocationByCoordinates(latitude, longitude);
|
|||
|
|
|
|||
|
|
if (location.district || location.city) {
|
|||
|
|
console.log('📍 逆地理编码成功,更新地址信息:', location);
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
currentDistrict: location.district || '',
|
|||
|
|
currentCity: location.city || '',
|
|||
|
|
currentAddress: location.address || this.data.currentAddress
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('逆地理编码失败:', error);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 🔥 新增:基于坐标的简化位置推断
|
|||
|
|
getLocationByCoordinates(latitude, longitude) {
|
|||
|
|
console.log('📍 基于坐标推断位置信息');
|
|||
|
|
|
|||
|
|
// 这是一个简化的位置推断,基于经纬度范围
|
|||
|
|
// 实际项目中应该调用专业的地理编码API
|
|||
|
|
|
|||
|
|
const lat = parseFloat(latitude);
|
|||
|
|
const lng = parseFloat(longitude);
|
|||
|
|
|
|||
|
|
let province = '';
|
|||
|
|
let city = '';
|
|||
|
|
let district = '';
|
|||
|
|
|
|||
|
|
// 简单的中国主要城市坐标范围判断
|
|||
|
|
if (lat >= 39.8 && lat <= 40.0 && lng >= 116.2 && lng <= 116.6) {
|
|||
|
|
province = '北京市';
|
|||
|
|
city = '北京市';
|
|||
|
|
district = '朝阳区'; // 默认区域
|
|||
|
|
} else if (lat >= 31.1 && lat <= 31.3 && lng >= 121.3 && lng <= 121.6) {
|
|||
|
|
province = '上海市';
|
|||
|
|
city = '上海市';
|
|||
|
|
district = '浦东新区';
|
|||
|
|
} else if (lat >= 22.4 && lat <= 22.8 && lng >= 113.8 && lng <= 114.5) {
|
|||
|
|
province = '广东省';
|
|||
|
|
city = '深圳市';
|
|||
|
|
district = '南山区';
|
|||
|
|
} else if (lat >= 23.0 && lat <= 23.3 && lng >= 113.1 && lng <= 113.5) {
|
|||
|
|
province = '广东省';
|
|||
|
|
city = '广州市';
|
|||
|
|
district = '天河区';
|
|||
|
|
} else {
|
|||
|
|
// 其他位置使用通用名称
|
|||
|
|
district = '当前区域';
|
|||
|
|
city = '当前城市';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const address = province && city ? `${province}${city}${district}` : `位置 ${lat.toFixed(4)}, ${lng.toFixed(4)}`;
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
province,
|
|||
|
|
city,
|
|||
|
|
district,
|
|||
|
|
address
|
|||
|
|
};
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 处理位置结果
|
|||
|
|
processLocationResult(location) {
|
|||
|
|
// 保存自己的位置信息
|
|||
|
|
const myLocation = {
|
|||
|
|
latitude: location.latitude,
|
|||
|
|
longitude: location.longitude,
|
|||
|
|
accuracy: location.accuracy || 0
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
longitude: location.longitude,
|
|||
|
|
latitude: location.latitude,
|
|||
|
|
accuracy: location.accuracy || 0,
|
|||
|
|
myLocation: myLocation
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 创建用户位置标记(带头像和电量信息)
|
|||
|
|
this.createUserMarkers(myLocation);
|
|||
|
|
|
|||
|
|
// 移动地图到当前位置
|
|||
|
|
this.mapContext.moveToLocation({
|
|||
|
|
latitude: location.latitude,
|
|||
|
|
longitude: location.longitude
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 解析地址
|
|||
|
|
this.resolveAddress(location);
|
|||
|
|
|
|||
|
|
// 加载好友位置
|
|||
|
|
this.loadFriendsLocation();
|
|||
|
|
|
|||
|
|
//获取商家信息
|
|||
|
|
this.fetchMerchantList();
|
|||
|
|
|
|||
|
|
// 获取附近用户
|
|||
|
|
this.loadNearbyUsers();
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 创建用户位置标记(带头像和电量信息)
|
|||
|
|
createUserMarkers(myLocation) {
|
|||
|
|
const systemInfo = this.systemInfoHelper.getSystemInfoSync();
|
|||
|
|
const battery = systemInfo.battery || 100; // 小程序无法获取真实电量,使用100%
|
|||
|
|
|
|||
|
|
// 创建自己的标记
|
|||
|
|
const userMarker = {
|
|||
|
|
id: 1,
|
|||
|
|
latitude: myLocation.latitude,
|
|||
|
|
longitude: myLocation.longitude,
|
|||
|
|
iconPath: marker_blank,
|
|||
|
|
type: 'mine',
|
|||
|
|
avatarUrl:this.data.userInfo.user.avatar,
|
|||
|
|
merchantType:'',
|
|||
|
|
nickName:'我',
|
|||
|
|
battery:100,
|
|||
|
|
width: 40,
|
|||
|
|
height: 50,
|
|||
|
|
title: '我的位置',
|
|||
|
|
joinCluster:true,
|
|||
|
|
customCallout: {
|
|||
|
|
anchorY: 80,
|
|||
|
|
anchorX: 0,
|
|||
|
|
display: 'ALWAYS'
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
markers: [userMarker]
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 解析地址 - 改进区域信息提取逻辑
|
|||
|
|
resolveAddress(location) {
|
|||
|
|
console.log('🏠 处理地址信息,location数据:', location);
|
|||
|
|
|
|||
|
|
let address = '未知位置';
|
|||
|
|
let addressDetail = {};
|
|||
|
|
let currentDistrict = '';
|
|||
|
|
let currentCity = '';
|
|||
|
|
|
|||
|
|
// 从高德地图定位结果中获取地址信息
|
|||
|
|
if (location.address && location.address.trim()) {
|
|||
|
|
address = location.address;
|
|||
|
|
console.log('✅ 使用高德地图返回的地址:', address);
|
|||
|
|
} else if (location.formattedAddress && location.formattedAddress.trim()) {
|
|||
|
|
address = location.formattedAddress;
|
|||
|
|
console.log('✅ 使用格式化地址:', address);
|
|||
|
|
} else {
|
|||
|
|
// 降级处理:使用坐标作为地址
|
|||
|
|
address = `位置: ${location.latitude.toFixed(6)}, ${location.longitude.toFixed(6)}`;
|
|||
|
|
console.log('⚠️ 降级使用坐标作为地址:', address);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 🔥 改进的区域信息提取逻辑
|
|||
|
|
// 优先使用SDK返回的结构化地址信息
|
|||
|
|
if (location.province || location.city || location.district) {
|
|||
|
|
addressDetail = {
|
|||
|
|
province: location.province || '',
|
|||
|
|
city: location.city || '',
|
|||
|
|
district: location.district || '',
|
|||
|
|
street: location.street || '',
|
|||
|
|
streetNumber: location.streetNumber || '',
|
|||
|
|
description: location.description || address
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
currentDistrict = location.district || '';
|
|||
|
|
currentCity = location.city || '';
|
|||
|
|
|
|||
|
|
console.log('📍 使用SDK返回的结构化地址:', { currentDistrict, currentCity });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 🔥 如果SDK没有返回结构化信息,从完整地址字符串中智能解析
|
|||
|
|
if (!currentDistrict && !currentCity && address && address !== '未知位置') {
|
|||
|
|
console.log('🔍 从完整地址解析区域信息:', address);
|
|||
|
|
|
|||
|
|
// 智能解析中国地址格式
|
|||
|
|
const addressPattern = /(.*?)省?(.*?)市?(.*?)区?(.*?)县?(.*?)镇?(.*?)乡?(.*)/;
|
|||
|
|
const match = address.match(addressPattern);
|
|||
|
|
|
|||
|
|
if (match) {
|
|||
|
|
const [, province, city, district] = match;
|
|||
|
|
currentCity = city || province; // 如果没有市,使用省作为城市
|
|||
|
|
currentDistrict = district;
|
|||
|
|
|
|||
|
|
console.log('📍 正则解析结果:', { province, city: currentCity, district: currentDistrict });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 🔥 备用解析方案:使用更精确的正则表达式
|
|||
|
|
if (!currentDistrict) {
|
|||
|
|
// 匹配 XX区、XX县、XX市、XX镇、XX乡
|
|||
|
|
const districtMatches = [
|
|||
|
|
address.match(/([\u4e00-\u9fa5]{2,}区)/), // XX区
|
|||
|
|
address.match(/([\u4e00-\u9fa5]{2,}县)/), // XX县
|
|||
|
|
address.match(/([\u4e00-\u9fa5]{2,}镇)/), // XX镇
|
|||
|
|
address.match(/([\u4e00-\u9fa5]{2,}乡)/), // XX乡
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
for (const match of districtMatches) {
|
|||
|
|
if (match) {
|
|||
|
|
currentDistrict = match[1];
|
|||
|
|
console.log('📍 备用正则匹配到区域:', currentDistrict);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!currentCity) {
|
|||
|
|
// 匹配 XX市
|
|||
|
|
const cityMatch = address.match(/([\u4e00-\u9fa5]{2,}市)/);
|
|||
|
|
if (cityMatch) {
|
|||
|
|
currentCity = cityMatch[1];
|
|||
|
|
console.log('📍 备用正则匹配到城市:', currentCity);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 🔥 最后的降级方案:从地址中提取前几个字符作为区域显示
|
|||
|
|
if (!currentDistrict && !currentCity) {
|
|||
|
|
// 提取地址前10个字符作为区域信息
|
|||
|
|
const shortAddress = address.length > 10 ? address.substring(0, 10) + '...' : address;
|
|||
|
|
currentDistrict = shortAddress;
|
|||
|
|
console.log('📍 降级使用地址片段:', currentDistrict);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 🔥 确保至少有一个显示内容
|
|||
|
|
if (!currentDistrict && !currentCity) {
|
|||
|
|
currentDistrict = '位置信息';
|
|||
|
|
console.log('📍 使用默认显示文案');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('📍 最终解析的区域信息:', {
|
|||
|
|
address,
|
|||
|
|
currentDistrict,
|
|||
|
|
currentCity,
|
|||
|
|
locationData: location
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
currentAddress: address,
|
|||
|
|
addressDetail: addressDetail,
|
|||
|
|
currentDistrict: currentDistrict,
|
|||
|
|
currentCity: currentCity
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 获取天气信息
|
|||
|
|
this.loadWeatherInfo(location.latitude, location.longitude);
|
|||
|
|
|
|||
|
|
// 更新位置信息到服务器
|
|||
|
|
this.updateLocationToServer({
|
|||
|
|
...location,
|
|||
|
|
address: address,
|
|||
|
|
addressDetail: addressDetail
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 更新位置到服务器 - 尝试从响应中获取地址信息
|
|||
|
|
async updateLocationToServer(locationData) {
|
|||
|
|
try {
|
|||
|
|
const systemInfo = this.systemInfoHelper.getSystemInfoSync();
|
|||
|
|
|
|||
|
|
const updateData = {
|
|||
|
|
latitude: parseFloat(locationData.latitude),
|
|||
|
|
longitude: parseFloat(locationData.longitude),
|
|||
|
|
altitude: parseFloat(locationData.altitude) || 0,
|
|||
|
|
accuracy: parseFloat(locationData.accuracy) || 0,
|
|||
|
|
speed: parseFloat(locationData.speed) || 0,
|
|||
|
|
direction: parseFloat(locationData.direction) || 0,
|
|||
|
|
deviceType: 'miniprogram',
|
|||
|
|
deviceModel: systemInfo.model || 'Unknown',
|
|||
|
|
battery: systemInfo.battery || 100
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
console.log('📤 更新位置到服务器:', updateData);
|
|||
|
|
|
|||
|
|
const response = await this.apiClient.updateLocation(updateData);
|
|||
|
|
console.log('✅ 位置更新成功,服务器响应:', response);
|
|||
|
|
|
|||
|
|
// 🔥 优化:从服务器响应中获取准确的地址信息
|
|||
|
|
if (response && response.data) {
|
|||
|
|
const serverData = response.data;
|
|||
|
|
|
|||
|
|
// 检查服务器是否返回了地址信息
|
|||
|
|
if (serverData.address || serverData.district || serverData.city || serverData.province) {
|
|||
|
|
console.log('📍 位置更新接口返回了地址信息:', {
|
|||
|
|
address: serverData.address,
|
|||
|
|
district: serverData.district,
|
|||
|
|
city: serverData.city,
|
|||
|
|
province: serverData.province
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 服务器位置信息是基于坐标查询的,比本地解析更准确
|
|||
|
|
// 如果当前区域信息不准确或缺失,优先使用服务器信息
|
|||
|
|
if (!this.data.currentDistrict ||
|
|||
|
|
this.data.currentDistrict === '定位中...' ||
|
|||
|
|
this.data.currentDistrict === '位置信息' ||
|
|||
|
|
this.data.currentDistrict.includes('位置 ')) {
|
|||
|
|
|
|||
|
|
const newDistrict = serverData.district || serverData.city || this.data.currentDistrict;
|
|||
|
|
const newCity = serverData.city || this.data.currentCity;
|
|||
|
|
const newAddress = serverData.address || this.data.currentAddress;
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
currentDistrict: newDistrict,
|
|||
|
|
currentCity: newCity,
|
|||
|
|
currentAddress: newAddress
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
console.log('✅ 已使用位置更新接口的地址信息更新左上角显示:', {
|
|||
|
|
district: newDistrict,
|
|||
|
|
city: newCity
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 位置更新失败:', error);
|
|||
|
|
// 不阻断用户体验,仅记录错误
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 处理位置错误
|
|||
|
|
handleLocationError(error) {
|
|||
|
|
console.error('位置服务错误:', error);
|
|||
|
|
|
|||
|
|
let errorMessage = '获取位置失败';
|
|||
|
|
|
|||
|
|
if (error.errMsg) {
|
|||
|
|
if (error.errMsg.includes('auth deny')) {
|
|||
|
|
errorMessage = '位置权限被拒绝,请在设置中开启位置权限';
|
|||
|
|
} else if (error.errMsg.includes('timeout')) {
|
|||
|
|
errorMessage = '定位超时,请检查网络连接';
|
|||
|
|
} else if (error.errMsg.includes('locate fail')) {
|
|||
|
|
errorMessage = '定位失败,请稍后重试';
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
wx.showToast({
|
|||
|
|
title: errorMessage,
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 3000
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 设置默认位置(如果有的话)
|
|||
|
|
if (this.data.defaultLocation) {
|
|||
|
|
this.setData({
|
|||
|
|
longitude: this.data.defaultLocation.longitude,
|
|||
|
|
latitude: this.data.defaultLocation.latitude,
|
|||
|
|
currentAddress: this.data.defaultLocation.address || '位置获取失败'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 启动位置更新服务
|
|||
|
|
startLocationService() {
|
|||
|
|
console.log('🔄 启动位置更新服务');
|
|||
|
|
|
|||
|
|
// 清除旧的定时器
|
|||
|
|
if (this.locationTimer) {
|
|||
|
|
clearInterval(this.locationTimer);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 每30秒更新一次位置
|
|||
|
|
this.locationTimer = setInterval(() => {
|
|||
|
|
if (this.data.amapReady) {
|
|||
|
|
this.getCurrentLocation();
|
|||
|
|
}
|
|||
|
|
}, 30000);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 停止位置更新服务
|
|||
|
|
stopLocationService() {
|
|||
|
|
if (this.locationTimer) {
|
|||
|
|
clearInterval(this.locationTimer);
|
|||
|
|
this.locationTimer = null;
|
|||
|
|
console.log('⏹️ 位置更新服务已停止');
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 计算两点之间的距离(米)
|
|||
|
|
calculateDistance(lat1, lng1, lat2, lng2) {
|
|||
|
|
const R = 6371000; // 地球半径(米)
|
|||
|
|
const dLat = (lat2 - lat1) * Math.PI / 180;
|
|||
|
|
const dLng = (lng2 - lng1) * Math.PI / 180;
|
|||
|
|
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
|
|||
|
|
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
|
|||
|
|
Math.sin(dLng / 2) * Math.sin(dLng / 2);
|
|||
|
|
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|||
|
|
return R * c;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 格式化距离显示
|
|||
|
|
formatDistance(distance) {
|
|||
|
|
if (distance < 1000) {
|
|||
|
|
return Math.round(distance) + 'm';
|
|||
|
|
} else if (distance < 10000) {
|
|||
|
|
return (distance / 1000).toFixed(1) + 'km';
|
|||
|
|
} else {
|
|||
|
|
return Math.round(distance / 1000) + 'km';
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 加载好友位置
|
|||
|
|
async loadFriendsLocation() {
|
|||
|
|
try {
|
|||
|
|
console.log('👥 开始加载好友位置');
|
|||
|
|
|
|||
|
|
const response = await this.apiClient.getFriendsLocation();
|
|||
|
|
|
|||
|
|
// 处理API响应数据结构
|
|||
|
|
const friendsLocation = response?.data || [];
|
|||
|
|
|
|||
|
|
if (friendsLocation && friendsLocation.length > 0) {
|
|||
|
|
console.log(`📍 获取到${friendsLocation.length}个好友位置:`, friendsLocation);
|
|||
|
|
|
|||
|
|
const myLocation = this.data.myLocation;
|
|||
|
|
const friendMarkers = friendsLocation.map((friend, index) => {
|
|||
|
|
// 计算距离
|
|||
|
|
const distance = myLocation ? this.calculateDistance(
|
|||
|
|
myLocation.latitude, myLocation.longitude,
|
|||
|
|
friend.latitude, friend.longitude
|
|||
|
|
) : 0;
|
|||
|
|
|
|||
|
|
const formattedDistance = distance > 0 ? this.formatDistance(distance) : '';
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
id: index + 10, // 避免与用户位置标记ID冲突
|
|||
|
|
latitude: friend.latitude,
|
|||
|
|
longitude: friend.longitude,
|
|||
|
|
iconPath: marker_blank,
|
|||
|
|
type: 'friend',
|
|||
|
|
avatarUrl:friend.avatar,
|
|||
|
|
merchantType:'',
|
|||
|
|
nickName:friend.nickname,
|
|||
|
|
battery:100,
|
|||
|
|
width: 35,
|
|||
|
|
height: 45,
|
|||
|
|
joinCluster:true,
|
|||
|
|
title: friend.nickname || '好友',
|
|||
|
|
customCallout: {
|
|||
|
|
anchorY: 80,
|
|||
|
|
anchorX: 0,
|
|||
|
|
display: 'ALWAYS'
|
|||
|
|
},
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 🔥 合并用户位置和好友位置标记 - 使用concat替代扩展运算符
|
|||
|
|
const currentMarkers = this.data.markers || [];
|
|||
|
|
const allMarkers = currentMarkers.concat(friendMarkers);
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
markers: allMarkers,
|
|||
|
|
friendsData: friendsLocation,
|
|||
|
|
friendsCount: friendsLocation.length
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
console.log(`✅ 成功加载${friendsLocation.length}个好友位置到地图`);
|
|||
|
|
/*this.mapContext.addMarkers({
|
|||
|
|
markers: this.data.markers,
|
|||
|
|
clear: true
|
|||
|
|
})*/
|
|||
|
|
} else {
|
|||
|
|
console.log('📍 暂无好友位置信息');
|
|||
|
|
this.setData({
|
|||
|
|
friendsCount: 0
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 加载好友位置失败:', error);
|
|||
|
|
this.setData({
|
|||
|
|
friendsCount: 0
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 显示友好的错误提示(但不阻断用户体验)
|
|||
|
|
if (error.message && !error.message.includes('401')) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '好友位置加载失败',
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 2000
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
fetchMerchantList() {
|
|||
|
|
// 假数据
|
|||
|
|
const merchants = [
|
|||
|
|
{
|
|||
|
|
id: 1,
|
|||
|
|
name: "星巴克咖啡",
|
|||
|
|
address: "北京市朝阳区建国路88号",
|
|||
|
|
latitude: 39.908823,
|
|||
|
|
longitude: 116.397470,
|
|||
|
|
distance: 205, // 单位:米
|
|||
|
|
packages: [
|
|||
|
|
{ title: "套餐一", desc: "咖啡+三明治", price: "¥28" },
|
|||
|
|
{ title: "套餐二", desc: "意面+饮料", price: "¥88" },
|
|||
|
|
{ title: "套餐三", desc: "蛋糕+拿铁", price: "¥288" },
|
|||
|
|
],
|
|||
|
|
isFavorited: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 2,
|
|||
|
|
name: "星巴克咖啡2",
|
|||
|
|
address: "北京市朝阳区建国路88号",
|
|||
|
|
latitude: 44.90697,
|
|||
|
|
longitude: 82.06665,
|
|||
|
|
distance: 205, // 单位:米
|
|||
|
|
packages: [
|
|||
|
|
{ title: "套餐一", desc: "咖啡+三明治", price: "¥28" },
|
|||
|
|
{ title: "套餐二", desc: "意面+饮料", price: "¥88" },
|
|||
|
|
{ title: "套餐三", desc: "蛋糕+拿铁", price: "¥288" },
|
|||
|
|
],
|
|||
|
|
isFavorited: false,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
id: 3,
|
|||
|
|
name: "星巴克咖啡3",
|
|||
|
|
address: "北京市朝阳区建国路88号",
|
|||
|
|
latitude: 44.90697,
|
|||
|
|
longitude: 82.06765,
|
|||
|
|
distance: 205, // 单位:米
|
|||
|
|
packages: [
|
|||
|
|
{ title: "套餐一", desc: "咖啡+三明治", price: "¥28" },
|
|||
|
|
{ title: "套餐二", desc: "意面+饮料", price: "¥88" },
|
|||
|
|
{ title: "套餐三", desc: "蛋糕+拿铁", price: "¥288" },
|
|||
|
|
],
|
|||
|
|
isFavorited: false,
|
|||
|
|
},
|
|||
|
|
];
|
|||
|
|
// 设置 marker
|
|||
|
|
const merchantMarkers = merchants.map(m => ({
|
|||
|
|
id: 10000 + m.id, // 避免与其他 marker 冲突
|
|||
|
|
latitude: m.latitude,
|
|||
|
|
longitude: m.longitude,
|
|||
|
|
iconPath: marker_blank, // 需准备商家marker图标
|
|||
|
|
type: 'merchant',
|
|||
|
|
avatarUrl:'',
|
|||
|
|
merchantType:'kafei',
|
|||
|
|
nickName:m.name,
|
|||
|
|
battery:100,
|
|||
|
|
width: 36,
|
|||
|
|
height: 36,
|
|||
|
|
joinCluster:true,
|
|||
|
|
customCallout: {
|
|||
|
|
anchorY: 80,
|
|||
|
|
anchorX: 0,
|
|||
|
|
display: 'ALWAYS'
|
|||
|
|
},
|
|||
|
|
merchantId: m.id,
|
|||
|
|
}));
|
|||
|
|
this.setData({
|
|||
|
|
merchantList: merchants,
|
|||
|
|
merchantMarkers,
|
|||
|
|
// 合并到地图markers
|
|||
|
|
markers: [...(this.data.markers || []), ...merchantMarkers],
|
|||
|
|
});
|
|||
|
|
/*this.mapContext.addMarkers({
|
|||
|
|
markers: this.data.markers,
|
|||
|
|
clear: true
|
|||
|
|
})*/
|
|||
|
|
},
|
|||
|
|
// 回到自己位置 - 定位按钮功能
|
|||
|
|
centerToUserLocation() {
|
|||
|
|
console.log('📍 回到我的位置');
|
|||
|
|
|
|||
|
|
if (!this.data.myLocation) {
|
|||
|
|
console.log('⚠️ 我的位置信息不存在,重新获取位置');
|
|||
|
|
this.getCurrentLocation();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 移动地图到自己的位置
|
|||
|
|
this.mapContext.moveToLocation({
|
|||
|
|
latitude: this.data.myLocation.latitude,
|
|||
|
|
longitude: this.data.myLocation.longitude
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 重置缩放级别到合适的级别
|
|||
|
|
this.setData({
|
|||
|
|
latitude: this.data.myLocation.latitude,
|
|||
|
|
longitude: this.data.myLocation.longitude,
|
|||
|
|
scale: 16
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 给用户一个反馈
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '已回到我的位置',
|
|||
|
|
icon: 'success',
|
|||
|
|
duration: 1500
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 地图区域变化完成事件
|
|||
|
|
onMapRegionChange(e) {
|
|||
|
|
const detail = e.detail || {};
|
|||
|
|
const changeType = e.type || 'unknown';
|
|||
|
|
console.log('🗺️ 地图区域变化:', {
|
|||
|
|
type: changeType,
|
|||
|
|
detail: detail,
|
|||
|
|
scale: detail.scale,
|
|||
|
|
latitude: detail.latitude,
|
|||
|
|
longitude: detail.longitude
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 只在拖拽结束时处理,避免频繁触发
|
|||
|
|
if (changeType === 'end' && detail.scale) {
|
|||
|
|
const currentScale = detail.scale;
|
|||
|
|
console.log(`📏 缩放级别变化完成: ${currentScale}, 阈值: ${this.data.autoSatelliteZoom}, 模式: ${this.data.currentMapType}`);
|
|||
|
|
this.handleAutoSatelliteSwitch(currentScale);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 自动卫星图切换逻辑
|
|||
|
|
handleAutoSatelliteSwitch(scale) {
|
|||
|
|
const threshold = this.data.autoSatelliteZoom;
|
|||
|
|
const shouldUseSatellite = scale >= threshold;
|
|||
|
|
const currentlyUsingSatellite = this.data.enableSatellite;
|
|||
|
|
const isStandardMode = this.data.currentMapType === 'standard';
|
|||
|
|
|
|||
|
|
console.log(`🔍 自动切换检查: 缩放=${scale}, 阈值=${threshold}, 应该用卫星=${shouldUseSatellite}, 当前用卫星=${currentlyUsingSatellite}, 标准模式=${isStandardMode}`);
|
|||
|
|
|
|||
|
|
// 只有在标准地图模式下才进行自动切换
|
|||
|
|
if (isStandardMode) {
|
|||
|
|
if (shouldUseSatellite && !currentlyUsingSatellite) {
|
|||
|
|
// 缩放级别够高,自动启用卫星图
|
|||
|
|
console.log('🛰️ 自动切换到卫星图 (缩放级别:', scale, ')');
|
|||
|
|
this.setData({
|
|||
|
|
enableSatellite: true
|
|||
|
|
});
|
|||
|
|
} else if (!shouldUseSatellite && currentlyUsingSatellite) {
|
|||
|
|
// 缩放级别降低,自动关闭卫星图
|
|||
|
|
console.log('🗺️ 自动切换回标准地图 (缩放级别:', scale, ')');
|
|||
|
|
this.setData({
|
|||
|
|
enableSatellite: false
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 地图点击事件
|
|||
|
|
onMapTap(e) {
|
|||
|
|
console.log('🗺️ 地图点击:', e.detail);
|
|||
|
|
// 点击地图时关闭用户详情卡片
|
|||
|
|
this.closeUserCard();
|
|||
|
|
// 相机移动到点击位置
|
|||
|
|
if (e && e.detail && e.detail.latitude && e.detail.longitude) {
|
|||
|
|
this.mapContext && this.mapContext.moveToLocation({
|
|||
|
|
latitude: e.detail.latitude,
|
|||
|
|
longitude: e.detail.longitude
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 地图长按事件
|
|||
|
|
onMapLongTap(e) {
|
|||
|
|
console.log('🗺️ 地图长按:', e.detail);
|
|||
|
|
// 你可以在这里弹窗、添加标记、获取经纬度等
|
|||
|
|
wx.showToast({
|
|||
|
|
title: `长按:${e.detail.latitude.toFixed(6)},${e.detail.longitude.toFixed(6)}`,
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 标记点击事件
|
|||
|
|
onMarkerTap(e) {
|
|||
|
|
const markerId = e.detail.markerId || e.markerId;
|
|||
|
|
console.log('📍 标记点击:', markerId);
|
|||
|
|
|
|||
|
|
if (markerId === 1) {
|
|||
|
|
// 点击的是用户自己的位置
|
|||
|
|
console.log('点击了自己的位置标记');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 查找对应的好友数据
|
|||
|
|
const friendIndex = markerId - 10; // 减去偏移量
|
|||
|
|
const friendData = this.data.friendsData[friendIndex];
|
|||
|
|
|
|||
|
|
if (friendData) {
|
|||
|
|
// 计算距离
|
|||
|
|
const myLocation = this.data.myLocation;
|
|||
|
|
const distance = myLocation ? this.calculateDistance(
|
|||
|
|
myLocation.latitude, myLocation.longitude,
|
|||
|
|
friendData.latitude, friendData.longitude
|
|||
|
|
) : 0;
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
selectedUser: {
|
|||
|
|
...friendData,
|
|||
|
|
distance: distance > 0 ? this.formatDistance(distance) : '',
|
|||
|
|
userId: friendData.customId || friendData.userId,
|
|||
|
|
isFriend: true
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (markerId >= 10000) {
|
|||
|
|
const merchant = this.data.merchantList.find(m => m.id === markerId - 10000);
|
|||
|
|
if (merchant) {
|
|||
|
|
this.setData({
|
|||
|
|
selectedMerchant: merchant,
|
|||
|
|
merchantInfoModalVisible: true,
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 地图POI点击事件
|
|||
|
|
onPoiTap(e) {
|
|||
|
|
var self = this;
|
|||
|
|
console.log('📍 POI点击事件:', e.detail);
|
|||
|
|
const poi = {
|
|||
|
|
name: e.detail.name,
|
|||
|
|
address: e.detail.address || '',
|
|||
|
|
latitude: e.detail.latitude,
|
|||
|
|
longitude: e.detail.longitude
|
|||
|
|
};
|
|||
|
|
//获取地址描述
|
|||
|
|
if(poi.address == ''){
|
|||
|
|
this.amapFun.getRegeo({
|
|||
|
|
location:''+poi.longitude+','+poi.latitude,
|
|||
|
|
success:function(data){
|
|||
|
|
console.log(data);
|
|||
|
|
poi.address = data[0].name
|
|||
|
|
self.setData({ poiDetail: poi });
|
|||
|
|
},
|
|||
|
|
fail: function(info){
|
|||
|
|
wx.showModal({title:info.errMsg})
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
this.setData({ poiDetail: poi });
|
|||
|
|
//this.reverseGeocodeForPoi(poi.latitude, poi.longitude);
|
|||
|
|
// 移动地图相机到POI位置,缩放到18级,并向上偏移
|
|||
|
|
const offsetY = this.data.windowHeight ? Math.round(this.data.windowHeight / 2.8) : 220;
|
|||
|
|
this.mapContext && this.mapContext.moveToLocation({
|
|||
|
|
latitude: poi.latitude,
|
|||
|
|
longitude: poi.longitude
|
|||
|
|
});
|
|||
|
|
this.setData({
|
|||
|
|
latitude: poi.latitude,
|
|||
|
|
longitude: poi.longitude,
|
|||
|
|
scale: 18
|
|||
|
|
});
|
|||
|
|
setTimeout(() => {
|
|||
|
|
this.mapContext && this.mapContext.translateMarker && this.mapContext.translateMarker({
|
|||
|
|
markerId: 0,
|
|||
|
|
destination: {
|
|||
|
|
latitude: poi.latitude,
|
|||
|
|
longitude: poi.longitude
|
|||
|
|
},
|
|||
|
|
autoRotate: false,
|
|||
|
|
duration: 300,
|
|||
|
|
// 通过animationEnd回调实现偏移
|
|||
|
|
animationEnd: () => {
|
|||
|
|
this.mapContext && this.mapContext.moveToLocation({
|
|||
|
|
latitude: poi.latitude,
|
|||
|
|
longitude: poi.longitude
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
// 通过include-points实现偏移(兼容无marker情况)
|
|||
|
|
this.mapContext && this.mapContext.includePoints && this.mapContext.includePoints({
|
|||
|
|
points: [{ latitude: poi.latitude, longitude: poi.longitude }],
|
|||
|
|
padding: [offsetY, 40, 40, 40]
|
|||
|
|
});
|
|||
|
|
}, 200);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 查询POI详细地址并更新弹窗
|
|||
|
|
async reverseGeocodeForPoi(latitude, longitude) {
|
|||
|
|
try {
|
|||
|
|
const location = this.getLocationByCoordinates(latitude, longitude);
|
|||
|
|
if (location && location.address) {
|
|||
|
|
this.setData({
|
|||
|
|
'poiDetail.address': location.address
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('POI逆地理编码失败:', error);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 关闭POI详情卡片
|
|||
|
|
closePoiCard() {
|
|||
|
|
this.setData({
|
|||
|
|
poiDetail: null
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// POI操作:导航
|
|||
|
|
onPoiNavigate() {
|
|||
|
|
const poi = this.data.poiDetail;
|
|||
|
|
if (!poi) {
|
|||
|
|
wx.showToast({ title: '无POI信息', icon: 'none' });
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
wx.openLocation({
|
|||
|
|
latitude: poi.latitude,
|
|||
|
|
longitude: poi.longitude,
|
|||
|
|
name: poi.name || '目标位置',
|
|||
|
|
address: poi.address || '',
|
|||
|
|
scale: 16
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// POI操作:提醒
|
|||
|
|
onPoiRemind() {
|
|||
|
|
// 关闭POI弹窗,打开提醒弹窗,初始化范围、好友、模式
|
|||
|
|
const poi = this.data.poiDetail;
|
|||
|
|
this.setData({
|
|||
|
|
showPoiRemindModal: true,
|
|||
|
|
poiRemindRadius: 300,
|
|||
|
|
poiRemindSelectedFriends: [],
|
|||
|
|
poiRemindMode: ['arrive'], // 多选
|
|||
|
|
showFriendSelectModal: false,
|
|||
|
|
lastPoiForRemind: poi
|
|||
|
|
});
|
|||
|
|
this.updatePoiRemindCircle(300);
|
|||
|
|
if (poi) {
|
|||
|
|
this.fitMapToCircle(poi.latitude, poi.longitude, 300);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
// 到达/离开提醒多选切换
|
|||
|
|
onPoiRemindModeChange(e) {
|
|||
|
|
let values = e.detail.value;
|
|||
|
|
if (!Array.isArray(values)) {
|
|||
|
|
values = values ? [values] : [];
|
|||
|
|
}
|
|||
|
|
// 至少保留一个选项,若全取消则默认到达
|
|||
|
|
if (values.length === 0) {
|
|||
|
|
values = ['arrive'];
|
|||
|
|
}
|
|||
|
|
this.setData({ poiRemindMode: values });
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 切换好友选中状态
|
|||
|
|
onToggleFriendSelect(e) {
|
|||
|
|
const userId = e.currentTarget.dataset.userid;
|
|||
|
|
// 选满且未选中的不能再点
|
|||
|
|
if (this.data.poiRemindSelectedFriends.length >= 3 && !this.isFriendSelected(userId)) return;
|
|||
|
|
let selected = this.data.poiRemindSelectedFriends.slice();
|
|||
|
|
const idx = selected.findIndex(f => f.userId === userId);
|
|||
|
|
if (idx > -1) {
|
|||
|
|
selected.splice(idx, 1);
|
|||
|
|
} else {
|
|||
|
|
if (selected.length >= 3) {
|
|||
|
|
wx.showToast({ title: '最多选择3位好友', icon: 'none' });
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const friend = this.data.allFriendsList.find(f => f.userId === userId);
|
|||
|
|
if (friend) selected.push(friend);
|
|||
|
|
}
|
|||
|
|
// 更新filteredFriendsList的selected字段
|
|||
|
|
const selectedIds = selected.map(f => f.userId);
|
|||
|
|
const filteredFriendsList = this.data.filteredFriendsList.map(f => ({
|
|||
|
|
...f,
|
|||
|
|
selected: selectedIds.includes(f.userId)
|
|||
|
|
}));
|
|||
|
|
this.setData({ poiRemindSelectedFriends: selected, filteredFriendsList });
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 判断某个好友是否已被选中
|
|||
|
|
isFriendSelected(userId) {
|
|||
|
|
return this.data.poiRemindSelectedFriends.some(f => f.userId === userId);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 完成好友选择,关闭弹窗
|
|||
|
|
onFriendSelectDone() {
|
|||
|
|
this.setData({ showFriendSelectModal: false });
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 关闭弹窗
|
|||
|
|
onCloseFriendSelect() {
|
|||
|
|
this.setData({ showFriendSelectModal: false });
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 移除已选好友
|
|||
|
|
onRemoveSelectedFriend(e) {
|
|||
|
|
const userId = e.currentTarget.dataset.userid;
|
|||
|
|
let selected = this.data.poiRemindSelectedFriends.slice();
|
|||
|
|
const idx = selected.findIndex(f => f.userId === userId);
|
|||
|
|
if (idx > -1) {
|
|||
|
|
selected.splice(idx, 1);
|
|||
|
|
// 更新filteredFriendsList的selected字段
|
|||
|
|
const selectedIds = selected.map(f => f.userId);
|
|||
|
|
const filteredFriendsList = this.data.filteredFriendsList.map(f => ({
|
|||
|
|
...f,
|
|||
|
|
selected: selectedIds.includes(f.userId)
|
|||
|
|
}));
|
|||
|
|
this.setData({ poiRemindSelectedFriends: selected, filteredFriendsList });
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 关闭提醒弹窗
|
|||
|
|
closePoiRemindModal() {
|
|||
|
|
this.setData({ showPoiRemindModal: false });
|
|||
|
|
this.updatePoiRemindCircle(0); // 隐藏圆圈
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 拖动滑动条时更新范围和圆圈
|
|||
|
|
onPoiRemindRadiusChange(e) {
|
|||
|
|
const radius = Number(e.detail.value);
|
|||
|
|
this.setData({ poiRemindRadius: radius });
|
|||
|
|
this.updatePoiRemindCircle(radius);
|
|||
|
|
// 地图相机包含提醒范围(自适应padding)
|
|||
|
|
const poi = this.data.lastPoiForRemind;
|
|||
|
|
if (poi) {
|
|||
|
|
this.fitMapToCircle(poi.latitude, poi.longitude, radius);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 更新地图上的圆圈覆盖物
|
|||
|
|
updatePoiRemindCircle(radius) {
|
|||
|
|
const poi = this.data.poiDetail || this.data.lastPoiForRemind;
|
|||
|
|
if (!poi || !radius) {
|
|||
|
|
this.setData({ circles: [] });
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
this.setData({
|
|||
|
|
circles: [{
|
|||
|
|
latitude: poi.latitude,
|
|||
|
|
longitude: poi.longitude,
|
|||
|
|
color: '#667eea88',
|
|||
|
|
fillColor: '#667eea22',
|
|||
|
|
radius: radius,
|
|||
|
|
strokeWidth: 2
|
|||
|
|
}],
|
|||
|
|
lastPoiForRemind: poi
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 刷新数据
|
|||
|
|
onRefresh() {
|
|||
|
|
console.log('🔄 刷新地图数据');
|
|||
|
|
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '刷新中...',
|
|||
|
|
icon: 'loading',
|
|||
|
|
duration: 1000
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 重新获取位置和好友数据
|
|||
|
|
this.getCurrentLocation();
|
|||
|
|
|
|||
|
|
// 如果已有位置信息,直接刷新其他数据
|
|||
|
|
if (this.data.myLocation) {
|
|||
|
|
this.loadWeatherInfo(this.data.myLocation.latitude, this.data.myLocation.longitude);
|
|||
|
|
this.loadNearbyUsers();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 切换地图图层
|
|||
|
|
toggleMapLayer() {
|
|||
|
|
const newMapType = this.data.currentMapType === 'standard' ? 'satellite' : 'standard';
|
|||
|
|
const newEnableSatellite = newMapType === 'satellite';
|
|||
|
|
|
|||
|
|
console.log(`🗺️ 手动切换地图图层: ${this.data.currentMapType} -> ${newMapType}`);
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
currentMapType: newMapType,
|
|||
|
|
enableSatellite: newEnableSatellite
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
wx.showToast({
|
|||
|
|
title: newMapType === 'satellite' ? '卫星地图' : '标准地图',
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 1000
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 关闭用户详情卡片
|
|||
|
|
closeUserCard() {
|
|||
|
|
this.setData({
|
|||
|
|
selectedUser: null
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 开始聊天
|
|||
|
|
startChat(e) {
|
|||
|
|
const userId = e.currentTarget.dataset.userid;
|
|||
|
|
console.log('💬 开始聊天:', userId);
|
|||
|
|
|
|||
|
|
// 获取当前用户信息
|
|||
|
|
const userInfo = this.data.userInfo;
|
|||
|
|
if (!userInfo) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '用户信息错误',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 获取当前用户ID
|
|||
|
|
const currentUserId = userInfo.user?.customId || userInfo.customId || '';
|
|||
|
|
if (!currentUserId) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '用户ID错误',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 构建会话ID(单聊格式)
|
|||
|
|
// 🔥 修复:不传递conversationId,让聊天页面从API获取正确的会话ID
|
|||
|
|
|
|||
|
|
// 跳转到聊天页面,使用正确的路径和参数格式
|
|||
|
|
wx.navigateTo({
|
|||
|
|
url: `/pages/message/chat/chat?targetId=${userId}&name=${encodeURIComponent('用户')}&chatType=0`
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 添加好友
|
|||
|
|
addFriend(e) {
|
|||
|
|
const userId = e.currentTarget.dataset.userid;
|
|||
|
|
console.log('👥 添加好友:', userId);
|
|||
|
|
|
|||
|
|
// 实现添加好友逻辑
|
|||
|
|
wx.showModal({
|
|||
|
|
title: '添加好友',
|
|||
|
|
content: '确定要添加这位用户为好友吗?',
|
|||
|
|
success: (res) => {
|
|||
|
|
if (res.confirm) {
|
|||
|
|
// 调用添加好友API
|
|||
|
|
this.performAddFriend(userId);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 执行添加好友
|
|||
|
|
async performAddFriend(userId) {
|
|||
|
|
try {
|
|||
|
|
const response = await this.apiClient.addFriend(userId, '通过地图添加');
|
|||
|
|
|
|||
|
|
if (response.code === 0) {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '好友请求已发送',
|
|||
|
|
icon: 'success'
|
|||
|
|
});
|
|||
|
|
this.closeUserCard();
|
|||
|
|
} else {
|
|||
|
|
throw new Error(response.message || '添加好友失败');
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('添加好友失败:', error);
|
|||
|
|
wx.showToast({
|
|||
|
|
title: error.message || '添加好友失败',
|
|||
|
|
icon: 'none'
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 查看用户资料
|
|||
|
|
viewProfile(e) {
|
|||
|
|
const userId = e.currentTarget.dataset.userid;
|
|||
|
|
console.log('👤 查看用户资料:', userId);
|
|||
|
|
|
|||
|
|
// 跳转到用户资料页面
|
|||
|
|
wx.navigateTo({
|
|||
|
|
url: `/pages/user-profile/user-profile?userId=${userId}`
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 获取天气信息
|
|||
|
|
async loadWeatherInfo(latitude, longitude) {
|
|||
|
|
try {
|
|||
|
|
console.log('🌤️ 开始获取天气信息');
|
|||
|
|
|
|||
|
|
const response = await this.apiClient.getWeatherInfo(latitude, longitude);
|
|||
|
|
|
|||
|
|
if (response && response.code === 0 && response.data) {
|
|||
|
|
const weatherData = response.data;
|
|||
|
|
|
|||
|
|
// 转换天气图标
|
|||
|
|
const weatherIcon = this.getWeatherIcon(weatherData.weather, weatherData.icon);
|
|||
|
|
|
|||
|
|
// 判断是否为云彩图标
|
|||
|
|
const isCloudIcon = this.isCloudWeatherIcon(weatherData.weather, weatherData.icon, weatherIcon);
|
|||
|
|
|
|||
|
|
const weatherInfo = {
|
|||
|
|
temperature: Math.round(weatherData.temperature),
|
|||
|
|
weather: weatherData.weather,
|
|||
|
|
icon: weatherIcon,
|
|||
|
|
isCloudIcon: isCloudIcon,
|
|||
|
|
humidity: weatherData.humidity,
|
|||
|
|
windSpeed: weatherData.windSpeed,
|
|||
|
|
windDir: weatherData.windDir,
|
|||
|
|
aqi: weatherData.aqi,
|
|||
|
|
city: weatherData.city,
|
|||
|
|
updateTime: weatherData.updateTime
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 🔥 重要修复:使用天气接口返回的准确位置信息更新左上角显示
|
|||
|
|
if (weatherData.city) {
|
|||
|
|
console.log('📍 使用天气接口返回的准确位置信息更新区域显示:', {
|
|||
|
|
weather_city: weatherData.city,
|
|||
|
|
current_district: this.data.currentDistrict,
|
|||
|
|
current_city: this.data.currentCity
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 天气接口返回的城市信息是最准确的(基于坐标查询的)
|
|||
|
|
// 优先使用天气接口的位置信息更新左上角显示
|
|||
|
|
let newDistrict = this.data.currentDistrict;
|
|||
|
|
let newCity = weatherData.city;
|
|||
|
|
|
|||
|
|
// 如果当前区域信息不准确或缺失,使用天气接口的城市信息
|
|||
|
|
if (!this.data.currentDistrict ||
|
|||
|
|
this.data.currentDistrict === '定位中...' ||
|
|||
|
|
this.data.currentDistrict === '位置信息' ||
|
|||
|
|
this.data.currentDistrict.includes('位置 ')) {
|
|||
|
|
newDistrict = weatherData.city;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新区域显示信息
|
|||
|
|
this.setData({
|
|||
|
|
currentCity: newCity,
|
|||
|
|
currentDistrict: newDistrict,
|
|||
|
|
weatherInfo: weatherInfo
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
console.log('✅ 已使用天气接口的位置信息更新左上角显示:', {
|
|||
|
|
district: newDistrict,
|
|||
|
|
city: newCity
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
// 没有城市信息时,只更新天气信息
|
|||
|
|
this.setData({
|
|||
|
|
weatherInfo: weatherInfo
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('✅ 天气信息获取成功:', weatherInfo);
|
|||
|
|
} else {
|
|||
|
|
console.log('⚠️ 天气信息获取失败或无数据');
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 获取天气信息失败:', error);
|
|||
|
|
// 不显示错误提示,静默失败,不影响用户体验
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 根据天气状况获取对应的表情符号
|
|||
|
|
getWeatherIcon(weather, iconCode) {
|
|||
|
|
// 天气图标映射
|
|||
|
|
const weatherIcons = {
|
|||
|
|
'晴': '☀️',
|
|||
|
|
'多云': '⛅',
|
|||
|
|
'阴': '☁️',
|
|||
|
|
'小雨': '🌦️',
|
|||
|
|
'中雨': '🌧️',
|
|||
|
|
'大雨': '⛈️',
|
|||
|
|
'雷雨': '⛈️',
|
|||
|
|
'雪': '❄️',
|
|||
|
|
'小雪': '🌨️',
|
|||
|
|
'大雪': '❄️',
|
|||
|
|
'雾': '🌫️',
|
|||
|
|
'霾': '😷',
|
|||
|
|
'沙尘': '🌪️'
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 根据iconCode映射
|
|||
|
|
const iconMapping = {
|
|||
|
|
'clear-day': '☀️',
|
|||
|
|
'clear-night': '🌙',
|
|||
|
|
'partly-cloudy-day': '⛅',
|
|||
|
|
'partly-cloudy-night': '☁️',
|
|||
|
|
'cloudy': '☁️',
|
|||
|
|
'rain': '🌧️',
|
|||
|
|
'sleet': '🌨️',
|
|||
|
|
'snow': '❄️',
|
|||
|
|
'wind': '💨',
|
|||
|
|
'fog': '🌫️'
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
let finalIcon = '🌤️';
|
|||
|
|
|
|||
|
|
// 优先使用iconCode映射,其次使用天气描述映射
|
|||
|
|
if (iconCode && iconMapping[iconCode]) {
|
|||
|
|
finalIcon = iconMapping[iconCode];
|
|||
|
|
} else if (weather && weatherIcons[weather]) {
|
|||
|
|
finalIcon = weatherIcons[weather];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return finalIcon;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 判断是否为云彩相关图标(需要变成黑色)
|
|||
|
|
isCloudWeatherIcon(weather, iconCode, icon) {
|
|||
|
|
// 云彩相关的天气状况
|
|||
|
|
const cloudWeatherTypes = ['多云', '阴', '雾', '霾'];
|
|||
|
|
|
|||
|
|
// 云彩相关的iconCode
|
|||
|
|
const cloudIconCodes = ['partly-cloudy-day', 'partly-cloudy-night', 'cloudy', 'fog'];
|
|||
|
|
|
|||
|
|
// 云彩相关的emoji
|
|||
|
|
const cloudEmojis = ['⛅', '☁️', '🌫️'];
|
|||
|
|
|
|||
|
|
// 检查各种条件
|
|||
|
|
if (weather && cloudWeatherTypes.includes(weather)) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (iconCode && cloudIconCodes.includes(iconCode)) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (icon && cloudEmojis.includes(icon)) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 获取附近用户(新增功能)
|
|||
|
|
async loadNearbyUsers() {
|
|||
|
|
try {
|
|||
|
|
const myLocation = this.data.myLocation;
|
|||
|
|
if (!myLocation) {
|
|||
|
|
console.log('⚠️ 当前位置信息不可用,无法获取附近用户');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('👥 开始获取附近用户');
|
|||
|
|
|
|||
|
|
const response = await this.apiClient.getNearbyUsers({
|
|||
|
|
latitude: myLocation.latitude,
|
|||
|
|
longitude: myLocation.longitude,
|
|||
|
|
radius: 1000 // 1公里范围
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
if (response && response.code === 0 && response.data) {
|
|||
|
|
const nearbyUsers = response.data;
|
|||
|
|
console.log(`📍 获取到${nearbyUsers.length}个附近用户:`, nearbyUsers);
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
strangersCount: nearbyUsers.length
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
console.log('📍 暂无附近用户');
|
|||
|
|
this.setData({
|
|||
|
|
strangersCount: 0
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('❌ 获取附近用户失败:', error);
|
|||
|
|
this.setData({
|
|||
|
|
strangersCount: 0
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 🔥 ===== 浮动UI数据加载 =====
|
|||
|
|
|
|||
|
|
// 加载浮动UI相关数据
|
|||
|
|
async loadFloatingUIData() {
|
|||
|
|
try {
|
|||
|
|
console.log('🔥 加载浮动UI数据');
|
|||
|
|
|
|||
|
|
// 并行加载各种统计数据
|
|||
|
|
await Promise.all([
|
|||
|
|
this.loadUnreadMessageCount(),
|
|||
|
|
this.loadFriendRequestCount(),
|
|||
|
|
this.loadNearbyCount()
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('加载浮动UI数据失败:', error);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 加载未读消息数
|
|||
|
|
async loadUnreadMessageCount() {
|
|||
|
|
try {
|
|||
|
|
// 这里应该调用消息API获取未读数
|
|||
|
|
// const response = await chatAPI.getTotalUnreadCount();
|
|||
|
|
// this.updateUnreadMessageCount(response.data?.count || 0);
|
|||
|
|
|
|||
|
|
// 临时模拟数据
|
|||
|
|
this.updateUnreadMessageCount(0);
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('加载未读消息数失败:', error);
|
|||
|
|
this.updateUnreadMessageCount(0);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 加载好友请求数
|
|||
|
|
async loadFriendRequestCount() {
|
|||
|
|
try {
|
|||
|
|
// 这里应该调用好友API获取请求数
|
|||
|
|
// const response = await friendAPI.getFriendRequestCount();
|
|||
|
|
// this.updateFriendRequestCount(response.data?.count || 0);
|
|||
|
|
|
|||
|
|
// 临时模拟数据
|
|||
|
|
this.updateFriendRequestCount(0);
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('加载好友请求数失败:', error);
|
|||
|
|
this.updateFriendRequestCount(0);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 加载附近的人数量
|
|||
|
|
async loadNearbyCount() {
|
|||
|
|
try {
|
|||
|
|
// 使用现有的loadNearbyUsers方法
|
|||
|
|
await this.loadNearbyUsers();
|
|||
|
|
this.updateNearbyCount(this.data.strangersCount);
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('加载附近的人数量失败:', error);
|
|||
|
|
this.updateNearbyCount(0);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 🔥 ===== 浮动UI事件处理 =====
|
|||
|
|
|
|||
|
|
// 打开个人页面
|
|||
|
|
openProfile() {
|
|||
|
|
console.log('🔥 打开个人页面');
|
|||
|
|
wx.navigateTo({
|
|||
|
|
url: '/pages/profile/profile'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 打开好友页面
|
|||
|
|
openFriends() {
|
|||
|
|
console.log('🔥 打开好友页面');
|
|||
|
|
wx.navigateTo({
|
|||
|
|
url: '/pages/social/friends/friends'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 打开消息页面
|
|||
|
|
openMessages() {
|
|||
|
|
console.log('🔥 打开消息页面');
|
|||
|
|
wx.navigateTo({
|
|||
|
|
url: '/pages/message/message'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 打开WebSocket测试页面(开发调试用)
|
|||
|
|
openWebSocketTest() {
|
|||
|
|
console.log('🔧 打开WebSocket测试页面');
|
|||
|
|
wx.navigateTo({
|
|||
|
|
url: '/pages/websocket-test/websocket-test'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
// 打开好友选择弹窗
|
|||
|
|
onOpenFriendSelectModal() {
|
|||
|
|
console.log('选择好友弹窗触发');
|
|||
|
|
// 同步selected字段
|
|||
|
|
const selectedIds = this.data.poiRemindSelectedFriends.map(f => f.userId);
|
|||
|
|
const filteredFriendsList = this.data.filteredFriendsList.map(f => ({
|
|||
|
|
...f,
|
|||
|
|
selected: selectedIds.includes(f.userId)
|
|||
|
|
}));
|
|||
|
|
this.setData({ showFriendSelectModal: true, filteredFriendsList });
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 搜索输入
|
|||
|
|
onFriendSearchInput(e) {
|
|||
|
|
const text = e.detail.value.trim();
|
|||
|
|
const list = this.data.allFriendsList.filter(f => !text || (f.nickname && f.nickname.indexOf(text) !== -1));
|
|||
|
|
// 同步selected字段
|
|||
|
|
const selectedIds = this.data.poiRemindSelectedFriends.map(f => f.userId);
|
|||
|
|
const filteredFriendsList = list.map(f => ({
|
|||
|
|
...f,
|
|||
|
|
selected: selectedIds.includes(f.userId)
|
|||
|
|
}));
|
|||
|
|
this.setData({ friendSearchText: text, filteredFriendsList });
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 切换地图图层
|
|||
|
|
toggleMapLayer() {
|
|||
|
|
const newSatelliteMode = !this.data.enableSatellite;
|
|||
|
|
console.log('🔥 切换地图图层:', newSatelliteMode ? '卫星图' : '标准地图');
|
|||
|
|
|
|||
|
|
this.setData({
|
|||
|
|
enableSatellite: newSatelliteMode,
|
|||
|
|
currentMapType: newSatelliteMode ? 'satellite' : 'standard'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
wx.showToast({
|
|||
|
|
title: newSatelliteMode ? '已切换到卫星图' : '已切换到标准地图',
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 1500
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 显示附近的人
|
|||
|
|
showNearbyPeople() {
|
|||
|
|
console.log('🔥 显示附近的人');
|
|||
|
|
|
|||
|
|
// 切换到显示附近的人
|
|||
|
|
this.setData({
|
|||
|
|
currentFilter: 'strangers'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 刷新附近用户数据
|
|||
|
|
this.loadNearbyUsers();
|
|||
|
|
|
|||
|
|
wx.showToast({
|
|||
|
|
title: `发现${this.data.strangersCount}个附近的人`,
|
|||
|
|
icon: 'none',
|
|||
|
|
duration: 2000
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 🔥 ===== 数据更新方法 =====
|
|||
|
|
|
|||
|
|
// 更新未读消息数
|
|||
|
|
updateUnreadMessageCount(count) {
|
|||
|
|
this.setData({
|
|||
|
|
unreadMessageCount: count || 0
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 更新好友请求数
|
|||
|
|
updateFriendRequestCount(count) {
|
|||
|
|
this.setData({
|
|||
|
|
friendRequestCount: count || 0
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 更新附近的人数量
|
|||
|
|
updateNearbyCount(count) {
|
|||
|
|
this.setData({
|
|||
|
|
nearbyCount: count || 0
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 更新在线状态
|
|||
|
|
updateOnlineStatus(isOnline) {
|
|||
|
|
this.setData({
|
|||
|
|
isOnline: isOnline !== false
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 让地图相机完整显示以(lat, lng)为圆心,radius为半径的圆
|
|||
|
|
fitMapToCircle(lat, lng, radius) {
|
|||
|
|
// 计算圆的四个边界点(上、下、左、右)
|
|||
|
|
// 1度纬度约等于111km,1度经度约等于111km*cos(纬度)
|
|||
|
|
const latDelta = radius / 111000;
|
|||
|
|
const lngDelta = radius / (111000 * Math.cos(lat * Math.PI / 180));
|
|||
|
|
const points = [
|
|||
|
|
{ latitude: lat + latDelta, longitude: lng }, // 上
|
|||
|
|
{ latitude: lat - latDelta, longitude: lng }, // 下
|
|||
|
|
{ latitude: lat, longitude: lng + lngDelta }, // 右
|
|||
|
|
{ latitude: lat, longitude: lng - lngDelta }, // 左
|
|||
|
|
{ latitude: lat, longitude: lng } // 圆心
|
|||
|
|
];
|
|||
|
|
// padding自适应,半径越大padding越小,最小40最大100
|
|||
|
|
let padding = Math.max(40, 120 - Math.round(radius / 10));
|
|||
|
|
this.mapContext && this.mapContext.includePoints && this.mapContext.includePoints({
|
|||
|
|
points,
|
|||
|
|
padding: [padding, padding, padding, padding]
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 保存POI提醒设置
|
|||
|
|
onSavePoiRemind() {
|
|||
|
|
wx.showToast({
|
|||
|
|
title: '提醒设置已保存',
|
|||
|
|
icon: 'success'
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 打开地点标记弹窗
|
|||
|
|
onOpenLocationMarkModal() {
|
|||
|
|
this.setData({ showLocationMarkModal: true });
|
|||
|
|
},
|
|||
|
|
// 关闭地点标记弹窗
|
|||
|
|
onCloseLocationMarkModal() {
|
|||
|
|
this.setData({ showLocationMarkModal: false });
|
|||
|
|
},
|
|||
|
|
// 筛选输入
|
|||
|
|
onLocationMarkSearchInput(e) {
|
|||
|
|
const text = e.detail.value.trim();
|
|||
|
|
const list = this.data.locationMarkList.filter(item => item.name.includes(text));
|
|||
|
|
this.setData({
|
|||
|
|
locationMarkSearchText: text,
|
|||
|
|
filteredLocationMarkList: list
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
// 删除按钮(静态演示)
|
|||
|
|
onDeleteLocationMark(e) {
|
|||
|
|
wx.showToast({ title: '删除演示', icon: 'none' });
|
|||
|
|
},
|
|||
|
|
// 修改按钮(静态演示)
|
|||
|
|
onEditLocationMarkName(e) {
|
|||
|
|
wx.showToast({ title: '修改名称演示', icon: 'none' });
|
|||
|
|
},
|
|||
|
|
// 设置提醒好友(静态演示)
|
|||
|
|
onSetRemindFriends(e) {
|
|||
|
|
wx.showToast({ title: '设置好友演示', icon: 'none' });
|
|||
|
|
},
|
|||
|
|
// 切换提醒类型(静态演示)
|
|||
|
|
onToggleRemindType(e) {
|
|||
|
|
wx.showToast({ title: '切换类型演示', icon: 'none' });
|
|||
|
|
},
|
|||
|
|
// POI提醒名称输入
|
|||
|
|
onPoiRemindNameInput(e) {
|
|||
|
|
const name = e.detail.value;
|
|||
|
|
this.setData({
|
|||
|
|
'lastPoiForRemind.name': name
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 地点标记列表项点击事件
|
|||
|
|
onLocationMarkItemTap(e) {
|
|||
|
|
const item = e.currentTarget.dataset.item;
|
|||
|
|
console.log('点击地点标记:', item);
|
|||
|
|
this.setData({ showLocationMarkModal: false });
|
|||
|
|
const poi = {detail:{
|
|||
|
|
name: item.name,
|
|||
|
|
address: item.address || '',
|
|||
|
|
latitude: item.lat,
|
|||
|
|
longitude: item.lng
|
|||
|
|
}};
|
|||
|
|
this.onPoiTap(poi);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 添加地点标记
|
|||
|
|
onAddLocationPlace() {
|
|||
|
|
console.log('点击添加地点标记');
|
|||
|
|
const self = this;
|
|||
|
|
this.amapFun.getPoiAround({
|
|||
|
|
success: function(data){
|
|||
|
|
var list = data.markers;
|
|||
|
|
// 遍历list,计算距离并添加distance属性
|
|||
|
|
list.forEach(item => {
|
|||
|
|
const lat = Number(item.latitude);
|
|||
|
|
const lng = Number(item.longitude);
|
|||
|
|
const distance = Math.round(
|
|||
|
|
self.calculateDistance(
|
|||
|
|
self.properties.latitude,
|
|||
|
|
self.properties.longitude,
|
|||
|
|
lat,
|
|||
|
|
lng
|
|||
|
|
)
|
|||
|
|
);
|
|||
|
|
// 格式化距离
|
|||
|
|
if (distance < 1000) {
|
|||
|
|
item.distanceStr = distance + '米';
|
|||
|
|
} else {
|
|||
|
|
item.distanceStr = (distance / 1000).toFixed(2) + '公里';
|
|||
|
|
}
|
|||
|
|
//item.distance = distance; // 如还需原始整数距离
|
|||
|
|
});
|
|||
|
|
self.setData({ poiAroundList: list, showLocationMarkModal: false ,showPoiAroundModal: true});
|
|||
|
|
|
|||
|
|
},
|
|||
|
|
fail: function(info){
|
|||
|
|
wx.showModal({title:info.errMsg})
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
onPoiAroundItemTap(e) {
|
|||
|
|
const item = e.currentTarget.dataset.item;
|
|||
|
|
this.setData({ showPoiAroundModal: false });
|
|||
|
|
const poi = {detail:{
|
|||
|
|
name: item.name,
|
|||
|
|
address: item.address || '',
|
|||
|
|
latitude: item.latitude,
|
|||
|
|
longitude: item.longitude
|
|||
|
|
}};
|
|||
|
|
this.onPoiTap(poi);
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onClosePoiAroundModal() {
|
|||
|
|
this.setData({ showPoiAroundModal: false });
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
closeMerchantInfo() {
|
|||
|
|
this.setData({ merchantInfoModalVisible: false });
|
|||
|
|
},
|
|||
|
|
onFavoriteMerchant() {
|
|||
|
|
const merchant = this.data.selectedMerchant;
|
|||
|
|
merchant.isFavorited = !merchant.isFavorited;
|
|||
|
|
this.setData({
|
|||
|
|
selectedMerchant: merchant,
|
|||
|
|
merchantList: this.data.merchantList.map(m => m.id === merchant.id ? merchant : m)
|
|||
|
|
});
|
|||
|
|
// 可加toast提示
|
|||
|
|
},
|
|||
|
|
onNavigateMerchant() {
|
|||
|
|
const merchant = this.data.selectedMerchant;
|
|||
|
|
wx.openLocation({
|
|||
|
|
latitude: merchant.latitude,
|
|||
|
|
longitude: merchant.longitude,
|
|||
|
|
name: merchant.name,
|
|||
|
|
address: merchant.address,
|
|||
|
|
scale: 16
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
formatDistance(d) {
|
|||
|
|
if (d < 1000) return d + '米';
|
|||
|
|
return (d / 1000).toFixed(2) + '公里';
|
|||
|
|
},
|
|||
|
|
});
|