UserTimeout.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php
  2. namespace app\admin\command;
  3. use think\console\Command;
  4. use think\console\Input;
  5. use think\console\Output;
  6. use app\admin\model\User;
  7. use app\admin\model\Config;
  8. use app\admin\model\KefuTime;
  9. use app\admin\model\KefuLog;
  10. use think\facade\Db;
  11. use GatewayClient\Gateway;
  12. use app\enterprise\model\{Message,Friend};
  13. /**
  14. * Worker 命令行类
  15. */
  16. class UserTimeout extends Command
  17. {
  18. public function configure()
  19. {
  20. $this->setName('user:timeout')
  21. ->setDescription('用户会话检测');
  22. }
  23. public function execute(Input $input, Output $output)
  24. {
  25. //检测离线用户状态
  26. $this->checkOfflineUser();
  27. $config = Config::whereIn('field',['kefu_timeout_reminder','kefu_timeout_warning','user_timeouted_warning', 'user_timeout_warning','user_inline_finished','kefu_inline_finished'])->column('val','field');
  28. $user_timeout_warning = 0;
  29. if (isset($config['user_timeout_warning']) && $config['user_timeout_warning'] > 0) {
  30. $user_timeout_warning = $config['user_timeout_warning'];
  31. //用户等待即将超时预警
  32. $list = User::where('status', 1)->where('is_online', 1)->where('service_status', 1)
  33. ->where('service_start', '<=', time() - $user_timeout_warning)
  34. ->where('timeout_type', 0)
  35. ->select()
  36. ->toArray();
  37. $this->sendMessage($list, 1);
  38. $output->writeln('用户等待即将超时预警:'.count($list));
  39. }
  40. if (isset($config['user_timeouted_warning']) && $config['user_timeouted_warning'] > 0) {
  41. $user_timeouted_warning = $config['user_timeouted_warning'];
  42. //用户等待已超时预警
  43. $list = User::where('status', 1)->where('is_online', 1)->where('service_status', 1)
  44. ->where('service_start', '<=', time() - $user_timeouted_warning)
  45. ->where(function($query) use ($user_timeout_warning){
  46. if ($user_timeout_warning > 0) {
  47. $query->where('service_start', '<=', time() - $user_timeout_warning);
  48. }
  49. })
  50. ->where('timeout_type', '<',2)
  51. ->select()
  52. ->toArray();
  53. $this->sendMessage($list, 2);
  54. $output->writeln('用户等待已超时预警'.count($list));
  55. }
  56. $kefu_timeout_warning = 0;
  57. if (isset($config['kefu_timeout_warning']) && $config['kefu_timeout_warning'] > 0) {
  58. $kefu_timeout_warning = $config['kefu_timeout_warning'];
  59. //用户服务中-即将超时预警时间
  60. $list = User::where('status', 1)->where('is_online', 1)->where('service_status', 2)
  61. ->where('service_start', '<=', time() - $kefu_timeout_warning)
  62. ->where('timeout_type', '<',3)
  63. ->select()
  64. ->toArray();
  65. $this->sendMessage($list, 3);
  66. $output->writeln('用户服务中-即将超时预警'.count($list));
  67. }
  68. if (isset($config['kefu_timeout_reminder']) && $config['kefu_timeout_reminder'] > 0) {
  69. $timeout_reminder = $config['kefu_timeout_reminder'];
  70. //用户服务中-已超时提醒
  71. $list = User::where('status', 1)->where('is_online', 1)->where('service_status', 2)
  72. ->where('service_start', '<=', time() - $timeout_reminder)
  73. ->where(function($query) use ($kefu_timeout_warning){
  74. if ($kefu_timeout_warning > 0) {
  75. $query->where('service_start', '<=', time() - $kefu_timeout_warning);
  76. }
  77. })
  78. ->where('timeout_type', '<',4)
  79. ->select()
  80. ->toArray();
  81. $output->writeln('用户服务中-已超时提醒'.count($list));
  82. $this->sendMessage($list, 4);
  83. }
  84. if (isset($config['user_inline_finished']) && $config['user_inline_finished'] > 0) {
  85. $user_inline_finished = $config['user_inline_finished'] * 60;
  86. //会员离线后自动结束会话时间
  87. $list = User::where('role', 0)
  88. ->where('is_online', 0)
  89. ->whereIn('service_status', [0,1,2])
  90. ->where('offline_time', '<=', time() - $user_inline_finished)
  91. ->select()
  92. ->toArray();
  93. $cs_uid = getAutoCsUid();//获取机器人ID
  94. foreach($list as $user) {
  95. try {
  96. Db::startTrans();
  97. //用户转给机器人客服
  98. User::where('user_id', $user['user_id'])->update(['service_status' => -1, 'service_start' => 0, 'timeout_type' => 0, 'cs_uid'=>$cs_uid]);
  99. KefuTime::endData($user['uid'], 3, $user['cs_uid']); //结束接线时间
  100. //客服对接记录表
  101. KefuLog::addData($cs_uid, $user['user_id'], 3);
  102. $user_id = $user['user_id'];
  103. $friend = Friend::where('create_user', $user_id)->order('create_time', 'desc')->find();
  104. if ($friend) {
  105. $old_cs_uid = $friend->friend_user_id;
  106. $friend->friend_user_id = $cs_uid;
  107. $friend->save();
  108. $chat_identify = chat_identify($cs_uid,$user_id);
  109. Message::where(['from_user' => $user_id, 'to_user' => $old_cs_uid])->update(['to_user' => $cs_uid, 'chat_identify' => $chat_identify, 'is_read' => 1]);
  110. Message::where(['from_user' => $old_cs_uid, 'to_user' => $user_id])->update(['from_user' => $cs_uid, 'chat_identify' => $chat_identify, 'is_read' => 1]);
  111. }
  112. Db::commit();
  113. $is_warning = $user['service_status'] == 1 || $user['service_status'] == 2 ? 1 : 0;
  114. //通知关闭聊天框
  115. wsSendMsg($user['cs_uid'],'closeChat',['user_id'=>$user['user_id'], 'realname' => $user['realname'], 'is_warning' => $is_warning]);
  116. //通知客服已结束
  117. wsSendMsg($user['cs_uid'],'handleChat',['user_id'=>$user['user_id']]);
  118. } catch (\Exception $e) {
  119. Db::rollback();
  120. }
  121. }
  122. $output->writeln('会员离线后自动结束会话时间'.count($list));
  123. }
  124. if (isset($config['kefu_inline_finished']) && $config['kefu_inline_finished'] > 0) {
  125. $kefu_inline_finished = $config['kefu_inline_finished'] * 60;
  126. //客服离线后自动结束会话时间
  127. $list = User::where('role', 3)
  128. ->where('is_online', 0)
  129. ->where('is_finished', 0)
  130. ->where('offline_time', '<=', time() - $kefu_inline_finished)
  131. ->select()
  132. ->toArray();
  133. $cs_uid = getAutoCsUid();//获取机器人ID
  134. foreach($list as $user) {
  135. try {
  136. Db::startTrans();
  137. User::kefuOffline($user['user_id'], $user['uid']);
  138. Db::commit();
  139. } catch (\Exception $e) {
  140. Db::rollback();
  141. }
  142. }
  143. $output->writeln('客服离线后自动结束会话时间'.count($list));
  144. }
  145. }
  146. //检测离线用户,更新在线状态
  147. public function checkOfflineUser()
  148. {
  149. Gateway::$registerAddress = config('gateway.registerAddress');
  150. $onlineList=Gateway::getAllUidList();
  151. $userOnlineList = User::where('is_online', '>', 0)->column('user_id');
  152. foreach($userOnlineList as $user_id) {
  153. if(!isset($onlineList[$user_id])) {
  154. User::where('user_id', $user_id)->update(['is_online' => 0, 'offline_time' => time()]);
  155. }
  156. }
  157. }
  158. /**
  159. * 发送提醒通知
  160. */
  161. public function sendMessage($list, $type)
  162. {
  163. foreach($list as $user) {
  164. //更新用户超时提醒的状态
  165. User::where('user_id', $user['user_id'])->update(['timeout_type' => $type]);
  166. //通知客服已结束
  167. wsSendMsg($user['cs_uid'],'timeout',['user_id'=>$user['user_id'], 'realname'=>$user['realname'], 'type'=>$type]);
  168. }
  169. }
  170. }