浏览代码

Merge remote-tracking branch 'origin/package' into package

zhangxianyu 12 小时之前
父节点
当前提交
26dc9e61df
共有 33 个文件被更改,包括 1573 次插入581 次删除
  1. 37 0
      game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/pojo/dto/TencentAppOrderBackQueryRpcDTO.java
  2. 24 39
      game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/pojo/dto/TencentOrderAppRpcDTO.java
  3. 17 17
      game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/pojo/dto/TencentRoleRegisterAppRpcDTO.java
  4. 24 19
      game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/pojo/dto/TencentUserAppRpcDTO.java
  5. 7 8
      game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/rpc/ITencentAppBackRpc.java
  6. 4 15
      game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/rpc/ITtAppBackRpc.java
  7. 1 1
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/GameBackApplication.java
  8. 60 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/controller/TencentAppController.java
  9. 78 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/dto/GameTencentAppOrderDTO.java
  10. 62 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/dto/GameTencentAppUserDTO.java
  11. 32 30
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameTencentAppBackLog.java
  12. 45 52
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameTencentAppOrder.java
  13. 1 31
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameTencentAppOrderSplitLog.java
  14. 33 29
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameTencentAppRoleRegister.java
  15. 25 34
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameTencentAppUser.java
  16. 33 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/vo/GameTencentAppOrderSplitLogVO.java
  17. 101 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/vo/GameTencentAppOrderVO.java
  18. 146 85
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/rpc/impl/TencentAppBackRpcImpl.java
  19. 8 33
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/rpc/impl/TtAppBackRpcImpl.java
  20. 0 4
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameOceanengineAppCallbackService.java
  21. 7 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameTencentAppOrderService.java
  22. 6 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameTencentAppOrderSplitLogService.java
  23. 2 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameTencentAppRoleRegisterService.java
  24. 7 0
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameTencentAppUserService.java
  25. 1 31
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameOceanengineAppCallbackServiceImpl.java
  26. 483 3
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentAppOrderServiceImpl.java
  27. 34 1
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentAppOrderSplitLogServiceImpl.java
  28. 90 1
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentAppRoleRegisterServiceImpl.java
  29. 57 98
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentAppUserServiceImpl.java
  30. 1 1
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/SDKApplication.java
  31. 38 21
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/AgentServiceImpl.java
  32. 81 21
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/CallBackServiceImpl.java
  33. 28 7
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/GameBackLogMediaSdkServiceImpl.java

+ 37 - 0
game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/pojo/dto/TencentAppOrderBackQueryRpcDTO.java

@@ -0,0 +1,37 @@
+package com.zanxiang.game.back.base.pojo.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @author : lingfeng
+ * @time : 2025-05-08
+ * @description : 订单回传查询参数
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class TencentAppOrderBackQueryRpcDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+     * 游戏 id
+     */
+    private Long gameId;
+    /**
+     * sdk 里面的用户 id(要求唯一)
+     */
+    private String userId;
+    /**
+     * 订单编号
+     */
+    private String orderId;
+    /**
+     * 渠道标识
+     */
+    private String agentKey;
+}

+ 24 - 39
game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/pojo/dto/TencentOrderAppRpcDTO.java

