Explorar el Código

fix : 微信支付延迟到账的问题, 配置初始化修改

bilingfeng hace 1 año
padre
commit
09ab8a0039
Se han modificado 14 ficheros con 442 adiciones y 57 borrados
  1. 1 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/ManageApplication.java
  2. 15 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/enums/KfWebSocketMsgEnum.java
  3. 44 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/enums/OrderStateEnum.java
  4. 52 21
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/dto/KfWebSocketMsgDTO.java
  5. 1 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/KfWebSocketMsgParam.java
  6. 11 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfRoomMsgService.java
  7. 26 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfRoomService.java
  8. 8 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IPayApplicationService.java
  9. 61 3
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfAppletMsgServiceImpl.java
  10. 31 2
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfRoomMsgServiceImpl.java
  11. 106 8
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfRoomServiceImpl.java
  12. 16 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/PayApplicationServiceImpl.java
  13. 60 21
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/websocket/KfMsgWebsocketHandler.java
  14. 10 0
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/KfSessionUser.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服务启动成功 <Websocket图片消息处理44> ( ´・・)ノ(._.`) \n" +
+        System.out.println("赞象Manage服务启动成功 <Websocket图片消息处理55> ( ´・・)ノ(._.`) \n" +
                 "___  ___  ___   _   _   ___  _____  _____ \n" +
                 "|  \\/  | / _ \\ | \\ | | / _ \\|  __ \\|  ___|\n" +
                 "| .  . |/ /_\\ \\|  \\| |/ /_\\ \\ |  \\/| |__  \n" +

+ 15 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/enums/KfWebSocketMsgEnum.java

