|
@@ -4,14 +4,15 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.github.sd4324530.jtuple.Tuple2;
|
|
|
+import com.github.sd4324530.jtuple.Tuple3;
|
|
|
import com.zanxiang.game.back.base.ServerInfo;
|
|
|
+import com.zanxiang.game.back.base.pojo.dto.TencentMiniGameOrderBackQueryRpcDTO;
|
|
|
import com.zanxiang.game.back.base.pojo.dto.TtAppOrderBackQueryRpcDTO;
|
|
|
import com.zanxiang.game.back.base.pojo.vo.OrderBackQueryRpcVO;
|
|
|
+import com.zanxiang.game.back.base.rpc.ITencentMiniGameBackRpc;
|
|
|
import com.zanxiang.game.back.base.rpc.ITtAppBackRpc;
|
|
|
-import com.zanxiang.game.module.mybatis.entity.Agent;
|
|
|
-import com.zanxiang.game.module.mybatis.entity.GameBackLogMediaSdk;
|
|
|
-import com.zanxiang.game.module.mybatis.entity.User;
|
|
|
-import com.zanxiang.game.module.mybatis.entity.UserEvent;
|
|
|
+import com.zanxiang.game.module.base.pojo.enums.AccountTypeEnum;
|
|
|
+import com.zanxiang.game.module.mybatis.entity.*;
|
|
|
import com.zanxiang.game.module.mybatis.mapper.GameBackLogMediaSdkMapper;
|
|
|
import com.zanxiang.game.module.sdk.constant.RedisKeyConstant;
|
|
|
import com.zanxiang.game.module.sdk.enums.CallBackTypeEnum;
|
|
@@ -28,7 +29,10 @@ import org.apache.logging.log4j.util.Strings;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import java.time.LocalDate;
|
|
|
import java.time.LocalDateTime;
|
|
|
+import java.time.LocalTime;
|
|
|
+import java.time.temporal.ChronoUnit;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
import java.util.stream.Collectors;
|
|
@@ -45,8 +49,8 @@ public class GameBackLogMediaSdkServiceImpl extends ServiceImpl<GameBackLogMedia
|
|
|
@DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
|
|
|
private ITtAppBackRpc ttAppBackRpc;
|
|
|
|
|
|
- @Autowired
|
|
|
- private IAgentService agentService;
|
|
|
+ @DubboReference(providedBy = ServerInfo.SERVER_DUBBO_NAME)
|
|
|
+ private ITencentMiniGameBackRpc tencentMiniGameBackRpc;
|
|
|
|
|
|
@Autowired
|
|
|
private IUserService userService;
|
|
@@ -55,11 +59,17 @@ public class GameBackLogMediaSdkServiceImpl extends ServiceImpl<GameBackLogMedia
|
|
|
private IOrderService orderService;
|
|
|
|
|
|
@Autowired
|
|
|
- private IDistributedLockComponent distributedLockComponent;
|
|
|
+ private IAgentService agentService;
|
|
|
|
|
|
@Autowired
|
|
|
private IUserEventService userEventService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private IUserLoginLogService userLoginLogService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IDistributedLockComponent distributedLockComponent;
|
|
|
+
|
|
|
@Override
|
|
|
public Map<String, Object> callBackJudge(CallBackControlParam param, UserData userData) {
|
|
|
Map<String, Object> resultMap = new HashMap<>(7);
|
|
@@ -95,13 +105,14 @@ public class GameBackLogMediaSdkServiceImpl extends ServiceImpl<GameBackLogMedia
|
|
|
log.error("重复请求触发线程锁, 直接返回false, lockKey : {}", lockKey);
|
|
|
return resultMap;
|
|
|
}
|
|
|
+ //执行回传判断
|
|
|
try {
|
|
|
- //判断回传
|
|
|
- this.checkCallBack(user.getId(), agent, param.getCallBackTypeEnum(), resultMap, param);
|
|
|
+ this.checkCallBack(user, agent, resultMap, param);
|
|
|
} catch (Exception e) {
|
|
|
- log.error("事件回传判断, 出现异常, param : {}, userData : {}, e : {}", JsonUtil.toString(param),
|
|
|
- JsonUtil.toString(userData), e.getMessage(), e);
|
|
|
+ log.error("事件回传判断, 出现异常, param : {}, userData : {}, e : {}",
|
|
|
+ JsonUtil.toString(param), JsonUtil.toString(userData), e.getMessage(), e);
|
|
|
} finally {
|
|
|
+ //释放线程锁
|
|
|
distributedLockComponent.unlock(lockKey);
|
|
|
}
|
|
|
//返回结果
|
|
@@ -124,11 +135,13 @@ public class GameBackLogMediaSdkServiceImpl extends ServiceImpl<GameBackLogMedia
|
|
|
|
|
|
private Tuple2<Boolean, String> callBackParamCheck(CallBackControlParam param, Map<String, Object> resultMap) {
|
|
|
CallBackTypeEnum callBackTypeEnum = param.getCallBackTypeEnum();
|
|
|
- //创角和新手引导回传, 必须传角色id
|
|
|
+ //创角, 新手引导, 等级提升回传, 必须传角色id
|
|
|
if (Objects.equals(callBackTypeEnum, CallBackTypeEnum.CALL_BACK_ACTIVATE)
|
|
|
- || Objects.equals(callBackTypeEnum, CallBackTypeEnum.CALL_BACK_TUTORIAL_FINISH)) {
|
|
|
+ || Objects.equals(callBackTypeEnum, CallBackTypeEnum.CALL_BACK_CREATE_ROLE)
|
|
|
+ || Objects.equals(callBackTypeEnum, CallBackTypeEnum.CALL_BACK_TUTORIAL_FINISH)
|
|
|
+ || Objects.equals(callBackTypeEnum, CallBackTypeEnum.CALL_BACK_UPDATE_LEVEL)) {
|
|
|
if (Strings.isBlank(param.getRoleId())) {
|
|
|
- return Tuple2.with(Boolean.FALSE, "参数错误, 创角或新手引导回传, 必须传角色id");
|
|
|
+ return Tuple2.with(Boolean.FALSE, "参数错误, 创角, 新手引导或者等级提升回传, 必须传角色id");
|
|
|
}
|
|
|
resultMap.put("roleId", param.getRoleId());
|
|
|
}
|
|
@@ -168,8 +181,14 @@ public class GameBackLogMediaSdkServiceImpl extends ServiceImpl<GameBackLogMedia
|
|
|
return Tuple2.with(callBack, amountList);
|
|
|
}
|
|
|
|
|
|
- private void checkCallBack(Long userId, Agent agent, CallBackTypeEnum callBackTypeEnum, Map<String, Object> resultMap,
|
|
|
- CallBackControlParam param) {
|
|
|
+ private void checkCallBack(User user, Agent agent, Map<String, Object> resultMap, CallBackControlParam param) {
|
|
|
+ //玩家id
|
|
|
+ Long userId = user.getId();
|
|
|
+ //游戏id
|
|
|
+ Long gameId = agent.getGameId();
|
|
|
+ //回传类型
|
|
|
+ CallBackTypeEnum callBackTypeEnum = param.getCallBackTypeEnum();
|
|
|
+ //按不同类型判断
|
|
|
switch (callBackTypeEnum) {
|
|
|
case CALL_BACK_LOGIN_IN:
|
|
|
break;
|
|
@@ -185,35 +204,106 @@ public class GameBackLogMediaSdkServiceImpl extends ServiceImpl<GameBackLogMedia
|
|
|
resultMap.put("callBack", Boolean.TRUE);
|
|
|
break;
|
|
|
case CALL_BACK_RE_ACTIVE:
|
|
|
- //沉默唤起
|
|
|
- resultMap.put("callBack", Boolean.TRUE);
|
|
|
+ Tuple3<Boolean, Long, String> tuple = this.callBackReActiveCheck(param.getRoleId(), userId, gameId);
|
|
|
+ resultMap.put("callBack", tuple.first);
|
|
|
+ resultMap.put("backFlowDay", tuple.second);
|
|
|
+ resultMap.put("backMsg", tuple.third);
|
|
|
break;
|
|
|
case CALL_BACK_TUTORIAL_FINISH:
|
|
|
- //完成新手引导
|
|
|
- resultMap.put("callBack", Boolean.TRUE);
|
|
|
+ Tuple2<Boolean, String> tuple2 = this.callBackTutorialFinishCheck(param.getRoleId(), userId, gameId);
|
|
|
+ resultMap.put("callBack", tuple2.first);
|
|
|
+ resultMap.put("backMsg", tuple2.second);
|
|
|
break;
|
|
|
case CALL_BACK_PAY_ORDER:
|
|
|
- TtAppOrderBackQueryRpcDTO orderTransform = this.transform(userId, param.getOrderId(), agent);
|
|
|
- OrderBackQueryRpcVO orderBackQueryRpcVO = ttAppBackRpc.orderBackQuery(orderTransform).getData();
|
|
|
- resultMap.put("orderId", param.getOrderId());
|
|
|
- resultMap.put("callBack", orderBackQueryRpcVO.getDoBack());
|
|
|
- resultMap.put("backMsg", orderBackQueryRpcVO.getBackMsg());
|
|
|
- if (Objects.equals(orderBackQueryRpcVO.getDoBack(), Boolean.TRUE)) {
|
|
|
- //传过来的金额是分, 换算成元, 存在小数直接舍弃
|
|
|
- List<Long> backMoney = orderBackQueryRpcVO.getBackMoney()
|
|
|
- .stream().map(money -> money / 100)
|
|
|
- .collect(Collectors.toList());
|
|
|
- resultMap.put("amount", backMoney);
|
|
|
- }
|
|
|
+ Tuple3<Boolean, List<Long>, String> tuple3 = this.callBackOrderCheck(param.getOrderId(), user, agent);
|
|
|
+ resultMap.put("callBack", tuple3.first);
|
|
|
+ resultMap.put("amount", tuple3.second);
|
|
|
+ resultMap.put("backMsg", tuple3.third);
|
|
|
break;
|
|
|
default:
|
|
|
resultMap.put("backMsg", "未知的回传类型");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private Tuple3<Boolean, Long, String> callBackReActiveCheck(String roleId, Long userId, Long gameId) {
|
|
|
+ //判断玩家今日是否已经沉默唤起回传
|
|
|
+ if (super.count(new LambdaQueryWrapper<GameBackLogMediaSdk>()
|
|
|
+ .eq(GameBackLogMediaSdk::getGameId, gameId)
|
|
|
+ .eq(GameBackLogMediaSdk::getUserId, userId)
|
|
|
+ .eq(GameBackLogMediaSdk::getRoleId, roleId)
|
|
|
+ .eq(GameBackLogMediaSdk::getCallBackParam, CallBackTypeEnum.CALL_BACK_RE_ACTIVE)
|
|
|
+ .ge(GameBackLogMediaSdk::getCreateTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIN))
|
|
|
+ ) > 0) {
|
|
|
+ return Tuple3.with(Boolean.FALSE, null, "今日已执行沉默唤起回传, 不重复执行");
|
|
|
+ }
|
|
|
+ //获取玩家今天之前最后一次登录日志
|
|
|
+ UserLoginLog userLoginLog = userLoginLogService.getOne(new LambdaQueryWrapper<UserLoginLog>()
|
|
|
+ .eq(UserLoginLog::getUserId, userId)
|
|
|
+ .le(UserLoginLog::getCreateTime, LocalDateTime.of(LocalDate.now(), LocalTime.MIN))
|
|
|
+ .orderByDesc(UserLoginLog::getCreateTime)
|
|
|
+ .last("limit 1"));
|
|
|
+ if (userLoginLog == null) {
|
|
|
+ return Tuple3.with(Boolean.FALSE, null, "不存在今日之前的登录日志, 不执行沉默唤起回传");
|
|
|
+ }
|
|
|
+ //最长未登录天数, 判断标准暂定 30 天
|
|
|
+ long backFlowDay = 30;
|
|
|
+ long betweenDay = ChronoUnit.DAYS.between(userLoginLog.getCreateTime().toLocalDate(), LocalDate.now());
|
|
|
+ //返回判断结果
|
|
|
+ return Tuple3.with(betweenDay >= backFlowDay, backFlowDay, "沉默唤起判断依据登录日志id: " + userLoginLog.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ private Tuple2<Boolean, String> callBackTutorialFinishCheck(String roleId, Long userId, Long gameId) {
|
|
|
+ long count = super.count(new LambdaQueryWrapper<GameBackLogMediaSdk>()
|
|
|
+ .eq(GameBackLogMediaSdk::getGameId, gameId)
|
|
|
+ .eq(GameBackLogMediaSdk::getUserId, userId)
|
|
|
+ .eq(GameBackLogMediaSdk::getRoleId, roleId)
|
|
|
+ .eq(GameBackLogMediaSdk::getCallBackParam, CallBackTypeEnum.CALL_BACK_TUTORIAL_FINISH)
|
|
|
+ );
|
|
|
+ return Tuple2.with(count <= 0, count <= 0 ? "执行新手引导回传" : "角色已执行新手引导回传, 不重复执行, count : " + count);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Tuple3<Boolean, List<Long>, String> callBackOrderCheck(String orderId, User user, Agent agent) {
|
|
|
+ Boolean doBack = Boolean.FALSE;
|
|
|
+ List<Long> amount = null;
|
|
|
+ String backMsg = null;
|
|
|
+ //头条APP直投回传
|
|
|
+ if (Objects.equals(agent.getAccountType(), AccountTypeEnum.BYTE_APP.getValue())) {
|
|
|
+ TtAppOrderBackQueryRpcDTO orderQuery = this.transform(user.getId(), orderId, agent);
|
|
|
+ OrderBackQueryRpcVO orderBackQueryRpcVO = ttAppBackRpc.orderBackQuery(orderQuery).getData();
|
|
|
+ //传过来的金额是分, 头条媒体SDK需要换算成元, 存在小数直接舍弃
|
|
|
+ if (Objects.equals(orderBackQueryRpcVO.getDoBack(), Boolean.TRUE)) {
|
|
|
+ amount = orderBackQueryRpcVO.getBackMoney().stream().map(money -> money / 100).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ doBack = orderBackQueryRpcVO.getDoBack();
|
|
|
+ backMsg = orderBackQueryRpcVO.getBackMsg();
|
|
|
+ }
|
|
|
+ //腾讯小游戏媒体SDK回传
|
|
|
+ if (Objects.equals(agent.getAccountType(), AccountTypeEnum.TENCENT_MINI_GAME.getValue())) {
|
|
|
+ TencentMiniGameOrderBackQueryRpcDTO orderQuery = this.transform(user.getOpenId(), orderId, agent);
|
|
|
+ OrderBackQueryRpcVO orderBackQueryRpcVO = tencentMiniGameBackRpc.orderBackQuery(orderQuery).getData();
|
|
|
+ if (Objects.equals(orderBackQueryRpcVO.getDoBack(), Boolean.TRUE)) {
|
|
|
+ amount = orderBackQueryRpcVO.getBackMoney();
|
|
|
+ }
|
|
|
+ doBack = orderBackQueryRpcVO.getDoBack();
|
|
|
+ backMsg = orderBackQueryRpcVO.getBackMsg();
|
|
|
+ }
|
|
|
+ return Tuple3.with(doBack, amount, Strings.isBlank(backMsg) ? "未知的渠道投放类型" : backMsg);
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public boolean addMediaSdkBackLog(BackLogMediaSdkParam param, UserData userData) {
|
|
|
- return super.save(this.transform(param, userData));
|
|
|
+ GameBackLogMediaSdk gameBackLogMediaSdk = this.transform(param, userData);
|
|
|
+ Map<String, Object> callBackJudgeResult = param.getCallBackJudgeResult();
|
|
|
+ //回传判断结果参数不为空
|
|
|
+ if (!callBackJudgeResult.isEmpty()) {
|
|
|
+ if (callBackJudgeResult.containsKey("roleId")) {
|
|
|
+ gameBackLogMediaSdk.setRoleId(String.valueOf(callBackJudgeResult.get("roleId")));
|
|
|
+ }
|
|
|
+ if (callBackJudgeResult.containsKey("orderId")) {
|
|
|
+ gameBackLogMediaSdk.setOrderId(String.valueOf(callBackJudgeResult.get("orderId")));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return super.save(gameBackLogMediaSdk);
|
|
|
}
|
|
|
|
|
|
private GameBackLogMediaSdk transform(BackLogMediaSdkParam param, UserData userData) {
|
|
@@ -236,8 +326,13 @@ public class GameBackLogMediaSdkServiceImpl extends ServiceImpl<GameBackLogMedia
|
|
|
.agentKey(agent.getAgentKey())
|
|
|
.build();
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
|
|
|
+ private TencentMiniGameOrderBackQueryRpcDTO transform(String wechatOpenid, String orderId, Agent agent) {
|
|
|
+ return TencentMiniGameOrderBackQueryRpcDTO.builder()
|
|
|
+ .gameId(agent.getGameId())
|
|
|
+ .wechatOpenid(wechatOpenid)
|
|
|
+ .orderId(orderId)
|
|
|
+ .agentKey(agent.getAgentKey())
|
|
|
+ .build();
|
|
|
+ }
|
|
|
+}
|