'您好,欢迎您使用金壶医药商城,请问您有什么疑问,我将为您在线解答。', 'work_time'=>'工作日9:00-17:30', ]; /*protected function initBaseChat($user_store,$cs_store) { Log::info('用户ID'.$user_store.',客服ID'.$cs_store); $cs_info_data = RedisCache::hget('CHAT_CS_INFO',$cs_store); $user_info_data = RedisCache::hget('CHAT_USER_INFO',$user_store); $result['cs_info_data']=$cs_info_data; $result['user_info_data']=$user_info_data; return $result; }*/ /*protected function pushToCS($server,$cs_store,$user_info_data) { //找出客服对应的fd $fd_store=RedisCache::hget('CHAT_CS_FD',$cs_store); if ($fd_store) { $push_data['message_type']='connect'; $push_data['data']=["user_info"=>$user_info_data]; $server->push($fd_store,myResult($push_data['message_type'],$push_data['data'])); } } protected function pushToUser($server,$user_store,$cs_info_data) { //找出用户对应的fd $fd_store=RedisCache::hget('CHAT_USER_FD',$user_store); if ($fd_store) { $push_data['message_type']='connect'; $push_data['data']=["cs_info"=>$cs_info_data]; $server->push($fd_store,myResult($push_data['message_type'],$push_data['data'])); } }*/ //当前在线等待用户数 protected function pushUserQueueNum($server,$fd=0) { $user_queue_num=RedisCache::llen('CHAT_USER_QUEUE'); $fd_list=[]; if ($fd>0) { //单播 $fd_list[]=$fd; } else { //广播在线客服 $fd_list=RedisCache::hkeys('CHAT_CS_FD_MAP'); } Log::info('向客服'.json_encode($fd_list).'发送在线等待人数'.$user_queue_num); foreach ($fd_list as $v) { $message_type='userQueueNum'; $push_data=["user_queue_num"=>$user_queue_num]; $server->push($v,myResult($message_type,$push_data)); } } //建立对话关系,并通知双方 protected function createChatRelation($server,$user_fd,$user_store,$cs_fd,$cs_store){ $now_time=date('Y-m-d H:i:s'); $cs_info_data = json_decode(RedisCache::hget('CHAT_CS_INFO',$cs_store),true); $user_info_data = json_decode(RedisCache::hget('CHAT_USER_INFO',$user_store),true); //建立对话关系 //RedisCache::hset('CHAT_RELATION', $user_store, $cs_store); RedisCache::lpush('CHAT_DATA_'.$user_store.'_'.$cs_store,json_encode(['time'=>$now_time,"content"=>self::TALK_WORDS['hello_words'],"from_id"=>$cs_store,"to_id"=>$user_store])); //通知用户 $message_type = 'connect'; $push_data = $cs_info_data; $server->push($user_fd,myResult($message_type,$push_data)); //通知客服 $message_type = 'connect'; $push_data = ["user_info"=>$user_info_data]; $server->push($cs_fd,myResult($message_type,$push_data)); //发送模版问侯 $message_type='chatMessage'; $push_data=["cs_info"=>$cs_info_data,"time"=>$now_time,"content"=>self::TALK_WORDS['hello_words']]; $server->push($user_fd,myResult($message_type,$push_data)); //如果有未存入数据库的离线消息,要发给客服 //取出用户本次离线消息的记录 $offline_chat_message_list=RedisCache::lrange('OFFLINE_CHAT_DATA_'.$user_store.'_'.$cs_store); if (!$offline_chat_message_list) { $offline_chat_message_list=[]; } Log::info('和客服离线留言数据:'.json_encode($offline_chat_message_list)); if (!checkGuestFlag($user_store)) { //还要取出离线留言 $offline_chat_message_list_0=RedisCache::lrange('OFFLINE_CHAT_DATA_'.$user_store.'_0'); if ($offline_chat_message_list_0) { $offline_chat_message_list=array_merge($offline_chat_message_list,$offline_chat_message_list_0); } } Log::info('加上和系统离线留言数据:'.json_encode($offline_chat_message_list)); //组装离线消息信息 $offline_chat_message_array=[]; foreach ($offline_chat_message_list as $k=>$v) { $tmp_message=json_decode($v,true); $offline_chat_message_array[$tmp_message['time'].$k]=$tmp_message; } ksort($offline_chat_message_array); foreach ($offline_chat_message_array as $v) { $message_type='chatMessage'; $push_data=["user_info"=>$user_info_data,"time"=>$v['time'],"content"=>$v['content'],"offline"=>1]; $server->push($cs_fd,myResult($message_type,$push_data)); } //-- //模版问侯也发送给客服,因为是模拟客服发送,需要换种消息类型 $message_type='systemChatMessage'; $push_data=["user_info"=>$user_info_data,"time"=>$now_time,"content"=>self::TALK_WORDS['hello_words']]; $server->push($cs_fd,myResult($message_type,$push_data)); } //自动分配客服(用户使用) protected function assignCS($server,$fd,$store_id,$guest_flag){ $assign_flag=false; $online_cs_list = RedisCache::lrange("CUSTOMER_ONLINE_QUEUE"); if (count($online_cs_list)>0) { if (!$guest_flag) { //如果不是游客,则看用户是否有专属客服 //若专属客服不在线,则自动分配在线客服 //从数据库中取用户专属客服 $cs_admin_id = Db::name("users")->where(['user_id' => $store_id])->value('custom_service_id'); if (in_array($cs_admin_id, $online_cs_list)) { $assign_flag = true; } } //如果未分配,则取一个在线客服 if (!$assign_flag) { $cs_admin_id = RedisCache::rpoplpush("CUSTOMER_ONLINE_QUEUE"); if ($cs_admin_id) { $assign_flag=true; } } } if ($assign_flag) { //获得客服的fd $cs_fd=RedisCache::hget('CHAT_CS_FD',$cs_admin_id);; //建立对话关系 $this->createChatRelation($server,$fd,$store_id,$cs_fd,$cs_admin_id); } else { //没有分配成功,进入等待队列,该队列用户可考虑留言功能 RedisCache::lpush("CHAT_USER_QUEUE", $store_id); $message_type='wait'; if (checkGuestFlag($store_id)) { $push_data['content']='在线客服服务时间为'.self::TALK_WORDS['work_time'].'。当前暂无客服接待,您可以等待,登录平台可以进行离线留言'; } else { $push_data['content']='在线客服服务时间为'.self::TALK_WORDS['work_time'].'。当前暂无客服接待,您可以离线留言或等待'; } $server->push($fd,myResult($message_type,$push_data)); //向所有在线客服发送等待用户数 $this->pushUserQueueNum($server); } } //用户关闭通知(用户使用) protected function noticeUserLeave($server,$user_store,$cs_store,$remove_flag,$user_info_data){ //通知用户 $message_type = 'disconnect'; //$user_info_data = json_decode(RedisCache::hget('CHAT_USER_INFO',$user_store),true); $push_data = $user_info_data; //群体通知 if (is_array($cs_store)) { if (count($cs_store) > 0) { foreach ($cs_store as $k=>$v) { $cs_fd = RedisCache::hget('CHAT_CS_FD', $v); if ($cs_fd != null) { $push_data['remove_flag']=$remove_flag[$k]; Log::info('是否需要关闭'.json_encode($push_data['remove_flag'])); $server->push($cs_fd, myResult($message_type, $push_data)); } } /*$cs_fd_list = RedisCache::hmget('CHAT_CS_FD', $cs_store); if ($cs_fd_list !== false) { foreach ($cs_fd_list as $v) { $server->push($v, myResult($message_type, $push_data)); } }*/ } } else { //获得用户的fd $cs_fd=RedisCache::hget('CHAT_CS_FD',$cs_store); $server->push($cs_fd,myResult($message_type,$push_data)); } } //客服关闭通知(客服使用) protected function noticeCSLeave($server,$user_store,$cs_store,$message_type='disconnect'){ //通知用户 $cs_info_data = json_decode(RedisCache::hget('CHAT_CS_INFO',$cs_store),true); $push_data = $cs_info_data; //群体通知 if (is_array($user_store)) { if (count($user_store) > 0) { $user_fd_list = RedisCache::hmget('CHAT_USER_FD', $user_store); if ($user_fd_list !== false) { foreach ($user_fd_list as $v) { $server->push($v, myResult($message_type, $push_data)); } } } } else { //获得用户的fd $user_fd=RedisCache::hget('CHAT_USER_FD',$user_store); $server->push($user_fd,myResult($message_type,$push_data)); } } //IP获取地址 public function getIPArea($ip) { require_once Env::get('extend_path').'ip2region/Ip2Region.php'; $ip2region = new \Ip2Region(); $info = $ip2region->btreeSearch($ip); $city = explode('|', $info['region']); if (0 != $info['city_id']) { return $city['2'] . $city['3'] . $city['4']; } else { return $city['0']; } } //通过area_id获取地址 public function getIDArea($area_id) { $tmp_area_data=Db::name('area')->field('area_name,parent_area_id')->where(['id'=>$area_id])->find(); if ($tmp_area_data==null) { return ''; } if ($tmp_area_data['parent_area_id']!=0) { return $this->getIDArea($tmp_area_data['parent_area_id']).'-'.$tmp_area_data['area_name']; } else { return $tmp_area_data['area_name']; } } //解析session数据 protected function unserializePhp($session_data) { $return_data = array(); $offset = 0; while ($offset < strlen($session_data)) { if (!strstr(substr($session_data, $offset), "|")) { return false; } $pos = strpos($session_data, "|", $offset); $num = $pos - $offset; $varname = substr($session_data, $offset, $num); $offset += $num + 1; $data = unserialize(substr($session_data, $offset)); $return_data[$varname] = $data; $offset += strlen(serialize($data)); } return $return_data; } }