@@ -62,6 +62,21 @@ public enum KfWebSocketMsgEnum {
      */
     WEBSOCKET_MSG_FINISH_SESSION("WEBSOCKET_MSG_FINISH_SESSION"),
 
+    /**
+     * 获取玩家信息
+     */
+    WEBSOCKET_MSG_GET_USER("WEBSOCKET_MSG_GET_USER"),
+
+    /**
+     * 获取角色列表
+     */
+    WEBSOCKET_MSG_GET_ROLE_LIST("WEBSOCKET_MSG_GET_ROLE_LIST"),
+
+    /**
+     * 获取订单列表
+     */
+    WEBSOCKET_MSG_GET_ORDER_LIST("WEBSOCKET_MSG_GET_ORDER_LIST"),
+
     /**
      * 快捷回复, 接收前端消息,请求动作包含查询, 修改, 删除, 新增
      */

+ 44 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/enums/OrderStateEnum.java

@@ -0,0 +1,44 @@
+package com.zanxiang.game.module.manage.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author : lingfeng
+ * @time : 2022-06-07
+ * @description : 用户状态
+ */
+@Getter
+@AllArgsConstructor
+public enum OrderStateEnum {
+
+    /**
+     * 预下单
+     */
+    READY_PAY(0, "预下单"),
+
+    /**
+     * 待支付
+     */
+    WAIT_PAY(1, "待支付"),
+
+    /**
+     * 支付成功
+     */
+    SUCCESS_PAY(2, "支付成功"),
+
+    /**
+     * 订单关闭
+     */
+    CANCEL_PAY(-1, "订单关闭");
+
+    /**
+     * 状态
+     */
+    private final Integer code;
+
+    /**
+     * 描述
+     */
+    private final String msg;
+}

+ 52 - 21
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/dto/KfWebSocketMsgDTO.java

@@ -8,6 +8,7 @@ import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.List;
 
@@ -74,6 +75,21 @@ public class KfWebSocketMsgDTO {
      */
     private List<RoomMsgBean> roomMsgList;
 
+    /**
+     * 玩家信息
+     */
+    private UserBean user;
+
+    /**
+     * 角色列表
+     */
+    private List<GameRoleBean> roleList;
+
+    /**
+     * 订单列表
+     */
+    private List<OrderBean> orderList;
+
     public KfWebSocketMsgDTO(KfWebSocketMsgEnum webSocketMsgType, Integer errorCode, String errorMsg) {
         this.webSocketMsgType = webSocketMsgType;
         this.kfUserId = SecurityUtil.getUserId();
@@ -125,17 +141,22 @@ public class KfWebSocketMsgDTO {
         /**
          * 充值笔数
          */
-        private Long orderCount;
+        private Integer orderCount;
 
         /**
          * 最大充值金额
          */
-        private Long orderMaxAmount;
+        private BigDecimal orderMaxAmount;
 
         /**
          * 累计充值金额
          */
-        private Long orderAmountSum;
+        private BigDecimal orderAmountSum;
+
+        /**
+         * 最后充值时间
+         */
+        private LocalDateTime lastPayTime;
     }
 
     @Data
@@ -152,12 +173,12 @@ public class KfWebSocketMsgDTO {
         /**
          * 最近角色id
          */
-        private String lastRoleId;
+        private String roleId;
 
         /**
          * 最近角色名称
          */
-        private String lastRoleName;
+        private String roleName;
 
         /**
          * 角色服务器id
@@ -170,19 +191,19 @@ public class KfWebSocketMsgDTO {
         private String serverName;
 
         /**
-         * 充值笔数
+         * 角色等级
          */
-        private Long orderCount;
+        private Long roleLevel;
 
         /**
-         * 最大充值金额
+         * 玩家角色战力
          */
-        private Long orderMaxAmount;
+        private Long rolePower;
 
         /**
-         * 累计充值金额
+         * 角色创建时间
          */
-        private Long orderAmountSum;
+        private LocalDateTime createTime;
     }
 
     @Data
@@ -197,14 +218,19 @@ public class KfWebSocketMsgDTO {
         private Long userId;
 
         /**
-         * 最近角色id
+         * 订单id
          */
-        private String lastRoleId;
+        private String orderId;
 
         /**
-         * 最近角色名称
+         * 角色id
          */
-        private String lastRoleName;
+        private String roleId;
+
+        /**
+         * 角色名称
+         */
+        private String roleName;
 
         /**
          * 角色服务器id
@@ -217,19 +243,24 @@ public class KfWebSocketMsgDTO {
         private String serverName;
 
         /**
-         * 充值笔数
+         * 游戏商品名称
          */
-        private Long orderCount;
+        private String productName;
 
         /**
-         * 最大充值金额
+         * 充值金额
          */
-        private Long orderMaxAmount;
+        private BigDecimal amount;
 
         /**
-         * 累计充值金额
+         * 下单时间
+         */
+        private LocalDateTime createTime;
+
+        /**
+         * 支付时间
          */
-        private Long orderAmountSum;
+        private LocalDateTime payTime;
     }
 
     @Data

+ 1 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/KfWebSocketMsgParam.java

@@ -33,7 +33,7 @@ public class KfWebSocketMsgParam {
     private PageBean page;
 
     /**
-     * 玩家id, 玩家接入的时候必须传
+     * 玩家id, 玩家接入的时候必须传, 查询玩家信息的时候必须传
      */
     private String openId;
 

+ 11 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfRoomMsgService.java

@@ -3,6 +3,7 @@ package com.zanxiang.game.module.manage.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.zanxiang.game.module.manage.pojo.dto.KfWebSocketMsgDTO;
 import com.zanxiang.game.module.manage.pojo.params.KfWebSocketMsgParam;
+import com.zanxiang.game.module.mybatis.entity.KfRoom;
 import com.zanxiang.game.module.mybatis.entity.KfRoomMsg;
 import reactor.util.function.Tuple2;
 
@@ -23,4 +24,14 @@ public interface IKfRoomMsgService extends IService<KfRoomMsg> {
      * @return : 返回分页数据
      */
     Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.RoomMsgBean>> msgRoomHistory(Long roomId, KfWebSocketMsgParam.PageBean pageBean);
+
+    /**
+     * 发送消息保存
+     *
+     * @param gameId     : 游戏id
+     * @param kfRoom     : 房间
+     * @param msgContent : 消息内容
+     * @return : 返回保存结果
+     */
+    boolean sendMsgSave(Long gameId, KfRoom kfRoom, KfWebSocketMsgParam.MsgContentBean msgContent);
 }

+ 26 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfRoomService.java

@@ -63,4 +63,30 @@ public interface IKfRoomService extends IService<KfRoom> {
      * @return : 返回房间信息
      */
     List<KfWebSocketMsgDTO.RoomBean> getRoomByRoomId(Long roomId);
+
+    /**
+     * 获取玩家信息
+     *
+     * @param openId : 玩家openId
+     * @return : 返回玩家信息
+     */
+    KfWebSocketMsgDTO.UserBean getUserBean(String openId);
+
+    /**
+     * 分页获取玩家角色列表
+     *
+     * @param openId   : 玩家openId
+     * @param pageBean : 分页信息
+     * @return : 返回单页数据
+     */
+    Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.GameRoleBean>> getRoleBeanList(String openId, KfWebSocketMsgParam.PageBean pageBean);
+
+    /**
+     * 分页获取玩家订单列表
+     *
+     * @param openId   : 玩家openId
+     * @param pageBean : 分页信息
+     * @return : 返回单页数据
+     */
+    Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.OrderBean>> getOrderBeanList(String openId, KfWebSocketMsgParam.PageBean pageBean);
 }

+ 8 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IPayApplicationService.java

@@ -91,4 +91,12 @@ public interface IPayApplicationService extends IService<PayApplication> {
      * @return {@link PayApplicationDTO}
      */
     PayApplicationDTO getByAppId(String appId);
+
+    /**
+     * 根据支付盒子id获取支付用用
+     *
+     * @param payBoxId : 支付盒子id
+     * @return : 返回支付应用
+     */
+    PayApplicationDTO getPayApplicationByPayBoxId(Long payBoxId);
 }

+ 61 - 3
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfAppletMsgServiceImpl.java

@@ -9,7 +9,9 @@ import com.zanxiang.game.module.manage.enums.KfRoomMsgTypeEnum;
 import com.zanxiang.game.module.manage.enums.KfWebSocketMsgEnum;
 import com.zanxiang.game.module.manage.pojo.dto.KfAppletMsgDTO;
 import com.zanxiang.game.module.manage.pojo.dto.KfWebSocketMsgDTO;
+import com.zanxiang.game.module.manage.pojo.dto.PayApplicationDTO;
 import com.zanxiang.game.module.manage.service.*;
+import com.zanxiang.game.module.manage.service.api.KfWxApiService;
 import com.zanxiang.game.module.manage.utils.FileUtil;
 import com.zanxiang.game.module.mybatis.entity.*;
 import com.zanxiang.module.oss.service.IOssService;
@@ -17,17 +19,19 @@ import com.zanxiang.module.util.JsonUtil;
 import com.zanxiang.module.util.bean.BeanUtil;
 import com.zanxiang.module.util.exception.BaseException;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.logging.log4j.util.Strings;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.util.UriComponentsBuilder;
 
 import java.io.IOException;
+import java.math.BigDecimal;
+import java.net.URI;
 import java.time.LocalDateTime;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 
 /**
  * @author : lingfeng
@@ -41,6 +45,21 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
     @Value("${media.realm-name}")
     private String realmName;
 
+    @Value("${payConfig.wxPay.customH5Url}")
+    private String customH5Url;
+
+    @Autowired
+    private KfWxApiService kfWxApiService;
+
+    @Autowired
+    private IOrderService orderService;
+
+    @Autowired
+    private IGamePayWayService gamePayWayService;
+
+    @Autowired
+    private IPayApplicationService payApplicationService;
+
     @Autowired
     private IOssService ossService;
 
@@ -154,6 +173,8 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
                 .set(KfSessionUser::getUserId, user == null ? null : user.getId())
                 .set(KfSessionUser::getLastRoleId, gameUserRole == null ? "0" : gameUserRole.getRoleId())
                 .set(KfSessionUser::getLastRoleName, gameUserRole == null ? kfAppletMsgDTO.getFromUserName() : gameUserRole.getRoleName())
+                .set(gameUserRole != null, KfSessionUser::getServerId, gameUserRole == null ? null : gameUserRole.getServerId())
+                .set(gameUserRole != null, KfSessionUser::getServerName, gameUserRole == null ? null : gameUserRole.getServerName())
                 .set(KfSessionUser::getUpdateTime, LocalDateTime.now())
                 .eq(KfSessionUser::getOpenId, kfAppletMsgDTO.getFromUserName()));
     }
@@ -166,6 +187,8 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
                 .isWait(Boolean.FALSE)
                 .lastRoleId(gameUserRole == null ? "0" : gameUserRole.getRoleId())
                 .lastRoleName(gameUserRole == null ? kfAppletMsgDTO.getFromUserName() : gameUserRole.getRoleName())
+                .serverId(gameUserRole == null ? null : gameUserRole.getServerId())
+                .serverName(gameUserRole == null ? null : gameUserRole.getServerName())
                 .createTime(LocalDateTime.now())
                 .updateTime(LocalDateTime.now())
                 .build();
@@ -215,6 +238,41 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
         return this.realmName + "image/" + fileName;
     }
 
+    private void sendSystemMessage(Long gameId, String openId, Order order) {
+        //查询订单支付方式
+        GamePayWay gamePayWay = gamePayWayService.getById(order.getGamePayWayId());
+        //查询支付应用信息
+        PayApplicationDTO payApplicationDTO = payApplicationService.getPayApplicationByPayBoxId(gamePayWay.getPayBoxId());
+        //客服支付链接显示图片地址
+        String thumbUrl = gamePayWay.getThumbUrl();
+        //支付配置参数判断
+        if (Strings.isBlank(thumbUrl)) {
+            log.error("客服消息卡片图片地址不存在, gamePayWayDTO : {}", JsonUtil.toString(gamePayWay));
+            return;
+        }
+        //订单金额
+        BigDecimal amount = order.getAmount();
+        //构造跳转链接url
+        URI url = UriComponentsBuilder.fromHttpUrl(this.customH5Url)
+                .queryParam("appId", payApplicationDTO.getAppId())
+                .queryParam("orderId", order.getOrderId())
+                .queryParam("amount", amount)
+                .queryParam("description", "购买" + amount + "元档充值")
+                .build().toUri();
+        //link参数构造
+        Map<String, Object> linkMap = new HashMap<>(4);
+        linkMap.put("title", "点我充值");
+        linkMap.put("description", "点我充值" + amount + "元,用于购买" + amount + "元档充值");
+        linkMap.put("url", url);
+        linkMap.put("thumb_url", thumbUrl);
+        //发送客服消息
+        Map<String, Object> msgParamMap = new HashMap<>(3);
+        msgParamMap.put("touser", openId);
+        msgParamMap.put("msgtype", KfRoomMsgTypeEnum.KF_MSG_TYPE_LINK.getValue());
+        msgParamMap.put(KfRoomMsgTypeEnum.KF_MSG_TYPE_LINK.getValue(), linkMap);
+        kfWxApiService.sendCustomMessageApi(gameId, msgParamMap);
+    }
+
     /**
      * 消息发送到redis广播
      */

+ 31 - 2
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfRoomMsgServiceImpl.java

@@ -4,23 +4,33 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zanxiang.game.module.base.pojo.enums.HttpStatusEnum;
+import com.zanxiang.game.module.manage.enums.KfRoomMsgOwnerEnum;
 import com.zanxiang.game.module.manage.enums.KfRoomMsgTypeEnum;
+import com.zanxiang.game.module.manage.pojo.dto.GameAppletDTO;
+import com.zanxiang.game.module.manage.pojo.dto.GamePayWayDTO;
 import com.zanxiang.game.module.manage.pojo.dto.KfWebSocketMsgDTO;
+import com.zanxiang.game.module.manage.pojo.dto.PayApplicationDTO;
 import com.zanxiang.game.module.manage.pojo.params.KfWebSocketMsgParam;
 import com.zanxiang.game.module.manage.service.IKfRoomMsgService;
+import com.zanxiang.game.module.mybatis.entity.KfRoom;
 import com.zanxiang.game.module.mybatis.entity.KfRoomMsg;
+import com.zanxiang.game.module.mybatis.entity.Order;
 import com.zanxiang.game.module.mybatis.mapper.KfRoomMsgMapper;
 import com.zanxiang.module.util.JsonUtil;
 import com.zanxiang.module.util.bean.BeanUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.logging.log4j.util.Strings;
 import org.springframework.stereotype.Service;
+import org.springframework.web.util.UriComponentsBuilder;
 import reactor.util.function.Tuple2;
 import reactor.util.function.Tuples;
 
+import java.math.BigDecimal;
+import java.net.URI;
 import java.time.LocalDateTime;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -75,4 +85,23 @@ public class KfRoomMsgServiceImpl extends ServiceImpl<KfRoomMsgMapper, KfRoomMsg
                 .total(kfRoomMsgPage.getTotal())
                 .build();
     }
+
+    @Override
+    public boolean sendMsgSave(Long gameId, KfRoom kfRoom, KfWebSocketMsgParam.MsgContentBean msgContent) {
+        return super.save(KfRoomMsg.builder()
+                .msgId(UUID.randomUUID().toString().replace("-", ""))
+                .msgType(msgContent.getMsgType().getValue())
+                .gameId(gameId)
+                .openId(kfRoom.getOpenId())
+                .userId(kfRoom.getUserId())
+                .kfUserId(kfRoom.getKfUserId())
+                .readStatus(Boolean.TRUE)
+                .roomId(kfRoom.getId())
+                .msgOwner(KfRoomMsgOwnerEnum.KF_MSG_OWNER_KF.getValue())
+                .content(JsonUtil.toString(BeanUtil.copy(msgContent, KfWebSocketMsgDTO.MsgContentBean.class)))
+                .source(JsonUtil.toString(msgContent))
+                .createTime(LocalDateTime.now())
+                .updateTime(LocalDateTime.now())
+                .build());
+    }
 }

+ 106 - 8
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfRoomServiceImpl.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.zanxiang.erp.security.util.SecurityUtil;
 import com.zanxiang.game.module.manage.enums.KfRoomMsgTypeEnum;
+import com.zanxiang.game.module.manage.enums.OrderStateEnum;
 import com.zanxiang.game.module.manage.pojo.dto.KfWebSocketMsgDTO;
 import com.zanxiang.game.module.manage.pojo.params.KfWebSocketMsgParam;
 import com.zanxiang.game.module.manage.service.*;
@@ -21,10 +22,9 @@ import org.springframework.stereotype.Service;
 import reactor.util.function.Tuple2;
 import reactor.util.function.Tuples;
 
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -48,9 +48,15 @@ public class KfRoomServiceImpl extends ServiceImpl<KfRoomMapper, KfRoom> impleme
     @Autowired
     private IUserService userService;
 
+    @Autowired
+    private IOrderService orderService;
+
     @Autowired
     private IKfSessionUserService kfSessionUserService;
 
+    @Autowired
+    private IGameUserRoleService gameUserRoleService;
+
     @Override
     public Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.RoomBean>> getFinishRoomList(Long gameId, KfWebSocketMsgParam.PageBean pageBean) {
         Page<KfRoom> kfRoomPage = super.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()),
@@ -64,12 +70,12 @@ public class KfRoomServiceImpl extends ServiceImpl<KfRoomMapper, KfRoom> impleme
         return Tuples.of(this.transform(kfRoomPage), roomBeanList);
     }
 
-    private KfWebSocketMsgDTO.PageBean transform(Page<KfRoom> kfRoomPage) {
+    private KfWebSocketMsgDTO.PageBean transform(Page<?> pageBean) {
         return KfWebSocketMsgDTO.PageBean.builder()
-                .pageNum(kfRoomPage.getCurrent())
-                .pageSize(kfRoomPage.getSize())
-                .pageTotal(kfRoomPage.getPages())
-                .total(kfRoomPage.getTotal())
+                .pageNum(pageBean.getCurrent())
+                .pageSize(pageBean.getSize())
+                .pageTotal(pageBean.getPages())
+                .total(pageBean.getTotal())
                 .build();
     }
 
@@ -198,4 +204,96 @@ public class KfRoomServiceImpl extends ServiceImpl<KfRoomMapper, KfRoom> impleme
         }
         return roomBean;
     }
