瀏覽代碼

Merge branch 'package' of GameCenter/game-center into dev

zhimo 1 年之前
父節點
當前提交
a3de4b3693
共有 18 個文件被更改,包括 344 次插入27 次删除
  1. 6 0
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/dto/RoleRechargeRankingDTO.java
  2. 4 0
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/RoleManageServiceImpl.java
  3. 1 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/ManageApplication.java
  4. 8 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/GameVipController.java
  5. 11 3
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/KfMsgController.java
  6. 6 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/enums/KfActionEnum.java
  7. 11 4
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/enums/KfApiEnum.java
  8. 67 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/GameVipAddBatchParam.java
  9. 3 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IGameVipService.java
  10. 10 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfMsgContentService.java
  11. 56 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/GameVipServiceImpl.java
  12. 51 6
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfMsgContentServiceImpl.java
  13. 40 0
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/KfLink.java
  14. 12 0
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/mapper/KfLinkMapper.java
  15. 1 1
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/SDKApplication.java
  16. 12 0
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/IKfLinkService.java
  17. 27 11
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/GameAppletServiceImpl.java
  18. 18 0
      game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/KfLinkServiceImpl.java

+ 6 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/dto/RoleRechargeRankingDTO.java

@@ -189,4 +189,10 @@ public class RoleRechargeRankingDTO extends BasePage {
     @ApiModelProperty(notes = "是否唤醒 1-是;0-否; 2-空(默认)")
     private Integer isWakeUp;
 
+    /**
+     * 玩家操作系统筛选:windows;mac;ios;devtools;android
+     */
+    @ApiModelProperty(notes = "玩家操作系统筛选:windows;mac;ios;devtools;android")
+    private String os;
+
 }

+ 4 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/RoleManageServiceImpl.java

@@ -133,6 +133,10 @@ public class RoleManageServiceImpl implements IRoleManageService {
             //累计充值金额最大值
             criA.where().andLTE("amount", dto.getTotalRechargeMax());
         }
+        if (StringUtils.isNotBlank(dto.getOs())) {
+            //玩家操作系统
+            criA.where().andEquals("os", dto.getOs());
+        }
         if (dto.getIsRemoveGame() != null) {
             if (dto.getIsRemoveGame() == 2) {
                 //是否退游

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

@@ -21,7 +21,7 @@ public class ManageApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(ManageApplication.class, args);
-        System.out.println("赞象Manage服务启动成功 <客服系统04> ( ´・・)ノ(._.`) \n" +
+        System.out.println("赞象Manage服务启动成功 <客服系统08> ( ´・・)ノ(._.`) \n" +
                 "___  ___  ___   _   _   ___  _____  _____ \n" +
                 "|  \\/  | / _ \\ | \\ | | / _ \\|  __ \\|  ___|\n" +
                 "| .  . |/ /_\\ \\|  \\| |/ /_\\ \\ |  \\/| |__  \n" +

+ 8 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/GameVipController.java

@@ -2,6 +2,7 @@ package com.zanxiang.game.module.manage.controller;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.zanxiang.erp.security.annotation.PreAuthorize;
+import com.zanxiang.game.module.manage.pojo.params.GameVipAddBatchParam;
 import com.zanxiang.game.module.manage.pojo.params.GameVipAddParam;
 import com.zanxiang.game.module.manage.pojo.params.GameVipListParam;
 import com.zanxiang.game.module.manage.pojo.vo.GameVipListVO;
@@ -52,4 +53,11 @@ public class GameVipController {
         return ResultVO.ok(gameVipService.gameVipList(param));
     }
 
+    @ApiOperation(value = "批量添加VIP档位")
+    @PostMapping("/add/batch")
+    @PreAuthorize(permissionKey = "manage:gameVip:addBatch")
+    public ResultVO<Boolean> addVipBatch(@Validated @RequestBody GameVipAddBatchParam param) {
+        return ResultVO.ok(gameVipService.addBatch(param));
+    }
+
 }

+ 11 - 3
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/controller/KfMsgController.java

@@ -2,7 +2,6 @@ package com.zanxiang.game.module.manage.controller;
 
 import com.zanxiang.erp.security.annotation.PreAuthorize;
 import com.zanxiang.game.module.manage.pojo.params.KfApiParam;
-import com.zanxiang.game.module.manage.pojo.vo.CpVO;
 import com.zanxiang.game.module.manage.pojo.vo.KfGameVO;
 import com.zanxiang.game.module.manage.service.IKfMsgContentService;
 import com.zanxiang.module.util.pojo.ResultVO;
@@ -14,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
 
@@ -31,10 +31,18 @@ public class KfMsgController {
     @Autowired
     private IKfMsgContentService kfMsgContentService;
 
+    @ApiOperation(value = "发送图片消息 (参数按照发送消息的参数给, 外加图片文件)")
+    @PostMapping(value = "/upload/msg")
+    @PreAuthorize(permissionKey = "manage:kf:uploadMsg")
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = String.class)})
+    public ResultVO<String> uploadMsg(@Validated @RequestBody KfApiParam param, MultipartFile files) {
+        return ResultVO.ok(kfMsgContentService.uploadMsg(param, files));
+    }
+
     @ApiOperation(value = "小游戏列表查询")
     @GetMapping(value = "/game/list")
     @PreAuthorize(permissionKey = "manage:kf:gameList")
-    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = CpVO.class)})
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = KfGameVO.class)})
     public ResultVO<List<KfGameVO>> list() {
         return ResultVO.ok(kfMsgContentService.getKfGameList());
     }
