用户在线状态处理

This commit is contained in:
2025-10-19 13:40:20 +08:00
parent 39fa0b2d04
commit 118ec38550
7 changed files with 283 additions and 157 deletions

View File

@@ -34,11 +34,12 @@
- **员工信息验证**: 注册时验证员工信息是否存在
- **角色管理**: 支持管理员和配送员两种角色分配
### 📍 位置追踪功能
### 位置追踪功能
- **实时位置更新**: 通过WebSocket实现货运人员实时位置追踪
- **位置订阅机制**: 支持订阅特定货运人员的位置更新
- **在线状态管理**: 实时显示货运人员在线/离线状态
- **位置历史记录**: 记录货运人员位置历史轨迹
- **位置列表更新机制**: 系统通过WebSocket被动接收服务器推送的位置列表更新不主动请求刷新
### 🔧 系统管理功能
- **API配置管理**: 可以配置API服务器地址等参数
@@ -230,14 +231,35 @@
#### WebSocket实时位置消息
1. **位置更新消息**
1. **在线用户列表消息**
```json
{
"type": "updateLocation", // 消息类型
"deliveryPersonId": number, // 货运人员ID
"latitude": number, // 纬度
"longitude": number, // 经度
"timestamp": number // 时间戳
"type": "onlineUserList", // 消息类型
"users": [ // 在线用户列表
{
"id": number, // 用户ID
"name": "string", // 用户名或userName字段
"latitude": number, // 纬度
"longitude": number, // 经度
"timestamp": number // 时间戳或lastUpdateTime字段
}
]
}
```
2. **用户位置列表消息**
```json
{
"type": "userLocationList", // 消息类型
"users": [ // 用户位置列表
{
"id": number, // 用户ID
"name": "string", // 用户名或userName字段
"latitude": number, // 纬度
"longitude": number, // 经度
"timestamp": number // 时间戳或lastUpdateTime字段
}
]
}
```

View File