+
+    @Override
+    public KfWebSocketMsgDTO.UserBean getUserBean(String openId) {
+        KfSessionUser kfSessionUser = kfSessionUserService.getById(openId);
+        KfWebSocketMsgDTO.UserBean userBean = BeanUtil.copy(kfSessionUser, KfWebSocketMsgDTO.UserBean.class);
+        if (userBean == null || userBean.getUserId() == null) {
+            return userBean;
+        }
+        //查询订单
+        List<Order> orderList = orderService.list(new LambdaQueryWrapper<Order>()
+                .select(Order::getOrderId, Order::getAmount, Order::getPayTime)
+                .eq(Order::getUserId, userBean.getUserId())
+                .eq(kfSessionUser.getGameId() != null, Order::getGameId, kfSessionUser.getGameId())
+                .eq(Order::getStatus, OrderStateEnum.SUCCESS_PAY.getCode()));
+        //设置参数
+        if (CollectionUtils.isNotEmpty(orderList)) {
+            //订单数
+            userBean.setOrderCount(orderList.size());
+            //最大订单金额
+            Optional<Order> maxAmountOrder = orderList.stream()
+                    .max(Comparator.comparing(Order::getAmount));
+            userBean.setOrderMaxAmount(maxAmountOrder.map(Order::getAmount).orElse(null));
+            //最近支付时间
+            Optional<Order> lastPayTimeOrder = orderList.stream()
+                    .max(Comparator.comparing(Order::getPayTime));
+            userBean.setLastPayTime(lastPayTimeOrder.map(Order::getPayTime).orElse(null));
+            //支付总金额
+            BigDecimal totalAmount = orderList.stream()
+                    .map(Order::getAmount)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+            userBean.setOrderAmountSum(totalAmount);
+        }
+        return userBean;
+    }
+
+    @Override
+    public Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.GameRoleBean>> getRoleBeanList(String openId, KfWebSocketMsgParam.PageBean pageBean) {
+        KfSessionUser kfSessionUser = kfSessionUserService.getById(openId);
+        if (kfSessionUser == null || kfSessionUser.getUserId() == null) {
+            return Tuples.of(this.transform(pageBean), Collections.emptyList());
+        }
+        Page<GameUserRole> gameUserRolePage = gameUserRoleService.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()),
+                new QueryWrapper<GameUserRole>().lambda()
+                        .eq(GameUserRole::getUserId, kfSessionUser.getUserId())
+                        .orderByDesc(GameUserRole::getCreateTime)
+        );
+        //构造角色列表
+        List<KfWebSocketMsgDTO.GameRoleBean> gameRoleList = gameUserRolePage.getRecords().stream()
+                .map(this::transform).collect(Collectors.toList());
+        return Tuples.of(this.transform(gameUserRolePage), gameRoleList);
+    }
+
+    private KfWebSocketMsgDTO.GameRoleBean transform(GameUserRole gameUserRole) {
+        if (gameUserRole == null) {
+            return null;
+        }
+        return BeanUtil.copy(gameUserRole, KfWebSocketMsgDTO.GameRoleBean.class);
+    }
+
+    @Override
+    public Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.OrderBean>> getOrderBeanList(String openId, KfWebSocketMsgParam.PageBean pageBean) {
+        KfSessionUser kfSessionUser = kfSessionUserService.getById(openId);
+        if (kfSessionUser == null || kfSessionUser.getUserId() == null) {
+            return Tuples.of(this.transform(pageBean), Collections.emptyList());
+        }
+        Page<Order> orderPage = orderService.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()),
+                new QueryWrapper<Order>().lambda()
+                        .eq(Order::getUserId, kfSessionUser.getUserId())
+                        .orderByDesc(Order::getCreateTime)
+        );
+        //构造订单列表
+        List<KfWebSocketMsgDTO.OrderBean> orderList = orderPage.getRecords().stream()
+                .map(this::transform).collect(Collectors.toList());
+        return Tuples.of(this.transform(orderPage), orderList);
+    }
+
+    private KfWebSocketMsgDTO.OrderBean transform(Order order) {
+        if (order == null) {
+            return null;
+        }
+        return BeanUtil.copy(order, KfWebSocketMsgDTO.OrderBean.class);
+    }
+
+    private KfWebSocketMsgDTO.PageBean transform(KfWebSocketMsgParam.PageBean pageBean) {
+        return KfWebSocketMsgDTO.PageBean.builder()
+                .pageNum(pageBean.getPageNum())
+                .pageSize(pageBean.getPageSize())
+                .pageTotal(0L)
+                .total(0L)
+                .build();
+    }
+
 }

