Просмотр исходного кода

fix : 提交用户访问下载地址提交记录接口1

bilingfeng 1 год назад
Родитель
Сommit
ce2277c5cd

+ 1 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/adapter/ArgumentAdapter.java

@@ -67,6 +67,7 @@ public class ArgumentAdapter implements HandlerMethodArgumentResolver {
         UserData data = UserData.builder()
                 .gameId(gameExt.getGameId())
                 .ip(IpUtil.getRealIp(request))
+                .ua(request.getHeader("User-Agent"))
                 .deviceType(deviceType)
                 .deviceSystem(request.getHeader("os"))
                 .mac(request.getHeader("mac"))

+ 5 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/pojo/param/UserData.java

@@ -35,6 +35,11 @@ public class UserData implements Serializable {
      */
     private String ip;
 
+    /**
+     * 客户端ua
+     */
+    private String ua;
+
     /**
      * token
      */

+ 138 - 7
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/AgentServiceImpl.java

@@ -5,11 +5,12 @@ 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.Agent;
-import com.zanxiang.game.module.mybatis.entity.User;
-import com.zanxiang.game.module.mybatis.entity.UserLoginLog;
+import com.zanxiang.game.module.base.pojo.enums.GameCategoryEnum;
+import com.zanxiang.game.module.mybatis.entity.*;
 import com.zanxiang.game.module.mybatis.mapper.AgentMapper;
+import com.zanxiang.game.module.sdk.pojo.param.UserData;
 import com.zanxiang.game.module.sdk.service.*;
+import com.zanxiang.module.util.DateUtil;
 import com.zanxiang.module.util.JsonUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.logging.log4j.util.Strings;
@@ -19,10 +20,7 @@ import reactor.util.function.Tuple3;
 import reactor.util.function.Tuples;
 
 import java.time.LocalDateTime;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * @author bilingfeng
@@ -43,6 +41,15 @@ public class AgentServiceImpl extends ServiceImpl<AgentMapper, Agent> implements
     @Autowired
     private IUserAgentLogService userAgentLogService;
 
+    @Autowired
+    private IUserVisitLogService userVisitLogService;
+
+    @Autowired
+    private IGameService gameService;
+
+    @Autowired
+    private IGameExtService gameExtService;
+
     @Override
     public void userAgentUpdate(User user, String channel) {
         log.error("用户登录接收到的渠道参数 userId : {}, channel : {}", user.getId(), channel);
@@ -112,6 +119,130 @@ public class AgentServiceImpl extends ServiceImpl<AgentMapper, Agent> implements
         return Tuples.of(agent.getId(), urlParamMap, Strings.isBlank(shareUserId) ? Strings.EMPTY : shareUserId);
     }
 
+    public Tuple3<Long, Map<String, String>, String> getUserAgentId(UserData userData) {
+        GameExt gameExt = gameExtService.getByGameId(userData.getGameId());
+        Game game = gameService.getById(userData.getGameId());
+        String channel = userData.getChannel();
+
+        if (Objects.equals(game.getCategory(), GameCategoryEnum.CATEGORY_APP.getId())
+                && !Objects.equals(gameExt.getAdCallBackSwitch(), Boolean.TRUE)){
+
+        }
+
+
+
+        log.error("用户注册接收到的渠道参数 channel : {}", channel);
+        if (Strings.isBlank(channel)) {
+            return Tuples.of(0L, Collections.emptyMap(), Strings.EMPTY);
+        }
+        //数据解析
+        Map<String, String> urlParamMap = this.channelTransform(channel);
+        String shareUserId = urlParamMap.get("shareUserId");
+        //查询渠道
+        Agent agent = null;
+        if (Strings.isNotBlank(shareUserId)) {
+            User user = userService.getById(Long.valueOf(shareUserId));
+            if (user != null) {
+                agent = super.getById(user.getAgentId());
+            }
+        } else {
+            agent = this.getAgentByKey(urlParamMap);
+        }
+        if (agent == null) {
+
+
+
+
+
+
+            return Tuples.of(0L, Collections.emptyMap(), Strings.isBlank(shareUserId) ? Strings.EMPTY : shareUserId);
+        }
+        return Tuples.of(agent.getId(), urlParamMap, Strings.isBlank(shareUserId) ? Strings.EMPTY : shareUserId);
+    }
+
+    public Long getUserAgentIda(UserData userData) {
+        //当前时间
+        LocalDateTime regTime = LocalDateTime.now();
+        // 0. 优先前置策略, 单独判断ip是否只有一个用户, 只有一个用户则是该用户
+        List<UserVisitLog> userVisitLogList = userVisitLogService.list(new LambdaQueryWrapper<UserVisitLog>()
+                .eq(UserVisitLog::getIp, userData.getIp()));
+        if (CollectionUtils.isNotEmpty(userVisitLogList) && userVisitLogList.size() == 1) {
+            return userVisitLogList.get(0).getAgentId();
+        }
+        // 1. 策略一 : 根据 ip + ua 精准匹配用户
+        userVisitLogList = userVisitLogService.list(new LambdaQueryWrapper<UserVisitLog>()
+                .eq(UserVisitLog::getIp, userData.getIp())
+                .eq(UserVisitLog::getUa, userData)
+                .le(UserVisitLog::getCreateTime, regTime));
+        // 判断通过策略一是否拿到数据, 筛选出访问时间与注册时间最接近的
+        if (CollectionUtils.isNotEmpty(userVisitLogList)) {
+            UserVisitLog lastUserCall = this.getLastUserCall(userVisitLogList, regTime);
+            return lastUserCall == null ? null : lastUserCall.getAgentId();
+        }
+        // 2. 策略二 : 根据 ip + regTime 模糊匹配用户, 数据误差在15分钟以内
+        userVisitLogList = userVisitLogService.list(new LambdaQueryWrapper<UserVisitLog>()
+                .eq(UserVisitLog::getIp, userData.getIp())
+                .ge(UserVisitLog::getCreateTime, regTime.minusMinutes(15))
+                .le(UserVisitLog::getCreateTime, regTime));
+        // 判断通过策略二是否拿到数据, 筛选出访问时间与注册时间最接近的
+        if (CollectionUtils.isNotEmpty(userVisitLogList)) {
+            UserVisitLog lastUserCall = this.getLastUserCall(userVisitLogList, regTime);
+            return lastUserCall == null ? null : lastUserCall.getAgentId();
+        }
+        // 3. 策略三 : 根据 ua + regTime 模糊匹配用户, 数据误差在15分钟以内
+        userVisitLogList = userVisitLogService.list(new LambdaQueryWrapper<UserVisitLog>()
+                .eq(UserVisitLog::getUa, userData.getUa())
+                .ge(UserVisitLog::getCreateTime, regTime.minusMinutes(15))
+                .le(UserVisitLog::getCreateTime, regTime));
+        // 判断通过策略三是否拿到数据, 筛选出访问时间与注册时间最接近的
+        if (CollectionUtils.isNotEmpty(userVisitLogList)) {
+            UserVisitLog lastUserCall = this.getLastUserCall(userVisitLogList, regTime);
+            return lastUserCall == null ? null : lastUserCall.getAgentId();
+        }
+        // 4. 策略四 : 根据 regTime 模糊匹配用户, 数据误差在15分钟以内, 此策略为兜底策略
+        userVisitLogList = userVisitLogService.list(new LambdaQueryWrapper<UserVisitLog>()
+                .ge(UserVisitLog::getCreateTime, regTime.minusMinutes(15))
+                .le(UserVisitLog::getCreateTime, regTime));
+        if (CollectionUtils.isNotEmpty(userVisitLogList)) {
+            UserVisitLog lastUserCall = this.getLastUserCall(userVisitLogList, regTime);
+            return lastUserCall == null ? null : lastUserCall.getAgentId();
+        }
+        return null;
+    }
+
+    /**
+     * 对比获取访问时间与注册时间最接近的访问记录
+     *
+     * @param regTime          用户注册时间
+     * @param userVisitLogList 用户访问日志列表
+     * @return {@link UserVisitLog}
+     */
+    private UserVisitLog getLastUserCall(List<UserVisitLog> userVisitLogList, LocalDateTime regTime) {
+        //只匹配到一个用户, 直接返回
+        if (userVisitLogList.size() == 1) {
+            return userVisitLogList.get(0);
+        }
+        //注册时间转换毫秒
+        long regTimeMill = DateUtil.localDateTimeToMilli(regTime);
+        //用户访问时间与注册时间差
+        Map<Long, Long> timeDiffMap = new HashMap<>(userVisitLogList.size());
+        //循环用户列表
+        userVisitLogList.forEach(user -> {
+            //用户访问时间
+            LocalDateTime createTime = user.getCreateTime();
+            //用户访问时间转换
+            long createTimeMill = DateUtil.localDateTimeToMilli(createTime);
+            //计算时间差, 并添加到集合
+            timeDiffMap.put(user.getId(), regTimeMill - createTimeMill);
+        });
+        //取出map中最小的value值对应的key值
+        List<Map.Entry<Long, Long>> list = new ArrayList<>(timeDiffMap.entrySet());
+        list.sort(Comparator.comparingLong(Map.Entry::getValue));
+        Long minId = list.get(0).getKey();
+        //过滤出对应的对象返回
+        return userVisitLogList.stream().filter(user -> Objects.equals(user.getId(), minId)).findFirst().orElse(null);
+    }
+
     private Agent getAgentByKey(Map<String, String> urlParamMap) {
         //参数不存在
         if (CollectionUtils.isEmpty(urlParamMap)) {

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

@@ -49,7 +49,7 @@ public class UserVisitLogServiceImpl extends ServiceImpl<UserVisitLogMapper, Use
                 .gameId(agent == null ? null : agent.getId())
                 .ip(IpUtil.getRealIp(httpServletRequest))
                 .ua(userAgent)
-                .ua(urlParamMap.get("url"))
+                .url(urlParamMap.get("url"))
                 .channel(urlParamMap.get("channel"))
                 .createTime(LocalDateTime.now())
                 .updateTime(LocalDateTime.now())