Explorar el Código

fix : 腾讯小游戏监测链接匹配优化

bilingfeng hace 1 mes
padre
commit
12502a162c
Se han modificado 12 ficheros con 66 adiciones y 420 borrados
  1. 1 1
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/GameBackApplication.java
  2. 8 10
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/controller/TencentMiniGameLogController.java
  3. 0 12
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/dao/mapper/TempCallbackMapper.java
  4. 0 211
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/TempCallback.java
  5. 1 1
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/rpc/impl/TencentMiniGameBackRpcImpl.java
  6. 1 1
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/IGameTencentMiniGameCallbackService.java
  7. 0 14
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/ITempCallbackService.java
  8. 28 34
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentMiniGameBackLogServiceImpl.java
  9. 2 2
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentMiniGameCallbackServiceImpl.java
  10. 20 12
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentMiniGameRoleRegisterServiceImpl.java
  11. 5 4
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentMiniGameUserServiceImpl.java
  12. 0 118
      game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/TempCallbackServiceImpl.java

+ 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("腾讯广告新增监测链接注册回传(解决监测链接匹配问题02) (´・・)ノ(._.`)  \n" +
+        System.out.println("腾讯广告新增监测链接注册回传(腾讯小游戏监测链接匹配优化) (´・・)ノ(._.`)  \n" +
                 " ______  __     __     \n" +
                 "/_____/\\/__/\\ /__/\\    \n" +
                 "\\:::__\\/\\ \\::\\\\:.\\ \\   \n" +

+ 8 - 10
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/controller/TencentMiniGameLogController.java

@@ -8,7 +8,10 @@ import com.zanxiang.game.back.serve.pojo.dto.OrderReportDTO;
 import com.zanxiang.game.back.serve.pojo.vo.GameTencentMiniGameOrderVO;
 import com.zanxiang.game.back.serve.pojo.vo.GameTencentMiniGameUserVO;
 import com.zanxiang.game.back.serve.pojo.vo.GameTencentMiniOrderSplitLogVO;
-import com.zanxiang.game.back.serve.service.*;
+import com.zanxiang.game.back.serve.service.IGameTencentMiniGameOrderService;
+import com.zanxiang.game.back.serve.service.IGameTencentMiniGameOrderSplitLogService;
+import com.zanxiang.game.back.serve.service.IGameTencentMiniGameRoleRegisterService;
+import com.zanxiang.game.back.serve.service.IGameTencentMiniGameUserService;
 import com.zanxiang.module.util.exception.BaseException;
 import com.zanxiang.module.util.pojo.ResultVO;
 import io.swagger.annotations.Api;
@@ -26,16 +29,18 @@ import java.util.List;
 @RequestMapping("/tencentMiniGame")
 @Api("腾讯小游戏回传")
 public class TencentMiniGameLogController {
+
     @Autowired
     private IGameTencentMiniGameUserService gameTencentMiniGameUserService;
+
     @Autowired
     private IGameTencentMiniGameOrderService gameTencentMiniGameOrderService;
+
     @Autowired
     private IGameTencentMiniGameOrderSplitLogService gameTencentMiniGameOrderSplitLogService;
+
     @Autowired
     private IGameTencentMiniGameRoleRegisterService gameTencentMiniGameRoleRegisterService;
-    @Autowired
-    private ITempCallbackService tempCallbackService;
 
     @PreAuthorize(permissionKey = "gameBack:tencentMiniGame:orderLogs")
     @PostMapping("/orderLogs")
@@ -111,11 +116,4 @@ public class TencentMiniGameLogController {
         return ResultVO.ok(gameTencentMiniGameRoleRegisterService.doReport(ids));
     }
 
-    @PreAuthorize(permissionKey = "gameBack:tencentMiniGame:checkCallBackUrl")
-    @PostMapping("/check/back/url")
-    @ApiOperation(value = "腾讯玩家注册回传地址检测")
-    public ResultVO<Boolean> checkCallBackUrl() {
-        tempCallbackService.checkCallBackUrl();
-        return ResultVO.ok();
-    }
 }

+ 0 - 12
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/dao/mapper/TempCallbackMapper.java

@@ -1,12 +0,0 @@
-package com.zanxiang.game.back.serve.dao.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.zanxiang.game.back.serve.pojo.entity.TempCallback;
-
-/**
- * @author : lingfeng
- * @time : 2025-03-06
- * @description : 临时表
- */
-public interface TempCallbackMapper extends BaseMapper<TempCallback> {
-}

+ 0 - 211
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/pojo/entity/TempCallback.java

@@ -1,211 +0,0 @@
-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 lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serializable;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-
-/**
- * @author : lingfeng
- * @time : 2025-03-06
- * @description : 腾讯小游戏监测链接数据临时表
- */
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-@Builder
-@TableName(TempCallback.TABLE_NAME)
-public class TempCallback implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-    public static final String TABLE_NAME = "t_temp_callback";
-
-    @TableId(value = "id", type = IdType.AUTO)
-    private Long id;
-
-    private String agentKey;
-
-    private Long gameId;
-
-    /**
-     * 时间发生日期
-     */
-    private LocalDate day;
-
-    /**
-     * 点击id, ex: 24oi6xq2aaakvagnqu7a, 宏: __CLICK_ID__
-     */
-    private String clickId;
-
-    /**
-     * 点击时间, ex: 1586437362, 宏: __CLICK_TIME__
-     */
-    private LocalDateTime clickTime;
-
-    /**
-     * 曝光时间, ex: 1586437361, ex: , 宏: __IMPRESSION_TIME__
-     */
-    private LocalDateTime impressionTime;
-
-    /**
-     * 广告组id(实际为广告id), ex: 228691429, ex: , 宏: __ADGROUP_ID__
-     */
-    private Long adgroupId;
-
-    /**
-     * 创意 ID, ex: 654321, 宏: __DYNAMIC_CREATIVE_ID__
-     */
-    private Long dynamicCreativeId;
-
-    /**
-     * 营销资产ID, ex: 12345, 宏: __MARKETING_ASSET_ID__
-     */
-    private Long marketingAssetId;
-
-    /**
-     * 素材标签ID, 宏: __MATERIAL_PACKAGE_ID__
-     */
-    private String materialPackageId;
-
-    /**
-     * 广告投放平台, 1:GDT entrance、3:京东直投、5:经 wechat mp 投放的广告、6:京东运营、8:QQ 公众账号平台、9:移动联盟 SSP、10:58 运营、11:58 商户、12:易车运营、13:易车商户、14:融 360 运营、15:融 360 商户、16:点评运营、17:点评商户、18:来自 OMG 的广告主、19:京东外单, 宏: __AD_PLATFORM_TYPE__
-     */
-    private Integer adPlatformType;
-
-    /**
-     * 广告主id, ex: 9471147, 宏: __ACCOUNT_ID__
-     */
-    private Long accountId;
-
-    /**
-     * 代理商id, ex: 1050262, 宏: __AGENCY_ID__
-     */
-    private Long agencyId;
-
-    /**
-     * 点击sku, ex: 478c4a93a054f7c9087b4ecb1f03f8a1, 宏: __CLICK_SKU_ID__
-     */
-    private String clickSkuId;
-
-    /**
-     * 设备类型, ex: ios、android, 宏: __DEVICE_OS_TYPE__
-     */
-    private String deviceOsType;
-
-    /**
-     * 请求时间, ex: 1586437335, 宏: __PROCESS_TIME__
-     */
-    private LocalDateTime processTime;
-
-    /**
-     * 应用id, ex: 1101072624、wx69618ae091cf2c76, 宏: __PROMOTED_OBJECT_ID__
-     */
-    private String promotedObjectId;
-
-    /**
-     * 请求id, ex: vqp7xdombqonw, 宏: __REQUEST_ID__
-     */
-    private String requestId;
-
-    /**
-     * 曝光id, ex: xkrx5et47h7g401, 宏: __IMPRESSION_ID__
-     */
-    private String impressionId;
-
-    /**
-     * 设备id(imei或idfa的加密值),对 IMEI 设备号转成小写,再进行md5编码,再小写,32位、对 IDFA 设备号保持大写,再进行 md5 编码,再小写,32位, 宏: __MUID__
-     */
-    private String muid;
-
-    /**
-     * 安卓id做md5加密后小写, ex: 797745b011e3286de9e1a1c59ba72c97, 宏: __HASH_ANDROID_ID__
-     */
-    private String hashAndroidId;
-
-    /**
-     * 媒体投放系统获取的用户终端的公共IPV4地址, ex: 183.226.102.120, 宏: __IP__
-     */
-    private String ip;
-
-    /**
-     * 用户代理(user_agent), ex: Dalvik%2F2.1.0+%28Linux%3B+U%3B+Android+8.0.0%3B+PIC-AL00+Build%2FHUAWEIPIC-AL00%29, 宏: __USER_AGENT__
-     */
-    private String userAgent;
-
-    /**
-     * 情况1:使用 DataNexus 配置,并与广告直接绑定(ex: 空值)、情况2:新版转化归因中的监测链接信息(使用 DataNexus 或直接填写监测链接)直接提供上报信息回传接口的 url,示例为url encode 编码原值,广告主需要 decode 作为 post 请求url回传至腾讯广告(ex: http%3A%2F%2Ftracking.e.qq.com%2Fconv%3Fcb%3DxXx%252BxXx%253D%26conv_id%3D123)、情况3:使用投放管理平台 - 工具(ex: http://tracking.e.qq.com/conv?cb=%s&&%s&&%s&&%s 其中%s代表的参数分别为 productId、productType、advertiserId、clickId), 宏: __CALLBACK__
-     */
-    private String callback;
-
-    /**
-     * 联盟广告位id, ex: 8144201, 宏: __ENCRYPTED_POSITION_ID__
-     */
-    private String encryptedPositionId;
-
-    /**
-     * 媒体投放系统获取的用户终端的公共IPV6地址, ex: 2409%3A8a55%3A4cc0%3A4050%3A2507%3A4922%3Abbe0%3A524b, 宏: __IPV6__
-     */
-    private String ipv6;
-
-    /**
-     * Android Q 及更高版本的设备号,64位及以下,取原值后做md5加密, ex: 9d271e4d04de7e4b0b4f1df20e79ce64, 宏: __HASH_OAID__
-     */
-    private String hashOaid;
-
-    /**
-     * URL Encode后的JSON数组;其中qaid为中广协ID(即CAID),hash_qaid为CAID原值MD5加密后的结果, version为腾讯版本号,支持两个版本同时下发(即最新版和上一版),腾讯版本号与中广协版本对应关系为:腾讯 1001 = 中广协 20200901;腾讯 1003 = 中广协 20201230; 腾讯1004 = 中广协 20211207;腾讯1005=中广协 20220111;腾讯1006=中广协 20230330, 宏: __QAID_CAA__
-     */
-    private String caid;
-
-    /**
-     * 机型, ex:  PCKM00、Redmi 7、iPhone 7..., 宏: __MODEL__
-     */
-    private String model;
-
-    /**
-     * 专用于网页类小程序转化规则的点击监测下发,其它类型不支持该字段下发。每个用户针对小程序应用会产生一个安全的OpenID,只针对当前的小程序有效, ex: ozWH25VK0aodxYMZrX0Lqj9HHhrg, 宏: __WECHAT_OPEN_ID__
-     */
-    private String wechatOpenid;
-
-    /**
-     * 媒体投放系统获取的用户终端的公共IPV4地址MD5加密后转小写,仅在新版转化里支持配置, 宏: __IP_MD5__
-     */
-    private String ipMd5;
-
-    /**
-     * 媒体投放系统获取的用户终端的公共IPV6地址MD5加密后转小写,仅在新版转化里支持配置, 宏: __IPV6_MD5__
-     */
-    private String ipv6Md5;
-
-    /**
-     * 渠道包id, 只 for Android 设备生效, 宏: __CHANNEL_PACKAGE_ID__
-     */
-    private String channelPackageId;
-
-    /**
-     * 操作系统版本, 只 for iOS 和 Android 设备生效, 宏: __DEVICE_OS_VERSION__
-     */
-    private String deviceOsVersion;
-
-    /**
-     * 行为类型, LANDING_PAGE_CLICK:点击跳转按钮,RESERVATION:表单预约, 宏: __ACT_TYPE__
-     */
-    private String actType;
-
-    /**
-     * 行为时间, ex: 1586437361, 宏: __ACT_TIME__
-     */
-    private LocalDateTime actTime;
-
-    /**
-     * 微信小游戏appid
-     */
-    private String wechatAppId;
-}

+ 1 - 1
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/rpc/impl/TencentMiniGameBackRpcImpl.java

@@ -236,7 +236,7 @@ public class TencentMiniGameBackRpcImpl implements ITencentMiniGameBackRpc {
                 .build();
         //匹配回传URL
         String callBackUrl = gameTencentMiniGameCallbackService.getCallBackUrl(dto.getGameId(), dto.getWechatOpenid(),
-                dto.getClickId(), dto.getRegisterTime());
+                dto.getClickId(), dto.getRegisterTime(), true);
         if (Strings.isNotBlank(callBackUrl)) {
             userLog.setCallBackUrl(callBackUrl);
         }

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

@@ -10,5 +10,5 @@ public interface IGameTencentMiniGameCallbackService extends IService<GameTencen
 
     boolean callback(GameTencentCallbackDTO dto);
 
-    String getCallBackUrl(Long gameId, String wechatOpenid, String clickId, LocalDateTime registerTime);
+    String getCallBackUrl(Long gameId, String wechatOpenid, String clickId, LocalDateTime registerTime, boolean matchTime);
 }

