diff --git a/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/dto/lucky/Lucky24GiftConfig.java b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/dto/lucky/Lucky24GiftConfig.java index 9c6037076..7005bc508 100644 --- a/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/dto/lucky/Lucky24GiftConfig.java +++ b/accompany-business/accompany-business-sdk/src/main/java/com/accompany/business/dto/lucky/Lucky24GiftConfig.java @@ -77,13 +77,9 @@ public class Lucky24GiftConfig { private Integer dayCountLimit; private List timesJudgeArray; - private Map userRechargeLevelJudgeConfigMap; + // 今天avg(input)-三天内sum(input)-三天内productionRatio-drawMultiple + private TreeMap>> judgeConfig; - @Data - public static class UserRechargeLevelJudgeConfig{ - private int historyTimes; - private TreeMap productionRatioMultipleMap; - } } } diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/lucky/Lucky24ExtraService.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/lucky/Lucky24ExtraService.java index 4f67d0a2b..620a52548 100644 --- a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/lucky/Lucky24ExtraService.java +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/lucky/Lucky24ExtraService.java @@ -2,18 +2,13 @@ package com.accompany.business.service.lucky; import com.accompany.business.constant.Lucky24PoolTypeEnum; import com.accompany.business.dto.lucky.Lucky24GiftConfig; -import com.accompany.business.dto.lucky.Lucky24Result; import com.accompany.business.model.Gift; import com.accompany.common.utils.DateTimeUtil; -import com.accompany.common.utils.RandomUtil; import com.accompany.core.enumeration.PartitionEnum; import com.accompany.core.model.Room; -import com.accompany.payment.service.UserRechargeLevelService; import com.accompany.sharding.model.Lucky24Record; import com.accompany.sharding.vo.Lucky24StockResultVo; -import com.alibaba.fastjson2.JSON; import lombok.extern.slf4j.Slf4j; -import org.redisson.api.RList; import org.redisson.api.RMap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -23,6 +18,8 @@ import java.math.RoundingMode; import java.time.ZonedDateTime; import java.util.*; +import static com.accompany.business.service.lucky.Lucky24UserMetaService.*; + @Slf4j @Service public class Lucky24ExtraService { @@ -30,8 +27,6 @@ public class Lucky24ExtraService { @Autowired private Lucky24ExtraStockService stockService; @Autowired - private UserRechargeLevelService userRechargeLevelService; - @Autowired private Lucky24UserMetaService userMetaService; @Autowired private Lucky24RobotMsgService robotMsgService; @@ -61,7 +56,7 @@ public class Lucky24ExtraService { return null; } - String todayTimesKey = String.join("_", today, Lucky24UserMetaService.TIMES_KEY); + String todayTimesKey = String.join("_", today, TIMES_KEY); long todayTimes = userMetaSnapshot.getOrDefault(todayTimesKey, 0L).longValue(); List timesJudgeList = extraPoolConfig.getTimesJudgeArray(); @@ -123,25 +118,61 @@ public class Lucky24ExtraService { public Lucky24Record randomExtraRecord(Lucky24GiftConfig config, Lucky24GiftConfig.Lucky24ExtraPoolConfig extraPoolConfig, long senderUid, Integer partitionId, Long receiverUid, Gift gift, int giftNum, long everyoneGoldNum, Room room, Date sendGiftTime) { - String userRechargeLevel = userRechargeLevelService.getLevelByUid(senderUid); - Lucky24GiftConfig.Lucky24ExtraPoolConfig.UserRechargeLevelJudgeConfig judgeConfig = extraPoolConfig.getUserRechargeLevelJudgeConfigMap().get(userRechargeLevel); + Map userMetaMapSnapshot = userMetaService.getUserMeta(senderUid).readAllMap(); - RList historyQueue = userMetaService.getUserHistoryQueue(senderUid); - int historySize = historyQueue.size(); - int num = Math.min(historySize, judgeConfig.getHistoryTimes()); - List historyResultList = historyQueue.range(num); + PartitionEnum partitionEnum = PartitionEnum.getByPartitionId(partitionId); + long todayStartTimeLong = DateTimeUtil.getZonedTodayTime(partitionEnum.getZoneId()); - BigDecimal totalInput = historyResultList.stream().map(Lucky24Result::getInput).map(BigDecimal::valueOf).reduce(BigDecimal.ZERO, BigDecimal::add); - BigDecimal totalOutput = historyResultList.stream().map(Lucky24Result::getOutput).map(BigDecimal::valueOf).reduce(BigDecimal.ZERO, BigDecimal::add); - BigDecimal totalProductionRatio = totalOutput.compareTo(BigDecimal.ZERO) <= 0 || totalInput.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO: - totalOutput.divide(totalInput, 4, RoundingMode.HALF_UP); + String today = String.valueOf(todayStartTimeLong); + String todayTimesKey = String.join("_", today, TIMES_KEY); + long todayTimes = userMetaMapSnapshot.getOrDefault(todayTimesKey, 0L).longValue(); + String todayInputKey = String.join("_", today, INPUT_KEY); + long todayInput = userMetaMapSnapshot.getOrDefault(todayInputKey, 0L).longValue(); + String todayOutputKey = String.join("_", today, INPUT_KEY); + long todayOutput = userMetaMapSnapshot.getOrDefault(todayOutputKey, 0L).longValue(); - //nullable - Map.Entry drawMultipleEntry = judgeConfig.getProductionRatioMultipleMap().ceilingEntry(totalProductionRatio); - int drawMultiple = drawMultipleEntry == null ? 0: drawMultipleEntry.getValue(); + // 第一层 + // 今天avg(input) + BigDecimal todayAvgInput = todayInput <= 0L? BigDecimal.ZERO: + BigDecimal.valueOf(todayInput).divide(BigDecimal.valueOf(todayTimes), 4, RoundingMode.HALF_UP); - log.info("[lucky24] extra randomExtra uid {} partitionId {} totalInput {} totalOutput {} totalProductionRatio {} drawMultipleEntry {} drawMultiple {}", - senderUid, partitionId, totalInput, totalOutput, totalProductionRatio, drawMultipleEntry, drawMultiple); + // ceiling返回大于或等于 key 的最小键值对 + Map.Entry>> inputJudgeEntry = extraPoolConfig.getJudgeConfig().ceilingEntry(todayAvgInput); + TreeMap> inputJudgeMap = inputJudgeEntry.getValue(); + + log.info("[lucky24] extra randomExtra first uid {} partitionId {} todayInput {} todayTimes {} todayAvgInput {} ceilingKey {}", + senderUid, partitionId, todayInput, todayTimes, todayAvgInput.toPlainString(), inputJudgeEntry.getKey()); + + // 第二层 + // 三天内sum(input) + + String twoDayAgoInputKey = String.join("_", INPUT_KEY, TWO_DAY_AGO); + long twoDayAgoInput = userMetaMapSnapshot.getOrDefault(twoDayAgoInputKey, 0L).longValue(); + long threeDayAgoInput = todayInput + twoDayAgoInput; + + // floor返回小于或等于 key 的最大键值对 + Map.Entry> threeDayAgoInputEntry = inputJudgeMap.floorEntry(threeDayAgoInput); + TreeMap threeDayAgoInputMap = threeDayAgoInputEntry.getValue(); + + log.info("[lucky24] extra randomExtra second uid {} partitionId {} todayInput {} twoDayAgoInput {} threeDayAgoInput {} floorKey {}", + senderUid, partitionId, todayInput, twoDayAgoInput, threeDayAgoInput, threeDayAgoInputEntry.getKey()); + + // 第三层 + // 三天内productionRation + + String twoDayAgoOutputKey = String.join("_", OUTPUT_KEY, TWO_DAY_AGO); + long twoDayAgoOutput = userMetaMapSnapshot.getOrDefault(twoDayAgoOutputKey, 0L).longValue(); + long threeDayAgoOutput = todayOutput + twoDayAgoOutput; + + BigDecimal threeDayProductionRatio = threeDayAgoOutput <= 0L || threeDayAgoInput <= 0 ? BigDecimal.ZERO: + BigDecimal.valueOf(threeDayAgoOutput).divide(BigDecimal.valueOf(threeDayAgoInput), 4, RoundingMode.HALF_UP); + + // floor返回小于或等于 key 的最大键值对 + Map.Entry threeDayProductionRatioEntry = threeDayAgoInputMap.floorEntry(threeDayProductionRatio); + int drawMultiple = threeDayProductionRatioEntry.getValue(); + + log.info("[lucky24] extra randomExtra uid {} partitionId {} todayOutput {} twoDayAgoOutput {} threeDayAgoOutput {} threeDayAgoInput {} productionRation {} floorKey {} result {}", + senderUid, partitionId, todayOutput, twoDayAgoOutput, threeDayAgoOutput, threeDayAgoInput, threeDayProductionRatio.toPlainString(), threeDayAgoInputEntry.getKey(), drawMultiple); long afterMultiple = drawMultiple; diff --git a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/lucky/Lucky24UserMetaService.java b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/lucky/Lucky24UserMetaService.java index 10e95edb9..a134a49df 100644 --- a/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/lucky/Lucky24UserMetaService.java +++ b/accompany-business/accompany-business-service/src/main/java/com/accompany/business/service/lucky/Lucky24UserMetaService.java @@ -28,7 +28,7 @@ public class Lucky24UserMetaService { public static final String OUTPUT_KEY = "output"; private static final String TODAY = "today"; - private static final String TWO_DAY_AGO = "two_day_ago"; + public static final String TWO_DAY_AGO = "two_day_ago"; public static final String EXTRA_POOL_COUNT = "extra_pool_count"; @@ -151,13 +151,15 @@ public class Lucky24UserMetaService { long todayStartTimeLong = DateTimeUtil.getZonedTodayTime(partitionEnum.getZoneId()); String today = String.valueOf(todayStartTimeLong); + String todayTimesKey = String.join("_", today, TIMES_KEY); + long todayTimes = userMetaMap.addAndGet(todayTimesKey, 1L).longValue(); String todayInputKey = String.join("_", today, INPUT_KEY); long todayInput = userMetaMap.addAndGet(todayInputKey, input).longValue(); String todayOutputKey = String.join("_", today, OUTPUT_KEY); long todayOutput = userMetaMap.addAndGet(todayOutputKey, output).longValue(); - log.info("[Lucky24] updateExtraUserMeta uid {} times {} today {} todayInput {} todayOutput {}", - senderUid, times, todayStartTimeLong, todayInput, todayOutput); + log.info("[Lucky24] updateExtraUserMeta uid {} times {} today {} todayTime {} todayInput {} todayOutput {}", + senderUid, times, todayStartTimeLong, todayTimes, todayInput, todayOutput); } public void updateUserMeta(long senderUid, int partitionId, long input, long output) {