| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670 |
- <?php
- namespace addons\fastchat\library;
- use GatewayWorker\Lib\Gateway;
- use think\Db;
- /**
- *
- */
- class Common
- {
- function __construct()
- {
- }
- /**
- * 直接添加会话
- * @param string $user_id 会话对象
- * @return array
- */
- public static function add_session($user_id)
- {
- $session_user = self::user_info($user_id);
- $session = [
- 'user_id' => $_SESSION['user_id'],
- 'session_type' => $session_user['session_type'],
- 'session_user_id' => $session_user['id'],
- 'createtime' => time(),
- 'deletetime' => NULL,
- 'deleteuser' => ''
- ];
- Db::name('fastchat_session')->insert($session);
- $session['id'] = Db::name('fastchat_session')->getLastInsID();
- return $session;
- }
- /**
- * 获取一个用户的基本信息
- * @param string user 待标识符的用户id
- * @return array
- */
- public static function user_info($user)
- {
- $user = explode('||', $user);
- if (isset($user[1])) {
- if ($user[1] == 'user' || $user[1] == 'admin') {
- $user_info = Db::name($user[1])->where('id', $user[0])->find();
- $user_info['source'] = $user[1];
- $user_info['session_type'] = ($user[1] == 'user') ? 0 : 1;
- } elseif ($user[1] == 'tourists') {
- $user_info = Db::name('fastchat_tourists')->where('id', $user[0])->find();
- $user_info['source'] = $user[1];
- $user_info['session_type'] = 2;
- } elseif ($user[1] == 'service_user') {
- $user_info = Db::name('fastchat_service_user')->where('id', $user[0])->find();
- $user_info['session_type'] = 5;
- } elseif ($user[1] == 'massager') {
- $user_info = Db::name("massager")->where("id", $user[0])->find();
- $avatar = '';
- if (isset($user_info["photo_images"]) && mb_strlen($user_info["photo_images"]) > 0) {
- $avatar = explode(",", $user_info["photo_images"])[0];
- }
- $user_info["avatar"] = $avatar;
- $user_info["nickname"] = isset($user_info['name']) ? $user_info['name'] : "未知";
- $user_info['session_type'] = 6;
- }
- if (!isset($user_info) || !isset($user_info['id'])) {
- $user_info['id'] = $user[0];
- $user_info['source'] = 'unknown';
- $user_info['nickname'] = '未知用户' . $user[0];
- $user_info['avatar'] = false;
- $user_info['session_type'] = 4;
- }
- $user_info['avatar'] = self::img_src_fill($user_info['avatar']);
- } else {
- $user_info['id'] = $user[0];
- $user_info['source'] = 'none';
- $user_info['nickname'] = '未知' . $user[0];
- $user_info['avatar'] = self::img_src_fill(false);
- $user_info['session_type'] = 3;
- }
- return $user_info;
- }
- /**
- * 获取图片的完整地址
- * @param string src 待处理的图片
- * @return string
- */
- public static function img_src_fill($src)
- {
- $upload = \app\common\model\Config::upload();
- \think\Hook::listen("upload_config_init", $upload);
- $view_cdn = config('view_replace_str.__CDN__');
- $view_cdn = $view_cdn ? $view_cdn : cdnurl('', true);
- $domain = $upload['cdnurl'] ?? $view_cdn;
- return $src ? cdnurl($src, $domain) : $domain . '/assets/img/avatar.png';
- }
- /**
- * 发送消息
- * @param string user_id 带标识符的发送人
- * @param string session_user_id 带标识符的接受人
- * @param string message 消息内容
- * @return array
- */
- public static function send_message($user_id, $session_user_id, $message)
- {
- // 检查黑名单
- $blacklist = Db::name('fastchat_blacklist')
- ->where('user_id', $session_user_id)
- ->where('session_user_id', $user_id)
- ->value('id');
- if ($blacklist) {
- return ['msgtype' => 'send_message', 'code' => 0, 'msg' => '发送失败,对方已屏蔽您的发言!'];
- }
- // 检查是否有会话,没有则添加,有则直接发送消息
- $user = self::user_info($user_id);
- $session_user = self::user_info($session_user_id);
- $session = Db::name('fastchat_session')->where(function ($query) use ($user_id, $session_user) {
- $query->where('user_id', $user_id)
- ->where('session_type', $session_user['session_type'])
- ->where('session_user_id', $session_user['id']);
- })->whereOr(function ($query) use ($session_user_id, $user) {
- $query->where('user_id', $session_user_id)
- ->where('session_type', $user['session_type'])
- ->where('session_user_id', $user['id']);
- })
- ->find();
- if (!$session) {
- $session = [
- 'user_id' => $user_id,
- 'session_type' => $session_user['session_type'],
- 'session_user_id' => $session_user['id'],
- 'createtime' => time(),
- 'deletetime' => NULL,
- 'deleteuser' => ''
- ];
- Db::name('fastchat_session')->insert($session);
- $session['id'] = Db::name('fastchat_session')->getLastInsID();
- }
- $message_text = strip_tags($message, '<br><div><img><a>');
- $message = [
- 'session_id' => $session['id'],
- 'sender' => $user_id,
- 'message' => $message_text,
- 'createtime' => time()
- ];
- if (Db::name('fastchat_record')->insert($message)) {
- $message['record_id'] = Db::name('fastchat_record')->getLastInsID();//消息记录ID
- // 确定会话状态
- Db::name('fastchat_session')->where('id', $session['id'])->update(['deleteuser' => '', 'deletetime' => NULL, 'createtime' => time()]);
- if (Gateway::isUidOnline($session_user_id)) {
- // 加上发信人的信息
- $message['avatar'] = $user['avatar'];
- $message['nickname'] = $user['nickname'];
- $message['session_user'] = $user_id;
- $message['online'] = 1;
- $message['id'] = $message['session_id'];// 兼容前台
- unset($message['session_id']);
- $message['last_message'] = self::session_message($message_text);
- $message['last_time'] = self::format_time(NULL);
- $message['message'] = htmlspecialchars_decode($message['message']);
- // 查询当前用户发送的未读消息条数
- $message['unread_msg_count'] = Db::name('fastchat_record')
- ->where('session_id', $message['id'])
- ->where('sender', $user_id)
- ->where('status', 0)
- ->count('id');
- $message['sender'] = 'you';
- Gateway::sendToUid($session_user_id, json_encode(['msgtype' => 'new_message', 'data' => $message]));
- } else {
- // 检查是否有绑定服务号
- if ($session_user['session_type'] == 1) {
- $service_user = Db::name('fastchat_service_user')
- ->where('admin_id', $session_user['id'])
- ->where('status', '1')
- ->where('deletetime', NULL)
- ->find();
- if ($service_user) {
- $msg = '对方正使用服务账号【' . $service_user['nickname'] . '】接收消息,您的消息可能无法被对方查看!';
- return ['msgtype' => 'send_message', 'code' => 0, 'msg' => $msg];
- }
- }
- }
- return ['msgtype' => 'send_message', 'code' => 1];
- } else {
- return ['msgtype' => 'send_message', 'code' => 0, 'msg' => '发送失败,请重试!'];
- }
- }
- /**
- * 格式化消息-将图片和连接用文字代替
- * @param string message 消息内容
- * @return string
- */
- public static function session_message($message)
- {
- $message = htmlspecialchars_decode($message);
- $message = preg_replace("/<img(.*)>/", '[图片]', $message);
- $message = preg_replace("/<a(.*)<\/a>/", '[链接]', $message);
- return $message;
- }
- /**
- * 格式化时间
- * @param int time 时间戳
- * @return string
- */
- public static function format_time($time = NULL)
- {
- $text = '';
- $now_time = time();
- $time = ($time === NULL || $time > $now_time || $time == $now_time) ? $now_time + 1 : intval($time);
- $t = (int)($now_time - $time); //时间差 (秒)
- $y = date('Y', $time) - date('Y', $now_time);//是否跨年
- switch ($t) {
- case $t <= 0:
- $text = '刚刚';
- break;
- case $t < 60:
- $text = $t . '秒前'; // 一分钟内
- break;
- case $t < 60 * 60:
- $text = floor($t / 60) . '分钟前'; //一小时内
- break;
- case $t < 60 * 60 * 24:
- $text = floor($t / (60 * 60)) . '小时前'; // 一天内
- break;
- case $t < 60 * 60 * 24 * 3:
- $text = floor($time / (60 * 60 * 24)) == 1 ? '昨天' . date('H:i', $time) : '前天' . date('H:i', $time); //昨天和前天
- break;
- case $t < 60 * 60 * 24 * 30:
- $text = date('m-d H:i', $time); //一个月内
- break;
- case $t < 60 * 60 * 24 * 365 && $y == 0:
- $text = date('m-d', $time); //一年内
- break;
- default:
- $text = date('Y-m-d', $time); //一年以前
- break;
- }
- return $text;
- }
- /**
- * 用户token加密
- * @param string $token 待加密的token
- */
- public static function getEncryptedToken($token)
- {
- $token_config = \think\Config::get('token');
- $config = array(
- // 缓存前缀
- 'key' => $token_config['key'],
- // 加密方式
- 'hashalgo' => $token_config['hashalgo']
- );
- return hash_hmac($config['hashalgo'], $token, $config['key']);
- }
- /**
- * 检查用户身份
- * @param string user_cookie 用户cookie
- * @param int user_id 用户ID直接登录
- */
- public static function check_fa_user($user_cookie = null, $user_id = 0)
- {
- if ($user_cookie && !$user_id) {
- $cookie_httponly = config('cookie.httponly');
- if (!$cookie_httponly) {
- $user_id = Db::name('user_token')->where('token', Common::getEncryptedToken($user_cookie))->value('user_id');
- } else {
- list($id, $key) = explode('|', $user_cookie);
- $user_token_list = Db::name('user_token')
- ->where('user_id', $id)
- ->where('expiretime', '>', time())
- ->select();
- foreach ($user_token_list as $user_token) {
- $sign = $user_token['token'] . 'fastchat_user_sign_additional';
- $user_key = md5(md5($id) . md5($sign));
- if ($user_key == $key) {
- $user_id = $id;
- break;
- } else {
- $user_id = false;
- }
- }
- }
- }
- if ($user_id) {
- $user_info = Db::name('user')
- ->field('password,salt,token', true)
- ->where('id', $user_id)
- ->find();
- if ($user_info) {
- $user_info['user_id'] = $user_info['id'] . '||user';
- return $user_info;
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
- /**
- * 检查助教身份
- * @param string $token
- * @param int user_id 用户ID直接登录
- */
- public static function check_massager($token = null)
- {
- if ($token) {
- $massager_info = Db::name('massager')
- ->where('session_token', $token)
- ->find();
- if ($massager_info) {
- $massager_info['user_id'] = $massager_info['id'] . '||massager';
- return $massager_info;
- }
- }
- return false;
- }
- /**
- * 检查管理员身份
- * @param string keeplogin 管理员cookie信息
- * @param int admin_id 管理员ID直接登录
- * @return array
- */
- public static function check_admin($keeplogin, $admin_id = 0)
- {
- if ($admin_id) {
- $admin = Db::name('admin')->field(['password', 'salt'], true)->where('id', $admin_id)->find();
- if (!$admin) {
- return false;
- }
- } else {
- list($id, $keeptime, $expiretime, $key) = explode('|', $keeplogin);
- if ($id && $keeptime && $expiretime && $key && $expiretime > time()) {
- $admin = Db::name('admin')->where('id', $id)->find();
- if (!$admin || !$admin['token']) {
- return false;
- }
- //token有变更
- $sign = $id . 'fastchat_admin_sign_additional';
- if ($key != md5(md5($sign) . md5($keeptime) . md5($expiretime) . $admin['token'])) {
- return false;
- }
- } else {
- return false;
- }
- }
- // 检查是否与服务号绑定
- $service_user = Db::name('fastchat_service_user')
- ->where('admin_id', $admin['id'])
- ->where('status', '1')
- ->where('deletetime', NULL)
- ->find();
- if ($service_user) {
- $service_user['username'] = $service_user['nickname'];
- $service_user['user_id'] = $service_user['id'] . '||service_user';
- $service_user['token'] = $admin['token'];
- return $service_user;
- }
- $admin['user_id'] = $admin['id'] . '||admin';
- $admin['admin_id'] = $admin['id'];// 和服务号字段统一
- return $admin;
- }
- /**
- * 将游客的会话转到用户
- * @param string tourists 游客的cookie信息
- * @param string user_id 带标识符的用户id
- * @return bool
- */
- public static function tourists_to_login($tourists, $user_id)
- {
- $user = self::user_info($user_id);//登录人信息
- $tourists_info = self::check_tourists($tourists);//游客信息
- if (!$tourists_info) {
- return;
- }
- // 查出游客的所有会话-》把 user_id 没有的会话转给 user_id
- $session_list = Db::name('fastchat_session')
- ->where(function ($query) use ($tourists_info) {
- $query->where('user_id', $tourists_info['user_id']);
- })->whereOr(function ($query) use ($tourists_info) {
- $query->where('session_user_id', $tourists_info['id'])->where('session_type', 2);
- })
- ->order('createtime desc')
- ->select();
- foreach ($session_list as $key => $value) {
- $session_user = Common::session_user($value, $tourists_info['user_id']);//本会话的会话对象
- $session_user_info = Common::user_info($session_user);//会话对象信息
- $session = Db::name('fastchat_session')->where(function ($query) use ($user_id, $session_user_info) {
- $query->where('user_id', $user_id)
- ->where('session_type', $session_user_info['session_type'])
- ->where('session_user_id', $session_user_info['id']);
- })->whereOr(function ($query) use ($session_user, $user) {
- $query->where('user_id', $session_user)
- ->where('session_type', $user['session_type'])
- ->where('session_user_id', $user['id']);
- })
- ->find();
- if (!$session) {
- // 将此会话转给用户
- if ($value['user_id'] == $tourists_info['user_id']) {
- Db::name('fastchat_session')
- ->where('id', $value['id'])
- ->update(['user_id' => $user_id]);
- } else {
- Db::name('fastchat_session')
- ->where('id', $value['id'])
- ->update(['session_user_id' => $user['id'], 'session_type' => $user['session_type']]);
- }
- Db::name('fastchat_record')
- ->where('session_id', $value['id'])
- ->where('sender', $tourists_info['user_id'])
- ->update(['sender' => $user_id]);
- }
- }
- return true;
- }
- /**
- * 检查游客身份
- * @param string tourists 游客的cookie信息
- * @return array
- */
- public static function check_tourists($tourists)
- {
- list($id, $keeptime, $expiretime, $key) = explode('|', $tourists);
- if ($id && $keeptime && $expiretime && $key && $expiretime > time()) {
- $tourists = Db::name('fastchat_tourists')->where('id', $id)->find();
- if (!$tourists || !$tourists['token']) {
- return false;
- }
- //token有变更
- if ($key != md5(md5($id) . md5($keeptime) . md5($expiretime) . $tourists['token'])) {
- return false;
- }
- } else {
- return false;
- }
- $tourists['user_id'] = $tourists['id'] . '||tourists';
- $tourists['username'] = $tourists['nickname'];
- unset($tourists['token']);
- return $tourists;
- }
- /**
- * 获取用户的未读消息->获取他的会话->获取会话中的非他自己发送的未读消息
- * @param string user_id 带标识符的用户id
- * @param bool is_latest 是否只获取用户未链接websocket时的消息
- * @return string
- */
- public static function get_unread_messages($user_id, $is_latest = false)
- {
- $new_msg = '';
- $user = self::user_info($user_id);
- $session_list = Db::name('fastchat_session')->where(function ($query) use ($user_id) {
- $query->where('user_id', $user_id);
- })->whereOr(function ($query) use ($user) {
- $query->where('session_user_id', $user['id'])->where('session_type', $user['session_type']);
- })
- ->order('createtime desc')
- ->select();
- foreach ($session_list as $key => $value) {
- $session_user = self::session_user($value, $user_id);
- $where['session_id'] = $value['id'];
- $where['sender'] = $session_user;
- $where['status'] = 0;
- if ($is_latest) {
- $where['createtime'] = ['>', time() - 10];
- }
- $new_msg = Db::name('fastchat_record')
- ->where($where)
- ->value('id');
- if ($new_msg) {
- $session_user_info = self::user_info($session_user);
- $new_msg = $session_user_info['nickname'] . ' 发来一条新消息!';
- break;
- }
- }
- return $new_msg;
- }
- /**
- * 获取会话的会话对象
- * @param array session 会话信息
- * @param string user_id 带标识符的当前用户id
- * @return string
- */
- public static function session_user($session, $oneself = NULL)
- {
- if (!$oneself) {
- $oneself = $_SESSION['user_id'];
- }
- if ($oneself == $session['user_id']) {
- switch ($session['session_type']) {
- case '0':
- $session_user = $session['session_user_id'] . '||user';
- break;
- case '1':
- $session_user = $session['session_user_id'] . '||admin';
- break;
- case '2':
- $session_user = $session['session_user_id'] . '||tourists';
- break;
- case '5':
- $session_user = $session['session_user_id'] . '||service_user';
- break;
- case '6':
- $session_user = $session['session_user_id'] . '||massager';
- break;
- default:
- $session_user = $session['session_user_id'] . '||none';
- break;
- }
- } else {
- $session_user = $session['user_id'];
- }
- return $session_user;
- }
- /**
- * 处理前台搜索框的提示文字
- * @param string search_type 配置信息
- * @return string
- */
- public static function search_tip_fill($search_type)
- {
- $search_tip = '';
- if ($search_type && strstr($search_type, 'none') === false) {
- $search_type = explode(',', $search_type);
- foreach ($search_type as $key => $value) {
- switch ($value) {
- case "username":
- $search_tip .= '用户名/';
- break;
- case "usermobile":
- $search_tip .= '手机号/';
- break;
- case "userid":
- $search_tip .= '用户ID/';
- break;
- case "nickname":
- $search_tip .= '用户昵称/';
- break;
- default:
- $search_tip .= '未知/';
- break;
- }
- }
- }
- if (!$search_tip) {
- $search_tip = '搜索其实很简单';
- } else {
- $search_tip = '搜索' . trim($search_tip, '/') . '发起会话';
- }
- return $search_tip;
- }
- /*
- * 检查/过滤变量
- */
- public static function check_variable(&$variable)
- {
- $variable = htmlspecialchars($variable);
- $variable = stripslashes($variable); // 删除反斜杠
- $variable = addslashes($variable); // 转义特殊符号
- $variable = trim($variable); // 去除字符两边的空格
- }
- }
|