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

308 lines
8.9 KiB
TypeScript
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.

// 地图模块 - 处理地图显示、定位、标记点管理
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. 更新用户位置
this.dataModule.updateUserLocation(location.latitude, location.longitude);
// 2. 重置地图缩放级别到15详细级别
this.dataModule.setMapScale(15);
// 3. 添加地图动画效果,让视角平滑回到用户位置
this.animateMapToUserLocation(location.latitude, location.longitude);
console.log('[MAP MODULE] 定位成功,坐标已更新,视角已重置:', location);
showToast('已定位到您的位置');
} 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);
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 });
}
/**
* 加载地图数据(仓库和货运人员)
*/
loadMapData(): void {
// 这里会调用具体的服务来获取数据
// 目前使用模拟数据
const markers = this.generateInitialMarkers();
// 更新数据模块中的标记点
this.dataModule.updateMarkers(markers);
console.log('地图数据加载完成');
}
/**
* 生成初始标记点
*/
public generateInitialMarkers(): Marker[] {
console.log('生成初始标记点');
const markers: Marker[] = [];
// 获取用户位置
const userLocation = this.pageContext.data.userLocation;
if (userLocation && userLocation.longitude && userLocation.latitude) {
// 添加用户位置标记点
markers.push({
id: -1,
title: '用户位置',
longitude: userLocation.longitude,
latitude: userLocation.latitude,
iconPath: '/images/trucks.png',
width: 40,
height: 40,
zIndex: 99
});
console.log('已添加用户位置标记点');
}
return markers;
}
/**
* 更新用户标记图标为用户头像
*/
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('单个员工标记点更新完成');
}
/**
* 处理地图点击事件
*/
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();
}
// 可以添加其他标记点的处理逻辑
}
}