278 lines
8.4 KiB
TypeScript
278 lines
8.4 KiB
TypeScript
// 位置模块 - 处理位置追踪、位置更新和地图标记点更新
|
|
import { DataModule } from './dataModule';
|
|
import { showToast } from '../../../utils/helpers';
|
|
import locationTrackingService from '../../../services/locationTrackingService';
|
|
import { OnlineUserInfo } from '../../../services/locationTrackingService';
|
|
|
|
// 位置模块接口定义
|
|
export interface LocationModule {
|
|
initialize(): Promise<void>;
|
|
cleanup(): void;
|
|
startRealTimeTracking(): Promise<void>;
|
|
stopRealTimeTracking(): Promise<void>;
|
|
updateEmployeeLocation(employeeId: number, location: { longitude: number, latitude: number }): Promise<void>;
|
|
}
|
|
|
|
export class LocationModule {
|
|
private pageContext: any;
|
|
private dataModule: DataModule;
|
|
private isTracking: boolean;
|
|
|
|
constructor(pageContext: any, dataModule: DataModule) {
|
|
this.pageContext = pageContext;
|
|
this.dataModule = dataModule;
|
|
this.isTracking = false;
|
|
|
|
// 绑定回调方法
|
|
this.handleLocationUpdates = this.handleLocationUpdates.bind(this);
|
|
}
|
|
|
|
/**
|
|
* 初始化位置模块
|
|
*/
|
|
async initialize(): Promise<void> {
|
|
console.log('位置模块初始化');
|
|
|
|
// 订阅位置更新
|
|
this.subscribeToLocationUpdates();
|
|
|
|
console.log('位置模块初始化完成');
|
|
}
|
|
|
|
/**
|
|
* 清理位置模块
|
|
*/
|
|
cleanup(): void {
|
|
console.log('清理位置模块');
|
|
|
|
// 取消位置更新订阅
|
|
this.unsubscribeFromLocationUpdates();
|
|
|
|
// 停止实时跟踪
|
|
if (this.isTracking) {
|
|
this.stopRealTimeTracking().catch(error => {
|
|
console.error('停止实时跟踪失败:', error);
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 开始实时跟踪位置
|
|
*/
|
|
async startRealTimeTracking(): Promise<void> {
|
|
try {
|
|
// 获取当前用户信息
|
|
const userInfo = this.dataModule.getData().userInfo;
|
|
if (!userInfo || !userInfo.id) {
|
|
throw new Error('用户信息获取失败');
|
|
}
|
|
|
|
// 启动位置跟踪订阅
|
|
await locationTrackingService.startTrackingAfterSignIn();
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 更新员工位置
|
|
*/
|
|
async updateEmployeeLocation(employeeId: number, location: { longitude: number, latitude: number }): Promise<void> {
|
|
try {
|
|
console.log(`员工 ${employeeId} 位置更新:`, location);
|
|
|
|
// 通过locationTrackingService更新位置
|
|
await locationTrackingService.updateUserLocation(location);
|
|
|
|
console.log(`员工 ${employeeId} 位置更新完成`);
|
|
} catch (error) {
|
|
console.error('更新员工位置失败:', error);
|
|
showToast('更新位置失败');
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 订阅位置更新
|
|
*/
|
|
private subscribeToLocationUpdates(): void {
|
|
console.log('订阅位置更新');
|
|
locationTrackingService.subscribeToLocationUpdates(this.handleLocationUpdates);
|
|
}
|
|
|
|
/**
|
|
* 取消订阅位置更新
|
|
*/
|
|
private unsubscribeFromLocationUpdates(): void {
|
|
console.log('取消订阅位置更新');
|
|
locationTrackingService.unsubscribeFromLocationUpdates(this.handleLocationUpdates);
|
|
}
|
|
|
|
/**
|
|
* 处理位置更新回调
|
|
*/
|
|
private handleLocationUpdates(locationData: any): void {
|
|
console.log('收到位置更新回调:', locationData);
|
|
|
|
if (locationData.type === 'onlineUserList' && locationData.users) {
|
|
// 处理在线用户列表更新
|
|
console.log('处理在线用户列表,用户数量:', locationData.users.length);
|
|
this.updateEmployeeMarkers(locationData.users);
|
|
} else if (Array.isArray(locationData)) {
|
|
// 处理位置更新数组(旧格式)
|
|
console.log('处理位置更新数组,用户数量:', locationData.length);
|
|
this.updateEmployeeMarkers(locationData);
|
|
} else if (locationData.userId && locationData.latitude && locationData.longitude) {
|
|
// 处理单个用户位置更新
|
|
console.log('处理单个用户位置更新:', locationData.userId);
|
|
this.updateSingleEmployeeMarker(locationData);
|
|
} else {
|
|
console.warn('未知的位置数据格式:', locationData);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 更新员工标记点
|
|
*/
|
|
private updateEmployeeMarkers(onlineUsers: any[]): void {
|
|
console.log('开始更新员工标记点,在线用户数量:', onlineUsers.length);
|
|
|
|
// 获取地图模块来更新标记点
|
|
const mapModule = this.dataModule.getMapModule();
|
|
if (!mapModule) {
|
|
console.error('地图模块未找到,无法更新员工标记点');
|
|
return;
|
|
}
|
|
|
|
// 为每个在线用户创建标记点
|
|
const employeeMarkers = onlineUsers.map(user => {
|
|
// 获取用户角色信息
|
|
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();
|
|
|
|
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;
|
|
});
|
|
|
|
// 调用地图模块更新员工标记点
|
|
mapModule.updateEmployeeMarkers(employeeMarkers);
|
|
|
|
console.log(`成功更新了 ${employeeMarkers.length} 个员工标记点`);
|
|
}
|
|
|
|
/**
|
|
* 更新单个员工标记点
|
|
*/
|
|
private updateSingleEmployeeMarker(locationUpdate: any): void {
|
|
console.log('更新单个员工标记点:', locationUpdate.userId);
|
|
|
|
// 获取地图模块
|
|
const mapModule = this.dataModule.getMapModule();
|
|
if (!mapModule) {
|
|
console.error('地图模块未找到,无法更新员工标记点');
|
|
return;
|
|
}
|
|
|
|
// 获取用户角色信息
|
|
const userRole = this.getUserRole(locationUpdate.userId);
|
|
|
|
// 创建单个员工标记点
|
|
const employeeMarker = {
|
|
id: 10000 + locationUpdate.userId,
|
|
type: 'employee',
|
|
title: `员工${locationUpdate.userId}`,
|
|
longitude: locationUpdate.longitude,
|
|
latitude: locationUpdate.latitude,
|
|
iconPath: this.getEmployeeIcon(locationUpdate.userId, userRole),
|
|
width: 32,
|
|
height: 32,
|
|
zIndex: 30,
|
|
data: {
|
|
userId: locationUpdate.userId,
|
|
role: userRole,
|
|
lastUpdateTime: locationUpdate.timestamp || Date.now()
|
|
}
|
|
};
|
|
|
|
// 调用地图模块更新单个标记点
|
|
mapModule.updateSingleEmployeeMarker(employeeMarker);
|
|
|
|
console.log('单个员工标记点更新完成');
|
|
}
|
|
|
|
/**
|
|
* 获取用户角色
|
|
*/
|
|
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 {
|
|
return '/images/trucks.png'; // 货运人员图标
|
|
}
|
|
}
|
|
} |