Преглед изворни кода

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

lth пре 1 година
родитељ
комит
d71b17a9ad

+ 56 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/GameBackLog.java

@@ -0,0 +1,56 @@
+package com.zanxiang.game.module.mybatis.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @author : lingfeng
+ * @time : 2023-08-02
+ * @description : 回传日志
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+@Builder
+@TableName("t_game_back_log")
+public class GameBackLog implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+    /**
+     * 订单id
+     */
+    private String orderId;
+
+    /**
+     * 接口描述
+     */
+    private String describe;
+
+    /**
+     * 回传调接口参数
+     */
+    private String callBackParam;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+}

+ 12 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/mapper/GameBackLogMapper.java

@@ -0,0 +1,12 @@
+package com.zanxiang.game.module.mybatis.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zanxiang.game.module.mybatis.entity.GameBackLog;
+
+/**
+ * @author : lingfeng
+ * @time : 2023-08-02
+ * @description : ${description}
+ */
+public interface GameBackLogMapper extends BaseMapper<GameBackLog> {
+}

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

@@ -23,7 +23,7 @@ public class SDKApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(SDKApplication.class, args);
-        System.out.println("赞象SDK服务启动成功 <dubbo升级3.0, 小游戏导量H5上线> ( ´・・)ノ(._.`) \n" +
+        System.out.println("赞象SDK服务启动成功 <H5导量兼容账号密码, 回传调接口增加日志> ( ´・・)ノ(._.`) \n" +
                 " ___________ _   __\n" +
                 "/  ___|  _  \\ | / /\n" +
                 "\\ `--.| | | | |/ / \n" +

+ 22 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/IGameBackLogService.java

@@ -0,0 +1,22 @@
+package com.zanxiang.game.module.sdk.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zanxiang.game.module.mybatis.entity.GameBackLog;
+
+/**
+ * @author : lingfeng
+ * @time : 2023-08-02
+ * @description : 游戏回传日志
+ */
+public interface IGameBackLogService extends IService<GameBackLog> {
+
+    /**
+     * 添加日志
+     *
+     * @param userId   用户id
+     * @param orderId  订单id
+     * @param describe 描述
+     * @param param    参数
+     */
+    void addLog(Long userId, String orderId, String describe, String param);
+}

+ 9 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/IGameUserRoleService.java

@@ -2,6 +2,7 @@ package com.zanxiang.game.module.sdk.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.zanxiang.game.module.mybatis.entity.GameUserRole;
+import com.zanxiang.game.module.mybatis.entity.User;
 import com.zanxiang.game.module.sdk.pojo.param.GameUserRoleUpdateParam;
 import com.zanxiang.game.module.sdk.pojo.param.UserData;
 
@@ -17,6 +18,14 @@ public interface IGameUserRoleService extends IService<GameUserRole> {
      */
     Boolean updateUserGameRole(GameUserRoleUpdateParam param, UserData userData);
 
+    /**
+     * 用户指南游戏角色检查
+     *
+     * @param user         用户
+     * @param relationUser 用户关系
+     */
+    void userGuideGameRoleCheck(User user, User relationUser);
+
     /**
      * 通知监听服务
      *

+ 9 - 6
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/CallBackServiceImpl.java

@@ -55,6 +55,9 @@ public class CallBackServiceImpl implements ICallBackService {
     @Autowired
     private IGameExtService gameExtService;
 
+    @Autowired
+    private IGameBackLogService gameBackLogService;
+
     @Override
     public void userCallBack(User user, Map<String, String> urlParamMap) {
         //判断游戏是否开启广告回传, 未开启, 不回传
@@ -80,8 +83,8 @@ public class CallBackServiceImpl implements ICallBackService {
             //腾讯H5回传
             if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_H5.getValue())) {
                 TencentUserDTO tencentUserDTO = this.transform(user, agent, gameApplet);
-                log.error("用户注册 --> 腾讯H5回传提交, tencentUserDTO : {}", JsonUtil.toString(tencentUserDTO));
                 tencentUserActionBackRpc.backUser(tencentUserDTO);
+                gameBackLogService.addLog(user.getId(), null, "腾讯H5用户回传提交", JsonUtil.toString(tencentUserDTO));
             }
             //腾讯小游戏回传
             if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_MINI_GAME.getValue())) {
@@ -89,8 +92,8 @@ public class CallBackServiceImpl implements ICallBackService {
                 //解析设置clickId
                 Map<String, String> channelMap = agentService.channelTransform(user.getChannel());
                 tencentUserDTO.setClickId(channelMap.get("gdt_vid"));
-                log.error("用户注册 --> 腾讯小游戏回传提交, tencentUserDTO : {}", JsonUtil.toString(tencentUserDTO));
                 tencentMiniGameBackRpc.backUser(tencentUserDTO);
+                gameBackLogService.addLog(user.getId(), null, "腾讯小游戏用户回传提交", JsonUtil.toString(tencentUserDTO));
             }
             //头条回传
             if (CollectionUtils.isNotEmpty(urlParamMap) && Objects.equals(agent.getAccountType(), AccountTypeEnum.BYTE.getValue())) {
@@ -98,8 +101,8 @@ public class CallBackServiceImpl implements ICallBackService {
                 //判断是微信小游戏
                 if (Objects.equals(game.getCategory(), GameCategoryEnum.CATEGORY_WX_APPLET.getId())) {
                     TtUserActiveRpcDTO activeReportRpcDTO = this.transform(user, agent, gameApplet, urlParamMap);
-                    log.error("用户注册 --> 头条回传提交, activeReportRpcDTO : {}", JsonUtil.toString(activeReportRpcDTO));
                     ttMiniGameBackRpc.userActiveReport(activeReportRpcDTO);
+                    gameBackLogService.addLog(user.getId(), null, "头条用户回传提交", JsonUtil.toString(activeReportRpcDTO));
                 }
             }
         } catch (Exception e) {
@@ -130,8 +133,8 @@ public class CallBackServiceImpl implements ICallBackService {
             //腾讯H5回传
             if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_H5.getValue())) {
                 TencentOrderDTO tencentOrderDTO = this.transform(platformOrderDTO, user, agent, gameApplet);
-                log.error("用户下单 --> 腾讯H5回传提交, tencentOrderDTO : {}", JsonUtil.toString(tencentOrderDTO));
                 tencentUserActionBackRpc.backOrder(tencentOrderDTO);
+                gameBackLogService.addLog(user.getId(), platformOrderDTO.getOrderId(), "腾讯H5订单回传提交", JsonUtil.toString(tencentOrderDTO));
             }
             //腾讯小游戏回传
             if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_MINI_GAME.getValue())) {
@@ -139,8 +142,8 @@ public class CallBackServiceImpl implements ICallBackService {
                 //解析设置clickId
                 Map<String, String> channelMap = agentService.channelTransform(user.getChannel());
                 tencentOrderDTO.setClickId(channelMap.get("gdt_vid"));
-                log.error("用户下单 --> 腾讯小游戏回传提交, tencentOrderDTO : {}", JsonUtil.toString(tencentOrderDTO));
                 tencentMiniGameBackRpc.backOrder(tencentOrderDTO);
+                gameBackLogService.addLog(user.getId(), platformOrderDTO.getOrderId(), "腾讯小游戏订单回传提交", JsonUtil.toString(tencentOrderDTO));
             }
             //头条回传
             if (Objects.equals(agent.getAccountType(), AccountTypeEnum.BYTE.getValue())) {
@@ -148,8 +151,8 @@ public class CallBackServiceImpl implements ICallBackService {
                 Game game = gameService.getById(platformOrderDTO.getGameId());
                 if (Objects.equals(game.getCategory(), GameCategoryEnum.CATEGORY_WX_APPLET.getId())) {
                     TtOrderRpcDTO ttOrderRpcDTO = this.transform(platformOrderDTO, user.getOpenId(), agent, gameApplet, user.getCreateTime());
-                    log.error("用户下单 --> 头条回传提交, orderReportRpcDTO : {}", JsonUtil.toString(ttOrderRpcDTO));
                     ttMiniGameBackRpc.orderReport(ttOrderRpcDTO);
+                    gameBackLogService.addLog(user.getId(), platformOrderDTO.getOrderId(), "头条订单回传提交", JsonUtil.toString(ttOrderRpcDTO));
                 }
             }
         } catch (Exception e) {

+ 36 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/GameBackLogServiceImpl.java

@@ -0,0 +1,36 @@
+package com.zanxiang.game.module.sdk.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zanxiang.game.module.mybatis.entity.GameBackLog;
+import com.zanxiang.game.module.mybatis.mapper.GameBackLogMapper;
+import com.zanxiang.game.module.sdk.service.IGameBackLogService;
+import com.zanxiang.module.util.JsonUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author : lingfeng
+ * @time : 2023-08-02
+ * @description : 游戏回传日志
+ */
+@Slf4j
+@Service
+public class GameBackLogServiceImpl extends ServiceImpl<GameBackLogMapper, GameBackLog> implements IGameBackLogService {
+
+    @Override
+    public void addLog(Long userId, String orderId, String describe, String param) {
+        try {
+            super.save(GameBackLog.builder()
+                    .userId(userId)
+                    .orderId(orderId)
+                    .describe(describe)
+                    .callBackParam(JsonUtil.toString(param))
+                    .createTime(LocalDateTime.now())
+                    .build());
+        } catch (Exception e) {
+            log.error("回传接口日志保存异常, param : {}, e : {}", param, e.getMessage());
+        }
+    }
+}

+ 60 - 3
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/GameUserRoleServiceImpl.java

@@ -2,6 +2,7 @@ package com.zanxiang.game.module.sdk.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zanxiang.game.module.mybatis.entity.GameUser;
 import com.zanxiang.game.module.mybatis.entity.GameUserRole;
@@ -26,9 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.client.RestTemplate;
 
 import java.time.LocalDateTime;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -158,6 +157,64 @@ public class GameUserRoleServiceImpl extends ServiceImpl<GameUserRoleMapper, Gam
         distributedLockComponent.unlock(RedisKeyConstant.ROLE_UPDATE_KEY + "_" + userData.getUserId());
     }
 
+    @Override
+    public void userGuideGameRoleCheck(User user, User relationUser) {
+        //查询H5游戏角色列表
+        List<GameUserRole> relationUserRoleList = super.list(new LambdaQueryWrapper<GameUserRole>()
+                .eq(GameUserRole::getUserId, relationUser.getId())
+                .eq(GameUserRole::getGameId, relationUser.getGameId()));
+        //查询小游戏角色列表
+        List<GameUserRole> userRoleList = super.list(new LambdaQueryWrapper<GameUserRole>()
+                .eq(GameUserRole::getUserId, user.getId())
+                .eq(GameUserRole::getGameId, user.getGameId()));
+        //角色数量一致, 结束
+        if (userRoleList.size() == relationUserRoleList.size()) {
+            return;
+        }
+        //查询游戏玩家信息
+        GameUser gameUser = gameUserService.getOne(new LambdaQueryWrapper<GameUser>()
+                .eq(GameUser::getUserId, user.getId())
+                .eq(GameUser::getGameId, user.getGameId()));
+        if (gameUser == null) {
+            return;
+        }
+        //循环
+        List<GameUserRole> gameUserRoleList = new ArrayList<>();
+        relationUserRoleList.forEach(gameUserRole -> {
+            String roleId = gameUserRole.getRoleId();
+            GameUserRole userRole = userRoleList.stream()
+                    .filter(role -> Objects.equals(role.getRoleId(), roleId))
+                    .findFirst().orElse(null);
+            //缺少角色, 说明转到H5之后又重新在小程序登录创建了角色
+            if (userRole == null) {
+                gameUserRoleList.add(this.transform(user, gameUserRole, gameUser));
+            }
+        });
+        if (CollectionUtils.isNotEmpty(gameUserRoleList)) {
+            super.saveBatch(gameUserRoleList);
+        }
+    }
+
+    private GameUserRole transform(User user, GameUserRole gameUserRole, GameUser gameUser) {
+        return GameUserRole.builder()
+                .userId(user.getId())
+                .gameUserId(gameUser.getId())
+                .gameId(user.getGameId())
+                .serverId(gameUserRole.getServerId())
+                .serverName(gameUserRole.getServerName())
+                .roleId(gameUserRole.getRoleId())
+                .roleName(gameUserRole.getRoleName())
+                .roleLevel(gameUserRole.getRoleLevel())
+                .roleVipLevel(gameUserRole.getRoleVipLevel())
+                .rolePower(gameUserRole.getRolePower())
+                .os(gameUserRole.getOs())
+                .regTime(gameUserRole.getCreateTime())
+                .createTime(gameUserRole.getCreateTime())
+                .updateTime(gameUserRole.getUpdateTime())
+                .lastLoginTime(gameUserRole.getLastLoginTime())
+                .build();
+    }
+
     @Override
     public void callListenIn(GameUserRoleUpdateParam param, UserData userData) {
         Map<String, String> map = new HashMap<>(2);

+ 45 - 11
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/LoginServiceImpl.java

@@ -24,7 +24,9 @@ import org.apache.logging.log4j.util.Strings;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import reactor.util.function.Tuple2;
 import reactor.util.function.Tuple3;
+import reactor.util.function.Tuples;
 
 import java.time.LocalDateTime;
 import java.util.Map;
@@ -90,6 +92,9 @@ public class LoginServiceImpl implements IRegisterLoginService {
     @Autowired
     private IGameService gameService;
 
+    @Autowired
+    private IGameUserRoleService gameUserRoleService;
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public ResultVO<UserLoginVO> loginWxCode(LoginVxCodeParam param, UserData userData) {
@@ -178,11 +183,18 @@ public class LoginServiceImpl implements IRegisterLoginService {
             }
             //渠道更新和回传判断
             agentService.userAgentUpdate(user, userData.getChannel());
+            //登录信息
+            UserLoginVO userLoginVO = this.createUserLoginVO(user, userData);
+            Tuple2<Boolean, Long> tuple2 = this.userGuideCheck(user);
+            //导量用户返回原有的用户id
+            if (tuple2.getT1()) {
+                userLoginVO.setUserId(tuple2.getT2());
+            }
             //返回登录信息
-            return ResultVO.ok(this.createUserLoginVO(user, userData));
+            return ResultVO.ok(userLoginVO);
         }
         //用户注册, 用户名密码校验
-        HttpStatusEnum checkRegisterEnum = this.checkRegister(username, password);
+        HttpStatusEnum checkRegisterEnum = this.checkRegister(userData.getGameId(), username, password);
         if (!Objects.equals(checkRegisterEnum, HttpStatusEnum.SUCCESS)) {
             return ResultVO.fail(checkRegisterEnum.getMsg());
         }
@@ -218,14 +230,11 @@ public class LoginServiceImpl implements IRegisterLoginService {
             //渠道更新和回传判断
             agentService.userAgentUpdate(user, userData.getChannel());
             UserLoginVO userLoginVO = this.createUserLoginVO(user, userData);
-            Game game = gameService.getById(user.getGameId());
             //判断是否导量用户
-            if (user.getRelationUserId() != null && game.getGuideGameId() != null) {
-                User relationUser = userService.getById(user.getRelationUserId());
-                if (relationUser != null) {
-                    //导量用户返回原有的用户id
-                    userLoginVO.setUserId(relationUser.getId());
-                }
+            Tuple2<Boolean, Long> tuple2 = this.userGuideCheck(user);
+            //导量用户返回原有的用户id
+            if (tuple2.getT1()) {
+                userLoginVO.setUserId(tuple2.getT2());
             }
             //返回登录信息
             return ResultVO.ok(userLoginVO);
@@ -236,6 +245,28 @@ public class LoginServiceImpl implements IRegisterLoginService {
         return ResultVO.ok(this.createUserLoginVO(user, userData));
     }
 
+    private Tuple2<Boolean, Long> userGuideCheck(User user) {
+        //游戏信息
+        Game game = gameService.getById(user.getGameId());
+        //非导量用户
+        if (user.getRelationUserId() == null || game.getGuideGameId() == null) {
+            return Tuples.of(Boolean.FALSE, 0L);
+        }
+        //导量用户信息
+        User relationUser = userService.getById(user.getRelationUserId());
+        //确定导量匹配
+        if (relationUser != null && Objects.equals(relationUser.getRelationUserId(), user.getId())) {
+            try {
+                //监测角色是否导全, 或者导过之后又跑去小程序创建了其他角色
+                gameUserRoleService.userGuideGameRoleCheck(user, relationUser);
+            } catch (Exception ignored) {
+            }
+            return Tuples.of(Boolean.TRUE, relationUser.getId());
+        }
+        //非导量兜底逻辑
+        return Tuples.of(Boolean.FALSE, 0L);
+    }
+
     private User userCreateSave(UserData userData, String userName, String password, String mobile, String openId, String sessionKey) {
         //渠道id, 链接参数, 分享人id
         Tuple3<Long, Map<String, String>, String> tuple3 = agentService.getUserAgentId(userData);
@@ -333,13 +364,16 @@ public class LoginServiceImpl implements IRegisterLoginService {
         return Boolean.TRUE;
     }
 
-    private HttpStatusEnum checkRegister(String username, String password) {
+    private HttpStatusEnum checkRegister(Long gameId, String username, String password) {
         //判断用户名是否存在敏感词
         if (wordCheckService.hasWord(username)) {
             return HttpStatusEnum.USERNAME_SENSITIVE;
         }
         //判断用户名是否已存在
-        if (userService.count(new LambdaQueryWrapper<User>().eq(User::getUsername, username)) > 0) {
+        if (userService.count(new LambdaQueryWrapper<User>()
+                .eq(User::getGameId, gameId)
+                .eq(User::getUsername, username)
+        ) > 0) {
             return HttpStatusEnum.USERNAME_EXISTS;
         }
         //用户名合规检测