Przeglądaj źródła

盲票购票成功

chunping 3 lat temu
rodzic
commit
c8f63e3e95

+ 6 - 0
mp-admin/src/main/resources/application.yml

@@ -145,3 +145,9 @@ pay:
   channel-shopNo: 1646882813774
   channel-sign: 614140724fb74085be8aef8bebc538ed
 
+#幸运数字加密密钥对
+rsa:
+  private-key: MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJsdnYuNQGwzutcBPzVXXP9oizi5nVMlI4IohcoLH5iV2dZ39XkcWMbjithn4FBe2Y7N7lougVCRtSyOCLc63vJ9V2w7NrqHnQVIOkse9XhiBNEpQy9PKEm1lM9lZZL6fya4UDaYzGZUD9qq7FzNBBvXwhlXP3Bj4uSodf1M4HmBAgMBAAECgYB43EJ9Ebo4lLXoANi3PzL+7v5LXJTwy+c260wTeUdNJLVvHljt3OBvV6w/ofBtrvnlAx/MtJ+dn2qDJMg1vHEpWPVwTvL+8cqih5RwD6TBG9WH4ERF1fb40Z5FD+muDHK5ubgZNGicPH7T0/L6GYrGCeF9PS6sP+FvdywE5xHKgQJBANI2cpqM8B4c+LC3yQEQDJFbid1EaJEWeX9pHglAn7HhAJgpVCPO3vLainZ9Y2mgyR9ZntWW46YmtRWEOha/Lp0CQQC85u9CE1JPJGyYhIPw8+VVvdWlXzOzYIxtuQjr7ryMMYJttXLbp2q30rCRICyzsmpR26s+GXFGgo5XusvRoS81AkEAwID8EmxeuDTvyWWEvWRlHfgmGGs9FyDtwrAQwYhcthjG4pF2bBRWNy/K/Rd2opSLmhoISrETaGSqEDo2t/38QQJAK69sXWeCfXL6+jqLGMoOm0mPgvMFTdJiJ23HNmi7ieBZPW3c5hdNgr1iv+0k6Vm1ZMDcVTwlCh1fNcKpKA2SkQJBAL0DAXA26tk6LUWdBkXp54dJV/nm4/NDN6KWB+Tu5kcqteW7qCqgBToWJsxv6wLIcd5T20875gns1Btt1Vsq9Ss=
+  public-key: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbHZ2LjUBsM7rXAT81V1z/aIs4uZ1TJSOCKIXKCx+YldnWd/V5HFjG44rYZ+BQXtmOze5aLoFQkbUsjgi3Ot7yfVdsOza6h50FSDpLHvV4YgTRKUMvTyhJtZTPZWWS+n8muFA2mMxmVA/aquxczQQb18IZVz9wY+LkqHX9TOB5gQIDAQAB
+
+

+ 6 - 2
mp-common/src/main/java/com/qs/mp/common/exception/ServiceException.java

@@ -4,7 +4,7 @@ import com.qs.mp.common.enums.ErrorCodeEnum;
 
 /**
  * 业务异常
- * 
+ *
  * @author ygp
  */
 public final class ServiceException extends RuntimeException
@@ -40,6 +40,10 @@ public final class ServiceException extends RuntimeException
         this.code = errorCodeEnum.getCode();
     }
 
+    public ServiceException( String message, Throwable throwable) {
+        super(message, throwable);
+    }
+
 
     public ServiceException(String message)
     {
@@ -78,4 +82,4 @@ public final class ServiceException extends RuntimeException
         this.detailMessage = detailMessage;
         return this;
     }
-}
+}

+ 130 - 0
mp-common/src/main/java/com/qs/mp/common/utils/RSAUtil.java

