Эх сурвалжийг харах

Merge branch 'dev' into 'mp-server-test'

Dev

See merge request quanshu/mp-server!162
zhong chunping 3 жил өмнө
parent
commit
177a78e08b
18 өөрчлөгдсөн 425 нэмэгдсэн , 13 устгасан
  1. 103 0
      mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/ChannelOrderMgrController.java
  2. 124 0
      mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/UserDeliverOrderMgrController.java
  3. 14 3
      mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserTicketController.java
  4. 2 2
      mp-admin/src/main/resources/application.yml
  5. 1 1
      mp-common/src/main/java/com/qs/mp/common/enums/CoinLogTypeEnum.java
  6. 2 0
      mp-common/src/main/java/com/qs/mp/common/enums/ErrorCodeEnum.java
  7. 3 0
      mp-service/src/main/java/com/qs/mp/admin/domain/param/TicketParam.java
  8. 5 1
      mp-service/src/main/java/com/qs/mp/system/service/id/BizIdGenerator.java
  9. 1 1
      mp-service/src/main/java/com/qs/mp/user/domain/UserDeliverOrderItem.java
  10. 2 2
      mp-service/src/main/java/com/qs/mp/user/domain/UserPrizeStorage.java
  11. 19 0
      mp-service/src/main/java/com/qs/mp/user/domain/vo/UserDeliverOrderVO.java
  12. 8 0
      mp-service/src/main/java/com/qs/mp/user/service/IUserCoinService.java
  13. 7 0
      mp-service/src/main/java/com/qs/mp/user/service/IUserExchangeOrderService.java
  14. 25 1
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserCoinServiceImpl.java
  15. 1 1
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserDeliverOrderServiceImpl.java
  16. 101 0
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserExchangeOrderServiceImpl.java
  17. 6 0
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserPrizeStorageServiceImpl.java
  18. 1 1
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserTicketOrderServiceImpl.java

+ 103 - 0
mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/ChannelOrderMgrController.java

@@ -0,0 +1,103 @@
+package com.qs.mp.web.controller.api.admin;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.qs.mp.channel.domain.ChannelOrder;
+import com.qs.mp.channel.domain.ChannelOrderItem;
+import com.qs.mp.channel.domain.vo.ChannelOrderVO;
+import com.qs.mp.channel.service.IChannelOrderItemService;
+import com.qs.mp.channel.service.IChannelOrderService;
+import com.qs.mp.common.core.domain.AjaxResult;
+import com.qs.mp.common.core.page.TableDataInfo;
+import com.qs.mp.common.core.redis.RedisCache;
+import com.qs.mp.common.enums.ErrorCodeEnum;
+import com.qs.mp.web.controller.common.BaseApiController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import ma.glasnost.orika.MapperFacade;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@RestController
+@RequestMapping("/api/v1/admin/channel/order")
+@Api(tags = "渠道订单管理接口")
+@AllArgsConstructor
+public class ChannelOrderMgrController extends BaseApiController {
+
+  @Autowired
+  private IChannelOrderService channelOrderService;
+
+  @Autowired
+  private IChannelOrderItemService channelOrderItemService;
+
+  @Autowired
+  private MapperFacade mapperFacade;
+
+  @Autowired
+  private RedisCache redisCache;
+
+  /**
+   * 订单列表
+   */
+  @PostMapping("/list")
+  @ApiOperation(value = "订单列表" , notes = "获取所有订单信息")
+  public TableDataInfo list(@RequestBody JSONObject param) {
+   // Long channelId = SecurityUtils.getLoginUser().getChannelId();
+    Integer status = param.getInteger("status");
+    startPage();
+    LambdaQueryWrapper<ChannelOrder> queryWrapper = new LambdaQueryWrapper<ChannelOrder>();
+    // queryWrapper.eq(ChannelOrder::getChannelId, channelId);
+    queryWrapper.eq(null != status, ChannelOrder::getStatus, status);
+    queryWrapper.orderByDesc(ChannelOrder::getCreatedTime);
+    List<ChannelOrder> channelOrders = channelOrderService.list(queryWrapper);
+    List<ChannelOrderVO> channelOrderVOList = mapperFacade.mapAsList(channelOrders, ChannelOrderVO.class);
+    for (ChannelOrderVO channelOrderVO : channelOrderVOList) {
+      channelOrderVO.setItems(channelOrderItemService.list(new LambdaQueryWrapper<ChannelOrderItem>()
+          .eq(ChannelOrderItem::getOrderId, channelOrderVO.getOrderId())));
+    }
+    TableDataInfo rspData = getDataTable(channelOrders);
+    rspData.setRows(channelOrderVOList);
+    return rspData;
+  }
+
+  /**
+   * 订单详情
+   */
+  @PostMapping("/detail")
+  @ApiOperation(value = "订单详情" , notes = "在订单列表页面查看详情")
+  public AjaxResult query(@RequestBody ChannelOrder order) {
+    if(null == order || StringUtils.isBlank(order.getOrderId())) {
+    	return error(ErrorCodeEnum.ERROR_CODE_1001);
+    }    
+    LambdaQueryWrapper<ChannelOrder> queryWrapper = new LambdaQueryWrapper<ChannelOrder>();
+    queryWrapper.eq(ChannelOrder::getOrderId, order.getOrderId());
+    
+    ChannelOrder channelOrder = channelOrderService.getOne(queryWrapper);
+    ChannelOrderVO channelOrderVO = mapperFacade.map(channelOrder, ChannelOrderVO.class);
+    channelOrderVO.setItems(channelOrderItemService.list(new LambdaQueryWrapper<ChannelOrderItem>()
+        .eq(ChannelOrderItem::getOrderId, channelOrderVO.getOrderId())));
+    return AjaxResult.success(channelOrderVO);
+  }
+
+  
+
+  /**
+   * 订单发货
+   */
+  @PostMapping("/ship")
+  @ApiOperation(value = "订单发货" , notes = "在订单发货页面提交")
+  public AjaxResult ship(@RequestBody ChannelOrder order) {
+
+    return AjaxResult.success();
+  }
+
+
+}

