Browse Source

修改群组逻辑

779513719 5 years ago
parent
commit
9e3ee72753
21 changed files with 421 additions and 179 deletions
  1. 7 1
      jim-common/src/main/java/org/jim/common/ImStatus.java
  2. 2 2
      jim-common/src/main/java/org/jim/common/packets/ChatBody.java
  3. 8 0
      jim-server/src/main/java/org/jim/server/command/handler/ChatReqHandler.java
  4. 105 6
      jim-server/src/main/java/org/jim/server/command/handler/CloseReqHandler.java
  5. 1 0
      jim-server/src/main/java/org/jim/server/command/handler/UserReqHandler.java
  6. 29 0
      jim-server/src/main/java/org/jim/server/enums/ConsumerTypeEnum.java
  7. 3 3
      jim-server/src/main/java/org/jim/server/enums/GroupStateEnum.java
  8. 29 0
      jim-server/src/main/java/org/jim/server/enums/MessageStateEnum.java
  9. 2 2
      jim-server/src/main/java/org/jim/server/enums/ServiceAccountOfflineTypeEnum.java
  10. 1 0
      jim-server/src/main/java/org/jim/server/http/DefaultHttpRequestHandler.java
  11. 1 1
      server-chat/src/main/java/com/cn/model/ChatGroup.java
  12. 1 1
      server-chat/src/main/java/com/cn/model/Conversation.java
  13. 1 1
      server-chat/src/main/java/com/cn/model/ConversationRecord.java
  14. 1 1
      server-chat/src/main/java/com/cn/model/RoleDepartmentMiddle.java
  15. 1 1
      server-chat/src/main/java/com/cn/model/ServiceAccount.java
  16. 1 1
      server-chat/src/main/java/com/cn/model/ServiceAccountRoleDepartmentMiddle.java
  17. 0 10
      server-chat/src/main/java/com/cn/ServerChatStart.java
  18. 1 1
      server-chat/src/main/java/com/cn/config/PropertyDataBaseConfigBuilder.java
  19. 10 22
      server-chat/src/main/java/com/cn/listener/IMChatGroupListener.java
  20. 42 37
      server-chat/src/main/java/com/cn/processor/IMChatAsyncChatMessageProcessor.java
  21. 175 89
      server-chat/src/main/java/com/cn/service/IMChatLoginServiceProcessor.java

+ 7 - 1
jim-common/src/main/java/org/jim/common/ImStatus.java

