Files
WXProgram/miniprogram/pages/index/modules/locationModule.ts
2025-10-19 23:38:54 +08:00

287 lines
9.5 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 { showToast } from '../../../utils/helpers';
import { DataModule } from './dataModule';
import locationTrackingService from '../../../services/locationTrackingService';
// 位置模块接口定义
export interface LocationModule {
initialize(): Promise<void>;
cleanup(): void;
startRealTimeTracking(): Promise<void>;
stopRealTimeTracking(): Promise<void>;
}
export class LocationModule {
private dataModule: DataModule;
private isTracking: boolean;
constructor(_pageContext: any, dataModule: DataModule) {
this.dataModule = dataModule;
this.isTracking = false;
}
/**
* 初始化位置模块
*/
async initialize(): Promise<void> {
console.log('位置模块初始化');
// 注册位置更新回调,当位置追踪服务有更新时自动刷新地图标记
this.setupLocationUpdateCallback();
console.log('✅ 位置模块初始化完成');
}
/**
* 设置位置更新回调
*/
private setupLocationUpdateCallback(): void {
console.log('📝 [LocationModule] 设置位置更新回调');
// 注册位置更新回调
locationTrackingService.subscribeToLocationUpdates((onlineUsers) => {
console.log('🔔 [LocationModule] 收到位置更新通知');
console.log('👥 [LocationModule] 在线用户数量:', onlineUsers.length);
// 调用updateEmployeeMarkers方法更新地图标记
this.updateEmployeeMarkers(onlineUsers);
});
console.log('✅ [LocationModule] 位置更新回调设置完成');
}
/**
* 清理位置模块
*/
cleanup(): void {
console.log('清理位置模块');
// 停止实时跟踪
if (this.isTracking) {
this.stopRealTimeTracking().catch(error => {
console.error('停止实时跟踪失败:', error);
});
}
console.log('✅ 位置模块清理完成');
}
/**
* 开始实时跟踪位置
*/
async startRealTimeTracking(): Promise<void> {
try {
// 获取当前用户信息
const userInfo = this.dataModule.getData().userInfo;
if (!userInfo || !userInfo.id) {
throw new Error('用户信息获取失败');
}
// 启动位置跟踪订阅WebSocket连接
await locationTrackingService.startTracking();
this.isTracking = true;
showToast('已开始实时跟踪');
console.log('开始实时跟踪位置');
} catch (error) {
console.error('开始实时跟踪失败:', error);
showToast('开始实时跟踪失败');
throw error;
}
}
/**
* 停止实时跟踪位置
*/
async stopRealTimeTracking(): Promise<void> {
try {
// 获取当前用户信息
const userInfo = this.dataModule.getData().userInfo;
if (!userInfo || !userInfo.id) {
throw new Error('用户信息获取失败');
}
// 停止位置跟踪
await locationTrackingService.stopTracking();
this.isTracking = false;
showToast('已停止实时跟踪');
console.log('停止实时跟踪位置');
} catch (error) {
console.error('停止实时跟踪失败:', error);
showToast('停止实时跟踪失败');
throw error;
}
}
/**
* 更新员工标记点
*/
public updateEmployeeMarkers(onlineUsers: any[]): void {
console.log('📍 [LocationModule] 开始更新员工标记点');
console.log('👥 [LocationModule] 传入用户数量:', onlineUsers.length);
// 获取地图模块来更新标记点
const mapModule = this.dataModule.getMapModule();
if (!mapModule) {
console.error('地图模块未找到,无法更新员工标记点');
return;
}
// 获取当前地图上的所有标记点
const { markers } = this.dataModule.getData();
const currentEmployeeMarkers = markers.filter((marker: any) => marker.type === 'employee');
console.log('🗺️ [LocationModule] 当前地图上员工标记点数量:', currentEmployeeMarkers.length);
// 为每个在线用户创建标记点
const newEmployeeMarkers = onlineUsers.map((user, index) => {
console.log(`🔍 [LocationModule] 处理第 ${index + 1} 个用户:`, user.userId || '未知ID');
// 获取用户角色信息
const userRole = user.role || this.getUserRole(user.userId);
// 解析位置信息(支持多种格式)
const longitude = user.longitude || (user.lastLocation && user.lastLocation.longitude) || 0;
const latitude = user.latitude || (user.lastLocation && user.lastLocation.latitude) || 0;
const lastUpdateTime = user.lastUpdateTime || Date.now();
console.log(`📡 [LocationModule] 用户 ${index + 1} 位置: ${latitude}, ${longitude}`);
console.log(`👤 [LocationModule] 用户 ${index + 1} 信息: ${user.userName || '未知用户'} (${userRole})`);
const employeeMarker = {
id: 10000 + user.userId, // 避免ID冲突
type: 'employee',
title: user.userName || `员工${user.userId}`,
longitude: longitude,
latitude: latitude,
iconPath: this.getEmployeeIcon(user.userId, userRole),
width: 32,
height: 32,
zIndex: 30,
data: {
userId: user.userId,
role: userRole,
lastUpdateTime: lastUpdateTime
}
};
return employeeMarker;
});
console.log('📍 [LocationModule] 新生成标记点数量:', newEmployeeMarkers.length);
// 对比新旧标记点,精确更新
this.updateMarkersPrecisely(mapModule, currentEmployeeMarkers, newEmployeeMarkers);
console.log('✅ [LocationModule] 员工标记点更新完成');
}
/**
* 精确更新标记点 - 通过对比新旧标记点来添加、更新和删除
*/
private updateMarkersPrecisely(mapModule: any, currentMarkers: any[], newMarkers: any[]): void {
console.log('🎯 [LocationModule] 开始精确更新标记点');
// 创建用户ID到标记点的映射
const currentMarkerMap = new Map();
currentMarkers.forEach(marker => {
if (marker.data && marker.data.userId) {
currentMarkerMap.set(marker.data.userId, marker);
}
});
const newMarkerMap = new Map();
newMarkers.forEach(marker => {
if (marker.data && marker.data.userId) {
newMarkerMap.set(marker.data.userId, marker);
}
});
console.log('📊 [LocationModule] 当前标记点用户ID:', Array.from(currentMarkerMap.keys()));
console.log('📊 [LocationModule] 新标记点用户ID:', Array.from(newMarkerMap.keys()));
// 找出需要删除的标记点(在当前但不在新的)
const markersToRemove = currentMarkers.filter(marker => {
if (marker.data && marker.data.userId) {
return !newMarkerMap.has(marker.data.userId);
}
return false;
});
// 找出需要添加的标记点(在新的但不在当前的)
const markersToAdd = newMarkers.filter(marker => {
if (marker.data && marker.data.userId) {
return !currentMarkerMap.has(marker.data.userId);
}
return false;
});
// 找出需要更新的标记点(位置或信息有变化)
const markersToUpdate = newMarkers.filter(marker => {
if (marker.data && marker.data.userId) {
const currentMarker = currentMarkerMap.get(marker.data.userId);
if (currentMarker) {
// 检查位置是否变化
return currentMarker.longitude !== marker.longitude ||
currentMarker.latitude !== marker.latitude ||
currentMarker.title !== marker.title ||
currentMarker.iconPath !== marker.iconPath;
}
}
return false;
});
console.log(`🗑️ [LocationModule] 需要删除的标记点数量: ${markersToRemove.length}`);
console.log(` [LocationModule] 需要添加的标记点数量: ${markersToAdd.length}`);
console.log(`🔄 [LocationModule] 需要更新的标记点数量: ${markersToUpdate.length}`);
// 执行删除操作
markersToRemove.forEach(marker => {
console.log(`🗑️ [LocationModule] 删除标记点: 用户 ${marker.data.userId}`);
mapModule.removeEmployeeMarker(marker.id);
});
// 执行添加操作
markersToAdd.forEach(marker => {
console.log(` [LocationModule] 添加标记点: 用户 ${marker.data.userId}`);
mapModule.addEmployeeMarker(marker);
});
// 执行更新操作
markersToUpdate.forEach(marker => {
console.log(`🔄 [LocationModule] 更新标记点: 用户 ${marker.data.userId}`);
mapModule.updateSingleEmployeeMarker(marker);
});
console.log('🎯 [LocationModule] 精确更新标记点完成');
}
/**
* 获取用户角色
*/
private getUserRole(userId: number): string {
// 从数据模块获取用户信息
const userInfo = this.dataModule.getData().userInfo;
if (userInfo && userInfo.id === userId) {
return userInfo.role || 'employee';
}
// 如果是其他用户,默认为货运人员
return 'employee';
}
/**
* 获取员工图标
*/
private getEmployeeIcon(_userId: number, userRole: string): string {
// 根据用户角色返回不同的图标
if (userRole === 'ADMIN') {
return '/images/crown.png'; // 管理员图标
} else if (userRole === 'DRIVER') {
return '/images/truck.png'; // 司机图标
} else {
return '👤'; // 普通员工图标(表情符号)
}
}
}