From eb77373d92f01e51b98bda8fae66315ed9a4394d Mon Sep 17 00:00:00 2001 From: 彭雪彬 <1724387007@qq.com> Date: Mon, 14 Jul 2025 17:08:57 +0800 Subject: [PATCH] 骑手接单和骑手取消订单 --- oying-system/src/main/java/com/oying/modules/rider/service/impl/RiderOrderRecordServiceImpl.java | 56 ++++++++++++++++++++++++++- oying-system/src/main/java/com/oying/modules/rider/service/RiderOrderRecordService.java | 15 +++++++ oying-system/src/main/java/com/oying/modules/rider/utils/Constants.java | 2 + oying-system/src/main/java/com/oying/modules/rider/rest/WxRiderController.java | 26 +++++++++++++ oying-common/src/main/java/com/oying/utils/RedisUtils.java | 21 ++++++++++ 5 files changed, 117 insertions(+), 3 deletions(-) diff --git a/oying-common/src/main/java/com/oying/utils/RedisUtils.java b/oying-common/src/main/java/com/oying/utils/RedisUtils.java index 4467f18..361c573 100644 --- a/oying-common/src/main/java/com/oying/utils/RedisUtils.java +++ b/oying-common/src/main/java/com/oying/utils/RedisUtils.java @@ -392,6 +392,27 @@ } } + /** + * 分布式ID生成器 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期,注意:这里将会替换原有的时间 + * @return true成功 false 失败 + */ + public boolean setIfAbsent(String key, Object value, long time) { + try { + if (time > 0) { + Boolean result = redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS); + return result; + } else { + return false; + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return false; + } + } // ================================Map================================= /** diff --git a/oying-system/src/main/java/com/oying/modules/rider/rest/WxRiderController.java b/oying-system/src/main/java/com/oying/modules/rider/rest/WxRiderController.java index 2adcfa4..89a1ecc 100644 --- a/oying-system/src/main/java/com/oying/modules/rider/rest/WxRiderController.java +++ b/oying-system/src/main/java/com/oying/modules/rider/rest/WxRiderController.java @@ -6,6 +6,7 @@ import com.oying.modules.rider.domain.dto.RiderOrderRecordQueryCriteria; import com.oying.modules.rider.domain.dto.RiderWithdrawalRecordQueryCriteria; import com.oying.modules.rider.service.*; +import com.oying.modules.rider.utils.Constants; import com.oying.utils.PageResult; import com.oying.utils.R; import io.swagger.annotations.Api; @@ -88,4 +89,29 @@ return ResponseEntity.ok(R.success(riderOrderRecordPageResult)); } + + @GetMapping("riderGrabOrder/{orderNum}") + @ApiOperation("骑手接单") + @PreAuthorize("@el.check('riderOrderRecord:list')") + public ResponseEntity<?> riderGrabOrder(@PathVariable String orderNum) { + // 订单号不能为空 + if (orderNum == null || orderNum.equals("")) { + return ResponseEntity.ok(R.fail(Constants.HTTP_CODE_FAIL, "订单号不能为空")); + } + R result = riderOrderRecordService.riderGrabOrder(orderNum); + return ResponseEntity.ok(result); + } + + @GetMapping("riderCancelOrder/{orderNum}") + @ApiOperation("骑手取消接单") + @PreAuthorize("@el.check('riderOrderRecord:list')") + public ResponseEntity<?> riderCancelOrder(@PathVariable String orderNum) { + // 订单号不能为空 + if (orderNum == null || orderNum.equals("")) { + return ResponseEntity.ok(R.fail(Constants.HTTP_CODE_FAIL, "订单号不能为空")); + } + R result = riderOrderRecordService.riderCancelOrder(orderNum); + return ResponseEntity.ok(R.success(result)); + } + } diff --git a/oying-system/src/main/java/com/oying/modules/rider/service/RiderOrderRecordService.java b/oying-system/src/main/java/com/oying/modules/rider/service/RiderOrderRecordService.java index bb45f54..9ba9d0a 100644 --- a/oying-system/src/main/java/com/oying/modules/rider/service/RiderOrderRecordService.java +++ b/oying-system/src/main/java/com/oying/modules/rider/service/RiderOrderRecordService.java @@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.oying.utils.PageResult; +import com.oying.utils.R; /** * @description 服务接口 @@ -56,4 +57,18 @@ * @throws IOException / */ void download(List<RiderOrderRecord> all, HttpServletResponse response) throws IOException; + + /** + * 骑手接单 + * @param orderNum + * @throws IOException / + */ + R riderGrabOrder(String orderNum); + + /** + * 骑手取消接单 + * @param orderNum + * @throws IOException / + */ + R riderCancelOrder(String orderNum); } diff --git a/oying-system/src/main/java/com/oying/modules/rider/service/impl/RiderOrderRecordServiceImpl.java b/oying-system/src/main/java/com/oying/modules/rider/service/impl/RiderOrderRecordServiceImpl.java index d1b9785..ea3d97a 100644 --- a/oying-system/src/main/java/com/oying/modules/rider/service/impl/RiderOrderRecordServiceImpl.java +++ b/oying-system/src/main/java/com/oying/modules/rider/service/impl/RiderOrderRecordServiceImpl.java @@ -1,7 +1,9 @@ package com.oying.modules.rider.service.impl; +import cn.hutool.core.lang.UUID; +import com.oying.exception.BadRequestException; import com.oying.modules.rider.domain.RiderOrderRecord; -import com.oying.utils.FileUtil; +import com.oying.utils.*; import lombok.RequiredArgsConstructor; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -10,14 +12,13 @@ import com.oying.modules.rider.mapper.RiderOrderRecordMapper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.oying.utils.PageUtil; + import java.util.List; import java.util.Map; import java.io.IOException; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.LinkedHashMap; -import com.oying.utils.PageResult; /** * @description 服务实现 @@ -29,6 +30,7 @@ public class RiderOrderRecordServiceImpl extends ServiceImpl<RiderOrderRecordMapper, RiderOrderRecord> implements RiderOrderRecordService { private final RiderOrderRecordMapper riderOrderRecordMapper; + private final RedisUtils redisUtils; @Override public PageResult<RiderOrderRecord> queryAll(RiderOrderRecordQueryCriteria criteria, Page<Object> page){ @@ -87,4 +89,52 @@ } FileUtil.downloadExcel(list, response); } + + @Override + @Transactional(rollbackFor = Exception.class) + public R riderGrabOrder(String orderNum) { + // 唯一标识当前线程/客户端 + String clientId = UUID.randomUUID().toString(); + // Redis 锁 key + String lockKey = "lock:order:" + orderNum; + try { + // 获取分布式锁,设置超时时间10秒 + boolean isLocked = redisUtils.setIfAbsent(lockKey, clientId, 10); + if (!isLocked) { + return R.fail(400, "请稍后重试"); + } + // 查询当前订单 检查订单是否已经被其他骑手抢到或取消 直接返回 + + // 订单没有被接单或取消的情况下,进行接单操作 + // 1.修改订单状态 + + // 2.新增订单接单流程信息 + + // 3.新增骑手端订单记录详情 + + // 返回成功信息 + return R.success(null, "接单成功"); + } catch (Exception e) { + throw new BadRequestException("接单失败,请稍后重试"); + } finally { + // 安全释放锁(仅释放自己持有的锁) + String currentClientId = (String) redisUtils.get(lockKey); + // 当前线程持有锁 + if (StringUtils.equals(currentClientId, clientId)) { + // 释放锁 + redisUtils.del(lockKey); + } + } + } + + @Override + public R riderCancelOrder(String orderNum) { + // 查询当前订单信息 + // 根据信息判断当前订单信息是否满足取消条件 + // 满足取消订单 + // 不满足取消订单条件,返回错误信息 + // 取消订单后通知商家 + return null; + } + } diff --git a/oying-system/src/main/java/com/oying/modules/rider/utils/Constants.java b/oying-system/src/main/java/com/oying/modules/rider/utils/Constants.java index 929139b..a5fbb13 100644 --- a/oying-system/src/main/java/com/oying/modules/rider/utils/Constants.java +++ b/oying-system/src/main/java/com/oying/modules/rider/utils/Constants.java @@ -20,6 +20,7 @@ * HTTP请求成功状态码 */ String HTTP_CODE_SUCCESS = "200"; + int HTTP_CODE_FAIL = 400; /** * 状态 0不生效,1生效 其他平台是否满足接单的条件 @@ -37,4 +38,5 @@ */ String WALLET_STATUS_NORMAL = "1"; String WALLET_STATUS_FROZEN = "0"; + } -- Gitblit v1.9.3