@@ -1,5 +1,6 @@
// app.ts
import userService from "./services/userService";
import locationTrackingService from "./services/locationTrackingService";
import { showToast } from "./utils/helpers";
// 定义应用类
@@ -26,6 +27,11 @@ class MyApp {
console.log("=== 应用启动 ===");
console.log("调试信息 - 开始执行onLaunch");
try {
// 初始化位置追踪服务
console.log("调试信息 - 初始化位置追踪服务");
await locationTrackingService.initialize();
console.log("调试信息 - 位置追踪服务初始化完成");
// 初始化日志存储
const logs = wx.getStorageSync("logs") || [];
logs.unshift(Date.now());

View File

@@ -142,30 +142,36 @@ export class LocationModule {
* 处理位置更新回调
*/
private handleLocationUpdates(locationData: any): void {
console.log('收到位置更新回调:', locationData);
console.log('🔔 [LocationModule] 收到位置更新回调');
console.log('📊 [LocationModule] 回调数据类型:', locationData.type || '未知类型');
console.log('📋 [LocationModule] 回调数据内容:', JSON.stringify(locationData, null, 2));
if (locationData.type === 'onlineUserList' && locationData.users) {
// 处理在线用户列表更新
console.log('处理在线用户列表,用户数量:', locationData.users.length);
console.log('👥 [LocationModule] 处理在线用户列表,用户数量:', locationData.users.length);
this.updateEmployeeMarkers(locationData.users);
} else if (Array.isArray(locationData)) {
// 处理位置更新数组(旧格式)
console.log('处理位置更新数组,用户数量:', locationData.length);
console.log('📋 [LocationModule] 处理位置更新数组,用户数量:', locationData.length);
this.updateEmployeeMarkers(locationData);
} else if (locationData.userId && locationData.latitude && locationData.longitude) {
// 处理单个用户位置更新
console.log('处理单个用户位置更新:', locationData.userId);
console.log('👤 [LocationModule] 处理单个用户位置更新:', locationData.userId);
this.updateSingleEmployeeMarker(locationData);
} else {
console.warn('未知的位置数据格式:', locationData);
console.warn('❌ [LocationModule] 未知的位置数据格式:', locationData);
}
console.log('🏁 [LocationModule] 位置更新回调处理完成');
}
/**
* 更新员工标记点
*/
private updateEmployeeMarkers(onlineUsers: any[]): void {
console.log('开始更新员工标记点,在线用户数量:', onlineUsers.length);
console.log('📍 [LocationModule] 开始更新员工标记点');
console.log('👥 [LocationModule] 传入用户数量:', onlineUsers.length);
console.log('📋 [LocationModule] 用户数据示例:', JSON.stringify(onlineUsers[0], null, 2));
// 获取地图模块来更新标记点
const mapModule = this.dataModule.getMapModule();
@@ -175,7 +181,9 @@ export class LocationModule {
}
// 为每个在线用户创建标记点
const employeeMarkers = onlineUsers.map(user => {
const employeeMarkers = onlineUsers.map((user, index) => {
console.log(`🔍 [LocationModule] 处理第 ${index + 1} 个用户:`, user.userId || '未知ID');
// 获取用户角色信息
const userRole = user.role || this.getUserRole(user.userId);
@@ -184,6 +192,9 @@ export class LocationModule {
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',
@@ -204,10 +215,13 @@ export class LocationModule {
return employeeMarker;
});
console.log('📍 [LocationModule] 生成标记点数量:', employeeMarkers.length);
console.log('📋 [LocationModule] 标记点数据示例:', JSON.stringify(employeeMarkers[0], null, 2));
// 调用地图模块更新员工标记点
mapModule.updateEmployeeMarkers(employeeMarkers);
console.log(`成功更新了 ${employeeMarkers.length} 个员工标记点`);
console.log('✅ [LocationModule] 员工标记点更新完成');
}
/**

View File

@@ -193,8 +193,24 @@ export class LoginModule {
title: '签到中...',
});
// 调用实际的签到接口
const signInResult = await userService.signIn();
// 先获取地图位置和当前时间
let initialLocation: { latitude: number; longitude: number; timestamp: number };
try {
const location = await locationTrackingService.getCurrentLocation();
// 使用秒级时间戳除以1000取整
initialLocation = {
latitude: location.latitude,
longitude: location.longitude,
timestamp: Math.floor(Date.now() / 1000)
};
console.log('获取到签到位置数据:', initialLocation);
} catch (error) {
console.error('获取位置失败:', error);
throw new Error('获取位置失败,请检查位置权限设置');
}
// 调用实际的签到接口,传递位置数据
const signInResult = await userService.signIn(initialLocation);
wx.hideLoading();

View File

@@ -7,7 +7,7 @@ import { WarehouseInfo, UserInfo, DeliveryPerson, Order, EmployeeInfo } from '..
*/
// API基础URL配置
const IS_LOCAL_DEV = false; // true: 本地开发环境, false: 生产环境
const IS_LOCAL_DEV = true; // true: 本地开发环境, false: 生产环境
const API_BASE_URL = IS_LOCAL_DEV ? 'http://localhost:8080' : 'https://www.doubleyin.cn';
console.log(`当前API地址: ${API_BASE_URL} (${IS_LOCAL_DEV ? '本地开发环境' : '生产环境'})`);
@@ -140,15 +140,24 @@ async ServerLogin(code: string) {
/**
* 签到接口
* @param userId 用户ID
* @param initialLocation 初始位置数据(必须)
* @returns 签到结果和员工信息
*/
async userSignIn(userId: number): Promise<{ success: boolean; employeeInfo: EmployeeInfo; message?: string }> {
console.log('API userSignIn调用参数userId:', userId);
async userSignIn(userId: number, initialLocation: { latitude: number; longitude: number; timestamp: number }): Promise<{ success: boolean; employeeInfo: EmployeeInfo; message?: string }> {
console.log('API userSignIn调用参数userId:', userId, 'initialLocation:', initialLocation);
// 构建请求数据,必须包含位置数据
const requestData: any = {
userId,
latitude: initialLocation.latitude,
longitude: initialLocation.longitude,
timestamp: initialLocation.timestamp
};
// 服务器返回的是用户对象,需要转换为前端期望的格式
const response = await this.request<any>('/user/signin', {
method: 'POST',
data: { userId },
data: requestData,
});
// 转换响应格式
@@ -562,29 +571,7 @@ async ServerLogin(code: string) {
}
}
/**
* 注册位置更新回调函数
* @param callback 位置更新回调函数
* @returns 取消订阅函数
*/
onLocationUpdate(callback: (location: any) => void): () => void {
// 添加回调到集合
if (!this.locationUpdateCallbacks) {
this.locationUpdateCallbacks = new Set();
}
this.locationUpdateCallbacks.add(callback);
// 返回取消订阅函数
return () => {
if (this.locationUpdateCallbacks) {
this.locationUpdateCallbacks.delete(callback);
// 如果没有回调了可以关闭WebSocket连接
if (this.locationUpdateCallbacks.size === 0 && this.locationWebSocket) {
this.closeLocationWebSocket();
}
}
};
}
/**
* 注册在线用户列表回调函数
@@ -625,8 +612,18 @@ async ServerLogin(code: string) {
const serverUrl = API_BASE_URL.replace('http', 'ws');
const wsUrl = `${serverUrl}/ws/location`;
// 获取当前用户ID从全局应用数据中获取
const app = getApp<any>();
const userInfo = app.globalData.userInfo;
const userId = userInfo?.id;
// 构建带用户ID参数的WebSocket URL
const finalWsUrl = userId ? `${wsUrl}?userId=${userId}` : wsUrl;
console.log(`WebSocket连接URL: ${finalWsUrl}`);
this.locationWebSocket = wx.connectSocket({
url: wsUrl,
url: finalWsUrl,
header: {
'content-type': 'application/json'
}
@@ -714,18 +711,61 @@ async ServerLogin(code: string) {
return;
}
console.log(`📡 收到WebSocket消息类型: ${message.type}`, message);
switch (message.type) {
case 'updateLocation':
// 处理位置更新消息
this.triggerLocationUpdateCallbacks(message);
break;
case 'onlineUserList':
// 处理在线用户列表消息
this.triggerOnlineUserListCallbacks(message);
// 处理在线用户列表消息(服务器发送当前在线用户列表)
console.log('👥 处理在线用户列表,用户数量:', message.users ? message.users.length : 0);
if (message.users && Array.isArray(message.users)) {
this.triggerOnlineUserListCallbacks({
type: 'onlineUserList',
users: message.users.map((user: any) => ({
userId: user.userId,
name: user.name,
role: user.role,
userStatus: user.userStatus,
lastUpdateTime: user.lastUpdateTime,
latitude: user.locationData?.latitude || user.latitude,
longitude: user.locationData?.longitude || user.longitude,
timestamp: user.locationData?.timestamp || user.timestamp
}))
});
}else {
console.warn('❌ onlineUserList消息格式错误users字段不存在或不是数组');
}
break;
case 'subscribed':
// 处理订阅成功响应
console.log('WebSocket订阅成功:', message);
case 'userLocationList':
// 处理用户位置列表消息服务器每30秒发送所有在线用户的位置列表
console.log('👥 处理用户位置列表,用户数量:', message.users ? message.users.length : 0);
// 确保用户列表存在且是数组
if (message.users && Array.isArray(message.users)) {
// 转换用户数据格式,确保与位置追踪服务兼容
const formattedUsers = message.users.map((user: any) => {
// 支持多种数据格式locationData字段或直接字段
const locationData = user.locationData || user;
return {
userId: user.userId || locationData.userId,
name: user.name || user.userName || `用户${user.userId || locationData.userId}`,
role: user.role || 'employee',
userStatus: user.userStatus !== false, // 转换为布尔值
lastUpdateTime: user.lastUpdateTime || locationData.timestamp || Date.now(),
latitude: locationData.latitude,
longitude: locationData.longitude,
timestamp: locationData.timestamp || user.timestamp || Date.now()
};
});
console.log('📊 转换后的用户位置数据:', formattedUsers);
this.triggerOnlineUserListCallbacks({
type: 'userLocationList',
users: formattedUsers
});
} else {
console.warn('❌ userLocationList消息格式错误users字段不存在或不是数组');
}
break;
default:
console.warn('收到未知类型的WebSocket消息:', message);
@@ -733,41 +773,40 @@ async ServerLogin(code: string) {
}
}
/**
* 触发位置更新回调
* @param locationUpdate 位置更新信息
*/
private triggerLocationUpdateCallbacks(locationUpdate: any): void {
if (this.locationUpdateCallbacks) {
this.locationUpdateCallbacks.forEach(callback => {
try {
callback(locationUpdate);
} catch (error) {
console.error('位置更新回调执行失败:', error);
}
});
}
}
/**
* 触发在线用户列表回调
* @param userList 在线用户列表信息
*/
private triggerOnlineUserListCallbacks(userList: any): void {
console.log('🔔 [apiService] 开始触发在线用户列表回调,消息类型:', userList.type);
console.log('📊 [apiService] 回调数据内容:', JSON.stringify(userList, null, 2));
if (this.onlineUserListCallbacks) {
this.onlineUserListCallbacks.forEach(callback => {
console.log(`📞 [apiService] 准备执行 ${this.onlineUserListCallbacks.size} 个回调函数`);
let index = 0;
this.onlineUserListCallbacks.forEach((callback) => {
try {
callback(userList);
console.log(`🔄 [apiService] 执行第 ${index + 1} 个回调函数`);
// 传递正确的数据格式只传递users数组而不是整个消息对象
callback(userList.users);
console.log(`✅ [apiService] 第 ${index + 1} 个回调函数执行成功`);
index++;
} catch (error) {
console.error('在线用户列表回调执行失败:', error);
console.error(`❌ [apiService] 第 ${index + 1} 个回调函数执行失败:`, error);
index++;
}
});
} else {
console.warn('⚠️ [apiService] 没有注册的在线用户列表回调函数');
}
console.log('🏁 [apiService] 在线用户列表回调触发完成');
}
/**
* 发送WebSocket消息
* @param message 要发送的消息
* @param message 要发送的消息对象
*/
private sendWebSocketMessage(message: any): void {
if (!this.locationWebSocket) {

View File

@@ -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,12 +151,16 @@ 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);

View File

@@ -255,9 +255,10 @@ class UserService {
/**
* 用户签到
* @param initialLocation 初始位置数据(必须)
* @returns 签到结果和更新后的用户信息
*/
async signIn(): Promise<{ success: boolean; employeeInfo: EmployeeInfo; message?: string }> {
async signIn(initialLocation: { latitude: number; longitude: number; timestamp: number }): Promise<{ success: boolean; employeeInfo: EmployeeInfo; message?: string }> {
const userInfo = this.getGlobalUserInfo();
if (!userInfo || !userInfo.id) {
throw new Error('用户未登录,无法签到');
@@ -269,7 +270,7 @@ class UserService {
throw new Error('用户认证信息缺失,请重新登录');
}
return apiService.userSignIn(userInfo.id);
return apiService.userSignIn(userInfo.id, initialLocation);
}
/**