Parcourir la source

游客自动分配原则,根据上次服务状态,优先分配上次服务客服,若上次服务客服不在线或不存在上次服务客服状况,则优先根据当前在线客服服务人数最少的客服进行分配,和服务上限无关;

779513719 il y a 5 ans
Parent
commit
dac920379d

+ 9 - 3
jim-server/src/main/java/org/jim/server/command/handler/CloseReqHandler.java

@@ -10,6 +10,7 @@ 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.jim.server.model.VisitorDepartmentMiddle;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.tio.core.ChannelContext;
@@ -81,7 +82,10 @@ public class CloseReqHandler extends AbstractCmdHandler
 								chatGroup.set("service_account_type", ServiceAccountOfflineTypeEnum.OFF_LINE.getKey()).update();
 							}
 						}
-
+					}
+					if( VisitTypeEnum.VISITOR.getKey().equals(visitType) ){
+						//修改 sw_visitor_department_middle 表中的 online状态; '用户状态 1:已下线 0:在线'
+						VisitorDepartmentMiddle.dao.findById(user.getId()).set("online",1).update();
 					}
 				}
 			}
@@ -113,9 +117,11 @@ public class CloseReqHandler extends AbstractCmdHandler
 						chatGroup.set("service_account_type", ServiceAccountOfflineTypeEnum.OFF_LINE.getKey()).update();
 					}
 				}
-
 			}
-
+			if( VisitTypeEnum.VISITOR.getKey().equals(visitType) ){
+				//修改 sw_visitor_department_middle 表中的 online状态; '用户状态 1:已下线 0:在线'
+				VisitorDepartmentMiddle.dao.findById(user.getId()).set("online",1).update();
+			}
 			ImAio.remove(userId, "收到关闭请求!");
 		}
 		return ImKit.ConvertRespPacket(new RespBody(Command.COMMAND_CLOSE_REQ, ImStatus.C10021), channelContext);

+ 3 - 1
jim-server/src/main/java/org/jim/server/command/handler/LoginReqHandler.java

