|
@@ -2,34 +2,41 @@ package com.zanxiang.game.back.serve.service.impl;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.github.sd4324530.jtuple.Tuple2;
|
|
|
+import com.zanxiang.game.back.base.pojo.vo.OrderBackQueryRpcVO;
|
|
|
import com.zanxiang.game.back.serve.dao.mapper.GameOceanengineAppCallbackXgltMapper;
|
|
|
-import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineAppCallbackXglt;
|
|
|
-import com.zanxiang.game.back.serve.pojo.entity.GameOceanengineAppUserLog;
|
|
|
-import com.zanxiang.game.back.serve.service.GameOceanengineAppCallbackXgltService;
|
|
|
+import com.zanxiang.game.back.serve.pojo.entity.*;
|
|
|
+import com.zanxiang.game.back.serve.service.IGameOceanengineAppBackLogXgltService;
|
|
|
+import com.zanxiang.game.back.serve.service.IGameOceanengineAppCallbackXgltService;
|
|
|
+import com.zanxiang.game.back.serve.service.IGameOceanengineAppUserLogService;
|
|
|
import com.zanxiang.game.module.base.ServerInfo;
|
|
|
import com.zanxiang.game.module.base.pojo.vo.AgentRpcVO;
|
|
|
import com.zanxiang.game.module.base.rpc.IAgentRpc;
|
|
|
import com.zanxiang.module.util.DateUtil;
|
|
|
import com.zanxiang.module.util.JsonUtil;
|
|
|
import com.zanxiang.module.util.URIUtil;
|
|
|
-import com.zanxiang.module.util.bean.BeanUtil;
|
|
|
import com.zanxiang.module.util.encryption.Md5Util;
|
|
|
import com.zanxiang.module.util.pojo.ResultVO;
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import lombok.Getter;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
+import org.springframework.scheduling.annotation.Async;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.web.client.RestTemplate;
|
|
|
|
|
|
import java.time.LocalDate;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
@Slf4j
|
|
|
@Service
|
|
|
public class GameOceanengineAppCallbackXgltServiceImpl extends ServiceImpl<GameOceanengineAppCallbackXgltMapper, GameOceanengineAppCallbackXglt>
|
|
|
- implements GameOceanengineAppCallbackXgltService {
|
|
|
+ implements IGameOceanengineAppCallbackXgltService {
|
|
|
|
|
|
@DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
|
|
|
private IAgentRpc agentRpc;
|
|
@@ -37,6 +44,15 @@ public class GameOceanengineAppCallbackXgltServiceImpl extends ServiceImpl<GameO
|
|
|
@Autowired
|
|
|
private RestTemplate restTemplate;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private RedisTemplate<String, String> redisTemplate;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IGameOceanengineAppUserLogService gameOceanengineAppUserLogService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IGameOceanengineAppBackLogXgltService gameOceanengineAppBackLogXgltService;
|
|
|
+
|
|
|
@Override
|
|
|
public boolean callback(Map<String, Object> paramMap) {
|
|
|
try {
|
|
@@ -52,11 +68,11 @@ public class GameOceanengineAppCallbackXgltServiceImpl extends ServiceImpl<GameO
|
|
|
|
|
|
@Override
|
|
|
public String getCallBackParamByUser(GameOceanengineAppUserLog userLog) {
|
|
|
- //没有渠道标识, 无法匹配
|
|
|
- if (StringUtils.isBlank(userLog.getAgentKey())) {
|
|
|
- return null;
|
|
|
- }
|
|
|
try {
|
|
|
+ //没有渠道标识, 无法匹配
|
|
|
+ if (StringUtils.isBlank(userLog.getAgentKey())) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
ResultVO<List<AgentRpcVO>> resultVO = agentRpc.getByAgentKeys(Collections.singletonList(userLog.getAgentKey()));
|
|
|
Long demandId = Optional.ofNullable(resultVO).map(ResultVO::getData)
|
|
|
.filter(list -> !list.isEmpty()).map(list -> list.get(0))
|
|
@@ -66,7 +82,13 @@ public class GameOceanengineAppCallbackXgltServiceImpl extends ServiceImpl<GameO
|
|
|
}
|
|
|
GameOceanengineAppCallbackXglt callBack = this.getCallBack(demandId, userLog.getAndroidId(), userLog.getOaid(),
|
|
|
userLog.getImei(), userLog.getActiveTime());
|
|
|
- return callBack == null ? null : callBack.getCallbackParam();
|
|
|
+ if (callBack == null || StringUtils.isBlank(callBack.getCallbackParam())) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ Map<String, String> map = new HashMap<>(2);
|
|
|
+ map.put("demandId", demandId.toString());
|
|
|
+ map.put("callBack", callBack.getCallbackParam());
|
|
|
+ return JsonUtil.toString(map);
|
|
|
} catch (Exception e) {
|
|
|
log.error("头条APP玩家匹配星广联投监测链接数据异常, userLogId : {}, e : {}", JsonUtil.toString(userLog), e.getMessage(), e);
|
|
|
}
|
|
@@ -110,16 +132,192 @@ public class GameOceanengineAppCallbackXgltServiceImpl extends ServiceImpl<GameO
|
|
|
return super.getOne(queryWrapper);
|
|
|
}
|
|
|
|
|
|
- private String doCallBack(String callback, String eventType, Long amount) {
|
|
|
+ @Async
|
|
|
+ @Override
|
|
|
+ public void regBack(GameOceanengineAppUserLog userLog) {
|
|
|
+ //注册只回传一次
|
|
|
+ if (gameOceanengineAppBackLogXgltService.count(new LambdaQueryWrapper<GameOceanengineAppBackLogXglt>()
|
|
|
+ .eq(GameOceanengineAppBackLogXglt::getGameId, userLog.getGameId())
|
|
|
+ .eq(GameOceanengineAppBackLogXglt::getUserId, userLog.getUserId())
|
|
|
+ .eq(GameOceanengineAppBackLogXglt::getEventType, EventType.Event_ACTIVE.getEventType())
|
|
|
+ ) > 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //判断是否关联星广联投, 未关联, 跳过
|
|
|
+ Tuple2<Long, String> tuple2 = this.getCallBackParam(userLog);
|
|
|
+ if (tuple2 == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //线程锁, 避免并发或者多次请求
|
|
|
+ String lockKey = "game-back:TtAppXgltBack:" + userLog.getGameId() + ":" + userLog.getUserId() + ":"
|
|
|
+ + EventType.Event_ACTIVE.getEventType();
|
|
|
+ if (Boolean.FALSE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, "lock", 30, TimeUnit.SECONDS))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //执行回传
|
|
|
+ Tuple2<String, String> resultTuple2 = this.doCallBack(tuple2.second, EventType.Event_ACTIVE, null);
|
|
|
+ //回传记录
|
|
|
+ GameOceanengineAppBackLogXglt gameOceanengineAppBackLogXglt = GameOceanengineAppBackLogXglt.builder()
|
|
|
+ .demandId(tuple2.first)
|
|
|
+ .gameId(userLog.getGameId())
|
|
|
+ .userId(userLog.getUserId())
|
|
|
+ .eventType(EventType.Event_ACTIVE.getEventType())
|
|
|
+ .callBackUri(resultTuple2.first)
|
|
|
+ .callBackResult(resultTuple2.second)
|
|
|
+ .createTime(LocalDateTime.now())
|
|
|
+ .build();
|
|
|
+ //保存记录
|
|
|
+ gameOceanengineAppBackLogXgltService.save(gameOceanengineAppBackLogXglt);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Async
|
|
|
+ @Override
|
|
|
+ public void createRoleBack(GameOceanengineAppRoleRegisterLog roleLog) {
|
|
|
+ //判断创角只回传一次
|
|
|
+ if (gameOceanengineAppBackLogXgltService.count(new LambdaQueryWrapper<GameOceanengineAppBackLogXglt>()
|
|
|
+ .eq(GameOceanengineAppBackLogXglt::getGameId, roleLog.getGameId())
|
|
|
+ .eq(GameOceanengineAppBackLogXglt::getUserId, roleLog.getUserId())
|
|
|
+ .eq(GameOceanengineAppBackLogXglt::getRoleId, roleLog.getRoleId())
|
|
|
+ .eq(GameOceanengineAppBackLogXglt::getEventType, EventType.Event_REGISTER.getEventType())
|
|
|
+ ) > 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //判断是否关联星广联投, 未关联, 跳过
|
|
|
+ Tuple2<Long, String> tuple2 = this.getCallBackParam(roleLog.getGameId(), roleLog.getUserId(), roleLog.getAccountId());
|
|
|
+ if (tuple2 == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //线程锁, 避免并发或者多次请求
|
|
|
+ String lockKey = "game-back:TtAppXgltBack:" + roleLog.getGameId() + ":" + roleLog.getUserId() + ":"
|
|
|
+ + roleLog.getRoleId() + ":" + EventType.Event_REGISTER.getEventType();
|
|
|
+ if (Boolean.FALSE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, "lock", 30, TimeUnit.SECONDS))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //执行回传
|
|
|
+ Tuple2<String, String> resultTuple2 = this.doCallBack(tuple2.second, EventType.Event_REGISTER, null);
|
|
|
+ //回传记录
|
|
|
+ GameOceanengineAppBackLogXglt gameOceanengineAppBackLogXglt = GameOceanengineAppBackLogXglt.builder()
|
|
|
+ .demandId(tuple2.first)
|
|
|
+ .gameId(roleLog.getGameId())
|
|
|
+ .userId(roleLog.getUserId())
|
|
|
+ .roleId(roleLog.getRoleId())
|
|
|
+ .eventType(EventType.Event_REGISTER.getEventType())
|
|
|
+ .callBackUri(resultTuple2.first)
|
|
|
+ .callBackResult(resultTuple2.second)
|
|
|
+ .createTime(LocalDateTime.now())
|
|
|
+ .build();
|
|
|
+ //保存记录
|
|
|
+ gameOceanengineAppBackLogXgltService.save(gameOceanengineAppBackLogXglt);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Async
|
|
|
+ @Override
|
|
|
+ public void orderPayBack(GameOceanengineAppOrderLog orderLog, OrderBackQueryRpcVO orderBackQueryRpcVO) {
|
|
|
+ //判断是否关联星广联投, 未关联, 跳过
|
|
|
+ Tuple2<Long, String> tuple2 = this.getCallBackParam(orderLog.getGameId(), orderLog.getUserId(), orderLog.getAccountId());
|
|
|
+ if (tuple2 == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //单个订单只回传一次
|
|
|
+ if (gameOceanengineAppBackLogXgltService.count(new LambdaQueryWrapper<GameOceanengineAppBackLogXglt>()
|
|
|
+ .eq(GameOceanengineAppBackLogXglt::getGameId, orderLog.getGameId())
|
|
|
+ .eq(GameOceanengineAppBackLogXglt::getUserId, orderLog.getUserId())
|
|
|
+ .eq(GameOceanengineAppBackLogXglt::getOrderId, orderLog.getOrderNo())
|
|
|
+ .eq(GameOceanengineAppBackLogXglt::getEventType, EventType.Event_PAY.getEventType())
|
|
|
+ ) > 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //线程锁, 避免并发或者多次请求
|
|
|
+ String lockKey = "game-back:TtAppXgltBack:" + orderLog.getGameId() + ":" + orderLog.getUserId() + ":"
|
|
|
+ + orderLog.getRoleId() + ":" + orderLog.getOrderNo() + ":" + EventType.Event_PAY.getEventType();
|
|
|
+ if (Boolean.FALSE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, "lock", 30, TimeUnit.SECONDS))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //回传的金额列表
|
|
|
+ List<Long> backMoneyList = orderBackQueryRpcVO.getBackMoney();
|
|
|
+ //循环执行回传
|
|
|
+ backMoneyList.forEach(amount -> {
|
|
|
+ //执行回传
|
|
|
+ Tuple2<String, String> resultTuple2 = this.doCallBack(tuple2.second, EventType.Event_PAY, amount);
|
|
|
+ //回传记录
|
|
|
+ GameOceanengineAppBackLogXglt gameOceanengineAppBackLogXglt = GameOceanengineAppBackLogXglt.builder()
|
|
|
+ .demandId(tuple2.first)
|
|
|
+ .gameId(orderLog.getGameId())
|
|
|
+ .userId(orderLog.getUserId())
|
|
|
+ .roleId(orderLog.getRoleId())
|
|
|
+ .orderId(orderLog.getOrderNo())
|
|
|
+ .eventType(EventType.Event_PAY.getEventType())
|
|
|
+ .callBackUri(resultTuple2.first)
|
|
|
+ .callBackResult(resultTuple2.second)
|
|
|
+ .createTime(LocalDateTime.now())
|
|
|
+ .build();
|
|
|
+ //保存记录
|
|
|
+ gameOceanengineAppBackLogXgltService.save(gameOceanengineAppBackLogXglt);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private Tuple2<Long, String> getCallBackParam(Long gameId, String userId, Long accountId) {
|
|
|
+ GameOceanengineAppUserLog userLog = gameOceanengineAppUserLogService.getOne(new LambdaQueryWrapper<GameOceanengineAppUserLog>()
|
|
|
+ .eq(GameOceanengineAppUserLog::getGameId, gameId)
|
|
|
+ .eq(GameOceanengineAppUserLog::getUserId, userId)
|
|
|
+ .eq(GameOceanengineAppUserLog::getAccountId, accountId)
|
|
|
+ .orderByDesc(GameOceanengineAppUserLog::getCreateTime)
|
|
|
+ .last("limit 1"));
|
|
|
+ //参数解析返回
|
|
|
+ return this.getCallBackParam(userLog);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Tuple2<Long, String> getCallBackParam(GameOceanengineAppUserLog userLog) {
|
|
|
+ //参数判断
|
|
|
+ if (userLog == null || StringUtils.isBlank(userLog.getXgltCallback())) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ //解析
|
|
|
+ Map<String, String> map = JsonUtil.toMap(userLog.getXgltCallback(), Map.class, String.class);
|
|
|
+ //返回参数
|
|
|
+ return Tuple2.with(Long.valueOf(map.get("demandId")), map.get("callBack"));
|
|
|
+ }
|
|
|
+
|
|
|
+ private Tuple2<String, String> doCallBack(String callback, EventType eventType, Long amount) {
|
|
|
Map<String, String> paramMap = new HashMap<>(3);
|
|
|
paramMap.put("callback", callback);
|
|
|
- paramMap.put("event_type", eventType);
|
|
|
+ paramMap.put("event_type", eventType.getEventType());
|
|
|
//付费回传
|
|
|
- if (Objects.equals(eventType, "2") && amount != null) {
|
|
|
+ if (Objects.equals(eventType, EventType.Event_PAY) && amount != null) {
|
|
|
Map<String, String> payAmount = Collections.singletonMap("pay_amount", amount.toString());
|
|
|
paramMap.put("props", URIUtil.encodeURIComponent(JsonUtil.toString(payAmount)));
|
|
|
}
|
|
|
String uri = URIUtil.fillUrlParams("https://ad.oceanengine.com/track/activate/", paramMap, false);
|
|
|
- return restTemplate.getForObject(uri, String.class);
|
|
|
+ String result;
|
|
|
+ try {
|
|
|
+ result = restTemplate.getForObject(uri, String.class);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("头条星广联投回调异常, uri : {}, errorMsg : {}", uri, e.getMessage(), e);
|
|
|
+ result = "头条星广联投回传接口调用异常";
|
|
|
+ }
|
|
|
+ return Tuple2.with(uri, result);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Getter
|
|
|
+ @AllArgsConstructor
|
|
|
+ public enum EventType {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 激活
|
|
|
+ */
|
|
|
+ Event_ACTIVE("0"),
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 注册
|
|
|
+ */
|
|
|
+ Event_REGISTER("1"),
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 付费
|
|
|
+ * props:{"pay_amount":"xxx"}, xxx单位为分
|
|
|
+ */
|
|
|
+ Event_PAY("2");
|
|
|
+
|
|
|
+ private final String eventType;
|
|
|
}
|
|
|
}
|