zhangkaikai 1 éve
szülő
commit
4fca0e5e18
24 módosított fájl, 323 hozzáadás és 44 törlés
  1. 6 7
      mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/CdKeyMgrController.java
  2. 8 0
      mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserDeliverOrderController.java
  3. 31 14
      mp-admin/src/main/java/com/qs/mp/web/controller/api/user/UserMineController.java
  4. 2 1
      mp-common/src/main/java/com/qs/mp/common/enums/CoinLogTypeEnum.java
  5. 4 1
      mp-common/src/main/java/com/qs/mp/common/enums/DeliverOrderResourceEnum.java
  6. 4 1
      mp-common/src/main/java/com/qs/mp/common/enums/PrizeStorageInTypeEnum.java
  7. 13 0
      mp-common/src/main/java/com/qs/mp/common/enums/ValidityPeriodEnum.java
  8. 0 3
      mp-service/src/main/java/com/qs/mp/admin/domain/excel/CdKeyOrderExcel.java
  9. 1 1
      mp-service/src/main/java/com/qs/mp/admin/mapper/CdKeyMapper.java
  10. 2 0
      mp-service/src/main/java/com/qs/mp/admin/service/ICdKeyExchangeService.java
  11. 5 1
      mp-service/src/main/java/com/qs/mp/admin/service/ICdKeyService.java
  12. 7 0
      mp-service/src/main/java/com/qs/mp/admin/service/ICouponPkgService.java
  13. 7 0
      mp-service/src/main/java/com/qs/mp/admin/service/ICouponService.java
  14. 125 1
      mp-service/src/main/java/com/qs/mp/admin/service/impl/CdKeyExchangeServiceImpl.java
  15. 1 0
      mp-service/src/main/java/com/qs/mp/admin/service/impl/CdKeyGroupServiceImpl.java
  16. 47 1
      mp-service/src/main/java/com/qs/mp/admin/service/impl/CdKeyServiceImpl.java
  17. 15 0
      mp-service/src/main/java/com/qs/mp/admin/service/impl/CouponPkgServiceImpl.java
  18. 15 0
      mp-service/src/main/java/com/qs/mp/admin/service/impl/CouponServiceImpl.java
  19. 2 0
      mp-service/src/main/java/com/qs/mp/framework/redis/RedisLockKey.java
  20. 1 1
      mp-service/src/main/java/com/qs/mp/user/domain/UserPrizeStorage.java
  21. 0 6
      mp-service/src/main/java/com/qs/mp/user/domain/param/CdKeyExchangeParam.java
  22. 22 0
      mp-service/src/main/java/com/qs/mp/user/domain/vo/UserExchangeCdKeyVO.java
  23. 1 1
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserDeliverOrderServiceImpl.java
  24. 4 5
      mp-service/src/main/resources/mapper/admin/CdKeyMapper.xml

+ 6 - 7
mp-admin/src/main/java/com/qs/mp/web/controller/api/admin/CdKeyMgrController.java

