소스 검색

活动开奖

cup 2 년 전
부모
커밋
5e1ebb0e2f
19개의 변경된 파일447개의 추가작업 그리고 34개의 파일을 삭제
  1. 22 0
      mp-common/src/main/java/com/qs/mp/common/core/redis/RedisCache.java
  2. 5 1
      mp-common/src/main/java/com/qs/mp/common/enums/CoinLogTypeEnum.java
  3. 76 0
      mp-quartz/src/main/java/com/qs/mp/quartz/task/MarketingTask.java
  4. 6 0
      mp-service/src/main/java/com/qs/mp/admin/service/ICouponPkgService.java
  5. 7 0
      mp-service/src/main/java/com/qs/mp/admin/service/ICouponService.java
  6. 6 0
      mp-service/src/main/java/com/qs/mp/admin/service/IMarketingService.java
  7. 16 0
      mp-service/src/main/java/com/qs/mp/admin/service/impl/CouponPkgServiceImpl.java
  8. 26 1
      mp-service/src/main/java/com/qs/mp/admin/service/impl/CouponServiceImpl.java
  9. 240 12
      mp-service/src/main/java/com/qs/mp/admin/service/impl/MarketingServiceImpl.java
  10. 7 0
      mp-service/src/main/java/com/qs/mp/system/mapper/SysUserMapper.java
  11. 8 0
      mp-service/src/main/java/com/qs/mp/system/service/ISysUserService.java
  12. 5 0
      mp-service/src/main/java/com/qs/mp/system/service/impl/SysUserServiceImpl.java
  13. 2 2
      mp-service/src/main/java/com/qs/mp/user/domain/MarketingHitPrize.java
  14. 2 1
      mp-service/src/main/java/com/qs/mp/user/service/IUserCoinService.java
  15. 1 1
      mp-service/src/main/java/com/qs/mp/user/service/IUserPrizeStorageService.java
  16. 4 4
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserCoinServiceImpl.java
  17. 3 8
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserHitPrizeServiceImpl.java
  18. 4 4
      mp-service/src/main/java/com/qs/mp/user/service/impl/UserPrizeStorageServiceImpl.java
  19. 7 0
      mp-service/src/main/resources/mapper/system/SysUserMapper.xml

+ 22 - 0
mp-common/src/main/java/com/qs/mp/common/core/redis/RedisCache.java

@@ -160,6 +160,28 @@ public class RedisCache
         return redisTemplate.opsForSet().members(key);
     }
 
+    /**
+     * 随机获取N个缓存的set
+     *
+     * @param key
+     * @return
+     */
+    public <T> List<T> popCacheSet(final String key, final long count)
+    {
+        return redisTemplate.opsForSet().pop(key,count);
+    }
+
+    /**
+     * 删除缓存的set中指定的值
+     *
+     * @param key 缓存键值
+     */
+    public void removeSetValueByKey(final String key, final List<Object> values)
+    {
+        redisTemplate.opsForSet().remove(key, values.toArray());
+    }
+
+
     /**
      * 缓存Map
      *

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

@@ -11,7 +11,8 @@ import com.baomidou.mybatisplus.annotation.IEnum;
 public enum CoinLogTypeEnum implements IEnum<Integer> {
 
   PRIZE(1, "盲票奖品"),
-  EXCHANGE(2, "商品兑换");
+  EXCHANGE(2, "商品兑换"),
+  MARKETING(3,"营销活动");
 
 
   private final int value;
@@ -38,6 +39,9 @@ public enum CoinLogTypeEnum implements IEnum<Integer> {
     return value;
   }
 
+  public String getDesc() {
+    return desc;
+  }
 
   @Override
   public String toString() {

+ 76 - 0
mp-quartz/src/main/java/com/qs/mp/quartz/task/MarketingTask.java

@@ -0,0 +1,76 @@
+package com.qs.mp.quartz.task;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.qs.mp.admin.domain.Marketing;
+import com.qs.mp.admin.service.IMarketingAwardsService;
+import com.qs.mp.admin.service.IMarketingService;
+import com.qs.mp.common.core.redis.DistributedLocker;
+import com.qs.mp.common.core.redis.RedisCache;
+import com.qs.mp.common.enums.MarketingStatusEnum;
+import com.qs.mp.common.utils.DateUtils;
+import com.qs.mp.user.service.IMarketingUserCodeService;
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 营销活动相关任务
+ *
+ * @author Cup
+ * @date 2022/5/18
+ */
+@Component("marketingTask")
+public class MarketingTask {
+
+    public static final String MARKETING_LOTTERY_KEY = "MARKETING_LOTTERY_KEY";
+
+
+    @Autowired
+    private DistributedLocker distributedLocker;
+
+    @Autowired
+    private IMarketingService marketingService;
+
+
+    /**
+     * 开奖任务方法
+     */
+    public void lottery() {
+
+        // 加锁
+        if (!distributedLocker.tryLock(MARKETING_LOTTERY_KEY)) {
+            return;
+        }
+        try {
+            // 获取结束时间小于等于当前时间且未开奖的一个活动
+            Date now = DateUtils.getNowDate();
+            Marketing marketing = marketingService.getOne(new LambdaQueryWrapper<Marketing>()
+                    .eq(Marketing::getTriggerStatus, 0)
+                    .eq(Marketing::getIsOn, MarketingStatusEnum.ON.getValue())
+                    .le(Marketing::getEndTime, now)
+                    .last("limit 1"));
+            if (Objects.isNull(marketing)) {
+                return;
+            }
+
+            // 开奖
+            marketingService.lottery(marketing);
+
+
+        }finally {
+            // 释放锁
+            distributedLocker.unlock(MARKETING_LOTTERY_KEY);
+        }
+
+
+
+    }
+
+
+}

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

