Преглед изворни кода

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

Letianhua пре 1 година
родитељ
комит
6655f024c6

+ 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" +

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

+ 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);
+
     /**
      * 获取游戏列表
      *

+ 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 {
+}