14 KiB
14 KiB
骑手端订单智能分配方案
一、现状分析
1.1 现有系统架构
- 订单表结构:
ls_retail_bill_order(主订单)+ls_rider_order(配送订单) - 骑手管理:
ls_rider_info(骑手信息)+ 相关统计和收入表 - 分配方式: 主要依赖手动分配和骑手抢单,缺乏智能化分配
1.2 存在问题
- 效率低下: 手动分配耗时,影响配送时效
- 分配不均: 缺乏负载均衡,部分骑手过忙,部分闲置
- 距离优化不足: 未考虑骑手位置与商家/客户距离
- 成本控制薄弱: 没有综合考虑配送成本和收益
二、智能分配策略设计
2.1 分配模式
采用混合分配模式:
- 智能推荐 + 骑手抢单 + 手动干预
2.2 核心分配算法
2.2.1 骑手筛选条件
-- 可分配骑手筛选条件
SELECT * FROM ls_rider_info
WHERE status = 1 -- 正常状态
AND auth_status = 2 -- 已认证
AND health_status = 1 -- 健康证通过
AND work_status IN (1, 2) -- 在线或忙碌但未达上限
AND (SELECT COUNT(*) FROM ls_rider_order
WHERE rider_id = ls_rider_info.id
AND order_status IN (1,2,3,4,5)) < max_orders_per_time -- 未达最大接单数
2.2.2 距离权重计算
/**
* 计算骑手到商家的距离权重
* @param float $rider_lat 骑手纬度
* @param float $rider_lng 骑手经度
* @param float $store_lat 商家纬度
* @param float $store_lng 商家经度
* @return float 距离权重分数 (0-100)
*/
function calculateDistanceScore($rider_lat, $rider_lng, $store_lat, $store_lng) {
$distance = getDistance($rider_lat, $rider_lng, $store_lat, $store_lng);
if ($distance <= 1) return 100; // 1公里内满分
if ($distance <= 3) return 80; // 1-3公里
if ($distance <= 5) return 60; // 3-5公里
if ($distance <= 8) return 40; // 5-8公里
if ($distance <= 12) return 20; // 8-12公里
return 0; // 超过12公里不推荐
}
2.2.3 骑手能力评分
/**
* 计算骑手综合能力评分
* @param array $rider 骑手信息
* @return float 能力评分 (0-100)
*/
function calculateRiderScore($rider) {
$score = 0;
// 评分权重 (30%)
$score += ($rider['rating'] / 5) * 30;
// 准时率权重 (25%)
$score += ($rider['on_time_rate'] / 100) * 25;
// 完成订单数权重 (20%) - 经验值
$experience_score = min(($rider['completed_orders'] / 1000) * 20, 20);
$score += $experience_score;
// 当前负载权重 (15%) - 负载越低分数越高
$current_orders = getCurrentOrderCount($rider['id']);
$load_score = (1 - ($current_orders / $rider['max_orders_per_time'])) * 15;
$score += $load_score;
// 在线时长权重 (10%) - 今日在线时长
$online_hours = getTodayOnlineHours($rider['id']);
$time_score = min(($online_hours / 8) * 10, 10);
$score += $time_score;
return $score;
}
2.2.4 订单优先级计算
/**
* 计算订单优先级
* @param array $order 订单信息
* @return int 优先级分数 (1-100)
*/
function calculateOrderPriority($order) {
$priority = 50; // 基础优先级
// VIP客户 +20
if ($order['is_vip']) $priority += 20;
// 预约单 +15
if ($order['order_type'] == 2) $priority += 15;
// 高价值订单 +10
if ($order['all_money'] > 100) $priority += 10;
// 距离远的订单 +5 (避免无人接单)
if ($order['distance'] > 5) $priority += 5;
// 等待时间过长 +时间权重
$wait_minutes = (time() - strtotime($order['add_time'])) / 60;
if ($wait_minutes > 10) $priority += min($wait_minutes - 10, 20);
return min($priority, 100);
}
2.3 智能分配流程
2.3.1 自动分配流程
1. 新订单产生 → 触发分配任务
2. 筛选可用骑手 → 应用筛选条件
3. 计算匹配度 → 距离 + 能力 + 偏好匹配
4. 排序推荐 → 按综合评分排序
5. 推送通知 → 向前3名骑手推送
6. 等待响应 → 30秒内等待接单
7. 超时处理 → 扩大范围或转手动分配
2.3.2 匹配度计算公式
/**
* 计算骑手与订单的匹配度
*/
function calculateMatchScore($rider, $order) {
// 距离权重 40%
$distance_score = calculateDistanceScore(
$rider['last_location_lat'],
$rider['last_location_lng'],
$order['store_lat'],
$order['store_lng']
) * 0.4;
// 骑手能力 35%
$rider_score = calculateRiderScore($rider) * 0.35;
// 订单偏好匹配 15%
$preference_score = checkOrderPreference($rider, $order) * 0.15;
// 时间匹配 10%
$time_score = checkTimePreference($rider, $order) * 0.1;
return $distance_score + $rider_score + $preference_score + $time_score;
}
三、分配策略细化
3.1 分时段策略
- 早高峰 (7:00-9:00): 优先就近分配,减少等待时间
- 午高峰 (11:00-13:00): 负载均衡优先,避免骑手过载
- 晚高峰 (17:00-20:00): 综合考虑距离和能力
- 其他时段: 标准分配策略
3.2 特殊订单处理
- VIP订单: 优先分配给高评分骑手
- 预约订单: 提前30分钟开始分配
- 紧急订单: 立即分配给最近的可用骑手
- 大额订单: 分配给经验丰富的骑手
3.3 负载均衡机制
/**
* 负载均衡调整
*/
function adjustForLoadBalance($candidates) {
foreach ($candidates as &$candidate) {
$current_load = getCurrentOrderCount($candidate['rider_id']);
$max_load = $candidate['max_orders_per_time'];
$load_ratio = $current_load / $max_load;
// 负载过高降低匹配度
if ($load_ratio > 0.8) {
$candidate['match_score'] *= 0.7;
} elseif ($load_ratio < 0.3) {
// 负载过低提升匹配度
$candidate['match_score'] *= 1.2;
}
}
return $candidates;
}
四、技术实现方案
4.1 数据库设计优化
4.1.1 新增配置表
-- 分配规则配置表
CREATE TABLE `ls_allocation_config` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`config_key` varchar(50) NOT NULL COMMENT '配置键',
`config_value` text NOT NULL COMMENT '配置值(JSON)',
`description` varchar(255) DEFAULT '' COMMENT '配置描述',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `config_key` (`config_key`)
) COMMENT='订单分配配置表';
-- 分配记录表
CREATE TABLE `ls_allocation_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` int(11) NOT NULL COMMENT '订单ID',
`allocation_type` tinyint(1) NOT NULL COMMENT '分配类型:1自动2手动3抢单',
`candidate_riders` text COMMENT '候选骑手列表(JSON)',
`selected_rider_id` int(11) DEFAULT 0 COMMENT '选中的骑手ID',
`allocation_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '分配时间',
`response_time` int(11) DEFAULT 0 COMMENT '响应时间(秒)',
`allocation_result` tinyint(1) DEFAULT 0 COMMENT '分配结果:0失败1成功',
`failure_reason` varchar(255) DEFAULT '' COMMENT '失败原因',
PRIMARY KEY (`id`),
KEY `order_id` (`order_id`),
KEY `allocation_time` (`allocation_time`)
) COMMENT='订单分配日志表';
4.1.2 骑手表字段扩展
-- 为ls_rider_info表添加分配相关字段
ALTER TABLE `ls_rider_info`
ADD COLUMN `allocation_score` decimal(5,2) DEFAULT 0.00 COMMENT '分配评分',
ADD COLUMN `last_allocation_time` datetime DEFAULT NULL COMMENT '最后分配时间',
ADD COLUMN `allocation_count_today` int(11) DEFAULT 0 COMMENT '今日分配次数',
ADD COLUMN `refuse_count_today` int(11) DEFAULT 0 COMMENT '今日拒单次数',
ADD COLUMN `auto_accept_conditions` text COMMENT '自动接单条件(JSON)';
4.2 核心服务类设计
4.2.1 订单分配服务
<?php
/**
* 订单分配服务类
*/
class OrderAllocationService {
/**
* 主分配方法
*/
public function allocateOrder($order_id) {
$order = $this->getOrderInfo($order_id);
if (!$order) return false;
// 1. 获取候选骑手
$candidates = $this->getCandidateRiders($order);
// 2. 计算匹配度
$scored_candidates = $this->scoreRiders($candidates, $order);
// 3. 负载均衡调整
$balanced_candidates = $this->adjustForLoadBalance($scored_candidates);
// 4. 排序并选择前N名
$top_candidates = $this->selectTopCandidates($balanced_candidates, 3);
// 5. 推送通知
$result = $this->notifyRiders($top_candidates, $order);
// 6. 记录分配日志
$this->logAllocation($order_id, $top_candidates, $result);
return $result;
}
/**
* 获取候选骑手
*/
private function getCandidateRiders($order) {
// 实现骑手筛选逻辑
}
/**
* 计算骑手评分
*/
private function scoreRiders($candidates, $order) {
// 实现评分算法
}
// ... 其他方法
}
4.2.2 分配任务队列
<?php
/**
* 分配任务队列处理
*/
class AllocationQueue {
/**
* 添加分配任务
*/
public function addTask($order_id, $priority = 'normal') {
$task = [
'order_id' => $order_id,
'priority' => $priority,
'created_at' => time(),
'attempts' => 0
];
// 添加到Redis队列
$this->redis->lpush('allocation_queue', json_encode($task));
}
/**
* 处理队列任务
*/
public function processQueue() {
while (true) {
$task_data = $this->redis->brpop('allocation_queue', 1);
if ($task_data) {
$task = json_decode($task_data[1], true);
$this->processTask($task);
}
}
}
private function processTask($task) {
$allocation_service = new OrderAllocationService();
$result = $allocation_service->allocateOrder($task['order_id']);
if (!$result && $task['attempts'] < 3) {
// 重试机制
$task['attempts']++;
$this->addTask($task['order_id'], 'retry');
}
}
}
4.3 API接口设计
4.3.1 自动分配接口
/**
* 触发自动分配
* POST /api/allocation/auto
*/
public function autoAllocate() {
$order_id = I('order_id', 0, 'intval');
if (!$order_id) {
$this->ajaxReturn(['code' => 400, 'msg' => '订单ID不能为空']);
}
$allocation_service = new OrderAllocationService();
$result = $allocation_service->allocateOrder($order_id);
if ($result) {
$this->ajaxReturn(['code' => 200, 'msg' => '分配成功', 'data' => $result]);
} else {
$this->ajaxReturn(['code' => 500, 'msg' => '分配失败']);
}
}
4.3.2 骑手推荐接口
/**
* 获取推荐骑手列表
* GET /api/allocation/recommend
*/
public function getRecommendRiders() {
$order_id = I('order_id', 0, 'intval');
$limit = I('limit', 5, 'intval');
$allocation_service = new OrderAllocationService();
$recommendations = $allocation_service->getRecommendations($order_id, $limit);
$this->ajaxReturn([
'code' => 200,
'msg' => '获取成功',
'data' => $recommendations
]);
}
4.4 前端界面优化
4.4.1 智能分配面板
<!-- 订单分配面板 -->
<div class="allocation-panel">
<div class="order-info">
<h3>订单 #{{ order.order_no }}</h3>
<p>商家:{{ order.store_name }}</p>
<p>距离:{{ order.distance }}km</p>
<p>配送费:¥{{ order.delivery_fee }}</p>
</div>
<div class="allocation-options">
<el-button type="primary" @click="autoAllocate">智能分配</el-button>
<el-button @click="showRecommendations">查看推荐</el-button>
<el-button @click="manualAssign">手动分配</el-button>
</div>
<div class="recommendations" v-if="showRecommendList">
<h4>推荐骑手</h4>
<div v-for="rider in recommendations" :key="rider.id" class="rider-card">
<div class="rider-info">
<img :src="rider.avatar" class="avatar">
<div class="details">
<h5>{{ rider.name }}</h5>
<p>评分:{{ rider.rating }}⭐</p>
<p>距离:{{ rider.distance }}km</p>
<p>匹配度:{{ rider.match_score }}%</p>
</div>
</div>
<el-button size="mini" @click="assignToRider(rider.id)">分配</el-button>
</div>
</div>
</div>
五、实施计划
5.1 第一阶段:基础功能 (2周)
- 数据库表结构调整
- 核心分配算法实现
- 基础API接口开发
- 简单的管理后台界面
5.2 第二阶段:智能优化 (2周)
- 机器学习模型训练
- 实时数据分析
- 分配效果监控
- 骑手端推送优化
5.3 第三阶段:完善优化 (1周)
- 性能优化
- 异常处理完善
- 用户体验优化
- 数据统计分析
六、预期效果
6.1 效率提升
- 分配时间: 从平均5分钟降低到30秒内
- 接单率: 提升至85%以上
- 配送时效: 平均配送时间缩短15%
6.2 成本控制
- 人工成本: 减少50%的手动分配工作量
- 配送成本: 通过距离优化降低10%的配送成本
- 客户满意度: 提升20%的客户满意度
6.3 数据驱动
- 实时监控: 分配成功率、响应时间等关键指标
- 智能调优: 基于历史数据持续优化分配算法
- 预测分析: 预测高峰期订单量,提前调配资源
七、风险控制
7.1 技术风险
- 算法准确性: 建立A/B测试机制,逐步优化
- 系统稳定性: 设置降级机制,确保服务可用性
- 数据安全: 加强位置数据和个人信息保护
7.2 业务风险
- 骑手适应性: 提供培训和激励机制
- 客户体验: 建立反馈机制,及时调整策略
- 成本控制: 设置分配成本上限,避免过度优化
这个方案结合了现有系统的特点,提供了一个渐进式的智能化升级路径,既保证了系统的稳定性,又能显著提升订单分配的效率和准确性。