|
|
@@ -9,6 +9,8 @@ import beilv.order.mapper.StoreOrderMapper;
|
|
|
import beilv.order.mapper.StoreRefundMapper;
|
|
|
import beilv.system.domain.SysMember;
|
|
|
import beilv.system.service.ISysMemberService;
|
|
|
+import beilv.vipCardLog.domain.VipCardLog;
|
|
|
+import beilv.vipCardLog.service.IVipCardLogService;
|
|
|
import beilv.wx.pay.config.WxPayProperties;
|
|
|
import beilv.wx.pay.domain.vo.AppPayParam;
|
|
|
import beilv.wx.pay.domain.vo.AppRefundParam;
|
|
|
@@ -26,8 +28,10 @@ import com.github.binarywang.wxpay.exception.WxPayException;
|
|
|
import com.github.binarywang.wxpay.service.WxPayService;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.ObjectUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
import org.springframework.http.ResponseEntity;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
@@ -35,7 +39,9 @@ import javax.servlet.http.HttpServletRequest;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
-import java.util.*;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.UUID;
|
|
|
|
|
|
@Slf4j
|
|
|
@Service
|
|
|
@@ -54,19 +60,35 @@ public class IWxPayService {
|
|
|
private ISysMemberService sysMemberService;
|
|
|
@Autowired
|
|
|
private StoreRefundMapper storeRefundMapper;
|
|
|
+ @Autowired
|
|
|
+ private StringRedisTemplate redisTemplate;
|
|
|
+ @Autowired
|
|
|
+ private IVipCardLogService vipCardLogService;
|
|
|
|
|
|
private WxPayService wxService;
|
|
|
|
|
|
|
|
|
+ // Redis中订单延迟队列的key前缀
|
|
|
+ private static final String ORDER_DELAY_QUEUE_PREFIX = "order:delay:queue:";
|
|
|
+ // 订单超时时间(5分钟)
|
|
|
+ private static final long ORDER_TIMEOUT_SECONDS = 5 * 60;
|
|
|
+
|
|
|
/**
|
|
|
* 统一下单接口
|
|
|
*
|
|
|
* @return 预支付交易会话标识
|
|
|
*/
|
|
|
public JsapiResult unifiedOrder(AppPayParam param) throws Exception {
|
|
|
+ log.info("开始处理统一下单请求,订单号: {}", param.getOrderId());
|
|
|
+ // 幂等性校验 - 检查订单是否已存在且已支付
|
|
|
+ StoreOrder existingOrder = storeOrderMapper.selectStoreOrderByOrderId(param.getOrderId());
|
|
|
+ if (existingOrder != null && existingOrder.getPaid() != null && existingOrder.getPaid() == 1) {
|
|
|
+ log.warn("订单 {} 已支付,不能重复下单", param.getOrderId());
|
|
|
+ throw new Exception("订单已支付,不能重复下单");
|
|
|
+ }
|
|
|
SysMember user = getSysMember(param.getUserId());
|
|
|
param.setSysMember(user);
|
|
|
- //生成唯一标识商家订单号
|
|
|
+ //微信支付需要的参数
|
|
|
WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request();
|
|
|
request.setAppid(wxPayProperties.getAppId());
|
|
|
request.setMchid(wxPayProperties.getMchId());
|
|
|
@@ -78,16 +100,24 @@ public class IWxPayService {
|
|
|
amount.setCurrency("CNY");
|
|
|
request.setAmount(amount);
|
|
|
request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(user.getOpenId()));
|
|
|
+ log.info("调用微信统一下单接口,订单号: {}", param.getOrderId());
|
|
|
JsapiResult jsapiResult = this.wxService.createOrderV3(TradeTypeEnum.JSAPI, request);
|
|
|
if (StringUtils.isNotEmpty(jsapiResult.getPackageValue())) {
|
|
|
+ log.info("微信统一下单成功,订单号: {},开始创建本地订单", param.getOrderId());
|
|
|
//成功之后创建订单
|
|
|
generateOrder(param, jsapiResult.getPackageValue());
|
|
|
+ //将订单添加到延迟队列中
|
|
|
+ addOrderToDelayQueue(param.getOrderId());
|
|
|
+ log.info("订单创建完成并加入延迟队列,订单号: {}", param.getOrderId());
|
|
|
+ } else {
|
|
|
+ log.warn("微信统一下单失败,订单号: {}", param.getOrderId());
|
|
|
}
|
|
|
return jsapiResult;
|
|
|
}
|
|
|
|
|
|
//获取当前用户信息
|
|
|
private SysMember getSysMember(Long userId) {
|
|
|
+ log.debug("获取用户信息,用户ID: {}", userId);
|
|
|
return sysMemberService.selectSysMemberById(userId);
|
|
|
}
|
|
|
|
|
|
@@ -112,19 +142,60 @@ public class IWxPayService {
|
|
|
* @return 预支付交易会话标识
|
|
|
*/
|
|
|
private void generateOrder(AppPayParam param, String payId) {
|
|
|
- StoreOrder storeOrder = new StoreOrder();
|
|
|
- storeOrder.setOrderId(param.getOrderId());
|
|
|
- storeOrder.setUid(param.getSysMember().getId());
|
|
|
- storeOrder.setRealName(param.getSysMember().getUsername());
|
|
|
- storeOrder.setUserPhone(param.getSysMember().getMobile());
|
|
|
- storeOrder.setUserAddress(param.getSysMember().getAddress());
|
|
|
- storeOrder.setTotalNum(1);
|
|
|
- storeOrder.setTotalPrice(param.getTotalPrice());
|
|
|
- storeOrder.setPayPrice(param.getPayPrice());
|
|
|
- storeOrder.setPayTime(new Date());
|
|
|
- storeOrder.setPayId(payId);
|
|
|
- storeOrder.setCreateTime(new Date());
|
|
|
- storeOrderMapper.insertStoreOrder(storeOrder);
|
|
|
+ log.info("开始生成订单,订单号: {}", param.getOrderId());
|
|
|
+ //查看是否已经生成订单,但是未支付
|
|
|
+ if (!isOrderInDelayQueue(param.getOrderId())) {
|
|
|
+ // 订单不存在,创建新订单
|
|
|
+ log.info("订单不存在,创建新订单,订单号: {}", param.getOrderId());
|
|
|
+ StoreOrder storeOrder = new StoreOrder();
|
|
|
+ storeOrder.setOrderId(param.getOrderId());
|
|
|
+ storeOrder.setUid(param.getSysMember().getId());
|
|
|
+ storeOrder.setRealName(param.getSysMember().getUsername());
|
|
|
+ storeOrder.setUserPhone(param.getSysMember().getMobile());
|
|
|
+ storeOrder.setUserAddress(param.getSysMember().getAddress());
|
|
|
+ storeOrder.setTotalNum(1);
|
|
|
+ storeOrder.setTotalPrice(param.getTotalPrice());
|
|
|
+ storeOrder.setPayPrice(param.getPayPrice());
|
|
|
+ storeOrder.setPayTime(new Date());
|
|
|
+ storeOrder.setPayId(payId);
|
|
|
+ storeOrder.setCreateTime(new Date());
|
|
|
+ storeOrderMapper.insertStoreOrder(storeOrder);
|
|
|
+ log.info("新订单创建成功,订单号: {}", param.getOrderId());
|
|
|
+ } else {
|
|
|
+ StoreOrder order = storeOrderMapper.selectStoreOrderByOrderId(param.getOrderId());
|
|
|
+ // 订单已存在,更新支付相关信息
|
|
|
+ log.info("订单已存在,更新支付信息,订单号: {}", param.getOrderId());
|
|
|
+ order.setPayTime(new Date());
|
|
|
+ order.setPayId(payId);
|
|
|
+ storeOrderMapper.updateStoreOrder(order);
|
|
|
+ log.info("订单支付信息更新完成,订单号: {}", param.getOrderId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将订单添加到延迟队列
|
|
|
+ *
|
|
|
+ * @param orderId 订单ID
|
|
|
+ */
|
|
|
+ private void addOrderToDelayQueue(String orderId) {
|
|
|
+ log.info("将订单添加到延迟队列,订单号: {}", orderId);
|
|
|
+ // 计算订单超时时间戳(当前时间+5分钟)
|
|
|
+ long expireTime = System.currentTimeMillis() + (ORDER_TIMEOUT_SECONDS * 1000);
|
|
|
+ // 将订单添加到Redis有序集合中,以超时时间戳作为score
|
|
|
+ redisTemplate.opsForZSet().add(ORDER_DELAY_QUEUE_PREFIX + "orders", orderId, expireTime);
|
|
|
+ log.info("订单 {} 已添加到延迟队列,超时时间: {}", orderId, new Date(expireTime));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从延迟队列中移除订单(支付成功时调用)
|
|
|
+ *
|
|
|
+ * @param orderId 订单ID
|
|
|
+ */
|
|
|
+ private void removeOrderFromDelayQueue(String orderId) {
|
|
|
+ log.info("从延迟队列中移除订单,订单号: {}", orderId);
|
|
|
+ // 从Redis有序集合中移除订单
|
|
|
+ redisTemplate.opsForZSet().remove(ORDER_DELAY_QUEUE_PREFIX + "orders", orderId);
|
|
|
+ log.info("订单 {} 已从延迟队列中移除", orderId);
|
|
|
}
|
|
|
|
|
|
//生成退款订单号
|
|
|
@@ -140,21 +211,30 @@ public class IWxPayService {
|
|
|
* @return 处理结果
|
|
|
*/
|
|
|
public AjaxResult handleNotify(String notifyData, HttpServletRequest request) {
|
|
|
+ log.info("收到微信支付回调通知");
|
|
|
SignatureHeader header = getRequestHeader(request);
|
|
|
try {
|
|
|
WxPayNotifyV3Result res = this.wxService.parseOrderNotifyV3Result(notifyData, header);
|
|
|
WxPayNotifyV3Result.DecryptNotifyResult decryptRes = res.getResult();
|
|
|
- // TODO 根据自己业务场景需要构造返回对象
|
|
|
+ log.info("解析微信支付回调结果,订单号: {}, 交易状态: {}", decryptRes.getOutTradeNo(), decryptRes.getTradeState());
|
|
|
if (WxPayConstants.WxpayTradeStatus.SUCCESS.equals(decryptRes.getTradeState())) {
|
|
|
+ log.info("支付成功,开始处理订单,订单号: {}", decryptRes.getOutTradeNo());
|
|
|
// 成功处理订单
|
|
|
processOrderPayment(decryptRes.getOutTradeNo());
|
|
|
+ //调用充值记录服务,更新充值记录状态
|
|
|
+ VipCardLog vipCardLog = new VipCardLog();
|
|
|
+ vipCardLog.setId(decryptRes.getOutTradeNo());
|
|
|
+ vipCardLogService.updateVipCardLogByOrderId(vipCardLog);
|
|
|
// 成功返回200/204,body无需有内容
|
|
|
+ log.info("订单处理完成,订单号: {}", decryptRes.getOutTradeNo());
|
|
|
return AjaxResult.success();
|
|
|
} else {
|
|
|
+ log.warn("支付失败,订单号: {},状态: {}", decryptRes.getOutTradeNo(), decryptRes.getTradeState());
|
|
|
// 失败返回4xx或5xx,且需要构造body信息
|
|
|
return AjaxResult.error();
|
|
|
}
|
|
|
} catch (WxPayException e) {
|
|
|
+ log.error("处理微信支付回调失败", e);
|
|
|
// 失败返回4xx或5xx,且需要构造body信息
|
|
|
return AjaxResult.error("微信支付回调失败");
|
|
|
}
|
|
|
@@ -163,19 +243,28 @@ public class IWxPayService {
|
|
|
/**
|
|
|
* 处理订单支付完成后的业务逻辑
|
|
|
*
|
|
|
- * @param outTradeNo 商户订单号
|
|
|
+ * @param orderId 订单号
|
|
|
*/
|
|
|
- private void processOrderPayment(String outTradeNo) {
|
|
|
- StoreOrder order = storeOrderMapper.selectStoreOrderByOrderId(outTradeNo);
|
|
|
+ private void processOrderPayment(String orderId) {
|
|
|
+ log.info("开始处理订单支付完成逻辑,订单号: {}", orderId);
|
|
|
+ StoreOrder order = storeOrderMapper.selectStoreOrderByOrderId(orderId);
|
|
|
if (order != null) {
|
|
|
// 检查订单是否已经处理过
|
|
|
if (order.getPaid() == null || order.getPaid() != 1) {
|
|
|
+ log.info("更新订单状态为已支付,订单号: {}", orderId);
|
|
|
// 更新订单状态
|
|
|
order.setPaid(1); // 设置为已支付
|
|
|
order.setStatus(1); // 设置订单状态为已支付
|
|
|
- order.setPayTime(new java.util.Date()); // 设置支付时间
|
|
|
+ order.setPayTime(new Date()); // 设置支付时间
|
|
|
storeOrderMapper.updateStoreOrder(order);
|
|
|
+ // 从延迟队列中移除订单
|
|
|
+ removeOrderFromDelayQueue(orderId);
|
|
|
+ log.info("订单状态更新完成,订单号: {}", orderId);
|
|
|
+ } else {
|
|
|
+ log.info("订单已处理过,无需重复处理,订单号: {}", orderId);
|
|
|
}
|
|
|
+ } else {
|
|
|
+ log.warn("订单不存在,订单号: {}", orderId);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -184,6 +273,31 @@ public class IWxPayService {
|
|
|
*
|
|
|
*/
|
|
|
public WxPayRefundV3Result refund(AppRefundParam param) throws WxPayException {
|
|
|
+ log.info("开始处理退款请求,订单号: {}", param.getOrderId());
|
|
|
+ // 检查订单是否存在
|
|
|
+ StoreOrder order = storeOrderMapper.selectStoreOrderByOrderId(param.getOrderId());
|
|
|
+ if (order == null) {
|
|
|
+ log.warn("退款失败,订单不存在,订单号: {}", param.getOrderId());
|
|
|
+ throw new WxPayException("订单不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查订单是否已支付
|
|
|
+ if (order.getPaid() == null || order.getPaid() != 1) {
|
|
|
+ log.warn("退款失败,订单未支付,订单号: {}", param.getOrderId());
|
|
|
+ throw new WxPayException("订单未支付,无法退款");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查订单是否已退款
|
|
|
+ if (order.getRefundStatus() != null && order.getRefundStatus() == 2) {
|
|
|
+ log.warn("退款失败,订单已退款,订单号: {}", param.getOrderId());
|
|
|
+ throw new WxPayException("订单已退款");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查退款金额是否合法
|
|
|
+ if (param.getRefundAmount().compareTo(order.getPayPrice()) > 0) {
|
|
|
+ log.warn("退款失败,退款金额大于支付金额,订单号: {}", param.getOrderId());
|
|
|
+ throw new WxPayException("退款金额不能大于支付金额");
|
|
|
+ }
|
|
|
WxPayRefundV3Request request = new WxPayRefundV3Request();
|
|
|
//商户退款单号
|
|
|
request.setOutRefundNo(param.getOrderId());
|
|
|
@@ -201,8 +315,16 @@ public class IWxPayService {
|
|
|
request.setAmount(amount);
|
|
|
request.setNotifyUrl(wxPayProperties.getRefundNotifyUrl());
|
|
|
param.setSysMember(getSysMember(param.getUserId()));
|
|
|
- refundOrder(param);
|
|
|
- return this.wxService.refundV3(request);
|
|
|
+ // 检查是否已存在退款记录
|
|
|
+ StoreRefund existingRefund = storeRefundMapper.selectStoreRefundByOrderId(param.getOrderId());
|
|
|
+ if (existingRefund == null) {
|
|
|
+ log.info("创建退款记录,订单号: {}", param.getOrderId());
|
|
|
+ refundOrder(param);
|
|
|
+ }
|
|
|
+ log.info("调用微信退款接口,订单号: {}", param.getOrderId());
|
|
|
+ WxPayRefundV3Result result = this.wxService.refundV3(request);
|
|
|
+ log.info("微信退款接口调用完成,订单号: {}", param.getOrderId());
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -211,6 +333,7 @@ public class IWxPayService {
|
|
|
* @return 预支付交易会话标识
|
|
|
*/
|
|
|
private void refundOrder(AppRefundParam param) {
|
|
|
+ log.info("生成退款订单记录,订单号: {}", param.getOrderId());
|
|
|
StoreRefund storeRefund = new StoreRefund();
|
|
|
storeRefund.setUid(param.getSysMember().getId());
|
|
|
storeRefund.setRefundNo(generateOutTradeNo());
|
|
|
@@ -219,6 +342,7 @@ public class IWxPayService {
|
|
|
storeRefund.setRefundReason(param.getReason());
|
|
|
storeRefund.setCreateTime(new Date());
|
|
|
storeRefundMapper.insertStoreRefund(storeRefund);
|
|
|
+ log.info("退款订单记录创建完成,订单号: {}", param.getOrderId());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -227,21 +351,27 @@ public class IWxPayService {
|
|
|
* @return 处理结果
|
|
|
*/
|
|
|
public AjaxResult parseRefundNotify(String notifyData, HttpServletRequest request) {
|
|
|
+ log.info("收到微信退款回调通知");
|
|
|
SignatureHeader header = getRequestHeader(request);
|
|
|
try {
|
|
|
WxPayRefundNotifyV3Result res = this.wxService.parseRefundNotifyV3Result(notifyData, header);
|
|
|
WxPayRefundNotifyV3Result.DecryptNotifyResult decryptRes = res.getResult();
|
|
|
+ log.info("解析微信退款回调结果,订单号: {}, 退款状态: {}", decryptRes.getOutTradeNo(), decryptRes.getRefundStatus());
|
|
|
// TODO 根据自己业务场景需要构造返回对象
|
|
|
if (WxPayConstants.RefundStatus.SUCCESS.equals(decryptRes.getRefundStatus())) {
|
|
|
+ log.info("退款成功,开始处理订单,订单号: {}", decryptRes.getOutTradeNo());
|
|
|
// 成功处理订单
|
|
|
processOrderRefund(decryptRes.getOutTradeNo());
|
|
|
//成功返回200/204,body无需有内容
|
|
|
+ log.info("退款处理完成,订单号: {}", decryptRes.getOutTradeNo());
|
|
|
return AjaxResult.success();
|
|
|
} else {
|
|
|
+ log.warn("退款失败,订单号: {},状态: {}", decryptRes.getOutTradeNo(), decryptRes.getRefundStatus());
|
|
|
//失败返回4xx或5xx,且需要构造body信息
|
|
|
return AjaxResult.error();
|
|
|
}
|
|
|
} catch (WxPayException e) {
|
|
|
+ log.error("处理微信退款回调失败", e);
|
|
|
//失败返回4xx或5xx,且需要构造body信息
|
|
|
return AjaxResult.error("微信退款回调失败");
|
|
|
}
|
|
|
@@ -250,28 +380,41 @@ public class IWxPayService {
|
|
|
/**
|
|
|
* 退款完成后的业务逻辑
|
|
|
*
|
|
|
- * @param outTradeNo 商户订单号
|
|
|
+ * @param orderId 订单号
|
|
|
*/
|
|
|
- private void processOrderRefund(String outTradeNo) {
|
|
|
- StoreOrder order = storeOrderMapper.selectStoreOrderByOrderId(outTradeNo);
|
|
|
+ private void processOrderRefund(String orderId) {
|
|
|
+ log.info("开始处理订单退款完成逻辑,订单号: {}", orderId);
|
|
|
+ StoreOrder order = storeOrderMapper.selectStoreOrderByOrderId(orderId);
|
|
|
if (order != null) {
|
|
|
// 检查订单是否已经处理过
|
|
|
if (order.getRefundStatus() != null && order.getPaid() == 1) {
|
|
|
- // 更新订单状态
|
|
|
- order.setStatus(2); // 设置订单状态为已退款
|
|
|
+ log.info("更新订单状态为已退款,订单号: {}", orderId);
|
|
|
+ //更新支付订单状态为退款
|
|
|
+ order.setStatus(2); // 3表示已取消
|
|
|
order.setUpdateTime(new Date());
|
|
|
storeOrderMapper.updateStoreOrder(order);
|
|
|
+ log.info("订单状态更新完成,订单号: {}", orderId);
|
|
|
+ } else {
|
|
|
+ log.info("订单退款状态无需更新,订单号: {}", orderId);
|
|
|
}
|
|
|
+ } else {
|
|
|
+ log.warn("订单不存在,订单号: {}", orderId);
|
|
|
}
|
|
|
- StoreRefund refund = storeRefundMapper.selectStoreRefundByOrderId(outTradeNo);
|
|
|
+ StoreRefund refund = storeRefundMapper.selectStoreRefundByOrderId(orderId);
|
|
|
if (refund != null) {
|
|
|
// 检查订单是否已经处理过
|
|
|
if (refund.getRefundStatus() != null && refund.getRefundStatus().equals("1")) {
|
|
|
+ log.info("更新退款记录状态为已退款,退款单号: {}", refund.getRefundNo());
|
|
|
// 更新订单状态
|
|
|
refund.setRefundStatus("2"); // 设置订单状态为已退款
|
|
|
refund.setSuccessTime(new Date());
|
|
|
storeRefundMapper.updateStoreRefund(refund);
|
|
|
+ log.info("退款记录状态更新完成,退款单号: {}", refund.getRefundNo());
|
|
|
+ } else {
|
|
|
+ log.info("退款记录状态无需更新,退款单号: {}", refund.getRefundNo());
|
|
|
}
|
|
|
+ } else {
|
|
|
+ log.warn("退款记录不存在,订单号: {}", orderId);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -283,6 +426,7 @@ public class IWxPayService {
|
|
|
* @return
|
|
|
*/
|
|
|
private SignatureHeader getRequestHeader(HttpServletRequest request) {
|
|
|
+ log.debug("解析微信回调请求头信息");
|
|
|
// 获取通知签名
|
|
|
String signature = request.getHeader("Wechatpay-Signature");
|
|
|
String nonce = request.getHeader("Wechatpay-Nonce");
|
|
|
@@ -296,5 +440,69 @@ public class IWxPayService {
|
|
|
return signatureHeader;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 处理超时订单
|
|
|
+ * 定时任务调用此方法检查并处理超时订单
|
|
|
+ */
|
|
|
+ public void processTimeoutOrders() {
|
|
|
+ log.info("开始处理超时订单");
|
|
|
+ // 获取当前时间戳
|
|
|
+ long currentTime = System.currentTimeMillis();
|
|
|
+
|
|
|
+ // 从Redis有序集合中获取所有已超时的订单(score小于当前时间的元素)
|
|
|
+ redisTemplate.opsForZSet().rangeByScore(ORDER_DELAY_QUEUE_PREFIX + "orders", 0, currentTime)
|
|
|
+ .forEach(orderId -> {
|
|
|
+ try {
|
|
|
+ log.info("处理超时订单: {}", orderId);
|
|
|
+ // 查询订单信息
|
|
|
+ StoreOrder order = storeOrderMapper.selectStoreOrderByOrderId(orderId);
|
|
|
+ if (order != null && (order.getPaid() == null || order.getPaid() != 1)) {
|
|
|
+ // 订单未支付,执行删除操作或更新状态
|
|
|
+ // 这里我们更新订单状态为已取消
|
|
|
+ order.setStatus(3); // 3表示已取消
|
|
|
+ order.setUpdateTime(new Date());
|
|
|
+ storeOrderMapper.updateStoreOrder(order);
|
|
|
+ log.info("订单 {} 已超时,状态已更新为已取消", orderId);
|
|
|
+ } else if (order != null) {
|
|
|
+ log.info("订单 {} 已支付,无需处理", orderId);
|
|
|
+ } else {
|
|
|
+ log.warn("订单 {} 不存在", orderId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从延迟队列中移除订单
|
|
|
+ redisTemplate.opsForZSet().remove(ORDER_DELAY_QUEUE_PREFIX + "orders", orderId);
|
|
|
+ log.info("超时订单 {} 处理完成", orderId);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("处理超时订单 {} 时发生错误", orderId, e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ log.info("超时订单处理完成");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 取消订单
|
|
|
+ *
|
|
|
+ * @param orderId 订单ID
|
|
|
+ * @return 处理结果
|
|
|
+ */
|
|
|
+ public int cancelOrder(String orderId) {
|
|
|
+ StoreOrder order = storeOrderMapper.selectStoreOrderByOrderId(orderId);
|
|
|
+ order.setStatus(3); // 3表示已取消
|
|
|
+ order.setUpdateTime(new Date());
|
|
|
+ return storeOrderMapper.updateStoreOrder(order);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查订单是否在延迟队列中
|
|
|
+ *
|
|
|
+ * @param orderId 订单ID
|
|
|
+ * @return 如果订单在延迟队列中返回true,否则返回false
|
|
|
+ */
|
|
|
+ public boolean isOrderInDelayQueue(String orderId) {
|
|
|
+ // 使用rank命令检查订单是否在有序集合中
|
|
|
+ // 如果返回null,说明订单不在集合中
|
|
|
+ Long rank = redisTemplate.opsForZSet().rank(ORDER_DELAY_QUEUE_PREFIX + "orders", orderId);
|
|
|
+ return rank != null;
|
|
|
+ }
|
|
|
|
|
|
}
|