14 KiB
14 KiB
骑手订单分配系统 - 测试与发布指南
📋 概述
本指南详细说明如何测试和发布订单到骑手端,包括完整的操作流程、API接口使用方法和故障排除指南。
🚀 快速开始
1. 运行测试脚本
# 完整测试流程
php test_order_dispatch.php
# 或者通过Web访问
http://your-domain.com/test_order_dispatch.php
2. 查看系统状态
# 查看骑手和订单状态
php test_order_dispatch.php status
# 或者Web访问
http://your-domain.com/test_order_dispatch.php?action=status
📊 系统架构
核心组件
-
订单分配引擎 (
RiderOrderDispatch.class.php)- 自动分配算法
- 骑手评分计算
- 距离和时间优化
-
骑手端API (
RiderApi\Controller\OrderController.class.php)- 获取可接订单
- 接受/拒绝订单
- 订单状态更新
-
订单管理 (
RiderOrderController.class.php)- 订单列表查询
- 状态流转控制
- 配送流程管理
🔄 完整测试流程
步骤1:创建测试订单
// 使用测试脚本创建订单
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:订单分配
自动分配
$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
]);
手动分配
$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:骑手接单
获取可接订单
// API: /RiderApi/Order/getAvailableOrders
$orders = $riderController->getAvailableOrders([
'rider_id' => 3,
'page' => 1,
'limit' => 10
]);
接受订单
// API: /RiderApi/Order/acceptOrder
$result = $riderController->acceptOrder([
'rider_id' => 3,
'order_id' => $orderId
]);
步骤4:配送流程
订单状态流转
0 - 待分配 → 1 - 已接单 → 2 - 已取餐 → 3 - 配送中 → 4 - 已送达
更新订单状态
// 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:正常订单流程测试
- 创建订单 → 2. 自动分配 → 3. 骑手接单 → 4. 配送完成
# 运行完整测试
php test_order_dispatch.php full
场景2:手动分配测试
// 指定骑手分配
$dispatch = new \Common\Business\RiderOrderDispatch();
$result = $dispatch->dispatchOrder([
'bill_id' => 'TEST_20240115001',
'rider_id' => 3,
'auto_assign' => false
]);
场景3:高峰期压力测试
// 批量创建订单测试
for ($i = 0; $i < 10; $i++) {
$test = new OrderDispatchTest();
$orderId = $test->createTestOrder();
$test->testOrderDispatch($orderId);
}
场景4:异常情况测试
- 无可用骑手
- 骑手拒绝订单
- 网络异常
- 位置信息缺失
📱 骑手端集成
移动端接入
1. 初始化配置
// 骑手端配置
const riderConfig = {
apiBaseUrl: 'http://your-domain.com/RiderApi',
riderId: 3,
autoRefresh: true,
refreshInterval: 30000 // 30秒
};
2. 获取订单列表
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. 接受订单
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. 更新位置和状态
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;
}
🔧 配置说明
骑手配置参数
-- 骑手信息表关键字段
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 '工作结束时间';
系统配置参数
// 配置文件 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) - 确认骑手位置信息完整
- 验证门店和订单位置信息
- 检查骑手当前订单数量是否达到上限
-- 检查骑手状态
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. 骑手无法接单
问题: 骑手端显示无可接订单 解决方案:
- 确认骑手认证状态
- 检查工作时间设置
- 验证接单偏好配置
- 确认网络连接正常
// 调试骑手接单条件
$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)
- 验证坐标范围合理性
// 验证坐标有效性
function validateCoordinates($lat, $lng) {
return ($lat >= -90 && $lat <= 90) && ($lng >= -180 && $lng <= 180);
}
4. 订单状态同步问题
问题: 订单状态更新不及时或不一致 解决方案:
- 检查数据库连接
- 确认事务处理正确
- 验证缓存更新机制
- 检查并发处理逻辑
调试工具
1. 日志查看
# 查看系统日志
tail -f Runtime/Logs/Common/24_01_15.log
# 查看错误日志
tail -f Runtime/Logs/Common/24_01_15_error.log
2. 数据库调试
-- 开启SQL日志
SET GLOBAL general_log = 'ON';
SET GLOBAL general_log_file = '/var/log/mysql/mysql.log';
-- 查看慢查询
SHOW PROCESSLIST;
3. 性能监控
// 添加性能监控
$startTime = microtime(true);
// ... 业务逻辑 ...
$endTime = microtime(true);
$executionTime = ($endTime - $startTime) * 1000;
error_log("执行时间: {$executionTime}ms");
📈 性能优化
数据库优化
1. 索引优化
-- 骑手信息表索引
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. 查询优化
// 使用合适的查询条件
$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缓存
// 缓存骑手位置信息
$redis = new Redis();
$redis->setex("rider_location_{$riderId}", 300, json_encode([
'lat' => $lat,
'lng' => $lng,
'update_time' => time()
]));
2. 内存缓存
// 使用静态变量缓存计算结果
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. 监控告警
- 配置系统监控
- 设置错误告警
- 建立日志分析
- 制定应急预案
📞 技术支持
如果在使用过程中遇到问题,请按以下步骤排查:
- 查看日志文件 - 检查系统和错误日志
- 运行测试脚本 - 使用
test_order_dispatch.php验证功能 - 检查配置 - 确认数据库和系统配置正确
- 联系技术支持 - 提供详细的错误信息和日志
最后更新: 2024年1月15日
版本: v1.0.0
维护者: 骑手订单分配系统开发团队