@@ -0,0 +1,130 @@
+package com.qs.mp.common.utils;
+
+import com.qs.mp.common.exception.ServiceException;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+import javax.crypto.Cipher;
+import org.apache.commons.codec.binary.Base64;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RSAUtil {
+
+  private static String privateKey;
+
+  @Value("${rsa.private-key}")
+  public static void setPrivateKey(String priKey) {
+    privateKey = priKey;
+  }
+
+  private static String publicKey;
+
+  @Value("${rsa.public-key}")
+  public static void setPublicKey(String pubKey) {
+    publicKey = pubKey;
+  }
+
+  private static final Map<Integer, String> keyMap = new HashMap<Integer, String>();  //用于封装随机产生的公钥与私钥
+
+  public static void main(String[] args) throws Exception {
+    //生成公钥和私钥
+    genKeyPair();
+    //加密字符串
+    String message = "5";
+    System.out.println("随机生成的公钥为:" + keyMap.get(0));
+    System.out.println("随机生成的私钥为:" + keyMap.get(1));
+//    String messageEn = encrypt(message,keyMap.get(0));
+//    System.out.println(message + "\t加密后的字符串为:" + messageEn);
+//    String messageDe = decrypt(messageEn,keyMap.get(1));
+//    System.out.println("还原后的字符串为:" + messageDe);
+  }
+
+  /**
+   * 随机生成密钥对
+   *
+   * @throws NoSuchAlgorithmException
+   */
+  public static void genKeyPair() throws NoSuchAlgorithmException {
+    // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
+    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
+    // 初始化密钥对生成器,密钥大小为96-1024位
+    keyPairGen.initialize(1024, new SecureRandom());
+    // 生成一个密钥对,保存在keyPair中
+    KeyPair keyPair = keyPairGen.generateKeyPair();
+    RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥
+    RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥
+    String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
+    // 得到私钥字符串
+    String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
+    // 将公钥和私钥保存到Map
+    keyMap.put(0, publicKeyString);  //0表示公钥
+    keyMap.put(1, privateKeyString);  //1表示私钥
+  }
+
+  /**
+   * RSA公钥加密
+   *
+   * @param str       加密字符串
+   * @param publicKey 公钥
+   * @return 密文
+   * @throws Exception 加密过程中的异常信息
+   */
+  public static String encrypt(String str) {
+    try {
+
+      //base64编码的公钥
+      byte[] decoded = Base64.decodeBase64(publicKey);
+      RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
+          .generatePublic(new X509EncodedKeySpec(decoded));
+      //RSA加密
+      Cipher cipher = Cipher.getInstance("RSA");
+      cipher.init(Cipher.ENCRYPT_MODE, pubKey);
+      String outStr = Base64.encodeBase64String(
+          cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
+      return outStr;
+    } catch (Exception e) {
+      throw new ServiceException("加密幸运数字异常,str:" + str, e);
+    }
+  }
+
+  /**
+   * RSA私钥解密
+   *
+   * @param str        加密字符串
+   * @param privateKey 私钥
+   * @return 铭文
+   * @throws Exception 解密过程中的异常信息
+   */
+  public static String decrypt(String str) {
+    try {
+
+      //64位解码加密后的字符串
+      byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
+      //base64编码的私钥
+      byte[] decoded = Base64.decodeBase64(privateKey);
+      RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
+          .generatePrivate(new PKCS8EncodedKeySpec(decoded));
+      //RSA解密
+      Cipher cipher = Cipher.getInstance("RSA");
+      cipher.init(Cipher.DECRYPT_MODE, priKey);
+      String outStr = new String(cipher.doFinal(inputByte));
+      return outStr;
+    } catch (Exception e) {
+      throw new ServiceException("解密幸运数字异常,str:" + str, e);
+    }
+  }
+
+}
+
+

+ 13 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/Goods.java

@@ -80,6 +80,19 @@ public class Goods implements Serializable {
   @TableField("exchanged_qty")
   private Integer exchangedQty;
 
+  /**
+   * 兑换大厅是否展示,0不展示,1展示
+   */
+  @TableField("exchange_show")
+  private Integer exchangeShow;
+
+  /**
+   * 是否多sku,0否,1是
+   */
+  @TableField("multi_sku")
+  private Integer multiSku;
+
+
   /**
    * 上架状态;上架/下架
    */

+ 2 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/Ticket.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
 import com.qs.mp.common.enums.TicketStatusEnum;
 import java.io.Serializable;
 import java.util.Date;
@@ -99,6 +100,7 @@ public class Ticket implements Serializable {
    * 更新时间
    */
   @TableField("UPDATED_TIME")
+  @Version
   private Date updatedTime;
 
 

+ 7 - 1
mp-service/src/main/java/com/qs/mp/admin/mapper/TicketMapper.java

@@ -1,7 +1,13 @@
 package com.qs.mp.admin.mapper;
 
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
 import com.qs.mp.admin.domain.Ticket;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qs.mp.admin.domain.TicketAwardsPrize;
+import com.qs.mp.admin.domain.vo.TicketAwardsPrizeVO;
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * @auther quanshu
@@ -9,5 +15,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  * @describe 盲票mapper类
  */
 public interface TicketMapper extends BaseMapper<Ticket> {
-
+  Ticket getRandOne(@Param(Constants.WRAPPER) Wrapper<Ticket> queryWrapper);
 }

+ 9 - 0
mp-service/src/main/java/com/qs/mp/admin/service/ITicketService.java

@@ -1,7 +1,10 @@
 package com.qs.mp.admin.service;
 
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
 import com.qs.mp.admin.domain.Ticket;
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * <p>
@@ -13,4 +16,10 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface ITicketService extends IService<Ticket> {
 
+  /**
+   * 随机取一条
+   * @param queryWrapper
+   * @return
+   */
+  Ticket getRandOne(@Param(Constants.WRAPPER) Wrapper<Ticket> queryWrapper);
 }

+ 5 - 0
mp-service/src/main/java/com/qs/mp/admin/service/impl/TicketServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qs.mp.admin.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.qs.mp.admin.domain.Ticket;
 import com.qs.mp.admin.mapper.TicketMapper;
 import com.qs.mp.admin.service.ITicketService;
@@ -17,4 +18,8 @@ import org.springframework.stereotype.Service;
 @Service
 public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> implements ITicketService {
 
+  @Override
+  public Ticket getRandOne(Wrapper<Ticket> queryWrapper) {
+    return getBaseMapper().getRandOne(queryWrapper);
+  }
 }

+ 2 - 0
mp-service/src/main/java/com/qs/mp/user/domain/UserTicketOrder.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
 import com.qs.mp.admin.domain.Ticket;
 import com.qs.mp.common.enums.TicketTypeEnum;
 import com.qs.mp.common.enums.UserTicketOrderStatusEnum;
@@ -107,6 +108,7 @@ public class UserTicketOrder implements Serializable {
    * 更新时间
    */
   @TableField("updated_time")
+  @Version
   private Date updatedTime;
 
 

+ 2 - 0
mp-service/src/main/java/com/qs/mp/user/domain/UserTicketOrderItem.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
 import java.io.Serializable;
 import java.util.Date;
 import lombok.Data;
@@ -65,6 +66,7 @@ public class UserTicketOrderItem implements Serializable {
    * 更新时间
    */
   @TableField("updated_time")
+  @Version
   private Date updatedTime;
 
 

+ 78 - 50
mp-service/src/main/java/com/qs/mp/user/service/impl/UserTicketOrderServiceImpl.java

@@ -2,15 +2,15 @@ package com.qs.mp.user.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qs.mp.admin.domain.Ticket;
 import com.qs.mp.admin.domain.TicketBox;
 import com.qs.mp.admin.service.ITicketBoxService;
 import com.qs.mp.admin.service.ITicketService;
-import com.qs.mp.channel.domain.ChannelOrder;
 import com.qs.mp.channel.domain.ChannelUserRel;
 import com.qs.mp.channel.service.IChannelUserRelService;
-import com.qs.mp.common.enums.ChannelOrderStatusEnum;
 import com.qs.mp.common.enums.TicketBoxStatusEnum;
 import com.qs.mp.common.enums.TicketStatusEnum;
 import com.qs.mp.common.enums.TicketTypeEnum;
@@ -18,6 +18,7 @@ import com.qs.mp.common.enums.UserCouponStatusEnum;
 import com.qs.mp.common.enums.UserTicketOrderStatusEnum;
 import com.qs.mp.common.exception.ServiceException;
 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.pay.domain.PayOrder;
 import com.qs.mp.system.service.id.BizIdGenerator;
@@ -30,8 +31,6 @@ import com.qs.mp.user.mapper.UserTicketOrderMapper;
 import com.qs.mp.user.service.IUserCouponService;
 import com.qs.mp.user.service.IUserTicketOrderItemService;
 import com.qs.mp.user.service.IUserTicketOrderService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
@@ -40,6 +39,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.Assert;
 
 /**
  * <p>
@@ -50,7 +50,8 @@ import org.springframework.transaction.annotation.Transactional;
  * @since 2022-03-07
  */
 @Service
-public class UserTicketOrderServiceImpl extends ServiceImpl<UserTicketOrderMapper, UserTicketOrder> implements IUserTicketOrderService {
+public class UserTicketOrderServiceImpl extends
+    ServiceImpl<UserTicketOrderMapper, UserTicketOrder> implements IUserTicketOrderService {
 
   protected final Logger logger = LoggerFactory.getLogger(this.getClass());
 
@@ -71,10 +72,11 @@ public class UserTicketOrderServiceImpl extends ServiceImpl<UserTicketOrderMappe
 
   @Autowired
   private BizIdGenerator bizIdGenerator;
+
   @Override
   @Transactional
   public String submitOrder(Long userId, TicketOrderSettleVO orderSettleVO) {
-    if (StringUtils.isNotBlank(orderSettleVO.getBoxId())){
+    if (StringUtils.isNotBlank(orderSettleVO.getBoxId())) {
       return createOnlineOrder(userId, orderSettleVO);
     }
 
@@ -85,17 +87,23 @@ public class UserTicketOrderServiceImpl extends ServiceImpl<UserTicketOrderMappe
   private String createOnlineOrder(Long userId, TicketOrderSettleVO orderSettleVO) {
     // 线上票更新票组销量,防止超卖
     TicketBox ticketBox = ticketBoxService.getById(orderSettleVO.getBoxId());
-    if (ticketBox.getStatus() == TicketBoxStatusEnum.PUT_OFF || ticketBox.getSaleQty() + orderSettleVO.getOrderNum() > ticketBox.getQuantity()) {
-      LogUtil.error(logger, "库存不足,boxId:{0},qty:{1},saleQty:{2},orderNum:{3}", new Object[]{ticketBox.getBoxId(), ticketBox.getQuantity(), ticketBox.getSaleQty(), orderSettleVO.getOrderNum()});
+    if (ticketBox.getStatus() == TicketBoxStatusEnum.PUT_OFF
+        || ticketBox.getSaleQty() + orderSettleVO.getOrderNum() > ticketBox.getQuantity()) {
+      LogUtil.error(logger, "库存不足,boxId:{0},qty:{1},saleQty:{2},orderNum:{3}",
+          ticketBox.getBoxId(), ticketBox.getQuantity(), ticketBox.getSaleQty(),
+          orderSettleVO.getOrderNum());
       throw new ServiceException("库存不足");
     }
-    boolean rst = ticketBoxService.update(new LambdaUpdateWrapper<TicketBox>().set(TicketBox::getSaleQty, ticketBox.getSaleQty() + orderSettleVO.getOrderNum())
-            .set(ticketBox.getSaleQty() + orderSettleVO.getOrderNum() == ticketBox.getQuantity(),TicketBox::getStatus, TicketBoxStatusEnum.PUT_OFF)
-        .eq(TicketBox::getBoxId, ticketBox.getBoxId()).eq(TicketBox::getSaleQty, ticketBox.getSaleQty()));
-    if (!rst) {
-      LogUtil.error(logger, "盲票购买订单创建时,更新盲票销量失败。boxId:{0}, saleQty:{1}", new Object[]{ticketBox.getBoxId(), ticketBox.getSaleQty()});
-      throw new ServiceException("盲票购买订单创建时,更新盲票销量失败");
-    }
+    boolean rst = ticketBoxService.update(
+        new LambdaUpdateWrapper<TicketBox>().set(TicketBox::getSaleQty,
+                ticketBox.getSaleQty() + orderSettleVO.getOrderNum())
+            .set(ticketBox.getSaleQty() + orderSettleVO.getOrderNum() == ticketBox.getQuantity(),
+                TicketBox::getStatus, TicketBoxStatusEnum.PUT_OFF)
+            .eq(TicketBox::getBoxId, ticketBox.getBoxId())
+            .eq(TicketBox::getSaleQty, ticketBox.getSaleQty()));
+    Assert.isTrue(rst,
+        "盲票购买订单创建时,更新盲票销量失败。boxId:" + ticketBox.getBoxId() + "saleQty:" + ticketBox.getSaleQty());
+
     // 核销优惠券
     String couponIds = verifyUserCoupon(orderSettleVO.getCouponList());
 
@@ -116,8 +124,9 @@ public class UserTicketOrderServiceImpl extends ServiceImpl<UserTicketOrderMappe
     save(userTicketOrder);
 
     // 查询用户的所属经销商,线上票直接查询
-    ChannelUserRel channelUserRel = channelUserRelService.getOne(new LambdaQueryWrapper<ChannelUserRel>()
-        .eq(ChannelUserRel::getUserId, userId));
+    ChannelUserRel channelUserRel = channelUserRelService.getOne(
+        new LambdaQueryWrapper<ChannelUserRel>()
+            .eq(ChannelUserRel::getUserId, userId));
     for (int i = 0; i < orderSettleVO.getOrderNum(); i++) {
       UserTicketOrderItem orderItem = new UserTicketOrderItem();
       orderItem.setItemId(bizIdGenerator.newId());
@@ -133,9 +142,9 @@ public class UserTicketOrderServiceImpl extends ServiceImpl<UserTicketOrderMappe
 
   private String createOfflineOrder(Long userId, TicketOrderSettleVO orderSettleVO) {
     Ticket ticket = ticketService.getById(orderSettleVO.getTicketId());
-    if (ticket.getStatus() != TicketStatusEnum.NOT_PAY) {
-      LogUtil.error(logger, "盲票已付款,ticketId:{0},status:{1}", new Object[]{ticket.getTicketId(), ticket.getStatus()});
-    }
+    Assert.isTrue(ticket.getStatus() == TicketStatusEnum.NOT_PAY,
+        "盲票已付款,ticketId:" + ticket.getTicketId());
+
     // 核销优惠券
     String couponIds = verifyUserCoupon(orderSettleVO.getCouponList());
 
@@ -155,8 +164,9 @@ public class UserTicketOrderServiceImpl extends ServiceImpl<UserTicketOrderMappe
     save(ticketOrder);
 
     // 查询用户的所属经销商,线上票直接查询
-    ChannelUserRel channelUserRel = channelUserRelService.getOne(new LambdaQueryWrapper<ChannelUserRel>()
-        .eq(ChannelUserRel::getUserId, userId));
+    ChannelUserRel channelUserRel = channelUserRelService.getOne(
+        new LambdaQueryWrapper<ChannelUserRel>()
+            .eq(ChannelUserRel::getUserId, userId));
     UserTicketOrderItem orderItem = new UserTicketOrderItem();
     orderItem.setItemId(bizIdGenerator.newId());
     orderItem.setOrderId(ticketOrder.getOrderId());
@@ -168,21 +178,18 @@ public class UserTicketOrderServiceImpl extends ServiceImpl<UserTicketOrderMappe
     return ticketOrder.getOrderId();
   }
 
-  private String verifyUserCoupon (List<UserCouponVO> userCouponVOList) {
+  private String verifyUserCoupon(List<UserCouponVO> userCouponVOList) {
     StringBuilder sb = new StringBuilder();
     for (UserCouponVO userCouponVO : userCouponVOList) {
       UserCoupon userCoupon = userCouponService.getById(userCouponVO.getId());
       userCoupon.setVerifyTime(new Date());
       userCoupon.setStatus(UserCouponStatusEnum.USED);
       boolean rst = userCouponService.updateById(userCoupon);
-      if (!rst) {
-        LogUtil.error(logger, "盲票购买订单创建时,核销优惠券失败。userCoupon:{0}", new Object[]{JSONObject.toJSONString(userCoupon)});
-        throw new ServiceException("盲票购买订单创建时,核销优惠券失败");
-      }
+      Assert.isTrue(rst, "盲票购买订单创建时,核销优惠券失败。userCoupon:" + JSONObject.toJSONString(userCoupon));
       sb.append(userCouponVO.getId()).append(",");
     }
     if (sb.length() > 0) {
-      return sb.substring(0, sb.length() -1);
+      return sb.substring(0, sb.length() - 1);
     }
     return sb.toString();
   }
@@ -192,7 +199,8 @@ public class UserTicketOrderServiceImpl extends ServiceImpl<UserTicketOrderMappe
   public boolean cancelOrder(String orderId) {
     UserTicketOrder userTicketOrder = getById(orderId);
     if (userTicketOrder.getStatus() != UserTicketOrderStatusEnum.NOT_PAY) {
-      LogUtil.warn(logger, "取消购票订单时,订单状态不是待支付,忽略。orderId:{0}, status:{1}", new Object[]{orderId, userTicketOrder.getStatus()});
+      LogUtil.warn(logger, "取消购票订单时,订单状态不是待支付,忽略。orderId:{0}, status:{1}",
+          orderId, userTicketOrder.getStatus());
       return false;
     }
 
@@ -203,26 +211,28 @@ public class UserTicketOrderServiceImpl extends ServiceImpl<UserTicketOrderMappe
           .set(UserCoupon::getStatus, UserCouponStatusEnum.UNUSED)
           .set(UserCoupon::getVerifyTime, null)
           .in(UserCoupon::getId, userCouponIds));
-      if (!rst) {
-        LogUtil.error(logger, "盲票购买订单取消时,反核销优惠券失败。orderId:{0}, userCouponIds:{1}", new Object[]{orderId, userTicketOrder.getCouponInfo()});
-        throw new ServiceException("盲票购买订单取消时,反核销优惠券失败");
-      }
+      Assert.isTrue(rst, "盲票购买订单取消时,反核销优惠券失败。orderId:" + orderId + "userCouponIds:"
+          + userTicketOrder.getCouponInfo());
     }
     if (userTicketOrder.getResource() == TicketTypeEnum.ONLINE) {
       // TODO 线上票库存回滚,此处需要按票组累计起来回滚
       TicketBox ticketBox = ticketBoxService.getById(userTicketOrder.getBoxId());
-      ticketBoxService.update(new LambdaUpdateWrapper<TicketBox>().set(TicketBox::getSaleQty, ticketBox.getSaleQty() - userTicketOrder.getTicketNum())
-          .set(ticketBox.getStatus() == TicketBoxStatusEnum.PUT_OFF && ticketBox.getManualOff() != 1,TicketBox::getStatus, TicketBoxStatusEnum.PUT_ON)
-          .eq(TicketBox::getBoxId, ticketBox.getBoxId()).eq(TicketBox::getSaleQty, ticketBox.getSaleQty()));
+      ticketBoxService.update(new LambdaUpdateWrapper<TicketBox>().set(TicketBox::getSaleQty,
+              ticketBox.getSaleQty() - userTicketOrder.getTicketNum())
+          .set(
+              ticketBox.getStatus() == TicketBoxStatusEnum.PUT_OFF && ticketBox.getManualOff() != 1,
+              TicketBox::getStatus, TicketBoxStatusEnum.PUT_ON)
+          .eq(TicketBox::getBoxId, ticketBox.getBoxId())
+          .eq(TicketBox::getSaleQty, ticketBox.getSaleQty()));
 
     }
 
-    boolean rst = update(new LambdaUpdateWrapper<UserTicketOrder>().set(UserTicketOrder::getStatus, UserTicketOrderStatusEnum.CANCELED)
-        .eq(UserTicketOrder::getOrderId, orderId).eq(UserTicketOrder::getStatus, UserTicketOrderStatusEnum.NOT_PAY));
-    if (!rst) {
-      LogUtil.error(logger, "盲票购买订单取消时,更新订单状态失败。orderId:{0}", orderId);
-      throw new ServiceException("盲票购买订单取消时,更新订单状态失败");
-    }
+    boolean rst = update(new LambdaUpdateWrapper<UserTicketOrder>().set(UserTicketOrder::getStatus,
+            UserTicketOrderStatusEnum.CANCELED)
+        .eq(UserTicketOrder::getOrderId, orderId)
+        .eq(UserTicketOrder::getStatus, UserTicketOrderStatusEnum.NOT_PAY));
+    Assert.isTrue(rst, "盲票购买订单取消时,更新订单状态失败。orderId:" + orderId);
+
     return true;
   }
 
@@ -234,15 +244,33 @@ public class UserTicketOrderServiceImpl extends ServiceImpl<UserTicketOrderMappe
           JSONObject.toJSONString(payOrder), JSONObject.toJSONString(ticketOrder));
       throw new ServiceException("支付回调用户购票订单处理,订单状态异常,不是待支付。orderId:" + payOrder.getBizId());
     }
-    // 线上票,要先分配票ticketId
-    if (ticketOrder.getResource() == TicketTypeEnum.ONLINE) {
-      List<UserTicketOrderItem> orderItemList = userTicketOrderItemService.list(new LambdaQueryWrapper<UserTicketOrderItem>()
-          .eq(UserTicketOrderItem::getOrderId, ticketOrder.getOrderId()));
-    }
-    // 更新订单状态为已完成
+    List<UserTicketOrderItem> orderItemList = userTicketOrderItemService.list(
+        new LambdaQueryWrapper<UserTicketOrderItem>()
+            .eq(UserTicketOrderItem::getOrderId, ticketOrder.getOrderId()));
 
-    // 开幸运数字
+    for (UserTicketOrderItem orderItem : orderItemList) {
+      Ticket ticket;
+      if (ticketOrder.getResource() == TicketTypeEnum.ONLINE) {
+        // 线上票,要先分配票ticketId
+        ticket = ticketService.getRandOne(new QueryWrapper<Ticket>()
+            .eq("box_id", ticketOrder.getBoxId()).eq("status", TicketStatusEnum.NOT_PAY));
+        orderItem.setTicketId(ticket.getTicketId());
+        boolean rst = userTicketOrderItemService.updateById(orderItem);
+        Assert.isTrue(rst, "支付回调用户购票订单处理,更新订单明细的盲票ID失败,itemId:" + orderItem.getItemId());
+      } else {
+        ticket = ticketService.getById(orderItem.getTicketId());
+      }
+      // 开幸运数字,更新ticket状态为已激活
+      ticket.setPlainLuckyNum(Integer.valueOf(RSAUtil.decrypt(ticket.getCipherLuckyNum())));
+      ticket.setStatus(TicketStatusEnum.ACTIVATED);
+      boolean rtn = ticketService.updateById(ticket);
+      Assert.isTrue(rtn, "支付回调用户购票订单处理,更新盲票状态失败,ticketId:" + ticket.getTicketId());
+    }
 
-    return false;
+    // 更新订单状态为已完成
+    ticketOrder.setStatus(UserTicketOrderStatusEnum.FINISHED);
+    boolean updateRst = updateById(ticketOrder);
+    Assert.isTrue(updateRst, "支付回调用户购票订单处理,更新订单状态失败,orderId:" + ticketOrder.getOrderId());
+    return true;
   }
 }

+ 3 - 1
mp-service/src/main/resources/mapper/admin/GoodsMapper.xml

@@ -15,6 +15,8 @@
         <result column="quantity" property="quantity" />
         <result column="exchanged_qty" property="exchangedQty" />
         <result column="status" property="status" />
+        <result column="exchange_show" property="exchangeShow" />
+        <result column="multi_sku" property="multiSku" />
         <result column="is_deleted" property="isDeleted" />
         <result column="created_time" property="createdTime" />
         <result column="updated_time" property="updatedTime" />
@@ -22,7 +24,7 @@
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        goods_id, title, category_id, pic_url, description, origin_price, exchange_price, value, quantity, exchanged_qty, status, is_deleted, created_time, updated_time
+        goods_id, title, category_id, pic_url, description, origin_price, exchange_price, value, quantity, exchanged_qty, status, exchange_show, multi_sku, is_deleted, created_time, updated_time
     </sql>
 
 </mapper>

+ 8 - 1
mp-service/src/main/resources/mapper/admin/TicketMapper.xml

@@ -24,4 +24,11 @@
         ticket_id, box_id, pkg_id, title, serial_no, face_price, cipher_lucky_num, plain_lucky_num, draw_num, IS_PHYSICAL, STATUS, CREATED_TIME, UPDATED_TIME
     </sql>
 
-</mapper>
+    <select id="getRandOne" resultMap="BaseResultMap">
+        select *
+        from mp_ticket
+        ${ew.customSqlSegment}
+        order by rand() limit 1
+    </select>
+
+</mapper>