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