miniprogramme/pages/map/map.js

2060 lines
60 KiB
JavaScript
Raw Normal View History

2025-09-12 16:08:17 +08:00
// 地图页面 - 高德地图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度纬度约等于111km1度经度约等于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) + '公里';
},
});