Commit 215ff4299bb501545f968bf97d11553c4468edb0

Authored by 杨刚
1 parent efa4fb8d

新增骑手持单上限功能,包括上限解析、校验及批量查询接口,并优化相关订单分配逻辑

src/main/java/com/diligrp/rider/controller/AdminRiderController.java
@@ -93,6 +93,15 @@ public class AdminRiderController { @@ -93,6 +93,15 @@ public class AdminRiderController {
93 return Result.success(); 93 return Result.success();
94 } 94 }
95 95
  96 + /** 设置个人持单上限:0=不限制 */
  97 + @PostMapping("/setHoldOrderLimit")
  98 + public Result<Void> setHoldOrderLimit(@RequestParam Long riderId,
  99 + @RequestParam int holdOrderLimit,
  100 + HttpServletRequest request) {
  101 + adminRiderService.setHoldOrderLimit(riderId, holdOrderLimit, resolveScopedCityId(request));
  102 + return Result.success();
  103 + }
  104 +
96 /** 指派骑手接单 */ 105 /** 指派骑手接单 */
97 @PostMapping("/order/designate") 106 @PostMapping("/order/designate")
98 public Result<Void> designate(@RequestParam Long orderId, 107 public Result<Void> designate(@RequestParam Long orderId,
src/main/java/com/diligrp/rider/entity/Rider.java
@@ -59,6 +59,9 @@ public class Rider { @@ -59,6 +59,9 @@ public class Rider {
59 /** 是否休息:0=否 1=是 */ 59 /** 是否休息:0=否 1=是 */
60 private Integer isRest; 60 private Integer isRest;
61 61
  62 + /** 个人持单上限:0=不限制 */
  63 + private Integer holdOrderLimit;
  64 +
62 /** 身份证号 */ 65 /** 身份证号 */
63 private String idNo; 66 private String idNo;
64 67
src/main/java/com/diligrp/rider/service/AdminRiderService.java
@@ -22,6 +22,8 @@ public interface AdminRiderService { @@ -22,6 +22,8 @@ public interface AdminRiderService {
22 void setEnableStatus(Long riderId, int status, Long cityId); 22 void setEnableStatus(Long riderId, int status, Long cityId);
23 /** 切换全职/兼职 */ 23 /** 切换全职/兼职 */
24 void setType(Long riderId, int type, Long cityId); 24 void setType(Long riderId, int type, Long cityId);
  25 + /** 设置个人持单上限 */
  26 + void setHoldOrderLimit(Long riderId, int holdOrderLimit, Long cityId);
25 /** 指派骑手接单 */ 27 /** 指派骑手接单 */
26 void designate(Long orderId, Long riderId, Long cityId); 28 void designate(Long orderId, Long riderId, Long cityId);
27 /** 处理转单申请(1=通过 3=拒绝) */ 29 /** 处理转单申请(1=通过 3=拒绝) */
src/main/java/com/diligrp/rider/service/RiderHoldLimitService.java 0 → 100644
  1 +package com.diligrp.rider.service;
  2 +
  3 +import com.diligrp.rider.entity.Rider;
  4 +import com.diligrp.rider.vo.DispatchRuleTemplateVO;
  5 +
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +
  9 +public interface RiderHoldLimitService {
  10 + /** 当前持单量(status=3/4) */
  11 + int countCurrentLoad(Long riderId);
  12 +
  13 + /** 批量查询当前持单量(status=3/4) */
  14 + Map<Long, Integer> getCurrentLoadMap(List<Long> riderIds);
  15 +
  16 + /** 解析骑手个人持单上限,null 表示不限制 */
  17 + Integer resolveHoldOrderLimit(Rider rider);
  18 +
  19 + /** 解析抢单场景生效上限,null 表示不限制 */
  20 + Integer resolveGrabLimit(Rider rider, DispatchRuleTemplateVO rule);
  21 +
  22 + /** 校验骑手是否还能继续接单 */
  23 + void assertWithinLimit(Long riderId, Integer limit, String message);
  24 +}
src/main/java/com/diligrp/rider/service/impl/AdminRiderServiceImpl.java
@@ -16,6 +16,7 @@ import com.diligrp.rider.entity.*; @@ -16,6 +16,7 @@ import com.diligrp.rider.entity.*;
16 import com.diligrp.rider.mapper.*; 16 import com.diligrp.rider.mapper.*;
17 import com.diligrp.rider.service.AdminRiderService; 17 import com.diligrp.rider.service.AdminRiderService;
18 import com.diligrp.rider.service.DeliveryOrderService; 18 import com.diligrp.rider.service.DeliveryOrderService;
  19 +import com.diligrp.rider.service.RiderHoldLimitService;
19 import com.diligrp.rider.vo.DeliveryOrderCreateVO; 20 import com.diligrp.rider.vo.DeliveryOrderCreateVO;
20 import lombok.RequiredArgsConstructor; 21 import lombok.RequiredArgsConstructor;
21 import org.springframework.stereotype.Service; 22 import org.springframework.stereotype.Service;
@@ -40,6 +41,7 @@ public class AdminRiderServiceImpl implements AdminRiderService { @@ -40,6 +41,7 @@ public class AdminRiderServiceImpl implements AdminRiderService {
40 private final RiderBalanceMapper balanceMapper; 41 private final RiderBalanceMapper balanceMapper;
41 private final AdminScopeGuard adminScopeGuard; 42 private final AdminScopeGuard adminScopeGuard;
42 private final DeliveryOrderService deliveryOrderService; 43 private final DeliveryOrderService deliveryOrderService;
  44 + private final RiderHoldLimitService riderHoldLimitService;
43 45
44 @Override 46 @Override
45 public void add(AdminRiderAddDTO dto, Long cityId) { 47 public void add(AdminRiderAddDTO dto, Long cityId) {
@@ -171,6 +173,17 @@ public class AdminRiderServiceImpl implements AdminRiderService { @@ -171,6 +173,17 @@ public class AdminRiderServiceImpl implements AdminRiderService {
171 } 173 }
172 174
173 @Override 175 @Override
  176 + public void setHoldOrderLimit(Long riderId, int holdOrderLimit, Long cityId) {
  177 + if (holdOrderLimit < 0) throw new BizException("个人持单上限不能小于0");
  178 + Rider rider = riderMapper.selectById(riderId);
  179 + if (rider == null) throw new BizException("骑手不存在");
  180 + adminScopeGuard.assertCityAccessible(cityId, rider.getCityId());
  181 + riderMapper.update(null, new LambdaUpdateWrapper<Rider>()
  182 + .eq(Rider::getId, riderId)
  183 + .set(Rider::getHoldOrderLimit, holdOrderLimit));
  184 + }
  185 +
  186 + @Override
174 @Transactional 187 @Transactional
175 public void designate(Long orderId, Long riderId, Long cityId) { 188 public void designate(Long orderId, Long riderId, Long cityId) {
176 Orders order = ordersMapper.selectById(orderId); 189 Orders order = ordersMapper.selectById(orderId);
@@ -187,6 +200,8 @@ public class AdminRiderServiceImpl implements AdminRiderService { @@ -187,6 +200,8 @@ public class AdminRiderServiceImpl implements AdminRiderService {
187 if (order.getIsTrans() == 1 && riderId.equals(order.getOldRiderId())) { 200 if (order.getIsTrans() == 1 && riderId.equals(order.getOldRiderId())) {
188 throw new BizException("此订单为该骑手转单订单,无法指派给该骑手"); 201 throw new BizException("此订单为该骑手转单订单,无法指派给该骑手");
189 } 202 }
  203 + Integer holdOrderLimit = riderHoldLimitService.resolveHoldOrderLimit(rider);
  204 + riderHoldLimitService.assertWithinLimit(riderId, holdOrderLimit, "该骑手当前持单量已达个人上限,无法指派");
190 205
191 long now = System.currentTimeMillis() / 1000; 206 long now = System.currentTimeMillis() / 1000;
192 LambdaUpdateWrapper<Orders> wrapper = new LambdaUpdateWrapper<Orders>() 207 LambdaUpdateWrapper<Orders> wrapper = new LambdaUpdateWrapper<Orders>()
src/main/java/com/diligrp/rider/service/impl/DispatchServiceImpl.java
@@ -7,6 +7,7 @@ import com.diligrp.rider.entity.*; @@ -7,6 +7,7 @@ import com.diligrp.rider.entity.*;
7 import com.diligrp.rider.mapper.*; 7 import com.diligrp.rider.mapper.*;
8 import com.diligrp.rider.service.DispatchRuleService; 8 import com.diligrp.rider.service.DispatchRuleService;
9 import com.diligrp.rider.service.DispatchService; 9 import com.diligrp.rider.service.DispatchService;
  10 +import com.diligrp.rider.service.RiderHoldLimitService;
10 import com.diligrp.rider.service.WebhookService; 11 import com.diligrp.rider.service.WebhookService;
11 import com.diligrp.rider.util.GeoUtil; 12 import com.diligrp.rider.util.GeoUtil;
12 import com.diligrp.rider.vo.DispatchRuleTemplateVO; 13 import com.diligrp.rider.vo.DispatchRuleTemplateVO;
@@ -33,6 +34,7 @@ public class DispatchServiceImpl implements DispatchService { @@ -33,6 +34,7 @@ public class DispatchServiceImpl implements DispatchService {
33 private final OrdersMapper ordersMapper; 34 private final OrdersMapper ordersMapper;
34 private final RiderOrderCountMapper countMapper; 35 private final RiderOrderCountMapper countMapper;
35 private final RiderOrderRefuseMapper refuseMapper; 36 private final RiderOrderRefuseMapper refuseMapper;
  37 + private final RiderHoldLimitService riderHoldLimitService;
36 private final WebhookService webhookService; 38 private final WebhookService webhookService;
37 private final ObjectMapper objectMapper; 39 private final ObjectMapper objectMapper;
38 40
@@ -94,7 +96,7 @@ public class DispatchServiceImpl implements DispatchService { @@ -94,7 +96,7 @@ public class DispatchServiceImpl implements DispatchService {
94 double orderTLng = parseDouble(order.getTLng()); 96 double orderTLng = parseDouble(order.getTLng());
95 97
96 // 5. 预加载每个骑手的统计数据 98 // 5. 预加载每个骑手的统计数据
97 - Map<Long, Integer> currentLoadMap = getCurrentLoadMap(riderIds); 99 + Map<Long, Integer> currentLoadMap = riderHoldLimitService.getCurrentLoadMap(riderIds);
98 Map<Long, Integer> dailyCountMap = getDailyCountMap(riderIds); 100 Map<Long, Integer> dailyCountMap = getDailyCountMap(riderIds);
99 101
100 // 6. 对每个候选骑手评分 102 // 6. 对每个候选骑手评分
@@ -111,7 +113,8 @@ public class DispatchServiceImpl implements DispatchService { @@ -111,7 +113,8 @@ public class DispatchServiceImpl implements DispatchService {
111 113
112 // 持单量检查(强制过滤) 114 // 持单量检查(强制过滤)
113 int currentLoad = currentLoadMap.getOrDefault(rider.getId(), 0); 115 int currentLoad = currentLoadMap.getOrDefault(rider.getId(), 0);
114 - if (rule.getGrabMaxPerRider() != null && currentLoad >= rule.getGrabMaxPerRider()) { 116 + Integer holdOrderLimit = riderHoldLimitService.resolveHoldOrderLimit(rider);
  117 + if (holdOrderLimit != null && currentLoad >= holdOrderLimit) {
115 continue; // 持单已满,跳过 118 continue; // 持单已满,跳过
116 } 119 }
117 120
@@ -283,21 +286,6 @@ public class DispatchServiceImpl implements DispatchService { @@ -283,21 +286,6 @@ public class DispatchServiceImpl implements DispatchService {
283 return map; 286 return map;
284 } 287 }
285 288
286 - /** 获取每个骑手当前持单量(status=3 或 4 的订单数) */  
287 - private Map<Long, Integer> getCurrentLoadMap(List<Long> riderIds) {  
288 - Map<Long, Integer> map = new HashMap<>();  
289 - if (riderIds.isEmpty()) return map;  
290 - List<Orders> inProgress = ordersMapper.selectList(  
291 - new LambdaQueryWrapper<Orders>()  
292 - .in(Orders::getRiderId, riderIds)  
293 - .in(Orders::getStatus, List.of(3, 4))  
294 - .select(Orders::getRiderId));  
295 - for (Orders o : inProgress) {  
296 - map.merge(o.getRiderId(), 1, Integer::sum);  
297 - }  
298 - return map;  
299 - }  
300 -  
301 /** 获取每个骑手当日接单量 */ 289 /** 获取每个骑手当日接单量 */
302 private Map<Long, Integer> getDailyCountMap(List<Long> riderIds) { 290 private Map<Long, Integer> getDailyCountMap(List<Long> riderIds) {
303 Map<Long, Integer> map = new HashMap<>(); 291 Map<Long, Integer> map = new HashMap<>();
src/main/java/com/diligrp/rider/service/impl/RiderHoldLimitServiceImpl.java 0 → 100644
  1 +package com.diligrp.rider.service.impl;
  2 +
  3 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  4 +import com.diligrp.rider.common.exception.BizException;
  5 +import com.diligrp.rider.entity.Orders;
  6 +import com.diligrp.rider.entity.Rider;
  7 +import com.diligrp.rider.mapper.OrdersMapper;
  8 +import com.diligrp.rider.service.RiderHoldLimitService;
  9 +import com.diligrp.rider.vo.DispatchRuleTemplateVO;
  10 +import lombok.RequiredArgsConstructor;
  11 +import org.springframework.stereotype.Service;
  12 +
  13 +import java.util.HashMap;
  14 +import java.util.List;
  15 +import java.util.Map;
  16 +
  17 +@Service
  18 +@RequiredArgsConstructor
  19 +public class RiderHoldLimitServiceImpl implements RiderHoldLimitService {
  20 +
  21 + private final OrdersMapper ordersMapper;
  22 +
  23 + @Override
  24 + public int countCurrentLoad(Long riderId) {
  25 + if (riderId == null || riderId < 1) {
  26 + return 0;
  27 + }
  28 + return Math.toIntExact(ordersMapper.selectCount(new LambdaQueryWrapper<Orders>()
  29 + .eq(Orders::getRiderId, riderId)
  30 + .eq(Orders::getIsDel, 0)
  31 + .in(Orders::getStatus, List.of(3, 4))));
  32 + }
  33 +
  34 + @Override
  35 + public Map<Long, Integer> getCurrentLoadMap(List<Long> riderIds) {
  36 + Map<Long, Integer> map = new HashMap<>();
  37 + if (riderIds == null || riderIds.isEmpty()) {
  38 + return map;
  39 + }
  40 + List<Orders> inProgress = ordersMapper.selectList(new LambdaQueryWrapper<Orders>()
  41 + .in(Orders::getRiderId, riderIds)
  42 + .eq(Orders::getIsDel, 0)
  43 + .in(Orders::getStatus, List.of(3, 4))
  44 + .select(Orders::getRiderId));
  45 + for (Orders order : inProgress) {
  46 + map.merge(order.getRiderId(), 1, Integer::sum);
  47 + }
  48 + return map;
  49 + }
  50 +
  51 + @Override
  52 + public Integer resolveHoldOrderLimit(Rider rider) {
  53 + if (rider == null || rider.getHoldOrderLimit() == null || rider.getHoldOrderLimit() <= 0) {
  54 + return null;
  55 + }
  56 + return rider.getHoldOrderLimit();
  57 + }
  58 +
  59 + @Override
  60 + public Integer resolveGrabLimit(Rider rider, DispatchRuleTemplateVO rule) {
  61 + Integer personalLimit = resolveHoldOrderLimit(rider);
  62 + Integer templateLimit = null;
  63 + if (rule != null && rule.getGrabEnabled() != null && rule.getGrabEnabled() == 1
  64 + && rule.getGrabMaxPerRider() != null && rule.getGrabMaxPerRider() > 0) {
  65 + templateLimit = rule.getGrabMaxPerRider();
  66 + }
  67 + if (personalLimit == null) {
  68 + return templateLimit;
  69 + }
  70 + if (templateLimit == null) {
  71 + return personalLimit;
  72 + }
  73 + return Math.min(personalLimit, templateLimit);
  74 + }
  75 +
  76 + @Override
  77 + public void assertWithinLimit(Long riderId, Integer limit, String message) {
  78 + if (limit == null) {
  79 + return;
  80 + }
  81 + if (countCurrentLoad(riderId) >= limit) {
  82 + throw new BizException(message);
  83 + }
  84 + }
  85 +}
src/main/java/com/diligrp/rider/service/impl/RiderLocationServiceImpl.java
@@ -10,12 +10,11 @@ import com.diligrp.rider.mapper.OrdersMapper; @@ -10,12 +10,11 @@ import com.diligrp.rider.mapper.OrdersMapper;
10 import com.diligrp.rider.mapper.RiderLocationMapper; 10 import com.diligrp.rider.mapper.RiderLocationMapper;
11 import com.diligrp.rider.mapper.RiderMapper; 11 import com.diligrp.rider.mapper.RiderMapper;
12 import com.diligrp.rider.service.CityService; 12 import com.diligrp.rider.service.CityService;
13 -import com.diligrp.rider.service.DispatchRuleService; 13 +import com.diligrp.rider.service.RiderHoldLimitService;
14 import com.diligrp.rider.service.RiderLocationService; 14 import com.diligrp.rider.service.RiderLocationService;
15 import com.diligrp.rider.util.GeoUtil; 15 import com.diligrp.rider.util.GeoUtil;
16 import com.diligrp.rider.vo.AdminRiderDashboardVO; 16 import com.diligrp.rider.vo.AdminRiderDashboardVO;
17 import com.diligrp.rider.vo.AdminRiderLocationVO; 17 import com.diligrp.rider.vo.AdminRiderLocationVO;
18 -import com.diligrp.rider.vo.DispatchRuleTemplateVO;  
19 import com.diligrp.rider.vo.NearbyRiderVO; 18 import com.diligrp.rider.vo.NearbyRiderVO;
20 import com.diligrp.rider.websocket.LocationPushService; 19 import com.diligrp.rider.websocket.LocationPushService;
21 import lombok.RequiredArgsConstructor; 20 import lombok.RequiredArgsConstructor;
@@ -37,7 +36,7 @@ public class RiderLocationServiceImpl implements RiderLocationService { @@ -37,7 +36,7 @@ public class RiderLocationServiceImpl implements RiderLocationService {
37 private final RiderMapper riderMapper; 36 private final RiderMapper riderMapper;
38 private final OrdersMapper ordersMapper; 37 private final OrdersMapper ordersMapper;
39 private final CityService cityService; 38 private final CityService cityService;
40 - private final DispatchRuleService dispatchRuleService; 39 + private final RiderHoldLimitService riderHoldLimitService;
41 private final LocationPushService locationPushService; 40 private final LocationPushService locationPushService;
42 41
43 /** 42 /**
@@ -146,9 +145,6 @@ public class RiderLocationServiceImpl implements RiderLocationService { @@ -146,9 +145,6 @@ public class RiderLocationServiceImpl implements RiderLocationService {
146 return result; 145 return result;
147 } 146 }
148 147
149 - DispatchRuleTemplateVO rule = dispatchRuleService.getActiveRule(cityId);  
150 - Integer maxHoldOrderCount = normalizeMaxHoldOrderCount(rule);  
151 -  
152 List<Rider> riders = riderMapper.selectList(new LambdaQueryWrapper<Rider>() 148 List<Rider> riders = riderMapper.selectList(new LambdaQueryWrapper<Rider>()
153 .eq(Rider::getCityId, cityId) 149 .eq(Rider::getCityId, cityId)
154 .orderByDesc(Rider::getId)); 150 .orderByDesc(Rider::getId));
@@ -165,8 +161,8 @@ public class RiderLocationServiceImpl implements RiderLocationService { @@ -165,8 +161,8 @@ public class RiderLocationServiceImpl implements RiderLocationService {
165 .in(Orders::getStatus, List.of(3, 4)) 161 .in(Orders::getStatus, List.of(3, 4))
166 .in(Orders::getRiderId, riderIds) 162 .in(Orders::getRiderId, riderIds)
167 .eq(Orders::getIsDel, 0)); 163 .eq(Orders::getIsDel, 0));
168 - log.debug("商铺骑手看板基础数据查询完成,cityId={} riderCount={} locationCount={} holdingOrderCount={} maxHoldOrderCount={}",  
169 - cityId, riders.size(), locations.size(), holdingOrders.size(), maxHoldOrderCount); 164 + log.debug("商铺骑手看板基础数据查询完成,cityId={} riderCount={} locationCount={} holdingOrderCount={}",
  165 + cityId, riders.size(), locations.size(), holdingOrders.size());
170 166
171 java.util.Map<Long, RiderLocation> locationMap = new java.util.HashMap<>(); 167 java.util.Map<Long, RiderLocation> locationMap = new java.util.HashMap<>();
172 for (RiderLocation location : locations) { 168 for (RiderLocation location : locations) {
@@ -191,6 +187,7 @@ public class RiderLocationServiceImpl implements RiderLocationService { @@ -191,6 +187,7 @@ public class RiderLocationServiceImpl implements RiderLocationService {
191 vo.setStatus(buildRiderStatus(rider, locationMap.get(rider.getId()))); 187 vo.setStatus(buildRiderStatus(rider, locationMap.get(rider.getId())));
192 188
193 int holdOrderCount = holdCountMap.getOrDefault(rider.getId(), 0); 189 int holdOrderCount = holdCountMap.getOrDefault(rider.getId(), 0);
  190 + Integer maxHoldOrderCount = riderHoldLimitService.resolveHoldOrderLimit(rider);
194 vo.setHoldOrderCount(holdOrderCount); 191 vo.setHoldOrderCount(holdOrderCount);
195 vo.setMaxHoldOrderCount(maxHoldOrderCount); 192 vo.setMaxHoldOrderCount(maxHoldOrderCount);
196 vo.setLoadRate(calcLoadRate(holdOrderCount, maxHoldOrderCount)); 193 vo.setLoadRate(calcLoadRate(holdOrderCount, maxHoldOrderCount));
@@ -290,13 +287,6 @@ public class RiderLocationServiceImpl implements RiderLocationService { @@ -290,13 +287,6 @@ public class RiderLocationServiceImpl implements RiderLocationService {
290 return "在线"; 287 return "在线";
291 } 288 }
292 289
293 - private Integer normalizeMaxHoldOrderCount(DispatchRuleTemplateVO rule) {  
294 - if (rule == null || rule.getGrabMaxPerRider() == null || rule.getGrabMaxPerRider() <= 0) {  
295 - return null;  
296 - }  
297 - return rule.getGrabMaxPerRider();  
298 - }  
299 -  
300 private Integer calcLoadRate(int holdOrderCount, Integer maxHoldOrderCount) { 290 private Integer calcLoadRate(int holdOrderCount, Integer maxHoldOrderCount) {
301 if (maxHoldOrderCount == null || maxHoldOrderCount <= 0) { 291 if (maxHoldOrderCount == null || maxHoldOrderCount <= 0) {
302 return null; 292 return null;
src/main/java/com/diligrp/rider/service/impl/RiderOrderServiceImpl.java
@@ -8,6 +8,7 @@ import com.fasterxml.jackson.core.type.TypeReference; @@ -8,6 +8,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
8 import com.fasterxml.jackson.databind.ObjectMapper; 8 import com.fasterxml.jackson.databind.ObjectMapper;
9 import com.diligrp.rider.common.exception.BizException; 9 import com.diligrp.rider.common.exception.BizException;
10 import com.diligrp.rider.service.DispatchRuleService; 10 import com.diligrp.rider.service.DispatchRuleService;
  11 +import com.diligrp.rider.service.RiderHoldLimitService;
11 import com.diligrp.rider.service.RiderLevelService; 12 import com.diligrp.rider.service.RiderLevelService;
12 import com.diligrp.rider.service.RiderOrderService; 13 import com.diligrp.rider.service.RiderOrderService;
13 import com.diligrp.rider.service.WebhookService; 14 import com.diligrp.rider.service.WebhookService;
@@ -40,6 +41,7 @@ public class RiderOrderServiceImpl implements RiderOrderService { @@ -40,6 +41,7 @@ public class RiderOrderServiceImpl implements RiderOrderService {
40 private final RiderMapper riderMapper; 41 private final RiderMapper riderMapper;
41 private final RiderLevelService riderLevelService; 42 private final RiderLevelService riderLevelService;
42 private final DispatchRuleService dispatchRuleService; 43 private final DispatchRuleService dispatchRuleService;
  44 + private final RiderHoldLimitService riderHoldLimitService;
43 private final ObjectMapper objectMapper; 45 private final ObjectMapper objectMapper;
44 private final WebhookService webhookService; 46 private final WebhookService webhookService;
45 47
@@ -130,14 +132,8 @@ public class RiderOrderServiceImpl implements RiderOrderService { @@ -130,14 +132,8 @@ public class RiderOrderServiceImpl implements RiderOrderService {
130 } 132 }
131 133
132 DispatchRuleTemplateVO rule = dispatchRuleService.getActiveRule(cityId); 134 DispatchRuleTemplateVO rule = dispatchRuleService.getActiveRule(cityId);
133 - if (rule != null && rule.getGrabMaxPerRider() != null && rule.getGrabMaxPerRider() > 0) {  
134 - Long currentLoad = ordersMapper.selectCount(new LambdaQueryWrapper<Orders>()  
135 - .eq(Orders::getRiderId, riderId)  
136 - .in(Orders::getStatus, List.of(3, 4)));  
137 - if (currentLoad >= rule.getGrabMaxPerRider()) {  
138 - throw new BizException(1000, "当前持单量已达上限,无法继续抢单");  
139 - }  
140 - } 135 + Integer grabLimit = riderHoldLimitService.resolveGrabLimit(rider, rule);
  136 + riderHoldLimitService.assertWithinLimit(riderId, grabLimit, "当前持单量已达上限,无法继续抢单");
141 if (order.getIsTrans() == 1 && riderId.equals(order.getOldRiderId())) { 137 if (order.getIsTrans() == 1 && riderId.equals(order.getOldRiderId())) {
142 throw new BizException(980, "抢单失败,不能抢自己转出的单"); 138 throw new BizException(980, "抢单失败,不能抢自己转出的单");
143 } 139 }
src/main/resources/schema.sql
@@ -20,6 +20,7 @@ CREATE TABLE `rider` ( @@ -20,6 +20,7 @@ CREATE TABLE `rider` (
20 `status` TINYINT NOT NULL DEFAULT 1 COMMENT '账号状态:0=禁用 1=正常', 20 `status` TINYINT NOT NULL DEFAULT 1 COMMENT '账号状态:0=禁用 1=正常',
21 `balance` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '余额(兼职用)', 21 `balance` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '余额(兼职用)',
22 `is_rest` TINYINT NOT NULL DEFAULT 0 COMMENT '是否休息:0=否 1=是', 22 `is_rest` TINYINT NOT NULL DEFAULT 0 COMMENT '是否休息:0=否 1=是',
  23 + `hold_order_limit` INT NOT NULL DEFAULT 0 COMMENT '个人持单上限,0=不限制',
23 `id_no` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '身份证号', 24 `id_no` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '身份证号',
24 `thumb` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '手持身份证照片', 25 `thumb` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '手持身份证照片',
25 `create_time` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '注册时间', 26 `create_time` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '注册时间',
@@ -500,7 +501,8 @@ ALTER TABLE `orders` ADD COLUMN `ext_store_id` BIGINT UNSIGNED NOT NULL DEFAULT @@ -500,7 +501,8 @@ ALTER TABLE `orders` ADD COLUMN `ext_store_id` BIGINT UNSIGNED NOT NULL DEFAULT
500 ALTER TABLE `orders` ADD COLUMN `dispatch_time` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '系统派单时间' AFTER `trans_time`; 501 ALTER TABLE `orders` ADD COLUMN `dispatch_time` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '系统派单时间' AFTER `trans_time`;
501 ALTER TABLE `orders` ADD COLUMN `dispatch_rider_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '系统指派骑手ID' AFTER `dispatch_time`; 502 ALTER TABLE `orders` ADD COLUMN `dispatch_rider_id` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '系统指派骑手ID' AFTER `dispatch_time`;
502 503
503 --- rider 表补充评分统计字段 504 +-- rider 表补充个人持单上限与评分统计字段
  505 +ALTER TABLE `rider` ADD COLUMN `hold_order_limit` INT NOT NULL DEFAULT 0 COMMENT '个人持单上限,0=不限制' AFTER `is_rest`;
504 ALTER TABLE `rider` ADD COLUMN `star_total` INT NOT NULL DEFAULT 0 COMMENT '评分总分' AFTER `thumb`; 506 ALTER TABLE `rider` ADD COLUMN `star_total` INT NOT NULL DEFAULT 0 COMMENT '评分总分' AFTER `thumb`;
505 ALTER TABLE `rider` ADD COLUMN `star_count` INT NOT NULL DEFAULT 0 COMMENT '评分次数' AFTER `star_total`; 507 ALTER TABLE `rider` ADD COLUMN `star_count` INT NOT NULL DEFAULT 0 COMMENT '评分次数' AFTER `star_total`;
506 508