Bladeren bron

fix : 消息处理逻辑提交

bilingfeng 1 jaar geleden
bovenliggende
commit
6ed6087cde
12 gewijzigde bestanden met toevoegingen van 409 en 84 verwijderingen
  1. 1 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/enums/KfWebSocketMsgEnum.java
  2. 160 9
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/dto/KfWebSocketMsgDTO.java
  3. 2 2
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/KfWebSocketMsgParam.java
  4. 14 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfRoomMsgService.java
  5. 15 3
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfRoomService.java
  6. 2 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfSessionUserService.java
  7. 4 2
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/CpCallServiceImpl.java
  8. 16 6
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfAppletMsgServiceImpl.java
  9. 34 3
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfRoomMsgServiceImpl.java
  10. 42 14
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfRoomServiceImpl.java
  11. 2 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfSessionUserServiceImpl.java
  12. 117 42
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/websocket/KfMsgWebsocketHandler.java

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

@@ -43,7 +43,7 @@ public enum KfWebSocketMsgEnum {
     WEBSOCKET_MSG_KF_SEND("WEBSOCKET_MSG_KF_SEND"),
 
     /**
-     * 房间消息, 推送玩家消息
+     * 房间消息, 主动推送玩家消息
      */
     WEBSOCKET_MSG_ROOM_MSG("WEBSOCKET_MSG_ROOM_MSG"),
 

+ 160 - 9
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/dto/KfWebSocketMsgDTO.java

@@ -73,16 +73,162 @@ public class KfWebSocketMsgDTO {
      */
     private List<RoomMsgBean> roomMsgList;
 
-    public KfWebSocketMsgDTO(KfWebSocketMsgEnum webSocketMsgType, String errorMsg) {
+    public KfWebSocketMsgDTO(KfWebSocketMsgEnum webSocketMsgType, Integer errorCode, String errorMsg, Long kfUserId) {
         this.webSocketMsgType = webSocketMsgType;
+        this.kfUserId = kfUserId;
         this.result = ResultBean.builder()
-                .errorCode(500)
+                .errorCode(errorCode)
                 .errorMsg(errorMsg)
                 .build();
     }
 
-    public static KfWebSocketMsgDTO fail(KfWebSocketMsgEnum webSocketMsgType, String errorMsg) {
-        return new KfWebSocketMsgDTO(webSocketMsgType, errorMsg);
+    public static KfWebSocketMsgDTO ok(Long kfUserId, KfWebSocketMsgEnum webSocketMsgType) {
+        return new KfWebSocketMsgDTO(webSocketMsgType, 0, "success", kfUserId);
+    }
+
+    public static KfWebSocketMsgDTO fail(Long kfUserId, KfWebSocketMsgEnum webSocketMsgType, String errorMsg) {
+        return new KfWebSocketMsgDTO(webSocketMsgType, 400, errorMsg, kfUserId);
+    }
+
+    @Data
+    @Builder
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class UserBean {
+
+        /**
+         * 玩家id
+         */
+        private Long userId;
+
+        /**
+         * 最近角色id
+         */
+        private String lastRoleId;
+
+        /**
+         * 最近角色名称
+         */
+        private String lastRoleName;
+
+        /**
+         * 角色服务器id
+         */
+        private String serverId;
+
+        /**
+         * 角色服务器名称
+         */
+        private String serverName;
+
+        /**
+         * 充值笔数
+         */
+        private Long orderCount;
+
+        /**
+         * 最大充值金额
+         */
+        private Long orderMaxAmount;
+
+        /**
+         * 累计充值金额
+         */
+        private Long orderAmountSum;
+    }
+
+    @Data
+    @Builder
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class GameRoleBean {
+
+        /**
+         * 玩家id
+         */
+        private Long userId;
+
+        /**
+         * 最近角色id
+         */
+        private String lastRoleId;
+
+        /**
+         * 最近角色名称
+         */
+        private String lastRoleName;
+
+        /**
+         * 角色服务器id
+         */
+        private String serverId;
+
+        /**
+         * 角色服务器名称
+         */
+        private String serverName;
+
+        /**
+         * 充值笔数
+         */
+        private Long orderCount;
+
+        /**
+         * 最大充值金额
+         */
+        private Long orderMaxAmount;
+
+        /**
+         * 累计充值金额
+         */
+        private Long orderAmountSum;
+    }
+
+    @Data
+    @Builder
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class OrderBean {
+
+        /**
+         * 玩家id
+         */
+        private Long userId;
+
+        /**
+         * 最近角色id
+         */
+        private String lastRoleId;
+
+        /**
+         * 最近角色名称
+         */
+        private String lastRoleName;
+
+        /**
+         * 角色服务器id
+         */
+        private String serverId;
+
+        /**
+         * 角色服务器名称
+         */
+        private String serverName;
+
+        /**
+         * 充值笔数
+         */
+        private Long orderCount;
+
+        /**
+         * 最大充值金额
+         */
+        private Long orderMaxAmount;
+
+        /**
+         * 累计充值金额
+         */
+        private Long orderAmountSum;
     }
 
     @Data
@@ -215,6 +361,11 @@ public class KfWebSocketMsgDTO {
          */
         private String msgId;
 
+        /**
+         * 消息类型
+         */
+        private KfRoomMsgTypeEnum msgType;
+
         /**
          * 消息游戏id
          */
@@ -225,11 +376,6 @@ public class KfWebSocketMsgDTO {
          */
         private Long roomId;
 
-        /**
-         * 消息类型
-         */
-        private KfRoomMsgTypeEnum msgType;
-
         /**
          * 已读状态
          */
@@ -326,6 +472,11 @@ public class KfWebSocketMsgDTO {
          * 总页数
          */
         private Long pageTotal;
+
+        /**
+         * 数据总量
+         */
+        private Long total;
     }
 
     @Data

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

@@ -71,11 +71,11 @@ public class KfWebSocketMsgParam {
         /**
          * 当前页数
          */
-        private Long pageNum;
+        private Long pageNum = 1L;
 
         /**
          * 单页数量
          */
-        private Long pageSize;
+        private Long pageSize = 10L;
     }
 }

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

@@ -1,7 +1,12 @@
 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.KfRoomMsg;
+import reactor.util.function.Tuple2;
+
+import java.util.List;
 
 /**
  * @author : lingfeng
@@ -9,4 +14,13 @@ import com.zanxiang.game.module.mybatis.entity.KfRoomMsg;
  * @description : 客服房间消息
  */
 public interface IKfRoomMsgService extends IService<KfRoomMsg> {
+
+    /**
+     * 分页获取房间历史消息
+     *
+     * @param roomId   : 房间id
+     * @param pageBean : 分页条件
+     * @return : 返回分页数据
+     */
+    Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.RoomMsgBean>> msgRoomHistory(Long roomId, KfWebSocketMsgParam.PageBean pageBean);
 }

+ 15 - 3
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfRoomService.java

@@ -2,7 +2,9 @@ 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 reactor.util.function.Tuple2;
 
 import java.util.List;
 
@@ -13,14 +15,23 @@ import java.util.List;
  */
 public interface IKfRoomService extends IService<KfRoom> {
 
+    /**
+     * 分页获取已结束房间列表
+     *
+     * @param gameId   : 游戏id
+     * @param pageBean : 分页信息
+     * @return : 返回分页数据
+     */
+    Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.RoomBean>> getFinishRoomList(Long gameId, KfWebSocketMsgParam.PageBean pageBean);
+
     /**
      * 玩家加入房间
      *
      * @param openId : 玩家openId
      * @param gameId : 游戏id
-     * @return : 返回更新结果
+     * @return : 返回关联房间id
      */
-    boolean userJoinRoom(String openId, Long gameId);
+    Long userJoinRoom(String openId, Long gameId);
 
     /**
      * 客服获取游戏列表
@@ -32,7 +43,8 @@ public interface IKfRoomService extends IService<KfRoom> {
     /**
      * 待接入房间列表
      *
+     * @param gameId : 游戏id
      * @return : 返回待接入房间列表
      */
-    List<KfWebSocketMsgDTO.RoomBean> getOnlineRoomList();
+    List<KfWebSocketMsgDTO.RoomBean> getOnlineRoomList(Long gameId);
 }

+ 2 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfSessionUserService.java

@@ -16,7 +16,8 @@ public interface IKfSessionUserService extends IService<KfSessionUser> {
     /**
      * 获取待接入列表
      *
+     * @param gameId : 游戏id
      * @return : 返回待接入列表
      */
-    List<KfWebSocketMsgDTO.WaitUserBean> getWaitUserList();
+    List<KfWebSocketMsgDTO.WaitUserBean> getWaitUserList(Long gameId);
 }

+ 4 - 2
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/CpCallServiceImpl.java

@@ -1,6 +1,5 @@
 package com.zanxiang.game.module.manage.service.impl;
 
-import com.zanxiang.game.module.manage.pojo.params.KfWebSocketMsgParam;
 import com.zanxiang.module.util.JsonUtil;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
@@ -63,15 +62,18 @@ public class CpCallServiceImpl {
 
         param.put("pushType", 1);
 
-        String text = "111尊敬的尊享玩家“角色名”:\n" +
+        String text = "尊敬的尊享玩家“角色名”:\n" +
                 "叮,尊享管家小诗正在微信上等待与您的见面,根据您的游戏角色成长,小诗特意为您定制一份战力快速升级的攻略和几个尊享限定礼包,助您快速提升~\n" +
                 "您要尽快通过游戏内“联系客服”按钮与我联系,时间有限,请您尽快与我联系哦。\n" +
                 "联系时请您带上此页面截图,同时请您保密勿将此内容分享给其他玩家,可能会导致尊享限定礼包被冒领哦!";
         Map<String, Object> msgContent = new HashMap<>();
         msgContent.put("text", text);
+
         List<String> imgs = new ArrayList<>();
+        //图片地址弄一张最小的, CP方不会用, 有默认底图
         imgs.add("https://test.84game.cn/1709024863.jpeg");
         msgContent.put("imgs", JsonUtil.toString(imgs));
+
         param.put("msgContent", msgContent);
 
         System.out.println("接口参数 param :" + JsonUtil.toString(param));

+ 16 - 6
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfAppletMsgServiceImpl.java

@@ -56,6 +56,10 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
         KfAppletMsgDTO kfAppletMsgDTO = JsonUtil.toObj(postData, KfAppletMsgDTO.class);
         GameApplet gameApplet = gameAppletService.getOne(new LambdaQueryWrapper<GameApplet>()
                 .eq(GameApplet::getGhId, kfAppletMsgDTO.getToUserName()));
+        //小游戏信息不存在, 消息不处理
+        if (gameApplet == null) {
+            return;
+        }
         //用户进入会话事件
         if (Objects.equals(kfAppletMsgDTO.getMsgType(), KfAppletMsgDTO.MSG_TYPE_EVENT)
                 && Objects.equals(kfAppletMsgDTO.getEvent(), KfAppletMsgDTO.EVENT_USER_ENTER_TEMP_SESSION)) {
@@ -74,6 +78,7 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
         //查询玩家的房间连接状态
         KfRoom kfRoom = kfRoomService.getOne(new LambdaQueryWrapper<KfRoom>()
                 .eq(KfRoom::getOpenId, kfAppletMsgDTO.getFromUserName())
+                .eq(KfRoom::getGameId, gameApplet.getGameId())
                 .eq(KfRoom::getOnline, Boolean.TRUE));
         //消息存储
         KfWebSocketMsgDTO.MsgContentBean msgContent = this.getMsgContent(kfAppletMsgDTO);
@@ -88,17 +93,22 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
                     .eq(KfSessionUser::getOpenId, kfAppletMsgDTO.getFromUserName()));
         }
         //消息转发到redis频道
-        kfMsgWebsocketHandler.pushMessage(this.transform(kfRoomMsg, msgContent));
+        kfMsgWebsocketHandler.pushMessage(this.transform(kfRoom, gameApplet.getGameId(), kfRoomMsg, msgContent));
     }
 
-    private KfWebSocketMsgDTO transform(KfRoomMsg kfRoomMsg, KfWebSocketMsgDTO.MsgContentBean msgContent) {
-        //todo : 需要修改
+    private KfWebSocketMsgDTO transform(KfRoom kfRoom, Long gameId, KfRoomMsg kfRoomMsg, KfWebSocketMsgDTO.MsgContentBean msgContent) {
+        //消息对象
         KfWebSocketMsgDTO.RoomMsgBean roomMsgBean = BeanUtil.copy(kfRoomMsg, KfWebSocketMsgDTO.RoomMsgBean.class);
         roomMsgBean.setContent(msgContent);
-        KfWebSocketMsgEnum kfWebSocketMsgEnum = roomMsgBean.getRoomId() == null ?
-                KfWebSocketMsgEnum.WEBSOCKET_MSG_WAIT_LIST : KfWebSocketMsgEnum.WEBSOCKET_MSG_ROOM_MSG;
+        //
+
+
+
         return KfWebSocketMsgDTO.builder()
-                .webSocketMsgType(kfWebSocketMsgEnum)
+                .webSocketMsgType(kfRoom == null ? KfWebSocketMsgEnum.WEBSOCKET_MSG_WAIT_LIST : KfWebSocketMsgEnum.WEBSOCKET_MSG_ROOM_MSG)
+                .kfUserId(kfRoom == null ? null : kfRoom.getKfUserId())
+                .gameId(gameId)
+                .roomId(kfRoom == null ? null : kfRoom.getId())
                 .roomMsgList(Collections.singletonList(roomMsgBean))
                 .build();
     }

+ 34 - 3
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfRoomMsgServiceImpl.java

@@ -1,14 +1,21 @@
 package com.zanxiang.game.module.manage.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 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.IKfRoomMsgService;
 import com.zanxiang.game.module.mybatis.entity.KfRoomMsg;
 import com.zanxiang.game.module.mybatis.mapper.KfRoomMsgMapper;
+import com.zanxiang.module.util.bean.BeanUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import reactor.util.function.Tuple2;
+import reactor.util.function.Tuples;
+
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * @author : lingfeng
@@ -19,7 +26,31 @@ import reactor.util.function.Tuple2;
 @Service
 public class KfRoomMsgServiceImpl extends ServiceImpl<KfRoomMsgMapper, KfRoomMsg> implements IKfRoomMsgService {
 
-//    public Tuple2<> msgRoomHistory(Long roomId, KfWebSocketMsgParam.PageBean page) {
-//
-//    }
+    @Override
+    public Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.RoomMsgBean>> msgRoomHistory(Long roomId, KfWebSocketMsgParam.PageBean pageBean) {
+        Page<KfRoomMsg> kfRoomMsgPage = super.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()),
+                new QueryWrapper<KfRoomMsg>().lambda()
+                        .eq(KfRoomMsg::getRoomId, roomId)
+                        .orderByDesc(KfRoomMsg::getCreateTime)
+        );
+        List<KfWebSocketMsgDTO.RoomMsgBean> roomMsgBeanList = kfRoomMsgPage.getRecords().stream()
+                .map(this::transform).collect(Collectors.toList());
+        return Tuples.of(this.transform(kfRoomMsgPage), roomMsgBeanList);
+    }
+
+    private KfWebSocketMsgDTO.RoomMsgBean transform(KfRoomMsg kfRoomMsg) {
+        if (kfRoomMsg == null) {
+            return null;
+        }
+        return BeanUtil.copy(kfRoomMsg, KfWebSocketMsgDTO.RoomMsgBean.class);
+    }
+
+    private KfWebSocketMsgDTO.PageBean transform(Page<KfRoomMsg> kfRoomMsgPage) {
+        return KfWebSocketMsgDTO.PageBean.builder()
+                .pageNum(kfRoomMsgPage.getCurrent())
+                .pageSize(kfRoomMsgPage.getSize())
+                .pageTotal(kfRoomMsgPage.getPages())
+                .total(kfRoomMsgPage.getTotal())
+                .build();
+    }
 }

+ 42 - 14
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfRoomServiceImpl.java

@@ -1,12 +1,15 @@
 package com.zanxiang.game.module.manage.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+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.pojo.dto.KfWebSocketMsgDTO;
+import com.zanxiang.game.module.manage.pojo.params.KfWebSocketMsgParam;
 import com.zanxiang.game.module.manage.service.*;
 import com.zanxiang.game.module.mybatis.entity.*;
 import com.zanxiang.game.module.mybatis.mapper.KfRoomMapper;
@@ -15,6 +18,8 @@ import com.zanxiang.module.util.bean.BeanUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import reactor.util.function.Tuple2;
+import reactor.util.function.Tuples;
 
 import java.time.LocalDateTime;
 import java.util.Collections;
@@ -38,26 +43,51 @@ public class KfRoomServiceImpl extends ServiceImpl<KfRoomMapper, KfRoom> impleme
     @Autowired
     private IGameAppletService gameAppletService;
 
-    @Autowired
-    private IGameUserRoleService gameUserRoleService;
-
     @Autowired
     private IKfRoomMsgService kfRoomMsgService;
 
     @Autowired
     private IUserService userService;
 
+    @Autowired
+    private IKfSessionUserService kfSessionUserService;
+
     @Override
-    public boolean userJoinRoom(String openId, Long gameId) {
+    public Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.RoomBean>> getFinishRoomList(Long gameId, KfWebSocketMsgParam.PageBean pageBean) {
+        Page<KfRoom> kfRoomPage = super.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()),
+                new QueryWrapper<KfRoom>().lambda()
+                        .eq(KfRoom::getGameId, gameId)
+                        .eq(KfRoom::getOnline, Boolean.FALSE)
+                        .orderByDesc(KfRoom::getUpdateTime)
+        );
+        List<KfWebSocketMsgDTO.RoomBean> roomBeanList = kfRoomPage.getRecords().stream()
+                .map(this::transform).collect(Collectors.toList());
+        return Tuples.of(this.transform(kfRoomPage), roomBeanList);
+    }
+
+    private KfWebSocketMsgDTO.PageBean transform(Page<KfRoom> kfRoomPage) {
+        return KfWebSocketMsgDTO.PageBean.builder()
+                .pageNum(kfRoomPage.getCurrent())
+                .pageSize(kfRoomPage.getSize())
+                .pageTotal(kfRoomPage.getPages())
+                .total(kfRoomPage.getTotal())
+                .build();
+    }
+
+    @Override
+    public Long userJoinRoom(String openId, Long gameId) {
         KfRoom kfRoom = super.getOne(new LambdaQueryWrapper<KfRoom>()
                 .eq(KfRoom::getOpenId, openId)
                 .eq(KfRoom::getKfUserId, SecurityUtil.getUserId()));
         if (kfRoom == null) {
-            return super.save(this.transform(openId, gameId));
+            kfRoom = this.transform(openId, gameId);
+            super.save(kfRoom);
+            return kfRoom.getId();
         }
-        return super.update(new LambdaUpdateWrapper<KfRoom>()
+        super.update(new LambdaUpdateWrapper<KfRoom>()
                 .set(KfRoom::getOnline, Boolean.TRUE)
                 .set(KfRoom::getUpdateTime, LocalDateTime.now()));
+        return kfRoom.getId();
     }
 
     private KfRoom transform(String openId, Long gameId) {
@@ -97,9 +127,10 @@ public class KfRoomServiceImpl extends ServiceImpl<KfRoomMapper, KfRoom> impleme
     }
 
     @Override
-    public List<KfWebSocketMsgDTO.RoomBean> getOnlineRoomList() {
+    public List<KfWebSocketMsgDTO.RoomBean> getOnlineRoomList(Long gameId) {
         return super.list(new LambdaQueryWrapper<KfRoom>()
                 .eq(KfRoom::getKfUserId, SecurityUtil.getUserId())
+                .eq(KfRoom::getGameId, gameId)
                 .eq(KfRoom::getOnline, Boolean.TRUE)
         ).stream().map(this::transform).collect(Collectors.toList());
     }
@@ -110,13 +141,10 @@ public class KfRoomServiceImpl extends ServiceImpl<KfRoomMapper, KfRoom> impleme
         }
         KfWebSocketMsgDTO.RoomBean roomBean = BeanUtil.copy(kfRoom, KfWebSocketMsgDTO.RoomBean.class);
         //最近角色信息
-        GameUserRole gameUserRole = null;
-        if (kfRoom.getUserId() != null) {
-            gameUserRole = gameUserRoleService.getLastGameUserRoleName(kfRoom.getUserId(), kfRoom.getGameId());
-        }
-        if (gameUserRole != null) {
-            roomBean.setLastRoleName(gameUserRole.getRoleName());
-            roomBean.setLastRoleId(gameUserRole.getRoleId());
+        KfSessionUser kfSessionUser = kfSessionUserService.getById(kfRoom.getOpenId());
+        if (kfSessionUser != null) {
+            roomBean.setLastRoleId(kfSessionUser.getLastRoleId());
+            roomBean.setLastRoleName(kfSessionUser.getLastRoleName());
         }
         //最后一条消息
         KfRoomMsg kfRoomMsg = kfRoomMsgService.getOne(new LambdaQueryWrapper<KfRoomMsg>()

+ 2 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfSessionUserServiceImpl.java

@@ -33,8 +33,9 @@ public class KfSessionUserServiceImpl extends ServiceImpl<KfSessionUserMapper, K
     private IKfRoomMsgService kfRoomMsgService;
 
     @Override
-    public List<KfWebSocketMsgDTO.WaitUserBean> getWaitUserList() {
+    public List<KfWebSocketMsgDTO.WaitUserBean> getWaitUserList(Long gameId) {
         return super.list(new LambdaQueryWrapper<KfSessionUser>()
+                .eq(KfSessionUser::getGameId, gameId)
                 .eq(KfSessionUser::getIsWait, Boolean.TRUE)
         ).stream().map(this::transform).collect(Collectors.toList());
     }

+ 117 - 42
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/websocket/KfMsgWebsocketHandler.java

@@ -4,12 +4,15 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.zanxiang.erp.base.pojo.TokenInfo;
 import com.zanxiang.erp.security.util.SecurityUtil;
 import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
+import com.zanxiang.game.module.manage.enums.KfRoomMsgOwnerEnum;
 import com.zanxiang.game.module.manage.enums.KfWebSocketMsgEnum;
 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.IKfRoomMsgService;
 import com.zanxiang.game.module.manage.service.IKfRoomService;
 import com.zanxiang.game.module.manage.service.IKfSessionUserService;
 import com.zanxiang.game.module.mybatis.entity.KfRoom;
+import com.zanxiang.game.module.mybatis.entity.KfRoomMsg;
 import com.zanxiang.game.module.mybatis.entity.KfSessionUser;
 import com.zanxiang.module.util.JsonUtil;
 import lombok.extern.slf4j.Slf4j;
@@ -22,6 +25,7 @@ import org.springframework.web.socket.CloseStatus;
 import org.springframework.web.socket.WebSocketHandler;
 import org.springframework.web.socket.WebSocketMessage;
 import org.springframework.web.socket.WebSocketSession;
+import reactor.util.function.Tuple2;
 
 import java.time.LocalDateTime;
 import java.util.List;
@@ -49,6 +53,9 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
     @Autowired
     private IKfSessionUserService kfSessionUserService;
 
+    @Autowired
+    private IKfRoomMsgService kfRoomMsgService;
+
     /**
      * websocket连接建立成功
      */
@@ -64,52 +71,59 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
         String msgStr = message.getPayload().toString();
         log.error("收到前端消息 msgStr : {}", msgStr);
         //消息解析
-        KfWebSocketMsgParam kfWebSocketMsgParam = JsonUtil.toObj(msgStr, KfWebSocketMsgParam.class);
-        log.error("收到前端消息解析结果 kfWebSocketMsgParam : {}", JsonUtil.toString(kfWebSocketMsgParam));
+        KfWebSocketMsgParam param = JsonUtil.toObj(msgStr, KfWebSocketMsgParam.class);
+        log.error("收到前端消息解析结果 kfWebSocketMsgParam : {}", JsonUtil.toString(param));
         //消息类型
-        KfWebSocketMsgEnum webSocketMsgType = kfWebSocketMsgParam.getWebSocketMsgType();
+        KfWebSocketMsgEnum webSocketMsgType = param.getWebSocketMsgType();
+        //游戏id
+        Long gameId = param.getGameId();
         //请求令牌
-        String token = kfWebSocketMsgParam.getToken();
-        //连接身份验证
-        boolean tokenCheckResult = this.tokenCheck(webSocketMsgType, token);
-        //身份验证失败, 没有后续动作
-        if (!tokenCheckResult) {
+        String token = param.getToken();
+        //参数验证
+        boolean checkResult = this.paramCheck(webSocketMsgType, token, gameId);
+        //参数验证失败, 没有后续动作
+        if (!checkResult) {
             log.error("token验证失败, token : {}", token);
             return;
         }
         //握手-消息处理
-        if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_HAND_SHAKE)) {
+        if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_HAND_SHAKE)) {
             log.error("首次握手, kfUserId : {}", SecurityUtil.getUserId());
             this.kfHandShake(session, webSocketMsgType);
         }
         //创建连接-消息处理
-        if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_CREATE_CONNECT)) {
-            log.error("创建连接, kfUserId : {}", SecurityUtil.getUserId());
-            this.kfCreateConnect(webSocketMsgType);
+        if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_CREATE_CONNECT)) {
+            log.error("创建连接, kfUserId : {}, gameId : {}", SecurityUtil.getUserId(), gameId);
+            this.kfCreateConnect(webSocketMsgType, gameId);
         }
         //玩家接入-消息处理
-        if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_USER_CONNECT_JOIN)) {
-            log.error("玩家接入, kfUserId : {}", SecurityUtil.getUserId());
-            this.userConnectJoin(kfWebSocketMsgParam);
+        if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_USER_CONNECT_JOIN)) {
+            log.error("玩家接入, kfUserId : {}, gameId : {}", SecurityUtil.getUserId(), gameId);
+            this.userConnectJoin(param);
         }
         //获取房间历史消息-消息处理