@@ -57,4 +57,10 @@ public interface ICouponPkgService extends IService<CouponPkg> {
      */
     void distribute(Ticket ticket, Long userId, String couponPkgId);
 
+    /**
+     * 营销活动券包发券
+     * @param userId
+     * @param couponPkgId
+     */
+    void distributeByMarketing(Long userId, String couponPkgId);
 }

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

@@ -41,4 +41,11 @@ public interface ICouponService extends IService<Coupon> {
 	 * @param couponId
 	 */
 	void distribute(Ticket ticket, Long userId, String couponId);
+
+	/**
+	 * 营销活动优惠券发放
+	 * @param userId
+	 * @param couponId
+	 */
+    void distributeByMarketing(Long userId, String couponId);
 }

+ 6 - 0
mp-service/src/main/java/com/qs/mp/admin/service/IMarketingService.java

@@ -51,4 +51,10 @@ public interface IMarketingService extends IService<Marketing> {
      * @param userId
      */
     void help(MarketingHelpParam marketingHelpParam, Long userId);
+
+    /**
+     * 开奖
+     * @param marketing
+     */
+    void lottery(Marketing marketing);
 }

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

@@ -66,6 +66,22 @@ public class CouponPkgServiceImpl extends ServiceImpl<CouponPkgMapper, CouponPkg
     @Autowired
     private ICouponService couponService;
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+
+    public void distributeByMarketing(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.distributeByMarketing(userId, couponPkgItem.getCouponId().toString());
+            }
+        }
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void distribute(Ticket ticket, Long userId, String couponPkgId) {

+ 26 - 1
mp-service/src/main/java/com/qs/mp/admin/service/impl/CouponServiceImpl.java

@@ -75,7 +75,32 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
 	@Autowired
 	private IChannelService channelService;
 
-  @Override
+	@Override
+	@Transactional(rollbackFor = Exception.class)
+	public void distributeByMarketing(Long userId, String couponId) {
+		Coupon coupon = getById(couponId);
+		UserCoupon userCoupon = new UserCoupon();
+		userCoupon.setId(bizIdGenerator.newIdWithUidSharding(String.valueOf(userId)));
+		userCoupon.setUserId(userId);
+		userCoupon.setVerifyCode(bizIdGenerator.newIdWithUidSharding(String.valueOf(userId)));
+		userCoupon.setCouponId(coupon.getCouponId());
+		if (coupon.getDueDays() > 0) {
+			userCoupon.setValidStart(DateUtils.getToday());
+			userCoupon.setValidEnd(DateUtils.addDays(userCoupon.getValidStart(), coupon.getDueDays() - 1));
+		} else {
+			userCoupon.setValidStart(coupon.getValidStart());
+			userCoupon.setValidEnd(coupon.getValidEnd());
+		}
+		userCoupon.setStatus(UserCouponStatusEnum.UNUSED);
+		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()));
+		Assert.isTrue(rtn, "发放优惠券奖品,更新优惠券发放量失败。couponId:" + coupon.getCouponId());
+	}
+
+
+	@Override
   @Transactional(rollbackFor = Exception.class)
   public void distribute(Ticket ticket, Long userId, String couponId) {
     Coupon coupon = getById(couponId);

+ 240 - 12
mp-service/src/main/java/com/qs/mp/admin/service/impl/MarketingServiceImpl.java

@@ -1,6 +1,7 @@
 package com.qs.mp.admin.service.impl;
 
-import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.RandomUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -11,26 +12,30 @@ import com.qs.mp.admin.mapper.MarketingMapper;
 import com.qs.mp.admin.service.*;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qs.mp.common.core.domain.AjaxResult;
-import com.qs.mp.common.enums.MarketingStatusEnum;
-import com.qs.mp.common.enums.TicketPrizeTypeEnum;
-import com.qs.mp.common.enums.UserTypeEnum;
+import com.qs.mp.common.core.redis.RedisCache;
+import com.qs.mp.common.enums.*;
 import com.qs.mp.common.exception.ServiceException;
 import com.qs.mp.common.utils.DateUtils;
 import com.qs.mp.common.utils.bean.BeanUtils;
+import com.qs.mp.system.domain.SysUser;
+import com.qs.mp.system.service.ISysUserService;
+import com.qs.mp.system.service.id.BizIdGenerator;
+import com.qs.mp.user.domain.MarketingHitPrize;
 import com.qs.mp.user.domain.MarketingUserCode;
 import com.qs.mp.user.domain.param.MarketingHelpParam;
+import com.qs.mp.user.service.IMarketingHitPrizeService;
 import com.qs.mp.user.service.IMarketingUserCodeService;
+import com.qs.mp.user.service.IUserCoinService;
+import com.qs.mp.user.service.IUserPrizeStorageService;
 import com.qs.mp.utils.MarketingUtils;
 import org.apache.commons.lang3.StringUtils;
 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.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -44,6 +49,13 @@ import java.util.stream.Collectors;
 @Service
 public class MarketingServiceImpl extends ServiceImpl<MarketingMapper, Marketing> implements IMarketingService {
 
+    // 内部奖池
+    public static final String MARKETING_LOTTERY_INSIDE_POOL = "MARKETING_LOTTERY_INSIDE_POOL";
+
+    // 普通奖池
+    public static final String MARKETING_LOTTERY_ORDINARY_POOL = "MARKETING_LOTTERY_ORDINARY_POOL";
+
+
     @Autowired
     private IGoodsService goodsService;
 
@@ -62,6 +74,221 @@ public class MarketingServiceImpl extends ServiceImpl<MarketingMapper, Marketing
     @Autowired
     private IMarketingUserCodeService marketingUserCodeService;
 
+    @Autowired
+    private ISysUserService sysUserService;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    @Autowired
+    private IMarketingHitPrizeService marketingHitPrizeService;
+
+    @Autowired
+    private IUserCoinService userCoinService;
+
+    @Autowired
+    private IUserPrizeStorageService userPrizeStorageService;
+
+    @Autowired
+    private BizIdGenerator bizIdGenerator;
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void lottery(Marketing marketing) {
+
+        // 获取奖级信息
+        List<MarketingAwards> marketingAwardsList = marketingAwardsService.list(new LambdaQueryWrapper<MarketingAwards>()
+                .eq(MarketingAwards::getMarketingId, marketing.getId()));
+
+        // 奖品总数
+        int prizeQuantity = marketingAwardsList.stream().mapToInt(MarketingAwards::getQuantity).sum();
+
+        // 校准并获取真实参与人数
+        int realNum = marketingUserCodeService.count(new LambdaQueryWrapper<MarketingUserCode>()
+                .eq(MarketingUserCode::getMarketingId, marketing.getId())
+                .eq(MarketingUserCode::getUserType, UserTypeEnum.ORDINARY.getValue())
+                .groupBy(MarketingUserCode::getMarketingId));
+
+        // 设置需要的内定人数
+        int insideNum = 0;
+
+        boolean isInside = false;
+
+        // 参与人数不足,全部采用内定人员开奖
+        if (prizeQuantity >= realNum) {
+            insideNum = prizeQuantity;
+            isInside = true;
+        } else {
+            insideNum = marketingAwardsList.stream().mapToInt(MarketingAwards::getInsideNum).sum();
+        }
+
+        // 获取一定数量的内定人员设置抽奖码加入抽奖关系表和抽奖池
+        List<SysUser> insideUserList = sysUserService.selectUserListByRand(UserTypeEnum.INSIDE.getValue(), insideNum);
+
+        Set<String> codeList = new HashSet<>();
+        for (SysUser sysUser : insideUserList) {
+            // 生成抽奖码
+            String code = MarketingUtils.generatePrizeCode();
+            while (true) {
+                // 判断抽奖码是否已经存在
+                int codeCount = marketingUserCodeService.count(new LambdaQueryWrapper<MarketingUserCode>()
+                        .eq(MarketingUserCode::getMarketingId, marketing.getId())
+                        .eq(MarketingUserCode::getCode, code));
+                if (codeCount > 0) {
+                    code = MarketingUtils.generatePrizeCode();
+                    continue;
+                }
+                break;
+            }
+            codeList.add(code);
+            MarketingUserCode marketingUserCode = new MarketingUserCode();
+            marketingUserCode.setMarketingId(marketing.getId());
+            marketingUserCode.setUserId(sysUser.getUserId());
+            marketingUserCode.setUserType(UserTypeEnum.INSIDE.getValue());
+            marketingUserCode.setCode(code);
+            marketingUserCode.setHelpUserId(0L);
+            // 设置中奖
+            marketingUserCode.setIsHit(1);
+            marketingUserCodeService.save(marketingUserCode);
+        }
+        // 将抽奖码放入内部抽奖池
+        redisCache.setCacheSet(MARKETING_LOTTERY_INSIDE_POOL, codeList);
+
+
+        // 获取普通用户所有的抽奖码
+        List<MarketingUserCode> userCodeList = marketingUserCodeService.list(new LambdaQueryWrapper<MarketingUserCode>()
+                .eq(MarketingUserCode::getMarketingId, marketing.getId())
+                .eq(MarketingUserCode::getUserType, UserTypeEnum.ORDINARY.getValue()));
+        codeList.clear();
+        if (CollectionUtils.isNotEmpty(userCodeList)) {
+            codeList = userCodeList.stream().map(MarketingUserCode::getCode).collect(Collectors.toSet());
+        }
+        // 将抽奖码放入普通抽奖池
+        redisCache.setCacheSet(MARKETING_LOTTERY_ORDINARY_POOL, codeList);
+
+        // 所有中奖名单
+        List<MarketingHitPrize> allHitPrizeList = new ArrayList<>();
+
+        // 普通用户中奖名单
+        List<MarketingHitPrize> userHitPrizeList = new ArrayList<>();
+
+        // 抽奖码中奖状态更新列表
+        List<MarketingUserCode> userCodeUpdateList = new ArrayList<>();
+
+        // 遍历奖级进行抽奖
+        for (MarketingAwards marketingAwards : marketingAwardsList) {
+            // 获取内部人数
+            if (isInside) {
+                insideNum = marketingAwards.getQuantity();
+            } else {
+                insideNum = marketingAwards.getInsideNum();
+            }
+
+            List<MarketingAwardsPrize> marketingAwardsPrizeList = marketingAwardsPrizeService.list(new LambdaQueryWrapper<MarketingAwardsPrize>()
+                    .eq(MarketingAwardsPrize::getMarketingId, marketing.getId())
+                    .eq(MarketingAwardsPrize::getAwardsId, marketingAwards.getId()));
+
+            if (insideNum != 0) {
+                // 设置内部用户抽奖信息
+                List<String> insideCodeList = redisCache.popCacheSet(MARKETING_LOTTERY_INSIDE_POOL, insideNum);
+                for (String code : insideCodeList) {
+                    MarketingUserCode marketingUserCode = marketingUserCodeService.getOne(new LambdaQueryWrapper<MarketingUserCode>()
+                            .eq(MarketingUserCode::getMarketingId, marketing.getId())
+                            .eq(MarketingUserCode::getCode, code));
+
+                    // 设置中奖信息
+                    MarketingHitPrize marketingHitPrize = new MarketingHitPrize();
+                    marketingHitPrize.setId(bizIdGenerator.newId());
+                    marketingHitPrize.setMarketingId(marketing.getId());
+                    marketingHitPrize.setAwardsId(marketingAwards.getId());
+                    marketingHitPrize.setMarketingUserCodeId(marketingUserCode.getId());
+                    marketingHitPrize.setUserId(marketingUserCode.getUserId());
+                    marketingHitPrize.setUserType(marketingUserCode.getUserType());
+
+                    // 随机抽取奖品,[0, list.size)  左闭右开
+                    int randomIndex = RandomUtil.randomInt(0, marketingAwardsPrizeList.size());
+                    marketingHitPrize.setPrizeId(marketingAwardsPrizeList.get(randomIndex).getId());
+
+                    allHitPrizeList.add(marketingHitPrize);
+                }
+            }
+
+            // 用户中奖数量为 名额 - 内定人数
+            int userNum = marketingAwards.getQuantity() - insideNum;
+            if (userNum > 0) {
+                // 设置普通用户抽奖信息
+                for (int i = 0; i < userNum; i++) {
+                    List<String> insideCodeList = redisCache.popCacheSet(MARKETING_LOTTERY_INSIDE_POOL, 1);
+                    MarketingUserCode marketingUserCode = marketingUserCodeService.getOne(new LambdaQueryWrapper<MarketingUserCode>()
+                            .eq(MarketingUserCode::getMarketingId, marketing.getId())
+                            .eq(MarketingUserCode::getCode, insideCodeList.get(0)));
+
+                    // 删除redis中该用户所有的抽奖码
+                    List<MarketingUserCode> list = marketingUserCodeService.list(new LambdaQueryWrapper<MarketingUserCode>()
+                            .eq(MarketingUserCode::getMarketingId, marketing.getId())
+                            .eq(MarketingUserCode::getUserId, marketingUserCode.getUserId()));
+                    List<Object> delUserCodeList = list.stream().map(MarketingUserCode::getCode).collect(Collectors.toList());
+                    redisCache.removeSetValueByKey(MARKETING_LOTTERY_ORDINARY_POOL, delUserCodeList);
+
+
+                    // 设置中奖信息
+                    MarketingHitPrize marketingHitPrize = new MarketingHitPrize();
+                    marketingHitPrize.setId(bizIdGenerator.newId());
+                    marketingHitPrize.setMarketingId(marketing.getId());
+                    marketingHitPrize.setAwardsId(marketingAwards.getId());
+                    marketingHitPrize.setMarketingUserCodeId(marketingUserCode.getId());
+                    marketingHitPrize.setUserId(marketingUserCode.getUserId());
+                    marketingHitPrize.setUserType(marketingUserCode.getUserType());
+
+                    // 随机抽取奖品,[0, list.size)  左闭右开
+                    int randomIndex = RandomUtil.randomInt(0, marketingAwardsPrizeList.size());
+                    marketingHitPrize.setPrizeId(marketingAwardsPrizeList.get(randomIndex).getId());
+
+                    allHitPrizeList.add(marketingHitPrize);
+                    userHitPrizeList.add(marketingHitPrize);
+
+                    // 更新用户中奖状态
+                    marketingUserCode.setIsHit(1);
+                    userCodeUpdateList.add(marketingUserCode);
+                }
+            }
+        }
+        // 保存中奖信息
+        marketingHitPrizeService.saveBatch(allHitPrizeList);
+
+        // 更新抽奖码中奖状态
+        if (CollectionUtils.isNotEmpty(userCodeUpdateList)) {
+            marketingUserCodeService.updateBatchById(userCodeUpdateList);
+        }
+
+        // 发奖品
+        if (CollectionUtils.isNotEmpty(userHitPrizeList)) {
+            for (MarketingHitPrize marketingHitPrize : userHitPrizeList) {
+                MarketingAwardsPrize marketingAwardsPrize = marketingAwardsPrizeService.getById(marketingHitPrize.getPrizeId());
+
+                // 放入仓库
+                if (marketingAwardsPrize.getPrizeType() == TicketPrizeTypeEnum.COIN) {
+                    userCoinService.produce(marketingHitPrize.getUserId(), marketingAwardsPrize.getValue(), String.valueOf(marketingHitPrize.getId()), CoinLogTypeEnum.MARKETING);
+                } else if (marketingAwardsPrize.getPrizeType() == TicketPrizeTypeEnum.COUPON) {
+                    couponService.distributeByMarketing(marketingHitPrize.getUserId(), marketingAwardsPrize.getRefId());
+                } else if (marketingAwardsPrize.getPrizeType() == TicketPrizeTypeEnum.COUPON_PKG) {
+                    couponPkgService.distributeByMarketing(marketingHitPrize.getUserId(), marketingAwardsPrize.getRefId());
+                } else {
+                    // 实物奖品
+                    userPrizeStorageService.takeInStorage(marketingHitPrize.getUserId(), marketingAwardsPrize.getTitle(), marketingAwardsPrize.getPicUrl(), marketingAwardsPrize.getRefId(), PrizeStorageInTypeEnum.MARKETING, marketingHitPrize.getId());
+                }
+            }
+        }
+
+        // 更新活动状态
+        boolean rtn = this.update(new LambdaUpdateWrapper<Marketing>().set(Marketing::getTriggerStatus, 1)
+                .eq(Marketing::getId, marketing.getId())
+                .eq(Marketing::getTriggerStatus, 0));
+        Assert.isTrue(rtn, "更新活动开奖状态失败。marketingId:" + marketing.getId());
+
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void help(MarketingHelpParam marketingHelpParam, Long userId) {
@@ -106,7 +333,7 @@ public class MarketingServiceImpl extends ServiceImpl<MarketingMapper, Marketing
             code = MarketingUtils.generatePrizeCode();
             // 判断抽奖码是否已经存在
             int codeCount = marketingUserCodeService.count(new LambdaQueryWrapper<MarketingUserCode>()
-                    .eq(MarketingUserCode::getMarketingId,marketing.getId())
+                    .eq(MarketingUserCode::getMarketingId, marketing.getId())
                     .eq(MarketingUserCode::getCode, code));
             if (codeCount > 0) {
                 continue;
@@ -169,14 +396,14 @@ public class MarketingServiceImpl extends ServiceImpl<MarketingMapper, Marketing
                     MarketingStatusEnum.OFF.getValue().equals(marketingQueryParam.getStatus()) ||
                     MarketingStatusEnum.ON.getValue().equals(marketingQueryParam.getStatus())) {
                 queryWrapper.eq(Marketing::getIsOn, marketingQueryParam.getStatus());
-            }else if (MarketingStatusEnum.UNSTART.getValue().equals(marketingQueryParam.getStatus())){
+            } else if (MarketingStatusEnum.UNSTART.getValue().equals(marketingQueryParam.getStatus())) {
                 queryWrapper.gt(Marketing::getStartTime, new Date());
                 queryWrapper.eq(Marketing::getIsOn, MarketingStatusEnum.ON.getValue());
-            }else if (MarketingStatusEnum.START.getValue().equals(marketingQueryParam.getStatus())){
+            } else if (MarketingStatusEnum.START.getValue().equals(marketingQueryParam.getStatus())) {
                 queryWrapper.le(Marketing::getStartTime, new Date());
                 queryWrapper.ge(Marketing::getEndTime, new Date());
                 queryWrapper.eq(Marketing::getIsOn, MarketingStatusEnum.ON.getValue());
-            }else if (MarketingStatusEnum.END.getValue().equals(marketingQueryParam.getStatus())){
+            } else if (MarketingStatusEnum.END.getValue().equals(marketingQueryParam.getStatus())) {
                 queryWrapper.lt(Marketing::getEndTime, new Date());
                 queryWrapper.eq(Marketing::getIsOn, MarketingStatusEnum.ON.getValue());
             }
@@ -254,6 +481,7 @@ public class MarketingServiceImpl extends ServiceImpl<MarketingMapper, Marketing
 
     /**
      * 创建奖级和奖品信息
+     *
      * @param awardsList
      * @param marketing
      */

+ 7 - 0
mp-service/src/main/java/com/qs/mp/system/mapper/SysUserMapper.java

@@ -145,4 +145,11 @@ public interface SysUserMapper  extends BaseMapper<SysUser>
      */
     int updateUserGzhOpenId(@Param("unionId") String unionId, @Param("gzhOpenId") String gzhOpenId);
 
+    /**
+     * 获取一定数量用户
+     * @param userType
+     * @param insideNum
+     * @return
+     */
+    List<SysUser> selectUserListByRand(@Param("userType") String userType,@Param("num") int num);
 }

+ 8 - 0
mp-service/src/main/java/com/qs/mp/system/service/ISysUserService.java

@@ -221,4 +221,12 @@ public interface ISysUserService  extends IService<SysUser>
      * @return 结果
      */
     public String importUser(List<SysUser> userList, Boolean isUpdateSupport, String operName);
+
+    /**
+     * 随机获取一定数量的用户
+     * @param userType
+     * @param insideNum
+     * @return
+     */
+    List<SysUser> selectUserListByRand(String userType, int num);
 }

+ 5 - 0
mp-service/src/main/java/com/qs/mp/system/service/impl/SysUserServiceImpl.java

@@ -572,4 +572,9 @@ public class SysUserServiceImpl  extends ServiceImpl<SysUserMapper, SysUser> imp
         }
         return successMsg.toString();
     }