+ 16 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/PayApplicationServiceImpl.java

@@ -14,7 +14,9 @@ import com.zanxiang.game.module.manage.pojo.vo.PayApplicationChoiceVO;
 import com.zanxiang.game.module.manage.pojo.vo.PayApplicationVO;
 import com.zanxiang.game.module.manage.service.IGameAppletService;
 import com.zanxiang.game.module.manage.service.IPayApplicationService;
+import com.zanxiang.game.module.manage.service.IPayBoxService;
 import com.zanxiang.game.module.mybatis.entity.PayApplication;
+import com.zanxiang.game.module.mybatis.entity.PayBox;
 import com.zanxiang.game.module.mybatis.mapper.PayApplicationMapper;
 import com.zanxiang.module.util.bean.BeanUtil;
 import com.zanxiang.module.util.exception.BaseException;
@@ -43,6 +45,9 @@ public class PayApplicationServiceImpl extends ServiceImpl<PayApplicationMapper,
     @Autowired
     private IGameAppletService gameAppletService;
 
+    @Autowired
+    private IPayBoxService payBoxService;
+
     @Override
     public List<PayApplicationChoiceVO> payApplicationChoiceList() {
         List<PayApplication> payApplicationList = super.list(new LambdaQueryWrapper<PayApplication>()
@@ -203,4 +208,15 @@ public class PayApplicationServiceImpl extends ServiceImpl<PayApplicationMapper,
         }
         return BeanUtil.copy(payApplication, PayApplicationDTO.class);
     }
