瀏覽代碼

fix : Websocket快捷回复的增删改查

bilingfeng 1 年之前
父節點
當前提交
b7733e662d
共有 12 個文件被更改,包括 360 次插入4 次删除
  1. 1 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/ManageApplication.java
  2. 39 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/enums/KfOperateEnum.java
  3. 32 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/dto/KfWebSocketMsgDTO.java
  4. 25 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/params/KfWebSocketMsgParam.java
  5. 49 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfQuickReplyService.java
  6. 8 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfAppletMsgServiceImpl.java
  7. 82 0
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfQuickReplyServiceImpl.java
  8. 1 2
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfRoomServiceImpl.java
  9. 51 1
      game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/websocket/KfMsgWebsocketHandler.java
  10. 5 0
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/Game.java
  11. 55 0
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/KfQuickReply.java
  12. 12 0
      game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/mapper/KfQuickReplyMapper.java

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

@@ -23,7 +23,7 @@ public class ManageApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(ManageApplication.class, args);
-        System.out.println("赞象Manage服务启动成功 <Websocket图片消息处理01> ( ´・・)ノ(._.`) \n" +
+        System.out.println("赞象Manage服务启动成功 <Websocket快捷回复的增删改查> ( ´・・)ノ(._.`) \n" +
                 "___  ___  ___   _   _   ___  _____  _____ \n" +
                 "|  \\/  | / _ \\ | \\ | | / _ \\|  __ \\|  ___|\n" +
                 "| .  . |/ /_\\ \\|  \\| |/ /_\\ \\ |  \\/| |__  \n" +

+ 39 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/enums/KfOperateEnum.java

@@ -0,0 +1,39 @@
+package com.zanxiang.game.module.manage.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-03-05
+ * @description : 快捷回复操作
+ */
+@Getter
+@AllArgsConstructor
+public enum KfOperateEnum {
+
+    /**
+     * 添加
+     */
+    KF_OPERATE_ADD("KF_OPERATE_ADD"),
+
+    /**
+     * 删除
+     */
+    KF_OPERATE_DELETE("KF_OPERATE_DELETE"),
+
+    /**
+     * 修改
+     */
+    KF_OPERATE_UPDATE("KF_OPERATE_UPDATE"),
+
+    /**
+     * 查询
+     */
+    KF_OPERATE_SELECT("KF_OPERATE_SELECT");
+
+    /**
+     * 交互类型
+     */
+    private String value;
+}

+ 32 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/pojo/dto/KfWebSocketMsgDTO.java

@@ -1,5 +1,6 @@
 package com.zanxiang.game.module.manage.pojo.dto;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.zanxiang.erp.security.util.SecurityUtil;
 import com.zanxiang.game.module.manage.enums.KfRoomMsgTypeEnum;
 import com.zanxiang.game.module.manage.enums.KfWebSocketMsgEnum;
@@ -90,6 +91,11 @@ public class KfWebSocketMsgDTO {
      */
     private List<OrderBean> orderList;
 
+    /**
+     * 快捷回复列表
+     */
+    private List<QuickReplyBean> quickReplyList;
+
     public KfWebSocketMsgDTO(KfWebSocketMsgEnum webSocketMsgType, Integer errorCode, String errorMsg) {
         this.webSocketMsgType = webSocketMsgType;
         this.kfUserId = SecurityUtil.getUserId();
@@ -107,6 +113,32 @@ public class KfWebSocketMsgDTO {
         return new KfWebSocketMsgDTO(webSocketMsgType, 400, errorMsg);
     }
 
+    public static KfWebSocketMsgDTO.PageBean transformPage(Page<?> pageBean) {
+        return KfWebSocketMsgDTO.PageBean.builder()
+                .pageNum(pageBean.getCurrent())
+                .pageSize(pageBean.getSize())
+                .pageTotal(pageBean.getPages())
+                .total(pageBean.getTotal())
+                .build();
+    }
+
+    @Data
+    @Builder
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class QuickReplyBean {
+
+        /**
+         * 主键id
+         */
+        private Long id;
+
+        /**
+         * 内容
+         */
+        private String content;
+    }
+
     @Data
     @Builder
     @AllArgsConstructor

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

@@ -1,5 +1,6 @@
 package com.zanxiang.game.module.manage.pojo.params;
 
+import com.zanxiang.game.module.manage.enums.KfOperateEnum;
 import com.zanxiang.game.module.manage.enums.KfRoomMsgTypeEnum;
 import com.zanxiang.game.module.manage.enums.KfWebSocketMsgEnum;
 import lombok.Data;
@@ -47,6 +48,30 @@ public class KfWebSocketMsgParam {
      */
     private MsgContentBean msgContent;
 
+    /**
+     * 快捷回复
+     */
+    private QuickReplyBean quickReplyBean;
+
+    @Data
+    public static class QuickReplyBean {
+
+        /**
+         * 交互类型, 必传
+         */
+        private KfOperateEnum kfOperateEnum;
+
+        /**
+         * 主键id, 删除和修改的时候必传
+         */
+        private Long id;
+
+        /**
+         * 内容, 添加和修改的时候必传
+         */
+        private String content;
+    }
+
     @Data
     public static class MsgContentBean {
 

+ 49 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/IKfQuickReplyService.java

@@ -0,0 +1,49 @@
+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.KfQuickReply;
+import reactor.util.function.Tuple2;
+
+import java.util.List;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-03-05
+ * @description : 客服快捷回复
+ */
+public interface IKfQuickReplyService extends IService<KfQuickReply> {
+
+    /**
+     * 添加快捷回复
+     *
+     * @param param : 参数
+     * @return : 返回结果
+     */
+    boolean quickReplyAdd(KfWebSocketMsgParam.QuickReplyBean param);
+
+    /**
+     * 删除快捷回复
+     *
+     * @param param : 参数
+     * @return : 返回结果
+     */
+    boolean quickReplyDelete(KfWebSocketMsgParam.QuickReplyBean param);
+
+    /**
+     * 更新快捷回复
+     *
+     * @param param : 参数
+     * @return : 返回结果
+     */
+    boolean quickReplyUpdate(KfWebSocketMsgParam.QuickReplyBean param);
+
+    /**
+     * 分页查询
+     *
+     * @param pageBean : 分页参数
+     * @return : 返回
+     */
+    Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.QuickReplyBean>> quickReplyList(KfWebSocketMsgParam.PageBean pageBean);
+}

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

@@ -34,6 +34,7 @@ import java.io.IOException;
 import java.math.BigDecimal;
 import java.net.URI;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.*;
 
 /**
@@ -162,6 +163,13 @@ public class KfAppletMsgServiceImpl implements IKfAppletMsgService {
         if (Strings.isBlank(orderId)) {
             return;
         }
+        //判断玩家当天是否发送过消息
+        if (kfRoomMsgService.count(new LambdaQueryWrapper<KfRoomMsg>()
+                .eq(KfRoomMsg::getOpenId, kfAppletMsgDTO.getFromUserName())
+                .ge(KfRoomMsg::getCreateTime, LocalDateTime.now().with(LocalTime.MIDNIGHT))
+        ) <= 0) {
+            return;
+        }
         //查询订单
         Order order = orderService.getOne(new LambdaQueryWrapper<Order>()
                 .eq(Order::getOrderId, orderId)

+ 82 - 0
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/service/impl/KfQuickReplyServiceImpl.java

@@ -0,0 +1,82 @@
+package com.zanxiang.game.module.manage.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zanxiang.erp.security.util.SecurityUtil;
+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.IKfQuickReplyService;
+import com.zanxiang.game.module.mybatis.entity.KfQuickReply;
+import com.zanxiang.game.module.mybatis.mapper.KfQuickReplyMapper;
+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.time.LocalDateTime;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-03-05
+ * @description : 客服快捷回复
+ */
+@Slf4j
+@Service
+public class KfQuickReplyServiceImpl extends ServiceImpl<KfQuickReplyMapper, KfQuickReply> implements IKfQuickReplyService {
+
+    @Override
+    public boolean quickReplyAdd(KfWebSocketMsgParam.QuickReplyBean param) {
+        return super.save(KfQuickReply.builder()
+                .kfUserId(SecurityUtil.getUserId())
+                .content(param.getContent())
+                .status(Boolean.TRUE)
+                .createTime(LocalDateTime.now())
+                .updateTime(LocalDateTime.now())
+                .build());
+    }
+
+    @Override
+    public boolean quickReplyDelete(KfWebSocketMsgParam.QuickReplyBean param) {
+        return super.update(new LambdaUpdateWrapper<KfQuickReply>()
+                .set(KfQuickReply::getStatus, Boolean.FALSE)
+                .set(KfQuickReply::getUpdateTime, LocalDateTime.now())
+                .eq(KfQuickReply::getId, param.getId())
+                .eq(KfQuickReply::getKfUserId, SecurityUtil.getUserId())
+        );
+    }
+
+    @Override
+    public boolean quickReplyUpdate(KfWebSocketMsgParam.QuickReplyBean param) {
+        return super.update(new LambdaUpdateWrapper<KfQuickReply>()
+                .set(KfQuickReply::getContent, param.getContent())
+                .set(KfQuickReply::getUpdateTime, LocalDateTime.now())
+                .eq(KfQuickReply::getId, param.getId())
+                .eq(KfQuickReply::getKfUserId, SecurityUtil.getUserId())
+        );
+    }
+
+    @Override
+    public Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.QuickReplyBean>> quickReplyList(KfWebSocketMsgParam.PageBean pageBean) {
+        Page<KfQuickReply> kfQuickReplyPage = super.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()),
+                new QueryWrapper<KfQuickReply>().lambda()
+                        .eq(KfQuickReply::getKfUserId, SecurityUtil.getUserId())
+                        .eq(KfQuickReply::getStatus, Boolean.TRUE)
+                        .orderByDesc(KfQuickReply::getCreateTime)
+        );
+        List<KfWebSocketMsgDTO.QuickReplyBean> quickReplyList = kfQuickReplyPage.getRecords().stream()
+                .map(this::transform).collect(Collectors.toList());
+        return Tuples.of(KfWebSocketMsgDTO.transformPage(kfQuickReplyPage), quickReplyList);
+    }
+
+    private KfWebSocketMsgDTO.QuickReplyBean transform(KfQuickReply kfQuickReply) {
+        if (kfQuickReply == null) {
+            return null;
+        }
+        return BeanUtil.copy(kfQuickReply, KfWebSocketMsgDTO.QuickReplyBean.class);
+    }
+}

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

@@ -275,8 +275,7 @@ public class KfRoomServiceImpl extends ServiceImpl<KfRoomMapper, KfRoom> impleme
         Page<Order> orderPage = orderService.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()),
                 new QueryWrapper<Order>().lambda()
                         .eq(Order::getUserId, kfSessionUser.getUserId())
-                        //todo : 这里要放开
-                        //.eq(Order::getStatus, OrderStateEnum.SUCCESS_PAY.getCode())
+                        .eq(Order::getStatus, OrderStateEnum.SUCCESS_PAY.getCode())
                         .orderByDesc(Order::getCreateTime)
         );
         //构造订单列表

+ 51 - 1
game-module/game-module-manage/src/main/java/com/zanxiang/game/module/manage/websocket/KfMsgWebsocketHandler.java

@@ -4,11 +4,13 @@ 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.KfOperateEnum;
 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.pojo.dto.KfWebSocketMsgDTO;
 import com.zanxiang.game.module.manage.pojo.params.KfWebSocketMsgParam;
+import com.zanxiang.game.module.manage.service.IKfQuickReplyService;
 import com.zanxiang.game.module.manage.service.IKfRoomMsgService;
 import com.zanxiang.game.module.manage.service.IKfRoomService;
 import com.zanxiang.game.module.manage.service.IKfSessionUserService;
@@ -63,6 +65,9 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
     @Autowired
     private KfWxApiService wxApiService;
 
+    @Autowired
+    private IKfQuickReplyService kfQuickReplyService;
+
     /**
      * websocket连接建立成功
      */
@@ -119,7 +124,7 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
                 getOrderList(session, param);
                 break;
             case WEBSOCKET_MSG_QUICK_REPLY:
-                // 快捷回复,可以添加对应的处理逻辑
+                quickReply(session, param);
                 break;
             default:
                 this.sendMessage(session, KfWebSocketMsgDTO.fail(webSocketMsgType, "参数错误, 未知的消息类型"));
@@ -156,10 +161,51 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
         return false;
     }
 
+    private void quickReply(WebSocketSession session, KfWebSocketMsgParam param) {
+        KfWebSocketMsgParam.QuickReplyBean quickReplyBean = param.getQuickReplyBean();
+        if (quickReplyBean == null) {
+            this.sendMessage(session, KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
+                    "快捷回复参数错误, 参数对象不可为空, param : " + JsonUtil.toString(param)));
+            return;
+        }
+        //查询
+        if (Objects.equals(quickReplyBean.getKfOperateEnum(), KfOperateEnum.KF_OPERATE_SELECT)) {
+            Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.QuickReplyBean>> tuple2 = kfQuickReplyService
+                    .quickReplyList(param.getPage());
+            this.sendMessage(session, KfWebSocketMsgDTO.builder()
+                    .webSocketMsgType(param.getWebSocketMsgType())
+                    .page(tuple2.getT1())
+                    .quickReplyList(tuple2.getT2())
+                    .build());
+            return;
+        }
+        //处理不同类型的消息
+        Boolean result = null;
+        switch (quickReplyBean.getKfOperateEnum()) {
+            case KF_OPERATE_ADD:
+                result = kfQuickReplyService.quickReplyAdd(param.getQuickReplyBean());
+                break;
+            case KF_OPERATE_DELETE:
+                result = kfQuickReplyService.quickReplyDelete(param.getQuickReplyBean());
+                break;
+            case KF_OPERATE_UPDATE:
+                result = kfQuickReplyService.quickReplyUpdate(param.getQuickReplyBean());
+                break;
+            default:
+        }
+        if (result != null && result) {
+            this.sendMessage(session, KfWebSocketMsgDTO.ok(param.getWebSocketMsgType()));
+            return;
+        }
+        this.sendMessage(session, KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
+                "快捷回复操作失败, param : " + JsonUtil.toString(param)));
+    }
+
     private void getUser(WebSocketSession session, KfWebSocketMsgParam param) {
         if (Strings.isBlank(param.getOpenId())) {
             this.sendMessage(session, KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
                     "获取玩家信息参数错误, openId不可为空, param : " + JsonUtil.toString(param)));
+            return;
         }
         KfWebSocketMsgDTO.UserBean userBean = kfRoomService.getUserBean(param.getOpenId());
         this.sendMessage(session, KfWebSocketMsgDTO.builder()
@@ -173,6 +219,7 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
         if (Strings.isBlank(param.getOpenId())) {
             this.sendMessage(session, KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
                     "获取玩家角色列表参数错误, openId不可为空, param : " + JsonUtil.toString(param)));
+            return;
         }
         Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.GameRoleBean>> tuple2 = kfRoomService
                 .getRoleBeanList(param.getOpenId(), param.getPage());
