|
@@ -0,0 +1,240 @@
|
|
|
+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.service.*;
|
|
|
+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.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.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 IPayBoxService payBoxService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IGamePayWayService gamePayWayService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IListenCallService listenCallService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IPayApplicationService payApplicationService;
|
|
|
+
|
|
|
+ @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) {
|
|
|
+ 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 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 -> 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(1).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.isNotBlank(result) && result.contains("errcode")) {
|
|
|
+ log.error("小程序封停监测结果, appName : {}, result : {}", appName, result);
|
|
|
+ return Boolean.FALSE;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("小程序封停监测异常, appName : {}, e : {}", appName, e.getMessage());
|
|
|
+ return Boolean.FALSE;
|
|
|
+ }
|
|
|
+ return Boolean.TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|