瀏覽代碼

Merge branch 'dev' of http://git.bocai108.com:10180/Ethan/Customer-Service into dev

Ethan 6 年之前
父節點
當前提交
3055c4fda1
共有 1 個文件被更改,包括 250 次插入56 次删除
  1. 250 56
      vendor/GatewayWorker_windows/Applications/whisper/Events.php

+ 250 - 56
vendor/GatewayWorker_windows/Applications/whisper/Events.php

@@ -41,6 +41,7 @@ class Events
     const  KFINFOKEY = 'KFINFO';              //客服信息hash表
     const  USERINFOKEY = 'USERINFO';          //用户信息hash表
     const  USERLIST = 'USERLIST';             //用户排队表
+    const  SERVICELOG = 'SERVICELOG';            //工单信息
 
     /**
      * 进程启动后初始化数据库连接
@@ -166,6 +167,7 @@ class Events
                     break;
                 // 客服更改状态.
                 case 'kfOnline':
+                    self::KFStatusCg($client_id, $message);
                     break;
                 case 'changeOtherhKeFu';
                     break;
@@ -200,6 +202,38 @@ class Events
         return;
     }
 
+
+    public static function KFStatusCg($client_id, $message)
+    {
+        if (!isset($_SESSION['iskefu']) || $_SESSION['iskefu'] != 1) {
+            return;
+        }
+
+        $userId = $message['data']['uid'];
+        $status = intval($message['data']['status']);
+        if (!in_array($status, [1, 2, 3])) {
+            return false;
+        }
+        $oldstatus = '';
+        $kfinfo = self::$redis->hget(self::KFINFOKEY, $userId);
+        if (empty($kfinfo)) {
+            return false;
+        }
+        $kfinfo = json_decode($kfinfo, true);
+        if (!$kfinfo) {
+            return false;
+        }
+        if ($kfinfo['status'] != $status) {
+            $oldstatus = $kfinfo['status'];
+            $kfinfo['status'] = $status;
+            self::$redis->hset(self::KFINFOKEY, $userId, json_encode($kfinfo, 256));
+        }
+
+        self::writeLogKfStatus($userId, $status);
+        Gateway::sendToCurrentClient(json_encode(['message_type' => 'cgstatus', 'data' => ['new_status' => $status, 'old_status' => $oldstatus]]));
+        return;
+    }
+
     //获取某个用户全部信息
     public static function getClientIndo($id)
     {
@@ -257,10 +291,10 @@ class Events
                 'group' => $group,
                 'client_id' => $client_id,
                 'task' => 0,
+                'intime' => time(),
                 'signature' => $kfinfo['signature'],
                 'status' => 2, // 1为在线(接收分配、接收消息)2为隐身(不接收分配、只接收消息)3、休息
-                'user_info' => [],  //在会话的用户cid
-                'serverids' => [],
+                'user_info' => [],  //在会话的用户cid  key为clientid ,值为工单号
             ];
 
         self::$redis->hset(self::KFINFOKEY, $uid, json_encode($newinfo, 256));
@@ -330,15 +364,15 @@ class Events
         $uid = intval($message['uid']);
         $group = intval($message['group']);
 
-        if (isset(self::$global->groupmap[$group])) {
+        if (!isset(self::$global->groupmap[$group])) {
             self::MySendMsg($client_id, (json_encode(['message_type' => 'reLoginErr', 'msg' => '不存在客服组....'], 256)));
-            Gateway::closeClient($oldcontid);
+            Gateway::closeCurrentClient();
         }
 
         $loginstate = self::$logic->userIsLogin($client_id, $uid, $group);
         if ($loginstate == 1) {
             self::MySendMsg($oldcontid, (json_encode(['message_type' => 'reLoginErr', 'msg' => '正在登陆中,请稍后...'], 256)));
-            Gateway::closeClient($oldcontid);
+            Gateway::closeCurrentClient();
             return;
         }
 
@@ -372,6 +406,7 @@ class Events
             'group' => $message['group'],
             'intime' => time(),
             'kfuid' => '',
+            'ip' => $_SESSION['remotip'],
             'serverid' => 0,
             'client_id' => $client_id
         ];
@@ -390,7 +425,7 @@ class Events
         $_SESSION['uid'] = $message['uid'];
 
         // 尝试分配新会员进入服务
-        self::userOnlineTask($group, $uid = 0);
+        self::userOnlineTask($group, $uid);
     }
 
     /**
@@ -538,32 +573,202 @@ class Events
      * @param $uid
      */
     private static function userOnlineTask($group = 0, $uid = 0)
