|
@@ -0,0 +1,708 @@
|
|
|
+package com.qs.mp.admin.service.impl;
|
|
|
+
|
|
|
+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;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.qs.mp.admin.domain.*;
|
|
|
+import com.qs.mp.admin.domain.param.*;
|
|
|
+import com.qs.mp.admin.domain.vo.GroupBuying;
|
|
|
+import com.qs.mp.admin.mapper.GroupBuyingMapper;
|
|
|
+import com.qs.mp.admin.service.*;
|
|
|
+import com.qs.mp.common.constant.Constants;
|
|
|
+import com.qs.mp.common.core.redis.DistributedLocker;
|
|
|
+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.framework.redis.RedisKey;
|
|
|
+import com.qs.mp.framework.service.IWxSubscribeMessage;
|
|
|
+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.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.net.URLDecoder;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @ClassName GroupBuyingServiceImpl
|
|
|
+ * @author yang.zhao
|
|
|
+ * @Version 1.0
|
|
|
+ * @Description 拼团活动表 服务实现类
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class GroupBuyingServiceImpl extends ServiceImpl<GroupBuyingMapper, GroupBuying> implements IGroupBuyingService {
|
|
|
+
|
|
|
+ // 内部奖池
|
|
|
+ public static final String MARKETING_LOTTERY_INSIDE_POOL = "MARKETING_LOTTERY_INSIDE_POOL:%s";
|
|
|
+
|
|
|
+ // 普通奖池
|
|
|
+ public static final String MARKETING_LOTTERY_ORDINARY_POOL = "MARKETING_LOTTERY_ORDINARY_POOL:%s";
|
|
|
+
|
|
|
+ // 普通用户低阶奖池
|
|
|
+ public static final String MARKETING_LOW_LOTTERY_ORDINARY_POOL = "MARKETING_LOW_LOTTERY_ORDINARY_POOL:%s";
|
|
|
+
|
|
|
+
|
|
|
+ protected final Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IGoodsService goodsService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ICouponService couponService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ICouponPkgService couponPkgService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IMarketingAwardsService marketingAwardsService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IMarketingAwardsPrizeService marketingAwardsPrizeService;
|
|
|
+
|
|
|
+ @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;
|
|
|
+
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IWxSubscribeMessage wxSubscribeMessage;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private DistributedLocker distributedLocker;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IMarketingMsgService marketingMsgService;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //拼团活动奖项
|
|
|
+ @Autowired
|
|
|
+ private IGroupBuyingAwardsService groupBuyingAwardsService;
|
|
|
+
|
|
|
+ //拼团活动奖项对应奖品
|
|
|
+ @Autowired
|
|
|
+ private IGroupBuyingAwardsPrizeService groupBuyingAwardsPrizeService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 复制拼团活动
|
|
|
+ * @param groupBuyingId
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void copyById(Long groupBuyingId) {
|
|
|
+ GroupBuying groupBuying = this.getById(groupBuyingId);
|
|
|
+ if (Objects.isNull(groupBuying)) {
|
|
|
+ throw new ServiceException("拼团活动不存在");
|
|
|
+ }
|
|
|
+ // 初始化活动
|
|
|
+ groupBuying.setId(null);
|
|
|
+ groupBuying.setTitle(groupBuying.getTitle()+"(1)");
|
|
|
+ groupBuying.setIsPutaway(1);
|
|
|
+ groupBuying.setCreateTime(new Date());
|
|
|
+ groupBuying.setUpdateTime(new Date());
|
|
|
+ Assert.isTrue(this.save(groupBuying), "复制拼团活动失败");
|
|
|
+
|
|
|
+ List<GroupBuyingAwards> groupBuyingAwardsList = groupBuyingAwardsService.list(new LambdaQueryWrapper<GroupBuyingAwards>().eq(GroupBuyingAwards::getGroupbuyingId, groupBuyingId));
|
|
|
+ if (CollectionUtils.isEmpty(groupBuyingAwardsList)) {
|
|
|
+ throw new ServiceException("活动奖级信息不存在");
|
|
|
+ }
|
|
|
+ for (GroupBuyingAwards groupBuyingAwards : groupBuyingAwardsList) {
|
|
|
+ List<GroupBuyingAwardsPrize> groupBuyingAwardsPrizeList = groupBuyingAwardsPrizeService.list(new LambdaQueryWrapper<GroupBuyingAwardsPrize>()
|
|
|
+ .eq(GroupBuyingAwardsPrize::getGroupbuyingId, groupBuyingAwards.getGroupbuyingId())
|
|
|
+ .eq(GroupBuyingAwardsPrize::getAwardsId, groupBuyingAwards.getId()));
|
|
|
+ groupBuyingAwards.setId(null);
|
|
|
+ groupBuyingAwards.setGroupbuyingId(groupBuying.getId());
|
|
|
+ Assert.isTrue(groupBuyingAwardsService.save(groupBuyingAwards),"复制拼团活动奖级失败");
|
|
|
+
|
|
|
+ for (GroupBuyingAwardsPrize groupBuyingAwardsPrize : groupBuyingAwardsPrizeList) {
|
|
|
+ groupBuyingAwardsPrize.setId(null);
|
|
|
+ groupBuyingAwardsPrize.setAwardsId(groupBuyingAwards.getId());
|
|
|
+ groupBuyingAwardsPrize.setGroupbuyingId(groupBuying.getId());
|
|
|
+ }
|
|
|
+ Assert.isTrue(groupBuyingAwardsPrizeService.saveBatch(groupBuyingAwardsPrizeList),"复制拼团活动奖品失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建拼团活动
|
|
|
+ * @param groupBuyingCreateParam
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void createGroupBuying(GroupBuyingCreateParam groupBuyingCreateParam) {
|
|
|
+ // 保存拼团活动
|
|
|
+ GroupBuying groupBuying = new GroupBuying();
|
|
|
+ BeanUtils.copyProperties(groupBuyingCreateParam, groupBuying);
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(groupBuyingCreateParam.getDescription())) {
|
|
|
+ groupBuying.setDescription(URLDecoder.decode(groupBuyingCreateParam.getDescription()));
|
|
|
+ }
|
|
|
+
|
|
|
+ this.save(groupBuying);
|
|
|
+
|
|
|
+ // 创建奖级和奖品信息
|
|
|
+ createAwardsAndPrize(groupBuyingCreateParam.getAwardsList(), groupBuying);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建奖级和奖品信息
|
|
|
+ *
|
|
|
+ * @param awardsList
|
|
|
+ * @param groupBuying
|
|
|
+ */
|
|
|
+ private void createAwardsAndPrize(List<GroupBuyingAwardsParam> awardsList, GroupBuying groupBuying) {
|
|
|
+
|
|
|
+ int insideNum = 0;
|
|
|
+
|
|
|
+ // 创建奖级对应的奖品列表
|
|
|
+ List<GroupBuyingAwardsPrize> groupBuyingAwardsPrizeList = new ArrayList<>();
|
|
|
+
|
|
|
+ // 创建奖级
|
|
|
+ for (GroupBuyingAwardsParam awardsParam : awardsList) {
|
|
|
+ insideNum += awardsParam.getInsideNum();
|
|
|
+ if (awardsParam.getInsideNum() > awardsParam.getQuantity()) {
|
|
|
+ throw new ServiceException("内定数量不能大于奖品数量");
|
|
|
+ }
|
|
|
+ GroupBuyingAwards groupBuyingAwards = new GroupBuyingAwards();
|
|
|
+ BeanUtils.copyProperties(awardsParam, groupBuyingAwards);
|
|
|
+ groupBuyingAwards.setId(null);
|
|
|
+ // 设置活动id
|
|
|
+ groupBuyingAwards.setGroupbuyingId(groupBuying.getId());
|
|
|
+ groupBuyingAwardsService.save(groupBuyingAwards);
|
|
|
+
|
|
|
+ for (GroupBuyingAwardsPrizeParam prizeParam : awardsParam.getPrizeList()) {
|
|
|
+ GroupBuyingAwardsPrize awardsPrize = new GroupBuyingAwardsPrize();
|
|
|
+ BeanUtils.copyProperties(prizeParam, awardsPrize);
|
|
|
+ awardsPrize.setId(null);
|
|
|
+ awardsPrize.setGroupbuyingId(groupBuying.getId());
|
|
|
+ awardsPrize.setAwardsId(groupBuyingAwards.getId());
|
|
|
+ if (null == awardsPrize.getQuantity() || 0 == awardsPrize.getQuantity()) {
|
|
|
+ // 页面没设置奖品的具体数量,则默认为整个奖项的数量
|
|
|
+ awardsPrize.setQuantity(groupBuyingAwards.getQuantity());
|
|
|
+ }
|
|
|
+ if (prizeParam.getPrizeType() == TicketPrizeTypeEnum.GOODS) {
|
|
|
+ Goods goods = goodsService.getById(awardsPrize.getRefId());
|
|
|
+ awardsPrize.setTitle(goods.getTitle());
|
|
|
+ awardsPrize.setPicUrl(goods.getPicUrl());
|
|
|
+ awardsPrize.setValue(goods.getValue());
|
|
|
+ } else if (prizeParam.getPrizeType() == TicketPrizeTypeEnum.COUPON) {
|
|
|
+ Coupon coupon = couponService.getById(awardsPrize.getRefId());
|
|
|
+ awardsPrize.setTitle(coupon.getTitle());
|
|
|
+ awardsPrize.setPicUrl(coupon.getPicUrl());
|
|
|
+ awardsPrize.setValue(coupon.getDiscount());
|
|
|
+ } else if (prizeParam.getPrizeType() == TicketPrizeTypeEnum.COUPON_PKG) {
|
|
|
+ CouponPkg couponPkg = couponPkgService.getById(awardsPrize.getRefId());
|
|
|
+ awardsPrize.setTitle(couponPkg.getTitle());
|
|
|
+ awardsPrize.setValue(couponPkg.getFacePrice());
|
|
|
+ awardsPrize.setPicUrl(couponPkg.getPicUrl());
|
|
|
+ } else {
|
|
|
+ awardsPrize.setTitle("盲豆");
|
|
|
+ awardsPrize.setPicUrl(Constants.MANGDOU_PIC);
|
|
|
+ }
|
|
|
+ groupBuyingAwardsPrizeList.add(awardsPrize);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (insideNum > 100) {
|
|
|
+ throw new ServiceException("内定人数不能超过100");
|
|
|
+ }
|
|
|
+
|
|
|
+ groupBuyingAwardsPrizeService.saveBatch(groupBuyingAwardsPrizeList);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新拼团活动
|
|
|
+ * @param groupBuyingUpdateParam
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void updateGroupBuying(GroupBuyingUpdateParam groupBuyingUpdateParam) {
|
|
|
+ GroupBuying groupBuying = this.getById(groupBuyingUpdateParam.getId());
|
|
|
+ if (Objects.isNull(groupBuying)) {
|
|
|
+ throw new ServiceException("拼团活动不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (GroupBuyingStatusEnum.UP.getValue().equals(groupBuying.getIsPutaway())) {
|
|
|
+ throw new ServiceException("活动当前状态不支持修改");
|
|
|
+ }
|
|
|
+
|
|
|
+ Date now = DateUtils.getNowDate();
|
|
|
+ if (GroupBuyingStatusEnum.END.getValue().equals(groupBuying.getIsPutaway()) && now.after(groupBuying.getEndTime())) {
|
|
|
+ throw new ServiceException("活动当前状态不支持修改");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新拼团活动
|
|
|
+ BeanUtils.copyProperties(groupBuyingUpdateParam, groupBuying);
|
|
|
+
|
|
|
+ if (StringUtils.isNotBlank(groupBuyingUpdateParam.getDescription())) {
|
|
|
+ groupBuying.setDescription(URLDecoder.decode(groupBuyingUpdateParam.getDescription()));
|
|
|
+ }
|
|
|
+
|
|
|
+ this.updateById(groupBuying);
|
|
|
+
|
|
|
+ // 删除奖级和奖品信息
|
|
|
+ groupBuyingAwardsService.remove(new LambdaUpdateWrapper<GroupBuyingAwards>().eq(GroupBuyingAwards::getGroupbuyingId, groupBuying.getId()));
|
|
|
+ groupBuyingAwardsPrizeService.remove(new LambdaUpdateWrapper<GroupBuyingAwardsPrize>().eq(GroupBuyingAwardsPrize::getGroupbuyingId, groupBuying.getId()));
|
|
|
+
|
|
|
+ // 创建奖级和奖品信息
|
|
|
+ createAwardsAndPrize(groupBuyingUpdateParam.getAwardsList(), groupBuying);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 拼团活动列表
|
|
|
+ * @param groupBuyingQueryParam
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<GroupBuying> listGroupBuying(GroupBuyingQueryParam groupBuyingQueryParam) {
|
|
|
+ LambdaQueryWrapper<GroupBuying> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ if (StringUtils.isNotBlank(groupBuyingQueryParam.getTitle())) {
|
|
|
+ queryWrapper.like(GroupBuying::getTitle, groupBuyingQueryParam.getTitle());
|
|
|
+ }
|
|
|
+
|
|
|
+ //活动状态:0上架,1下架,2已结束,3进行中,4预热中
|
|
|
+ if (Objects.nonNull(groupBuyingQueryParam.getStatus())) {
|
|
|
+ //0上架,1下架,2已结束
|
|
|
+ if (GroupBuyingStatusEnum.UP.getValue().equals(groupBuyingQueryParam.getStatus()) ||
|
|
|
+ GroupBuyingStatusEnum.DOWN.getValue().equals(groupBuyingQueryParam.getStatus()) ||
|
|
|
+ GroupBuyingStatusEnum.END.getValue().equals(groupBuyingQueryParam.getStatus())) {
|
|
|
+ queryWrapper.eq(GroupBuying::getIsPutaway, groupBuyingQueryParam.getStatus());
|
|
|
+
|
|
|
+ } else if (GroupBuyingStatusEnum.UNDERWAY.getValue().equals(groupBuyingQueryParam.getStatus())) {
|
|
|
+ //3进行中
|
|
|
+ queryWrapper.gt(GroupBuying::getStartTime, new Date());
|
|
|
+ queryWrapper.lt(GroupBuying::getEndTime, new Date());
|
|
|
+ queryWrapper.eq(GroupBuying::getIsPutaway, GroupBuyingStatusEnum.UP.getValue());
|
|
|
+
|
|
|
+ } else if (GroupBuyingStatusEnum.WARMUP.getValue().equals(groupBuyingQueryParam.getStatus())) {
|
|
|
+ //4预热中
|
|
|
+ queryWrapper.lt(GroupBuying::getStartTime, new Date());
|
|
|
+ queryWrapper.eq(GroupBuying::getIsPutaway, GroupBuyingStatusEnum.UP.getValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ queryWrapper.orderByDesc(GroupBuying::getCreateTime);
|
|
|
+
|
|
|
+
|
|
|
+ return this.list(queryWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void generateCode(Long marketingId, Long userId) {
|
|
|
+
|
|
|
+ // 判断是否已经获取过
|
|
|
+ int count = marketingUserCodeService.count(new LambdaQueryWrapper<MarketingUserCode>()
|
|
|
+ .eq(MarketingUserCode::getUserId, userId)
|
|
|
+ .eq(MarketingUserCode::getMarketingId, marketingId)
|
|
|
+ .eq(MarketingUserCode::getHelpUserId, -1L));
|
|
|
+ if (count > 0) {
|
|
|
+ throw new ServiceException("您已经获取过抽奖码了");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 生成唯一抽奖码
|
|
|
+ String code = getOnlyCode(marketingId);
|
|
|
+
|
|
|
+ MarketingUserCode marketingUserCode = new MarketingUserCode();
|
|
|
+ // 设置活动id
|
|
|
+ marketingUserCode.setMarketingId(marketingId);
|
|
|
+ // 设置抽奖码
|
|
|
+ marketingUserCode.setCode(code);
|
|
|
+ // 设置用户
|
|
|
+ marketingUserCode.setUserId(userId);
|
|
|
+ // -1为无人助力获取抽奖码
|
|
|
+ marketingUserCode.setHelpUserId(-1L);
|
|
|
+ // 设置用户类型
|
|
|
+ marketingUserCode.setUserType(UserTypeEnum.ORDINARY.getValue());
|
|
|
+
|
|
|
+ // 保存助力信息
|
|
|
+ marketingUserCodeService.save(marketingUserCode);
|
|
|
+
|
|
|
+
|
|
|
+ // 设置更新虚拟参与人数
|
|
|
+ int randomNum = (int) 1 + (int) (Math.random() * 3);
|
|
|
+ String fakeNumKey = RedisKey.build(RedisKey.MARKETING_FAKE_NUM, marketingId);
|
|
|
+ Integer fakeNum = redisCache.getCacheObject(fakeNumKey);
|
|
|
+ if (fakeNum == null) {
|
|
|
+ fakeNum = marketingUserCodeService.countRealUserNumByMarketingId(marketingId);
|
|
|
+ redisCache.setCacheObject(fakeNumKey, fakeNum * 2 + randomNum, 30, TimeUnit.HOURS);
|
|
|
+ } else {
|
|
|
+ redisCache.setCacheObject(fakeNumKey, fakeNum + randomNum, 30, TimeUnit.HOURS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void lottery(Marketing marketing) {
|
|
|
+
|
|
|
+ // 用户抽奖池
|
|
|
+ String userLotteryPool = String.format(MARKETING_LOTTERY_ORDINARY_POOL, marketing.getId());
|
|
|
+ // 用户低阶奖池
|
|
|
+ String userLowLotteryPool = String.format(MARKETING_LOW_LOTTERY_ORDINARY_POOL, marketing.getId());
|
|
|
+ // 内部抽奖池
|
|
|
+ String insideLotteryPool = String.format(MARKETING_LOTTERY_INSIDE_POOL, marketing.getId());
|
|
|
+
|
|
|
+ // 获取奖级信息
|
|
|
+ List<MarketingAwards> marketingAwardsList = marketingAwardsService.list(new LambdaQueryWrapper<MarketingAwards>()
|
|
|
+ .eq(MarketingAwards::getMarketingId, marketing.getId()));
|
|
|
+
|
|
|
+ // 奖品总数
|
|
|
+ int prizeQuantity = marketingAwardsList.stream().mapToInt(MarketingAwards::getQuantity).sum();
|
|
|
+
|
|
|
+ // 校准并获取真实参与人数
|
|
|
+ int realNum = marketingUserCodeService.countRealUserNumByMarketingId(marketing.getId());
|
|
|
+
|
|
|
+ // 设置需要的内定人数
|
|
|
+ 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> insideCodes = 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;
|
|
|
+ }
|
|
|
+ insideCodes.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(insideLotteryPool, insideCodes);
|
|
|
+
|
|
|
+
|
|
|
+ // 获取普通用户拉新所获得的所有的抽奖码
|
|
|
+ List<MarketingUserCode> userCodeList = marketingUserCodeService.list(new LambdaQueryWrapper<MarketingUserCode>()
|
|
|
+ .eq(MarketingUserCode::getMarketingId, marketing.getId())
|
|
|
+ .eq(MarketingUserCode::getUserType, UserTypeEnum.ORDINARY.getValue()));
|
|
|
+ if (CollectionUtils.isNotEmpty(userCodeList)) {
|
|
|
+ // 用户普通抽奖码
|
|
|
+ Set<String> userCodes = new HashSet<>();
|
|
|
+ // 用户低阶抽奖码
|
|
|
+ Set<String> userLowCodes = new HashSet<>();
|
|
|
+ for (MarketingUserCode marketingUserCode : userCodeList) {
|
|
|
+ if (marketingUserCode.getHelpUserId() == -1L) {
|
|
|
+ userLowCodes.add(marketingUserCode.getCode());
|
|
|
+ } else {
|
|
|
+ userCodes.add(marketingUserCode.getCode());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (CollectionUtils.isNotEmpty(userCodes)) {
|
|
|
+ // 将抽奖码放入普通抽奖池
|
|
|
+ redisCache.setCacheSet(userLotteryPool, userCodes);
|
|
|
+ }
|
|
|
+ if (CollectionUtils.isNotEmpty(userLowCodes)) {
|
|
|
+ // 将抽奖码放入低阶抽奖池
|
|
|
+ redisCache.setCacheSet(userLowLotteryPool, userLowCodes);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 所有中奖名单
|
|
|
+ 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(insideLotteryPool, insideNum);
|
|
|
+ for (String code : insideCodeList) {
|
|
|
+ MarketingUserCode marketingUserCode = marketingUserCodeService.getOne(new LambdaQueryWrapper<MarketingUserCode>()
|
|
|
+ .eq(MarketingUserCode::getMarketingId, marketing.getId())
|
|
|
+ .eq(MarketingUserCode::getCode, code));
|
|
|
+
|
|
|
+ // 设置中奖信息
|
|
|
+ exchangeMarketingHitPrize(marketing, allHitPrizeList, marketingAwards, marketingAwardsPrizeList, marketingUserCode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 用户中奖数量为 名额 - 内定人数
|
|
|
+ int userNum = marketingAwards.getQuantity() - insideNum;
|
|
|
+ if (userNum > 0) {
|
|
|
+ // 设置普通用户抽奖信息
|
|
|
+ for (int i = 0; i < userNum; i++) {
|
|
|
+ List<String> hitCodeList = redisCache.popCacheSet(userLotteryPool, 1);
|
|
|
+ if (CollectionUtils.isEmpty(hitCodeList)) {
|
|
|
+ hitCodeList = redisCache.popCacheSet(userLowLotteryPool, 1);
|
|
|
+ }
|
|
|
+ if (CollectionUtils.isEmpty(hitCodeList)) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ MarketingUserCode marketingUserCode = marketingUserCodeService.getOne(new LambdaQueryWrapper<MarketingUserCode>()
|
|
|
+ .eq(MarketingUserCode::getMarketingId, marketing.getId())
|
|
|
+ .eq(MarketingUserCode::getCode, hitCodeList.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(userLotteryPool, delUserCodeList);
|
|
|
+ redisCache.removeSetValueByKey(userLowLotteryPool, delUserCodeList);
|
|
|
+ MarketingHitPrize marketingHitPrize = exchangeMarketingHitPrize(marketing, allHitPrizeList, marketingAwards, marketingAwardsPrizeList, marketingUserCode);
|
|
|
+
|
|
|
+ userHitPrizeList.add(marketingHitPrize);
|
|
|
+
|
|
|
+ // 更新用户中奖状态
|
|
|
+ marketingUserCode.setIsHit(1);
|
|
|
+ userCodeUpdateList.add(marketingUserCode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 保存中奖信息
|
|
|
+ Assert.isTrue(marketingHitPrizeService.saveBatch(allHitPrizeList), "保存中奖信息失败。marketingId:" + marketing.getId());
|
|
|
+
|
|
|
+ // 更新抽奖码中奖状态
|
|
|
+ if (CollectionUtils.isNotEmpty(userCodeUpdateList)) {
|
|
|
+ boolean rtn = marketingUserCodeService.updateBatchById(userCodeUpdateList);
|
|
|
+ Assert.isTrue(rtn, "更新抽奖码中奖状态失败。marketingId:" + marketing.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 发奖品
|
|
|
+ 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());
|
|
|
+
|
|
|
+ // 删除抽奖池
|
|
|
+ redisCache.deleteObject(userLotteryPool);
|
|
|
+ redisCache.deleteObject(userLowLotteryPool);
|
|
|
+ redisCache.deleteObject(insideLotteryPool);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private MarketingHitPrize exchangeMarketingHitPrize(Marketing marketing, List<MarketingHitPrize> allHitPrizeList, MarketingAwards marketingAwards, List<MarketingAwardsPrize> marketingAwardsPrizeList, MarketingUserCode marketingUserCode) {
|
|
|
+ // 设置中奖信息
|
|
|
+ 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);
|
|
|
+ return marketingHitPrize;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void help(MarketingHelpParam marketingHelpParam, Long userId) {
|
|
|
+ String inviteCode = marketingHelpParam.getInviteCode();
|
|
|
+ // 邀请码解码,被助力人id
|
|
|
+ Long helpedUserId = MarketingUtils.decodeInviteCode(inviteCode);
|
|
|
+
|
|
|
+ Marketing marketing = this.getById(marketingHelpParam.getMarketingId());
|
|
|
+
|
|
|
+ // 处理助力信息
|
|
|
+ // 判断是否已经助力过
|
|
|
+ int count = marketingUserCodeService.count(new LambdaQueryWrapper<MarketingUserCode>()
|
|
|
+ .eq(MarketingUserCode::getHelpUserId, userId));
|
|
|
+ if (count > 0) {
|
|
|
+ throw new ServiceException("您已经助力过了");
|
|
|
+ }
|
|
|
+ // 生成唯一抽奖码
|
|
|
+ String code = getOnlyCode(marketing.getId());
|
|
|
+
|
|
|
+ MarketingUserCode marketingUserCode = new MarketingUserCode();
|
|
|
+ // 设置活动id
|
|
|
+ marketingUserCode.setMarketingId(marketingHelpParam.getMarketingId());
|
|
|
+ // 设置抽奖码
|
|
|
+ marketingUserCode.setCode(code);
|
|
|
+ // 设置被助力人
|
|
|
+ marketingUserCode.setUserId(helpedUserId);
|
|
|
+ // 设置助力人
|
|
|
+ marketingUserCode.setHelpUserId(userId);
|
|
|
+ marketingUserCode.setUserType(UserTypeEnum.ORDINARY.getValue());
|
|
|
+
|
|
|
+ // 保存助力信息
|
|
|
+ marketingUserCodeService.save(marketingUserCode);
|
|
|
+
|
|
|
+
|
|
|
+ // 自己获得一个普通抽奖码
|
|
|
+ MarketingUserCode myCode= new MarketingUserCode();
|
|
|
+ myCode.setMarketingId(marketing.getId());
|
|
|
+ // 设置抽奖码
|
|
|
+ myCode.setCode(getOnlyCode(marketing.getId()));
|
|
|
+ // 设置被助力人
|
|
|
+ myCode.setUserId(userId);
|
|
|
+ myCode.setHelpUserId(-1L);
|
|
|
+ myCode.setUserType(UserTypeEnum.ORDINARY.getValue());
|
|
|
+
|
|
|
+ // 保存抽奖码
|
|
|
+ marketingUserCodeService.save(myCode);
|
|
|
+
|
|
|
+
|
|
|
+ // 设置更新虚拟参与人数
|
|
|
+ int randomNum = (int) 1 + (int) (Math.random() * 3);
|
|
|
+ String fakeNumKey = RedisKey.build(RedisKey.MARKETING_FAKE_NUM, marketing.getId());
|
|
|
+ Integer fakeNum = redisCache.getCacheObject(fakeNumKey);
|
|
|
+ if (fakeNum == null) {
|
|
|
+ fakeNum = marketingUserCodeService.countRealUserNumByMarketingId(marketing.getId());
|
|
|
+ redisCache.setCacheObject(fakeNumKey, fakeNum * 2 + randomNum, 30, TimeUnit.HOURS);
|
|
|
+ } else {
|
|
|
+ redisCache.setCacheObject(fakeNumKey, fakeNum + randomNum, 30, TimeUnit.HOURS);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ */
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前活动用户唯一的抽奖码
|
|
|
+ * @param marketingId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ /**
|
|
|
+ private String getOnlyCode(Long marketingId) {
|
|
|
+ String code = "";
|
|
|
+ while (true) {
|
|
|
+ code = MarketingUtils.generatePrizeCode();
|
|
|
+ // 判断抽奖码是否已经存在
|
|
|
+ int codeCount = marketingUserCodeService.count(new LambdaQueryWrapper<MarketingUserCode>()
|
|
|
+ .eq(MarketingUserCode::getMarketingId, marketingId)
|
|
|
+ .eq(MarketingUserCode::getCode, code));
|
|
|
+ if (codeCount > 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return code;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void deleteById(Long id) {
|
|
|
+ this.removeById(id);
|
|
|
+
|
|
|
+ // 删除奖级和奖品信息
|
|
|
+ marketingAwardsService.remove(new LambdaQueryWrapper<MarketingAwards>().eq(MarketingAwards::getMarketingId, id));
|
|
|
+
|
|
|
+ marketingAwardsPrizeService.remove(new LambdaQueryWrapper<MarketingAwardsPrize>().eq(MarketingAwardsPrize::getMarketingId, id));
|
|
|
+
|
|
|
+ }
|
|
|
+ */
|
|
|
+
|
|
|
+}
|