+
+    @Override
+    public List<SysUser> selectUserListByRand(String userType, int num) {
+        return userMapper.selectUserListByRand(userType, num);
+    }
 }

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

@@ -31,8 +31,8 @@ public class MarketingHitPrize implements Serializable {
      * 主键
      */
     @ApiModelProperty("中奖记录id")
-    @TableId(value = "id", type = IdType.AUTO)
-    private Long id;
+    @TableId(value = "id", type = IdType.INPUT)
+    private String id;
 
     /**
      * 营销活动id

+ 2 - 1
mp-service/src/main/java/com/qs/mp/user/service/IUserCoinService.java

@@ -1,5 +1,6 @@
 package com.qs.mp.user.service;
 
+import com.qs.mp.common.enums.CoinLogTypeEnum;
 import com.qs.mp.user.domain.UserCoin;
 import com.baomidou.mybatisplus.extension.service.IService;
 
@@ -19,7 +20,7 @@ public interface IUserCoinService extends IService<UserCoin> {
    * @param logCoin
    * @param bizId
    */
-  void produce(Long userId, Integer logCoin, String bizId);
+  void produce(Long userId, Integer logCoin, String bizId, CoinLogTypeEnum coinLogTypeEnum);
 
   /**
    * 消耗代币

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

@@ -22,5 +22,5 @@ public interface IUserPrizeStorageService extends IService<UserPrizeStorage> {
    * @param inTypeEnum
    * @param refId
    */
-  void takeInStorage(Long userId, TicketAwardsPrize ticketAwardsPrize, PrizeStorageInTypeEnum inTypeEnum, String refId);
+  void takeInStorage(Long userId, String title, String picUrl, String goodsId, PrizeStorageInTypeEnum inTypeEnum, String refId);
 }

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

