// 货运人员服务 - 处理货运人员相关的数据操作 import { DeliveryPerson, LocationData } from '../types'; import apiService from './apiService'; import { isMockMode } from './apiService'; /** * 货运人员服务类 * 提供货运人员信息管理、位置更新、状态管理等功能 */ class DeliveryPersonService { // 模拟货运人员数据 private mockDeliveryPersons: DeliveryPerson[]; /** * 构造函数 */ constructor() { this.mockDeliveryPersons = [ { id: 101, name: '张师傅', phone: '13812345678', status: 'idle', currentLocation: { longitude: 102.714585, latitude: 25.046321 }, currentOrders: [] }, { id: 102, name: '李师傅', phone: '13912345678', status: 'busy', currentLocation: { longitude: 102.690181, latitude: 24.994788 }, currentOrders: [ { id: 1002, startPoint: { id: 2, name: '瓦尔塔蓄电池盘龙区分店', longitude: 102.728421, latitude: 25.042498 }, endPoint: { name: '云南中致远汽车销售有限公司', longitude: 102.796212, latitude: 24.936947 }, status: 'assigned', goodsType: '瓦尔塔EFB蓄电池', goodsWeight: 120, createTime: Date.now() - 7200000 } ] } ]; this.locationUpdateCallbacks = null; this.locationUpdateTimer = null; this.unsubscribeFunction = null; } /** * 获取所有货运人员 * @returns 货运人员列表 */ async getDeliveryPersons(): Promise { if (isMockMode) { // 模拟数据 - 返回所有货运人员 console.log('[MOCK] 获取所有货运人员'); return [...this.mockDeliveryPersons]; } return apiService.getDeliveryPersons(); } /** * 根据ID获取货运人员 * @param id 货运人员ID * @returns 货运人员信息或null */ async getDeliveryPersonById(id: number): Promise { if (isMockMode) { // 模拟数据 - 根据ID查找货运人员 console.log('[MOCK] 根据ID获取货运人员,ID:', id); const person = this.mockDeliveryPersons.find(p => p.id === id); return person || null; } try { const result = await apiService.getDeliveryPersonById(id); return result; } catch (error) { console.error('获取货运人员失败:', error); return null; } } /** * 更新货运人员位置 * @param id 货运人员ID * @param location 位置信息 */ async updateDeliveryPersonLocation( id: number, location: { longitude: number; latitude: number } ): Promise { if (isMockMode) { // 模拟数据 - 更新货运人员位置 console.log('[MOCK] 更新货运人员位置,ID:', id, '位置:', location); const person = this.mockDeliveryPersons.find(p => p.id === id); if (person) { person.currentLocation = location; } return; } return apiService.updateDeliveryPersonLocation(id, location); } /** * 批量更新货运人员位置 * @param locations 位置信息数组 */ async batchUpdateDeliveryPersonLocations(locations: Array<{ deliveryPersonId: number; longitude: number; latitude: number; timestamp: number; }>): Promise { if (isMockMode) { // 模拟数据 - 批量更新货运人员位置 console.log('[MOCK] 批量更新货运人员位置'); locations.forEach(item => { const person = this.mockDeliveryPersons.find(p => p.id === item.deliveryPersonId); if (person) { person.currentLocation = { longitude: item.longitude, latitude: item.latitude }; } }); return; } // 修复:转换参数格式以匹配apiService的要求 const formattedLocations = locations.map(loc => ({ userId: loc.deliveryPersonId, // 将deliveryPersonId转换为userId longitude: loc.longitude, latitude: loc.latitude, timestamp: loc.timestamp })); return apiService.batchUpdateDeliveryPersonLocations(formattedLocations); } /** * 获取空闲的货运人员 * @returns 空闲货运人员列表 */ async getIdleDeliveryPersons(): Promise { if (isMockMode) { // 模拟数据 - 返回空闲的货运人员 console.log('[MOCK] 获取空闲的货运人员'); return this.mockDeliveryPersons.filter(p => p.status === 'idle'); } return apiService.getIdleDeliveryPersons(); } /** * 获取忙碌的货运人员 * @returns 忙碌货运人员列表 */ async getBusyDeliveryPersons(): Promise { if (isMockMode) { // 模拟数据 - 返回忙碌的货运人员 console.log('[MOCK] 获取忙碌的货运人员'); return this.mockDeliveryPersons.filter(p => p.status === 'busy'); } return apiService.getBusyDeliveryPersons(); } /** * 获取位置历史记录 * @param deliveryPersonId 货运人员ID * @param limit 记录数量 * @returns 位置历史记录 */ async getLocationHistory(deliveryPersonId: number, limit: number = 50): Promise> { if (isMockMode) { // 模拟数据 - 返回位置历史记录 console.log('[MOCK] 获取货运人员位置历史记录,ID:', deliveryPersonId); const mockHistory = []; const person = this.mockDeliveryPersons.find(p => p.id === deliveryPersonId); if (person) { // 生成一些模拟的位置历史记录 for (let i = 0; i < limit; i++) { // 在当前位置附近随机生成一些位置点 const baseLongitude = person.currentLocation.longitude; const baseLatitude = person.currentLocation.latitude; mockHistory.push({ timestamp: Date.now() - i * 60000, // 每分钟一个点 longitude: baseLongitude + (Math.random() - 0.5) * 0.01, latitude: baseLatitude + (Math.random() - 0.5) * 0.01, speed: Math.random() * 60, // 0-60 km/h accuracy: 5 + Math.random() * 15 // 5-20 meters }); } } return mockHistory; } return apiService.getLocationHistory(deliveryPersonId, limit); } /** * 订阅实时位置更新(兼容mapService参数) * @param callback 位置更新回调函数 */ async subscribeToRealTimeLocations(callback: (location: LocationData) => void): Promise { if (isMockMode) { // 模拟实时位置更新 console.log('[MOCK] 订阅实时位置更新'); // 保存回调引用,以便在取消订阅时使用 if (!this.locationUpdateCallbacks) { this.locationUpdateCallbacks = new Set(); } this.locationUpdateCallbacks.add(callback); // 如果是首次订阅,启动模拟更新 if (!this.locationUpdateTimer) { this.startMockLocationUpdates(); } return; } // 真实环境中实现WebSocket连接 try { // 获取当前用户信息 const userInfo = wx.getStorageSync('userInfo'); if (!userInfo || !userInfo.id) { throw new Error('用户未登录,无法订阅位置更新'); } // 初始化WebSocket连接 await apiService.initLocationWebSocket(); // 订阅位置更新 await apiService.subscribeToLocationUpdates(userInfo.id); // 设置位置更新回调 this.unsubscribeFunction = apiService.onLocationUpdate((location) => { callback(location as LocationData); }); console.log('WebSocket位置订阅成功'); } catch (error) { console.error('订阅实时位置更新失败:', error); throw error; } } /** * 取消订阅实时位置更新(兼容无参数调用) */ async unsubscribeFromRealTimeLocations(): Promise { if (isMockMode) { // 模拟取消订阅 console.log('[MOCK] 取消订阅实时位置更新'); // 清除所有回调 if (this.locationUpdateCallbacks) { this.locationUpdateCallbacks.clear(); } // 停止模拟更新定时器 if (this.locationUpdateTimer) { clearInterval(this.locationUpdateTimer); this.locationUpdateTimer = null; } return; } // 真实环境中关闭WebSocket连接 try { // 获取当前用户信息 const userInfo = wx.getStorageSync('userInfo'); if (userInfo && userInfo.id) { // 取消订阅 await apiService.unsubscribeFromLocationUpdates(userInfo.id); } // 调用取消订阅函数 if (this.unsubscribeFunction) { this.unsubscribeFunction(); this.unsubscribeFunction = null; } // 关闭WebSocket连接 apiService.closeLocationWebSocket(); console.log('WebSocket位置订阅已取消'); } catch (error) { console.error('取消订阅实时位置更新失败:', error); throw error; } } /** * 发送位置更新到服务器 * @param deliveryPersonId 配送员ID * @param latitude 纬度 * @param longitude 经度 */ async sendLocationUpdate(deliveryPersonId: number, latitude: number, longitude: number): Promise { if (isMockMode) { console.log('[MOCK] 发送位置更新:', { deliveryPersonId, latitude, longitude }); return; } try { await apiService.sendLocationUpdate(deliveryPersonId, latitude, longitude); console.log('位置更新发送成功'); } catch (error) { console.error('发送位置更新失败:', error); throw error; } } // ===== 私有辅助方法 ===== /** * 存储位置更新回调函数的集合 */ private locationUpdateCallbacks: Set<(location: LocationData) => void> | null; /** * 模拟位置更新的定时器 */ private locationUpdateTimer: number | null; /** * 取消订阅函数引用 */ private unsubscribeFunction: (() => void) | null; /** * 启动模拟位置更新 */ private startMockLocationUpdates(): void { // 每5秒发送一次模拟位置更新 this.locationUpdateTimer = setInterval(() => { if (this.locationUpdateCallbacks && this.locationUpdateCallbacks.size > 0) { // 为每个货运人员生成模拟位置更新 this.mockDeliveryPersons.forEach(person => { // 在当前位置附近随机生成新位置 const baseLongitude = person.currentLocation.longitude; const baseLatitude = person.currentLocation.latitude; const newLocation: LocationData = { userId: person.id, longitude: baseLongitude + (Math.random() - 0.5) * 0.001, // 小范围随机移动 latitude: baseLatitude + (Math.random() - 0.5) * 0.001, // 小范围随机移动 timestamp: Date.now() }; // 更新模拟数据中的位置 person.currentLocation = { longitude: newLocation.longitude, latitude: newLocation.latitude }; // 通知所有回调函数 this.locationUpdateCallbacks!.forEach(callback => { try { callback(newLocation); } catch (error) { console.error('位置更新回调执行失败:', error); } }); }); } }, 5000); // 5秒更新一次 } /** * 获取货运人员当前订单 * @param deliveryPersonId 货运人员ID * @returns 订单列表 */ async getDeliveryPersonOrders(deliveryPersonId: number): Promise> { if (isMockMode) { // 模拟数据 - 返回货运人员当前订单 console.log('[MOCK] 获取货运人员当前订单,ID:', deliveryPersonId); const person = this.mockDeliveryPersons.find(p => p.id === deliveryPersonId); return person ? person.currentOrders : []; } return apiService.getDeliveryPersonOrders(deliveryPersonId); } } /** * 货运人员服务单例实例 * 导出供应用程序全局使用 */ export default new DeliveryPersonService();