Kaynağa Gözat

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

Letianhua 1 yıl önce
ebeveyn
işleme
f7ab407645
17 değiştirilmiş dosya ile 519 ekleme ve 10 silme
  1. 18 0
      game-module/game-module-base/src/main/java/com/zanxiang/game/module/base/rpc/IWxApiServiceRpc.java
  2. 3 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/ManageApplication.java
  3. 18 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/rpc/impl/PayBoxRpcImpl.java
  4. 23 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IAppletCheckService.java
  5. 13 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IListenCallService.java
  6. 240 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/AppletCheckServiceImpl.java
  7. 18 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/ListenCallServiceImpl.java
  8. 4 3
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/UserServiceImpl.java
  9. 51 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/task/PayApplicationTask.java
  10. 1 1
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/SDKApplication.java
  11. 10 0
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/controller/LoginController.java
  12. 28 0
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/pojo/vo/CpTokenCheckVO.java
  13. 23 0
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/rpc/impl/WxApiServiceRpcImpl.java
  14. 12 0
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/IUserTokenService.java
  15. 53 0
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/UserTokenServiceImpl.java
  16. 3 3
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/pay/AliPayService.java
  17. 1 1
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/pay/WxPayService.java

+ 18 - 0
game-module/game-module-base/src/main/java/com/zanxiang/game/module/base/rpc/IWxApiServiceRpc.java

@@ -0,0 +1,18 @@
+package com.zanxiang.game.module.base.rpc;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-01-20
+ * @description : 微信接口
+ */
+public interface IWxApiServiceRpc {
+
+    /**
+     * 获取访问令牌
+     *
+     * @param appId  应用程序id
+     * @param secret 秘密
+     * @return {@link String}
+     */
+    String getAccessToken(String appId, String secret);
+}

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

@@ -5,6 +5,7 @@ import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.scheduling.annotation.EnableScheduling;
 import springfox.documentation.swagger2.annotations.EnableSwagger2;
 
 /**
@@ -17,11 +18,12 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
 @SpringBootApplication
 @EnableDubbo
 @EnableSwagger2
+@EnableScheduling
 public class ManageApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(ManageApplication.class, args);
-        System.out.println("赞象Manage服务启动成功 <客服系统, 新增授权接口4> ( ´・・)ノ(._.`) \n" +
+        System.out.println("赞象Manage服务启动成功 <小程序监听修改完成上线02> ( ´・・)ノ(._.`) \n" +
                 "___  ___  ___   _   _   ___  _____  _____ \n" +
                 "|  \\/  | / _ \\ | \\ | | / _ \\|  __ \\|  ___|\n" +
                 "| .  . |/ /_\\ \\|  \\| |/ /_\\ \\ |  \\/| |__  \n" +

+ 18 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/rpc/impl/PayBoxRpcImpl.java

@@ -1,8 +1,13 @@
 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 org.apache.dubbo.config.annotation.DubboService;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * @author : lingfeng
@@ -12,8 +17,20 @@ import org.apache.dubbo.config.annotation.DubboService;
 @DubboService
 public class PayBoxRpcImpl implements IPayBoxRpc {
 
+    @Autowired
+    private IAppletCheckService appletCheckService;
+
+    @Autowired
+    private IPayApplicationService payApplicationService;
+
     @Override
     public ResultVO<Boolean> payBoxBan(String appId) {
-        return null;
+        PayApplication payApplication = payApplicationService.getOne(new LambdaQueryWrapper<PayApplication>()
+                .eq(PayApplication::getAppId, appId));
+        if (payApplication == null) {
+            return ResultVO.ok(Boolean.FALSE);
+        }
+        appletCheckService.payApplicationCheck(payApplication);
+        return ResultVO.ok(Boolean.TRUE);
     }
 }

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

@@ -0,0 +1,23 @@
+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);
+}

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

@@ -0,0 +1,13 @@
+package com.zanxiang.game.module.manage.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zanxiang.game.module.mybatis.entity.ListenCall;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-01-16
+ * @description : 监听呼叫
+ */
+public interface IListenCallService extends IService<ListenCall> {
+
+}

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

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

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