@@ -188,6 +235,7 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
         if (Strings.isBlank(param.getOpenId())) {
             this.sendMessage(session, KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
                     "获取玩家订单列表参数错误, openId不可为空, param : " + JsonUtil.toString(param)));
+            return;
         }
         Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.OrderBean>> tuple2 = kfRoomService
                 .getOrderBeanList(param.getOpenId(), param.getPage());
@@ -283,6 +331,7 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
         if (param.getRoomId() == null) {
             this.sendMessage(session, KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
                     "获取房间历史消息参数错误, roomId不可为空, param : " + JsonUtil.toString(param)));
+            return;
         }
         //分页获取房间消息列表
         Tuple2<KfWebSocketMsgDTO.PageBean, List<KfWebSocketMsgDTO.RoomMsgBean>> tuple2 = kfRoomMsgService
@@ -308,6 +357,7 @@ public class KfMsgWebsocketHandler implements WebSocketHandler {
         if (Strings.isBlank(param.getOpenId())) {
             this.sendMessage(session, KfWebSocketMsgDTO.fail(param.getWebSocketMsgType(),
                     "接入玩家参数错误, openId不可为空, param : " + JsonUtil.toString(param)));
+            return;
         }
         //触发玩家接入线程锁
         if (!distributedLockComponent.doLock(RedisKeyConstant.KF_MSG_USER_CONNECT_JOIN + param.getOpenId(),

+ 5 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/Game.java

@@ -132,4 +132,9 @@ public class Game implements Serializable {
      */
     private Boolean isCommonGame;
 
+    /**
+     * 应用系统类型, IOS, Android
+     */
+    private String appType;
+
 }

+ 55 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/entity/KfQuickReply.java

@@ -0,0 +1,55 @@
+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.*;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-03-05
+ * @description : ${description}
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+@Builder
+@TableName("t_kf_quick_reply")
+public class KfQuickReply {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 客服id
+     */
+    private Long kfUserId;
+
+    /**
+     * 快捷回复
+     */
+    private String content;
+
+    /**
+     * 是否有效
+     */
+    private Boolean status;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 12 - 0
game-module/game-module-mybatis/src/main/java/com/zanxiang/game/module/mybatis/mapper/KfQuickReplyMapper.java

@@ -0,0 +1,12 @@
+package com.zanxiang.game.module.mybatis.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zanxiang.game.module.mybatis.entity.KfQuickReply;
+
+/**
+ * @author : lingfeng
+ * @time : 2024-03-05
+ * @description : ${description}
+ */
+public interface KfQuickReplyMapper extends BaseMapper<KfQuickReply> {
+}