+ 124 - 0
mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/UserDeliverOrderMgrController.java

@@ -0,0 +1,124 @@
+package com.qs.mp.web.controller.api.admin;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.qs.mp.channel.domain.param.OrderPayParam;
+import com.qs.mp.common.core.domain.AjaxResult;
+import com.qs.mp.common.core.page.TableDataInfo;
+import com.qs.mp.common.core.redis.RedisCache;
+import com.qs.mp.common.enums.BizTypeEnum;
+import com.qs.mp.common.enums.ErrorCodeEnum;
+import com.qs.mp.common.enums.PrizeStorageStatusEnum;
+import com.qs.mp.common.exception.ServiceException;
+import com.qs.mp.framework.redis.RedisKey;
+import com.qs.mp.pay.service.IWalletService;
+import com.qs.mp.user.domain.UserAddr;
+import com.qs.mp.user.domain.UserDeliverOrder;
+import com.qs.mp.user.domain.UserDeliverOrderItem;
+import com.qs.mp.user.domain.UserPrizeStorage;
+import com.qs.mp.user.domain.param.DeliverOrderParam;
+import com.qs.mp.user.domain.vo.DeliverOrderSettleVO;
+import com.qs.mp.user.domain.vo.UserDeliverOrderVO;
+import com.qs.mp.user.service.IUserAddrService;
+import com.qs.mp.user.service.IUserDeliverOrderItemService;
+import com.qs.mp.user.service.IUserDeliverOrderService;
+import com.qs.mp.user.service.IUserPrizeStorageService;
+import com.qs.mp.utils.SecurityUtils;
+import com.qs.mp.web.controller.common.BaseApiController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import javax.validation.Valid;
+import lombok.AllArgsConstructor;
+import ma.glasnost.orika.MapperFacade;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@RestController
+@RequestMapping("/api/v1/admin/deliver/order")
+@Api(tags = "用户提货订单接口")
+@AllArgsConstructor
+public class UserDeliverOrderMgrController extends BaseApiController {
+
+  @Autowired
+  private IUserDeliverOrderService userDeliverOrderService;
+  
+  @Autowired
+  private IUserDeliverOrderItemService userDeliverOrderItemService;
+
+  @Autowired
+  private IUserPrizeStorageService userPrizeStorageService;
+
+  @Autowired
+  private IUserAddrService userAddrService;
+  
+  @Autowired
+  private IWalletService walletService;
+
+  @Autowired
+  private MapperFacade mapperFacade;
+
+  @Autowired
+  private RedisCache redisCache;
+
+  /**
+   * 订单列表
+   */
+  @PostMapping("/list")
+  @ApiOperation(value = "订单列表" , notes = "获取所有订单信息")
+  public TableDataInfo list(@RequestBody JSONObject param) {
+   // Long channelId = SecurityUtils.getLoginUser().getChannelId();
+    Integer status = param.getInteger("status");
+    startPage();
+    LambdaQueryWrapper<UserDeliverOrder> queryWrapper = new LambdaQueryWrapper<UserDeliverOrder>();
+    // queryWrapper.eq(UserDeliverOrder::getChannelId, channelId);
+    queryWrapper.eq(null != status, UserDeliverOrder::getStatus, status);
+    queryWrapper.orderByDesc(UserDeliverOrder::getCreatedTime);
+    List<UserDeliverOrder> userDeliverOrders = userDeliverOrderService.list(queryWrapper);
+    List<UserDeliverOrderVO> userDeliverOrderVOList = mapperFacade.mapAsList(userDeliverOrders, UserDeliverOrderVO.class);
+    for (UserDeliverOrderVO userDeliverOrderVO : userDeliverOrderVOList) {
+      userDeliverOrderVO.setItems(userDeliverOrderItemService.list(new LambdaQueryWrapper<UserDeliverOrderItem>()
+          .eq(UserDeliverOrderItem::getOrderId, userDeliverOrderVO.getOrderId())));
+    }
+    TableDataInfo rspData = getDataTable(userDeliverOrders);
+    rspData.setRows(userDeliverOrderVOList);
+    return rspData;
+  }
+
+  /**
+   * 订单详情
+   */
+  @PostMapping("/detail")
+  @ApiOperation(value = "订单详情" , notes = "在订单列表页面查看详情")
+  public AjaxResult query(@RequestBody UserDeliverOrder order) {
+	  if(null == order || StringUtils.isBlank(order.getOrderId())) {
+	    	return error(ErrorCodeEnum.ERROR_CODE_1001);
+	    } 
+    LambdaQueryWrapper<UserDeliverOrder> queryWrapper = new LambdaQueryWrapper<UserDeliverOrder>();
+    queryWrapper.eq(UserDeliverOrder::getOrderId, order.getOrderId());
+    UserDeliverOrder userDeliverOrder = userDeliverOrderService.getOne(queryWrapper);
+    UserDeliverOrderVO userDeliverOrderVO = mapperFacade.map(userDeliverOrder, UserDeliverOrderVO.class);
+    userDeliverOrderVO.setItems(userDeliverOrderItemService.list(new LambdaQueryWrapper<UserDeliverOrderItem>()
+        .eq(UserDeliverOrderItem::getOrderId, userDeliverOrderVO.getOrderId())));
+    return AjaxResult.success(userDeliverOrderVO);
+  }
+
+  
+
+  /**
+   * 订单发货
+   */
+  @PostMapping("/ship")
+  @ApiOperation(value = "订单发货" , notes = "在订单发货页面提交")
+  public AjaxResult ship(@RequestBody UserDeliverOrder order) {
+
+    return AjaxResult.success();
+  }
+}