@@ -0,0 +1,18 @@
+package com.zanxiang.game.module.manage.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zanxiang.game.module.manage.service.IListenCallService;
+import com.zanxiang.game.module.mybatis.entity.ListenCall;
+import com.zanxiang.game.module.mybatis.mapper.ListenCallMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-01-16
+ * @description : 监听呼叫
+ */
+@Slf4j
+@Service
+public class ListenCallServiceImpl extends ServiceImpl<ListenCallMapper, ListenCall> implements IListenCallService {
+}

+ 4 - 3
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/UserServiceImpl.java

@@ -59,6 +59,9 @@ import java.util.stream.Collectors;
 @Service
 public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
 
+    @DubboReference(providedBy = CorpServer.SERVER_DUBBO_NAME)
+    private ICorpExternalUserServiceRpc corpExternalUserServiceRpc;
+
     @Autowired
     private IGameService gameService;
 
@@ -74,9 +77,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
     @Autowired
     private IGameUserRoleService gameUserRoleService;
 
-    @DubboReference(providedBy = CorpServer.SERVER_DUBBO_NAME)
-    private ICorpExternalUserServiceRpc corpExternalUserServiceRpc;
-
     @Autowired
     private IGameUserService gameUserService;
 
@@ -121,6 +121,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
         h5User.setGameId(gameDTO.getId());
         h5User.setMobile(mobile);
         h5User.setRelationUserId(user.getId());
+        h5User.setRelationGameId(user.getGameId());
         h5User.setRelationCreateTime(LocalDateTime.now());
         //充值统计数据归零设置
         h5User.setSessionKey(null);

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

@@ -0,0 +1,51 @@
+package com.zanxiang.game.module.manage.task;
+
+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.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;
+
+    /**
+     * 小程序每10分钟检查
+     */
+    @Scheduled(cron = "0 0/10 * * * ?")
+    public void payApplicationCheck() {
+        String lockKey = "payApplicationCheck_lock";
+        //上锁
+        if (!distributedLockComponent.doLock(lockKey, 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(lockKey);
+        }
+        log.error("小程序每10分钟封停监控定时器执行结束 , endTime  : {}", LocalDateTime.now().toString());
+    }
+
+}

+ 1 - 1
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/SDKApplication.java

@@ -23,7 +23,7 @@ public class SDKApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(SDKApplication.class, args);
-        System.out.println("赞象SDK服务启动成功 <兼容ios通用客户端, 新增创角回传--01> ( ´・・)ノ(._.`) \n" +
+        System.out.println("赞象SDK服务启动成功 <新增token验证接口> ( ´・・)ノ(._.`) \n" +
                 " ___________ _   __\n" +
                 "/  ___|  _  \\ | / /\n" +
                 "\\ `--.| | | | |/ / \n" +

+ 10 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/controller/LoginController.java

@@ -6,6 +6,7 @@ import com.zanxiang.game.module.sdk.pojo.param.LoginMobileParam;
 import com.zanxiang.game.module.sdk.pojo.param.LoginPasswordParam;
 import com.zanxiang.game.module.sdk.pojo.param.LoginVxCodeParam;
 import com.zanxiang.game.module.sdk.pojo.param.UserData;
+import com.zanxiang.game.module.sdk.pojo.vo.CpTokenCheckVO;
 import com.zanxiang.game.module.sdk.pojo.vo.UserLoginVO;
 import com.zanxiang.game.module.sdk.service.IRegisterLoginService;
 import com.zanxiang.game.module.sdk.service.IUserTokenService;
@@ -44,6 +45,15 @@ public class LoginController {
         return registerLoginService.loginWxCode(param, userData, request);
     }
 
+    @UnSignCheck
+    @ApiOperation(value = "CP登录凭证验证")
+    @GetMapping("/token/check/new")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = CpTokenCheckVO.class)})
+    public ResultVO<CpTokenCheckVO> cpTokenCheckNew(@RequestParam String appId, @RequestParam Long userId,
+                                                    @RequestParam String token, @RequestParam String sign) {
+        return userTokenService.cpTokenCheckNew(appId, userId, token, sign);
+    }
+
     @UnSignCheck
     @ApiOperation(value = "CP登录凭证验证")
     @GetMapping("/token/check")

