Преглед на файлове

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

zhangxianyu преди 1 година
родител
ревизия
be8b86047f

+ 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服务启动成功 < ( 下班时间, 已接入玩家取消自动回复´・・)ノ(._.`) \n" +
+        System.out.println("赞象Manage服务启动成功 < (客服系统KfSessionUser表更新为复合主键´・・)ノ(._.`) \n" +
                 "___  ___  ___   _   _   ___  _____  _____ \n" +
                 "|  \\/  | / _ \\ | \\ | | / _ \\|  __ \\|  ___|\n" +
                 "| .  . |/ /_\\ \\|  \\| |/ /_\\ \\ |  \\/| |__  \n" +

+ 5 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/constant/RedisKeyConstant.java

@@ -42,4 +42,9 @@ public class RedisKeyConstant {
      */
     public static final String GAME_CUSTOM_PAY_SIGN = "game_sdk_manage_custom_pay_sign_";
 
+    /**
+     * 客服系统玩家信息更新
+     */
+    public static final String KF_MSG_USER_SESSION_UPDATE = RedisKeyConstant.REDIS_PREFIX + "kf_msg_user_session_update_";
+
 }

+ 5 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/dto/KfAppletMsgDTO.java

@@ -18,6 +18,11 @@ public class KfAppletMsgDTO {
      */
     public static final String MSG_TYPE_EVENT = "event";
 
+    /**
+     * 玩家反馈消息
+     */
+    public static final String MSG_USER_FEEDBACK = "【来源于用户反馈】";
+
     /**
      * 用户进入会话事件
      */

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

@@ -69,25 +69,28 @@ public interface IKfRoomService extends IService<KfRoom> {
      * 获取玩家信息
      *
      * @param openId : 玩家openId
+     * @param gameId : 游戏id
      * @return : 返回玩家信息
      */
-    KfWebSocketMsgDTO.UserBean getUserBean(String openId);
+    KfWebSocketMsgDTO.UserBean getUserBean(String openId, Long gameId);
 
     /**
      * 分页获取玩家角色列表
      *
      * @param openId   : 玩家openId
+     * @param gameId   : 游戏id
      * @param pageBean : 分页信息
      * @return : 返回单页数据
      */
-    Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.GameRoleBean>> getRoleBeanList(String openId, KfWebSocketMsgParam.PageBean pageBean);
+    Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.GameRoleBean>> getRoleBeanList(String openId, Long gameId, KfWebSocketMsgParam.PageBean pageBean);
 
     /**
      * 分页获取玩家订单列表
      *
      * @param openId   : 玩家openId
+     * @param gameId   : 游戏id
      * @param pageBean : 分页信息
      * @return : 返回单页数据
      */
-    Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.OrderBean>> getOrderBeanList(String openId, KfWebSocketMsgParam.PageBean pageBean);
+    Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.OrderBean>> getOrderBeanList(String openId, Long gameId, KfWebSocketMsgParam.PageBean pageBean);
 }

+ 9 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfSessionUserService.java

@@ -13,6 +13,15 @@ import java.util.List;
  */
 public interface IKfSessionUserService extends IService<KfSessionUser> {
 
+    /**
+     * 查询玩家信息
+     *
+     * @param openId : 玩家id
+     * @param gameId : 游戏id
+     * @return : 返回玩家信息
+     */
+    KfSessionUser getById(String openId, Long gameId);
+
     /**
      * 获取待接入列表
      *

+ 36 - 10
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfAppletMsgServiceImpl.java

@@ -19,6 +19,7 @@ import com.zanxiang.game.module.manage.utils.FileUtil;
 import com.zanxiang.game.module.manage.utils.RedisUtil;
 import com.zanxiang.game.module.mybatis.entity.*;
 import com.zanxiang.module.oss.service.IOssService;
+import com.zanxiang.module.redis.service.IDistributedLockComponent;
 import com.zanxiang.module.util.JsonUtil;
 import com.zanxiang.module.util.bean.BeanUtil;
 import com.zanxiang.module.util.exception.BaseException;
@@ -37,6 +38,7 @@ import java.net.URI;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @author : lingfeng
@@ -101,6 +103,9 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
     @Autowired
     private RedisUtil<String> redisUtil;
 
+    @Autowired
+    private IDistributedLockComponent distributedLockComponent;
+
     @Override
     public void appletMsg(String postData) {
         KfAppletMsgDTO kfAppletMsgDTO = JsonUtil.toObj(postData, KfAppletMsgDTO.class);
@@ -119,6 +124,11 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
         if (kfAppletMsgDTO.getMsgId() == null) {
             return;
         }
+        //判断是否为玩家反馈信息, 如果是反馈信息需要检查玩家身份信息是否存在, 腾讯个坑比先给消息再给客服进入事件
+        if (Strings.isNotBlank(kfAppletMsgDTO.getContent())
+                && kfAppletMsgDTO.getContent().contains(KfAppletMsgDTO.MSG_USER_FEEDBACK)) {
+            this.kfSessionUserUpdateSave(kfAppletMsgDTO, gameApplet);
+        }
         //查询玩家的房间连接状态
         KfRoom kfRoom = kfRoomService.getOne(new LambdaQueryWrapper<KfRoom>()
                 .eq(KfRoom::getOpenId, kfAppletMsgDTO.getFromUserName())
@@ -151,7 +161,9 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
                     .set(KfSessionUser::getIsWait, Boolean.TRUE)
                     .set(KfSessionUser::getWaitStartTime, LocalDateTime.now())
                     .set(KfSessionUser::getUpdateTime, LocalDateTime.now())
-                    .eq(KfSessionUser::getOpenId, kfAppletMsgDTO.getFromUserName()));
+                    .eq(KfSessionUser::getOpenId, kfAppletMsgDTO.getFromUserName())
+                    .eq(KfSessionUser::getGameId, gameApplet.getGameId())
+            );
         }
         //消息转发到redis频道
         this.pushMessage(this.transform(kfRoom, gameApplet.getGameId(), kfAppletMsgDTO.getFromUserName(), kfRoomMsg, msgContent));
@@ -187,7 +199,7 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
             return;
         }
         //查询玩家信息
-        KfSessionUser kfSessionUser = kfSessionUserService.getById(openId);
+        KfSessionUser kfSessionUser = kfSessionUserService.getById(openId, gameId);
         //判断是否开启充值自动回复
         if (Objects.equals(kfSystemReply.getRechargeReplySwitch(), Boolean.TRUE)) {
             //查询订单
@@ -321,7 +333,12 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
     }
 
     private void kfSessionUserUpdateSave(KfAppletMsgDTO kfAppletMsgDTO, GameApplet gameApplet) {
-        KfSessionUser kfSessionUser = kfSessionUserService.getById(kfAppletMsgDTO.getFromUserName());
+        //上锁
+        String lockKey = RedisKeyConstant.KF_MSG_USER_SESSION_UPDATE
+                + kfAppletMsgDTO.getFromUserName() + "_" + gameApplet.getGameId();
+        if (!distributedLockComponent.doLock(lockKey, 0L, 5L, TimeUnit.MINUTES)) {
+            return;
+        }
         //查询用户
         User user = userService.getOne(new LambdaQueryWrapper<User>()
                 .eq(User::getGameId, gameApplet.getGameId())
@@ -332,19 +349,28 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
             gameUserRole = gameUserRoleService.getLastGameUserRoleName(user.getId(), user.getGameId());
         }
         //不存在玩家信息, 创建保存
-        if (kfSessionUser == null) {
+        if (kfSessionUserService.count(new LambdaQueryWrapper<KfSessionUser>()
+                .eq(KfSessionUser::getOpenId, kfAppletMsgDTO.getFromUserName())
+                .eq(KfSessionUser::getGameId, gameApplet.getGameId())
+        ) <= 0) {
             kfSessionUserService.save(this.transform(kfAppletMsgDTO, gameApplet, user, gameUserRole));
             return;
         }
+        //不存在角色信息, 不做更新
+        if (gameUserRole == null) {
+            return;
+        }
         //存在, 更新玩家信息
         kfSessionUserService.update(new LambdaUpdateWrapper<KfSessionUser>()
-                .set(KfSessionUser::getUserId, user == null ? null : user.getId())
-                .set(KfSessionUser::getLastRoleId, gameUserRole == null ? null : gameUserRole.getRoleId())
-                .set(KfSessionUser::getLastRoleName, gameUserRole == null ? "神秘人[未创角]" : gameUserRole.getRoleName())
-                .set(gameUserRole != null, KfSessionUser::getServerId, gameUserRole == null ? null : gameUserRole.getServerId())
-                .set(gameUserRole != null, KfSessionUser::getServerName, gameUserRole == null ? null : gameUserRole.getServerName())
+                .set(KfSessionUser::getUserId, user.getId())
+                .set(KfSessionUser::getLastRoleId, gameUserRole.getRoleId())
+                .set(KfSessionUser::getLastRoleName, gameUserRole.getRoleName())
+                .set(KfSessionUser::getServerId, gameUserRole.getServerId())
+                .set(KfSessionUser::getServerName, gameUserRole.getServerName())
                 .set(KfSessionUser::getUpdateTime, LocalDateTime.now())
-                .eq(KfSessionUser::getOpenId, kfAppletMsgDTO.getFromUserName()));
+                .eq(KfSessionUser::getOpenId, kfAppletMsgDTO.getFromUserName())
+                .eq(KfSessionUser::getGameId, gameApplet.getGameId())
+        );
     }
 
     private KfSessionUser transform(KfAppletMsgDTO kfAppletMsgDTO, GameApplet gameApplet, User user, GameUserRole gameUserRole) {

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

@@ -173,7 +173,7 @@ public class KfRoomServiceImpl extends ServiceImpl<KfRoomMapper, KfRoom> impleme
         KfWebSocketMsgDTO.RoomBean roomBean = BeanUtil.copy(kfRoom, KfWebSocketMsgDTO.RoomBean.class);
         roomBean.setRoomId(kfRoom.getId());
         //最近角色信息
-        KfSessionUser kfSessionUser = kfSessionUserService.getById(kfRoom.getOpenId());
+        KfSessionUser kfSessionUser = kfSessionUserService.getById(kfRoom.getOpenId(), kfRoom.getGameId());
         if (kfSessionUser != null) {
             roomBean.setLastRoleId(kfSessionUser.getLastRoleId());
             roomBean.setLastRoleName(kfSessionUser.getLastRoleName());
@@ -212,8 +212,8 @@ public class KfRoomServiceImpl extends ServiceImpl<KfRoomMapper, KfRoom> impleme
     }
 
     @Override
-    public KfWebSocketMsgDTO.UserBean getUserBean(String openId) {
-        KfSessionUser kfSessionUser = kfSessionUserService.getById(openId);
+    public KfWebSocketMsgDTO.UserBean getUserBean(String openId, Long gameId) {
+        KfSessionUser kfSessionUser = kfSessionUserService.getById(openId, gameId);
         KfWebSocketMsgDTO.UserBean userBean = BeanUtil.copy(kfSessionUser, KfWebSocketMsgDTO.UserBean.class);
         if (userBean == null || userBean.getUserId() == null) {
             return userBean;
@@ -248,8 +248,8 @@ public class KfRoomServiceImpl extends ServiceImpl<KfRoomMapper, KfRoom> impleme
     }
 
     @Override
-    public Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.GameRoleBean>> getRoleBeanList(String openId, KfWebSocketMsgParam.PageBean pageBean) {
-        KfSessionUser kfSessionUser = kfSessionUserService.getById(openId);
+    public Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.GameRoleBean>> getRoleBeanList(String openId, Long gameId, KfWebSocketMsgParam.PageBean pageBean) {
+        KfSessionUser kfSessionUser = kfSessionUserService.getById(openId, gameId);
         if (kfSessionUser == null || kfSessionUser.getUserId() == null) {
             return Tuples.of(KfWebSocketMsgDTO.defaultPage(pageBean.getPageNum(), pageBean.getPageSize()), Collections.emptyList());
         }
@@ -272,8 +272,8 @@ public class KfRoomServiceImpl extends ServiceImpl<KfRoomMapper, KfRoom> impleme
     }
 
     @Override
-    public Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.OrderBean>> getOrderBeanList(String openId, KfWebSocketMsgParam.PageBean pageBean) {
-        KfSessionUser kfSessionUser = kfSessionUserService.getById(openId);
+    public Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.OrderBean>> getOrderBeanList(String openId, Long gameId, KfWebSocketMsgParam.PageBean pageBean) {
+        KfSessionUser kfSessionUser = kfSessionUserService.getById(openId, gameId);
         if (kfSessionUser == null || kfSessionUser.getUserId() == null) {
             return Tuples.of(KfWebSocketMsgDTO.defaultPage(pageBean.getPageNum(), pageBean.getPageSize()), Collections.emptyList());
         }

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

@@ -38,6 +38,14 @@ public class KfSessionUserServiceImpl extends ServiceImpl<KfSessionUserMapper, K
     @Autowired
     private IRoleOperateService roleOperateService;
 
+    @Override
+    public KfSessionUser getById(String openId, Long gameId) {
+        return super.getOne(new LambdaQueryWrapper<KfSessionUser>()
+                .eq(KfSessionUser::getOpenId, openId)
+                .eq(KfSessionUser::getGameId, gameId)
+        );
+    }
+
     @Override
     public List<KfWebSocketMsgDTO.WaitUserBean> getWaitUserList(Long gameId) {
         return super.list(new LambdaQueryWrapper<KfSessionUser>()

+ 11 - 7
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/websocket/KfMsgWebsocketHandler.java

@@ -211,7 +211,7 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
                     "获取玩家信息参数错误, openId不可为空, param : " + JsonUtil.toString(param)));
             return;
         }
-        KfWebSocketMsgDTO.UserBean userBean = kfRoomService.getUserBean(param.getOpenId());
+        KfWebSocketMsgDTO.UserBean userBean = kfRoomService.getUserBean(param.getOpenId(), param.getGameId());
         this.sendMessage(session, KfWebSocketMsgDTO.builder()
                 .webSocketMsgType(param.getWebSocketMsgType())
                 .kfUserId(SecurityUtil.getUserId())
@@ -226,7 +226,7 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
             return;
         }
         Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.GameRoleBean>> tuple2 = kfRoomService
-                .getRoleBeanList(param.getOpenId(), param.getPage());
+                .getRoleBeanList(param.getOpenId(), param.getGameId(), param.getPage());
         this.sendMessage(session, KfWebSocketMsgDTO.builder()
                 .webSocketMsgType(param.getWebSocketMsgType())
                 .kfUserId(SecurityUtil.getUserId())
@@ -242,7 +242,7 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
             return;
         }
         Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.OrderBean>> tuple2 = kfRoomService
-                .getOrderBeanList(param.getOpenId(), param.getPage());
+                .getOrderBeanList(param.getOpenId(), param.getGameId(), param.getPage());
         this.sendMessage(session, KfWebSocketMsgDTO.builder()
                 .webSocketMsgType(param.getWebSocketMsgType())
                 .kfUserId(SecurityUtil.getUserId())
@@ -318,7 +318,9 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
         //玩家信息更新
         kfSessionUserService.update(new LambdaUpdateWrapper<KfSessionUser>()
                 .set(KfSessionUser::getUpdateTime, LocalDateTime.now())
-                .eq(KfSessionUser::getOpenId, kfRoom.getOpenId()));
+                .eq(KfSessionUser::getOpenId, kfRoom.getOpenId())
+                .eq(KfSessionUser::getGameId, kfRoom.getGameId())
+        );
         //推送完整的已链接房间列表
         List<KfWebSocketMsgDTO.RoomBean> onlineRoomList = kfRoomService.getOnlineRoomList(gameId);
         this.sendMessage(session, KfWebSocketMsgDTO.builder()
@@ -389,13 +391,13 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
             return;
         }
         //玩家信息, 判断玩家是否已经被接入
-        KfSessionUser kfSessionUser = kfSessionUserService.getById(param.getOpenId());
+        KfSessionUser kfSessionUser = kfSessionUserService.getById(param.getOpenId(), param.getGameId());
         if (!kfSessionUser.getIsWait()) {
             this.sendMessage(session, KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(), "玩家非待接入状态(已被其他客服接入)"));
             return;
         }
         //触发玩家接入线程锁
-        String lockKey = RedisKeyConstant.KF_MSG_USER_CONNECT_JOIN + param.getOpenId();
+        String lockKey = RedisKeyConstant.KF_MSG_USER_CONNECT_JOIN + param.getOpenId() + "_" + param.getGameId();
         log.error("玩家接入触发线程锁, key : {}", lockKey);
         if (!redisUtil.setIfAbsent(lockKey, lockKey, ExpireTimeEnum.FIVE_MIN.getTime())) {
             log.error("玩家接入锁碰撞, 未接入成功, key : {}", lockKey);
@@ -406,7 +408,9 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
         kfSessionUserService.update(new LambdaUpdateWrapper<KfSessionUser>()
                 .set(KfSessionUser::getIsWait, Boolean.FALSE)
                 .set(KfSessionUser::getUpdateTime, LocalDateTime.now())
-                .eq(KfSessionUser::getOpenId, param.getOpenId()));
+                .eq(KfSessionUser::getOpenId, param.getOpenId())
+                .eq(KfSessionUser::getGameId, param.getGameId())
+        );
         //房间更新
         Long roomId = kfRoomService.userJoinRoom(param.getOpenId(), param.getGameId());
         //玩家未读消息, 系统消息更新到房间

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

@@ -1,7 +1,5 @@
 package com.zanxiang.game.module.mybatis.entity;
 
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.*;
 
@@ -26,7 +24,6 @@ public class KfSessionUser implements Serializable {
     /**
      * 玩家openId
      */
-    @TableId(value = "open_id", type = IdType.INPUT)
     private String openId;
 
     /**