miniprogramme/pages/map/map.js
2025-09-12 16:08:17 +08:00

2060 lines
No EOL
60 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 地图页面 - 高德地图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) + '公里';
},
});