+ 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.TicketStatusEnum;
 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.service.IUserHitPrizeService;
 import com.qs.mp.user.service.IUserTicketOrderItemService;
@@ -30,6 +31,7 @@ import java.util.List;
 import lombok.AllArgsConstructor;
 import ma.glasnost.orika.MapperFacade;
 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.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -150,11 +152,20 @@ public class UserTicketController extends BaseApiController {
   @ApiOperation(value = "查看兑奖奖品" , notes = "根据盲票ID,查看兑奖奖品")
   public AjaxResult queryHitPrizeList(@RequestBody TicketParam param) {
     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) {
       return AjaxResult.error("参数异常,盲票不存在");
     }

+ 2 - 2
mp-admin/src/main/resources/application.yml

@@ -145,8 +145,8 @@ pay:
   baseUrl: https://jlpays.kakapaypay.com
   user-shopNo: 1646882813774
   user-sign: 614140724fb74085be8aef8bebc538ed
-  channel-shopNo: 1646882813774
-  channel-sign: 614140724fb74085be8aef8bebc538ed
+  channel-shopNo: 1647504328218
+  channel-sign: 0e0c00555fee4549b1a88af4d988415b
 
 #幸运数字加密密钥对
 rsa:

+ 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> {
 
   PRIZE(1, "盲票奖品"),
-  CASHED(2, "商品兑换");
+  EXCHANGE(2, "商品兑换");
 
 
   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_1018(1018, "无权限查看"),
   ERROR_CODE_1019(1019, "盲票未付款"),
+  ERROR_CODE_1020(1020, "库存不足"),
+  ERROR_CODE_1021(1021, "盲豆余额不足"),
   ;
   private int code;
   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)
 	private String ticketId;
 
+	@ApiModelProperty(value = "盲票购买订单ID",required=false)
+	private String orderId;
+
 	@ApiModelProperty(value = "奖项ID",required=false)
 	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){
         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
    */
   @TableField("storage_id")
-  private Long storageId;
+  private String storageId;
 
   /**
    * 商品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

+ 19 - 0
mp-service/src/main/java/com/qs/mp/user/domain/vo/UserDeliverOrderVO.java

@@ -0,0 +1,19 @@
+package com.qs.mp.user.domain.vo;
+
+import java.util.List;
+
+import com.qs.mp.user.domain.UserDeliverOrder;
+import com.qs.mp.user.domain.UserDeliverOrderItem;
+
+import lombok.Data;
+
+
+/**
+ * @author liugl
+ * @Date 2022/3/17
+ */
+@Data
+public class UserDeliverOrderVO extends UserDeliverOrder{
+
+	private List<UserDeliverOrderItem> items;
+}

+ 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
    */
   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> {
 
+  /**
+   * 兑换
+   * @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.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.Assert;
 
 /**
  * <p>
@@ -37,8 +38,9 @@ public class UserCoinServiceImpl extends ServiceImpl<UserCoinMapper, UserCoin> i
       userCoin.setCoin(logCoin);
       save(userCoin);
     } 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()));
+      Assert.isTrue(rtn, "更新盲豆余额失败。userId:" + userId);
     }
 
     UserCoinLog userCoinLog = new UserCoinLog();
@@ -53,4 +55,26 @@ public class UserCoinServiceImpl extends ServiceImpl<UserCoinMapper, UserCoin> i
     userCoinLog.setRefId(bizId);
     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.setArea(userAddr.getArea());
     userDeliverOrder.setAddress(userAddr.getAddr());
-    userDeliverOrder.setOrderNum(orderSettleVO.getPrizeList().size());
+    userDeliverOrder.setOrderNum(orderSettleVO.getPrizeList().stream().mapToInt(UserPrizeStorage::getGoodsNum).sum());
     userDeliverOrder.setPayAmt(orderSettleVO.getPayAmt());
     userDeliverOrder.setFreightAmt(orderSettleVO.getFreightAmt());
     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;
 
+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.UserPrizeStorage;
+import com.qs.mp.user.domain.param.ExchangeOrderParam;
 import com.qs.mp.user.mapper.UserExchangeOrderMapper;
+import com.qs.mp.user.service.IUserCoinService;
 import com.qs.mp.user.service.IUserExchangeOrderService;
 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.transaction.annotation.Transactional;
+import org.springframework.util.Assert;
 
 /**
  * <p>
@@ -17,4 +36,86 @@ import org.springframework.stereotype.Service;
 @Service
 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.common.enums.PrizeStorageInTypeEnum;
 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.mapper.UserPrizeStorageMapper;
 import com.qs.mp.user.service.IUserPrizeStorageService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 /**
@@ -21,6 +23,9 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class UserPrizeStorageServiceImpl extends ServiceImpl<UserPrizeStorageMapper, UserPrizeStorage> implements IUserPrizeStorageService {
+  @Autowired
+  private BizIdGenerator bizIdGenerator;
+
   @Override
   public void takeInStorage(Long userId, TicketAwardsPrize ticketAwardsPrize, PrizeStorageInTypeEnum inTypeEnum, String refId) {
     UserPrizeStorage userPrizeStorage = getOne(new LambdaQueryWrapper<UserPrizeStorage>()
@@ -29,6 +34,7 @@ public class UserPrizeStorageServiceImpl extends ServiceImpl<UserPrizeStorageMap
         .eq(UserPrizeStorage::getStatus, PrizeStorageStatusEnum.NOT_DISTRIBUTED));
     if (null == userPrizeStorage) {
       userPrizeStorage = new UserPrizeStorage();
+      userPrizeStorage.setStorageId(bizIdGenerator.newIdWithUidSharding(String.valueOf(userId)));
       userPrizeStorage.setUserId(userId);
       userPrizeStorage.setGoodsId(ticketAwardsPrize.getRefId());
       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.setOrderId(bizIdGenerator.newId());
     userTicketOrder.setUserId(userId);
-    userTicketOrder.setTitle(orderSettleVO.getTitle());
+    userTicketOrder.setTitle(ticketBox.getTitle());
     userTicketOrder.setBoxId(orderSettleVO.getBoxId());
     userTicketOrder.setOrderAmt(orderSettleVO.getOrderAmt());
     userTicketOrder.setDiscountAmt(orderSettleVO.getDiscountAmt());