Parcourir la source

Merge remote-tracking branch 'origin/package' into package

zhangxianyu il y a 11 mois
Parent
commit
23e4d8a168
12 fichiers modifiés avec 430 ajouts et 391 suppressions
  1. 1 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/ManageApplication.java
  2. 46 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/api/CpServerApi.java
  3. 53 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/ChatSubmitParam.java
  4. 65 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/OpenGameServerParam.java
  5. 4 17
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/rpc/impl/PayBoxRpcImpl.java
  6. 0 23
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IAppletCheckService.java
  7. 18 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IListenCallService.java
  8. 129 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/api/CpServerApiService.java
  9. 0 289
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/AppletCheckServiceImpl.java
  10. 109 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/ListenCallServiceImpl.java
  11. 0 61
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/task/PayApplicationTask.java
  12. 5 0
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/GameSupper.java

+ 1 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/ManageApplication.java

@@ -23,7 +23,7 @@ public class ManageApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(ManageApplication.class, args);
-        System.out.println("赞象Manage服务启动成功 < (客服消息已读状态在结束房间的时候更新´・・)ノ(._.`) \n" +
+        System.out.println("赞象Manage服务启动成功 < (CP接口修改03´・・)ノ(._.`) \n" +
                 "___  ___  ___   _   _   ___  _____  _____ \n" +
                 "|  \\/  | / _ \\ | \\ | | / _ \\|  __ \\|  ___|\n" +
                 "| .  . |/ /_\\ \\|  \\| |/ /_\\ \\ |  \\/| |__  \n" +

+ 46 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/api/CpServerApi.java

@@ -0,0 +1,46 @@
+package com.zanxiang.game.module.manage.controller.api;
+
+import com.zanxiang.game.module.manage.pojo.params.ChatSubmitParam;
+import com.zanxiang.game.module.manage.pojo.params.OpenGameServerParam;
+import com.zanxiang.game.module.manage.service.api.CpServerApiService;
+import com.zanxiang.module.util.pojo.ResultVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-04-25
+ * @description : Cp服务端接口
+ */
+@Api(tags = {"Cp服务端接口"})
+@RestController
+@RequestMapping("/api")
+@Slf4j
+public class CpServerApi {
+
+    @Autowired
+    private CpServerApiService cpServerApiService;
+
+    @ApiOperation(value = "cp提交游戏聊天记录")
+    @PostMapping(value = "/chat/msg/submit")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Boolean.class)})
+    public ResultVO<Boolean> chatMsgSubmit(@Validated @RequestBody ChatSubmitParam param) {
+        return ResultVO.ok(cpServerApiService.chatMsgSubmit(param));
+    }
+
+    @ApiOperation(value = "CP开服通知")
+    @PostMapping(value = "/open/game/server")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = Boolean.class)})
+    public ResultVO<Boolean> list(@Validated @RequestBody OpenGameServerParam param) {
+        return ResultVO.ok(cpServerApiService.openGameServer(param));
+    }
+}

+ 53 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/ChatSubmitParam.java

@@ -0,0 +1,53 @@
+package com.zanxiang.game.module.manage.pojo.params;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.Map;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-04-25
+ * @description : 游戏聊天内容提交
+ */
+@Data
+public class ChatSubmitParam {
+
+    /**
+     * 加密标识
+     */
+    @NotNull(message = "加密标识不可为空")
+    @ApiModelProperty(notes = "加密标识")
+    private String sign;
+
+    /**
+     * 请求时间
+     */
+    @NotNull(message = "请求时间不可为空")
+    @ApiModelProperty(notes = "请求时间, 时间戳 : 13位")
+    private Long signTime;
+
+    /**
+     * 超父游戏id
+     */
+    @NotNull(message = "超父游戏id不可为空")
+    @ApiModelProperty(notes = "超父游戏id")
+    private Long gameId;
+
+    /**
+     * 区服id
+     */
+    @NotBlank(message = "区服id不可为空")
+    @ApiModelProperty(notes = "区服id, 必传")
+    private String serverId;
+
+    /**
+     * 聊天内容
+     */
+    @NotEmpty(message = "聊天内容不可为空")
+    @ApiModelProperty(notes = "聊天内容, 必传")
+    private Map<String, Object> chatContentMap;
+}

+ 65 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/OpenGameServerParam.java

