Customer.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <?php
  2. namespace addons\shopro\library\chat\provider\auth\traits;
  3. /**
  4. * 顾客事件
  5. */
  6. trait Customer
  7. {
  8. public function customerOn()
  9. {
  10. // 顾客连接客服事件
  11. $this->register('customer_login', function ($data, $callback) {
  12. // 加入的客服房间
  13. $room_id = $data['room_id'] ?? 'admin';
  14. $this->session('room_id', $room_id);
  15. // 存储当前房间
  16. $this->nspRoomIdAdd($room_id);
  17. // 顾客上线
  18. $this->chatService->customerOnline();
  19. // 通知所有房间中的客服,用户上线了
  20. $this->sender->customerOnline();
  21. // 注册顾客相关的事件
  22. $this->customerEvent();
  23. // 获取常见问题,提醒给顾客
  24. $questions = $this->getter('db')->getChatQuestions($room_id);
  25. // 通知自己连接成功
  26. $this->sender->successSocket($callback, '顾客初始成功', [
  27. 'questions' => $questions
  28. ]);
  29. // 分配客服
  30. $this->allocatCustomerService();
  31. });
  32. }
  33. public function customerEvent()
  34. {
  35. // 检测是否登录过
  36. if ($this->socket->listeners('message')) {
  37. // 已经注册过了,避免重复注册
  38. return false;
  39. }
  40. // 发送消息
  41. $this->register('message', function ($data, $callback) {
  42. $message = $data['message'] ?? []; // 发送的消息
  43. $question_id = $data['question_id'] ?? 0; // 猜你想问
  44. // 过滤 message
  45. if ($message['message_type'] == 'text') {
  46. $message['message'] = trim(strip_tags($message['message']));
  47. }
  48. $room_id = $this->session('room_id');
  49. $session_id = $this->session('session_id');
  50. $customer_service_id = $this->session('customer_service_id');
  51. // 给客服发消息
  52. $this->sender->messageToCustomerService($message, [
  53. 'sender_identify' => 'customer',
  54. 'session_id' => $session_id,
  55. ], $customer_service_id);
  56. // 通知自己发送成功
  57. $this->sender->successSocket($callback, '发送成功');
  58. // 检查并获取 question
  59. $question = $this->getter('db')->getChatQuestion($room_id, $question_id);
  60. if ($question) {
  61. // 是猜你想问,自动回答问题
  62. $this->sender->messageToBoth($question, $session_id, $customer_service_id);
  63. }
  64. });
  65. // 获取消息列表
  66. $this->register('messages', function ($data, $callback) {
  67. // 当前房间
  68. $room_id = $this->session('room_id');
  69. $session_id = $this->session('session_id');
  70. // 获取 聊天记录
  71. $messages = $this->getter('db')->getCustomerMessagesBySessionId($room_id, $session_id, 'customer_service', $data);
  72. // 获取消息列表
  73. $this->sender->successSocket($callback, '获取成功', [
  74. 'messages' => $messages
  75. ]);
  76. });
  77. // 顾客退出
  78. $this->register('customer_logout', function ($data, $callback) {
  79. $session_id = $this->session('session_id');
  80. $room_id = $this->session('room_id');
  81. $chatUser = $this->session('chat_user');
  82. // 顾客下线
  83. $this->chatService->customerOffline();
  84. // 顾客断开连接
  85. if (!$this->getter('socket')->isOnLineCustomerById($session_id)) {
  86. // 当前所遇用户端都断开了
  87. // 这里顾客的所有客户端都断开了,在排队排名中移除
  88. $this->nspWaitingDel($room_id, $session_id);
  89. // 排队发生变化,通知房间中所有排队用户
  90. $this->sender->allWaitingQueue($room_id);
  91. // 通知所有房间中的客服,顾客下线
  92. $this->sender->customerOffline();
  93. }
  94. // 解绑顾客相关的事件,等下次顾客在登录时再重新绑定 【customerEvent 方法绑定的所有事件】
  95. $this->socket->removeAllListeners('message');
  96. $this->socket->removeAllListeners('messages');
  97. $this->socket->removeAllListeners('customer_logout');
  98. $this->sender->successSocket($callback, '顾客退出成功');
  99. });
  100. }
  101. /**
  102. * 分配客服
  103. *
  104. * @return void
  105. */
  106. private function allocatCustomerService()
  107. {
  108. $room_id = $this->session('room_id');
  109. $session_id = $this->session('session_id');
  110. $auth = $this->session('auth');
  111. // 检测并分配客服
  112. $customerService = $this->chatService->checkAndAllocatCustomerService();
  113. if ($customerService) {
  114. // 将用户 session_id 从等待排名中移除(这个用户的所有客户端都会被接入)
  115. $this->nspWaitingDel($room_id, $session_id);
  116. // 排队发生变化,通知房间中所有排队用户
  117. $this->sender->allWaitingQueue($room_id);
  118. // 顾客被接入,通知所有自己的客户端被接入,通知房间中所有客服用户被接入(等待中移除),通知新客服,新用户接入
  119. $this->sender->customerAccessed($room_id, $session_id, $customerService);
  120. } else {
  121. if ($this->getter('socket')->hasCustomerServiceByRoomId($room_id)) {
  122. // 有客服
  123. $this->sender->waiting();
  124. } else {
  125. // 通知用户没有客服在线
  126. $this->sender->noCustomerService();
  127. }
  128. }
  129. }
  130. }