-        if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_ROOM_HISTORY)) {
-            log.error("获取房间历史消息, kfUserId : {}", SecurityUtil.getUserId());
+        if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_ROOM_HISTORY)) {
+            log.error("获取房间历史消息, kfUserId : {}, gameId : {}, roomId : {}",
+                    SecurityUtil.getUserId(), param.getGameId(), param.getRoomId());
+            this.msgRoomHistory(param);
         }
         //客服发送消息-消息处理
-        if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_SEND)) {
+        if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_SEND)) {
 
         }
         //获取已结束房间列表-消息处理
-        if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_FINISH_ROOM_LIST)) {
-
+        if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_FINISH_ROOM_LIST)) {
+            log.error("获取已结束房间列表, kfUserId : {}, gameId : {}", SecurityUtil.getUserId(), param.getGameId());
+            this.finishRoomList(param);
         }
         //结束会话-消息处理
-        if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_FINISH_SESSION)) {
-
+        if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_FINISH_SESSION)) {
+            log.error("结束会话, kfUserId : {}, gameId : {}, roomId : {}",
+                    SecurityUtil.getUserId(), param.getGameId(), param.getRoomId());
+            this.kfFinishSession(webSocketMsgType, param.getGameId(), param.getRoomId());
         }
         //快捷回复-消息处理
