// 地图模块 - 处理地图显示、定位、标记点管理 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 { try { // 检查并请求位置权限 await this.checkAndRequestLocationPermission(); // 加载地图数据 this.loadMapData(); } catch (error) { console.error('初始化地图失败:', error); showToast('地图初始化失败,请重试'); } } /** * 检查并请求位置权限 */ async checkAndRequestLocationPermission(): Promise { 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 { 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(); } // 可以添加其他标记点的处理逻辑 } }