@@ -0,0 +1,65 @@
+package com.zanxiang.game.module.manage.pojo.params;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-04-25
+ * @description : 开服参数
+ */
+@Data
+public class OpenGameServerParam {
+
+    /**
+     * 加密标识
+     */
+    @NotNull(message = "加密标识不可为空")
+    @ApiModelProperty(notes = "加密标识")
+    private String sign;
+
+    /**
+     * 请求时间
+     */
+    @NotNull(message = "请求时间不可为空")
+    @ApiModelProperty(notes = "请求时间, 时间戳 : 13位")
+    private Long signTime;
+
+    /**
+     * 超父游戏id
+     */
+    @NotNull(message = "超父游戏id不可为空")
+    @ApiModelProperty(notes = "超父游戏id")
+    private Long gameId;
+
+    /**
+     * 区服id
+     */
+    @NotBlank(message = "区服id不可为空")
+    @ApiModelProperty(notes = "区服id, 必传")
+    private String serverId;
+
+    /**
+     * 区服名称
+     */
+    @NotBlank(message = "区服名称不可为空")
+    @ApiModelProperty(notes = "区服名称, 必传")
+    private String serverName;
+
+    /**
+     * 开服时间
+     */
+    @NotNull(message = "开服时间不可为空")
+    @ApiModelProperty(notes = "开服时间, 必传")
+    private LocalDateTime startTime;
+
+    /**
+     * 区服冠名
+     */
+    @ApiModelProperty(notes = "区服冠名, 非必传")
+    private String nickName;
+}

+ 4 - 17
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/rpc/impl/PayBoxRpcImpl.java

@@ -1,36 +1,23 @@
 package com.zanxiang.game.module.manage.rpc.impl;
 
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.zanxiang.game.module.base.rpc.IPayBoxRpc;
-import com.zanxiang.game.module.manage.service.IAppletCheckService;
-import com.zanxiang.game.module.manage.service.IPayApplicationService;
-import com.zanxiang.game.module.mybatis.entity.PayApplication;
 import com.zanxiang.module.util.pojo.ResultVO;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboService;
-import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * @author : lingfeng
  * @time : 2024-01-16
  * @description : 支付盒子
  */
+@Slf4j
 @DubboService
 public class PayBoxRpcImpl implements IPayBoxRpc {
 
-    @Autowired
-    private IAppletCheckService appletCheckService;
-
-    @Autowired
-    private IPayApplicationService payApplicationService;
-
     @Override
     public ResultVO<Boolean> payBoxBan(String appId) {
-        PayApplication payApplication = payApplicationService.getOne(new LambdaQueryWrapper<PayApplication>()
-                .eq(PayApplication::getAppId, appId));
-        if (payApplication == null) {
-            return ResultVO.ok(Boolean.FALSE);
-        }
-        appletCheckService.payApplicationCheck(payApplication);
+        log.error("监测到的 appId : {}", appId);
         return ResultVO.ok(Boolean.TRUE);
     }
+
 }

+ 0 - 23
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IAppletCheckService.java

@@ -1,23 +0,0 @@
-package com.zanxiang.game.module.manage.service;
-
-import com.zanxiang.game.module.mybatis.entity.PayApplication;
-
-/**
- * @author : lingfeng
- * @time : 2024-01-20
- * @description : 小程序检查
- */
-public interface IAppletCheckService {
-
-    /**
-     * 小程序检查
-     */
-    void payApplicationCheck();
-
-    /**
-     * 小程序更新且通知
-     *
-     * @param payApplication : 支付应用
-     */
-    void payApplicationCheck(PayApplication payApplication);
-}

+ 18 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IListenCallService.java

@@ -10,4 +10,22 @@ import com.zanxiang.game.module.mybatis.entity.ListenCall;
  */
 public interface IListenCallService extends IService<ListenCall> {
 
+    /**
+     * 监测异常发送钉钉通知
+     *
+     * @param gameId  : 游戏id
+     * @param isSuper : 是否超父
+     * @param content : 通知内容
+     */
+    void sendDingTalkMsg(Long gameId, boolean isSuper, String content);
+
+    /**
+     * 监测异常电话通知
+     *
+     * @param gameId     : 游戏id
+     * @param isSuper    : 是否超父
+     * @param listenName : 模块名称
+     */
+    void sendPhoneTalkMsg(Long gameId, boolean isSuper, String listenName);
+
 }

+ 129 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/api/CpServerApiService.java

