فهرست منبع

盲票购买订单支付优化

chunping 3 سال پیش
والد
کامیت
617c69aa44

+ 11 - 0
mp-admin/src/main/java/com/qs/mp/web/controller/api/callback/PayCallBackController.java

@@ -1,6 +1,8 @@
 package com.qs.mp.web.controller.api.callback;
 
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.qs.mp.common.enums.PayOrderStatusEnum;
+import com.qs.mp.common.exception.ServiceException;
 import com.qs.mp.common.utils.LogUtil;
 import com.qs.mp.common.utils.StringUtils;
 import com.qs.mp.common.utils.WebhookService;
@@ -79,6 +81,15 @@ public class PayCallBackController {
     payOrder.setOrderStatus(orderStatus);
 
     try {
+      // 订单支付状态单独保存
+      LambdaUpdateWrapper<PayOrder> updateWrapper = new LambdaUpdateWrapper<>();
+      updateWrapper.eq(PayOrder::getOrderStatus, PayOrderStatusEnum.WAIT.getValue());
+      updateWrapper.eq(PayOrder::getOrderId, orderNo);
+      boolean ret = payOrderService.update(payOrder, updateWrapper);
+      if (!ret) {
+        throw new ServiceException("支付订单更新失败,orderNo:" + orderNo);
+      }
+
       // 更新订单,单个事务处理
       logger.info("支付回调消息更新成功 shopOrderNo:"+shopOrderNo);
       walletService.payOrderStatusHandle(payOrder);

+ 11 - 0
mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserTicketOrderController.java

@@ -15,8 +15,10 @@ import com.qs.mp.common.core.redis.RedisCache;
 import com.qs.mp.common.enums.BizTypeEnum;
 import com.qs.mp.common.enums.CouponUseAreaEnum;
 import com.qs.mp.common.enums.ErrorCodeEnum;
+import com.qs.mp.common.enums.MqTopicType;
 import com.qs.mp.common.enums.TicketTypeEnum;
 import com.qs.mp.common.exception.ServiceException;
+import com.qs.mp.common.pulsar.PulsarClientService;
 import com.qs.mp.common.utils.LogUtil;
 import com.qs.mp.common.utils.StringUtils;
 import com.qs.mp.framework.redis.RedisKey;
@@ -41,6 +43,7 @@ import java.util.concurrent.TimeUnit;
 import javax.validation.Valid;
 import lombok.AllArgsConstructor;
 import ma.glasnost.orika.MapperFacade;
+import org.apache.pulsar.client.api.PulsarClientException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -80,6 +83,9 @@ public class UserTicketOrderController extends BaseApiController {
   @Autowired
   private RedisCache redisCache;
 
+  @Autowired
+  private PulsarClientService pulsarClientService;
+
 
   /**
    * 订单结算,每次更换优惠券时需重新请求此接口
@@ -159,6 +165,11 @@ public class UserTicketOrderController extends BaseApiController {
       jsonObject.put("needPay", 1);
     } else {
       jsonObject.put("needPay", 0);
+      try {
+          pulsarClientService.producer(MqTopicType.ticket_pay, orderId);
+      } catch (PulsarClientException e) {
+        LogUtil.error(logger, e, "盲票支付成功,发送异步消息失败. orderId:{0}", orderId);
+      }
     }
     // 清除缓存的订单
     redisCache.deleteObject(RedisKey.build(RedisKey.USER_TICKET_ORDER_KEY, userId));

+ 1 - 1
mp-common/src/main/java/com/qs/mp/common/pulsar/PulsarClientService.java

@@ -143,7 +143,7 @@ public class PulsarClientService {
     Producer<byte[]> finalProducer = producer;
     messageIdFuture.whenComplete(((messageId, throwable) -> {
       if (null != throwable) {
-        logger.error("【消息投递异常,开始重试】", throwable);
+        logger.error("【消息投递异常,开始重试】mq data:" + data, throwable);
         //todo 失败重试策略
         try {
           finalProducer.newMessage().deliverAfter(5, TimeUnit.SECONDS

+ 2 - 1
mp-service/src/main/java/com/qs/mp/framework/redis/RedisKey.java

@@ -12,7 +12,8 @@ public enum RedisKey {
     WX_APP_TOKEN_KEY("app_token_key_{0}", "小程序app token"),
     CHANNEL_ORDER_KEY("channel_order_{0}", "经销商下的盲票采购单"),
     USER_TICKET_ORDER_KEY("user_ticket_order_key_{0}", "用户购票订单"),
-    USER_DELIVER_ORDER_KEY("user_deliver_order_key_{0}", "用户提货订单");
+    USER_DELIVER_ORDER_KEY("user_deliver_order_key_{0}", "用户提货订单"),
+    OFFLINE_TICKET_ID_KEY("offline_ticket_id_key_{0}", "线下盲票ID"),;
 
     public String keyTemplate;
     public String desc;

+ 11 - 0
mp-service/src/main/java/com/qs/mp/mq/impl/PulsarConsumerImpl.java

@@ -8,6 +8,7 @@ import com.qs.mp.admin.service.ITicketBoxService;
 import com.qs.mp.common.enums.CommStatusEnum;
 import com.qs.mp.common.enums.MqTopicType;
 import com.qs.mp.common.enums.TicketBoxStatusEnum;
+import com.qs.mp.common.enums.TicketTypeEnum;
 import com.qs.mp.common.enums.UserTicketOrderStatusEnum;
 import com.qs.mp.common.pulsar.PulsarConsumer;
 import com.qs.mp.common.utils.LogUtil;
@@ -51,6 +52,16 @@ public class PulsarConsumerImpl implements PulsarConsumer {
   private void processTicketPayMsg(String mqData) {
     String orderId = mqData;
     UserTicketOrder ticketOrder = userTicketOrderService.getById(orderId);
+
+    TicketBox ticketBox = ticketBoxService.getById(ticketOrder.getBoxId());
+    if (ticketBox.getType() == TicketTypeEnum.OFFLINE) {
+      // 线下票更新销量,此处不做乐观锁控制,因为不用控制库存
+      ticketBoxService.update(
+          new LambdaUpdateWrapper<TicketBox>().set(TicketBox::getSaleQty,
+                  ticketBox.getSaleQty() + 1)
+              .eq(TicketBox::getBoxId, ticketBox.getBoxId()));
+    }
+
     if (ticketOrder.getCommStatus() != CommStatusEnum.NO) {
       LogUtil.warn(logger, "收到盲票支付成功消息,订单结佣状态不是未结佣,忽略消息。orderId=" + orderId);
       return;

+ 15 - 10
mp-service/src/main/java/com/qs/mp/pay/service/impl/WalletServiceImpl.java

@@ -5,8 +5,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.qs.mp.channel.service.IChannelOrderService;
 import com.qs.mp.common.enums.BizTypeEnum;
+import com.qs.mp.common.enums.MqTopicType;
 import com.qs.mp.common.enums.PayOrderStatusEnum;
 import com.qs.mp.common.exception.ServiceException;
+import com.qs.mp.common.pulsar.PulsarClientService;
 import com.qs.mp.common.utils.DateUtils;
 import com.qs.mp.common.utils.LogUtil;
 import com.qs.mp.common.utils.StringUtils;
@@ -18,6 +20,7 @@ import com.qs.mp.system.service.id.BizIdGenerator;
 import com.qs.mp.user.service.IUserDeliverOrderService;
 import com.qs.mp.user.service.IUserTicketOrderService;
 import java.util.List;
+import org.apache.pulsar.client.api.PulsarClientException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -48,6 +51,9 @@ public class WalletServiceImpl implements IWalletService {
   @Autowired
   private IUserDeliverOrderService userDeliverOrderService;
 
+  @Autowired
+  private PulsarClientService pulsarClientService;
+
   @Autowired
   private BizIdGenerator bizIdGenerator;
 
@@ -121,17 +127,9 @@ public class WalletServiceImpl implements IWalletService {
   }
 
   @Override
-  @Transactional
   public void payOrderStatusHandle(PayOrder payOrder) {
     String orderNo = payOrder.getOrderId();
-    // 订单支付状态单独保存
-    LambdaUpdateWrapper<PayOrder> updateWrapper = new LambdaUpdateWrapper<>();
-    updateWrapper.eq(PayOrder::getOrderStatus, PayOrderStatusEnum.WAIT.getValue());
-    updateWrapper.eq(PayOrder::getOrderId, orderNo);
-    boolean ret = payOrderService.update(payOrder, updateWrapper);
-    if (!ret) {
-      throw new ServiceException("支付订单更新失败,orderNo:" + orderNo);
-    }
+
     //查询统一支付订单表,查询订单类型,然后根据不同类型做对应的逻辑处理
     //查询支付状态为1:支付成功,2:订单创建成功,等待支付。
     PayOrder order = payOrderService.getById(orderNo);
@@ -142,7 +140,14 @@ public class WalletServiceImpl implements IWalletService {
       channelOrderService.paySuccess(order);
     } else if (BizTypeEnum.TICKET_ORDER == order.getBizType()) {
       // 用户盲票购买订单支付成功,调用业务订单服务处理
-      userTicketOrderService.paySuccess(order);
+      boolean rst = userTicketOrderService.paySuccess(order);
+      try {
+        if (rst) {
+          pulsarClientService.producer(MqTopicType.ticket_pay, order.getBizId());
+        }
+      } catch (PulsarClientException e) {
+        LogUtil.error(logger, e, "盲票支付成功,发送异步消息失败. orderId:{0}", order.getBizId());
+      }
     } else if (BizTypeEnum.DELIVER_ORDER == order.getBizType()) {
       // 用户提货订单支付成功,调用业务订单服务处理
       userDeliverOrderService.paySuccess(order);

+ 11 - 14
mp-service/src/main/java/com/qs/mp/user/service/impl/UserTicketOrderServiceImpl.java

@@ -21,6 +21,7 @@ import com.qs.mp.channel.service.IChannelMoneyLogService;
 import com.qs.mp.channel.service.IChannelOrderDetailService;
 import com.qs.mp.channel.service.IChannelService;
 import com.qs.mp.channel.service.IChannelUserRelService;
+import com.qs.mp.common.core.redis.RedisCache;
 import com.qs.mp.common.enums.ChannelMoneyEnum;
 import com.qs.mp.common.enums.CommStatusEnum;
 import com.qs.mp.common.enums.ErrorCodeEnum;
@@ -35,6 +36,7 @@ import com.qs.mp.common.pulsar.PulsarClientService;
 import com.qs.mp.common.utils.LogUtil;
 import com.qs.mp.common.utils.RSAUtil;
 import com.qs.mp.common.utils.StringUtils;
+import com.qs.mp.framework.redis.RedisKey;
 import com.qs.mp.pay.domain.PayOrder;
 import com.qs.mp.system.service.id.BizIdGenerator;
 import com.qs.mp.user.domain.UserCoupon;
@@ -54,6 +56,7 @@ import java.math.RoundingMode;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 import org.apache.pulsar.client.api.PulsarClientException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -94,9 +97,6 @@ public class UserTicketOrderServiceImpl extends
   @Autowired
   private ITicketService ticketService;
 
-  @Autowired
-  private PulsarClientService pulsarClientService;
-
   @Autowired
   private IChannelService channelService;
 
@@ -109,6 +109,9 @@ public class UserTicketOrderServiceImpl extends
   @Autowired
   private BizIdGenerator bizIdGenerator;
 
+  @Autowired
+  private RedisCache redisCache;
+
   @Override
   @Transactional
   public String submitOrder(Long userId, TicketOrderSettleVO orderSettleVO, UserShareVO userShareVO) {
@@ -213,6 +216,11 @@ public class UserTicketOrderServiceImpl extends
     Ticket ticket = ticketService.getById(orderSettleVO.getTicketId());
     Assert.isTrue(ticket.getStatus() == TicketStatusEnum.NOT_PAY,
         "盲票已付款,ticketId:" + ticket.getTicketId());
+    if (redisCache.getCacheObject(RedisKey.build(RedisKey.OFFLINE_TICKET_ID_KEY, ticket.getTicketId()))) {
+      LogUtil.error(logger, "线下盲票重复购买,ticketNo:", ticket.getSerialNo());
+      throw new ServiceException("重复购买,请稍后再试");
+    }
+    redisCache.setCacheObject(RedisKey.build(RedisKey.OFFLINE_TICKET_ID_KEY, ticket.getTicketId()), userId, 5, TimeUnit.MINUTES);
 
     // 核销优惠券
     String couponIds = verifyUserCoupon(orderSettleVO.getCouponList());
@@ -373,11 +381,6 @@ public class UserTicketOrderServiceImpl extends
         Assert.isTrue(rst, "支付回调用户购票订单处理,更新订单明细的盲票ID失败,itemId:" + orderItem.getItemId());
       } else {
         ticket = ticketService.getById(orderItem.getTicketId());
-        // 线下票更新销量,此处不做乐观锁控制,因为不用控制库存
-        TicketBox ticketBox = ticketBoxService.getById(ticket.getBoxId());
-        ticketBoxService.update(
-            new LambdaUpdateWrapper<TicketBox>().set(TicketBox::getSaleQty, ticketBox.getSaleQty() + 1)
-                .eq(TicketBox::getBoxId, ticketBox.getBoxId()));
       }
       // 开幸运数字,更新ticket状态为已激活
       boolean rtn = ticketService.update(
@@ -396,12 +399,6 @@ public class UserTicketOrderServiceImpl extends
             .eq(UserTicketOrder::getStatus, UserTicketOrderStatusEnum.NOT_PAY));
     Assert.isTrue(updateRst, "支付回调用户购票订单处理,更新订单状态失败,orderId:" + ticketOrder.getOrderId());
 
-    try {
-      pulsarClientService.producer(MqTopicType.ticket_pay, ticketOrder.getOrderId());
-    } catch (PulsarClientException e) {
-      LogUtil.error(logger, e, "盲票支付成功,发送异步消息失败. {0}", JSONObject.toJSONString(ticketOrder));
-    }
-
     return true;
   }