From 528e4757dd4d0ae4dcda68c38552bd8f227286bc Mon Sep 17 00:00:00 2001 From: Doubleyin <953994191@qq.com> Date: Wed, 10 Dec 2025 22:49:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=B0=E5=9B=BE=E8=AE=A2=E5=8D=95=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- miniprogram/pages/admin/admin.ts | 21 ++-- miniprogram/pages/index/index.ts | 18 +++ miniprogram/pages/index/index.wxml | 18 +-- miniprogram/pages/index/modules/dataModule.ts | 22 ++-- .../pages/index/modules/locationModule.ts | 17 +-- miniprogram/pages/index/modules/mapModule.ts | 66 +++++++++-- .../pages/index/modules/orderModule.ts | 10 +- miniprogram/pages/staff/employee-dashboard.ts | 26 +++-- miniprogram/pages/staff/order-management.ts | 35 +++--- miniprogram/pages/staff/order-management.wxml | 2 +- miniprogram/pages/staff/profile.ts | 22 ++-- miniprogram/services/apiService.ts | 20 ++-- .../services/locationTrackingService.ts | 103 +++++++----------- miniprogram/services/mapService.ts | 10 ++ miniprogram/services/statisticsService.ts | 86 +++++++++++++++ miniprogram/types/index.ts | 29 ++--- miniprogram/utils/avatarCache.ts | 3 +- 17 files changed, 325 insertions(+), 183 deletions(-) diff --git a/miniprogram/pages/admin/admin.ts b/miniprogram/pages/admin/admin.ts index a0a5662..d4a4b0d 100644 --- a/miniprogram/pages/admin/admin.ts +++ b/miniprogram/pages/admin/admin.ts @@ -571,24 +571,21 @@ Page({ // 获取仓库信息 const warehouse = warehouses[warehouseIndex]; - // 模拟终点坐标(实际应用中应该通过地图选择或搜索获取) - // 从已有仓库中获取一个坐标作为参考点 - const referenceWarehouse = this.data.warehouses[0]; - const endPoint = { - name: endName, - longitude: referenceWarehouse.address ? 102.715 + (Math.random() - 0.5) * 0.1 : 102.715, - latitude: referenceWarehouse.address ? 25.045 + (Math.random() - 0.5) * 0.1 : 25.045 - }; - // 创建订单数据 const newOrder: Omit = { startPoint: { id: warehouse.id, name: warehouse.name, - longitude: 102.715, // 临时使用固定坐标 - latitude: 25.045 // 临时使用固定坐标 + longitude: warehouse.longitude || 0, + latitude: warehouse.latitude || 0 + }, + endPoint: { + name: endName, + // 后端服务器应该根据地址名称进行地理编码 + // 这里只提供地址名称,由后端处理坐标获取 + longitude: 0, + latitude: 0 }, - endPoint, status: 'pending', goodsType, goodsWeight diff --git a/miniprogram/pages/index/index.ts b/miniprogram/pages/index/index.ts index 8564f90..dff7208 100644 --- a/miniprogram/pages/index/index.ts +++ b/miniprogram/pages/index/index.ts @@ -10,6 +10,7 @@ import { MainPageModule } from './modules/mainPageModule'; // 导入类型定义 import { IndexPageComponent } from '../../types'; +import { API_BASE_URL } from '../../services/apiService'; // 主页面组件 Component({ @@ -94,6 +95,23 @@ Component({ return `${API_BASE_URL}${avatarPath}`; }, + // 格式化时间戳(用于wxml显示) + formatTimestamp(timestamp: number): string { + if (!timestamp) { + return '未知'; + } + + const date = new Date(timestamp); + return date.toLocaleString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + }); + }, + // 处理货运人员底部弹窗关闭 onDeliveryPersonModalClose() { diff --git a/miniprogram/pages/index/index.wxml b/miniprogram/pages/index/index.wxml index 3def006..46574c7 100644 --- a/miniprogram/pages/index/index.wxml +++ b/miniprogram/pages/index/index.wxml @@ -236,11 +236,11 @@ - + {{currentDeliveryPerson.name}} - 工号:{{currentDeliveryPerson.phone}} + 角色:{{currentDeliveryPerson.role}} @@ -248,16 +248,16 @@ - 工号 - {{currentDeliveryPerson.phone}} - - - 状态 - {{deliveryService.getDeliveryPersonStatusText(currentDeliveryPerson.status)}} + 用户ID + {{currentDeliveryPerson.userId}} 当前位置 - {{currentDeliveryPerson.currentLocation.address}} + 经度:{{currentDeliveryPerson.longitude}},纬度:{{currentDeliveryPerson.latitude}} + + + 最后更新时间 + {{currentDeliveryPerson.timestamp ? formatTimestamp(currentDeliveryPerson.timestamp) : '未知'}} diff --git a/miniprogram/pages/index/modules/dataModule.ts b/miniprogram/pages/index/modules/dataModule.ts index a9dad55..4b6f0d3 100644 --- a/miniprogram/pages/index/modules/dataModule.ts +++ b/miniprogram/pages/index/modules/dataModule.ts @@ -1,5 +1,6 @@ import { UserInfo, Marker } from '../../../types'; import { avatarCache } from '../../../utils/avatarCache'; +import { API_BASE_URL } from '../../../services/apiService'; /** * 页面数据管理模块 @@ -203,19 +204,22 @@ export class DataModule { const processedPerson = { ...person }; if (person.avatarPath) { try { - // 只有在用户已签到的情况下才使用头像缓存 - const app = getApp(); - const isSignedIn = app.globalData.userInfo && app.globalData.userInfo.status === 'signed_in'; - - if (isSignedIn) { - processedPerson.avatarPath = await avatarCache.getAvatarPath(person.avatarPath); - } else { - // 未签到状态,直接使用原始路径 - processedPerson.avatarPath = person.avatarPath; + // 将相对路径转换为完整URL + let avatarUrl = person.avatarPath; + if (!avatarUrl.startsWith('http')) { + avatarUrl = `${API_BASE_URL}${avatarUrl}`; } + + // 使用头像缓存获取本地图片路径 + processedPerson.avatarPath = await avatarCache.getAvatarPath(avatarUrl); } catch (error) { console.error('处理货运人员头像缓存失败:', error); + // 如果头像缓存失败,使用默认头像 + processedPerson.avatarPath = '/images/user-avatar.png'; } + } else { + // 如果没有头像路径,使用默认头像 + processedPerson.avatarPath = '/images/user-avatar.png'; } this.pageContext.setData({ currentDeliveryPerson: processedPerson }); diff --git a/miniprogram/pages/index/modules/locationModule.ts b/miniprogram/pages/index/modules/locationModule.ts index 743dd23..543bbba 100644 --- a/miniprogram/pages/index/modules/locationModule.ts +++ b/miniprogram/pages/index/modules/locationModule.ts @@ -170,13 +170,14 @@ export class LocationModule { zIndex: 30, data: { userId: user.userId, + name: user.name || user.userName || `用户${user.userId}`, role: userRole, + avatarPath: user.avatarPath || undefined, + latitude: latitude, // 直接使用纬度字段 + longitude: longitude, // 直接使用经度字段 + timestamp: user.timestamp || lastUpdateTime, lastUpdateTime: lastUpdateTime, - currentLocation: { - address: user.address || '位置信息获取中...', - longitude: longitude, - latitude: latitude - } + status: user.status || 'online' } }; @@ -294,20 +295,20 @@ export class LocationModule { // 优先使用传入的用户数据中的头像信息 if (userData) { // 尝试使用avatarPath(相对路径) - if (userData.avatarPath) { + if (userData.avatarPath && userData.avatarPath !== 'null') { console.log(`📸 [LocationModule] 使用用户数据中的avatarPath: ${userData.avatarPath}`); const fullAvatarUrl = `${API_BASE_URL}${userData.avatarPath}`; return await avatarCache.getAvatarPath(fullAvatarUrl); } // 尝试使用avatarUrl(完整URL) - if (userData.avatarUrl) { + if (userData.avatarUrl && userData.avatarUrl !== 'null') { console.log(`📸 [LocationModule] 使用用户数据中的avatarUrl: ${userData.avatarUrl}`); return await avatarCache.getAvatarPath(userData.avatarUrl); } // 尝试使用avatar(兼容字段) - if (userData.avatar) { + if (userData.avatar && userData.avatar !== 'null') { console.log(`📸 [LocationModule] 使用用户数据中的avatar: ${userData.avatar}`); return await avatarCache.getAvatarPath(userData.avatar); } diff --git a/miniprogram/pages/index/modules/mapModule.ts b/miniprogram/pages/index/modules/mapModule.ts index 6551e65..6493c4e 100644 --- a/miniprogram/pages/index/modules/mapModule.ts +++ b/miniprogram/pages/index/modules/mapModule.ts @@ -4,6 +4,8 @@ import userService from '../../../services/userService'; import { showToast } from '../../../utils/helpers'; import { Marker } from '../../../types'; import { DataModule } from './dataModule'; +import warehouseService from '../../../services/warehouseService'; +import deliveryService from '../../../services/deliveryPersonService'; export class MapModule { private pageContext: any; @@ -152,15 +154,65 @@ export class MapModule { /** * 加载地图数据(仓库和货运人员) */ - loadMapData(): void { - // 这里会调用具体的服务来获取数据 - // 目前使用模拟数据 - const markers = this.generateInitialMarkers(); + async loadMapData(): Promise { + try { + // 调用具体的服务来获取数据 + const warehouses = await warehouseService.getWarehouses(); + const deliveryPersons = await deliveryService.getDeliveryPersons(); + + // 生成标记点 + const markers = this.generateMarkersFromData(warehouses, deliveryPersons); + + // 更新数据模块中的标记点 + this.dataModule.updateMarkers(markers); + + console.log('地图数据加载完成'); + } catch (error) { + console.error('加载地图数据失败:', error); + // 如果API调用失败,使用空标记点 + this.dataModule.updateMarkers([]); + } + } + + /** + * 从数据生成标记点 + */ + private generateMarkersFromData(warehouses: any[], deliveryPersons: any[]): Marker[] { + const markers: Marker[] = []; - // 更新数据模块中的标记点 - this.dataModule.updateMarkers(markers); + // 添加仓库标记点 + warehouses.forEach(warehouse => { + if (warehouse.longitude && warehouse.latitude) { + markers.push({ + id: warehouse.id, + latitude: warehouse.latitude, + longitude: warehouse.longitude, + title: warehouse.name, + iconPath: '/images/warehouse-marker.png', + width: 30, + height: 30, + type: 'warehouse' + }); + } + }); - console.log('地图数据加载完成'); + // 添加货运人员标记点 + deliveryPersons.forEach(person => { + if (person.longitude && person.latitude) { + markers.push({ + id: person.id, + latitude: person.latitude, + longitude: person.longitude, + title: person.name, + iconPath: '/images/delivery-marker.png', + width: 30, + height: 30, + type: 'employee' + }); + } + }); + + return markers; } /** diff --git a/miniprogram/pages/index/modules/orderModule.ts b/miniprogram/pages/index/modules/orderModule.ts index e7d01f0..758a6ad 100644 --- a/miniprogram/pages/index/modules/orderModule.ts +++ b/miniprogram/pages/index/modules/orderModule.ts @@ -1,3 +1,4 @@ +import mapService from '../../../services/mapService'; import orderService from '../../../services/orderService'; import { Order } from '../../../types'; import { showToast } from '../../../utils/helpers'; @@ -76,13 +77,8 @@ export class OrderModule { console.log(`开始规划路线: 起点=${origin}, 终点=${destination}`); - // 这里应该调用地图服务的路线规划功能 - // 目前先模拟一个简单的路线规划结果 - const routeResult = { - distance: 1500, // 1.5公里 - duration: 300, // 5分钟 - polyline: null // 路线数据 - }; + // 调用地图服务的路线规划功能 + const routeResult = await mapService.calculateRoute(origin, destination); console.log('路线规划结果:', routeResult); diff --git a/miniprogram/pages/staff/employee-dashboard.ts b/miniprogram/pages/staff/employee-dashboard.ts index e457a89..74a1cc7 100644 --- a/miniprogram/pages/staff/employee-dashboard.ts +++ b/miniprogram/pages/staff/employee-dashboard.ts @@ -1,6 +1,7 @@ // 员工界面 - 全屏工作面板 import { UserInfo } from '../../types'; import userService from '../../services/userService'; +import statisticsService from '../../services/statisticsService'; Page({ data: { @@ -81,15 +82,22 @@ Page({ /** * 加载工作统计数据 */ - loadWorkStats() { - // 模拟加载工作统计数据 - this.setData({ - workStats: { - todayOrders: 8, - completedOrders: 5, - pendingOrders: 3 - } - }); + async loadWorkStats() { + try { + // 调用API获取工作统计数据 + const workStats = await statisticsService.getWorkStats(); + this.setData({ workStats }); + } catch (error) { + console.error('加载工作统计数据失败:', error); + // 如果API调用失败,设置默认值 + this.setData({ + workStats: { + todayOrders: 0, + completedOrders: 0, + pendingOrders: 0 + } + }); + } }, /** diff --git a/miniprogram/pages/staff/order-management.ts b/miniprogram/pages/staff/order-management.ts index 0b5dc4a..af18b43 100644 --- a/miniprogram/pages/staff/order-management.ts +++ b/miniprogram/pages/staff/order-management.ts @@ -260,8 +260,10 @@ Page({ }, endPoint: { name: endName, - longitude: 102.715 + (Math.random() - 0.5) * 0.1, - latitude: 25.045 + (Math.random() - 0.5) * 0.1 + // 后端服务器应该根据地址名称进行地理编码 + // 这里只提供地址名称,由后端处理坐标获取 + longitude: 0, + latitude: 0 }, status: 'pending', goodsType, @@ -316,21 +318,17 @@ Page({ success: (res) => { if (res.confirm) { // 调用删除订单接口 - // orderService.deleteOrder(orderId).then(() => { - // this.showSuccess('订单删除成功'); - // this.refreshData(); - // }).catch(error => { - // console.error('删除订单失败:', error); - // this.showError('删除订单失败'); - // }); - - // 暂时使用模拟删除 - const orders = this.data.orders.filter(order => order.id !== orderId); - this.setData({ - orders + orderService.deleteOrder(orderId).then((result) => { + if (result.success) { + this.showSuccess('订单删除成功'); + this.refreshData(); + } else { + this.showError(result.message || '删除失败'); + } + }).catch(error => { + console.error('删除订单失败:', error); + this.showError('删除订单失败'); }); - this.filterOrders(); - this.showSuccess('订单删除成功'); } } }); @@ -426,6 +424,11 @@ Page({ }); }, + // 阻止事件冒泡 + stopPropagation(e: any) { + // 阻止事件冒泡,不执行任何操作 + }, + // 返回上一页 goBack() { wx.navigateBack(); diff --git a/miniprogram/pages/staff/order-management.wxml b/miniprogram/pages/staff/order-management.wxml index d19a8cf..1dc9a46 100644 --- a/miniprogram/pages/staff/order-management.wxml +++ b/miniprogram/pages/staff/order-management.wxml @@ -73,7 +73,7 @@ - + diff --git a/miniprogram/pages/staff/profile.ts b/miniprogram/pages/staff/profile.ts index 457d228..6bb9139 100644 --- a/miniprogram/pages/staff/profile.ts +++ b/miniprogram/pages/staff/profile.ts @@ -11,9 +11,9 @@ Page({ totalOrders: 0, // 总订单数 completedOrders: 0, // 已完成订单数 pendingOrders: 0, // 待处理订单数 - deliveryRate: 0, // 配送成功率 - averageTime: 0 // 平均配送时间 - }, + averageDeliveryTime: 0, // 平均配送时间(分钟) + timestamp: 0 // 数据时间戳 + } as any, // 系统统计数据 systemStats: { employeeCount: 0, // 员工总数 @@ -103,15 +103,9 @@ Page({ */ async getPersonalStats() { try { - // 这里应该调用个人统计API - // 暂时使用模拟数据 - return { - totalOrders: 156, - completedOrders: 142, - pendingOrders: 14, - deliveryRate: 91.0, - averageTime: 45 - }; + // 调用个人统计API + const personalStats = await statisticsService.getPersonalStats(); + return personalStats; } catch (error) { console.error('获取个人统计数据失败:', error); // 返回默认值 @@ -119,8 +113,8 @@ Page({ totalOrders: 0, completedOrders: 0, pendingOrders: 0, - deliveryRate: 0, - averageTime: 0 + averageDeliveryTime: 0, + timestamp: Date.now() }; } }, diff --git a/miniprogram/services/apiService.ts b/miniprogram/services/apiService.ts index c47696a..a003c49 100644 --- a/miniprogram/services/apiService.ts +++ b/miniprogram/services/apiService.ts @@ -451,15 +451,14 @@ async ServerLogin(code: string) { if (res.statusCode >= 200 && res.statusCode < 300) { try { const data = JSON.parse(res.data); + // 使用服务器返回的实际路径,而不是构造的路径 + const avatarUrl = data.avatarPath ? `${API_BASE_URL}${data.avatarPath}` : data.avatarUrl; resolve({ success: true, - avatarUrl: data.avatarUrl + avatarUrl: avatarUrl }); } catch (error) { - resolve({ - success: true, - avatarUrl: `${API_BASE_URL}/avatars/${employeeId}.jpg` - }); + reject(new Error(`解析响应失败: ${error}`)); } } else { reject(new Error(`上传失败: HTTP ${res.statusCode}`)); @@ -479,12 +478,13 @@ async ServerLogin(code: string) { */ async getEmployeeAvatar(employeeId: number): Promise { try { - // 尝试获取头像信息 - const response = await this.request<{ avatarUrl: string }>(`/employees/${employeeId}/avatar`); - return response.avatarUrl || `${API_BASE_URL}/avatars/${employeeId}.jpg`; + // 使用RESTful API获取头像信息,确保路径一致性 + const response = await this.request<{ avatarPath: string }>(`/employees/${employeeId}/avatar`); + // 使用服务器返回的实际路径 + return response.avatarPath ? `${API_BASE_URL}${response.avatarPath}` : '/images/user-avatar.png'; } catch (error) { - // 如果获取失败,返回默认头像URL - return `${API_BASE_URL}/avatars/${employeeId}.jpg`; + // 如果获取失败,返回默认头像 + return '/images/user-avatar.png'; } } diff --git a/miniprogram/services/locationTrackingService.ts b/miniprogram/services/locationTrackingService.ts index 3e21b13..3fc0014 100644 --- a/miniprogram/services/locationTrackingService.ts +++ b/miniprogram/services/locationTrackingService.ts @@ -1,5 +1,5 @@ // 位置追踪服务 - 处理用户签到后的位置追踪和状态管理 -import { LocationData } from '../types'; +// import { LocationData } from '../types'; // 已弃用,服务器不再使用嵌套对象 import apiService from './apiService'; import userService from './userService'; import mapService from './mapService'; @@ -14,7 +14,9 @@ export interface OnlineUserInfo { name: string; avatarPath?: string; // 头像相对路径(服务器下发) role: string; - lastLocation: LocationData; + latitude: number; // 纬度(直接字段,不再使用嵌套对象) + longitude: number; // 经度(直接字段,不再使用嵌套对象) + timestamp: number; // 时间戳(直接字段,不再使用嵌套对象) lastUpdateTime: number; status: 'online' | 'offline'| 'timeout'; } @@ -220,7 +222,7 @@ class LocationTrackingService { /** * 获取当前位置 */ - public async getCurrentLocation(): Promise { + public async getCurrentLocation(): Promise<{ longitude: number; latitude: number; timestamp: number }> { const userInfo = userService.getGlobalUserInfo(); if (!userInfo || !userInfo.id) { throw new Error('用户未登录'); @@ -233,7 +235,6 @@ class LocationTrackingService { console.log('[位置追踪服务] 获取真实位置成功:', location); return { - userId: userInfo.id, longitude: location.longitude, latitude: location.latitude, timestamp: Date.now() @@ -243,7 +244,6 @@ class LocationTrackingService { // 定位失败时返回默认位置作为降级方案 return { - userId: userInfo.id, longitude: 102.833722, latitude: 24.880095, timestamp: Date.now() @@ -417,22 +417,24 @@ class LocationTrackingService { // 处理在线用户列表消息(服务器发送当前在线用户列表) 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) => ({ + // 转换用户数据格式,确保与位置追踪服务兼容 + const formattedUsers = 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, - avatarPath: user.avatarPath, - address: user.address - })) - }); - }else { + latitude: user.latitude, // 直接使用latitude字段 + longitude: user.longitude, // 直接使用longitude字段 + timestamp: user.timestamp, // 直接使用timestamp字段 + avatarPath: user.avatarPath || undefined, // 确保null转换为undefined + })); + + console.log('📊 转换后的在线用户数据:', formattedUsers); + + // 关键修复:调用handleOnlineUserList方法填充onlineUsers Map + this.handleOnlineUserList(formattedUsers); + } else { console.warn('❌ onlineUserList消息格式错误,users字段不存在或不是数组'); } break; @@ -444,32 +446,29 @@ class LocationTrackingService { if (message.users && Array.isArray(message.users)) { // 转换用户数据格式,确保与位置追踪服务兼容 const formattedUsers = message.users.map((user: any) => { - // 支持多种数据格式:locationData字段或直接字段 - const locationData = user.locationData || user; - // 验证必需字段是否存在 - if (!user.userId && !locationData.userId) { + if (!user.userId) { console.error('❌ 用户数据缺少userId字段:', user); return null; } - if (locationData.latitude === undefined || locationData.longitude === undefined) { + if (user.latitude === undefined || user.longitude === undefined) { console.error('❌ 用户数据缺少位置信息:', user); return null; } // 对于位置更新消息,允许缺少name和role字段,从本地缓存中获取 - const existingUser = this.onlineUsers.get(user.userId || locationData.userId); + const existingUser = this.onlineUsers.get(user.userId); const formattedUser = { - userId: user.userId || locationData.userId, - name: user.name || user.userName || (existingUser ? existingUser.name : `用户${user.userId || locationData.userId}`), + userId: user.userId, + name: user.name || user.userName || (existingUser ? existingUser.name : `用户${user.userId}`), role: user.role || (existingUser ? existingUser.role : 'DRIVER'), userStatus: user.userStatus !== false, // 转换为布尔值 - lastUpdateTime: user.lastUpdateTime || locationData.timestamp || Date.now(), - latitude: locationData.latitude, - longitude: locationData.longitude, - timestamp: locationData.timestamp || user.timestamp || Date.now(), + lastUpdateTime: user.lastUpdateTime || user.timestamp || Date.now(), + latitude: user.latitude, + longitude: user.longitude, + timestamp: user.timestamp || Date.now(), avatarPath: user.avatarPath || (existingUser ? existingUser.avatarPath : undefined), }; @@ -478,16 +477,16 @@ class LocationTrackingService { console.error('❌ 用户数据缺少userId字段:', formattedUser); return null; } - + if (formattedUser.latitude === undefined || formattedUser.longitude === undefined) { + console.error('❌ 用户数据缺少位置信息:', formattedUser); + return null; + } + return formattedUser; }).filter((user: any) => user !== null); // 过滤掉无效数据 console.log('📊 转换后的用户位置数据:', formattedUsers); - - this.triggerOnlineUserListCallbacks({ - type: 'userLocationList', - users: formattedUsers - }); + this.handleOnlineUserList(formattedUsers); } else { console.warn('❌ userLocationList消息格式错误,users字段不存在或不是数组'); } @@ -498,26 +497,6 @@ class LocationTrackingService { } } - /** - * 触发在线用户列表回调函数 - * @param userList 在线用户列表数据 - */ - private triggerOnlineUserListCallbacks(userList: any): void { - console.log('🔔 [apiService] 开始触发在线用户列表回调,消息类型:', userList.type); - console.log('📊 [apiService] 回调数据内容:', JSON.stringify(userList, null, 2)); - - - try { - console.log('🔄 [apiService] 执行在线用户列表回调函数'); - // 传递正确的数据格式:只传递users数组,而不是整个消息对象 - this.handleOnlineUserList(userList.users); - console.log('✅ [apiService] 在线用户列表回调函数执行成功'); - } catch (error) { - console.error('❌ [apiService] 在线用户列表回调函数执行失败:', error); - } - console.log('🏁 [apiService] 在线用户列表回调触发完成'); - } - /** * 处理在线用户列表 * @param userList 服务器下发的在线用户列表 @@ -542,7 +521,7 @@ class LocationTrackingService { 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(); @@ -556,19 +535,11 @@ class LocationTrackingService { name: user.name || user.userName || (existingUser ? existingUser.name : `用户${user.userId}`), avatarPath: user.avatarPath || (existingUser ? existingUser.avatarPath : undefined), role: user.role || (existingUser ? existingUser.role : 'DRIVER'), - lastLocation: { - userId: user.userId, - longitude: longitude, - latitude: latitude, - timestamp: timestamp - }, + latitude: latitude, // 直接使用纬度字段 + longitude: longitude, // 直接使用经度字段 + timestamp: timestamp, // 直接使用时间戳字段 lastUpdateTime: timestamp, status: user.userStatus === false ? 'offline' : 'online', - // currentLocation: { - // address: user.address || (existingUser ? existingUser.currentLocation?.address : '位置信息获取中...'), - // longitude: longitude, - // latitude: latitude - // } }); console.log(`[LocationTrackingService] 更新用户 ${user.userId} 位置: (${latitude}, ${longitude})`); diff --git a/miniprogram/services/mapService.ts b/miniprogram/services/mapService.ts index 5d8ec0c..89f0c0f 100644 --- a/miniprogram/services/mapService.ts +++ b/miniprogram/services/mapService.ts @@ -260,6 +260,16 @@ class MapService { return R * c; } + /** + * 计算路线(calculateRoute的别名方法) + * @param origin 起点坐标字符串 (经度,纬度) + * @param destination 终点坐标字符串 (经度,纬度) + * @returns 路线规划结果 + */ + async calculateRoute(origin: string, destination: string): Promise { + return this.getDrivingRoute(origin, destination); + } + /** * 获取路线规划(通用版本) * @param origin 起点坐标 diff --git a/miniprogram/services/statisticsService.ts b/miniprogram/services/statisticsService.ts index ac28580..54569e7 100644 --- a/miniprogram/services/statisticsService.ts +++ b/miniprogram/services/statisticsService.ts @@ -14,6 +14,27 @@ export interface StatisticsData { timestamp: number; // 数据时间戳 } +/** + * 工作统计数据接口 + */ +export interface WorkStats { + todayOrders: number; // 今日订单数 + completedOrders: number; // 已完成订单数 + pendingOrders: number; // 待处理订单数 + timestamp: number; // 数据时间戳 +} + +/** + * 个人统计数据接口 + */ +export interface PersonalStats { + totalOrders: number; // 总订单数 + completedOrders: number; // 已完成订单数 + pendingOrders: number; // 待处理订单数 + averageDeliveryTime: number; // 平均配送时间(分钟) + timestamp: number; // 数据时间戳 +} + /** * 统计服务类 * 提供系统统计数据的获取和缓存功能 @@ -25,6 +46,13 @@ class StatisticsService { // 缓存超时时间(5分钟) private readonly cacheTimeout = 5 * 60 * 1000; + /** + * 构造函数 + */ + constructor() { + // 不需要初始化HTTP客户端,直接使用apiService + } + /** * 获取系统统计数据 * 采用一个API请求获取三个统计数据,后续操作客户端自行统计 @@ -101,6 +129,64 @@ class StatisticsService { } } + /** + * 获取工作统计数据 + */ + async getWorkStats(): Promise { + try { + // 使用apiService的getOrderStats方法获取今日订单统计 + const response = await apiService.getOrderStats('today'); + + // 转换API响应格式为WorkStats格式 + return { + todayOrders: response.totalOrders || 0, + completedOrders: response.completedOrders || 0, + pendingOrders: response.inProgressOrders || 0, + timestamp: Date.now() + }; + } catch (error) { + console.error('获取工作统计数据失败:', error); + // 如果API调用失败,返回默认值 + return { + todayOrders: 0, + completedOrders: 0, + pendingOrders: 0, + timestamp: Date.now() + }; + } + } + + /** + * 获取个人统计数据 + * 由于API中没有直接的个人统计接口,这里返回默认值 + * 实际应用中应该从订单服务中获取当前用户的订单统计 + */ + async getPersonalStats(): Promise { + try { + // 在实际应用中,这里应该调用订单服务获取当前用户的订单统计 + // 由于API限制,暂时返回默认值 + console.warn('个人统计API不可用,返回默认值'); + + return { + totalOrders: 0, + completedOrders: 0, + pendingOrders: 0, + averageDeliveryTime: 0, + timestamp: Date.now() + }; + } catch (error) { + console.error('获取个人统计数据失败:', error); + // 如果API调用失败,返回默认值 + return { + totalOrders: 0, + completedOrders: 0, + pendingOrders: 0, + averageDeliveryTime: 0, + timestamp: Date.now() + }; + } + } + /** * 手动刷新统计数据(清除缓存) */ diff --git a/miniprogram/types/index.ts b/miniprogram/types/index.ts index d026593..40b9e44 100644 --- a/miniprogram/types/index.ts +++ b/miniprogram/types/index.ts @@ -113,19 +113,20 @@ export interface Order { deliveryPersonId?: number; // 货运人员ID } -// 货运人员接口 -export interface DeliveryPerson { - id: number; - name: string; - phone: string; +// 货运人员接口(扩展自员工信息,包含员工管理中的字段) +export interface DeliveryPerson extends Omit { status: 'idle' | 'busy' | 'offline'; currentLocation: { // 当前位置 longitude: number; latitude: number; }; currentOrders: Order[]; // 当前订单列表 - avatarPath?: string; // 头像相对路径(服务器返回的路径,如 "/avatars/1.jpg") - avatarThumbnail?: string; // 头像缩略图URL + // 以下字段已从EmployeeInfo继承: + // id: number; // 员工ID + // name: string; // 员工姓名 + // phone: string; // 员工电话 + // avatarPath?: string; // 头像相对路径 + // avatarThumbnail?: string; // 头像缩略图URL } // 路径规划结果接口 @@ -135,13 +136,13 @@ export interface RoutePlanResult { duration: number; // 预计时间(秒) } -// 实时位置数据接口 -export interface LocationData { - userId: number; // 用户ID - longitude: number; // 经度 - latitude: number; // 纬度 - timestamp: number; // 时间戳 -} +// 实时位置数据接口(已弃用,服务器不再使用嵌套对象) +// export interface LocationData { +// userId: number; // 用户ID +// longitude: number; // 经度 +// latitude: number; // 纬度 +// timestamp: number; // 时间戳 +// } // 高德地图逆地理编码响应接口 export interface AMapRegeoResponse { diff --git a/miniprogram/utils/avatarCache.ts b/miniprogram/utils/avatarCache.ts index 948048f..937d52b 100644 --- a/miniprogram/utils/avatarCache.ts +++ b/miniprogram/utils/avatarCache.ts @@ -23,7 +23,8 @@ class AvatarCache { * @returns 本地图片路径或Promise */ public async getAvatarPath(avatarUrl: string): Promise { - if (!avatarUrl) { + if (!avatarUrl || avatarUrl === 'null' || avatarUrl.includes('null')) { + console.warn('❌ [AvatarCache] 无效的头像URL:', avatarUrl); return this.getDefaultAvatarPath(); }