// 管理员页面逻辑 import { UserInfo, Marker, Order, DeliveryPerson, WarehouseInfo } from '../../types'; import mapService from '../../services/mapService'; import warehouseService from '../../services/warehouseService'; import orderService from '../../services/orderService'; import deliveryService from '../../services/deliveryPersonService'; Page({ data: { userInfo: null as UserInfo | null, mapCenter: mapService.getKunmingCenter(), markers: [] as Marker[], polyline: {} as any, // 订单相关 orders: [] as Order[], filteredOrders: [] as Order[], activeTab: 'all', showAssignModal: false, selectedOrderId: 0, showAddModal: false, // 新增订单表单数据 warehouseIndex: 0, warehouses: [] as WarehouseInfo[], endName: '', goodsType: '', goodsWeight: 0, // 员工相关 deliveryPersons: [] as DeliveryPerson[], availableStaff: [] as DeliveryPerson[], // 底部页签 currentTab: 'main' }, onLoad() { // 模拟管理员登录状态 this.setData({ userInfo: { id: 1, name: '管理员', role: 'ADMIN' as any, phone: '13800138000' } }); // 初始化数据 this.initData(); }, onShow() { // 页面显示时刷新数据 this.refreshData(); }, // 初始化数据 initData() { // 获取仓库数据 warehouseService.getWarehouses().then(warehouses => { this.setData({ warehouses }); }).catch(error => { console.error('获取仓库数据失败:', error); }); // 刷新数据 this.refreshData(); }, // 刷新数据 refreshData() { // 获取订单数据 - 使用正确的getPendingOrders方法 orderService.getPendingOrders().then(orders => { // 获取员工数据 - 使用正确的getDeliveryPersons方法 deliveryService.getDeliveryPersons().then(deliveryPersons => { // 更新地图标记点 const markers = this.generateMarkers(orders, deliveryPersons); this.setData({ orders, deliveryPersons, markers }); // 过滤订单 this.filterOrders(); }).catch(error => { console.error('获取货运人员数据失败:', error); }); }).catch(error => { console.error('获取订单数据失败:', error); }); }, // 生成地图标记点 generateMarkers(orders: Order[], deliveryPersons: DeliveryPerson[]): Marker[] { const markers: Marker[] = []; // 添加订单起点标记(仓库) const warehouseMarkers = new Map(); orders.forEach(order => { if (!warehouseMarkers.has(order.startPoint.id)) { warehouseMarkers.set(order.startPoint.id, { id: order.startPoint.id, longitude: order.startPoint.longitude, latitude: order.startPoint.latitude, title: order.startPoint.name, iconPath: '/images/warehouse.png', width: 32, height: 32, zIndex: 10, callout: { content: order.startPoint.name, color: '#333', fontSize: 24, borderRadius: 10, bgColor: '#fff', padding: 10, display: 'BYCLICK' } }); } }); // 添加订单终点标记 orders.forEach((order) => { markers.push({ id: 10000 + order.id, // 避免ID冲突 longitude: order.endPoint.longitude, latitude: order.endPoint.latitude, title: order.endPoint.name, iconPath: this.getOrderStatusIcon(order.status), width: 32, height: 32, zIndex: 20, callout: { content: `${order.endPoint.name}\n${order.goodsType} ${order.goodsWeight}kg`, color: '#333', fontSize: 24, borderRadius: 10, bgColor: '#fff', padding: 10, display: 'BYCLICK' } }); }); // 添加员工位置标记 deliveryPersons.forEach(person => { // 使用默认坐标,实际位置由locationTrackingService统一管理 markers.push({ id: 20000 + person.id, // 避免ID冲突 longitude: 102.833722, // 默认经度 latitude: 24.880095, // 默认纬度 title: person.name, iconPath: this.getStaffStatusIcon(person.status), width: 32, height: 32, zIndex: 30, callout: { content: `${person.name}\n订单数: ${person.currentOrders.length}\n状态: ${this.getStatusText(person.status)}`, color: '#333', fontSize: 24, borderRadius: 10, bgColor: '#fff', padding: 10, display: 'BYCLICK' } }); }); // 添加仓库标记 markers.push(...Array.from(warehouseMarkers.values())); return markers; }, // 获取订单状态对应的图标 getOrderStatusIcon(status: string): string { switch (status) { case 'pending': return '/images/order-pending.png'; case 'assigned': return '/images/order-assigned.png'; case 'in_transit': return '/images/order-transit.png'; case 'delivered': return '/images/order-delivered.png'; default: return '/images/order-pending.png'; } }, // 获取员工状态对应的图标 getStaffStatusIcon(_status: string): string { // 统一使用trucks.png作为货运人员图标 return '/images/trucks.png'; }, // 获取状态文本 getStatusText(status: string): string { const statusMap: Record = { 'pending': '未分配', 'assigned': '已分配', 'in_transit': '配送中', 'delivered': '已完成', 'idle': '空闲', 'busy': '忙碌', 'offline': '离线' }; return statusMap[status] || status; }, // 过滤订单 filterOrders() { const { orders, activeTab } = this.data; let filteredOrders = orders; if (activeTab !== 'all') { filteredOrders = orders.filter(order => order.status === activeTab); } this.setData({ filteredOrders }); }, // 切换订单标签 switchTab(e: any) { const tab = e.currentTarget.dataset.tab; this.setData({ activeTab: tab }); this.filterOrders(); }, // 处理订单点击 handleOrderTap(e: any) { const orderId = e.currentTarget.dataset.id; const order = this.data.orders.find(o => o.id === orderId); if (!order) return; if (order.status === 'pending') { // 未分配的订单,显示分配弹窗 const availableStaff = this.data.deliveryPersons.filter(person => person.status === 'idle'); this.setData({ showAssignModal: true, selectedOrderId: orderId, availableStaff }); } else if (order.status === 'assigned' || order.status === 'in_transit') { // 已分配的订单,跳转到地图并聚焦到配送员 const assignedPerson = this.data.deliveryPersons.find(person => person.currentOrders.some(o => o.id === orderId) ); if (assignedPerson) { this.setData({ mapCenter: { longitude: 102.833722, latitude: 24.880095 } // 默认坐标 }); // 绘制从起点到终点的路线 this.drawRoute(order.startPoint.longitude, order.startPoint.latitude, order.endPoint.longitude, order.endPoint.latitude); } } }, // 处理员工点击 handleStaffTap(e: any) { const staffId = e.currentTarget.dataset.id; const staff = this.data.deliveryPersons.find(p => p.id === staffId); if (staff) { // 跳转到地图并聚焦到员工位置 this.setData({ mapCenter: staff.currentLocation }); } }, // 绘制路线 drawRoute(startLng: number, startLat: number, endLng: number, endLat: number) { const origin = `${startLng},${startLat}`; const destination = `${endLng},${endLat}`; mapService.getDrivingRoute(origin, destination).then(result => { if (result.polyline) { // 解码polyline const points = this.decodePolyline(result.polyline); if (points.length > 0) { this.setData({ polyline: { points, color: '#0091ff', width: 8, dottedLine: false } }); } } }).catch(err => { console.error('绘制路线失败:', err); }); }, // 解码polyline decodePolyline(polyline: string): Array<{ longitude: number; latitude: number }> { const points: Array<{ longitude: number; latitude: number }> = []; let index = 0, len = polyline.length; let lat = 0, lng = 0; while (index < len) { let b, shift = 0, result = 0; do { b = polyline.charCodeAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); const dlat = ((result & 1) !== 0 ? ~(result >> 1) : (result >> 1)); lat += dlat; shift = 0; result = 0; do { b = polyline.charCodeAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); const dlng = ((result & 1) !== 0 ? ~(result >> 1) : (result >> 1)); lng += dlng; points.push({ longitude: lng / 100000, latitude: lat / 100000 }); } return points; }, // 显示分配弹窗 showAssignModal() { this.setData({ showAssignModal: true }); }, // 隐藏分配弹窗 hideAssignModal() { this.setData({ showAssignModal: false }); }, // 分配订单 assignOrder(e: any) { const staffId = e.currentTarget.dataset.id; const { selectedOrderId } = this.data; if (!selectedOrderId || !staffId) { wx.showToast({ title: '请选择订单和货运人员', icon: 'none' }); return; } // 修复:使用正确的orderService.assignOrder方法 orderService.assignOrder(selectedOrderId, staffId).then(result => { if (result.success) { wx.showToast({ title: '指派成功', icon: 'success' }); // 刷新数据 this.refreshData(); } else { wx.showToast({ title: result.message || '指派失败', icon: 'none' }); } }).catch(error => { console.error('指派订单失败:', error); wx.showToast({ title: '指派失败,请重试', icon: 'none' }); }); this.hideAssignModal(); }, // 显示新增订单弹窗 showAddOrderModal() { this.setData({ showAddModal: true, endName: '', goodsType: '', goodsWeight: 0, warehouseIndex: 0 }); }, // 隐藏新增订单弹窗 hideAddModal() { this.setData({ showAddModal: false }); }, // 仓库选择变化 onWarehouseChange(e: any) { this.setData({ warehouseIndex: e.detail.value }); }, // 终点名称输入 onEndNameInput(e: any) { this.setData({ endName: e.detail.value }); }, // 货物类型输入 onGoodsTypeInput(e: any) { this.setData({ goodsType: e.detail.value }); }, // 货物重量输入 onGoodsWeightInput(e: any) { this.setData({ goodsWeight: parseFloat(e.detail.value) || 0 }); }, // 创建订单 createOrder() { const { warehouses, warehouseIndex, endName, goodsType, goodsWeight } = this.data; // 表单验证 if (!warehouses[warehouseIndex]) { wx.showToast({ title: '请选择仓库', icon: 'none' }); return; } if (!endName) { wx.showToast({ title: '请输入终点名称', icon: 'none' }); return; } if (!goodsType) { wx.showToast({ title: '请输入货物类型', icon: 'none' }); return; } if (goodsWeight <= 0) { wx.showToast({ title: '请输入有效的货物重量', icon: 'none' }); return; } // 获取仓库信息 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 // 临时使用固定坐标 }, endPoint, status: 'pending', goodsType, goodsWeight }; // 调用服务创建订单 - 使用正确的orderService.createOrder方法 orderService.createOrder(newOrder).then(() => { wx.showToast({ title: '创建成功', icon: 'success' }); // 刷新数据 this.refreshData(); }).catch(error => { console.error('创建订单失败:', error); wx.showToast({ title: '创建失败', icon: 'error' }); }); this.hideAddModal(); }, // 底部页签切换 switchMainTab(e: any) { const tab = e.currentTarget.dataset.tab; this.setData({ currentTab: tab }); }, // 跳转到员工管理页面 goToEmployeeManagement() { wx.navigateTo({ url: '/pages/employee/employee' }); }, // 地图点击事件 onMapTap() { // 清除路线 this.setData({ polyline: {} }); }, // 格式化时间 formatTime(time: number): string { const date = new Date(time); const now = new Date(); const diff = now.getTime() - date.getTime(); if (diff < 60000) { return '刚刚'; } else if (diff < 3600000) { return `${Math.floor(diff / 60000)}分钟前`; } else if (diff < 86400000) { return `${Math.floor(diff / 3600000)}小时前`; } else { const month = date.getMonth() + 1; const day = date.getDate(); const hour = date.getHours(); const minute = date.getMinutes(); return `${month}月${day}日 ${hour}:${minute < 10 ? '0' + minute : minute}`; } } });