@@ -14,59 +14,45 @@ import java.time.LocalDateTime;
 @Builder
 public class TencentOrderAppRpcDTO implements Serializable {
     private static final long serialVersionUID = 1L;
-    /**
-     * 回传策略ID
-     */
-    private Long backPolicyId;
-    /**
-     * sdk 里面的用户 id(要求唯一)
-     */
-    private String userId;
-    /**
-     * 游戏ID
-     */
-    private Long gameId;
 
     /**
-     * 广告账号ID
+     * 游戏 id
      */
-    private Long adAccountId;
-
+    private Long gameId;
     /**
-     * 注册时间
+     * 广告账号id
      */
-    private LocalDateTime registerTime;
-
+    private Long accountId;
     /**
-     * 关注时间
+     * sdk 里面的用户 id(要求唯一)
      */
-    private LocalDateTime subscribeTime;
-
+    private String userId;
     /**
-     * 充值金额(分)
+     * 订单编号
      */
-    private Long rechargeMoney;
-
+    private String orderId;
     /**
-     * 充值时间
+     * 渠道标识
      */
-    private LocalDateTime rechargeTime;
-
+    private String agentKey;
     /**
-     * 订单ID
+     * 回传策略 id
      */
-    private String orderId;
-
+    private Long backPolicyId;
     /**
-     * 渠道号
+     * 订单金额(分)
      */
-    private String channel;
-
+    private Long rechargeMoney;
     /**
      * 支付状态,0 : 预下单, 1 : 待支付,2 : 支付成功,-1 : 已取消
      */
     private Integer orderStatus;
 
+    private LocalDateTime regTime;
+    /**
+     * 下单时间
+     */
+    private LocalDateTime createTime;
     /**
      * 支付时间
      */
@@ -75,12 +61,6 @@ public class TencentOrderAppRpcDTO implements Serializable {
     private String roleId;
 
     private String roleName;
-
-    /**
-     * 数据源ID
-     */
-    private Long userActionSetId;
-
     /**
      * 用户设备mac地址
      */
@@ -110,4 +90,9 @@ public class TencentOrderAppRpcDTO implements Serializable {
      * IOS设备CAID
      */
     private String caid;
+
+    /**
+     * 数据源ID
+     */
+    private Long userActionSetId;
 }

+ 17 - 17
game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/pojo/dto/TencentRoleRegisterAppRpcDTO.java

@@ -15,45 +15,40 @@ import java.time.LocalDateTime;
 public class TencentRoleRegisterAppRpcDTO implements Serializable {
     private static final long serialVersionUID = 1L;
 
-
     /**
-     * 回传策略ID
+     * 游戏 id
      */
-    private Long backPolicyId;
+    private Long gameId;
+
     /**
      * sdk 里面的用户 id(要求唯一)
      */
     private String userId;
-    /**
-     * 游戏ID
-     */
-    private Long gameId;
 
     /**
-     * 广告账号ID
+     * 回传策略ID
      */
-    private Long adAccountId;
+    private Long backPolicyId;
+
     /**
-     * 注册时间
+     * 广告账号id
      */
-    private LocalDateTime registerTime;
+    private Long accountId;
 
     /**
-     * 渠道
+     * 渠道标识
      */
-    private String channel;
+    private String agentKey;
 
     private String roleId;
 
     private String roleName;
 
     private Long roleLevel;
-
     /**
-     * 数据源ID
+     * 激活/注册时间
      */
-    private Long userActionSetId;
-
+    private LocalDateTime registerTime;
     /**
      * 用户设备mac地址
      */
@@ -83,4 +78,9 @@ public class TencentRoleRegisterAppRpcDTO implements Serializable {
      * IOS设备CAID
      */
     private String caid;
+
+    /**
+     * 数据源ID
+     */
+    private Long userActionSetId;
 }

+ 24 - 19
game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/pojo/dto/TencentUserAppRpcDTO.java

@@ -14,42 +14,37 @@ import java.time.LocalDateTime;
 @Builder
 public class TencentUserAppRpcDTO implements Serializable {
     private static final long serialVersionUID = 1L;
+
     /**
-     * 回传策略ID
-     */
-    private Long backPolicyId;
-    /**
-     * sdk 里面的用户 id(要求唯一)
-     */
-    private String userId;
-    /**
-     * 游戏ID
+     * 游戏 id
      */
     private Long gameId;
 
     /**
-     * 广告账号ID
+     * 广告账号id
      */
-    private Long adAccountId;
+    private Long accountId;
+
     /**
-     * 注册时间
+     * 渠道标识
      */
-    private LocalDateTime registerTime;
+    private String agentKey;
 
     /**
-     * 关注时间
+     * 激活/注册时间
      */
-    private LocalDateTime subscribeTime;
+    private LocalDateTime activeTime;
 
     /**
-     * 渠道号
+     * 回传策略 id
      */
-    private String channel;
+    private Long backPolicyId;
 
     /**
-     * 数据源ID
+     * sdk 里面的用户 id(要求唯一)
      */
-    private Long userActionSetId;
+    private String userId;
+
     /**
      * 用户设备mac地址
      */
@@ -79,4 +74,14 @@ public class TencentUserAppRpcDTO implements Serializable {
      * IOS设备CAID
      */
     private String caid;
+
+    /**
+     * 注册ip
+     */
+    private String regIp;
+
+    /**
+     * 数据源ID
+     */
+    private Long userActionSetId;
 }

+ 7 - 8
game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/rpc/ITencentAppBackRpc.java

@@ -1,23 +1,22 @@
 package com.zanxiang.game.back.base.rpc;
 
-import com.zanxiang.game.back.base.pojo.dto.*;
+import com.zanxiang.game.back.base.pojo.dto.TencentAppOrderBackQueryRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TencentOrderAppRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TencentRoleRegisterAppRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TencentUserAppRpcDTO;
+import com.zanxiang.game.back.base.pojo.vo.OrderBackQueryRpcVO;
 import com.zanxiang.module.util.pojo.ResultVO;
 
 /**
  * 腾讯数据源回传
  */
 public interface ITencentAppBackRpc {
-    /**
-     * 订单回传
-     */
+
     ResultVO<Boolean> backOrder(TencentOrderAppRpcDTO dto);
 
-    /**
-     * 用户回传
-     */
     ResultVO<Boolean> backUser(TencentUserAppRpcDTO dto);
 
     ResultVO<Boolean> backRoleRegister(TencentRoleRegisterAppRpcDTO dto);
 
-    ResultVO<String> queryUserAgentFromCallback(TencentAppApiUserAgentQueryRpcDTO dto);
+    ResultVO<OrderBackQueryRpcVO> orderBackQuery(TencentAppOrderBackQueryRpcDTO dto);
 }

+ 4 - 15
game-back/game-back-base/src/main/java/com/zanxiang/game/back/base/rpc/ITtAppBackRpc.java

@@ -1,6 +1,9 @@
 package com.zanxiang.game.back.base.rpc;
 
-import com.zanxiang.game.back.base.pojo.dto.*;
+import com.zanxiang.game.back.base.pojo.dto.TtAppOrderBackQueryRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TtOrderAppRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TtRoleRegisterAppRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TtUserActiveAppRpcDTO;
 import com.zanxiang.game.back.base.pojo.vo.OrderBackQueryRpcVO;
 import com.zanxiang.module.util.pojo.ResultVO;
 
@@ -25,22 +28,8 @@ public interface ITtAppBackRpc {
      */
     ResultVO<Boolean> roleRegisterReport(TtRoleRegisterAppRpcDTO dto);
 
-
-
-    /**
-     * 用户是否回传
-     */
-    ResultVO<Boolean> userBackQuery(TtAppUserBackQueryRpcDTO dto);
-
     /**
      * 订单是否回传
      */
     ResultVO<OrderBackQueryRpcVO> orderBackQuery(TtAppOrderBackQueryRpcDTO dto);
-
-    /**
-     * 创角是否回传
-     */
-    ResultVO<Boolean> roleRegisterBackQuery(TtAppRoleRegisterBackQueryRpcDTO dto);
-
-    ResultVO<String> queryUserAgentFromCallback(TtAppUserAgentQueryRpcDTO dto);
 }

+ 1 - 1
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/GameBackApplication.java

@@ -18,7 +18,7 @@ public class GameBackApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(GameBackApplication.class, args);
-        System.out.println("微信小游戏投腾讯广告新增openId监测链接匹配-02 (´・・)ノ(._.`)  \n" +
+        System.out.println("新增腾讯APP回传业务逻辑-补充参数, 数据源id (´・・)ノ(._.`)  \n" +
                 " ______  __     __     \n" +
                 "/_____/\\/__/\\ /__/\\    \n" +
                 "\\:::__\\/\\ \\::\\\\:.\\ \\   \n" +

+ 60 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/controller/TencentAppController.java

@@ -0,0 +1,60 @@
+package com.zanxiang.game.back.serve.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.zanxiang.erp.security.annotation.PreAuthorize;
+import com.zanxiang.game.back.serve.pojo.dto.GameTencentAppOrderDTO;
+import com.zanxiang.game.back.serve.pojo.dto.GameTencentAppUserDTO;
+import com.zanxiang.game.back.serve.pojo.vo.GameTencentAppOrderSplitLogVO;
+import com.zanxiang.game.back.serve.pojo.vo.GameTencentAppOrderVO;
+import com.zanxiang.game.back.serve.pojo.vo.GameTencentUserVO;
+import com.zanxiang.game.back.serve.service.IGameTencentAppOrderService;
+import com.zanxiang.game.back.serve.service.IGameTencentAppOrderSplitLogService;
+import com.zanxiang.game.back.serve.service.IGameTencentAppUserService;
+import com.zanxiang.module.util.pojo.ResultVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author : lingfeng
+ * @time : 2025-05-08
+ * @description : 腾讯APP回传
+ */
+@RestController
+@RequestMapping("/tencentApp")
+@Api("腾讯APP回传")
+public class TencentAppController {
+
+    @Autowired
+    private IGameTencentAppOrderService gameTencentAppOrderService;
+
+    @Autowired
+    private IGameTencentAppOrderSplitLogService gameTencentAppOrderSplitLogService;
+
+    @Autowired
+    private IGameTencentAppUserService gameTencentAppUserService;
+
+    @PreAuthorize(permissionKey = "gameBack:tencentApp:orderLogs")
+    @PostMapping("/orderLogs")
+    @ApiOperation(value = "腾讯订单回传日志列表")
+    public ResultVO<IPage<GameTencentAppOrderVO>> tencentAppOrderList(@RequestBody GameTencentAppOrderDTO dto) {
+        return ResultVO.ok(gameTencentAppOrderService.gameTencentAppOrderLogList(dto));
+    }
+
+    @PreAuthorize(permissionKey = "gameBack:tencentApp:orderLogs")
+    @GetMapping("/orderSplitList/{orderId}")
+    public ResultVO<List<GameTencentAppOrderSplitLogVO>> tencentOrderSplitList(@PathVariable("orderId") String orderId) {
+        return ResultVO.ok(gameTencentAppOrderSplitLogService.listByOrderNo(Collections.singletonList(orderId)));
+    }
+
+    @PreAuthorize(permissionKey = "gameBack:tencentApp:userLogs")
+    @PostMapping("/userLogs")
+    @ApiOperation(value = "腾讯用户回传日志列表")
+    public ResultVO<IPage<GameTencentUserVO>> tencentAppUserList(@RequestBody GameTencentAppUserDTO dto) {
+        return ResultVO.ok(gameTencentAppUserService.tencentUserLogList(dto));
+    }
+}

+ 78 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/dto/GameTencentAppOrderDTO.java

@@ -0,0 +1,78 @@
+package com.zanxiang.game.back.serve.pojo.dto;
+
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppOrder;
+import com.zanxiang.module.web.pojo.BaseListDTO;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDate;
+
+/**
+ * 头条订单上报日志
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class GameTencentAppOrderDTO extends BaseListDTO<GameTencentAppOrder> {
+
+    @ApiModelProperty("用户ID")
+    private String userId;
+
+    @ApiModelProperty("用户设备mac地址")
+    private String mac;
+
+    @ApiModelProperty("设备唯一编号IMEI")
+    private String imei;
+
+    @ApiModelProperty("设备OAID")
+    private String oaid;
+
+    @ApiModelProperty("安卓id, (仅安卓设备才有值)")
+    private String androidId;
+
+    @ApiModelProperty("IOS设备IDFA")
+    private String idfa;
+
+    @ApiModelProperty("IOS设备CAID")
+    private String caid;
+
+    @ApiModelProperty("游戏ID")
+    private Long gameId;
+
+    @ApiModelProperty("广告账号ID")
+    private Long accountId;
+
+    @ApiModelProperty("渠道标识")
+    private String agentKey;
+
+    @ApiModelProperty("订单编号")
+    private String orderNo;
+
+    @ApiModelProperty("支付状态,0 : 预下单, 1 : 待支付,2 : 支付成功,-1 : 已取消")
+    private Integer orderStatus;
+
+    @ApiModelProperty("注册时间")
+    private LocalDate regTimeBegin;
+
+    @ApiModelProperty("注册时间")
+    private LocalDate regTimeEnd;
+
+    @ApiModelProperty("回传状态 -1:回传失败;0:未回传;1:回传")
+    private Integer backStatus;
+
+    @ApiModelProperty("角色名")
+    private String roleName;
+
+    @ApiModelProperty("充值到支付的间隔时间(分)")
+    private Long regPayIntervalTimeMin;
+
+    @ApiModelProperty("充值到支付的间隔时间(分)")
+    private Long regPayIntervalTimeMax;
+
+    @ApiModelProperty("是否是首单")
+    private Boolean isFirstOrder;
+}

+ 62 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/dto/GameTencentAppUserDTO.java

@@ -0,0 +1,62 @@
+package com.zanxiang.game.back.serve.pojo.dto;
+
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppUser;
+import com.zanxiang.module.web.pojo.BaseListDTO;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDate;
+
+/**
+ * @author : lingfeng
+ * @time : 2025-05-07
+ * @description : 腾讯APP订单上报日志
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class GameTencentAppUserDTO extends BaseListDTO<GameTencentAppUser> {
+
+    @ApiModelProperty("用户ID")
+    private String userId;
+
+    @ApiModelProperty("用户设备mac地址")
+    private String mac;
+
+    @ApiModelProperty("设备唯一编号IMEI")
+    private String imei;
+
+    @ApiModelProperty("设备OAID")
+    private String oaid;
+
+    @ApiModelProperty("安卓id, (仅安卓设备才有值)")
+    private String androidId;
+
+    @ApiModelProperty("IOS设备IDFA")
+    private String idfa;
+
+    @ApiModelProperty("IOS设备CAID")
+    private String caid;
+
+    @ApiModelProperty("游戏ID")
+    private Long gameId;
+
+    @ApiModelProperty("广告账号ID")
+    private Long accountId;
+
+    @ApiModelProperty("渠道标识")
+    private String agentKey;
+
+    @ApiModelProperty("回传状态")
+    private Integer backStatus;
+
+    @ApiModelProperty("注册时间")
+    private LocalDate activeTimeBegin;
+
+    @ApiModelProperty("注册时间")
+    private LocalDate activeTimeEnd;
+}

+ 32 - 30
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameTencentAppBackLog.java

@@ -30,27 +30,10 @@ public class GameTencentAppBackLog implements Serializable {
     @TableId(value = "id", type = IdType.AUTO)
     private Long id;
 
-    private String userId;
-
-    /**
-     * 游戏id
-     */
-    private Long gameId;
-
     /**
-     * 广告账号ID
+     * 用户id
      */
-    private Long adAccountId;
-
-    /**
-     * 数据源ID
-     */
-    private Long userActionSetId;
-
-    /**
-     * 行为发生时,客户端的时间点
-     */
-    private LocalDateTime actionTime;
+    private String userId;
 
     /**
      * 用户设备mac地址
@@ -83,29 +66,48 @@ public class GameTencentAppBackLog implements Serializable {
     private String caid;
 
     /**
-     * 行为类型:(REGISTER/PURCHASE/COMPLETE_ORDER)
+     * 游戏id
      */
-    private String actionType;
+    private Long gameId;
 
     /**
-     * 订单ID
+     * 广告账号ID
      */
-    private String orderId;
+    private Long accountId;
 
     /**
-     * 回传时间
+     * 事件类型
      */
-    private LocalDateTime createTime;
+    private String eventType;
+
+    /**
+     * 触发回传的日志 id
+     */
+    private Long eventLogId;
+
+    /**
+     * 支付回传的支付金额
+     */
+    private Long payAmount;
 
     /**
-     * 回传日志
+     * 回传状态(0:成功、-1:失败)
      */
-    private String backLog;
+    private Integer backStatus;
 
     /**
-     * 行为参数
+     * 回传失败的错误日志
      */
-    private String actionParam;
+    private String errMsg;
 
+    /**
+     * 回传时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 数据源ID
+     */
+    private Long userActionSetId;
 
-}
+}

+ 45 - 52
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameTencentAppOrder.java

@@ -3,13 +3,14 @@ package com.zanxiang.game.back.serve.pojo.entity;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
-import java.io.Serializable;
-import java.time.LocalDateTime;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
 /**
  * <p>
  * 游戏腾讯APP订单表
@@ -30,82 +31,80 @@ public class GameTencentAppOrder implements Serializable {
     @TableId(value = "id", type = IdType.AUTO)
     private Long id;
 
-    private String userId;
-
     /**
-     * 渠道号
+     * 用户id
      */
-    private String channel;
+    private String userId;
 
     /**
-     * 游戏ID
+     * 用户设备mac地址
      */
-    private Long gameId;
+    private String mac;
 
     /**
-     * 广告账号ID
+     * 设备唯一编号IMEI
      */
-    private Long adAccountId;
+    private String imei;
 
     /**
-     * 注册时间
+     * 设备OAID
      */
-    private LocalDateTime registerTime;
+    private String oaid;
 
     /**
-     * 关注时间
+     * 安卓id, (仅安卓设备才有值)
      */
-    private LocalDateTime subscribeTime;
+    private String androidId;
 
     /**
-     * 充值金额(分)
+     * IOS设备IDFA
      */
-    private Long rechargeMoney;
+    private String idfa;
 
     /**
-     * 充值时间
+     * IOS设备CAID
      */
-    private LocalDateTime rechargeTime;
+    private String caid;
 
     /**
-     * 订单ID
+     * 游戏ID
      */
-    private String orderId;
+    private Long gameId;
 
     /**
-     * 用户设备mac地址
+     * 广告账号_id
      */
-    private String mac;
+    private Long accountId;
 
     /**
-     * 设备唯一编号IMEI
+     * 回传策略id
      */
-    private String imei;
+    private Long backPolicyId;
 
     /**
-     * 设备OAID
+     * 渠道标识
      */
-    private String oaid;
+    private String agentKey;
 
     /**
-     * 安卓id, (仅安卓设备才有值)
+     * 订单编号
      */
-    private String androidId;
+    private String orderNo;
 
     /**
-     * IOS设备IDFA
+     * 订单金额(分)
      */
-    private String idfa;
+    private Long amount;
 
     /**
-     * IOS设备CAID
+     * 支付状态,0 : 预下单, 1 : 待支付,2 : 支付成功,-1 : 已取消
      */
-    private String caid;
+    private Integer orderStatus;
 
     /**
-     * 支付状态,0 : 预下单, 1 : 待支付,2 : 支付成功,-1 : 已取消
+     * 下单时间
      */
-    private Integer orderStatus;
+    private LocalDateTime createTime;
 
     /**
      * 支付时间
@@ -113,33 +112,23 @@ public class GameTencentAppOrder implements Serializable {
     private LocalDateTime payTime;
 
     /**
-     * 0:未回传;1:回传
+     * 回传状态
      */
-    private Integer isBack;
-
-    private LocalDateTime createTime;
-
-    private LocalDateTime updateTime;
-
-    private Long updateBy;
+    private Integer backStatus;
 
     /**
-     * 回传日志
+     * 注册时间
      */
-    private String backLog;
+    private LocalDateTime regTime;
 
     /**
-     * 回传策略id
+     * 角色id
      */
-    private Long backPolicyId;
+    private String roleId;
 
     /**
-     * 数据源ID
+     * 角色名称
      */
-    private Long userActionSetId;
-
-    private String roleId;
-
     private String roleName;
 
     /**
@@ -157,5 +146,9 @@ public class GameTencentAppOrder implements Serializable {
      */
     private String backMsg;
 
+    /**
+     * 数据源ID
+     */
+    private Long userActionSetId;
 
-}
+}

+ 1 - 31
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameTencentAppOrderSplitLog.java

@@ -31,54 +31,24 @@ public class GameTencentAppOrderSplitLog implements Serializable {
     @TableId(value = "id", type = IdType.AUTO)
     private Long id;
 
-    private String userId;
-
-    /**
-     * 回传日期
-     */
     private LocalDate backDay;
 
-    /**
-     * 订单编号
-     */
     private String orderNo;
 
-    /**
-     * 回传序号
-     */
     private Integer backIndex;
 
-    /**
-     * 总计拆成几单
-     */
     private Integer backCount;
 
-    /**
-     * 拆分的回传金额
-     */
     private Long splitMoney;
 
-    /**
-     * 回传时间
-     */
     private LocalDateTime backTime;
 
-    /**
-     * 真实的回传时间
-     */
     private LocalDateTime executeTime;
 
-    /**
-     * 回传状态
-     */
     private Integer backStatus;
 
-    private LocalDateTime createTime;
-
-    /**
-     * 回传失败消息
-     */
     private String backErrorMsg;
 
+    private LocalDateTime createTime;
 
 }

+ 33 - 29
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameTencentAppRoleRegister.java

@@ -30,27 +30,15 @@ public class GameTencentAppRoleRegister implements Serializable {
     @TableId(value = "id", type = IdType.AUTO)
     private Long id;
 
-    private String userId;
-
-    /**
-     * 渠道号
-     */
-    private String channel;
-
-    /**
-     * 游戏ID
-     */
-    private Long gameId;
-
     /**
-     * 广告账号ID
+     * 回传策略id
      */
-    private Long adAccountId;
+    private Long backPolicyId;
 
     /**
-     * 注册时间
+     * 用户id
      */
-    private LocalDateTime registerTime;
+    private String userId;
 
     /**
      * 用户设备mac地址
@@ -83,37 +71,53 @@ public class GameTencentAppRoleRegister implements Serializable {
     private String caid;
 
     /**
-     * 0:未回传;1:回传
+     * 游戏ID
      */
-    private Integer isBack;
-
-    private LocalDateTime createTime;
+    private Long gameId;
 
     /**
-     * 回传日志
+     * 广告账号_id
      */
-    private String backLog;
+    private Long accountId;
 
     /**
-     * 回传策略id
+     * 渠道标识
      */
-    private Long backPolicyId;
+    private String agentKey;
 
     /**
-     * 数据源ID
+     * 角色 id
      */
-    private Long userActionSetId;
-
     private String roleId;
 
+    /**
+     * 角色名称
+     */
     private String roleName;
 
+    /**
+     * 角色等级
+     */
     private Long roleLevel;
 
     /**
-     * 回传信息
+     * 创角时间
      */
-    private String backMsg;
+    private LocalDateTime registerTime;
 
+    /**
+     * 回传状态
+     */
+    private Integer backStatus;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 数据源ID
+     */
+    private Long userActionSetId;
 
 }

+ 25 - 34
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/GameTencentAppUser.java

@@ -30,32 +30,10 @@ public class GameTencentAppUser implements Serializable {
     @TableId(value = "id", type = IdType.AUTO)
     private Long id;
 
-    private String userId;
-
-    /**
-     * 渠道号
-     */
-    private String channel;
-
-    /**
-     * 游戏ID
-     */
-    private Long gameId;
-
-    /**
-     * 广告账号ID
-     */
-    private Long adAccountId;
-
-    /**
-     * 注册时间
-     */
-    private LocalDateTime registerTime;
-
     /**
-     * 关注时间
+     * 用户id
      */
-    private LocalDateTime subscribeTime;
+    private String userId;
 
     /**
      * 用户设备mac地址
@@ -88,30 +66,43 @@ public class GameTencentAppUser implements Serializable {
     private String caid;
 
     /**
-     * 0:未回传;1:回传;-1:回传失败
+     * 游戏ID
      */
-    private Integer isBack;
+    private Long gameId;
 
-    private LocalDateTime createTime;
+    /**
+     * 广告账号_id
+     */
+    private Long accountId;
 
-    private LocalDateTime updateTime;
+    /**
+     * 渠道标识
+     */
+    private String agentKey;
 
-    private Long updateBy;
+    /**
+     * 激活/注册时间
+     */
+    private LocalDateTime activeTime;
 
     /**
-     * 回传日志
+     * 回传状态
      */
-    private String backLog;
+    private Integer backStatus;
 
     /**
-     * 回传策略id
+     * 创建时间
      */
-    private Long backPolicyId;
+    private LocalDateTime createTime;
+
+    /**
+     * 注册IP
+     */
+    private String ip;
 
     /**
      * 数据源ID
      */
     private Long userActionSetId;
 
-
 }

+ 33 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/vo/GameTencentAppOrderSplitLogVO.java

@@ -0,0 +1,33 @@
+package com.zanxiang.game.back.serve.pojo.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+@Data
+public class GameTencentAppOrderSplitLogVO {
+
+    private Long id;
+
+    private LocalDate backDay;
+
+    private String orderNo;
+
+    private Integer backIndex;
+
+    private Integer backCount;
+
+    private BigDecimal splitMoney;
+
+    private LocalDateTime backTime;
+
+    private LocalDateTime executeTime;
+
+    private Integer backStatus;
+
+    private String backErrorMsg;
+
+    private LocalDateTime createTime;
+}

+ 101 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/vo/GameTencentAppOrderVO.java

@@ -0,0 +1,101 @@
+package com.zanxiang.game.back.serve.pojo.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 腾讯订单上报日志
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class GameTencentAppOrderVO {
+
+    @ApiModelProperty("主键ID")
+    private Long id;
+
+    @ApiModelProperty("用户ID")
+    private String userId;
+
+    @ApiModelProperty("用户设备mac地址")
+    private String mac;
+
+    @ApiModelProperty("设备唯一编号IMEI")
+    private String imei;
+
+    @ApiModelProperty("设备OAID")
+    private String oaid;
+
+    @ApiModelProperty("安卓id, (仅安卓设备才有值)")
+    private String androidId;
+
+    @ApiModelProperty("IOS设备IDFA")
+    private String idfa;
+
+    @ApiModelProperty("IOS设备CAID")
+    private String caid;
+
+    @ApiModelProperty("游戏ID")
+    private Long gameId;
+
+    @ApiModelProperty("广告账号ID")
+    private Long accountId;
+
+    @ApiModelProperty("回传策略ID")
+    private Long backPolicyId;
+
+    @ApiModelProperty("渠道标识")
+    private String agentKey;
+
+    @ApiModelProperty("渠道名称")
+    private String agentName;
+
+    @ApiModelProperty("订单编号")
+    private String orderNo;
+
+    @ApiModelProperty("订单金额(分)")
+    private Long amount;
+
+    @ApiModelProperty("支付状态,0 : 预下单, 1 : 待支付,2 : 支付成功,-1 : 已取消")
+    private Integer orderStatus;
+
+    @ApiModelProperty("下单时间")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("支付时间")
+    private LocalDateTime payTime;
+
+    @ApiModelProperty("注册时间")
+    private LocalDateTime regTime;
+
+    @ApiModelProperty("回传状态 -1:回传失败;0:未回传;1:回传")
+    private Integer backStatus;
+
+    @ApiModelProperty("角色ID")
+    private String roleId;
+
+    @ApiModelProperty("角色名")
+    private String roleName;
+
+    @ApiModelProperty("注册到付费的间隔时间")
+    private String regPayIntervalTime;
+
+    @ApiModelProperty("是否是首单")
+    private Boolean isFirstOrder;
+
+    @ApiModelProperty("回传金额")
+    private Long backMoney;
+
+    @ApiModelProperty("回传日志")
+    private String backMsg;
+
+    @ApiModelProperty("回传拆分订单")
+    private List<GameTencentAppOrderSplitLogVO> splitOrderList;
+}

+ 146 - 85
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/rpc/impl/TencentAppBackRpcImpl.java

@@ -2,36 +2,56 @@ package com.zanxiang.game.back.serve.rpc.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.zanxiang.game.back.base.pojo.dto.*;
+import com.zanxiang.game.back.base.pojo.dto.TencentAppOrderBackQueryRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TencentOrderAppRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TencentRoleRegisterAppRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TencentUserAppRpcDTO;
 import com.zanxiang.game.back.base.pojo.enums.OrderStatusEnum;
+import com.zanxiang.game.back.base.pojo.vo.OrderBackQueryRpcVO;
 import com.zanxiang.game.back.base.rpc.ITencentAppBackRpc;
-import com.zanxiang.game.back.serve.pojo.entity.*;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppOrder;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppOrderSplitLog;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppRoleRegister;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppUser;
 import com.zanxiang.game.back.serve.pojo.enums.BackStatusEnum;
-import com.zanxiang.game.back.serve.service.IGameTencentAppCallbackService;
 import com.zanxiang.game.back.serve.service.IGameTencentAppOrderService;
+import com.zanxiang.game.back.serve.service.IGameTencentAppOrderSplitLogService;
 import com.zanxiang.game.back.serve.service.IGameTencentAppRoleRegisterService;
 import com.zanxiang.game.back.serve.service.IGameTencentAppUserService;
 import com.zanxiang.module.util.JsonUtil;
 import com.zanxiang.module.util.pojo.ResultVO;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
 
 import java.time.LocalDateTime;
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 @Slf4j
 @DubboService
 public class TencentAppBackRpcImpl implements ITencentAppBackRpc {
+
     @Autowired
-    private IGameTencentAppUserService gameTencentAppUserService;
+    private RedisTemplate<String, Object> redisTemplate;
+
     @Autowired
-    private IGameTencentAppRoleRegisterService gameTencentAppRoleRegisterService;
+    private IGameTencentAppUserService gameTencentAppUserService;
+
     @Autowired
     private IGameTencentAppOrderService gameTencentAppOrderService;
+
+    @Autowired
+    private IGameTencentAppOrderSplitLogService gameTencentAppOrderSplitLogService;
+
     @Autowired
-    private IGameTencentAppCallbackService gameTencentAppCallbackService;
+    private IGameTencentAppRoleRegisterService gameTencentAppRoleRegisterService;
 
     @Override
     public ResultVO<Boolean> backUser(TencentUserAppRpcDTO dto) {
@@ -54,34 +74,32 @@ public class TencentAppBackRpcImpl implements ITencentAppBackRpc {
         if (StringUtils.isBlank(dto.getCaid())) {
             dto.setCaid("");
         }
-        if (StringUtils.isBlank(dto.getImei())
+        if (StringUtils.isBlank(dto.getUserId()) || (StringUtils.isBlank(dto.getImei())
                 && StringUtils.isBlank(dto.getOaid())
                 && StringUtils.isBlank(dto.getAndroidId())
                 && StringUtils.isBlank(dto.getIdfa())
-                && StringUtils.isBlank(dto.getCaid())) {
+                && StringUtils.isBlank(dto.getCaid()))) {
             return ResultVO.fail("找不到用户唯一标识");
         }
-        GameTencentAppUser gameTencentUser = GameTencentAppUser.builder()
-                .adAccountId(dto.getAdAccountId())
-                .gameId(dto.getGameId())
+        GameTencentAppUser userLog = GameTencentAppUser.builder()
                 .userId(dto.getUserId())
-                .channel(dto.getChannel())
-                .subscribeTime(dto.getSubscribeTime())
-                .registerTime(dto.getRegisterTime())
                 .mac(dto.getMac())
                 .imei(dto.getImei())
                 .oaid(dto.getOaid())
                 .androidId(dto.getAndroidId())
                 .idfa(dto.getIdfa())
                 .caid(dto.getCaid())
-                .isBack(BackStatusEnum.NO.getBackStatus())
-                .userActionSetId(dto.getUserActionSetId())
+                .gameId(dto.getGameId())
+                .accountId(dto.getAccountId())
+                .agentKey(dto.getAgentKey())
+                .activeTime(dto.getActiveTime())
+                .ip(dto.getRegIp())
+                .backStatus(BackStatusEnum.NO.getBackStatus())
                 .createTime(LocalDateTime.now())
+                .userActionSetId(dto.getUserActionSetId())
                 .build();
-        gameTencentAppUserService.save(gameTencentUser);
-        return ResultVO.ok(true);
-        // 激活现在默认不回传了,等创角的时候一起回传
-        // return ResultVO.ok(gameTencentUserService.userBack(gameTencentUser, false));
+        gameTencentAppUserService.save(userLog);
+        return ResultVO.ok(gameTencentAppUserService.userBack(userLog, Boolean.FALSE));
     }
 
     @Override
@@ -105,14 +123,14 @@ public class TencentAppBackRpcImpl implements ITencentAppBackRpc {
         if (StringUtils.isBlank(dto.getCaid())) {
             dto.setCaid("");
         }
-        if (StringUtils.isBlank(dto.getImei())
+        if (StringUtils.isBlank(dto.getUserId()) || (StringUtils.isBlank(dto.getImei())
                 && StringUtils.isBlank(dto.getOaid())
                 && StringUtils.isBlank(dto.getAndroidId())
                 && StringUtils.isBlank(dto.getIdfa())
-                && StringUtils.isBlank(dto.getCaid())) {
+                && StringUtils.isBlank(dto.getCaid()))) {
             return ResultVO.fail("找不到用户唯一标识");
         }
-        GameTencentAppRoleRegister roleRegister;
+        GameTencentAppRoleRegister roleRegisterLog;
         GameTencentAppRoleRegister oldRole = gameTencentAppRoleRegisterService.getOne(new LambdaQueryWrapper<GameTencentAppRoleRegister>()
                 .eq(GameTencentAppRoleRegister::getGameId, dto.getGameId())
                 .eq(GameTencentAppRoleRegister::getUserId, dto.getUserId())
@@ -120,7 +138,7 @@ public class TencentAppBackRpcImpl implements ITencentAppBackRpc {
                 .last("limit 1")
         );
         if (oldRole != null) {
-            roleRegister = oldRole;
+            roleRegisterLog = oldRole;
             if (dto.getRoleLevel() != null && (oldRole.getRoleLevel() == null || oldRole.getRoleLevel() < dto.getRoleLevel())) {
                 gameTencentAppRoleRegisterService.update(new LambdaUpdateWrapper<GameTencentAppRoleRegister>()
                         .set(GameTencentAppRoleRegister::getRoleLevel, dto.getRoleLevel())
@@ -128,35 +146,34 @@ public class TencentAppBackRpcImpl implements ITencentAppBackRpc {
                         .eq(GameTencentAppRoleRegister::getId, oldRole.getId())
                 );
             }
-            if (Objects.equals(oldRole.getIsBack(), BackStatusEnum.SUCCESS.getBackStatus())) {
+            if (Objects.equals(oldRole.getBackStatus(), BackStatusEnum.SUCCESS.getBackStatus())) {
                 // 创角已回传。不重复传了
                 return ResultVO.ok(true);
             }
         } else {
-            roleRegister = GameTencentAppRoleRegister.builder()
+            roleRegisterLog = GameTencentAppRoleRegister.builder()
                     .backPolicyId(dto.getBackPolicyId())
-                    .channel(dto.getChannel())
                     .userId(dto.getUserId())
-                    .gameId(dto.getGameId())
-                    .adAccountId(dto.getAdAccountId())
-                    .registerTime(dto.getRegisterTime())
                     .mac(dto.getMac())
                     .imei(dto.getImei())
                     .oaid(dto.getOaid())
                     .androidId(dto.getAndroidId())
                     .idfa(dto.getIdfa())
                     .caid(dto.getCaid())
-                    .isBack(BackStatusEnum.NO.getBackStatus())
-                    .userActionSetId(dto.getUserActionSetId())
-                    .createTime(LocalDateTime.now())
+                    .gameId(dto.getGameId())
+                    .accountId(dto.getAccountId())
+                    .agentKey(dto.getAgentKey())
                     .roleId(dto.getRoleId())
                     .roleName(dto.getRoleName())
                     .roleLevel(dto.getRoleLevel())
+                    .registerTime(dto.getRegisterTime())
+                    .backStatus(BackStatusEnum.NO.getBackStatus())
+                    .createTime(LocalDateTime.now())
+                    .userActionSetId(dto.getUserActionSetId())
                     .build();
-            gameTencentAppRoleRegisterService.save(roleRegister);
+            gameTencentAppRoleRegisterService.save(roleRegisterLog);
         }
-        // return ResultVO.ok(gameTencentAppRoleRegisterService.roleRegisterBack(roleRegister));
-        return ResultVO.ok(true);
+        return ResultVO.ok(gameTencentAppRoleRegisterService.callback(roleRegisterLog));
     }
 
     @Override
@@ -185,62 +202,106 @@ public class TencentAppBackRpcImpl implements ITencentAppBackRpc {
         if (StringUtils.isBlank(dto.getCaid())) {
             dto.setCaid("");
         }
-        if (StringUtils.isBlank(dto.getImei())
+        if (StringUtils.isBlank(dto.getUserId()) || (StringUtils.isBlank(dto.getImei())
                 && StringUtils.isBlank(dto.getOaid())
                 && StringUtils.isBlank(dto.getAndroidId())
                 && StringUtils.isBlank(dto.getIdfa())
-                && StringUtils.isBlank(dto.getCaid())) {
+                && StringUtils.isBlank(dto.getCaid()))) {
             return ResultVO.fail("找不到用户唯一标识");
         }
-        boolean isFirstOrder = gameTencentAppOrderService.getOne(new LambdaQueryWrapper<GameTencentAppOrder>()
-                .select(GameTencentAppOrder::getOrderId)
-                .eq(GameTencentAppOrder::getGameId, dto.getGameId())
-                .eq(GameTencentAppOrder::getAdAccountId, dto.getAdAccountId())
-                .eq(GameTencentAppOrder::getMac, dto.getMac())
-                .eq(GameTencentAppOrder::getImei, dto.getImei())
-                .eq(GameTencentAppOrder::getOaid, dto.getOaid())
-                .eq(GameTencentAppOrder::getAndroidId, dto.getAndroidId())
-                .eq(GameTencentAppOrder::getIdfa, dto.getIdfa())
-                .eq(GameTencentAppOrder::getCaid, dto.getCaid())
-                .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
-                .last("limit 1")
-        ) == null;
-        //订单保存
-        GameTencentAppOrder gameTencentOrder = GameTencentAppOrder.builder()
-                .adAccountId(dto.getAdAccountId())
-                .userId(dto.getUserId())
-                .gameId(dto.getGameId())
-                .orderId(dto.getOrderId())
-                .channel(dto.getChannel())
-                .rechargeMoney(dto.getRechargeMoney())
-                .rechargeTime(dto.getRechargeTime())
-                .subscribeTime(dto.getSubscribeTime())
-                .registerTime(dto.getRegisterTime())
-                .mac(dto.getMac())
-                .imei(dto.getImei())
-                .oaid(dto.getOaid())
-                .androidId(dto.getAndroidId())
-                .idfa(dto.getIdfa())
-                .caid(dto.getCaid())
-                .orderStatus(dto.getOrderStatus())
-                .payTime(dto.getPayTime())
-                .createTime(LocalDateTime.now())
-                .isBack(BackStatusEnum.NO.getBackStatus())
-                .backPolicyId(dto.getBackPolicyId())
-                .userActionSetId(dto.getUserActionSetId())
-                .roleId(dto.getRoleId())
-                .roleName(dto.getRoleName())
-                .isFirstOrder(isFirstOrder)
-                .build();
-        gameTencentAppOrderService.save(gameTencentOrder);
-        return ResultVO.ok(true);
-        // return ResultVO.ok(gameTencentAppOrderService.orderBack(gameTencentOrder));
+        // 此处加锁防止 cp 方调用过快,导致查询回传结果时判断逻辑没走完
+        String lockKey = com.zanxiang.game.back.base.ServerInfo.SERVER_NAME + ":TencentAppOrderBack:" + dto.getGameId() + ":" + dto.getOrderId();
+        redisTemplate.opsForValue().set(lockKey, dto.getOrderId(), 2L, TimeUnit.MINUTES);
+        try {
+            GameTencentAppOrder orderLog = GameTencentAppOrder.builder()
+                    .userId(dto.getUserId())
+                    .mac(dto.getMac())
+                    .imei(dto.getImei())
+                    .oaid(dto.getOaid())
+                    .androidId(dto.getAndroidId())
+                    .idfa(dto.getIdfa())
+                    .caid(dto.getCaid())
+                    .gameId(dto.getGameId())
+                    .backPolicyId(dto.getBackPolicyId())
+                    .accountId(dto.getAccountId())
+                    .agentKey(dto.getAgentKey())
+                    .regTime(dto.getRegTime())
+                    .orderNo(dto.getOrderId())
+                    .amount(dto.getRechargeMoney())
+                    .orderStatus(dto.getOrderStatus())
+                    .createTime(dto.getCreateTime())
+                    .payTime(dto.getPayTime())
+                    .backStatus(BackStatusEnum.NO.getBackStatus())
+                    .roleId(dto.getRoleId())
+                    .roleName(dto.getRoleName())
+                    .userActionSetId(dto.getUserActionSetId())
+                    .build();
+            boolean isFirstOrder = gameTencentAppOrderService.getOne(new LambdaQueryWrapper<GameTencentAppOrder>()
+                    .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                    .eq(GameTencentAppOrder::getUserId, orderLog.getUserId())
+                    .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                    .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .last("limit 1")
+            ) == null;
+            orderLog.setIsFirstOrder(isFirstOrder);
+            gameTencentAppOrderService.save(orderLog);
+            return ResultVO.ok(gameTencentAppOrderService.callback(orderLog));
+        } finally {
+            redisTemplate.delete(lockKey);
+        }
     }
 
     @Override
-    public ResultVO<String> queryUserAgentFromCallback(TencentAppApiUserAgentQueryRpcDTO dto) {
-        /*GameTencentAppCallback callback = gameTencentAppCallbackService.getUserCallback(dto.getGameId(), dto.getImei(), dto.getOaid(), dto.getAndroidId(), dto.getIdfa(), dto.getCaid());
-        return ResultVO.ok(callback == null ? null : callback.getAgentKey());*/
-        return ResultVO.ok(null);
+    public ResultVO<OrderBackQueryRpcVO> orderBackQuery(TencentAppOrderBackQueryRpcDTO dto) {
+        log.error("腾讯APP订单回传结果查询:{}", JsonUtil.toString(dto));
+        GameTencentAppOrder orderLog = queryOrder(dto);
+        if (orderLog == null) {
+            try {
+                Thread.sleep(15 * 1000L);
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+            orderLog = queryOrder(dto);
+        }
+        if (orderLog == null) {
+            return ResultVO.ok(OrderBackQueryRpcVO.builder()
+                    .doBack(Boolean.FALSE)
+                    .backMsg("回传异常,找不到订单:" + dto.getOrderId())
+                    .build());
+        }
+        List<Long> splitMoney = gameTencentAppOrderSplitLogService.list(new LambdaQueryWrapper<GameTencentAppOrderSplitLog>()
+                .eq(GameTencentAppOrderSplitLog::getOrderNo, orderLog.getOrderNo())
+                .orderByAsc(GameTencentAppOrderSplitLog::getBackIndex)
+        ).stream().map(GameTencentAppOrderSplitLog::getSplitMoney).collect(Collectors.toList());
+        OrderBackQueryRpcVO orderBackQueryRpcVO = OrderBackQueryRpcVO.builder()
+                .doBack(BackStatusEnum.getByValue(orderLog.getBackStatus()) == BackStatusEnum.SUCCESS)
+                .backMoney(CollectionUtils.isEmpty(splitMoney) ? Collections.singletonList(orderLog.getBackMoney()) : splitMoney)
+                .backMsg(orderLog.getBackMsg())
+                .build();
+        return ResultVO.ok(orderBackQueryRpcVO);
+    }
+
+    private GameTencentAppOrder queryOrder(TencentAppOrderBackQueryRpcDTO dto) {
+        String lockKey = com.zanxiang.game.back.base.ServerInfo.SERVER_NAME + ":TencentAppOrderBack:" + dto.getGameId() + ":" + dto.getOrderId();
+        int maxCount = 0;
+        while (true) {
+            if (redisTemplate.opsForValue().get(lockKey) == null) {
+                break;
+            }
+            if (maxCount++ >= 120 / 10) {
+                break;
+            }
+            try {
+                Thread.sleep(10 * 1000L);
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        return gameTencentAppOrderService.getOne(new LambdaQueryWrapper<GameTencentAppOrder>()
+                .eq(GameTencentAppOrder::getOrderNo, dto.getOrderId())
+                .eq(GameTencentAppOrder::getGameId, dto.getGameId())
+                .eq(GameTencentAppOrder::getAgentKey, dto.getAgentKey())
+                .eq(GameTencentAppOrder::getUserId, dto.getUserId())
+        );
     }
 }

+ 8 - 33
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/rpc/impl/TtAppBackRpcImpl.java

@@ -2,11 +2,17 @@ package com.zanxiang.game.back.serve.rpc.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.zanxiang.game.back.base.pojo.dto.*;
+import com.zanxiang.game.back.base.pojo.dto.TtAppOrderBackQueryRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TtOrderAppRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TtRoleRegisterAppRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TtUserActiveAppRpcDTO;
 import com.zanxiang.game.back.base.pojo.enums.OrderStatusEnum;
 import com.zanxiang.game.back.base.pojo.vo.OrderBackQueryRpcVO;
 import com.zanxiang.game.back.base.rpc.ITtAppBackRpc;
-import com.zanxiang.game.back.serve.pojo.entity.*;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineAppOrderLog;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineAppOrderSplitLog;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineAppRoleRegisterLog;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineAppUserLog;
 import com.zanxiang.game.back.serve.pojo.enums.BackStatusEnum;
 import com.zanxiang.game.back.serve.service.*;
 import com.zanxiang.module.util.JsonUtil;
@@ -44,9 +50,6 @@ public class TtAppBackRpcImpl implements ITtAppBackRpc {
     @Autowired
     private RedisTemplate<String, Object> redisTemplate;
 
-    @Autowired
-    private IGameOceanengineAppCallbackService gameOceanengineAppCallbackService;
-
     @Autowired
     private IGameOceanengineAppCallbackXgltService gameOceanengineAppCallbackXgltService;
 
@@ -253,12 +256,6 @@ public class TtAppBackRpcImpl implements ITtAppBackRpc {
         return ResultVO.ok(gameOceanengineAppRoleRegisterLogService.callback(roleRegisterLog));
     }
 
-    @Override
-    public ResultVO<Boolean> userBackQuery(TtAppUserBackQueryRpcDTO dto) {
-        log.error("头条APP用户回传结果查询:{}", JsonUtil.toString(dto));
-        return ResultVO.ok(Boolean.TRUE);
-    }
-
     @Override
     public ResultVO<OrderBackQueryRpcVO> orderBackQuery(TtAppOrderBackQueryRpcDTO dto) {
         log.error("头条APP订单回传结果查询:{}", JsonUtil.toString(dto));
@@ -300,25 +297,6 @@ public class TtAppBackRpcImpl implements ITtAppBackRpc {
         return ResultVO.ok(orderBackQueryRpcVO);
     }
 
-    @Override
-    public ResultVO<Boolean> roleRegisterBackQuery(TtAppRoleRegisterBackQueryRpcDTO dto) {
-        log.error("头条APP创角回传结果查询:{}", JsonUtil.toString(dto));
-        return ResultVO.ok(Boolean.TRUE);
-    }
-
-    @Override
-    public ResultVO<String> queryUserAgentFromCallback(TtAppUserAgentQueryRpcDTO dto) {
-        GameOceanengineAppUserLog userLog = gameOceanengineAppUserLogService.getOne(new LambdaQueryWrapper<GameOceanengineAppUserLog>()
-                .eq(GameOceanengineAppUserLog::getGameId, dto.getGameId())
-                .eq(GameOceanengineAppUserLog::getUserId, dto.getUserId())
-        );
-        if (userLog == null) {
-            return ResultVO.fail("找不到用户. gameId: " + dto.getGameId() + ", userId: " + dto.getUserId());
-        }
-        GameOceanengineAppCallback callback = gameOceanengineAppCallbackService.getUserCallback(dto.getGameId(), dto.getOaid(), dto.getMac(), dto.getIdfa(), dto.getCaid(), userLog.getIp(), userLog.getActiveTime());
-        return ResultVO.ok(callback == null ? null : callback.getAgentKey());
-    }
-
     private GameOceanengineAppOrderLog queryOrder(TtAppOrderBackQueryRpcDTO dto) {
         String lockKey = com.zanxiang.game.back.base.ServerInfo.SERVER_NAME + ":TtAppOrderBack:" + dto.getGameId() + ":" + dto.getOrderId();
         int maxCount = 0;
@@ -335,9 +313,6 @@ public class TtAppBackRpcImpl implements ITtAppBackRpc {
                 log.error(e.getMessage(), e);
             }
         }
-        // 加锁最大等待 120s
-        // distributedLockComponent.doLock(lockKey, 60, 1L, TimeUnit.SECONDS);
-
         return gameOceanengineAppOrderLogService.getOne(new LambdaQueryWrapper<GameOceanengineAppOrderLog>()
                 .eq(GameOceanengineAppOrderLog::getOrderNo, dto.getOrderId())
                 .eq(GameOceanengineAppOrderLog::getGameId, dto.getGameId())

+ 0 - 4
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameOceanengineAppCallbackService.java

@@ -4,11 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.zanxiang.game.back.serve.pojo.dto.GameOceanengineAppCallbackDTO;
 import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineAppCallback;
 
-import java.time.LocalDateTime;
-
 public interface IGameOceanengineAppCallbackService extends IService<GameOceanengineAppCallback> {
 
     boolean callback(GameOceanengineAppCallbackDTO dto);
-
-    GameOceanengineAppCallback getUserCallback(Long gameId, String oaid, String mac, String idfa, String caid, String ip, LocalDateTime regTime);
 }

+ 7 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameTencentAppOrderService.java

@@ -1,7 +1,14 @@
 package com.zanxiang.game.back.serve.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.zanxiang.game.back.serve.pojo.dto.GameTencentAppOrderDTO;
 import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppOrder;
+import com.zanxiang.game.back.serve.pojo.vo.GameTencentAppOrderVO;
 
 public interface IGameTencentAppOrderService extends IService<GameTencentAppOrder> {
+
+    boolean callback(GameTencentAppOrder orderLog);
+
+    IPage<GameTencentAppOrderVO> gameTencentAppOrderLogList(GameTencentAppOrderDTO dto);
 }

+ 6 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameTencentAppOrderSplitLogService.java

@@ -2,6 +2,12 @@ package com.zanxiang.game.back.serve.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppOrderSplitLog;
+import com.zanxiang.game.back.serve.pojo.vo.GameTencentAppOrderSplitLogVO;
+
+import java.util.Collection;
+import java.util.List;
 
 public interface IGameTencentAppOrderSplitLogService extends IService<GameTencentAppOrderSplitLog> {
+
+    List<GameTencentAppOrderSplitLogVO> listByOrderNo(Collection<String> orderNos);
 }

+ 2 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameTencentAppRoleRegisterService.java

@@ -4,4 +4,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppRoleRegister;
 
 public interface IGameTencentAppRoleRegisterService extends IService<GameTencentAppRoleRegister> {
+
+    boolean callback(GameTencentAppRoleRegister roleRegisterLog);
 }

+ 7 - 0
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameTencentAppUserService.java

@@ -1,7 +1,14 @@
 package com.zanxiang.game.back.serve.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.zanxiang.game.back.serve.pojo.dto.GameTencentAppUserDTO;
 import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppUser;
+import com.zanxiang.game.back.serve.pojo.vo.GameTencentUserVO;
 
 public interface IGameTencentAppUserService extends IService<GameTencentAppUser> {
+
+    boolean userBack(GameTencentAppUser userLog, boolean mustBack);
+
+    IPage<GameTencentUserVO> tencentUserLogList(GameTencentAppUserDTO dto);
 }

+ 1 - 31
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameOceanengineAppCallbackServiceImpl.java

@@ -1,6 +1,5 @@
 package com.zanxiang.game.back.serve.service.impl;
 
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zanxiang.game.back.serve.dao.mapper.GameOceanengineAppCallbackMapper;
 import com.zanxiang.game.back.serve.pojo.dto.GameOceanengineAppCallbackDTO;
@@ -12,9 +11,7 @@ import com.zanxiang.game.module.base.rpc.IAgentRpc;
 import com.zanxiang.module.util.DateUtil;
 import com.zanxiang.module.util.JsonUtil;
 import com.zanxiang.module.util.bean.BeanUtil;
-import com.zanxiang.module.util.encryption.Md5Util;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.apache.kafka.clients.producer.KafkaProducer;
 import org.apache.kafka.clients.producer.ProducerRecord;
@@ -24,12 +21,11 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDate;
-import java.time.LocalDateTime;
 
 @Slf4j
 @Service
 public class GameOceanengineAppCallbackServiceImpl extends ServiceImpl<GameOceanengineAppCallbackMapper, GameOceanengineAppCallback>
-implements IGameOceanengineAppCallbackService {
+        implements IGameOceanengineAppCallbackService {
 
     @Value("${spring.kafka.oceanengineAppCallbackTopic}")
     private String oceanengineAppCallbackTopic;
@@ -62,30 +58,4 @@ implements IGameOceanengineAppCallbackService {
         }
         return true;
     }
-
-    @Override
-    public GameOceanengineAppCallback getUserCallback(Long gameId, String oaid, String mac, String idfa, String caid, String ip, LocalDateTime regTime) {
-        LambdaQueryWrapper<GameOceanengineAppCallback> qw = new LambdaQueryWrapper<GameOceanengineAppCallback>()
-                .lt(GameOceanengineAppCallback::getTs, DateUtil.localDateTimeToMilli(regTime))
-                .eq(GameOceanengineAppCallback::getGameId, gameId)
-                .orderByDesc(GameOceanengineAppCallback::getTs)
-                .last("limit 1");
-
-        qw.and(and -> {
-            if(StringUtils.isNoneBlank(oaid)) {
-                and.or().eq(GameOceanengineAppCallback::getOaid, oaid)
-                        .or().eq(GameOceanengineAppCallback::getOaidMd5, Md5Util.encrypt32(oaid).toLowerCase());
-            }
-            if (StringUtils.isNoneBlank(idfa)) {
-                and.or().eq(GameOceanengineAppCallback::getIdfaMd5, Md5Util.encrypt32(idfa).toLowerCase())
-                        .or().eq(GameOceanengineAppCallback::getIdfa, idfa);
-            }
-            and.or().eq(StringUtils.isNoneBlank(mac), GameOceanengineAppCallback::getMac, StringUtils.isBlank(oaid) ? null : Md5Util.encrypt32(mac.replaceAll(":","").toUpperCase()).toLowerCase())
-                    .or().and(StringUtils.isNoneBlank(ip), tmp -> {
-                        tmp.ge(GameOceanengineAppCallback::getTs, DateUtil.localDateTimeToMilli(regTime.plusDays(2)))
-                                .eq(GameOceanengineAppCallback::getIp, ip);
-                    });
-        });
-        return getOne(qw);
-    }
 }

+ 483 - 3
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentAppOrderServiceImpl.java

@@ -1,14 +1,494 @@
 package com.zanxiang.game.back.serve.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.sd4324530.jtuple.Tuple2;
+import com.github.sd4324530.jtuple.Tuple4;
+import com.zanxiang.game.back.base.pojo.enums.OrderStatusEnum;
 import com.zanxiang.game.back.serve.dao.mapper.GameTencentAppOrderMapper;
-import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppOrder;
-import com.zanxiang.game.back.serve.service.IGameTencentAppOrderService;
+import com.zanxiang.game.back.serve.oceanengine.MiniGameCallback;
+import com.zanxiang.game.back.serve.pojo.dto.GameOceanengineAppOrderLogDTO;
+import com.zanxiang.game.back.serve.pojo.dto.GameTencentAppOrderDTO;
+import com.zanxiang.game.back.serve.pojo.entity.*;
+import com.zanxiang.game.back.serve.pojo.enums.BackStatusEnum;
+import com.zanxiang.game.back.serve.pojo.enums.BackUnitEnum;
+import com.zanxiang.game.back.serve.pojo.vo.GameOceanengineAppOrderLogVO;
+import com.zanxiang.game.back.serve.pojo.vo.GameOceanengineAppOrderSplitLogVO;
+import com.zanxiang.game.back.serve.pojo.vo.GameTencentAppOrderSplitLogVO;
+import com.zanxiang.game.back.serve.pojo.vo.GameTencentAppOrderVO;
+import com.zanxiang.game.back.serve.service.*;
+import com.zanxiang.game.back.serve.utils.BackPolicyUtil;
+import com.zanxiang.game.back.serve.utils.OrderUtil;
+import com.zanxiang.game.module.base.ServerInfo;
+import com.zanxiang.game.module.base.pojo.vo.AgentRpcVO;
+import com.zanxiang.game.module.base.rpc.IAgentRpc;
+import com.zanxiang.module.util.ObjectUtil;
+import com.zanxiang.module.util.bean.BeanUtil;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
 public class GameTencentAppOrderServiceImpl extends ServiceImpl<GameTencentAppOrderMapper, GameTencentAppOrder>
-implements IGameTencentAppOrderService {
+        implements IGameTencentAppOrderService {
+
+    @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
+    private IAgentRpc agentRpc;
+
+    @Autowired
+    private IGameBackPolicyService gameBackPolicyService;
+
+    @Autowired
+    private IGameTencentAppUserService gameTencentAppUserService;
+
+
+    @Autowired
+    private IGameTencentAppBackLogService gameTencentAppBackLogService;
+
+    @Autowired
+    private IGameTencentAppOrderSplitLogService gameTencentAppOrderSplitLogService;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean callback(GameTencentAppOrder orderLog) {
+        if (!Objects.equals(orderLog.getOrderStatus(), OrderStatusEnum.SUCCESS_PAY.getValue())) {
+            // 腾讯只要回传支付订单
+            return true;
+        }
+        GameTencentAppUser userLog = userLog(orderLog);
+        if (userLog == null) {
+            // 找不到用户
+            return update(new LambdaUpdateWrapper<GameTencentAppOrder>()
+                    .set(GameTencentAppOrder::getBackStatus, BackStatusEnum.NO.getBackStatus())
+                    .set(GameTencentAppOrder::getBackMoney, orderLog.getAmount())
+                    .set(GameTencentAppOrder::getBackMsg, "回传失败!找不到回传用户")
+                    .eq(GameTencentAppOrder::getId, orderLog.getId())
+            );
+        }
+
+        GameBackPolicy gameBackPolicy = gameBackPolicyService.getById(orderLog.getBackPolicyId());
+        Tuple4<Boolean, Long, String, List<Tuple2<Long, LocalDateTime>>> backInfo = BackPolicyUtil.backOrder(orderLog.getOrderNo(), gameBackPolicy, orderLog.getAmount(),
+                orderLog.getIsFirstOrder(),
+                orderLog.getPayTime(),
+                // 此处使用用户最近一次的重新染色时间
+                userLog.getCreateTime(),
+                orderLog.getUserId(),
+                new GameTencentAppOrderServiceImpl.TencentAppOrderBackPolicyCheck(this, gameTencentAppOrderSplitLogService, userLog, orderLog, gameBackPolicy)
+        );
+        boolean doBack = backInfo.first;
+        Long backMoney = backInfo.second;
+        String backMsg = backInfo.third;
+
+        if (!doBack) {
+            // 不回传
+            return update(new LambdaUpdateWrapper<GameTencentAppOrder>()
+                    .set(GameTencentAppOrder::getBackStatus, BackStatusEnum.NO.getBackStatus())
+                    .set(GameTencentAppOrder::getBackMoney, backMoney)
+                    .set(GameTencentAppOrder::getBackMsg, backMsg)
+                    .eq(GameTencentAppOrder::getId, orderLog.getId())
+            );
+        }
+        // 拆单
+        if (CollectionUtils.isNotEmpty(backInfo.fourth)) {
+            // 需要拆单
+            List<GameTencentAppOrderSplitLog> splitOrderLogList = new ArrayList<>(backInfo.fourth.size());
+            for (int i = 0; i < backInfo.fourth.size(); i++) {
+                Tuple2<Long, LocalDateTime> splitOrder = backInfo.fourth.get(i);
+                splitOrderLogList.add(GameTencentAppOrderSplitLog.builder()
+                        .backDay(splitOrder.second.toLocalDate())
+                        .orderNo(orderLog.getOrderNo())
+                        .backIndex(i + 1)
+                        .backCount(backInfo.fourth.size())
+                        .splitMoney(splitOrder.first)
+                        .backTime(splitOrder.second)
+                        .backStatus(BackStatusEnum.SUCCESS.getBackStatus())
+                        .createTime(LocalDateTime.now())
+                        .build()
+                );
+            }
+            gameTencentAppOrderSplitLogService.saveBatch(splitOrderLogList);
+            return update(new LambdaUpdateWrapper<GameTencentAppOrder>()
+                    .set(GameTencentAppOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                    .set(GameTencentAppOrder::getBackMoney, backInfo.second)
+                    .set(GameTencentAppOrder::getBackMsg, backMsg)
+                    .eq(GameTencentAppOrder::getId, orderLog.getId())
+            );
+        }
+
+        Tuple2<BackStatusEnum, String> backResult = doCallback(orderLog,  backMoney);
+        if (StringUtils.isNotBlank(backResult.second)) {
+            backMsg = backMsg + ("回传失败:" + backResult.second);
+        }
+        return update(new LambdaUpdateWrapper<GameTencentAppOrder>()
+                .set(GameTencentAppOrder::getBackStatus, backResult.first.getBackStatus())
+                .set(GameTencentAppOrder::getBackMoney, backMoney)
+                .set(GameTencentAppOrder::getBackMsg, backMsg)
+                .eq(GameTencentAppOrder::getId, orderLog.getId())
+        );
+    }
+
+
+    private Tuple2<BackStatusEnum, String> doCallback(GameTencentAppOrder orderLog,  Long backMoney) {
+        GameTencentAppUser userLog = userLog(orderLog);
+        if (userLog == null) {
+            gameTencentAppBackLogService.save(GameTencentAppBackLog.builder()
+                    .userId(orderLog.getUserId())
+                    .mac(orderLog.getMac())
+                    .imei(orderLog.getImei())
+                    .oaid(orderLog.getOaid())
+                    .androidId(orderLog.getAndroidId())
+                    .idfa(orderLog.getIdfa())
+                    .caid(orderLog.getCaid())
+                    .gameId(orderLog.getGameId())
+                    .accountId(orderLog.getAccountId())
+                    .eventType(String.valueOf(MiniGameCallback.EventType.ACTIVE_PAY.getEventType()))
+                    .eventLogId(orderLog.getId())
+                    .createTime(LocalDateTime.now())
+                    .payAmount(backMoney)
+                    .backStatus(BackStatusEnum.FAILED.getBackStatus())
+                    .errMsg("找不到用户注册信息")
+                    .build());
+            return Tuple2.with(BackStatusEnum.FAILED, "找不到用户注册信息");
+        }
+        Integer eventType = MiniGameCallback.EventType.ACTIVE_PAY.getEventType();
+        BackStatusEnum backStatus = BackStatusEnum.SUCCESS;
+        String errMsg = null;
+        gameTencentAppBackLogService.save(GameTencentAppBackLog.builder()
+                .userId(orderLog.getUserId())
+                .mac(orderLog.getMac())
+                .imei(orderLog.getImei())
+                .oaid(orderLog.getOaid())
+                .androidId(orderLog.getAndroidId())
+                .idfa(orderLog.getIdfa())
+                .caid(orderLog.getCaid())
+                .gameId(orderLog.getGameId())
+                .accountId(orderLog.getAccountId())
+                .eventType(String.valueOf(eventType))
+                .eventLogId(orderLog.getId())
+                .createTime(LocalDateTime.now())
+                .payAmount(backMoney)
+                .backStatus(backStatus.getBackStatus())
+                .errMsg(errMsg)
+                .build());
+        return Tuple2.with(backStatus, errMsg);
+    }
+
+    @Override
+    public IPage<GameTencentAppOrderVO> gameTencentAppOrderLogList(GameTencentAppOrderDTO dto) {
+        IPage<GameTencentAppOrder> page = page(dto.toPage(), new LambdaQueryWrapper<GameTencentAppOrder>()
+                .eq(StringUtils.isNotBlank(dto.getUserId()), GameTencentAppOrder::getUserId, dto.getUserId())
+                .eq(StringUtils.isNotBlank(dto.getMac()), GameTencentAppOrder::getMac, dto.getMac())
+                .eq(StringUtils.isNotBlank(dto.getImei()), GameTencentAppOrder::getImei, dto.getImei())
+                .eq(StringUtils.isNotBlank(dto.getOaid()), GameTencentAppOrder::getOaid, dto.getOaid())
+                .eq(StringUtils.isNotBlank(dto.getAndroidId()), GameTencentAppOrder::getAndroidId, dto.getAndroidId())
+                .eq(StringUtils.isNotBlank(dto.getIdfa()), GameTencentAppOrder::getIdfa, dto.getIdfa())
+                .eq(StringUtils.isNotBlank(dto.getCaid()), GameTencentAppOrder::getCaid, dto.getCaid())
+                .eq(StringUtils.isNotBlank(dto.getAgentKey()), GameTencentAppOrder::getAgentKey, dto.getAgentKey())
+                .ge(dto.getRegTimeBegin() != null, GameTencentAppOrder::getRegTime, dto.getRegTimeBegin() == null ? null : LocalDateTime.of(dto.getRegTimeBegin(), LocalTime.MIDNIGHT))
+                .le(dto.getRegTimeEnd() != null, GameTencentAppOrder::getRegTime, dto.getRegTimeEnd() == null ? null : LocalDateTime.of(dto.getRegTimeEnd(), LocalTime.MAX))
+                .eq(null != dto.getGameId(), GameTencentAppOrder::getGameId, dto.getGameId())
+                .eq(null != dto.getAccountId(), GameTencentAppOrder::getAccountId, dto.getAccountId())
+                .eq(StringUtils.isNotBlank(dto.getOrderNo()), GameTencentAppOrder::getOrderNo, dto.getOrderNo())
+                .eq(null != dto.getBackStatus(), GameTencentAppOrder::getBackStatus, dto.getBackStatus())
+                .eq(dto.getIsFirstOrder() != null, GameTencentAppOrder::getIsFirstOrder, dto.getIsFirstOrder())
+                .eq(null != dto.getOrderStatus(), GameTencentAppOrder::getOrderStatus, dto.getOrderStatus())
+                .like(StringUtils.isNotBlank(dto.getRoleName()), GameTencentAppOrder::getRoleName, dto.getRoleName())
+                .apply(dto.getRegPayIntervalTimeMin() != null, "if(pay_time is not null, TIMESTAMPDIFF(minute, reg_time, pay_time), null) >= {0}", dto.getRegPayIntervalTimeMin())
+                .apply(dto.getRegPayIntervalTimeMax() != null, "if(pay_time is not null, TIMESTAMPDIFF(minute, reg_time, pay_time), null) <= {0}", dto.getRegPayIntervalTimeMax())
+                .orderByDesc(GameTencentAppOrder::getCreateTime)
+        );
+        IPage<GameTencentAppOrderVO> result = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
+        if (CollectionUtils.isEmpty(page.getRecords())) {
+            return result;
+        }
+        result.setRecords(toVOBatch(page.getRecords()));
+        return result;
+    }
+
+    private List<GameTencentAppOrderVO> toVOBatch(List<GameTencentAppOrder> logList) {
+        if (CollectionUtils.isEmpty(logList)) {
+            return Collections.emptyList();
+        }
+        List<GameTencentAppOrderSplitLogVO> orderSplitList = gameTencentAppOrderSplitLogService.listByOrderNo(
+                logList.stream().map(GameTencentAppOrder::getOrderNo).collect(Collectors.toSet()));
+        Set<String> agentKeys = logList.stream().map(GameTencentAppOrder::getAgentKey)
+                .filter(StringUtils::isNotBlank).collect(Collectors.toSet());
+        Map<String, AgentRpcVO> agentMap = CollectionUtils.isEmpty(agentKeys) ? Collections.emptyMap() : agentRpc.getByAgentKeys(new ArrayList<>(agentKeys))
+                .getData().stream().collect(Collectors.toMap(AgentRpcVO::getAgentKey, Function.identity()));
+        return logList.stream().map(log -> {
+            GameTencentAppOrderVO vo = toVOSimple(log);
+            if (StringUtils.isNotBlank(log.getAgentKey())) {
+                AgentRpcVO agent = agentMap.get(log.getAgentKey());
+                if (agent != null) {
+                    vo.setAgentName(agent.getAgentName());
+                }
+            }
+            List<GameTencentAppOrderSplitLogVO> splitList = orderSplitList.stream()
+                    .filter(obj -> obj.getOrderNo().equals(log.getOrderNo()))
+                    .collect(Collectors.toList());
+            vo.setSplitOrderList(splitList);
+            return vo;
+        }).collect(Collectors.toList());
+    }
+
+    private GameTencentAppOrderVO toVOSimple(GameTencentAppOrder log) {
+        if (log == null) {
+            return null;
+        }
+        GameTencentAppOrderVO vo = BeanUtil.copy(log, GameTencentAppOrderVO.class);
+        vo.setRegPayIntervalTime(OrderUtil.regPayIntervalTime(log.getPayTime(), log.getRegTime()));
+        return vo;
+    }
+
+    private GameTencentAppUser userLog(GameTencentAppOrder orderLog) {
+        return gameTencentAppUserService.getOne(new LambdaQueryWrapper<GameTencentAppUser>()
+                .eq(GameTencentAppUser::getGameId, orderLog.getGameId())
+                .eq(GameTencentAppUser::getUserId, orderLog.getUserId())
+                .eq(GameTencentAppUser::getAccountId, orderLog.getAccountId())
+                .orderByDesc(GameTencentAppUser::getCreateTime)
+                .last("limit 1")
+        );
+    }
+
+    public static class TencentAppOrderBackPolicyCheck implements BackPolicyUtil.IBackPolicyCheck {
+        private final IGameTencentAppOrderService gameTencentAppOrderService;
+        private final IGameTencentAppOrderSplitLogService gameTencentAppOrderSplitLogService;
+        private final GameBackPolicy gameBackPolicy;
+        private final GameTencentAppUser userLog;
+        private final GameTencentAppOrder orderLog;
+
+        public TencentAppOrderBackPolicyCheck(IGameTencentAppOrderService gameTencentAppOrderService,
+                                              IGameTencentAppOrderSplitLogService gameTencentAppOrderSplitLogService,
+                                              GameTencentAppUser userLog, GameTencentAppOrder orderLog, GameBackPolicy gameBackPolicy) {
+            this.gameTencentAppOrderService = gameTencentAppOrderService;
+            this.gameTencentAppOrderSplitLogService = gameTencentAppOrderSplitLogService;
+            this.gameBackPolicy = gameBackPolicy;
+            this.userLog = userLog;
+            this.orderLog = orderLog;
+        }
+
+        public Tuple2<Long, Long> backCountForUserWithSplitOrder(String userId) {
+            Map<String, Long> orderMap = gameTencentAppOrderService.list(new LambdaQueryWrapper<GameTencentAppOrder>()
+                    .select(GameTencentAppOrder::getOrderNo, GameTencentAppOrder::getBackMoney)
+                    .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                    .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                    .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .eq(GameTencentAppOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                    .eq(GameTencentAppOrder::getUserId, userId)
+                    .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+            ).stream().collect(Collectors.toMap(GameTencentAppOrder::getOrderNo, GameTencentAppOrder::getBackMoney));
+            if (MapUtils.isEmpty(orderMap)) {
+                return Tuple2.with(0L, 0L);
+            }
+            Map<String, Integer> splitBackCountMap = gameTencentAppOrderSplitLogService.list(new LambdaQueryWrapper<GameTencentAppOrderSplitLog>()
+                    .select(GameTencentAppOrderSplitLog::getOrderNo, GameTencentAppOrderSplitLog::getBackIndex, GameTencentAppOrderSplitLog::getBackCount)
+                    .in(GameTencentAppOrderSplitLog::getOrderNo, orderMap.keySet())
+            ).stream().collect(Collectors.toMap(GameTencentAppOrderSplitLog::getOrderNo, GameTencentAppOrderSplitLog::getBackCount, (obj1, obj2) -> obj1));
+            long count = 0;
+            long backMoney = 0;
+            for (Map.Entry<String, Long> entry : orderMap.entrySet()) {
+                Integer splitBackCount = splitBackCountMap.get(entry.getKey());
+                backMoney += entry.getValue();
+                if (splitBackCount != null) {
+                    count += splitBackCount;
+                } else {
+                    count += 1;
+                }
+            }
+            return Tuple2.with(count, backMoney);
+        }
+
+        @Override
+        public long backCountForFixedRate(int numberOfRound, BackUnitEnum backUnit, Boolean firstPolicy) {
+            numberOfRound = numberOfRound - 1;
+            if (backUnit == BackUnitEnum.UNIT_ONCE) {
+                return gameTencentAppOrderService.list(new LambdaQueryWrapper<GameTencentAppOrder>()
+                        .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                        .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentAppOrder::getIsFirstOrder, firstPolicy)
+                        .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+                        .orderByDesc(GameTencentAppOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
+                return gameTencentAppOrderService.list(new LambdaQueryWrapper<GameTencentAppOrder>()
+                        .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                        .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .apply(firstPolicy, "date(reg_time) = date(pay_time)")
+                        .apply(!firstPolicy, "date(reg_time) != date(pay_time)")
+                        .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+                        .orderByDesc(GameTencentAppOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
+                return gameTencentAppOrderService.list(new LambdaQueryWrapper<GameTencentAppOrder>()
+                        .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                        .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) < 24")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) >= 24")
+                        .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+                        .orderByDesc(GameTencentAppOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
+                return gameTencentAppOrderService.list(new LambdaQueryWrapper<GameTencentAppOrder>()
+                        .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                        .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) < 48")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) >= 48")
+                        .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+                        .orderByDesc(GameTencentAppOrder::getCreateTime)
+                        .last("limit " + numberOfRound)
+                ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
+                return gameTencentAppOrderService.list(new LambdaQueryWrapper<GameTencentAppOrder>()
+                        .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                        .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+                        .orderByDesc(GameTencentAppOrder::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 gameTencentAppOrderService.count(new LambdaQueryWrapper<GameTencentAppOrder>()
+                        .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                        .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentAppOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentAppOrder::getUserId, userId)
+                        .eq(GameTencentAppOrder::getIsFirstOrder, firstPolicy)
+                        .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+                );
+            } else if (backUnit == BackUnitEnum.UNIT_DAY) {
+                return gameTencentAppOrderService.count(new LambdaQueryWrapper<GameTencentAppOrder>()
+                        .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                        .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentAppOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentAppOrder::getUserId, userId)
+                        .apply(firstPolicy, "date(reg_time) = date(pay_time)")
+                        .apply(!firstPolicy, "date(reg_time) != date(pay_time)")
+                        .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+                );
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_DAY) {
+                return gameTencentAppOrderService.count(new LambdaQueryWrapper<GameTencentAppOrder>()
+                        .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                        .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentAppOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentAppOrder::getUserId, userId)
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) < 24")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) >= 24")
+                        .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+                );
+            } else if (backUnit == BackUnitEnum.UNIT_TIME_2DAY) {
+                return gameTencentAppOrderService.count(new LambdaQueryWrapper<GameTencentAppOrder>()
+                        .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                        .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentAppOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentAppOrder::getUserId, userId)
+                        .apply(firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) < 48")
+                        .apply(!firstPolicy, "TIMESTAMPDIFF(HOUR, reg_time, pay_time) >= 48")
+                        .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+                );
+            } else if (backUnit == BackUnitEnum.LARGE_AMOUNT) {
+                return gameTencentAppOrderService.count(new LambdaQueryWrapper<GameTencentAppOrder>()
+                        .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                        .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                        .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                        .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                        .eq(GameTencentAppOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                        .eq(GameTencentAppOrder::getUserId, userId)
+                        .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+                );
+            } else {
+                throw new RuntimeException("不支持的回传单位[" + backUnit.getValue() + "]");
+            }
+        }
+
+        @Override
+        public long markUpOfFixedRate(int numberOfRound, Long markUpTime) {
+            numberOfRound = numberOfRound - 1;
+            return gameTencentAppOrderService.list(new LambdaQueryWrapper<GameTencentAppOrder>()
+                    .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                    .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                    .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .apply("TIMESTAMPDIFF(MINUTE, reg_time, pay_time) > {0}", markUpTime)
+                    .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+                    .orderByDesc(GameTencentAppOrder::getCreateTime)
+                    .last("limit " + numberOfRound)
+            ).stream().filter(log -> log.getBackStatus().equals(BackStatusEnum.SUCCESS.getBackStatus())).count();
+        }
+
+        @Override
+        public long markUpForUser(String userId, Long markUpTime) {
+            return gameTencentAppOrderService.count(new LambdaQueryWrapper<GameTencentAppOrder>()
+                    .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                    .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                    .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .eq(GameTencentAppOrder::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                    .eq(GameTencentAppOrder::getUserId, userId)
+                    .apply("TIMESTAMPDIFF(MINUTE, reg_time, pay_time) > {0}", markUpTime)
+                    .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+            );
+        }
+
+        @Override
+        public Long totalRechargeAmount() {
+            Map<String, Object> data = gameTencentAppOrderService.getMap(new QueryWrapper<GameTencentAppOrder>()
+                    .select("ifnull(sum(amount), 0) as amount").lambda()
+                    .eq(GameTencentAppOrder::getGameId, orderLog.getGameId())
+                    .eq(GameTencentAppOrder::getAccountId, orderLog.getAccountId())
+                    .eq(GameTencentAppOrder::getBackPolicyId, gameBackPolicy.getId())
+                    .eq(GameTencentAppOrder::getOrderStatus, OrderStatusEnum.SUCCESS_PAY.getValue())
+                    .eq(GameTencentAppOrder::getUserId, userLog.getUserId())
+                    .ne(GameTencentAppOrder::getOrderNo, orderLog.getOrderNo())
+            );
+            return ObjectUtil.objToLong(data.get("amount"), 0L);
+        }
+    }
 }

+ 34 - 1
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentAppOrderSplitLogServiceImpl.java

@@ -1,14 +1,47 @@
 package com.zanxiang.game.back.serve.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zanxiang.game.back.serve.dao.mapper.GameTencentAppOrderSplitLogMapper;
 import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppOrderSplitLog;
+import com.zanxiang.game.back.serve.pojo.vo.GameTencentAppOrderSplitLogVO;
 import com.zanxiang.game.back.serve.service.IGameTencentAppOrderSplitLogService;
+import com.zanxiang.module.util.NumberUtil;
+import com.zanxiang.module.util.bean.BeanUtil;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
 @Slf4j
 @Service
 public class GameTencentAppOrderSplitLogServiceImpl extends ServiceImpl<GameTencentAppOrderSplitLogMapper, GameTencentAppOrderSplitLog>
-implements IGameTencentAppOrderSplitLogService {
+        implements IGameTencentAppOrderSplitLogService {
+
+    @Override
+    public List<GameTencentAppOrderSplitLogVO> listByOrderNo(Collection<String> orderNos) {
+        if (CollectionUtils.isEmpty(orderNos)) {
+            return Collections.emptyList();
+        }
+        return list(new LambdaQueryWrapper<GameTencentAppOrderSplitLog>()
+                .in(GameTencentAppOrderSplitLog::getOrderNo, orderNos)
+                .orderByAsc(GameTencentAppOrderSplitLog::getBackIndex)
+        ).stream().map(this::toVOSimple).collect(Collectors.toList());
+    }
+
+    private GameTencentAppOrderSplitLogVO toVOSimple(GameTencentAppOrderSplitLog log) {
+        if (log == null) {
+            return null;
+        }
+        GameTencentAppOrderSplitLogVO vo = BeanUtil.copy(log, GameTencentAppOrderSplitLogVO.class);
+        if (log.getSplitMoney() != null) {
+            vo.setSplitMoney(NumberUtil.divide100(new BigDecimal(log.getSplitMoney())));
+        }
+        return vo;
+    }
 }

+ 90 - 1
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentAppRoleRegisterServiceImpl.java

@@ -1,14 +1,103 @@
 package com.zanxiang.game.back.serve.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zanxiang.game.back.serve.dao.mapper.GameTencentAppRoleRegisterMapper;
+import com.zanxiang.game.back.serve.oceanengine.MiniGameCallback;
+import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineAppRoleRegisterLog;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppBackLog;
 import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppRoleRegister;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppUser;
+import com.zanxiang.game.back.serve.pojo.enums.BackStatusEnum;
+import com.zanxiang.game.back.serve.service.IGameTencentAppBackLogService;
 import com.zanxiang.game.back.serve.service.IGameTencentAppRoleRegisterService;
+import com.zanxiang.game.back.serve.service.IGameTencentAppUserService;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.Objects;
 
 @Slf4j
 @Service
 public class GameTencentAppRoleRegisterServiceImpl extends ServiceImpl<GameTencentAppRoleRegisterMapper, GameTencentAppRoleRegister>
-implements IGameTencentAppRoleRegisterService {
+        implements IGameTencentAppRoleRegisterService {
+
+    @Autowired
+    private IGameTencentAppUserService gameTencentAppUserService;
+
+    @Autowired
+    private IGameTencentAppBackLogService gameTencentAppBackLogService;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean callback(GameTencentAppRoleRegister roleRegisterLog) {
+        BackStatusEnum backStatus = doCallback(roleRegisterLog);
+        return update(new LambdaUpdateWrapper<GameTencentAppRoleRegister>()
+                .set(GameTencentAppRoleRegister::getBackStatus, backStatus.getBackStatus())
+                .eq(GameTencentAppRoleRegister::getId, roleRegisterLog.getId())
+        );
+    }
+
+    private BackStatusEnum doCallback(GameTencentAppRoleRegister roleRegisterLog) {
+        GameTencentAppUser userLog = gameTencentAppUserService.getOne(new LambdaQueryWrapper<GameTencentAppUser>()
+                .eq(GameTencentAppUser::getGameId, roleRegisterLog.getGameId())
+                .eq(GameTencentAppUser::getUserId, roleRegisterLog.getUserId())
+                .eq(GameTencentAppUser::getAccountId, roleRegisterLog.getAccountId())
+                .orderByDesc(GameTencentAppUser::getCreateTime)
+                .last("limit 1")
+        );
+        if (userLog == null) {
+            gameTencentAppBackLogService.save(GameTencentAppBackLog.builder()
+                    .userId(roleRegisterLog.getUserId())
+                    .mac(roleRegisterLog.getMac())
+                    .imei(roleRegisterLog.getImei())
+                    .oaid(roleRegisterLog.getOaid())
+                    .androidId(roleRegisterLog.getAndroidId())
+                    .idfa(roleRegisterLog.getIdfa())
+                    .caid(roleRegisterLog.getCaid())
+                    .gameId(roleRegisterLog.getGameId())
+                    .accountId(roleRegisterLog.getAccountId())
+                    .eventType(String.valueOf(MiniGameCallback.EventType.ACTIVE_REGISTER.getEventType()))
+                    .eventLogId(roleRegisterLog.getId())
+                    .createTime(LocalDateTime.now())
+                    .backStatus(BackStatusEnum.FAILED.getBackStatus())
+                    .errMsg("找不到用户注册信息")
+                    .build());
+            return BackStatusEnum.FAILED;
+        }
+        //判断创角是否已回传
+        if (gameTencentAppBackLogService.count(new LambdaQueryWrapper<GameTencentAppBackLog>()
+                .eq(GameTencentAppBackLog::getGameId, userLog.getGameId())
+                .eq(GameTencentAppBackLog::getUserId, userLog.getUserId())
+                .eq(GameTencentAppBackLog::getAccountId, userLog.getAccountId())
+                .eq(GameTencentAppBackLog::getEventType, MiniGameCallback.EventType.ACTIVE_REGISTER.getEventType())
+                .eq(GameTencentAppBackLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+        ) > 0) {
+            //创角已回传
+            return BackStatusEnum.NO;
+        }
+        BackStatusEnum backStatus = BackStatusEnum.SUCCESS;
+        String errMsg = null;
+        gameTencentAppBackLogService.save(GameTencentAppBackLog.builder()
+                .userId(roleRegisterLog.getUserId())
+                .mac(roleRegisterLog.getMac())
+                .imei(roleRegisterLog.getImei())
+                .oaid(roleRegisterLog.getOaid())
+                .androidId(roleRegisterLog.getAndroidId())
+                .idfa(roleRegisterLog.getIdfa())
+                .caid(roleRegisterLog.getCaid())
+                .gameId(roleRegisterLog.getGameId())
+                .accountId(roleRegisterLog.getAccountId())
+                .eventType(String.valueOf(MiniGameCallback.EventType.ACTIVE_REGISTER.getEventType()))
+                .eventLogId(roleRegisterLog.getId())
+                .createTime(LocalDateTime.now())
+                .backStatus(backStatus.getBackStatus())
+                .errMsg(errMsg)
+                .build());
+        return backStatus;
+    }
 }

+ 57 - 98
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentAppUserServiceImpl.java

@@ -1,33 +1,30 @@
 package com.zanxiang.game.back.serve.service.impl;
 
+import com.alibaba.nacos.common.utils.CollectionUtils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zanxiang.advertising.tencent.base.AdvertisingTencentServer;
-import com.zanxiang.advertising.tencent.base.pojo.dto.DataReportOfAppIdRpcDTO;
-import com.zanxiang.advertising.tencent.base.pojo.dto.UserActionRpcDTO;
 import com.zanxiang.advertising.tencent.base.rpc.IUserActionSetRpc;
 import com.zanxiang.erp.base.ErpServer;
 import com.zanxiang.erp.base.rpc.ISysUserRpc;
 import com.zanxiang.game.back.serve.dao.mapper.GameTencentAppUserMapper;
-import com.zanxiang.game.back.serve.pojo.dto.GameTencentUserDTO;
-import com.zanxiang.game.back.serve.pojo.entity.*;
-import com.zanxiang.game.back.serve.pojo.enums.ActionTypeEnum;
+import com.zanxiang.game.back.serve.oceanengine.MiniGameCallback;
+import com.zanxiang.game.back.serve.pojo.dto.GameTencentAppUserDTO;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppBackLog;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentAppUser;
 import com.zanxiang.game.back.serve.pojo.enums.BackStatusEnum;
 import com.zanxiang.game.back.serve.pojo.vo.GameTencentUserVO;
 import com.zanxiang.game.back.serve.service.IGameTencentAppBackLogService;
 import com.zanxiang.game.back.serve.service.IGameTencentAppCallbackService;
 import com.zanxiang.game.back.serve.service.IGameTencentAppUserService;
-import com.zanxiang.game.back.serve.service.IGameTencentBackLogService;
 import com.zanxiang.game.module.base.ServerInfo;
 import com.zanxiang.game.module.base.pojo.vo.AgentRpcVO;
 import com.zanxiang.game.module.base.rpc.IAgentRpc;
 import com.zanxiang.module.util.bean.BeanUtil;
-import com.zanxiang.module.util.pojo.ResultVO;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -43,136 +40,98 @@ import java.util.stream.Collectors;
 @Slf4j
 @Service
 public class GameTencentAppUserServiceImpl extends ServiceImpl<GameTencentAppUserMapper, GameTencentAppUser>
-implements IGameTencentAppUserService {
-    @DubboReference(providedBy = AdvertisingTencentServer.SERVER_DUBBO_NAME)
-    private IUserActionSetRpc userActionSetRpc;
-    @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
-    private ISysUserRpc sysUserRpc;
-    @Autowired
-    private IGameTencentAppBackLogService gameTencentAppBackLogService;
+        implements IGameTencentAppUserService {
+
     @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
     private IAgentRpc agentRpc;
+
     @Autowired
-    private IGameTencentAppCallbackService gameTencentAppCallbackService;
+    private IGameTencentAppBackLogService gameTencentAppBackLogService;
 
-    /*@Override
+    @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean userBack(GameTencentAppUser userLog, boolean mustBack) {
         BackStatusEnum backStatus = doCallback(userLog, mustBack);
         return update(new LambdaUpdateWrapper<GameTencentAppUser>()
-                .set(GameTencentAppUser::getIsBack, backStatus.getBackStatus())
+                .set(GameTencentAppUser::getBackStatus, backStatus.getBackStatus())
                 .eq(GameTencentAppUser::getId, userLog.getId())
         );
     }
 
-
     @Override
-    public IPage<GameTencentUserVO> tencentUserLogList(GameTencentUserDTO dto) {
-        IPage<GameTencentUser> page = page(dto.toPage(), new LambdaQueryWrapper<GameTencentUser>()
-                .eq(StringUtils.isNotBlank(dto.getChannel()), GameTencentUser::getChannel, dto.getChannel())
-                .ge(dto.getActiveTimeBegin() != null, GameTencentUser::getRegisterTime, dto.getActiveTimeBegin() == null ? null : LocalDateTime.of(dto.getActiveTimeBegin(), LocalTime.MIDNIGHT))
-                .le(dto.getActiveTimeEnd() != null, GameTencentUser::getRegisterTime, dto.getActiveTimeEnd() == null ? null : LocalDateTime.of(dto.getActiveTimeEnd(), LocalTime.MAX))
-                .eq(null != dto.getGameId(), GameTencentUser::getGameId, dto.getGameId())
-                .eq(null != dto.getAdAccountId(), GameTencentUser::getAdAccountId, dto.getAdAccountId())
-                .eq(StringUtils.isNotBlank(dto.getWechatAppId()), GameTencentUser::getWechatAppId, dto.getWechatAppId())
-                .eq(StringUtils.isNotBlank(dto.getWechatOpenid()), GameTencentUser::getWechatOpenid, dto.getWechatOpenid())
-                .eq(null != dto.getIsBack(), GameTencentUser::getIsBack, dto.getIsBack())
-                .orderByDesc(GameTencentUser::getCreateTime)
+    public IPage<GameTencentUserVO> tencentUserLogList(GameTencentAppUserDTO dto) {
+        IPage<GameTencentAppUser> page = page(dto.toPage(), new LambdaQueryWrapper<GameTencentAppUser>()
+                .eq(StringUtils.isNotBlank(dto.getUserId()), GameTencentAppUser::getUserId, dto.getUserId())
+                .eq(StringUtils.isNotBlank(dto.getMac()), GameTencentAppUser::getMac, dto.getMac())
+                .eq(StringUtils.isNotBlank(dto.getImei()), GameTencentAppUser::getImei, dto.getImei())
+                .eq(StringUtils.isNotBlank(dto.getOaid()), GameTencentAppUser::getOaid, dto.getOaid())
+                .eq(StringUtils.isNotBlank(dto.getAndroidId()), GameTencentAppUser::getAndroidId, dto.getAndroidId())
+                .eq(StringUtils.isNotBlank(dto.getIdfa()), GameTencentAppUser::getIdfa, dto.getIdfa())
+                .eq(StringUtils.isNotBlank(dto.getCaid()), GameTencentAppUser::getCaid, dto.getCaid())
+                .eq(StringUtils.isNotBlank(dto.getAgentKey()), GameTencentAppUser::getAgentKey, dto.getAgentKey())
+                .ge(dto.getActiveTimeBegin() != null, GameTencentAppUser::getActiveTime, dto.getActiveTimeBegin() == null ? null : LocalDateTime.of(dto.getActiveTimeBegin(), LocalTime.MIDNIGHT))
+                .le(dto.getActiveTimeEnd() != null, GameTencentAppUser::getActiveTime, dto.getActiveTimeEnd() == null ? null : LocalDateTime.of(dto.getActiveTimeEnd(), LocalTime.MAX))
+                .eq(null != dto.getGameId(), GameTencentAppUser::getGameId, dto.getGameId())
+                .eq(null != dto.getAccountId(), GameTencentAppUser::getAccountId, dto.getAccountId())
+                .eq(null != dto.getBackStatus(), GameTencentAppUser::getBackStatus, dto.getBackStatus())
+                .orderByDesc(GameTencentAppUser::getCreateTime)
         );
-
         IPage<GameTencentUserVO> result = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
         if (CollectionUtils.isEmpty(page.getRecords())) {
             return result;
         }
-        result.setRecords(toVOBatch(page.getRecords()));
+        result.setRecords(this.toVOBatch(page.getRecords()));
         return result;
     }
 
-    @Override
-    public boolean tencentUserReport(List<Long> ids) {
-        listByIds(ids).forEach(userLog -> {
-            BackStatusEnum backStatus = doCallback(userLog, true);
-            update(new LambdaUpdateWrapper<GameTencentUser>()
-                    .set(GameTencentUser::getIsBack, backStatus.getBackStatus())
-                    .eq(GameTencentUser::getId, userLog.getId())
-            );
-        });
-        return true;
-    }
-
-    private List<GameTencentUserVO> toVOBatch(List<GameTencentUser> logList) {
+    private List<GameTencentUserVO> toVOBatch(List<GameTencentAppUser> logList) {
         if (CollectionUtils.isEmpty(logList)) {
             return Collections.emptyList();
         }
-        Set<String> agentKeys = logList.stream().map(GameTencentUser::getChannel).filter(StringUtils::isNotBlank).collect(Collectors.toSet());
+        Set<String> agentKeys = logList.stream().map(GameTencentAppUser::getAgentKey)
+                .filter(StringUtils::isNotBlank).collect(Collectors.toSet());
         Map<String, AgentRpcVO> agentMap = CollectionUtils.isEmpty(agentKeys) ? Collections.emptyMap() : agentRpc.getByAgentKeys(new ArrayList<>(agentKeys))
-                .getData().stream().collect(Collectors.toMap(AgentRpcVO::getAgentKey, Function.identity()));
+                        .getData().stream().collect(Collectors.toMap(AgentRpcVO::getAgentKey, Function.identity()));
         return logList.stream().map(log -> {
             GameTencentUserVO vo = BeanUtil.copy(log, GameTencentUserVO.class);
-            if (StringUtils.isNotBlank(log.getChannel())) {
-                AgentRpcVO agent = agentMap.get(log.getChannel());
+            if (StringUtils.isNotBlank(log.getAgentKey())) {
+                AgentRpcVO agent = agentMap.get(log.getAgentKey());
                 if (agent != null) {
                     vo.setAgentName(agent.getAgentName());
                 }
             }
             return vo;
         }).collect(Collectors.toList());
-
     }
 
-
     private BackStatusEnum doCallback(GameTencentAppUser userLog, boolean mustBack) {
-        boolean isBack = mustBack ? false : gameTencentAppBackLogService.count(new LambdaQueryWrapper<GameTencentAppBackLog>()
+        // 是否已经回传过
+        if (!mustBack && gameTencentAppBackLogService.count(new LambdaQueryWrapper<GameTencentAppBackLog>()
                 .eq(GameTencentAppBackLog::getGameId, userLog.getGameId())
-                .eq(GameTencentAppBackLog::getMac, userLog.getMac())
-                .eq(GameTencentAppBackLog::getImei, userLog.getImei())
-                .eq(GameTencentAppBackLog::getOaid, userLog.getOaid())
-                .eq(GameTencentAppBackLog::getAndroidId, userLog.getAndroidId())
-                .eq(GameTencentAppBackLog::getIdfa, userLog.getIdfa())
-                .eq(GameTencentAppBackLog::getCaid, userLog.getCaid())
-                .eq(GameTencentAppBackLog::getAdAccountId, userLog.getAdAccountId())
-                .eq(GameTencentAppBackLog::getBackLog, "回传成功")
-        ) > 0;
-        if (isBack) {
+                .eq(GameTencentAppBackLog::getUserId, userLog.getUserId())
+                .eq(GameTencentAppBackLog::getAccountId, userLog.getAccountId())
+                .eq(GameTencentAppBackLog::getEventType, MiniGameCallback.EventType.ACTIVE.getEventType())
+                .eq(GameTencentAppBackLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+        ) > 0) {
             return BackStatusEnum.NO;
         }
-
-        Map<String, Object> actionParam = new HashMap<>(2);
-        actionParam.put("claim_type", 0);
-        DataReportOfAppIdRpcDTO dataReportOfAppIdRpcDTO = DataReportOfAppIdRpcDTO.builder()
-                .appId(userLog.getWechatAppId())
-                .userActionSetId(userLog.getUserActionSetId())
-                .action(UserActionRpcDTO.builder()
-                        .actionTime(userLog.getRegisterTime())
-                        .actionType(ActionTypeEnum.REGISTER.getActionType())
-                        .userId(UserActionRpcDTO.UserIdRpcDTO.builder()
-                                .wechatAppId(userLog.getWechatAppId())
-                                .wechatOpenid(userLog.getWechatOpenid())
-                                .build())
-                        .actionParam(actionParam)
-                        .build())
-                .build();
-
-        GameTencentBackLog gameTencentBackLog = GameTencentBackLog.builder()
+        BackStatusEnum backStatus = BackStatusEnum.SUCCESS;
+        gameTencentAppBackLogService.save(GameTencentAppBackLog.builder()
+                .userId(userLog.getUserId())
+                .mac(userLog.getMac())
+                .imei(userLog.getImei())
+                .oaid(userLog.getOaid())
+                .androidId(userLog.getAndroidId())
+                .idfa(userLog.getIdfa())
+                .caid(userLog.getCaid())
                 .gameId(userLog.getGameId())
-                .adAccountId(userLog.getAdAccountId())
-                .actionTime(userLog.getRegisterTime())
+                .accountId(userLog.getAccountId())
+                .eventType(String.valueOf(MiniGameCallback.EventType.ACTIVE.getEventType()))
+                .eventLogId(userLog.getId())
                 .createTime(LocalDateTime.now())
-                .actionType(ActionTypeEnum.REGISTER.getActionType())
-                .wechatAppId(userLog.getWechatAppId())
-                .wechatOpenid(userLog.getWechatOpenid())
-                .userActionSetId(userLog.getUserActionSetId())
-                .actionParam(actionParam.toString())
-                .build();
-        ResultVO<Boolean> result = userActionSetRpc.reportByAppId(dataReportOfAppIdRpcDTO);
-        BackStatusEnum backStatus = BackStatusEnum.FAILED;
-        if (result.isSuccess()) {
-            backStatus = BackStatusEnum.SUCCESS;
-            gameTencentBackLog.setBackLog("回传成功");
-        } else {
-            gameTencentBackLog.setBackLog(result.getMsg());
-        }
-        gameTencentBackLogService.save(gameTencentBackLog);
+                .backStatus(backStatus.getBackStatus())
+                .errMsg(null)
+                .build());
         return backStatus;
-    }*/
+    }
 }

+ 1 - 1
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/SDKApplication.java

@@ -25,7 +25,7 @@ public class SDKApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(SDKApplication.class, args);
-        System.out.println("赞象SDK服务启动成功 <封禁新增设备信息封禁, 实名信息封禁> ( ´・・)ノ(._.`) \n" +
+        System.out.println("赞象SDK服务启动成功 <全面兼容腾讯APP直投归因回传> ( ´・・)ノ(._.`) \n" +
                 " ___________ _   __\n" +
                 "/  ___|  _  \\ | / /\n" +
                 "\\ `--.| | | | |/ / \n" +

+ 38 - 21
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/AgentServiceImpl.java

@@ -208,12 +208,22 @@ public class AgentServiceImpl extends ServiceImpl<AgentMapper, Agent> implements
     }
 
     private Tuple3<Long, Map<String, String>, String> appChannelTransform(Game game, UserData userData) {
-        //游戏拓展信息
-        GameExt gameExt = gameExtService.getByGameId(userData.getGameId());
         //直投的APP, 必定兼容了媒体的回传sdk
         if (Strings.isNotBlank(game.getAdSdkConfig())) {
-            Agent agent = super.getOne(new LambdaQueryWrapper<Agent>().eq(Agent::getAgentKey, userData.getChannel()));
-            return Tuples.of(agent == null ? 0 : agent.getId(), Collections.singletonMap("agentKey", userData.getChannel()), Strings.EMPTY);
+            //头条巨量引擎
+            if (Objects.equals(game.getPutType(), 1)) {
+                Agent agent = super.getOne(new LambdaQueryWrapper<Agent>().eq(Agent::getAgentKey, userData.getChannel()));
+                return Tuples.of(agent == null ? 0 : agent.getId(), Collections.singletonMap("agentKey", userData.getChannel()), Strings.EMPTY);
+            }
+            //腾讯广点通
+            if (Objects.equals(game.getPutType(), 2)) {
+                Map<String, String> channelMap = JsonUtil.toMap(userData.getChannel(), Map.class, String.class);
+                if (channelMap == null || !channelMap.containsKey("agentKey")) {
+                    return Tuples.of(0L, Collections.emptyMap(), Strings.EMPTY);
+                }
+                Agent agent = super.getOne(new LambdaQueryWrapper<Agent>().eq(Agent::getAgentKey, channelMap.get("agentKey")));
+                return Tuples.of(agent == null ? 0 : agent.getId(), channelMap, Strings.EMPTY);
+            }
         }
         //头条私域, 虚拟游戏方式
         if (Objects.equals(game.getPutType(), 3)) {
@@ -232,29 +242,22 @@ public class AgentServiceImpl extends ServiceImpl<AgentMapper, Agent> implements
         }
         //腾讯私域, 直接加企微方式
         if (Objects.equals(game.getPutType(), 4)) {
-            TencentAppApiUserAgentQueryRpcDTO tencentAppApiUserAgentQueryRpcDTO = TencentAppApiUserAgentQueryRpcDTO.builder()
-                    .gameId(game.getId())
-                    .regIp(userData.getIp())
-                    .registerTime(LocalDateTime.now())
-                    .imei(userData.getImei())
-                    .oaid(userData.getOaid())
-                    .androidId(userData.getAndroidId())
-                    .idfa(userData.getIdfa())
-                    .caid(userData.getCaid())
-                    .build();
-            Tuple2<String, Long> tuple2 = tencentAppApiBackRpc.queryUserAgentFromCallback(tencentAppApiUserAgentQueryRpcDTO).getData();
+            Tuple2<String, Long> tuple2 = this.queryUserAgentFromCallback(game, userData);
             Map<String, String> map = new HashMap<>(2);
             map.put("agentKey", tuple2.first);
             map.put("callbackId", tuple2.second.toString());
             Agent agent = super.getOne(new LambdaQueryWrapper<Agent>().eq(Agent::getAgentKey, tuple2.first));
             return Tuples.of(agent == null ? 0 : agent.getId(), map, Strings.EMPTY);
         }
-        //不投放, 不回传, 只归因渠道, -- 不投放, 且回传只存在于导量情况, 导量无注册行为
-        if (Objects.equals(game.getIsPut(), Boolean.FALSE) && Objects.equals(gameExt.getAdCallBackSwitch(), Boolean.FALSE)) {
-            //查询访问记录
-            UserVisitLog userVisitLog = this.getUserVisitLog(userData);
-            //返回渠道信息
-            return Tuples.of(userVisitLog == null ? 0L : userVisitLog.getAgentId(), Collections.emptyMap(), Strings.EMPTY);
+        //不投放, 不回传, 只归因渠道, -- 不投放, 且回传只存在于导量情况, 无注册行为
+        if (Objects.equals(game.getIsPut(), Boolean.FALSE)) {
+            GameExt gameExt = gameExtService.getByGameId(userData.getGameId());
+            if (gameExt != null && Objects.equals(gameExt.getAdCallBackSwitch(), Boolean.FALSE)) {
+                //查询访问记录
+                UserVisitLog userVisitLog = this.getUserVisitLog(userData);
+                //返回渠道信息
+                return Tuples.of(userVisitLog == null ? 0L : userVisitLog.getAgentId(), Collections.emptyMap(), Strings.EMPTY);
+            }
         }
         //默认返回自然量
         return Tuples.of(0L, Collections.emptyMap(), Strings.EMPTY);
@@ -273,6 +276,20 @@ public class AgentServiceImpl extends ServiceImpl<AgentMapper, Agent> implements
         return Tuples.of(agent == null ? 0L : agent.getId(), urlParamMap, Strings.EMPTY);
     }
 
+    private Tuple2<String, Long> queryUserAgentFromCallback(Game game, UserData userData) {
+        TencentAppApiUserAgentQueryRpcDTO tencentAppApiUserAgentQueryRpcDTO = TencentAppApiUserAgentQueryRpcDTO.builder()
+                .gameId(game.getId())
+                .regIp(userData.getIp())
+                .registerTime(LocalDateTime.now())
+                .imei(userData.getImei())
+                .oaid(userData.getOaid())
+                .androidId(userData.getAndroidId())
+                .idfa(userData.getIdfa())
+                .caid(userData.getCaid())
+                .build();
+        return tencentAppApiBackRpc.queryUserAgentFromCallback(tencentAppApiUserAgentQueryRpcDTO).getData();
+    }
+
     private UserVisitLog getUserVisitLog(UserData userData) {
         //当前时间
         LocalDateTime regTime = LocalDateTime.now();

+ 81 - 21
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/CallBackServiceImpl.java

@@ -46,6 +46,9 @@ public class CallBackServiceImpl implements ICallBackService {
     @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
     private ITtAppBackRpc ttAppBackRpc;
 
+    @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
+    private ITencentAppBackRpc tencentAppBackRpc;
+
     @Autowired
     private IAgentService agentService;
 
@@ -118,6 +121,12 @@ public class CallBackServiceImpl implements ICallBackService {
                 ttAppBackRpc.userActiveReport(ttUserActiveAppRpcDTO);
                 gameBackLogService.addLog(user.getId(), null, "头条APP用户回传提交", JsonUtil.toString(ttUserActiveAppRpcDTO));
             }
+            //腾讯APP直投回传
+            if (CollectionUtils.isNotEmpty(urlParamMap) && Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_APP.getValue())) {
+                TencentUserAppRpcDTO tencentUserAppRpcDTO = this.transform(agent, user);
+                tencentAppBackRpc.backUser(tencentUserAppRpcDTO);
+                gameBackLogService.addLog(user.getId(), null, "腾讯APP用户回传提交", JsonUtil.toString(tencentUserAppRpcDTO));
+            }
         } catch (Exception e) {
             log.error("用户回传异常, userId : {}, e : {}", user.getId(), e.getMessage());
         }
@@ -196,6 +205,12 @@ public class CallBackServiceImpl implements ICallBackService {
                 ttAppBackRpc.roleRegisterReport(ttRoleRegisterAppRpcDTO);
                 gameBackLogService.addLog(user.getId(), gameUserRole.getRoleId(), "头条APP创角回传提交", JsonUtil.toString(ttRoleRegisterAppRpcDTO));
             }
+            //腾讯APP直投回传
+            if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_APP.getValue())) {
+                TencentRoleRegisterAppRpcDTO tencentRoleRegisterAppRpcDTO = this.transform(agent, user, gameUserRole);
+                tencentAppBackRpc.backRoleRegister(tencentRoleRegisterAppRpcDTO);
+                gameBackLogService.addLog(user.getId(), gameUserRole.getRoleId(), "腾讯APP创角回传提交", JsonUtil.toString(tencentRoleRegisterAppRpcDTO));
+            }
         } catch (Exception e) {
             log.error("创角回传异常, userId : {}, e : {}", user.getId(), e.getMessage());
         }
@@ -271,6 +286,12 @@ public class CallBackServiceImpl implements ICallBackService {
                 ttAppBackRpc.orderReport(ttOrderAppRpcDTO);
                 gameBackLogService.addLog(user.getId(), platformOrderDTO.getOrderId(), "头条APP订单回传提交", JsonUtil.toString(ttOrderAppRpcDTO));
             }
+            //腾讯APP直投回传
+            if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_APP.getValue())) {
+                TencentOrderAppRpcDTO tencentOrderAppRpcDTO = this.transform(platformOrderDTO, agent, user);
+                tencentAppBackRpc.backOrder(tencentOrderAppRpcDTO);
+                gameBackLogService.addLog(user.getId(), platformOrderDTO.getOrderId(), "腾讯APP订单回传提交", JsonUtil.toString(tencentOrderAppRpcDTO));
+            }
         } catch (Exception e) {
             log.error("订单回传异常, orderId : {}, e : {}", platformOrderDTO.getOrderId(), e.getMessage());
         }
@@ -422,6 +443,25 @@ public class CallBackServiceImpl implements ICallBackService {
                 .build();
     }
 
+    private TencentUserAppRpcDTO transform(Agent agent, User user) {
+        return TencentUserAppRpcDTO.builder()
+                .gameId(agent.getGameId())
+                .accountId(agent.getAccountId())
+                .agentKey(agent.getAgentKey())
+                .activeTime(user.getCreateTime())
+                .backPolicyId(agent.getBackPolicyId())
+                .userId(user.getId().toString())
+                .mac(user.getMac())
+                .imei(user.getImei())
+                .oaid(user.getOaid())
+                .androidId(user.getAndroidId())
+                .idfa(user.getIdfa())
+                .caid(user.getCaid())
+                .regIp(user.getIp())
+                .userActionSetId(agent.getUserActionSetId())
+                .build();
+    }
+
     private TtOrderAppRpcDTO transform(PlatformOrderDTO platformOrderDTO, User user, Agent agent) {
         return TtOrderAppRpcDTO.builder()
                 .gameId(agent.getGameId())
@@ -446,6 +486,31 @@ public class CallBackServiceImpl implements ICallBackService {
                 .build();
     }
 
+    private TencentOrderAppRpcDTO transform(PlatformOrderDTO platformOrderDTO, Agent agent, User user) {
+        return TencentOrderAppRpcDTO.builder()
+                .gameId(agent.getGameId())
+                .accountId(agent.getAccountId())
+                .userId(user.getId().toString())
+                .orderId(platformOrderDTO.getOrderId())
+                .agentKey(agent.getAgentKey())
+                .backPolicyId(agent.getBackPolicyId())
+                .rechargeMoney(platformOrderDTO.getAmount().multiply(new BigDecimal(100)).longValue())
+                .orderStatus(platformOrderDTO.getStatus())
+                .regTime(user.getCreateTime())
+                .createTime(platformOrderDTO.getCreateTime())
+                .payTime(platformOrderDTO.getPayTime())
+                .roleId(platformOrderDTO.getRoleId())
+                .roleName(platformOrderDTO.getRoleName())
+                .mac(user.getMac())
+                .imei(user.getImei())
+                .oaid(user.getOaid())
+                .androidId(user.getAndroidId())
+                .idfa(user.getIdfa())
+                .caid(user.getCaid())
+                .userActionSetId(agent.getUserActionSetId())
+                .build();
+    }
+
     private TtRoleRegisterAppRpcDTO transform(User user, Agent agent, GameUserRole gameUserRole) {
         return TtRoleRegisterAppRpcDTO.builder()
                 .gameId(agent.getGameId())
@@ -466,29 +531,24 @@ public class CallBackServiceImpl implements ICallBackService {
                 .build();
     }
 
-    private TtAppUserBackQueryRpcDTO transform(Long userId, Agent agent) {
-        return TtAppUserBackQueryRpcDTO.builder()
-                .gameId(agent.getGameId())
-                .userId(userId.toString())
-                .agentKey(agent.getAgentKey())
-                .build();
-    }
-
-    private TtAppOrderBackQueryRpcDTO transform(Long userId, String orderId, Agent agent) {
-        return TtAppOrderBackQueryRpcDTO.builder()
-                .gameId(agent.getGameId())
-                .userId(userId.toString())
-                .orderId(orderId)
-                .agentKey(agent.getAgentKey())
-                .build();
-    }
-
-    private TtAppRoleRegisterBackQueryRpcDTO transform(Long userId, Agent agent, String roleId) {
-        return TtAppRoleRegisterBackQueryRpcDTO.builder()
+    private TencentRoleRegisterAppRpcDTO transform(Agent agent, User user, GameUserRole gameUserRole) {
+        return TencentRoleRegisterAppRpcDTO.builder()
                 .gameId(agent.getGameId())
-                .userId(userId.toString())
+                .userId(user.getId().toString())
+                .backPolicyId(agent.getBackPolicyId())
+                .accountId(agent.getAccountId())
                 .agentKey(agent.getAgentKey())
-                .roleId(roleId)
+                .roleId(gameUserRole.getRoleId())
+                .roleName(gameUserRole.getRoleName())
+                .roleLevel(gameUserRole.getRoleLevel())
+                .registerTime(gameUserRole.getCreateTime())
+                .mac(user.getMac())
+                .imei(user.getImei())
+                .oaid(user.getOaid())
+                .androidId(user.getAndroidId())
+                .idfa(user.getIdfa())
+                .caid(user.getCaid())
+                .userActionSetId(agent.getUserActionSetId())
                 .build();
     }
 

+ 28 - 7
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/GameBackLogMediaSdkServiceImpl.java

@@ -6,12 +6,13 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.sd4324530.jtuple.Tuple2;
 import com.github.sd4324530.jtuple.Tuple3;
 import com.zanxiang.game.back.base.ServerInfo;
-import com.zanxiang.game.back.base.pojo.dto.TencentMiniGameOrderBackQueryRpcDTO;
+import com.zanxiang.game.back.base.pojo.dto.TencentAppOrderBackQueryRpcDTO;
 import com.zanxiang.game.back.base.pojo.dto.TtAppOrderBackQueryRpcDTO;
 import com.zanxiang.game.back.base.pojo.enums.OrderStatusEnum;
 import com.zanxiang.game.back.base.pojo.vo.GameBackPolicyRpcVO;
 import com.zanxiang.game.back.base.pojo.vo.OrderBackQueryRpcVO;
 import com.zanxiang.game.back.base.rpc.IGameBackPolicyRpc;
+import com.zanxiang.game.back.base.rpc.ITencentAppBackRpc;
 import com.zanxiang.game.back.base.rpc.ITencentMiniGameBackRpc;
 import com.zanxiang.game.back.base.rpc.ITtAppBackRpc;
 import com.zanxiang.game.module.base.pojo.enums.AccountTypeEnum;
@@ -60,6 +61,9 @@ public class GameBackLogMediaSdkServiceImpl extends ServiceImpl<GameBackLogMedia
     @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
     private ITencentMiniGameBackRpc tencentMiniGameBackRpc;
 
+    @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
+    private ITencentAppBackRpc tencentAppBackRpc;
+
     @Autowired
     private IUserService userService;
 
@@ -241,11 +245,19 @@ public class GameBackLogMediaSdkServiceImpl extends ServiceImpl<GameBackLogMedia
         //判断是否订单付费回传, 添加回传金额
         if (Objects.equals(callBackTypeEnum, CallBackTypeEnum.CALL_BACK_PAY_ORDER) && Strings.isNotBlank(param.getOrderId())) {
             PlatformOrderDTO platformOrderDTO = orderService.getByOrderId(param.getOrderId());
-            //头条APP媒体回传, 返回的单位是元
+            //APP直投回传
             if (Objects.equals(game.getCategory(), GameCategoryEnum.CATEGORY_APP.getId())) {
-                resultMap.put("amount", Collections.singletonList(platformOrderDTO.getAmount().intValue()));
+                //头条APP媒体回传, 返回的单位是元
+                if (Objects.equals(game.getPutType(), 1)) {
+                    resultMap.put("amount", Collections.singletonList(platformOrderDTO.getAmount().intValue()));
+                }
+                //腾讯APP媒体回传, 返回的单位是分
+                if (Objects.equals(game.getPutType(), 2)) {
+                    int amount = platformOrderDTO.getAmount().multiply(new BigDecimal(100)).intValue();
+                    resultMap.put("amount", Collections.singletonList(amount));
+                }
             }
-            //腾讯小游戏媒体SDK回传, 返回的单位是分, 乘以100
+            //腾讯小游戏媒体, 腾讯广点通SDK回传, 返回的单位是分, 乘以100
             if (Objects.equals(game.getCategory(), GameCategoryEnum.CATEGORY_WX_APPLET.getId())) {
                 if (this.orderPayAndBackCheck(platformOrderDTO, param.getMipeiSuces())) {
                     resultMap.put("callBack", Boolean.FALSE);
@@ -522,6 +534,15 @@ public class GameBackLogMediaSdkServiceImpl extends ServiceImpl<GameBackLogMedia
             doBack = orderBackQueryRpcVO.getDoBack();
             backMsg = orderBackQueryRpcVO.getBackMsg();
         }
+        //腾讯APP直投回传
+        if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_APP.getValue())) {
+            TencentAppOrderBackQueryRpcDTO orderQuery = this.transform(agent, user.getId(), orderId);
+            OrderBackQueryRpcVO orderBackQueryRpcVO = tencentAppBackRpc.orderBackQuery(orderQuery).getData();
+            //腾讯回传金额单位为分, 不需要处理
+            amount = orderBackQueryRpcVO.getBackMoney();
+            doBack = orderBackQueryRpcVO.getDoBack();
+            backMsg = orderBackQueryRpcVO.getBackMsg();
+        }
         //微信小游戏投放腾讯广告或巨量广告 (坑逼腾讯要其他渠道的订单数据)
         if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_MINI_GAME.getValue())
                 || Objects.equals(agent.getAccountType(), AccountTypeEnum.BYTE.getValue())) {
@@ -578,10 +599,10 @@ public class GameBackLogMediaSdkServiceImpl extends ServiceImpl<GameBackLogMedia
                 .build();
     }
 
-    private TencentMiniGameOrderBackQueryRpcDTO transform(String wechatOpenid, String orderId, Agent agent) {
-        return TencentMiniGameOrderBackQueryRpcDTO.builder()
+    private TencentAppOrderBackQueryRpcDTO transform(Agent agent, Long userId, String orderId) {
+        return TencentAppOrderBackQueryRpcDTO.builder()
                 .gameId(agent.getGameId())
-                .wechatOpenid(wechatOpenid)
+                .userId(userId.toString())
                 .orderId(orderId)
                 .agentKey(agent.getAgentKey())
                 .build();