Browse Source

重归因问题

wcc 1 year ago
parent
commit
194a4c1d78

+ 235 - 206
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameOceanengineOrderLogServiceImpl.java

@@ -68,7 +68,7 @@ public class GameOceanengineOrderLogServiceImpl extends ServiceImpl<GameOceaneng
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean callback(GameOceanengineOrderLog orderLog, boolean mustBack, Long backMoneyOfInput) {
-        boolean doBack = false;
+        boolean doBack;
         Long backMoney;
         String backMsg;
         if (mustBack) {
@@ -80,203 +80,26 @@ public class GameOceanengineOrderLogServiceImpl extends ServiceImpl<GameOceaneng
                 // 头条只要回传支付订单
                 return true;
             }
-            GameBackPolicy gameBackPolicy = gameBackPolicyService.getById(orderLog.getBackPolicyId());
-            Tuple3<Boolean, Long, String> backInfo = BackPolicyUtil.backOrder(orderLog.getOrderNo(), gameBackPolicy, orderLog.getAmount(),
-                    orderLog.getIsFirstOrder(),
-                    orderLog.getPayTime(), orderLog.getRegTime(),
-                    orderLog.getOpenId(),
-                    new BackPolicyUtil.IBackPolicyCheck() {
-                        @Override
-                        public long backCountForFixedRate(int numberOfRound, BackUnitEnum backUnit, Boolean firstPolicy) {
-                            numberOfRound = numberOfRound - 1;
-                            if (backUnit == BackUnitEnum.UNIT_ONCE) {
-                                return list(new LambdaQueryWrapper<GameOceanengineOrderLog>()
-                                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameOceanengineOrderLog::getIsFirstOrder, firstPolicy)
-                                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                                        .orderByDesc(GameOceanengineOrderLog::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
-                                return list(new LambdaQueryWrapper<GameOceanengineOrderLog>()
-                                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .apply(firstPolicy, "date(reg_time) = date(pay_time)")
-                                        .apply(!firstPolicy, "date(reg_time) != date(pay_time)")
-                                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                                        .orderByDesc(GameOceanengineOrderLog::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
-                                return list(new LambdaQueryWrapper<GameOceanengineOrderLog>()
-                                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) < 24")
-                                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) >= 24")
-                                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                                        .orderByDesc(GameOceanengineOrderLog::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
-                                return list(new LambdaQueryWrapper<GameOceanengineOrderLog>()
-                                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) < 48")
-                                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) >= 48")
-                                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                                        .orderByDesc(GameOceanengineOrderLog::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
-                                return list(new LambdaQueryWrapper<GameOceanengineOrderLog>()
-                                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                                        .orderByDesc(GameOceanengineOrderLog::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else {
-                                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
-                            }
-                        }
-
-                        @Override
-                        public long backCountForUser(BackUnitEnum backUnit, String userId, Boolean firstPolicy) {
-                            if (backUnit == BackUnitEnum.UNIT_ONCE) {
-                                if (firstPolicy) {
-                                    // 首单直接返回 0,必定回传
-                                    return 0;
-                                }
-                                return count(new LambdaQueryWrapper<GameOceanengineOrderLog>()
-                                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameOceanengineOrderLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameOceanengineOrderLog::getOpenId, userId)
-                                        .eq(GameOceanengineOrderLog::getIsFirstOrder, firstPolicy)
-                                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                                );
-                            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
-                                return count(new LambdaQueryWrapper<GameOceanengineOrderLog>()
-                                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameOceanengineOrderLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameOceanengineOrderLog::getOpenId, userId)
-                                        .apply(firstPolicy, "date(reg_time) = date(pay_time)")
-                                        .apply(!firstPolicy, "date(reg_time) != date(pay_time)")
-                                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                                );
-                            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
-                                return count(new LambdaQueryWrapper<GameOceanengineOrderLog>()
-                                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameOceanengineOrderLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameOceanengineOrderLog::getOpenId, userId)
-                                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) < 24")
-                                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) >= 24")
-                                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                                );
-                            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
-                                return count(new LambdaQueryWrapper<GameOceanengineOrderLog>()
-                                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameOceanengineOrderLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameOceanengineOrderLog::getOpenId, userId)
-                                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) < 48")
-                                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) >= 48")
-                                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                                );
-                            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
-                                return count(new LambdaQueryWrapper<GameOceanengineOrderLog>()
-                                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameOceanengineOrderLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameOceanengineOrderLog::getOpenId, userId)
-                                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                                );
-                            } else {
-                                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
-                            }
-                        }
-
-                        @Override
-                        public long markUpOfFixedRate(int numberOfRound, Long markUpTime) {
-                            numberOfRound = numberOfRound - 1;
-                            return list(new LambdaQueryWrapper<GameOceanengineOrderLog>()
-                                    .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                    .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                    .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                    .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                    .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                    .apply("TIMESTAMPDIFF(MINUTE, reg_time, pay_time) > {0}", markUpTime)
-                                    .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                                    .orderByDesc(GameOceanengineOrderLog::getCreateTime)
-                                    .last("limit " + numberOfRound)
-                            ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                        }
-
-                        @Override
-                        public long markUpForUser(String userId, Long markUpTime) {
-                            return count(new LambdaQueryWrapper<GameOceanengineOrderLog>()
-                                    .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                    .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                    .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                    .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                    .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                    .eq(GameOceanengineOrderLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                                    .eq(GameOceanengineOrderLog::getOpenId, userId)
-                                    .apply("TIMESTAMPDIFF(MINUTE, reg_time, pay_time) > {0}", markUpTime)
-                                    .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                            );
-                        }
-
-                        @Override
-                        public Long totalRechargeAmount() {
-                            return getOne(new QueryWrapper<GameOceanengineOrderLog>()
-                                    .select("ifnull(sum(amount), 0) as amount").lambda()
-                                    .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
-                                    .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
-                                    .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
-                                    .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
-                                    .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                    .eq(GameOceanengineOrderLog::getOpenId, orderLog.getOpenId())
-                                    .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
-                            ).getAmount();
-                        }
-                    });
-            doBack = backInfo.first;
-            backMoney = backInfo.second;
-            backMsg = backInfo.third;
+            // 用户回传失败
+            GameOceanengineUserLog userLog = userLog(orderLog);
+            if (userLog == null) {
+                doBack = false;
+                backMoney = orderLog.getAmount();
+                backMsg = "回传失败!找不到回传用户";
+            } else {
+                GameBackPolicy gameBackPolicy = gameBackPolicyService.getById(orderLog.getBackPolicyId());
+                Tuple3<Boolean, Long, String> backInfo = BackPolicyUtil.backOrder(orderLog.getOrderNo(), gameBackPolicy, orderLog.getAmount(),
+                        orderLog.getIsFirstOrder(),
+                        orderLog.getPayTime(),
+                        // 此处使用用户最近一次的重新染色时间
+                        userLog.getCreateTime(),
+                        orderLog.getOpenId(),
+                        new OceanengineOrderBackPolicyCheck(this, userLog, orderLog, gameBackPolicy)
+                );
+                doBack = backInfo.first;
+                backMoney = backInfo.second;
+                backMsg = backInfo.third;
+            }
         }
         BackStatusEnum backStatus = BackStatusEnum.NO;
         orderLog.setBackMoney(backMoney);