@@ -13,7 +13,13 @@ public enum ImStatus implements Status{
 	C10000(10000,"ok","发送成功"),
 	C10001(10001,"offline","用户不在线"),
 	C10019(10019,"online","用户在线"),
-	C10002(10002,"send failed","消息发送失败,数据格式不正确,请参考:{'from':来源ID,'to':目标ID,'cmd':'消息命令码','createTime':消息创建时间(Long型),'msgType':Integer消息类型,'content':内容}"),
+	C10002(
+			10002,"send failed"
+			,"消息发送失败,数据格式不正确,请参考:" +
+			"{'from':来源ID,'to':目标ID,'cmd':'消息命令码','createTime':消息创建时间(Long型)" +
+			",'msgType':Integer消息类型,'chatType':Integer聊天类型{0:未知,1:群聊,2:私聊}" +
+			",'group_id':String群组id仅在chatType为1时需要,'content':内容}"
+	),
 	C10003(10003,"ok","获取用户信息成功!"),
 	C10004(10004,"get user failed !","获取用户信息失败!"),
 	C10005(10005,"ok","获取所有在线用户信息成功!"),

+ 2 - 2
jim-common/src/main/java/org/jim/common/packets/ChatBody.java

@@ -37,7 +37,7 @@ public class ChatBody extends Message {
 	 * 消息发到哪个群组;
 	 */
 	private String group_id;
-	
+
 	private ChatBody(){}
 	
 	private ChatBody(String id , String from , String to , Integer msgType , Integer chatType , String content , String group_id , Integer cmd , Long createTime , JSONObject extras){
@@ -52,7 +52,7 @@ public class ChatBody extends Message {
 		this.createTime = createTime;
 		this.extras = extras;
 	}
-	
+
 	public static ChatBody.Builder newBuilder(){
 		return new ChatBody.Builder();
 	}

+ 8 - 0
jim-server/src/main/java/org/jim/server/command/handler/ChatReqHandler.java

@@ -43,6 +43,14 @@ public class ChatReqHandler extends AbstractCmdHandler {
 			ImPacket respChatPacket = ChatKit.dataInCorrectRespPacket(channelContext);
 			return respChatPacket;
 		}
+		//对聊天格式进行校验 (在当前系统中 所有的聊天都是 群聊)
+		if( chatBody.getChatType() == ChatType.CHAT_TYPE_PUBLIC.getNumber() ){
+			//群聊
+			if( null == chatBody.getGroup_id() ){
+				ImPacket respChatPacket = ChatKit.dataInCorrectRespPacket(channelContext);
+				return respChatPacket;
+			}
+		}
 		//聊天的业务处理器  (自己定义)
 		List<ChatCmdProcessor> chatProcessors = this.getProcessorNotEqualName(Sets.newHashSet(ImConst.BASE_ASYNC_CHAT_MESSAGE_PROCESSOR),ChatCmdProcessor.class);
 		if(CollectionUtils.isNotEmpty(chatProcessors)){

+ 105 - 6
jim-server/src/main/java/org/jim/server/command/handler/CloseReqHandler.java

@@ -1,16 +1,21 @@
 package org.jim.server.command.handler;
 
-import org.jim.common.ImAio;
-import org.jim.common.ImPacket;
-import org.jim.common.ImStatus;
-import org.jim.common.packets.CloseReqBody;
-import org.jim.common.packets.Command;
-import org.jim.common.packets.RespBody;
+import org.apache.commons.collections4.CollectionUtils;
+import org.jim.common.*;
+import org.jim.common.cache.redis.JedisTemplate;
+import org.jim.common.packets.*;
 import org.jim.common.utils.ImKit;
 import org.jim.common.utils.JsonKit;
 import org.jim.server.command.AbstractCmdHandler;
+import org.jim.server.enums.ServiceAccountOfflineTypeEnum;
+import org.jim.server.enums.VisitTypeEnum;
+import org.jim.server.model.ChatGroup;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.tio.core.ChannelContext;
 
+import java.util.List;
+
 /**
  * 版本: [1.0]
  * 功能说明: 关闭请求cmd命令处理器
@@ -18,6 +23,23 @@ import org.tio.core.ChannelContext;
  */
 public class CloseReqHandler extends AbstractCmdHandler
 {
+
+	private static Logger logger = LoggerFactory.getLogger(CloseReqHandler.class);
+
+	private static JedisTemplate jedisTemplate = null;
+
+	private static final String GROUP_PROPERTY = " group_id,name,avatar,service_account_role_department_middle_id,consumer_id,group_type,company_id,department_id ";
+
+
+	static {
+		try {
+			jedisTemplate = JedisTemplate.me();
+		} catch (Exception e) {
+			logger.info("JedisTemplate初始化失败!");
+			e.printStackTrace();
+		}
+	}
+
 	@Override
 	public ImPacket handler(ImPacket packet, ChannelContext channelContext) throws Exception
 	{
@@ -28,15 +50,92 @@ public class CloseReqHandler extends AbstractCmdHandler
 			//关闭请求消息格式不正确
 			return ImKit.ConvertRespPacket(new RespBody(Command.COMMAND_CLOSE_REQ, ImStatus.C10020), channelContext);
 		}
+		logger.info("执行关闭请求cmd命令处理器,移除客服容器中的客服...");
 		if(closeReqBody == null || closeReqBody.getUserid() == null){
+			ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
+			Client client = imSessionContext.getClient();
+			if( null != client){
+				User user = client.getUser();
+				if( null != user ){
+					String visitType = user.getVisitType();
+					if( VisitTypeEnum.SERVICEACCOUNT.getKey().equals(visitType) ){
+						//移除客服容器中的 客服
+						String serviceAccountContainerKey
+								=  user.getExtras().getString("companyId") + ImConst.SEPARATOR
+								+ user.getExtras().getString("departmentId") + ImConst.SEPARATOR
+								+ VisitTypeEnum.SERVICEACCOUNT.getKey() ;
+						String[] userIdArray = {user.getId()};
+						jedisTemplate.hashDel(serviceAccountContainerKey,userIdArray);
+
+						//判断 客服是否具有查看当前部门下 全部客服通话的权限 如果有移除
+						if( Boolean.valueOf(user.getExtras().getString("hasViewAllServiceAccount")) ){
+							String adminContainerKey = user.getExtras().getString("companyId")
+									+ ImConst.SEPARATOR + user.getExtras().getString("departmentId")
+									+ ImConst.SEPARATOR +  ImConst.ADMIN ;
+							jedisTemplate.listRemove(adminContainerKey,0,user.getId());
+						}
+						List<ChatGroup> chatGroups = ChatGroup.dao.find(this.createSelectGroupSql(user));
+						if( CollectionUtils.isNotEmpty(chatGroups) ){
+							for (ChatGroup chatGroup : chatGroups) {
+								//客服是否是离线状态 1: 是 0: 否
+								chatGroup.set("service_account_type", ServiceAccountOfflineTypeEnum.OFF_LINE.getKey()).update();
+							}
+						}
+
+					}
+				}
+			}
 			ImAio.remove(channelContext, "收到关闭请求");
 		}else{
 			String userId = closeReqBody.getUserid();
+			User user = ImAio.getUser(userId);
+			//访问类型 (SERVICEACCOUNT 客服 / CUSTOMER 客户 / VISITOR 游客)
+			String visitType = user.getVisitType();
+			if( VisitTypeEnum.SERVICEACCOUNT.getKey().equals(visitType) ){
+				//移除客服容器中的 客服
+				String serviceAccountContainerKey
+						=  user.getExtras().getString("companyId") + ImConst.SEPARATOR
+						+ user.getExtras().getString("departmentId") + ImConst.SEPARATOR
+						+ VisitTypeEnum.SERVICEACCOUNT.getKey() ;
+				String[] userIdArray = {userId};
+				jedisTemplate.hashDel(serviceAccountContainerKey,userIdArray);
+				//判断 客服是否具有查看当前部门下 全部客服通话的权限
+				if( Boolean.valueOf(user.getExtras().getString("hasViewAllServiceAccount")) ){
+					String adminContainerKey = user.getExtras().getString("companyId")
+							+ ImConst.SEPARATOR + user.getExtras().getString("departmentId")
+							+ ImConst.SEPARATOR +  ImConst.ADMIN ;
+					jedisTemplate.listRemove(adminContainerKey,0,userId);
+				}
+				List<ChatGroup> chatGroups = ChatGroup.dao.find(this.createSelectGroupSql(user));
+				if( CollectionUtils.isNotEmpty(chatGroups) ){
+					for (ChatGroup chatGroup : chatGroups) {
+						//客服是否是离线状态 1: 是 0: 否
+						chatGroup.set("service_account_type", ServiceAccountOfflineTypeEnum.OFF_LINE.getKey()).update();
+					}
+				}
+
+			}
+
 			ImAio.remove(userId, "收到关闭请求!");
 		}
 		return ImKit.ConvertRespPacket(new RespBody(Command.COMMAND_CLOSE_REQ, ImStatus.C10021), channelContext);
 	}
 
+	private String createSelectGroupSql(User user){
+		StringBuilder sql = new StringBuilder();
+		sql
+				.append(" select ")
+				.append(GROUP_PROPERTY)
+				.append(" from sw_group where 1 = 1 ")
+				.append(" and company_id = " + user.getExtras().getString("companyId"))
+				.append(" and department_id = " + user.getExtras().getString("departmentId"))
+				.append(
+						" and service_account_role_department_middle_id = "
+								+ user.getExtras().getString("serviceAccountRoleDepartmentId")
+				);
+		return sql.toString();
+	}
+
 	@Override
 	public Command command() {
 		return Command.COMMAND_CLOSE_REQ;

+ 1 - 0
jim-server/src/main/java/org/jim/server/command/handler/UserReqHandler.java

@@ -40,6 +40,7 @@ public class UserReqHandler extends AbstractCmdHandler {
 		RespBody resPacket = null;
 		
 		String userId = userReqBody.getUserid();
+		System.out.println("执行获取用户信息消息命令处理器... ");
 		if(StringUtils.isEmpty(userId)) {
 			return ImKit.ConvertRespPacket(new RespBody(Command.COMMAND_GET_USER_RESP, ImStatus.C10004), channelContext);
 		}

+ 29 - 0
jim-server/src/main/java/org/jim/server/enums/ConsumerTypeEnum.java

@@ -0,0 +1,29 @@
+package org.jim.server.enums;
+
+/**
+ * 客户/游客 离线状态 1:离线 0:在线
+ * @author Darren
+ * @date 2020/2/9 19:39
+ */
+public enum ConsumerTypeEnum {
+
+    OFF_LINE(1, "离线状态"),
+    ON_LINE(0, "在线状态");
+
+    private int key;
+    private String desc;
+
+    private ConsumerTypeEnum(int key, String desc) {
+        this.key = key;
+        this.desc = desc;
+    }
+
+    public int getKey() {
+        return key;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+}

+ 3 - 3
jim-server/src/main/java/org/jim/server/enums/GroupStateEnum.java

@@ -1,14 +1,14 @@
 package org.jim.server.enums;
 
 /**
- * 群组状态 1:在线 0:离线
+ * 群组离线状态 1: 离线 0: 在线
  * @author Darren
  * @date 2020/2/7 19:21
  */
 public enum GroupStateEnum {
 
-    ON_LINE(1, "在线状态"),
-    OFF_LINE(0, "离线状态");
+    OFF_LINE(1, "离线状态"),
+    ON_LINE(0, "在线状态");
 
     private int key;
     private String desc;

+ 29 - 0
jim-server/src/main/java/org/jim/server/enums/MessageStateEnum.java

@@ -0,0 +1,29 @@
+package org.jim.server.enums;
+
+/**
+ * sw_group 表中 message_state 群组留言状态 1:留言 0:非留言
+ * @author Darren
+ * @date 2020/2/9 17:14
+ */
+public enum MessageStateEnum {
+
+    YES(1, "留言状态"),
+    NO(0, "非留言状态");
+
+    private int key;
+    private String desc;
+
+    private MessageStateEnum(int key, String desc) {
+        this.key = key;
+        this.desc = desc;
+    }
+
+    public int getKey() {
+        return key;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+}

+ 2 - 2
jim-server/src/main/java/org/jim/server/enums/ServiceAccountOfflineTypeEnum.java

@@ -7,8 +7,8 @@ package org.jim.server.enums;
  */
 public enum ServiceAccountOfflineTypeEnum {
 
-    YES(1, "是离线状态"),
-    NO(0, "不是离线状态");
+    OFF_LINE(1, "离线状态"),
+    ON_LINE(0, "在线状态");
 
     private int key;
     private String desc;

+ 1 - 0
jim-server/src/main/java/org/jim/server/http/DefaultHttpRequestHandler.java

@@ -137,6 +137,7 @@ public class DefaultHttpRequestHandler implements IHttpRequestHandler {
 
 	@Override
 	public HttpResponse handler(HttpRequest request, RequestLine requestLine) throws Exception {
+		log.info("执行 DefaultHttpRequestHandler.handler()方法...");
 		HttpResponse ret = null;
 		try {
 			processCookieBeforeHandler(request, requestLine);

+ 1 - 1
server-chat/src/main/java/com/cn/model/ChatGroup.java

@@ -1,4 +1,4 @@
-package com.cn.model;
+package org.jim.server.model;
 
 import com.jfinal.plugin.activerecord.Model;
 

+ 1 - 1
server-chat/src/main/java/com/cn/model/Conversation.java

@@ -1,4 +1,4 @@
-package com.cn.model;
+package org.jim.server.model;
 
 import com.jfinal.plugin.activerecord.Model;
 

+ 1 - 1
server-chat/src/main/java/com/cn/model/ConversationRecord.java

@@ -1,4 +1,4 @@
-package com.cn.model;
+package org.jim.server.model;
 
 import com.jfinal.plugin.activerecord.Model;
 

+ 1 - 1
server-chat/src/main/java/com/cn/model/RoleDepartmentMiddle.java

@@ -1,4 +1,4 @@
-package com.cn.model;
+package org.jim.server.model;
 
 import com.jfinal.plugin.activerecord.Model;
 

+ 1 - 1
server-chat/src/main/java/com/cn/model/ServiceAccount.java

@@ -1,4 +1,4 @@
-package com.cn.model;
+package org.jim.server.model;
 
 import com.jfinal.plugin.activerecord.Model;
 

+ 1 - 1
server-chat/src/main/java/com/cn/model/ServiceAccountRoleDepartmentMiddle.java

@@ -1,4 +1,4 @@
-package com.cn.model;
+package org.jim.server.model;
 
 import com.jfinal.plugin.activerecord.Model;
 

+ 0 - 10
server-chat/src/main/java/com/cn/ServerChatStart.java

@@ -2,25 +2,15 @@ package com.cn;
 
 import com.cn.config.PropertyDataBaseConfigBuilder;
 import com.cn.listener.IMChatGroupListener;
-import com.cn.model.ServiceAccountRoleDepartmentMiddle;
 import com.cn.processor.IMChatWsHandshakeProcessor;
 import com.cn.service.IMChatLoginServiceProcessor;
-import org.apache.commons.lang3.StringUtils;
 import org.jim.common.ImConfig;
-import org.jim.common.ImConst;
-import org.jim.common.cache.redis.JedisTemplate;
 import org.jim.common.config.PropertyImConfigBuilder;
 import org.jim.common.packets.Command;
-import org.jim.common.utils.PropUtil;
 import org.jim.server.ImServerStarter;
 import org.jim.server.command.CommandManager;
 import org.jim.server.command.handler.HandshakeReqHandler;
 import org.jim.server.command.handler.LoginReqHandler;
-import org.jim.server.enums.VisitTypeEnum;
-import org.tio.core.ssl.SslConfig;
-
-import java.sql.SQLOutput;
-import java.util.List;
 
 /**
  * @author Darren

+ 1 - 1
server-chat/src/main/java/com/cn/config/PropertyDataBaseConfigBuilder.java

@@ -1,11 +1,11 @@
 package com.cn.config;
 
-import com.cn.model.*;
 import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
 import com.jfinal.plugin.druid.DruidPlugin;
 import org.apache.commons.lang3.StringUtils;
 import org.jim.common.utils.Prop;
 import org.jim.common.utils.PropUtil;
+import org.jim.server.model.*;
 
 /**
  * @author Darren

+ 10 - 22
server-chat/src/main/java/com/cn/listener/IMChatGroupListener.java

@@ -1,22 +1,19 @@
 package com.cn.listener;
 
-import com.cn.model.ChatGroup;
+import org.jim.server.model.ChatGroup;
 import org.jim.common.ImAio;
-import org.jim.common.ImConst;
 import org.jim.common.ImPacket;
 import org.jim.common.ImSessionContext;
 import org.jim.common.cache.redis.JedisTemplate;
 import org.jim.common.packets.*;
+import org.jim.server.enums.ConsumerTypeEnum;
 import org.jim.server.enums.GroupStateEnum;
-import org.jim.server.enums.ServiceAccountOfflineTypeEnum;
 import org.jim.server.enums.VisitTypeEnum;
 import org.jim.server.listener.ImGroupListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.tio.core.ChannelContext;
 
-import java.util.Map;
-
 /**
  * @author Darren
  * @date 2020/2/6 15:53
@@ -39,6 +36,7 @@ public class IMChatGroupListener extends ImGroupListener {
     @Override
     public void onAfterUnbind(ChannelContext channelContext, String group) throws Exception {
 
+        logger.info("解绑群组后,执行 onAfterUnbind() 方法...");
         ImSessionContext imSessionContext = (ImSessionContext)channelContext.getAttribute();
         ExitGroupNotifyRespBody exitGroupNotifyRespBody = new ExitGroupNotifyRespBody();
         exitGroupNotifyRespBody.setGroup(group);
@@ -52,26 +50,16 @@ public class IMChatGroupListener extends ImGroupListener {
         }
         //访问类型 (SERVICEACCOUNT 客服 / CUSTOMER 客户 / VISITOR 游客)
         String visitType = clientUser.getVisitType();
-        if( !VisitTypeEnum.SERVICEACCOUNT.equals(visitType) ){
+        if( !VisitTypeEnum.SERVICEACCOUNT.getKey().equals(visitType) ){
             ChatGroup chatGroup = ChatGroup.dao.findById(group);
             if( null != chatGroup ){
-                Integer serviceAccountType = chatGroup.getInt("service_account_type");
-                // service_account_type  客服是否是离线状态 1: 是 0: 否
-                if( ServiceAccountOfflineTypeEnum.NO.getKey() == serviceAccountType ){
-                    //只能更改 客服 是在线时 的群组状态;  group_state 群组状态 1:在线 0:离线
-                    chatGroup.set("group_state", GroupStateEnum.OFF_LINE.getKey()).update();
-                }
+                //更改 group_state: 1 (群组离线状态 1: 离线 0: 在线)
+                //更改 consumer_type: 1 (客户/游客 离线状态 1:离线 0:在线)
+                chatGroup
+                        .set("group_state", GroupStateEnum.OFF_LINE.getKey())
+                        .set("consumer_type", ConsumerTypeEnum.OFF_LINE.getKey())
+                        .update();
             }
-
-        }else{
-            //移除客服容器中的 客服
-            String serviceAccountContainerKey
-                    =  clientUser.getExtras().getString("companyId") + ImConst.SEPARATOR
-                    + clientUser.getExtras().getString("departmentId") + ImConst.SEPARATOR
-                    + VisitTypeEnum.SERVICEACCOUNT.getKey() ;
-            String userId = clientUser.getId();
-            String[] userIdArray = {userId};
-            jedisTemplate.hashDel(serviceAccountContainerKey,userIdArray);
         }
 
         User notifyUser = new User(clientUser.getId(),clientUser.getNick());

+ 42 - 37
server-chat/src/main/java/com/cn/processor/IMChatAsyncChatMessageProcessor.java

@@ -1,8 +1,8 @@
 package com.cn.processor;
 
-import com.cn.model.ChatGroup;
-import com.cn.model.Conversation;
-import com.cn.model.ConversationRecord;
+import org.jim.server.model.ChatGroup;
+import org.jim.server.model.Conversation;
+import org.jim.server.model.ConversationRecord;
 import org.jim.common.ImAio;
 import org.jim.common.packets.ChatBody;
 import org.jim.common.packets.ChatType;
@@ -20,6 +20,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 /**
+ * 异步聊天持久化
  * @author Darren
  * @date 2020/2/6 19:42
  */
@@ -34,46 +35,50 @@ public class IMChatAsyncChatMessageProcessor extends DefaultAsyncChatMessageProc
 
         log.info("聊天记录持久化... 开始:" + sdf.format(new Date()));
 
-        //聊天类型(如 0:未知 1:聊、2:私聊)
+        //聊天类型(如 0:未知 1:聊、2:私聊)
         Integer chatType = chatBody.getChatType();
         //消息类型;(如:0:text、1:image、2:voice、3:vedio、4:music、5:news)
         Integer msgType = chatBody.getMsgType();
         if( ChatType.CHAT_TYPE_PUBLIC.getNumber() == chatType ){
-            //公聊
-            // group_id 与 conversation_id一致
-            Conversation conversation = Conversation.dao.findById(chatBody.getGroup_id());
+            //群聊
+            ChatGroup group = ChatGroup.dao.findById(chatBody.getGroup_id());
+            if( null != group){
+                Conversation conversation = Conversation.dao.findById(group.getLong("conversation_id"));
+                if( null != conversation){
+                    Map<String, Object> conversationRecordAttrs = new HashMap<>();
+                    conversationRecordAttrs.put("id", SnowflakeIdUtils.getInstance().nextId());
+                    conversationRecordAttrs.put("chat_body_id",chatBody.getId());
+                    conversationRecordAttrs.put("content",chatBody.getContent());
+                    conversationRecordAttrs.put("is_recall",0);
+                    String fromId = chatBody.getFrom();
+                    // customerDepartmentId  visitorDepartmentId  serviceAccountRoleDepartmentId
+                    User user = ImAio.getUser(fromId);
+                    String visitType = user.getVisitType();
+                    if(VisitTypeEnum.CUSTOMER.getKey().equals(visitType)){
+                        // CUSTOMER 客户  发送的消息
+                        String companyId = user.getExtras().getString("customerId");
+                        conversationRecordAttrs.put("from_id",Long.valueOf(companyId));
+                        conversationRecordAttrs.put("to_id",conversation.getLong("service_account_id"));
+                        conversationRecordAttrs.put("type",0);
 
-            Map<String, Object> attrs = new HashMap<>();
-            attrs.put("id", SnowflakeIdUtils.getInstance().nextId());
-            attrs.put("chat_body_id",chatBody.getId());
-            attrs.put("content",chatBody.getContent());
-            attrs.put("is_recall",0);
-
-            String fromId = chatBody.getFrom();
-            // customerDepartmentId  visitorDepartmentId  serviceAccountRoleDepartmentId
-            User user = ImAio.getUser(fromId);
-            String visitType = user.getVisitType();
-            if(VisitTypeEnum.CUSTOMER.getKey().equals(visitType)){
-                // CUSTOMER 客户  发送的消息
-                String companyId = user.getExtras().getString("customerId");
-                attrs.put("from_id",Long.valueOf(companyId));
-                attrs.put("to_id",conversation.getLong("service_account_id"));
-                attrs.put("type",0);
-            }else if(VisitTypeEnum.VISITOR.getKey().equals(visitType)){
-                // VISITOR 游客  发送的消息
-                String visitorId = user.getExtras().getString("visitorId");
-                attrs.put("from_id",Long.valueOf(visitorId));
-                attrs.put("to_id",conversation.getLong("service_account_id"));
-                attrs.put("type",0);
-            }else{
-                //SERVICEACCOUNT 客服  发送的消息
-                String serviceAccountId = user.getExtras().getString("serviceAccountId");
-                attrs.put("from_id",Long.valueOf(serviceAccountId));
-                attrs.put("to_id",conversation.getLong("user_id"));
-                attrs.put("type",1);
+                    }else if(VisitTypeEnum.VISITOR.getKey().equals(visitType)){
+                        // VISITOR 游客  发送的消息
+                        String visitorId = user.getExtras().getString("visitorId");
+                        conversationRecordAttrs.put("from_id",Long.valueOf(visitorId));
+                        conversationRecordAttrs.put("to_id",conversation.getLong("service_account_id"));
+                        conversationRecordAttrs.put("type",0);
+                    }else{
+                        //SERVICEACCOUNT 客服  发送的消息
+                        String serviceAccountId = user.getExtras().getString("serviceAccountId");
+                        conversationRecordAttrs.put("from_id",Long.valueOf(serviceAccountId));
+                        conversationRecordAttrs.put("to_id",conversation.getLong("user_id"));
+                        conversationRecordAttrs.put("type",1);
+                    }
+                    conversationRecordAttrs.put("conversation_id",group.getLong("conversation_id"));
+                    ConversationRecord.dao._setAttrs(conversationRecordAttrs).save();
+                }
             }
-            attrs.put("conversation_id",user.getExtras().getLong("conversationId"));
-            ConversationRecord.dao._setAttrs(attrs).save();
+
         }
 
         log.info("聊天记录持久化... 结束:" + sdf.format(new Date()));

+ 175 - 89
server-chat/src/main/java/com/cn/service/IMChatLoginServiceProcessor.java

@@ -1,9 +1,9 @@
 package com.cn.service;
 
 import com.alibaba.fastjson.JSONObject;
-import com.cn.model.ChatGroup;
-import com.cn.model.Conversation;
-import com.cn.model.ServiceAccountRoleDepartmentMiddle;
+import org.jim.server.model.ChatGroup;
+import org.jim.server.model.Conversation;
+import org.jim.server.model.ServiceAccountRoleDepartmentMiddle;
 import nl.basjes.shaded.org.springframework.util.CollectionUtils;
 import org.jim.server.enums.*;
 import org.apache.commons.lang3.StringUtils;
@@ -152,27 +152,52 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
      * @date 2020/2/5 15:25
      */
     private List<Group> disposeVisitorGroupData(User user){
+        List<Group> groups = new ArrayList<>();
+
         //获取 当前平台下 部门下 在线的 客服
         String serviceAccountContainerKey
                 =  user.getExtras().getString("companyId") + ImConst.SEPARATOR
                 + user.getExtras().getString("departmentId") + ImConst.SEPARATOR
                 + VisitTypeEnum.SERVICEACCOUNT.getKey() ;
-        List<Group> groups = new ArrayList<>();
-        //从当前在线的客服中 获取 连接客户数最少的 客服
         //value组成 : Map<String ( serviceAccountRoleDepartmentId ), String (当前连接客户人数)>
         Map<String, String> serviceAccountContainer = jedisTemplate.hashGetAll(serviceAccountContainerKey);
+
+        // //从当前在线的客服中 获取 连接客户数最少的 客服
         Map.Entry<String, String> minReceptionNumServiceAccount = this.getServiceAccountMinReceptionNum(serviceAccountContainer);
         if( null != minReceptionNumServiceAccount ){
             //当前平台下部门下 存在客服
             user.getExtras().put("serviceAccountRoleDepartmentId",minReceptionNumServiceAccount.getKey());
-            //创建临时在线群组 当客户 断开连接时 删除群组
-            Group group = this.createGroup(user);
-            //把 Group 转成 Map 用于 jfianl框架的 添加使用
-            Map<String, Object> attrs = groupToMap(group);
-            attrs.put("service_account_type", ServiceAccountOfflineTypeEnum.NO.getKey());
-            //jfianl框架的 保存
-            ChatGroup.dao._setAttrs(attrs).save();
-            groups.add(group);
+            String sql = this.createSelectGroupSql(user);
+            ChatGroup chatGroup = ChatGroup.dao.findFirst(sql);
+            if( null != chatGroup){
+                chatGroup
+                        // 更改 sw_group 表中 group_state 字段为在线 (群组离线状态 1: 离线 0: 在线)
+                        .set("group_state",GroupStateEnum.ON_LINE.getKey())
+                        // 更改 sw_group 表中 consumer_type 字段为在线 (客户/游客 离线状态 1:离线 0:在线)
+                        .set("consumer_type",ConsumerTypeEnum.ON_LINE.getKey())
+                        // 更改 sw_group 表中 service_account_type 字段为 在线 (客服离线状态 1: 离线 0: 在线)
+                        .set("service_account_type",ServiceAccountOfflineTypeEnum.ON_LINE.getKey())
+                        // 更改 sw_group 表中 message_state 字段为 非留言 (群组留言状态 1:留言 0:非留言)
+                        .set("message_state",MessageStateEnum.NO.getKey())
+                        .update();
+                //之前 客服 和 客户/游客 之间 有群组
+                Group group = disposeChatGroupToGroup(chatGroup);
+                groups.add(group);
+            }else{
+                //创建群组
+                Group group = this.createGroup(user);
+                //把 Group 转成 Map 用于 jfianl框架的 添加使用
+                Map<String, Object> groupAttrs = groupToMap(group);
+                groupAttrs.put("group_state", GroupStateEnum.ON_LINE.getKey());
+                groupAttrs.put("consumer_type", ConsumerTypeEnum.ON_LINE.getKey());
+                //客服是否是离线状态 1: 是 0: 否
+                groupAttrs.put("service_account_type", ServiceAccountOfflineTypeEnum.ON_LINE.getKey());
+                //群组留言状态 1:留言 0:非留言
+                groupAttrs.put("message_state", MessageStateEnum.NO.getKey());
+                //jfianl框架的 保存
+                ChatGroup.dao._setAttrs(groupAttrs).save();
+                groups.add(group);
+            }
             //更改 客服正在 服务的 客户/游客 数量
             int num = Integer.valueOf(minReceptionNumServiceAccount.getValue());
             jedisTemplate.hashSet(serviceAccountContainerKey,minReceptionNumServiceAccount.getKey(),String.valueOf(++num));
@@ -231,33 +256,69 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
                 + user.getExtras().getString("departmentId") + ImConst.SEPARATOR
                 + VisitTypeEnum.SERVICEACCOUNT.getKey() ;
 
+        //是否创建 会话
+        user.getExtras().put("isCreateConversation",true);
+
         List<Group> groups = new ArrayList<>();
-        //是否认领 1:是 0:否
-        String isClaim = user.getExtras().getString("isClaim");
-        //是否加入黑名单 1:是 0:否
-        String isBlack = user.getExtras().getString("isBlack");
-        if( CustomerClaimTypeEnum.YES.getKey().equals(isClaim) && BlackListStateEnum.NO.getKey().equals(isBlack) ){
+        // isClaim: 是否认领 1:是 0:否; isBlack: 是否加入黑名单 1:是 0:否;
+        if(
+                CustomerClaimTypeEnum.YES.getKey().equals(user.getExtras().getString("isClaim")) &&
+                        BlackListStateEnum.NO.getKey().equals(user.getExtras().getString("isBlack"))
+        ){
             //被认领 并且 没有加入黑名单
             String receptionNum
                     = jedisTemplate.hashGet(
-                            serviceAccountContainerKey
+                    serviceAccountContainerKey
                     , user.getExtras().getString("serviceAccountRoleDepartmentId")
             );
             String sql = this.createSelectGroupSql(user);
             ChatGroup chatGroup = ChatGroup.dao.findFirst(sql);
             if( null != chatGroup){
+                //判断  (之前群组 是否是留言群组 且 客服是离线状态)
+                if(
+                    MessageStateEnum.YES.getKey() == chatGroup.getInt("message_state")
+                            && ServiceAccountOfflineTypeEnum.OFF_LINE.getKey() == chatGroup.getInt("service_account_type")
+                ){
+                    //如果 之前群组 客户是否 在线 且 群组是否 在线 或 之前群组 是留言群组 则不重新创建会话
+                    user.getExtras().put("isCreateConversation",false);
+                }
+                chatGroup
+                        // 更改 sw_group 表中 group_state 字段为在线 (群组离线状态 1: 离线 0: 在线)
+                        .set("group_state",GroupStateEnum.ON_LINE.getKey())
+                        // 更改 sw_group 表中 consumer_type 字段为在线 (客户/游客 离线状态 1:离线 0:在线)
+                        .set("consumer_type",ConsumerTypeEnum.ON_LINE.getKey())
+                        .update();
+                //判断当前 认领这个 客户 的客服 是否在线
+                if( StringUtils.isNotBlank(receptionNum) ){
+                    //在线
+                    chatGroup
+                            // 更改 sw_group 表中 service_account_type 字段为 在线 (客服离线状态 1: 离线 0: 在线)
+                            .set("service_account_type",ServiceAccountOfflineTypeEnum.ON_LINE.getKey())
+                            // 更改 sw_group 表中 message_state 字段为 非留言 (群组留言状态 1:留言 0:非留言)
+                            .set("message_state",MessageStateEnum.NO.getKey())
+                            .update();
+                    //更改客服的服务数量
+                    Integer num = Integer.valueOf(receptionNum);
+                    jedisTemplate.hashSet(serviceAccountContainerKey,user.getExtras().getString("serviceAccountRoleDepartmentId"),String.valueOf(++num));
+                }else{
+                    //离线
+                    chatGroup
+                            // 更改 sw_group 表中 service_account_type 字段为 离线 (客服离线状态 1: 离线 0: 在线)
+                            .set("service_account_type",ServiceAccountOfflineTypeEnum.OFF_LINE.getKey())
+                            // 更改 sw_group 表中 message_state 字段为 留言 (群组留言状态 1:留言 0:非留言)
+                            .set("message_state",MessageStateEnum.YES.getKey())
+                            .update();
+                }
                 //之前 客服 和 客户 之间 有群组
                 Group group = disposeChatGroupToGroup(chatGroup);
                 groups.add(group);
-
-                // 更改 sw_group 表中 group_state 字段为在线    (group_state 1:在线 0:离线0
-                chatGroup.set("group_state",GroupStateEnum.ON_LINE.getKey()).update();
             }else{
                 // 创建新的群组
                 Group group = this.createGroup(user);
                 //把 Group 转成 Map 用于 jfianl框架的 添加使用
-                Map<String, Object> attrs = groupToMap(group);
-                attrs.put("group_state", GroupStateEnum.ON_LINE.getKey());
+                Map<String, Object> groupAttrs = groupToMap(group);
+                groupAttrs.put("group_state", GroupStateEnum.ON_LINE.getKey());
+                groupAttrs.put("consumer_type", ConsumerTypeEnum.ON_LINE.getKey());
                 //判断当前 认领这个 客户 的客服 是否在线
                 if( StringUtils.isNotBlank(receptionNum) ){
                     //在线
@@ -265,16 +326,18 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
                     Integer num = Integer.valueOf(receptionNum);
                     jedisTemplate.hashSet(serviceAccountContainerKey,user.getExtras().getString("serviceAccountRoleDepartmentId"),String.valueOf(++num));
                     //客服是否是离线状态 1: 是 0: 否
-                    attrs.put("service_account_type", ServiceAccountOfflineTypeEnum.NO.getKey());
+                    groupAttrs.put("service_account_type", ServiceAccountOfflineTypeEnum.ON_LINE.getKey());
+                    //群组留言状态 1:留言 0:非留言
+                    groupAttrs.put("message_state", MessageStateEnum.NO.getKey());
                 }else{
                     //离线
                     //客服是否是离线状态 1: 是 0: 否
-                    attrs.put("service_account_type", ServiceAccountOfflineTypeEnum.YES.getKey());
+                    groupAttrs.put("service_account_type", ServiceAccountOfflineTypeEnum.OFF_LINE.getKey());
+                    //群组留言状态 1:留言 0:非留言
+                    groupAttrs.put("message_state", MessageStateEnum.YES.getKey());
                 }
-
                 //jfianl框架的 保存
-                ChatGroup.dao._setAttrs(attrs).save();
-
+                ChatGroup.dao._setAttrs(groupAttrs).save();
                 groups.add(group);
             }
 
@@ -282,7 +345,9 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
             //按照游客 方式 处理 找到 在线客服 连接数 最少的
             groups.addAll(this.disposeVisitorGroupData(user));
         }
-        this.createConversation(groups.get(0),user);
+        if( user.getExtras().getBoolean("isCreateConversation")){
+            this.createConversation(groups.get(0),user);
+        }
         return groups;
     }
 
@@ -315,7 +380,7 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
         attrs.put("service_account_id", pojo.getLong("service_account_id"));
         Conversation.dao._setAttrs(attrs).save();
         //保存 会话id 存入user中
-        user.getExtras().put("conversationId",conversationId);
+        ChatGroup.dao.findById(group.getGroup_id()).set("conversation_id",conversationId).update();
     }
 
     /**
@@ -325,7 +390,7 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
      * @author Darren
      * @date 2020/2/4 20:45
      */
-    public String createSelectGroupSql(User user){
+    private String createSelectGroupSql(User user){
         StringBuilder sql = new StringBuilder();
         sql.append(" select ")
                 .append(GROUP_PROPERTY)
@@ -421,11 +486,9 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
         //当前访问人为客服
         user.setId(map.get("serviceAccountRoleDepartmentId"));
         //用户头像
-        String headImg = map.get("headImg");
-        user.setAvatar(headImg);
+        user.setAvatar(map.get("headImg"));
         //user nick
-        String nickname = map.get("nickname");
-        user.setNick(nickname);
+        user.setNick( map.get("nickname"));
         //扩展预留字段;
         Map<String, Object> serviceAccountMap = new HashMap<>();
         serviceAccountMap.put("companyId", map.get("companyId"));
@@ -449,10 +512,9 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
      * @date 2020/2/3 20:29
      */
     private List<Group> initViewAllServiceAccountGroup(User user) {
-        List<Group> groups = null;
+        List<Group> groups = new ArrayList<>();
         //1.判断当前客服是否具有查看当前部门下 全部客服通话的权限
-        String hasViewAllServiceAccount = user.getExtras().getString("hasViewAllServiceAccount");
-        if( Boolean.valueOf(hasViewAllServiceAccount) ){
+        if( Boolean.valueOf(user.getExtras().getString("hasViewAllServiceAccount")) ){
             boolean flag = false;
             //获取 具有查看全部客服通话权限 的客服容器  并且 加入到该容器中   key数据格式: companyId : departmentId : ADMIN
             String adminContainerKey = user.getExtras().getString("companyId")
@@ -473,39 +535,53 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
 
             //... 然后把当前 客服  加入到 该平台下 部门下 所有群组中
             if(flag){
-                //1.从redis中获取数据
-                //获取平台该部门下 所有 群组  key数据格式: companyId : departmentId : GROUP
-                /*String groupContainerKey = user.getExtras().getString("companyId")
-                        + SEPARATOR + user.getExtras().getString("departmentId") + SEPARATOR + GROUP ;
-                Map<String, String> serviceAccountGroupContainer = jedisTemplate.hashGetAll(groupContainerKey);
-                if( !CollectionUtils.isEmpty(serviceAccountGroupContainer) ){
-                    //如果 客服群组容器中 有值 绑定群组
-                    groups = serviceAccountGroupContainer
-                            .values()
-                            .stream()
-                            .map(x -> JsonKit.toBean(x, Group.class))
-                            //过滤掉 属于该客服的群组
-                            .filter(x -> !x.getServiceAccountRoleDepartmentId().equals(user.getId()))
+                //从数据库中获取数据
+                //1.查询所有留言群组
+                StringBuilder sql1 = new StringBuilder();
+                sql1
+                        .append(" select ")
+                        .append(GROUP_PROPERTY)
+                        //message_state: 群组留言状态 1:留言 0:非留言
+                        //group_type: 群组类型 0:游客-客服 类型 1:客户-客服 类型
+                        .append(" from sw_group where group_type = 1 and message_state = 1 ")
+                        .append(" and company_id = "+ user.getExtras().getString("companyId") + " ")
+                        .append(" and department_id = " + user.getExtras().getString("departmentId") + " ");
+                List<ChatGroup> messageChatGroups = ChatGroup.dao.find(sql1.toString());
+                if( !CollectionUtils.isEmpty(messageChatGroups) ){
+                    messageChatGroups = messageChatGroups.stream()
+                            .filter(
+                                    x -> !x.get("service_account_role_department_middle_id").equals(user.getId())
+                            )
                             .collect(Collectors.toList());
-                }else{
-                }*/
-                //2.从数据库中获取数据
-                StringBuilder sql = new StringBuilder();
-                sql
+                    List<Group> messageGroups = this.disposeChatGroupsToGroups(messageChatGroups);
+                    if( !CollectionUtils.isEmpty(messageGroups) ){
+                        groups.addAll(messageGroups);
+                    }
+                }
+
+                //2.查询所有在线群组
+                StringBuilder sql2 = new StringBuilder();
+                sql2
                         .append(" select ")
                         .append(GROUP_PROPERTY)
                         //查看当前平台下 部门下 的所有在线群组
-                        .append(" from sw_group where group_state = 1 ")
+                        //group_state: 群组离线状态 1: 离线 0: 在线
+                        //consumer_type: 客户/游客 离线状态 1:离线 0:在线
+                        //message_state: 群组留言状态 1:留言 0:非留言
+                        .append(" from sw_group where group_state = 0 and consumer_type = 0 and message_state = 0 ")
                         .append(" and company_id = "+ user.getExtras().getString("companyId") + " ")
                         .append(" and department_id = " + user.getExtras().getString("departmentId") + " ");
-                List<ChatGroup> chatGroups = ChatGroup.dao.find(sql.toString());
-                if( !CollectionUtils.isEmpty(chatGroups) ){
-                    chatGroups = chatGroups.stream()
+                List<ChatGroup> onlineChatGroups = ChatGroup.dao.find(sql2.toString());
+                if( !CollectionUtils.isEmpty(onlineChatGroups) ){
+                    onlineChatGroups = onlineChatGroups.stream()
                             .filter(
                                     x -> !x.get("service_account_role_department_middle_id").equals(user.getId())
                             )
                             .collect(Collectors.toList());
-                    groups = this.disposeChatGroupsToGroups(chatGroups);
+                    List<Group> onlineGroups = this.disposeChatGroupsToGroups(onlineChatGroups);
+                    if( !CollectionUtils.isEmpty(onlineGroups) ){
+                        groups.addAll(onlineGroups);
+                    }
                 }
 
             }
@@ -522,44 +598,54 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
      * @date 2020/2/3 19:55
      */
     private List<Group> initServiceAccountGroups(User user) {
-        //1.从redis中获取数据
-        // 查看当前是否有相关该客服的群组  key数据格式: companyId : departmentId : userId : GROUP
-       /* String serviceAccountGroupContainerKey = user.getExtras().getString("companyId")
-                + SEPARATOR + user.getExtras().getString("departmentId") + SEPARATOR + user.getId() + GROUP ;
-        // value 数据结构 (field 域 : value) : consumerId 游客或者客户的 userID : {group 群组对象json串 }
-        Map<String, String> serviceAccountGroupContainer = jedisTemplate.hashGetAll(serviceAccountGroupContainerKey);
-        if( !CollectionUtils.isEmpty(serviceAccountGroupContainer) ){
-            //如果 客服群组容器中 有值 绑定群组
-            groups = serviceAccountGroupContainer
-                    .values()
-                    .stream()
-                    .map(x -> JsonKit.toBean(x, Group.class))
-                    .collect(Collectors.toList());
-        }else{
-        }*/
-        //2.从数据库中获取数据
-        StringBuilder sql = new StringBuilder();
-        sql
+
+        List<ChatGroup> chatGroups = new ArrayList<>();
+        //从数据库中获取数据
+        //2.查询 客户/游客 对应平台下 对应部门下 在线群组状态 和 客户/游客在线状态 和 群组非留言状态
+        StringBuilder sql2 = new StringBuilder();
+        sql2
                 .append(" select ")
                 .append(GROUP_PROPERTY)
-                //  service_account_type = 1 判断 当前的 是否是离线状态下的; group_state 群组状态 1:在线 0:离线
-                .append(" from sw_group where group_state = 1 and service_account_type = 1 and group_type = 1 ")
+                //message_state: 群组留言状态 1:留言 0:非留言
+                //consumer_type: 客户/游客 离线状态 1:离线 0:在线
+                //group_state: 群组离线状态 1: 离线 0: 在线
+                .append(" from sw_group where group_state = 0 and consumer_type = 0 and  message_state = 0")
                 .append(" and company_id = "+ user.getExtras().getString("companyId") + " ")
                 .append(" and department_id = " + user.getExtras().getString("departmentId") + " ")
                 .append(
                         " and service_account_role_department_middle_id = " + user.getId()
                 );
-        List<ChatGroup> chatGroups = ChatGroup.dao.find(sql.toString());
-        List<Group> groups = this.disposeChatGroupsToGroups(chatGroups);
+        List<ChatGroup> onlineChatGroups = ChatGroup.dao.find(sql2.toString());
+        if( !CollectionUtils.isEmpty(onlineChatGroups) ){
+            chatGroups.addAll(onlineChatGroups);
+        }
 
-        //修改 sw_group 字段service_account_type 状态   客服是否是离线状态 1: 是 0: 否
-        if( !CollectionUtils.isEmpty(chatGroups) ){
-            for (ChatGroup chatGroup : chatGroups) {
-                chatGroup .set("service_account_type", ServiceAccountOfflineTypeEnum.NO.getKey())
+        //1.查询 对应平台下 对应部门下 留言群组
+        StringBuilder sql1 = new StringBuilder();
+        sql1
+                .append(" select ")
+                .append(GROUP_PROPERTY)
+                //message_state: 群组留言状态 1:留言 0:非留言
+                //group_type: 群组类型 0:游客-客服 类型 1:客户-客服 类型
+                .append(" from sw_group where group_type = 1 and message_state = 1 ")
+                .append(" and company_id = "+ user.getExtras().getString("companyId") + " ")
+                .append(" and department_id = " + user.getExtras().getString("departmentId") + " ")
+                .append(
+                        " and service_account_role_department_middle_id = " + user.getId()
+                );
+        List<ChatGroup> messageChatGroups = ChatGroup.dao.find(sql1.toString());
+        if( !CollectionUtils.isEmpty(messageChatGroups) ){
+            chatGroups.addAll(messageChatGroups);
+            //修改 sw_group 表中的 message_state 状态;  群组留言状态 1:留言 0:非留言
+            //修改 sw_group 表中的 service_account_type 状态; 客服离线状态 1: 离线 0: 在线
+            for (ChatGroup chatGroup : messageChatGroups) {
+                chatGroup .set("message_state", MessageStateEnum.NO.getKey())
+                        .set("service_account_type",ServiceAccountOfflineTypeEnum.ON_LINE.getKey())
                         .update();
             }
         }
-        return groups;
+
+        return this.disposeChatGroupsToGroups(chatGroups);
     }
 
     /***