|
@@ -12,10 +12,12 @@ 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.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.LogUtil;
|
|
|
import com.qs.mp.common.utils.bean.BeanUtils;
|
|
|
import com.qs.mp.framework.service.IWxSubscribeMessage;
|
|
|
import com.qs.mp.system.domain.SysUser;
|
|
@@ -30,6 +32,8 @@ 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;
|
|
@@ -37,6 +41,7 @@ import org.springframework.util.Assert;
|
|
|
|
|
|
import java.net.URLDecoder;
|
|
|
import java.util.*;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
@@ -56,6 +61,10 @@ public class MarketingServiceImpl extends ServiceImpl<MarketingMapper, Marketing
|
|
|
// 普通奖池
|
|
|
public static final String MARKETING_LOTTERY_ORDINARY_POOL = "MARKETING_LOTTERY_ORDINARY_POOL:%s";
|
|
|
|
|
|
+ // 营销活动真实参与人数锁
|
|
|
+ public static final String MARKETING_REAL_NUM_LOCK = "MARKETING_REAL_NUM_LOCK:%s";
|
|
|
+
|
|
|
+ protected final Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());
|
|
|
|
|
|
@Autowired
|
|
|
private IGoodsService goodsService;
|
|
@@ -97,6 +106,9 @@ public class MarketingServiceImpl extends ServiceImpl<MarketingMapper, Marketing
|
|
|
@Autowired
|
|
|
private IWxSubscribeMessage wxSubscribeMessage;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private DistributedLocker distributedLocker;
|
|
|
+
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@@ -239,11 +251,12 @@ public class MarketingServiceImpl extends ServiceImpl<MarketingMapper, Marketing
|
|
|
}
|
|
|
}
|
|
|
// 保存中奖信息
|
|
|
- marketingHitPrizeService.saveBatch(allHitPrizeList);
|
|
|
+ Assert.isTrue(marketingHitPrizeService.saveBatch(allHitPrizeList), "保存中奖信息失败。marketingId:" + marketing.getId());
|
|
|
|
|
|
// 更新抽奖码中奖状态
|
|
|
if (CollectionUtils.isNotEmpty(userCodeUpdateList)) {
|
|
|
- marketingUserCodeService.updateBatchById(userCodeUpdateList);
|
|
|
+ boolean rtn = marketingUserCodeService.updateBatchById(userCodeUpdateList);
|
|
|
+ Assert.isTrue(rtn, "更新抽奖码中奖状态失败。marketingId:" + marketing.getId());
|
|
|
}
|
|
|
|
|
|
// 发奖品
|
|
@@ -327,59 +340,65 @@ public class MarketingServiceImpl extends ServiceImpl<MarketingMapper, Marketing
|
|
|
if (userId.equals(helpedUserId)) {
|
|
|
throw new ServiceException("不能助力自己哦");
|
|
|
}
|
|
|
-
|
|
|
- // 判断是否已经助力过
|
|
|
- int count = marketingUserCodeService.count(new LambdaQueryWrapper<MarketingUserCode>()
|
|
|
- .eq(MarketingUserCode::getHelpUserId, userId));
|
|
|
- if (count > 0) {
|
|
|
- throw new ServiceException("您已经助力过了");
|
|
|
+ String lockKey = String.format(MARKETING_REAL_NUM_LOCK, marketing.getId());
|
|
|
+ // 等待3秒
|
|
|
+ if (!distributedLocker.tryLock(lockKey, 3, 30, TimeUnit.SECONDS)) {
|
|
|
+ throw new ServiceException("活动太火爆了,请稍后重试!");
|
|
|
}
|
|
|
|
|
|
+ try {
|
|
|
|
|
|
- // 生成抽奖码
|
|
|
- String code = "";
|
|
|
- while (true) {
|
|
|
- code = MarketingUtils.generatePrizeCode();
|
|
|
- // 判断抽奖码是否已经存在
|
|
|
- int codeCount = marketingUserCodeService.count(new LambdaQueryWrapper<MarketingUserCode>()
|
|
|
- .eq(MarketingUserCode::getMarketingId, marketing.getId())
|
|
|
- .eq(MarketingUserCode::getCode, code));
|
|
|
- if (codeCount > 0) {
|
|
|
- continue;
|
|
|
+ // 判断是否已经助力过
|
|
|
+ int count = marketingUserCodeService.count(new LambdaQueryWrapper<MarketingUserCode>()
|
|
|
+ .eq(MarketingUserCode::getHelpUserId, userId));
|
|
|
+ if (count > 0) {
|
|
|
+ throw new ServiceException("您已经助力过了");
|
|
|
}
|
|
|
- break;
|
|
|
- }
|
|
|
|
|
|
- MarketingUserCode marketingUserCode = new MarketingUserCode();
|
|
|
- marketingUserCode.setMarketingId(marketingHelpParam.getMarketingId());
|
|
|
- marketingUserCode.setCode(code);
|
|
|
- // 设置被助力人
|
|
|
- marketingUserCode.setUserId(helpedUserId);
|
|
|
- // 设置助力人
|
|
|
- marketingUserCode.setHelpUserId(userId);
|
|
|
- marketingUserCode.setUserType(UserTypeEnum.ORDINARY.getValue());
|
|
|
|
|
|
+ // 生成抽奖码
|
|
|
+ String code = "";
|
|
|
+ while (true) {
|
|
|
+ code = MarketingUtils.generatePrizeCode();
|
|
|
+ // 判断抽奖码是否已经存在
|
|
|
+ int codeCount = marketingUserCodeService.count(new LambdaQueryWrapper<MarketingUserCode>()
|
|
|
+ .eq(MarketingUserCode::getMarketingId, marketing.getId())
|
|
|
+ .eq(MarketingUserCode::getCode, code));
|
|
|
+ if (codeCount > 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- // 保存助力信息
|
|
|
- marketingUserCodeService.save(marketingUserCode);
|
|
|
+ MarketingUserCode marketingUserCode = new MarketingUserCode();
|
|
|
+ marketingUserCode.setMarketingId(marketingHelpParam.getMarketingId());
|
|
|
+ marketingUserCode.setCode(code);
|
|
|
+ // 设置被助力人
|
|
|
+ marketingUserCode.setUserId(helpedUserId);
|
|
|
+ // 设置助力人
|
|
|
+ marketingUserCode.setHelpUserId(userId);
|
|
|
+ marketingUserCode.setUserType(UserTypeEnum.ORDINARY.getValue());
|
|
|
|
|
|
- // 给被助力人发送成功消息
|
|
|
- wxSubscribeMessage.sendMarketingHelp(helpedUserId, marketing);
|
|
|
+ // 保存助力信息
|
|
|
+ marketingUserCodeService.save(marketingUserCode);
|
|
|
|
|
|
- // 增加活动参与人数
|
|
|
- int userCount = marketingUserCodeService.count(new LambdaQueryWrapper<MarketingUserCode>()
|
|
|
- .eq(MarketingUserCode::getMarketingId, marketing.getId())
|
|
|
- .eq(MarketingUserCode::getUserType, UserTypeEnum.ORDINARY.getValue())
|
|
|
- .groupBy(MarketingUserCode::getMarketingId));
|
|
|
|
|
|
- Marketing marketingParam = new Marketing();
|
|
|
- marketingParam.setId(marketing.getId());
|
|
|
- marketingParam.setRealNum(userCount);
|
|
|
- int randomNum = (int) 1 + (int) (Math.random() * 10);
|
|
|
- marketingParam.setFakeNum(marketing.getFakeNum() + randomNum);
|
|
|
+ // 获取最新活动信息
|
|
|
+ Marketing marketingParam = this.getById(marketing.getId());
|
|
|
+ marketingParam.setRealNum(marketingParam.getRealNum() + 1);
|
|
|
+ int randomNum = (int) 1 + (int) (Math.random() * 10);
|
|
|
+ marketingParam.setFakeNum(marketingParam.getFakeNum() + randomNum);
|
|
|
+ // 更新活动参与人数
|
|
|
+ boolean rtn = this.updateById(marketingParam);
|
|
|
+ Assert.isTrue(rtn, "更新活动参与人数异常。marketingId:" + marketing.getId());
|
|
|
+
|
|
|
+ } finally {
|
|
|
+ distributedLocker.unlock(lockKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 给被助力人发送成功消息
|
|
|
+ wxSubscribeMessage.sendMarketingHelp(helpedUserId, marketing);
|
|
|
|
|
|
- // 更新活动参与人数
|
|
|
- this.updateById(marketingParam);
|
|
|
|
|
|
}
|
|
|
|