# 骑手端订单智能分配方案 ## 一、现状分析 ### 1.1 现有系统架构 - **订单表结构**: `ls_retail_bill_order`(主订单)+ `ls_rider_order`(配送订单) - **骑手管理**: `ls_rider_info`(骑手信息)+ 相关统计和收入表 - **分配方式**: 主要依赖手动分配和骑手抢单,缺乏智能化分配 ### 1.2 存在问题 1. **效率低下**: 手动分配耗时,影响配送时效 2. **分配不均**: 缺乏负载均衡,部分骑手过忙,部分闲置 3. **距离优化不足**: 未考虑骑手位置与商家/客户距离 4. **成本控制薄弱**: 没有综合考虑配送成本和收益 ## 二、智能分配策略设计 ### 2.1 分配模式 采用**混合分配模式**: - **智能推荐** + **骑手抢单** + **手动干预** ### 2.2 核心分配算法 #### 2.2.1 骑手筛选条件 ```sql -- 可分配骑手筛选条件 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 距离权重计算 ```php /** * 计算骑手到商家的距离权重 * @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 骑手能力评分 ```php /** * 计算骑手综合能力评分 * @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 订单优先级计算 ```php /** * 计算订单优先级 * @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 匹配度计算公式 ```php /** * 计算骑手与订单的匹配度 */ 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 负载均衡机制 ```php /** * 负载均衡调整 */ 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 新增配置表 ```sql -- 分配规则配置表 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 骑手表字段扩展 ```sql -- 为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 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 $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 自动分配接口 ```php /** * 触发自动分配 * 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 骑手推荐接口 ```php /** * 获取推荐骑手列表 * 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 智能分配面板 ```html
商家:{{ order.store_name }}
距离:{{ order.distance }}km
配送费:¥{{ order.delivery_fee }}
评分:{{ rider.rating }}⭐
距离:{{ rider.distance }}km
匹配度:{{ rider.match_score }}%