|
@@ -1,289 +0,0 @@
|
|
|
-package com.zanxiang.game.module.manage.service.impl;
|
|
|
-
|
|
|
-import cn.hutool.http.ContentType;
|
|
|
-import cn.hutool.http.HttpUtil;
|
|
|
-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.zanxiang.erp.base.ErpServer;
|
|
|
-import com.zanxiang.erp.base.rpc.IDingTalkMsgRpc;
|
|
|
-import com.zanxiang.game.module.base.ServerInfo;
|
|
|
-import com.zanxiang.game.module.base.pojo.enums.PayApplicationTypeEnum;
|
|
|
-import com.zanxiang.game.module.base.pojo.enums.StatusEnum;
|
|
|
-import com.zanxiang.game.module.base.rpc.IWxApiServiceRpc;
|
|
|
-import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
|
|
|
-import com.zanxiang.game.module.manage.enums.ExpireTimeEnum;
|
|
|
-import com.zanxiang.game.module.manage.service.*;
|
|
|
-import com.zanxiang.game.module.manage.utils.RedisUtil;
|
|
|
-import com.zanxiang.game.module.mybatis.entity.GamePayWay;
|
|
|
-import com.zanxiang.game.module.mybatis.entity.ListenCall;
|
|
|
-import com.zanxiang.game.module.mybatis.entity.PayApplication;
|
|
|
-import com.zanxiang.game.module.mybatis.entity.PayBox;
|
|
|
-import com.zanxiang.module.redis.service.IDistributedLockComponent;
|
|
|
-import com.zanxiang.module.util.JsonUtil;
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
-import org.apache.logging.log4j.util.Strings;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.http.HttpEntity;
|
|
|
-import org.springframework.http.HttpHeaders;
|
|
|
-import org.springframework.http.HttpMethod;
|
|
|
-import org.springframework.http.ResponseEntity;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-import org.springframework.util.LinkedMultiValueMap;
|
|
|
-import org.springframework.util.MultiValueMap;
|
|
|
-import org.springframework.web.client.RestTemplate;
|
|
|
-
|
|
|
-import java.time.LocalDate;
|
|
|
-import java.time.LocalDateTime;
|
|
|
-import java.util.*;
|
|
|
-import java.util.concurrent.TimeUnit;
|
|
|
-import java.util.function.Function;
|
|
|
-import java.util.stream.Collectors;
|
|
|
-
|
|
|
-/**
|
|
|
- * @author : lingfeng
|
|
|
- * @time : 2024-01-20
|
|
|
- * @description : 小程序检查
|
|
|
- */
|
|
|
-@Slf4j
|
|
|
-@Service
|
|
|
-public class AppletCheckServiceImpl implements IAppletCheckService {
|
|
|
-
|
|
|
- @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
|
|
|
- private IDingTalkMsgRpc dingTalkMsgRpc;
|
|
|
-
|
|
|
- @DubboReference(providedBy = ServerInfo.SERVER_SDK_DUBBO_NAME)
|
|
|
- private IWxApiServiceRpc wxApiServiceRpc;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private RedisUtil<Integer> redisUtil;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private IPayBoxService payBoxService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private IGamePayWayService gamePayWayService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private IListenCallService listenCallService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private IPayApplicationService payApplicationService;
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private IDistributedLockComponent distributedLockComponent;
|
|
|
-
|
|
|
- @Override
|
|
|
- public void payApplicationCheck() {
|
|
|
- List<PayApplication> payApplicationList = payApplicationService.list(new LambdaQueryWrapper<PayApplication>()
|
|
|
- .eq(PayApplication::getStatus, StatusEnum.YES.getCode())
|
|
|
- .eq(PayApplication::getType, PayApplicationTypeEnum.WX_MINI_APP.getType()));
|
|
|
- if (CollectionUtils.isEmpty(payApplicationList)) {
|
|
|
- return;
|
|
|
- }
|
|
|
- payApplicationList.forEach(payApplication -> {
|
|
|
- String accessToken = null;
|
|
|
- try {
|
|
|
- accessToken = wxApiServiceRpc.getAccessToken(payApplication.getAppId(), payApplication.getAppSecret());
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("获取小程序token异常, appName : {}, e : {}", payApplication.getAppName(), e.getMessage());
|
|
|
- }
|
|
|
- if (Strings.isBlank(accessToken) || !this.appletCheck(accessToken, payApplication.getAppName())) {
|
|
|
- log.error("小程序判定封停或者禁用, appName : {}, accessToken : {}", payApplication.getAppName(), accessToken);
|
|
|
- this.payApplicationCheck(payApplication);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void payApplicationCheck(PayApplication payApplication) {
|
|
|
- //异常计数器, 返回false的时候过滤
|
|
|
- if (!this.countUpdate(payApplication.getAppId())) {
|
|
|
- return;
|
|
|
- }
|
|
|
- //连续三次报警, 进行通知
|
|
|
- try {
|
|
|
- //更新游戏支付
|
|
|
- this.gamePayUpdate(payApplication);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("支付应用异常更新游戏支付盒子失败, appName : {}, e : {}", payApplication.getAppName(), e.getMessage());
|
|
|
- }
|
|
|
- try {
|
|
|
- //钉钉通知
|
|
|
- this.sendDingTalkMsg(payApplication);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("支付应用异常钉钉通知失败, appName : {}, e : {}", payApplication.getAppName(), e.getMessage());
|
|
|
- }
|
|
|
- try {
|
|
|
- //电话通知
|
|
|
- this.sendPhoneTalkMsg(payApplication);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("支付应用异常电话通知失败, appName : {}, e : {}", payApplication.getAppName(), e.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private boolean countUpdate(String appId) {
|
|
|
- String key = RedisKeyConstant.APPLET_ERROR_COUNT + appId;
|
|
|
- Integer count = redisUtil.getCache(key);
|
|
|
- if (count != null && count >= 2) {
|
|
|
- redisUtil.deleteCache(key);
|
|
|
- return Boolean.TRUE;
|
|
|
- }
|
|
|
- if (count == null) {
|
|
|
- count = 1;
|
|
|
- } else {
|
|
|
- count += 1;
|
|
|
- }
|
|
|
- redisUtil.setCache(key, count, ExpireTimeEnum.HALF_HOUR.getTime());
|
|
|
- return Boolean.FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- private void gamePayUpdate(PayApplication payApplication) {
|
|
|
- //修改支付应用状态
|
|
|
- log.error("支付应用异常 - 修改支付应用状态, appName : {}", payApplication.getAppName());
|
|
|
- payApplicationService.update(new LambdaUpdateWrapper<PayApplication>()
|
|
|
- .eq(PayApplication::getAppId, payApplication.getAppId())
|
|
|
- .set(PayApplication::getStatus, StatusEnum.NO.getCode())
|
|
|
- .set(PayApplication::getUpdateTime, LocalDateTime.now()));
|
|
|
- //查询支付应用对应的盒子
|
|
|
- List<PayBox> payBoxList = payBoxService.list(new LambdaQueryWrapper<PayBox>()
|
|
|
- .eq(PayBox::getAppId, payApplication.getAppId())
|
|
|
- .eq(PayBox::getStatus, StatusEnum.YES.getCode()));
|
|
|
- if (CollectionUtils.isEmpty(payBoxList)) {
|
|
|
- log.error("支付应用异常 - 支付应用不存在相关支付盒子, appName : {}", payApplication.getAppName());
|
|
|
- return;
|
|
|
- }
|
|
|
- Set<Integer> payBoxIdList = payBoxList.stream().map(PayBox::getId).collect(Collectors.toSet());
|
|
|
- //修改支付应用相关支付盒子状态
|
|
|
- log.error("支付应用异常 - 修改支付盒子状态, appName : {}, payBoxIdList : {}", payApplication.getAppName(), payBoxIdList);
|
|
|
- payBoxService.update(new LambdaUpdateWrapper<PayBox>()
|
|
|
- .in(PayBox::getId, payBoxIdList)
|
|
|
- .set(PayBox::getStatus, StatusEnum.NO.getCode())
|
|
|
- .set(PayBox::getUpdateTime, LocalDateTime.now()));
|
|
|
- //游戏支付应用修改
|
|
|
-// this.gamePayWayUpdate(payApplication, payBoxIdList);
|
|
|
- }
|
|
|
-
|
|
|
- private void gamePayWayUpdate(PayApplication payApplication, Set<Integer> payBoxIdList) {
|
|
|
- //查询相关盒子被使用到的游戏
|
|
|
- List<GamePayWay> gamePayWayList = gamePayWayService.list(new LambdaQueryWrapper<GamePayWay>()
|
|
|
- .in(GamePayWay::getPayBoxId, payBoxIdList));
|
|
|
- if (CollectionUtils.isEmpty(gamePayWayList)) {
|
|
|
- log.error("支付应用异常 - 支付应用不存在相关联游戏支付配置, appName : {}", payApplication.getAppName());
|
|
|
- return;
|
|
|
- }
|
|
|
- //获取一个能用的支付盒子
|
|
|
- PayBox payBox = payBoxService.getOne(new LambdaQueryWrapper<PayBox>()
|
|
|
- .eq(PayBox::getType, payApplication.getType())
|
|
|
- .eq(PayBox::getStatus, StatusEnum.YES.getCode())
|
|
|
- .last("limit 1"));
|
|
|
- if (payBox == null) {
|
|
|
- log.error("支付应用异常 - 不存在正常可用的支付盒子, appName : {}", payApplication.getAppName());
|
|
|
- return;
|
|
|
- }
|
|
|
- //相关游戏支付配置id列表
|
|
|
- Set<Long> gamePayWayIdSet = gamePayWayList.stream().map(GamePayWay::getId).collect(Collectors.toSet());
|
|
|
- //修改游戏支付配置
|
|
|
- log.error("支付应用异常 - 修改游戏支付配置, appName : {}, gamePayWayIdSet : {}, payBoxId : {}", payApplication.getAppName(),
|
|
|
- gamePayWayIdSet, payBox.getId());
|
|
|
- gamePayWayService.update(new LambdaUpdateWrapper<GamePayWay>()
|
|
|
- .in(GamePayWay::getId, gamePayWayIdSet)
|
|
|
- .set(GamePayWay::getPayBoxId, payBox.getId())
|
|
|
- .set(GamePayWay::getUpdateTime, LocalDateTime.now()));
|
|
|
- }
|
|
|
-
|
|
|
- private void sendDingTalkMsg(PayApplication payApplication) {
|
|
|
- List<ListenCall> listenCallList = this.callListenUser();
|
|
|
- if (CollectionUtils.isEmpty(listenCallList)) {
|
|
|
- return;
|
|
|
- }
|
|
|
- String content = System.currentTimeMillis() + " 小程序 : <" + payApplication.getAppName() + "> 可能被封停或者禁用, 请注意验证";
|
|
|
- Set<Long> userIdSet = listenCallList.stream().map(ListenCall::getUserId).collect(Collectors.toSet());
|
|
|
- userIdSet.forEach(userId -> dingTalkMsgRpc.sendByUserId(userId, content));
|
|
|
- }
|
|
|
-
|
|
|
- private void sendPhoneTalkMsg(PayApplication payApplication) {
|
|
|
- List<ListenCall> listenCallList = this.callListenUser();
|
|
|
- if (CollectionUtils.isEmpty(listenCallList)) {
|
|
|
- return;
|
|
|
- }
|
|
|
- String content = payApplication.getAppName() + "监测异常";
|
|
|
- Set<String> phoneNumSet = listenCallList.stream().map(ListenCall::getPhoneNum).collect(Collectors.toSet());
|
|
|
- phoneNumSet.forEach(phoneNum -> {
|
|
|
- String lockKey = RedisKeyConstant.PHONE_CALL_LOCK + phoneNum;
|
|
|
- if (!distributedLockComponent.doLock(lockKey, 0L, 1L, TimeUnit.MINUTES)) {
|
|
|
- return;
|
|
|
- }
|
|
|
- this.phoneCall(content, phoneNum);
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- private List<ListenCall> callListenUser() {
|
|
|
- List<ListenCall> listenCallList = listenCallService.list(new LambdaQueryWrapper<ListenCall>()
|
|
|
- .eq(ListenCall::getStatus, StatusEnum.YES.getCode()));
|
|
|
- if (CollectionUtils.isEmpty(listenCallList)) {
|
|
|
- return Collections.emptyList();
|
|
|
- }
|
|
|
- Collection<ListenCall> collection = listenCallList.stream()
|
|
|
- .collect(Collectors.toMap(ListenCall::getUserId, Function.identity(), (existing, replacement) -> existing))
|
|
|
- .values();
|
|
|
- return new ArrayList<>(collection);
|
|
|
- }
|
|
|
-
|
|
|
- private boolean appletCheck(String token, String appName) {
|
|
|
- //参数对象
|
|
|
- String dayTime = LocalDate.now().minusDays(3).toString();
|
|
|
- Map<String, String> paramMap = new HashMap<>(2);
|
|
|
- paramMap.put("begin_date", dayTime);
|
|
|
- paramMap.put("end_date", dayTime);
|
|
|
- String host = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyretaininfo?access_token=" + token;
|
|
|
- try {
|
|
|
- // 带参POST请求
|
|
|
- String result = HttpUtil.post(host, JsonUtil.toString(paramMap));
|
|
|
- //结果为空, 判定腾讯接口返回错误, 不判定为封禁
|
|
|
- if (Strings.isBlank(result)) {
|
|
|
- return Boolean.TRUE;
|
|
|
- }
|
|
|
- //没有报错
|
|
|
- if (!result.contains("errcode")) {
|
|
|
- return Boolean.TRUE;
|
|
|
- }
|
|
|
- //结果返回错误
|
|
|
- Map<String, Object> resultMap = JsonUtil.toMap(result, Map.class, Object.class);
|
|
|
- //排除计算中的特殊报错
|
|
|
- if (Objects.equals(resultMap.get("errcode").toString(), "61503")) {
|
|
|
- return Boolean.TRUE;
|
|
|
- }
|
|
|
- log.error("小程序封停监测结果, appName : {}, result : {}", appName, result);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("小程序封停监测异常, appName : {}, e : {}", appName, e.getMessage());
|
|
|
- return Boolean.FALSE;
|
|
|
- }
|
|
|
- return Boolean.FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- private void phoneCall(String param, String mobile) {
|
|
|
- RestTemplate restTemplate = new RestTemplate();
|
|
|
- String appCode = "f395b1587fc04a49a975f908660fb1e9";
|
|
|
- String host = "https://jumfixed.market.alicloudapi.com/voice-notify/send";
|
|
|
- HttpHeaders headers = new HttpHeaders();
|
|
|
- headers.set("Authorization", "APPCODE " + appCode);
|
|
|
- headers.set("Content-Type", ContentType.FORM_URLENCODED.getValue());
|
|
|
- //参数
|
|
|
- MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
|
|
|
- requestParams.add("mobile", mobile);
|
|
|
- requestParams.add("templateId", "JMJNAWUQOJP9");
|
|
|
- requestParams.add("param", param);
|
|
|
- String result = null;
|
|
|
- try {
|
|
|
- ResponseEntity<String> responseEntity = restTemplate.exchange(host, HttpMethod.POST,
|
|
|
- new HttpEntity<>(requestParams, headers), String.class);
|
|
|
- result = responseEntity.getBody();
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("阿里语音呼叫失败, requestParams : {}, e : {}", JsonUtil.toString(requestParams), e.getMessage());
|
|
|
- }
|
|
|
- log.error("阿里语音呼叫结果, result : {}", result);
|
|
|
- }
|
|
|
-
|
|
|
-}
|