Bläddra i källkod

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

zhimo 1 år sedan
förälder
incheckning
fdcd2cd2ee
16 ändrade filer med 355 tillägg och 64 borttagningar
  1. 3 1
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/dto/GameDTO.java
  2. 48 1
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/PromotionDayTotalVO.java
  3. 43 0
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/PromotionDayVO.java
  4. 33 4
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/PromotionDayServiceImpl.java
  5. 96 26
      game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/RoleManageServiceImpl.java
  6. 1 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/ManageApplication.java
  7. 5 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/constant/RedisKeyConstant.java
  8. 5 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/dto/KfAppletMsgDTO.java
  9. 6 3
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfRoomService.java
  10. 9 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfSessionUserService.java
  11. 65 11
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfAppletMsgServiceImpl.java
  12. 7 7
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfRoomServiceImpl.java
  13. 8 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfSessionUserServiceImpl.java
  14. 11 7
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/websocket/KfMsgWebsocketHandler.java
  15. 0 3
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/KfSessionUser.java
  16. 15 0
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/KfSystemReply.java

+ 3 - 1
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/dto/GameDTO.java

@@ -6,9 +6,11 @@ import lombok.Data;
 public class GameDTO {
 
 
-    private Integer id;
+    private Long id;
 
     private Long parentId;
 
     private String gameName;
+
+    private Long superGameId;
 }

+ 48 - 1
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/PromotionDayTotalVO.java

@@ -901,7 +901,13 @@ public class PromotionDayTotalVO {
      * 七日人均付费次数(广告)
      */
     @ApiModelProperty("七日人均付费次数(广告)")
-    private Long attributionActivePay7dPerCount;
+    private BigDecimal attributionActivePay7dPerCount;
+
+    /**
+     * 七日首次付费次数(广告)(也就是7日内付费的人数)
+     */
+    @ApiModelProperty("七日首次付费次数(广告)(也就是7日内付费的人数)")
+    private Long firstAttributionGamePay7dCount;
 
     /**
      * 七日付费成本(广告)
@@ -976,4 +982,45 @@ public class PromotionDayTotalVO {
     @ApiModelProperty(value = "至今付费200+用户付费成本")
     private BigDecimal newUserTwoHundredUserNumCost;
 
+
+    /**
+     * 激活后一日付费ROI
+     */
+    @ApiModelProperty(value = "激活后一日付费ROI")
+    private BigDecimal attributionGameInAppRoi2days;
+
+    /**
+     * 激活后二日付费ROI
+     */
+    @ApiModelProperty(value = "激活后二日付费ROI")
+    private BigDecimal attributionGameInAppRoi3days;
+    /**
+     * 激活后三日付费ROI
+     */
+    @ApiModelProperty(value = "激活后三日付费ROI")
+    private BigDecimal attributionGameInAppRoi4days;
+    /**
+     * 激活后四日付费ROI
+     */
+    @ApiModelProperty(value = "激活后四日付费ROI")
+    private BigDecimal attributionGameInAppRoi5days;
+    /**
+     * 激活后五日付费ROI
+     */
+    @ApiModelProperty(value = "激活后五日付费ROI")
+    private BigDecimal attributionGameInAppRoi6days;
+    /**
+     * 激活后六日付费ROI
+     */
+    @ApiModelProperty(value = "激活后六日付费ROI")
+    private BigDecimal attributionGameInAppRoi7days;
+    /**
+     * 激活后七日付费ROI
+     */
+    @ApiModelProperty(value = "激活后七日付费ROI")
+    private BigDecimal attributionGameInAppRoi8days;
+
+
+
+
 }

+ 43 - 0
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/pojo/vo/PromotionDayVO.java