@@ -359,14 +182,7 @@ public class GameOceanengineOrderLogServiceImpl extends ServiceImpl<GameOceaneng
     }
 
     private BackStatusEnum doCallback(GameOceanengineOrderLog orderLog) {
-        GameOceanengineUserLog userLog = gameOceanengineUserLogService.getOne(new LambdaQueryWrapper<GameOceanengineUserLog>()
-                .eq(GameOceanengineUserLog::getGameId, orderLog.getGameId())
-                .eq(GameOceanengineUserLog::getAppId, orderLog.getAppId())
-                .eq(GameOceanengineUserLog::getOpenId, orderLog.getOpenId())
-                .eq(GameOceanengineUserLog::getAccountId, orderLog.getAccountId())
-                .orderByDesc(GameOceanengineUserLog::getCreateTime)
-                .last("limit 1")
-        );
+        GameOceanengineUserLog userLog = userLog(orderLog);
         if (userLog == null) {
             gameOceanengineBackLogService.save(GameOceanengineBackLog.builder()
                     .appId(orderLog.getAppId())
@@ -423,4 +239,217 @@ public class GameOceanengineOrderLogServiceImpl extends ServiceImpl<GameOceaneng
                 .build());
         return backStatus;
     }
+
+    private GameOceanengineUserLog userLog(GameOceanengineOrderLog orderLog) {
+        return gameOceanengineUserLogService.getOne(new LambdaQueryWrapper<GameOceanengineUserLog>()
+                .eq(GameOceanengineUserLog::getGameId, orderLog.getGameId())
+                .eq(GameOceanengineUserLog::getAppId, orderLog.getAppId())
+                .eq(GameOceanengineUserLog::getOpenId, orderLog.getOpenId())
+                .eq(GameOceanengineUserLog::getAccountId, orderLog.getAccountId())
+                .orderByDesc(GameOceanengineUserLog::getCreateTime)
+                .last("limit 1")
+        );
+    }
+
+    public static class OceanengineOrderBackPolicyCheck implements BackPolicyUtil.IBackPolicyCheck {
+        private final IGameOceanengineOrderLogService gameOceanengineOrderLogService;
+        private final GameBackPolicy gameBackPolicy;
+        private final GameOceanengineUserLog userLog;
+        private final GameOceanengineOrderLog orderLog;
+
+        public OceanengineOrderBackPolicyCheck(IGameOceanengineOrderLogService gameOceanengineOrderLogService, GameOceanengineUserLog userLog, GameOceanengineOrderLog orderLog, GameBackPolicy gameBackPolicy) {
+            this.gameOceanengineOrderLogService = gameOceanengineOrderLogService;
+            this.gameBackPolicy = gameBackPolicy;
+            this.userLog = userLog;
+            this.orderLog = orderLog;
+        }
+
+        @Override
+        public long backCountForFixedRate(int numberOfRound, BackUnitEnum backUnit, Boolean firstPolicy) {
+            numberOfRound = numberOfRound - 1;
+            if (backUnit == BackUnitEnum.UNIT_ONCE) {
+                return gameOceanengineOrderLogService.list(new LambdaQueryWrapper<GameOceanengineOrderLog>()
+                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameOceanengineOrderLog::getIsFirstOrder, firstPolicy)
+                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+                        .orderByDesc(GameOceanengineOrderLog::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
+                return gameOceanengineOrderLogService.list(new LambdaQueryWrapper<GameOceanengineOrderLog>()
+                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .apply(firstPolicy, "date(reg_time) = date(pay_time)")
+                        .apply(!firstPolicy, "date(reg_time) != date(pay_time)")
+                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+                        .orderByDesc(GameOceanengineOrderLog::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
+                return gameOceanengineOrderLogService.list(new LambdaQueryWrapper<GameOceanengineOrderLog>()
+                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) < 24")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) >= 24")
+                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+                        .orderByDesc(GameOceanengineOrderLog::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
+                return gameOceanengineOrderLogService.list(new LambdaQueryWrapper<GameOceanengineOrderLog>()
+                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) < 48")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) >= 48")
+                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+                        .orderByDesc(GameOceanengineOrderLog::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
+                return gameOceanengineOrderLogService.list(new LambdaQueryWrapper<GameOceanengineOrderLog>()
+                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+                        .orderByDesc(GameOceanengineOrderLog::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else {
+                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
+            }
+        }
+
+        @Override
+        public long backCountForUser(BackUnitEnum backUnit, String userId, Boolean firstPolicy) {
+            if (backUnit == BackUnitEnum.UNIT_ONCE) {
+                if (firstPolicy) {
+                    // 首单直接返回 0,必定回传
+                    return 0;
+                }
+                return gameOceanengineOrderLogService.count(new LambdaQueryWrapper<GameOceanengineOrderLog>()
+                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameOceanengineOrderLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameOceanengineOrderLog::getOpenId, userId)
+                        .eq(GameOceanengineOrderLog::getIsFirstOrder, firstPolicy)
+                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+                );
+            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
+                return gameOceanengineOrderLogService.count(new LambdaQueryWrapper<GameOceanengineOrderLog>()
+                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameOceanengineOrderLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameOceanengineOrderLog::getOpenId, userId)
+                        .apply(firstPolicy, "date(reg_time) = date(pay_time)")
+                        .apply(!firstPolicy, "date(reg_time) != date(pay_time)")
+                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+                );
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
+                return gameOceanengineOrderLogService.count(new LambdaQueryWrapper<GameOceanengineOrderLog>()
+                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameOceanengineOrderLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameOceanengineOrderLog::getOpenId, userId)
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) < 24")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) >= 24")
+                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+                );
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
+                return gameOceanengineOrderLogService.count(new LambdaQueryWrapper<GameOceanengineOrderLog>()
+                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameOceanengineOrderLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameOceanengineOrderLog::getOpenId, userId)
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) < 48")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) >= 48")
+                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+                );
+            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
+                return gameOceanengineOrderLogService.count(new LambdaQueryWrapper<GameOceanengineOrderLog>()
+                        .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                        .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                        .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                        .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameOceanengineOrderLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameOceanengineOrderLog::getOpenId, userId)
+                        .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+                );
+            } else {
+                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
+            }
+        }
+
+        @Override
+        public long markUpOfFixedRate(int numberOfRound, Long markUpTime) {
+            numberOfRound = numberOfRound - 1;
+            return gameOceanengineOrderLogService.list(new LambdaQueryWrapper<GameOceanengineOrderLog>()
+                    .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                    .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                    .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                    .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .apply("TIMESTAMPDIFF(MINUTE, reg_time, pay_time) > {0}", markUpTime)
+                    .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+                    .orderByDesc(GameOceanengineOrderLog::getCreateTime)
+                    .last("limit " + numberOfRound)
+            ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+        }
+
+        @Override
+        public long markUpForUser(String userId, Long markUpTime) {
+            return gameOceanengineOrderLogService.count(new LambdaQueryWrapper<GameOceanengineOrderLog>()
+                    .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                    .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                    .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                    .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .eq(GameOceanengineOrderLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                    .eq(GameOceanengineOrderLog::getOpenId, userId)
+                    .apply("TIMESTAMPDIFF(MINUTE, reg_time, pay_time) > {0}", markUpTime)
+                    .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+            );
+        }
+
+        @Override
+        public Long totalRechargeAmount() {
+            return gameOceanengineOrderLogService.getOne(new QueryWrapper<GameOceanengineOrderLog>()
+                    .select("ifnull(sum(amount), 0) as amount").lambda()
+                    .eq(GameOceanengineOrderLog::getGameId, orderLog.getGameId())
+                    .eq(GameOceanengineOrderLog::getAppId, orderLog.getAppId())
+                    .eq(GameOceanengineOrderLog::getAccountId, orderLog.getAccountId())
+                    .eq(GameOceanengineOrderLog::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameOceanengineOrderLog::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .eq(GameOceanengineOrderLog::getOpenId, orderLog.getOpenId())
+                    .ne(GameOceanengineOrderLog::getOrderNo, orderLog.getOrderNo())
+            ).getAmount();
+        }
+    }
 }

+ 233 - 197
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentMiniGameOrderServiceImpl.java

@@ -74,7 +74,7 @@ public class GameTencentMiniGameOrderServiceImpl extends ServiceImpl<GameTencent
             // 没有点击 id(之后做监测链接,从监测链接里面找)
             return false;
         }
