Files
CompanyProject/金壶/ydyd_service/application/http/service/CommonService.php
2024-09-27 01:32:49 +08:00

274 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\http\service;
use app\facade\AppConstant;
use app\facade\RedisCache;
use think\captcha\Captcha;
use think\Db;
use think\facade\Cache;
use think\facade\Config;
use think\facade\Env;
use think\facade\Log;
class CommonService
{
const TALK_WORDS=[
'hello_words'=>'您好,欢迎您使用金壶医药商城,请问您有什么疑问,我将为您在线解答。',
'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;
}
}