+    {
+        $allusergkarr = self::getUserListData();
+        if (empty($allusergkarr)) {
+            return;
+        }
+
+        $allkfgkarr = self::getWorkKfData();
+        if (empty($allkfgkarr)) {
+            return;
+        }
+
+        $maxset = (self::$global->systemconfig)['KFMaxServices'] ?? 5;
+        $maxset = intval($maxset);
+
+        if ($group && $uid) {
+            // 指定用指定组 [可能存在断线重连的情况] 如果存在旧的会话,直接连线客服和用户
+            //否则按先到后到以及客服最大服务数限制
+            $last = self::UserHasOldTalk($uid);
+            echo "last-> " . print_r($last, true) . "\n";
+            if ($last) {
+                self::BeginTalk(self::getkfuid($last['kf_id']), $uid, $last['group_id'], $last['servicelog_id']);
+                return;
+            }
+        }
+
+        //系统定时调用时,无组,无用户
+        foreach ($allusergkarr as $group => $gusersArr) {
+            if (!isset($allkfgkarr[$group]) || count($allkfgkarr[$group]) <= 0) {
+                //所属客服组无人在线
+                continue;
+            }
+            $nowkfs = $allkfgkarr[$group];
+            $count = count($nowkfs);
+            $i = 0;
+
+            foreach ($gusersArr as $user) {
+                if ($nowkfs[$i]['task'] > $maxset) {
+                    break;
+                }
+                $nowkfs[$i]['task']++;
+
+                self::BeginTalk($nowkfs[$i]['id'], $user['id'], $group, 0, $user);
+                self::$redis->hdel(self::USERLIST, $user['id']);
+
+                $i++;
+                if ($i >= $count) {
+                    $i = 0;
+                }
+            }
+        }
+        return;
+    }
+
+    //开启一个会话
+    private static function BeginTalk($kfuid, $uid, $group, $serviceid = 0, $userInfo = false)
+    {
+
+        $serviceid = intval($serviceid);
+        if (!$userInfo) {
+            $userInfo = json_decode(self::$redis->hget(self::USERINFOKEY, $uid), true);
+        }
+        $kfinfo = json_decode(self::$redis->hget(self::KFINFOKEY, $kfuid), true);
+        if (empty($userInfo) || empty($kfinfo)) {
+            return false;
+        }
+
+        $server = [];
+        $armarr = [];
+        if ($serviceid) {
+            $server = self::$db->select('*')->from('ws_service_log')->where("servicelog_id=$serviceid ")->row();
+            if ($server) {
+                $armarr = self::$db->select('*')->from('ws_alarm')->where("servicelog_id=$serviceid ")->row();
+            }
+        }
+
+        if (empty($server)) {
+            $array = [
+                'user_id' => $uid,
+                'client_id' => $userInfo['client_id'],
+                'user_name' => $userInfo['name'],
+                'user_avatar' => $userInfo['avatar'],
+                'user_ip' => $userInfo['ip'],
+                'kf_id' => self::getkfid($kfuid),
+                'start_time' => time(),
+                'group_id' => $userInfo['group'],
+                'website' => $userInfo['website'],
+                'system' => $userInfo['system'],
+                'browse' => $userInfo['browse'],
+                'intime' => $userInfo['intime'],
+            ];
+            $serviceid = self::$db->insert('ws_service_log')->cols($array)->query();
+            $server = array_merge(['servicelog_id' => $serviceid], $array);
+            $armid = self::$db->insert('ws_alarm')->cols(['servicelog_id' => $serviceid])->query();
+            $armarr = self::$db->select('*')->from('ws_alarm')->where("alarm_id=$armid")->row();
+        }
+
+        $redisData = array_merge($server, $armarr, ['kf_client_id' => $kfinfo['client_id']]);
+        self::$redis->hset(self::SERVICELOG, $serviceid, json_encode($redisData, 256));
+
+        $kfinfo['user_info'] = array_merge($kfinfo['user_info'], [$userInfo['client_id'] => $serviceid]);
+        $kfinfo['task'] = count($kfinfo['user_info']);
+        self::$redis->hset(self::KFINFOKEY, $kfuid, json_encode($kfinfo, 256));
+
+        $userInfo['serverid'] = $serviceid;
+        $userInfo['kfuid'] = $kfuid;
+        self::$redis->hset(self::USERINFOKEY, $uid, json_encode($userInfo, 256));
+
+        // 通知会员发送信息绑定客服的id
+        $noticeUser = [
+            'message_type' => 'connect',
+            'data' => [
+                'kf_id' => $kfuid,
+                'conversationId' => $serviceid,
+                'serverInfo' => $kfinfo,
+                'kf_name' => $kfinfo['job_name']
+            ]
+        ];
+        self::MySendMsg($userInfo['client_id'], json_encode($noticeUser, 256));
+
+
+        $sayHello = self::$db->query('select `word`,`status` from `ws_reply` where `id` = 2');
+        if (!empty($sayHello) && 1 == $sayHello['0']['status']) {
+            $chat_message = [
+                'message_type' => 'chatMessage',
+                'data' => [
+                    'id' => self::getkfuid($kfinfo['id']),
+                    'name' => $kfinfo['name'],
+                    'time' => date('H:i'),
+                    'content' => $sayHello['0']['word']
+                ]
+            ];
+            self::MySendMsg($userInfo['client_id'], json_encode($chat_message, 256));
+            unset($chat_message);
+        }
+
+
+        $noticeKf = [
+            'message_type' => 'connect',
+            'data' => [
+                'user_info' => $userInfo,
+                'conversationId' => $serviceid,
+            ]
+        ];
+        self::MySendMsg($kfinfo['client_id'], json_encode($noticeKf, 256));
+        unset($noticeKf);
+
+        $key = date('Ymd') . 'success_in';
+        $oldKey = date('Ymd', strtotime('-1 day')); // 删除前一天的统计值
+        unset(self::$global->$oldKey);
+        self::$global->increment($key);
+
+        return;
+    }
+
+
+    //用户排队数据  按组
+    private static function getUserListData()
     {
         $alluser = self::$redis->hgetall(self::USERLIST);
         if (empty($alluser)) {
-            return true;
+            return false;
         }
         $allusergkarr = [];
         foreach ($alluser as $val) {
-            $now = json_decode($val, 256);
+            $now = json_decode($val, true);
             if ($now) {
                 //用户分组后的数组
                 $allusergkarr[$now['group']][] = $now;
             }
         }
+        foreach ($allusergkarr as $group => $nowgroups) {
+            usort($allusergkarr[$group], function ($a, $b) {
+                if ($a['intime'] == $b['intime']) {
+                    return 0;
+                }
+                return ($a['intime'] > $b['intime']) ? 1 : -1;
+            });
+        }
+
         if (!$allusergkarr) {
             return false;
         }
         unset($alluser);
+        return $allusergkarr;
+    }
 
