|
@@ -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
|
|
|
*/
|