-        boolean doBack = false;
+        boolean doBack;
         Long backMoney;
         String backMsg;
         if (mustBack) {
@@ -86,202 +86,33 @@ public class GameTencentMiniGameOrderServiceImpl extends ServiceImpl<GameTencent
                 // 只要回传 支付行为
                 return true;
             }
-            GameBackPolicy gameBackPolicy = gameBackPolicyService.getById(orderLog.getBackPolicyId());
-            // 此处是否是首单用 limit 2。因为在执行判断之前订单已入库,所以库里只有一笔才是首单
-            Tuple3<Boolean, Long, String> backInfo = BackPolicyUtil.backOrder(orderLog.getOrderId(), gameBackPolicy, orderLog.getRechargeMoney(),
-                    orderLog.getIsFirstOrder(), orderLog.getPayTime(), orderLog.getRegisterTime(), orderLog.getWechatOpenid(),
-                    new BackPolicyUtil.IBackPolicyCheck() {
-                        @Override
-                        public long backCountForFixedRate(int numberOfRound, BackUnitEnum backUnit, Boolean firstPolicy) {
-                            numberOfRound = numberOfRound - 1;
-                            if (backUnit == BackUnitEnum.UNIT_ONCE) {
-                                return list(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
-                                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameTencentMiniGameOrder::getIsFirstOrder, firstPolicy)
-                                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                                        .orderByDesc(GameTencentMiniGameOrder::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
-                                return list(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
-                                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .apply(firstPolicy, "date(recharge_time) = date(pay_time)")
-                                        .apply(!firstPolicy, "date(recharge_time) != date(pay_time)")
-                                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                                        .orderByDesc(GameTencentMiniGameOrder::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
-                                return list(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
-                                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 24")
-                                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 24")
-                                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                                        .orderByDesc(GameTencentMiniGameOrder::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
-                                return list(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
-                                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 48")
-                                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 48")
-                                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                                        .orderByDesc(GameTencentMiniGameOrder::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
-                                return list(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
-                                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                                        .orderByDesc(GameTencentMiniGameOrder::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else {
-                                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
-                            }
-                        }
-
-                        @Override
-                        public long backCountForUser(BackUnitEnum backUnit, String userId, Boolean firstPolicy) {
-                            if (backUnit == BackUnitEnum.UNIT_ONCE) {
-                                if (firstPolicy) {
-                                    // 首单直接返回 0,必定回传
-                                    return 0;
-                                }
-                                return count(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
-                                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameTencentMiniGameOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameTencentMiniGameOrder::getWechatOpenid, userId)
-                                        .eq(GameTencentMiniGameOrder::getIsFirstOrder, firstPolicy)
-                                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                                );
-                            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
-                                return count(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
-                                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameTencentMiniGameOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameTencentMiniGameOrder::getWechatOpenid, userId)
-                                        .apply(firstPolicy, "date(recharge_time) = date(pay_time)")
-                                        .apply(!firstPolicy, "date(recharge_time) != date(pay_time)")
-                                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                                );
-                            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
-                                return count(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
-                                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameTencentMiniGameOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameTencentMiniGameOrder::getWechatOpenid, userId)
-                                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 24")
-                                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 24")
-                                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                                );
-                            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
-                                return count(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
-                                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameTencentMiniGameOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameTencentMiniGameOrder::getWechatOpenid, userId)
-                                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 48")
-                                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 48")
-                                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                                );
-                            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
-                                return count(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
-                                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameTencentMiniGameOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameTencentMiniGameOrder::getWechatOpenid, userId)
-                                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                                );
-                            } else {
-                                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
-                            }
-                        }
-
-                        @Override
-                        public long markUpOfFixedRate(int numberOfRound, Long markUpTime) {
-                            numberOfRound = numberOfRound - 1;
-                            return list(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
-                                    .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                    .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                    .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                    .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                    .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                    .apply("TIMESTAMPDIFF(MINUTE, recharge_time, pay_time) > {0}", markUpTime)
-                                    .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                                    .orderByDesc(GameTencentMiniGameOrder::getCreateTime)
-                                    .last("limit " + numberOfRound)
-                            ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                        }
-
-                        @Override
-                        public long markUpForUser(String userId, Long markUpTime) {
-                            return count(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
-                                    .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                    .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                    .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                    .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                    .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                    .eq(GameTencentMiniGameOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                                    .eq(GameTencentMiniGameOrder::getWechatOpenid, userId)
-                                    .apply("TIMESTAMPDIFF(MINUTE, recharge_time, pay_time) > {0}", markUpTime)
-                                    .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                            );
-                        }
-
-                        @Override
-                        public Long totalRechargeAmount() {
-                            return getOne(new QueryWrapper<GameTencentMiniGameOrder>()
-                                    .select("ifnull(sum(recharge_money), 0) as recharge_money").lambda()
-                                    .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
-                                    .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
-                                    .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
-                                    .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
-                                    .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                    .eq(GameTencentMiniGameOrder::getWechatOpenid, orderLog.getWechatOpenid())
-                                    .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
-                            ).getRechargeMoney();
-                        }
-                    });
-            doBack = backInfo.first;
-            backMoney = backInfo.second;
-            backMsg = backInfo.third;
+            GameTencentMiniGameUser userLog = gameTencentMiniGameUserService.getOne(new LambdaQueryWrapper<GameTencentMiniGameUser>()
+                    .select(GameTencentMiniGameUser::getBackStatus, GameTencentMiniGameUser::getClickId)
+                    .eq(GameTencentMiniGameUser::getGameId, orderLog.getGameId())
+                    .eq(GameTencentMiniGameUser::getWechatAppId, orderLog.getWechatAppId())
+                    .eq(GameTencentMiniGameUser::getWechatOpenid, orderLog.getWechatOpenid())
+                    .eq(GameTencentMiniGameUser::getAdAccountId, orderLog.getAdAccountId())
+                    .orderByDesc(GameTencentMiniGameUser::getCreateTime)
+                    .last("limit 1")
+            );
+            if (userLog == null) {
+                doBack = false;
+                backMoney = orderLog.getRechargeMoney();
+                backMsg = "回传失败!找不到回传用户";
+            } else {
+                GameBackPolicy gameBackPolicy = gameBackPolicyService.getById(orderLog.getBackPolicyId());
+                // 此处是否是首单用 limit 2。因为在执行判断之前订单已入库,所以库里只有一笔才是首单
+                Tuple3<Boolean, Long, String> backInfo = BackPolicyUtil.backOrder(orderLog.getOrderId(), gameBackPolicy, orderLog.getRechargeMoney(),
+                        orderLog.getIsFirstOrder(),
+                        orderLog.getPayTime(),
+                        // 此处使用用户最近一次的重新染色时间
+                        userLog.getCreateTime(),
+                        orderLog.getWechatOpenid(),
+                        new TencentMiniGameOrderBackPolicyCheck(this, gameBackPolicy, userLog, orderLog));
+                doBack = backInfo.first;
+                backMoney = backInfo.second;
+                backMsg = backInfo.third;
+            }
         }
         BackStatusEnum backStatus = BackStatusEnum.NO;
         orderLog.setBackMoney(backMoney);
@@ -358,4 +189,209 @@ public class GameTencentMiniGameOrderServiceImpl extends ServiceImpl<GameTencent
         vo.setRegPayIntervalTime(OrderUtil.regPayIntervalTime(orderLog.getPayTime(), orderLog.getRegisterTime()));
         return vo;
     }
+
+    public static class TencentMiniGameOrderBackPolicyCheck implements BackPolicyUtil.IBackPolicyCheck {
+        private final IGameTencentMiniGameOrderService gameTencentMiniGameOrderService;
+        private final GameBackPolicy gameBackPolicy;
+        private final GameTencentMiniGameUser userLog;
+        private final GameTencentMiniGameOrder orderLog;
+
+        public TencentMiniGameOrderBackPolicyCheck(IGameTencentMiniGameOrderService gameTencentMiniGameOrderService,
+                                                   GameBackPolicy gameBackPolicy,
+                                                   GameTencentMiniGameUser userLog,
+                                                   GameTencentMiniGameOrder orderLog) {
+            this.gameTencentMiniGameOrderService = gameTencentMiniGameOrderService;
+            this.gameBackPolicy = gameBackPolicy;
+            this.orderLog = orderLog;
+            this.userLog = userLog;
+        }
+
+        @Override
+        public long backCountForFixedRate(int numberOfRound, BackUnitEnum backUnit, Boolean firstPolicy) {
+            numberOfRound = numberOfRound - 1;
+            if (backUnit == BackUnitEnum.UNIT_ONCE) {
+                return gameTencentMiniGameOrderService.list(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
+                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentMiniGameOrder::getIsFirstOrder, firstPolicy)
+                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+                        .orderByDesc(GameTencentMiniGameOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
+                return gameTencentMiniGameOrderService.list(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
+                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .apply(firstPolicy, "date(recharge_time) = date(pay_time)")
+                        .apply(!firstPolicy, "date(recharge_time) != date(pay_time)")
+                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+                        .orderByDesc(GameTencentMiniGameOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
+                return gameTencentMiniGameOrderService.list(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
+                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 24")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 24")
+                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+                        .orderByDesc(GameTencentMiniGameOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
+                return gameTencentMiniGameOrderService.list(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
+                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 48")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 48")
+                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+                        .orderByDesc(GameTencentMiniGameOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
+                return gameTencentMiniGameOrderService.list(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
+                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+                        .orderByDesc(GameTencentMiniGameOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else {
+                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
+            }
+        }
+
+        @Override
+        public long backCountForUser(BackUnitEnum backUnit, String userId, Boolean firstPolicy) {
+            if (backUnit == BackUnitEnum.UNIT_ONCE) {
+                if (firstPolicy) {
+                    // 首单直接返回 0,必定回传
+                    return 0;
+                }
+                return gameTencentMiniGameOrderService.count(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
+                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentMiniGameOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentMiniGameOrder::getWechatOpenid, userId)
+                        .eq(GameTencentMiniGameOrder::getIsFirstOrder, firstPolicy)
+                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+                );
+            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
+                return gameTencentMiniGameOrderService.count(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
+                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentMiniGameOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentMiniGameOrder::getWechatOpenid, userId)
+                        .apply(firstPolicy, "date(recharge_time) = date(pay_time)")
+                        .apply(!firstPolicy, "date(recharge_time) != date(pay_time)")
+                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+                );
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
+                return gameTencentMiniGameOrderService.count(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
+                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentMiniGameOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentMiniGameOrder::getWechatOpenid, userId)
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 24")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 24")
+                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+                );
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
+                return gameTencentMiniGameOrderService.count(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
+                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentMiniGameOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentMiniGameOrder::getWechatOpenid, userId)
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 48")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 48")
+                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+                );
+            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
+                return gameTencentMiniGameOrderService.count(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
+                        .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentMiniGameOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentMiniGameOrder::getWechatOpenid, userId)
+                        .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+                );
+            } else {
+                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
+            }
+        }
+
+        @Override
+        public long markUpOfFixedRate(int numberOfRound, Long markUpTime) {
+            numberOfRound = numberOfRound - 1;
+            return gameTencentMiniGameOrderService.list(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
+                    .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                    .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                    .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                    .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .apply("TIMESTAMPDIFF(MINUTE, recharge_time, pay_time) > {0}", markUpTime)
+                    .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+                    .orderByDesc(GameTencentMiniGameOrder::getCreateTime)
+                    .last("limit " + numberOfRound)
+            ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+        }
+
+        @Override
+        public long markUpForUser(String userId, Long markUpTime) {
+            return gameTencentMiniGameOrderService.count(new LambdaQueryWrapper<GameTencentMiniGameOrder>()
+                    .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                    .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                    .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                    .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .eq(GameTencentMiniGameOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                    .eq(GameTencentMiniGameOrder::getWechatOpenid, userId)
+                    .apply("TIMESTAMPDIFF(MINUTE, recharge_time, pay_time) > {0}", markUpTime)
+                    .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+            );
+        }
+
+        @Override
+        public Long totalRechargeAmount() {
+            return gameTencentMiniGameOrderService.getOne(new QueryWrapper<GameTencentMiniGameOrder>()
+                    .select("ifnull(sum(recharge_money), 0) as recharge_money").lambda()
+                    .eq(GameTencentMiniGameOrder::getGameId, orderLog.getGameId())
+                    .eq(GameTencentMiniGameOrder::getWechatAppId, orderLog.getWechatAppId())
+                    .eq(GameTencentMiniGameOrder::getAdAccountId, orderLog.getAdAccountId())
+                    .eq(GameTencentMiniGameOrder::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameTencentMiniGameOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .eq(GameTencentMiniGameOrder::getWechatOpenid, orderLog.getWechatOpenid())
+                    .ne(GameTencentMiniGameOrder::getOrderId, orderLog.getOrderId())
+            ).getRechargeMoney();
+        }
+    }
 }

+ 235 - 197
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentOrderServiceImpl.java

@@ -19,6 +19,7 @@ import com.zanxiang.game.back.serve.pojo.entity.GameTencentBackLog;
 import com.zanxiang.game.back.serve.pojo.entity.GameTencentMiniGameOrder;
 import com.zanxiang.game.back.serve.pojo.entity.GameTencentOrder;
 import com.zanxiang.game.back.serve.dao.mapper.GameTencentOrderMapper;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentUser;
 import com.zanxiang.game.back.serve.pojo.enums.ActionTypeEnum;
 import com.zanxiang.game.back.serve.pojo.enums.BackStatusEnum;
 import com.zanxiang.game.back.serve.pojo.enums.BackUnitEnum;
@@ -27,6 +28,7 @@ import com.zanxiang.game.back.serve.service.IGameBackPolicyService;
 import com.zanxiang.game.back.serve.service.IGameTencentBackLogService;
 import com.zanxiang.game.back.serve.service.IGameTencentOrderService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zanxiang.game.back.serve.service.IGameTencentUserService;
 import com.zanxiang.game.back.serve.utils.BackPolicyUtil;
 import com.zanxiang.game.back.serve.utils.OrderUtil;
 import com.zanxiang.game.module.base.ServerInfo;
@@ -75,11 +77,13 @@ public class GameTencentOrderServiceImpl extends ServiceImpl<GameTencentOrderMap
     private IGameBackPolicyService gameBackPolicyService;
     @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
     private IAgentRpc agentRpc;
+    @Autowired
+    private IGameTencentUserService gameTencentUserService;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean orderBack(GameTencentOrder orderLog, boolean mustBack, Long backMoneyOfInput) {
-        boolean doBack = false;
+        boolean doBack;
         Long backMoney;
         String backMsg;
         if (mustBack) {
@@ -91,202 +95,30 @@ public class GameTencentOrderServiceImpl extends ServiceImpl<GameTencentOrderMap
                 // 只要回传 支付行为
                 return false;
             }
-            GameBackPolicy gameBackPolicy = gameBackPolicyService.getById(orderLog.getBackPolicyId());
-            Tuple3<Boolean, Long, String> backInfo = BackPolicyUtil.backOrder(orderLog.getOrderId(), gameBackPolicy, orderLog.getRechargeMoney(),
-                    orderLog.getIsFirstOrder(), orderLog.getPayTime(), orderLog.getRegisterTime(),
-                    orderLog.getWechatOpenid(),
-                    new BackPolicyUtil.IBackPolicyCheck() {
-                        @Override
-                        public long backCountForFixedRate(int numberOfRound, BackUnitEnum backUnit, Boolean firstPolicy) {
-                            numberOfRound = numberOfRound - 1;
-                            if (backUnit == BackUnitEnum.UNIT_ONCE) {
-                                return list(new LambdaQueryWrapper<GameTencentOrder>()
-                                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameTencentOrder::getIsFirstOrder, firstPolicy)
-                                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                                        .orderByDesc(GameTencentOrder::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getIsBack().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
-                                return list(new LambdaQueryWrapper<GameTencentOrder>()
-                                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .apply(firstPolicy, "date(recharge_time) = date(pay_time)")
-                                        .apply(!firstPolicy, "date(recharge_time) != date(pay_time)")
-                                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                                        .orderByDesc(GameTencentOrder::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getIsBack().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
-                                return list(new LambdaQueryWrapper<GameTencentOrder>()
-                                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 24")
-                                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 24")
-                                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                                        .orderByDesc(GameTencentOrder::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getIsBack().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
-                                return list(new LambdaQueryWrapper<GameTencentOrder>()
-                                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 48")
-                                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 48")
-                                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                                        .orderByDesc(GameTencentOrder::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getIsBack().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
-                                return list(new LambdaQueryWrapper<GameTencentOrder>()
-                                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                                        .orderByDesc(GameTencentOrder::getCreateTime)
-                                        .last("limit " + numberOfRound)
-                                ).stream().filter(log -> log.getIsBack().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                            } else {
-                                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
-                            }
-                        }
-
-                        @Override
-                        public long backCountForUser(BackUnitEnum backUnit, String userId, Boolean firstPolicy) {
-                            if (backUnit == BackUnitEnum.UNIT_ONCE) {
-                                if (firstPolicy) {
-                                    // 首单直接返回 0,必定回传
-                                    return 0;
-                                }
-                                return count(new LambdaQueryWrapper<GameTencentOrder>()
-                                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameTencentOrder::getIsBack, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameTencentOrder::getWechatOpenid, userId)
-                                        .eq(GameTencentOrder::getIsFirstOrder, firstPolicy)
-                                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                                );
-                            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
-                                return count(new LambdaQueryWrapper<GameTencentOrder>()
-                                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameTencentOrder::getIsBack, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameTencentOrder::getWechatOpenid, userId)
-                                        .apply(firstPolicy, "date(recharge_time) = date(pay_time)")
-                                        .apply(!firstPolicy, "date(recharge_time) != date(pay_time)")
-                                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                                );
-                            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
-                                return count(new LambdaQueryWrapper<GameTencentOrder>()
-                                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameTencentOrder::getIsBack, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameTencentOrder::getWechatOpenid, userId)
-                                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 24")
-                                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 24")
-                                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                                );
-                            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
-                                return count(new LambdaQueryWrapper<GameTencentOrder>()
-                                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameTencentOrder::getIsBack, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameTencentOrder::getWechatOpenid, userId)
-                                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 48")
-                                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 48")
-                                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                                );
-                            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
-                                return count(new LambdaQueryWrapper<GameTencentOrder>()
-                                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                        .eq(GameTencentOrder::getIsBack, BackStatusEnum.SUCCESS.getBackStatus())
-                                        .eq(GameTencentOrder::getWechatOpenid, userId)
-                                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                                );
-                            } else {
-                                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
-                            }
-                        }
-
-                        @Override
-                        public long markUpOfFixedRate(int numberOfRound, Long markUpTime) {
-                            numberOfRound = numberOfRound - 1;
-                            return list(new LambdaQueryWrapper<GameTencentOrder>()
-                                    .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                    .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                    .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                    .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                    .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                    .apply("TIMESTAMPDIFF(MINUTE, recharge_time, pay_time) > {0}", markUpTime)
-                                    .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                                    .orderByDesc(GameTencentOrder::getCreateTime)
-                                    .last("limit " + numberOfRound)
-                            ).stream().filter(log -> log.getIsBack().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
-                        }
-
-                        @Override
-                        public long markUpForUser(String userId, Long markUpTime) {
-                            return count(new LambdaQueryWrapper<GameTencentOrder>()
-                                    .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                    .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                    .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                    .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                    .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                    .eq(GameTencentOrder::getIsBack, BackStatusEnum.SUCCESS.getBackStatus())
-                                    .eq(GameTencentOrder::getWechatOpenid, userId)
-                                    .apply("TIMESTAMPDIFF(MINUTE, recharge_time, pay_time) > {0}", markUpTime)
-                                    .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                            );
-                        }
-
-                        @Override
-                        public Long totalRechargeAmount() {
-                            return count(new QueryWrapper<GameTencentOrder>()
-                                    .select("ifnull(sum(recharge_money), 0) as recharge_money").lambda()
-                                    .eq(GameTencentOrder::getGameId, orderLog.getGameId())
-                                    .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
-                                    .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
-                                    .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
-                                    .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                                    .eq(GameTencentOrder::getWechatOpenid, orderLog.getWechatOpenid())
-                                    .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
-                            );
-                        }
-                    });
-            doBack = backInfo.first;
-            backMoney = backInfo.second;
-            backMsg = backInfo.third;
+            GameTencentUser userLog = gameTencentUserService.getOne(new LambdaQueryWrapper<GameTencentUser>()
+                    .eq(GameTencentUser::getGameId, orderLog.getGameId())
+                    .eq(GameTencentUser::getWechatAppId, orderLog.getWechatAppId())
+                    .eq(GameTencentUser::getWechatOpenid, orderLog.getWechatOpenid())
+                    .eq(GameTencentUser::getAdAccountId, orderLog.getAdAccountId())
+                    .orderByDesc(GameTencentUser::getCreateTime)
+                    .last("limit 1")
+            );if (userLog == null) {
+                doBack = false;
+                backMoney = orderLog.getRechargeMoney();
+                backMsg = "回传失败!找不到回传用户";
+            } else {
+                GameBackPolicy gameBackPolicy = gameBackPolicyService.getById(orderLog.getBackPolicyId());
+                Tuple3<Boolean, Long, String> backInfo = BackPolicyUtil.backOrder(orderLog.getOrderId(), gameBackPolicy, orderLog.getRechargeMoney(),
+                        orderLog.getIsFirstOrder(),
+                        orderLog.getPayTime(),
+                        // 此处使用用户最近一次的重新染色时间
+                        userLog.getCreateTime(),
+                        orderLog.getWechatOpenid(),
+                        new TencentOrderBackPolicyCheck(this, gameBackPolicy, userLog, orderLog));
+                doBack = backInfo.first;
+                backMoney = backInfo.second;
+                backMsg = backInfo.third;
+            }
         }
         BackStatusEnum backStatus = BackStatusEnum.NO;
         orderLog.setBackMoney(backMoney);
@@ -412,4 +244,210 @@ public class GameTencentOrderServiceImpl extends ServiceImpl<GameTencentOrderMap
         gameTencentBackLogService.save(gameTencentBackLog);
         return backStatus;
     }
+
+    public static class TencentOrderBackPolicyCheck implements BackPolicyUtil.IBackPolicyCheck {
+        private final IGameTencentOrderService gameTencentOrderService;
+        private final GameBackPolicy gameBackPolicy;
+        private final GameTencentUser userLog;
+        private final GameTencentOrder orderLog;
+
+        public TencentOrderBackPolicyCheck(IGameTencentOrderService gameTencentOrderService,
+                                           GameBackPolicy gameBackPolicy,
+                                           GameTencentUser userLog,
+                                           GameTencentOrder orderLog) {
+            this.gameTencentOrderService = gameTencentOrderService;
+            this.gameBackPolicy = gameBackPolicy;
+            this.userLog = userLog;
+            this.orderLog = orderLog;
+
+        }
+
+        @Override
+        public long backCountForFixedRate(int numberOfRound, BackUnitEnum backUnit, Boolean firstPolicy) {
+            numberOfRound = numberOfRound - 1;
+            if (backUnit == BackUnitEnum.UNIT_ONCE) {
+                return gameTencentOrderService.list(new LambdaQueryWrapper<GameTencentOrder>()
+                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentOrder::getIsFirstOrder, firstPolicy)
+                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+                        .orderByDesc(GameTencentOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getIsBack().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
+                return gameTencentOrderService.list(new LambdaQueryWrapper<GameTencentOrder>()
+                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .apply(firstPolicy, "date(recharge_time) = date(pay_time)")
+                        .apply(!firstPolicy, "date(recharge_time) != date(pay_time)")
+                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+                        .orderByDesc(GameTencentOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getIsBack().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
+                return gameTencentOrderService.list(new LambdaQueryWrapper<GameTencentOrder>()
+                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 24")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 24")
+                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+                        .orderByDesc(GameTencentOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getIsBack().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
+                return gameTencentOrderService.list(new LambdaQueryWrapper<GameTencentOrder>()
+                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 48")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 48")
+                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+                        .orderByDesc(GameTencentOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getIsBack().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
+                return gameTencentOrderService.list(new LambdaQueryWrapper<GameTencentOrder>()
+                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+                        .orderByDesc(GameTencentOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getIsBack().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else {
+                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
+            }
+        }
+
+        @Override
+        public long backCountForUser(BackUnitEnum backUnit, String userId, Boolean firstPolicy) {
+            if (backUnit == BackUnitEnum.UNIT_ONCE) {
+                if (firstPolicy) {
+                    // 首单直接返回 0,必定回传
+                    return 0;
+                }
+                return gameTencentOrderService.count(new LambdaQueryWrapper<GameTencentOrder>()
+                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentOrder::getIsBack, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentOrder::getWechatOpenid, userId)
+                        .eq(GameTencentOrder::getIsFirstOrder, firstPolicy)
+                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+                );
+            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
+                return gameTencentOrderService.count(new LambdaQueryWrapper<GameTencentOrder>()
+                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentOrder::getIsBack, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentOrder::getWechatOpenid, userId)
+                        .apply(firstPolicy, "date(recharge_time) = date(pay_time)")
+                        .apply(!firstPolicy, "date(recharge_time) != date(pay_time)")
+                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+                );
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
+                return gameTencentOrderService.count(new LambdaQueryWrapper<GameTencentOrder>()
+                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentOrder::getIsBack, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentOrder::getWechatOpenid, userId)
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 24")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 24")
+                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+                );
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
+                return gameTencentOrderService.count(new LambdaQueryWrapper<GameTencentOrder>()
+                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentOrder::getIsBack, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentOrder::getWechatOpenid, userId)
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) < 48")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, recharge_time, pay_time) >= 48")
+                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+                );
+            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
+                return gameTencentOrderService.count(new LambdaQueryWrapper<GameTencentOrder>()
+                        .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                        .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                        .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentOrder::getIsBack, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentOrder::getWechatOpenid, userId)
+                        .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+                );
+            } else {
+                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
+            }
+        }
+
+        @Override
+        public long markUpOfFixedRate(int numberOfRound, Long markUpTime) {
+            numberOfRound = numberOfRound - 1;
+            return gameTencentOrderService.list(new LambdaQueryWrapper<GameTencentOrder>()
+                    .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                    .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                    .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                    .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .apply("TIMESTAMPDIFF(MINUTE, recharge_time, pay_time) > {0}", markUpTime)
+                    .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+                    .orderByDesc(GameTencentOrder::getCreateTime)
+                    .last("limit " + numberOfRound)
+            ).stream().filter(log -> log.getIsBack().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+        }
+
+        @Override
+        public long markUpForUser(String userId, Long markUpTime) {
+            return gameTencentOrderService.count(new LambdaQueryWrapper<GameTencentOrder>()
+                    .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                    .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                    .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                    .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .eq(GameTencentOrder::getIsBack, BackStatusEnum.SUCCESS.getBackStatus())
+                    .eq(GameTencentOrder::getWechatOpenid, userId)
+                    .apply("TIMESTAMPDIFF(MINUTE, recharge_time, pay_time) > {0}", markUpTime)
+                    .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+            );
+        }
+
+        @Override
+        public Long totalRechargeAmount() {
+            return gameTencentOrderService.count(new QueryWrapper<GameTencentOrder>()
+                    .select("ifnull(sum(recharge_money), 0) as recharge_money").lambda()
+                    .eq(GameTencentOrder::getGameId, orderLog.getGameId())
+                    .eq(GameTencentOrder::getWechatAppId, orderLog.getWechatAppId())
+                    .eq(GameTencentOrder::getAdAccountId, orderLog.getAdAccountId())
+                    .eq(GameTencentOrder::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameTencentOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .eq(GameTencentOrder::getWechatOpenid, orderLog.getWechatOpenid())
+                    .ne(GameTencentOrder::getOrderId, orderLog.getOrderId())
+            );
+        }
+    }
 }