用户在线状态处理
This commit is contained in:
@@ -69,13 +69,32 @@ class LocationTrackingService {
|
||||
throw new Error('用户未登录,无法启动位置追踪');
|
||||
}
|
||||
|
||||
// 先获取当前位置数据
|
||||
let initialLocation: { latitude: number; longitude: number; timestamp: number } ;
|
||||
|
||||
const location = await this.getCurrentLocation();
|
||||
initialLocation = {
|
||||
latitude: location.latitude,
|
||||
longitude: location.longitude,
|
||||
timestamp: Math.floor(Date.now() / 1000)
|
||||
}
|
||||
|
||||
console.log('获取到初始位置数据:', initialLocation);
|
||||
|
||||
// 调用签到接口,传递位置数据
|
||||
try {
|
||||
await userService.signIn(initialLocation);
|
||||
console.log('签到成功,位置数据已发送到服务器');
|
||||
} catch (error) {
|
||||
console.error('签到失败:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
this.isSignedIn = true;
|
||||
|
||||
// 将当前用户添加到在线列表
|
||||
await this.addUserToOnlineList(userInfo);
|
||||
|
||||
// 签到消息已通过REST API处理,服务器会自动处理订阅逻辑
|
||||
|
||||
// 设置实时位置订阅(初始化WebSocket连接)
|
||||
await this.setupRealTimeSubscription();
|
||||
|
||||
@@ -91,9 +110,6 @@ class LocationTrackingService {
|
||||
// 启动位置更新定时器(每30秒更新一次)
|
||||
this.startLocationUpdateTimer();
|
||||
|
||||
// 启动状态检查定时器(每60秒检查一次)
|
||||
this.startStatusCheckTimer();
|
||||
|
||||
console.log('位置追踪服务已启动');
|
||||
}
|
||||
|
||||
@@ -102,11 +118,6 @@ class LocationTrackingService {
|
||||
*/
|
||||
public async initialize(): Promise<void> {
|
||||
try {
|
||||
// 注册位置更新回调
|
||||
apiService.onLocationUpdate((locationUpdate) => {
|
||||
this.handleLocationUpdate(locationUpdate);
|
||||
});
|
||||
|
||||
// 注册在线用户列表回调
|
||||
apiService.onOnlineUserList((userList) => {
|
||||
this.handleOnlineUserList(userList);
|
||||
@@ -119,6 +130,8 @@ class LocationTrackingService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 用户签退后停止位置追踪
|
||||
*/
|
||||
@@ -138,11 +151,15 @@ class LocationTrackingService {
|
||||
// 停止定时器
|
||||
this.stopTimers();
|
||||
|
||||
|
||||
|
||||
// 关闭实时位置订阅(服务器会自动处理取消订阅)
|
||||
this.teardownRealTimeSubscription();
|
||||
|
||||
console.log('位置追踪服务已停止');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 手动更新用户位置
|
||||
@@ -158,13 +175,14 @@ class LocationTrackingService {
|
||||
console.log(`- 用户ID: ${userInfo.id}`);
|
||||
console.log(`- 经度: ${location.longitude}`);
|
||||
console.log(`- 纬度: ${location.latitude}`);
|
||||
console.log(`- 时间戳: ${Date.now()}`);
|
||||
const timestamp = Math.floor(Date.now() / 1000);
|
||||
console.log(`- 时间戳: ${timestamp}`);
|
||||
|
||||
const locationData: LocationData = {
|
||||
userId: userInfo.id,
|
||||
longitude: location.longitude,
|
||||
latitude: location.latitude,
|
||||
timestamp: Date.now()
|
||||
timestamp: timestamp
|
||||
};
|
||||
|
||||
// 真实模式:通过WebSocket发送位置更新
|
||||
@@ -174,9 +192,7 @@ class LocationTrackingService {
|
||||
// 同时更新本地缓存
|
||||
this.updateLocalUserLocation(userInfo.id, locationData);
|
||||
|
||||
// 通知所有回调
|
||||
this.notifyLocationUpdateCallbacks();
|
||||
console.log('[位置追踪服务] 位置更新完成,已通知回调');
|
||||
console.log('[位置追踪服务] 位置更新完成');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,7 +208,10 @@ class LocationTrackingService {
|
||||
* 订阅位置更新
|
||||
*/
|
||||
public subscribeToLocationUpdates(callback: (locations: OnlineUserInfo[]) => void): void {
|
||||
console.log('📝 [LocationTrackingService] 注册位置更新回调函数');
|
||||
console.log('📍 [LocationTrackingService] 当前已注册回调数量:', this.locationUpdateCallbacks.size);
|
||||
this.locationUpdateCallbacks.add(callback);
|
||||
console.log('✅ [LocationTrackingService] 位置更新回调注册完成,当前回调数量:', this.locationUpdateCallbacks.size);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,7 +257,7 @@ class LocationTrackingService {
|
||||
avatarUrl: '/images/user-avatar.png',
|
||||
role: userInfo.role || 'delivery_person', // 用户角色
|
||||
lastLocation: currentLocation,
|
||||
lastUpdateTime: Date.now(),
|
||||
lastUpdateTime: Math.floor(Date.now() / 1000),
|
||||
status: 'online'
|
||||
};
|
||||
|
||||
@@ -330,7 +349,7 @@ class LocationTrackingService {
|
||||
/**
|
||||
* 获取当前位置
|
||||
*/
|
||||
private async getCurrentLocation(): Promise<LocationData> {
|
||||
public async getCurrentLocation(): Promise<LocationData> {
|
||||
const userInfo = userService.getGlobalUserInfo();
|
||||
if (!userInfo || !userInfo.id) {
|
||||
throw new Error('用户未登录');
|
||||
@@ -415,10 +434,7 @@ class LocationTrackingService {
|
||||
// 服务器会自动处理订阅逻辑,无需发送订阅消息
|
||||
console.log('WebSocket连接已建立,服务器将自动处理位置订阅逻辑');
|
||||
|
||||
// 设置位置更新回调
|
||||
this.unsubscribeCallback = apiService.onLocationUpdate((locationUpdate) => {
|
||||
this.handleLocationUpdate(locationUpdate);
|
||||
});
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error('设置实时位置订阅失败:', error);
|
||||
@@ -476,18 +492,28 @@ class LocationTrackingService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 通知位置更新回调
|
||||
*/
|
||||
private notifyLocationUpdateCallbacks(): void {
|
||||
const onlineUsers = this.getOnlineUsers();
|
||||
this.locationUpdateCallbacks.forEach(callback => {
|
||||
console.log('🔔 [LocationTrackingService] 开始通知位置更新回调');
|
||||
console.log('👥 [LocationTrackingService] 在线用户数量:', onlineUsers.length);
|
||||
console.log('📞 [LocationTrackingService] 准备执行', this.locationUpdateCallbacks.size, '个回调函数');
|
||||
|
||||
this.locationUpdateCallbacks.forEach((callback, index) => {
|
||||
try {
|
||||
console.log(`🔄 [LocationTrackingService] 执行第 ${index + 1} 个位置更新回调`);
|
||||
callback(onlineUsers);
|
||||
console.log(`✅ [LocationTrackingService] 第 ${index + 1} 个位置更新回调执行成功`);
|
||||
} catch (error) {
|
||||
console.error('位置更新回调执行失败:', error);
|
||||
console.error(`❌ [LocationTrackingService] 第 ${index + 1} 个位置更新回调执行失败:`, error);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('🏁 [LocationTrackingService] 位置更新回调通知完成');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -505,82 +531,84 @@ class LocationTrackingService {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 处理位置更新
|
||||
*/
|
||||
private handleLocationUpdate(locationUpdate: any): void {
|
||||
console.log('收到位置更新:', locationUpdate);
|
||||
|
||||
// 验证位置更新消息格式
|
||||
if (!locationUpdate || typeof locationUpdate !== 'object') {
|
||||
console.warn('无效的位置更新消息格式');
|
||||
return;
|
||||
}
|
||||
|
||||
// 提取关键信息
|
||||
const { deliveryPersonId, latitude, longitude, timestamp } = locationUpdate;
|
||||
|
||||
if (!deliveryPersonId || latitude === undefined || longitude === undefined) {
|
||||
console.warn('位置更新消息缺少必要字段:', locationUpdate);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`处理员工 ${deliveryPersonId} 的位置更新: (${longitude}, ${latitude})`);
|
||||
|
||||
// 更新本地缓存中的员工位置
|
||||
this.updateLocalUserLocation(deliveryPersonId, {
|
||||
userId: deliveryPersonId,
|
||||
longitude: longitude,
|
||||
latitude: latitude,
|
||||
timestamp: timestamp || Date.now()
|
||||
});
|
||||
|
||||
// 通知所有位置更新回调(UI层会监听这些回调来更新地图标记点)
|
||||
this.notifyLocationUpdateCallbacks();
|
||||
|
||||
console.log(`员工 ${deliveryPersonId} 位置更新处理完成`);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理在线用户列表消息
|
||||
* @param userList 在线用户列表消息
|
||||
* 处理在线用户列表
|
||||
* @param userList 服务器下发的在线用户列表
|
||||
*/
|
||||
private handleOnlineUserList(userList: any): void {
|
||||
private handleOnlineUserList(userList: any[]): void {
|
||||
try {
|
||||
console.log('[LocationTrackingService] 收到在线用户列表:', userList);
|
||||
|
||||
if (!userList || !userList.users) {
|
||||
console.warn('[LocationTrackingService] 无效的在线用户列表消息');
|
||||
// 验证数据格式
|
||||
if (!Array.isArray(userList)) {
|
||||
console.warn('[LocationTrackingService] 无效的在线用户列表数据格式');
|
||||
return;
|
||||
}
|
||||
|
||||
// 清空当前在线用户列表
|
||||
this.onlineUsers.clear();
|
||||
console.log(`[LocationTrackingService] 开始处理在线用户列表,用户数量: ${userList.length}`);
|
||||
|
||||
// 更新在线用户列表
|
||||
userList.users.forEach((userInfo: any) => {
|
||||
if (userInfo && userInfo.userId) {
|
||||
this.onlineUsers.set(userInfo.userId, {
|
||||
userId: userInfo.userId,
|
||||
name: userInfo.userName || '未知用户',
|
||||
// 获取当前本地用户列表的userId集合
|
||||
const currentUserIds = new Set(this.onlineUsers.keys());
|
||||
|
||||
// 处理服务器下发的用户列表
|
||||
const newUserIds = new Set();
|
||||
|
||||
userList.forEach(user => {
|
||||
if (user && user.userId && user.latitude !== undefined && user.longitude !== undefined) {
|
||||
newUserIds.add(user.userId);
|
||||
|
||||
// 提取位置数据(支持多种数据格式)
|
||||
const latitude = user.latitude;
|
||||
const longitude = user.longitude;
|
||||
const timestamp = user.timestamp || user.lastUpdateTime || Date.now();
|
||||
|
||||
// 更新或添加用户信息
|
||||
this.onlineUsers.set(user.userId, {
|
||||
userId: user.userId,
|
||||
name: user.name || user.userName || `用户${user.userId}`,
|
||||
avatarUrl: '/images/user-avatar.png',
|
||||
role: userInfo.role || 'delivery_person', // 用户角色,默认为配送员
|
||||
role: user.role || 'employee',
|
||||
lastLocation: {
|
||||
userId: userInfo.userId,
|
||||
longitude: userInfo.longitude || 0,
|
||||
latitude: userInfo.latitude || 0,
|
||||
timestamp: userInfo.lastUpdateTime || Date.now()
|
||||
userId: user.userId,
|
||||
longitude: longitude,
|
||||
latitude: latitude,
|
||||
timestamp: timestamp
|
||||
},
|
||||
lastUpdateTime: userInfo.lastUpdateTime || Date.now(),
|
||||
status: 'online'
|
||||
lastUpdateTime: timestamp,
|
||||
status: user.userStatus === false ? 'offline' : 'online'
|
||||
});
|
||||
|
||||
console.log(`[LocationTrackingService] 更新用户 ${user.userId} 位置: (${latitude}, ${longitude})`);
|
||||
|
||||
// 如果用户是新上线的,触发用户状态回调
|
||||
if (!currentUserIds.has(user.userId)) {
|
||||
this.notifyUserStatusChange(user.userId, 'online');
|
||||
console.log(`[LocationTrackingService] 新用户上线: ${user.userId}`);
|
||||
}
|
||||
} else {
|
||||
console.warn(`[LocationTrackingService] 跳过无效用户数据:`, user);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('[LocationTrackingService] 在线用户列表已更新,当前在线用户数:', this.onlineUsers.size);
|
||||
// 删除本地列表中不在服务器列表中的用户
|
||||
let removedCount = 0;
|
||||
currentUserIds.forEach(userId => {
|
||||
if (!newUserIds.has(userId)) {
|
||||
// 删除离线用户
|
||||
this.onlineUsers.delete(userId);
|
||||
removedCount++;
|
||||
|
||||
// 触发用户状态回调(离线)
|
||||
this.notifyUserStatusChange(userId, 'offline');
|
||||
console.log(`[LocationTrackingService] 用户离线: ${userId}`);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`[LocationTrackingService] 在线用户列表更新完成: 新增 ${newUserIds.size - (currentUserIds.size - removedCount)} 个用户,删除 ${removedCount} 个用户`);
|
||||
|
||||
// 通知位置模块更新地图标记点
|
||||
// 通知位置模块更新地图标记点(无论是否有变化都通知,确保地图标记点同步)
|
||||
this.notifyLocationUpdateCallbacks();
|
||||
console.log('[LocationTrackingService] 已通知位置模块更新地图标记点');
|
||||
|
||||
} catch (error) {
|
||||
console.error('[LocationTrackingService] 处理在线用户列表失败:', error);
|
||||
|
Reference in New Issue
Block a user