Files
WXProgram/miniprogram/pages/index/modules/mapModule.ts

308 lines
8.9 KiB
TypeScript
Raw Normal View History

2025-10-16 21:32:16 +08:00
// 地图模块 - 处理地图显示、定位、标记点管理
import mapService from '../../../services/mapService';
import userService from '../../../services/userService';
import { showToast } from '../../../utils/helpers';
import { Marker } from '../../../types';
import { DataModule } from './dataModule';
export class MapModule {
private pageContext: any;
private dataModule: DataModule;
constructor(pageContext: any, dataModule: DataModule) {
this.pageContext = pageContext;
this.dataModule = dataModule;
}
/**
*
*/
async initMap(): Promise<void> {
try {
// 检查并请求位置权限
await this.checkAndRequestLocationPermission();
// 加载地图数据
this.loadMapData();
} catch (error) {
console.error('初始化地图失败:', error);
showToast('地图初始化失败,请重试');
}
}
/**
*
*/
async checkAndRequestLocationPermission(): Promise<void> {
try {
// 检查位置权限
const hasPermission = await userService.checkLocationPermission();
if (hasPermission) {
// 已授权,开始定位
await this.startLocation();
} else {
// 未授权,请求权限
const permissionGranted = await userService.requestLocationPermission();
if (permissionGranted) {
await this.startLocation();
} else {
// 授权失败,使用默认位置
this.setDefaultLocation();
showToast('已使用默认位置');
}
}
} catch (error) {
console.error('检查位置权限失败:', error);
this.setDefaultLocation();
}
}
/**
*
*/
async startLocation(): Promise<void> {
try {
console.log('[MAP MODULE] 开始获取用户位置...');
const location = await mapService.getCurrentLocation();
console.log('[MAP MODULE] 获取位置成功,原始坐标:', location);
console.log('[MAP MODULE] 详细位置信息:');
console.log(`- 经度: ${location.longitude}`);
console.log(`- 纬度: ${location.latitude}`);
console.log(`- 精度: ${location.accuracy}`);
console.log(`- 速度: ${location.speed}`);
// 验证获取的坐标是否有效
if (isNaN(location.latitude) || isNaN(location.longitude)) {
console.error('[MAP MODULE] 获取的位置坐标无效:', location);
this.setDefaultLocation();
showToast('获取的位置无效,已使用默认位置');
return;
}
// 强制重置地图视角到用户位置
// 1. 更新用户位置
2025-10-16 21:32:16 +08:00
this.dataModule.updateUserLocation(location.latitude, location.longitude);
// 2. 重置地图缩放级别到15详细级别
this.dataModule.setMapScale(15);
// 3. 添加地图动画效果,让视角平滑回到用户位置
this.animateMapToUserLocation(location.latitude, location.longitude);
2025-10-16 21:32:16 +08:00
console.log('[MAP MODULE] 定位成功,坐标已更新,视角已重置:', location);
showToast('已定位到您的位置');
2025-10-16 21:32:16 +08:00
} catch (error) {
console.error('[MAP MODULE] 定位失败:', error);
this.setDefaultLocation();
showToast('定位失败,已使用默认位置');
}
}
/**
*
*/
setDefaultLocation(): void {
const defaultLatitude = 24.880095;
const defaultLongitude = 102.833722;
// 更新数据模块中的位置信息和缩放级别
this.dataModule.updateUserLocation(defaultLatitude, defaultLongitude);
this.dataModule.setMapScale(13);
// 动画效果回到默认位置
this.animateMapToUserLocation(defaultLatitude, defaultLongitude);
2025-10-16 21:32:16 +08:00
console.log('[MAP MODULE] 默认位置设置完成');
}
/**
*
*/
private animateMapToUserLocation(latitude: number, longitude: number): void {
// 使用微信小程序的MapContext.moveToLocation方法实现地图移动
const mapContext = wx.createMapContext('myMap', this.pageContext);
// 先设置地图中心点
this.pageContext.setData({
latitude: latitude,
longitude: longitude
});
// 使用moveToLocation方法平滑移动地图视角
mapContext.moveToLocation({
latitude: latitude,
longitude: longitude,
success: () => {
console.log('[MAP MODULE] 地图视角移动成功,位置:', { latitude, longitude });
},
fail: (err: any) => {
console.error('[MAP MODULE] 地图视角移动失败:', err);
// 如果moveToLocation失败直接设置中心点
this.pageContext.setData({
latitude: latitude,
longitude: longitude
});
}
});
console.log('[MAP MODULE] 地图视角动画已启动,移动到位置:', { latitude, longitude });
}
2025-10-16 21:32:16 +08:00
/**
*
*/
loadMapData(): void {
// 这里会调用具体的服务来获取数据
// 目前使用模拟数据
const markers = this.generateInitialMarkers();
// 更新数据模块中的标记点
this.dataModule.updateMarkers(markers);
console.log('地图数据加载完成');
}
/**
*
*/
public generateInitialMarkers(): Marker[] {
console.log('生成初始标记点');
2025-10-16 21:32:16 +08:00
const markers: Marker[] = [];
2025-10-16 21:32:16 +08:00
// 获取用户位置
const userLocation = this.pageContext.data.userLocation;
if (userLocation && userLocation.longitude && userLocation.latitude) {
// 添加用户位置标记点
markers.push({
id: -1,
2025-10-16 21:32:16 +08:00
title: '用户位置',
longitude: userLocation.longitude,
latitude: userLocation.latitude,
2025-10-16 21:32:16 +08:00
iconPath: '/images/trucks.png',
width: 40,
height: 40,
zIndex: 99
});
console.log('已添加用户位置标记点');
}
return markers;
2025-10-16 21:32:16 +08:00
}
/**
*
*/
updateUserMarkerIcon(): void {
const { authStatus, userInfo, markers } = this.pageContext.data;
if (!authStatus.hasWxCode || !userInfo) {
console.warn('未登录或用户信息为空,无法更新头像');
return;
}
// 使用默认头像
const avatarUrl = '/images/trucks.png';
const updatedMarkers = markers.map((marker: Marker) => {
if (marker.id === -1) {
return {
...marker,
iconPath: avatarUrl
};
}
return marker;
});
// 更新数据模块中的标记点
this.dataModule.updateMarkers(updatedMarkers);
console.log('用户头像已更新');
}
/**
*
*/
updateEmployeeMarkers(employeeMarkers: Marker[]): void {
console.log('开始更新员工标记点,数量:', employeeMarkers.length);
const { markers } = this.pageContext.data;
// 过滤掉现有的员工标记点
const filteredMarkers = markers.filter((marker: any) =>
marker.type !== 'employee'
);
// 合并标记点
const updatedMarkers = [...filteredMarkers, ...employeeMarkers];
// 更新数据模块中的标记点
this.dataModule.updateMarkers(updatedMarkers);
console.log('员工标记点更新完成,总标记点数量:', updatedMarkers.length);
}
/**
*
*/
updateSingleEmployeeMarker(employeeMarker: Marker): void {
console.log('更新单个员工标记点:', employeeMarker.id);
const { markers } = this.pageContext.data;
// 查找现有的员工标记点
const markerIndex = markers.findIndex((marker: any) =>
marker.type === 'employee' && marker.id === employeeMarker.id
);
let updatedMarkers;
if (markerIndex !== -1) {
// 更新现有的标记点
updatedMarkers = [...markers];
updatedMarkers[markerIndex] = employeeMarker;
} else {
// 添加新的标记点
updatedMarkers = [...markers, employeeMarker];
}
// 更新数据模块中的标记点
this.dataModule.updateMarkers(updatedMarkers);
console.log('单个员工标记点更新完成');
}
2025-10-16 21:32:16 +08:00
/**
*
*/
onMapTap(e: any): void {
console.log('地图被点击:', e);
// 可以在这里添加地图点击的处理逻辑
}
/**
*
*/
onMarkerTap(e: any): void {
const markerId = e.markerId;
console.log('标记点被点击:', markerId);
// 根据标记点ID处理不同的点击逻辑
this.handleMarkerClick(markerId);
}
/**
*
*/
private handleMarkerClick(markerId: number): void {
// 这里可以根据标记点ID进行不同的处理
// 例如:显示订单详情、货运人员信息等
if (markerId === -1) {
// 用户位置标记
this.pageContext.showUserPanel();
}
// 可以添加其他标记点的处理逻辑
}
}