-
+    //找到可以接工单的客服 按组
+    private static function getWorkKfData()
+    {
         $allkfs = self::$redis->hgetall(self::KFINFOKEY);
         if (empty($allkfs)) {
-            return true;
+            return false;
         }
         $allkfgkarr = [];
         foreach ($allkfs as $val) {
-            $now = json_decode($val, 256);
+            $now = json_decode($val, true);
             if ($now && $now['status'] == 1) {
                 //客分组后的数组
                 $allkfgkarr[$now['group']][] = $now;
@@ -572,57 +777,30 @@ class Events
         if (!$allkfgkarr) {
             return false;
         }
-        //客服每组按任务数由小到大排序
+        //客服每组按任务数由小到大排序 任务相同时按时间先后顺序
         foreach ($allkfgkarr as $group => $nowgroups) {
             usort($allkfgkarr[$group], function ($a, $b) {
                 if ($a['task'] == $b['task']) {
-                    return 0;
+                    if ($a['intime'] == $b['intime']) {
+                        return 0;
+                    }
+                    return ($a['intime'] > $b['intime']) ? 1 : -1;
                 }
-                return ($a > $b) ? 1 : -1;
+                return ($a['task'] > $b['task']) ? 1 : -1;
             });
         }
         unset($allkfs);
 
-        $maxset = (self::$global->systemconfig)['KFMaxServices'] ?? 5;
-        $maxset = inval($maxset);
-
-        if ($group && $uid) {
-            // 指定用指定组 [可能存在断线重连的情况] 如果存在旧的会话,直接连线客服和用户
-            //否则按先到后到以及客服最大服务数限制
-            $last = self::UserHasOldTalk($uid);
-            if ($last) {
-                self::BeginTalk(self::getkfuid($last['kf_id']), $uid, $last['group_id'], $last['servicelog_id']);
-                return;
-            }
-        }
-        //系统定时调用时,无组,无用户
-        foreach ($allusergkarr as $group => $gusersArr) {
-            if (isset($allkfgkarr[$group])) {
-                //所属客服组无人在线
-                continue;
-            }
-            $nowkfs = $allkfgkarr[$group];
-            foreach ($gusersArr as $user) {
-
-
-            }
-        }
-
-        return;
-
+        return $allkfgkarr;
     }
 
-    //开启一个会话
-    private static function BeginTalk($kfuid, $uid, $group, $serviceid = 0)
-    {
-
-    }
 
     //找到用户是否有一条未关闭的会话
     private static function UserHasOldTalk($uid)
     {
         $uid = intval($uid);
-        $ret = self::$db->select('*')->from('ws_service_log')->where("user_id=$uid and  status!=2")->orderByDESC(['id'])->row();
+        $start_time = time() - 86400;
+        $ret = self::$db->select('*')->from('ws_service_log')->where("start_time>=$start_time and user_id=$uid and  status!=2 ")->orderByDESC(['servicelog_id'])->row();
         return $ret;
     }
 
@@ -766,6 +944,7 @@ class Events
         }
 
         $group = self::$db->query("SELECT *  FROM `ws_groups`");
+
         $arr = [];
         if ($group) {
             foreach ($group as $val) {
@@ -774,6 +953,9 @@ class Events
             self::$global->groupmap = $arr;
         }
 
+        //$sayHello = self::$db->query('select `word`,`status` from `ws_reply` where `id` = 2');
+
+
     }
 
     /**
@@ -966,10 +1148,11 @@ class Events
             }
             $kfid = intval($kfid);
             self::$db->query("update ws_service_log set status=2 where kf_id=$kfid and  start_time>=$t and  status!=2");
-            self::$redis->hdel('KFINFO', 'KF' . $kfid);
+            self::$redis->hdel(self::KFINFOKEY, 'KF' . $kfid);
         } else {
-            self::$redis->del('KFINFO');
-            self::$redis->del('USERINFOKEY');
+            self::$redis->del(self::KFINFOKEY);
+            self::$redis->del(self::USERLIST);
+            self::$redis->del(self::USERINFOKEY);
             self::$db->query("update ws_service_log set status=2 where  start_time>=$t and  status!=2");
         }
 
@@ -1051,9 +1234,21 @@ class Events
     //调试使用
     public static function mydebug($client_id, $message)
     {
-        $date = self::$db->select('*')->from('ws_service_log')->where('servicelog_id= :id')->bindValues(['id' => 1])->row();
-        self::$redis->hset('SERVICELOG', 1, json_encode($date, 256));
+        $ret = self::$db->insert('ws_service_log')->cols(array(
+            'user_id' => 1,
+            'client_id' => 'acasdfasf',
+            'user_name' => 'test',
+            'user_avatar' => '',
+            'user_ip' => '',
+            'kf_id' => 1,
+            'start_time' => 1212,
+            'group_id' => 4,
+            'website' => '',
+            'system' => '',
+            'browse' => ''
+        ))->query();
 
+        print_r($ret);
     }
 
     public static function MySendMsg($clientId, $msg)
@@ -1074,11 +1269,10 @@ class Events
     //得到客服的ID整数值
     public static function getkfid($id)
     {
-        if ($id == intval($id)) {
-            return $id;
-        } else {
+        if (strtolower(substr($id, 0, 2)) == 'kf') {
             return intval(substr($id, 2));
         }
+        return intval($id);
     }
 
     //从数组中获取参数
@@ -1110,7 +1304,7 @@ class Events
                     continue;
                 }
             }
-            $return[$val['id']] = $now;
+            $return[$now['id']] = $now;
         }
         return $return;
     }