@@ -0,0 +1,129 @@
+package com.zanxiang.game.module.manage.service.api;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zanxiang.game.module.base.pojo.enums.DeleteEnum;
+import com.zanxiang.game.module.manage.pojo.params.ChatSubmitParam;
+import com.zanxiang.game.module.manage.pojo.params.OpenGameServerParam;
+import com.zanxiang.game.module.manage.service.IGameServerService;
+import com.zanxiang.game.module.manage.service.IGameSupperService;
+import com.zanxiang.game.module.manage.service.IListenCallService;
+import com.zanxiang.game.module.mybatis.entity.GameServer;
+import com.zanxiang.game.module.mybatis.entity.GameSupper;
+import com.zanxiang.module.util.JsonUtil;
+import com.zanxiang.module.util.exception.BaseException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.time.LocalDateTime;
+import java.util.Objects;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-04-25
+ * @description : cp服务端交互
+ */
+@Slf4j
+@Service
+public class CpServerApiService {
+
+    @Autowired
+    private IGameServerService gameServerService;
+
+    @Autowired
+    private IGameSupperService gameSupperService;
+
+    @Autowired
+    private IListenCallService listenCallService;
+
+    public boolean chatMsgSubmit(ChatSubmitParam param) {
+        GameSupper gameSupper = gameSupperService.getById(param.getGameId());
+        if (gameSupper == null) {
+            throw new BaseException("参数错误");
+        }
+        this.signCheck(gameSupper.getCpServerKey(), param.getGameId(), param.getServerId(),
+                param.getSignTime(), param.getSign());
+        log.error("接收到推送的聊天消息, param : {}", JsonUtil.toString(param));
+        //调武哥接口发送过去
+        return Boolean.TRUE;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public boolean openGameServer(OpenGameServerParam param) {
+        GameSupper gameSupper = gameSupperService.getById(param.getGameId());
+        if (gameSupper == null) {
+            throw new BaseException("参数错误");
+        }
+        this.signCheck(gameSupper.getCpServerKey(), param.getGameId(), param.getServerId(),
+                param.getSignTime(), param.getSign());
+        //查询区服id
+        GameServer gameServer = gameServerService.getOne(new LambdaQueryWrapper<GameServer>()
+                .eq(GameServer::getGameId, param.getGameId())
+                .eq(GameServer::getServerId, param.getServerId())
+        );
+        GameServer transform = this.transform(param);
+        if (gameServer == null) {
+            gameServer = transform;
+        } else {
+            gameServer.setGameId(transform.getGameId());
+            gameServer.setServerId(transform.getServerId());
+            gameServer.setServerName(transform.getServerName());
+            gameServer.setNickName(transform.getNickName());
+            gameServer.setStartTime(transform.getStartTime());
+            gameServer.setUpdateTime(LocalDateTime.now());
+        }
+        //区服添加或者更新
+        gameServerService.saveOrUpdate(gameServer);
+        //钉钉通知
+        String content = LocalDateTime.now().toString() + "游戏开服通知\n游戏名称 : " + gameSupper.getName()
+                + "\n区服名称:" + param.getServerName() + "\n开服时间:" + param.getStartTime().toString();
+        listenCallService.sendDingTalkMsg(param.getGameId(), Boolean.TRUE, content);
+        return Boolean.TRUE;
+    }
+
+    private GameServer transform(OpenGameServerParam param) {
+        return GameServer.builder()
+                .gameId(param.getGameId())
+                .serverId(param.getServerId())
+                .serverName(param.getServerName())
+                .nickName(param.getNickName())
+                .startTime(param.getStartTime())
+                .isDelete(DeleteEnum.NO.getCode())
+                .createBy(0L)
+                .createTime(LocalDateTime.now())
+                .isSourceServer(Boolean.TRUE)
+                .isMerge(Boolean.FALSE)
+                .updateBy(0L)
+                .updateTime(LocalDateTime.now())
+                .build();
+    }
+
+    private void signCheck(String cpServerKey, Long gameId, String serverId, Long signTime, String sign) {
+        String signStr = "cpServerKey=" + cpServerKey + "gameId=" + gameId
+                + "serverId=" + serverId + "signTime=" + signTime;
+        log.error("请求加密字符串 signStr : {}", signStr);
+        String mySign = this.md5(signStr);
+        if (Objects.equals(mySign, sign)) {
+            log.error("加密验证失败, sign : {}, mySign : {}", sign, mySign);
+            throw new BaseException("加密标识错误");
+        }
+    }
+
+    private String md5(String data) {
+        try {
+            java.security.MessageDigest md = MessageDigest.getInstance("MD5");
+            byte[] array = md.digest(data.getBytes(StandardCharsets.UTF_8));
+            StringBuilder sb = new StringBuilder();
+            for (byte item : array) {
+                sb.append(Integer.toHexString((item & 0xFF) | 0x100), 1, 3);
+            }
+            return sb.toString().toUpperCase();
+        } catch (Exception e) {
+            log.error("MD5加密异常, data : {}", data);
+            throw new BaseException("MD5加密异常");
+        }
+    }
+}

+ 0 - 289
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/AppletCheckServiceImpl.java

@@ -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);
-    }
-
-}

+ 109 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/ListenCallServiceImpl.java

@@ -1,11 +1,37 @@
 package com.zanxiang.game.module.manage.service.impl;
 
+import cn.hutool.http.ContentType;
+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.zanxiang.erp.base.ErpServer;
+import com.zanxiang.erp.base.rpc.IDingTalkMsgRpc;
+import com.zanxiang.game.module.base.pojo.enums.StatusEnum;
+import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
+import com.zanxiang.game.module.manage.service.IGameService;
 import com.zanxiang.game.module.manage.service.IListenCallService;
