SenderFunc.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. <?php
  2. namespace addons\shopro\library\chat\traits\sender;
  3. use addons\shopro\library\chat\traits\Helper;
  4. use addons\shopro\library\chat\traits\Session;
  5. use addons\shopro\library\chat\traits\NspData;
  6. /**
  7. * 绑定 uid
  8. */
  9. trait SenderFunc
  10. {
  11. use Session;
  12. use Helper;
  13. use NspData;
  14. /**
  15. * 用户自己触发:发送给自己,登录成功
  16. *
  17. * @param \Closure $callback
  18. * @return void
  19. */
  20. public function authSuccess($callback)
  21. {
  22. // 通过回调发送给自己
  23. $this->successSocket($callback, '连接成功', [
  24. 'session_id' => $this->session('session_id'),
  25. 'chat_user' => $this->session('chat_user') ?: null,
  26. ]);
  27. }
  28. /**
  29. * 用户自己触发:通知所有房间中的客服,用户上线了
  30. *
  31. * @return void
  32. */
  33. public function customerOnline()
  34. {
  35. $session_id = $this->session('session_id');
  36. $room_id = $this->session('room_id');
  37. $chatUser = $this->session('chat_user');
  38. $chatUser = $this->getter()->chatUsersFormat($room_id, [$chatUser], ['first' => true]);
  39. $this->successRoom('customer_online', '顾客上线', [
  40. 'session_id' => $session_id,
  41. 'chat_user' => $chatUser,
  42. ], $this->getRoomName('customer_service_room', ['room_id' => $room_id]));
  43. }
  44. /**
  45. * 用户自己触发:通知所有房间中的客服,用户下线了
  46. *
  47. * @return void
  48. */
  49. public function customerOffline()
  50. {
  51. $session_id = $this->session('session_id');
  52. $room_id = $this->session('room_id');
  53. $chatUser = $this->session('chat_user');
  54. $chatUser = $this->getter()->chatUsersFormat($room_id, [$chatUser], ['first' => true]);
  55. $this->successRoom('customer_offline', '顾客下线', [
  56. 'session_id' => $session_id,
  57. 'chat_user' => $chatUser,
  58. ], $this->getRoomName('customer_service_room', ['room_id' => $room_id]));
  59. }
  60. /**
  61. * 用户自己触发:通知用户的客户端,排队中,通知客服,有新的等待中用户
  62. *
  63. * @param array $waiting 等待中的顾客
  64. * @return void
  65. */
  66. public function waiting()
  67. {
  68. $session_id = $this->session('session_id');
  69. $room_id = $this->session('room_id');
  70. // 通知客服更新 等待中列表,返回整个等待的列表
  71. $this->successRoom('customer_waiting', '顾客等待', [
  72. 'waitings' => $this->getter()->getCustomersFormatWaiting($room_id),
  73. ], $this->getRoomName('customer_service_room', ['room_id' => $room_id]));
  74. // 通知用户前面排队人数
  75. $this->waitingQueue($room_id, $session_id);
  76. }
  77. /**
  78. * 用户自己触发,服务器定时触发:通知用户的客户端,当前有客服,但是需要排队 (传参是因为别的地方也需要调用)
  79. *
  80. * @param string $room_id
  81. * @param string $session_id
  82. * @return void
  83. */
  84. public function waitingQueue($room_id, $session_id)
  85. {
  86. $rank = $this->nspWaitingRank($room_id, $session_id);
  87. $title = $rank > 0 ? '当前还有 ' . $rank . ' 位顾客,请耐心等待' : '客服马上为您服务,请稍等';
  88. // 通知用户等待接入
  89. $this->successUId('waiting_queue', '排队等待', [
  90. 'title' => $title,
  91. ], ['id' => $session_id, 'type' => 'customer']);
  92. }
  93. /**
  94. * 当有变动,批量通知排队等待排名
  95. *
  96. * @param string|null $room_id
  97. * @return void
  98. */
  99. public function allWaitingQueue($room_id = null)
  100. {
  101. $waitings = $this->nspGetWaitings($room_id);
  102. if ($room_id) {
  103. // 只处理该房间的
  104. if ($this->getter->driver('socket')->hasCustomerServiceByRoomId($room_id)) {
  105. foreach ($waitings as $key => $session_id) {
  106. $this->waitingQueue($room_id, $session_id);
  107. }
  108. }
  109. } else {
  110. // 定时器调用, 处理所有房间的
  111. foreach ($waitings as $current_room_id => $roomWaitings) {
  112. // 判断是否有客服在线
  113. if ($this->getter->driver('socket')->hasCustomerServiceByRoomId($current_room_id)) {
  114. foreach ($roomWaitings as $key => $session_id) {
  115. $this->waitingQueue($current_room_id, $session_id);
  116. }
  117. }
  118. }
  119. }
  120. }
  121. /**
  122. * 用户自己触发:通知用户的客户端,当前没有客服在线
  123. *
  124. * @return void
  125. */
  126. public function noCustomerService()
  127. {
  128. $session_id = $this->session('session_id');
  129. $this->successUId('no_customer_service', '暂无客服在线', [
  130. 'message' => [
  131. 'message_type' => 'system',
  132. 'message' => '当前客服不在线',
  133. 'createtime' => time()
  134. ],
  135. ], ['id' => $session_id, 'type' => 'customer']);
  136. }
  137. /**
  138. * 给客服发消息
  139. *
  140. * @param array $message 消息原始内容
  141. * @param array $sender 发送者信息
  142. * @param integer $customer_service_id 客服 id
  143. * @return void
  144. */
  145. public function messageToCustomerService($message, $sender, $customer_service_id)
  146. {
  147. // 给客服发送消息
  148. $this->messageUId('message', '收到消息', [
  149. 'message' => $message,
  150. 'sender' => $sender
  151. ], ['id' => $customer_service_id, 'type' => 'customer_service']);
  152. }
  153. /**
  154. * 给顾客发消息
  155. *
  156. * @param array $message 消息原始内容
  157. * @param array $sender 发送者信息
  158. * @param integer $session_id 顾客 session_id
  159. * @return void
  160. */
  161. public function messageToCustomer($message, $sender, $session_id)
  162. {
  163. // 给用户发送消息
  164. $this->messageUId('message', '收到消息', [
  165. 'message' => $message,
  166. 'sender' => $sender
  167. ], ['id' => $session_id, 'type' => 'customer']);
  168. }
  169. /**
  170. * 同时通知客服和顾客
  171. *
  172. * @param array $question 要回答的问题
  173. * @param string $session_id 用户表示
  174. * @param string $customer_service_id 客服
  175. * @return void
  176. */
  177. public function messageToBoth($question, $session_id, $customer_service_id)
  178. {
  179. $customerService = $this->session('customer_service');
  180. $chatUser = $this->session('chat_user');
  181. $message = [
  182. 'message_type' => 'text',
  183. 'message' => $question['content'],
  184. ];
  185. $sender = [
  186. 'sender_identify' => 'customer_service',
  187. 'customer_service' => $customerService,
  188. ];
  189. // 发给用户
  190. $this->messageUId('message', '收到消息', [
  191. 'message' => $message,
  192. 'sender' => $sender
  193. ], ['id' => $session_id, 'type' => 'customer']);
  194. // 发给客服
  195. if ($customer_service_id) {
  196. // 有客服,发给客服
  197. $message['sender_identify'] = 'customer_service';
  198. $message['sender_id'] = $customerService['id'];
  199. $message['sender'] = $customerService;
  200. $message['createtime'] = time();
  201. $sender['session_id'] = $session_id;
  202. $this->successUId('message', '收到消息', [
  203. 'message' => $message,
  204. 'sender' => $sender
  205. ], ['id' => $customer_service_id, 'type' => 'customer_service']);
  206. }
  207. }
  208. /**
  209. * 通知连接的用户(在当前客服服务的房间里面的用户),客服上线了
  210. *
  211. * @return void
  212. */
  213. public function customerServiceOnline()
  214. {
  215. $room_id = $this->session('room_id');
  216. $customerService = $this->session('customer_service');
  217. // 给客服发送消息
  218. $this->successRoom('customer_service_online', '客服 ' . $customerService['name'] . ' 上线', [
  219. 'customer_service' => $customerService,
  220. ], $this->getRoomName('customer_service_room_user', ['room_id' => $room_id, 'customer_service_id' => $customerService['id']]));
  221. }
  222. /**
  223. * 通知连接的用户(在当前客服服务的房间里面的用户),客服忙碌
  224. *
  225. * @return void
  226. */
  227. public function customerServiceBusy()
  228. {
  229. $room_id = $this->session('room_id');
  230. $customerService = $this->session('customer_service');
  231. // 给客服发送消息
  232. $this->successRoom('customer_service_busy', '客服 ' . $customerService['name'] . ' 忙碌', [
  233. 'customer_service' => $customerService,
  234. ], $this->getRoomName('customer_service_room_user', ['room_id' => $room_id, 'customer_service_id' => $customerService['id']]));
  235. }
  236. /**
  237. * 通知连接的用户(在当前客服服务的房间里面的用户),客服下线了
  238. *
  239. * @return void
  240. */
  241. public function customerServiceOffline()
  242. {
  243. $room_id = $this->session('room_id');
  244. $customerService = $this->session('customer_service');
  245. $this->successRoom('customer_service_offline', '客服 ' . $customerService['name'] . ' 离线', [
  246. 'customer_service' => $customerService,
  247. ], $this->getRoomName('customer_service_room_user', ['room_id' => $room_id, 'customer_service_id' => $customerService['id']]));
  248. }
  249. /**
  250. * 通知当前房间的在线客服,更新当前在线客服列表
  251. *
  252. * @return void
  253. */
  254. public function customerServiceUpdate()
  255. {
  256. $room_id = $this->session('room_id');
  257. // 给客服发送消息
  258. $customerServices = $this->getter('socket')->getCustomerServicesByRoomId($room_id);
  259. $this->successRoom('customer_service_update', '更新客服列表', [
  260. 'customer_services' => $customerServices,
  261. ], $this->getRoomName('customer_service_room', ['room_id' => $room_id]));
  262. }
  263. /**
  264. * 服务结束,通知顾客客服断开连接
  265. *
  266. * @param string $session_id
  267. * @return void
  268. */
  269. public function customerServiceBreak($session_id)
  270. {
  271. $this->successUId('customer_service_break', '客服断开', [
  272. 'message' => [
  273. 'message_type' => 'system',
  274. 'message' => '服务已结束',
  275. 'createtime' => time()
  276. ],
  277. ], ['id' => $session_id, 'type' => 'customer']);
  278. }
  279. /**
  280. * 客服转接
  281. *
  282. * @param string $room_id 房间号
  283. * @param string $session_id 用户 UId
  284. * @param array $customerService 老客服
  285. * @param array $newCustomerService 新客服
  286. * @return void
  287. */
  288. public function customerTransfer($room_id, $session_id, $customerService, $newCustomerService)
  289. {
  290. // 通知用户客服被转接
  291. $this->customerAccessedToCustomer($session_id, $customerService, $newCustomerService);
  292. // 通知所有客服用户被接入
  293. $this->customerAccessedToCustomerServices($room_id, $session_id, $newCustomerService);
  294. // 通知新的客服,新用户接入
  295. $this->customerAccessedToCustomerService($room_id, $session_id, $newCustomerService);
  296. }
  297. /**
  298. * 客服接入
  299. *
  300. * @param string $room_id 房间号
  301. * @param string $session_id 用户 UId
  302. * @param array $customerService 老客服
  303. * @return void
  304. */
  305. public function customerAccessed($room_id, $session_id, $customerService)
  306. {
  307. // 通知用户客服接入
  308. $this->customerAccessedToCustomer($session_id, $customerService);
  309. // 通知所有客服用户被接入
  310. $this->customerAccessedToCustomerServices($room_id, $session_id, $customerService);
  311. // 通知新的客服,新用户接入
  312. $this->customerAccessedToCustomerService($room_id, $session_id, $customerService);
  313. }
  314. /**
  315. * 通知顾客 客服接入
  316. *
  317. * @param string $session_id 用户 UId
  318. * @param array $customerService 老客服
  319. * @param array $newCustomerService 新客服
  320. * @return void
  321. */
  322. private function customerAccessedToCustomer($session_id, $customerService, $newCustomerService = null)
  323. {
  324. // 通知当前用户的所有客户端,客服接入
  325. $message = '您好,客服 ' . $customerService['name'] . " 为您服务";
  326. if ($newCustomerService) {
  327. $message = '您好,您的客服已由 ' . $customerService['name'] . " 切换为 " . $newCustomerService['name'];
  328. }
  329. $this->successUId('customer_service_access', '客服接入', [
  330. 'message' => [
  331. 'message_type' => 'system',
  332. 'message' => $message,
  333. 'createtime' => time()
  334. ],
  335. 'customer_service' => $newCustomerService ? : $customerService
  336. ], ['id' => $session_id, 'type' => 'customer']);
  337. }
  338. /**
  339. * 通知所有客服,用户被接入
  340. *
  341. * @param string $room_id 房间号
  342. * @param string $session_id 用户 UId
  343. * @param array $customerService 老客服
  344. * @return void
  345. */
  346. private function customerAccessedToCustomerServices($room_id, $session_id, $customerService)
  347. {
  348. // 通知所有客服,用户被接入
  349. $this->successRoom('customer_accessed', '顾客被接入', [
  350. 'session_id' => $session_id,
  351. 'chat_user' => $this->getter('db')->getChatUserBySessionId($session_id),
  352. 'customer_service' => $customerService,
  353. ], $this->getRoomName('customer_service_room', ['room_id' => $room_id]));
  354. }
  355. /**
  356. * 通知被接入客服,新用户接入
  357. *
  358. * @param [type] $session_id
  359. * @param [type] $customerService
  360. * @return void
  361. */
  362. private function customerAccessedToCustomerService($room_id, $session_id, $customerService)
  363. {
  364. // 获取chatUser
  365. $chatUser = $this->getter('db')->getChatUserBySessionId($session_id);
  366. // 格式化chatUser
  367. $chatUser = $this->getter()->chatUsersFormat($room_id, [$chatUser], ['first' => true]);
  368. // 通知新的客服,新用户接入
  369. $this->successUId('customer_access', '新顾客接入', [
  370. 'session_id' => $session_id,
  371. 'chat_user' => $chatUser,
  372. ], ['id' => $customerService['id'], 'type' => 'customer_service']);
  373. }
  374. }