-        if (Objects.equals(kfWebSocketMsgParam.getWebSocketMsgType(), KfWebSocketMsgEnum.WEBSOCKET_MSG_QUICK_REPLY)) {
+        if (Objects.equals(webSocketMsgType, KfWebSocketMsgEnum.WEBSOCKET_MSG_QUICK_REPLY)) {
 
         }
     }
@@ -128,11 +142,6 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
     public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
         //从session中获取客服id
         Long kfUserId = Long.valueOf(session.getAttributes().get("kfUserId").toString());
-        //关闭session关联的房间, 有在线状态的更新为断开状态
-        kfRoomService.update(new LambdaUpdateWrapper<KfRoom>()
-                .set(KfRoom::getOnline, Boolean.FALSE)
-                .set(KfRoom::getUpdateTime, LocalDateTime.now())
-                .eq(KfRoom::getKfUserId, kfUserId));
         //关闭连接
         session.close();
         //移除连接
@@ -144,48 +153,108 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
         return false;
     }
 
+    private void kfFinishSession(KfWebSocketMsgEnum webSocketMsgType, Long gameId, Long roomId) {
+        //房间在线状态更新
+        kfRoomService.update(new LambdaUpdateWrapper<KfRoom>()
+                .set(KfRoom::getOnline, Boolean.FALSE)
+                .set(KfRoom::getUpdateTime, LocalDateTime.now())
+                .eq(KfRoom::getId, roomId));
+        //推送完整的已链接房间列表
+        List<KfWebSocketMsgDTO.RoomBean> onlineRoomList = kfRoomService.getOnlineRoomList(gameId);
+        this.pushMessage(KfWebSocketMsgDTO.builder()
+                .webSocketMsgType(webSocketMsgType)
+                .kfUserId(SecurityUtil.getUserId())
+                .gameId(gameId)
+                .roomList(onlineRoomList)
+                .build());
+    }
+
+    private void finishRoomList(KfWebSocketMsgParam param) {
+        Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.RoomBean>> tuple2 = kfRoomService
+                .getFinishRoomList(param.getGameId(), param.getPage());
+        this.pushMessage(KfWebSocketMsgDTO.builder()
+                .webSocketMsgType(param.getWebSocketMsgType())
+                .kfUserId(SecurityUtil.getUserId())
+                .gameId(param.getGameId())
+                .page(tuple2.getT1())
+                .roomList(tuple2.getT2())
+                .build());
+    }
+
     private void msgRoomHistory(KfWebSocketMsgParam param) {
-        if (param.getRoomId() == null || param.getPage() == null) {
-            this.pushMessage(KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
-                    "获取房间历史消息参数错误, roomId和page都不可为空, param : " + JsonUtil.toString(param)));
+        if (param.getRoomId() == null) {
+            this.pushMessage(KfWebSocketMsgDTO.fail(SecurityUtil.getUserId(), param.getWebSocketMsgType(),
+                    "获取房间历史消息参数错误, roomId不可为空, param : " + JsonUtil.toString(param)));
         }
+        //当获取第一页的时候, 房间未读消息全部更新成已读消息
+        if (param.getPage().getPageNum() == 1) {
+            kfRoomMsgService.update(new LambdaUpdateWrapper<KfRoomMsg>()
+                    .set(KfRoomMsg::getReadStatus, Boolean.TRUE)
+                    .set(KfRoomMsg::getUpdateTime, LocalDateTime.now())
+                    .eq(KfRoomMsg::getRoomId, param.getRoomId()));
+        }
+        //分页获取房间消息列表
+        Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.RoomMsgBean>> tuple2 = kfRoomMsgService
+                .msgRoomHistory(param.getRoomId(), param.getPage());
+        this.pushMessage(KfWebSocketMsgDTO.builder()
+                .webSocketMsgType(param.getWebSocketMsgType())
+                .kfUserId(SecurityUtil.getUserId())
+                .page(tuple2.getT1())
+                .gameId(param.getGameId())
+                .roomId(param.getRoomId())
+                .roomMsgList(tuple2.getT2())
+                .build());
     }
 
     private void userConnectJoin(KfWebSocketMsgParam param) {
-        if (Strings.isBlank(param.getOpenId()) || param.getGameId() == null) {
-            this.pushMessage(KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
+        if (Strings.isBlank(param.getOpenId())) {
+            this.pushMessage(KfWebSocketMsgDTO.fail(SecurityUtil.getUserId(), param.getWebSocketMsgType(),
                     "接入玩家参数错误, openId和gameId都不可为空, param : " + JsonUtil.toString(param)));
         }
+        //todo : 判断玩家是否已被接入
+
+
         //玩家更新
         kfSessionUserService.update(new LambdaUpdateWrapper<KfSessionUser>()
                 .set(KfSessionUser::getIsWait, Boolean.FALSE)
                 .set(KfSessionUser::getUpdateTime, LocalDateTime.now()));
         //房间更新
-        kfRoomService.userJoinRoom(param.getOpenId(), param.getGameId());
+        Long roomId = kfRoomService.userJoinRoom(param.getOpenId(), param.getGameId());
+        //玩家未读消息更新到房间
+        kfRoomMsgService.update(new LambdaUpdateWrapper<KfRoomMsg>()
+                .set(KfRoomMsg::getRoomId, roomId)
+                .set(KfRoomMsg::getUpdateTime, LocalDateTime.now())
+                .eq(KfRoomMsg::getOpenId, param.getOpenId())
+                .eq(KfRoomMsg::getGameId, param.getGameId())
+                .ne(KfRoomMsg::getMsgOwner, KfRoomMsgOwnerEnum.KF_MSG_OWNER_KF.getValue())
+                .eq(KfRoomMsg::getReadStatus, Boolean.FALSE));
         //发送消息, 给该客服返回完整的已接入房间列表
-        List<KfWebSocketMsgDTO.RoomBean> roomList = kfRoomService.getOnlineRoomList();
+        List<KfWebSocketMsgDTO.RoomBean> roomList = kfRoomService.getOnlineRoomList(param.getGameId());
         this.pushMessage(KfWebSocketMsgDTO.builder()
                 .webSocketMsgType(param.getWebSocketMsgType())
                 .kfUserId(SecurityUtil.getUserId())
+                .gameId(param.getGameId())
                 .roomList(roomList)
                 .build());
         //发送消息, 给所有在线客服推送完整待接入列表
-        List<KfWebSocketMsgDTO.WaitUserBean> waitUserList = kfSessionUserService.getWaitUserList();
+        List<KfWebSocketMsgDTO.WaitUserBean> waitUserList = kfSessionUserService.getWaitUserList(param.getGameId());
         this.pushMessage(KfWebSocketMsgDTO.builder()
                 .webSocketMsgType(param.getWebSocketMsgType())
+                .gameId(param.getGameId())
                 .waitUserList(waitUserList)
                 .build());
     }
 
-    private void kfCreateConnect(KfWebSocketMsgEnum msgTypeEnum) {
+    private void kfCreateConnect(KfWebSocketMsgEnum msgTypeEnum, Long gameId) {
         //获取待接入列表
-        List<KfWebSocketMsgDTO.WaitUserBean> waitUserList = kfSessionUserService.getWaitUserList();
+        List<KfWebSocketMsgDTO.WaitUserBean> waitUserList = kfSessionUserService.getWaitUserList(gameId);
         //获取已接入房间列表
-        List<KfWebSocketMsgDTO.RoomBean> roomList = kfRoomService.getOnlineRoomList();
+        List<KfWebSocketMsgDTO.RoomBean> roomList = kfRoomService.getOnlineRoomList(gameId);
         //发送消息
         this.pushMessage(KfWebSocketMsgDTO.builder()
                 .webSocketMsgType(msgTypeEnum)
                 .kfUserId(SecurityUtil.getUserId())
+                .gameId(gameId)
                 .waitUserList(waitUserList)
                 .roomList(roomList)
                 .build());
@@ -206,16 +275,22 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
                 .build());
     }
 
-    private boolean tokenCheck(KfWebSocketMsgEnum webSocketMsgType, String token) {
+    private boolean paramCheck(KfWebSocketMsgEnum webSocketMsgType, String token, Long gameId) {
         //令牌为空
         if (Strings.isBlank(token)) {
-            this.pushMessage(KfWebSocketMsgDTO.fail(webSocketMsgType, "非法参数, token令牌不可为空"));
+            this.pushMessage(KfWebSocketMsgDTO.fail(SecurityUtil.getUserId(), webSocketMsgType, "非法参数, token令牌不可为空"));
             return Boolean.FALSE;
         }
         //令牌验证
         TokenInfo tokenInfo = SecurityUtil.parseToken(token);
         if (tokenInfo == null) {
-            this.pushMessage(KfWebSocketMsgDTO.fail(webSocketMsgType, "参数错误, 令牌验证不通过"));
+            this.pushMessage(KfWebSocketMsgDTO.fail(SecurityUtil.getUserId(), webSocketMsgType, "参数错误, 令牌验证不通过"));
+            return Boolean.FALSE;
+        }
+        //非首次握手, 校验gameId参数
+        if (!Objects.equals(KfWebSocketMsgEnum.WEBSOCKET_MSG_KF_HAND_SHAKE, webSocketMsgType)
+                && gameId == null) {
+            this.pushMessage(KfWebSocketMsgDTO.fail(SecurityUtil.getUserId(), webSocketMsgType, "参数错误, gameId为空"));
             return Boolean.FALSE;
         }
         //将token设置到当前线程