hyperf-chat/app/Service/Message/FormatMessageService.php

228 lines
8.5 KiB
PHP
Raw Normal View History

2021-07-17 00:07:24 +08:00
<?php
2021-07-20 23:12:18 +08:00
declare(strict_types=1);
2021-07-17 00:07:24 +08:00
namespace App\Service\Message;
2021-07-18 23:41:25 +08:00
use App\Cache\VoteCache;
2021-07-19 23:58:14 +08:00
use App\Cache\VoteStatisticsCache;
2021-07-17 00:07:24 +08:00
use App\Constants\TalkMessageType;
use App\Model\Talk\TalkRecordsCode;
use App\Model\Talk\TalkRecordsFile;
use App\Model\Talk\TalkRecordsForward;
use App\Model\Talk\TalkRecordsInvite;
2021-09-12 16:23:43 +08:00
use App\Model\Talk\TalkRecordsLogin;
2021-07-18 23:41:25 +08:00
use App\Model\Talk\TalkRecordsVote;
2021-07-17 00:07:24 +08:00
use App\Model\User;
class FormatMessageService
{
/**
* 格式化对话的消息体
*
* @param array $data 对话的消息
* @return array
*/
private function formatTalkMessage(array $data): array
{
$message = [
2021-07-21 23:31:41 +08:00
"id" => 0, // 消息记录ID
2021-09-14 09:15:39 +08:00
"talk_type" => 1, // 消息来源[1:私信;2:群聊]
2021-07-21 23:31:41 +08:00
"msg_type" => 1, // 消息类型
"user_id" => 0, // 发送者用户ID
"receiver_id" => 0, // 接收者ID[好友ID或群ID]
2021-07-17 00:07:24 +08:00
// 发送消息人的信息
2021-07-21 23:31:41 +08:00
"nickname" => '', // 用户昵称
"avatar" => '', // 用户头像
"group_name" => '', // 群组名称
"group_avatar" => '', // 群组头像
2021-07-17 00:07:24 +08:00
// 不同的消息类型
2021-07-21 23:31:41 +08:00
"file" => [], // 文件消息
"code_block" => [], // 代码消息
"forward" => [], // 转发消息
"invite" => [], // 邀请消息
"vote" => [], // 投票消息
2021-09-12 16:23:43 +08:00
"login" => [], // 登录消息
2021-07-17 00:07:24 +08:00
// 消息创建时间
2021-07-21 23:31:41 +08:00
"content" => '', // 文本消息
"created_at" => '', // 发送时间
2021-07-17 00:07:24 +08:00
// 消息属性
2021-07-21 23:31:41 +08:00
"is_revoke" => 0, // 消息是否撤销
"is_mark" => 0, // 消息是否重要
"is_read" => 0, // 消息是否已读
2021-07-17 00:07:24 +08:00
];
return array_merge($message, array_intersect_key($data, $message));
}
/**
* 处理聊天记录信息
*
* @param array $rows 聊天记录
* @return array
*/
2021-08-14 17:31:21 +08:00
public function handleChatRecords(array $rows): array
2021-07-17 00:07:24 +08:00
{
2021-07-21 23:31:41 +08:00
if (!$rows) return [];
2021-07-17 00:07:24 +08:00
2021-09-12 16:23:43 +08:00
$files = $codes = $forwards = $invites = $votes = $logins = [];
2021-07-17 00:07:24 +08:00
foreach ($rows as $value) {
switch ($value['msg_type']) {
case TalkMessageType::FILE_MESSAGE:
$files[] = $value['id'];
break;
case TalkMessageType::GROUP_INVITE_MESSAGE:
$invites[] = $value['id'];
break;
case TalkMessageType::FORWARD_MESSAGE:
$forwards[] = $value['id'];
break;
case TalkMessageType::CODE_MESSAGE:
$codes[] = $value['id'];
break;
2021-07-17 21:27:48 +08:00
case TalkMessageType::VOTE_MESSAGE:
$votes[] = $value['id'];
break;
2021-09-12 16:23:43 +08:00
case TalkMessageType::USER_LOGIN_MESSAGE:
$logins[] = $value['id'];
break;
2021-07-17 21:27:48 +08:00
default:
2021-07-17 00:07:24 +08:00
}
}
// 查询聊天文件信息
if ($files) {
2021-09-14 09:15:39 +08:00
$files = TalkRecordsFile::whereIn('record_id', $files)->get([
2022-01-17 21:06:27 +08:00
'id', 'record_id', 'user_id', 'source', 'type', 'drive',
2022-01-22 12:48:28 +08:00
'original_name', 'suffix', 'size', 'path', 'url'
2021-09-14 09:15:39 +08:00
])->keyBy('record_id')->toArray();
2021-07-17 00:07:24 +08:00
}
// 查询群聊邀请信息
if ($invites) {
2021-09-14 09:15:39 +08:00
$invites = TalkRecordsInvite::whereIn('record_id', $invites)->get([
'record_id', 'type', 'operate_user_id', 'user_ids'
])->keyBy('record_id')->toArray();
2021-07-17 00:07:24 +08:00
}
// 查询代码块消息
if ($codes) {
2021-09-14 09:15:39 +08:00
$codes = TalkRecordsCode::whereIn('record_id', $codes)->get([
2022-01-17 21:06:27 +08:00
'record_id', 'lang', 'code'
2021-09-14 09:15:39 +08:00
])->keyBy('record_id')->toArray();
2021-07-17 00:07:24 +08:00
}
// 查询消息转发信息
if ($forwards) {
2021-09-14 09:15:39 +08:00
$forwards = TalkRecordsForward::whereIn('record_id', $forwards)->get([
'record_id', 'records_id', 'text'
])->keyBy('record_id')->toArray();
2021-07-17 00:07:24 +08:00
}
2021-07-21 23:31:41 +08:00
// 查询投票消息
2021-07-18 23:41:25 +08:00
if ($votes) {
$votes = TalkRecordsVote::whereIn('record_id', $votes)->get([
'id', 'record_id', 'title', 'answer_mode', 'status', 'answer_option', 'answer_num', 'answered_num'
])->keyBy('record_id')->toArray();
}
2021-09-12 16:23:43 +08:00
// 登录消息
if ($logins) {
$logins = TalkRecordsLogin::whereIn('record_id', $logins)->get([
'id', 'record_id', 'ip', 'platform', 'agent', 'address', 'reason', 'created_at'
])->keyBy('record_id')->toArray();
}
2021-07-17 00:07:24 +08:00
foreach ($rows as $k => $row) {
$rows[$k]['file'] = [];
$rows[$k]['code_block'] = [];
$rows[$k]['forward'] = [];
$rows[$k]['invite'] = [];
$rows[$k]['vote'] = [];
2021-09-12 16:23:43 +08:00
$rows[$k]['login'] = [];
2021-07-17 00:07:24 +08:00
switch ($row['msg_type']) {
2021-07-21 23:31:41 +08:00
// 文件消息
case TalkMessageType::FILE_MESSAGE:
2021-07-17 00:07:24 +08:00
$rows[$k]['file'] = $files[$row['id']] ?? [];
if ($rows[$k]['file']) {
2022-01-22 12:48:28 +08:00
$rows[$k]['file']['file_url'] = $rows[$k]['file']['url'];
2021-07-17 00:07:24 +08:00
}
break;
2021-07-21 23:31:41 +08:00
// 会话记录消息
case TalkMessageType::FORWARD_MESSAGE:
2021-07-17 00:07:24 +08:00
if (isset($forwards[$row['id']])) {
$rows[$k]['forward'] = [
'num' => substr_count($forwards[$row['id']]['records_id'], ',') + 1,
'list' => json_decode($forwards[$row['id']]['text'], true) ?? []
];
}
break;
2021-07-21 23:31:41 +08:00
// 代码块消息
case TalkMessageType::CODE_MESSAGE:
2021-07-17 00:07:24 +08:00
$rows[$k]['code_block'] = $codes[$row['id']] ?? [];
if ($rows[$k]['code_block']) {
$rows[$k]['code_block']['code'] = htmlspecialchars_decode($rows[$k]['code_block']['code']);
unset($rows[$k]['code_block']['record_id']);
}
break;
2021-07-21 23:31:41 +08:00
// 投票消息
case TalkMessageType::VOTE_MESSAGE:
2021-07-18 23:41:25 +08:00
$options = [];
foreach ($votes[$row['id']]['answer_option'] as $k2 => $value) {
$options[] = [
'key' => $k2,
'value' => $value
];
}
$votes[$row['id']]['answer_option'] = $options;
2021-07-19 23:58:14 +08:00
$rows[$k]['vote'] = [
'statistics' => VoteStatisticsCache::getInstance()->getOrSetVoteCache($votes[$row['id']]['id']),
2021-07-28 23:42:21 +08:00
'vote_users' => VoteCache::getInstance()->getOrSetCache($votes[$row['id']]['id']),
2021-07-19 23:58:14 +08:00
'detail' => $votes[$row['id']],
2021-07-18 23:41:25 +08:00
];
2021-07-17 00:07:24 +08:00
break;
2021-09-12 16:23:43 +08:00
// 登录消息
case TalkMessageType::USER_LOGIN_MESSAGE:
2022-01-20 21:55:44 +08:00
if (isset($logins[$row['id']])) {
$rows[$k]['login'] = $logins[$row['id']];
}
2021-09-12 16:23:43 +08:00
break;
2021-07-21 23:31:41 +08:00
// 入群消息/退群消息
case TalkMessageType::GROUP_INVITE_MESSAGE:
2021-07-17 00:07:24 +08:00
if (isset($invites[$row['id']])) {
$rows[$k]['invite'] = [
'type' => $invites[$row['id']]['type'],
'operate_user' => [
'id' => $invites[$row['id']]['operate_user_id'],
'nickname' => User::where('id', $invites[$row['id']]['operate_user_id'])->value('nickname')
],
'users' => []
];
if ($rows[$k]['invite']['type'] == 1 || $rows[$k]['invite']['type'] == 3) {
2021-09-04 20:18:20 +08:00
$rows[$k]['invite']['users'] = User::select(['id', 'nickname'])->whereIn('id', parse_ids($invites[$row['id']]['user_ids']))->get()->toArray();
2021-07-17 00:07:24 +08:00
} else {
$rows[$k]['invite']['users'] = $rows[$k]['invite']['operate_user'];
}
}
break;
}
$rows[$k] = $this->formatTalkMessage($rows[$k]);
}
return $rows;
}
}