chunping 3 年之前
父节点
当前提交
2cf56f7efa

+ 14 - 3
mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserTicketController.java

@@ -19,6 +19,7 @@ import com.qs.mp.common.enums.ErrorCodeEnum;
 import com.qs.mp.common.enums.TicketBoxStatusEnum;
 import com.qs.mp.common.enums.TicketBoxStatusEnum;
 import com.qs.mp.common.enums.TicketStatusEnum;
 import com.qs.mp.common.enums.TicketStatusEnum;
 import com.qs.mp.common.utils.StringUtils;
 import com.qs.mp.common.utils.StringUtils;
+import com.qs.mp.user.domain.UserDeliverOrderItem;
 import com.qs.mp.user.domain.UserTicketOrderItem;
 import com.qs.mp.user.domain.UserTicketOrderItem;
 import com.qs.mp.user.service.IUserHitPrizeService;
 import com.qs.mp.user.service.IUserHitPrizeService;
 import com.qs.mp.user.service.IUserTicketOrderItemService;
 import com.qs.mp.user.service.IUserTicketOrderItemService;
@@ -30,6 +31,7 @@ import java.util.List;
 import lombok.AllArgsConstructor;
 import lombok.AllArgsConstructor;
 import ma.glasnost.orika.MapperFacade;
 import ma.glasnost.orika.MapperFacade;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -150,11 +152,20 @@ public class UserTicketController extends BaseApiController {
   @ApiOperation(value = "查看兑奖奖品" , notes = "根据盲票ID,查看兑奖奖品")
   @ApiOperation(value = "查看兑奖奖品" , notes = "根据盲票ID,查看兑奖奖品")
   public AjaxResult queryHitPrizeList(@RequestBody TicketParam param) {
   public AjaxResult queryHitPrizeList(@RequestBody TicketParam param) {
     Long userId = SecurityUtils.getLoginUser().getUserId();
     Long userId = SecurityUtils.getLoginUser().getUserId();
-    if (StringUtils.isBlank(param.getTicketId())) {
-      return AjaxResult.error("参数异常,盲票ID缺失");
+    if (StringUtils.isBlank(param.getTicketId()) && StringUtils.isBlank(param.getOrderId())) {
+      return AjaxResult.error("参数缺失");
+    }
+    String ticketId = param.getTicketId();
+    if (StringUtils.isBlank(ticketId)) {
+      List<UserTicketOrderItem> orderItemList = userTicketOrderItemService.list(new LambdaQueryWrapper<UserTicketOrderItem>()
+          .eq(UserTicketOrderItem::getOrderId, param.getOrderId()));
+      if (CollectionUtils.isEmpty(orderItemList)) {
+        return AjaxResult.error("参数异常,盲票不存在");
+      }
+      ticketId = orderItemList.get(0).getTicketId();
     }
     }
+    Ticket ticket = ticketService.getById(ticketId);
 
 
-    Ticket ticket = ticketService.getById(param.getTicketId());
     if (null == ticket) {
     if (null == ticket) {
       return AjaxResult.error("参数异常,盲票不存在");
       return AjaxResult.error("参数异常,盲票不存在");
     }
     }

+ 1 - 1
mp-common/src/main/java/com/qs/mp/common/enums/CoinLogTypeEnum.java

@@ -11,7 +11,7 @@ import com.baomidou.mybatisplus.annotation.IEnum;
 public enum CoinLogTypeEnum implements IEnum<Integer> {
 public enum CoinLogTypeEnum implements IEnum<Integer> {
 
 
   PRIZE(1, "盲票奖品"),
   PRIZE(1, "盲票奖品"),
-  CASHED(2, "商品兑换");
+  EXCHANGE(2, "商品兑换");
 
 
 
 
   private final int value;
   private final int value;

+ 2 - 0
mp-common/src/main/java/com/qs/mp/common/enums/ErrorCodeEnum.java

@@ -26,6 +26,8 @@ public enum ErrorCodeEnum {
   ERROR_CODE_1017(1017, "盲票已兑奖"),
   ERROR_CODE_1017(1017, "盲票已兑奖"),
   ERROR_CODE_1018(1018, "无权限查看"),
   ERROR_CODE_1018(1018, "无权限查看"),
   ERROR_CODE_1019(1019, "盲票未付款"),
   ERROR_CODE_1019(1019, "盲票未付款"),
+  ERROR_CODE_1020(1020, "库存不足"),
+  ERROR_CODE_1021(1021, "盲豆余额不足"),
   ;
   ;
   private int code;
   private int code;
   private String msg;
   private String msg;

+ 3 - 0
mp-service/src/main/java/com/qs/mp/admin/domain/param/TicketParam.java

@@ -16,6 +16,9 @@ public class TicketParam {
 	@ApiModelProperty(value = "盲票ID",required=false)
 	@ApiModelProperty(value = "盲票ID",required=false)
 	private String ticketId;
 	private String ticketId;
 
 
+	@ApiModelProperty(value = "盲票购买订单ID",required=false)
+	private String orderId;
+
 	@ApiModelProperty(value = "奖项ID",required=false)
 	@ApiModelProperty(value = "奖项ID",required=false)
 	private String awardsId;
 	private String awardsId;
 
 

+ 5 - 1
mp-service/src/main/java/com/qs/mp/system/service/id/BizIdGenerator.java

@@ -45,6 +45,10 @@ public class BizIdGenerator {
      */
      */
     private String getSharding(String custId){
     private String getSharding(String custId){
         int length = custId.length();
         int length = custId.length();
-        return custId.substring(length - 2, length);
+        if (length > 1) {
+            return custId.substring(length - 2, length);
+        } else {
+            return custId;
+        }
     }
     }
 }
 }

+ 1 - 1
mp-service/src/main/java/com/qs/mp/user/domain/UserDeliverOrderItem.java

@@ -35,7 +35,7 @@ public class UserDeliverOrderItem implements Serializable {
    * 奖品库ID
    * 奖品库ID
    */
    */
   @TableField("storage_id")
   @TableField("storage_id")
-  private Long storageId;
+  private String storageId;
 
 
   /**
   /**
    * 商品ID
    * 商品ID

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

@@ -26,8 +26,8 @@ public class UserPrizeStorage implements Serializable {
   /**
   /**
    * 主键
    * 主键
    */
    */
-  @TableId(value = "storage_id", type = IdType.AUTO)
-  private Long storageId;
+  @TableId(value = "storage_id", type = IdType.INPUT)
+  private String storageId;
 
 
   /**
   /**
    * 用户ID
    * 用户ID

+ 8 - 0
mp-service/src/main/java/com/qs/mp/user/service/IUserCoinService.java

@@ -20,4 +20,12 @@ public interface IUserCoinService extends IService<UserCoin> {
    * @param bizId
    * @param bizId
    */
    */
   void produce(Long userId, Integer logCoin, String bizId);
   void produce(Long userId, Integer logCoin, String bizId);
+
+  /**
+   * 消耗代币
+   * @param userId
+   * @param logCoin
+   * @param bizId
+   */
+  void consume(Long userId, Integer logCoin, String bizId);
 }
 }

+ 7 - 0
mp-service/src/main/java/com/qs/mp/user/service/IUserExchangeOrderService.java

@@ -13,4 +13,11 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
  */
 public interface IUserExchangeOrderService extends IService<UserExchangeOrder> {
 public interface IUserExchangeOrderService extends IService<UserExchangeOrder> {
 
 
+  /**
+   * 兑换
+   * @param goodsId
+   * @param skuId
+   * @param orderNum
+   */
+  void exchange(Long userId, String goodsId, String skuId, int orderNum);
 }
 }

+ 25 - 1
mp-service/src/main/java/com/qs/mp/user/service/impl/UserCoinServiceImpl.java

@@ -12,6 +12,7 @@ import java.util.Date;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.Assert;
 
 
 /**
 /**
  * <p>
  * <p>
@@ -37,8 +38,9 @@ public class UserCoinServiceImpl extends ServiceImpl<UserCoinMapper, UserCoin> i
       userCoin.setCoin(logCoin);
       userCoin.setCoin(logCoin);
       save(userCoin);
       save(userCoin);
     } else {
     } else {
-      update(new LambdaUpdateWrapper<UserCoin>().set(UserCoin::getCoin, userCoin.getCoin() + logCoin)
+      boolean rtn = update(new LambdaUpdateWrapper<UserCoin>().set(UserCoin::getCoin, userCoin.getCoin() + logCoin)
           .eq(UserCoin::getUserId, userId).eq(UserCoin::getCoin, userCoin.getCoin()));
           .eq(UserCoin::getUserId, userId).eq(UserCoin::getCoin, userCoin.getCoin()));
+      Assert.isTrue(rtn, "更新盲豆余额失败。userId:" + userId);
     }
     }
 
 
     UserCoinLog userCoinLog = new UserCoinLog();
     UserCoinLog userCoinLog = new UserCoinLog();
@@ -53,4 +55,26 @@ public class UserCoinServiceImpl extends ServiceImpl<UserCoinMapper, UserCoin> i
     userCoinLog.setRefId(bizId);
     userCoinLog.setRefId(bizId);
     userCoinLogService.save(userCoinLog);
     userCoinLogService.save(userCoinLog);
   }
   }
+
+  @Override
+  @Transactional
+  public void consume(Long userId, Integer logCoin, String bizId) {
+    UserCoin userCoin = getById(userId);
+
+    boolean rtn = update(new LambdaUpdateWrapper<UserCoin>().set(UserCoin::getCoin, userCoin.getCoin() - logCoin)
+          .eq(UserCoin::getUserId, userId).eq(UserCoin::getCoin, userCoin.getCoin()));
+    Assert.isTrue(rtn, "更新盲豆余额失败。userId:" + userId);
+
+    UserCoinLog userCoinLog = new UserCoinLog();
+    userCoinLog.setUserId(userId);
+    userCoinLog.setType(CoinLogTypeEnum.EXCHANGE);
+    userCoinLog.setMoney(userCoin.getCoin() - logCoin);
+    userCoinLog.setLogMoney(0 - logCoin);
+    userCoinLog.setIncomeExpense(CoinLogTypeEnum.EXPENSES);
+    userCoinLog.setLogText("兑换商品");
+    userCoinLog.setBizTime(new Date());
+    userCoinLog.setRefType(2);
+    userCoinLog.setRefId(bizId);
+    userCoinLogService.save(userCoinLog);
+  }
 }
 }

+ 1 - 1
mp-service/src/main/java/com/qs/mp/user/service/impl/UserDeliverOrderServiceImpl.java

@@ -64,7 +64,7 @@ public class UserDeliverOrderServiceImpl extends ServiceImpl<UserDeliverOrderMap
     userDeliverOrder.setCity(userAddr.getCity());
     userDeliverOrder.setCity(userAddr.getCity());
     userDeliverOrder.setArea(userAddr.getArea());
     userDeliverOrder.setArea(userAddr.getArea());
     userDeliverOrder.setAddress(userAddr.getAddr());
     userDeliverOrder.setAddress(userAddr.getAddr());
-    userDeliverOrder.setOrderNum(orderSettleVO.getPrizeList().size());
+    userDeliverOrder.setOrderNum(orderSettleVO.getPrizeList().stream().mapToInt(UserPrizeStorage::getGoodsNum).sum());
     userDeliverOrder.setPayAmt(orderSettleVO.getPayAmt());
     userDeliverOrder.setPayAmt(orderSettleVO.getPayAmt());
     userDeliverOrder.setFreightAmt(orderSettleVO.getFreightAmt());
     userDeliverOrder.setFreightAmt(orderSettleVO.getFreightAmt());
     userDeliverOrder.setMemo(null);
     userDeliverOrder.setMemo(null);

+ 101 - 0
mp-service/src/main/java/com/qs/mp/user/service/impl/UserExchangeOrderServiceImpl.java

@@ -1,10 +1,29 @@
 package com.qs.mp.user.service.impl;
 package com.qs.mp.user.service.impl;
 
 
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.qs.mp.admin.domain.Goods;
+import com.qs.mp.admin.domain.GoodsSku;
+import com.qs.mp.admin.service.IGoodsService;
+import com.qs.mp.admin.service.IGoodsSkuService;
+import com.qs.mp.common.enums.ErrorCodeEnum;
+import com.qs.mp.common.enums.PrizeStorageInTypeEnum;
+import com.qs.mp.common.enums.PrizeStorageStatusEnum;
+import com.qs.mp.common.exception.ServiceException;
+import com.qs.mp.common.utils.StringUtils;
+import com.qs.mp.system.service.id.BizIdGenerator;
+import com.qs.mp.user.domain.UserCoin;
 import com.qs.mp.user.domain.UserExchangeOrder;
 import com.qs.mp.user.domain.UserExchangeOrder;
+import com.qs.mp.user.domain.UserPrizeStorage;
+import com.qs.mp.user.domain.param.ExchangeOrderParam;
 import com.qs.mp.user.mapper.UserExchangeOrderMapper;
 import com.qs.mp.user.mapper.UserExchangeOrderMapper;
+import com.qs.mp.user.service.IUserCoinService;
 import com.qs.mp.user.service.IUserExchangeOrderService;
 import com.qs.mp.user.service.IUserExchangeOrderService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qs.mp.user.service.IUserPrizeStorageService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.Assert;
 
 
 /**
 /**
  * <p>
  * <p>
@@ -17,4 +36,86 @@ import org.springframework.stereotype.Service;
 @Service
 @Service
 public class UserExchangeOrderServiceImpl extends ServiceImpl<UserExchangeOrderMapper, UserExchangeOrder> implements IUserExchangeOrderService {
 public class UserExchangeOrderServiceImpl extends ServiceImpl<UserExchangeOrderMapper, UserExchangeOrder> implements IUserExchangeOrderService {
 
 
+  @Autowired
+  private IGoodsService goodsService;
+
+  @Autowired
+  private IGoodsSkuService goodsSkuService;
+
+  @Autowired
+  private IUserCoinService userCoinService;
+
+  @Autowired
+  private IUserPrizeStorageService userPrizeStorageService;
+
+  @Autowired
+  private BizIdGenerator bizIdGenerator;
+
+  @Override
+  @Transactional
+  public void exchange(Long userId, String goodsId, String skuId, int orderNum) {
+    int orderAmt = 0;
+    Goods goods = goodsService.getById(goodsId);
+    GoodsSku goodsSku = new GoodsSku();
+    // 商品库存校验
+    // 计算兑换盲豆数
+    if (StringUtils.isNotBlank(skuId)) {
+      goodsSku = goodsSkuService.getById(skuId);
+      if (goodsSku.getQuantity() < orderNum) {
+        throw new ServiceException(ErrorCodeEnum.ERROR_CODE_1020);
+      }
+      orderAmt = goodsSku.getExchangePrice() * orderNum;
+    } else {
+      if (goods.getQuantity() < orderNum) {
+        throw new ServiceException(ErrorCodeEnum.ERROR_CODE_1020);
+      }
+      orderAmt = goods.getExchangePrice() * orderNum;
+    }
+    // 盲豆余额校验
+    UserCoin userCoin = userCoinService.getById(userId);
+    if (null == userCoin.getCoin() || userCoin.getCoin() < orderAmt) {
+      throw new ServiceException(ErrorCodeEnum.ERROR_CODE_1021);
+    }
+
+    // 生成兑换订单
+    UserExchangeOrder exchangeOrder = new UserExchangeOrder();
+    exchangeOrder.setOrderId(bizIdGenerator.newIdWithUidSharding(String.valueOf(userId)));
+    exchangeOrder.setUserId(userId);
+    exchangeOrder.setGoodsId(goodsId);
+    exchangeOrder.setSkuId(skuId);
+    exchangeOrder.setOrderCoin(orderAmt);
+    save(exchangeOrder);
+
+    // 扣除盲豆数
+    userCoinService.consume(userId, orderAmt, exchangeOrder.getOrderId());
+
+    // 放入奖品库
+    UserPrizeStorage userPrizeStorage = new UserPrizeStorage();
+    userPrizeStorage.setStorageId(bizIdGenerator.newIdWithUidSharding(String.valueOf(userId)));
+    userPrizeStorage.setUserId(userId);
+    userPrizeStorage.setGoodsId(goodsId);
+    userPrizeStorage.setSkuId(skuId);
+    userPrizeStorage.setProperties(goodsSku.getProperties());
+    userPrizeStorage.setTitle(goods.getTitle());
+    userPrizeStorage.setPicUrl(goods.getPicUrl());
+    userPrizeStorage.setGoodsNum(orderNum);
+    userPrizeStorage.setInType(PrizeStorageInTypeEnum.COIN_EXCHANGE);
+    userPrizeStorage.setRefId(exchangeOrder.getOrderId());
+    userPrizeStorage.setStatus(PrizeStorageStatusEnum.NOT_DISTRIBUTED);
+    userPrizeStorageService.save(userPrizeStorage);
+
+    // 修改商品库存
+    if (StringUtils.isNotBlank(skuId)) {
+      boolean updateSku = goodsSkuService.update(new LambdaUpdateWrapper<GoodsSku>()
+          .set(GoodsSku::getQuantity, goodsSku.getQuantity() - orderNum)
+          .set(GoodsSku::getSoldQty, goodsSku.getSoldQty() + orderNum)
+          .eq(GoodsSku::getSkuId, skuId).eq(GoodsSku::getQuantity, goodsSku.getQuantity()).eq(GoodsSku::getSoldQty, goodsSku.getSoldQty()));
+      Assert.isTrue(updateSku, "兑换商品更新SKU库存失败。goodsId:" + goodsId + ",skuId:" + skuId);
+    }
+    boolean updateGoods = goodsService.update(new LambdaUpdateWrapper<Goods>()
+        .set(Goods::getQuantity, goods.getQuantity() - orderNum)
+        .set(Goods::getExchangedQty, goods.getExchangedQty() + orderNum)
+        .eq(Goods::getGoodsId, goodsId).eq(Goods::getQuantity, goods.getQuantity()).eq(Goods::getExchangedQty, goods.getExchangedQty()));
+    Assert.isTrue(updateGoods, "兑换商品更新GOODS库存失败。goodsId:" + goodsId );
+  }
 }
 }

+ 6 - 0
mp-service/src/main/java/com/qs/mp/user/service/impl/UserPrizeStorageServiceImpl.java

@@ -5,10 +5,12 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.qs.mp.admin.domain.TicketAwardsPrize;
 import com.qs.mp.admin.domain.TicketAwardsPrize;
 import com.qs.mp.common.enums.PrizeStorageInTypeEnum;
 import com.qs.mp.common.enums.PrizeStorageInTypeEnum;
 import com.qs.mp.common.enums.PrizeStorageStatusEnum;
 import com.qs.mp.common.enums.PrizeStorageStatusEnum;
+import com.qs.mp.system.service.id.BizIdGenerator;
 import com.qs.mp.user.domain.UserPrizeStorage;
 import com.qs.mp.user.domain.UserPrizeStorage;
 import com.qs.mp.user.mapper.UserPrizeStorageMapper;
 import com.qs.mp.user.mapper.UserPrizeStorageMapper;
 import com.qs.mp.user.service.IUserPrizeStorageService;
 import com.qs.mp.user.service.IUserPrizeStorageService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 /**
 /**
@@ -21,6 +23,9 @@ import org.springframework.stereotype.Service;
  */
  */
 @Service
 @Service
 public class UserPrizeStorageServiceImpl extends ServiceImpl<UserPrizeStorageMapper, UserPrizeStorage> implements IUserPrizeStorageService {
 public class UserPrizeStorageServiceImpl extends ServiceImpl<UserPrizeStorageMapper, UserPrizeStorage> implements IUserPrizeStorageService {
+  @Autowired
+  private BizIdGenerator bizIdGenerator;
+
   @Override
   @Override
   public void takeInStorage(Long userId, TicketAwardsPrize ticketAwardsPrize, PrizeStorageInTypeEnum inTypeEnum, String refId) {
   public void takeInStorage(Long userId, TicketAwardsPrize ticketAwardsPrize, PrizeStorageInTypeEnum inTypeEnum, String refId) {
     UserPrizeStorage userPrizeStorage = getOne(new LambdaQueryWrapper<UserPrizeStorage>()
     UserPrizeStorage userPrizeStorage = getOne(new LambdaQueryWrapper<UserPrizeStorage>()
@@ -29,6 +34,7 @@ public class UserPrizeStorageServiceImpl extends ServiceImpl<UserPrizeStorageMap
         .eq(UserPrizeStorage::getStatus, PrizeStorageStatusEnum.NOT_DISTRIBUTED));
         .eq(UserPrizeStorage::getStatus, PrizeStorageStatusEnum.NOT_DISTRIBUTED));
     if (null == userPrizeStorage) {
     if (null == userPrizeStorage) {
       userPrizeStorage = new UserPrizeStorage();
       userPrizeStorage = new UserPrizeStorage();
+      userPrizeStorage.setStorageId(bizIdGenerator.newIdWithUidSharding(String.valueOf(userId)));
       userPrizeStorage.setUserId(userId);
       userPrizeStorage.setUserId(userId);
       userPrizeStorage.setGoodsId(ticketAwardsPrize.getRefId());
       userPrizeStorage.setGoodsId(ticketAwardsPrize.getRefId());
       userPrizeStorage.setSkuId(null);
       userPrizeStorage.setSkuId(null);

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

@@ -142,7 +142,7 @@ public class UserTicketOrderServiceImpl extends
     UserTicketOrder userTicketOrder = new UserTicketOrder();
     UserTicketOrder userTicketOrder = new UserTicketOrder();
     userTicketOrder.setOrderId(bizIdGenerator.newId());
     userTicketOrder.setOrderId(bizIdGenerator.newId());
     userTicketOrder.setUserId(userId);
     userTicketOrder.setUserId(userId);
-    userTicketOrder.setTitle(orderSettleVO.getTitle());
+    userTicketOrder.setTitle(ticketBox.getTitle());
     userTicketOrder.setBoxId(orderSettleVO.getBoxId());
     userTicketOrder.setBoxId(orderSettleVO.getBoxId());
     userTicketOrder.setOrderAmt(orderSettleVO.getOrderAmt());
     userTicketOrder.setOrderAmt(orderSettleVO.getOrderAmt());
     userTicketOrder.setDiscountAmt(orderSettleVO.getDiscountAmt());
     userTicketOrder.setDiscountAmt(orderSettleVO.getDiscountAmt());