初始化代码
This commit is contained in:
212
app/im/TLSSigAPIv2.php
Normal file
212
app/im/TLSSigAPIv2.php
Normal file
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
namespace Tencent;
|
||||
if (version_compare(PHP_VERSION, '5.1.2') < 0) {
|
||||
trigger_error('need php 5.1.2 or newer', E_USER_ERROR);
|
||||
}
|
||||
class TLSSigAPIv2 {
|
||||
private $key = false;
|
||||
private $sdkappid = 0;
|
||||
public function __construct($sdkappid, $key) {
|
||||
$this->sdkappid = $sdkappid;
|
||||
$this->key = $key;
|
||||
}
|
||||
/**
|
||||
* 用于 url 的 base64 encode
|
||||
* '+' => '*', '/' => '-', '=' => '_'
|
||||
* @param string $string 需要编码的数据
|
||||
* @return string 编码后的base64串,失败返回false
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function base64_url_encode($string) {
|
||||
static $replace = Array('+' => '*', '/' => '-', '=' => '_');
|
||||
$base64 = base64_encode($string);
|
||||
if ($base64 === false) {
|
||||
throw new \Exception('base64_encode error');
|
||||
}
|
||||
return str_replace(array_keys($replace), array_values($replace), $base64);
|
||||
}
|
||||
/**
|
||||
* 用于 url 的 base64 decode
|
||||
* '+' => '*', '/' => '-', '=' => '_'
|
||||
* @param string $base64 需要解码的base64串
|
||||
* @return string 解码后的数据,失败返回false
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function base64_url_decode($base64) {
|
||||
static $replace = Array('+' => '*', '/' => '-', '=' => '_');
|
||||
$string = str_replace(array_values($replace), array_keys($replace), $base64);
|
||||
$result = base64_decode($string);
|
||||
if ($result == false) {
|
||||
throw new \Exception('base64_url_decode error');
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
* 使用 hmac sha256 生成 sig 字段内容,经过 base64 编码
|
||||
* @param $identifier 用户名,utf-8 编码
|
||||
* @param $curr_time 当前生成 sig 的 unix 时间戳
|
||||
* @param $expire 有效期,单位秒
|
||||
* @param $base64_userbuf base64 编码后的 userbuf
|
||||
* @param $userbuf_enabled 是否开启 userbuf
|
||||
* @return string base64 后的 sig
|
||||
*/
|
||||
private function hmacsha256($identifier, $curr_time, $expire, $base64_userbuf, $userbuf_enabled) {
|
||||
$content_to_be_signed = "TLS.identifier:" . $identifier . "\n"
|
||||
. "TLS.sdkappid:" . $this->sdkappid . "\n"
|
||||
. "TLS.time:" . $curr_time . "\n"
|
||||
. "TLS.expire:" . $expire . "\n";
|
||||
if (true == $userbuf_enabled) {
|
||||
$content_to_be_signed .= "TLS.userbuf:" . $base64_userbuf . "\n";
|
||||
}
|
||||
return base64_encode(hash_hmac( 'sha256', $content_to_be_signed, $this->key, true));
|
||||
}
|
||||
/**
|
||||
* 生成签名。
|
||||
*
|
||||
* @param $identifier 用户账号
|
||||
* @param int $expire 过期时间,单位秒,默认 180 天
|
||||
* @param $userbuf base64 编码后的 userbuf
|
||||
* @param $userbuf_enabled 是否开启 userbuf
|
||||
* @return string 签名字符串
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function __genSig($identifier, $expire, $userbuf, $userbuf_enabled) {
|
||||
$curr_time = time();
|
||||
$sig_array = Array(
|
||||
'TLS.ver' => '2.0',
|
||||
'TLS.identifier' => strval($identifier),
|
||||
'TLS.sdkappid' => intval($this->sdkappid),
|
||||
'TLS.expire' => intval($expire),
|
||||
'TLS.time' => intval($curr_time)
|
||||
);
|
||||
$base64_userbuf = '';
|
||||
if (true == $userbuf_enabled) {
|
||||
$base64_userbuf = base64_encode($userbuf);
|
||||
$sig_array['TLS.userbuf'] = strval($base64_userbuf);
|
||||
}
|
||||
$sig_array['TLS.sig'] = $this->hmacsha256($identifier, $curr_time, $expire, $base64_userbuf, $userbuf_enabled);
|
||||
if ($sig_array['TLS.sig'] === false) {
|
||||
throw new \Exception('base64_encode error');
|
||||
}
|
||||
$json_str_sig = json_encode($sig_array);
|
||||
if ($json_str_sig === false) {
|
||||
throw new \Exception('json_encode error');
|
||||
}
|
||||
$compressed = gzcompress($json_str_sig);
|
||||
if ($compressed === false) {
|
||||
throw new \Exception('gzcompress error');
|
||||
}
|
||||
return $this->base64_url_encode($compressed);
|
||||
}
|
||||
/**
|
||||
* 生成签名
|
||||
*
|
||||
* @param $identifier 用户账号
|
||||
* @param int $expire 过期时间,单位秒,默认 180 天
|
||||
* @return string 签名字符串
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function genSig($identifier, $expire=86400*180) {
|
||||
return $this->__genSig($identifier, $expire, '', false);
|
||||
}
|
||||
/**
|
||||
* 带 userbuf 生成签名。
|
||||
* @param $identifier 用户账号
|
||||
* @param int $expire 过期时间,单位秒,默认 180 天
|
||||
* @param string $userbuf 用户数据
|
||||
* @return string 签名字符串
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function genSigWithUserBuf($identifier, $expire, $userbuf) {
|
||||
return $this->__genSig($identifier, $expire, $userbuf, true);
|
||||
}
|
||||
/**
|
||||
* 验证签名。
|
||||
*
|
||||
* @param string $sig 签名内容
|
||||
* @param string $identifier 需要验证用户名,utf-8 编码
|
||||
* @param int $init_time 返回的生成时间,unix 时间戳
|
||||
* @param int $expire_time 返回的有效期,单位秒
|
||||
* @param string $userbuf 返回的用户数据
|
||||
* @param string $error_msg 失败时的错误信息
|
||||
* @return boolean 验证是否成功
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function __verifySig($sig, $identifier, &$init_time, &$expire_time, &$userbuf, &$error_msg) {
|
||||
try {
|
||||
$error_msg = '';
|
||||
$compressed_sig = $this->base64_url_decode($sig);
|
||||
$pre_level = error_reporting(E_ERROR);
|
||||
$uncompressed_sig = gzuncompress($compressed_sig);
|
||||
error_reporting($pre_level);
|
||||
if ($uncompressed_sig === false) {
|
||||
throw new \Exception('gzuncompress error');
|
||||
}
|
||||
$sig_doc = json_decode($uncompressed_sig);
|
||||
if ($sig_doc == false) {
|
||||
throw new \Exception('json_decode error');
|
||||
}
|
||||
$sig_doc = (array)$sig_doc;
|
||||
if ($sig_doc['TLS.identifier'] !== $identifier) {
|
||||
throw new \Exception("identifier dosen't match");
|
||||
}
|
||||
if ($sig_doc['TLS.sdkappid'] != $this->sdkappid) {
|
||||
throw new \Exception("sdkappid dosen't match");
|
||||
}
|
||||
$sig = $sig_doc['TLS.sig'];
|
||||
if ($sig == false) {
|
||||
throw new \Exception('sig field is missing');
|
||||
}
|
||||
$init_time = $sig_doc['TLS.time'];
|
||||
$expire_time = $sig_doc['TLS.expire'];
|
||||
$curr_time = time();
|
||||
if ($curr_time > $init_time+$expire_time) {
|
||||
throw new \Exception('sig expired');
|
||||
}
|
||||
$userbuf_enabled = false;
|
||||
$base64_userbuf = '';
|
||||
if (isset($sig_doc['TLS.userbuf'])) {
|
||||
$base64_userbuf = $sig_doc['TLS.userbuf'];
|
||||
$userbuf = base64_decode($base64_userbuf);
|
||||
$userbuf_enabled = true;
|
||||
}
|
||||
$sigCalculated = $this->hmacsha256($identifier, $init_time, $expire_time, $base64_userbuf, $userbuf_enabled);
|
||||
if ($sig != $sigCalculated) {
|
||||
throw new \Exception('verify failed');
|
||||
}
|
||||
return true;
|
||||
} catch (\Exception $ex) {
|
||||
$error_msg = $ex->getMessage();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 带 userbuf 验证签名。
|
||||
*
|
||||
* @param string $sig 签名内容
|
||||
* @param string $identifier 需要验证用户名,utf-8 编码
|
||||
* @param int $init_time 返回的生成时间,unix 时间戳
|
||||
* @param int $expire_time 返回的有效期,单位秒
|
||||
* @param string $error_msg 失败时的错误信息
|
||||
* @return boolean 验证是否成功
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function verifySig($sig, $identifier, &$init_time, &$expire_time, &$error_msg) {
|
||||
$userbuf = '';
|
||||
return $this->__verifySig($sig, $identifier, $init_time, $expire_time, $userbuf, $error_msg);
|
||||
}
|
||||
/**
|
||||
* 验证签名
|
||||
* @param string $sig 签名内容
|
||||
* @param string $identifier 需要验证用户名,utf-8 编码
|
||||
* @param int $init_time 返回的生成时间,unix 时间戳
|
||||
* @param int $expire_time 返回的有效期,单位秒
|
||||
* @param string $userbuf 返回的用户数据
|
||||
* @param string $error_msg 失败时的错误信息
|
||||
* @return boolean 验证是否成功
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function verifySigWithUserBuf($sig, $identifier, &$init_time, &$expire_time, &$userbuf, &$error_msg) {
|
||||
return $this->__verifySig($sig, $identifier, $init_time, $expire_time, $userbuf, $error_msg);
|
||||
}
|
||||
}
|
||||
112
app/im/common.php
Normal file
112
app/im/common.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
// 这是系统自动生成的im应用公共文件
|
||||
use app\im\model\ImUser;
|
||||
use app\im\model\ImChat;
|
||||
//获取用户缓存
|
||||
function getCacheUser($user_id ,$uniacid = '7777')
|
||||
{
|
||||
$key = 'longbing_card_user_' . $user_id;
|
||||
if(!hasCache($key ,$uniacid)) return null;
|
||||
return getCache($key ,$uniacid);
|
||||
}
|
||||
|
||||
//设置用户缓存数据
|
||||
function setCacheUser($user_id ,$value ,$uniacid = '7777')
|
||||
{
|
||||
$key = 'longbing_card_user_' . $user_id;
|
||||
return setCache ( $key, $value, 3600, $uniacid);
|
||||
}
|
||||
|
||||
//获取用户信息
|
||||
function getUser($user_id ,$uniacid ='7777')
|
||||
{
|
||||
//判断缓存是否存在
|
||||
$user = getCacheUser($user_id ,$uniacid);
|
||||
if(!empty($user)) return $user;
|
||||
//生成查询类
|
||||
$user_model = new ImUser();
|
||||
//获取数据
|
||||
$user = $user_model->getUser(['id' => $user_id ,'uniacid' => $uniacid]);
|
||||
if(empty($user)) return null;
|
||||
setCacheUser($user_id ,$user ,3600,$uniacid);
|
||||
return $user;
|
||||
}
|
||||
|
||||
////返回数据处理
|
||||
//function getWxApiReturnData($result)
|
||||
//{
|
||||
// if(isset($result['data']['page'])) $result['data']['current_page'] = $result['data']['page'];unset($result['data']['page']);
|
||||
// if(isset($result['data']['page_count'])) $result['data']['current_page'] = $result['data']['page_count'];unset($result['data']['page_count']);
|
||||
// if(isset($result['data']['total'])) $result['data']['current_page'] = $result['data']['total'];unset($result['data']['total']);
|
||||
// if(isset($result['data']['total_page'])) $result['data']['current_page'] = $result['data']['total_page'];unset($result['data']['total_page']);
|
||||
// return $result;
|
||||
//}
|
||||
|
||||
//获取chat
|
||||
function longbingGetChatById($chat_id ,$uniacid)
|
||||
{
|
||||
//设置key
|
||||
$key = 'longbing_card_chat_new_' . $chat_id;
|
||||
//从缓存中获取数据
|
||||
$chat = getCache($key ,$uniacid);
|
||||
//判断缓存数据是否存在
|
||||
if(empty($chat))
|
||||
{
|
||||
//生成chat操作模型
|
||||
$chat_model = new ImChat();
|
||||
//获取数据
|
||||
$chat = $chat_model->getChatById($chat_id);
|
||||
if(!empty($chat)) setCache($key ,$chat ,$uniacid);
|
||||
}
|
||||
return $chat;
|
||||
}
|
||||
|
||||
//获取chat
|
||||
function longbingGetChat($user_id ,$customer_id ,$uniacid = 7777 ,$is_create = true)
|
||||
{
|
||||
//判断用户和客户是否是同一人
|
||||
if(empty($user_id) || empty($customer_id) || in_array($user_id, [$customer_id])) return false;
|
||||
//查找数据
|
||||
$chat_model = new ImChat();
|
||||
$chat = $chat_model->getChat($user_id ,$customer_id ,$uniacid);
|
||||
if(isset($chat['id'])){
|
||||
$key = 'longbing_card_chat_new_' . $chat['id'];
|
||||
setCache($key ,$chat ,$uniacid);
|
||||
}
|
||||
//如果数据不存在
|
||||
if(empty($chat) && $is_create){
|
||||
//判断用户是否存在
|
||||
$user = longbingGetUser($user_id ,$uniacid);
|
||||
if(empty($user)) return false;
|
||||
//判断客户是否存在
|
||||
$customer = longbingGetUser($customer_id ,$uniacid);
|
||||
if(empty($customer)) return false;
|
||||
//生成chat数据
|
||||
$chat_data = array(
|
||||
'user_id' => $user_id,
|
||||
'target_id' => $customer_id,
|
||||
'uniacid' => $uniacid
|
||||
);
|
||||
if($chat_model->createChat($chat_data)){
|
||||
$chat = longbingGetChat($user_id ,$customer_id ,$uniacid);
|
||||
}
|
||||
}
|
||||
if(isset($chat['chat_id'])) $chat['id'] = $chat['chat_id'];
|
||||
return $chat;
|
||||
}
|
||||
|
||||
/**
|
||||
* 腾讯聊天签名方法
|
||||
*
|
||||
* @param $sdkappid
|
||||
* @param $key
|
||||
* @param $user_id
|
||||
* @return mixed
|
||||
* @author shuixian
|
||||
* @DataTime: 2019/12/10 11:29
|
||||
*/
|
||||
function longbing_publics_tim_genSig($sdkappid, $key,$user_id){
|
||||
require_once 'TLSSigAPIv2.php';
|
||||
$TLSSigAPIv2 = new \Tencent\TLSSigAPIv2($sdkappid, $key);
|
||||
return $TLSSigAPIv2->genSig($user_id);
|
||||
}
|
||||
50
app/im/controller/BaseMessage.php
Normal file
50
app/im/controller/BaseMessage.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Longbing [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright Chengdu longbing Technology Co., Ltd.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Website http://longbing.org/
|
||||
// +----------------------------------------------------------------------
|
||||
// | Sales manager: +86-13558882532 / +86-13330887474
|
||||
// | Technical support: +86-15680635005
|
||||
// | After-sale service: +86-17361005938
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\im\controller;
|
||||
|
||||
|
||||
class BaseMessage
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $server
|
||||
* @param $client_id
|
||||
* @param $action
|
||||
* @param bool $status
|
||||
* @param string $message
|
||||
* @param array $data
|
||||
* @功能说明:发送消息方式
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/13 13:53
|
||||
*/
|
||||
public function sendServerMsg($server, $client_id , $action , $status = true, $message = '' , $data = []){
|
||||
|
||||
$dataStr = json_encode(
|
||||
[
|
||||
'action' => $action ,
|
||||
'status' => $status ,
|
||||
'message'=> $message ,
|
||||
'data' => $data,
|
||||
'time' => time()
|
||||
]
|
||||
);
|
||||
|
||||
$server->push($client_id , $dataStr) ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
178
app/im/controller/Car.php
Normal file
178
app/im/controller/Car.php
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
//include 'crc.php';
|
||||
//include 'net.php';
|
||||
|
||||
|
||||
//打印十六进制(可以不用)
|
||||
function println($bytes) {
|
||||
for($i=0;$i<count($bytes);$i++)
|
||||
{
|
||||
printf("%02X ", $bytes[$i]);
|
||||
}
|
||||
printf(".");
|
||||
}
|
||||
|
||||
|
||||
//这里开始
|
||||
//$net = new net();
|
||||
$socket = listen('0.0.0.0', 50000);
|
||||
|
||||
|
||||
|
||||
while(true) {
|
||||
$cs = accept($socket);
|
||||
|
||||
printf($cs);
|
||||
|
||||
while($cs) {
|
||||
|
||||
try{
|
||||
$ret = recv_bytes($cs, 1024);
|
||||
abc($ret);
|
||||
//println($ret);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
close();
|
||||
printf('cs close');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
close();
|
||||
|
||||
|
||||
function listen($ip, $port)
|
||||
{
|
||||
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
|
||||
socket_bind($socket, $ip, $port);
|
||||
$ex = socket_listen($socket, 4);
|
||||
//socket_bind($this->socket, '127.0.0.1', $port) or die("socket_bind() fail:" . socket_strerror(socket_last_error()) . "/n");
|
||||
//$ex = socket_listen($this->socket, 4) or die("socket_listen() fail:" . socket_strerror(socket_last_error()) . "/n");
|
||||
|
||||
// return $ex;
|
||||
return $socket;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//abc处理读取到的卡(4字节);
|
||||
function abc($ret)
|
||||
{
|
||||
$len = $ret[4];
|
||||
|
||||
if($len < 14)
|
||||
{
|
||||
//printf('无效数据');
|
||||
return ;
|
||||
}
|
||||
//
|
||||
$count = $ret[9];
|
||||
|
||||
$count = ($count - 3) / 4;
|
||||
//
|
||||
for($i=0; $i<$count; $i++)
|
||||
{
|
||||
$idx = 10 + ($i * 4);
|
||||
|
||||
$card = sprintf("%02X%02X%02X%02X", $ret[$idx+0], $ret[$idx+1], $ret[$idx+2], $ret[$idx+3]);//这是获取到的卡数据(按文档意思可能会读到多张卡,处理这个$card就可以了)
|
||||
$card = sprintf("%02X%02X%02X", $ret[$idx+0], $ret[$idx+1], $ret[$idx+2]);//这是获取到的卡数据(按文档意思可能会读到多张卡,处理这个$card就可以了)
|
||||
|
||||
printf('card['.$i.']>>'.$card.' | ');
|
||||
|
||||
// $post_data['data'] = 'card['.$i.']>>'.$card.' | ';
|
||||
|
||||
$card_id = $card;
|
||||
|
||||
$card = 'card['.$i.']>>'.$card.' | ';
|
||||
|
||||
$url = 'https://car.cncnconnect.com/massage/admin/Tcp/getInfo?card_id='.$card_id.'&time='.msectime();
|
||||
|
||||
$a = file_get_contents($url);
|
||||
|
||||
// printf(json_encode($a));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function msectime() {
|
||||
|
||||
list($msec,$sec) = explode(' ', microtime());
|
||||
|
||||
$msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
|
||||
|
||||
return $msectime;
|
||||
}
|
||||
|
||||
function crulGetData($url, $post, $method, $header=1){
|
||||
// $this->_errno = NULL;
|
||||
// $this->_error = NULL;
|
||||
$ch = curl_init($url);
|
||||
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
|
||||
if($post != NULL)
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,true);
|
||||
curl_setopt($ch, CURLOPT_AUTOREFERER,true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
|
||||
|
||||
if($header)
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
'Content-type: application/json',
|
||||
)
|
||||
);
|
||||
$result = curl_exec($ch);
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function accept($socket)
|
||||
{
|
||||
return socket_accept($socket);
|
||||
}
|
||||
|
||||
function close()
|
||||
{
|
||||
if($this->socket == 0) return;
|
||||
socket_close($this->socket);
|
||||
$this->socket = 0;
|
||||
}
|
||||
|
||||
function recv_bytes($cs, $len = 1024)
|
||||
{
|
||||
$ret = recv($cs, $len);
|
||||
|
||||
$bytes = string_to_bytes($ret);
|
||||
return $bytes;
|
||||
}
|
||||
function recv($cs, $len = 1024)
|
||||
{
|
||||
|
||||
|
||||
$ret = socket_read($cs, $len) or die("/n");
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
function string_to_bytes($str)
|
||||
{
|
||||
$bytes = array();
|
||||
for($i=0; $i<strlen($str); $i++)
|
||||
{
|
||||
$bytes[] = ord($str[$i]);
|
||||
}
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
624
app/im/controller/Im.php
Normal file
624
app/im/controller/Im.php
Normal file
@@ -0,0 +1,624 @@
|
||||
<?php
|
||||
|
||||
namespace app\im\controller;
|
||||
use app\ApiRest;
|
||||
use app\Common\service\LongbingUserInfoService;
|
||||
use app\im\model\ImMessageFriend;
|
||||
use app\im\service\ImMessageFriendService;
|
||||
use app\im\service\ImService;
|
||||
use longbingcore\tools\LongbingDefault;
|
||||
use longbingcore\tools\LongbingTime;
|
||||
use think\App;
|
||||
use think\Request;
|
||||
use app\im\model\ImChart;
|
||||
use app\im\model\ImChat;
|
||||
use app\im\model\ImMessage;
|
||||
use app\im\model\ImUser;
|
||||
use app\im\model\ImMyReply;
|
||||
use app\im\model\ImReplyType;
|
||||
use app\card\model\UserInfo;
|
||||
use app\card\model\UserPhone;
|
||||
use app\im\model\ImClient;
|
||||
class Im extends ApiRest
|
||||
{
|
||||
public $user_id = null;
|
||||
public $user = null;
|
||||
public function __construct(App $app) {
|
||||
parent::__construct($app);
|
||||
$this->user_id = $this->getUserId();
|
||||
$this->user = $this->getUserInfo();
|
||||
}
|
||||
|
||||
//获取客户列表
|
||||
public function listCustomer()
|
||||
{
|
||||
//获取参数列表
|
||||
$param = $this->_param;
|
||||
//获取用户列表
|
||||
$user_id = $this->user_id;
|
||||
//判断用户是否存在
|
||||
if(empty($user_id)) return $this->error('not login ,please login again.');
|
||||
|
||||
|
||||
//生成分页信息
|
||||
$page_config = array(
|
||||
'page' => 1,
|
||||
'page_count' => 10
|
||||
);
|
||||
//获取分页信息
|
||||
if(isset($param['page']) && $param['page'] > 0) $page_config['page'] = $param['page'];
|
||||
if(isset($param['page_count']) && $param['page_count'] > 0) $page_config['page_count'] = $param['page_count'];
|
||||
//生成查询模型
|
||||
$chat_model = new ImChat();
|
||||
//生成消息查询模型
|
||||
$message_model = new ImMessage();
|
||||
//生成用户查询模型
|
||||
// $user_model = new ImUser();
|
||||
//生成查询
|
||||
$page_config['total'] = $chat_model->listChatCount($user_id ,$this->_uniacid );
|
||||
$chats = $chat_model->listChat($user_id ,$this->_uniacid ,$page_config);
|
||||
$data = [];
|
||||
if(!empty($chats))
|
||||
{
|
||||
foreach($chats as $key => $value)
|
||||
{
|
||||
//获取客户信息
|
||||
$customer_id = null;
|
||||
if(!in_array($value['user_id'], [$user_id])) $customer_id = $value['user_id'];
|
||||
if(!in_array($value['target_id'], [$user_id])) $customer_id = $value['target_id'];
|
||||
if(empty($customer_id)) continue;
|
||||
//获取客户信息
|
||||
// $value['customer'] = $user_model->getUser(['id' => $customer_id]);
|
||||
$customer = longbingGetUser($customer_id ,$this->_uniacid);
|
||||
if(!empty($customer['is_staff']))
|
||||
{
|
||||
$customer_info = longbingGetUserInfo($customer_id ,$this->_uniacid);
|
||||
if(isset($customer_info['is_staff']) && !empty($customer_info['is_staff']))
|
||||
{
|
||||
if(!empty($customer_info['avatar'])) {
|
||||
$customer_info = transImagesOne($customer_info ,['avatar'] ,$this->_uniacid);
|
||||
}
|
||||
//是员工 就用员工头像 By.jingshuixian
|
||||
//if(!empty($customer_info['avatar'])) $customer['avatarUrl'] = $customer_info['avatar'];
|
||||
}
|
||||
}
|
||||
$value['customer'] = $customer;
|
||||
if(empty($value['customer'])) continue;
|
||||
|
||||
//获取最后一条消息
|
||||
$lastmessage = $message_model->lastMessage(['chat_id' => $value['id']]);
|
||||
//如果最后一条消息是图片
|
||||
if(isset($lastmessage['message_type']) && !in_array($lastmessage['message_type'], ['text' ])) $lastmessage['content'] = lang($lastmessage['message_type']);
|
||||
$value['lastmessage'] = $lastmessage;
|
||||
//获取未读消息总数
|
||||
$not_rear_message_count = $message_model->listMessageCount(['chat_id' => $value['id'] ,'user_id' => $customer_id ,'target_id' => $user_id ,'status' => 1]);
|
||||
|
||||
//未读消息总数
|
||||
$value['not_read_message_count'] = $not_rear_message_count;
|
||||
//获取时间
|
||||
if(isset($value['update_time']) && !empty($value['update_time'])) $value['time'] = date('Y-m-d H:i:s', $value['update_time']);
|
||||
//判断用户是否存在头像
|
||||
if(!isset($value['customer']['avatarUrl']) || empty($value['customer']['avatarUrl'])) $value['customer']['avatarUrl'] = $this->defaultImage['avatar'];
|
||||
//判断客户是否是员工
|
||||
if(isset($value['customer']['is_staff']) && !empty($value['customer']['is_staff']))
|
||||
{
|
||||
//获取员工信息
|
||||
$user_info = longbingGetUserInfo($customer_id ,$this->_uniacid);
|
||||
if(isset($user_info['is_staff']) && !empty($user_info['is_staff']) && isset($user_info['name']) && !empty($user_info['name'])){
|
||||
$value['customer']['nickName'] = $user_info['name'];
|
||||
}
|
||||
}
|
||||
$data[] = $value;
|
||||
}
|
||||
}
|
||||
$page_config['total_page'] = (int)($page_config['total'] / $page_config['page_count']);
|
||||
if(($page_config['total'] % $page_config['page_count']) > 0) $page_config['total_page'] = $page_config['total_page'] + 1;
|
||||
$result = $page_config;
|
||||
$result['data'] = $data;
|
||||
|
||||
//总计未读数
|
||||
$result['unReadMessageCount'] = ImService::getUnReadMessageCount($this->user_id);
|
||||
|
||||
//数据处理
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/16 15:58
|
||||
* @功能说明:新版获取用户列表信息
|
||||
*/
|
||||
public function listCustomerV2(){
|
||||
|
||||
//获取参数列表
|
||||
$param = $this->_param;
|
||||
//获取用户列表
|
||||
$user_id = $this->user_id;
|
||||
//判断用户是否存在
|
||||
if(empty($user_id)) return $this->error('not login ,please login again.');
|
||||
//初始化朋友列表,兼容老数据
|
||||
ImMessageFriendService::initOldFriendList($this->_uniacid , $user_id) ;
|
||||
|
||||
$result = ImMessageFriendService::getFriendList($this->_uniacid , $user_id , $param['page_count'] ) ;
|
||||
//总计未读数
|
||||
$result['unReadMessageCount'] = ImService::getUnReadMessageCount($this->user_id);
|
||||
//数据处理
|
||||
return $this->success($result);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//获取未读消息列表
|
||||
public function listNotReadMessage()
|
||||
{
|
||||
//获取参数
|
||||
$param = $this->_param;
|
||||
$user_id = $this->user_id;
|
||||
if(!isset($param['chat_id']) || !isset($param['target_id'])) return $this->error(lang('not chat id ,please check param'));
|
||||
if(isset($param['target_id']) && !isset($param['chat_id']) && !empty($param['target_id']))
|
||||
{
|
||||
//获取chat数据
|
||||
$chat = longbingGetChat($user_id ,$param['target_id'] ,$this->_uniacid);
|
||||
if(isset($chat['id'])) $param['chat_id'] = $chat['id'];
|
||||
}
|
||||
//判断chat_id参数是否存在
|
||||
if(!isset($param['chat_id'])) return $this->error('not chat id ,please check param');
|
||||
//if(!isset($param['user_id'])) return $this->error('not user id ,please check param');
|
||||
$chat_id = $param['chat_id'];
|
||||
//获取客户关系
|
||||
$chat = longbingGetChatById($chat_id ,$this->_uniacid);
|
||||
//判断数据是否存在
|
||||
if(empty($chat)) return $this->error('not the chat ,please check chat id');
|
||||
$customer_id = $chat['user_id'];
|
||||
if(in_array($customer_id, [$this->user_id])) $customer_id = $chat['target_id'];
|
||||
$user_id = $this->user_id;
|
||||
//生成查询模型
|
||||
$message_model = new ImMessage();
|
||||
//查询数据
|
||||
$messages = $message_model->listNotReadMessage(['chat_id' => $chat_id ,'target_id' => $user_id]);
|
||||
|
||||
$result['data'] = [];
|
||||
if(!empty($page_config['total'])){
|
||||
foreach($messages as $key => $val)
|
||||
{
|
||||
if(isset($val['create_time']) && !empty($val['create_time'])) $val['time'] = date('Y-m-d H:i:s', $val['create_time']);
|
||||
$result['data'][] = $val;
|
||||
}
|
||||
|
||||
}
|
||||
if(isset($this->user['qr_path'])) $this->user = transImagesOne ( $this->user, ['qr_path'] );
|
||||
$result['user'] = $this->user;
|
||||
$customer = getUser($customer_id ,$this->_uniacid);
|
||||
|
||||
|
||||
if(isset($customer['qr_path'])) $customer = transImagesOne ( $customer, ['qr_path'] );
|
||||
$result['customer'] = $customer;
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
//获取消息列表
|
||||
public function listMessage()
|
||||
{
|
||||
$user = longbingGetUser($this->user_id ,$this->_uniacid);
|
||||
//获取参数
|
||||
$param = $this->_param;
|
||||
$chat_id = null;
|
||||
$customer_id = null;
|
||||
$chat = null;
|
||||
//判断参数是否存在
|
||||
if(isset($param['chat_id'])) $chat_id = $param['chat_id'];
|
||||
if(isset($param['customer_id'])) $customer_id = $param['customer_id'];
|
||||
if(empty($chat_id) && empty($customer_id)) $this->error(lang('not customer id,please check param'));
|
||||
//参数处理(兼容处理)
|
||||
$result = [];
|
||||
if(!empty($chat_id))
|
||||
{
|
||||
$chat = longbingGetChatById($chat_id ,$this->_uniacid);
|
||||
}
|
||||
else{
|
||||
$chat = longbingGetChat($this->user_id ,$customer_id ,$this->_uniacid ,true);
|
||||
}
|
||||
//生成分页信息
|
||||
$page_config = array(
|
||||
'page' => 1,
|
||||
'page_count' => 20
|
||||
);
|
||||
|
||||
|
||||
//获取分页信息
|
||||
if(isset($param['page']) && $param['page'] > 0) $page_config['page'] = $param['page'];
|
||||
if(isset($param['page_count']) && $param['page_count'] > 0) $page_config['page_count'] = $param['page_count'];
|
||||
if(!empty($chat))
|
||||
{
|
||||
$customer_id = $chat['user_id'];
|
||||
if(empty($chat_id)) $chat_id = $chat['chat_id'];
|
||||
if(in_array($customer_id, [$this->user_id])) $customer_id = $chat['target_id'];
|
||||
//生成消息查询模型
|
||||
$message_model = new ImMessage();
|
||||
//获取查询总数
|
||||
$page_config['total'] = $message_model->listMessageCount(['chat_id' => $chat_id]);
|
||||
//生成分页数据
|
||||
$page_config['total_page'] = (int)($page_config['total'] / $page_config['page_count']);
|
||||
if(($page_config['total'] % $page_config['page_count']) > 0) $page_config['total_page'] = $page_config['total_page'] + 1;
|
||||
//生成返回数据
|
||||
}else{
|
||||
$page_config['total'] = 0;
|
||||
$page_config['total_page'] = 0;
|
||||
}
|
||||
$result = $page_config;
|
||||
$result['data'] = [];
|
||||
//获取客户信息
|
||||
$customer = longbingGetUser($customer_id ,$this->_uniacid);
|
||||
if(empty($customer)) return $this->error(lang('user not exist.'));
|
||||
//获取头像
|
||||
if(isset($customer['avatarUrl'])) {
|
||||
$customer = transImagesOne ( $customer, ['avatarUrl'] ,$this->_uniacid);
|
||||
}else{
|
||||
$customer['avatarUrl'] = $this->defaultImage['avatarUrl'];
|
||||
}
|
||||
//判断客户是否是员工
|
||||
if(!empty($customer['is_staff']))
|
||||
{
|
||||
$customer_info = longbingGetUserInfo($customer_id ,$this->_uniacid);
|
||||
if(isset($customer_info['is_staff']) && !empty($customer_info['is_staff']))
|
||||
{
|
||||
if(!empty($customer_info['avatar'])) {
|
||||
$customer_info = transImagesOne($customer_info ,['avatar'] ,$this->_uniacid);
|
||||
}
|
||||
if(!empty($customer_info['avatar'])) $customer['avatarUrl'] = $customer_info['avatar'];
|
||||
}
|
||||
}
|
||||
//获取客户电话号码和微信号码
|
||||
$customer['wechat'] = null;
|
||||
$phone = null;
|
||||
$user_info_model = new UserInfo();
|
||||
//获取微信和电话号码
|
||||
$user_info = $user_info_model->getUserPhone($customer_id ,$this->_uniacid);
|
||||
if(isset($user_info['phone']) && !empty($user_info['phone'])) $phone = $user_info['phone'];
|
||||
if(isset($user_info['wechat']) && !empty($user_info['wechat'])) $customer['wechat'] = $user_info['wechat'];
|
||||
if(empty($phone)){
|
||||
$user_phone_model = new UserPhone();
|
||||
$user_phone = $user_phone_model->getUserPhone($customer_id ,$this->_uniacid);
|
||||
if(isset($user_phone['phone']) && !empty($user_phone['phone'])) $phone = $user_phone['phone'];
|
||||
}
|
||||
//判断聊天者是否是客户
|
||||
$customer['is_customer'] = false;
|
||||
$collection_model = new ImClient();
|
||||
if(!empty($collection_model->isCustomer($this->user_id , $customer_id ,$this->_uniacid))) $customer['is_customer'] = true;
|
||||
//判断客户是否是员工
|
||||
if(isset($customer['is_staff']) && !empty($customer['is_staff']))
|
||||
{
|
||||
$customer_info = longbingGetUserInfo($customer_id ,$this->_uniacid);
|
||||
if(isset($customer_info['is_staff']) && !empty($customer_info['is_staff']) && isset($customer_info['name']) && !empty($customer_info['name'])){
|
||||
$customer['nickName'] = $customer_info['name'];
|
||||
//生成第一条默认返回数据
|
||||
$result['data'][] = array(
|
||||
'chat_id' => $chat['id'],
|
||||
'user_id' => $customer_id,
|
||||
'target_id' => $this->user_id,
|
||||
'status' => 2,
|
||||
'uniacid' => $this->_uniacid,
|
||||
'message_type' => 'welcome',
|
||||
'content' => lang('Hello, I am ') . $customer['nickName'] . lang(', May I help you? Please contact me!')
|
||||
);
|
||||
}
|
||||
}
|
||||
$customer['phone'] = $phone;
|
||||
|
||||
if(!empty($page_config['total'])){
|
||||
|
||||
$msgwhere[] = ['chat_id','=',$chat_id];
|
||||
//自己发送的
|
||||
$msgwhere[] = ['is_show','<>',2];
|
||||
|
||||
$msgwhere[] = ['user_id','=',$this->getUserId()];
|
||||
|
||||
$msgwhere[] = ['deleted','=',0];
|
||||
|
||||
$whereT[] = ['deleted','=',0];
|
||||
//自己接受的
|
||||
$whereT[] = ['target_id','=',$this->getUserId()];
|
||||
|
||||
$whereT[] = ['target_is_show','<>',2];
|
||||
|
||||
$whereT[] = ['chat_id','=',$chat_id];
|
||||
|
||||
foreach($message_model->listMessageV2($msgwhere ,$page_config,$whereT) as $key => $val)
|
||||
{
|
||||
if(isset($val['create_time']) && !empty($val['create_time'])) $val['time'] = date('Y-m-d H:i:s', $val['create_time']);
|
||||
$result['data'][] = $val;
|
||||
}
|
||||
|
||||
//dump($this->getUserId(),$chat['user_id'],$msgwhere,$result['data']);exit;
|
||||
|
||||
}
|
||||
// if(isset($this->user['qr_path'])) $this->user = transImagesOne ( $this->user, ['qr_path'] );
|
||||
|
||||
//判断用户是否是员工
|
||||
if(!empty($user['is_staff']))
|
||||
{
|
||||
$user_info = longbingGetUserInfo($this->user_id ,$this->_uniacid);
|
||||
if(isset($user_info['is_staff']) && !empty($user_info['is_staff']))
|
||||
{
|
||||
if(!empty($user_info['avatar'])) {
|
||||
$user_info = transImagesOne($user_info ,['avatar'] ,$this->_uniacid);
|
||||
}
|
||||
if(!empty($user_info['avatar'])) $user['avatarUrl'] = $user_info['avatar'];
|
||||
}
|
||||
}
|
||||
|
||||
//默认头像处理
|
||||
|
||||
//没有头像就给一个默认头像
|
||||
$customer['avatarUrl'] = empty($customer['avatarUrl']) ? LongbingDefault::$avatarImgUrl : $customer['avatarUrl'];
|
||||
$user['avatarUrl'] = empty($user['avatarUrl']) ? LongbingDefault::$avatarImgUrl : $user['avatarUrl'];
|
||||
|
||||
$result['user'] = $user;
|
||||
|
||||
$result['customer'] = $customer;
|
||||
//阅读所有消息
|
||||
$result['readMessageNumber'] = ImService::readMessage($this->_uniacid ,$this->user_id , $customer_id);
|
||||
|
||||
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
//标记已读消息
|
||||
public function readMessage()
|
||||
{
|
||||
$param = $this->_param ;
|
||||
$message_model = new ImMessage();
|
||||
$count = 0 ;
|
||||
if ( isset($param['id']) ) {
|
||||
$id = $param['id'] ;
|
||||
$message = $message_model->find($id);
|
||||
if($message){
|
||||
ImService::readMessage($this->_uniacid ,$this->user_id , $message['user_id'] ) ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->success(['count' => $count ] );
|
||||
|
||||
}
|
||||
|
||||
//获取常用话术
|
||||
public function listReply()
|
||||
{
|
||||
//获取用户信息
|
||||
$user_id = $this->user_id;
|
||||
//生成话术分类查询模型
|
||||
$reply_type_model = new ImReplyType();
|
||||
//生成快速回复话术查询模型
|
||||
$reply_model = new ImMyReply();
|
||||
//获取自定义话术
|
||||
$my_replys = $reply_model->listReply(['uniacid' => $this->_uniacid ,'user_id' => $user_id ,'status' => 1]);
|
||||
$result[] = ['title' => lang('my reply') , 'data' => $my_replys ,'is_myself' => true];
|
||||
//获取types
|
||||
$types = $reply_type_model->listAllType(['uniacid' => $this->_uniacid ,'status' => 1]);
|
||||
foreach($types as $type)
|
||||
{
|
||||
$data['title'] = $type['title'];
|
||||
$data['data'] = $reply_model->listReply(['uniacid' => $this->_uniacid ,'user_id' => 0 ,'status' => 1 ,'type' => $type['id']]);
|
||||
$data['is_myself'] = false;
|
||||
$result[] = $data;
|
||||
}
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
//创建和更新常用话术
|
||||
public function addReply()
|
||||
{
|
||||
//获取参数
|
||||
$input = $this->_input;
|
||||
$param = $this->_param;
|
||||
if(!isset($input['content'])) return $this->error('content is not exist ,please check .');
|
||||
$is_create = true;
|
||||
if(isset($input['id']) && !empty($input['id'])) $is_create = false;
|
||||
//获取用户信息
|
||||
$user_id = $this->user_id;
|
||||
//生成快速回复话术查询模型
|
||||
$my_reply_model = new ImMyReply();
|
||||
if($is_create)
|
||||
{
|
||||
//创建
|
||||
$result = $my_reply_model->createReply(['uniacid' => $this->_uniacid ,'status' => 1 ,'content' => $input['content'] ,'user_id' => $user_id]);
|
||||
}else{
|
||||
//修改
|
||||
$result = $my_reply_model->updateReply(['id' =>$param['id'] , 'uniacid' => $this->_uniacid ,'user_id' => $user_id] ,['content' => $input['content']]);
|
||||
}
|
||||
|
||||
//获取自定义话术
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
//删除常用话术
|
||||
public function delReply()
|
||||
{
|
||||
$param = $this->_param;
|
||||
$user_id = $this->user_id;
|
||||
if(!isset($param['id'])) return $this->error('reoly id is not exist ,please check .');
|
||||
//生成快速回复话术查询模型
|
||||
$my_reply_model = new ImMyReply();
|
||||
//删除话术
|
||||
$result = $my_reply_model->deleteReply(['id' =>$param['id'] ,'uniacid' => $this->_uniacid ,'user_id' => $user_id]);
|
||||
|
||||
return $this->success($result);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 腾讯IM签名
|
||||
*
|
||||
* @author shuixian
|
||||
* @DataTime: 2019/12/10 11:30
|
||||
*/
|
||||
public function getTimUserSig(){
|
||||
//需要远程获取和加密
|
||||
$sdkappid = 1400288706 ;
|
||||
$key = 'd31548b81e57bf823e12d240e4cce237e09f666bdff3fc325eb4bc386e62832d' ;
|
||||
$user_id = $this->_param['user_id'];
|
||||
$userSig = longbing_publics_tim_genSig($sdkappid , $key , $user_id );
|
||||
|
||||
$result = ['user_id'=>$user_id , 'userSig' => $userSig] ;
|
||||
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存聊天信息
|
||||
*
|
||||
* @return \think\Response
|
||||
* @author shuixian
|
||||
* @DataTime: 2019/12/11 9:29
|
||||
*/
|
||||
public function sendMessage(){
|
||||
//获取参数列表
|
||||
|
||||
//{type: "text", content: "456789", target_id: 14, uniacid: "8890", user_id: 20} //发消息
|
||||
//{"action":"getUnReadMessageCount","status":true,"message":"","data":{"count":2}} // 获取未读消息树
|
||||
$param = $this->_param;
|
||||
|
||||
//获取房间ID
|
||||
|
||||
$chat_id = ImService::getChatId($this->_uniacid , $this->user_id, $param['target_id']);
|
||||
//还需要校验参数合法新
|
||||
|
||||
$value['message_type'] = $param['message_type'];
|
||||
$value['chat_id'] = $chat_id;//需要获取和判断
|
||||
$value['user_id'] = $this->user_id;
|
||||
$value['target_id'] = $param['target_id']; //需要判断接收用户的合法性
|
||||
$value['content'] = $param['content'];
|
||||
$value['status'] = 1;
|
||||
$value['uniacid'] = $this->_uniacid;
|
||||
$value['create_time'] = time();
|
||||
$value['update_time'] = time();
|
||||
$value['is_show'] = 1;
|
||||
|
||||
$result = ImService::addMessage($value);
|
||||
|
||||
if($result){
|
||||
$value['id'] = $result ;
|
||||
|
||||
ImService::sendImMessageTmpl($this->_uniacid , $value['user_id'] , $value['target_id']) ;
|
||||
|
||||
|
||||
return $this->success( $value );
|
||||
}else{
|
||||
$this->error('');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/15 13:13
|
||||
* @功能说明:获取目标客户发送的消息数量
|
||||
*/
|
||||
public function getCustomerUnReadMessageCount(){
|
||||
|
||||
|
||||
$param = $this->_param ;
|
||||
|
||||
$user_id = $this->user_id;
|
||||
|
||||
$target_id = 0 ;
|
||||
|
||||
$count = 0 ;
|
||||
|
||||
if (isset($param['target_id'])) {
|
||||
|
||||
$target_id = $param['target_id'];
|
||||
|
||||
$count = ImService::getUnReadMessageCountByUserIdAndTargetId( $target_id , $user_id);
|
||||
|
||||
}
|
||||
|
||||
$data[] = ['action'=> 'getCustomerUnReadMessageCount' , 'data' => ['count' => $count, 'user_id' => $user_id , 'target_id' => $target_id ] ] ;
|
||||
|
||||
$data[] = ['action' => 'getUnReadMessageCount' , 'data' => ['count' => ImService::getUnReadMessageCount($user_id) ] ] ;
|
||||
|
||||
$message_model = new ImMessage();
|
||||
|
||||
$messageList = $message_model->where( [ ['user_id' , '=' ,$target_id ] ,[ 'target_id' , '=' , $user_id ] , ['status', '=' , 1]] )->select();
|
||||
|
||||
foreach ($messageList as $item ){
|
||||
|
||||
$data[] = ['action' => 'getNewMessage' , 'data' => $item ] ;
|
||||
}
|
||||
|
||||
$key = 'message'.$user_id.'-'.$target_id;
|
||||
//获取撤回消息
|
||||
$cancel_msg = getCache($key,$this->_uniacid);
|
||||
|
||||
$data[] = ['action' => 'getCancelMessage' , 'data' => $cancel_msg ] ;
|
||||
|
||||
setCache($key,[],0,$this->_uniacid);
|
||||
|
||||
return $this->success( $data ) ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-05-26 17:33
|
||||
* @功能说明:修改消息状态 1都可见 2删除对方可见 撤回都不可见
|
||||
*/
|
||||
public function updateMsgStatus(){
|
||||
|
||||
$input = $this->_input;
|
||||
|
||||
$message_model = new ImMessage();
|
||||
|
||||
$info = $message_model->where(['id'=>$input['id']])->find()->toArray();
|
||||
//撤回只有送人课操作
|
||||
if($input['is_show']==-1){
|
||||
|
||||
$update['is_show'] = -1;
|
||||
|
||||
if($info['target_is_show']==1){
|
||||
|
||||
$update['target_is_show'] = -1;
|
||||
}
|
||||
|
||||
}
|
||||
//删除
|
||||
if($input['is_show']==2){
|
||||
//判断我是否是发送者
|
||||
if($info['user_id']==$this->getUserId()){
|
||||
|
||||
$update['is_show'] = 2;
|
||||
|
||||
}else{
|
||||
|
||||
$update['target_is_show'] = 2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$res = $message_model->where(['id'=>$input['id']])->update($update);
|
||||
|
||||
$data = $message_model->where(['id'=>$input['id']])->find();
|
||||
|
||||
if(!empty($data)){
|
||||
|
||||
$data = $data->toArray();
|
||||
|
||||
$key = 'message'.$data['target_id'].'-'.$data['user_id'];
|
||||
|
||||
setCache($key,$data,0,$this->_uniacid);
|
||||
|
||||
}
|
||||
|
||||
return $this->success( $res ) ;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
10
app/im/controller/Index.php
Normal file
10
app/im/controller/Index.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace app\im\controller;
|
||||
|
||||
class Index
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return '您好!这是一个[im]示例应用';
|
||||
}
|
||||
}
|
||||
594
app/im/controller/MessageHandler.php
Normal file
594
app/im/controller/MessageHandler.php
Normal file
@@ -0,0 +1,594 @@
|
||||
<?php
|
||||
namespace app\im\controller;
|
||||
use think\App;
|
||||
use app\ApiRest;
|
||||
use app\BaseController;
|
||||
use app\im\model\ImUser;
|
||||
use app\im\model\ImChat;
|
||||
use app\im\model\ImMessage;
|
||||
use think\Exception;
|
||||
|
||||
class MessageHandler
|
||||
{
|
||||
protected $connect_name = 'longbing_im_connect_';
|
||||
protected $chat_name = 'longbing_chat_';
|
||||
protected $uniacid_wss = 'wss';
|
||||
|
||||
|
||||
// public function __construct ()
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//登陆
|
||||
public function login($server ,$client_id ,$data)
|
||||
{
|
||||
//获取参数
|
||||
$value = [];
|
||||
if(isset($data['data'])) $value = $data['data'];
|
||||
if(empty($value)) return ;
|
||||
$user_id = null;
|
||||
$uniacid = '7777';
|
||||
if(isset($value['user_id'])) $user_id = $value['user_id'];
|
||||
if(isset($value['uniacid'])) $uniacid = $value['uniacid'];
|
||||
if(empty($user_id) || empty($uniacid)) return ;
|
||||
//获取用户信息
|
||||
$user = $this->getUser($user_id ,$uniacid);
|
||||
//判断用户是否存在
|
||||
if(empty($user)) {
|
||||
return $server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> lang('login error') ,'data' =>[]]));
|
||||
}
|
||||
//设置用户连接数据
|
||||
$user['client_id'] = $client_id;
|
||||
$cache_user = $this->setCacheUser($user_id ,$user ,$uniacid);
|
||||
//设置用户连接
|
||||
$cache_connect = $this->setConnect($client_id ,['user_id' => $user_id ,'uniacid' => $uniacid]);
|
||||
//判断缓存是否插入成功
|
||||
if(empty($cache_user) || empty($cache_connect)) $server->push($client_id ,json_encode(lang('login error')));
|
||||
//返回登陆成功
|
||||
$server->push($client_id ,json_encode(['action' => 'login' ,'status' => true ,'message'=> 'login success.' ,'data' =>$user]));
|
||||
}
|
||||
|
||||
//检查登录
|
||||
public function checkLogin($client_id ,$data = [])
|
||||
{
|
||||
$result = false;
|
||||
//获取连接信息
|
||||
$connect = $this->getConnect($client_id);
|
||||
//如果没有登录
|
||||
if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid']))
|
||||
{
|
||||
$user_id = null;
|
||||
$uniacid = '7777';
|
||||
//判断用户id是否存在
|
||||
if(!isset($data['user_id'])) return $result;
|
||||
//获取用户id
|
||||
$user_id = $data['user_id'];
|
||||
|
||||
//获取uniacid
|
||||
if(isset($data['uniacid'])) $uniacid = $data['uniacid'];
|
||||
//获取用户数据
|
||||
$user = $this->getUser($user_id ,$uniacid);
|
||||
//判断用书是否存在
|
||||
|
||||
if(empty($user)) return $result;
|
||||
//设置用户连接数据
|
||||
$user['client_id'] = $client_id;
|
||||
$cache_user = $this->setCacheUser($user_id ,$user ,$uniacid);
|
||||
//设置用户连接
|
||||
$cache_connect = $this->setConnect($client_id ,['user_id' => $user_id ,'uniacid' => $uniacid]);
|
||||
|
||||
//判断缓存是否插入成功
|
||||
if(!empty($cache_user) && !empty($cache_connect)) $result = true;
|
||||
}else{
|
||||
$result = true;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
//退出
|
||||
public function logout($client_id)
|
||||
{
|
||||
$this->delConnect($client_id);
|
||||
}
|
||||
//发送消息
|
||||
public function sendMessage($server ,$client_id ,$data)
|
||||
{
|
||||
//登录检查
|
||||
if(!$this->checkLogin($client_id ,$data['data'])){
|
||||
$server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
|
||||
return;
|
||||
}
|
||||
//获取用户是否登录
|
||||
$connect = $this->getConnect($client_id);
|
||||
$user = null;
|
||||
if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid']))
|
||||
{
|
||||
return;
|
||||
}else{
|
||||
$user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
|
||||
}
|
||||
|
||||
//判断用户是否存在
|
||||
if(empty($user)) return ;
|
||||
//判断连接是否正确
|
||||
if(!isset($user['client_id']) || !in_array($user['client_id'], [$client_id]))
|
||||
{
|
||||
$user['client_id'] = $client_id;
|
||||
$this->setCacheUser($connect['user_id'], $user ,'ws');
|
||||
}
|
||||
//检查消息
|
||||
$value['message_type'] = 'text';
|
||||
$value['status'] = 1;
|
||||
$value['user_id'] = $connect['user_id'];
|
||||
$value['uniacid'] = $connect['uniacid'];
|
||||
$value['create_time'] = time();
|
||||
if(isset($data['data'])){
|
||||
$data = $data['data'];
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
//判断接受者是否存在
|
||||
if(isset($data['target_id'])) {
|
||||
$value['target_id'] = $data['target_id'];
|
||||
}else{
|
||||
return ;
|
||||
}
|
||||
//判断数据类型是否存在
|
||||
if(isset($data['type'])) $value['message_type'] = $data['type'];
|
||||
//判断状态是否存在
|
||||
if(isset($data['status'])) $value['status'] = $data['status'];
|
||||
//判断发送者是否存在
|
||||
if(isset($data['user_id'])) $value['user_id'] = $data['user_id'];
|
||||
//判断uniacid是否存在
|
||||
if(isset($data['uniacid'])) $value['uniacid'] = $data['uniacid'];
|
||||
if(isset($data['chat_id']))
|
||||
{
|
||||
$value['chat_id'] = $data['chat_id'];
|
||||
}else{
|
||||
// $data = $this->getChat($value['user_id'], $value['target_id'] ,$data['uniacid']);
|
||||
$value['chat_id'] = $this->getChatId($value['user_id'], $value['target_id'] ,$data['uniacid'] ,true);
|
||||
//$server->push($client_id , json_encode($value ,true));die;
|
||||
}
|
||||
//判断发送消息是否存在
|
||||
if(isset($data['content'])) {
|
||||
$value['content'] = $data['content'];
|
||||
}else{
|
||||
return ;
|
||||
}
|
||||
|
||||
//检查数据(防止伪造数据的存在)
|
||||
$target = $this->getUser($value['target_id'] ,$value['uniacid']);
|
||||
//判断用户是否存在
|
||||
if(empty($target)) return;
|
||||
//存储数据
|
||||
// $push_data = array(
|
||||
// 'action' => 'addMessage',
|
||||
// 'event' => 'asyncAddMessage',
|
||||
// 'message' => $value
|
||||
// );
|
||||
// $i = 1000000;
|
||||
// while($i>0)
|
||||
// {
|
||||
// publisher(json_encode($push_data ,true));
|
||||
// $i = $i -1;
|
||||
// }
|
||||
// publisher(json_encode($push_data ,true));
|
||||
$resultAddMsg = false ;
|
||||
|
||||
|
||||
//随机模拟发送消息失败情况
|
||||
/*mt_srand();
|
||||
$demoError = mt_rand(0, 1);
|
||||
|
||||
if($demoError){
|
||||
if(isset($value['chat_id']) && !empty($value['chat_id'])) $resultAddMsg = asyncAddMessage($value);
|
||||
}*/
|
||||
|
||||
if(isset($value['chat_id']) && !empty($value['chat_id'])) $resultAddMsg = asyncAddMessage($value);
|
||||
|
||||
//By.jingshuixian 如果消息存储失败,直接返回
|
||||
if(!$resultAddMsg){
|
||||
$server->push($client_id ,json_encode(['action' => 'sendMessage' ,'status' => $resultAddMsg,'data' => $value] ,true));
|
||||
return false ;
|
||||
}
|
||||
|
||||
//判断用户是否登录
|
||||
if(isset($target['client_id'])) {
|
||||
$value['time'] = date('Y-m-d H:i:s', time());
|
||||
try{
|
||||
$server->push($target['client_id'] , json_encode(['action' => 'getNewMessage' ,'status' => $resultAddMsg , 'data' => $value] ,true));
|
||||
}catch (Exception $e){
|
||||
//echo "$server->push error" ;
|
||||
}
|
||||
|
||||
//向消息接受者发送未读消息数量
|
||||
//$this->getCustomerUnReadMessageCount($server ,$target['client_id'] ,['target_id' => $data['user_id']]);
|
||||
$this->getCustomer($server ,$target['client_id'] ,['data' => ['user_id' => $value['target_id'] ,'target_id' => $value['user_id'] ,'uniacid' => $value['uniacid']]]);
|
||||
$this->getCustomerUnReadMessageCount($server ,$target['client_id'] ,['data' => ['user_id' => $value['target_id'] ,'target_id' => $value['user_id'] ,'uniacid' => $value['uniacid']]]);
|
||||
$this->getUnReadMessageCount($server ,$target['client_id'] ,['data' => ['user_id' => $value['target_id'] ,'target_id' => $value['user_id'] ,'uniacid' => $value['uniacid']]]);
|
||||
}else{
|
||||
//发送服务通知
|
||||
// $push_data = array(
|
||||
// 'action' => 'sendMessageWxServiceNotice',
|
||||
// 'event' => 'longbingSendMessageWxServiceNotice',
|
||||
// 'message' => $value
|
||||
// );
|
||||
// publisher(json_encode($push_data ,true));
|
||||
longbingSendMessageWxServiceNotice($value);
|
||||
|
||||
}
|
||||
$value['status'] = 1;
|
||||
$value['creat_time'] = time();
|
||||
$value['time'] = date('Y-m-d H:i:s', time());
|
||||
$server->push($client_id ,json_encode(['action' => 'sendMessage' ,'status' => $resultAddMsg,'data' => $value] ,true));
|
||||
//存储数据
|
||||
// $push_data = array(
|
||||
// 'action' => 'addMessage',
|
||||
// 'event' => 'asyncAddMessage',
|
||||
// 'message' => $value
|
||||
// );
|
||||
// publisher(json_encode($push_data ,true) ,1000);
|
||||
//发送用户总的未读数据获取用户
|
||||
|
||||
}
|
||||
//获取用户缓存
|
||||
function getCacheUser($user_id ,$uniacid = '7777')
|
||||
{
|
||||
$key = 'longbing_ws_card_user_' . $user_id;
|
||||
if(!hasCache($key ,$uniacid)) return null;
|
||||
return getCache($key ,$uniacid);
|
||||
}
|
||||
|
||||
//设置用户缓存数据
|
||||
function setCacheUser($user_id ,$value ,$uniacid = '7777')
|
||||
{
|
||||
$key = 'longbing_ws_card_user_' . $user_id;
|
||||
return setCache ( $key, $value, 3600, $uniacid);
|
||||
}
|
||||
|
||||
//获取用户信息
|
||||
function getUser($user_id ,$uniacid ='7777')
|
||||
{
|
||||
//判断缓存是否存在
|
||||
$user = $this->getCacheUser($user_id ,$uniacid);
|
||||
if(!empty($user)) return $user;
|
||||
// //生成查询类
|
||||
// $user_model = new ImUser();
|
||||
// //获取数据
|
||||
// $user = $user_model->getUser(['id' => $user_id ,'uniacid' => $uniacid]);
|
||||
$user = longbingGetUser($user_id ,$uniacid);
|
||||
if(empty($user)) return null;
|
||||
$this->setCacheUser($user_id ,$user ,$uniacid);
|
||||
return $user;
|
||||
}
|
||||
//获取当前连接状态
|
||||
function getConnect($client_id ,$uniacid = 'ws')
|
||||
{
|
||||
$key = $this->connect_name . $client_id;
|
||||
$connect = getCache($key ,$uniacid);
|
||||
return $connect;
|
||||
}
|
||||
//设置连接状态
|
||||
function setConnect($client_id ,$value , $uniacid = 'ws')
|
||||
{
|
||||
$key = $this->connect_name . $client_id;
|
||||
return setCache ( $key, $value, 3600, $uniacid);
|
||||
}
|
||||
//注销连接
|
||||
function delConnect($client_id ,$uniacid = 'ws')
|
||||
{
|
||||
$key = $this->connect_name . $client_id;
|
||||
$connect = $this->getConnect($client_id ,$uniacid);
|
||||
if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid'])) return false;
|
||||
$user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
|
||||
if(isset($user['client_id'])){
|
||||
unset($user['client_id']);
|
||||
$this->setCacheUser($connect['user_id'],$user, $connect['uniacid']);
|
||||
}
|
||||
delCache($key ,$uniacid);
|
||||
}
|
||||
//获取所有chat
|
||||
function getChats($user_id ,$uniacid = '7777' ,$is_update = false)
|
||||
{
|
||||
// $key = $this->chat_name . $user_id;
|
||||
// $chats = [];
|
||||
// //判断是否更新
|
||||
// if($is_update)
|
||||
// {
|
||||
// $chat_model = new ImChat();
|
||||
// $chats_data = $chat_model->listChatAll($user_id ,$uniacid);
|
||||
// foreach($chats_data as $chat)
|
||||
// {
|
||||
// if(!isset($chat['chat_id']) || !isset($chat['user_id']) || !isset($chat['target_id'])) continue;
|
||||
// $customer_id = $chat['user_id'];
|
||||
// if(!in_array($chat['user_id'], [$user_id])) $customer_id = $chat['target_id'];
|
||||
// $chats[$customer_id] = $chat['chat_id'];
|
||||
// }
|
||||
// if(!empty($chats)) $this->setChat($user_id ,$chats ,$uniacid);
|
||||
// }else{
|
||||
// if(hasCache($key ,$uniacid)){
|
||||
// $chats = getCache($key ,$uniacid);
|
||||
// }else{
|
||||
// $chats = $this->getChats($user_id ,$uniacid ,true);
|
||||
// }
|
||||
// }
|
||||
// return $chats;
|
||||
$key = $this->chat_name . $user_id;
|
||||
$chats = [];
|
||||
if(hasCache($key ,$uniacid)){
|
||||
$chats = getCache($key ,$uniacid);
|
||||
}
|
||||
return $chats;
|
||||
}
|
||||
//获取用户与客户的chat
|
||||
function getChatId($user_id ,$customer_id ,$uniacid ,$is_create = false)
|
||||
{
|
||||
// //获取chats
|
||||
// $chats = $this->getChats($user_id ,$uniacid);
|
||||
// $chat_id = null;
|
||||
// //判断数据是否存在
|
||||
// if(!isset($chats[$customer_id])){
|
||||
// $this->createChat(['user_id' => $user_id ,'target_id' => $customer_id ,'uniacid' => $uniacid ,'create_time' => time()]);
|
||||
// $chat_id = $this->getChatId($user_id ,$customer_id ,$uniacid);
|
||||
// }else{
|
||||
// $chat_id = $this->getChats($user_id ,$uniacid)[$customer_id];
|
||||
// }
|
||||
// //返回数据
|
||||
// return $chat_id;
|
||||
//获取chats
|
||||
$chats = $this->getChats($user_id ,$uniacid);
|
||||
$chat_id = null;
|
||||
//判断数据是否存在
|
||||
if(!isset($chats[$customer_id])){
|
||||
//从数据库中查询数据
|
||||
$chat = $this->getChat($user_id, $customer_id ,$uniacid);
|
||||
if(empty($chat))
|
||||
{
|
||||
if(!empty($is_create)){
|
||||
$chat_id = $this->createChat(['user_id' => $user_id ,'target_id' => $customer_id ,'uniacid' => $uniacid ,'create_time' => time()]);
|
||||
// $chat_id = $this->getChatId($user_id ,$customer_id ,$uniacid);
|
||||
}
|
||||
}else{
|
||||
$chats[$customer_id] = $chat['chat_id'];
|
||||
$this->setChat($user_id, $chats ,$uniacid);
|
||||
}
|
||||
|
||||
}else{
|
||||
$chat_id = $this->getChats($user_id ,$uniacid)[$customer_id];
|
||||
}
|
||||
//返回数据
|
||||
return $chat_id;
|
||||
}
|
||||
|
||||
//获取chat
|
||||
function getChat($user_id ,$customer_id ,$uniacid = '7777')
|
||||
{
|
||||
$chat_model = new ImChat();
|
||||
$chat = $chat_model->getChat($user_id ,$customer_id ,$uniacid);
|
||||
return $chat;
|
||||
}
|
||||
|
||||
//设置Chat
|
||||
function setChat($user_id ,$value ,$uniacid ='7777')
|
||||
{
|
||||
$key = $this->chat_name . $user_id;
|
||||
return setCache($key, $value, 60, $uniacid);
|
||||
}
|
||||
|
||||
//创建Chat
|
||||
function createChat($data)
|
||||
{
|
||||
$chat_model = new ImChat();
|
||||
$result = $chat_model->createChat($data);
|
||||
//$this->getChats($data['user_id'] ,$data['uniacid'] ,true);
|
||||
return $result;
|
||||
}
|
||||
|
||||
//获取客户列表
|
||||
function listCustomer($data)
|
||||
{
|
||||
//获取参数列表
|
||||
$param = $this->$data;
|
||||
//获取用户列表
|
||||
$user_id = $param['user_id'];
|
||||
//判断用户是否存在
|
||||
if(empty($user_id)) return $this->error('not login ,please login again.');
|
||||
//生成分页信息
|
||||
$page_config = array(
|
||||
'page' => 1,
|
||||
'page_count' => 10
|
||||
);
|
||||
//获取分页信息
|
||||
if(isset($param['page']) && $param['page'] > 0) $page_config['page'] = $param['page'];
|
||||
if(isset($param['page_count']) && $param['page_count'] > 0) $page_config['page_count'] = $param['page_count'];
|
||||
//生成查询模型
|
||||
$chat_model = new ImChat();
|
||||
//生成消息查询模型
|
||||
$message_model = new ImMessage();
|
||||
//生成用户查询模型
|
||||
// $user_model = new ImUser();
|
||||
//生成查询
|
||||
$page_config['total'] = $chat_model->listChatCount($user_id);
|
||||
$chats = $chat_model->listChat($user_id ,$page_config);
|
||||
if(!empty($chats))
|
||||
{
|
||||
foreach($chats as $key => $value)
|
||||
{
|
||||
$lastmessage = $message_model->lastMessage(['chat_id' => $value['id']]);
|
||||
$value['lastmessage'] = $lastmessage;
|
||||
$customer_id = null;
|
||||
if(!in_array($value['user_id'], [$user_id])) $customer_id = $value['user_id'];
|
||||
if(!in_array($value['target_id'], [$user_id])) $customer_id = $value['target_id'];
|
||||
// $value['customer'] = $user_model->getUser(['id' => $customer_id]);
|
||||
$value['customer'] = longbingGetUser($customer_id ,$value['uniacid']);
|
||||
$chats[$key] = $value;
|
||||
}
|
||||
}
|
||||
$page_config['total_page'] = (int)($page_config['total'] / $page_config['page_count']);
|
||||
if(($page_config['total'] % $page_config['page_count']) > 0) $page_config['total_page'] = $page_config['total_page'] + 1;
|
||||
$result = $page_config;
|
||||
$result['chats'] = $chats;
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
//获取未读消息总数
|
||||
public function getUnReadMessageCount($server ,$client_id ,$data)
|
||||
{
|
||||
//登录检查
|
||||
if(!$this->checkLogin($client_id ,$data['data'])){
|
||||
$server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
|
||||
return;
|
||||
}
|
||||
//获取用户是否登录
|
||||
$connect = $this->getConnect($client_id);
|
||||
$user = null;
|
||||
if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid']))
|
||||
{
|
||||
return;
|
||||
}else{
|
||||
$user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
|
||||
}
|
||||
//判断用户是否存在
|
||||
if(empty($user)) return ;
|
||||
//判断连接是否正确
|
||||
if(!isset($user['client_id']) || !in_array($user['client_id'], [$client_id]))
|
||||
{
|
||||
$user['client_id'] = $client_id;
|
||||
$this->setCacheUser($connect['user_id'], $user ,'ws');
|
||||
}
|
||||
//获取未读消息总数
|
||||
$message_model = new ImMessage();
|
||||
// $server->push($client_id ,json_encode($user));
|
||||
$count = $message_model->listMessageCount(['target_id' => $user['id'] ,'status' => 1]);
|
||||
// $count = $message_model->listMessageCount(['status' => 1]);
|
||||
$server->push($client_id ,json_encode(['action' => 'getUnReadMessageCount' ,'status' => true ,'message'=> '' ,'data' =>['count' => $count]]));
|
||||
return;
|
||||
}
|
||||
//获取用户未读消息数
|
||||
public function getCustomerUnReadMessageCount($server ,$client_id ,$data)
|
||||
{
|
||||
//登录检查
|
||||
if(!$this->checkLogin($client_id ,$data['data'])){
|
||||
$server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
|
||||
return;
|
||||
}
|
||||
if(!isset($data['data']['target_id'])) return;
|
||||
$customer_id = $data['data']['target_id'];
|
||||
//获取用户是否登录
|
||||
$connect = $this->getConnect($client_id);
|
||||
$user = null;
|
||||
if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid']))
|
||||
{
|
||||
return;
|
||||
}else{
|
||||
$user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
|
||||
}
|
||||
//判断用户是否存在
|
||||
if(empty($user)) return ;
|
||||
//判断连接是否正确
|
||||
if(!isset($user['client_id']) || !in_array($user['client_id'], [$client_id]))
|
||||
{
|
||||
$user['client_id'] = $client_id;
|
||||
$this->setCacheUser($connect['user_id'], $user ,'ws');
|
||||
}
|
||||
//获取未读消息总数
|
||||
$message_model = new ImMessage();
|
||||
$chat_id = $this->getChatId($user['id'] ,$customer_id ,$user['uniacid'] ,true);
|
||||
if(empty($chat_id)) return;
|
||||
$count = $message_model->listMessageCount(['user_id' => $customer_id,'target_id' => $user['id'] ,'status' => 1]);
|
||||
// $count = $message_model->listMessageCount(['status' => 1]);
|
||||
$server->push($client_id ,json_encode(['action' => 'getCustomerUnReadMessageCount' ,'status' => true ,'message'=> '' ,'data' =>['count' => $count ,'target_id' => $customer_id ,'user_id' => $user['id']]]));
|
||||
return;
|
||||
}
|
||||
//获取客户信息
|
||||
public function getCustomer($server ,$client_id ,$data)
|
||||
{
|
||||
//登录检查
|
||||
if(!$this->checkLogin($client_id ,$data['data'])){
|
||||
$server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
|
||||
return;
|
||||
}
|
||||
if(!isset($data['data'])) return;
|
||||
if(!isset($data['data']['user_id'])) return;
|
||||
if(!isset($data['data']['target_id'])) return;
|
||||
if(!isset($data['data']['uniacid'])) return;
|
||||
$user_id = $data['data']['user_id'];
|
||||
$customer_id = $data['data']['target_id'];
|
||||
$uniacid = $data['data']['uniacid'];
|
||||
//生成关系操作类
|
||||
$chat_model = new ImChat();
|
||||
//获取chat_id
|
||||
$chat_id = $this->getChatId($user_id ,$customer_id ,$uniacid ,true);
|
||||
if(empty($chat_id)) return;
|
||||
//获取数据
|
||||
$chat = $chat_model->getChatById($chat_id);
|
||||
if(empty($chat)) return;
|
||||
//获取客户信息
|
||||
$customer = $this->getUser($customer_id ,$uniacid);
|
||||
$chat['customer'] = $customer;
|
||||
$chat['time'] = date('Y-m-d H:i:s', time());
|
||||
if(isset($chat['update'])) $chat['time'] = date('Y-m-d H:i:s', $chat['update']);
|
||||
|
||||
$message_model = new ImMessage();
|
||||
//获取最后一条消息
|
||||
$last_message = $message_model->lastMessage(['chat_id' => $chat_id]);
|
||||
$chat['lastmessage'] = $last_message;
|
||||
//获取未读客户数据数量
|
||||
$not_rear_message_count = $message_model->listMessageCount(['chat_id' => $chat_id ,'user_id' => $customer_id ,'target_id' =>$user_id ,'status' => 1]);
|
||||
$chat['not_read_message_count'] = $not_rear_message_count;
|
||||
//返回数据
|
||||
$server->push($client_id ,json_encode(['action' => 'getCustomer' ,'status' => true ,'data' => $chat ,'message' => ''] ,true));
|
||||
}
|
||||
|
||||
//检查链接是否正常
|
||||
public function checkWs($server ,$client_id ,$data)
|
||||
{
|
||||
if(!isset($data['data']['check']) || !in_array($data['data']['check'], ['78346+SJDHFA.longbing'])) return ;
|
||||
// $server->push($client_id ,json_encode(['action' => 'checkWs' ,'status' => true ,'message'=> '' ,'data' =>['check' => '78346+SJDHFA.longbing']]));
|
||||
$server->push($client_id ,json_encode(['action' => 'checkWs' ,'status' => true ,'message' => '' ,'data' => ['check' => '78346+SJDHFA.longbing']]));
|
||||
}
|
||||
//标记消息已读
|
||||
public function readMessage($server ,$client_id ,$data)
|
||||
{
|
||||
//登录检查
|
||||
if(!$this->checkLogin($client_id ,$data['data'])){
|
||||
$server->push($client_id ,json_encode(['action' => 'login' ,'status' => false ,'message'=> 'login error ,please check login param.' ,'data' =>[]]));
|
||||
return;
|
||||
}
|
||||
//获取用户是否登录
|
||||
$connect = $this->getConnect($client_id);
|
||||
$user = null;
|
||||
if(empty($connect) || !isset($connect['user_id']) || !isset($connect['uniacid']))
|
||||
{
|
||||
return;
|
||||
}else{
|
||||
$user = $this->getUser($connect['user_id'] ,$connect['uniacid']);
|
||||
}
|
||||
//判断用户是否存在
|
||||
if(empty($user)) return ;
|
||||
//判断连接是否正确
|
||||
if(!isset($user['client_id']) || !in_array($user['client_id'], [$client_id]))
|
||||
{
|
||||
$user['client_id'] = $client_id;
|
||||
$this->setCacheUser($connect['user_id'], $user ,'ws');
|
||||
}
|
||||
|
||||
|
||||
if(!isset($data['data']['target_id'])) return ;
|
||||
$target_id = $data['data']['target_id'];
|
||||
if(isset($data['data']['uniacid'])) $uniacid = $data['data']['uniacid'];
|
||||
if(isset($user['uniacid'])) $uniacid = $user['uniacid'];
|
||||
$user_id = $user['id'];
|
||||
$chat_id = $this->getChatId($user_id, $target_id ,$uniacid , true);
|
||||
if(empty($chat_id)) return;
|
||||
//设置已读数据
|
||||
$message_model = new ImMessage();
|
||||
$message_model->readMessage(['chat_id' => $chat_id ,'user_id' => $target_id ,'target_id' => $user_id ,'deleted' => 0]);
|
||||
//发数据给自己
|
||||
$this->getCustomer($server ,$client_id ,['data' => ['user_id' => $user_id ,'target_id' => $target_id,'uniacid' => $uniacid]]);
|
||||
//
|
||||
$this->getUnReadMessageCount($server ,$client_id ,['data' => ['user_id' => $user_id,'target_id' => $target_id ,'uniacid' => $uniacid]]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
220
app/im/controller/MessageHandlerV2.php
Normal file
220
app/im/controller/MessageHandlerV2.php
Normal file
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
namespace app\im\controller;
|
||||
use app\Common\LongbingServiceNotice;
|
||||
use app\Common\service\LongbingUserInfoService;
|
||||
use app\im\service\ImService;
|
||||
use longbingcore\tools\LongbingStr;
|
||||
use longbingcore\tools\LongbingTime;
|
||||
use think\App;
|
||||
|
||||
|
||||
class MessageHandlerV2 extends BaseMessage
|
||||
{
|
||||
//连接客户端ID
|
||||
protected $connect_name = 'longbing_im_connect_';
|
||||
//链接对应的用户ID
|
||||
protected $connect_user_name = 'longbing_im_connect_user';
|
||||
|
||||
//房间ID
|
||||
protected $chat_name = 'longbing_chat_';
|
||||
|
||||
protected $uniacid_wss = 'wss';
|
||||
|
||||
protected $noLogin = ['code' => 401, 'error' => '请登录系统!'] ;
|
||||
|
||||
//发送消息
|
||||
public function sendMessage($server ,$client_id ,$data)
|
||||
{
|
||||
|
||||
//检查登录
|
||||
$user_id = $this->checkLogin($server ,$client_id ,$data);
|
||||
if(!$user_id){
|
||||
return $this->sendLogin($server , $client_id ) ;
|
||||
}
|
||||
|
||||
|
||||
$uniacid = $data['data']['uniacid'];
|
||||
$target_id = $data['data']['target_id']; //接收消息用户id
|
||||
$content = $data['data']['content'];
|
||||
|
||||
|
||||
if( isset($data['data']['id']) && $data['data']['id'] > 0 ) { //
|
||||
|
||||
$message = $data['data'] ;
|
||||
$message_type = $data['data']['message_type'];
|
||||
}else{
|
||||
|
||||
$chat_id = ImService::getChatId($uniacid, $user_id, $target_id);
|
||||
$message_type = $data['data']['type'];
|
||||
$message['message_type'] = $message_type; //
|
||||
$message['status'] = 1; //消息状态 1=>未读消息 2=>已读 3=>已撤销 4=>已删除
|
||||
$message['user_id'] = $user_id; //发送消息用户id
|
||||
$message['target_id'] = $target_id; //接收消息用户id
|
||||
$message['content'] = $content; // 消息内容
|
||||
$message['uniacid'] = $uniacid; //平台ID
|
||||
$message['chat_id'] = $chat_id; // 房间ID
|
||||
$message['create_time'] = time();
|
||||
$message['update_time'] = time();
|
||||
|
||||
|
||||
ImService::addMessage($message);
|
||||
}
|
||||
|
||||
|
||||
$pushTargetClientId = intval( $this->getClientIdByUserId($target_id) ) ;
|
||||
|
||||
//客户在线
|
||||
if($pushTargetClientId){
|
||||
|
||||
$this->sendServerMsg($server , $pushTargetClientId , 'getNewMessage' ,true,'', $message );
|
||||
$this->getUnReadMessageCount($server , $pushTargetClientId , ['data'=>['user_id' => $target_id ] ] );
|
||||
$this->getCustomerUnReadMessageCount($server , $pushTargetClientId , ['data'=>['user_id' => $target_id ,'target_id' => $user_id ] ] );
|
||||
|
||||
}else{
|
||||
//发送服务通知给客户
|
||||
//员工姓名,必须为中文,不能带有数字和符号
|
||||
//$name = LongbingUserInfoService::getNameByUserId($user_id);
|
||||
//ImService::sendTmplMsg($uniacid,$target_id,[ $name , '有未读私信' , LongbingTime::getChinaNowTime()] , 'pages/user/home' );
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->sendServerMsg($server , $client_id , 'sendMessage' ,true,'', $message );
|
||||
$this->getUnReadMessageCount($server , $client_id , ['data'=>['user_id' => $user_id ] ] );
|
||||
|
||||
//给员工发通知消息
|
||||
|
||||
//$note = new LongbingServiceNotice($uniacid);
|
||||
//$note->sendImMessageServiceNoticeToStaff($target_id , $content) ;
|
||||
|
||||
}
|
||||
|
||||
//获取未读消息总数
|
||||
public function getUnReadMessageCount($server ,$client_id ,$data)
|
||||
{
|
||||
$user_id = $data['data']['user_id'] ;
|
||||
$count = ImService::getUnReadMessageCount($user_id);
|
||||
|
||||
$this->sendServerMsg($server ,$client_id , 'getUnReadMessageCount' , true,'', ['count' => $count ] ) ;
|
||||
}
|
||||
|
||||
//查询目标客户,给我发送的消息数量
|
||||
public function getCustomerUnReadMessageCount($server ,$client_id ,$data)
|
||||
{
|
||||
|
||||
if (isset($data['data']['target_id']) && isset($data['data']['user_id'])) {
|
||||
|
||||
$user_id = $data['data']['user_id'];
|
||||
$target_id = $data['data']['target_id'];
|
||||
|
||||
$count = ImService::getUnReadMessageCountByUserIdAndTargetId( $target_id , $user_id);
|
||||
|
||||
$this->sendServerMsg($server, $client_id, 'getCustomerUnReadMessageCount', true, '', ['count' => $count, 'user_id' => $user_id , 'target_id' => $target_id ]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//登陆
|
||||
public function login($server ,$client_id ,$data)
|
||||
{
|
||||
|
||||
//登录失败
|
||||
$user_id = $this->checkLogin($server ,$client_id ,$data);
|
||||
if(!$user_id){
|
||||
return $this->sendLogin($server , $client_id ) ;
|
||||
}
|
||||
|
||||
$this->updateClentAndUserIdCache($client_id , $user_id);
|
||||
|
||||
$this->sendServerMsg($server ,$client_id , 'login' , true ) ;
|
||||
|
||||
//用户登录成功,给客户发未读消息数量
|
||||
$this->getUnReadMessageCount($server , $client_id , ['data'=>['user_id' => $user_id ] ] );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//检查登录
|
||||
public function checkLogin( $server ,$client_id ,$data ){
|
||||
|
||||
if(isset($data['data']['token'])){
|
||||
|
||||
$token = $data['data']['token'];
|
||||
$uniacid = $data['data']['uniacid'] ;
|
||||
$user = getCache($token , $uniacid );
|
||||
|
||||
if(empty($user)){
|
||||
return false ;
|
||||
}
|
||||
|
||||
return $user['id'] ;
|
||||
|
||||
}else{
|
||||
echo json_encode($data);
|
||||
}
|
||||
|
||||
return false ;
|
||||
|
||||
}
|
||||
|
||||
//发送登录提示消息信息
|
||||
public function sendLogin( $server ,$client_id ){
|
||||
|
||||
$this->sendServerMsg($server, $client_id ,'login',false,'',$this->noLogin);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//更新缓存客户和用户ID
|
||||
public function updateClentAndUserIdCache($client_id , $user_id){
|
||||
//缓存客户端对应的用户ID
|
||||
$key = $this->connect_name . $client_id;
|
||||
setCache ( $key, $user_id, 3600, $this->uniacid_wss );
|
||||
|
||||
//缓存用户登录对应的客户端ID
|
||||
$key = $this->connect_user_name . $user_id;
|
||||
setCache ( $key, $client_id, 3600, $this->uniacid_wss );
|
||||
}
|
||||
|
||||
//根据用户ID获取 $client_id
|
||||
public function getClientIdByUserId($userId){
|
||||
|
||||
$key = $this->connect_user_name . $userId;
|
||||
$client_id = getCache( $key , $this->uniacid_wss ) ;
|
||||
|
||||
return $client_id;
|
||||
}
|
||||
|
||||
//退出
|
||||
public function logout($client_id)
|
||||
{
|
||||
$key = $this->connect_name . $client_id;
|
||||
$user_id = getCache( $key , $this->uniacid_wss ) ;
|
||||
|
||||
//删除客户对应的用户ID
|
||||
delCache($key ,$this->uniacid_wss);
|
||||
|
||||
//删除用户对应的客户ID
|
||||
$key = $this->connect_user_name . $user_id;
|
||||
delCache($key ,$this->uniacid_wss);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//检查链接是否正常
|
||||
public function checkWs($server ,$client_id ,$data)
|
||||
{
|
||||
|
||||
//检查登录
|
||||
$user_id = $this->checkLogin($server ,$client_id ,$data);
|
||||
if(!$user_id){
|
||||
return $this->sendLogin($server , $client_id ) ;
|
||||
}
|
||||
$this->updateClentAndUserIdCache($client_id , $user_id) ;
|
||||
|
||||
$this->sendServerMsg($server, $client_id ,'checkWsOk');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
147
app/im/controller/PushServer.php
Normal file
147
app/im/controller/PushServer.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
namespace app\im\controller;
|
||||
use app\im\controller\MessageHander;
|
||||
//use think\swoole\Websocket as websocket;
|
||||
use Swoole\Http\Server as HttpServer;
|
||||
use Swoole\Websocket\Server as WebsocketServer;
|
||||
use think\App;
|
||||
use think\Route;
|
||||
use think\swoole\command\Server as ServerCommand;
|
||||
use think\swoole\facade\Server;
|
||||
use think\swoole\websocket\socketio\Controller;
|
||||
use think\swoole\websocket\socketio\Middleware;
|
||||
use think\facade\Config;
|
||||
|
||||
|
||||
//推送服务器
|
||||
class PushServer extends \think\Service
|
||||
{
|
||||
private static $instance;
|
||||
private static $server;
|
||||
private $config;
|
||||
//处理消息对象
|
||||
private $messageHandler;
|
||||
|
||||
protected $isWebsocket = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// parent::__construct();
|
||||
//创建websocket对象
|
||||
// self::$server = new swoole_websocket_server("0.0.0.0", 8006);
|
||||
// self::$server = $server::$server;
|
||||
// self::$server = new websocket("0.0.0.0", 8006);
|
||||
$this->init();
|
||||
$this->register();
|
||||
//设置
|
||||
// self::initServer();
|
||||
//注册事件
|
||||
//连接客户端
|
||||
self::$server->on("open" ,[$this , "onOpen"]);
|
||||
//发送消息
|
||||
self::$server->on('message' ,[$this ,'onMessage']);
|
||||
//关闭连接
|
||||
self::$server->on('close' ,[$this ,'onClose']);
|
||||
//异步
|
||||
self::$server->on('task' ,[$this ,'onTask']);
|
||||
//启动时运行
|
||||
self::$server->on('workerStart' ,[$this ,'onWorkerStart']);
|
||||
|
||||
}
|
||||
//获取
|
||||
public static function getInstance()
|
||||
{
|
||||
if(!self::$instance instanceof self)
|
||||
{
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
protected function init()
|
||||
{
|
||||
$this->config = Config::get('swoole');
|
||||
}
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->isWebsocket = Config::get('swoole.websocket.enabled');
|
||||
$this->createSwooleServer();
|
||||
}
|
||||
|
||||
public function boot(Route $route)
|
||||
{
|
||||
$this->commands(ServerCommand::class);
|
||||
if ($this->isWebsocket) {
|
||||
$route->group(function () use ($route) {
|
||||
$route->get('socket.io/', '@upgrade');
|
||||
$route->post('socket.io/', '@reject');
|
||||
})->prefix(Controller::class)->middleware(Middleware::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create swoole server.
|
||||
*/
|
||||
protected function createSwooleServer()
|
||||
{
|
||||
$server = $this->isWebsocket ? WebsocketServer::class : HttpServer::class;
|
||||
$config = $this->config;
|
||||
$host = Config::get('swoole.server.host');
|
||||
$port = Config::get('swoole.server.port');
|
||||
$socketType = Config::get('swoole.server.socket_type', SWOOLE_SOCK_TCP);
|
||||
$mode = Config::get('swoole.server.mode', SWOOLE_PROCESS);
|
||||
self::$server = new $server($host, $port, $mode, $socketType);
|
||||
$options = Config::get('swoole.server.options');
|
||||
self::$server->set($options);
|
||||
}
|
||||
|
||||
|
||||
//启动服务器
|
||||
public function start()
|
||||
{
|
||||
self::$server->start();
|
||||
}
|
||||
|
||||
//客户端连接上后执行的方法
|
||||
public function onOpen($server ,$req)
|
||||
{
|
||||
self::$server->push($req->fd ,json_encode(['action' => 'connect' ,'status' => true ,'data' => [] ,'message' => 'connect success.'] ,true));
|
||||
}
|
||||
|
||||
//客户端连接上后执行的方法
|
||||
public function onMessage($server ,$frame)
|
||||
{
|
||||
self::$server->reload();//重新加载代码
|
||||
$data = json_decode($frame->data ,true);
|
||||
$result = null;
|
||||
if(method_exists($this->messageHandler, $data['action']))
|
||||
{
|
||||
$result = call_user_func([$this->messageHandler, $data['action']] ,self::$server ,$frame->fd ,$data);
|
||||
}
|
||||
}
|
||||
//异步
|
||||
public function onTask($server ,$frame)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//关闭连接
|
||||
public function onClose($server ,$fd)
|
||||
{
|
||||
call_user_func([$this->messageHandler, 'logout'] ,$fd);
|
||||
}
|
||||
//onWorkerStart
|
||||
public function onWorkerStart()
|
||||
{
|
||||
// 加载框架里面的文件
|
||||
require __DIR__ . '/../../../vendor/autoload.php';
|
||||
$http = ( new App() )->http;
|
||||
$response = $http->run();
|
||||
$this->messageHandler = new MessageHandlerV2();
|
||||
}
|
||||
//发送消息
|
||||
public function sendMessage($fd ,$data){
|
||||
self::$server->push($fd ,$data);
|
||||
}
|
||||
}
|
||||
612
app/im/controller/Some.php
Normal file
612
app/im/controller/Some.php
Normal file
@@ -0,0 +1,612 @@
|
||||
<?php
|
||||
namespace app\im\controller;
|
||||
|
||||
use app\card\model\UserInfo;
|
||||
use app\material\model\BrochureIm;
|
||||
use app\material\model\ImVideo;
|
||||
use app\shop\model\IndexUser;
|
||||
use Redis;
|
||||
use think\facade\Cache;
|
||||
use think\facade\Config;
|
||||
|
||||
class Some {
|
||||
|
||||
|
||||
public $redis;
|
||||
|
||||
public function __construct() {
|
||||
|
||||
$host = Config::get('cache.stores.redis.host');
|
||||
|
||||
$port = Config::get('cache.stores.redis.port');
|
||||
|
||||
$password = Config::get('cache.stores.redis.password');
|
||||
|
||||
if(empty($this->redis)||$this->redis->ping()!=true){
|
||||
|
||||
$this->redis = new Redis();
|
||||
|
||||
$this->redis->connect($host,$port);
|
||||
|
||||
if(!empty($password)){
|
||||
|
||||
$this->redis->auth($password); //设置密码
|
||||
}
|
||||
|
||||
// $connect_status = $this->redis->ping();
|
||||
|
||||
// if($connect_status != "+PONG")
|
||||
// if($connect_status != true)
|
||||
// {
|
||||
// $this->redis->connect($host,$port);
|
||||
//
|
||||
// if(!empty($password)){
|
||||
//
|
||||
// $this->redis->auth($password); //设置密码
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $ws
|
||||
* @param $request
|
||||
* @功能说明:建立连接回调(智能物料)
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-02 18:17
|
||||
*/
|
||||
public function mOnOpen($data,$fd) {
|
||||
|
||||
$room_key = $data['room_key'];
|
||||
|
||||
$uid = !empty($data['user_id'])?$data['user_id']:0;
|
||||
|
||||
$target_id= !empty($data['target_id'])?$data['target_id']:0;
|
||||
|
||||
$uniacid = !empty($data['uniacid'])?$data['uniacid']:0;
|
||||
//是否是群主
|
||||
$leader =!empty($data['presenter'])?$data['presenter']:0;
|
||||
//1是文件 2是宣传册
|
||||
$type = !empty($data['type'])?$data['type']:1;
|
||||
//加入房间域
|
||||
$this->redis->hset($room_key,$uid,$fd);
|
||||
//加入组集合
|
||||
$this->redis->sadd('group', $room_key);
|
||||
//如果是群主
|
||||
if($leader==1){
|
||||
|
||||
$key = $room_key.'-leader';
|
||||
//群主
|
||||
$this->redis->set($key,$uid,86400);
|
||||
|
||||
}
|
||||
|
||||
$bIm_model = new BrochureIm();
|
||||
|
||||
$dis = [
|
||||
|
||||
'user_id' => $uid,
|
||||
|
||||
'room_key' => $room_key,
|
||||
|
||||
'brochure_id' => $target_id,
|
||||
|
||||
'type' => $type,
|
||||
];
|
||||
|
||||
$find = $bIm_model->dataInfo($dis);
|
||||
|
||||
$room_status = $bIm_model->where(['room_key'=>$room_key,'leader'=>1])->value('status');
|
||||
|
||||
$room_status = !empty($room_status)?$room_status:1;
|
||||
|
||||
if(empty($find)){
|
||||
|
||||
$key = $room_key.'-leader';
|
||||
//群主
|
||||
$user_id = $this->redis->get($key);
|
||||
|
||||
$user_info = new UserInfo();
|
||||
|
||||
$user_id = !empty($user_id)?$user_id:0;
|
||||
|
||||
$company_id = $user_info->where(['fans_id'=>$user_id])->value('company_id');
|
||||
|
||||
$insert = [
|
||||
|
||||
'uniacid' => $uniacid,
|
||||
|
||||
'user_id' => $uid,
|
||||
|
||||
'room_key' => $room_key,
|
||||
|
||||
'brochure_id' => $target_id,
|
||||
|
||||
'leader' => $leader,
|
||||
|
||||
'type' => $type,
|
||||
|
||||
'company_id' => !empty($company_id)?$company_id:0,
|
||||
|
||||
'status' => $room_status
|
||||
|
||||
];
|
||||
|
||||
$bIm_model->dataAdd($insert);
|
||||
}else{
|
||||
|
||||
$bIm_model->dataUpdate($dis,['status'=>$room_status]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $ws
|
||||
* @param $frame
|
||||
* @功能说明:接受消息回调(智能物料)
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-02 18:17
|
||||
*/
|
||||
public function mOnMessage($ws, $data,$fd) {
|
||||
|
||||
$room_key = $data['data']['room_key'];
|
||||
//获取房间
|
||||
$room = $this->redis->hGetAll($room_key);
|
||||
|
||||
if(!empty($room)){
|
||||
|
||||
foreach ($room as $k => $vv) {
|
||||
//投递消息
|
||||
$ws->push($vv, json_encode($data));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $ws
|
||||
* @param $data
|
||||
* @param $fd
|
||||
* @功能说明:保存音频
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-08-10 17:25
|
||||
*/
|
||||
public function addVideo($ws, $data,$fd){
|
||||
|
||||
$room_key = $data['data']['room_key'];
|
||||
|
||||
$uniacid = !empty($data['data']['uniacid'])?$data['data']['uniacid']:0;
|
||||
|
||||
$video = FILE_UPLOAD_PATH.$data['data']['video'];
|
||||
|
||||
if(!empty($data['data']['video'])){
|
||||
|
||||
$im_video_model = new ImVideo();
|
||||
|
||||
$insert = [
|
||||
|
||||
'uniacid' => $uniacid,
|
||||
|
||||
'room_key' => $room_key,
|
||||
|
||||
'video' => $video,
|
||||
|
||||
];
|
||||
|
||||
$im_video_model->dataAdd($insert);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param $ws
|
||||
* @param $frame
|
||||
* @功能说明:接受消息回调(智能物料)
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-02 18:17
|
||||
*/
|
||||
public function onLogin($ws, $data,$fd) {
|
||||
|
||||
$room_key = $data['data']['room_key'];
|
||||
|
||||
// $room_key = '20210802093606035000000350';
|
||||
//获取房间
|
||||
$room = $this->redis->hgetall($room_key);
|
||||
|
||||
if(!empty($room)){
|
||||
|
||||
$user_model = new IndexUser();
|
||||
|
||||
$bIm_model = new BrochureIm();
|
||||
|
||||
$user_id = array_keys($room);
|
||||
|
||||
$key = $room_key.'-leader';
|
||||
//获取群组的用户id
|
||||
$leader_id = $this->redis->get($key);
|
||||
|
||||
if(!empty($leader_id)){
|
||||
|
||||
$user_key = array_search($leader_id,$user_id);
|
||||
|
||||
if(is_numeric($user_key)&&array_key_exists($user_key,$user_id)){
|
||||
|
||||
unset($user_id[$user_key]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$user = $user_model->where('id','in',$user_id)->field('nickName,avatarUrl')->select()->toArray();
|
||||
|
||||
$list['data']['user'] = $user;
|
||||
|
||||
$list['action'] = $data['action'];
|
||||
|
||||
$list['data']['room_key'] = $room_key;
|
||||
|
||||
$list['data']['count'] = count($user_id);
|
||||
|
||||
$dis = [
|
||||
|
||||
'room_key' => $room_key,
|
||||
|
||||
'leader' => 1
|
||||
];
|
||||
//演示状态
|
||||
$list['data']['is_start'] = $bIm_model->where($dis)->value('status');
|
||||
|
||||
foreach ($room as $k => $vv) {
|
||||
//投递消息
|
||||
$ws->push($vv, json_encode($list));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-28 16:50
|
||||
* @功能说明:开始演示
|
||||
*/
|
||||
public function startAction($ws, $data,$fd){
|
||||
|
||||
$room_key = $data['data']['room_key'];
|
||||
|
||||
$bIm_model = new BrochureIm();
|
||||
|
||||
$dis = [
|
||||
|
||||
'room_key' => $room_key,
|
||||
|
||||
// 'leader' => 1
|
||||
];
|
||||
//修改演示状态
|
||||
$bIm_model->dataUpdate($dis,['status'=>2]);
|
||||
|
||||
$bIm_model->dataUpdate(['room_key'=>$room_key],['time_long'=>0,'update_time'=>time()]);
|
||||
|
||||
$room = $this->redis->hGetAll($room_key);
|
||||
|
||||
$list['data']['is_start'] = 2;
|
||||
|
||||
$list['data']['room_key'] = $room_key;
|
||||
|
||||
$list['action'] = $data['action'];
|
||||
|
||||
if(!empty($room)){
|
||||
|
||||
foreach ($room as $k=>$vv){
|
||||
//投递消息
|
||||
$ws->push($vv, json_encode($list));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $serv
|
||||
* @param $task_id
|
||||
* @param $worker_id
|
||||
* @param $data
|
||||
* @功能说明:完成异步任务回调
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-02 18:17
|
||||
*/
|
||||
public function onTask($serv, $task_id, $worker_id, $data) {
|
||||
|
||||
//返回字符串给worker进程——>触发onFinish
|
||||
return "success";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $serv
|
||||
* @param $task_id
|
||||
* @param $data
|
||||
* @功能说明:完成任务投递回调
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-02 18:16
|
||||
*/
|
||||
public function onFinish($serv, $task_id, $data) {
|
||||
//task_worker进程将任务处理结果发送给worker进程
|
||||
echo "完成任务{$task_id}投递 处理结果:{$data}";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $ws
|
||||
* @param $fd
|
||||
* @功能说明:关闭连接回调
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-02 18:16
|
||||
*/
|
||||
public function onClose($ws, $fd) {
|
||||
//退出并删除多余的分组fd
|
||||
$group = $this->redis->sMembers('group');
|
||||
|
||||
foreach ($group as $v) {
|
||||
|
||||
$fangjian = $this->redis->hgetall($v);
|
||||
|
||||
foreach ($fangjian as $k => $vv) {
|
||||
|
||||
if ($fd == $vv) {
|
||||
|
||||
$this->redis->hdel($v, $vv);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// echo "{$fd}关闭了连接1";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $ws
|
||||
* @param $fd
|
||||
* @功能说明:解散群
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-27 18:04
|
||||
*/
|
||||
public function allLoginOut($ws,$data,$fd){
|
||||
|
||||
$room_key = $data['data']['room_key'];
|
||||
|
||||
$fangjian = $this->redis->hgetall($room_key);
|
||||
|
||||
$im_model = new BrochureIm();
|
||||
|
||||
$data['action'] = 'mOnMessage';
|
||||
|
||||
$data['data']['message_type'] = 2;
|
||||
//给剩下的人发消息
|
||||
$this->mOnMessage($ws,$data,$fd);
|
||||
|
||||
$bIm_model = new BrochureIm();
|
||||
|
||||
$dis = [
|
||||
|
||||
'room_key' => $room_key,
|
||||
|
||||
];
|
||||
//修改演示状态
|
||||
$bIm_model->where($dis)->update(['status'=>3]);
|
||||
|
||||
if(!empty($fangjian)){
|
||||
|
||||
foreach ($fangjian as $k => $vv) {
|
||||
|
||||
$this->redis->Hdel($room_key,$k);
|
||||
|
||||
$dis = [
|
||||
|
||||
'user_id' => $k,
|
||||
|
||||
'room_key'=> $room_key
|
||||
];
|
||||
|
||||
$find = $im_model->dataInfo($dis);
|
||||
|
||||
if(!empty($find)&&$find['status']>1){
|
||||
|
||||
$time_long = time()-$find['update_time'];
|
||||
|
||||
$im_model->dataUpdate($dis,['time_long'=>$time_long+$find['time_long']]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
//删除房间
|
||||
@$this->redis->sRem('group',$room_key);
|
||||
}
|
||||
|
||||
|
||||
// if(!empty($data['data']['url'])){
|
||||
//
|
||||
// $url = $data['data']['url'];
|
||||
// //合并录音
|
||||
// $im_model->addAudio($room_key,$url);
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $ws
|
||||
* @param $fd
|
||||
* @功能说明:退出
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-23 17:44
|
||||
*/
|
||||
public function loginOut($ws, $fd){
|
||||
|
||||
$im_model = new BrochureIm();
|
||||
//退出并删除多余的分组fd
|
||||
$group = $this->redis->sMembers('group');
|
||||
|
||||
if(!empty($group)){
|
||||
|
||||
foreach ($group as $v) {
|
||||
|
||||
$fangjian = $this->redis->hgetall($v);
|
||||
|
||||
$data['data']['room_key'] = $v;
|
||||
|
||||
if(!empty($fangjian)){
|
||||
|
||||
foreach ($fangjian as $k => $vv) {
|
||||
|
||||
if ($fd == $vv) {
|
||||
|
||||
$this->redis->Hdel($v,$k);
|
||||
|
||||
$dis = [
|
||||
|
||||
'user_id' => $k,
|
||||
|
||||
'room_key'=> $v
|
||||
];
|
||||
|
||||
$find = $im_model->dataInfo($dis);
|
||||
|
||||
if(!empty($find)&&$find['status']>1){
|
||||
|
||||
$time_long = time()-$find['update_time'];
|
||||
|
||||
$im_model->dataUpdate($dis,['time_long'=>$time_long+$find['time_long']]);
|
||||
|
||||
}
|
||||
|
||||
$data['action'] = 'onLogin';
|
||||
//给剩下的人发消息
|
||||
$this->onLogin($ws,$data,$fd);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
@$this->redis->sRem('group',$v);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param $ws
|
||||
* @param $fd
|
||||
* @功能说明:退出
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-23 17:44
|
||||
*/
|
||||
public function loginOutV2($ws, $fd){
|
||||
|
||||
$im_model = new BrochureIm();
|
||||
//退出并删除多余的分组fd
|
||||
$group = $this->redis->sMembers('group');
|
||||
|
||||
foreach ($group as $v) {
|
||||
|
||||
$fangjian = $this->redis->hgetall($v);
|
||||
|
||||
$key = $v.'-leader';
|
||||
//获取群组的用户id
|
||||
$leader_id = $this->redis->get($key);
|
||||
//当前用户的id
|
||||
$user_id = array_search($fd,$fangjian);
|
||||
//如果是群组则全部退出
|
||||
$is_all = !empty($user_id)&&$leader_id==$user_id?1:0;
|
||||
|
||||
$data['data']['room_key'] = $v;
|
||||
//修改房间状态
|
||||
if($is_all==1){
|
||||
|
||||
$start_key = $v.'-is_start';
|
||||
|
||||
$this->redis->set($start_key,0);
|
||||
|
||||
$data['action'] = 'mOnMessage';
|
||||
|
||||
$data['data']['message_type'] = 2;
|
||||
//给剩下的人发消息
|
||||
$this->mOnMessage($ws,$data,$fd);
|
||||
|
||||
}
|
||||
|
||||
if(!empty($fangjian)){
|
||||
|
||||
foreach ($fangjian as $k => $vv) {
|
||||
|
||||
if ($fd == $vv||$is_all==1) {
|
||||
|
||||
$this->redis->hdel($v, $k);
|
||||
|
||||
|
||||
$dis = [
|
||||
|
||||
'user_id' => $k,
|
||||
|
||||
'room_key'=> $v
|
||||
];
|
||||
|
||||
$find = $im_model->dataInfo($dis);
|
||||
|
||||
if(!empty($find)){
|
||||
|
||||
$time_long = time()-$find['update_time'];
|
||||
|
||||
$im_model->dataUpdate($dis,['time_long'=>$time_long+$find['time_long']]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
@$this->redis->sRem('group',$v);
|
||||
|
||||
}
|
||||
//如果是群主断开链接
|
||||
if($is_all==0){
|
||||
|
||||
$data['action'] = 'onLogin';
|
||||
//给剩下的人发消息
|
||||
$this->onLogin($ws,$data,$fd);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
82
app/im/controller/Tcp.php
Normal file
82
app/im/controller/Tcp.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Longbing [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright Chengdu longbing Technology Co., Ltd.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Website http://longbing.org/
|
||||
// +----------------------------------------------------------------------
|
||||
// | Sales manager: +86-13558882532 / +86-13330887474
|
||||
// | Technical support: +86-15680635005
|
||||
// | After-sale service: +86-17361005938
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
use Swoole\WebSocket\Server;
|
||||
use think\facade\Cache;
|
||||
|
||||
class Tcp {
|
||||
|
||||
public $server;
|
||||
|
||||
public $redis;
|
||||
|
||||
public $key;
|
||||
|
||||
|
||||
public function __construct() {
|
||||
|
||||
|
||||
if(empty($this->redis)){
|
||||
|
||||
$this->redis = new Redis();
|
||||
|
||||
$this->redis ->connect('127.0.0.1',6379);
|
||||
}
|
||||
|
||||
|
||||
//创建Server对象,监听 127.0.0.1:9501 端口
|
||||
$server = new \Swoole\Server('127.0.0.1', 9501);
|
||||
|
||||
// $this->server->set(array(
|
||||
//
|
||||
// 'reactor_num' => 2, //reactor thread num
|
||||
//
|
||||
// 'worker_num' => 4, //worker process num
|
||||
//
|
||||
// 'backlog' => 128, //listen backlog
|
||||
//
|
||||
// 'max_request' => 50,
|
||||
//
|
||||
// 'dispatch_mode' => 1,
|
||||
//
|
||||
//// 'daemonize' => 1
|
||||
//
|
||||
// ));
|
||||
|
||||
|
||||
//监听连接进入事件
|
||||
$server->on('Connect', function ($server, $fd) {
|
||||
echo "Client: Connect.\n";
|
||||
});
|
||||
|
||||
//监听数据接收事件
|
||||
$server->on('Receive', function ($server, $fd, $reactor_id, $data) {
|
||||
$server->send($fd, "Server: {$data}");
|
||||
});
|
||||
|
||||
//监听连接关闭事件
|
||||
$server->on('Close', function ($server, $fd) {
|
||||
echo "Client: Close.\n";
|
||||
});
|
||||
|
||||
//启动服务器
|
||||
$server->start();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
new Tcp();
|
||||
142
app/im/controller/WebsocketTest.php
Normal file
142
app/im/controller/WebsocketTest.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Longbing [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright Chengdu longbing Technology Co., Ltd.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Website http://longbing.org/
|
||||
// +----------------------------------------------------------------------
|
||||
// | Sales manager: +86-13558882532 / +86-13330887474
|
||||
// | Technical support: +86-15680635005
|
||||
// | After-sale service: +86-17361005938
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
use Swoole\WebSocket\Server;
|
||||
use think\facade\Cache;
|
||||
|
||||
class WebsocketTest {
|
||||
|
||||
public $server;
|
||||
|
||||
public $redis;
|
||||
|
||||
public $key;
|
||||
|
||||
|
||||
public function __construct() {
|
||||
|
||||
$this->key = '122345446';
|
||||
|
||||
if(empty($this->redis)){
|
||||
|
||||
$this->redis = new Redis();
|
||||
|
||||
$this->redis ->connect('127.0.0.1',6379);
|
||||
}
|
||||
|
||||
|
||||
$this->server = new Swoole\WebSocket\Server("0.0.0.0", 9501);
|
||||
|
||||
$this->server->set(array(
|
||||
|
||||
'reactor_num' => 2, //reactor thread num
|
||||
|
||||
'worker_num' => 4, //worker process num
|
||||
|
||||
'backlog' => 128, //listen backlog
|
||||
|
||||
'max_request' => 50,
|
||||
|
||||
'dispatch_mode' => 1,
|
||||
|
||||
// 'daemonize' => 1
|
||||
|
||||
));
|
||||
|
||||
|
||||
$this->server->on('open', function (swoole_websocket_server $server, $request) {
|
||||
|
||||
//加入房间域
|
||||
$this->redis->hset($this->key,$request->fd,$request->fd);
|
||||
//加入组集合
|
||||
$this->redis->sadd('group', $this->key);
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$this->server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
|
||||
// echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
|
||||
|
||||
$group = $this->redis->sMembers('group');
|
||||
|
||||
foreach ($group as $v) {
|
||||
|
||||
$fangjian = $this->redis->hGetAll($v);
|
||||
|
||||
foreach ($fangjian as $k => $vv) {
|
||||
|
||||
$server->push($vv, count($fangjian).$frame->fd);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
$this->server->on('close', function ($server, $fd) {
|
||||
|
||||
$this->redis->hdel($this->key, 2);
|
||||
|
||||
//echo "client {$fd} closed\n";
|
||||
//退出并删除多余的分组fd
|
||||
$group = $this->redis->sMembers('group');
|
||||
|
||||
foreach ($group as $v) {
|
||||
|
||||
$fangjian = $this->redis->hgetall($v);
|
||||
|
||||
foreach ($fangjian as $k => $vv) {
|
||||
|
||||
// if ($fd == $vv) {
|
||||
|
||||
$this->redis->hdel($v, $vv);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
$this->server->on('request', function ($request, $response) {
|
||||
// 接收http请求从get获取message参数的值,给用户推送
|
||||
// $this->server->connections 遍历所有websocket连接用户的fd,给所有用户推送
|
||||
foreach ($this->server->connections as $fd) {
|
||||
// 需要先判断是否是正确的websocket连接,否则有可能会push失败
|
||||
if ($this->server->isEstablished($fd)) {
|
||||
$this->server->push($fd, '11');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$this->server->start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
new WebsocketTest();
|
||||
197
app/im/controller/Ws.php
Normal file
197
app/im/controller/Ws.php
Normal file
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
namespace app\im\controller;
|
||||
use app\im\controller\MessageHandlerV2;
|
||||
use app\material\model\BrochureIm;
|
||||
use Exception;
|
||||
use Swoole\WebSocket\Server;
|
||||
use think\App;
|
||||
use think\facade\Config;
|
||||
use think\session\driver\Cache;
|
||||
|
||||
|
||||
class Ws {
|
||||
|
||||
public $ws = null;
|
||||
|
||||
public $server;
|
||||
|
||||
public $redis;
|
||||
|
||||
public $key;
|
||||
|
||||
public $messageHandler;
|
||||
|
||||
public function __construct() {
|
||||
|
||||
// $this->key = '1223454461';
|
||||
// 加载框架里面的文件
|
||||
require __DIR__ . '/../../../vendor/autoload.php';
|
||||
|
||||
$http = ( new App() )->http;
|
||||
|
||||
$response = $http->run();
|
||||
|
||||
$this->ws = new Server("0.0.0.0", Config::get('swoole.server.mport'));
|
||||
|
||||
$this->ws->set([
|
||||
//worker进程数
|
||||
'worker_num' => 4,
|
||||
//task进程数
|
||||
'task_worker_num' => 4,
|
||||
//listen backlog
|
||||
'backlog' => 128,
|
||||
|
||||
'max_request' => 50,
|
||||
//心跳检测 每隔多少秒,遍历一遍所有的连接
|
||||
'heartbeat_check_interval' => 30,
|
||||
//心跳检测 最大闲置时间,超时触发close并关闭
|
||||
'heartbeat_idle_time' => 65,
|
||||
// 总开关,用来开启tcp_keepalive
|
||||
'open_tcp_keepalive' => 1,
|
||||
// 4s没有数据传输就进行检测
|
||||
'tcp_keepidle' => 10,
|
||||
// 4s没有数据传输就进行检测
|
||||
'tcp_keepcount' => 10,
|
||||
// 1s探测一次,即每隔1s给客户端发一个包(然后客户端可能会回一个ack的包,如果服务端收到了这个ack包,那么说明这个连接是活着的)'tcp_keepcount' => 5,
|
||||
// 探测的次数,超过5次后客户端还没有回ack包,那么close此连接
|
||||
'tcp_keepinterval' => 5,
|
||||
|
||||
'log_file' => '/www/wwwroot/swoole.log',
|
||||
|
||||
'daemonize' => 1
|
||||
]);
|
||||
|
||||
|
||||
|
||||
$this->ws->on("open", [$this, 'onOpen']);
|
||||
|
||||
$this->ws->on("message", [$this, 'onMessage']);
|
||||
|
||||
$this->ws->on("task", [$this, 'onTask']);
|
||||
|
||||
$this->ws->on("finish", [$this, 'onFinish']);
|
||||
|
||||
$this->ws->on("close", [$this, 'onClose']);
|
||||
|
||||
$this->ws->on('workerStart' ,[$this ,'onWorkerStart']);
|
||||
|
||||
$this->ws->start();
|
||||
}
|
||||
|
||||
|
||||
public function onWorkerStart()
|
||||
{
|
||||
|
||||
$this->messageHandler = new Some();
|
||||
|
||||
}
|
||||
/**
|
||||
* @param $ws
|
||||
* @param $request
|
||||
* @功能说明:建立连接回调
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-02 18:17
|
||||
*/
|
||||
public function onOpen($ws, $request) {
|
||||
|
||||
$request->get['action'] = !empty($request->get['action'])?$request->get['action']:'mOnOpen';
|
||||
|
||||
if(method_exists($this->messageHandler, $request->get['action']))
|
||||
{
|
||||
// try{
|
||||
call_user_func([$this->messageHandler, $request->get['action']] , $request->get,$request->fd);
|
||||
|
||||
// }catch(Exception $e) {
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
// echo FILE_UPLOAD_PATH;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $ws
|
||||
* @param $frame
|
||||
* @功能说明:接受消息回调
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-02 18:17
|
||||
*/
|
||||
public function onMessage($ws, $frame) {
|
||||
|
||||
$data = @json_decode($frame->data,true);
|
||||
|
||||
if(is_array($data)){
|
||||
|
||||
if(method_exists($this->messageHandler, $data['action']))
|
||||
{
|
||||
// try{
|
||||
|
||||
call_user_func([$this->messageHandler, $data['action']] ,$ws,$data,$frame->fd);
|
||||
|
||||
// }catch(Exception $e) {
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param $serv
|
||||
* @param $task_id
|
||||
* @param $worker_id
|
||||
* @param $data
|
||||
* @功能说明:完成异步任务回调
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-02 18:17
|
||||
*/
|
||||
public function onTask($serv, $task_id, $worker_id, $data) {
|
||||
|
||||
//返回字符串给worker进程——>触发onFinish
|
||||
return "success";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $serv
|
||||
* @param $task_id
|
||||
* @param $data
|
||||
* @功能说明:完成任务投递回调
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-02 18:16
|
||||
*/
|
||||
public function onFinish($serv, $task_id, $data) {
|
||||
//task_worker进程将任务处理结果发送给worker进程
|
||||
echo "完成任务{$task_id}投递 处理结果:{$data}";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $ws
|
||||
* @param $fd
|
||||
* @功能说明:关闭连接回调
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-07-02 18:16
|
||||
*/
|
||||
public function onClose($ws, $fd) {
|
||||
|
||||
// try{
|
||||
|
||||
call_user_func([$this->messageHandler, 'loginOut'] ,$ws, $fd);
|
||||
|
||||
// }catch(Exception $e) {
|
||||
//
|
||||
// }
|
||||
|
||||
// echo "{$fd}关闭了连接1";
|
||||
}
|
||||
}
|
||||
|
||||
$obj = new Ws();
|
||||
82
app/im/controller/net.php
Normal file
82
app/im/controller/net.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
//SOCKET
|
||||
//
|
||||
class net
|
||||
{
|
||||
public $socket = 0;
|
||||
|
||||
//func
|
||||
function listen($ip, $port)
|
||||
{
|
||||
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
|
||||
socket_bind($this->socket, $ip, $port);
|
||||
$ex = socket_listen($this->socket, 4);
|
||||
//socket_bind($this->socket, '127.0.0.1', $port) or die("socket_bind() fail:" . socket_strerror(socket_last_error()) . "/n");
|
||||
//$ex = socket_listen($this->socket, 4) or die("socket_listen() fail:" . socket_strerror(socket_last_error()) . "/n");
|
||||
|
||||
return $ex;
|
||||
}
|
||||
|
||||
function accept()
|
||||
{
|
||||
return socket_accept($this->socket);
|
||||
}
|
||||
|
||||
function close()
|
||||
{
|
||||
if($this->socket == 0) return;
|
||||
socket_close($this->socket);
|
||||
$this->socket = 0;
|
||||
}
|
||||
|
||||
function send_bytes($cs, $bytes)
|
||||
{
|
||||
$str = $this->bytes_to_string($arr);
|
||||
$ex = $this->send($cs, $str);
|
||||
return $ex;
|
||||
}
|
||||
|
||||
function recv_bytes($cs, $len = 1024)
|
||||
{
|
||||
$ret = $this->recv($cs, $len);
|
||||
$bytes = $this->string_to_bytes($ret);
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
function send($cs, $msg)
|
||||
{
|
||||
$ex = socket_write($cs, $msg);
|
||||
return $ex;
|
||||
}
|
||||
|
||||
function recv($cs, $len = 1024)
|
||||
{
|
||||
$ret = socket_read($cs, $len);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
///accessibility
|
||||
|
||||
function bytes_to_string($bytes)
|
||||
{
|
||||
$str = '';
|
||||
for($i=0; $i<count($bytes); $i++)
|
||||
{
|
||||
$str .= chr($bytes[$i]);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
function string_to_bytes($str)
|
||||
{
|
||||
$bytes = array();
|
||||
for($i=0; $i<strlen($str); $i++)
|
||||
{
|
||||
$bytes[] = ord($str[$i]);
|
||||
}
|
||||
return $bytes;
|
||||
}
|
||||
}
|
||||
?>
|
||||
61
app/im/controller/test.php
Normal file
61
app/im/controller/test.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
//include 'crc.php';
|
||||
include 'net.php';
|
||||
|
||||
|
||||
//打印十六进制(可以不用)
|
||||
function println($bytes) {
|
||||
for($i=0;$i<count($bytes);$i++)
|
||||
{
|
||||
printf("%02X ", $bytes[$i]);
|
||||
}
|
||||
printf(".");
|
||||
}
|
||||
|
||||
|
||||
//这里开始
|
||||
$net = new net();
|
||||
$net->listen('192.168.1.55', 50000);
|
||||
|
||||
while(true) {
|
||||
$cs = $net->accept();
|
||||
|
||||
while($cs) {
|
||||
|
||||
try{
|
||||
$ret = $net->recv_bytes($cs, 1024);
|
||||
abc($ret);
|
||||
//println($ret);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
//printf('cs close');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$net->close();
|
||||
|
||||
|
||||
//abc处理读取到的卡(4字节);
|
||||
function abc($ret)
|
||||
{
|
||||
$len = $ret[4];
|
||||
if($len < 14)
|
||||
{
|
||||
//printf('无效数据');
|
||||
return ;
|
||||
}
|
||||
//
|
||||
$count = $ret[9];
|
||||
$count = ($count - 3) / 4;
|
||||
//
|
||||
for($i=0; $i<$count; $i++)
|
||||
{
|
||||
$idx = 10 + ($i * 4);
|
||||
$card = sprintf("%02X%02X%02X%02X", $ret[$idx+0], $ret[$idx+1], $ret[$idx+2], $ret[$idx+3]);//这是获取到的卡数据(按文档意思可能会读到多张卡,处理这个$card就可以了)
|
||||
printf('card['.$i.']>>'.$card.' | ');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
5
app/im/event.php
Normal file
5
app/im/event.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
// 这是系统自动生成的im应用event定义文件
|
||||
return [
|
||||
|
||||
];
|
||||
42
app/im/info/Info.php
Normal file
42
app/im/info/Info.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Longbing [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright Chengdu longbing Technology Co., Ltd.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Website http://longbing.org/
|
||||
// +----------------------------------------------------------------------
|
||||
// | Sales manager: +86-13558882532 / +86-13330887474
|
||||
// | Technical support: +86-15680635005
|
||||
// | After-sale service: +86-17361005938
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
|
||||
//模块名称[必填]
|
||||
'name' => 'im',
|
||||
//模块标题[必填]
|
||||
'title' =>'即时通讯',
|
||||
//内容简介
|
||||
'desc' =>'',
|
||||
//封面图标
|
||||
'icon' =>'',
|
||||
//模块类型[必填] model:模块 可以出现在左侧一级 app:应用中心 , 是一个应用中心的应用
|
||||
'type' => 'model',
|
||||
// 模块唯一标识[必填],格式:模块名.开发者标识.module
|
||||
'identifier' => 'im.longbing.module',
|
||||
// 版本[必填],格式采用三段式:主版本号.次版本号.修订版本号
|
||||
'version' => '1.0.2',
|
||||
// 模块依赖[可选],格式[[模块名, 模块唯一标识, 依赖版本, 对比方式]]
|
||||
'need_module' => [
|
||||
['admin', 'admin.longbing.module', '1.0.0']
|
||||
],
|
||||
// 应用依赖[可选],格式[[插件名, 应用唯一标识, 依赖版本, 对比方式]]
|
||||
'need_app' => [],
|
||||
|
||||
//订阅消息
|
||||
'tmpl_name'=>['im_msg']
|
||||
|
||||
];
|
||||
71
app/im/info/PermissionIm.php
Normal file
71
app/im/info/PermissionIm.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Longbing [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright Chengdu longbing Technology Co., Ltd.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Website http://longbing.org/
|
||||
// +----------------------------------------------------------------------
|
||||
// | Sales manager: +86-13558882532 / +86-13330887474
|
||||
// | Technical support: +86-15680635005
|
||||
// | After-sale service: +86-17361005938
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace app\im\info;
|
||||
|
||||
use longbingcore\permissions\PermissionAbstract;
|
||||
|
||||
/**
|
||||
* 模块功能权限
|
||||
* Class PermissionSendmsg
|
||||
*/
|
||||
class PermissionIm extends PermissionAbstract {
|
||||
|
||||
const tabbarKey = null;
|
||||
//后台管理菜单对应key[必填] , 当前模块文件夹名称
|
||||
const adminMenuKey = 'im';
|
||||
public $saasKey ;
|
||||
const apiPaths = [];
|
||||
|
||||
|
||||
public function __construct(int $uniacid,$infoConfigOptions = [])
|
||||
{
|
||||
parent::__construct($uniacid, self::tabbarKey, self::adminMenuKey, $this->saasKey, self::apiPaths , $infoConfigOptions);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回saas端授权结果
|
||||
* @return bool
|
||||
*/
|
||||
public function sAuth(): bool
|
||||
{
|
||||
return true ;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回p端授权结果
|
||||
* @return bool
|
||||
*/
|
||||
public function pAuth(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回c端授权结果
|
||||
*
|
||||
* @param int $user_id
|
||||
* @return bool
|
||||
* @author ArtizanZhang
|
||||
* @DataTime: 2019/12/9 17:13
|
||||
*/
|
||||
public function cAuth(int $user_id): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
82
app/im/info/Subscribe.php
Normal file
82
app/im/info/Subscribe.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Longbing [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright Chengdu longbing Technology Co., Ltd.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Website http://longbing.org/
|
||||
// +----------------------------------------------------------------------
|
||||
// | Sales manager: +86-13558882532 / +86-13330887474
|
||||
// | Technical support: +86-15680635005
|
||||
// | After-sale service: +86-17361005938
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\im\info;
|
||||
|
||||
use app\card\model\CardCount;
|
||||
use app\radar\model\RadarMessage;
|
||||
use app\radar\model\RadarOrder;
|
||||
use longbingcore\diy\BaseSubscribe;
|
||||
|
||||
/**
|
||||
* @author shuixian
|
||||
* @DataTime: 2019/12/11 16:23
|
||||
* Class Subscribe
|
||||
* @package app\ucenter\info
|
||||
*/
|
||||
class Subscribe extends BaseSubscribe
|
||||
{
|
||||
/**
|
||||
* 相应个人中心工具菜单
|
||||
*
|
||||
* @return mixed
|
||||
* @author shuixian
|
||||
* @DataTime: 2019/12/12 11:24
|
||||
*/
|
||||
public function onAddWorkStaffCenterMenu(){
|
||||
$toolsMenu= [
|
||||
|
||||
"title" => '话术库管理',
|
||||
"icon" => 'iconhuashuku',
|
||||
"link" => '/admin/pages/speech/index',
|
||||
"linkType"=> '4',
|
||||
|
||||
];
|
||||
|
||||
return [$toolsMenu];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 员工 客户获取列表查询
|
||||
*
|
||||
* @param $data
|
||||
* @return array
|
||||
* @author shuixian
|
||||
* @DataTime: 2019/12/26 10:30
|
||||
*/
|
||||
public function onStaffCustomerList($data)
|
||||
{
|
||||
// 聊天数量
|
||||
$map1 = [ [ 'user_id', '=', $data[ 'uid' ] ], [ 'target_id', '=', $data['to_uid'] ] ];
|
||||
$map2 = [ [ 'target_id', '=', $data[ 'uid' ] ], [ 'user_id', '=', $data['to_uid'] ] ];
|
||||
$messageCount = RadarMessage::whereOr( [ $map1, $map2 ] )->count();
|
||||
|
||||
$msgData[ 'count' ] = $messageCount;
|
||||
$msgData[ 'title' ] = "聊天";
|
||||
|
||||
// 通话数量
|
||||
$phoneCount = CardCount::where( [ [ 'user_id', '=', $data[ 'uid' ] ], [ 'to_uid', '=', $data['to_uid'] ],
|
||||
[ 'sign', '=', 'copy' ], [ 'type', 'in', [ 2, 3, 11 ] ] ]
|
||||
)->count();
|
||||
|
||||
|
||||
$phoneData[ 'count' ] = $phoneCount;
|
||||
$phoneData[ 'title' ] = "通话";
|
||||
|
||||
return [$msgData , $phoneData];
|
||||
}
|
||||
|
||||
}
|
||||
30
app/im/info/UpdateSql.php
Normal file
30
app/im/info/UpdateSql.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
//获取表前缀
|
||||
$prefix = longbing_get_prefix();
|
||||
|
||||
//每个一个sql语句结束,都必须以英文分号结束。因为在执行sql时,需要分割单个脚本执行。
|
||||
//表前缀需要自己添加{$prefix} 以下脚本被测试脚本
|
||||
|
||||
|
||||
$sql = <<<updateSql
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `{$prefix}longbing_card_message_friend` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(10) NOT NULL COMMENT '发送消息用户id',
|
||||
`friend_id` int(10) NOT NULL COMMENT '接收消息用户id',
|
||||
`message_type` varchar(50) NOT NULL DEFAULT 'text',
|
||||
`lastmessage` text COMMENT '消息内容',
|
||||
`not_read_message_count` int(11) NOT NULL DEFAULT '0' COMMENT '未读消息数量',
|
||||
`uniacid` int(10) NOT NULL,
|
||||
`create_time` int(11) NOT NULL DEFAULT '0',
|
||||
`update_time` int(11) NOT NULL DEFAULT '0',
|
||||
`is_read` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `chat_id` (`user_id`,`friend_id`,`create_time`) USING BTREE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=175 DEFAULT CHARSET=utf8mb4 COMMENT='名片--聊天记录表';
|
||||
|
||||
ALTER TABLE `{$prefix}longbing_card_message_friend` ADD COLUMN `is_read` tinyint(1) NOT NULL DEFAULT 0;
|
||||
|
||||
updateSql;
|
||||
|
||||
return $sql;
|
||||
14
app/im/lang/zh-cn.php
Normal file
14
app/im/lang/zh-cn.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
return [
|
||||
'hello thinkphp' => '欢迎使用ThinkPHP',
|
||||
'data type error' => '数据类型错误',
|
||||
'test' => '你好啊',
|
||||
'picture' => '图片',
|
||||
'audio' => '音频',
|
||||
'vedio' => '视频',
|
||||
'Hello, I am ' => '您好,我是',
|
||||
', May I help you? Please contact me!' => ',有什么可以帮到您的吗?记得联系我!',
|
||||
'not chat id ,please check param' => '没有关系数据,请检查传入参数。',
|
||||
'my reply' => '自定义话术',
|
||||
'login error' => '登陆失败',
|
||||
];
|
||||
5
app/im/middleware.php
Normal file
5
app/im/middleware.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
// 这是系统自动生成的im应用middleware定义文件
|
||||
return [
|
||||
|
||||
];
|
||||
59
app/im/model/ImChart.php
Normal file
59
app/im/model/ImChart.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
namespace app\im\model;
|
||||
|
||||
use app\BaseModel;
|
||||
use think\facade\Db;
|
||||
class ImChart extends BaseModel
|
||||
{
|
||||
protected $name = 'longbing_card_chart';
|
||||
|
||||
//创建
|
||||
public function createChart($data)
|
||||
{
|
||||
$data['create_time'] = time();
|
||||
return $this->createRow($data);
|
||||
}
|
||||
|
||||
//更新
|
||||
public function updateChart($filter ,$data)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
return $this->updateRow($filter ,$data);
|
||||
}
|
||||
|
||||
//获取列表
|
||||
public function listChart($filter)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
$result = $this->where($filter)->select();
|
||||
if(!empty($result)) $result = $result->toArray();
|
||||
return $result;
|
||||
}
|
||||
|
||||
//获取总数
|
||||
public function listChartCount($filter)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
return $this->where($filter)->count();
|
||||
}
|
||||
|
||||
//获取详情
|
||||
public function getChart($filter)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
return $this->getRow($filter);
|
||||
}
|
||||
|
||||
//删除
|
||||
public function delChart($filter)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
return $this->delRow($filter);
|
||||
}
|
||||
|
||||
//真删除
|
||||
public function destoryChart($filter)
|
||||
{
|
||||
return $this->destoryRow($filter);
|
||||
}
|
||||
}
|
||||
122
app/im/model/ImChat.php
Normal file
122
app/im/model/ImChat.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
namespace app\im\model;
|
||||
|
||||
use app\BaseModel;
|
||||
use think\facade\Db;
|
||||
class ImChat extends BaseModel
|
||||
{
|
||||
//定义表名称
|
||||
protected $name = 'longbing_card_chat';
|
||||
//获取用户信息
|
||||
// public function customer()
|
||||
// {
|
||||
// return $this->hasOne('ImCustomer' ,)
|
||||
// }
|
||||
//创建
|
||||
public function createChat($data)
|
||||
{
|
||||
$data['create_time'] = time();
|
||||
$result = $this->save($data);
|
||||
if(!empty($result)) $result = $this->id;
|
||||
return $result;
|
||||
}
|
||||
|
||||
//更新
|
||||
public function updateChat($filter ,$data)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
return $this->updateRow($filter ,$data);
|
||||
}
|
||||
|
||||
//获取列表
|
||||
public function listChat($user_id , $uniacid,$page_config)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$start_row = 0;
|
||||
$page_count = 10;
|
||||
if(isset($page_config['page_count']) && !empty($page_config['page_count']) && $page_config['page_count'] > 0) $page_count = $page_config['page_count'];
|
||||
if(isset($page_config['page']) && !empty($page_config['page']) && $page_config['page'] > 0) $start_row = ($page_config['page'] -1) * $page_count;
|
||||
$result = $this->where(function ($query) use ($user_id) {
|
||||
$query->whereOr(['target_id' => $user_id , 'user_id' => $user_id]) ;
|
||||
})
|
||||
->where(['deleted' => 0 ,'uniacid' => $uniacid])
|
||||
->order('update_time', 'desc')
|
||||
->limit($start_row,$page_count)
|
||||
->select();
|
||||
|
||||
// $result = $this->where(['deleted' => 0])
|
||||
// ->where(function($query) use($user_id) {
|
||||
// $query->
|
||||
// })
|
||||
// ->limit($start_row,$page_count)
|
||||
// ->select();
|
||||
|
||||
if(!empty($result)) $result = $result->toArray();
|
||||
return $result;
|
||||
}
|
||||
|
||||
//获取总数
|
||||
public function listChatCount($user_id , $uniacid)
|
||||
{
|
||||
return $this->where(function ($query) use ($user_id) {
|
||||
$query->whereOr(['target_id' => $user_id , 'user_id' => $user_id]) ;
|
||||
})
|
||||
->where(['deleted' => 0 ,'uniacid' => $uniacid])
|
||||
->count();
|
||||
}
|
||||
//获取所有
|
||||
public function listChatAll($user_id ,$uniacid)
|
||||
{
|
||||
$result = $this->where(function ($query) use ($user_id) {
|
||||
$query->whereOr(['target_id' => $user_id] , ['user_id' => $user_id]) ;
|
||||
})
|
||||
->where(['deleted' => 0 ,'uniacid' => $uniacid])
|
||||
->field('id as chat_id,user_id,target_id')
|
||||
->select();
|
||||
|
||||
if(!empty($result)) $result = $result->toArray();
|
||||
return $result;
|
||||
}
|
||||
//获取单个Chat
|
||||
public function getChat($user_id ,$target_id ,$uniacid)
|
||||
{
|
||||
//查询条件1
|
||||
$where = [
|
||||
['user_id' , '=' ,$user_id],
|
||||
['target_id' ,'=' , $target_id],
|
||||
];
|
||||
$whereOr = [
|
||||
['user_id' , '=' ,$target_id],
|
||||
['target_id' ,'=' , $user_id],
|
||||
];
|
||||
$result = $this->where(function ($query) use($where, $whereOr){
|
||||
$query->whereOr([$where,$whereOr]);
|
||||
})
|
||||
->where(['uniacid' => $uniacid ,'deleted' => 0])
|
||||
->field('id as chat_id,user_id,target_id')
|
||||
->find();
|
||||
return $result;
|
||||
}
|
||||
//通过id获取chat
|
||||
public function getChatById($chat_id)
|
||||
{
|
||||
$result = $this->where(['id' => $chat_id])->find();
|
||||
if(!empty($result)) $result = $result->toArray();
|
||||
return $result;
|
||||
}
|
||||
//删除
|
||||
public function delChat($filter)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
return $this->updateChat($filter ,['deleted' => 0]);
|
||||
}
|
||||
//真删除
|
||||
public function destroyChat($filter)
|
||||
{
|
||||
return $this->destroyRow($filter);
|
||||
}
|
||||
}
|
||||
24
app/im/model/ImClient.php
Normal file
24
app/im/model/ImClient.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace app\im\model;
|
||||
|
||||
use app\BaseModel;
|
||||
|
||||
class ImClient extends BaseModel
|
||||
{
|
||||
//定义表名称
|
||||
protected $name = 'longbing_card_collection';
|
||||
|
||||
//是否是客户
|
||||
public function isCustomer($user_id ,$customer_id ,$uniacid)
|
||||
{
|
||||
$filter = array(
|
||||
'uid' => $customer_id,
|
||||
'to_uid' => $user_id,
|
||||
'uniacid' => $uniacid,
|
||||
'intention' => 1
|
||||
);
|
||||
|
||||
$result = $this->where($filter)->count();
|
||||
return !empty($result);
|
||||
}
|
||||
}
|
||||
124
app/im/model/ImMessage.php
Normal file
124
app/im/model/ImMessage.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
namespace app\im\model;
|
||||
|
||||
use app\BaseModel;
|
||||
use think\facade\Db;
|
||||
class ImMessage extends BaseModel
|
||||
{
|
||||
//定义表名称
|
||||
protected $name = 'longbing_card_message';
|
||||
|
||||
//创建聊天消息
|
||||
public function createMessage($data)
|
||||
{
|
||||
$data['create_time'] = time();
|
||||
return $this->createRow($data);
|
||||
}
|
||||
|
||||
//修改聊天消息
|
||||
public function updateMessage($filter ,$data)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
return $this->updateRow($filter ,$data);
|
||||
}
|
||||
|
||||
//标记已读消息
|
||||
public function readMessage($filter)
|
||||
{
|
||||
$filter['status'] = 1;
|
||||
return $this->updateMessage($filter ,['status' => 2]);
|
||||
}
|
||||
|
||||
//撤销消息
|
||||
public function recallMessage($filter)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
return $this->updateMessage($filter, ['status' => 3]);
|
||||
}
|
||||
|
||||
//查询聊天消息列表
|
||||
public function listMessage($filter ,$page_config)
|
||||
{
|
||||
$start_row = 0;
|
||||
$page_count = 10;
|
||||
if(isset($page_config['page_count']) && !empty($page_config['page_count']) && $page_config['page_count'] > 0) $page_count = $page_config['page_count'];
|
||||
if(isset($page_config['page']) && !empty($page_config['page']) && $page_config['page'] > 0) $start_row = ($page_config['page'] -1) * $page_count;
|
||||
// $filter['deleted'] = 0;
|
||||
$result = $this->where($filter)
|
||||
->where(['deleted'=>0])
|
||||
->order('id desc')
|
||||
->limit($start_row ,$page_count)
|
||||
->select();
|
||||
if(!empty($result))
|
||||
{
|
||||
$result = $result->toArray();
|
||||
$result = array_reverse($result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
//查询聊天消息列表
|
||||
public function listMessageV2($filter ,$page_config,$dis)
|
||||
{
|
||||
$start_row = 0;
|
||||
$page_count = 10;
|
||||
if(isset($page_config['page_count']) && !empty($page_config['page_count']) && $page_config['page_count'] > 0) $page_count = $page_config['page_count'];
|
||||
if(isset($page_config['page']) && !empty($page_config['page']) && $page_config['page'] > 0) $start_row = ($page_config['page'] -1) * $page_count;
|
||||
// $filter['deleted'] = 0;
|
||||
$result = $this->where($filter)
|
||||
->whereOr(function ($query) use ($dis){
|
||||
$query->where($dis);
|
||||
})
|
||||
->order('id desc')
|
||||
->limit($start_row ,$page_count)
|
||||
->select();
|
||||
if(!empty($result))
|
||||
{
|
||||
$result = $result->toArray();
|
||||
$result = array_reverse($result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
//获取聊天消息总量
|
||||
public function listMessageCount($filter)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
$count = $this->where($filter)->count();
|
||||
return $count;
|
||||
}
|
||||
|
||||
//删除聊天消息
|
||||
public function delMessage($filter)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
return $this->deleteRow($filter);
|
||||
}
|
||||
|
||||
//查询最后一条消息
|
||||
public function lastMessage($filter)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
$result = $this->where($filter)->order('create_time', 'desc')->field(['create_time' ,'content' ,'message_type'])->find();
|
||||
return $result;
|
||||
}
|
||||
//获取未读消息列表
|
||||
public function listNotReadMessage($filter)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
$filter['status'] = 1;
|
||||
$result = $this->where($filter)
|
||||
->order('create_time' ,'asc')
|
||||
->select();
|
||||
if(!empty($result)) $result = $result->toArray();
|
||||
$this->updateMessage($filter, ['status' =>2]);
|
||||
return $result;
|
||||
}
|
||||
|
||||
//真删除
|
||||
public function destroyMessage($filter)
|
||||
{
|
||||
return $this->destoryRow($filter);
|
||||
}
|
||||
}
|
||||
11
app/im/model/ImMessageFriend.php
Normal file
11
app/im/model/ImMessageFriend.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace app\im\model;
|
||||
|
||||
use app\BaseModel;
|
||||
|
||||
class ImMessageFriend extends BaseModel
|
||||
{
|
||||
//定义表名称
|
||||
protected $name = 'longbing_card_message_friend';
|
||||
|
||||
}
|
||||
82
app/im/model/ImMyReply.php
Normal file
82
app/im/model/ImMyReply.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
namespace app\im\model;
|
||||
|
||||
use app\BaseModel;
|
||||
|
||||
class ImMyReply extends BaseModel
|
||||
{
|
||||
//定义表名称
|
||||
protected $name = 'longbing_card_quick_reply';
|
||||
|
||||
public function searchContentAttr($query, $value, $data)
|
||||
{
|
||||
$query->where('content','like', '%' . $value . '%');
|
||||
}
|
||||
public function searchUserIdAttr($query, $value, $data)
|
||||
{
|
||||
$query->where('user_id','=', $value);
|
||||
}
|
||||
public function searchUniacidAttr($query, $value, $data)
|
||||
{
|
||||
$query->where('uniacid','=', $value);
|
||||
}
|
||||
public function type()
|
||||
{
|
||||
return $this->hasOne('ImReplyType' ,'id' ,'type');
|
||||
}
|
||||
//创建话术
|
||||
public function createReply($data)
|
||||
{
|
||||
$data['create_time'] = time();
|
||||
$result = $this->save($data);
|
||||
return !empty($result);
|
||||
}
|
||||
|
||||
//更新话术
|
||||
public function updateReply($filter ,$data)
|
||||
{
|
||||
$data['update_time'] = time();
|
||||
$result = $this->where($filter)->update($data);
|
||||
return !empty($result);
|
||||
}
|
||||
|
||||
//获取话术列表
|
||||
public function listReply($filter)
|
||||
{
|
||||
$result = $this->where($filter)
|
||||
->select();
|
||||
if(!empty($result)) $result = $result->toArray();
|
||||
return $result;
|
||||
}
|
||||
//获取话术列表(分页)
|
||||
public function listReplys($filter ,$page_config)
|
||||
{
|
||||
$result = $this->with(['type'])
|
||||
->withSearch(['content' ,'user_id' ,'uniacid'] ,$filter)
|
||||
->order('top' ,'desc')
|
||||
->page($page_config['page'] ,$page_config['page_count'])
|
||||
->select();
|
||||
if(!empty($result)) $result = $result->toArray();
|
||||
return $result;
|
||||
}
|
||||
//获取话术总数
|
||||
public function getReplyCount($filter)
|
||||
{
|
||||
$result = $this->withSearch(['content' ,'user_id' ,'uniacid'] ,$filter)->count();
|
||||
if(empty($result)) $result = 0;
|
||||
return $result;
|
||||
}
|
||||
|
||||
//删除话术
|
||||
public function deleteReply($filter)
|
||||
{
|
||||
return $this->destoryReply($filter);
|
||||
}
|
||||
|
||||
//删除(真删除)
|
||||
public function destoryReply($filter)
|
||||
{
|
||||
$result = $this->where($filter)->delete();
|
||||
return !empty($result);
|
||||
}
|
||||
}
|
||||
74
app/im/model/ImReplyType.php
Normal file
74
app/im/model/ImReplyType.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
namespace app\im\model;
|
||||
|
||||
use app\BaseModel;
|
||||
|
||||
class ImReplyType extends BaseModel
|
||||
{
|
||||
//定义表名称
|
||||
protected $name = 'longbing_card_reply_type';
|
||||
|
||||
public function searchTitleAttr($query, $value, $data)
|
||||
{
|
||||
$query->where('title','like', '%' . $value . '%');
|
||||
}
|
||||
|
||||
public function searchUniacidAttr($query, $value, $data)
|
||||
{
|
||||
$query->where('uniacid','=', $value );
|
||||
}
|
||||
|
||||
public function reply()
|
||||
{
|
||||
return $this->belongsTo('ImMyReply' ,'id' ,'type');
|
||||
}
|
||||
//创建话术
|
||||
public function createType($data)
|
||||
{
|
||||
$data['create_time'] = time();
|
||||
return $this->save($data);
|
||||
}
|
||||
//更新话术
|
||||
public function updateType($filter ,$data)
|
||||
{
|
||||
$data['update_time'] = time();
|
||||
$result = $this->where($filter)->update($data);
|
||||
return !empty($result);
|
||||
}
|
||||
|
||||
//获取话术列表
|
||||
public function listType($filter ,$page_config = ['page' => 1 ,'page_count' => 20])
|
||||
{
|
||||
$result = $this->withSearch(['title' ,'uniacid'] ,$filter)
|
||||
->page($page_config['page'] ,$page_config['page_count'])
|
||||
->order('top desc, id desc')
|
||||
->select();
|
||||
if(!empty($result)) $result = $result->toArray();
|
||||
return $result;
|
||||
}
|
||||
//获取话术列表
|
||||
public function getTypeCount($filter)
|
||||
{
|
||||
$result = $this->withSearch(['title' ,'uniacid'] ,$filter)
|
||||
->count();
|
||||
if(empty($result)) $result = 0;
|
||||
return $result;
|
||||
}
|
||||
|
||||
//删除话术
|
||||
public function delType($filter)
|
||||
{
|
||||
$result = $this->where($filter)->delete();
|
||||
return !empty($result);
|
||||
}
|
||||
|
||||
public function listAllType($filter)
|
||||
{
|
||||
$result = $this->where($filter)
|
||||
->order('top' ,'desc')
|
||||
->select();
|
||||
if(empty($result)) $result = $result->toArray();
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
38
app/im/model/ImSystemReply.php
Normal file
38
app/im/model/ImSystemReply.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
namespace app\im\model;
|
||||
|
||||
use app\BaseModel;
|
||||
|
||||
class ImReplyType extends BaseModel
|
||||
{
|
||||
//定义表名称
|
||||
protected $name = 'longbing_card_reply_type';
|
||||
|
||||
//创建话术
|
||||
public function createReply($data)
|
||||
{
|
||||
return $this->createRow($data);
|
||||
}
|
||||
//更新话术
|
||||
public function updateReply($filter ,$data)
|
||||
{
|
||||
return $this->updateRow($filter ,$data);
|
||||
}
|
||||
|
||||
//获取话术列表
|
||||
public function listReply($filter)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
$result = $this->where($filter)
|
||||
->select();
|
||||
if(!empty($result)) $result = $result->toArray();
|
||||
return $result;
|
||||
}
|
||||
|
||||
//删除话术
|
||||
public function delReply($filter)
|
||||
{
|
||||
return $this->deleteRow($filter);
|
||||
}
|
||||
|
||||
}
|
||||
19
app/im/model/ImUser.php
Normal file
19
app/im/model/ImUser.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace app\im\model;
|
||||
|
||||
use app\BaseModel;
|
||||
|
||||
class ImUser extends BaseModel
|
||||
{
|
||||
//定义表名称
|
||||
protected $name = 'longbing_card_user';
|
||||
|
||||
//获取用户信息
|
||||
public function getUser($filter)
|
||||
{
|
||||
$filter['deleted'] = 0;
|
||||
$result = $this->where($filter)->find();
|
||||
if(!empty($result)) $result = $result->toArray();
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
5
app/im/provider.php
Normal file
5
app/im/provider.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
// 这是系统自动生成的im应用provider定义文件
|
||||
return [
|
||||
|
||||
];
|
||||
51
app/im/route/route.php
Normal file
51
app/im/route/route.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
use think\facade\Route;
|
||||
/**
|
||||
* @model im
|
||||
* @author yangqi
|
||||
* @create time 2019年11月25日23:09:59
|
||||
*
|
||||
*/
|
||||
|
||||
Route::group('admin' ,function() {
|
||||
|
||||
});
|
||||
|
||||
Route::group('app' ,function() {
|
||||
|
||||
Route::post('listCustomer' , 'im/listCustomer');
|
||||
Route::post('listCustomerV2' , 'im/listCustomerV2');
|
||||
Route::get('listNotReadMessage' , 'im/listNotReadMessage');
|
||||
Route::get('listMessage' , 'im/listMessage');
|
||||
Route::get('listReply' , 'im/listReply');
|
||||
Route::post('addReply' , 'im/addReply');
|
||||
Route::get('delReply' , 'im/delReply');
|
||||
|
||||
//获取IM签名
|
||||
Route::get('getTimUserSig' , 'im/getTimUserSig');
|
||||
//保存发送成功的消息
|
||||
Route::post('sendMessage' , 'im/sendMessage');
|
||||
Route::post('readMessage' , 'im/readMessage');
|
||||
//获取目标客户给我发送的消息数量
|
||||
Route::post('getCustomerUnReadMessageCount' , 'im/getCustomerUnReadMessageCount');
|
||||
//修改消息状态 1都可见 2删除对方可见 撤回都不可见
|
||||
Route::post('updateMsgStatus' , 'im/updateMsgStatus');
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
Route::any('im/listCustomer' , 'im/listCustomer');
|
||||
Route::any('im/listNotReadMessage' , 'im/listNotReadMessage');
|
||||
Route::any('im/listMessage' , 'im/listMessage');
|
||||
Route::any('im/listReply' , 'im/listReply');
|
||||
Route::any('im/addReply' , 'im/addReply');
|
||||
Route::any('im/delReply' , 'im/delReply');
|
||||
|
||||
|
||||
Route::any('listCustomer' , 'im/listCustomer');
|
||||
Route::any('listNotReadMessage' , 'im/listNotReadMessage');
|
||||
Route::any('listMessage' , 'im/listMessage');
|
||||
Route::any('listReply' , 'im/listReply');
|
||||
Route::any('addReply' , 'im/addReply');
|
||||
Route::any('delReply' , 'im/delReply');
|
||||
395
app/im/service/ImMessageFriendService.php
Normal file
395
app/im/service/ImMessageFriendService.php
Normal file
@@ -0,0 +1,395 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Longbing [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright Chengdu longbing Technology Co., Ltd.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Website http://longbing.org/
|
||||
// +----------------------------------------------------------------------
|
||||
// | Sales manager: +86-13558882532 / +86-13330887474
|
||||
// | Technical support: +86-15680635005
|
||||
// | After-sale service: +86-17361005938
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\im\service;
|
||||
|
||||
|
||||
use app\Common\service\LongbingUserService;
|
||||
use app\im\model\ImChat;
|
||||
use app\im\model\ImMessage;
|
||||
use app\im\model\ImMessageFriend;
|
||||
use longbingcore\tools\LongbingDefault;
|
||||
|
||||
class ImMessageFriendService
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param $uniacid
|
||||
* @param $userId
|
||||
* @param int $page
|
||||
* @param int $page_count
|
||||
* @功能说明:获得用户的好友列表
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/16 14:51
|
||||
*/
|
||||
public static function getFriendList($uniacid , $userId ,$page_count = 10 ){
|
||||
|
||||
$imMessageFriend = new ImMessageFriend() ;
|
||||
|
||||
$message_model = new ImMessage();
|
||||
|
||||
$where[] = [ 'user_id' , '=' , $userId ];
|
||||
|
||||
$friendList = $imMessageFriend->where($where)->order('is_read desc , update_time desc' )->paginate($page_count);
|
||||
foreach ($friendList as $key => &$friend ){
|
||||
|
||||
$friendId = $friend['friend_id'] ;
|
||||
|
||||
$customer = longbingGetUser($friendId , $uniacid );
|
||||
|
||||
//判断客户是否是员工
|
||||
if(isset($customer['is_staff']) && !empty($customer['is_staff']))
|
||||
{
|
||||
$customer_info = longbingGetUserInfo($friendId , $uniacid );
|
||||
if(isset($customer_info['is_staff']) && !empty($customer_info['is_staff']))
|
||||
{
|
||||
if(!empty($customer_info['avatar'])) {
|
||||
$customer_info = transImagesOne($customer_info ,['avatar'] , $uniacid );
|
||||
}
|
||||
//是员工 就用员工头像 By.jingshuixian
|
||||
if(!empty($customer_info['avatar'])) $customer['avatarUrl'] = $customer_info['avatar'];
|
||||
|
||||
$customer['nickName'] = empty($customer_info['name']) ? $customer['nickName'] : $customer_info['name'];
|
||||
}
|
||||
}
|
||||
|
||||
//没有头像就给一个默认头像
|
||||
$customer['avatarUrl'] = empty($customer['avatarUrl']) ? LongbingDefault::$avatarImgUrl : $customer['avatarUrl'];
|
||||
|
||||
$friend['customer'] = $customer ;
|
||||
|
||||
$friend['target_id'] = $friendId ;
|
||||
|
||||
$friend['not_read_message_count'] = self::notReadCount($friend) ;
|
||||
|
||||
$last_msg = self::getLastMsg($friend);
|
||||
//兼容老数据格式
|
||||
$friend['lastmessage'] = [
|
||||
|
||||
'message_type' => !empty($last_msg)?$last_msg['message_type']:'text',
|
||||
|
||||
'content' => !empty($last_msg)?$last_msg['content']:'',
|
||||
|
||||
'is_show' => !empty($last_msg)?$last_msg['is_show']:1,
|
||||
|
||||
'is_self' => !empty($last_msg)&&$last_msg['user_id'] == $friend['user_id']?1:0
|
||||
|
||||
];
|
||||
|
||||
$friend['time'] = date('Y-m-d H:i:s', $friend['update_time']);
|
||||
|
||||
}
|
||||
|
||||
return empty($friendList) ? [] : $friendList->toArray() ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-05-27 16:10
|
||||
* @功能说明:后去最后一条消息(除开自己删除的)
|
||||
*
|
||||
*
|
||||
*/
|
||||
public static function getLastMsg($friend){
|
||||
|
||||
$message_model = new ImMessage();
|
||||
//自己接收的
|
||||
$dis = [
|
||||
|
||||
'user_id' => $friend['friend_id'],
|
||||
|
||||
'target_id' => $friend['user_id']
|
||||
];
|
||||
|
||||
$where = [];
|
||||
//自己发送的
|
||||
$where[] = ['user_id','=',$friend['user_id']];
|
||||
|
||||
$where[] = ['target_id','=',$friend['target_id']];
|
||||
//要除开删除的
|
||||
$where[] = ['is_show','<>',2];
|
||||
|
||||
// $where[] = ['target_is_show','<>',2];
|
||||
|
||||
$last_msg = $message_model->where($dis)->where('target_is_show','<>',2)->whereOr(function ($query) use ($where) {
|
||||
$query->where($where);
|
||||
})->order('create_time desc')->find();
|
||||
|
||||
|
||||
return !empty($last_msg)?$last_msg->toArray():[];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @author chenniang
|
||||
* @DataTime: 2021-05-27 16:38
|
||||
* @功能说明:未读消息读数量
|
||||
*/
|
||||
public static function notReadCount($friend){
|
||||
|
||||
$message_model = new ImMessage();
|
||||
//自己接收的
|
||||
$dis = [
|
||||
|
||||
'user_id' => $friend['friend_id'],
|
||||
|
||||
'target_id' => $friend['user_id'],
|
||||
|
||||
'status' => 1,
|
||||
|
||||
'target_is_show' => 1
|
||||
|
||||
];
|
||||
|
||||
$count = $message_model->where($dis)->count();
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $uniacid
|
||||
* @param $userId
|
||||
* @功能说明:老数据转移到新数据上
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/16 14:52
|
||||
*/
|
||||
public static function initOldFriendList($uniacid , $userId){
|
||||
$imMessageFriend = new ImMessageFriend() ;
|
||||
|
||||
$where[] = ['uniacid' , '=' , $uniacid ] ;
|
||||
$where[] = ['user_id' , '=' , $userId ] ;
|
||||
$friendCount = $imMessageFriend->where($where)->count();
|
||||
|
||||
if(! $friendCount){ //没有好友就用message数据导入好友列表
|
||||
$imMessage = new ImMessage() ;
|
||||
|
||||
|
||||
$whereIm[] = ['uniacid' , '=' , $uniacid ] ;
|
||||
$whereIm[] = ['status' ,'in' , [ 1,2] ] ;
|
||||
|
||||
$whereOr[] = ['user_id' ,'=' ,$userId ] ;
|
||||
$whereOr[] = ['target_id' ,'=' ,$userId ] ;
|
||||
|
||||
$chat_ids = $imMessage->where($whereIm)->where(function ($query) use($whereOr) {
|
||||
$query->whereOr($whereOr);
|
||||
})->distinct(true)->field('chat_id')->select();
|
||||
|
||||
$friendData = [] ;
|
||||
foreach ($chat_ids as $key => $item) {
|
||||
|
||||
if ($item) {
|
||||
|
||||
$chat_id = $item['chat_id'];
|
||||
$message = $imMessage->where([['uniacid', '=', $uniacid], ['chat_id', '=', intval($chat_id)], ['status', 'in', [1,2] ]])->where(function ($query) use ($whereOr) {
|
||||
$query->whereOr($whereOr);
|
||||
})->order('id desc')->find();
|
||||
|
||||
//这里代码和 updateFriendByMessage 里的代码,大部分是重复的,只是一个批量插入和一个此插入
|
||||
if ($message) {
|
||||
|
||||
$friendId = $message['user_id'] != $userId ? $message['user_id'] : $message['target_id'];
|
||||
//判断用户是否存在
|
||||
if( !LongbingUserService::isUser($uniacid , $friendId) ) continue ;
|
||||
|
||||
$friendItem['user_id'] = $userId;
|
||||
|
||||
$friendItem['friend_id'] = $friendId;
|
||||
|
||||
$friendItem['uniacid'] = $uniacid;
|
||||
//获取最后一条消息内容
|
||||
$whereOr = [];
|
||||
|
||||
$whereOr[] = ['user_id', '=', $userId];
|
||||
|
||||
$whereOr[] = ['target_id', '=', $userId];
|
||||
|
||||
$friendItem['message_type'] = $message['message_type'];
|
||||
|
||||
$friendItem['lastmessage'] = in_array( $message['message_type'] , ['image' , 'picture' ]) ? '[图片]' :$message['content'];
|
||||
|
||||
$friendItem['create_time'] = $message['create_time'];
|
||||
|
||||
$friendItem['update_time'] = $message['update_time'];
|
||||
|
||||
$friendItem['is_show'] = $message['is_show'];
|
||||
|
||||
$notReadMessageCount = $imMessage->where([
|
||||
['uniacid', '=', $uniacid],
|
||||
['user_id', '=', $friendId],
|
||||
['target_id', '=', $userId],
|
||||
['status', '=', 1]
|
||||
])->count();
|
||||
|
||||
$friendItem['not_read_message_count'] = $notReadMessageCount;
|
||||
|
||||
$friendItem['is_read'] = $notReadMessageCount ? 1 : 0 ;
|
||||
|
||||
$friendData[] = $friendItem;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$inserCount = $imMessageFriend->insertAll($friendData);
|
||||
|
||||
return $inserCount;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return false ;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/16 15:03
|
||||
* @功能说明:根据消息数据更新好友信息
|
||||
*/
|
||||
public static function updateFriendByMessage( ImMessage $message ){
|
||||
|
||||
if ($message) {
|
||||
|
||||
$userId = $message['user_id'] ;
|
||||
$friendId = $message['target_id'] ;
|
||||
$uniacid = $message['uniacid'] ;
|
||||
|
||||
self::updateFriendByUserIdAndFriend($uniacid , $userId , $friendId ) ;
|
||||
self::updateFriendByUserIdAndFriend($uniacid , $friendId , $userId ) ;
|
||||
|
||||
|
||||
}
|
||||
|
||||
return false ;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ImMessage $message
|
||||
* @功能说明:更新用户好友的关系和未读数据信息
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/16 16:47
|
||||
*/
|
||||
public static function updateFriendByUserIdAndFriend( $uniacid , $userId , $friendId){
|
||||
|
||||
//判断用户是否存在
|
||||
if( !LongbingUserService::isUser($uniacid , $userId) && !LongbingUserService::isUser( $uniacid , $friendId) ) return false ;
|
||||
|
||||
$imMessage = new ImMessage() ;
|
||||
$imMessageFriend = new ImMessageFriend() ;
|
||||
|
||||
$friendItem['user_id'] = $userId;
|
||||
$friendItem['friend_id'] = $friendId;
|
||||
$friendItem['uniacid'] = $uniacid;
|
||||
|
||||
//获取最后一条消息内容
|
||||
$message = ImMessageService::getLastMessage( $uniacid , $userId , $friendId ) ;
|
||||
if($message){
|
||||
|
||||
$friendItem['message_type'] = $message['message_type'];
|
||||
$friendItem['lastmessage'] = in_array( $message['message_type'] , ['image' ,'picture' ]) ? '[图片]' : $message['content'];
|
||||
$friendItem['create_time'] = $message['create_time'];
|
||||
$friendItem['update_time'] = $message['update_time'];
|
||||
|
||||
}else{
|
||||
$friendItem['message_type'] = '';
|
||||
$friendItem['lastmessage'] = '';
|
||||
$friendItem['create_time'] = time();
|
||||
$friendItem['update_time'] = time();
|
||||
}
|
||||
|
||||
//更新我的未读消息
|
||||
$notReadMessageCount = $imMessage->where([
|
||||
['uniacid', '=', $uniacid],
|
||||
['user_id', '=',$friendId ],
|
||||
['target_id', '=', $userId ],
|
||||
['status', '=', 1]
|
||||
])->count();
|
||||
|
||||
$friendItem['not_read_message_count'] = $notReadMessageCount;
|
||||
|
||||
$friendItem['is_read'] = $notReadMessageCount ? 1 : 0 ;
|
||||
|
||||
//判断 消息发送人好友关系
|
||||
$oneFriend = self::getOneByUserIdAndFriendId($userId,$friendId);
|
||||
if($oneFriend){
|
||||
$friendItem['id'] = $oneFriend['id'];
|
||||
|
||||
$friendItem['create_time'] = $oneFriend['create_time'];
|
||||
|
||||
return $imMessageFriend->update( $friendItem );
|
||||
}else{
|
||||
return $imMessageFriend->insert( $friendItem );
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $userId
|
||||
* @param $friendId
|
||||
* @功能说明:判断是否是好友关系
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/16 15:12
|
||||
*/
|
||||
public static function isFriend($userId , $friendId){
|
||||
|
||||
$imMessageFriend = new ImMessageFriend() ;
|
||||
$where[] = ['user_id' ,'=' ,$userId ] ;
|
||||
$where[] = ['friend_id' ,'=' ,$friendId ] ;
|
||||
|
||||
$count = $imMessageFriend->where($where)->count();
|
||||
|
||||
return $count ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $userId
|
||||
* @param $friendId
|
||||
* @功能说明:更新用户ID和朋友ID获取好友关系数据
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/16 15:14
|
||||
*/
|
||||
public static function getOneByUserIdAndFriendId($userId , $friendId){
|
||||
|
||||
$imMessageFriend = new ImMessageFriend() ;
|
||||
$where[] = ['user_id' ,'=' ,$userId ] ;
|
||||
$where[] = ['friend_id' ,'=' ,$friendId ] ;
|
||||
|
||||
return $imMessageFriend->where($where)->find() ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $uniacid
|
||||
* @param $userId
|
||||
* @param $friendId
|
||||
* @功能说明:处理好友的已读情况
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/16 17:23
|
||||
*/
|
||||
public static function readMessage($uniacid , $userId , $friendId){
|
||||
$imMessageFriend = new ImMessageFriend() ;
|
||||
$count = $imMessageFriend->where([ ['uniacid' , '=', $uniacid ] , ['user_id' , '=' ,$userId ] , ['friend_id' , '=' , $friendId ] ])->update([ 'is_read' => 0 , 'not_read_message_count' => 0 ]) ;
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
}
|
||||
51
app/im/service/ImMessageService.php
Normal file
51
app/im/service/ImMessageService.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Longbing [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright Chengdu longbing Technology Co., Ltd.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Website http://longbing.org/
|
||||
// +----------------------------------------------------------------------
|
||||
// | Sales manager: +86-13558882532 / +86-13330887474
|
||||
// | Technical support: +86-15680635005
|
||||
// | After-sale service: +86-17361005938
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\im\service;
|
||||
|
||||
|
||||
use app\im\model\ImMessage;
|
||||
|
||||
class ImMessageService
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $uniacid
|
||||
* @param $userId
|
||||
* @param $friendId
|
||||
* @功能说明: 我和好友之间聊天的最后一条记录
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/16 16:57
|
||||
*/
|
||||
public static function getLastMessage($uniacid , $userId , $friendId ){
|
||||
|
||||
$whereOr1[] = ['user_id' ,'=' , $friendId] ;
|
||||
$whereOr1[] = ['target_id' ,'=' ,$userId ] ;
|
||||
|
||||
$whereOr2[] = ['user_id' ,'=' ,$userId ] ;
|
||||
$whereOr2[] = ['target_id' ,'=' ,$friendId ] ;
|
||||
|
||||
$imMessage = new ImMessage() ;
|
||||
|
||||
$message = $imMessage->where([['uniacid', '=', $uniacid] , ['status', 'in', [1,2] ]])->whereOr(function ($query) use ($whereOr1) {
|
||||
$query->where($whereOr1);
|
||||
})->whereOr(function ($query) use ($whereOr2) {
|
||||
$query->where($whereOr2);
|
||||
})->order('id desc')->find();
|
||||
|
||||
return $message ;
|
||||
|
||||
}
|
||||
}
|
||||
244
app/im/service/ImService.php
Normal file
244
app/im/service/ImService.php
Normal file
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | Longbing [ WE CAN DO IT JUST THINK IT ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright Chengdu longbing Technology Co., Ltd.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Website http://longbing.org/
|
||||
// +----------------------------------------------------------------------
|
||||
// | Sales manager: +86-13558882532 / +86-13330887474
|
||||
// | Technical support: +86-15680635005
|
||||
// | After-sale service: +86-17361005938
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\im\service;
|
||||
|
||||
|
||||
use app\Common\LongbingServiceNotice;
|
||||
use app\Common\model\LongbingUserInfo;
|
||||
use app\Common\service\LongbingUserInfoService;
|
||||
use app\Common\service\LongbingUserService;
|
||||
use app\im\model\ImChat;
|
||||
use app\im\model\ImMessage;
|
||||
use app\publics\model\TmplConfig;
|
||||
use longbingcore\tools\LongbingTime;
|
||||
use longbingcore\wxcore\WxTmpl;
|
||||
|
||||
class ImService
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @功能说明:新增消息
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/13 17:01
|
||||
*/
|
||||
public static function addMessage($data){
|
||||
|
||||
|
||||
//存储消息
|
||||
$message_model = new ImMessage();
|
||||
$result = $message_model->insertGetId( $data );
|
||||
if($result){
|
||||
//修改时间chat
|
||||
$chat_model = new ImChat();
|
||||
$chat_model->updateChat(['id' => $data['chat_id']] ,[]);
|
||||
|
||||
//修改朋友表数据
|
||||
ImMessageFriendService::updateFriendByMessage($message_model->find($result));
|
||||
|
||||
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $uniacid
|
||||
* @param $user_id
|
||||
* @param $customer_id
|
||||
* @功能说明:获取聊天房间ID
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/13 17:01
|
||||
*/
|
||||
public static function getChatId($uniacid , $user_id ,$target_id )
|
||||
{
|
||||
$chat_model = new ImChat();
|
||||
|
||||
//查询条件
|
||||
$where = [
|
||||
['user_id' , '=' ,$user_id],
|
||||
['target_id' ,'=' , $target_id],
|
||||
];
|
||||
$whereOr = [
|
||||
['user_id' , '=' ,$target_id],
|
||||
['target_id' ,'=' , $user_id],
|
||||
];
|
||||
$chatId = $chat_model->where(function ($query) use($where, $whereOr){
|
||||
$query->whereOr([$where,$whereOr]);
|
||||
})
|
||||
->where(['uniacid' => $uniacid ,'deleted' => 0])
|
||||
->field('id as chat_id,user_id,target_id')
|
||||
->value('id');
|
||||
|
||||
|
||||
if(empty($chatId))
|
||||
{
|
||||
$chatData= (['user_id' => $user_id ,'target_id' => $target_id ,'uniacid' => $uniacid ,'create_time' => time()]);
|
||||
$chatId = $chat_model->createChat($chatData);
|
||||
}
|
||||
|
||||
return $chatId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $userId
|
||||
* @功能说明:获取未读消息数量
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/13 17:22
|
||||
*/
|
||||
public static function getUnReadMessageCount($userId){
|
||||
|
||||
$message_model = new ImMessage();
|
||||
$count = $message_model->listMessageCount(['target_id' => $userId ,'status' => 1]);
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $userId
|
||||
* @param $target_id
|
||||
* @功能说明:根据用户ID和目标用户ID获取未读消息数量
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/15 12:10
|
||||
*/
|
||||
public static function getUnReadMessageCountByUserIdAndTargetId($userId , $target_id ){
|
||||
|
||||
$message_model = new ImMessage();
|
||||
$count = $message_model->listMessageCount(['user_id'=> $userId ,'target_id' => $target_id ,'status' => 1]);
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $uniacid
|
||||
* @param $chat_id
|
||||
* @param $user_id
|
||||
* @功能说明: 更新消息未读信息,返回修改数量
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/14 9:54
|
||||
*/
|
||||
public static function readMessage($uniacid , $user_id , $friendId){
|
||||
|
||||
$message_model = new ImMessage();
|
||||
|
||||
$count = $message_model->where([
|
||||
['uniacid' , '=' , $uniacid] ,
|
||||
['user_id' , '=' , $friendId ] ,
|
||||
['target_id' , '=' , $user_id ]
|
||||
|
||||
])->update([ 'status' => 2 ]) ;
|
||||
|
||||
//处理未读消息数据
|
||||
ImMessageFriendService::readMessage( $uniacid , $user_id , $friendId ) ;
|
||||
|
||||
|
||||
return $count ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $uniacid
|
||||
* @param $userId
|
||||
* @param $data
|
||||
* @param string $page
|
||||
* @功能说明:发送模板消息
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/1/14 13:42
|
||||
*/
|
||||
public static function sendTmplMsg($uniacid , $userId ,$data , $page='' , $tmpl_name = 'im_msg'){
|
||||
|
||||
$openid = LongbingUserService::getUserOpenId($userId);
|
||||
|
||||
//模版消息model
|
||||
$tmpl_model = new TmplConfig();
|
||||
//获取模版
|
||||
$tmpl = $tmpl_model->where(['uniacid'=>$uniacid,'tmpl_name'=>$tmpl_name])->find();
|
||||
|
||||
//如果未添加模版消息 则不发送
|
||||
if(empty($tmpl)){
|
||||
return true;
|
||||
}else{
|
||||
$tmpl = $tmpl->toArray();
|
||||
}
|
||||
//模版id
|
||||
$tmpl_id = $tmpl['tmpl_id'];
|
||||
|
||||
$service_model = new WxTmpl( $uniacid );
|
||||
|
||||
$key_worlds = $service_model::getTmplKey($tmpl_id);
|
||||
|
||||
if(!empty($openid)&&!empty($tmpl_id)&&!empty($key_worlds)){
|
||||
|
||||
//发送内容
|
||||
$send_data = [];
|
||||
foreach ($key_worlds as $key => $item ){
|
||||
$send_data[$item]['value'] = $data[$key -1 ] ;
|
||||
}
|
||||
//模版消息库类
|
||||
$tmpl_sever = new WxTmpl($uniacid);
|
||||
//发送模版消息
|
||||
$res = $tmpl_sever::sendTmpl($openid,$tmpl_id,$send_data,$page);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $uniacid
|
||||
* @param $user_id
|
||||
* @param $target_id
|
||||
* @功能说明:发送聊天通知信息
|
||||
* @author jingshuixian
|
||||
* @DataTime: 2020/2/27 11:49
|
||||
*/
|
||||
public static function sendImMessageTmpl($uniacid , $user_id , $target_id , $message = ''){
|
||||
|
||||
|
||||
|
||||
|
||||
if(LongbingUserInfoService::isStraffByUserId($user_id) && !LongbingUserInfoService::isStraffByUserId($target_id)) //发送者是员工并且接收者是普通用户,员工回复消息,通知用户采用订阅消息
|
||||
{
|
||||
|
||||
|
||||
$message = '有未读私信' ;
|
||||
|
||||
$name= $name = LongbingUserInfoService::getNameByUserId($user_id);
|
||||
|
||||
|
||||
ImService::sendTmplMsg($uniacid , $target_id , [ $name , $message , LongbingTime::getChinaNowTime()] , 'pages/user/home' );
|
||||
|
||||
}else //发送者是普通用户,消息接收人是员工
|
||||
{
|
||||
|
||||
|
||||
$count = self::getUnReadMessageCount($target_id);
|
||||
|
||||
$message = '有' . $count .'条未读私信' ;
|
||||
|
||||
$notice = new LongbingServiceNotice($uniacid);
|
||||
|
||||
$name = LongbingUserService::getUserNickNameOpenId($user_id);
|
||||
|
||||
$notice->sendImMessageServiceNoticeToStaff($target_id ,$message , $name);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
0
app/im/view/index/index.html
Normal file
0
app/im/view/index/index.html
Normal file
Reference in New Issue
Block a user