+
+    @Override
+    public PayApplicationDTO getPayApplicationByPayBoxId(Long payBoxId) {
+        PayBox payBox = payBoxService.getById(payBoxId);
+        PayApplication payApplication = super.getOne(new LambdaQueryWrapper<PayApplication>()
+                .eq(PayApplication::getAppId, payBox.getAppId()));
+        if (payApplication == null) {
+            throw new BaseException("参数错误, 支付商城小程序信息不存在");
+        }
+        return BeanUtil.copy(payApplication, PayApplicationDTO.class);
+    }
 }

+ 60 - 21
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/websocket/KfMsgWebsocketHandler.java

@@ -19,7 +19,6 @@ import com.zanxiang.game.module.mybatis.entity.KfRoomMsg;
 import com.zanxiang.game.module.mybatis.entity.KfSessionUser;
 import com.zanxiang.module.redis.service.IDistributedLockComponent;
 import com.zanxiang.module.util.JsonUtil;
-import com.zanxiang.module.util.bean.BeanUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.logging.log4j.util.Strings;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -30,7 +29,10 @@ import reactor.util.function.Tuple2;
 
 import java.io.IOException;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -122,6 +124,18 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
                 log.error("结束会话, kfUserId : {}, param : {}", SecurityUtil.getUserId(), JsonUtil.toString(param));
                 kfFinishSession(session, webSocketMsgType, gameId, param.getRoomId());
                 break;