+ 0 - 14
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/ITempCallbackService.java

@@ -1,14 +0,0 @@
-package com.zanxiang.game.back.serve.service;
-
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.zanxiang.game.back.serve.pojo.entity.TempCallback;
-
-/**
- * @author : lingfeng
- * @time : 2025-03-06
- * @description : 临时表
- */
-public interface ITempCallbackService extends IService<TempCallback> {
-
-    void checkCallBackUrl();
-}

+ 28 - 34
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentMiniGameBackLogServiceImpl.java

@@ -1,12 +1,14 @@
 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.github.sd4324530.jtuple.Tuple2;
 import com.zanxiang.game.back.base.pojo.enums.OrderStatusEnum;
 import com.zanxiang.game.back.serve.dao.mapper.GameTencentMiniGameBackLogMapper;
-import com.zanxiang.game.back.serve.pojo.entity.*;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentMiniGameBackLog;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentMiniGameOrder;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentMiniGameRoleRegister;
+import com.zanxiang.game.back.serve.pojo.entity.GameTencentMiniGameUser;
 import com.zanxiang.game.back.serve.pojo.enums.ActionTypeEnum;
 import com.zanxiang.game.back.serve.pojo.enums.BackStatusEnum;
 import com.zanxiang.game.back.serve.pojo.enums.BackTypeEnum;
