|  | @@ -2,32 +2,46 @@ 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.google.common.util.concurrent.ThreadFactoryBuilder;
 | 
	
		
			
				|  |  |  import com.zanxiang.erp.base.ErpServer;
 | 
	
		
			
				|  |  |  import com.zanxiang.erp.base.rpc.IDingTalkMsgRpc;
 | 
	
		
			
				|  |  |  import com.zanxiang.game.back.serve.dao.mapper.GameTencentMiniGameCallbackMapper;
 | 
	
		
			
				|  |  | -import com.zanxiang.game.back.serve.pojo.dto.GameTencentCallbackDTO;
 | 
	
		
			
				|  |  |  import com.zanxiang.game.back.serve.pojo.entity.GameTencentMiniGameCallback;
 | 
	
		
			
				|  |  | +import com.zanxiang.game.back.serve.pojo.entity.GameTencentMiniGameRoleRegister;
 | 
	
		
			
				|  |  | +import com.zanxiang.game.back.serve.pojo.entity.GameTencentMiniGameUser;
 | 
	
		
			
				|  |  | +import com.zanxiang.game.back.serve.pojo.enums.BackStatusEnum;
 | 
	
		
			
				|  |  | +import com.zanxiang.game.back.serve.pojo.enums.BackTypeEnum;
 | 
	
		
			
				|  |  |  import com.zanxiang.game.back.serve.service.IGameTencentMiniGameCallbackService;
 | 
	
		
			
				|  |  | +import com.zanxiang.game.back.serve.service.IGameTencentMiniGameRoleRegisterService;
 | 
	
		
			
				|  |  | +import com.zanxiang.game.back.serve.service.IGameTencentMiniGameUserService;
 | 
	
		
			
				|  |  |  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 lombok.extern.slf4j.Slf4j;
 | 
	
		
			
				|  |  | +import org.apache.commons.collections4.CollectionUtils;
 | 
	
		
			
				|  |  |  import org.apache.dubbo.config.annotation.DubboReference;
 | 
	
		
			
				|  |  |  import org.apache.kafka.clients.producer.KafkaProducer;
 | 
	
		
			
				|  |  |  import org.apache.kafka.clients.producer.ProducerRecord;
 | 
	
		
			
				|  |  |  import org.apache.logging.log4j.util.Strings;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.annotation.Value;
 | 
	
		
			
				|  |  | +import org.springframework.context.annotation.Lazy;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import java.time.LocalDate;
 | 
	
		
			
				|  |  |  import java.time.LocalDateTime;
 | 
	
		
			
				|  |  | +import java.util.List;
 | 
	
		
			
				|  |  |  import java.util.Map;
 | 
	
		
			
				|  |  | +import java.util.Objects;
 | 
	
		
			
				|  |  |  import java.util.Optional;
 | 
	
		
			
				|  |  | +import java.util.concurrent.CompletableFuture;
 | 
	
		
			
				|  |  | +import java.util.concurrent.LinkedBlockingQueue;
 | 
	
		
			
				|  |  | +import java.util.concurrent.ThreadPoolExecutor;
 | 
	
		
			
				|  |  | +import java.util.concurrent.TimeUnit;
 | 
	
		
			
				|  |  | +import java.util.stream.Collectors;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  @Slf4j
 | 
	
		
			
				|  |  |  @Service
 | 
	
	
		
			
				|  | @@ -46,31 +60,22 @@ public class GameTencentMiniGameCallbackServiceImpl extends ServiceImpl<GameTenc
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  |      private KafkaProducer<String, String> kafkaProducer;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    @Override
 | 
	
		
			
				|  |  | -    public boolean callback(GameTencentCallbackDTO dto) {
 | 
	
		
			
				|  |  | -        AgentRpcVO agent = agentRpc.getByTencentAccountId(dto.getAccountId()).getData();
 | 
	
		
			
				|  |  | -        if (agent == null) {
 | 
	
		
			
				|  |  | -            log.error("腾讯检测链接数据找不到渠道:{}", JsonUtil.toString(dto));
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        GameTencentMiniGameCallback callback = BeanUtil.copy(dto, GameTencentMiniGameCallback.class);
 | 
	
		
			
				|  |  | -        if (agent != null) {
 | 
	
		
			
				|  |  | -            callback.setAgentKey(agent.getAgentKey());
 | 
	
		
			
				|  |  | -            callback.setGameId(agent.getGameId());
 | 
	
		
			
				|  |  | -            callback.setWechatAppId(agent.getAppId());
 | 
	
		
			
				|  |  | -        } else {
 | 
	
		
			
				|  |  | -            callback.setAgentKey("-");
 | 
	
		
			
				|  |  | -            callback.setGameId(-1L);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        callback.setDay(dto.getClickTime() == null || dto.getClickTime() < 1000 ? LocalDate.now() : DateUtil.secondToLocalDate(dto.getClickTime()));
 | 
	
		
			
				|  |  | -        save(callback);
 | 
	
		
			
				|  |  | -        //信息发送到卡夫卡
 | 
	
		
			
				|  |  | -        try {
 | 
	
		
			
				|  |  | -            kafkaProducer.send(new ProducerRecord<>(tencentCallbackTopic, dto.getAccountId().toString(), JsonUtil.toString(callback)));
 | 
	
		
			
				|  |  | -        } catch (Exception e) {
 | 
	
		
			
				|  |  | -            log.error(e.getMessage(), e);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        return true;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +    @Lazy
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private IGameTencentMiniGameUserService gameTencentMiniGameUserService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Lazy
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private IGameTencentMiniGameRoleRegisterService gameTencentMiniGameRoleRegisterService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static final ThreadPoolExecutor THREAD_POOL_CALL_BACK_URL_UPDATE = new ThreadPoolExecutor(
 | 
	
		
			
				|  |  | +            10,
 | 
	
		
			
				|  |  | +            10,
 | 
	
		
			
				|  |  | +            0,
 | 
	
		
			
				|  |  | +            TimeUnit.MINUTES,
 | 
	
		
			
				|  |  | +            new LinkedBlockingQueue<>(),
 | 
	
		
			
				|  |  | +            new ThreadFactoryBuilder()
 | 
	
		
			
				|  |  | +                    .setNameFormat("sync-ipDataAssay-%d").build());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public boolean callback(Map<String, Object> paramMap) {
 | 
	
	
		
			
				|  | @@ -151,4 +156,71 @@ public class GameTencentMiniGameCallbackServiceImpl extends ServiceImpl<GameTenc
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          return null;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public void delayUpdateMiniGameUserCallBackUrl(Long gameId, LocalDateTime startTime) {
 | 
	
		
			
				|  |  | +        //时间范围
 | 
	
		
			
				|  |  | +        LocalDateTime minCreateTime = startTime == null ? LocalDateTime.now().minusHours(1) : startTime;
 | 
	
		
			
				|  |  | +        //查询5分钟之内, callBackUrl未匹配上的数据
 | 
	
		
			
				|  |  | +        List<GameTencentMiniGameUser> miniGameUserList = gameTencentMiniGameUserService.list(
 | 
	
		
			
				|  |  | +                new LambdaQueryWrapper<GameTencentMiniGameUser>()
 | 
	
		
			
				|  |  | +                        .eq(GameTencentMiniGameUser::getGameId, gameId)
 | 
	
		
			
				|  |  | +                        .isNull(GameTencentMiniGameUser::getCallBackUrl)
 | 
	
		
			
				|  |  | +                        .gt(GameTencentMiniGameUser::getCreateTime, minCreateTime)
 | 
	
		
			
				|  |  | +                        .eq(GameTencentMiniGameUser::getBackType, BackTypeEnum.BACK_API.getBackType()));
 | 
	
		
			
				|  |  | +        if (CollectionUtils.isEmpty(miniGameUserList)) {
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        //数据处理
 | 
	
		
			
				|  |  | +        List<CompletableFuture<?>> futures = miniGameUserList.stream().map(user -> CompletableFuture.runAsync(() -> {
 | 
	
		
			
				|  |  | +            try {
 | 
	
		
			
				|  |  | +                this.miniGameUserUpdate(user);
 | 
	
		
			
				|  |  | +            } catch (Exception e) {
 | 
	
		
			
				|  |  | +                log.error("定时器-腾讯小游戏村注册检测异常, id : {}, e : {}", user.getId(), e.getMessage(), e);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }, THREAD_POOL_CALL_BACK_URL_UPDATE)).collect(Collectors.toList());
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get();
 | 
	
		
			
				|  |  | +        } catch (Exception e) {
 | 
	
		
			
				|  |  | +            log.error("定时器-腾讯小游戏村注册检测等待所有队列消息消费完成时出现异常: {}", e.getMessage());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private void miniGameUserUpdate(GameTencentMiniGameUser miniGameUser) {
 | 
	
		
			
				|  |  | +        //匹配回传URL
 | 
	
		
			
				|  |  | +        String callBackUrl = this.getCallBackUrl(miniGameUser.getGameId(),
 | 
	
		
			
				|  |  | +                miniGameUser.getWechatOpenid(), miniGameUser.getClickId(), miniGameUser.getRegisterTime(), false);
 | 
	
		
			
				|  |  | +        if (Strings.isBlank(callBackUrl)) {
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        //设置回传地址
 | 
	
		
			
				|  |  | +        miniGameUser.setCallBackUrl(callBackUrl);
 | 
	
		
			
				|  |  | +        //数据修正
 | 
	
		
			
				|  |  | +        gameTencentMiniGameUserService.updateById(miniGameUser);
 | 
	
		
			
				|  |  | +        //判断是否已经执行回传异常
 | 
	
		
			
				|  |  | +        if (Objects.equals(miniGameUser.getBackStatus(), BackStatusEnum.FAILED.getBackStatus())) {
 | 
	
		
			
				|  |  | +            //已执行的重新补回传
 | 
	
		
			
				|  |  | +            gameTencentMiniGameUserService.userBack(miniGameUser);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        //查询相关创角回传是否存在
 | 
	
		
			
				|  |  | +        List<GameTencentMiniGameRoleRegister> miniGameRoleRegisterList = gameTencentMiniGameRoleRegisterService.list(
 | 
	
		
			
				|  |  | +                new LambdaQueryWrapper<GameTencentMiniGameRoleRegister>()
 | 
	
		
			
				|  |  | +                        .eq(GameTencentMiniGameRoleRegister::getGameId, miniGameUser.getGameId())
 | 
	
		
			
				|  |  | +                        .eq(GameTencentMiniGameRoleRegister::getWechatAppId, miniGameUser.getWechatAppId())
 | 
	
		
			
				|  |  | +                        .eq(GameTencentMiniGameRoleRegister::getWechatOpenid, miniGameUser.getWechatOpenid())
 | 
	
		
			
				|  |  | +                        .eq(GameTencentMiniGameRoleRegister::getAdAccountId, miniGameUser.getAdAccountId())
 | 
	
		
			
				|  |  | +                        .eq(GameTencentMiniGameRoleRegister::getBackStatus, BackStatusEnum.FAILED.getBackStatus())
 | 
	
		
			
				|  |  | +                        .eq(GameTencentMiniGameRoleRegister::getBackType, BackTypeEnum.BACK_API.getBackType()));
 | 
	
		
			
				|  |  | +        if (CollectionUtils.isEmpty(miniGameRoleRegisterList)) {
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        //注册回传补充
 | 
	
		
			
				|  |  | +        miniGameRoleRegisterList.forEach(miniGameRole -> {
 | 
	
		
			
				|  |  | +            try {
 | 
	
		
			
				|  |  | +                gameTencentMiniGameRoleRegisterService.roleRegisterBack(miniGameRole);
 | 
	
		
			
				|  |  | +            } catch (Exception e) {
 | 
	
		
			
				|  |  | +                log.error("定时器-腾讯小游戏村创角补回传异常, id : {}, e : {}", miniGameRole.getId(), e.getMessage(), e);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  }
 |