@@ -167,7 +167,7 @@ public class LoginReqHandler extends AbstractCmdHandler {
 	}
 
 	/**
-	 * 初始化绑定或者解绑群组;
+	 * 初始化绑定,并且解绑与绑定群组不一致的群组;
 	 */
 	public void bindUnbindGroup(ChannelContext channelContext ,  User user, List<Group> groups)throws Exception{
 		String userId = user.getId();
@@ -197,6 +197,8 @@ public class LoginReqHandler extends AbstractCmdHandler {
 				//为 该群组 绑定 具有查看全部客服权限的 所有客服
 				this.bindGroupForViewAllServiceAccountAuthority(user, group);
 			}
+			//清除 缓存中 不存在于 user中绑定的群组 的群组
+			//例子: 缓存中:1 2 3 4 5; user中要绑定的群组 : 1 2 3; 清除的是: 4 5
 			if(isStore && groupIds != null){
 				for(String groupId : groupIds){
 					messageHelper.getBindListener().onAfterGroupUnbind(channelContext, groupId);

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

@@ -51,12 +51,15 @@ public class UserReqHandler extends AbstractCmdHandler {
 			user = getUserInfo(userId, type);
 			//在线用户
 			if(0 == userReqBody.getType()){
+				//获取所有在线用户信息成功
 				resPacket = new RespBody(Command.COMMAND_GET_USER_RESP,ImStatus.C10005);
 			//离线用户;
 			}else if(1 == userReqBody.getType()){
+				//获取所有离线用户信息成功!
 				resPacket = new RespBody(Command.COMMAND_GET_USER_RESP,ImStatus.C10006);
 			//在线+离线用户;
 			}else if(2 == userReqBody.getType()){
+				//获取用户信息成功!
 				resPacket = new RespBody(Command.COMMAND_GET_USER_RESP,ImStatus.C10003);
 			}
 		}

+ 11 - 0
jim-server/src/main/java/org/jim/server/model/CustomerDepartmentMiddle.java

@@ -0,0 +1,11 @@
+package org.jim.server.model;
+
+import com.jfinal.plugin.activerecord.Model;
+
+/**
+ * @author Darren
+ * @date 2020/2/10 19:06
+ */
+public class CustomerDepartmentMiddle extends Model<CustomerDepartmentMiddle> {
+    public static final CustomerDepartmentMiddle dao = new CustomerDepartmentMiddle();
+}

+ 11 - 0
jim-server/src/main/java/org/jim/server/model/VisitorDepartmentMiddle.java

@@ -0,0 +1,11 @@
+package org.jim.server.model;
+
+import com.jfinal.plugin.activerecord.Model;
+
+/**
+ * @author Darren
+ * @date 2020/2/10 19:04
+ */
+public class VisitorDepartmentMiddle extends Model<VisitorDepartmentMiddle> {
+    public static final VisitorDepartmentMiddle dao = new VisitorDepartmentMiddle();
+}

+ 84 - 45
server-chat/src/main/java/com/cn/service/IMChatLoginServiceProcessor.java

@@ -1,9 +1,7 @@
 package com.cn.service;
 
 import com.alibaba.fastjson.JSONObject;
-import org.jim.server.model.ChatGroup;
-import org.jim.server.model.Conversation;
-import org.jim.server.model.ServiceAccountRoleDepartmentMiddle;
+import org.jim.server.model.*;
 import nl.basjes.shaded.org.springframework.util.CollectionUtils;
 import org.jim.server.enums.*;
 import org.apache.commons.lang3.StringUtils;
@@ -97,6 +95,11 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
                 if( VisitTypeEnum.VISITOR.getKey().equals(visitType) ){
                     //当前访问人为游客
                     user = this.createVisitorData(map);
+                    //修改游客在线状态
+                    Boolean noOnlineService = user.getExtras().getBoolean("noOnlineService");
+                    if(!noOnlineService){
+                        VisitorDepartmentMiddle.dao.findById(user.getId()).set("online",0).update();
+                    }
                 }
             }
         }
@@ -141,7 +144,7 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
     private List<Group> initVisitorGroups(User user) {
         List<Group> groups = disposeVisitorGroupData(user);
         Boolean noOnlineService = user.getExtras().getBoolean("noOnlineService");
-        if(noOnlineService == null){
+        if(!noOnlineService){
             this.createConversation(groups.get(0),user);
         }
         return groups;
@@ -149,6 +152,9 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
 
     /**
      * 处理游客群组数据
+     * 自动分配原则,根据上次服务状态,优先分配上次服务客服,
+     * 若上次服务客服不在线或不存在上次服务客服状况,
+     * 则优先根据当前在线客服服务人数最少的客服进行分配,和服务上限无关;
      * @param user
      * @return {@link {@link List< Group>}}
      * @author Darren
@@ -157,7 +163,7 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
     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
@@ -165,49 +171,82 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
         //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());
-            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);
+        StringBuilder sql1 = new StringBuilder();
+        sql1.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 consumer_id = " + user.getId())
+                .append(" order by create_time desc");
+        //判断 游客在平台下部门下 是否有群组 且判断 游客对应的客服 是否在线
+        ChatGroup chatGroup1 = ChatGroup.dao.findFirst(sql1.toString());
+        boolean isOnline = false;
+        if( null != chatGroup1 ){
+            String accountRoleDepartmentId = chatGroup1.getStr("service_account_role_department_middle_id");
+            //游客对应客服存在 且 在线; isOnline=true;
+            isOnline = serviceAccountContainer.containsKey(accountRoleDepartmentId);
+        }
+        user.getExtras().put("noOnlineService",false);
+        if(!isOnline){
+            // 从当前在线的客服中 获取 连接客户数最少的 客服
+            Map.Entry<String, String> minReceptionNumServiceAccount = this.getServiceAccountMinReceptionNum(serviceAccountContainer);
+            if( null != minReceptionNumServiceAccount ){
+                //当前平台下部门下 存在客服
+                user.getExtras().put("serviceAccountRoleDepartmentId",minReceptionNumServiceAccount.getKey());
+                String sql2 = this.createSelectGroupSql(user);
+                ChatGroup chatGroup2 = ChatGroup.dao.findFirst(sql2);
+                if( null != chatGroup2){
+                    chatGroup2
+                            // 更改 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(chatGroup2);
+                    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));
             }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);
+                //当前平台下部门下 没有在线客服
+                user.getExtras().put("noOnlineService",true);
             }
-            //更改 客服正在 服务的 客户/游客 数量
-            int num = Integer.valueOf(minReceptionNumServiceAccount.getValue());
-            jedisTemplate.hashSet(serviceAccountContainerKey,minReceptionNumServiceAccount.getKey(),String.valueOf(++num));
         }else{
-            //当前平台下部门下 没有在线客服
-            user.getExtras().put("noOnlineService",true);
+            Group group = disposeChatGroupToGroup(chatGroup1);
+            groups.add(group);
+            chatGroup1
+                    // 更改 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();
         }
+
         return groups;
     }
 
@@ -350,7 +389,7 @@ public class IMChatLoginServiceProcessor implements LoginCmdProcessor {
         }
         if( user.getExtras().getBoolean("isCreateConversation")){
             Boolean noOnlineService = user.getExtras().getBoolean("noOnlineService");
-            if(noOnlineService == null){
+            if(!noOnlineService){
                 this.createConversation(groups.get(0),user);
             }
         }