彭雪彬
2025-07-14 eb77373d92f01e51b98bda8fae66315ed9a4394d
骑手接单和骑手取消订单
5 files modified
120 ■■■■■ changed files
oying-common/src/main/java/com/oying/utils/RedisUtils.java 21 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/rider/rest/WxRiderController.java 26 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/rider/service/RiderOrderRecordService.java 15 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/rider/service/impl/RiderOrderRecordServiceImpl.java 56 ●●●●● patch | view | raw | blame | history
oying-system/src/main/java/com/oying/modules/rider/utils/Constants.java 2 ●●●●● patch | view | raw | blame | history
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=================================
    /**
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));
    }
}
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);
}
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;
    }
}
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";
}