+            case WEBSOCKET_MSG_GET_USER:
+                log.error("获取玩家信息, kfUserId : {}, openId : {}", SecurityUtil.getUserId(), param.getOpenId());
+                getUser(session, param);
+                break;
+            case WEBSOCKET_MSG_GET_ROLE_LIST:
+                log.error("获取玩家角色列表, kfUserId : {}, openId : {}", SecurityUtil.getUserId(), param.getOpenId());
+                getRoleList(session, param);
+                break;
+            case WEBSOCKET_MSG_GET_ORDER_LIST:
+                log.error("获取玩家订单列表, kfUserId : {}, openId : {}", SecurityUtil.getUserId(), param.getOpenId());
+                getOrderList(session, param);
+                break;
             case WEBSOCKET_MSG_QUICK_REPLY:
                 // 快捷回复,可以添加对应的处理逻辑
                 break;
@@ -160,6 +174,49 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
         return false;
     }
 
+    private void getUser(WebSocketSession session, KfWebSocketMsgParam param) {
+        if (Strings.isBlank(param.getOpenId())) {
+            this.sendMessage(session, KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
+                    "获取玩家信息参数错误, openId不可为空, param : " + JsonUtil.toString(param)));
+        }
+        KfWebSocketMsgDTO.UserBean userBean = kfRoomService.getUserBean(param.getOpenId());
+        this.sendMessage(session, KfWebSocketMsgDTO.builder()
+                .webSocketMsgType(param.getWebSocketMsgType())
+                .kfUserId(SecurityUtil.getUserId())
+                .user(userBean)
+                .build());
+    }
+
+    private void getRoleList(WebSocketSession session, KfWebSocketMsgParam param) {
+        if (Strings.isBlank(param.getOpenId())) {
+            this.sendMessage(session, KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
+                    "获取玩家角色列表参数错误, openId不可为空, param : " + JsonUtil.toString(param)));
+        }
+        Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.GameRoleBean>> tuple2 = kfRoomService
+                .getRoleBeanList(param.getOpenId(), param.getPage());
+        this.sendMessage(session, KfWebSocketMsgDTO.builder()
+                .webSocketMsgType(param.getWebSocketMsgType())
+                .kfUserId(SecurityUtil.getUserId())
+                .page(tuple2.getT1())
+                .roleList(tuple2.getT2())
+                .build());
+    }
+
+    private void getOrderList(WebSocketSession session, KfWebSocketMsgParam param) {
+        if (Strings.isBlank(param.getOpenId())) {
+            this.sendMessage(session, KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
+                    "获取玩家订单列表参数错误, openId不可为空, param : " + JsonUtil.toString(param)));
+        }
+        Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.OrderBean>> tuple2 = kfRoomService
+                .getOrderBeanList(param.getOpenId(), param.getPage());
+        this.sendMessage(session, KfWebSocketMsgDTO.builder()
+                .webSocketMsgType(param.getWebSocketMsgType())
+                .kfUserId(SecurityUtil.getUserId())
+                .page(tuple2.getT1())
+                .orderList(tuple2.getT2())
+                .build());
+    }
+
     private void kfSendMsg(WebSocketSession session, KfWebSocketMsgParam param) {
         if (param.getRoomId() == null) {
             this.sendMessage(session, KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(), "参数错误,roomId为空"));
@@ -208,28 +265,10 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
             return;
         }
         //发送成功, 消息入库
