|
@@ -1,14 +1,22 @@
|
|
|
package com.fs.live.service.impl;
|
|
package com.fs.live.service.impl;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
|
+import com.fs.common.constant.LiveKeysConstant;
|
|
|
import com.fs.common.core.domain.R;
|
|
import com.fs.common.core.domain.R;
|
|
|
import com.fs.common.core.redis.RedisCache;
|
|
import com.fs.common.core.redis.RedisCache;
|
|
|
import com.fs.common.utils.DateUtils;
|
|
import com.fs.common.utils.DateUtils;
|
|
|
|
|
+import com.fs.live.domain.Live;
|
|
|
|
|
+import com.fs.live.domain.LiveAutoTask;
|
|
|
import com.fs.live.domain.LiveLotteryConf;
|
|
import com.fs.live.domain.LiveLotteryConf;
|
|
|
import com.fs.live.domain.LiveLotteryRegistration;
|
|
import com.fs.live.domain.LiveLotteryRegistration;
|
|
|
|
|
+import com.fs.live.domain.LiveUserLotteryRecord;
|
|
|
|
|
+import com.fs.live.mapper.LiveAutoTaskMapper;
|
|
|
import com.fs.live.mapper.LiveLotteryConfMapper;
|
|
import com.fs.live.mapper.LiveLotteryConfMapper;
|
|
|
import com.fs.live.mapper.LiveLotteryProductConfMapper;
|
|
import com.fs.live.mapper.LiveLotteryProductConfMapper;
|
|
|
import com.fs.live.mapper.LiveLotteryRegistrationMapper;
|
|
import com.fs.live.mapper.LiveLotteryRegistrationMapper;
|
|
|
|
|
+import com.fs.live.mapper.LiveMapper;
|
|
|
|
|
+import com.fs.live.mapper.LiveUserLotteryRecordMapper;
|
|
|
import com.fs.live.param.LiveLotteryProduct;
|
|
import com.fs.live.param.LiveLotteryProduct;
|
|
|
import com.fs.live.param.LiveLotteryProductSaveParam;
|
|
import com.fs.live.param.LiveLotteryProductSaveParam;
|
|
|
import com.fs.live.param.LotteryPO;
|
|
import com.fs.live.param.LotteryPO;
|
|
@@ -18,12 +26,14 @@ import com.fs.live.vo.LiveLotteryConfVo;
|
|
|
import com.fs.live.vo.LiveLotteryProductListVo;
|
|
import com.fs.live.vo.LiveLotteryProductListVo;
|
|
|
import com.fs.live.vo.LiveLotteryProductVO;
|
|
import com.fs.live.vo.LiveLotteryProductVO;
|
|
|
import com.fs.live.vo.LiveUserLotteryRecordVo;
|
|
import com.fs.live.vo.LiveUserLotteryRecordVo;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -33,6 +43,7 @@ import java.util.stream.Collectors;
|
|
|
* @date 2025-07-17
|
|
* @date 2025-07-17
|
|
|
*/
|
|
*/
|
|
|
@Service
|
|
@Service
|
|
|
|
|
+@Slf4j
|
|
|
public class LiveLotteryConfServiceImpl implements ILiveLotteryConfService {
|
|
public class LiveLotteryConfServiceImpl implements ILiveLotteryConfService {
|
|
|
|
|
|
|
|
@Autowired
|
|
@Autowired
|
|
@@ -44,11 +55,15 @@ public class LiveLotteryConfServiceImpl implements ILiveLotteryConfService {
|
|
|
private RedisCache redisCache;
|
|
private RedisCache redisCache;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private LiveLotteryRegistrationMapper lotteryRegistrationMapper;
|
|
private LiveLotteryRegistrationMapper lotteryRegistrationMapper;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private LiveUserLotteryRecordMapper liveUserLotteryRecordMapper;
|
|
|
|
|
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private LiveLotteryConfMapper baseMapper;
|
|
private LiveLotteryConfMapper baseMapper;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private ILiveAutoTaskService liveAutoTaskService;
|
|
private ILiveAutoTaskService liveAutoTaskService;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private LiveMapper liveMapper;
|
|
|
/**
|
|
/**
|
|
|
* 查询直播抽奖配置
|
|
* 查询直播抽奖配置
|
|
|
*
|
|
*
|
|
@@ -313,5 +328,402 @@ public class LiveLotteryConfServiceImpl implements ILiveLotteryConfService {
|
|
|
return baseMapper.selectLiveUserLotteryRecordByUserId(userId);
|
|
return baseMapper.selectLiveUserLotteryRecordByUserId(userId);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 自动化开始抽奖
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void autoStartLottery(Long lotteryId) {
|
|
|
|
|
+ String lockKey = "lottery:auto:start:" + lotteryId;
|
|
|
|
|
+ try {
|
|
|
|
|
+ Boolean lockAcquired = redisCache.redisTemplate.opsForValue()
|
|
|
|
|
+ .setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
|
|
|
|
|
+
|
|
|
|
|
+ if (!Boolean.TRUE.equals(lockAcquired)) {
|
|
|
|
|
+ log.warn("[自动抽奖-开始] 任务正在执行,lotteryId={}", lotteryId);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ LiveLotteryConf conf = baseMapper.selectLiveLotteryConfByLotteryId(lotteryId);
|
|
|
|
|
+ if (conf == null) {
|
|
|
|
|
+ log.error("[自动抽奖-开始] 抽奖不存在,lotteryId={}", lotteryId);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!"0".equals(conf.getLotteryStatus())) {
|
|
|
|
|
+ log.warn("[自动抽奖-开始] 抽奖状态不是未开始,lotteryId={}, status={}", lotteryId, conf.getLotteryStatus());
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ log.info("[自动抽奖-开始] 开始执行,liveId={}, lotteryId={}", conf.getLiveId(), lotteryId);
|
|
|
|
|
+
|
|
|
|
|
+ // 更新抽奖状态为进行中
|
|
|
|
|
+ conf.setLotteryStatus("1");
|
|
|
|
|
+ conf.setUpdateTime(new Date());
|
|
|
|
|
+ baseMapper.updateLiveLotteryConf(conf);
|
|
|
|
|
+
|
|
|
|
|
+ log.info("[自动抽奖-开始] 执行成功,liveId={}, lotteryId={}", conf.getLiveId(), lotteryId);
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("[自动抽奖-开始] 执行失败,lotteryId={}", lotteryId, e);
|
|
|
|
|
+ throw e;
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ redisCache.deleteObject(lockKey);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 自动化结算抽奖
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public List<Map<String, Object>> autoSettleLottery(Long lotteryId) {
|
|
|
|
|
+ String lockKey = "lottery:auto:settle:" + lotteryId;
|
|
|
|
|
+ List<Map<String, Object>> winners = new ArrayList<>();
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ Boolean lockAcquired = redisCache.redisTemplate.opsForValue()
|
|
|
|
|
+ .setIfAbsent(lockKey, "1", 30, TimeUnit.SECONDS);
|
|
|
|
|
+
|
|
|
|
|
+ if (!Boolean.TRUE.equals(lockAcquired)) {
|
|
|
|
|
+ log.warn("[自动抽奖-结算] 任务正在执行,lotteryId={}", lotteryId);
|
|
|
|
|
+ return winners;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ LiveLotteryConf conf = baseMapper.selectLiveLotteryConfByLotteryId(lotteryId);
|
|
|
|
|
+ if (conf == null) {
|
|
|
|
|
+ log.error("[自动抽奖-结算] 抽奖不存在,lotteryId={}", lotteryId);
|
|
|
|
|
+ return winners;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ("2".equals(conf.getLotteryStatus())) {
|
|
|
|
|
+ log.warn("[自加抽奖-结算] 抽奖已结束,跳过重复执行,lotteryId={}", lotteryId);
|
|
|
|
|
+ return winners;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ log.info("[自动抽奖-结算] 开始执行,liveId={}, lotteryId={}", conf.getLiveId(), lotteryId);
|
|
|
|
|
+
|
|
|
|
|
+ // 从Redis读取参与者
|
|
|
|
|
+ String redisKey = String.format(LiveKeysConstant.LIVE_HOME_PAGE_CONFIG_DRAW, conf.getLiveId(), lotteryId);
|
|
|
|
|
+ Map<Object, Object> redisData = redisCache.redisTemplate.opsForHash().entries(redisKey);
|
|
|
|
|
+
|
|
|
|
|
+ if (redisData == null || redisData.isEmpty()) {
|
|
|
|
|
+ log.info("[自动抽奖-结算] Redis无参与者,liveId={}, lotteryId={}", conf.getLiveId(), lotteryId);
|
|
|
|
|
+ // 直接更新状态为已结束
|
|
|
|
|
+ conf.setLotteryStatus("2");
|
|
|
|
|
+ conf.setUpdateTime(new Date());
|
|
|
|
|
+ baseMapper.updateLiveLotteryConf(conf);
|
|
|
|
|
+ return winners;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 解析参与者
|
|
|
|
|
+ List<LiveLotteryRegistration> participants = new ArrayList<>();
|
|
|
|
|
+ for (Map.Entry<Object, Object> entry : redisData.entrySet()) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ LiveLotteryRegistration registration = JSON.parseObject(
|
|
|
|
|
+ entry.getValue().toString(),
|
|
|
|
|
+ LiveLotteryRegistration.class
|
|
|
|
|
+ );
|
|
|
|
|
+ if (registration != null) {
|
|
|
|
|
+ participants.add(registration);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("[自动抽奖-结算] 解析参与者失败", e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (participants.isEmpty()) {
|
|
|
|
|
+ log.info("[自加抽奖-结算] 无有效参与者,liveId={}, lotteryId={}", conf.getLiveId(), lotteryId);
|
|
|
|
|
+ conf.setLotteryStatus("2");
|
|
|
|
|
+ conf.setUpdateTime(new Date());
|
|
|
|
|
+ baseMapper.updateLiveLotteryConf(conf);
|
|
|
|
|
+ return winners;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 查询奖品配置
|
|
|
|
|
+ List<LiveLotteryProduct> prizes = productMapper.selectLiveLotteryProductConfByLotteryId(lotteryId);
|
|
|
|
|
+ if (prizes == null || prizes.isEmpty()) {
|
|
|
|
|
+ log.error("[自动抽奖-结算] 无奖品配置,lotteryId={}", lotteryId);
|
|
|
|
|
+ return winners;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 执行抽奖逻辑
|
|
|
|
|
+ winners = performLottery(participants, prizes, conf.getLiveId(), lotteryId);
|
|
|
|
|
+
|
|
|
|
|
+ // 更新抽奖状态为已结束
|
|
|
|
|
+ conf.setLotteryStatus("2");
|
|
|
|
|
+ conf.setUpdateTime(new Date());
|
|
|
|
|
+ baseMapper.updateLiveLotteryConf(conf);
|
|
|
|
|
+
|
|
|
|
|
+ // 清理Redis
|
|
|
|
|
+ redisCache.deleteObject(redisKey);
|
|
|
|
|
+
|
|
|
|
|
+ log.info("[自加抽奖-结算] 执行成功,liveId={}, lotteryId={}, 参与人数={}, 中奖人数={}",
|
|
|
|
|
+ conf.getLiveId(), lotteryId, participants.size(), winners.size());
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("[自加抽奖-结算] 执行失败,lotteryId={}", lotteryId, e);
|
|
|
|
|
+ throw e;
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ redisCache.deleteObject(lockKey);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return winners;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 执行抽奖逻辑
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<Map<String, Object>> performLottery(List<LiveLotteryRegistration> participants,
|
|
|
|
|
+ List<LiveLotteryProduct> prizes,
|
|
|
|
|
+ Long liveId, Long lotteryId) {
|
|
|
|
|
+ List<Map<String, Object>> winners = new ArrayList<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 打乱参与者
|
|
|
|
|
+ Collections.shuffle(participants);
|
|
|
|
|
+
|
|
|
|
|
+ // 按奖品等级排序
|
|
|
|
|
+ prizes.sort(Comparator.comparing(LiveLotteryProduct::getPrizeLevel));
|
|
|
|
|
+
|
|
|
|
|
+ // 分配奖品
|
|
|
|
|
+ int winnerIndex = 0;
|
|
|
|
|
+ List<LiveLotteryRegistration> winnerRegistrations = new ArrayList<>();
|
|
|
|
|
+ List<LiveUserLotteryRecord> lotteryRecords = new ArrayList<>();
|
|
|
|
|
+ Date now = new Date();
|
|
|
|
|
+
|
|
|
|
|
+ for (LiveLotteryProduct prize : prizes) {
|
|
|
|
|
+ int totalLots = prize.getTotalLots() != null ? prize.getTotalLots().intValue() : 0;
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < totalLots && winnerIndex < participants.size(); i++) {
|
|
|
|
|
+ LiveLotteryRegistration winner = participants.get(winnerIndex);
|
|
|
|
|
+ winner.setIsWin(1L);
|
|
|
|
|
+ winner.setRizeLevel(prize.getPrizeLevel());
|
|
|
|
|
+ winner.setUpdateTime(now);
|
|
|
|
|
+ winnerRegistrations.add(winner);
|
|
|
|
|
+
|
|
|
|
|
+ // 创建中奖记录
|
|
|
|
|
+ LiveUserLotteryRecord record = new LiveUserLotteryRecord();
|
|
|
|
|
+ record.setLotteryId(lotteryId);
|
|
|
|
|
+ record.setLiveId(liveId);
|
|
|
|
|
+ record.setUserId(winner.getUserId());
|
|
|
|
|
+ record.setProductId(prize.getProductId());
|
|
|
|
|
+ record.setOrderStatus(-9);
|
|
|
|
|
+ record.setCreateTime(now);
|
|
|
|
|
+ lotteryRecords.add(record);
|
|
|
|
|
+
|
|
|
|
|
+ // 构造返回结果
|
|
|
|
|
+ Map<String, Object> winnerInfo = new HashMap<>();
|
|
|
|
|
+ winnerInfo.put("userId", winner.getUserId());
|
|
|
|
|
+ winnerInfo.put("prizeLevel", prize.getPrizeLevel());
|
|
|
|
|
+ winnerInfo.put("productId", prize.getProductId());
|
|
|
|
|
+ winners.add(winnerInfo);
|
|
|
|
|
+
|
|
|
|
|
+ winnerIndex++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 批量写入数据库:先插入参与者,再更新中奖者,最后插入中奖记录
|
|
|
|
|
+ if (!participants.isEmpty()) {
|
|
|
|
|
+ batchInsertOrUpdateParticipants(participants, liveId, lotteryId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!lotteryRecords.isEmpty()) {
|
|
|
|
|
+ batchInsertLotteryRecords(lotteryRecords, lotteryId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return winners;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 批量插入或更新参与者(包括中奖者)
|
|
|
|
|
+ */
|
|
|
|
|
+ private void batchInsertOrUpdateParticipants(List<LiveLotteryRegistration> participants, Long liveId, Long lotteryId) {
|
|
|
|
|
+ // 查询已存在的记录
|
|
|
|
|
+ LiveLotteryRegistration query = new LiveLotteryRegistration();
|
|
|
|
|
+ query.setLotteryId(lotteryId);
|
|
|
|
|
+ List<LiveLotteryRegistration> existing = lotteryRegistrationMapper.selectLiveLotteryRegistrationList(query);
|
|
|
|
|
+
|
|
|
|
|
+ Map<Long, LiveLotteryRegistration> existingMap = new HashMap<>();
|
|
|
|
|
+ if (existing != null) {
|
|
|
|
|
+ for (LiveLotteryRegistration reg : existing) {
|
|
|
|
|
+ existingMap.put(reg.getUserId(), reg);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<LiveLotteryRegistration> toInsert = new ArrayList<>();
|
|
|
|
|
+ List<LiveLotteryRegistration> toUpdate = new ArrayList<>();
|
|
|
|
|
+ Date now = new Date();
|
|
|
|
|
+
|
|
|
|
|
+ for (LiveLotteryRegistration registration : participants) {
|
|
|
|
|
+ registration.setLiveId(liveId);
|
|
|
|
|
+ registration.setLotteryId(lotteryId);
|
|
|
|
|
+ registration.setUpdateTime(now);
|
|
|
|
|
+
|
|
|
|
|
+ if (existingMap.containsKey(registration.getUserId())) {
|
|
|
|
|
+ // 已存在,需要更新
|
|
|
|
|
+ toUpdate.add(registration);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 不存在,需要插入
|
|
|
|
|
+ if (registration.getIsWin() == null) {
|
|
|
|
|
+ registration.setIsWin(0L);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (registration.getRizeLevel() == null) {
|
|
|
|
|
+ registration.setRizeLevel(-1L);
|
|
|
|
|
+ }
|
|
|
|
|
+ registration.setCreateTime(now);
|
|
|
|
|
+ toInsert.add(registration);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 批量插入
|
|
|
|
|
+ if (!toInsert.isEmpty()) {
|
|
|
|
|
+ int batchSize = 500;
|
|
|
|
|
+ for (int i = 0; i < toInsert.size(); i += batchSize) {
|
|
|
|
|
+ int end = Math.min(i + batchSize, toInsert.size());
|
|
|
|
|
+ List<LiveLotteryRegistration> batch = toInsert.subList(i, end);
|
|
|
|
|
+ lotteryRegistrationMapper.insertLiveLotteryRegistrationBatch(batch);
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("[自动抽奖] 批量插入参与者,lotteryId={}, count={}", lotteryId, toInsert.size());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 批量更新
|
|
|
|
|
+ if (!toUpdate.isEmpty()) {
|
|
|
|
|
+ for (LiveLotteryRegistration registration : toUpdate) {
|
|
|
|
|
+ lotteryRegistrationMapper.updateLiveLotteryRegistrationNoId(registration);
|
|
|
|
|
+ }
|
|
|
|
|
+ log.info("[自动抽奖] 批量更新参与者,lotteryId={}, count={}", lotteryId, toUpdate.size());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 批量插入中奖记录
|
|
|
|
|
+ */
|
|
|
|
|
+ private void batchInsertLotteryRecords(List<LiveUserLotteryRecord> records, Long lotteryId) {
|
|
|
|
|
+ if (records.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Set<Long> existingUserIds = new HashSet<>();
|
|
|
|
|
+ for (LiveUserLotteryRecord record : records) {
|
|
|
|
|
+ LiveUserLotteryRecord query = new LiveUserLotteryRecord();
|
|
|
|
|
+ query.setLotteryId(record.getLotteryId());
|
|
|
|
|
+ query.setUserId(record.getUserId());
|
|
|
|
|
+ List<LiveUserLotteryRecord> existing = liveUserLotteryRecordMapper.selectLiveUserLotteryRecordList(query);
|
|
|
|
|
+
|
|
|
|
|
+ if (existing != null && !existing.isEmpty()) {
|
|
|
|
|
+ existingUserIds.add(record.getUserId());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<LiveUserLotteryRecord> toInsert = new ArrayList<>();
|
|
|
|
|
+ for (LiveUserLotteryRecord record : records) {
|
|
|
|
|
+ if (!existingUserIds.contains(record.getUserId())) {
|
|
|
|
|
+ toInsert.add(record);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (toInsert.isEmpty()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 单条插入
|
|
|
|
|
+ for (LiveUserLotteryRecord record : toInsert) {
|
|
|
|
|
+ liveUserLotteryRecordMapper.insertLiveUserLotteryRecord(record);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ log.info("[自加抽奖] 批量插入中奖记录,lotteryId={}, count={}", lotteryId, toInsert.size());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 设置自动化抽奖
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public R setAutoLottery(Long lotteryId, String autoStartTime, String autoSettlementTime) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ LiveLotteryConf conf = baseMapper.selectLiveLotteryConfByLotteryId(lotteryId);
|
|
|
|
|
+ if (conf == null) {
|
|
|
|
|
+ return R.error("抽奖配置不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!"0".equals(conf.getLotteryStatus())) {
|
|
|
|
|
+ return R.error("抽奖已开始,无法设置自动化");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<LiveLotteryProduct> prizes = productMapper.selectLiveLotteryProductConfByLotteryId(lotteryId);
|
|
|
|
|
+ if (prizes == null || prizes.isEmpty()) {
|
|
|
|
|
+ return R.error("请先添加奖品");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Live live = liveMapper.selectLiveByLiveId(conf.getLiveId());
|
|
|
|
|
+ if (live == null) {
|
|
|
|
|
+ return R.error("直播间不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Date startTime = com.fs.common.utils.DateUtils.parseDate(autoStartTime);
|
|
|
|
|
+ Date settlementTime = com.fs.common.utils.DateUtils.parseDate(autoSettlementTime);
|
|
|
|
|
+ Date now = new Date();
|
|
|
|
|
+
|
|
|
|
|
+ if (startTime.before(now)) {
|
|
|
|
|
+ return R.error("开始时间不能早于当前时间");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (settlementTime.before(startTime)) {
|
|
|
|
|
+ return R.error("结算时间不能早于开始时间");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ LiveAutoTask startTask = new LiveAutoTask();
|
|
|
|
|
+ startTask.setLiveId(conf.getLiveId());
|
|
|
|
|
+ startTask.setTaskName("自动开始抽奖-" + conf.getDesc());
|
|
|
|
|
+ startTask.setTaskType(7L);
|
|
|
|
|
+ startTask.setTriggerType(1L);
|
|
|
|
|
+ startTask.setTriggerValue(startTime);
|
|
|
|
|
+ startTask.setAbsValue(startTime);
|
|
|
|
|
+ startTask.setContent(JSON.toJSONString(conf));
|
|
|
|
|
+ startTask.setStatus(1L);
|
|
|
|
|
+ startTask.setFinishStatus(0L);
|
|
|
|
|
+ startTask.setCreateTime(now);
|
|
|
|
|
+ startTask.setUpdateTime(now);
|
|
|
|
|
+ liveAutoTaskService.directInsertLiveAutoTask(startTask);
|
|
|
|
|
+
|
|
|
|
|
+ LiveAutoTask settlementTask = new LiveAutoTask();
|
|
|
|
|
+ settlementTask.setLiveId(conf.getLiveId());
|
|
|
|
|
+ settlementTask.setTaskName("自动结算抽奖-" + conf.getDesc());
|
|
|
|
|
+ settlementTask.setTaskType(8L);
|
|
|
|
|
+ settlementTask.setTriggerType(1L);
|
|
|
|
|
+ settlementTask.setTriggerValue(settlementTime);
|
|
|
|
|
+ settlementTask.setAbsValue(settlementTime);
|
|
|
|
|
+ settlementTask.setContent(JSON.toJSONString(conf));
|
|
|
|
|
+ settlementTask.setStatus(1L);
|
|
|
|
|
+ settlementTask.setFinishStatus(0L);
|
|
|
|
|
+ settlementTask.setCreateTime(now);
|
|
|
|
|
+ settlementTask.setUpdateTime(now);
|
|
|
|
|
+ liveAutoTaskService.directInsertLiveAutoTask(settlementTask);
|
|
|
|
|
+
|
|
|
|
|
+ if (live.getStatus() == 2) {
|
|
|
|
|
+ redisCache.redisTemplate.opsForZSet().add(
|
|
|
|
|
+ "live:auto_task:" + live.getLiveId(),
|
|
|
|
|
+ JSON.toJSONString(startTask),
|
|
|
|
|
+ startTime.getTime()
|
|
|
|
|
+ );
|
|
|
|
|
+ redisCache.redisTemplate.opsForZSet().add(
|
|
|
|
|
+ "live:auto_task:" + live.getLiveId(),
|
|
|
|
|
+ JSON.toJSONString(settlementTask),
|
|
|
|
|
+ settlementTime.getTime()
|
|
|
|
|
+ );
|
|
|
|
|
+ redisCache.redisTemplate.expire(
|
|
|
|
|
+ "live:auto_task:" + live.getLiveId(),
|
|
|
|
|
+ 30,
|
|
|
|
|
+ TimeUnit.MINUTES
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return R.ok("自动化抽奖设置成功");
|
|
|
|
|
+
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("设置自动化抽奖失败,lotteryId: {}", lotteryId, e);
|
|
|
|
|
+ return R.error("设置失败:" + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
}
|
|
}
|