|  | @@ -2,13 +2,17 @@ package com.zanxiang.game.back.serve.utils;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import com.github.sd4324530.jtuple.Tuple2;
 | 
	
		
			
				|  |  |  import com.github.sd4324530.jtuple.Tuple3;
 | 
	
		
			
				|  |  | +import com.github.sd4324530.jtuple.Tuple4;
 | 
	
		
			
				|  |  |  import com.github.sd4324530.jtuple.Tuples;
 | 
	
		
			
				|  |  | +import com.zanxiang.game.back.serve.pojo.BackPolicyOfSplitLevel;
 | 
	
		
			
				|  |  | +import com.zanxiang.game.back.serve.pojo.BackPolicyOfSumRecharge;
 | 
	
		
			
				|  |  |  import com.zanxiang.game.back.serve.pojo.entity.GameBackPolicy;
 | 
	
		
			
				|  |  |  import com.zanxiang.game.back.serve.pojo.enums.BackUnitEnum;
 | 
	
		
			
				|  |  |  import com.zanxiang.game.back.serve.pojo.vo.GameBackPolicyVO;
 | 
	
		
			
				|  |  |  import com.zanxiang.module.util.DateUtil;
 | 
	
		
			
				|  |  |  import com.zanxiang.module.util.JsonUtil;
 | 
	
		
			
				|  |  |  import com.zanxiang.module.util.NumberUtil;
 | 
	
		
			
				|  |  | +import com.zanxiang.module.util.exception.BaseException;
 | 
	
		
			
				|  |  |  import lombok.extern.slf4j.Slf4j;
 | 
	
		
			
				|  |  |  import org.apache.commons.collections4.CollectionUtils;
 | 
	
		
			
				|  |  |  import org.apache.commons.lang3.RandomUtils;
 | 
	
	
		
			
				|  | @@ -23,28 +27,205 @@ import java.util.Collections;
 | 
	
		
			
				|  |  |  import java.util.List;
 | 
	
		
			
				|  |  |  import java.util.Objects;
 | 
	
		
			
				|  |  |  import java.util.function.Function;
 | 
	
		
			
				|  |  | +import java.util.stream.Collectors;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  @Slf4j
 | 
	
		
			
				|  |  |  public class BackPolicyUtil {
 | 
	
		
			
				|  |  | -    private static final long[] RECHARGE_LEVEL = {12 * 100L, 30 * 100L, 50 * 100L, 98 * 100L, 198 * 100L, 328 * 100L, 649 * 100L, 998 * 100L, 2998 * 100L};
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    static {
 | 
	
		
			
				|  |  | -        Arrays.sort(RECHARGE_LEVEL);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 订单回传
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  |       * @return <是否回传,回传金额,回传描述>
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    public static Tuple3<Boolean, Long, String> backOrder(String orderId, GameBackPolicy gameBackPolicy,
 | 
	
		
			
				|  |  | -                                                          long rechargeMoney, boolean isFirstOrder,
 | 
	
		
			
				|  |  | -                                                          LocalDateTime payTime, LocalDateTime regTime,
 | 
	
		
			
				|  |  | -                                                          String userId, IBackPolicyCheck backPolicyCheck) {
 | 
	
		
			
				|  |  | +    public static Tuple4<Boolean, Long, String, List<Tuple2<Long, LocalDateTime>>> backOrder(String orderId, GameBackPolicy gameBackPolicy,
 | 
	
		
			
				|  |  | +                                                                                             long rechargeMoney, boolean isFirstOrder,
 | 
	
		
			
				|  |  | +                                                                                             LocalDateTime payTime, LocalDateTime regTime,
 | 
	
		
			
				|  |  | +                                                                                             String userId, IBackPolicyCheck backPolicyCheck) {
 | 
	
		
			
				|  |  |          if (null == gameBackPolicy) {
 | 
	
		
			
				|  |  |              log.error("订单 id[{}]找不到回传策略,默认回传", orderId);
 | 
	
		
			
				|  |  | -            return Tuples.tuple(Boolean.TRUE, rechargeMoney, "没有回传策略");
 | 
	
		
			
				|  |  | +            return Tuples.tuple(Boolean.TRUE, rechargeMoney, "没有回传策略", null);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (gameBackPolicy.getPolicyType() == null || Objects.equals(gameBackPolicy.getPolicyType(), GameBackPolicy.TYPE_DEFAULT)) {
 | 
	
		
			
				|  |  | +            Tuple3<Boolean, Long, String> backInfo = policyOfDefault(orderId, gameBackPolicy, rechargeMoney, isFirstOrder, payTime, regTime, userId, backPolicyCheck);
 | 
	
		
			
				|  |  | +            if (backInfo.first) {
 | 
	
		
			
				|  |  | +                Collection<GameBackPolicyVO.SplitStrategy> splitStrategyList = StringUtils.isBlank(gameBackPolicy.getSplitStrategy()) ? Collections.emptyList() : JsonUtil.toList(gameBackPolicy.getSplitStrategy(), List.class, GameBackPolicyVO.SplitStrategy.class);
 | 
	
		
			
				|  |  | +                Tuple3<Boolean, Long, List<Tuple2<Long, LocalDateTime>>> splitInfo = splitOrder(splitStrategyList, backInfo.second);
 | 
	
		
			
				|  |  | +                if (splitInfo.first) {
 | 
	
		
			
				|  |  | +                    return Tuple4.with(backInfo.first, backInfo.second, backInfo.third, splitInfo.third);
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    return Tuple4.with(backInfo.first, backInfo.second, backInfo.third, null);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                return Tuple4.with(backInfo.first, backInfo.second, backInfo.third, null);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        } else if (Objects.equals(gameBackPolicy.getPolicyType(), GameBackPolicy.TYPE_SPLIT_LEVEL)) {
 | 
	
		
			
				|  |  | +            // 按策略判断
 | 
	
		
			
				|  |  | +            BackPolicyOfSplitLevel policyOfSplitLevel = JsonUtil.toObj(gameBackPolicy.getTypeOfSplitLevelJson(), BackPolicyOfSplitLevel.class);
 | 
	
		
			
				|  |  | +            Tuple3<Boolean, Long, String> backInfo = policyOfSplitLevel(orderId, gameBackPolicy.getId(), policyOfSplitLevel, rechargeMoney, isFirstOrder, payTime, regTime, userId, backPolicyCheck);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (backInfo.first) {
 | 
	
		
			
				|  |  | +                Tuple3<Boolean, Long, List<Tuple2<Long, LocalDateTime>>> splitInfo = splitOrder(policyOfSplitLevel.getSplitStrategy(), backInfo.second);
 | 
	
		
			
				|  |  | +                if (splitInfo.first) {
 | 
	
		
			
				|  |  | +                    return Tuple4.with(backInfo.first, backInfo.second, backInfo.third, splitInfo.third);
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    return Tuple4.with(backInfo.first, backInfo.second, backInfo.third, null);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                return Tuple4.with(backInfo.first, backInfo.second, backInfo.third, null);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        } else if (Objects.equals(gameBackPolicy.getPolicyType(), GameBackPolicy.TYPE_SUM_RECHARGE)) {
 | 
	
		
			
				|  |  | +            // 按累充判断
 | 
	
		
			
				|  |  | +            BackPolicyOfSumRecharge policyOfSumRecharge = JsonUtil.toObj(gameBackPolicy.getTypeOfSumRechargeJson(), BackPolicyOfSumRecharge.class);
 | 
	
		
			
				|  |  | +            return policyOfSumRecharge(orderId, gameBackPolicy.getId(), policyOfSumRecharge, rechargeMoney, isFirstOrder, payTime, regTime, userId, backPolicyCheck);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        throw new BaseException("未知的回传策略类型:" + gameBackPolicy.getPolicyType());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 拆单逻辑
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public static Tuple3<Boolean, Long, List<Tuple2<Long, LocalDateTime>>> splitOrder(Collection<GameBackPolicyVO.SplitStrategy> splitStrategyList, Long backMoney) {
 | 
	
		
			
				|  |  | +        if (CollectionUtils.isEmpty(splitStrategyList)) {
 | 
	
		
			
				|  |  | +            return Tuple3.with(false, backMoney, null);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        GameBackPolicyVO.SplitStrategy backSplitStrategy = null;
 | 
	
		
			
				|  |  | +        for (GameBackPolicyVO.SplitStrategy splitStrategy : splitStrategyList) {
 | 
	
		
			
				|  |  | +            if (NumberUtil.multiply100(splitStrategy.getPayMoney()).longValue() == backMoney) {
 | 
	
		
			
				|  |  | +                backSplitStrategy = splitStrategy;
 | 
	
		
			
				|  |  | +                break;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (backSplitStrategy == null) {
 | 
	
		
			
				|  |  | +            return Tuple3.with(false, backMoney, null);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        List<Tuple2<Long, LocalDateTime>> result = new ArrayList<>();
 | 
	
		
			
				|  |  | +        LocalDateTime beginTime = LocalDateTime.now();
 | 
	
		
			
				|  |  | +        long sumMoney = 0L;
 | 
	
		
			
				|  |  | +        for (BigDecimal splitMoney : backSplitStrategy.getSplitList()) {
 | 
	
		
			
				|  |  | +            long money = NumberUtil.multiply100(splitMoney).longValue();
 | 
	
		
			
				|  |  | +            sumMoney += money;
 | 
	
		
			
				|  |  | +            result.add(Tuple2.with(money, beginTime));
 | 
	
		
			
				|  |  | +            int randomMinute = RandomUtils.nextInt(backSplitStrategy.getBetweenMinuteMin(), backSplitStrategy.getBetweenMinuteMax());
 | 
	
		
			
				|  |  | +            beginTime = beginTime.plusMinutes(randomMinute);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return Tuple3.with(true, sumMoney, result);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static Tuple3<Boolean, Long, String> policyOfSplitLevel(String orderId, Long policyId, BackPolicyOfSplitLevel policyOfSplitLevel,
 | 
	
		
			
				|  |  | +                                                                    long rechargeMoney, boolean isFirstOrder,
 | 
	
		
			
				|  |  | +                                                                    LocalDateTime payTime, LocalDateTime regTime,
 | 
	
		
			
				|  |  | +                                                                    String userId, IBackPolicyCheck backPolicyCheck) {
 | 
	
		
			
				|  |  | +        BigDecimal rechargeAmount = NumberUtil.divide100(new BigDecimal(rechargeMoney));
 | 
	
		
			
				|  |  | +        if (policyOfSplitLevel.getRegPayIntervalTime() != null
 | 
	
		
			
				|  |  | +                && ((DateUtil.localDateTimeToSecond(payTime) - DateUtil.localDateTimeToSecond(regTime)) / 60) > policyOfSplitLevel.getRegPayIntervalTime()) {
 | 
	
		
			
				|  |  | +            log.error("订单 id[{}]通过回传策略[{}]判断后,超过注册充值间隔时间({}),不回传", orderId, policyId, policyOfSplitLevel.getRegPayIntervalTime());
 | 
	
		
			
				|  |  | +            return Tuples.tuple(Boolean.FALSE, rechargeMoney, "超过注册充值间隔时间(" + policyOfSplitLevel.getRegPayIntervalTime() + "),不回传");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (policyOfSplitLevel.getBackCountOfUser() != null) {
 | 
	
		
			
				|  |  | +            long userBackCount = backPolicyCheck.backCountForUser(BackUnitEnum.LARGE_AMOUNT, userId, false);
 | 
	
		
			
				|  |  | +            if (userBackCount > policyOfSplitLevel.getBackCountOfUser()) {
 | 
	
		
			
				|  |  | +                return Tuples.tuple(Boolean.FALSE, rechargeMoney, "单用户最大回传 " + policyOfSplitLevel.getBackCountOfUser() + "笔,当前已回传 " + userBackCount + "笔");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        BackPolicyOfSplitLevel.RechargeLevel rechargeLevel = null;
 | 
	
		
			
				|  |  | +        for (BackPolicyOfSplitLevel.RechargeLevel item : policyOfSplitLevel.getRechargeLevelList()) {
 | 
	
		
			
				|  |  | +            if (rechargeAmount.compareTo(item.getMinAmount()) >= 0 && rechargeAmount.compareTo(item.getMaxAmount()) < 0) {
 | 
	
		
			
				|  |  | +                rechargeLevel = item;
 | 
	
		
			
				|  |  | +                break;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (rechargeLevel == null) {
 | 
	
		
			
				|  |  | +            log.error("订单 id[{}]通过回传策略[{}]判断后,找不到对应的充值挡位,不回传", orderId, policyId);
 | 
	
		
			
				|  |  | +            return Tuples.tuple(Boolean.FALSE, rechargeMoney, "充值金额(" + rechargeAmount + ")未找到对应的挡位,默认不回传");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (Objects.equals(rechargeLevel.getBackType(), GameBackPolicy.POLICY_TYPE_FIXED_RATE)) {
 | 
	
		
			
				|  |  | +            // 固定比例回传
 | 
	
		
			
				|  |  | +            String[] temp = rechargeLevel.getBackRate().split(":");
 | 
	
		
			
				|  |  | +            int backCount = Integer.parseInt(temp[0]);
 | 
	
		
			
				|  |  | +            int ignoreCount = Integer.parseInt(temp[1]);
 | 
	
		
			
				|  |  | +            if (backCount == 0) {
 | 
	
		
			
				|  |  | +                String backMsg = "按比例回传,回传比例为 0,全部不回传";
 | 
	
		
			
				|  |  | +                log.error("订单 id[{}]通过回传策略[{}]判断后,不回传,原因:{}", orderId, policyId, backMsg);
 | 
	
		
			
				|  |  | +                return Tuples.tuple(Boolean.FALSE, rechargeMoney, backMsg);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if (ignoreCount == 0) {
 | 
	
		
			
				|  |  | +                String backMsg = "按比例回传,忽略比例为 0,全部回传";
 | 
	
		
			
				|  |  | +                log.error("订单 id[{}]通过回传策略[{}]判断后,回传,原因:{}", orderId, policyId, backMsg);
 | 
	
		
			
				|  |  | +                return Tuples.tuple(Boolean.TRUE, downLevel(rechargeMoney, policyOfSplitLevel.getDownLevel()), backMsg);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            long isBackCount = backPolicyCheck.backCountForFixedRate(backCount + ignoreCount, BackUnitEnum.LARGE_AMOUNT, false);
 | 
	
		
			
				|  |  | +            String backMsg = "按比例回传,每 " + (backCount + ignoreCount) + "笔回传 " + backCount + "笔,当前第 " + (isBackCount + 1) + "笔";
 | 
	
		
			
				|  |  | +            if (isBackCount >= backCount) {
 | 
	
		
			
				|  |  | +                log.error("订单 id[{}]通过回传策略[{}]判断后,不回传,原因:{}", orderId, policyId, backMsg);
 | 
	
		
			
				|  |  | +                return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, policyOfSplitLevel.getDownLevel()), backMsg);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                log.error("订单 id[{}]通过回传策略[{}]判断后,回传,原因:{}", orderId, policyId, backMsg);
 | 
	
		
			
				|  |  | +                return Tuples.tuple(Boolean.TRUE, downLevel(rechargeMoney, policyOfSplitLevel.getDownLevel()), backMsg);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        } else if (Objects.equals(rechargeLevel.getBackType(), GameBackPolicy.POLICY_TYPE_RANDOM_RATE)) {
 | 
	
		
			
				|  |  | +            // 随机概率回传
 | 
	
		
			
				|  |  | +            boolean isBack = RandomUtils.nextInt(0, 100) < NumberUtil.multiply100(new BigDecimal(rechargeLevel.getBackRate())).intValue();
 | 
	
		
			
				|  |  | +            String backMsg = "随机概率回传(" + NumberUtil.multiply100(new BigDecimal(rechargeLevel.getBackRate())) + "%)";
 | 
	
		
			
				|  |  | +            if (!isBack) {
 | 
	
		
			
				|  |  | +                log.error("订单 id[{}]通过回传策略[{}]判断后,不回传,原因:{}", orderId, policyId, backMsg);
 | 
	
		
			
				|  |  | +                return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, policyOfSplitLevel.getDownLevel()), backMsg);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                log.error("订单 id[{}]通过回传策略[{}]判断后,回传,原因:{}", orderId, policyId, backMsg);
 | 
	
		
			
				|  |  | +                return Tuples.tuple(Boolean.TRUE, downLevel(rechargeMoney, policyOfSplitLevel.getDownLevel()), backMsg);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            throw new RuntimeException("回传策略[" + policyId + "]配置错误,未知的回传类型:" + rechargeLevel.getBackType());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static Tuple4<Boolean, Long, String, List<Tuple2<Long, LocalDateTime>>> policyOfSumRecharge(String orderId, Long policyId, BackPolicyOfSumRecharge policyOfSumRecharge,
 | 
	
		
			
				|  |  | +                                                                                                        long rechargeMoney, boolean isFirstOrder,
 | 
	
		
			
				|  |  | +                                                                                                        LocalDateTime payTime, LocalDateTime regTime,
 | 
	
		
			
				|  |  | +                                                                                                        String userId, IBackPolicyCheck backPolicyCheck) {
 | 
	
		
			
				|  |  | +        BigDecimal rechargeAmount = NumberUtil.divide100(new BigDecimal(rechargeMoney));
 | 
	
		
			
				|  |  | +        if (policyOfSumRecharge.getRegPayIntervalTime() != null
 | 
	
		
			
				|  |  | +                && ((DateUtil.localDateTimeToSecond(payTime) - DateUtil.localDateTimeToSecond(regTime)) / 60) > policyOfSumRecharge.getRegPayIntervalTime()) {
 | 
	
		
			
				|  |  | +            log.error("订单 id[{}]通过回传策略[{}]判断后,超过注册充值间隔时间({}),不回传", orderId, policyId, policyOfSumRecharge.getRegPayIntervalTime());
 | 
	
		
			
				|  |  | +            return Tuples.tuple(Boolean.FALSE, rechargeMoney, "超过注册充值间隔时间(" + policyOfSumRecharge.getRegPayIntervalTime() + "),不回传", null);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        BackPolicyOfSumRecharge.RechargeLevel rechargeLevel = null;
 | 
	
		
			
				|  |  | +        for (BackPolicyOfSumRecharge.RechargeLevel item : policyOfSumRecharge.getRechargeLevelList()) {
 | 
	
		
			
				|  |  | +            if (rechargeAmount.compareTo(item.getMinAmount()) >= 0 && rechargeAmount.compareTo(item.getMaxAmount()) < 0) {
 | 
	
		
			
				|  |  | +                rechargeLevel = item;
 | 
	
		
			
				|  |  | +                break;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (rechargeLevel == null) {
 | 
	
		
			
				|  |  | +            log.error("订单 id[{}]通过回传策略[{}]判断后,找不到对应的累充挡位,不回传", orderId, policyId);
 | 
	
		
			
				|  |  | +            return Tuples.tuple(Boolean.FALSE, rechargeMoney, "充值金额(" + rechargeAmount + ")未找到对应的挡位,默认不回传", null);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        Tuple2<Long, Long> backInfo = backPolicyCheck.backCountForUserWithSplitOrder(userId);
 | 
	
		
			
				|  |  | +        if (rechargeLevel.getBackCountOfUser() <= backInfo.first) {
 | 
	
		
			
				|  |  | +            log.error("订单 id[{}]通过回传策略[{}]判断后,已达到回传的订单数,不回传", orderId, policyId);
 | 
	
		
			
				|  |  | +            return Tuples.tuple(Boolean.FALSE, rechargeMoney, "充值金额(" + rechargeAmount + ")已达到回传的订单数(已回传:" + backInfo.first + "笔,当前挡位:" + rechargeLevel.getBackCountOfUser() + "笔),不回传", null);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        long backCount = rechargeLevel.getBackCountOfUser() - backInfo.first;
 | 
	
		
			
				|  |  | +        long backMoney = backInfo.second - NumberUtil.multiply100(rechargeLevel.getMinAmount()).longValue();
 | 
	
		
			
				|  |  | +        if (backMoney <= 0) {
 | 
	
		
			
				|  |  | +            // 最低回传一分钱
 | 
	
		
			
				|  |  | +            backMoney = 1;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        List<Tuple2<Long, LocalDateTime>> splitOrder = new ArrayList<>();
 | 
	
		
			
				|  |  | +        for (int i = 0; i < backCount; i++) {
 | 
	
		
			
				|  |  | +            splitOrder.add(Tuple2.with(backMoney, LocalDateTime.now()));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        String backMsg = "充值金额(" + rechargeAmount + ") 已回传:" + backInfo.first + "笔,当前挡位:" + rechargeLevel.getBackCountOfUser() + "笔,回传(" + backCount + "-" + backMoney + ")笔";
 | 
	
		
			
				|  |  | +        log.error("订单 id[{}]通过回传策略[{}]判断后,回传。回传日志:{}", orderId, policyId, backMsg);
 | 
	
		
			
				|  |  | +        return Tuples.tuple(Boolean.TRUE, rechargeMoney, backMsg, splitOrder);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static Tuple3<Boolean, Long, String> policyOfDefault(String orderId, GameBackPolicy gameBackPolicy,
 | 
	
		
			
				|  |  | +                                                                 long rechargeMoney, boolean isFirstOrder,
 | 
	
		
			
				|  |  | +                                                                 LocalDateTime payTime, LocalDateTime regTime,
 | 
	
		
			
				|  |  | +                                                                 String userId, IBackPolicyCheck backPolicyCheck) {
 | 
	
		
			
				|  |  |          if (gameBackPolicy.getSupperSmallAmount() != null && gameBackPolicy.getSupperSmallAmount() >= rechargeMoney) {
 | 
	
		
			
				|  |  |              log.error("订单 id[{}]被判定为超小额订单({}),默认不回传", orderId, gameBackPolicy.getSupperSmallAmount());
 | 
	
		
			
				|  |  |              return Tuples.tuple(Boolean.FALSE, rechargeMoney, "超小额订单(<=" + gameBackPolicy.getSupperSmallAmount() + "),不回传");
 | 
	
	
		
			
				|  | @@ -64,6 +245,9 @@ public class BackPolicyUtil {
 | 
	
		
			
				|  |  |                  && ((DateUtil.localDateTimeToSecond(payTime) - DateUtil.localDateTimeToSecond(regTime)) / 60) > gameBackPolicy.getRegPayIntervalTime()) {
 | 
	
		
			
				|  |  |              // 补单
 | 
	
		
			
				|  |  |              log.error("订单 id[{}]通过回传策略[{}]判断后,超过注册充值间隔时间,走补单逻辑 {}, money: {}.", orderId, gameBackPolicy.getId(), gameBackPolicy.getRegPayIntervalTime(), totalRechargeAmount);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            List<GameBackPolicyVO.PolicyDownLevel> downLevels = StringUtils.isEmpty(gameBackPolicy.getMarkUpDownLevel()) ? Collections.emptyList()
 | 
	
		
			
				|  |  | +                    : Arrays.stream(gameBackPolicy.getMarkUpDownLevel().split(",")).map(BackPolicyUtil::transformDownLevel).collect(Collectors.toList());
 | 
	
		
			
				|  |  |              if (gameBackPolicy.getMarkUpOrder() != null && gameBackPolicy.getMarkUpOrder()) {
 | 
	
		
			
				|  |  |                  long money = backUnit == BackUnitEnum.LARGE_AMOUNT ? totalRechargeAmount : rechargeMoney;
 | 
	
		
			
				|  |  |                  markUpTime = gameBackPolicy.getRegPayIntervalTime();
 | 
	
	
		
			
				|  | @@ -87,17 +271,17 @@ public class BackPolicyUtil {
 | 
	
		
			
				|  |  |                      int ignoreCount = Integer.parseInt(temp[1]);
 | 
	
		
			
				|  |  |                      if (backCount == 0) {
 | 
	
		
			
				|  |  |                          log.error("订单 id[{}]通过回传策略[{}]判断后,不回传,原因:回传比例 {}", orderId, gameBackPolicy.getId(), backRate);
 | 
	
		
			
				|  |  | -                        return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, gameBackPolicy.getMarkUpDownLevel()), "补单-按比例回传,回传比例为 0,全部不回传");
 | 
	
		
			
				|  |  | +                        return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, downLevels), "补单-按比例回传,回传比例为 0,全部不回传");
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                      if (ignoreCount == 0) {
 | 
	
		
			
				|  |  |                          log.error("订单 id[{}]通过回传策略[{}]判断后,回传,原因:回传比例 {}", orderId, gameBackPolicy.getId(), backRate);
 | 
	
		
			
				|  |  | -                        return Tuples.tuple(Boolean.TRUE, downLevel(rechargeMoney, gameBackPolicy.getMarkUpDownLevel()), "补单-按比例回传,忽略比例为 0,全部回传");
 | 
	
		
			
				|  |  | +                        return Tuples.tuple(Boolean.TRUE, downLevel(rechargeMoney, downLevels), "补单-按比例回传,忽略比例为 0,全部回传");
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                      long isBackCount = backPolicyCheck.markUpOfFixedRate(backCount + ignoreCount, markUpTime);
 | 
	
		
			
				|  |  |                      backMsg = "补单-按比例回传,每 " + (backCount + ignoreCount) + "笔回传 " + backCount + "笔,当前第 " + (isBackCount + 1) + "笔";
 | 
	
		
			
				|  |  |                      if (isBackCount >= backCount) {
 | 
	
		
			
				|  |  |                          log.error("订单 id[{}]通过回传策略[{}]判断后,不回传,原因:{}", orderId, gameBackPolicy.getId(), backMsg);
 | 
	
		
			
				|  |  | -                        return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, gameBackPolicy.getMarkUpDownLevel()), backMsg);
 | 
	
		
			
				|  |  | +                        return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, downLevels), backMsg);
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  } else if (Objects.equals(backType, GameBackPolicy.POLICY_TYPE_RANDOM_RATE)) {
 | 
	
		
			
				|  |  |                      // 随机概率回传
 | 
	
	
		
			
				|  | @@ -105,22 +289,22 @@ public class BackPolicyUtil {
 | 
	
		
			
				|  |  |                      backMsg = "补单-随机概率回传(" + NumberUtil.multiply100(new BigDecimal(backRate)) + "%)";
 | 
	
		
			
				|  |  |                      if (!isBack) {
 | 
	
		
			
				|  |  |                          log.error("订单 id[{}]通过回传策略[{}]判断后,不回传,原因:{}", orderId, gameBackPolicy.getId(), backMsg);
 | 
	
		
			
				|  |  | -                        return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, gameBackPolicy.getMarkUpDownLevel()), backMsg);
 | 
	
		
			
				|  |  | +                        return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, downLevels), backMsg);
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  } else {
 | 
	
		
			
				|  |  |                      throw new RuntimeException("回传策略[" + gameBackPolicy.getId() + "]配置错误,未知的回传类型:" + backType);
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  if (gameBackPolicy.getMarkUpBackCountOfUser() == null) {
 | 
	
		
			
				|  |  |                      log.error("订单 id[{}]通过回传策略[{}]判断后,回传,原因:回传概率 {}", orderId, gameBackPolicy.getId(), backMsg);
 | 
	
		
			
				|  |  | -                    return Tuples.tuple(Boolean.TRUE, downLevel(rechargeMoney, gameBackPolicy.getMarkUpDownLevel()), backMsg);
 | 
	
		
			
				|  |  | +                    return Tuples.tuple(Boolean.TRUE, downLevel(rechargeMoney, downLevels), backMsg);
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  long userBackCount = backPolicyCheck.markUpForUser(userId, markUpTime);
 | 
	
		
			
				|  |  |                  backMsg = backMsg + ",单用户最大回传 " + gameBackPolicy.getMarkUpBackCountOfUser() + "笔,当前已回传 " + userBackCount + "笔";
 | 
	
		
			
				|  |  |                  log.error("订单 id[{}]通过回传策略[{}]判断后,是否回传:{},原因:{}", orderId, gameBackPolicy.getId(), userBackCount < gameBackPolicy.getMarkUpBackCountOfUser(), backMsg);
 | 
	
		
			
				|  |  | -                return Tuples.tuple(userBackCount < gameBackPolicy.getMarkUpBackCountOfUser(), downLevel(rechargeMoney, gameBackPolicy.getMarkUpDownLevel()), backMsg);
 | 
	
		
			
				|  |  | +                return Tuples.tuple(userBackCount < gameBackPolicy.getMarkUpBackCountOfUser(), downLevel(rechargeMoney, downLevels), backMsg);
 | 
	
		
			
				|  |  |              } else {
 | 
	
		
			
				|  |  |                  log.error("订单 id[{}]通过回传策略[{}]判断后,不回传,原因:超过注册充值间隔时间但是未开启补单", orderId, gameBackPolicy.getId());
 | 
	
		
			
				|  |  | -                return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, gameBackPolicy.getMarkUpDownLevel()), "补单-未开启补单");
 | 
	
		
			
				|  |  | +                return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, downLevels), "补单-未开启补单");
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -176,6 +360,8 @@ public class BackPolicyUtil {
 | 
	
		
			
				|  |  |          Integer maxBackCountOfUser = firstPolicy ? gameBackPolicy.getFirstBackCountOfUser() : gameBackPolicy.getRechargeBackCountOfUser();
 | 
	
		
			
				|  |  |          String backMsg = firstPolicy ? "首-" : "次-";
 | 
	
		
			
				|  |  |          String downLevelString = firstPolicy ? gameBackPolicy.getFirstDownLevel() : gameBackPolicy.getRechargeDownLevel();
 | 
	
		
			
				|  |  | +        List<GameBackPolicyVO.PolicyDownLevel> downLevels = StringUtils.isEmpty(downLevelString) ? Collections.emptyList()
 | 
	
		
			
				|  |  | +                : Arrays.stream(downLevelString.split(",")).map(BackPolicyUtil::transformDownLevel).collect(Collectors.toList());
 | 
	
		
			
				|  |  |          if (Objects.equals(backType, GameBackPolicy.POLICY_TYPE_FIXED_RATE)) {
 | 
	
		
			
				|  |  |              // 固定比例回传
 | 
	
		
			
				|  |  |              String[] temp = backRate.split(":");
 | 
	
	
		
			
				|  | @@ -184,18 +370,18 @@ public class BackPolicyUtil {
 | 
	
		
			
				|  |  |              if (backCount == 0) {
 | 
	
		
			
				|  |  |                  backMsg = backMsg + "按比例回传,回传比例为 0,全部不回传";
 | 
	
		
			
				|  |  |                  log.error("订单 id[{}]通过回传策略[{}]判断后,不回传,原因:{}", orderId, gameBackPolicy.getId(), backMsg);
 | 
	
		
			
				|  |  | -                return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, downLevelString), backMsg);
 | 
	
		
			
				|  |  | +                return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, downLevels), backMsg);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              if (ignoreCount == 0) {
 | 
	
		
			
				|  |  |                  backMsg = backMsg + "按比例回传,忽略比例为 0,全部回传";
 | 
	
		
			
				|  |  |                  log.error("订单 id[{}]通过回传策略[{}]判断后,回传,原因:{}", orderId, gameBackPolicy.getId(), backMsg);
 | 
	
		
			
				|  |  | -                return Tuples.tuple(Boolean.TRUE, downLevel(rechargeMoney, downLevelString), backMsg);
 | 
	
		
			
				|  |  | +                return Tuples.tuple(Boolean.TRUE, downLevel(rechargeMoney, downLevels), backMsg);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              long isBackCount = backPolicyCheck.backCountForFixedRate(backCount + ignoreCount, backUnit, firstPolicy);
 | 
	
		
			
				|  |  |              backMsg = backMsg + "按比例回传,每 " + (backCount + ignoreCount) + "笔回传 " + backCount + "笔,当前第 " + (isBackCount + 1) + "笔";
 | 
	
		
			
				|  |  |              if (isBackCount >= backCount) {
 | 
	
		
			
				|  |  |                  log.error("订单 id[{}]通过回传策略[{}]判断后,不回传,原因:{}", orderId, gameBackPolicy.getId(), backMsg);
 | 
	
		
			
				|  |  | -                return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, downLevelString), backMsg);
 | 
	
		
			
				|  |  | +                return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, downLevels), backMsg);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          } else if (Objects.equals(backType, GameBackPolicy.POLICY_TYPE_RANDOM_RATE)) {
 | 
	
		
			
				|  |  |              // 随机概率回传
 | 
	
	
		
			
				|  | @@ -203,7 +389,7 @@ public class BackPolicyUtil {
 | 
	
		
			
				|  |  |              backMsg = backMsg + "随机概率回传(" + NumberUtil.multiply100(new BigDecimal(backRate)) + "%)";
 | 
	
		
			
				|  |  |              if (!isBack) {
 | 
	
		
			
				|  |  |                  log.error("订单 id[{}]通过回传策略[{}]判断后,不回传,原因:{}", orderId, gameBackPolicy.getId(), backMsg);
 | 
	
		
			
				|  |  | -                return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, downLevelString), backMsg);
 | 
	
		
			
				|  |  | +                return Tuples.tuple(Boolean.FALSE, downLevel(rechargeMoney, downLevels), backMsg);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          } else {
 | 
	
		
			
				|  |  |              throw new RuntimeException("回传策略[" + gameBackPolicy.getId() + "]配置错误,未知的回传类型:" + backType);
 | 
	
	
		
			
				|  | @@ -211,100 +397,34 @@ public class BackPolicyUtil {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          if (maxBackCountOfUser == null) {
 | 
	
		
			
				|  |  |              log.error("订单 id[{}]通过回传策略[{}]判断后,回传,原因:回传概率 {}", orderId, gameBackPolicy.getId(), backMsg);
 | 
	
		
			
				|  |  | -            return Tuples.tuple(Boolean.TRUE, downLevel(rechargeMoney, downLevelString), backMsg);
 | 
	
		
			
				|  |  | +            return Tuples.tuple(Boolean.TRUE, downLevel(rechargeMoney, downLevels), backMsg);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          long userBackCount = backPolicyCheck.backCountForUser(backUnit, userId, firstPolicy);
 | 
	
		
			
				|  |  |          backMsg = backMsg + ",单用户最大回传 " + maxBackCountOfUser + "笔,当前已回传 " + userBackCount + "笔";
 | 
	
		
			
				|  |  |          log.error("订单 id[{}]通过回传策略[{}]判断后,是否回传:{},原因:{}", orderId, gameBackPolicy.getId(), userBackCount < maxBackCountOfUser, backMsg);
 | 
	
		
			
				|  |  | -        return Tuples.tuple(userBackCount < maxBackCountOfUser, downLevel(rechargeMoney, downLevelString), backMsg);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /**
 | 
	
		
			
				|  |  | -     * 拆单逻辑
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    public static Tuple3<Boolean, Long, List<Tuple2<Long, LocalDateTime>>> splitOrder(GameBackPolicy gameBackPolicy, Long backMoney) {
 | 
	
		
			
				|  |  | -        if (gameBackPolicy == null || StringUtils.isBlank(gameBackPolicy.getSplitStrategy())) {
 | 
	
		
			
				|  |  | -            return Tuple3.with(false, backMoney, null);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        Collection<GameBackPolicyVO.SplitStrategy> splitStrategyList = JsonUtil.toList(gameBackPolicy.getSplitStrategy(), List.class, GameBackPolicyVO.SplitStrategy.class);
 | 
	
		
			
				|  |  | -        if (CollectionUtils.isEmpty(splitStrategyList)) {
 | 
	
		
			
				|  |  | -            return Tuple3.with(false, backMoney, null);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        GameBackPolicyVO.SplitStrategy backSplitStrategy = null;
 | 
	
		
			
				|  |  | -        for (GameBackPolicyVO.SplitStrategy splitStrategy : splitStrategyList) {
 | 
	
		
			
				|  |  | -            if (NumberUtil.multiply100(splitStrategy.getPayMoney()).longValue() == backMoney) {
 | 
	
		
			
				|  |  | -                backSplitStrategy = splitStrategy;
 | 
	
		
			
				|  |  | -                break;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        if (backSplitStrategy == null) {
 | 
	
		
			
				|  |  | -            return Tuple3.with(false, backMoney, null);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        List<Tuple2<Long, LocalDateTime>> result = new ArrayList<>();
 | 
	
		
			
				|  |  | -        LocalDateTime beginTime = LocalDateTime.now();
 | 
	
		
			
				|  |  | -        long sumMoney = 0L;
 | 
	
		
			
				|  |  | -        for (BigDecimal splitMoney : backSplitStrategy.getSplitList()) {
 | 
	
		
			
				|  |  | -            long money = NumberUtil.multiply100(splitMoney).longValue();
 | 
	
		
			
				|  |  | -            sumMoney += money;
 | 
	
		
			
				|  |  | -            result.add(Tuple2.with(money, beginTime));
 | 
	
		
			
				|  |  | -            int randomMinute = RandomUtils.nextInt(backSplitStrategy.getBetweenMinuteMin(), backSplitStrategy.getBetweenMinuteMax());
 | 
	
		
			
				|  |  | -            beginTime = beginTime.plusMinutes(randomMinute);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        return Tuple3.with(true, sumMoney, result);
 | 
	
		
			
				|  |  | +        return Tuples.tuple(userBackCount < maxBackCountOfUser, downLevel(rechargeMoney, downLevels), backMsg);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private static Long downLevel(Long rechargeMoney, String downLevelStr) {
 | 
	
		
			
				|  |  | -        if (StringUtils.isBlank(downLevelStr)) {
 | 
	
		
			
				|  |  | +    private static Long downLevel(Long rechargeMoney, List<GameBackPolicyVO.PolicyDownLevel> downLevels) {
 | 
	
		
			
				|  |  | +        if (CollectionUtils.isEmpty(downLevels)) {
 | 
	
		
			
				|  |  |              return rechargeMoney;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        String[] downLevelList = downLevelStr.split(",");
 | 
	
		
			
				|  |  | -        for (String downLevel : downLevelList) {
 | 
	
		
			
				|  |  | -            String[] tmp = downLevel.split("_");
 | 
	
		
			
				|  |  | -            long minMoney = Long.parseLong(tmp[0]);
 | 
	
		
			
				|  |  | -            long maxMoney = Long.parseLong(tmp[1]);
 | 
	
		
			
				|  |  | -            Long backMoney = Long.parseLong(tmp[2]);
 | 
	
		
			
				|  |  | -            if (rechargeMoney >= minMoney && rechargeMoney <= maxMoney) {
 | 
	
		
			
				|  |  | -                return backMoney;
 | 
	
		
			
				|  |  | +        BigDecimal rechargeAmount = NumberUtil.divide100(new BigDecimal(rechargeMoney));
 | 
	
		
			
				|  |  | +        for (GameBackPolicyVO.PolicyDownLevel downLevel : downLevels) {
 | 
	
		
			
				|  |  | +            if (rechargeAmount.compareTo(downLevel.getMinMoney()) >= 0 && rechargeAmount.compareTo(downLevel.getMaxMoney()) <= 0) {
 | 
	
		
			
				|  |  | +                return NumberUtil.multiply100(downLevel.getBackMoney()).longValue();
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          return rechargeMoney;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private static Tuple2<Integer, Integer> approximate(int molecular, int denominator) {
 | 
	
		
			
				|  |  | -        if (molecular % denominator == 0) {
 | 
	
		
			
				|  |  | -            int temp = molecular / denominator;
 | 
	
		
			
				|  |  | -            return Tuples.tuple(temp, temp);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        int model = 2;
 | 
	
		
			
				|  |  | -        do {
 | 
	
		
			
				|  |  | -            if (molecular % model == 0 && denominator % model == 0) {
 | 
	
		
			
				|  |  | -                molecular = molecular / model;
 | 
	
		
			
				|  |  | -                denominator = denominator / model;
 | 
	
		
			
				|  |  | -                continue;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            model++;
 | 
	
		
			
				|  |  | -        } while (model <= denominator / 2);
 | 
	
		
			
				|  |  | -        return Tuples.tuple(molecular, denominator);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /**
 | 
	
		
			
				|  |  | -     * 降档
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    public static long lowRechargeLevel(long rechargeMoney, String levelDownStr) {
 | 
	
		
			
				|  |  | -        if (StringUtils.isBlank(levelDownStr)) {
 | 
	
		
			
				|  |  | -            // 无需降档
 | 
	
		
			
				|  |  | -            return rechargeMoney;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        String[] levelDownStrList = levelDownStr.split(",");
 | 
	
		
			
				|  |  | -        for (String levelDown : levelDownStrList) {
 | 
	
		
			
				|  |  | -            String[] tmp = levelDown.split("_");
 | 
	
		
			
				|  |  | -            long min = Long.parseLong(tmp[0]), max = Long.parseLong(tmp[1]), back = Long.parseLong(tmp[2]);
 | 
	
		
			
				|  |  | -            if (rechargeMoney >= min && rechargeMoney <= max) {
 | 
	
		
			
				|  |  | -                return back;
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        // 没有匹配金额规则,直接返回
 | 
	
		
			
				|  |  | -        return rechargeMoney;
 | 
	
		
			
				|  |  | +    private static GameBackPolicyVO.PolicyDownLevel transformDownLevel(String downLevel) {
 | 
	
		
			
				|  |  | +        String[] tmp = downLevel.split("_");
 | 
	
		
			
				|  |  | +        return GameBackPolicyVO.PolicyDownLevel.builder()
 | 
	
		
			
				|  |  | +                .minMoney(NumberUtil.divide100(new BigDecimal(Long.parseLong(tmp[0]))))
 | 
	
		
			
				|  |  | +                .maxMoney(NumberUtil.divide100(new BigDecimal(Long.parseLong(tmp[1]))))
 | 
	
		
			
				|  |  | +                .backMoney(NumberUtil.divide100(new BigDecimal(Long.parseLong(tmp[2]))))
 | 
	
		
			
				|  |  | +                .build();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public interface IBackPolicyCheck {
 | 
	
	
		
			
				|  | @@ -332,5 +452,13 @@ public class BackPolicyUtil {
 | 
	
		
			
				|  |  |           * 获取用户的累充金额
 | 
	
		
			
				|  |  |           */
 | 
	
		
			
				|  |  |          Long totalRechargeAmount();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        /**
 | 
	
		
			
				|  |  | +         * 单个用户已回传订单数(包含拆单的订单数)
 | 
	
		
			
				|  |  | +         * Tuple2<回传订单数、回传金额>
 | 
	
		
			
				|  |  | +         */
 | 
	
		
			
				|  |  | +        default Tuple2<Long, Long> backCountForUserWithSplitOrder(String userId) {
 | 
	
		
			
				|  |  | +            throw new RuntimeException("暂不支持!!");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |