diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryMultiDrawExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryMultiDrawExe.java index 1ea99d46..03f0cb1f 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryMultiDrawExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryMultiDrawExe.java @@ -11,20 +11,25 @@ import com.red.circle.other.infra.database.rds.entity.activity.LotteryRecord; import com.red.circle.other.infra.database.rds.entity.activity.LotteryTicket; import com.red.circle.other.infra.database.rds.entity.activity.LotteryTicketRecord; import com.red.circle.other.infra.database.rds.entity.activity.LotteryUserCount; +import com.red.circle.other.infra.database.rds.entity.activity.LotteryUserProgress; import com.red.circle.other.infra.database.rds.service.activity.LotteryActivityService; import com.red.circle.other.infra.database.rds.service.activity.LotteryPrizeService; import com.red.circle.other.infra.database.rds.service.activity.LotteryRecordService; import com.red.circle.other.infra.database.rds.service.activity.LotteryTicketRecordService; import com.red.circle.other.infra.database.rds.service.activity.LotteryTicketService; import com.red.circle.other.infra.database.rds.service.activity.LotteryUserCountService; +import com.red.circle.other.infra.database.rds.service.activity.LotteryUserProgressService; import com.red.circle.other.inner.asserts.lottery.LotteryErrorCode; import com.red.circle.tool.core.date.TimestampUtils; import java.math.BigDecimal; import java.sql.Timestamp; import java.time.LocalDate; +import java.time.temporal.WeekFields; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; @@ -32,7 +37,7 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; /** - * 执行连抽. + * 执行连抽(支持动态概率池). * * @author system * @since 2025-10-20 @@ -48,6 +53,7 @@ public class LotteryMultiDrawExe { private final LotteryTicketService lotteryTicketService; private final LotteryTicketRecordService lotteryTicketRecordService; private final LotteryUserCountService lotteryUserCountService; + private final LotteryUserProgressService lotteryUserProgressService; @Transactional(rollbackFor = Exception.class) public LotteryMultiDrawResultCO execute(LotteryMultiDrawCmd cmd) { @@ -75,183 +81,271 @@ public class LotteryMultiDrawExe { deductTicket(userId, ticketCost); } - // 5. 生成批次号 + // 5. 获取或创建用户进度(用于动态概率) + LotteryUserProgress progress = getOrCreateUserProgress(userId, activityId); + + // 6. 生成批次号 String batchNo = generateBatchNo(); - // 6. 执行连抽 + // 7. 执行连抽 List results = new ArrayList<>(); boolean guaranteeTriggered = false; + BigDecimal batchTotalAmount = BigDecimal.ZERO; - // 前N-1次正常抽奖(使用连抽概率) - for (int i = 0; i < drawCount - 1; i++) { - LotteryPrize prize = drawPrizeWithMultiProbability(activityId); + // 每次抽奖都使用动态概率 + for (int i = 0; i < drawCount; i++) { + // 实时获取用户进度(因为每次抽奖后都会更新) + LotteryUserProgress currentProgress = lotteryUserProgressService.getById(progress.getId()); + + // 使用动态概率抽奖 + LotteryPrize prize = drawPrizeWithDynamicProbability(activityId, activity, currentProgress); // 扣减库存 if (prize != null) { - deductPrizeStock(prize.getId()); + boolean deductSuccess = deductPrizeStock(prize.getId()); + if (!deductSuccess) { + log.warn("Prize stock deduction failed in multi-draw, prizeId: {}", prize.getId()); + prize = null; + } } // 保存记录 LotteryRecord record = saveDrawRecord(userId, activityId, prize, now, batchNo, 2); results.add(convertToResultCO(record, prize)); + + // 临时更新用户进度(用于下次抽奖判断阶段) + if (prize != null && prize.getPrizeValue() != null) { + BigDecimal prizeValue = prize.getPrizeValue(); + batchTotalAmount = batchTotalAmount.add(prizeValue); + + // 立即更新数据库 + updateUserProgress(progress, prize); + } else { + // 没中奖也要更新次数 + lotteryUserProgressService.update() + .eq(LotteryUserProgress::getId, progress.getId()) + .setSql("total_draw_count = total_draw_count + 1") + .set(LotteryUserProgress::getLastDrawDate, LocalDate.now()) + .execute(); + } } - // 最后一次:检查是否需要保底 - BigDecimal totalAmount = calculateTotalAmount(results); + // 8. 检查连抽保底 BigDecimal guaranteeMinAmount = activity.getMultiDrawGuaranteeMinAmount() != null ? activity.getMultiDrawGuaranteeMinAmount() : BigDecimal.ZERO; - LotteryPrize lastPrize; - if (totalAmount.compareTo(guaranteeMinAmount) < 0) { - // 触发保底 + if (batchTotalAmount.compareTo(guaranteeMinAmount) < 0 && guaranteeMinAmount.compareTo(BigDecimal.ZERO) > 0) { + // 触发保底:替换最后一个未中奖的记录 guaranteeTriggered = true; - lastPrize = getGuaranteePrize(activityId, activity.getMultiDrawGuaranteePrizeId()); - log.info("Multi-draw guarantee triggered, userId: {}, activityId: {}", userId, activityId); - } else { - // 正常抽奖 - lastPrize = drawPrizeWithMultiProbability(activityId); + replaceWithGuaranteePrize(results, activity, userId, activityId, now, batchNo, progress); + log.info("Multi-draw guarantee triggered, userId: {}, activityId: {}, batchAmount: {}", + userId, activityId, batchTotalAmount); } - - // 扣减库存 - if (lastPrize != null) { - deductPrizeStock(lastPrize.getId()); - } - - // 保存最后一次记录 - LotteryRecord lastRecord = saveDrawRecord(userId, activityId, lastPrize, now, batchNo, 2); - results.add(convertToResultCO(lastRecord, lastPrize)); - // 7. 更新用户抽奖次数(+drawCount次) + // 9. 更新用户抽奖次数(+drawCount次) updateUserDrawCount(userId, activityId, drawCount); - // 8. 组装返回结果 + // 10. 组装返回结果 return buildMultiDrawResult(batchNo, results, guaranteeTriggered); } - /** - * 校验活动状态和时间. - */ private LotteryActivity validateActivity(Long activityId, Timestamp now) { LotteryActivity activity = lotteryActivityService.getById(activityId); ResponseAssert.isTrue(LotteryErrorCode.ACTIVITY_NOT_FOUND, activity != null); ResponseAssert.isTrue(LotteryErrorCode.ACTIVITY_CLOSED, activity.getStatus() == 1); ResponseAssert.isTrue(LotteryErrorCode.NOT_IN_ACTIVITY_TIME, now.after(activity.getStartTime()) && now.before(activity.getEndTime())); - return activity; } - /** - * 校验抽奖次数限制. - */ private void validateDrawCount(Long userId, Long activityId, LotteryActivity activity, Integer drawCount) { if (activity.getDrawCountLimit() == null || activity.getDrawCountLimit() <= 0) { - return; // 无限制 + return; } - LotteryUserCount userCount = lotteryUserCountService.query() .eq(LotteryUserCount::getUserId, userId) .eq(LotteryUserCount::getActivityId, activityId) .eq(LotteryUserCount::getDrawDate, LocalDate.now()) .getOne(); - int currentDrawCount = userCount != null ? userCount.getDrawCount() : 0; ResponseAssert.isTrue(LotteryErrorCode.DRAW_COUNT_EXHAUSTED, currentDrawCount + drawCount <= activity.getDrawCountLimit()); } - /** - * 扣除抽奖券. - */ - private void deductTicket(Long userId, Integer ticketCost) { - List tickets = lotteryTicketService.query() - .eq(LotteryTicket::getUserId, userId) - .eq(LotteryTicket::getStatus, 1) - .gt(LotteryTicket::getRemainingCount, 0) - .orderByAsc(LotteryTicket::getExpireTime) - .list(); - - int totalRemaining = tickets.stream() - .mapToInt(LotteryTicket::getRemainingCount) - .sum(); - ResponseAssert.isTrue(LotteryErrorCode.INSUFFICIENT_TICKETS, totalRemaining >= ticketCost); - - List records = new ArrayList<>(); - int remaining = ticketCost; - - for (LotteryTicket ticket : tickets) { - if (remaining <= 0) { - break; - } - - int deduct = Math.min(remaining, ticket.getRemainingCount()); - - boolean updateSuccess = lotteryTicketService.update() - .eq(LotteryTicket::getId, ticket.getId()) - .eq(LotteryTicket::getRemainingCount, ticket.getRemainingCount()) - .setSql("used_count = used_count + " + deduct) - .setSql("remaining_count = remaining_count - " + deduct) - .execute(); - - ResponseAssert.isTrue(LotteryErrorCode.INSUFFICIENT_TICKETS, updateSuccess); - - LotteryTicketRecord ticketRecord = new LotteryTicketRecord(); - ticketRecord.setUserId(userId); - ticketRecord.setTicketId(ticket.getId()); - ticketRecord.setChangeCount(-deduct); - ticketRecord.setChangeType(2); - ticketRecord.setRemark("连抽消耗"); - records.add(ticketRecord); - - remaining -= deduct; + private LotteryUserProgress getOrCreateUserProgress(Long userId, Long activityId) { + String weekKey = getWeekKey(); + LotteryUserProgress progress = lotteryUserProgressService.query() + .eq(LotteryUserProgress::getUserId, userId) + .eq(LotteryUserProgress::getActivityId, activityId) + .eq(LotteryUserProgress::getWeekKey, weekKey) + .getOne(); + if (progress == null) { + progress = new LotteryUserProgress(); + progress.setUserId(userId); + progress.setActivityId(activityId); + progress.setWeekKey(weekKey); + progress.setTotalAmount(BigDecimal.ZERO); + progress.setTotalDrawCount(0); + progress.setBigPrizeCount(0); + progress.setCurrentStage("EARLY"); + progress.setLastDrawDate(LocalDate.now()); + lotteryUserProgressService.save(progress); } + return progress; + } - if (!records.isEmpty()) { - lotteryTicketRecordService.saveBatch(records); + private LotteryPrize drawPrizeWithDynamicProbability(Long activityId, LotteryActivity activity, LotteryUserProgress progress) { + if (activity.getEnableDynamicProbability() == null || activity.getEnableDynamicProbability() != 1) { + return drawPrizeWithMultiProbability(activityId); + } + String stage = determinePrizePool(progress, activity); + log.debug("Multi-draw stage: {}, userId: {}, drawCount: {}, totalAmount: {}", + stage, progress.getUserId(), progress.getTotalDrawCount(), progress.getTotalAmount()); + List prizes = getPrizesByPool(activityId, stage); + prizes = filterOverThresholdPrizes(prizes, progress, activity.getWithdrawThreshold()); + if (prizes.isEmpty()) { + return null; + } + for (LotteryPrize prize : prizes) { + if (prize.getMultiDrawProbability() != null) { + prize.setProbability(prize.getMultiDrawProbability()); + } + } + adjustProbability(prizes, progress, activity.getWithdrawThreshold()); + return randomSelectByProbability(prizes); + } + + private String determinePrizePool(LotteryUserProgress progress, LotteryActivity activity) { + int drawCount = progress.getTotalDrawCount(); + BigDecimal totalAmount = progress.getTotalAmount(); + BigDecimal threshold = activity.getWithdrawThreshold() != null ? activity.getWithdrawThreshold() : new BigDecimal("10"); + int earlyMax = activity.getEarlyStageMaxCount() != null ? activity.getEarlyStageMaxCount() : 15; + int middleMax = activity.getMiddleStageMaxCount() != null ? activity.getMiddleStageMaxCount() : 50; + BigDecimal lateTrigger = activity.getLateStageTriggerAmount() != null ? activity.getLateStageTriggerAmount() : new BigDecimal("6"); + if (drawCount < earlyMax) { + return "EARLY"; + } + BigDecimal gap = threshold.subtract(totalAmount); + if (drawCount >= middleMax || gap.compareTo(lateTrigger) <= 0) { + return "LATE"; + } + return "MIDDLE"; + } + + private List getPrizesByPool(Long activityId, String pool) { + return lotteryPrizeService.query() + .eq(LotteryPrize::getActivityId, activityId) + .gt(LotteryPrize::getRemainingStock, 0) + .and(wrapper -> wrapper.eq(LotteryPrize::getPrizePool, pool).or().eq(LotteryPrize::getPrizePool, "ALL")) + .orderByAsc(LotteryPrize::getSortOrder) + .list(); + } + + private List filterOverThresholdPrizes(List prizes, LotteryUserProgress progress, BigDecimal threshold) { + if (threshold == null) { + return prizes; + } + BigDecimal currentAmount = progress.getTotalAmount(); + int drawCount = progress.getTotalDrawCount(); + if (currentAmount.compareTo(threshold) >= 0) { + return prizes.stream().filter(prize -> prize.getPrizeValue().compareTo(BigDecimal.ZERO) == 0).collect(Collectors.toList()); + } + if (currentAmount.compareTo(new BigDecimal("5.0")) >= 0 && drawCount < 50) { + return prizes.stream().filter(prize -> prize.getPrizeValue().compareTo(new BigDecimal("0.15")) <= 0).collect(Collectors.toList()); + } + return prizes.stream().filter(prize -> { + BigDecimal afterAmount = currentAmount.add(prize.getPrizeValue()); + return afterAmount.compareTo(threshold) <= 0; + }).collect(Collectors.toList()); + } + + private void adjustProbability(List prizes, LotteryUserProgress progress, BigDecimal threshold) { + if (threshold == null) { + return; + } + BigDecimal totalAmount = progress.getTotalAmount(); + BigDecimal gap = threshold.subtract(totalAmount); + for (LotteryPrize prize : prizes) { + BigDecimal prizeValue = prize.getPrizeValue(); + BigDecimal originalProbability = prize.getProbability(); + BigDecimal diff = gap.subtract(prizeValue).abs(); + if (diff.compareTo(new BigDecimal("0.5")) <= 0) { + prize.setProbability(originalProbability.multiply(new BigDecimal("2"))); + } + if (totalAmount.compareTo(new BigDecimal("9")) > 0) { + if (prizeValue.compareTo(gap) <= 0 && prizeValue.compareTo(new BigDecimal("0.5")) >= 0) { + prize.setProbability(originalProbability.multiply(new BigDecimal("3"))); + } + } } } - /** - * 使用连抽概率抽奖. - */ + private LotteryPrize randomSelectByProbability(List prizes) { + BigDecimal totalProbability = prizes.stream().map(LotteryPrize::getProbability).reduce(BigDecimal.ZERO, BigDecimal::add); + if (totalProbability.compareTo(BigDecimal.ZERO) == 0) { + return null; + } + double randomValue = ThreadLocalRandom.current().nextDouble() * totalProbability.doubleValue(); + double cumulative = 0.0; + for (LotteryPrize prize : prizes) { + cumulative += prize.getProbability().doubleValue(); + if (randomValue <= cumulative) { + return prize; + } + } + return prizes.get(prizes.size() - 1); + } + private LotteryPrize drawPrizeWithMultiProbability(Long activityId) { List prizes = lotteryPrizeService.query() .eq(LotteryPrize::getActivityId, activityId) .gt(LotteryPrize::getRemainingStock, 0) .orderByAsc(LotteryPrize::getSortOrder) .list(); - if (prizes.isEmpty()) { return null; } - - // 使用连抽概率(如果配置了) BigDecimal totalProbability = prizes.stream() - .map(prize -> prize.getMultiDrawProbability() != null - ? prize.getMultiDrawProbability() - : prize.getProbability()) + .map(prize -> prize.getMultiDrawProbability() != null ? prize.getMultiDrawProbability() : prize.getProbability()) .reduce(BigDecimal.ZERO, BigDecimal::add); - double randomValue = ThreadLocalRandom.current().nextDouble() * totalProbability.doubleValue(); double cumulative = 0.0; - for (LotteryPrize prize : prizes) { - BigDecimal probability = prize.getMultiDrawProbability() != null - ? prize.getMultiDrawProbability() - : prize.getProbability(); + BigDecimal probability = prize.getMultiDrawProbability() != null ? prize.getMultiDrawProbability() : prize.getProbability(); cumulative += probability.doubleValue(); if (randomValue <= cumulative) { return prize; } } - return prizes.get(prizes.size() - 1); } - /** - * 获取保底奖品. - */ + private void replaceWithGuaranteePrize(List results, LotteryActivity activity, Long userId, Long activityId, Timestamp now, String batchNo, LotteryUserProgress progress) { + int replaceIndex = results.size() - 1; + for (int i = results.size() - 1; i >= 0; i--) { + if (!results.get(i).getIsWin()) { + replaceIndex = i; + break; + } + } + LotteryPrize guaranteePrize = getGuaranteePrize(activityId, activity.getMultiDrawGuaranteePrizeId()); + if (guaranteePrize != null) { + deductPrizeStock(guaranteePrize.getId()); + LotteryDrawResultCO oldResult = results.get(replaceIndex); + LotteryRecord record = lotteryRecordService.query().eq(LotteryRecord::getRecordNo, oldResult.getRecordNo()).getOne(); + if (record != null) { + record.setPrizeId(guaranteePrize.getId()); + record.setPrizeName(guaranteePrize.getPrizeName()); + record.setPrizeType(guaranteePrize.getPrizeType()); + record.setIsWin(1); + lotteryRecordService.updateSelectiveById(record); + } + results.set(replaceIndex, convertToResultCO(record, guaranteePrize)); + updateUserProgress(progress, guaranteePrize); + } + } + private LotteryPrize getGuaranteePrize(Long activityId, Long guaranteePrizeId) { if (guaranteePrizeId != null) { LotteryPrize prize = lotteryPrizeService.getById(guaranteePrizeId); @@ -259,20 +353,34 @@ public class LotteryMultiDrawExe { return prize; } } - - // 如果没有配置保底奖品ID,查找可作为保底的奖品 - return lotteryPrizeService.query() - .eq(LotteryPrize::getActivityId, activityId) - .eq(LotteryPrize::getIsGuaranteePrize, 1) - .gt(LotteryPrize::getRemainingStock, 0) - .orderByAsc(LotteryPrize::getPrizeValue) - .last("LIMIT 1") - .getOne(); + return lotteryPrizeService.query().eq(LotteryPrize::getActivityId, activityId).eq(LotteryPrize::getIsGuaranteePrize, 1).gt(LotteryPrize::getRemainingStock, 0).orderByDesc(LotteryPrize::getPrizeValue).last("LIMIT 1").getOne(); + } + + private void deductTicket(Long userId, Integer ticketCost) { + List tickets = lotteryTicketService.query().eq(LotteryTicket::getUserId, userId).eq(LotteryTicket::getStatus, 1).gt(LotteryTicket::getRemainingCount, 0).orderByAsc(LotteryTicket::getExpireTime).list(); + int totalRemaining = tickets.stream().mapToInt(LotteryTicket::getRemainingCount).sum(); + ResponseAssert.isTrue(LotteryErrorCode.INSUFFICIENT_TICKETS, totalRemaining >= ticketCost); + List records = new ArrayList<>(); + int remaining = ticketCost; + for (LotteryTicket ticket : tickets) { + if (remaining <= 0) break; + int deduct = Math.min(remaining, ticket.getRemainingCount()); + boolean updateSuccess = lotteryTicketService.update().eq(LotteryTicket::getId, ticket.getId()).eq(LotteryTicket::getRemainingCount, ticket.getRemainingCount()).setSql("used_count = used_count + " + deduct).setSql("remaining_count = remaining_count - " + deduct).execute(); + ResponseAssert.isTrue(LotteryErrorCode.INSUFFICIENT_TICKETS, updateSuccess); + LotteryTicketRecord ticketRecord = new LotteryTicketRecord(); + ticketRecord.setUserId(userId); + ticketRecord.setTicketId(ticket.getId()); + ticketRecord.setChangeCount(-deduct); + ticketRecord.setChangeType(2); + ticketRecord.setRemark("连抽消耗"); + records.add(ticketRecord); + remaining -= deduct; + } + if (!records.isEmpty()) { + lotteryTicketRecordService.saveBatch(records); + } } - /** - * 扣减奖品库存. - */ private boolean deductPrizeStock(Long prizeId) { return lotteryPrizeService.update() .eq(LotteryPrize::getId, prizeId) @@ -281,11 +389,7 @@ public class LotteryMultiDrawExe { .execute(); } - /** - * 保存抽奖记录. - */ - private LotteryRecord saveDrawRecord(Long userId, Long activityId, LotteryPrize prize, - Timestamp now, String batchNo, Integer drawType) { + private LotteryRecord saveDrawRecord(Long userId, Long activityId, LotteryPrize prize, Timestamp now, String batchNo, Integer drawType) { String recordNo = generateRecordNo(); LotteryRecord record = new LotteryRecord(); record.setRecordNo(recordNo); @@ -294,7 +398,6 @@ public class LotteryMultiDrawExe { record.setDrawTime(now); record.setDrawBatchNo(batchNo); record.setDrawType(drawType); - if (prize != null) { record.setPrizeId(prize.getId()); record.setPrizeName(prize.getPrizeName()); @@ -304,24 +407,13 @@ public class LotteryMultiDrawExe { } else { record.setIsWin(0); } - lotteryRecordService.save(record); return record; } - /** - * 更新用户抽奖次数. - */ private void updateUserDrawCount(Long userId, Long activityId, Integer drawCount) { LocalDate today = LocalDate.now(); - - boolean updated = lotteryUserCountService.update() - .eq(LotteryUserCount::getUserId, userId) - .eq(LotteryUserCount::getActivityId, activityId) - .eq(LotteryUserCount::getDrawDate, today) - .setSql("draw_count = draw_count + " + drawCount) - .execute(); - + boolean updated = lotteryUserCountService.update().eq(LotteryUserCount::getUserId, userId).eq(LotteryUserCount::getActivityId, activityId).eq(LotteryUserCount::getDrawDate, today).setSql("draw_count = draw_count + " + drawCount).execute(); if (!updated) { try { LotteryUserCount userCount = new LotteryUserCount(); @@ -331,96 +423,66 @@ public class LotteryMultiDrawExe { userCount.setDrawCount(drawCount); lotteryUserCountService.save(userCount); } catch (Exception e) { - lotteryUserCountService.update() - .eq(LotteryUserCount::getUserId, userId) - .eq(LotteryUserCount::getActivityId, activityId) - .eq(LotteryUserCount::getDrawDate, today) - .setSql("draw_count = draw_count + " + drawCount) - .execute(); + lotteryUserCountService.update().eq(LotteryUserCount::getUserId, userId).eq(LotteryUserCount::getActivityId, activityId).eq(LotteryUserCount::getDrawDate, today).setSql("draw_count = draw_count + " + drawCount).execute(); } } } - /** - * 计算前N次的总金额. - */ - private BigDecimal calculateTotalAmount(List results) { - return results.stream() - .filter(LotteryDrawResultCO::getIsWin) - .map(r -> r.getPrize() != null ? r.getPrize().getPrizeValue() : BigDecimal.ZERO) - .reduce(BigDecimal.ZERO, BigDecimal::add); + private void updateUserProgress(LotteryUserProgress progress, LotteryPrize prize) { + BigDecimal addAmount = prize != null ? prize.getPrizeValue() : BigDecimal.ZERO; + int addBigPrizeCount = (prize != null && prize.getPrizeValue().compareTo(new BigDecimal("0.5")) >= 0) ? 1 : 0; + lotteryUserProgressService.update() + .eq(LotteryUserProgress::getId, progress.getId()) + .setSql("total_amount = total_amount + " + addAmount) + .setSql("total_draw_count = total_draw_count + 1") + .setSql("big_prize_count = big_prize_count + " + addBigPrizeCount) + .set(LotteryUserProgress::getLastDrawDate, LocalDate.now()) + .execute(); + } + + private String getWeekKey() { + LocalDate now = LocalDate.now(); + int year = now.getYear(); + int weekOfYear = now.get(WeekFields.of(Locale.getDefault()).weekOfYear()); + return String.format("%dW%02d", year, weekOfYear); } - /** - * 转换为结果CO. - */ private LotteryDrawResultCO convertToResultCO(LotteryRecord record, LotteryPrize prize) { LotteryDrawResultCO result = new LotteryDrawResultCO(); result.setRecordNo(record.getRecordNo()); result.setIsWin(record.getIsWin() == 1); result.setDrawTime(record.getDrawTime()); - if (prize != null) { LotteryPrizeCO prizeCO = new LotteryPrizeCO(); BeanUtils.copyProperties(prize, prizeCO); result.setPrize(prizeCO); } - return result; } - /** - * 构建连抽结果. - */ - private LotteryMultiDrawResultCO buildMultiDrawResult(String batchNo, - List results, - boolean guaranteeTriggered) { + private LotteryMultiDrawResultCO buildMultiDrawResult(String batchNo, List results, boolean guaranteeTriggered) { LotteryMultiDrawResultCO multiResult = new LotteryMultiDrawResultCO(); multiResult.setBatchNo(batchNo); multiResult.setDrawType(2); multiResult.setResults(results); - - // 汇总信息 LotteryMultiDrawResultCO.MultiDrawSummary summary = new LotteryMultiDrawResultCO.MultiDrawSummary(); - - BigDecimal totalAmount = results.stream() - .filter(LotteryDrawResultCO::getIsWin) - .map(r -> r.getPrize() != null ? r.getPrize().getPrizeValue() : BigDecimal.ZERO) - .reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal totalAmount = results.stream().filter(LotteryDrawResultCO::getIsWin).map(r -> r.getPrize() != null ? r.getPrize().getPrizeValue() : BigDecimal.ZERO).reduce(BigDecimal.ZERO, BigDecimal::add); summary.setTotalAmount(totalAmount); - summary.setGuaranteeTriggered(guaranteeTriggered); - - long winCount = results.stream() - .filter(LotteryDrawResultCO::getIsWin) - .count(); + long winCount = results.stream().filter(LotteryDrawResultCO::getIsWin).count(); summary.setWinCount((int) winCount); - - long bigPrizeCount = results.stream() - .filter(LotteryDrawResultCO::getIsWin) - .filter(r -> r.getPrize() != null && r.getPrize().getPrizeValue().compareTo(new BigDecimal("0.5")) >= 0) - .count(); + long bigPrizeCount = results.stream().filter(LotteryDrawResultCO::getIsWin).filter(r -> r.getPrize() != null && r.getPrize().getPrizeValue().compareTo(new BigDecimal("0.5")) >= 0).count(); summary.setBigPrizeCount((int) bigPrizeCount); - multiResult.setSummary(summary); - return multiResult; } - /** - * 生成批次号. - */ private String generateBatchNo() { - return "BATCH" + System.currentTimeMillis() + - String.format("%06d", ThreadLocalRandom.current().nextInt(1000000)); + return "BATCH" + System.currentTimeMillis() + String.format("%06d", ThreadLocalRandom.current().nextInt(1000000)); } - /** - * 生成记录编号. - */ private String generateRecordNo() { - return "LT" + System.currentTimeMillis() + - String.format("%06d", ThreadLocalRandom.current().nextInt(1000000)); + return "LT" + System.currentTimeMillis() + String.format("%06d", ThreadLocalRandom.current().nextInt(1000000)); } }