564 lines
15 KiB
TypeScript
564 lines
15 KiB
TypeScript
|
|
// 位置追踪服务 - 处理用户签到后的位置追踪和状态管理
|
|||
|
|
import { UserInfo, LocationData } from '../types';
|
|||
|
|
import apiService from './apiService';
|
|||
|
|
import { isMockMode } from './apiService';
|
|||
|
|
import userService from './userService';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 在线用户信息接口
|
|||
|
|
*/
|
|||
|
|
export interface OnlineUserInfo {
|
|||
|
|
userId: number;
|
|||
|
|
name: string;
|
|||
|
|
avatarUrl: string;
|
|||
|
|
lastLocation: LocationData;
|
|||
|
|
lastUpdateTime: number;
|
|||
|
|
status: 'online' | 'offline' | 'timeout';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 位置追踪服务类
|
|||
|
|
* 提供用户签到后的位置追踪、状态管理和位置分发功能
|
|||
|
|
*/
|
|||
|
|
class LocationTrackingService {
|
|||
|
|
// 在线用户列表
|
|||
|
|
private onlineUsers: Map<number, OnlineUserInfo>;
|
|||
|
|
|
|||
|
|
// 位置更新定时器
|
|||
|
|
private locationUpdateTimer: number | null;
|
|||
|
|
|
|||
|
|
// 状态检查定时器
|
|||
|
|
private statusCheckTimer: number | null;
|
|||
|
|
|
|||
|
|
// 位置更新回调集合
|
|||
|
|
private locationUpdateCallbacks: Set<(locations: OnlineUserInfo[]) => void>;
|
|||
|
|
|
|||
|
|
// 用户状态变化回调集合
|
|||
|
|
private userStatusCallbacks: Set<(userId: number, status: 'online' | 'offline' | 'timeout') => void>;
|
|||
|
|
|
|||
|
|
// 当前用户是否已签到
|
|||
|
|
private isSignedIn: boolean;
|
|||
|
|
|
|||
|
|
// 用户信息缓存
|
|||
|
|
private userInfo: UserInfo | null;
|
|||
|
|
|
|||
|
|
// 取消订阅回调函数
|
|||
|
|
private unsubscribeCallback: (() => void) | null;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 构造函数
|
|||
|
|
*/
|
|||
|
|
constructor() {
|
|||
|
|
this.onlineUsers = new Map();
|
|||
|
|
this.locationUpdateTimer = null;
|
|||
|
|
this.statusCheckTimer = null;
|
|||
|
|
this.locationUpdateCallbacks = new Set();
|
|||
|
|
this.userStatusCallbacks = new Set();
|
|||
|
|
this.isSignedIn = false;
|
|||
|
|
this.userInfo = null;
|
|||
|
|
this.unsubscribeCallback = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 用户签到后启动位置追踪
|
|||
|
|
*/
|
|||
|
|
public async startTrackingAfterSignIn(): Promise<void> {
|
|||
|
|
const userInfo = userService.getGlobalUserInfo();
|
|||
|
|
if (!userInfo || !userInfo.id) {
|
|||
|
|
throw new Error('用户未登录,无法启动位置追踪');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.isSignedIn = true;
|
|||
|
|
|
|||
|
|
// 将当前用户添加到在线列表
|
|||
|
|
await this.addUserToOnlineList(userInfo);
|
|||
|
|
|
|||
|
|
// 启动位置更新定时器(每30秒更新一次)
|
|||
|
|
this.startLocationUpdateTimer();
|
|||
|
|
|
|||
|
|
// 启动状态检查定时器(每60秒检查一次)
|
|||
|
|
this.startStatusCheckTimer();
|
|||
|
|
|
|||
|
|
// 订阅其他用户的位置更新
|
|||
|
|
await this.subscribeToOtherUsersLocations();
|
|||
|
|
|
|||
|
|
console.log('位置追踪服务已启动');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 用户签退后停止位置追踪
|
|||
|
|
*/
|
|||
|
|
public async stopTracking(): Promise<void> {
|
|||
|
|
const userInfo = userService.getGlobalUserInfo();
|
|||
|
|
if (!userInfo || !userInfo.id) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.isSignedIn = false;
|
|||
|
|
|
|||
|
|
// 从在线列表中移除用户
|
|||
|
|
this.removeUserFromOnlineList(userInfo.id);
|
|||
|
|
|
|||
|
|
// 停止定时器
|
|||
|
|
this.stopTimers();
|
|||
|
|
|
|||
|
|
// 取消订阅
|
|||
|
|
await this.unsubscribeFromLocations();
|
|||
|
|
|
|||
|
|
console.log('位置追踪服务已停止');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 手动更新用户位置
|
|||
|
|
*/
|
|||
|
|
public async updateUserLocation(location: { longitude: number; latitude: number }): Promise<void> {
|
|||
|
|
const userInfo = userService.getGlobalUserInfo();
|
|||
|
|
if (!userInfo || !userInfo.id || !this.isSignedIn) {
|
|||
|
|
console.warn('[位置追踪服务] 用户未登录或未签到,无法更新位置');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('[位置追踪服务] 前端发送给服务器的位置信息:');
|
|||
|
|
console.log(`- 用户ID: ${userInfo.id}`);
|
|||
|
|
console.log(`- 经度: ${location.longitude}`);
|
|||
|
|
console.log(`- 纬度: ${location.latitude}`);
|
|||
|
|
console.log(`- 时间戳: ${Date.now()}`);
|
|||
|
|
|
|||
|
|
const locationData: LocationData = {
|
|||
|
|
userId: userInfo.id,
|
|||
|
|
longitude: location.longitude,
|
|||
|
|
latitude: location.latitude,
|
|||
|
|
timestamp: Date.now()
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (isMockMode) {
|
|||
|
|
// 模拟模式:更新本地在线用户列表
|
|||
|
|
console.log('[位置追踪服务] 模拟模式:更新本地位置');
|
|||
|
|
this.updateLocalUserLocation(userInfo.id, locationData);
|
|||
|
|
} else {
|
|||
|
|
// 真实模式:调用API更新位置
|
|||
|
|
console.log('[位置追踪服务] 真实模式:调用API更新位置');
|
|||
|
|
await apiService.updateDeliveryPersonLocation(userInfo.id, location);
|
|||
|
|
|
|||
|
|
// 同时更新本地缓存
|
|||
|
|
this.updateLocalUserLocation(userInfo.id, locationData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 通知所有回调
|
|||
|
|
this.notifyLocationUpdateCallbacks();
|
|||
|
|
console.log('[位置追踪服务] 位置更新完成,已通知回调');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取所有在线用户信息
|
|||
|
|
*/
|
|||
|
|
public getOnlineUsers(): OnlineUserInfo[] {
|
|||
|
|
return Array.from(this.onlineUsers.values()).filter(user =>
|
|||
|
|
user.status === 'online'
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 订阅位置更新
|
|||
|
|
*/
|
|||
|
|
public subscribeToLocationUpdates(callback: (locations: OnlineUserInfo[]) => void): void {
|
|||
|
|
this.locationUpdateCallbacks.add(callback);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 取消订阅位置更新
|
|||
|
|
*/
|
|||
|
|
public unsubscribeFromLocationUpdates(callback: (locations: OnlineUserInfo[]) => void): void {
|
|||
|
|
this.locationUpdateCallbacks.delete(callback);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 订阅用户状态变化
|
|||
|
|
*/
|
|||
|
|
public subscribeToUserStatusChanges(callback: (userId: number, status: 'online' | 'offline' | 'timeout') => void): void {
|
|||
|
|
this.userStatusCallbacks.add(callback);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 取消订阅用户状态变化
|
|||
|
|
*/
|
|||
|
|
public unsubscribeFromUserStatusChanges(callback: (userId: number, status: 'online' | 'offline' | 'timeout') => void): void {
|
|||
|
|
this.userStatusCallbacks.delete(callback);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查用户是否在线
|
|||
|
|
*/
|
|||
|
|
public isUserOnline(userId: number): boolean {
|
|||
|
|
const userInfo = this.onlineUsers.get(userId);
|
|||
|
|
return userInfo ? userInfo.status === 'online' : false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ===== 私有方法 =====
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 添加用户到在线列表
|
|||
|
|
*/
|
|||
|
|
private async addUserToOnlineList(userInfo: UserInfo): Promise<void> {
|
|||
|
|
const currentLocation = await this.getCurrentLocation();
|
|||
|
|
|
|||
|
|
const onlineUser: OnlineUserInfo = {
|
|||
|
|
userId: userInfo.id,
|
|||
|
|
name: userInfo.name || '未知用户',
|
|||
|
|
avatarUrl: '/images/user-avatar.png',
|
|||
|
|
lastLocation: currentLocation,
|
|||
|
|
lastUpdateTime: Date.now(),
|
|||
|
|
status: 'online'
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
this.onlineUsers.set(userInfo.id, onlineUser);
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
console.log(`用户 ${userInfo.id} 已添加到在线列表`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 从在线列表中移除用户
|
|||
|
|
*/
|
|||
|
|
private removeUserFromOnlineList(userId: number): void {
|
|||
|
|
if (this.onlineUsers.has(userId)) {
|
|||
|
|
this.onlineUsers.delete(userId);
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
// 通知状态变化回调
|
|||
|
|
this.notifyUserStatusChange(userId, 'offline');
|
|||
|
|
|
|||
|
|
console.log(`用户 ${userId} 已从在线列表移除`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 更新本地用户位置
|
|||
|
|
*/
|
|||
|
|
private updateLocalUserLocation(userId: number, location: LocationData): void {
|
|||
|
|
const userInfo = this.onlineUsers.get(userId);
|
|||
|
|
if (userInfo) {
|
|||
|
|
userInfo.lastLocation = location;
|
|||
|
|
userInfo.lastUpdateTime = Date.now();
|
|||
|
|
userInfo.status = 'online';
|
|||
|
|
|
|||
|
|
this.onlineUsers.set(userId, userInfo);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 启动位置更新定时器
|
|||
|
|
*/
|
|||
|
|
private startLocationUpdateTimer(): void {
|
|||
|
|
this.stopLocationUpdateTimer();
|
|||
|
|
|
|||
|
|
this.locationUpdateTimer = setInterval(async () => {
|
|||
|
|
if (this.isSignedIn) {
|
|||
|
|
try {
|
|||
|
|
const location = await this.getCurrentLocation();
|
|||
|
|
await this.updateUserLocation(location);
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('自动位置更新失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}, 30000); // 每30秒更新一次
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 启动状态检查定时器
|
|||
|
|
*/
|
|||
|
|
private startStatusCheckTimer(): void {
|
|||
|
|
this.stopStatusCheckTimer();
|
|||
|
|
|
|||
|
|
this.statusCheckTimer = setInterval(() => {
|
|||
|
|
this.checkUserStatuses();
|
|||
|
|
}, 60000); // 每60秒检查一次
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查用户状态
|
|||
|
|
*/
|
|||
|
|
private checkUserStatuses(): void {
|
|||
|
|
const now = Date.now();
|
|||
|
|
const timeoutThreshold = 120000; // 2分钟无更新视为超时
|
|||
|
|
|
|||
|
|
this.onlineUsers.forEach((userInfo, userId) => {
|
|||
|
|
if (now - userInfo.lastUpdateTime > timeoutThreshold) {
|
|||
|
|
// 用户超时
|
|||
|
|
userInfo.status = 'timeout';
|
|||
|
|
this.onlineUsers.set(userId, userInfo);
|
|||
|
|
this.notifyUserStatusChange(userId, 'timeout');
|
|||
|
|
|
|||
|
|
console.log(`用户 ${userId} 因超时被标记为离线`);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取当前位置
|
|||
|
|
*/
|
|||
|
|
private async getCurrentLocation(): Promise<LocationData> {
|
|||
|
|
const userInfo = userService.getGlobalUserInfo();
|
|||
|
|
if (!userInfo || !userInfo.id) {
|
|||
|
|
throw new Error('用户未登录');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 这里应该调用地图服务获取当前位置
|
|||
|
|
// 暂时返回一个默认位置
|
|||
|
|
return {
|
|||
|
|
userId: userInfo.id,
|
|||
|
|
longitude: 102.833722,
|
|||
|
|
latitude: 24.880095,
|
|||
|
|
timestamp: Date.now()
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 订阅其他用户的位置更新
|
|||
|
|
*/
|
|||
|
|
private async subscribeToOtherUsersLocations(): Promise<void> {
|
|||
|
|
if (isMockMode) {
|
|||
|
|
// 模拟模式:定时生成其他用户的位置更新
|
|||
|
|
this.startMockOtherUsersUpdates();
|
|||
|
|
} else {
|
|||
|
|
// 真实模式:通过WebSocket订阅
|
|||
|
|
await this.setupRealTimeSubscription();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 取消订阅位置更新
|
|||
|
|
*/
|
|||
|
|
private async unsubscribeFromLocations(): Promise<void> {
|
|||
|
|
if (!isMockMode) {
|
|||
|
|
// 真实模式:取消WebSocket订阅
|
|||
|
|
await this.teardownRealTimeSubscription();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 启动模拟的其他用户位置更新
|
|||
|
|
*/
|
|||
|
|
private startMockOtherUsersUpdates(): void {
|
|||
|
|
// 模拟其他用户的位置更新(每45秒一次)
|
|||
|
|
setInterval(() => {
|
|||
|
|
if (this.isSignedIn) {
|
|||
|
|
this.generateMockOtherUsersLocations();
|
|||
|
|
this.notifyLocationUpdateCallbacks();
|
|||
|
|
}
|
|||
|
|
}, 45000);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 生成模拟的其他用户位置
|
|||
|
|
*/
|
|||
|
|
private generateMockOtherUsersLocations(): void {
|
|||
|
|
const currentUserInfo = userService.getGlobalUserInfo();
|
|||
|
|
if (!currentUserInfo) return;
|
|||
|
|
|
|||
|
|
// 模拟2个其他在线用户
|
|||
|
|
const mockUserIds = [101, 102]; // 模拟用户ID
|
|||
|
|
|
|||
|
|
mockUserIds.forEach(userId => {
|
|||
|
|
if (userId !== currentUserInfo.id) {
|
|||
|
|
const existingUser = this.onlineUsers.get(userId);
|
|||
|
|
|
|||
|
|
if (existingUser) {
|
|||
|
|
// 更新现有用户位置
|
|||
|
|
existingUser.lastLocation.longitude += (Math.random() - 0.5) * 0.001;
|
|||
|
|
existingUser.lastLocation.latitude += (Math.random() - 0.5) * 0.001;
|
|||
|
|
existingUser.lastUpdateTime = Date.now();
|
|||
|
|
existingUser.status = 'online';
|
|||
|
|
|
|||
|
|
this.onlineUsers.set(userId, existingUser);
|
|||
|
|
} else {
|
|||
|
|
// 添加新用户
|
|||
|
|
const newUser: OnlineUserInfo = {
|
|||
|
|
userId,
|
|||
|
|
name: `用户${userId}`,
|
|||
|
|
avatarUrl: '/images/user-avatar.png',
|
|||
|
|
lastLocation: {
|
|||
|
|
userId,
|
|||
|
|
longitude: 102.833722 + (Math.random() - 0.5) * 0.01,
|
|||
|
|
latitude: 24.880095 + (Math.random() - 0.5) * 0.01,
|
|||
|
|
timestamp: Date.now()
|
|||
|
|
},
|
|||
|
|
lastUpdateTime: Date.now(),
|
|||
|
|
status: 'online'
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
this.onlineUsers.set(userId, newUser);
|
|||
|
|
this.notifyUserStatusChange(userId, 'online');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设置实时位置订阅
|
|||
|
|
*/
|
|||
|
|
private setupRealTimeSubscription(): void {
|
|||
|
|
// 获取用户信息
|
|||
|
|
const userInfo = userService.getGlobalUserInfo();
|
|||
|
|
if (!userInfo || !userInfo.id) {
|
|||
|
|
console.warn('用户未登录,无法设置实时位置订阅');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 缓存用户信息
|
|||
|
|
this.userInfo = userInfo;
|
|||
|
|
|
|||
|
|
if (isMockMode) {
|
|||
|
|
console.log('[MOCK] 设置实时位置订阅');
|
|||
|
|
this.startMockLocationGeneration();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 真实环境:初始化WebSocket连接并订阅位置更新
|
|||
|
|
try {
|
|||
|
|
// 使用新的API接口
|
|||
|
|
apiService.initLocationWebSocket();
|
|||
|
|
|
|||
|
|
// 订阅当前用户的位置更新
|
|||
|
|
apiService.subscribeToLocationUpdates(this.userInfo.id)
|
|||
|
|
.then(() => {
|
|||
|
|
console.log('成功订阅位置更新');
|
|||
|
|
})
|
|||
|
|
.catch((error) => {
|
|||
|
|
console.error('订阅位置更新失败:', error);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 设置位置更新回调
|
|||
|
|
this.unsubscribeCallback = apiService.onLocationUpdate((locationUpdate) => {
|
|||
|
|
this.handleLocationUpdate(locationUpdate);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('设置实时位置订阅失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 关闭实时位置订阅
|
|||
|
|
*/
|
|||
|
|
private teardownRealTimeSubscription(): void {
|
|||
|
|
if (isMockMode) {
|
|||
|
|
console.log('[MOCK] 关闭实时位置订阅');
|
|||
|
|
this.stopMockLocationGeneration();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 真实环境:取消订阅并关闭WebSocket连接
|
|||
|
|
try {
|
|||
|
|
if (this.userInfo) {
|
|||
|
|
// 使用新的API接口取消订阅
|
|||
|
|
apiService.unsubscribeFromLocationUpdates(this.userInfo.id)
|
|||
|
|
.then(() => {
|
|||
|
|
console.log('成功取消订阅位置更新');
|
|||
|
|
})
|
|||
|
|
.catch((error) => {
|
|||
|
|
console.error('取消订阅位置更新失败:', error);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 移除位置更新回调
|
|||
|
|
if (this.unsubscribeCallback) {
|
|||
|
|
this.unsubscribeCallback();
|
|||
|
|
this.unsubscribeCallback = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 关闭WebSocket连接
|
|||
|
|
apiService.closeLocationWebSocket();
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('关闭实时位置订阅失败:', error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 停止所有定时器
|
|||
|
|
*/
|
|||
|
|
private stopTimers(): void {
|
|||
|
|
this.stopLocationUpdateTimer();
|
|||
|
|
this.stopStatusCheckTimer();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 停止位置更新定时器
|
|||
|
|
*/
|
|||
|
|
private stopLocationUpdateTimer(): void {
|
|||
|
|
if (this.locationUpdateTimer) {
|
|||
|
|
clearInterval(this.locationUpdateTimer);
|
|||
|
|
this.locationUpdateTimer = null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 停止状态检查定时器
|
|||
|
|
*/
|
|||
|
|
private stopStatusCheckTimer(): void {
|
|||
|
|
if (this.statusCheckTimer) {
|
|||
|
|
clearInterval(this.statusCheckTimer);
|
|||
|
|
this.statusCheckTimer = null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 通知位置更新回调
|
|||
|
|
*/
|
|||
|
|
private notifyLocationUpdateCallbacks(): void {
|
|||
|
|
const onlineUsers = this.getOnlineUsers();
|
|||
|
|
this.locationUpdateCallbacks.forEach(callback => {
|
|||
|
|
try {
|
|||
|
|
callback(onlineUsers);
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('位置更新回调执行失败:', error);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 通知用户状态变化回调
|
|||
|
|
*/
|
|||
|
|
private notifyUserStatusChange(userId: number, status: 'online' | 'offline' | 'timeout'): void {
|
|||
|
|
this.userStatusCallbacks.forEach(callback => {
|
|||
|
|
try {
|
|||
|
|
callback(userId, status);
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('用户状态变化回调执行失败:', error);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 启动模拟位置生成
|
|||
|
|
*/
|
|||
|
|
private startMockLocationGeneration(): void {
|
|||
|
|
console.log('[MOCK] 启动模拟位置生成');
|
|||
|
|
// 这里可以添加模拟位置生成的逻辑
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 停止模拟位置生成
|
|||
|
|
*/
|
|||
|
|
private stopMockLocationGeneration(): void {
|
|||
|
|
console.log('[MOCK] 停止模拟位置生成');
|
|||
|
|
// 这里可以添加停止模拟位置生成的逻辑
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 处理位置更新
|
|||
|
|
*/
|
|||
|
|
private handleLocationUpdate(locationUpdate: any): void {
|
|||
|
|
console.log('收到位置更新:', locationUpdate);
|
|||
|
|
// 这里可以添加处理位置更新的逻辑
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 位置追踪服务单例实例
|
|||
|
|
* 导出供应用程序全局使用
|
|||
|
|
*/
|
|||
|
|
export default new LocationTrackingService();
|