+ 28 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/pojo/vo/CpTokenCheckVO.java

@@ -0,0 +1,28 @@
+package com.zanxiang.game.module.sdk.pojo.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-01-23
+ * @description : token验证返回
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class CpTokenCheckVO {
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+    /**
+     * 应用id
+     */
+    private String appId;
+}

+ 23 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/rpc/impl/WxApiServiceRpcImpl.java

@@ -0,0 +1,23 @@
+package com.zanxiang.game.module.sdk.rpc.impl;
+
+import com.zanxiang.game.module.base.rpc.IWxApiServiceRpc;
+import com.zanxiang.game.module.sdk.service.api.WxApiService;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-01-20
+ * @description : 微信接口
+ */
+@DubboService
+public class WxApiServiceRpcImpl implements IWxApiServiceRpc {
+
+    @Autowired
+    private WxApiService wxApiService;
+
+    @Override
+    public String getAccessToken(String appId, String secret) {
+        return wxApiService.getAccessToken(appId, secret);
+    }
+}

+ 12 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/IUserTokenService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.zanxiang.game.module.mybatis.entity.UserToken;
 import com.zanxiang.game.module.sdk.pojo.dto.UserTokenDTO;
 import com.zanxiang.game.module.sdk.pojo.param.UserData;
+import com.zanxiang.game.module.sdk.pojo.vo.CpTokenCheckVO;
 import com.zanxiang.module.util.pojo.ResultVO;
 
 /**
@@ -13,6 +14,17 @@ import com.zanxiang.module.util.pojo.ResultVO;
  */
 public interface IUserTokenService extends IService<UserToken> {
 
+    /**
+     * cp令牌检查
+     *
+     * @param appId  应用程序id
+     * @param userId 用户id
+     * @param token  令牌
+     * @param sign   标志
+     * @return {@link ResultVO}<{@link CpTokenCheckVO}>
+     */
+    ResultVO<CpTokenCheckVO> cpTokenCheckNew(String appId, Long userId, String token, String sign);
+
     /**
      * cp令牌检查
      *

+ 53 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/UserTokenServiceImpl.java

@@ -15,6 +15,7 @@ import com.zanxiang.game.module.sdk.enums.LoginTypeEnum;
 import com.zanxiang.game.module.sdk.enums.TokenCheckEnum;
 import com.zanxiang.game.module.sdk.pojo.dto.UserTokenDTO;
 import com.zanxiang.game.module.sdk.pojo.param.UserData;
+import com.zanxiang.game.module.sdk.pojo.vo.CpTokenCheckVO;
 import com.zanxiang.game.module.sdk.service.*;
 import com.zanxiang.game.module.sdk.util.RedisUtil;
 import com.zanxiang.game.module.sdk.util.SignUtil;
@@ -57,6 +58,58 @@ public class UserTokenServiceImpl extends ServiceImpl<UserTokenMapper, UserToken
     @Autowired
     private IUserLoginLogService userLoginLogService;
 
+    @Override
+    public ResultVO<CpTokenCheckVO> cpTokenCheckNew(String appId, Long userId, String token, String sign) {
+        //查询登录签名
+        GameExt gameExt = gameExtService.getByGameAppId(appId);
+        if (gameExt == null || Strings.isBlank(gameExt.getLoginKey())) {
+            log.error("token验证失败 , 游戏拓展信息不存在, appId : {}, userId : {}", appId, userId);
+            return ResultVO.fail(TokenCheckEnum.PARAM_LACK.getMsg());
+        }
+        //用户信息
+        User user = userService.getById(userId);
+        //查询token是否存在
+        UserToken userToken = super.getOne(new LambdaQueryWrapper<UserToken>()
+                .eq(UserToken::getToken, token)
+                .eq(UserToken::getUserId, userId));
+        //导量用户携带的是 relationUserId 匹配的token
+        if (userToken == null && user.getRelationUserId() != null) {
+            userToken = super.getOne(new LambdaQueryWrapper<UserToken>()
+                    .eq(UserToken::getToken, token)
+                    .eq(UserToken::getUserId, user.getRelationUserId()));
+        }
+        //判断token是否存在, 并且没有过期
+        if (userToken == null || userToken.getExpireTime() < DateUtils.localDateTimeToSecond(LocalDateTime.now())) {
+            log.error("token验证失败 , token不存在或者已经失效, appId : {}, userId : {}, token : {}", appId, userId, token);
+            return ResultVO.fail(TokenCheckEnum.SIGN_ERROR.getMsg());
+        }
+        //登录密钥
+        String loginKey = gameExt.getLoginKey();
+        //计算用户签名
+        StringBuilder sb = new StringBuilder();
+        sb.append("loginKey=").append(loginKey);
+        sb.append("&appId=").append(appId);
+        sb.append("&userId=").append(userId);
+        sb.append("&token=").append(token);
+        String mySign;
+        try {
+            mySign = SignUtil.MD5(sb.toString());
+        } catch (Exception e) {
+            log.error("md5工具类加密异常, str : {}, e : {}", sb.toString(), e.getMessage());
+            throw new BaseException("MD5加密异常");
+        }
+        //签名错误
+        if (!Objects.equals(mySign, sign)) {
+            log.error("token验证失败 , str : {}, mySign : {}, sign : {}", sb.toString(), mySign, sign);
+            return ResultVO.fail(TokenCheckEnum.CHECK_FAIL.getMsg());
+        }
+        //构造返回
+        return ResultVO.ok(CpTokenCheckVO.builder()
+                .userId(userId)
+                .appId(gameExtService.getByGameId(user.getGameId()).getAppId())
+                .build());
+    }
+
     @Override
     public ResultVO<Long> cpTokenCheck(String appId, Long userId, String token, String sign) {
         //查询登录签名

+ 3 - 3
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/pay/AliPayService.java

@@ -203,7 +203,7 @@ public class AliPayService extends PayBaseService {
                     .pay(product.getSubject(), product.getOutTradeNo(), product.getTotalFee(), "", "");
         } catch (Exception e) {
             log.error("支付宝H5支付异常, product : {}, e:{}", JsonUtil.toString(product), e.getMessage());
-            this.listenCall(product.getGameId(), "支付宝H5支付");
+            this.listenCall(product.getGameId(), "阿宝网页端支付异常");
             throw new BaseException("支付宝H5支付异常");
         }
         //请求失败
@@ -307,7 +307,7 @@ public class AliPayService extends PayBaseService {
                     .pay(product.getSubject(), product.getOutTradeNo(), product.getTotalFee(), "");
         } catch (Exception e) {
             log.error("支付宝pc端支付异常, product : {}, e:{}", JsonUtil.toString(product), e.getMessage());
-            this.listenCall(product.getGameId(), "支付宝pc端支付");
+            this.listenCall(product.getGameId(), "阿宝电脑端支付异常");
             throw new BaseException("支付宝pc端支付异常");
         }
         if (!ResponseChecker.success(response)) {
@@ -329,7 +329,7 @@ public class AliPayService extends PayBaseService {
                     .pay(product.getSubject(), product.getOutTradeNo(), product.getTotalFee());
         } catch (Exception e) {
             log.error("支付宝app端支付异常, product : {}, e:{}", JsonUtil.toString(product), e.getMessage());
-            this.listenCall(product.getGameId(), "支付宝app端支付");
+            this.listenCall(product.getGameId(), "阿宝移动端支付异常");
             throw new BaseException("支付宝app端支付异常");
         }
         if (!ResponseChecker.success(response)) {

+ 1 - 1
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/pay/WxPayService.java

@@ -351,7 +351,7 @@ public class WxPayService extends PayBaseService {
             throw new BaseException("微信小程序支付下单失败");
         } catch (Exception e) {
             log.error("微信支付通信异常, 订单号:{}, e : {}", product.getOutTradeNo(), e.getMessage());
-            this.listenCall(product.getGameId(), "微信支付通道");
+            this.listenCall(product.getGameId(), "小马支付通道异常");
             throw new BaseException("微信小程序支付下单异常");
         }
     }