-        kfRoomMsgService.save(this.transform(param.getGameId(), kfRoom, msgContent));
+        kfRoomMsgService.sendMsgSave(param.getGameId(), kfRoom, msgContent);
         this.sendMessage(session, KfWebSocketMsgDTO.ok(param.getWebSocketMsgType()));
     }
 
-    private KfRoomMsg transform(Long gameId, KfRoom kfRoom, KfWebSocketMsgParam.MsgContentBean msgContent) {
-        return KfRoomMsg.builder()
-                .msgId(UUID.randomUUID().toString().replace("-", ""))
-                .msgType(msgContent.getMsgType().getValue())
-                .gameId(gameId)
-                .openId(kfRoom.getOpenId())
-                .userId(kfRoom.getUserId())
-                .kfUserId(kfRoom.getKfUserId())
-                .readStatus(Boolean.TRUE)
-                .roomId(kfRoom.getId())
-                .msgOwner(KfRoomMsgOwnerEnum.KF_MSG_OWNER_KF.getValue())
-                .content(JsonUtil.toString(BeanUtil.copy(msgContent, KfWebSocketMsgDTO.MsgContentBean.class)))
-                .source(JsonUtil.toString(msgContent))
-                .createTime(LocalDateTime.now())
-                .updateTime(LocalDateTime.now())
-                .build();
-    }
-
     private void kfFinishSession(WebSocketSession session, KfWebSocketMsgEnum webSocketMsgType, Long gameId, Long roomId) {
         //房间在线状态更新
         kfRoomService.update(new LambdaUpdateWrapper<KfRoom>()

+ 10 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/KfSessionUser.java

@@ -58,6 +58,16 @@ public class KfSessionUser {
      */
     private String lastRoleName;
 
+    /**
+     * 游戏服务器id,默认为0
+     */
+    private String serverId;
+
+    /**
+     * 所在服务器名称
+     */
+    private String serverName;
+
     /**
      * 创建时间
      */