lip 3 месяцев назад
Родитель
Сommit
6fd5e747b4

+ 94 - 0
app/admin/command/UserQueue.php

@@ -0,0 +1,94 @@
+<?php
+namespace app\admin\command;
+
+use think\console\Command;
+use think\console\Input;
+use think\console\Output;
+use app\admin\model\User;
+use app\admin\model\Config;
+use app\admin\model\KefuWork;
+use app\enterprise\model\{Message,Friend};
+use Exception;
+use think\facade\Db;
+
+/**
+ * Worker 命令行类
+ */
+class UserQueue extends Command
+{
+    public function configure()
+    {
+        $this->setName('user:queue')
+            ->setDescription('用户排队,自动分配客服');
+    }
+
+    public function execute(Input $input, Output $output)
+    {
+        $where = [
+            ['status', '=', 1],
+            ['is_online', '=', 1],
+            ['role', '=', 3],
+        ];
+
+        while(true) {
+            //查询当前最少接线数的客服
+            $kefu_chat_max = Config::getKefuChatMax();//单个客服接线上限
+            if ($kefu_chat_max) {
+                $where[] = ['chat_num', '<', $kefu_chat_max];
+            }
+
+            //排队用户
+            $list = User::where('status', 1)->where('is_online', 1)->where('service_status', 1)
+                        ->order('service_start', 'asc')
+                        ->select()
+                        ->toArray();
+            if (empty($list)) {
+                sleep(10);
+            }
+            foreach ($list as $item) {
+                $cs_user = User::where($where)->order('chat_num', 'asc')->find();
+                if (!$cs_user) {
+                    break;
+                }
+                $this->handleChat($item, $cs_user->user_id, $cs_user->uid);
+            }
+        }
+    }
+
+    /**
+     * 自动接线
+     */
+    public function handleChat($user, $cs_uid, $admin_id)
+    {
+        try {
+            Db::startTrans();
+            $user_id = $user['user_id'];
+            $user->cs_uid = $cs_uid;
+            $user->service_status = 1;
+            $user->service_start = time();
+            $user->save();
+            
+            //更新客服接线数量
+            User::where('user_id', $cs_uid)->update(['chat_num'=>Db::raw('chat_num+1')]);
+
+            $friend = Friend::where('create_user', $user_id)->order('create_time', 'desc')->find();
+            if ($friend) {
+                $robot_id = $friend->friend_user_id;
+                $friend->friend_user_id = $cs_uid;
+                $friend->save();
+                $chat_identify = $cs_uid . '-' . $user_id;
+                Message::where(['from_user' => $user_id, 'to_user' => $robot_id])->update(['to_user' => $cs_uid, 'chat_identify' => $chat_identify]);
+                Message::where(['from_user' => $robot_id, 'to_user' => $user_id])->update(['from_user' => $cs_uid, 'chat_identify' => $chat_identify]);
+            }
+
+            KefuWork::addNum($admin_id, 'chat_num');//客服接线次数更新
+
+            Db::commit();
+            //通知客服已接线
+            wsSendMsg(0,'handleChat',['user_id'=>$user_id]);
+        } catch (\Exception $e) {
+            Db::rollback();
+        }
+    }
+
+}

+ 17 - 4
app/admin/command/UserTimeout.php

@@ -7,6 +7,7 @@ use think\console\Output;
 use app\admin\model\User;
 use app\admin\model\Config;
 use app\admin\model\KefuTime;
