|
|
<?php
|
|
|
|
|
|
namespace app\chat\logic;
|
|
|
|
|
|
use app\base\model\user\UserInfo;
|
|
|
use app\chat\model\ChatFriendsRoom;
|
|
|
use app\chat\model\ChatFriendsRoomMessage;
|
|
|
use app\chat\model\ChatFriendsRoomUser;
|
|
|
use think\facade\Db;
|
|
|
|
|
|
class FriendsChat extends Base
|
|
|
{
|
|
|
|
|
|
/**
|
|
|
* 开启个人聊天会话并返回聊天房间ID(有事务)
|
|
|
* @param int $to_user_id 对方user_id
|
|
|
* @param string $client_id 客户端ID
|
|
|
* @date 2022-07-29
|
|
|
*/
|
|
|
public function updateChatRoom($to_user_id,$client_id)
|
|
|
{
|
|
|
$friends_room_model = new ChatFriendsRoom();
|
|
|
$friends_chat_service = new \app\chat\service\FriendsChat();
|
|
|
$websocket_param = get_websocket_config();
|
|
|
$group_class = new \websocket\Group($websocket_param);
|
|
|
|
|
|
if ($to_user_id == $this->userId) {
|
|
|
return sendErrorArray(3001, '您不能和自己聊天');
|
|
|
}
|
|
|
|
|
|
// 是否存在现有聊天房间
|
|
|
$room_id = $friends_room_model->getFriendsRoomId($to_user_id);
|
|
|
|
|
|
Db::startTrans();
|
|
|
|
|
|
// 不存在则创建新房间
|
|
|
if (empty($room_id)) {
|
|
|
// 创建新的聊天房间
|
|
|
$data = [
|
|
|
'uid' => $this->mid,
|
|
|
'user_id' => $this->userId,
|
|
|
'another_user_id' => $to_user_id
|
|
|
];
|
|
|
$room_id = $friends_room_model->dataUpdate($data);
|
|
|
if (!$room_id) {
|
|
|
Db::rollback();
|
|
|
return sendErrorArray(3001, '创建好友聊天失败');
|
|
|
}
|
|
|
// 存在client_id则绑定到组
|
|
|
if(!empty($client_id)){
|
|
|
// websocket加入某个组
|
|
|
$result = $group_class->joinGroup($client_id, $room_id);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 房间加入双方user_id
|
|
|
$result = $friends_chat_service->updateRoomUser($room_id, $to_user_id);
|
|
|
if (!$result) {
|
|
|
Db::rollback();
|
|
|
return sendErrorArray(3002, '创建好友聊天失败');
|
|
|
}
|
|
|
|
|
|
Db::commit();
|
|
|
|
|
|
return sendSuccessArray([
|
|
|
'room_id' => $room_id
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取聊天的用户列表
|
|
|
* @date 2022-08-01
|
|
|
*/
|
|
|
public function listChatRoom()
|
|
|
{
|
|
|
$friend_room_user_model = new ChatFriendsRoomUser();
|
|
|
$friend_chat_service = new \app\chat\service\FriendsChat();
|
|
|
|
|
|
// 获取聊天的用户列表
|
|
|
$result = $friend_chat_service->listChatRoom();
|
|
|
|
|
|
return $result;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 删除个人聊天会话
|
|
|
* @param int $room_id 房间ID
|
|
|
* @date 2022-09-20
|
|
|
*/
|
|
|
public function deleteChatRoom($room_id)
|
|
|
{
|
|
|
$friend_room_user_model = new ChatFriendsRoomUser();
|
|
|
|
|
|
// 删除聊天室
|
|
|
$res = $friend_room_user_model->dataDel([
|
|
|
['room_id', '=', $room_id],
|
|
|
['user_id', '=', $this->userId]
|
|
|
]);
|
|
|
// 有错误
|
|
|
if (!$res) {
|
|
|
return sendErrorArray(3001, '删除聊天室失败');
|
|
|
}
|
|
|
|
|
|
return sendSuccessArray([
|
|
|
'room_id' => $room_id
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取房间双方头像以及好友昵称
|
|
|
* @param int $room_id 聊天室ID
|
|
|
* @date 2022-08-03
|
|
|
*/
|
|
|
public function getChatRoomDetail($room_id)
|
|
|
{
|
|
|
$friend_room_user_model = new ChatFriendsRoomUser();
|
|
|
|
|
|
// 获取某个聊天室双方的头像和好友昵称
|
|
|
$result = $friend_room_user_model->getUsersInfo($room_id);
|
|
|
|
|
|
return $result;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 更改聊天室用户在线状态
|
|
|
* @param int $room_id 聊天室ID
|
|
|
* @param int $is_online 是否在线 1--在线 0--不在线
|
|
|
* @date 2022-08-16
|
|
|
*/
|
|
|
public function updateUserOnlineStatus($room_id, $is_online)
|
|
|
{
|
|
|
$friend_room_user_model = new ChatFriendsRoomUser();
|
|
|
$fried_chat_service = new \app\chat\service\FriendsChat();
|
|
|
|
|
|
// 更改在线状态
|
|
|
$result = $friend_room_user_model->updateUserOnlineStatus($room_id, $is_online);
|
|
|
if (!$result) {
|
|
|
return sendErrorArray(3001, '进入聊天室失败');
|
|
|
}
|
|
|
|
|
|
// 更改所有未读消息为已读 并清空未读数量
|
|
|
$result = $fried_chat_service->allMessageHasRead($room_id);
|
|
|
if (!$result['code']) {
|
|
|
return $result;
|
|
|
}
|
|
|
|
|
|
return sendSuccessArray();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 绑定用户和现有聊天室
|
|
|
* @param int $client_id 客户端ID
|
|
|
* @param int $room_id 聊天室ID
|
|
|
* @date 2022-08-16
|
|
|
*/
|
|
|
public function bindUser($client_id, $room_id = '')
|
|
|
{
|
|
|
$websocket_param = get_websocket_config();
|
|
|
|
|
|
$room_model = new ChatFriendsRoom();
|
|
|
$uid_class = new \websocket\Uid($websocket_param);
|
|
|
$group_class = new \websocket\Group($websocket_param);
|
|
|
|
|
|
// websocket绑定用户
|
|
|
$result = $uid_class->bindUid($client_id, $this->userId);
|
|
|
|
|
|
// 绑定所有需要监听的聊天室
|
|
|
$room_ids = $room_model->listRoomId();
|
|
|
|
|
|
foreach ($room_ids as $k => $v) {
|
|
|
// websocket加入某个组
|
|
|
$result = $group_class->joinGroup($client_id, $v);
|
|
|
}
|
|
|
|
|
|
return sendSuccessArray();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 发送消息
|
|
|
* @param int $room_id 聊天室ID
|
|
|
* @param string $content 聊天内容
|
|
|
* @param int $type 聊天类型 1--文字(有表情) 2--语音 3--图片 4--位置
|
|
|
* @param array $attach_data 附加数据 type=3时{seconds:录音时长,单位秒}
|
|
|
* @date 2022-08-08
|
|
|
*/
|
|
|
public function insertChatMessage($room_id, $content, $type = 1, $attach_data = [])
|
|
|
{
|
|
|
$websocket_param = get_websocket_config();
|
|
|
|
|
|
$user_info_model = new UserInfo();
|
|
|
$friend_room_user_model = new ChatFriendsRoomUser();
|
|
|
$friend_room_message_model = new ChatFriendsRoomMessage();
|
|
|
$friends_chat_service = new \app\chat\service\FriendsChat();
|
|
|
$group_class = new \websocket\Group($websocket_param);
|
|
|
|
|
|
// 查找房间的好友user_id
|
|
|
$to_user_id = $friend_room_user_model->getFriendUserId($room_id);
|
|
|
|
|
|
// 开启事务
|
|
|
Db::startTrans();
|
|
|
|
|
|
// 检查房间双方是否都存在 不存在则不全房间好友 房间加入双方user_id
|
|
|
$result = $friends_chat_service->updateRoomUser($room_id, $to_user_id);
|
|
|
if (!$result) {
|
|
|
Db::rollback();
|
|
|
return sendErrorArray(3001, '创建好友聊天失败');
|
|
|
}
|
|
|
|
|
|
// 图片在附加数据中存储宽高
|
|
|
if ($type == 3) {
|
|
|
// 获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息
|
|
|
$result = getimagesize($content);
|
|
|
$attach_data = [
|
|
|
'width' => $result[0],
|
|
|
'height' => $result[1],
|
|
|
];
|
|
|
}
|
|
|
|
|
|
// 插入聊天记录表
|
|
|
$data = [
|
|
|
'room_id' => $room_id,
|
|
|
'user_id' => $this->userId,
|
|
|
'to_user_id' => $to_user_id,
|
|
|
'type' => $type,
|
|
|
'content' => $content,
|
|
|
'attach_data' => $attach_data
|
|
|
];
|
|
|
|
|
|
// 查询聊天室对方是否在线
|
|
|
$is_friend_online = $friend_room_user_model->isFriendOnline($room_id, $to_user_id);
|
|
|
if ($is_friend_online) {
|
|
|
// 对方在线消息更改为已读
|
|
|
$data['is_read'] = 1;
|
|
|
}
|
|
|
|
|
|
$new_message_id = $friend_room_message_model->dataUpdate($data);
|
|
|
if (!$new_message_id) {
|
|
|
Db::rollback();
|
|
|
return sendErrorArray(3002, '插入聊天记录失败');
|
|
|
}
|
|
|
|
|
|
// 更新房间好友表的最近一条信息
|
|
|
$friend_room_user_update = [
|
|
|
'last_message_type' => $type,
|
|
|
'last_message_content' => $content,
|
|
|
'update_time' => time()
|
|
|
];
|
|
|
|
|
|
// 更新房间好友表数据
|
|
|
$res = $friend_room_user_model->where([
|
|
|
['room_id', '=', $room_id]
|
|
|
])->update($friend_room_user_update);
|
|
|
if ($res === false) {
|
|
|
Db::rollback();
|
|
|
return sendErrorArray(3003, '插入聊天记录失败');
|
|
|
}
|
|
|
|
|
|
// 好友不在线,更新消息未读数量
|
|
|
if (!$is_friend_online) {
|
|
|
$res = $friend_room_user_model->where([
|
|
|
['room_id', '=', $room_id],
|
|
|
['user_id', '=', $to_user_id]
|
|
|
])->save([
|
|
|
'unread_number' => Db::raw('unread_number + 1')
|
|
|
]);
|
|
|
if (!$res) {
|
|
|
Db::rollback();
|
|
|
return sendErrorArray(3004, '更新消息未读数量失败');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 提交事务
|
|
|
Db::commit();
|
|
|
|
|
|
// 获取用户头像
|
|
|
$user_info = $user_info_model->getOneData([
|
|
|
['user_id', '=', $this->userId]
|
|
|
], 'nick_name,head_img');
|
|
|
|
|
|
// 获取好友用户头像
|
|
|
$to_user_info = $user_info_model->getOneData([
|
|
|
['user_id', '=', $to_user_id]
|
|
|
], 'nick_name,head_img');
|
|
|
|
|
|
// 查询上一条消息的创建时间
|
|
|
$last_room_message_time = $friend_room_message_model->getOneData([
|
|
|
['id', '<', $new_message_id],
|
|
|
['room_id', '=', $room_id]
|
|
|
], 'create_time');
|
|
|
|
|
|
if (empty($last_room_message_time)) {
|
|
|
$is_show_time = 1;
|
|
|
$show_time = $friends_chat_service->timeShow(time());
|
|
|
} else {
|
|
|
// 5分钟以上显示时间
|
|
|
if (time() - $last_room_message_time >= 5 * 60) {
|
|
|
$is_show_time = 1;
|
|
|
$show_time = $friends_chat_service->timeShow(time());
|
|
|
// 5分钟以内不显示时间
|
|
|
} else {
|
|
|
$is_show_time = 0;
|
|
|
$show_time = '';
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// websocket发送消息
|
|
|
$show_message_text = $friends_chat_service->getShowMessageText($type, $content);
|
|
|
$list_time_show = $friends_chat_service->listTimeShow(time());
|
|
|
$message = [
|
|
|
'type' => 'chat_friend_message',
|
|
|
'send_type' => 'to_group',
|
|
|
'to_group' => $room_id,
|
|
|
'data' => [
|
|
|
// 消息ID
|
|
|
'id' => $new_message_id,
|
|
|
// 房间ID
|
|
|
'room_id' => $room_id,
|
|
|
// 用户ID
|
|
|
'user_id' => $this->userId,
|
|
|
// 接收的用户ID
|
|
|
'to_user_id' => $to_user_id,
|
|
|
// 消息类型
|
|
|
'type' => $type,
|
|
|
// 消息内容
|
|
|
'content' => $content,
|
|
|
// 附加数据
|
|
|
'attach_data' => $attach_data,
|
|
|
// 创建时间
|
|
|
'create_time' => date("Y-m-d H:i:s"),
|
|
|
// 头像
|
|
|
'user_head_img' => $user_info['head_img'],
|
|
|
// 是否显示时间
|
|
|
'is_show_time' => $is_show_time,
|
|
|
// 显示时间
|
|
|
'show_time' => $show_time,
|
|
|
|
|
|
// 消息列表需要,详情详情释放 列表显示信息内容
|
|
|
'show_message_text' => $show_message_text,
|
|
|
// 消息列表需要,详情详情释放 列表显示时间
|
|
|
'list_time_show' => $list_time_show,
|
|
|
// 消息列表需要,详情详情释放 列表显示好友昵称
|
|
|
'to_user_nick_name' => $to_user_info['nick_name'],
|
|
|
// 消息列表需要,详情详情释放 列表显示好友头像
|
|
|
'to_user_head_img' => $to_user_info['head_img']
|
|
|
]
|
|
|
];
|
|
|
|
|
|
$result = $group_class->sendToGroup($room_id, $message);
|
|
|
|
|
|
return sendSuccessArray();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取聊天记录
|
|
|
* @param int $room_id 房间ID
|
|
|
* @param int $cur_first_message_id 最上面一条的ID
|
|
|
* @date 2022-08-08
|
|
|
*/
|
|
|
public function listChatRoomMessage($room_id, $cur_first_message_id)
|
|
|
{
|
|
|
$message_model = new ChatFriendsRoomMessage();
|
|
|
$friend_room_user_model = new ChatFriendsRoomUser();
|
|
|
$friends_chat_service = new \app\chat\service\FriendsChat();
|
|
|
|
|
|
// 查找聊天室用户表,找到创建用户的时间为聊天的起始时间
|
|
|
$start_time = $friend_room_user_model->getOneData([
|
|
|
['uid', '=', $this->mid],
|
|
|
['room_id', '=', $room_id],
|
|
|
['user_id', '=', $this->userId]
|
|
|
], 'create_time');
|
|
|
|
|
|
// 查找聊天记录
|
|
|
$data_list = $message_model->listChatRoomMessage($room_id, $start_time, $cur_first_message_id);
|
|
|
|
|
|
// 聊天记录反转正序
|
|
|
$data_list['data'] = array_reverse($data_list['data']);
|
|
|
|
|
|
// 获取某个聊天室双方的头像和好友昵称
|
|
|
$users_info = $friend_room_user_model->getUsersInfo($room_id);
|
|
|
|
|
|
foreach ($data_list['data'] as $k => &$v) {
|
|
|
|
|
|
// 拼接头像信息 和 是否是自己发送
|
|
|
if ($v['user_id'] == $this->userId) {
|
|
|
// 拼接个人头像
|
|
|
$v['user_head_img'] = $users_info['user_head_img'];
|
|
|
} else {
|
|
|
// 拼接好友头像
|
|
|
$v['user_head_img'] = $users_info['to_user_head_img'];
|
|
|
}
|
|
|
|
|
|
#TODO 12小时和24小时格式判断
|
|
|
// 显示聊天时间
|
|
|
// 第1个一直显示时间
|
|
|
|
|
|
if ($k == 0) {
|
|
|
$v['is_show_time'] = 1;
|
|
|
$v['show_time'] = $friends_chat_service->timeShow(strtotime($v['create_time']));
|
|
|
|
|
|
// 间隔超过5分钟显示时间
|
|
|
} else if (strtotime($v['create_time']) - strtotime($data_list['data'][$k - 1]['create_time']) >= 5 * 60) {
|
|
|
$v['is_show_time'] = 1;
|
|
|
$v['show_time'] = $friends_chat_service->timeShow(strtotime($v['create_time']));
|
|
|
// 5分钟以内不显示时间
|
|
|
} else {
|
|
|
$v['is_show_time'] = 0;
|
|
|
$v['show_time'] = '';
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return $data_list;
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|