|
@@ -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.conditions.update.LambdaUpdateWrapper;
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
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.mybatis.mapper.AgentMapper;
|
|
|
|
+import com.zanxiang.game.module.sdk.pojo.param.UserData;
|
|
import com.zanxiang.game.module.sdk.service.*;
|
|
import com.zanxiang.game.module.sdk.service.*;
|
|
|
|
+import com.zanxiang.module.util.DateUtil;
|
|
import com.zanxiang.module.util.JsonUtil;
|
|
import com.zanxiang.module.util.JsonUtil;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.apache.logging.log4j.util.Strings;
|
|
import org.apache.logging.log4j.util.Strings;
|
|
@@ -19,10 +20,7 @@ import reactor.util.function.Tuple3;
|
|
import reactor.util.function.Tuples;
|
|
import reactor.util.function.Tuples;
|
|
|
|
|
|
import java.time.LocalDateTime;
|
|
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
|
|
* @author bilingfeng
|
|
@@ -43,6 +41,15 @@ public class AgentServiceImpl extends ServiceImpl<AgentMapper, Agent> implements
|
|
@Autowired
|
|
@Autowired
|
|
private IUserAgentLogService userAgentLogService;
|
|
private IUserAgentLogService userAgentLogService;
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
+ private IUserVisitLogService userVisitLogService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private IGameService gameService;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private IGameExtService gameExtService;
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public void userAgentUpdate(User user, String channel) {
|
|
public void userAgentUpdate(User user, String channel) {
|
|
log.error("用户登录接收到的渠道参数 userId : {}, channel : {}", user.getId(), 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);
|
|
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) {
|
|
private Agent getAgentByKey(Map<String, String> urlParamMap) {
|
|
//参数不存在
|
|
//参数不存在
|
|
if (CollectionUtils.isEmpty(urlParamMap)) {
|
|
if (CollectionUtils.isEmpty(urlParamMap)) {
|