增加处理定时任务的表及接口

This commit is contained in:
2025-09-27 22:37:14 +08:00
parent eaaf9d4902
commit 872d1d1b7b
12 changed files with 226 additions and 76 deletions

View File

@ -19,6 +19,7 @@ public enum PayStatusEnum {
REFUNDING("REFUNDING", "退款中"),
REFUND_SUCCESS("REFUND_SUCCESS", "退款成功"),
REFUND_ERROR("REFUND_ERROR", "退款失败"),
CLOSE("CLOSE", "订单关闭"),
;
private final String code;

View File

@ -74,7 +74,7 @@ public class ClientOrderController {
@ApiOperation(value = "取消订单")
@PostMapping("/cancelOrder")
public Result<Boolean> cancelOrder(@Valid @RequestBody PayOrderReq payOrderReq){
orderService.cancelOrder(payOrderReq);
orderService.cancelOrder(payOrderReq,null);
return Result.ok(true);
}

View File

@ -0,0 +1,16 @@
package com.sczx.order.mapper;
import com.sczx.order.po.OrderProcessPO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 订单异常处理表 Mapper 接口
* </p>
*
* @author zhangli
* @since 2025-09-27 22:05:11
*/
public interface OrderProcessMapper extends BaseMapper<OrderProcessPO> {
}

View File

@ -0,0 +1,56 @@
package com.sczx.order.po;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 订单异常处理表
* </p>
*
* @author zhangli
* @since 2025-09-27 22:05:11
*/
@Getter
@Setter
@TableName("zc_order_process")
@ApiModel(value = "OrderProcessPO对象", description = "订单异常处理表")
public class OrderProcessPO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("订单ID主键")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty("订单id")
private Long orderId;
@ApiModelProperty("订单编号")
private String orderNo;
@ApiModelProperty("处理类型NO_PAY未支付, RE_FUND退款")
private String processType;
@ApiModelProperty("处理次数")
private Integer retryNum;
@ApiModelProperty("删除标志0代表存在 2代表删除")
private String delFlag;
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
@ApiModelProperty("更新时间")
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,16 @@
package com.sczx.order.repository;
import com.sczx.order.po.OrderProcessPO;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 订单异常处理表 服务类
* </p>
*
* @author zhangli
* @since 2025-09-27 22:05:11
*/
public interface OrderProcessRepo extends IService<OrderProcessPO> {
}

View File

@ -0,0 +1,20 @@
package com.sczx.order.repository.impl;
import com.sczx.order.po.OrderProcessPO;
import com.sczx.order.mapper.OrderProcessMapper;
import com.sczx.order.repository.OrderProcessRepo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 订单异常处理表 服务实现类
* </p>
*
* @author zhangli
* @since 2025-09-27 22:05:11
*/
@Service
public class OrderProcessRepoImpl extends ServiceImpl<OrderProcessMapper, OrderProcessPO> implements OrderProcessRepo {
}

View File

@ -54,14 +54,20 @@ public interface OrderService {
* 取消订单
* @param payOrderReq
*/
void cancelOrder(PayOrderReq payOrderReq);
void cancelOrder(PayOrderReq payOrderReq,OrderMainPO orderMainPO);
/**
* 取消订单
* 取消续租订单
* @param orderMainPO
*/
void cancelRerentOrOverDueOrder(OrderMainPO orderMainPO);
/**
* 强制删除租车订单
* @param orderMainPO
*/
void forceRemoveRentOrder(OrderMainPO orderMainPO);
/**
* 逾期处理
* @param rentCarOrderReq

View File

@ -107,7 +107,7 @@ public class OrderServiceImpl implements OrderService {
log.info("存在待支付的订单,取消订单");
PayOrderReq payOrderReq = new PayOrderReq();
payOrderReq.setOrderNo(waitPayOrder.getOrderNo());
cancelOrder(payOrderReq);
cancelOrder(payOrderReq,null);
}
//判断是否存有空闲车辆可用
@ -264,7 +264,7 @@ public class OrderServiceImpl implements OrderService {
log.info("存在待支付的订单,取消订单");
PayOrderReq payOrderReq = new PayOrderReq();
payOrderReq.setOrderNo(waitPayOrder.getOrderNo());
cancelOrder(payOrderReq);
cancelOrder(payOrderReq,null);
}
//判断是否存有空闲车辆可用
LambdaQueryWrapper<CarPO> carWrapper = new LambdaQueryWrapper<>();
@ -594,9 +594,11 @@ public class OrderServiceImpl implements OrderService {
}
@Override
public void cancelOrder(PayOrderReq payOrderReq) {
public void cancelOrder(PayOrderReq payOrderReq,OrderMainPO orderMainPO) {
log.info("开始取消订单");
OrderMainPO orderMainPO = queryOrderMainPoByOrderNo(payOrderReq.getOrderNo(), "0");
if(Objects.isNull(orderMainPO)){
orderMainPO = queryOrderMainPoByOrderNo(payOrderReq.getOrderNo(), "0");
}
if(Objects.nonNull(orderMainPO)){
if(!OrderStatusEnum.WAIT_PAY.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())){
throw new BizException("订单非待支付状态,不能取消");
@ -718,6 +720,21 @@ public class OrderServiceImpl implements OrderService {
}
}
@Override
public void forceRemoveRentOrder(OrderMainPO orderMainPO) {
log.info("开始逻辑删除订单");
//逻辑删除订单
LambdaUpdateWrapper<OrderMainPO> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(OrderMainPO::getDelFlag, "2");
updateWrapper.eq(OrderMainPO::getOrderId, orderMainPO.getOrderId());
orderMainRepo.update(updateWrapper);
LambdaUpdateWrapper<OrderSubPO> updateSubWrapper = new LambdaUpdateWrapper<>();
updateSubWrapper.set(OrderSubPO::getDelFlag, "2");
updateSubWrapper.eq(OrderSubPO::getOrderId, orderMainPO.getOrderId());
orderSubRepo.update(updateSubWrapper);
}
@Transactional(rollbackFor = Exception.class)
@Override
@ -1015,7 +1032,7 @@ public class OrderServiceImpl implements OrderService {
if(orderMainPO.getOrderStatus().equals(OrderStatusEnum.WAIT_PAY.getCode())){
PayOrderReq payOrderReq = new PayOrderReq();
payOrderReq.setOrderNo(orderMainPO.getOrderNo());
cancelOrder(payOrderReq);
cancelOrder(payOrderReq,null);
return null;
}
if(orderMainPO.getOrderStatus().equals(OrderStatusEnum.RERENT_WAIT_PAY.getCode())){
@ -1446,7 +1463,7 @@ public class OrderServiceImpl implements OrderService {
if(OrderStatusEnum.WAIT_PAY.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())){
PayOrderReq payOrderReq = new PayOrderReq();
payOrderReq.setOrderNo(orderMainPO.getOrderNo());
cancelOrder(payOrderReq);
cancelOrder(payOrderReq,null);
}else if(OrderStatusEnum.RERENT_WAIT_PAY.getCode().equalsIgnoreCase(orderMainPO.getOrderStatus())){
//处理续租待支付订单
cancelRerentOrOverDueOrder(orderMainPO);

View File

@ -1,19 +1,17 @@
package com.sczx.order.task;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.sczx.order.common.enums.OrderStatusEnum;
import com.sczx.order.common.enums.PayStatusEnum;
import com.sczx.order.common.enums.PaymentTypeEnum;
import com.sczx.order.dto.PayOrderReq;
import com.sczx.order.po.OrderMainPO;
import com.sczx.order.po.OrderSubPO;
import com.sczx.order.po.OrderProcessPO;
import com.sczx.order.repository.OrderMainRepo;
import com.sczx.order.repository.OrderProcessRepo;
import com.sczx.order.repository.OrderSubRepo;
import com.sczx.order.thirdpart.dto.req.AlipayCloseRequest;
import com.sczx.order.service.OrderService;
import com.sczx.order.thirdpart.integration.PayInteg;
import lombok.extern.slf4j.Slf4j;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@ -22,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@Slf4j
@Component
@ -35,6 +34,12 @@ public class NoPayOrderProcessTask {
@Autowired
private PayInteg payInteg;
@Autowired
private OrderService orderService;
@Autowired
private OrderProcessRepo orderProcessRepo;
/**
* 每6分钟检查一次逾期订单
* 使用ShedLock确保在分布式环境下只有一个实例执行
@ -100,52 +105,31 @@ public class NoPayOrderProcessTask {
* @param orderMainPO
*/
private void processWayPay(OrderMainPO orderMainPO) {
LambdaQueryWrapper<OrderSubPO> orderSubQueryWrapper = new LambdaQueryWrapper<>();
orderSubQueryWrapper.eq(OrderSubPO::getOrderId, orderMainPO.getOrderId());
orderSubQueryWrapper.eq(OrderSubPO::getPayStatus, PayStatusEnum.USERPAYING.getCode());
orderSubQueryWrapper.orderByDesc(OrderSubPO::getCreatedAt).last(" limit 1");
OrderSubPO orderSubPO = orderSubRepo.getOne(orderSubQueryWrapper);
boolean closePayOrder = false;
//关闭支付单
if (StringUtils.equalsIgnoreCase(orderSubPO.getPaymentMethod(), PaymentTypeEnum.WX_PAY.getCode())) {
log.info("开始关闭支付单");
closePayOrder = payInteg.closeOrder(orderMainPO.getOperatorId(), orderSubPO.getPaymentId());
} else if (StringUtils.equalsIgnoreCase(orderSubPO.getPaymentMethod(), PaymentTypeEnum.ZFB_PAY.getCode())) {
log.info("开始关闭支付宝支付单");
AlipayCloseRequest alipayCloseRequest = new AlipayCloseRequest();
alipayCloseRequest.setCompanyId(orderMainPO.getOperatorId());
alipayCloseRequest.setOutTradeNo(orderSubPO.getPaymentId());
closePayOrder = payInteg.alipayCloseOrder(alipayCloseRequest);
OrderProcessPO orderProcessPO = orderProcessRepo.getOne(new LambdaQueryWrapper<OrderProcessPO>()
.eq(OrderProcessPO::getOrderId, orderMainPO.getOrderId())
.eq(OrderProcessPO::getProcessType, "NO_PAY"));
if(Objects.isNull(orderProcessPO)){
orderProcessPO = new OrderProcessPO();
orderProcessPO.setOrderId(orderMainPO.getOrderId());
orderProcessPO.setProcessType("NO_PAY");
orderProcessPO.setOrderNo(orderMainPO.getOrderNo());
orderProcessPO.setRetryNum(1);
orderProcessRepo.save(orderProcessPO);
}else {
orderProcessPO.setRetryNum(orderProcessPO.getRetryNum()+1);
orderProcessRepo.saveOrUpdate(orderProcessPO);
}
if (closePayOrder) {
LambdaUpdateWrapper<OrderSubPO> updateSubWrapper = new LambdaUpdateWrapper<>();
updateSubWrapper.set(OrderSubPO::getDelFlag, "2").eq(OrderSubPO::getOrderId, orderMainPO.getOrderId())
.eq(OrderSubPO::getPayStatus, PayStatusEnum.USERPAYING.getCode());
orderSubRepo.update(updateSubWrapper);
if (StringUtils.equalsIgnoreCase(orderMainPO.getOrderStatus(), OrderStatusEnum.WAIT_PAY.getCode())) {
log.info("开始逻辑删除订单");
//逻辑删除订单
LambdaUpdateWrapper<OrderMainPO> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(OrderMainPO::getDelFlag, "2");
updateWrapper.eq(OrderMainPO::getOrderId, orderMainPO.getOrderId());
orderMainRepo.update(updateWrapper);
} else if (StringUtils.equalsIgnoreCase(orderMainPO.getOrderStatus(), OrderStatusEnum.RERENT_WAIT_PAY.getCode())) {
log.info("开始恢复续租订单状态");
//更新订单状态及信息
LambdaUpdateWrapper<OrderMainPO> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(OrderMainPO::getOrderStatus, OrderStatusEnum.RENT_ING.getCode());
if(orderMainPO.getOverdueDays()>0){
updateWrapper.set(OrderMainPO::getOrderStatus, OrderStatusEnum.RENT_OVERDUE.getCode());
}else {
updateWrapper.set(OrderMainPO::getOrderStatus, OrderStatusEnum.RENT_ING.getCode());
}
updateWrapper.eq(OrderMainPO::getOrderId, orderMainPO.getOrderId());
orderMainRepo.update(updateWrapper);
}
if(orderProcessPO.getRetryNum()>5){
log.info("订单{}已超过最大重试次数,强行删除订单", orderMainPO.getOrderNo());
orderService.forceRemoveRentOrder(orderMainPO);
} else {
PayOrderReq payOrderReq = new PayOrderReq();
payOrderReq.setOrderNo(orderMainPO.getOrderNo());
orderService.cancelOrder(payOrderReq,orderMainPO);
}
}
}

View File

@ -6,8 +6,10 @@ import com.sczx.order.common.enums.PayStatusEnum;
import com.sczx.order.common.enums.PaymentTypeEnum;
import com.sczx.order.common.enums.SubOrderTypeEnum;
import com.sczx.order.po.OrderMainPO;
import com.sczx.order.po.OrderProcessPO;
import com.sczx.order.po.OrderSubPO;
import com.sczx.order.repository.OrderMainRepo;
import com.sczx.order.repository.OrderProcessRepo;
import com.sczx.order.repository.OrderSubRepo;
import com.sczx.order.thirdpart.dto.AlipayResponse;
import com.sczx.order.thirdpart.dto.req.AlipayRefundRequest;
@ -23,11 +25,15 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@Slf4j
@Component
public class RefundSubOrderProcessTask {
@Autowired
private OrderProcessRepo orderProcessRepo;
@Autowired
private OrderMainRepo orderMainRepo;
@ -101,27 +107,50 @@ public class RefundSubOrderProcessTask {
* @param subPO
*/
private void processRefund(OrderSubPO subPO) {
OrderMainPO orderMainPO = orderMainRepo.getById(subPO.getOrderId());
boolean fundResult = false;
if(PaymentTypeEnum.WX_PAY.getCode().equalsIgnoreCase(subPO.getPaymentMethod())){
Map<String, String> wxPayResult = payInteg.refundQuery(orderMainPO.getOperatorId(), subPO.getPaymentId());
String returnCode = wxPayResult.get("return_code");
if(StringUtils.isNotBlank(returnCode)){
fundResult = "SUCCESS".equals(returnCode);
}
} else {
AlipayRefundRequest request = new AlipayRefundRequest();
request.setOutTradeNo(subPO.getPaymentId());
request.setCompanyId(orderMainPO.getOperatorId());
AlipayResponse alipayResponse = payInteg.alipayRefundQuery(request);
fundResult = "SUCCESS".equals(alipayResponse.getCode());
OrderProcessPO orderProcessPO = orderProcessRepo.getOne(new LambdaQueryWrapper<OrderProcessPO>()
.eq(OrderProcessPO::getOrderNo, subPO.getSuborderNo())
.eq(OrderProcessPO::getProcessType, "RE_FUND"));
if(Objects.isNull(orderProcessPO)){
orderProcessPO = new OrderProcessPO();
orderProcessPO.setOrderId(subPO.getOrderId());
orderProcessPO.setProcessType("RE_FUND");
orderProcessPO.setOrderNo(subPO.getSuborderNo());
orderProcessPO.setRetryNum(1);
orderProcessRepo.save(orderProcessPO);
}else {
orderProcessPO.setRetryNum(orderProcessPO.getRetryNum()+1);
orderProcessRepo.saveOrUpdate(orderProcessPO);
}
if (fundResult) {
if(orderProcessPO.getRetryNum()>5){
log.info("支付单单{}已超过最大重试次数,强行关闭支付单", subPO.getSuborderNo());
LambdaUpdateWrapper<OrderSubPO> updateSubWrapper = new LambdaUpdateWrapper<>();
updateSubWrapper.set(OrderSubPO::getPayStatus, PayStatusEnum.REFUND_SUCCESS.getCode());
updateSubWrapper.set(OrderSubPO::getPayStatus, PayStatusEnum.CLOSE.getCode());
updateSubWrapper.eq(OrderSubPO::getSuborderId, subPO.getSuborderId());
orderSubRepo.update(updateSubWrapper);
} else {
OrderMainPO orderMainPO = orderMainRepo.getById(subPO.getOrderId());
boolean fundResult = false;
if(PaymentTypeEnum.WX_PAY.getCode().equalsIgnoreCase(subPO.getPaymentMethod())){
Map<String, String> wxPayResult = payInteg.refundQuery(orderMainPO.getOperatorId(), subPO.getPaymentId());
String returnCode = wxPayResult.get("return_code");
if(StringUtils.isNotBlank(returnCode)){
fundResult = "SUCCESS".equals(returnCode);
}
} else {
AlipayRefundRequest request = new AlipayRefundRequest();
request.setOutTradeNo(subPO.getPaymentId());
request.setCompanyId(orderMainPO.getOperatorId());
AlipayResponse alipayResponse = payInteg.alipayRefundQuery(request);
fundResult = "SUCCESS".equals(alipayResponse.getCode());
}
if (fundResult) {
LambdaUpdateWrapper<OrderSubPO> updateSubWrapper = new LambdaUpdateWrapper<>();
updateSubWrapper.set(OrderSubPO::getPayStatus, PayStatusEnum.REFUND_SUCCESS.getCode());
updateSubWrapper.eq(OrderSubPO::getSuborderId, subPO.getSuborderId());
orderSubRepo.update(updateSubWrapper);
}
}
}
}

View File

@ -122,7 +122,7 @@ public class PayInteg {
if(StringUtils.isNotBlank(returnCode)&&StringUtils.equalsIgnoreCase(returnCode, "SUCCESS")){
return true;
} else {
throw new InnerException("关闭订单失败");
return false;
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sczx.order.mapper.OrderProcessMapper">
</mapper>