+use think\facade\Db;
 
 /**
  * Worker 命令行类
@@ -83,10 +84,22 @@ class UserTimeout extends Command
                     ->select()
                     ->toArray();
             foreach($list as $user) {
-                User::where('user_id', $user['user_id'])->update(['service_status' => 3, 'service_start' => time()]);
-                KefuTime::endData($user['cs_uid'], 3); //结束接线时间
-                //通知客服已结束
-                wsSendMsg($user['cs_uid'],'handleChat',['user_id'=>$user['user_id']]);
+                try {
+                    Db::startTrans();
+                    
+                    User::where('user_id', $user['user_id'])->update(['service_status' => 3, 'service_start' => time()]);
+                    KefuTime::endData($user['cs_uid'], 3); //结束接线时间
+
+                    //更新客服接线数量
+                    User::where('user_id', $user['cs_uid'])->update(['chat_num'=>Db::raw('chat_num-1')]);
+
+                    Db::commit();
+                    
+                    //通知客服已结束
+                    wsSendMsg($user['cs_uid'],'handleChat',['user_id'=>$user['user_id']]);
+                } catch (\Exception $e) {
+                    Db::rollback();
+                }
             }
         }
         

+ 4 - 0
app/admin/controller/Config.php

@@ -61,6 +61,10 @@ class Config extends BaseController
         }
         //删除缓存
         Cache::delete('systemInfo');
+        //删除客服接数量上限的缓存
+        if (isset($params['field']) && $params['field'] == 'kefu_chat_max') {
+            Cache::delete('config_kefu_chat_max');
+        }
         return $this->success();
 
     }

+ 12 - 0
app/admin/controller/Kefu.php

@@ -202,6 +202,9 @@ class Kefu extends BaseController
             $user->service_start = time();
             $user->save();
 
+            //更新客服接线数量
+            User::where('user_id', $cs_uid)->update(['chat_num'=>Db::raw('chat_num+1')]);
+
             $friend = Friend::where('create_user', $user_id)->order('create_time', 'desc')->find();
             if ($friend) {
                 $robot_id = $friend->friend_user_id;
@@ -243,12 +246,18 @@ class Kefu extends BaseController
             $user->service_status = 1;
             $user->service_start = time();
             $user->save();
+            //更新客服接线数量
+            User::where('user_id', $cs_uid)->update(['chat_num'=>Db::raw('chat_num+1')]);
 
             $friend = Friend::where('create_user', $user_id)->order('create_time', 'desc')->find();
             if ($friend) {
                 $old_cs_uid = $friend->friend_user_id;
                 $friend->friend_user_id = $cs_uid;
                 $friend->save();
+
+                
+                //更新客服接线数量
+                User::where('user_id', $old_cs_uid)->update(['chat_num'=>Db::raw('chat_num-1')]);
                 
                 $chat_identify = $cs_uid . '-' . $user_id;
                 Message::where(['from_user' => $user_id, 'to_user' => $old_cs_uid])->update(['to_user' => $cs_uid, 'chat_identify' => $chat_identify]);
@@ -311,6 +320,9 @@ class Kefu extends BaseController
             if ($user->service_status != 3) {
                 KefuTime::endData($user->cs_uid, 3); //结束接线时间
                 $old_cs_uid = $user->cs_uid;
+                //更新客服接线数量
+                User::where('user_id', $old_cs_uid)->update(['chat_num'=>Db::raw('chat_num-1')]);
+                
                 //转成机器人聊天
                 $user->service_status = -1;
                 $user->service_time = 0;

+ 14 - 0
app/admin/model/Config.php

@@ -60,4 +60,18 @@ class Config extends BaseModel
         }
         return $data;
     }
+
+    //获取客服接线数量的上限配置
+    public function getKefuChatMax()
+    {
+        //先从缓存中读取config表获取客服接线数量的上限配置
+        $kefu_chat_max = cache('config_kefu_chat_max');
+        if ($kefu_chat_max) {
+            return $kefu_chat_max;
+        }
+        
+        $config = Config::whereIn('field',['kefu_chat_max'])->column('val', 'field');
+        cache('config_kefu_chat_max', $config['kefu_chat_max'] ?? 0);
+        return $config['kefu_chat_max'] ?? 0;
+    }
 }

+ 4 - 8
app/enterprise/controller/Im.php

@@ -204,14 +204,10 @@ class Im extends BaseController
                 $extends = $exist['extends'];
                 $id = $extends['question_id'] ?? 0;
                 if ($id) {
-                    $question = QuestionLanguages::where('id', $id)->find();
-                    if ($question) {
-                        if ($is_like == 1) {
-                            $question->like_count = $question->like_count + 1;
-                        } else {
-                            $question->dislike_count = $question->dislike_count + 1;
-                        }
-                        $question->save();
+                    if ($is_like == 1) {
+                        QuestionLanguages::where('id', $id)->update(['like_count'=>Db::raw('like_count+1')]);
+                    } else {
+                        QuestionLanguages::where('id', $id)->update(['dislike_count'=>Db::raw('dislike_count+1')]);
                     }
                 }
                 $exist->is_click = 1;

+ 1 - 0
app/lang/en_us.php

@@ -140,6 +140,7 @@ return [
         'queue' => 'Message Queue',  
         'worker' => 'Message Push',  
         'clearStd' => 'Clear Logs',  
+        'userQueue' => 'User Queue',  
         'null' => "Unknown task",  
         'winRun' => "To start on Windows, please run the 'start_for_win.bat' file in the root directory",  
         'alreadyRun' => "Process is already running",  

+ 1 - 0
app/lang/zh_cn.php

@@ -140,6 +140,7 @@ return [
         'queue' => '消息队列',
         'worker' => '消息推送',
         'clearStd' => '清理日志',
+        'userQueue' => '用户接线排队',
         'null'=>"未知任务",
         'winRun'=>"windows启动请运行根目录下的:start_for_win.bat",
         'alreadyRun'=>"进程已启动",

+ 1 - 0
app/manage/controller/Task.php

@@ -36,6 +36,7 @@ class Task extends BaseController
             'queue' => lang('task.queue'),
             'worker' => lang('task.worker'),
             'clearStd' => lang('task.clearStd'),
+            'userQueue' => lang('task.userQueue'),
         ];
     }
 

+ 4 - 0
extend/task/command/Task.php

@@ -55,6 +55,10 @@ class Task extends Command
         $task->addCommand('php think cron:run', 'schedule', 60);
         // 消息队列
         $task->addCommand('php think queue:listen --sleep 0.3 --queue im', 'queue', 0);
+
+        // 用户接线排队
+        $task->addCommand('php think user:queue', 'userQueue', 0);
+    
         
         // 定时删除运行日志
         $task->addFunc(function () {