Files
gdoo/app/Gdoo/Chat/Services/ChatService.php
T
2021-02-22 12:17:00 +08:00

724 lines
22 KiB
PHP

<?php namespace Gdoo\Chat\Services;
use DB;
use URL;
use Gdoo\Chat\Models\History;
use Gdoo\Chat\Models\GroupUser;
use Gdoo\Chat\Models\Message;
class ChatService
{
/**
* 构建ws连接url
*
* @param array $user
* @access public
* @return array
*/
public static function getServerURL($user) {
$key = env('REALTIME_KEY');
$url = env('REALTIME_URL');
$timestamp = time();
$nonce = rand(10000, 99999);
$signature = hash_hmac('sha256', $key.$timestamp.$nonce, $key);
$query = [
'signature' => $signature,
'timestamp' => $timestamp,
'nonce' => $nonce,
'user_id' => $user['id'],
'user_name' => $user['name'],
];
return ['url' => $url. '?'. http_build_query($query)];
}
/**
* 获取组
*
* @param int $admin_id
* @access public
* @return array
*/
public static function getGroup($auth_id = 0, $admin_id = 0)
{
static $rows = null;
if ($rows == null) {
$model = DB::table('chat_group as cg')
->leftJoin('chat_group_user', 'chat_group_user.group_id', '=', 'cg.id');
if ($auth_id > 0) {
$model->where('chat_group_user.user_id', $auth_id);
}
if ($admin_id > 0) {
$model->whereRaw(db_instr('admin_ids', $admin_id));
}
$model->leftJoin(DB::raw('(select count(id) utotal, group_id
FROM chat_group_user
GROUP BY group_id
) cgu
'), 'cg.id', '=', 'cgu.group_id')
->selectRaw('cg.*, cgu.utotal, cg.logo as face');
$rows = $model->get()->keyBy('id');
}
return $rows;
}
/**
* 撤回消息
*
* @param int $type
* @param int $auth_id
* @param int $group_id
* @param int $id
* @access public
* @return array
*/
public static function recallMessage($type, $auth_id, $group_id, $id)
{
$chehui = 5;
if ($chehui <= 0) {
abort_error('没有开启此功能');
}
$message = DB::table('chat_message')->where('id', $id)->first();
if(!$message) {
abort_error('记录不存在了');
}
$outtime = time() - strtotime($message['created_dt']);
if($outtime > $chehui * 60) {
abort_error('已经超过'.$chehui.'分钟无法撤回');
}
if ($type == 'user') {
$receiver = [$auth_id, (int)$message['receive_id']];
} elseif ($type == 'group') {
$user_ids = DB::table('chat_group_user')->where('group_id', $group_id)->pluck('user_id');
foreach($user_ids as $user_id) {
$receiver[] = (int)$user_id;
}
}
$msg = '已撤回';
DB::table('chat_message')->where('id', $message['id'])->update([
'file_id' => 0,
'content' => $msg,
]);
$pushData = [
'send_id' => $auth_id,
'content' => $msg,
'event' => 'recallMessage',
'receive_ids' => $receiver,
'message_id' => (int)$message['id'],
];
$push = new PushService();
$push->send($pushData);
return $pushData;
}
/**
* 格式化消息
*
* @param array $rows
* @access public
* @return array
*/
public static function formatMessage($rows)
{
$file_ids = [];
foreach($rows as $row) {
if ($row['file_id'] > 0) {
$file_ids[] = $row['file_id'];
}
}
$imgext = ['gif','png','jpg','jpeg','bmp'];
if (count($file_ids) > 0) {
$model = DB::table('attachment');
$farr = [];
$files = $model->whereIn('id', $file_ids)->get();
foreach ($files as $file)
$farr[$file['id']] = $file;
if ($farr) {
foreach ($rows as $k => $row) {
$frs = [];
$fid = $row['file_id'];
if (isset($farr[$fid])) {
$frs = $farr[$fid];
$frs['fileext'] = $frs['type'];
$frs['fileid'] = $fid;
}
if ($frs) {
$type = $frs['type'];
$path = $frs['path'];
$boc = false;
if (substr($path, 0, 4) == 'http') {
$boc = true;
} else {
if (is_file(upload_path().'/'.$path)) {
$path = url('uploads/'.$path);
$frs['thumbpath'] = $path;
$frs['filepath'] = $path;
$frs['filesize'] = $frs['size'];
$frs['filesizecn'] = human_filesize($frs['size']);
$frs['filename'] = $frs['name'];
$boc = true;
}
}
if ($boc) {
if (in_array($type, $imgext)) {
// $frs['thumbpath'] = $fobj->getthumbpath($frs);
$rows[$k]['cont'] = '<img fid="'.$fid.'" src="'.$path.'">';
}
$rows[$k]['filers'] = $frs;
} else {
$rows[$k]['fileid'] = 0;
}
}
}
}
}
return $rows;
}
/**
* 获取用户
*
* @param int $user_id
* @param int $group_id
* @access public
* @return array
*/
public static function getUser($status = 1, $group_id = 1)
{
static $rows = null;
if ($rows == null) {
$model = DB::table('user');
if (is_numeric($status)) {
$model->where('status', $status);
}
if (is_numeric($group_id)) {
$model->where('group_id', $group_id);
}
$model->selectRaw("''as pingyin,tel,(CASE WHEN (gender = 1) THEN '男' ELSE '女' END) as sex, email, id, name, phone, phone as mobile, role_id, department_id, department_id as deptid");
$rows = $model->get()->keyBy('id');
}
return $rows;
}
/**
* 邀请用户到组
*
* @param string $ids
* @param int $group_id
*/
public static function inviteUser($auth, $group_id, $ids)
{
$user_ids = explode(',', $ids);
if (count($user_ids) > 0) {
foreach($user_ids as $index => $user_id) {
$model = GroupUser::firstOrNew([
'user_id' => $user_id,
'group_id' => $group_id,
]);
if ($model->exists == true) {
unset($user_ids[$index]);
}
$model->save();
}
if (count($user_ids) > 0) {
$users = DB::table('user')->whereIn('id', $user_ids)->get()->pluck('name')->implode(',');
$gets = [
"cont" => $auth['name'].'邀请['.$users.']加入本会话',
"sendid" => $auth['id'],
"receid" => $group_id,
"type" => 'group',
"optdt" => date('Y-m-d H:i:s'),
"zt" => 0,
"fileid" => '',
"msgid" => "",
"gid" => $group_id,
"nuid" => time(),
];
$json = ChatService::sendMessage('group', $auth['id'], $group_id, $gets);
}
}
}
/**
* 退出用户组
*
* @param int $group_id
* @param int $auth_id
* @access public
* @return void
*/
public static function exitGroup($group_id, $auth_id)
{
// 删除用户组权限
GroupUser::where('group_id', $group_id)
->where('user_id', $auth_id)
->delete();
// 删除组聊天记录
DB::table('chat_message_status')
->where('type', 'group')
->where('group_id', $group_id)
->where('user_id', $auth_id)
->delete();
// 删除会话记录
DB::table('chat_history')
->where('type', 'group')
->where('receive_id', $group_id)
->where('send_id', $auth_id)
->delete();
}
/**
* 删除服务器上记录
*
* @param string $type
* @param int $group_id
* @param int $auth_id
* @param string $ids
* @param int $day
* @access public
* @return void
*/
public static function clearRecord($type, $group_id, $auth_id, $ids = [], $day = 0)
{
DB::beginTransaction();
try {
// 获取聊天记录数量
$model = DB::table('chat_message_status')
->where('type', $type);
if (count($ids) > 0) {
$model->whereIn('message_id', $ids);
}
if ($type == 'group') {
$model->where('group_id', $group_id);
} else if ($type == 'user') {
$model->whereRaw("((group_id = '$group_id' and user_id = '$auth_id') or (group_id = '$auth_id' and user_id = '$group_id'))");
}
$messages = $model->groupBy('message_id')
->selectRaw('message_id, count(id) as count')
->get();
$model = DB::table('chat_message_status')
->where('group_id', $group_id)
->where('user_id', $auth_id);
if (count($ids) > 0) {
$model->whereIn('message_id', $ids);
}
$model->delete();
// 获取回话的最后消息id
$last_message_id = DB::table('chat_message_status')
->where('type', $type)
->where('group_id', $group_id)
->where('user_id', $auth_id)
->orderBy('message_id', 'desc')
->value('message_id');
// 更新回话的最后消息id
DB::table('chat_history')
->where('type', $type)
->where('receive_id', $group_id)
->where('send_id', $auth_id)
->update(['last_message_id' => (int)$last_message_id]);
// 删除消息状统计为1的数据
foreach($messages as $message) {
if ($message['count'] == 1) {
DB::table('chat_message')->where('id', $message['message_id'])->delete();
}
}
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
abort_error($e->getMessage());
}
}
/**
* 删除会话记录
*
* @param string $type
* @param int $group_id
* @param int $auth_id
* @access public
* @return void
*/
public static function clearHistory($type, $group_id, $auth_id)
{
DB::beginTransaction();
try {
// 获取聊天记录数量
$model = DB::table('chat_message_status')
->where('type', $type);
if ($type == 'group') {
$model->where('group_id', $group_id);
} else if ($type == 'user') {
$model->whereRaw("((group_id = '$group_id' and user_id = '$auth_id') or (group_id = '$auth_id' and user_id = '$group_id'))");
}
$messages = $model->groupBy('message_id')
->selectRaw('message_id, count(id) as count')
->get();
// 删除聊天记录
$model = DB::table('chat_message_status')
->where('type', $type)
->where('group_id', $group_id)
->where('user_id', $auth_id)
->delete();
// 删除会话记录
DB::table('chat_history')
->where('type', $type)
->where('receive_id', $group_id)
->where('send_id', $auth_id)
->delete();
// 删除消息状统计为1的数据
foreach($messages as $message) {
if ($message['count'] == 1) {
DB::table('chat_message')->where('id', $message['message_id'])->delete();
}
}
DB::commit();
} catch (\Exception $e) {
DB::rollBack();
abort_error($e->getMessage());
}
}
/**
* 获取组和用户
*
* @param int $group_id
* @param int $auth_id
* @access public
* @return array
*/
public static function getGroupUser($group_id, $auth_id)
{
$group = DB::table('chat_group')->where('id', $group_id)->first();
$group['face'] = $group['logo'];
$group['deptid'] = $group['department_id'];
$group['utotal'] = DB::table('chat_group_user')->where('group_id', $group_id)->count();
$group['innei'] = DB::table('chat_group_user')->where('user_id', $auth_id)->count();
$rows = DB::table('chat_group_user as cgu')
->leftJoin('user', 'user.id', 'cgu.user_id')
->where('cgu.group_id', $group_id)
->get(['user.id', 'user.name', 'user.avatar as face']);
$users = [];
foreach($rows as $row) {
$row['face'] = avatar($row['avatar']);
$users[] = $row;
}
$json['infor'] = $group;
$json['uarr'] = $users;
return $json;
}
/**
* 获取发送者
* @access public
* @param int $type 回话类型
* @param int $send_id 发送人
* @param int $receive_id 接受者id,如果是group那就是group_id
* @param int $user_id group的user_id
* @param int $message_id 消息id
* @return array
*/
public static function getReceiver($type, $receive_id, $send_id)
{
if ($type == 'user') {
$receiver = DB::table('user')
->where('id', $receive_id)
->selectRaw('id, name, role_id, department_id as deptid, avatar')
->first();
$receiver['face'] = avatar($receiver['avatar']);
$receiver['type'] = 'user';
$receiver['utotal'] = 0;
$receiver['gid'] = $receiver['id'];
}
else if ($type == 'group') {
$receiver = DB::table('chat_group')
->where('id', $receive_id)
->selectRaw('id, name, logo')
->first();
$receiver['face'] = $receiver['logo'];
$receiver['type'] = 'group';
// 查询用户数量
$receiver['utotal'] = DB::table('chat_group_user')
->where('group_id', $receive_id)
->count();
// 查询自己是否在组中
$receiver['innei'] = DB::table('chat_group_user')
->where('group_id', $receive_id)
->where('user_id', $send_id)
->count();
$receiver['gid'] = $receiver['id'];
}
return $receiver;
}
/**
* 获取发送者
* @access public
* @param int $type 回话类型
* @param int $send_id 发送人
* @param int $receive_id 接受者id,如果是group那就是group_id
* @param array $data 发送内容
* @param int $client 0=app发送 1=web客户端
* @return array
*/
public static function sendMessage($type, $send_id, $receive_id, $data, $client = 1)
{
$gets = $data;
$data = [
'send_id' => $send_id,
'receive_id' => $receive_id,
"content" => $gets['cont'],
'type' => $type,
'url' => $gets['url'],
'file_id' => $gets['fileid'],
'created_dt' => date('Y-m-d H:i:s')
];
$message_id = Message::insertGetId($data);
// 返回数据
$json = [
"cont" => $gets['cont'],
"sendid" => $send_id,
"receid" => $receive_id,
"type" => $type,
"optdt" => date('Y-m-d H:i:s'),
"zt" => 0,
"fileid" => $gets['fileid'],
"msgid" => "",
"gid" => $receive_id,
"id" => $message_id,
"nuid" => $gets['nuid'],
];
$json['event'] = 'message';
$json['content'] = $gets['cont'];
$json['send_id'] = $send_id;
// 写入历史记录
$user_ids = ChatService::setHistory($type, $send_id, $receive_id, $message_id);
if ($type == 'user') {
// 写入已读(自己)
DB::table('chat_message_status')->insert([
'group_id' => $receive_id,
'user_id' => $send_id,
'message_id' => $message_id,
'status' => 1,
'type' => $type,
]);
// 写入未读(对方)
DB::table('chat_message_status')->insert([
'group_id' => $send_id,
'user_id' => $receive_id,
'message_id' => $message_id,
'status' => 0,
'type' => $type,
]);
} else if ($type == 'group') {
// 写入未读(讨论组)
foreach($user_ids as $user_id) {
// 设置为已读(自己)
$status = $send_id == $user_id ? 1 : 0;
DB::table('chat_message_status')->insert([
'group_id' => $receive_id,
'user_id' => $user_id,
'message_id' => $message_id,
'status' => $status,
'type' => $type,
]);
}
// 组的名称
$group = DB::table('chat_group')->where('id', $receive_id)->first();
$json['gname'] = $group['name'];
}
$json['receuid'] = join(',', $user_ids);
$json['receive_ids'] = $user_ids;
return $json;
}
/**
* 写入会话
* @access public
* @param int $type 会话类型
* @param int $send_id 发送人
* @param int $receive_id 接受者id,如果是group那就是group_id
* @param int $user_id group的user_id
* @param int $message_id 消息id
* @return array
*/
public static function setHistory($type, $send_id, $receive_id, $message_id)
{
$model = History::firstOrNew([
'send_id' => $send_id,
'receive_id' => $receive_id,
'type' => $type,
]);
$model->last_message_id = $message_id;
$model->updated_dt = date('Y-m-d H:i:s');
$model->save();
if ($type == 'user') {
$receive_ids = [$send_id, $receive_id];
$model = History::firstOrNew([
'send_id' => $receive_id,
'receive_id' => $send_id,
'type' => $type,
]);
$model->last_message_id = $message_id;
$model->updated_dt = date('Y-m-d H:i:s');
if ($send_id != $receive_id) {
$model->unread_total = $model->unread_total + 1;
}
$model->save();
} else if($type == 'group') {
$user_ids = DB::table('chat_group_user')
->where('group_id', $receive_id)
->pluck('user_id');
// 写入接收者历史记录
foreach($user_ids as $user_id) {
// 返回所有接受者
$receive_ids[] = (int)$user_id;
// 发送人和接收人相同
if ($send_id == $user_id) {
continue;
}
$model = History::firstOrNew([
'send_id' => $user_id,
'receive_id' => $receive_id,
'type' => $type,
]);
$model->last_message_id = $message_id;
$model->updated_dt = date('Y-m-d H:i:s');
if ($send_id != $user_id) {
$model->unread_total = $model->unread_total + 1;
}
$model->save();
}
}
return array_unique($receive_ids);
}
/**
* 获取回话历史
*
* @param int $user_id
* @param datetime $updated_dt
* @param int $unread
* @access public
* @return array
*/
public static function getHistory($user_id, $updated_dt = '', $unread = 0)
{
$model = DB::table('chat_history as ch')
->leftJoin('chat_message as cm', 'cm.id', '=', 'ch.last_message_id')
->where('ch.send_id', $user_id)
->orderBy('ch.updated_dt', 'desc')
->selectRaw("
ch.type type,
ch.send_id uid,
ch.receive_id receid,
ch.send_id sendid,
".sql_month_day('ch.updated_dt')." optdts,
cm.content cont,
cm.id messid,
cm.send_id,
ch.unread_total stotal,
0 utotal,
ch.updated_dt as optdt
");
if ($updated_dt) {
$model->where('ch.updated_dt', '>', $updated_dt);
}
if ($unread) {
$model->where('ch.unread_total', '>', $unread);
}
$rows = $model->get();
$users = static::getUser();
$groups = static::getGroup();
$historys = [];
foreach ($rows as $row) {
if ($row['type'] == 'user') {
$row['face'] = avatar($users[$row['receid']]['avatar']);
$row['name'] = $users[$row['receid']]['name'];
if (empty($row['cont'])) {
$row['cont'] = '';
}
}
if ($row['type'] == 'group') {
$row['deptid'] = $groups[$row['receid']]['department_id'];
$row['face'] = $groups[$row['receid']]['face'];
$row['name'] = $groups[$row['receid']]['name'];
if (empty($row['cont'])) {
$row['cont'] = '';
} else {
$row['cont'] = $users[$row['send_id']]['name'].':'.$row['cont'];
}
}
$historys[] = $row;
}
return $historys;
}
}