@@ -1073,6 +1073,12 @@ public class PromotionDayVO {
     @ApiModelProperty("7日付费次数(广告)")
     private Long attributionGamePay7dCount;
 
+    /**
+     * 七日首次付费次数(广告)(也就是7日内付费的人数)
+     */
+    @ApiModelProperty("七日首次付费次数(广告)(也就是7日内付费的人数)")
+    private Long firstAttributionGamePay7dCount;
+
     /**
      * 七日人均付费次数(广告)
      */
@@ -1152,5 +1158,42 @@ public class PromotionDayVO {
     @ApiModelProperty(value = "至今付费200+用户付费成本")
     private BigDecimal newUserTwoHundredUserNumCost;
 
+    /**
+     * 激活后一日付费ROI
+     */
+    @ApiModelProperty(value = "激活后一日付费ROI")
+    private BigDecimal attributionGameInAppRoi2days;
+
+    /**
+     * 激活后二日付费ROI
+     */
+    @ApiModelProperty(value = "激活后二日付费ROI")
+    private BigDecimal attributionGameInAppRoi3days;
+    /**
+     * 激活后三日付费ROI
+     */
+    @ApiModelProperty(value = "激活后三日付费ROI")
+    private BigDecimal attributionGameInAppRoi4days;
+    /**
+     * 激活后四日付费ROI
+     */
+    @ApiModelProperty(value = "激活后四日付费ROI")
+    private BigDecimal attributionGameInAppRoi5days;
+    /**
+     * 激活后五日付费ROI
+     */
+    @ApiModelProperty(value = "激活后五日付费ROI")
+    private BigDecimal attributionGameInAppRoi6days;
+    /**
+     * 激活后六日付费ROI
+     */
+    @ApiModelProperty(value = "激活后六日付费ROI")
+    private BigDecimal attributionGameInAppRoi7days;
+    /**
+     * 激活后七日付费ROI
+     */
+    @ApiModelProperty(value = "激活后七日付费ROI")
+    private BigDecimal attributionGameInAppRoi8days;
+
 
 }

+ 33 - 4
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/PromotionDayServiceImpl.java

@@ -146,6 +146,8 @@ public class PromotionDayServiceImpl implements IAdsPromotionDayService {
         Tuple2<List<Long>, List<Long>> poerInfo = dataPowerComponent.getPowerInfo();
         List<Long> userIds = dto.getPitcherId() == null ? poerInfo.first : Collections.singletonList(dto.getPitcherId());
         List<Long> gameIds = dto.getGameId() == null ? poerInfo.second : Collections.singletonList(dto.getGameId());
+//        List<Long> userIds = dto.getPitcherId() == null ? null : Collections.singletonList(dto.getPitcherId());
+//        List<Long> gameIds = dto.getGameId() == null ? null : Collections.singletonList(dto.getGameId());
 
         //如果没有排序条件给默认值
         if (StringUtils.isBlank(dto.getSortFiled())) {
@@ -230,6 +232,8 @@ public class PromotionDayServiceImpl implements IAdsPromotionDayService {
         Tuple2<List<Long>, List<Long>> poerInfo = dataPowerComponent.getPowerInfo();
         List<Long> userIds = dto.getPitcherId() == null ? poerInfo.first : Collections.singletonList(dto.getPitcherId());
         List<Long> gameIds = dto.getGameId() == null ? poerInfo.second : Collections.singletonList(dto.getGameId());
+//        List<Long> userIds = dto.getPitcherId() == null ? null : Collections.singletonList(dto.getPitcherId());
+//        List<Long> gameIds = dto.getGameId() == null ? null : Collections.singletonList(dto.getGameId());
 
         //创建查询条件
         Criteria cri = Cnd.cri();
@@ -1076,7 +1080,14 @@ public class PromotionDayServiceImpl implements IAdsPromotionDayService {
                     day7_two_hundred_amount_num,
                     day7_two_hundred_amount_num_cost,
                     new_user_two_hundred_user_num,
-                    new_user_two_hundred_user_num_cost
+                    new_user_two_hundred_user_num_cost,
+                    attribution_game_in_app_roi2days,
+                    attribution_game_in_app_roi3days,
+                    attribution_game_in_app_roi4days,
+                    attribution_game_in_app_roi5days,
+                    attribution_game_in_app_roi6days,
+                    attribution_game_in_app_roi7days,
+                    attribution_game_in_app_roi8days
                 FROM
                 	game_ads.ads_promotion_day
                 """;
@@ -1134,6 +1145,7 @@ public class PromotionDayServiceImpl implements IAdsPromotionDayService {
                 		SUM(new_user_total_amount_count) as new_user_total_amount_count,
                 		SUM(new_user_total_amount_num) as new_user_total_amount_num,
                 		SUM(new_user_total_amount) as new_user_total_amount,
+                		SUM(first_attribution_game_pay7d_count) as first_attribution_game_pay7d_count,  -- 七日首次付费次数(也就是七日付费人数)
                 		round(if(SUM(today_cost) > 0, SUM(first_new_user_amount) / SUM(today_cost), 0), 4) as first_roi,
                 		SUM(twenty_four_hours_amount) as twenty_four_hours_amount,
                 		round(if(SUM(today_cost) > 0, SUM(twenty_four_hours_amount) / SUM(today_cost), 0), 4) as twenty_four_hours_roi,
@@ -1199,7 +1211,15 @@ public class PromotionDayServiceImpl implements IAdsPromotionDayService {
                      	SUM(day7_two_hundred_amount_num) as day7_two_hundred_amount_num,
                      	SUM(day7_two_hundred_amount_num_cost) as day7_two_hundred_amount_num_cost,
                      	SUM(new_user_two_hundred_user_num) as new_user_two_hundred_user_num,
-                     	SUM(new_user_two_hundred_user_num_cost) as new_user_two_hundred_user_num_cost
+                     	SUM(new_user_two_hundred_user_num_cost) as new_user_two_hundred_user_num_cost,
+                        -- 2-8日的roi
+                        ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv2days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi2days,
+                        ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv3days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi3days,
+                        ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv4days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi4days,
+                        ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv5days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi5days,
+                        ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv6days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi6days,
+                        ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv7days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi7days,
+                        ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv8days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi8days
                 	FROM
                 		game_ads.ads_promotion_day
                 """ + criA +
@@ -1329,7 +1349,8 @@ public class PromotionDayServiceImpl implements IAdsPromotionDayService {
                     ROUND(IF(SUM(first_new_user_amount_count) > 0, SUM(today_cost) / SUM(first_new_user_amount_count), 0), 2) as first_new_user_amount_count_cost,
                     ROUND(IF(SUM(new_user_total_amount_count) > 0, SUM(today_cost) / SUM(new_user_total_amount_count), 0), 2) as new_user_total_amount_count_cost,
                     SUM(attribution_game_pay7d_count) as attribution_game_pay7d_count,
-                    SUM(attribution_active_pay7d_per_count) as attribution_active_pay7d_per_count,
+                    SUM(first_attribution_game_pay7d_count) as first_attribution_game_pay7d_count,
+                    ROUND(SUM(attribution_active_pay7d_per_count)/SUM(first_attribution_game_pay7d_count),2) as attribution_active_pay7d_per_count,   -- 总计的人均要用  七日付费次数/七日首次付费次数(也就是付费人数)
                     ROUND(if(SUM(attribution_game_pay7d_count) > 0, SUM(today_cost) / SUM(attribution_game_pay7d_count), 0), 2) as attribution_game_pay7d_cost,
                     SUM(day7_amount_count) as day7_amount_count,
                     ROUND(if(SUM(day7_amount_count) > 0, SUM(today_cost) / SUM(day7_amount_count), 0), 2) as day7_amount_per_cost,
@@ -1342,7 +1363,15 @@ public class PromotionDayServiceImpl implements IAdsPromotionDayService {
                     SUM(day7_two_hundred_amount_num) as day7_two_hundred_amount_num,
                     SUM(day7_two_hundred_amount_num_cost) as day7_two_hundred_amount_num_cost,
                     SUM(new_user_two_hundred_user_num) as new_user_two_hundred_user_num,
-                    SUM(new_user_two_hundred_user_num_cost) as new_user_two_hundred_user_num_cost
+                    SUM(new_user_two_hundred_user_num_cost) as new_user_two_hundred_user_num_cost,
+                     -- 2-8日的roi
+                    ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv2days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi2days,
+                    ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv3days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi3days,
+                    ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv4days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi4days,
+                    ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv5days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi5days,
+                    ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv6days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi6days,
+                    ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv7days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi7days,
+                    ROUND(IF(SUM(today_cost)>0,SUM(attribution_game_in_app_ltv8days)/SUM(today_cost)*100,0),2) as attribution_game_in_app_roi8days
                 FROM
                 	game_ads.ads_promotion_day
                 """;

+ 96 - 26
game-data/game-data-serve/src/main/java/com/zanxiang/game/data/serve/service/impl/RoleManageServiceImpl.java

@@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -236,8 +237,31 @@ public class RoleManageServiceImpl implements IRoleManageService {
         sql.setCallback(Sqls.callback.maps());
         sql.setPager(pager);
         dao.execute(sql);
-        List<Map> list = sql.getList(Map.class).stream().map(map -> {
-             getNameById(map);
+        //查询结果
+        List<Map> list = sql.getList(Map.class);
+        //用户id列表
+        List<Long> userIds = new ArrayList<>();
+        for (Map map : list) {
+//            getNameById(map);
+            //把投手id和运营id和GSID和客服人员ID 转成List
+            if(map.get("put_user_id") != null){
+                userIds.add(Long.valueOf(map.get("put_user_id").toString()));
+            }
+            if(map.get("oper_user_id") != null){
+                userIds.add(Long.valueOf(map.get("oper_user_id").toString()));
+            }
+            if(map.get("gs_id") != null){
+                userIds.add(Long.valueOf(map.get("gs_id").toString()));
+            }
+            if(map.get("customer_service_id") != null){
+                userIds.add(Long.valueOf(map.get("customer_service_id").toString()));
+            }
+            String str = (String) map.get("role_amount");
+            if(str!=null&&str.contains("[") && str.contains("]")){
+                //去掉字符串中的‘[]’
+                map.put("role_amount", str.replaceAll("\\[|\\]", ""));
+            }
+
             //去除‘null’字符串
             if ("null".equals(map.get("add_corp_user_id"))) {
                 map.put("add_corp_user_id", null);
@@ -254,13 +278,44 @@ public class RoleManageServiceImpl implements IRoleManageService {
             if ("null".equals(map.get("country"))) {
                 map.put("country", null);
             }
-            return map;
-        }).collect(Collectors.toList());
-
+        }
+        //去重userIds
+        userIds = userIds.stream().distinct().collect(Collectors.toList());
+        //发送RPC接口查询所有用户
+        ResultVO<Map<Long, String>> userMap = sysUserRpc.getUserNameByIds(userIds);
+
+        for (Map map : list) {
+            //投手名
+            updateUserName(map, "put_user_id", "put_user_name", userMap);
+            //运营人员名
+            updateUserName(map, "oper_user_id", "oper_user_name", userMap);
+            //GS人员名
+            updateUserName(map, "gs_id", "gs_name", userMap);
+            //客服人员名
+            updateUserName(map, "customer_service_id", "customer_service_name", userMap);
+        }
         //返回结果
         return new Page<>(list, pager);
     }
 
+    // 更新用户名称
+    private void updateUserName(Map<String, Object> map, String userIdKey, String userNameKey, ResultVO<Map<Long, String>> userMap) {
+        Object userIdObj = map.get(userIdKey);
+        if (userIdObj != null) {
+            try {
+                long userId = Long.parseLong(userIdObj.toString());
+                String userName = userMap.getData().get(userId);
+                if (userName != null) {
+                    map.put(userNameKey, userName);
+                }
+            } catch (NumberFormatException e) {
+                // 处理长整型转换异常
+                log.error("Error parsing user ID for key " + userIdKey + ": " + e.getMessage());
+            }
+        }
+    }
+
+
     private Criteria spliceRechargeTotalAmountWithin24h(RoleRechargeRankingDTO dto, Criteria criA) {
         switch (dto.getRechargeTotalAmountWithin24hUnit()) {
             case ">" -> criA.where().andGT("role_total_amount", dto.getRechargeTotalAmountWithin24h());
@@ -278,12 +333,13 @@ public class RoleManageServiceImpl implements IRoleManageService {
     private Criteria spliceRechargeAmountWithin24h(RoleRechargeRankingDTO dto, Criteria criA) {
         switch (dto.getRechargeAmountWithin24hUnit()) {
             case ">" -> criA.where().andGT("max_amount", dto.getRechargeAmountWithin24h());
-            case ">=" -> criA.where().andGTE("max_amount", dto.getRechargeAmountWithin24h());
-            case "=" -> criA.where().andEquals("max_amount", dto.getRechargeAmountWithin24h());
-            case "<" -> criA.where().andLT("max_amount", dto.getRechargeAmountWithin24h());
-            case "<=" -> criA.where().andLTE("max_amount", dto.getRechargeAmountWithin24h());
+//            case ">=" -> criA.where().andGTE("max_amount", dto.getRechargeAmountWithin24h());
+            //这里用到了array_contains 函数,如果包含则返回1,不包含则返回0
+            case "=" -> criA.where().andEquals("array_contains(role_amount,"+dto.getRechargeAmountWithin24h()+")", 1);
+            case "<" -> criA.where().andLT("min_amount", dto.getRechargeAmountWithin24h());
+//            case "<=" -> criA.where().andLTE("max_amount", dto.getRechargeAmountWithin24h());
             default -> {
-                criA.where().andGTE("max_amount", dto.getRechargeAmountWithin24h());
+                criA.where().andGT("max_amount", dto.getRechargeAmountWithin24h());
             }
         }
         return criA;
@@ -334,6 +390,12 @@ public class RoleManageServiceImpl implements IRoleManageService {
      */
     @Override
     public void createSendMsgTask(SendMsgTaskDTO dto) {
+        //校验游戏id的超父不为2的不让发消息,cp方未提供此功能
+        Map<Long, GameDTO> parentGameMap = getParentGameMap();
+        GameDTO gameDTO = parentGameMap.get(dto.getGameId());
+        if(gameDTO!=null && gameDTO.getSuperGameId()!=2){
+            throw new BaseException(gameDTO.getGameName()+">该游戏不支持发送消息");
+        }
         //获取当前用户id
         Long sysUserId = SecurityUtil.getUserId();
         //构建发送消息dto
@@ -571,17 +633,17 @@ public class RoleManageServiceImpl implements IRoleManageService {
             if(CollectionUtils.isEmpty(sendMsgTaskList.getRecords())){
                 return new Page<>(sendMsgTaskList.getRecords(),sendMsgTaskList.getTotal(),sendMsgTaskList.getSize(),sendMsgTaskList.getCurrent(),sendMsgTaskList.getPages());
             }
-            //查询所有游戏名称map key为游戏id,value为游戏名称
-            Map<Long, String> gameMap = getParentGameMap();
+            //查询所有游戏名称map key为游戏id,value为游戏名称
+            Map<Long, GameDTO> gameMap = getParentGameMap();
 
             //查询创建人id key为创建人id,value为创建人名称
             Map<Long, String> userMap = getCreateByNameMap(sendMsgTaskList);
 
             //循环遍历获取游戏名称, 获取创建人名称
             sendMsgTaskList.getRecords().forEach(item -> {
-                String gameName = gameMap.get(item.getGameId());
-                if (gameName != null){
-                    item.setGameName(gameName);
+                GameDTO gameDTO = gameMap.get(item.getGameId());
+                if (gameDTO!=null && gameDTO.getGameName() != null){
+                    item.setGameName(gameDTO.getGameName());
                 }
                 String userName = userMap.get(item.getCreateBy());
                 if (userName != null){
@@ -610,16 +672,16 @@ public class RoleManageServiceImpl implements IRoleManageService {
     }
 
     /**
-     * 获取游戏列表
+     * 获取游戏列表
      */
-    private Map<Long, String> getParentGameMap(){
+    private Map<Long, GameDTO> getParentGameMap(){
         Sql sql = Sqls.create(getGameSql());
         sql.setCallback(Sqls.callback.entities());
         sql.setEntity(dao.getEntity(GameDTO.class));
         dao.execute(sql);
         List<GameDTO> gameDtoList = sql.getList(GameDTO.class);
-        //将游戏拼成map key为游戏id,value为游戏名称
-        return gameDtoList.stream().collect(Collectors.toMap(GameDTO::getParentId, GameDTO::getGameName));
+        //将游戏拼成map key为游戏id,value为游戏名称
+        return gameDtoList.stream().collect(Collectors.toMap(GameDTO::getId, Function.identity()));
     }
 
     /**
@@ -646,7 +708,7 @@ public class RoleManageServiceImpl implements IRoleManageService {
             Criteria cri = Cnd.cri();
             //拼接游戏ID
             cri.where().andInStrList("role_id", roleId);
-            cri.where().andEquals("parent_id", sendMsgResultVo.getGameId());
+            cri.where().andEquals("b.id", sendMsgResultVo.getGameId());
 
             //补齐参数
             Sql sql = Sqls.create(getTaskResultSql() + cri);
@@ -713,7 +775,7 @@ public class RoleManageServiceImpl implements IRoleManageService {
                             parent_id,
                             super_game_id
                         FROM dm_game_order.t_game
-                        where source_system = 'ZX_ONE' and id = parent_id
+                        where source_system = 'ZX_ONE'
                 """;
     }
 
@@ -1368,7 +1430,9 @@ public class RoleManageServiceImpl implements IRoleManageService {
                 		j.update_by as update_by, -- 更新者
                 		j.is_delete as is_delete, -- 是否删除 1-删除;0-正常
                 		ara.role_total_amount as role_total_amount, -- 创角24小时内总充值金额
-                		ara.max_amount as max_amount -- 创角24小时内单笔最大充值金额
+                		ara.max_amount as max_amount, -- 创角24小时内单笔最大充值金额
+                		ara.min_amount as min_amount, -- 创角24小时内单笔最小充值金额
+                		ara.role_amount as role_amount -- 角色充值数组
                 	FROM
                 	(
                 		SELECT
@@ -1397,8 +1461,10 @@ public class RoleManageServiceImpl implements IRoleManageService {
                 	    SELECT source_system,
                 	    role_id,
                 	    role_total_amount,
-                	    array_max(role_amount) max_amount 
-                	FROM game_ads.ads_role_amount 
+                	    array_min(role_amount) min_amount,
+                	    array_max(role_amount) max_amount,
+                	    role_amount
+                	FROM game_ads.ads_role_amount
                 	) ara on a.role_id = ara.role_id and a.source_system = ara.source_system
                 	LEFT JOIN (
                 		SELECT
@@ -1777,7 +1843,9 @@ public class RoleManageServiceImpl implements IRoleManageService {
                         j.update_by as update_by, -- 更新者
                         j.is_delete as is_delete, -- 是否删除 1-删除;0-正常
                         ara.role_total_amount as role_total_amount, -- 创角24小时内总充值金额
-                		ara.max_amount as max_amount -- 创角24小时内单笔最大充值金额
+                		ara.max_amount as max_amount, -- 创角24小时内单笔最大充值金额
+                		ara.min_amount as min_amount, -- 创角24小时内单笔最小充值金额
+                		ara.role_amount as role_amount -- 角色充值数组
                     FROM
                     (
                         SELECT
@@ -1807,7 +1875,9 @@ public class RoleManageServiceImpl implements IRoleManageService {
                 	        source_system,
                 	        role_id,
                 	        role_total_amount,
-                	        array_max(role_amount) max_amount 
+                	        array_min(role_amount) min_amount,
+                	        array_max(role_amount) max_amount,
+                	        role_amount
                 	    FROM game_ads.ads_role_amount 
                 	) ara on a.role_id = ara.role_id and a.source_system = ara.source_system
                     LEFT JOIN (

+ 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);
+
     /**
      * 获取待接入列表
      *

+ 65 - 11
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfAppletMsgServiceImpl.java

@@ -2,12 +2,14 @@ package com.zanxiang.game.module.manage.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.zanxiang.erp.security.util.SecurityUtil;
 import com.zanxiang.game.back.base.pojo.enums.OrderStatusEnum;
 import com.zanxiang.game.module.manage.constant.RedisKeyConstant;
 import com.zanxiang.game.module.manage.enums.KfRoomMsgOwnerEnum;
 import com.zanxiang.game.module.manage.enums.KfRoomMsgTypeEnum;
 import com.zanxiang.game.module.manage.enums.KfWebSocketMsgEnum;
+import com.zanxiang.game.module.manage.enums.OrderStateEnum;
 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;
@@ -17,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;
@@ -35,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
@@ -99,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);
@@ -117,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())
@@ -149,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));
@@ -184,6 +198,27 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
         if (kfSystemReply == null) {
             return;
         }
+        //查询玩家信息
+        KfSessionUser kfSessionUser = kfSessionUserService.getById(openId, gameId);
+        //判断是否开启充值自动回复
+        if (Objects.equals(kfSystemReply.getRechargeReplySwitch(), Boolean.TRUE)) {
+            //查询订单
+            List<Order> orderList = orderService.list(new LambdaQueryWrapper<Order>()
+                    .select(Order::getAmount)
+                    .eq(Order::getUserId, kfSessionUser.getUserId())
+                    .eq(Order::getGameId, gameId)
+                    .eq(Order::getStatus, OrderStateEnum.SUCCESS_PAY.getCode()));
+            //玩家符合条件
+            if (CollectionUtils.isNotEmpty(orderList) && orderList.stream().map(Order::getAmount)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add).intValue() >= kfSystemReply.getRechargeReplyAmount()) {
+                //发送消息
+                this.sysMsgSend(gameId, openId, kfSystemReply.getRechargeReplyContent(), kfRoom);
+            }
+        }
+        //判断玩家是否已接入状态, 非带接入状态, 不发送
+        if (Objects.equals(kfSessionUser.getIsWait(), Boolean.FALSE)) {
+            return;
+        }
         //判断当前时间是否在时间内
         LocalTime nowTime = LocalTime.now();
         LocalTime startTime = LocalTime.parse(kfSystemReply.getStartTime());
@@ -191,9 +226,14 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
         if (nowTime.isAfter(startTime) && nowTime.isBefore(endTime)) {
             return;
         }
+        //休息时间, 发送指定消息
+        this.sysMsgSend(gameId, openId, kfSystemReply.getSysReply(), kfRoom);
+    }
+
+    private void sysMsgSend(Long gameId, String openId, String msgContent, KfRoom kfRoom) {
         //休息时间, 发送指定消息
         Map<String, Object> textMap = new HashMap<>(1);
-        textMap.put("content", kfSystemReply.getSysReply());
+        textMap.put("content", msgContent);
         Map<String, Object> msgParamMap = new HashMap<>(3);
         msgParamMap.put("touser", openId);
         msgParamMap.put("msgtype", KfRoomMsgTypeEnum.KF_MSG_TYPE_TEXT.getValue());
@@ -201,7 +241,7 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
         kfWxApiService.sendCustomMessageApi(gameId, msgParamMap);
         //保存消息
         Map<String, Object> kfRoomMsgMap = new HashMap<>(1);
-        kfRoomMsgMap.put("text", kfSystemReply.getSysReply());
+        kfRoomMsgMap.put("text", msgContent);
         kfRoomMsgService.save(this.transform(openId, gameId, kfRoom, KfRoomMsgTypeEnum.KF_MSG_TYPE_TEXT, JsonUtil.toString(kfRoomMsgMap)));
     }
 
@@ -293,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())
@@ -304,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;
 
     /**

+ 15 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/KfSystemReply.java

@@ -41,6 +41,21 @@ public class KfSystemReply {
      */
     private String workSysReply;
 
+    /**
+     * 充值回复开关
+     */
+    private Boolean rechargeReplySwitch;
+
+    /**
+     * 充值回复金额限定
+     */
+    private Integer rechargeReplyAmount;
+
+    /**
+     * 充值回复内容
+     */
+    private String rechargeReplyContent;
+
     /**
      * 开始时间
      */