@@ -42,7 +50,7 @@ public class KfMsgController {
     @ApiOperation(value = "客服接口通用api")
     @PostMapping(value = "/comm/api")
     @PreAuthorize(permissionKey = "manage:kf:commApi")
-    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = CpVO.class)})
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "成功", response = String.class)})
     public ResultVO<String> list(@Validated @RequestBody KfApiParam param) {
         return ResultVO.ok(kfMsgContentService.kfApi(param));
     }

+ 6 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/enums/KfActionEnum.java

@@ -65,7 +65,12 @@ public enum KfActionEnum {
     /**
      * 已接入列表
      */
-    GET_SESSION_SUMMARY("get_session_summary");
+    GET_SESSION_SUMMARY("get_session_summary"),
+
+    /**
+     * 上传图片
+     */
+    UPLOAD_PIC_MSG("upload_pic_msg");
 
     /**
      * 接口行为

+ 11 - 4
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/enums/KfApiEnum.java

@@ -26,28 +26,35 @@ public enum KfApiEnum {
      * 房间
      */
     ROOM("https://mpkf.weixin.qq.com/commkf/room", new KfActionEnum[]{
-            KfActionEnum.ACCEPT_ROOM, KfActionEnum.GET_ROOM_INFO, KfActionEnum.GET_USER_TAG
+            KfActionEnum.ACCEPT_ROOM, KfActionEnum.GET_ROOM_INFO, KfActionEnum.GET_USER_TAG, KfActionEnum.END_ROOM
     }),
 
     /**
      * 消息
      */
     MSG("https://mpkf.weixin.qq.com/commkf/msg", new KfActionEnum[]{
-            KfActionEnum.GET_ROOM_MSG, KfActionEnum.GET_MSG_ID, KfActionEnum.SEND_ROOM_MSG, KfActionEnum.END_ROOM
+            KfActionEnum.GET_ROOM_MSG, KfActionEnum.GET_MSG_ID, KfActionEnum.SEND_ROOM_MSG
     }),
 
     /**
      * 报告
      */
     REPORT("https://mpkf.weixin.qq.com/commkf/report", new KfActionEnum[]{
-            KfActionEnum.ACCEPT_ROOM
+
+    }),
+
+    /**
+     * 消息上传
+     */
+    UPLOAD_MSG("https://mpkf.weixin.qq.com/commkf/upload_msg", new KfActionEnum[]{
+            KfActionEnum.UPLOAD_PIC_MSG
     }),
 
     /**
      * 总汇表
      */
     SUMMARY("https://mpkf.weixin.qq.com/commkf/summary", new KfActionEnum[]{
-            KfActionEnum.BATCH_GET_NO_SESSION_EXTRA_INFO
+            KfActionEnum.BATCH_GET_NO_SESSION_EXTRA_INFO, KfActionEnum.GET_SESSION_SUMMARY
     });
 
     /**

+ 67 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/GameVipAddBatchParam.java

@@ -0,0 +1,67 @@
+package com.zanxiang.game.module.manage.pojo.params;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @author tianhua
+ * @version 1.0
+ * @description: TODO
+ * @date 2023/12/7 15:10
+ */
+@Data
+public class GameVipAddBatchParam {
+
+    /**
+     * 游戏id
+     */
+    @NotNull(message = "超父游戏id不能为空")
+    @ApiModelProperty("超父游戏id")
+    private Long superGameId;
+
+    /**
+     * 游戏id
+     */
+    @NotNull(message = "父游戏id不能为空")
+    @ApiModelProperty("父游戏id")
+    private List<Long> parentGameId;
+
+    /**
+     * 游戏VIP参数列表
+     */
+    @NotNull(message = "新增的游戏vip不能为空")
+    @ApiModelProperty("游戏VIP参数列表")
+    private List<GameVipParam> list;
+
+    /**
+     * 内部类
+     */
+    @Data
+    public static class GameVipParam {
+        /**
+         * 充值金额最小(包含)
+         */
+        @NotNull(message = "充值金额最小不能为空")
+        @ApiModelProperty("充值金额最小(包含)")
+        private BigDecimal rechargeMoneyMin;
+
+        /**
+         * 充值金额最大(不包含)
+         */
+        @NotNull(message = "充值金额最大不能为空")
+        @ApiModelProperty("充值金额最大(不包含)")
+        private BigDecimal rechargeMoneyMax;
+
+        /**
+         * vip档位
+         */
+        @NotNull(message = "vip档位不能为空")
+        @ApiModelProperty("vip档位")
+        private Integer vipLevel;
+    }
+
+}

+ 3 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IGameVipService.java

@@ -2,6 +2,7 @@ package com.zanxiang.game.module.manage.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.zanxiang.game.module.manage.pojo.params.GameVipAddBatchParam;
 import com.zanxiang.game.module.manage.pojo.params.GameVipAddParam;
 import com.zanxiang.game.module.manage.pojo.params.GameVipListParam;
 import com.zanxiang.game.module.manage.pojo.vo.GameVipListVO;
@@ -23,4 +24,6 @@ public interface IGameVipService extends IService<GameVip> {
 
     IPage<GameVipListVO> gameVipList(GameVipListParam param);
 
+    boolean addBatch(GameVipAddBatchParam param);
+
 }

+ 10 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfMsgContentService.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.zanxiang.game.module.manage.pojo.params.KfApiParam;
 import com.zanxiang.game.module.manage.pojo.vo.KfGameVO;
 import com.zanxiang.game.module.mybatis.entity.KfMsgContent;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
 
@@ -14,6 +15,15 @@ import java.util.List;
  */
 public interface IKfMsgContentService extends IService<KfMsgContent> {
 
+    /**
+     * 消息上传
+     *
+     * @param param : 接口参数
+     * @param files : 文件
+     * @return : 返回发送结果
+     */
+    String uploadMsg(KfApiParam param, MultipartFile files);
+
     /**
      * 获取游戏列表
      *

+ 56 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/GameVipServiceImpl.java

@@ -8,6 +8,7 @@ import com.zanxiang.erp.base.ErpServer;
 import com.zanxiang.erp.base.rpc.ISysUserRpc;
 import com.zanxiang.erp.security.util.SecurityUtil;
 import com.zanxiang.game.module.manage.pojo.dto.GameDTO;
+import com.zanxiang.game.module.manage.pojo.params.GameVipAddBatchParam;
 import com.zanxiang.game.module.manage.pojo.params.GameVipAddParam;
 import com.zanxiang.game.module.manage.pojo.params.GameVipListParam;
 import com.zanxiang.game.module.manage.pojo.vo.GameVipListVO;
@@ -18,13 +19,16 @@ import com.zanxiang.game.module.mybatis.entity.GameSupper;
 import com.zanxiang.game.module.mybatis.entity.GameVip;
 import com.zanxiang.game.module.mybatis.mapper.GameVipMapper;
 import com.zanxiang.module.util.exception.BaseException;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * @author tianhua
@@ -113,6 +117,58 @@ public class GameVipServiceImpl extends ServiceImpl<GameVipMapper, GameVip> impl
                 .convert(this::toVO);
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addBatch(GameVipAddBatchParam param) {
+        checkParam(param);
+        Long sysUserId = SecurityUtil.getUserId();
+        LocalDateTime now = LocalDateTime.now();
+        //得到需要添加的vip列表的所有vip等级
+        List<Integer> vipList = param.getList().stream()
+                .map(GameVipAddBatchParam.GameVipParam::getVipLevel).collect(Collectors.toList());
+
+        int count = count(new LambdaQueryWrapper<GameVip>()
+                .eq(GameVip::getSuperGameId, param.getSuperGameId())
+                .in(GameVip::getParentGameId, param.getParentGameId())
+                .in(GameVip::getVipLevel, vipList)
+                .eq(GameVip::getIsDelete, 0));
+        if (count > 0) {
+            throw new BaseException("已经存在需要添加的VIP等级,请勿重复设置。");
+        }
+        //总共需要建多少个GameVip实例
+        int size = param.getParentGameId().size() * param.getList().size();
+        List<GameVip> list = new ArrayList<>(size);
+        for (int i = 0; i < param.getParentGameId().size(); i++) {
+            //父游戏ID
+            Long parentGameId = param.getParentGameId().get(i);
+            for (GameVipAddBatchParam.GameVipParam gameVipParam : param.getList()) {
+                list.add(GameVip.builder()
+                                .parentGameId(parentGameId)
+                                .superGameId(param.getSuperGameId())
+                                .rechargeMoneyMin(gameVipParam.getRechargeMoneyMin())
+                                .rechargeMoneyMax(gameVipParam.getRechargeMoneyMax())
+                                .vipLevel(gameVipParam.getVipLevel())
+                                .createBy(sysUserId)
+                                .createTime(now)
+                                .updateTime(now)
+                                .updateBy(sysUserId)
+                                .build());
+            }
+        }
+        return saveBatch(list);
+    }
+
+    private void checkParam(GameVipAddBatchParam param) {
+        if (CollectionUtils.isEmpty(param.getList())) {
+            throw new BaseException("至少创建一个VIP档位。");
+        }
+        List<Integer> collect = param.getList().stream()
+                .map(GameVipAddBatchParam.GameVipParam::getVipLevel).collect(Collectors.toList())
+                .stream().distinct().collect(Collectors.toList());
+        if (collect.size() != param.getList().size()) {
+            throw new BaseException("不能创建重复的VIP档位。");
+        }
+    }
 
     private GameVipListVO toVO(GameVip vo) {
         GameDTO game = gameService.getById(vo.getParentGameId());

+ 51 - 6
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfMsgContentServiceImpl.java

@@ -24,13 +24,15 @@ import com.zanxiang.module.util.bean.BeanUtil;
 import com.zanxiang.module.util.exception.BaseException;
 import lombok.extern.slf4j.Slf4j;
 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.core.io.Resource;
+import org.springframework.http.*;
 import org.springframework.stereotype.Service;
+import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.web.client.RestTemplate;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.util.UriComponentsBuilder;
 
+import java.net.URI;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -58,6 +60,50 @@ public class KfMsgContentServiceImpl extends ServiceImpl<KfMsgContentMapper, KfM
     @Autowired
     private IGameAppletService gameAppletService;
 
+    @Override
+    public String uploadMsg(KfApiParam param, MultipartFile files) {
+        log.error("发送图片消息参数, param : {}", JsonUtil.toString(param));
+        //查询用户授权信息
+        KfUser kfUser = kfUserService.getKfUser(SecurityUtil.getUserId(), param.getAppId());
+        //图片上传腾讯
+        String uploadResult = this.imgUploadApi(kfUser, files);
+        //发送客服消息
+        Map<String, Object> paramMap = param.getParam();
+        paramMap.put("msg_content", uploadResult);
+        //腾讯api
+        return this.commKfApi(kfUser, param.getAction().getValue(), KfApiEnum.getApiUrl(param.getAction()), paramMap);
+    }
+
+    private String imgUploadApi(KfUser kfUser, MultipartFile files) {
+        //请求地址
+        URI uri = UriComponentsBuilder.fromHttpUrl(KfApiEnum.UPLOAD_MSG.getApiUrl())
+                .queryParam("action", KfActionEnum.UPLOAD_PIC_MSG.getValue())
+                .queryParam("token", kfUser.getToken())
+                .queryParam("lang", "zh_CN")
+                .build().toUri();
+        //最外层请求头
+        HttpHeaders httpHeaders = new HttpHeaders();
+        httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
+        httpHeaders.add("cookie", kfUser.getCookie());
+        LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
+        //文件内容请求头
+        HttpHeaders formHeader = new HttpHeaders();
+        formHeader.setContentType(MediaType.MULTIPART_FORM_DATA);
+        formHeader.setContentDispositionFormData("image", files.getOriginalFilename());
+        HttpEntity<Resource> formEntity = new HttpEntity<>(files.getResource(), formHeader);
+        map.add("image", formEntity);
+        //http请求头
+        HttpEntity<LinkedMultiValueMap<String, Object>> httpEntity = new HttpEntity<>(map, httpHeaders);
+        Object result;
+        try {
+            result = restTemplate.postForObject(uri, httpEntity, Object.class);
+        } catch (Exception e) {
+            log.error("腾讯上传图片接口调用异常, uri : {}, e : {}", uri, e.getMessage());
+            throw new BaseException("腾讯上传图片接口调用异常!");
+        }
+        return JsonUtil.toString(result);
+    }
+
     @Override
     public List<KfGameVO> getKfGameList() {
         List<GameAuth> gameAuthList = gameAuthService.list(new LambdaQueryWrapper<GameAuth>()
@@ -95,7 +141,6 @@ public class KfMsgContentServiceImpl extends ServiceImpl<KfMsgContentMapper, KfM
 
     @Override
     public String kfApi(KfApiParam param) {
-        log.error("请求参数, param : {}", JsonUtil.toString(param));
         //查询用户授权信息
         KfUser kfUser = kfUserService.getKfUser(SecurityUtil.getUserId(), param.getAppId());
         //请求调用腾讯接口
@@ -114,7 +159,7 @@ public class KfMsgContentServiceImpl extends ServiceImpl<KfMsgContentMapper, KfM
             responseEntity = restTemplate.exchange(URIUtil.fillUrlParams(url, pathParam, Boolean.FALSE),
                     HttpMethod.POST, new HttpEntity<>(param, headers), String.class);
         } catch (Exception e) {
-            log.error("腾讯接口调用异常, e : {}", e.getMessage());
+            log.error("腾讯接口调用异常, url : {}, param : {}, e : {}", url, param, e.getMessage());
             throw new BaseException("腾讯接口调用异常!");
         }
         return responseEntity.getBody();

+ 40 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/KfLink.java

@@ -0,0 +1,40 @@
+package com.zanxiang.game.module.mybatis.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author : lingfeng
+ * @time : 2023-12-06
+ * @description : 客服链接
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+@Builder
+@TableName("t_kf_link")
+public class KfLink {
+
+    /**
+     * 应用id
+     */
+    private String appId;
+
+    /**
+     * 第三方客服链接
+     */
+    private String customLink;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 12 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/mapper/KfLinkMapper.java

@@ -0,0 +1,12 @@
+package com.zanxiang.game.module.mybatis.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zanxiang.game.module.mybatis.entity.KfLink;
+
+/**
+ * @author : lingfeng
+ * @time : 2023-12-06
+ * @description :  ${description}
+ */
+public interface KfLinkMapper extends BaseMapper<KfLink> {
+}

+ 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服务启动成功 <国家属性老数据更新, 日志整理> ( ´・・)ノ(._.`) \n" +
+        System.out.println("赞象SDK服务启动成功 <兼容客服支付, 且发送指定客服消息> ( ´・・)ノ(._.`) \n" +
                 " ___________ _   __\n" +
                 "/  ___|  _  \\ | / /\n" +
                 "\\ `--.| | | | |/ / \n" +

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

@@ -0,0 +1,12 @@
+package com.zanxiang.game.module.sdk.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zanxiang.game.module.mybatis.entity.KfLink;
+
+/**
+ * @author : lingfeng
+ * @time : 2023-12-06
+ * @description : 客服链接
+ */
+public interface IKfLinkService extends IService<KfLink> {
+}

+ 27 - 11
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/GameAppletServiceImpl.java

@@ -6,10 +6,7 @@ import com.zanxiang.game.module.base.pojo.dto.H5GameConfigDTO;
 import com.zanxiang.game.module.base.pojo.enums.HttpStatusEnum;
 import com.zanxiang.game.module.base.pojo.enums.PayDeviceEnum;
 import com.zanxiang.game.module.base.pojo.enums.PayWayEnum;
-import com.zanxiang.game.module.mybatis.entity.Game;
-import com.zanxiang.game.module.mybatis.entity.GameApplet;
-import com.zanxiang.game.module.mybatis.entity.GameExt;
-import com.zanxiang.game.module.mybatis.entity.Order;
+import com.zanxiang.game.module.mybatis.entity.*;
 import com.zanxiang.game.module.mybatis.mapper.GameAppletMapper;
 import com.zanxiang.game.module.sdk.enums.OrderStateEnum;
 import com.zanxiang.game.module.sdk.pojo.dto.*;
@@ -73,6 +70,9 @@ public class GameAppletServiceImpl extends ServiceImpl<GameAppletMapper, GameApp
     @Autowired
     private MiPayService miPayService;
 
+    @Autowired
+    private IKfLinkService kfLinkService;
+
     @Value("${payConfig.wxPay.customH5Url}")
     private String customH5Url;
 
@@ -113,10 +113,16 @@ public class GameAppletServiceImpl extends ServiceImpl<GameAppletMapper, GameApp
         }
         //消息内容
         AppletMsgDTO appletMsgDTO = JsonUtil.toObj(postData, AppletMsgDTO.class);
-        //用户客服支付会话
-        if (Objects.equals(appletMsgDTO.getMsgType(), AppletMsgDTO.MSG_TYPE_TEXT)
-                && Objects.equals(appletMsgDTO.getContent(), AppletMsgDTO.MSG_CONTENT_PAY)) {
-            return this.customPayMessage(gameAppletDTO, appletMsgDTO);
+        //文本消息
+        if (Objects.equals(appletMsgDTO.getMsgType(), AppletMsgDTO.MSG_TYPE_TEXT)) {
+            //用户信息
+            UserDTO userDTO = userService.getUserByOpenId(gameAppletDTO.getGameId(), appletMsgDTO.getFromUserName());
+            //用户客服支付会话
+            if (Objects.equals(appletMsgDTO.getContent(), AppletMsgDTO.MSG_CONTENT_PAY)) {
+                return this.customPayMessage(gameAppletDTO, userDTO);
+            }
+            //非客服会话, 返回指定的客服链接
+            return this.customLinkMessage(gameAppletDTO, userDTO);
         }
         //米大师支付回调事件
         if (Objects.equals(appletMsgDTO.getMsgType(), AppletMsgDTO.MSG_TYPE_EVENT)
@@ -178,9 +184,7 @@ public class GameAppletServiceImpl extends ServiceImpl<GameAppletMapper, GameApp
         return Objects.equals(miPayNotifyResult, Boolean.TRUE) ? successResult : failResult;
     }
 
-    private String customPayMessage(GameAppletDTO gameAppletDTO, AppletMsgDTO appletMsgDTO) {
-        //用户信息
-        UserDTO userDTO = userService.getUserByOpenId(gameAppletDTO.getGameId(), appletMsgDTO.getFromUserName());
+    private String customPayMessage(GameAppletDTO gameAppletDTO, UserDTO userDTO) {
         //查询用户最新客服支付订单
         Order order = orderService.getOne(new LambdaQueryWrapper<Order>()
                 .eq(Order::getUserId, userDTO.getId())
@@ -196,6 +200,18 @@ public class GameAppletServiceImpl extends ServiceImpl<GameAppletMapper, GameApp
         return HttpStatusEnum.SUCCESS.getMsg();
     }
 
+    private String customLinkMessage(GameAppletDTO gameAppletDTO, UserDTO userDTO) {
+        //判断是否配置了第三方客服链接
+        KfLink kfLink = kfLinkService.getById(gameAppletDTO.getAppId());
+        if (kfLink == null || Strings.isBlank(kfLink.getCustomLink())) {
+            return HttpStatusEnum.SUCCESS.getMsg();
+        }
+        //其他消息对象
+        Map<String, Object> textMap = new HashMap<>(1);
+        textMap.put("content", kfLink.getCustomLink());
+        return this.sendCustomMessageApi(gameAppletDTO, userDTO.getOpenId(), "text", textMap);
+    }
+
     private String sendCustomMessage(GameAppletDTO gameAppletDTO, String openId, Order order) {
         //查询订单支付方式
         GamePayWayDTO gamePayWayDTO = gamePayWayService.getById(order.getGamePayWayId());

+ 18 - 0
game-module/game-module-sdk/src/main/java/com/zanxiang/game/module/sdk/service/impl/KfLinkServiceImpl.java

@@ -0,0 +1,18 @@
+package com.zanxiang.game.module.sdk.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zanxiang.game.module.mybatis.entity.KfLink;
+import com.zanxiang.game.module.mybatis.mapper.KfLinkMapper;
+import com.zanxiang.game.module.sdk.service.IKfLinkService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author : lingfeng
+ * @time : 2023-12-06
+ * @description : 客服链接
+ */
+@Slf4j
+@Service
+public class KfLinkServiceImpl extends ServiceImpl<KfLinkMapper, KfLink> implements IKfLinkService {
+}