# 骑手订单分配系统 - 测试与发布指南 ## 📋 概述 本指南详细说明如何测试和发布订单到骑手端,包括完整的操作流程、API接口使用方法和故障排除指南。 ## 🚀 快速开始 ### 1. 运行测试脚本 ```bash # 完整测试流程 php test_order_dispatch.php # 或者通过Web访问 http://your-domain.com/test_order_dispatch.php ``` ### 2. 查看系统状态 ```bash # 查看骑手和订单状态 php test_order_dispatch.php status # 或者Web访问 http://your-domain.com/test_order_dispatch.php?action=status ``` ## 📊 系统架构 ### 核心组件 1. **订单分配引擎** (`RiderOrderDispatch.class.php`) - 自动分配算法 - 骑手评分计算 - 距离和时间优化 2. **骑手端API** (`RiderApi\Controller\OrderController.class.php`) - 获取可接订单 - 接受/拒绝订单 - 订单状态更新 3. **订单管理** (`RiderOrderController.class.php`) - 订单列表查询 - 状态流转控制 - 配送流程管理 ## 🔄 完整测试流程 ### 步骤1:创建测试订单 ```php // 使用测试脚本创建订单 php test_order_dispatch.php create // 或者手动创建 $orderData = [ 'bill_id' => 'TEST_' . date('YmdHis') . rand(1000, 9999), 'order_no' => 'RO' . date('YmdHis') . rand(1000, 9999), 'merchant_id' => 1, 'store_id' => 1, 'customer_name' => '测试客户', 'customer_phone' => '13800138000', 'delivery_address' => '测试地址', 'delivery_lat' => 39.9042, 'delivery_lng' => 116.4074, 'order_amount' => 58.50, 'delivery_fee' => 8.00, 'total_amount' => 66.50, 'order_type' => 1, 'order_status' => 0, // 待分配 'add_time' => date('Y-m-d H:i:s') ]; ``` ### 步骤2:订单分配 #### 自动分配 ```php $dispatch = new \Common\Business\RiderOrderDispatch(); $result = $dispatch->dispatchOrder([ 'bill_id' => $orderData['bill_id'], 'merchant_id' => $orderData['merchant_id'], 'store_id' => $orderData['store_id'], 'auto_assign' => true ]); ``` #### 手动分配 ```php $result = $dispatch->dispatchOrder([ 'bill_id' => $orderData['bill_id'], 'merchant_id' => $orderData['merchant_id'], 'store_id' => $orderData['store_id'], 'rider_id' => 3, // 指定骑手ID 'auto_assign' => false ]); ``` ### 步骤3:骑手接单 #### 获取可接订单 ```php // API: /RiderApi/Order/getAvailableOrders $orders = $riderController->getAvailableOrders([ 'rider_id' => 3, 'page' => 1, 'limit' => 10 ]); ``` #### 接受订单 ```php // API: /RiderApi/Order/acceptOrder $result = $riderController->acceptOrder([ 'rider_id' => 3, 'order_id' => $orderId ]); ``` ### 步骤4:配送流程 #### 订单状态流转 ``` 0 - 待分配 → 1 - 已接单 → 2 - 已取餐 → 3 - 配送中 → 4 - 已送达 ``` #### 更新订单状态 ```php // API: /RiderApi/Order/updateOrderStatus $result = $riderController->updateOrderStatus([ 'rider_id' => 3, 'order_id' => $orderId, 'status' => 2, // 已取餐 'lat' => 39.9042, 'lng' => 116.4074 ]); ``` ## 🔌 API接口详解 ### 骑手端核心API #### 1. 获取可接订单列表 ``` GET /RiderApi/Order/getAvailableOrders 参数: - rider_id: 骑手ID - page: 页码 (默认1) - limit: 每页数量 (默认10) 返回: { "status": 1, "msg": "获取成功", "data": { "list": [...], "total": 5, "page": 1, "limit": 10 } } ``` #### 2. 接受订单 ``` POST /RiderApi/Order/acceptOrder 参数: - rider_id: 骑手ID - order_id: 订单ID 返回: { "status": 1, "msg": "接单成功", "data": { "order_id": 123, "accept_time": "2024-01-15 14:30:00" } } ``` #### 3. 更新订单状态 ``` POST /RiderApi/Order/updateOrderStatus 参数: - rider_id: 骑手ID - order_id: 订单ID - status: 新状态 (1-4) - lat: 当前纬度 (可选) - lng: 当前经度 (可选) 返回: { "status": 1, "msg": "状态更新成功", "data": { "order_id": 123, "new_status": 2, "update_time": "2024-01-15 14:35:00" } } ``` #### 4. 获取当前订单 ``` GET /RiderApi/Order/getCurrentOrder 参数: - rider_id: 骑手ID 返回: { "status": 1, "msg": "获取成功", "data": { "order_id": 123, "order_no": "RO20240115001", "status": 2, "customer_info": {...}, "delivery_info": {...} } } ``` ### 管理端API #### 1. 订单分配 ``` POST /Admin/RiderOrder/dispatchOrder 参数: - bill_id: 订单编号 - merchant_id: 商户ID - store_id: 门店ID - rider_id: 骑手ID (可选,用于手动分配) - auto_assign: 是否自动分配 (true/false) 返回: { "status": 1, "msg": "分配成功", "data": { "order_id": 123, "rider_id": 3, "rider_name": "张三", "assign_time": "2024-01-15 14:25:00" } } ``` #### 2. 获取可用骑手 ``` POST /Admin/RiderOrder/getAvailableRiders 参数: - merchant_id: 商户ID - store_id: 门店ID - order_lat: 订单纬度 - order_lng: 订单经度 返回: { "status": 1, "msg": "获取成功", "data": [ { "id": 3, "rider_name": "张三", "phone": "13800138000", "distance": 1.2, "score": 85.5, "current_orders": 1, "max_orders": 3 } ] } ``` ## 🧪 测试场景 ### 场景1:正常订单流程测试 1. **创建订单** → 2. **自动分配** → 3. **骑手接单** → 4. **配送完成** ```bash # 运行完整测试 php test_order_dispatch.php full ``` ### 场景2:手动分配测试 ```php // 指定骑手分配 $dispatch = new \Common\Business\RiderOrderDispatch(); $result = $dispatch->dispatchOrder([ 'bill_id' => 'TEST_20240115001', 'rider_id' => 3, 'auto_assign' => false ]); ``` ### 场景3:高峰期压力测试 ```php // 批量创建订单测试 for ($i = 0; $i < 10; $i++) { $test = new OrderDispatchTest(); $orderId = $test->createTestOrder(); $test->testOrderDispatch($orderId); } ``` ### 场景4:异常情况测试 - 无可用骑手 - 骑手拒绝订单 - 网络异常 - 位置信息缺失 ## 📱 骑手端集成 ### 移动端接入 #### 1. 初始化配置 ```javascript // 骑手端配置 const riderConfig = { apiBaseUrl: 'http://your-domain.com/RiderApi', riderId: 3, autoRefresh: true, refreshInterval: 30000 // 30秒 }; ``` #### 2. 获取订单列表 ```javascript async function getAvailableOrders() { const response = await fetch(`${riderConfig.apiBaseUrl}/Order/getAvailableOrders`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ rider_id: riderConfig.riderId, page: 1, limit: 10 }) }); const result = await response.json(); return result; } ``` #### 3. 接受订单 ```javascript async function acceptOrder(orderId) { const response = await fetch(`${riderConfig.apiBaseUrl}/Order/acceptOrder`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ rider_id: riderConfig.riderId, order_id: orderId }) }); const result = await response.json(); return result; } ``` #### 4. 更新位置和状态 ```javascript async function updateOrderStatus(orderId, status, location) { const response = await fetch(`${riderConfig.apiBaseUrl}/Order/updateOrderStatus`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ rider_id: riderConfig.riderId, order_id: orderId, status: status, lat: location.lat, lng: location.lng }) }); const result = await response.json(); return result; } ``` ## 🔧 配置说明 ### 骑手配置参数 ```sql -- 骑手信息表关键字段 ALTER TABLE ls_rider_info ADD COLUMN max_orders_per_time INT DEFAULT 3 COMMENT '同时接单上限'; ALTER TABLE ls_rider_info ADD COLUMN auto_accept_orders TINYINT DEFAULT 0 COMMENT '是否自动接单'; ALTER TABLE ls_rider_info ADD COLUMN min_delivery_fee DECIMAL(10,2) DEFAULT 0 COMMENT '最低配送费'; ALTER TABLE ls_rider_info ADD COLUMN max_delivery_distance DECIMAL(10,2) DEFAULT 10 COMMENT '最大配送距离(km)'; ALTER TABLE ls_rider_info ADD COLUMN work_start_time TIME DEFAULT '08:00:00' COMMENT '工作开始时间'; ALTER TABLE ls_rider_info ADD COLUMN work_end_time TIME DEFAULT '22:00:00' COMMENT '工作结束时间'; ``` ### 系统配置参数 ```php // 配置文件 Application/Common/Conf/config.php 'RIDER_SYSTEM' => [ 'AUTO_DISPATCH_ENABLED' => true, // 启用自动分配 'MAX_DISPATCH_DISTANCE' => 10, // 最大分配距离(km) 'DISPATCH_TIMEOUT' => 300, // 分配超时时间(秒) 'RIDER_RESPONSE_TIMEOUT' => 60, // 骑手响应超时(秒) 'MAX_RETRY_COUNT' => 3, // 最大重试次数 'SCORE_WEIGHTS' => [ // 评分权重 'distance' => 0.4, // 距离权重 'rating' => 0.3, // 评分权重 'on_time_rate' => 0.2, // 准时率权重 'order_count' => 0.1 // 订单数权重 ] ] ``` ## 🚨 故障排除 ### 常见问题 #### 1. 订单分配失败 **问题**: 订单创建后无法分配给骑手 **解决方案**: - 检查骑手状态 (`work_status = 1` 且 `auth_status = 2`) - 确认骑手位置信息完整 - 验证门店和订单位置信息 - 检查骑手当前订单数量是否达到上限 ```sql -- 检查骑手状态 SELECT id, rider_name, work_status, auth_status, current_orders, max_orders_per_time FROM ls_rider_info WHERE status = 1; -- 检查订单信息 SELECT id, bill_id, order_status, delivery_lat, delivery_lng, store_lat, store_lng FROM ls_rider_order WHERE order_status = 0; ``` #### 2. 骑手无法接单 **问题**: 骑手端显示无可接订单 **解决方案**: - 确认骑手认证状态 - 检查工作时间设置 - 验证接单偏好配置 - 确认网络连接正常 ```php // 调试骑手接单条件 $riderInfo = M('rider_info')->find($riderId); var_dump([ 'work_status' => $riderInfo['work_status'], 'auth_status' => $riderInfo['auth_status'], 'current_time' => date('H:i:s'), 'work_start_time' => $riderInfo['work_start_time'], 'work_end_time' => $riderInfo['work_end_time'] ]); ``` #### 3. 位置信息异常 **问题**: 距离计算错误或位置信息缺失 **解决方案**: - 检查GPS坐标格式 (纬度在前,经度在后) - 确认坐标系统一致性 (建议使用WGS84) - 验证坐标范围合理性 ```php // 验证坐标有效性 function validateCoordinates($lat, $lng) { return ($lat >= -90 && $lat <= 90) && ($lng >= -180 && $lng <= 180); } ``` #### 4. 订单状态同步问题 **问题**: 订单状态更新不及时或不一致 **解决方案**: - 检查数据库连接 - 确认事务处理正确 - 验证缓存更新机制 - 检查并发处理逻辑 ### 调试工具 #### 1. 日志查看 ```bash # 查看系统日志 tail -f Runtime/Logs/Common/24_01_15.log # 查看错误日志 tail -f Runtime/Logs/Common/24_01_15_error.log ``` #### 2. 数据库调试 ```sql -- 开启SQL日志 SET GLOBAL general_log = 'ON'; SET GLOBAL general_log_file = '/var/log/mysql/mysql.log'; -- 查看慢查询 SHOW PROCESSLIST; ``` #### 3. 性能监控 ```php // 添加性能监控 $startTime = microtime(true); // ... 业务逻辑 ... $endTime = microtime(true); $executionTime = ($endTime - $startTime) * 1000; error_log("执行时间: {$executionTime}ms"); ``` ## 📈 性能优化 ### 数据库优化 #### 1. 索引优化 ```sql -- 骑手信息表索引 ALTER TABLE ls_rider_info ADD INDEX idx_work_status (work_status, auth_status, status); ALTER TABLE ls_rider_info ADD INDEX idx_location (lat, lng); -- 订单表索引 ALTER TABLE ls_rider_order ADD INDEX idx_status_time (order_status, add_time); ALTER TABLE ls_rider_order ADD INDEX idx_rider_status (rider_id, order_status); ALTER TABLE ls_rider_order ADD INDEX idx_location (delivery_lat, delivery_lng); ``` #### 2. 查询优化 ```php // 使用合适的查询条件 $riders = M('rider_info') ->field('id, rider_name, lat, lng, current_orders, max_orders_per_time') ->where([ 'work_status' => 1, 'auth_status' => 2, 'status' => 1, 'merchant_id' => $merchantId ]) ->limit(50) // 限制查询数量 ->select(); ``` ### 缓存策略 #### 1. Redis缓存 ```php // 缓存骑手位置信息 $redis = new Redis(); $redis->setex("rider_location_{$riderId}", 300, json_encode([ 'lat' => $lat, 'lng' => $lng, 'update_time' => time() ])); ``` #### 2. 内存缓存 ```php // 使用静态变量缓存计算结果 class RiderOrderDispatch { private static $distanceCache = []; private function calculateDistance($lat1, $lng1, $lat2, $lng2) { $key = "{$lat1},{$lng1},{$lat2},{$lng2}"; if (!isset(self::$distanceCache[$key])) { self::$distanceCache[$key] = $this->haversineDistance($lat1, $lng1, $lat2, $lng2); } return self::$distanceCache[$key]; } } ``` ## 📋 部署清单 ### 生产环境部署 #### 1. 环境检查 - [ ] PHP 版本 >= 5.6 - [ ] MySQL 版本 >= 5.7 - [ ] Redis 服务正常 - [ ] 网络连接稳定 - [ ] SSL证书配置 #### 2. 数据库准备 - [ ] 执行数据库迁移脚本 - [ ] 创建必要的索引 - [ ] 配置数据库连接池 - [ ] 设置备份策略 #### 3. 配置文件 - [ ] 更新数据库配置 - [ ] 设置Redis连接 - [ ] 配置日志级别 - [ ] 设置错误报告 #### 4. 测试验证 - [ ] 运行单元测试 - [ ] 执行集成测试 - [ ] 进行压力测试 - [ ] 验证API接口 #### 5. 监控告警 - [ ] 配置系统监控 - [ ] 设置错误告警 - [ ] 建立日志分析 - [ ] 制定应急预案 ## 📞 技术支持 如果在使用过程中遇到问题,请按以下步骤排查: 1. **查看日志文件** - 检查系统和错误日志 2. **运行测试脚本** - 使用 `test_order_dispatch.php` 验证功能 3. **检查配置** - 确认数据库和系统配置正确 4. **联系技术支持** - 提供详细的错误信息和日志 --- **最后更新**: 2024年1月15日 **版本**: v1.0.0 **维护者**: 骑手订单分配系统开发团队