2020-11-04 11:57:16 +08:00
|
|
|
|
<?php
|
2021-09-05 21:13:48 +08:00
|
|
|
|
declare(strict_types=1);
|
2020-11-04 11:57:16 +08:00
|
|
|
|
|
2020-11-04 16:47:17 +08:00
|
|
|
|
namespace App\Service;
|
2020-11-04 11:57:16 +08:00
|
|
|
|
|
2022-01-22 20:08:19 +08:00
|
|
|
|
use App\Constant\TalkEventConstant;
|
|
|
|
|
use App\Constant\TalkMessageType;
|
|
|
|
|
use App\Constant\TalkModeConstant;
|
2021-07-20 23:12:18 +08:00
|
|
|
|
use App\Event\TalkEvent;
|
2021-09-12 16:23:43 +08:00
|
|
|
|
use App\Model\Robot;
|
2021-07-28 23:08:07 +08:00
|
|
|
|
use App\Service\Group\GroupMemberService;
|
2021-07-17 00:07:24 +08:00
|
|
|
|
use App\Service\Message\FormatMessageService;
|
2021-07-09 22:57:19 +08:00
|
|
|
|
use App\Model\Talk\TalkRecords;
|
|
|
|
|
use App\Model\Talk\TalkRecordsForward;
|
2020-11-09 22:59:25 +08:00
|
|
|
|
use App\Traits\PagingTrait;
|
|
|
|
|
use Hyperf\DbConnection\Db;
|
|
|
|
|
|
2020-11-04 11:57:16 +08:00
|
|
|
|
class TalkService extends BaseService
|
|
|
|
|
{
|
2020-11-09 22:59:25 +08:00
|
|
|
|
use PagingTrait;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 查询对话页面的历史聊天记录
|
|
|
|
|
*
|
2021-07-05 21:52:44 +08:00
|
|
|
|
* @param int $user_id 用户ID
|
|
|
|
|
* @param int $receiver_id 接收者ID(好友ID或群ID)
|
|
|
|
|
* @param int $talk_type 对话类型[1:好友消息;2:群聊消息;]
|
|
|
|
|
* @param int $record_id 上一次查询的聊天记录ID
|
|
|
|
|
* @param int $limit 查询数据长度
|
|
|
|
|
* @param array $msg_type 消息类型
|
2020-12-03 11:57:46 +08:00
|
|
|
|
* @return array
|
2020-11-09 22:59:25 +08:00
|
|
|
|
*/
|
2021-08-14 17:31:21 +08:00
|
|
|
|
public function getChatRecords(int $user_id, int $receiver_id, int $talk_type, int $record_id, $limit = 30, $msg_type = []): array
|
2020-11-09 22:59:25 +08:00
|
|
|
|
{
|
|
|
|
|
$fields = [
|
2021-07-05 21:52:44 +08:00
|
|
|
|
'talk_records.id',
|
|
|
|
|
'talk_records.talk_type',
|
|
|
|
|
'talk_records.msg_type',
|
|
|
|
|
'talk_records.user_id',
|
|
|
|
|
'talk_records.receiver_id',
|
|
|
|
|
'talk_records.is_revoke',
|
|
|
|
|
'talk_records.content',
|
|
|
|
|
'talk_records.created_at',
|
2020-11-09 22:59:25 +08:00
|
|
|
|
'users.nickname',
|
|
|
|
|
'users.avatar as avatar',
|
|
|
|
|
];
|
|
|
|
|
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$model = TalkRecords::select($fields);
|
|
|
|
|
$model->leftJoin('users', 'users.id', '=', 'talk_records.user_id');
|
2020-11-09 22:59:25 +08:00
|
|
|
|
if ($record_id) {
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$model->where('talk_records.id', '<', $record_id);
|
2020-11-09 22:59:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-07-20 23:12:18 +08:00
|
|
|
|
if ($talk_type == TalkModeConstant::PRIVATE_CHAT) {
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$model->where(function ($query) use ($user_id, $receiver_id) {
|
2020-11-09 22:59:25 +08:00
|
|
|
|
$query->where([
|
2021-07-05 21:52:44 +08:00
|
|
|
|
['talk_records.user_id', '=', $user_id],
|
|
|
|
|
['talk_records.receiver_id', '=', $receiver_id]
|
2020-11-09 22:59:25 +08:00
|
|
|
|
])->orWhere([
|
2021-07-05 21:52:44 +08:00
|
|
|
|
['talk_records.user_id', '=', $receiver_id],
|
|
|
|
|
['talk_records.receiver_id', '=', $user_id]
|
2020-11-09 22:59:25 +08:00
|
|
|
|
]);
|
|
|
|
|
});
|
|
|
|
|
} else {
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$model->where('talk_records.receiver_id', $receiver_id);
|
2020-11-09 22:59:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$model->where('talk_records.talk_type', $talk_type);
|
2021-08-14 17:31:21 +08:00
|
|
|
|
|
2020-11-09 22:59:25 +08:00
|
|
|
|
if ($msg_type) {
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$model->whereIn('talk_records.msg_type', $msg_type);
|
2020-11-09 22:59:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-07-17 00:07:24 +08:00
|
|
|
|
// 过滤用户删除记录
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$model->whereNotExists(function ($query) use ($user_id) {
|
2020-11-09 22:59:25 +08:00
|
|
|
|
$prefix = config('databases.default.prefix');
|
2021-07-05 21:52:44 +08:00
|
|
|
|
$query->select(Db::raw(1))->from('talk_records_delete');
|
|
|
|
|
$query->whereRaw("{$prefix}talk_records_delete.record_id = {$prefix}talk_records.id and {$prefix}talk_records_delete.user_id = {$user_id}");
|
2020-11-09 22:59:25 +08:00
|
|
|
|
$query->limit(1);
|
|
|
|
|
});
|
|
|
|
|
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$rows = $model->orderBy('talk_records.id', 'desc')->limit($limit)->get()->toArray();
|
2021-07-23 22:48:25 +08:00
|
|
|
|
|
2021-07-23 22:54:47 +08:00
|
|
|
|
if ($record_id === 0 && $talk_type == TalkModeConstant::PRIVATE_CHAT && empty($msg_type)) {
|
2021-09-12 16:23:43 +08:00
|
|
|
|
$isBoot = Robot::where('user_id', $receiver_id)->exists();
|
|
|
|
|
if (!$isBoot && !di()->get(UserFriendService::class)->isFriend($user_id, $receiver_id, true)) {
|
2021-07-23 22:54:47 +08:00
|
|
|
|
array_unshift($rows, [
|
|
|
|
|
'id' => ($rows[0]['id'] ?? 0) + 1,
|
|
|
|
|
'talk_type' => TalkModeConstant::PRIVATE_CHAT,
|
|
|
|
|
'msg_type' => TalkMessageType::SYSTEM_TEXT_MESSAGE,
|
|
|
|
|
'user_id' => 0,
|
|
|
|
|
'receiver_id' => $user_id,
|
|
|
|
|
'content' => '你与对方已解除好友关系,系统已禁止发送消息!',
|
|
|
|
|
'created_at' => date('Y-m-d H:i:s'),
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-07-23 22:48:25 +08:00
|
|
|
|
|
2021-07-23 21:34:29 +08:00
|
|
|
|
return di()->get(FormatMessageService::class)->handleChatRecords($rows);
|
2020-11-09 22:59:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取转发会话记录信息
|
|
|
|
|
*
|
2021-04-20 16:30:57 +08:00
|
|
|
|
* @param int $user_id 用户ID
|
2020-11-09 22:59:25 +08:00
|
|
|
|
* @param int $record_id 聊天记录ID
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
2021-08-14 17:31:21 +08:00
|
|
|
|
public function getForwardRecords(int $user_id, int $record_id): array
|
2020-11-09 22:59:25 +08:00
|
|
|
|
{
|
2021-07-05 21:52:44 +08:00
|
|
|
|
$result = TalkRecords::where('id', $record_id)->first([
|
|
|
|
|
'id', 'talk_type', 'msg_type', 'user_id', 'receiver_id', 'content', 'is_revoke', 'created_at'
|
2020-11-09 22:59:25 +08:00
|
|
|
|
]);
|
|
|
|
|
|
2021-04-22 16:54:01 +08:00
|
|
|
|
// 判断是否有权限查看
|
2021-07-20 23:12:18 +08:00
|
|
|
|
if ($result->talk_type == TalkModeConstant::PRIVATE_CHAT && ($result->user_id != $user_id && $result->receiver_id != $user_id)) {
|
2020-11-09 22:59:25 +08:00
|
|
|
|
return [];
|
2021-07-28 23:08:07 +08:00
|
|
|
|
} else if ($result->talk_type == TalkModeConstant::GROUP_CHAT && !di()->get(GroupMemberService::class)->isMember($result->receiver_id, $user_id)) {
|
2020-11-09 22:59:25 +08:00
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-05 21:52:44 +08:00
|
|
|
|
$forward = TalkRecordsForward::where('record_id', $record_id)->first();
|
2020-11-09 22:59:25 +08:00
|
|
|
|
|
|
|
|
|
$fields = [
|
2021-07-05 21:52:44 +08:00
|
|
|
|
'talk_records.id',
|
|
|
|
|
'talk_records.talk_type',
|
|
|
|
|
'talk_records.msg_type',
|
|
|
|
|
'talk_records.user_id',
|
|
|
|
|
'talk_records.receiver_id',
|
|
|
|
|
'talk_records.is_revoke',
|
|
|
|
|
'talk_records.content',
|
|
|
|
|
'talk_records.created_at',
|
2020-11-09 22:59:25 +08:00
|
|
|
|
'users.nickname',
|
|
|
|
|
'users.avatar as avatar',
|
|
|
|
|
];
|
|
|
|
|
|
2021-07-05 21:52:44 +08:00
|
|
|
|
$rowsSqlObj = TalkRecords::select($fields);
|
|
|
|
|
$rowsSqlObj->leftJoin('users', 'users.id', '=', 'talk_records.user_id');
|
|
|
|
|
$rowsSqlObj->whereIn('talk_records.id', explode(',', $forward->records_id));
|
2021-07-17 00:07:24 +08:00
|
|
|
|
$rows = $rowsSqlObj->get()->toArray();
|
2020-11-09 22:59:25 +08:00
|
|
|
|
|
2021-07-23 21:34:29 +08:00
|
|
|
|
return di()->get(FormatMessageService::class)->handleChatRecords($rows);
|
2020-11-09 22:59:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 批量删除聊天消息
|
|
|
|
|
*
|
2021-07-05 21:52:44 +08:00
|
|
|
|
* @param int $user_id 用户ID
|
|
|
|
|
* @param int $talk_type 对话类型[1:好友消息;2:群聊消息;]
|
|
|
|
|
* @param int $receiver_id 好友ID或者群聊ID
|
|
|
|
|
* @param array $record_ids 聊天记录ID
|
2020-11-09 22:59:25 +08:00
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2021-08-14 17:31:21 +08:00
|
|
|
|
public function removeRecords(int $user_id, int $talk_type, int $receiver_id, array $record_ids): bool
|
2020-11-09 22:59:25 +08:00
|
|
|
|
{
|
2021-07-20 23:12:18 +08:00
|
|
|
|
if ($talk_type == TalkModeConstant::PRIVATE_CHAT) {// 私聊信息
|
2021-07-05 21:52:44 +08:00
|
|
|
|
$ids = TalkRecords::whereIn('id', $record_ids)->where(function ($query) use ($user_id, $receiver_id) {
|
|
|
|
|
$query->where([['user_id', '=', $user_id], ['receiver_id', '=', $receiver_id]])
|
|
|
|
|
->orWhere([['user_id', '=', $receiver_id], ['receiver_id', '=', $user_id]]);
|
|
|
|
|
})->where('talk_type', $talk_type)->pluck('id');
|
2021-04-22 16:54:01 +08:00
|
|
|
|
} else {// 群聊信息
|
2021-11-07 22:40:52 +08:00
|
|
|
|
// 判读是否属于群消息并且判断是否是群成员
|
|
|
|
|
if ($talk_type == TalkModeConstant::GROUP_CHAT && !di()->get(GroupMemberService::class)->isMember($receiver_id, $user_id)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-20 23:12:18 +08:00
|
|
|
|
$ids = TalkRecords::whereIn('id', $record_ids)->where('talk_type', TalkModeConstant::GROUP_CHAT)->pluck('id');
|
2020-11-09 22:59:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 判断要删除的消息在数据库中是否存在
|
|
|
|
|
if (count($ids) != count($record_ids)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$data = array_map(function ($record_id) use ($user_id) {
|
|
|
|
|
return [
|
2021-04-20 16:30:57 +08:00
|
|
|
|
'record_id' => $record_id,
|
|
|
|
|
'user_id' => $user_id,
|
2020-11-09 22:59:25 +08:00
|
|
|
|
'created_at' => date('Y-m-d H:i:s'),
|
|
|
|
|
];
|
|
|
|
|
}, $ids->toArray());
|
|
|
|
|
|
2021-07-05 21:52:44 +08:00
|
|
|
|
return Db::table('talk_records_delete')->insert($data);
|
2020-11-09 22:59:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 撤回单条聊天消息
|
|
|
|
|
*
|
2021-04-20 16:30:57 +08:00
|
|
|
|
* @param int $user_id 用户ID
|
2020-11-09 22:59:25 +08:00
|
|
|
|
* @param int $record_id 聊天记录ID
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
2021-08-14 17:31:21 +08:00
|
|
|
|
public function revokeRecord(int $user_id, int $record_id): array
|
2020-11-09 22:59:25 +08:00
|
|
|
|
{
|
2021-07-05 21:52:44 +08:00
|
|
|
|
$result = TalkRecords::where('id', $record_id)->first(['id', 'talk_type', 'user_id', 'receiver_id', 'created_at']);
|
2020-11-09 22:59:25 +08:00
|
|
|
|
if (!$result) return [false, '消息记录不存在'];
|
|
|
|
|
|
2021-04-22 16:54:01 +08:00
|
|
|
|
// 判断是否在两分钟之内撤回消息,超过2分钟不能撤回消息
|
2020-11-09 22:59:25 +08:00
|
|
|
|
if ((time() - strtotime($result->created_at) > 120)) {
|
|
|
|
|
return [false, '已超过有效的撤回时间', []];
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-20 23:12:18 +08:00
|
|
|
|
if ($result->talk_type == TalkModeConstant::PRIVATE_CHAT) {
|
2021-07-05 21:52:44 +08:00
|
|
|
|
if ($result->user_id != $user_id && $result->receiver_id != $user_id) {
|
2020-11-09 22:59:25 +08:00
|
|
|
|
return [false, '非法操作', []];
|
|
|
|
|
}
|
2021-07-20 23:12:18 +08:00
|
|
|
|
} else if ($result->talk_type == TalkModeConstant::GROUP_CHAT) {
|
2021-07-28 23:08:07 +08:00
|
|
|
|
if (!di()->get(GroupMemberService::class)->isMember($result->receiver_id, $user_id)) {
|
2020-11-09 22:59:25 +08:00
|
|
|
|
return [false, '非法操作', []];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$result->is_revoke = 1;
|
|
|
|
|
$result->save();
|
|
|
|
|
|
2022-04-12 19:34:20 +08:00
|
|
|
|
event()->dispatch(new TalkEvent(TalkEventConstant::EVENT_TALK_REVOKE, [
|
2021-07-17 00:07:24 +08:00
|
|
|
|
'record_id' => $result->id
|
|
|
|
|
]));
|
|
|
|
|
|
2020-11-09 22:59:25 +08:00
|
|
|
|
return [true, '消息已撤回', $result->toArray()];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 关键词搜索聊天记录
|
|
|
|
|
*
|
2021-07-05 21:52:44 +08:00
|
|
|
|
* @param int $user_id 用户ID
|
|
|
|
|
* @param int $receiver_id 接收者ID
|
|
|
|
|
* @param int $talk_type 对话类型[1:私信;2:群聊;]
|
|
|
|
|
* @param int $page 当前查询分页
|
|
|
|
|
* @param int $page_size 分页大小
|
|
|
|
|
* @param array $params 查询参数
|
2021-04-22 16:14:34 +08:00
|
|
|
|
* @return array
|
2020-11-09 22:59:25 +08:00
|
|
|
|
*/
|
2021-08-14 17:31:21 +08:00
|
|
|
|
public function searchRecords(int $user_id, int $receiver_id, int $talk_type, int $page, int $page_size, array $params): array
|
2020-11-09 22:59:25 +08:00
|
|
|
|
{
|
|
|
|
|
$fields = [
|
2021-07-05 21:52:44 +08:00
|
|
|
|
'talk_records.id',
|
|
|
|
|
'talk_records.talk_type',
|
|
|
|
|
'talk_records.msg_type',
|
|
|
|
|
'talk_records.user_id',
|
|
|
|
|
'talk_records.receiver_id',
|
|
|
|
|
'talk_records.content',
|
|
|
|
|
'talk_records.is_revoke',
|
|
|
|
|
'talk_records.created_at',
|
2020-11-09 22:59:25 +08:00
|
|
|
|
'users.nickname',
|
|
|
|
|
'users.avatar as avatar',
|
|
|
|
|
];
|
|
|
|
|
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$model = TalkRecords::select($fields)->leftJoin('users', 'users.id', '=', 'talk_records.user_id');
|
2021-07-05 21:52:44 +08:00
|
|
|
|
if ($talk_type == 1) {
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$model->where(function ($query) use ($user_id, $receiver_id) {
|
2020-11-09 22:59:25 +08:00
|
|
|
|
$query->where([
|
2021-07-05 21:52:44 +08:00
|
|
|
|
['talk_records.user_id', '=', $user_id],
|
|
|
|
|
['talk_records.receiver_id', '=', $receiver_id]
|
2020-11-09 22:59:25 +08:00
|
|
|
|
])->orWhere([
|
2021-07-05 21:52:44 +08:00
|
|
|
|
['talk_records.user_id', '=', $receiver_id],
|
|
|
|
|
['talk_records.receiver_id', '=', $user_id]
|
2020-11-09 22:59:25 +08:00
|
|
|
|
]);
|
|
|
|
|
});
|
|
|
|
|
} else {
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$model->where('talk_records.receiver_id', $receiver_id);
|
2020-11-09 22:59:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$model->where('talk_records.talk_type', $talk_type);
|
2021-08-14 17:31:21 +08:00
|
|
|
|
|
2021-09-05 21:13:48 +08:00
|
|
|
|
if (isset($params['keywords']) && !empty($params['keywords'])) {
|
|
|
|
|
$model->where('talk_records.content', 'like', "%{$params['keywords']}%");
|
2020-11-09 22:59:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isset($params['date'])) {
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$model->whereDate('talk_records.created_at', $params['date']);
|
2020-11-09 22:59:25 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$count = $model->count();
|
2020-11-09 22:59:25 +08:00
|
|
|
|
if ($count == 0) {
|
|
|
|
|
return $this->getPagingRows([], 0, $page, $page_size);
|
|
|
|
|
}
|
2020-11-04 11:57:16 +08:00
|
|
|
|
|
2021-09-05 21:13:48 +08:00
|
|
|
|
$rows = $model->orderBy('talk_records.id', 'desc')->forPage($page, $page_size)->get()->toArray();
|
|
|
|
|
|
2021-07-23 21:34:29 +08:00
|
|
|
|
$rows = di()->get(FormatMessageService::class)->handleChatRecords($rows);
|
2021-07-17 00:07:24 +08:00
|
|
|
|
|
|
|
|
|
return $this->getPagingRows($rows, $count, $page, $page_size);
|
2020-11-09 22:59:25 +08:00
|
|
|
|
}
|
2020-11-04 11:57:16 +08:00
|
|
|
|
}
|