@@ -15,7 +17,6 @@ import com.zanxiang.game.back.serve.service.IGameTencentMiniGameCallbackService;
 import com.zanxiang.game.back.serve.service.IGameTencentMiniGameUserService;
 import com.zanxiang.module.util.DateUtil;
 import com.zanxiang.module.util.JsonUtil;
-import com.zanxiang.module.util.URIUtil;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -179,7 +180,11 @@ public class GameTencentMiniGameBackLogServiceImpl extends ServiceImpl<GameTence
                 .build();
         try {
             log.error("腾讯小游戏回传参数:{}", JsonUtil.toString(request));
-            ResponseEntity<Map> response = restTemplate.postForEntity(this.getCallBackUrl(backLog), request, Map.class);
+            String callBackUrl = this.getCallBackUrl(backLog);
+            if (Strings.isBlank(callBackUrl)) {
+                return Tuple2.with(BackStatusEnum.FAILED, "监测链接未匹配到callBackUrl");
+            }
+            ResponseEntity<Map> response = restTemplate.postForEntity(callBackUrl, request, Map.class);
             log.error("腾讯小游戏回传完成:{}", JsonUtil.toString(response.getBody()));
             if (response.getStatusCode().is2xxSuccessful()) {
                 if (Objects.equals(response.getBody().get("code").toString(), "0")) {
@@ -194,40 +199,29 @@ public class GameTencentMiniGameBackLogServiceImpl extends ServiceImpl<GameTence
     }
 
     private String getCallBackUrl(GameTencentMiniGameBackLog backLog) {
-        GameTencentMiniGameUser user = gameTencentMiniGameUserService.getOne(new LambdaQueryWrapper<GameTencentMiniGameUser>()
-                .eq(GameTencentMiniGameUser::getGameId, backLog.getGameId())
-                .eq(GameTencentMiniGameUser::getWechatAppId, backLog.getWechatAppId())
-                .eq(GameTencentMiniGameUser::getWechatOpenid, backLog.getWechatOpenid())
-                .eq(GameTencentMiniGameUser::getAdAccountId, backLog.getAdAccountId())
-                .eq(GameTencentMiniGameUser::getBackType, BackTypeEnum.BACK_API.getBackType())
-                .orderByDesc(GameTencentMiniGameUser::getCreateTime)
-                .last("limit 1"));
-        String callBackUrl = Optional.ofNullable(user)
+        GameTencentMiniGameUser gameTencentMiniGameUser = gameTencentMiniGameUserService.getOne(
+                new LambdaQueryWrapper<GameTencentMiniGameUser>()
+                        .eq(GameTencentMiniGameUser::getGameId, backLog.getGameId())
+                        .eq(GameTencentMiniGameUser::getWechatAppId, backLog.getWechatAppId())
+                        .eq(GameTencentMiniGameUser::getWechatOpenid, backLog.getWechatOpenid())
+                        .eq(GameTencentMiniGameUser::getAdAccountId, backLog.getAdAccountId())
+                        .eq(GameTencentMiniGameUser::getBackType, BackTypeEnum.BACK_API.getBackType())
+                        .orderByDesc(GameTencentMiniGameUser::getCreateTime)
+                        .last("limit 1"));
+        String callBackUrl = Optional.ofNullable(gameTencentMiniGameUser)
                 .map(GameTencentMiniGameUser::getCallBackUrl)
                 .orElse(null);
-        if (Strings.isNotBlank(callBackUrl)) {
+        if (Strings.isNotBlank(callBackUrl) || gameTencentMiniGameUser == null) {
             return callBackUrl;
         }
-        GameTencentMiniGameCallback tencentMiniGameCallback = gameTencentMiniGameCallbackService.getOne(
-                new LambdaQueryWrapper<GameTencentMiniGameCallback>()
-                        .eq(GameTencentMiniGameCallback::getWechatOpenid, backLog.getWechatOpenid())
-                        .and(qw -> qw.eq(GameTencentMiniGameCallback::getImpressionId, backLog.getClickId())
-                                .or().eq(GameTencentMiniGameCallback::getRequestId, backLog.getClickId())
-                        )
-                        .orderByDesc(GameTencentMiniGameCallback::getClickTime)
-                        .last("limit 1"));
-        String callBack = Optional.ofNullable(tencentMiniGameCallback)
-                .map(GameTencentMiniGameCallback::getCallback)
-                .orElse(null);
-        if (Strings.isBlank(callBack)) {
-            return "http://tracking.e.qq.com/conv";
-        }
-        callBackUrl = URIUtil.decodeURIComponent(callBack);
-        if (user != null) {
-            gameTencentMiniGameUserService.update(new LambdaUpdateWrapper<GameTencentMiniGameUser>()
-                    .set(GameTencentMiniGameUser::getCallBackUrl, callBackUrl)
-                    .eq(GameTencentMiniGameUser::getId, user.getId())
-            );
+        //再次查询回传URL, 抛开时间限制条件, 腾讯坑爹监测数据有可能延迟
+        callBackUrl = gameTencentMiniGameCallbackService.getCallBackUrl(gameTencentMiniGameUser.getGameId(),
+                gameTencentMiniGameUser.getWechatOpenid(), gameTencentMiniGameUser.getClickId(),
+                gameTencentMiniGameUser.getRegisterTime(), false);
+        //回传url更新到用户信息中
+        if (Strings.isNotBlank(callBackUrl)) {
+            gameTencentMiniGameUser.setCallBackUrl(callBackUrl);
+            gameTencentMiniGameUserService.updateById(gameTencentMiniGameUser);
         }
         return callBackUrl;
     }

+ 2 - 2
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentMiniGameCallbackServiceImpl.java

@@ -67,7 +67,7 @@ public class GameTencentMiniGameCallbackServiceImpl extends ServiceImpl<GameTenc
     }
 
     @Override
-    public String getCallBackUrl(Long gameId, String wechatOpenid, String clickId, LocalDateTime registerTime) {
+    public String getCallBackUrl(Long gameId, String wechatOpenid, String clickId, LocalDateTime registerTime, boolean matchTime) {
         try {
             //1. 精准匹配, openId 必须匹配, requestId, clickId, impressionId, 有一个匹配上即可
             GameTencentMiniGameCallback tencentMiniGameCallback = super.getOne(
@@ -86,7 +86,7 @@ public class GameTencentMiniGameCallbackServiceImpl extends ServiceImpl<GameTenc
                         .and(qw -> qw.eq(GameTencentMiniGameCallback::getImpressionId, clickId)
                                 .or().eq(GameTencentMiniGameCallback::getRequestId, clickId)
                                 .or().eq(GameTencentMiniGameCallback::getClickId, clickId))
-                        .le(GameTencentMiniGameCallback::getClickTime, DateUtil.localDateTimeToSecond(registerTime))
+                        .le(matchTime, GameTencentMiniGameCallback::getClickTime, DateUtil.localDateTimeToSecond(registerTime))
                         .orderByDesc(GameTencentMiniGameCallback::getClickTime)
                         .last("limit 1"));
             }

+ 20 - 12
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentMiniGameRoleRegisterServiceImpl.java

@@ -159,16 +159,8 @@ public class GameTencentMiniGameRoleRegisterServiceImpl extends ServiceImpl<Game
         GameBackPolicy gameBackPolicy = roleRegisterLog.getBackPolicyId() == null ? null
                 : gameBackPolicyService.getById(roleRegisterLog.getBackPolicyId());
 
-        //判断创角是否回传
-        if (gameTencentMiniGameBackLogService.count(new LambdaQueryWrapper<GameTencentMiniGameBackLog>()
-                .eq(GameTencentMiniGameBackLog::getGameId, roleRegisterLog.getGameId())
-                .eq(GameTencentMiniGameBackLog::getWechatAppId, roleRegisterLog.getWechatAppId())
-                .eq(GameTencentMiniGameBackLog::getWechatOpenid, roleRegisterLog.getWechatOpenid())
-                .eq(GameTencentMiniGameBackLog::getAdAccountId, roleRegisterLog.getAdAccountId())
-                .eq(GameTencentMiniGameBackLog::getActionType, ActionTypeEnum.CREATE_ROLE.getActionType())
-                .eq(GameTencentMiniGameBackLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
-                .eq(GameTencentMiniGameBackLog::getBackType, BackTypeEnum.BACK_API.getBackType())
-        ) > 0) {
+        //判断创角是否已成功回传
+        if (this.roleBackCheck(roleRegisterLog)) {
             //新手引导回传
             this.tutorialFinishBack(roleRegisterLog, gameBackPolicy);
             //创角已回传
@@ -181,16 +173,32 @@ public class GameTencentMiniGameRoleRegisterServiceImpl extends ServiceImpl<Game
             return Tuple2.with(BackStatusEnum.NO, "等级小于回传策略等级 " + gameBackPolicy.getRoleLevelMin() + "。不回传");
         }
 
-        //判断注册是否回传
-        if (user != null && Objects.equals(BackStatusEnum.NO.getBackStatus(), user.getBackStatus())) {
+        //判断注册是否成功回传
+        if (user != null && !Objects.equals(BackStatusEnum.SUCCESS.getBackStatus(), user.getBackStatus())) {
             //执行注册回传
             gameTencentMiniGameUserService.userBack(user);
+            //判断注册回传的时候是否合并了创角回传, 如果已经回传成功, 则不再回传
+            if (this.roleBackCheck(roleRegisterLog)) {
+                return Tuple2.with(BackStatusEnum.SUCCESS, "注册回传同步回传创角成功");
+            }
         }
 
         //创角回传
         return gameTencentMiniGameBackLogService.roleRegisterBack(roleRegisterLog);
     }
 
+    private boolean roleBackCheck(GameTencentMiniGameRoleRegister roleRegisterLog) {
+        return gameTencentMiniGameBackLogService.count(new LambdaQueryWrapper<GameTencentMiniGameBackLog>()
+                .eq(GameTencentMiniGameBackLog::getGameId, roleRegisterLog.getGameId())
+                .eq(GameTencentMiniGameBackLog::getWechatAppId, roleRegisterLog.getWechatAppId())
+                .eq(GameTencentMiniGameBackLog::getWechatOpenid, roleRegisterLog.getWechatOpenid())
+                .eq(GameTencentMiniGameBackLog::getAdAccountId, roleRegisterLog.getAdAccountId())
+                .eq(GameTencentMiniGameBackLog::getActionType, ActionTypeEnum.CREATE_ROLE.getActionType())
+                .eq(GameTencentMiniGameBackLog::getBackStatus, BackStatusEnum.SUCCESS.getBackStatus())
+                .eq(GameTencentMiniGameBackLog::getBackType, BackTypeEnum.BACK_API.getBackType())
+        ) > 0;
+    }
+
     @Override
     public void tutorialFinishBack(GameTencentMiniGameRoleRegister roleRegisterLog, GameBackPolicy gameBackPolicy) {
         //角色判断完成新手引导回传

+ 5 - 4
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/GameTencentMiniGameUserServiceImpl.java

@@ -45,16 +45,17 @@ import java.util.stream.Collectors;
 public class GameTencentMiniGameUserServiceImpl extends ServiceImpl<GameTencentMiniGameUserMapper, GameTencentMiniGameUser>
         implements IGameTencentMiniGameUserService {
 
+    @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
+    private IAgentRpc agentRpc;
+
     @DubboReference(providedBy = AdvertisingTencentServer.SERVER_DUBBO_NAME)
     private IUserActionSetRpc userActionSetRpc;
+
     @Autowired
     private IGameTencentMiniGameBackLogService gameTencentMiniGameBackLogService;
-    @Autowired
-    private IDistributedLockComponent distributedLockComponent;
+
     @Autowired
     private IGameBackPolicyService gameBackPolicyService;
-    @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
-    private IAgentRpc agentRpc;
 
     @Override
     @Transactional(rollbackFor = Exception.class)

+ 0 - 118
game-back/game-back-serve/src/main/java/com/zanxiang/game/back/serve/service/impl/TempCallbackServiceImpl.java

@@ -1,118 +0,0 @@
-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.plugins.pagination.Page;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.zanxiang.game.back.serve.dao.mapper.TempCallbackMapper;
-import com.zanxiang.game.back.serve.pojo.entity.GameTencentMiniGameUser;
-import com.zanxiang.game.back.serve.pojo.entity.TempCallback;
-import com.zanxiang.game.back.serve.service.IGameTencentMiniGameUserService;
-import com.zanxiang.game.back.serve.service.ITempCallbackService;
-import com.zanxiang.module.util.DateUtil;
-import com.zanxiang.module.util.URIUtil;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.logging.log4j.util.Strings;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.Optional;
-
-/**
- * @author : lingfeng
- * @time : 2025-03-06
- * @description : 临时表
- */
-@Slf4j
-@Service
-public class TempCallbackServiceImpl extends ServiceImpl<TempCallbackMapper, TempCallback> implements ITempCallbackService {
-
-    @Autowired
-    private IGameTencentMiniGameUserService gameTencentMiniGameUserService;
-
-    @Override
-    public void checkCallBackUrl() {
-        long current = 1;
-        long size = 5000;
-        long pages;
-        do {
-            Page<GameTencentMiniGameUser> miniGameUserPage = gameTencentMiniGameUserService.page(Page.of(current, size),
-                    new LambdaQueryWrapper<GameTencentMiniGameUser>()
-                            .select(GameTencentMiniGameUser::getId, GameTencentMiniGameUser::getGameId,
-                                    GameTencentMiniGameUser::getWechatOpenid, GameTencentMiniGameUser::getClickId,
-                                    GameTencentMiniGameUser::getRegisterTime)
-                            .eq(GameTencentMiniGameUser::getGameId, 35L)
-                            .eq(GameTencentMiniGameUser::getBackType, "BACK_API")
-                            .isNull(GameTencentMiniGameUser::getCallBackUrl)
-                            .orderByDesc(GameTencentMiniGameUser::getCreateTime));
-            pages = miniGameUserPage.getPages();
-            log.error("第 {} 页正在处理-------> , 共 {} 页", current, pages);
-            this.updateCallBackUrlBatch(miniGameUserPage.getRecords());
-            log.error("第 {} 处理完成 =========> , 共 {} 页", current, pages);
-        } while (++current <= pages);
-    }
-
-    private void updateCallBackUrlBatch(List<GameTencentMiniGameUser> records) {
-        if (CollectionUtils.isEmpty(records)) {
-            return;
-        }
-        records.forEach(r -> {
-            String callBackUrl = this.getCallBackUrl(r.getGameId(), r.getWechatOpenid(), r.getClickId(), r.getRegisterTime());
-            if (Strings.isBlank(callBackUrl)) {
-                return;
-            }
-            gameTencentMiniGameUserService.update(new LambdaUpdateWrapper<GameTencentMiniGameUser>()
-                    .set(GameTencentMiniGameUser::getCallBackUrl, callBackUrl)
-                    .eq(GameTencentMiniGameUser::getId, r.getId())
-            );
-        });
-    }
-
-    private String getCallBackUrl(Long gameId, String wechatOpenid, String clickId, LocalDateTime registerTime) {
-        try {
-            //1. 精准匹配, openId 必须匹配, requestId, clickId, impressionId, 有一个匹配上即可
-            TempCallback tempCallback = super.getOne(new LambdaQueryWrapper<TempCallback>()
-                    .eq(TempCallback::getGameId, gameId)
-                    .eq(TempCallback::getWechatOpenid, wechatOpenid)
-                    .and(qw -> qw.eq(TempCallback::getImpressionId, clickId)
-                            .or().eq(TempCallback::getRequestId, clickId)
-                            .or().eq(TempCallback::getClickId, clickId))
-                    .orderByDesc(TempCallback::getClickTime)
-                    .last("limit 1"));
-            //2. 模糊匹配, 分别使用 requestId, clickId, impressionId 匹配, 有一个匹配上即可, 加上注册时间距离最近条件
-            if (tempCallback == null) {
-                tempCallback = super.getOne(new LambdaQueryWrapper<TempCallback>()
-                        .eq(TempCallback::getGameId, gameId)
-                        .and(qw -> qw.eq(TempCallback::getImpressionId, clickId)
-                                .or().eq(TempCallback::getRequestId, clickId)
-                                .or().eq(TempCallback::getClickId, clickId))
-                        .le(TempCallback::getClickTime, registerTime)
-                        .orderByDesc(TempCallback::getClickTime)
-                        .last("limit 1"));
-            }
-            //3. 兜底逻辑, 只用openId匹配
-            if (tempCallback == null) {
-                tempCallback = super.getOne(new LambdaQueryWrapper<TempCallback>()
-                        .eq(TempCallback::getGameId, gameId)
-                        .eq(TempCallback::getWechatOpenid, wechatOpenid)
-                        .orderByDesc(TempCallback::getClickTime)
-                        .last("limit 1"));
-            }
-            String callBack = Optional.ofNullable(tempCallback)
-                    .map(TempCallback::getCallback)
-                    .orElse(null);
-            if (Strings.isBlank(callBack)) {
-                log.error("匹配监测链接为空, wechatOpenid : {}, clickId : {}", wechatOpenid, clickId);
-                return null;
-            }
-            //返回匹配回传地址
-            return URIUtil.decodeURIComponent(callBack);
-        } catch (Exception e) {
-            log.error("匹配监测链接异常, wechatOpenid : {}, clickId : {}, e : {}", wechatOpenid, clickId, e.getMessage());
-        }
-        return null;
-    }
-}