Przeglądaj źródła

Merge branch 'package' of GameCenter/game-center into dev

zhimo 3 miesięcy temu
rodzic
commit
555c11f151

+ 1 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/ManageApplication.java

@@ -23,7 +23,7 @@ public class ManageApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(ManageApplication.class, args);
-        System.out.println("赞象Manage服务启动成功 < (发码器完成 ・・)ノ(._.`) \n" +
+        System.out.println("赞象Manage服务启动成功 < (IP解析代码上线 ・・)ノ(._.`) \n" +
                 "___  ___  ___   _   _   ___  _____  _____ \n" +
                 "|  \\/  | / _ \\ | \\ | | / _ \\|  __ \\|  ___|\n" +
                 "| .  . |/ /_\\ \\|  \\| |/ /_\\ \\ |  \\/| |__  \n" +

+ 21 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/UserController.java

@@ -29,6 +29,9 @@ import java.util.List;
 @Slf4j
 public class UserController {
 
+    @Autowired
+    private IIpDataAssayService ipDataAssayService;
+
     @Autowired
     private IUserService userService;
 
@@ -153,4 +156,22 @@ public class UserController {
     public ResultVO<Boolean> appletToH5(@RequestParam Long userId, @RequestParam String mobile, @RequestParam Integer type) {
         return ResultVO.ok(userService.appletToH5(userId, mobile, type));
     }
+
+    @ApiOperation(value = "玩家注册数据IP解析")
+    @PatchMapping(value = "/ip/assay")
+    @PreAuthorize(permissionKey = "manage:user:ipAssay")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功")})
+    public ResultVO<Void> userIpAssay(@RequestParam Long supperGameId) {
+        ipDataAssayService.userHandle(supperGameId);
+        return ResultVO.ok();
+    }
+
+    @ApiOperation(value = "玩家登录日志数据IP解析")
+    @PatchMapping(value = "/login/log/ip/assay")
+    @PreAuthorize(permissionKey = "manage:user:loginLogIpAssay")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功")})
+    public ResultVO<Void> userLoginLogIpAssay() {
+        ipDataAssayService.userLoginLogHandle();
+        return ResultVO.ok();
+    }
 }

+ 28 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IIpDataAssayService.java

@@ -0,0 +1,28 @@
+package com.zanxiang.game.module.manage.service;
+
+import java.util.List;
+
+/**
+ * @author : lingfeng
+ * @time : 2025-01-15
+ * @description :
+ */
+public interface IIpDataAssayService {
+
+    /**
+     * 用户表处理
+     */
+    void userHandle(long supperGameId);
+
+    /**
+     * 登录日志处理
+     */
+    void userLoginLogHandle();
+
+    /**
+     * 队列IP数据处理
+     *
+     * @param msgList : 消息列表
+     */
+    void ipDataHandle(List<String> msgList);
+}

+ 1 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/CpSendMsgLogServiceImpl.java

@@ -73,7 +73,7 @@ public class CpSendMsgLogServiceImpl extends ServiceImpl<CpSendMsgLogMapper, CpS
             List<String> serverRoleIdList = cpSendMsgResultList.stream().map(CpSendMsgResult::getRoleId).collect(Collectors.toList());
             try {
                 CpSendMsgResultDTO result = this.cpSendMsgApi(gameSupper, cpSendMsgLog.getMsgId(), serverId, text, serverRoleIdList);
-                this.reResultHandle(cpSendMsgLog, result, sendResultList);
+                this.reResultHandle(cpSendMsgLog, result, cpSendMsgResultList);
             } catch (Exception e) {
                 log.error("CP消息发送API调用异常, cpSendMsgLog : {}, sendMsgResultList : {}, e : {}",
                         JsonUtil.toString(cpSendMsgLog), JsonUtil.toString(sendResultList), e.getMessage(), e);

+ 152 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/IpDataAssayServiceImpl.java

@@ -0,0 +1,152 @@
+package com.zanxiang.game.module.manage.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.github.sd4324530.jtuple.Tuple3;
+import com.zanxiang.erp.base.ErpServer;
+import com.zanxiang.erp.base.pojo.vo.SysIpv4RpcVO;
+import com.zanxiang.erp.base.rpc.ISysIpv4Rpc;
+import com.zanxiang.game.module.manage.service.IGameService;
+import com.zanxiang.game.module.manage.service.IIpDataAssayService;
+import com.zanxiang.game.module.manage.service.IUserLoginLogService;
+import com.zanxiang.game.module.manage.service.IUserService;
+import com.zanxiang.game.module.mybatis.entity.Game;
+import com.zanxiang.game.module.mybatis.entity.User;
+import com.zanxiang.game.module.mybatis.entity.UserLoginLog;
+import com.zanxiang.module.util.JsonUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.dubbo.config.annotation.DubboReference;
+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.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * @author : lingfeng
+ * @time : 2025-01-15
+ * @description : ip数据解析
+ */
+@Slf4j
+@Service
+public class IpDataAssayServiceImpl implements IIpDataAssayService {
+
+    @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
+    private ISysIpv4Rpc sysIpv4Rpc;
+
+    @Autowired
+    private IGameService gameService;
+
+    @Autowired
+    private IUserService userService;
+
+    @Autowired
+    private IUserLoginLogService userLoginLogService;
+
+    @Override
+    public void userHandle(long supperGameId) {
+        long page = 1L;
+        long pageSize = 5000L;
+        long totalPage;
+        List<Long> gameIdList = gameService.list(new LambdaQueryWrapper<Game>()
+                .select(Game::getId)
+                .eq(Game::getSuperGameId, supperGameId)
+        ).stream().map(Game::getId).collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(gameIdList)) {
+            return;
+        }
+        do {
+            Page<User> pageUser = userService.page(new Page<>(page, pageSize), new LambdaQueryWrapper<User>()
+                    .select(User::getId, User::getIp, User::getIpData)
+                    .in(User::getGameId, gameIdList)
+                    .orderByDesc(User::getCreateTime));
+            totalPage = pageUser.getPages();
+            List<User> userList = pageUser.getRecords();
+            userList.forEach(user -> {
+                if (Strings.isNotBlank(user.getIpData())) {
+                    return;
+                }
+                String ipData = this.ipAssay(user.getIp());
+                if (Strings.isBlank(ipData)) {
+                    return;
+                }
+                userService.update(new LambdaUpdateWrapper<User>()
+                        .set(User::getIpData, ipData)
+                        .eq(User::getId, user.getId()));
+            });
+        } while (++page <= totalPage);
+    }
+
+    @Override
+    public void userLoginLogHandle() {
+        long page = 1L;
+        long pageSize = 5000L;
+        long totalPage;
+        do {
+            Page<UserLoginLog> pageUserLoginLog = userLoginLogService.page(new Page<>(page, pageSize),
+                    new LambdaQueryWrapper<UserLoginLog>()
+                            .select(UserLoginLog::getId, UserLoginLog::getIp, UserLoginLog::getIpData)
+                            .ge(UserLoginLog::getCreateTime, LocalDateTime.now().minusMonths(2))
+                            .orderByDesc(UserLoginLog::getCreateTime));
+            totalPage = pageUserLoginLog.getPages();
+            List<UserLoginLog> userLoginLogList = pageUserLoginLog.getRecords();
+            userLoginLogList.forEach(userLoginLog -> {
+                if (Strings.isNotBlank(userLoginLog.getIpData())) {
+                    return;
+                }
+                String ipData = this.ipAssay(userLoginLog.getIp());
+                if (Strings.isBlank(ipData)) {
+                    return;
+                }
+                userLoginLogService.update(new LambdaUpdateWrapper<UserLoginLog>()
+                        .set(UserLoginLog::getIpData, ipData)
+                        .eq(UserLoginLog::getId, userLoginLog.getId()));
+            });
+        } while (++page <= totalPage);
+    }
+
+    @Override
+    public void ipDataHandle(List<String> msgList) {
+        msgList.forEach(msg -> {
+            String[] array = msg.split(":");
+            //消息类型(注册还是登录), 数据主键, ip地址
+            Tuple3<String, String, String> tuple3 = Tuple3.with(array[0], array[1], array[2]);
+            String ipData = this.ipAssay(tuple3.third);
+            if (Strings.isBlank(ipData)) {
+                return;
+            }
+            //注册用户, t_user表
+            if (Objects.equals(tuple3.first, "REG")) {
+                userService.update(new LambdaUpdateWrapper<User>()
+                        .set(User::getIpData, ipData)
+                        .eq(User::getId, Long.parseLong(tuple3.second))
+                );
+            }
+            //登录日志, t_user_login_log表
+            if (Objects.equals(tuple3.first, "LOGIN")) {
+                userLoginLogService.update(new LambdaUpdateWrapper<UserLoginLog>()
+                        .set(UserLoginLog::getIpData, ipData)
+                        .eq(UserLoginLog::getId, Long.parseLong(tuple3.second))
+                );
+            }
+        });
+    }
+
+    private String ipAssay(String ip) {
+        if (Strings.isBlank(ip)) {
+            return null;
+        }
+        SysIpv4RpcVO data = null;
+        try {
+            data = sysIpv4Rpc.getIpDetail(ip).getData();
+        } catch (Exception e) {
+            log.error("调用erp解析IP异常, ip : {}, e : {}", ip, e.getMessage());
+        }
+        return JsonUtil.toString(data);
+    }
+}

+ 51 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/task/IpDataAssayTask.java

@@ -0,0 +1,51 @@
+package com.zanxiang.game.module.manage.task;
+
+import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
+import com.zanxiang.game.module.manage.service.IIpDataAssayService;
+import com.zanxiang.game.module.manage.utils.RedisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @author : lingfeng
+ * @time : 2025-01-15
+ * @description : ip解析定时器
+ */
+@Slf4j
+@Component
+@RefreshScope
+public class IpDataAssayTask {
+
+    @Autowired
+    private RedisUtil<String> redisUtil;
+
+    @Autowired
+    private IIpDataAssayService ipDataAssayService;
+
+    /**
+     * IP解析每分钟检测
+     */
+    @Scheduled(cron = "0 0/5 * * * ?")
+    public void ipDataAssayCheck() {
+        String queueKey = RedisKeyConstant.IP_DATA_ASSAY_QUEUE;
+        //redis队列不存在, 或者长度为 0 , 不执行
+        if (!redisUtil.hasKey(queueKey) || redisUtil.getSetSize(queueKey) <= 0) {
+            return;
+        }
+        //随机移除取出5千条数据
+        List<String> msgList = redisUtil.popOfSet(queueKey, 5000);
+        //判断是否获取到数据, 没拿到数据, 结束
+        if (CollectionUtils.isEmpty(msgList)) {
+            return;
+        }
+        log.error("IP解析从队列中获取到数据长度 : {}", msgList.size());
+        //数据处理执行
+        ipDataAssayService.ipDataHandle(msgList);
+    }
+}

+ 17 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/utils/RedisUtil.java

@@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.*;
 import org.springframework.stereotype.Component;
 
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
@@ -159,6 +160,22 @@ public class RedisUtil<T> {
         return null;
     }
 
+    /**
+     * set集合随机删除元素, 且返回删除的结果(指定数量)
+     *
+     * @param key : 缓存key
+     * @return : 返回删除的值
+     */
+    public List<T> popOfSet(String key, long count) {
+        try {
+            SetOperations<String, T> setOperations = redisTemplate.opsForSet();
+            return setOperations.pop(key, count);
+        } catch (Exception e) {
+            log.error("Set随机删除失败,key : {}, e : {}", key, e.getMessage());
+        }
+        return null;
+    }
+
     /**
      * 判断元素是否存在于set集合
      *

+ 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服务启动成功 <新增IP解析任务队列> ( ´・・)ノ(._.`) \n" +
+        System.out.println("赞象SDK服务启动成功 <新增IP解析任务队列01> ( ´・・)ノ(._.`) \n" +
                 " ___________ _   __\n" +
                 "/  ___|  _  \\ | / /\n" +
                 "\\ `--.| | | | |/ / \n" +

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

@@ -282,7 +282,7 @@ public class GameBackLogMediaSdkServiceImpl extends ServiceImpl<GameBackLogMedia
             resultMap.put("callBack", Boolean.TRUE);
             resultMap.put("backMsg", "微信小游戏自然量订单全量回传");
             PlatformOrderDTO platformOrderDTO = orderService.getByOrderId(param.getOrderId());
-            resultMap.put("amount", platformOrderDTO.getAmount().longValue() * 100);
+            resultMap.put("amount", Collections.singletonList(platformOrderDTO.getAmount().longValue() * 100));
             return Tuple2.with(Boolean.FALSE, null);
         }
         //其他回传, 还是走判断

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

@@ -332,7 +332,7 @@ public class LoginServiceImpl implements IRegisterLoginService {
         //注册信息埋点数据发送到卡夫卡
         kafkaService.eventTrack(KafkaEventTrackEnum.KAFKA_EVENT_TRACK_REG, JsonUtil.toString(user));
         //发送到IP解析任务队列
-        redisUtil.addToSet(RedisKeyConstant.IP_DATA_ASSAY_QUEUE, "REG:" + user.getId());
+        redisUtil.addToSet(RedisKeyConstant.IP_DATA_ASSAY_QUEUE, "REG:" + user.getId()+ ":" + user.getIp());
         //返回用户信息
         return user;
     }

+ 2 - 2
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/UserLoginLogServiceImpl.java

@@ -40,7 +40,7 @@ public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, Use
                 .build();
         boolean result = super.save(loginLog);
         if (result) {
-            redisUtil.addToSet(RedisKeyConstant.IP_DATA_ASSAY_QUEUE, "LOGIN:" + loginLog.getId());
+            redisUtil.addToSet(RedisKeyConstant.IP_DATA_ASSAY_QUEUE, "LOGIN:" + loginLog.getId() + ":" + loginLog.getIp());
         }
         return result;
     }
@@ -58,7 +58,7 @@ public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, Use
                 .build();
         boolean result = super.save(loginLog);
         if (result) {
-            redisUtil.addToSet(RedisKeyConstant.IP_DATA_ASSAY_QUEUE, "LOGIN:" + loginLog.getId());
+            redisUtil.addToSet(RedisKeyConstant.IP_DATA_ASSAY_QUEUE, "LOGIN:" + loginLog.getId() + ":" + loginLog.getIp());
         }
         return result;
     }