@@ -29,8 +29,8 @@ public class UserCoinServiceImpl extends ServiceImpl<UserCoinMapper, UserCoin> i
   private IUserCoinLogService userCoinLogService;
 
   @Override
-  @Transactional
-  public void produce(Long userId, Integer logCoin, String bizId) {
+  @Transactional(rollbackFor = Exception.class)
+  public void produce(Long userId, Integer logCoin, String bizId, CoinLogTypeEnum coinLogTypeEnum) {
     UserCoin userCoin = getById(userId);
     if (null == userCoin) {
       userCoin = new UserCoin();
@@ -46,11 +46,11 @@ public class UserCoinServiceImpl extends ServiceImpl<UserCoinMapper, UserCoin> i
 
     UserCoinLog userCoinLog = new UserCoinLog();
     userCoinLog.setUserId(userId);
-    userCoinLog.setType(CoinLogTypeEnum.PRIZE);
+    userCoinLog.setType(coinLogTypeEnum);
     userCoinLog.setMoney(userCoin.getCoin());
     userCoinLog.setLogMoney(logCoin);
     userCoinLog.setIncomeExpense(CoinLogTypeEnum.INCOME);
-    userCoinLog.setLogText("盲票奖品");
+    userCoinLog.setLogText(coinLogTypeEnum.getDesc());
     userCoinLog.setBizTime(new Date());
     userCoinLog.setRefId(bizId);
     userCoinLogService.save(userCoinLog);

+ 3 - 8
mp-service/src/main/java/com/qs/mp/user/service/impl/UserHitPrizeServiceImpl.java

@@ -9,12 +9,7 @@ import com.qs.mp.admin.domain.TicketAwards;
 import com.qs.mp.admin.domain.TicketAwardsPrize;
 import com.qs.mp.admin.domain.dto.TicketDrawNumDTO;
 import com.qs.mp.admin.service.*;
-import com.qs.mp.common.enums.CouponUseAreaEnum;
-import com.qs.mp.common.enums.PrizeStorageInTypeEnum;
-import com.qs.mp.common.enums.PrizeStorageStatusEnum;
-import com.qs.mp.common.enums.TicketPrizeTypeEnum;
-import com.qs.mp.common.enums.TicketStatusEnum;
-import com.qs.mp.common.enums.UserCouponStatusEnum;
+import com.qs.mp.common.enums.*;
 import com.qs.mp.common.exception.ServiceException;
 import com.qs.mp.common.utils.DateUtils;
 import com.qs.mp.common.utils.LogUtil;
@@ -147,13 +142,13 @@ public class UserHitPrizeServiceImpl extends ServiceImpl<UserHitPrizeMapper, Use
 
         // 放入仓库
         if (ticketAwardsPrize.getPrizeType() == TicketPrizeTypeEnum.COIN) {
-            userCoinService.produce(userId, ticketAwardsPrize.getValue(), userHitPrize.getId());
+            userCoinService.produce(userId, ticketAwardsPrize.getValue(), userHitPrize.getId(),CoinLogTypeEnum.PRIZE);
         } else if (ticketAwardsPrize.getPrizeType() == TicketPrizeTypeEnum.COUPON) {
             couponService.distribute(ticket, userId, ticketAwardsPrize.getRefId());
         } else if (ticketAwardsPrize.getPrizeType() == TicketPrizeTypeEnum.COUPON_PKG) {
             couponPkgService.distribute(ticket, userId, ticketAwardsPrize.getRefId());
         }else {
-            userPrizeStorageService.takeInStorage(userId, ticketAwardsPrize, PrizeStorageInTypeEnum.TICKET_CASHED, userHitPrize.getId());
+            userPrizeStorageService.takeInStorage(userId, ticketAwardsPrize.getTitle(),ticketAwardsPrize.getPicUrl(),ticketAwardsPrize.getRefId(), PrizeStorageInTypeEnum.TICKET_CASHED, userHitPrize.getId());
         }
 
         boolean rtn = ticketService.update(new LambdaUpdateWrapper<Ticket>().set(Ticket::getStatus, TicketStatusEnum.CASHED)

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

@@ -27,15 +27,15 @@ public class UserPrizeStorageServiceImpl extends ServiceImpl<UserPrizeStorageMap
   private BizIdGenerator bizIdGenerator;
 
   @Override
-  public void takeInStorage(Long userId, TicketAwardsPrize ticketAwardsPrize, PrizeStorageInTypeEnum inTypeEnum, String refId) {
+  public void takeInStorage(Long userId, String title, String picUrl, String goodsId, PrizeStorageInTypeEnum inTypeEnum, String refId) {
       UserPrizeStorage userPrizeStorage = new UserPrizeStorage();
       userPrizeStorage.setStorageId(bizIdGenerator.newIdWithUidSharding(String.valueOf(userId)));
       userPrizeStorage.setUserId(userId);
-      userPrizeStorage.setGoodsId(Long.valueOf(ticketAwardsPrize.getRefId()));
+      userPrizeStorage.setGoodsId(Long.valueOf(goodsId));
       userPrizeStorage.setSkuId(null);
       userPrizeStorage.setProperties(null);
-      userPrizeStorage.setTitle(ticketAwardsPrize.getTitle());
-      userPrizeStorage.setPicUrl(ticketAwardsPrize.getPicUrl());
+      userPrizeStorage.setTitle(title);
+      userPrizeStorage.setPicUrl(picUrl);
       userPrizeStorage.setGoodsNum(1);
       userPrizeStorage.setInType(inTypeEnum);
       userPrizeStorage.setRefId(refId);

+ 7 - 0
mp-service/src/main/resources/mapper/system/SysUserMapper.xml

@@ -236,4 +236,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </foreach>
  	</delete>
 
+	<select id="selectUserListByRand" resultMap="SysUserResult">
+		SELECT user_id
+		FROM sys_user
+		WHERE user_type = #{userType}
+			order by rand()
+			LIMIT #{num};
+    </select>
 </mapper>