@@ -160,16 +160,15 @@ public class CdKeyMgrController extends BaseController {
     )
     public TableDataInfo exchangeDetail(@PathVariable String groupId) {
         startPage();
-        List<CdKey> cdKeyList = cdKeyService.list(new QueryWrapper<CdKey>().eq("group_id", groupId));
-        long unCashedCount = cdKeyList.stream().filter(cdKey -> CdKeyStatusEnum.UNCASHED.getValue().equals(cdKey.getStatus())).count();
-        long cashedCount = cdKeyList.stream().filter(cdKey -> CdKeyStatusEnum.CASHED.getValue().equals(cdKey.getStatus())).count();
-        List<CdKeyExchangeVO> exchangeVOList = mapperFacade.mapAsList(cdKeyList, CdKeyExchangeVO.class);
-        exchangeVOList.forEach(cdKeyExchangeVO -> {
+        List<CdKeyExchangeVO> cdKeyExchangeVOList = cdKeyService.listCdKeyExchangeVO(new QueryWrapper<CdKey>().eq("t1.group_id", groupId).orderByDesc("t2.exchange_time"));
+        long unCashedCount = cdKeyExchangeVOList.stream().filter(cdKey -> CdKeyStatusEnum.UNCASHED.getValue().equals(cdKey.getStatus())).count();
+        long cashedCount = cdKeyExchangeVOList.stream().filter(cdKey -> CdKeyStatusEnum.CASHED.getValue().equals(cdKey.getStatus())).count();
+        cdKeyExchangeVOList.forEach(cdKeyExchangeVO -> {
             cdKeyExchangeVO.setRemainQty((int) unCashedCount);
             cdKeyExchangeVO.setCashedQty((int) cashedCount);
         });
-        TableDataInfo resp = getDataTable(cdKeyList);
-        resp.setRows(exchangeVOList);
+        TableDataInfo resp = getDataTable(cdKeyExchangeVOList);
+        resp.setRows(cdKeyExchangeVOList);
         return resp;
     }
 

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

@@ -253,6 +253,14 @@ public class UserDeliverOrderController extends BaseApiController {
 
             prizeStorageList.add(prizeStorage);
             orderSettleVO.setResource(DeliverOrderResourceEnum.PAYMENT.getValue());
+        } else if (DeliverOrderResourceEnum.CD_KEY.equals(param.getResource())) {
+            // 兑换码兑换
+            prizeStorageList = userPrizeStorageService.list(new LambdaQueryWrapper<UserPrizeStorage>()
+                    .eq(UserPrizeStorage::getUserId, userId)
+                    .eq(UserPrizeStorage::getStatus, PrizeStorageStatusEnum.NOT_DISTRIBUTED)
+                    .in(UserPrizeStorage::getStorageId, param.getIds()));
+            goodsNum = prizeStorageList.stream().mapToInt(UserPrizeStorage::getGoodsNum).sum();
+            orderSettleVO.setResource(DeliverOrderResourceEnum.CD_KEY.getValue());
         } else {
             prizeStorageList = userPrizeStorageService.list(new LambdaQueryWrapper<UserPrizeStorage>()
                 .eq(UserPrizeStorage::getUserId, userId)

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

@@ -6,10 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.qs.mp.admin.domain.*;
 import com.qs.mp.admin.domain.vo.TicketListVO;
-import com.qs.mp.admin.service.ICdKeyService;
-import com.qs.mp.admin.service.ICouponChannelService;
-import com.qs.mp.admin.service.ICouponService;
-import com.qs.mp.admin.service.IGoodsService;
+import com.qs.mp.admin.service.*;
 import com.qs.mp.channel.domain.Channel;
 import com.qs.mp.channel.service.IChannelService;
 import com.qs.mp.common.annotation.Log;
@@ -30,6 +27,7 @@ import com.qs.mp.user.domain.param.CoinTransferParam;
 import com.qs.mp.user.domain.param.CouponChannelQueryParam;
 import com.qs.mp.user.domain.param.UserPrizeStorageUpdateParam;
 import com.qs.mp.user.domain.vo.UserCouponVO;
+import com.qs.mp.user.domain.vo.UserExchangeCdKeyVO;
 import com.qs.mp.user.domain.vo.UserPrizeStorageVO;
 import com.qs.mp.user.service.IUserCoinLogService;
 import com.qs.mp.user.service.IUserCoinService;
@@ -40,11 +38,8 @@ import com.qs.mp.utils.SecurityUtils;
 import com.qs.mp.web.controller.common.BaseApiController;
 import io.swagger.annotations.*;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
-import java.util.Objects;
 import java.util.stream.Collectors;
 import lombok.AllArgsConstructor;
 import ma.glasnost.orika.MapperFacade;
@@ -97,6 +92,12 @@ public class UserMineController extends BaseApiController {
     @Autowired
     private ICdKeyService cdKeyService;
 
+    @Autowired
+    private ICdKeyExchangeService exchangeService;
+
+    @Autowired
+    private ICdKeyGroupService cdKeyGroupService;
+
     @Log(title = "昵称和头像修改", businessType = BusinessType.UPDATE)
     @PostMapping("/updateUserInfo")
     public AjaxResult updateUserInfo(@RequestBody SysUser user) {
@@ -412,16 +413,32 @@ public class UserMineController extends BaseApiController {
         return AjaxResult.success(result);
     }
 
-    @ApiModelProperty(value = "兑换码兑换")
+    @ApiOperation(value = "兑换码兑换")
     @PostMapping("/cdKey/exchange")
     public AjaxResult ticketExchange(@RequestBody CdKeyExchangeParam param) {
+        CdKey cdKey = cdKeyService.getOne(new QueryWrapper<CdKey>().eq("cd_key", param.getCdKey()));
+        if (cdKey == null) {
+            return AjaxResult.error("兑换商品不存在");
+        }
+        if (cdKey.getStatus() == 1) {
+            return AjaxResult.error("该商品已被兑换");
+        }
+        // 判断兑换码是否失效
+        CdKeyGroup cdKeyGroup = cdKeyGroupService.getById(cdKey.getGroupId());
+        if (CdKeyGroupStatusEnum.ACTIVATED == cdKeyGroup.getStatus()) {
+            int validityPeriod = ValidityPeriodEnum.getByValue(cdKeyGroup.getValidityPeriod().getValue());
+            if (validityPeriod == 3 && DateUtils.diffMonth(cdKeyGroup.getActivationTime(), new Date()) > 3) {
+                return AjaxResult.error("兑换码只有三个月有效期,现已失效");
+            } else if (validityPeriod == 6 && DateUtils.diffMonth(cdKeyGroup.getActivationTime(), new Date()) > 6) {
+                return AjaxResult.error("兑换码只有六个月有效期,现已失效");
+            }
+        } else {
+            return AjaxResult.error("兑换码" + cdKeyGroup.getStatus().getDesc());
+        }
 
+        UserExchangeCdKeyVO userExchangeCdKeyVO = exchangeService.exchangeCdKey(cdKey.getKeyId());
 
-//        CdKey cdKey = cdKeyService.
-
-        return AjaxResult.success();
-
-
+        return AjaxResult.success(userExchangeCdKeyVO);
     }
 
 }

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

@@ -14,7 +14,8 @@ public enum CoinLogTypeEnum implements IEnum<Integer> {
   EXCHANGE(2, "兑换商品"),
   MARKETING(3,"营销活动"),
   RECOVERY(4,"商品兑换"),
-  TRANSFER(5,"盲豆转赠");
+  TRANSFER(5,"盲豆转赠"),
+  CD_KEPT(6,"兑换码兑换"),;
 
 
   private final int value;

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

@@ -17,7 +17,10 @@ import io.swagger.annotations.ApiModel;
 public enum DeliverOrderResourceEnum implements IEnum<Integer> {
 
     DELIVER(1, "提货订单"),
-    PAYMENT(2, "现金购买");
+    PAYMENT(2, "现金购买"),
+
+    CD_KEY(3, "兑换码兑换"),
+    ;
 
     private final int value;
     private final String desc;

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

@@ -14,7 +14,10 @@ public enum PrizeStorageInTypeEnum implements IEnum<Integer> {
   TICKET_CASHED(1, "盲票奖品"),
   COIN_EXCHANGE(2, "盲豆兑换"),
   MARKETING(3, "营销活动"),
-  TICKET_GOODS(4, "盲票购买");
+  TICKET_GOODS(4, "盲票购买"),
+
+  CD_KEY_EXCHANGE(5, "兑换码兑换"),
+  ;
 
 
   private final int value;

+ 13 - 0
mp-common/src/main/java/com/qs/mp/common/enums/ValidityPeriodEnum.java

@@ -44,4 +44,17 @@ public enum ValidityPeriodEnum implements IEnum<String> {
         object.put("desc", desc);
         return object.toString();
     }
+
+    public static int getByValue(String value) {
+        switch (value) {
+            case "threeMoths":
+                return 3;
+            case "sixMonths":
+                return 6;
+            case "forever":
+                return -1;
+            default:
+                return 0;
+        }
+    }
 }

+ 0 - 3
mp-service/src/main/java/com/qs/mp/admin/domain/excel/CdKeyOrderExcel.java

@@ -14,9 +14,6 @@ import lombok.Data;
 @Data
 public class CdKeyOrderExcel {
 
-    @Excel(name = "门店名称")
-    private String siteName;
-
     @Excel(name = "兑换码")
     private String cdKey;
 

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

@@ -20,5 +20,5 @@ public interface CdKeyMapper extends BaseMapper<CdKey> {
 
     List<CdKeyGroupListVO> listCdKeyVO(@Param(Constants.WRAPPER) QueryWrapper<CdKeyGroup> queryWrapper);
 
-    CdKeyExchangeVO listCdKeyExchangeVO(@Param(Constants.WRAPPER) QueryWrapper<CdKey> queryWrapper);
+    List<CdKeyExchangeVO> listCdKeyExchangeVO(@Param(Constants.WRAPPER) QueryWrapper<CdKey> queryWrapper);
 }

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

@@ -2,6 +2,7 @@ package com.qs.mp.admin.service;
 
 import com.qs.mp.admin.domain.CdKeyExchange;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.qs.mp.user.domain.vo.UserExchangeCdKeyVO;
 
 /**
  * @auther quanshu
@@ -10,4 +11,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface ICdKeyExchangeService extends IService<CdKeyExchange> {
 
+    UserExchangeCdKeyVO exchangeCdKey(Long keyId);
 }

+ 5 - 1
mp-service/src/main/java/com/qs/mp/admin/service/ICdKeyService.java

@@ -1,11 +1,13 @@
 package com.qs.mp.admin.service;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
 import com.qs.mp.admin.domain.CdKey;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qs.mp.admin.domain.CdKeyGroup;
 import com.qs.mp.admin.domain.vo.CdKeyExchangeVO;
 import com.qs.mp.admin.domain.vo.CdKeyGroupListVO;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -18,5 +20,7 @@ public interface ICdKeyService extends IService<CdKey> {
 
     List<CdKeyGroupListVO> listCdKeyVO(QueryWrapper<CdKeyGroup> queryWrapper);
 
-    CdKeyExchangeVO listCdKeyExchangeVO(QueryWrapper<CdKey> queryWrapper);
+    List<CdKeyExchangeVO> listCdKeyExchangeVO(@Param(Constants.WRAPPER) QueryWrapper<CdKey> queryWrapper);
+
+    void exchangeCdKey(Long keyId);
 }

+ 7 - 0
mp-service/src/main/java/com/qs/mp/admin/service/ICouponPkgService.java

@@ -63,4 +63,11 @@ public interface ICouponPkgService extends IService<CouponPkg> {
      * @param couponPkgId
      */
     void distributeByMarketing(Long userId, String couponPkgId);
+
+    /**
+     * 兑换码劵包发劵
+     * @param userId
+     * @param couponPkgId
+     */
+    void distributeByCdKey(Long userId, String couponPkgId);
 }

+ 7 - 0
mp-service/src/main/java/com/qs/mp/admin/service/ICouponService.java

@@ -56,4 +56,11 @@ public interface ICouponService extends IService<Coupon> {
 	 * @param couponId
 	 */
 	void distributeByNewUser(Long userId, Long couponId);
+
+	/**
+	 * 兑换码发卷
+	 * @param userId
+	 * @param couponId
+	 */
+	void distributeByCdKey(Long userId, String couponId);
 }

+ 125 - 1
mp-service/src/main/java/com/qs/mp/admin/service/impl/CdKeyExchangeServiceImpl.java

@@ -1,10 +1,37 @@
 package com.qs.mp.admin.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qs.mp.admin.domain.CdKey;
 import com.qs.mp.admin.domain.CdKeyExchange;
 import com.qs.mp.admin.mapper.CdKeyExchangeMapper;
 import com.qs.mp.admin.service.ICdKeyExchangeService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qs.mp.admin.service.ICdKeyService;
+import com.qs.mp.admin.service.ICouponPkgService;
+import com.qs.mp.admin.service.ICouponService;
+import com.qs.mp.common.core.redis.DistributedLocker;
+import com.qs.mp.common.enums.CdKeyGroupGoodsTypeEnum;
+import com.qs.mp.common.enums.CoinLogTypeEnum;
+import com.qs.mp.common.enums.PrizeStorageInTypeEnum;
+import com.qs.mp.common.exception.ServiceException;
+import com.qs.mp.core.domain.LoginUser;
+import com.qs.mp.framework.redis.RedisLockKey;
+import com.qs.mp.user.domain.UserCoin;
+import com.qs.mp.user.domain.UserCoinLog;
+import com.qs.mp.user.domain.vo.UserExchangeCdKeyVO;
+import com.qs.mp.user.service.IUserCoinLogService;
+import com.qs.mp.user.service.IUserCoinService;
+import com.qs.mp.user.service.IUserPrizeStorageService;
+import com.qs.mp.utils.SecurityUtils;
+import org.slf4j.Logger;
+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;
+
+import java.util.Date;
 
 /**
  * @auther quanshu
@@ -14,4 +41,101 @@ import org.springframework.stereotype.Service;
 @Service
 public class CdKeyExchangeServiceImpl extends ServiceImpl<CdKeyExchangeMapper, CdKeyExchange> implements ICdKeyExchangeService {
 
+    private static final Logger logger = LoggerFactory.getLogger(CdKeyExchangeServiceImpl.class);
+
+    @Autowired
+    private IUserPrizeStorageService userPrizeStorageService;
+
+    @Autowired
+    private ICdKeyService cdKeyService;
+
+    @Autowired
+    private ICouponService couponService;
+
+    @Autowired
+    private ICouponPkgService couponPkgService;
+
+    @Autowired
+    private IUserCoinService userCoinService;
+
+    @Autowired
+    private DistributedLocker distributedLocker;
+
+    @Autowired
+    private IUserCoinLogService userCoinLogService;
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public UserExchangeCdKeyVO exchangeCdKey(Long keyId) {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+        String LockKey = RedisLockKey.build(RedisLockKey.USER_CD_KEY_EXCHANGE_LOCK, loginUser.getUserId());
+        if (!distributedLocker.tryLock(LockKey)) {
+            throw new ServiceException("系统繁忙,请稍后再试");
+        }
+        UserExchangeCdKeyVO userExchangeCdKeyVO = null;
+        try {
+            // 更新兑换码状态
+            boolean rst = cdKeyService.update(new UpdateWrapper<CdKey>().set("status", "1").eq("key_id", keyId));
+            Assert.isTrue(rst, "更新兑换码状态失败");
+
+            // 插入兑换记录
+            CdKey cdKey = cdKeyService.getById(keyId);
+            CdKeyExchange exchange = new CdKeyExchange();
+            exchange.setGroupId(cdKey.getGroupId());
+            exchange.setKeyId(String.valueOf(cdKey.getKeyId()));
+            exchange.setUserId(loginUser.getUserId());
+            exchange.setExchangeTime(new Date());
+            save(exchange);
+
+            // 分发对应商品
+            if (CdKeyGroupGoodsTypeEnum.GOODS == cdKey.getType()) {
+                userPrizeStorageService.takeInStorage(loginUser.getUserId(), cdKey.getGoodsName(), cdKey.getPicUrl(), cdKey.getRefId(), PrizeStorageInTypeEnum.CD_KEY_EXCHANGE, String.valueOf(exchange.getId()));
+            }else if (CdKeyGroupGoodsTypeEnum.COUPON == cdKey.getType()) {
+                couponService.distributeByCdKey(loginUser.getUserId(), cdKey.getRefId());
+            } else if (CdKeyGroupGoodsTypeEnum.COUPON_PKG == cdKey.getType()) {
+                couponPkgService.distributeByCdKey(loginUser.getUserId(), cdKey.getRefId());
+            } else {
+                UserCoin userCoin = userCoinService.getById(loginUser.getUserId());
+                if (userCoin == null) {
+                    // 用户从未获得过盲豆
+                    UserCoin userNoCoin = new UserCoin();
+                    userNoCoin.setCoin(cdKey.getValue());
+                    userNoCoin.setUserId(loginUser.getUserId());
+                    userNoCoin.setCreatedTime(new Date());
+                    userNoCoin.setUpdatedTime(new Date());
+                    boolean rtn2 = userCoinService.save(userNoCoin);
+                    Assert.isTrue(rtn2, "从未获得过盲豆的用户通过兑换码兑换盲豆失败, userId:" + loginUser.getUserId());
+                } else {
+                    boolean rtn3 = userCoinService.update(new LambdaUpdateWrapper<UserCoin>().set(UserCoin::getCoin, userCoin.getCoin() + cdKey.getValue())
+                            .eq(UserCoin::getUserId, loginUser.getUserId()));
+                    Assert.isTrue(rtn3, "增加通过兑换码兑换盲豆失败,userId:" + loginUser.getUserId());
+                }
+
+                UserCoinLog userCoinToLog = new UserCoinLog();
+                userCoinToLog.setUserId(loginUser.getUserId());
+                userCoinToLog.setType(CoinLogTypeEnum.CD_KEPT);
+                userCoinToLog.setMoney(userCoin == null ? cdKey.getValue() : userCoin.getCoin() + cdKey.getValue());
+                userCoinToLog.setLogMoney(cdKey.getValue());
+                userCoinToLog.setIncomeExpense(CoinLogTypeEnum.INCOME);
+                userCoinToLog.setLogText("兑换码兑换");
+                userCoinToLog.setBizTime(new Date());
+                userCoinToLog.setCreatedTime(new Date());
+                userCoinToLog.setUpdatedTime(new Date());
+                userCoinLogService.save(userCoinToLog);
+            }
+
+            userExchangeCdKeyVO = new UserExchangeCdKeyVO();
+            userExchangeCdKeyVO.setType(cdKey.getType().getValue());
+            userExchangeCdKeyVO.setGoodsName(cdKey.getGoodsName());
+            userExchangeCdKeyVO.setPicUrl(cdKey.getPicUrl());
+            userExchangeCdKeyVO.setValue(cdKey.getValue());
+        } catch (Exception e) {
+            logger.error("兑换码兑换异常" + e.getMessage());
+            throw new RuntimeException(e);
+        } finally {
+            distributedLocker.unlock(LockKey);
+        }
+        return userExchangeCdKeyVO;
+    }
 }

+ 1 - 0
mp-service/src/main/java/com/qs/mp/admin/service/impl/CdKeyGroupServiceImpl.java

@@ -151,6 +151,7 @@ public class CdKeyGroupServiceImpl extends ServiceImpl<CdKeyGroupMapper, CdKeyGr
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void generateCdKey(String groupId) {
         QueryWrapper<CdKeyGroupGoods> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("group_id", groupId);

+ 47 - 1
mp-service/src/main/java/com/qs/mp/admin/service/impl/CdKeyServiceImpl.java

@@ -1,15 +1,27 @@
 package com.qs.mp.admin.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.qs.mp.admin.domain.CdKey;
+import com.qs.mp.admin.domain.CdKeyExchange;
 import com.qs.mp.admin.domain.CdKeyGroup;
 import com.qs.mp.admin.domain.vo.CdKeyExchangeVO;
 import com.qs.mp.admin.domain.vo.CdKeyGroupListVO;
 import com.qs.mp.admin.mapper.CdKeyMapper;
+import com.qs.mp.admin.service.ICdKeyExchangeService;
 import com.qs.mp.admin.service.ICdKeyService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qs.mp.common.enums.CdKeyGroupGoodsTypeEnum;
+import com.qs.mp.common.enums.PrizeStorageInTypeEnum;
+import com.qs.mp.core.domain.LoginUser;
+import com.qs.mp.user.service.IUserPrizeStorageService;
+import com.qs.mp.utils.SecurityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.Assert;
 
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -20,13 +32,47 @@ import java.util.List;
 @Service
 public class CdKeyServiceImpl extends ServiceImpl<CdKeyMapper, CdKey> implements ICdKeyService {
 
+    @Autowired
+    private IUserPrizeStorageService userPrizeStorageService;
+
+    @Autowired
+    private ICdKeyExchangeService cdKeyExchangeService;
+
     @Override
     public List<CdKeyGroupListVO> listCdKeyVO(QueryWrapper<CdKeyGroup> queryWrapper) {
         return getBaseMapper().listCdKeyVO(queryWrapper);
     }
 
     @Override
-    public CdKeyExchangeVO listCdKeyExchangeVO(QueryWrapper<CdKey> queryWrapper) {
+    public List<CdKeyExchangeVO> listCdKeyExchangeVO(QueryWrapper<CdKey> queryWrapper) {
         return getBaseMapper().listCdKeyExchangeVO(queryWrapper);
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void exchangeCdKey(Long keyId) {
+        LoginUser loginUser = SecurityUtils.getLoginUser();
+
+        // 更新兑换码状态
+        boolean rst = update(new UpdateWrapper<CdKey>().set("status", "1").eq("key_id", keyId));
+        Assert.isTrue(rst, "更新兑换码状态失败");
+
+        // 插入兑换记录
+        CdKey cdKey = getById(keyId);
+        CdKeyExchange exchange = new CdKeyExchange();
+        exchange.setGroupId(cdKey.getGroupId());
+        exchange.setKeyId(String.valueOf(cdKey.getKeyId()));
+        exchange.setUserId(loginUser.getUserId());
+        exchange.setExchangeTime(new Date());
+        cdKeyExchangeService.save(exchange);
+
+        // 分发对应商品
+        if (CdKeyGroupGoodsTypeEnum.GOODS == cdKey.getType()) {
+            userPrizeStorageService.takeInStorage(loginUser.getUserId(), cdKey.getGoodsName(), cdKey.getPicUrl(), cdKey.getRefId(), PrizeStorageInTypeEnum.CD_KEY_EXCHANGE, String.valueOf(exchange.getId()));
+        }else if (CdKeyGroupGoodsTypeEnum.COUPON == cdKey.getType()) {
+
+        }
+
+
+    }
 }

+ 15 - 0
mp-service/src/main/java/com/qs/mp/admin/service/impl/CouponPkgServiceImpl.java

@@ -83,6 +83,21 @@ public class CouponPkgServiceImpl extends ServiceImpl<CouponPkgMapper, CouponPkg
         }
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void distributeByCdKey(Long userId, String couponPkgId) {
+        List<CouponPkgItem> couponPkgItems = couponPkgItemService.list(new LambdaQueryWrapper<CouponPkgItem>().eq(CouponPkgItem::getCouponPkgId, couponPkgId));
+
+        if (CollectionUtils.isEmpty(couponPkgItems)) {
+            throw new ServiceException("券包下优惠券不存在");
+        }
+        for (CouponPkgItem couponPkgItem : couponPkgItems) {
+            for (int i = 0; i < couponPkgItem.getCouponNum(); i++) {
+                couponService.distributeByCdKey(userId, couponPkgItem.getCouponId().toString());
+            }
+        }
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void distribute(Ticket ticket, Long userId, String couponPkgId) {

+ 15 - 0
mp-service/src/main/java/com/qs/mp/admin/service/impl/CouponServiceImpl.java

@@ -110,6 +110,21 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
         }
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void distributeByCdKey(Long userId, String couponId) {
+        Coupon coupon = getById(couponId);
+        UserCoupon userCoupon = getUserCoupon(userId, coupon);
+        userCoupon.setUseAreaDesc(coupon.getUseArea().getDesc());
+        userCouponService.save(userCoupon);
+        boolean rtn = update(new LambdaUpdateWrapper<Coupon>().set(Coupon::getDistributeQty, coupon.getDistributeQty() + 1)
+                .eq(Coupon::getCouponId, coupon.getCouponId()).eq(Coupon::getDistributeQty, coupon.getDistributeQty()));
+        if (!rtn) {
+            logger.error("兑换码兑换发送优惠卷失败.couponId:{}", coupon.getCouponId());
+            throw new ServiceException("兑换码兑换发送优惠卷失败。couponId:" + coupon.getCouponId());
+        }
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void distribute(Ticket ticket, Long userId, String couponId) {

+ 2 - 0
mp-service/src/main/java/com/qs/mp/framework/redis/RedisLockKey.java

@@ -20,6 +20,8 @@ public enum RedisLockKey {
     USER_TICKET_CASH_LOCK("user_ticket_cash_lock_{0}", "盲票兑奖锁"),
 
     USER_COIN_TRANSFER_LOCK("user_coin_transfer_lock_{0}", "盲豆转赠锁"),
+
+    USER_CD_KEY_EXCHANGE_LOCK("user_cd_key_exchange_lock_{0}", "兑换码兑换锁"),
     ;
 
 

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

@@ -88,7 +88,7 @@ public class UserPrizeStorage implements Serializable {
    */
   @TableField("in_type")
   @JSONField(serialzeFeatures = SerializerFeature.WriteEnumUsingToString)
-  @ApiModelProperty("入库类型;1盲票兑奖、2盲豆兑换,3营销活动,4盲票购买")
+  @ApiModelProperty("入库类型;1盲票兑奖、2盲豆兑换,3营销活动,4盲票购买,5兑换码兑换")
   private PrizeStorageInTypeEnum inType;
 
   /**

+ 0 - 6
mp-service/src/main/java/com/qs/mp/user/domain/param/CdKeyExchangeParam.java

@@ -12,12 +12,6 @@ import lombok.Data;
 @Data
 public class CdKeyExchangeParam {
 
-    @ApiModelProperty("用户id")
-    private Long userId;
-
-    @ApiModelProperty("用户昵称")
-    private String nickName;
-
     @ApiModelProperty("兑换码")
     private String cdKey;
 

+ 22 - 0
mp-service/src/main/java/com/qs/mp/user/domain/vo/UserExchangeCdKeyVO.java

@@ -0,0 +1,22 @@
+package com.qs.mp.user.domain.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author zhangkaikai
+ * @create 2023-05-19 10:27 AM
+ **/
+@Data
+@ApiModel("用户兑换码兑换VO")
+public class UserExchangeCdKeyVO {
+    @ApiModelProperty("商品名称")
+    private String goodsName;
+    @ApiModelProperty("商品价值")
+    private Integer value;
+    @ApiModelProperty("商品图片")
+    private String picUrl;
+    @ApiModelProperty("商品类型 goods 实物商品 coupon优惠券 coin平台代币 coupon_pkg券包")
+    private String type;
+}

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

@@ -174,7 +174,7 @@ public class UserDeliverOrderServiceImpl extends ServiceImpl<UserDeliverOrderMap
                     .set(UserPrizeStorage::getStatus, PrizeStorageStatusEnum.HAS_DISTRIBUTED)
                     .eq(UserPrizeStorage::getStorageId, prizeStorage.getStorageId()));
 
-                Assert.isTrue(rtn, "提交提货订单时,更新状态失败。userDeliverOrder:" + JSONObject.toJSONString(userDeliverOrder));
+                Assert.isTrue(rtn, "提交提货或兑换码兑换订单时,更新状态失败。userDeliverOrder:" + JSONObject.toJSONString(userDeliverOrder));
 
             }
 

+ 4 - 5
mp-service/src/main/resources/mapper/admin/CdKeyMapper.xml

@@ -25,12 +25,11 @@
         left join mp_cd_key_group_goods t3 on t1.group_id = t3.group_id
         ${ew.customSqlSegment}
     </select>
-
     <select id="listCdKeyExchangeVO" resultType="com.qs.mp.admin.domain.vo.CdKeyExchangeVO">
-        select t1.title,t1.pic_url
-        from mp_cd_key_group_goods t1
-        left join on mp_cd_key_group t2 t1.group_id = t2.group_id
-        left join on
+        select t1.*
+        from mp_cd_key t1 left join mp_cd_key_exchange t2 on t1.key_id = t2.key_id
+            ${ew.customSqlSegment}
     </select>
 
+
 </mapper>