+import com.zanxiang.game.module.mybatis.entity.Game;
 import com.zanxiang.game.module.mybatis.entity.ListenCall;
 import com.zanxiang.game.module.mybatis.mapper.ListenCallMapper;
+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.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * @author : lingfeng
@@ -15,4 +41,87 @@ import org.springframework.stereotype.Service;
 @Slf4j
 @Service
 public class ListenCallServiceImpl extends ServiceImpl<ListenCallMapper, ListenCall> implements IListenCallService {
+
+    @DubboReference(providedBy = ErpServer.SERVER_DUBBO_NAME)
+    private IDingTalkMsgRpc dingTalkMsgRpc;
+
+    @Autowired
+    private IDistributedLockComponent distributedLockComponent;
+
+    @Autowired
+    private IGameService gameService;
+
+    @Override
+    public void sendDingTalkMsg(Long gameId, boolean isSuper, String content) {
+        List<ListenCall> listenCallList = this.callListenUser(gameId, isSuper);
+        if (CollectionUtils.isEmpty(listenCallList)) {
+            return;
+        }
+        Set<Long> userIdSet = listenCallList.stream()
+                .filter(listenCall -> Strings.isNotBlank(listenCall.getDingTalkNum()))
+                .map(ListenCall::getUserId).collect(Collectors.toSet());
+        userIdSet.forEach(userId -> dingTalkMsgRpc.sendByUserId(userId, content));
+    }
+
+    @Override
+    public void sendPhoneTalkMsg(Long gameId, boolean isSuper, String listenName) {
+        List<ListenCall> listenCallList = this.callListenUser(gameId, isSuper);
+        if (CollectionUtils.isEmpty(listenCallList)) {
+            return;
+        }
+        String content = listenName + "监测异常";
+        Set<String> phoneNumSet = listenCallList.stream()
+                .filter(listenCall -> Strings.isNotBlank(listenCall.getPhoneNum()))
+                .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(Long gameId, boolean isSuper) {
+        List<Long> gameIdList = new ArrayList<>();
+        if (isSuper) {
+            gameIdList = gameService.list(new LambdaQueryWrapper<Game>()
+                    .eq(Game::getSuperGameId, gameId)
+            ).stream().map(Game::getId).collect(Collectors.toList());
+        }
+        List<ListenCall> listenCallList = super.list(new LambdaQueryWrapper<ListenCall>()
+                .eq(!isSuper, ListenCall::getGameId, gameId)
+                .in(isSuper && CollectionUtils.isNotEmpty(gameIdList), ListenCall::getGameId, gameIdList)
+                .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 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);
+    }
 }

+ 0 - 61
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/task/PayApplicationTask.java

@@ -1,61 +0,0 @@
-package com.zanxiang.game.module.manage.task;
-
-import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
-import com.zanxiang.game.module.manage.service.IAppletCheckService;
-import com.zanxiang.module.redis.service.IDistributedLockComponent;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-
-import java.time.LocalDateTime;
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author : lingfeng
- * @time : 2024-01-20
- * @description : 支付应用任务
- */
-@Slf4j
-@Component
-public class PayApplicationTask {
-
-    @Autowired
-    private IDistributedLockComponent distributedLockComponent;
-
-    @Autowired
-    private IAppletCheckService appletCheckService;
-
-    /**
-     * 服务器域名
-     */
-    @Value("${taskRun}")
-    private Boolean taskRun;
-
-    /**
-     * 小程序每10分钟检查
-     */
-    @Scheduled(cron = "0 0/10 * * * ?")
-    public void payApplicationCheck() {
-        if (!taskRun) {
-            return;
-        }
-        //上锁
-        if (!distributedLockComponent.doLock(RedisKeyConstant.PAY_APP_CHECK_LOCK, 0L, 15L, TimeUnit.MINUTES)) {
-            return;
-        }
-        log.error("小程序每10分钟封停监控定时器开始执行, startTime : {}", LocalDateTime.now().toString());
-        try {
-            //执行检测
-            appletCheckService.payApplicationCheck();
-        } catch (Exception e) {
-            log.error("小程序每10分钟封停监控异常, e : {}", e.getMessage());
-        } finally {
-            //释放锁
-            distributedLockComponent.unlock(RedisKeyConstant.PAY_APP_CHECK_LOCK);
-        }
-        log.error("小程序每10分钟封停监控定时器执行结束 , endTime  : {}", LocalDateTime.now().toString());
-    }
-
-}

+ 5 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/GameSupper.java

@@ -50,6 +50,11 @@ public class GameSupper implements Serializable {
      */
     private String cpSendMsgKey;
 
+    /**
+     * CP服务端交互密钥
+     */
+    private String cpServerKey;
+
     /**
      * 1 删除  0 正常
      */