优化代码
parent
2750469159
commit
1dcb385280
|
@ -4,8 +4,10 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Command;
|
namespace App\Command;
|
||||||
|
|
||||||
|
use App\Model\Talk\TalkRecordsVote;
|
||||||
use Hyperf\Command\Command as HyperfCommand;
|
use Hyperf\Command\Command as HyperfCommand;
|
||||||
use Hyperf\Command\Annotation\Command;
|
use Hyperf\Command\Annotation\Command;
|
||||||
|
use Hyperf\DbConnection\Db;
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,6 +35,6 @@ class TestCommand extends HyperfCommand
|
||||||
|
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
echo chr(65);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,16 +185,20 @@ class TalkMessageController extends CController
|
||||||
'receiver_id' => 'required|integer|min:1',
|
'receiver_id' => 'required|integer|min:1',
|
||||||
'mode' => 'required|integer|in:0,1',
|
'mode' => 'required|integer|in:0,1',
|
||||||
'title' => 'required',
|
'title' => 'required',
|
||||||
'options' => 'required|array',
|
'options' => 'required|array|max:6',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$user_id = $this->uid();
|
$user_id = $this->uid();
|
||||||
|
if (!UserRelation::isFriendOrGroupMember($user_id, $params['receiver_id'], TalkMode::GROUP_CHAT)) {
|
||||||
|
return $this->response->fail('暂不属于好友关系或群聊成员,无法发送聊天消息!');
|
||||||
|
}
|
||||||
|
|
||||||
$this->talkMessageService->insertVoteMessage([
|
$isTrue = $this->talkMessageService->insertVoteMessage([
|
||||||
'talk_type' => TalkMode::GROUP_CHAT,
|
'talk_type' => TalkMode::GROUP_CHAT,
|
||||||
'user_id' => $user_id,
|
'user_id' => $user_id,
|
||||||
'receiver_id' => $params['receiver_id'],
|
'receiver_id' => $params['receiver_id'],
|
||||||
], [
|
], [
|
||||||
|
'user_id' => $user_id,
|
||||||
'mode' => $params['mode'],
|
'mode' => $params['mode'],
|
||||||
'title' => $params['title'],
|
'title' => $params['title'],
|
||||||
'options' => $params['options'],
|
'options' => $params['options'],
|
||||||
|
@ -205,6 +209,25 @@ class TalkMessageController extends CController
|
||||||
return $this->response->success();
|
return $this->response->success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 投票处理
|
||||||
|
* @RequestMapping(path="vote/handle", methods="post")
|
||||||
|
*/
|
||||||
|
public function handleVote()
|
||||||
|
{
|
||||||
|
$params = $this->request->inputs(['record_id', 'options']);
|
||||||
|
$this->validate($params, [
|
||||||
|
'record_id' => 'required|integer|min:1',
|
||||||
|
'options' => 'required|array',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$isTrue = $this->talkMessageService->handleVote($this->uid(), $params);
|
||||||
|
|
||||||
|
if (!$isTrue) return $this->response->fail('投票失败,请稍后再试!');
|
||||||
|
|
||||||
|
return $this->response->success();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送表情包消息
|
* 发送表情包消息
|
||||||
* @RequestMapping(path="emoticon", methods="post")
|
* @RequestMapping(path="emoticon", methods="post")
|
||||||
|
@ -335,10 +358,6 @@ class TalkMessageController extends CController
|
||||||
[$isTrue, $message,] = $this->talkService->revokeRecord($this->uid(), $params['record_id']);
|
[$isTrue, $message,] = $this->talkService->revokeRecord($this->uid(), $params['record_id']);
|
||||||
if (!$isTrue) return $this->response->fail($message);
|
if (!$isTrue) return $this->response->fail($message);
|
||||||
|
|
||||||
MessageProducer::publish(MessageProducer::create(TalkMessageEvent::EVENT_REVOKE_TALK, [
|
|
||||||
'record_id' => $params['record_id']
|
|
||||||
]));
|
|
||||||
|
|
||||||
return $this->response->success([], $message);
|
return $this->response->success([], $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Model\Talk;
|
||||||
|
|
||||||
|
use App\Model\BaseModel;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class TalkRecordsVoteAnswer
|
||||||
|
*
|
||||||
|
* @property int $id 自增ID
|
||||||
|
* @property int $vote_id 投票ID
|
||||||
|
* @property int $user_id 投票用户
|
||||||
|
* @property string $option 投票选项
|
||||||
|
* @property string $created_at 投票时间
|
||||||
|
* @package App\Model\Chat
|
||||||
|
*/
|
||||||
|
class TalkRecordsVoteAnswer extends BaseModel
|
||||||
|
{
|
||||||
|
protected $table = 'talk_records_vote_answer';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'vote_id',
|
||||||
|
'user_id',
|
||||||
|
'option',
|
||||||
|
'created_at',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'vote_id' => 'integer',
|
||||||
|
'user_id' => 'integer',
|
||||||
|
'created_at' => 'integer',
|
||||||
|
];
|
||||||
|
}
|
|
@ -0,0 +1,162 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Service\Message;
|
||||||
|
|
||||||
|
use App\Constants\TalkMessageType;
|
||||||
|
use App\Model\Talk\TalkRecordsCode;
|
||||||
|
use App\Model\Talk\TalkRecordsFile;
|
||||||
|
use App\Model\Talk\TalkRecordsForward;
|
||||||
|
use App\Model\Talk\TalkRecordsInvite;
|
||||||
|
use App\Model\User;
|
||||||
|
|
||||||
|
class FormatMessageService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 格式化对话的消息体
|
||||||
|
*
|
||||||
|
* @param array $data 对话的消息
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function formatTalkMessage(array $data): array
|
||||||
|
{
|
||||||
|
$message = [
|
||||||
|
"id" => 0, // 消息记录ID
|
||||||
|
"talk_type" => 1, // 消息来源[1:好友私信;2:群聊]
|
||||||
|
"msg_type" => 1, // 消息类型
|
||||||
|
"user_id" => 0, // 发送者用户ID
|
||||||
|
"receiver_id" => 0, // 接收者ID[好友ID或群ID]
|
||||||
|
|
||||||
|
// 发送消息人的信息
|
||||||
|
"nickname" => "",// 用户昵称
|
||||||
|
"avatar" => "",// 用户头像
|
||||||
|
"group_name" => "",// 群组名称
|
||||||
|
"group_avatar" => "",// 群组头像
|
||||||
|
|
||||||
|
// 不同的消息类型
|
||||||
|
"file" => [],
|
||||||
|
"code_block" => [],
|
||||||
|
"forward" => [],
|
||||||
|
"invite" => [],
|
||||||
|
"vote" => [],
|
||||||
|
|
||||||
|
// 消息创建时间
|
||||||
|
"content" => '',// 文本消息
|
||||||
|
"created_at" => "",
|
||||||
|
|
||||||
|
// 消息属性
|
||||||
|
"is_revoke" => 0, // 消息是否撤销
|
||||||
|
];
|
||||||
|
|
||||||
|
return array_merge($message, array_intersect_key($data, $message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理聊天记录信息
|
||||||
|
*
|
||||||
|
* @param array $rows 聊天记录
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function handleChatRecords(array $rows)
|
||||||
|
{
|
||||||
|
if (empty($rows)) return [];
|
||||||
|
|
||||||
|
$files = $codes = $forwards = $invites = [];
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询聊天文件信息
|
||||||
|
if ($files) {
|
||||||
|
$files = TalkRecordsFile::whereIn('record_id', $files)->get(['id', 'record_id', 'user_id', 'file_source', 'file_type', 'save_type', 'original_name', 'file_suffix', 'file_size', 'save_dir'])->keyBy('record_id')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询群聊邀请信息
|
||||||
|
if ($invites) {
|
||||||
|
$invites = TalkRecordsInvite::whereIn('record_id', $invites)->get(['record_id', 'type', 'operate_user_id', 'user_ids'])->keyBy('record_id')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询代码块消息
|
||||||
|
if ($codes) {
|
||||||
|
$codes = TalkRecordsCode::whereIn('record_id', $codes)->get(['record_id', 'code_lang', 'code'])->keyBy('record_id')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询消息转发信息
|
||||||
|
if ($forwards) {
|
||||||
|
$forwards = TalkRecordsForward::whereIn('record_id', $forwards)->get(['record_id', 'records_id', 'text'])->keyBy('record_id')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($rows as $k => $row) {
|
||||||
|
$rows[$k]['file'] = [];
|
||||||
|
$rows[$k]['code_block'] = [];
|
||||||
|
$rows[$k]['forward'] = [];
|
||||||
|
$rows[$k]['invite'] = [];
|
||||||
|
$rows[$k]['vote'] = [];
|
||||||
|
|
||||||
|
switch ($row['msg_type']) {
|
||||||
|
case TalkMessageType::FILE_MESSAGE:// 文件消息
|
||||||
|
$rows[$k]['file'] = $files[$row['id']] ?? [];
|
||||||
|
if ($rows[$k]['file']) {
|
||||||
|
$rows[$k]['file']['file_url'] = get_media_url($rows[$k]['file']['save_dir']);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TalkMessageType::FORWARD_MESSAGE:// 会话记录消息
|
||||||
|
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;
|
||||||
|
|
||||||
|
case TalkMessageType::CODE_MESSAGE:// 代码块消息
|
||||||
|
$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;
|
||||||
|
|
||||||
|
case TalkMessageType::VOTE_MESSAGE:// 投票消息
|
||||||
|
// todo 待开发
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TalkMessageType::GROUP_INVITE_MESSAGE:// 入群消息/退群消息
|
||||||
|
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) {
|
||||||
|
$rows[$k]['invite']['users'] = User::select('id', 'nickname')->whereIn('id', parse_ids($invites[$row['id']]['user_ids']))->get()->toArray();
|
||||||
|
} else {
|
||||||
|
$rows[$k]['invite']['users'] = $rows[$k]['invite']['operate_user'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows[$k] = $this->formatTalkMessage($rows[$k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rows;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,13 +4,8 @@ namespace App\Service\Message;
|
||||||
|
|
||||||
use App\Cache\SocketRoom;
|
use App\Cache\SocketRoom;
|
||||||
use App\Constants\TalkMessageEvent;
|
use App\Constants\TalkMessageEvent;
|
||||||
use App\Constants\TalkMessageType;
|
|
||||||
use App\Constants\TalkMode;
|
use App\Constants\TalkMode;
|
||||||
use App\Model\Talk\TalkRecords;
|
use App\Model\Talk\TalkRecords;
|
||||||
use App\Model\Talk\TalkRecordsCode;
|
|
||||||
use App\Model\Talk\TalkRecordsFile;
|
|
||||||
use App\Model\Talk\TalkRecordsForward;
|
|
||||||
use App\Model\Talk\TalkRecordsInvite;
|
|
||||||
use App\Model\Group\Group;
|
use App\Model\Group\Group;
|
||||||
use App\Model\User;
|
use App\Model\User;
|
||||||
use App\Model\UsersFriendApply;
|
use App\Model\UsersFriendApply;
|
||||||
|
@ -77,9 +72,8 @@ class SubscribeHandleService
|
||||||
* 对话聊天消息
|
* 对话聊天消息
|
||||||
*
|
*
|
||||||
* @param array $data 队列消息
|
* @param array $data 队列消息
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function onConsumeTalk(array $data): string
|
public function onConsumeTalk(array $data): void
|
||||||
{
|
{
|
||||||
$talk_type = $data['data']['talk_type'];
|
$talk_type = $data['data']['talk_type'];
|
||||||
$sender_id = $data['data']['sender_id'];
|
$sender_id = $data['data']['sender_id'];
|
||||||
|
@ -103,9 +97,8 @@ class SubscribeHandleService
|
||||||
}
|
}
|
||||||
|
|
||||||
// 客户端ID去重
|
// 客户端ID去重
|
||||||
if (!$fds = array_unique($fds)) {
|
if (!$fds = array_unique($fds)) return;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = TalkRecords::leftJoin('users', 'users.id', '=', 'talk_records.user_id')
|
$result = TalkRecords::leftJoin('users', 'users.id', '=', 'talk_records.user_id')
|
||||||
->where('talk_records.id', $record_id)
|
->where('talk_records.id', $record_id)
|
||||||
|
@ -122,103 +115,41 @@ class SubscribeHandleService
|
||||||
'users.avatar',
|
'users.avatar',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (!$result) return true;
|
if (!$result) return;
|
||||||
|
|
||||||
$file = $code_block = $forward = $invite = [];
|
|
||||||
|
|
||||||
switch ($result->msg_type) {
|
|
||||||
case TalkMessageType::FILE_MESSAGE:
|
|
||||||
$file = TalkRecordsFile::where('record_id', $result->id)->first([
|
|
||||||
'id', 'record_id', 'user_id', 'file_source', 'file_type',
|
|
||||||
'save_type', 'original_name', 'file_suffix', 'file_size', 'save_dir'
|
|
||||||
]);
|
|
||||||
|
|
||||||
$file = $file ? $file->toArray() : [];
|
|
||||||
$file && $file['file_url'] = get_media_url($file['save_dir']);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TalkMessageType::FORWARD_MESSAGE:
|
|
||||||
$forward = ['num' => 0, 'list' => []];
|
|
||||||
$forwardInfo = TalkRecordsForward::where('record_id', $result->id)->first(['records_id', 'text']);
|
|
||||||
if ($forwardInfo) {
|
|
||||||
$forward = [
|
|
||||||
'num' => count(parse_ids($forwardInfo->records_id)),
|
|
||||||
'list' => json_decode($forwardInfo->text, true) ?? []
|
|
||||||
];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TalkMessageType::CODE_MESSAGE:
|
|
||||||
$code_block = TalkRecordsCode::where('record_id', $result->id)->first(['record_id', 'code_lang', 'code']);
|
|
||||||
$code_block = $code_block ? $code_block->toArray() : [];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TalkMessageType::GROUP_INVITE_MESSAGE:
|
|
||||||
$notifyInfo = TalkRecordsInvite::where('record_id', $result->id)->first([
|
|
||||||
'record_id', 'type', 'operate_user_id', 'user_ids'
|
|
||||||
]);
|
|
||||||
|
|
||||||
$userInfo = User::where('id', $notifyInfo->operate_user_id)->first(['nickname', 'id']);
|
|
||||||
$invite = [
|
|
||||||
'type' => $notifyInfo->type,
|
|
||||||
'operate_user' => ['id' => $userInfo->id, 'nickname' => $userInfo->nickname],
|
|
||||||
'users' => User::whereIn('id', parse_ids($notifyInfo->user_ids))->get(['id', 'nickname'])->toArray()
|
|
||||||
];
|
|
||||||
|
|
||||||
unset($notifyInfo, $userInfo);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$message = container()->get(FormatMessageService::class)->handleChatRecords([$result->toArray()])[0];
|
||||||
$notify = [
|
$notify = [
|
||||||
'sender_id' => $sender_id,
|
'sender_id' => $sender_id,
|
||||||
'receiver_id' => $receiver_id,
|
'receiver_id' => $receiver_id,
|
||||||
'talk_type' => $talk_type,
|
'talk_type' => $talk_type,
|
||||||
'data' => $this->formatTalkMessage([
|
'data' => array_merge($message, [
|
||||||
'id' => $result->id,
|
|
||||||
'talk_type' => $result->talk_type,
|
|
||||||
'msg_type' => $result->msg_type,
|
|
||||||
"user_id" => $result->user_id,
|
|
||||||
"receiver_id" => $result->receiver_id,
|
|
||||||
'avatar' => $result->avatar,
|
|
||||||
'nickname' => $result->nickname,
|
|
||||||
'group_name' => $groupInfo ? $groupInfo->group_name : '',
|
'group_name' => $groupInfo ? $groupInfo->group_name : '',
|
||||||
'group_avatar' => $groupInfo ? $groupInfo->avatar : '',
|
'group_avatar' => $groupInfo ? $groupInfo->avatar : ''
|
||||||
"created_at" => $result->created_at,
|
|
||||||
"content" => $result->content,
|
|
||||||
"file" => $file,
|
|
||||||
"code_block" => $code_block,
|
|
||||||
'forward' => $forward,
|
|
||||||
'invite' => $invite
|
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->socketPushNotify($fds, json_encode([TalkMessageEvent::EVENT_TALK, $notify]));
|
$this->socketPushNotify($fds, json_encode([TalkMessageEvent::EVENT_TALK, $notify]));
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 键盘输入事件消息
|
* 键盘输入事件消息
|
||||||
*
|
*
|
||||||
* @param array $data 队列消息
|
* @param array $data 队列消息
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function onConsumeKeyboard(array $data): string
|
public function onConsumeKeyboard(array $data): void
|
||||||
{
|
{
|
||||||
$fds = $this->clientService->findUserFds($data['data']['receiver_id']);
|
$fds = $this->clientService->findUserFds($data['data']['receiver_id']);
|
||||||
|
|
||||||
$this->socketPushNotify($fds, json_encode([TalkMessageEvent::EVENT_KEYBOARD, $data['data']]));
|
$this->socketPushNotify($fds, json_encode([TalkMessageEvent::EVENT_KEYBOARD, $data['data']]));
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户上线或下线消息
|
* 用户上线或下线消息
|
||||||
*
|
*
|
||||||
* @param array $data 队列消息
|
* @param array $data 队列消息
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function onConsumeOnlineStatus(array $data): string
|
public function onConsumeOnlineStatus(array $data): void
|
||||||
{
|
{
|
||||||
$user_id = (int)$data['data']['user_id'];
|
$user_id = (int)$data['data']['user_id'];
|
||||||
$status = (int)$data['data']['status'];
|
$status = (int)$data['data']['status'];
|
||||||
|
@ -236,17 +167,14 @@ class SubscribeHandleService
|
||||||
'status' => $status
|
'status' => $status
|
||||||
]
|
]
|
||||||
]));
|
]));
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 撤销聊天消息
|
* 撤销聊天消息
|
||||||
*
|
*
|
||||||
* @param array $data 队列消息
|
* @param array $data 队列消息
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function onConsumeRevokeTalk(array $data): string
|
public function onConsumeRevokeTalk(array $data): void
|
||||||
{
|
{
|
||||||
$record = TalkRecords::where('id', $data['data']['record_id'])->first(['id', 'talk_type', 'user_id', 'receiver_id']);
|
$record = TalkRecords::where('id', $data['data']['record_id'])->first(['id', 'talk_type', 'user_id', 'receiver_id']);
|
||||||
|
|
||||||
|
@ -268,22 +196,19 @@ class SubscribeHandleService
|
||||||
'receiver_id' => $record->receiver_id,
|
'receiver_id' => $record->receiver_id,
|
||||||
'record_id' => $record->id,
|
'record_id' => $record->id,
|
||||||
]]));
|
]]));
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 好友申请消息
|
* 好友申请消息
|
||||||
*
|
*
|
||||||
* @param array $data 队列消息
|
* @param array $data 队列消息
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function onConsumeFriendApply(array $data): string
|
public function onConsumeFriendApply(array $data): void
|
||||||
{
|
{
|
||||||
$data = $data['data'];
|
$data = $data['data'];
|
||||||
|
|
||||||
$applyInfo = UsersFriendApply::where('id', $data['apply_id'])->first();
|
$applyInfo = UsersFriendApply::where('id', $data['apply_id'])->first();
|
||||||
if (!$applyInfo) return true;
|
if (!$applyInfo) return;
|
||||||
|
|
||||||
$fds = $this->clientService->findUserFds($data['type'] == 1 ? $applyInfo->friend_id : $applyInfo->user_id);
|
$fds = $this->clientService->findUserFds($data['type'] == 1 ? $applyInfo->friend_id : $applyInfo->user_id);
|
||||||
|
|
||||||
|
@ -312,8 +237,6 @@ class SubscribeHandleService
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->socketPushNotify(array_unique($fds), json_encode([TalkMessageEvent::EVENT_FRIEND_APPLY, $msg]));
|
$this->socketPushNotify(array_unique($fds), json_encode([TalkMessageEvent::EVENT_FRIEND_APPLY, $msg]));
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -329,42 +252,4 @@ class SubscribeHandleService
|
||||||
$server->exist(intval($fd)) && $server->push(intval($fd), $message);
|
$server->exist(intval($fd)) && $server->push(intval($fd), $message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 格式化对话的消息体
|
|
||||||
*
|
|
||||||
* @param array $data 对话的消息
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function formatTalkMessage(array $data): array
|
|
||||||
{
|
|
||||||
$message = [
|
|
||||||
"id" => 0, // 消息记录ID
|
|
||||||
"talk_type" => 1, // 消息来源[1:好友私信;2:群聊]
|
|
||||||
"msg_type" => 1, // 消息类型
|
|
||||||
"user_id" => 0, // 发送者用户ID
|
|
||||||
"receiver_id" => 0, // 接收者ID[好友ID或群ID]
|
|
||||||
|
|
||||||
// 发送消息人的信息
|
|
||||||
"nickname" => "",// 用户昵称
|
|
||||||
"avatar" => "",// 用户头像
|
|
||||||
"group_name" => "",// 群组名称
|
|
||||||
"group_avatar" => "",// 群组头像
|
|
||||||
|
|
||||||
// 不同的消息类型
|
|
||||||
"file" => [],
|
|
||||||
"code_block" => [],
|
|
||||||
"forward" => [],
|
|
||||||
"invite" => [],
|
|
||||||
|
|
||||||
// 消息创建时间
|
|
||||||
"content" => '',// 文本消息
|
|
||||||
"created_at" => "",
|
|
||||||
|
|
||||||
// 消息属性
|
|
||||||
"is_revoke" => 0, // 消息是否撤销
|
|
||||||
];
|
|
||||||
|
|
||||||
return array_merge($message, array_intersect_key($data, $message));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,12 @@ namespace App\Service;
|
||||||
use App\Cache\LastMessage;
|
use App\Cache\LastMessage;
|
||||||
use App\Constants\TalkMessageEvent;
|
use App\Constants\TalkMessageEvent;
|
||||||
use App\Constants\TalkMessageType;
|
use App\Constants\TalkMessageType;
|
||||||
|
use App\Model\Group\GroupMember;
|
||||||
use App\Model\Talk\TalkRecordsCode;
|
use App\Model\Talk\TalkRecordsCode;
|
||||||
use App\Model\Talk\TalkRecordsVote;
|
use App\Model\Talk\TalkRecordsVote;
|
||||||
|
use App\Model\Talk\TalkRecordsVoteAnswer;
|
||||||
use App\Support\MessageProducer;
|
use App\Support\MessageProducer;
|
||||||
|
use App\Support\UserRelation;
|
||||||
use Exception;
|
use Exception;
|
||||||
use App\Constants\MediaFileType;
|
use App\Constants\MediaFileType;
|
||||||
use App\Model\Talk\TalkRecords;
|
use App\Model\Talk\TalkRecords;
|
||||||
|
@ -112,11 +115,16 @@ class TalkMessageService
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 添加投票消息
|
||||||
|
*
|
||||||
* @param array $message
|
* @param array $message
|
||||||
* @param array $vote
|
* @param array $vote
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function insertVoteMessage(array $message, array $vote)
|
public function insertVoteMessage(array $message, array $vote)
|
||||||
{
|
{
|
||||||
|
$answer_num = GroupMember::where('group_id', $message['receiver_id'])->where('is_quit', 0)->count();
|
||||||
|
|
||||||
Db::beginTransaction();
|
Db::beginTransaction();
|
||||||
try {
|
try {
|
||||||
$message['msg_type'] = TalkMessageType::FILE_MESSAGE;
|
$message['msg_type'] = TalkMessageType::FILE_MESSAGE;
|
||||||
|
@ -124,11 +132,18 @@ class TalkMessageService
|
||||||
$message['updated_at'] = date('Y-m-d H:i:s');
|
$message['updated_at'] = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
$insert = TalkRecords::create($message);
|
$insert = TalkRecords::create($message);
|
||||||
if (!$insert) {
|
|
||||||
throw new Exception('插入聊天记录失败...');
|
$options = [];
|
||||||
|
foreach ($vote['options'] as $k => $option) {
|
||||||
|
$options[chr(65 + $k)] = $option;
|
||||||
}
|
}
|
||||||
|
|
||||||
$vote['record_id'] = $insert->id;
|
$vote['record_id'] = $insert->id;
|
||||||
|
$vote['user_id'] = $options;
|
||||||
|
$vote['options'] = $options;
|
||||||
|
$vote['answer_num'] = $answer_num;
|
||||||
|
$vote['created_at'] = date('Y-m-d H:i:s');
|
||||||
|
$vote['updated_at'] = $vote['created_at'];
|
||||||
if (!TalkRecordsVote::create($vote)) {
|
if (!TalkRecordsVote::create($vote)) {
|
||||||
throw new Exception('插入聊天记录(投票消息)失败...');
|
throw new Exception('插入聊天记录(投票消息)失败...');
|
||||||
}
|
}
|
||||||
|
@ -139,6 +154,7 @@ class TalkMessageService
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 推送消息通知
|
||||||
MessageProducer::publish(MessageProducer::create(TalkMessageEvent::EVENT_TALK, [
|
MessageProducer::publish(MessageProducer::create(TalkMessageEvent::EVENT_TALK, [
|
||||||
'sender_id' => $insert->user_id,
|
'sender_id' => $insert->user_id,
|
||||||
'receiver_id' => $insert->receiver_id,
|
'receiver_id' => $insert->receiver_id,
|
||||||
|
@ -153,4 +169,72 @@ class TalkMessageService
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群投票处理方法
|
||||||
|
*
|
||||||
|
* @param int $user_id
|
||||||
|
* @param array $params
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function handleVote(int $user_id, array $params): bool
|
||||||
|
{
|
||||||
|
$record = TalkRecords::join('talk_records_vote as vote', 'vote.record_id', '=', 'talk_records.id')
|
||||||
|
->where('talk_records.id', $params['record_id'])
|
||||||
|
->first([
|
||||||
|
'talk_records.id', 'talk_records.receiver_id', 'talk_records.talk_type',
|
||||||
|
'vote.id as vote_id', 'vote.answer_mode', 'vote.answer_option', 'vote.answer_num', 'vote.status as vote_status'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!$record) return false;
|
||||||
|
|
||||||
|
if ($record->msg_type != TalkMessageType::VOTE_MESSAGE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!UserRelation::isFriendOrGroupMember($user_id, $record->receiver_id, $record->talk_type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$options = explode(',', $params['options']);
|
||||||
|
if (!$options) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sort($options);
|
||||||
|
|
||||||
|
$answerOption = json_decode($record->answer_option, true);
|
||||||
|
foreach ($options as $value) {
|
||||||
|
if (!isset($answerOption[$value])) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 单选模式取第一个
|
||||||
|
if ($record->answer_mode == 1) {
|
||||||
|
$options = [$options[0]];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Db::transaction(function () use ($options, $record, $user_id) {
|
||||||
|
TalkRecordsVote::where('id', $record->vote_id)->update([
|
||||||
|
'answered_num' => Db::raw('answered_num + 1'),
|
||||||
|
'status' => Db::raw('if(answered_num >= answer_num, 1, 0)'),
|
||||||
|
'updated_at' => date('Y-m-d H:i:s'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
foreach ($options as $option) {
|
||||||
|
TalkRecordsVoteAnswer::create([
|
||||||
|
'vote_id' => $record->vote_id,
|
||||||
|
'user_id' => $user_id,
|
||||||
|
'option' => $option,
|
||||||
|
'created_at' => date('Y-m-d H:i:s'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
logger()->error($e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,17 @@
|
||||||
|
|
||||||
namespace App\Service;
|
namespace App\Service;
|
||||||
|
|
||||||
|
use App\Constants\TalkMessageEvent;
|
||||||
use App\Constants\TalkMessageType;
|
use App\Constants\TalkMessageType;
|
||||||
use App\Constants\TalkMode;
|
use App\Constants\TalkMode;
|
||||||
|
use App\Service\Message\FormatMessageService;
|
||||||
|
use App\Support\MessageProducer;
|
||||||
use Exception;
|
use Exception;
|
||||||
use App\Model\User;
|
|
||||||
use App\Model\UsersFriend;
|
|
||||||
use App\Model\Group\Group;
|
use App\Model\Group\Group;
|
||||||
use App\Model\Talk\TalkRecords;
|
use App\Model\Talk\TalkRecords;
|
||||||
use App\Model\Talk\TalkRecordsCode;
|
use App\Model\Talk\TalkRecordsCode;
|
||||||
use App\Model\Talk\TalkRecordsFile;
|
use App\Model\Talk\TalkRecordsFile;
|
||||||
use App\Model\Talk\TalkRecordsForward;
|
use App\Model\Talk\TalkRecordsForward;
|
||||||
use App\Model\Talk\TalkRecordsInvite;
|
|
||||||
use App\Traits\PagingTrait;
|
use App\Traits\PagingTrait;
|
||||||
use Hyperf\DbConnection\Db;
|
use Hyperf\DbConnection\Db;
|
||||||
|
|
||||||
|
@ -20,110 +20,6 @@ class TalkService extends BaseService
|
||||||
{
|
{
|
||||||
use PagingTrait;
|
use PagingTrait;
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理聊天记录信息
|
|
||||||
*
|
|
||||||
* @param array $rows 聊天记录
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function handleChatRecords(array $rows)
|
|
||||||
{
|
|
||||||
if (empty($rows)) return [];
|
|
||||||
|
|
||||||
$files = $codes = $forwards = $invites = [];
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询聊天文件信息
|
|
||||||
if ($files) {
|
|
||||||
$files = TalkRecordsFile::whereIn('record_id', $files)->get(['id', 'record_id', 'user_id', 'file_source', 'file_type', 'save_type', 'original_name', 'file_suffix', 'file_size', 'save_dir'])->keyBy('record_id')->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询群聊邀请信息
|
|
||||||
if ($invites) {
|
|
||||||
$invites = TalkRecordsInvite::whereIn('record_id', $invites)->get(['record_id', 'type', 'operate_user_id', 'user_ids'])->keyBy('record_id')->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询代码块消息
|
|
||||||
if ($codes) {
|
|
||||||
$codes = TalkRecordsCode::whereIn('record_id', $codes)->get(['record_id', 'code_lang', 'code'])->keyBy('record_id')->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询消息转发信息
|
|
||||||
if ($forwards) {
|
|
||||||
$forwards = TalkRecordsForward::whereIn('record_id', $forwards)->get(['record_id', 'records_id', 'text'])->keyBy('record_id')->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($rows as $k => $row) {
|
|
||||||
$rows[$k]['file'] = [];
|
|
||||||
$rows[$k]['code_block'] = [];
|
|
||||||
$rows[$k]['forward'] = [];
|
|
||||||
$rows[$k]['invite'] = [];
|
|
||||||
|
|
||||||
switch ($row['msg_type']) {
|
|
||||||
case TalkMessageType::FILE_MESSAGE:// 文件消息
|
|
||||||
$rows[$k]['file'] = $files[$row['id']] ?? [];
|
|
||||||
if ($rows[$k]['file']) {
|
|
||||||
$rows[$k]['file']['file_url'] = get_media_url($rows[$k]['file']['save_dir']);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TalkMessageType::FORWARD_MESSAGE:// 会话记录消息
|
|
||||||
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;
|
|
||||||
|
|
||||||
case TalkMessageType::CODE_MESSAGE:// 代码块消息
|
|
||||||
$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;
|
|
||||||
|
|
||||||
case TalkMessageType::GROUP_INVITE_MESSAGE:// 入群消息/退群消息
|
|
||||||
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) {
|
|
||||||
$rows[$k]['invite']['users'] = User::select('id', 'nickname')->whereIn('id', parse_ids($invites[$row['id']]['user_ids']))->get()->toArray();
|
|
||||||
} else {
|
|
||||||
$rows[$k]['invite']['users'] = $rows[$k]['invite']['operate_user'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($files, $codes, $forwards, $invites);
|
|
||||||
return $rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询对话页面的历史聊天记录
|
* 查询对话页面的历史聊天记录
|
||||||
*
|
*
|
||||||
|
@ -176,7 +72,7 @@ class TalkService extends BaseService
|
||||||
$rowsSqlObj->whereIn('talk_records.msg_type', $msg_type);
|
$rowsSqlObj->whereIn('talk_records.msg_type', $msg_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
//过滤用户删除记录
|
// 过滤用户删除记录
|
||||||
$rowsSqlObj->whereNotExists(function ($query) use ($user_id) {
|
$rowsSqlObj->whereNotExists(function ($query) use ($user_id) {
|
||||||
$prefix = config('databases.default.prefix');
|
$prefix = config('databases.default.prefix');
|
||||||
$query->select(Db::raw(1))->from('talk_records_delete');
|
$query->select(Db::raw(1))->from('talk_records_delete');
|
||||||
|
@ -184,9 +80,8 @@ class TalkService extends BaseService
|
||||||
$query->limit(1);
|
$query->limit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
return $this->handleChatRecords(
|
$rows = $rowsSqlObj->orderBy('talk_records.id', 'desc')->limit($limit)->get()->toArray();
|
||||||
$rowsSqlObj->orderBy('talk_records.id', 'desc')->limit($limit)->get()->toArray()
|
return container()->get(FormatMessageService::class)->handleChatRecords($rows);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -227,8 +122,9 @@ class TalkService extends BaseService
|
||||||
$rowsSqlObj = TalkRecords::select($fields);
|
$rowsSqlObj = TalkRecords::select($fields);
|
||||||
$rowsSqlObj->leftJoin('users', 'users.id', '=', 'talk_records.user_id');
|
$rowsSqlObj->leftJoin('users', 'users.id', '=', 'talk_records.user_id');
|
||||||
$rowsSqlObj->whereIn('talk_records.id', explode(',', $forward->records_id));
|
$rowsSqlObj->whereIn('talk_records.id', explode(',', $forward->records_id));
|
||||||
|
$rows = $rowsSqlObj->get()->toArray();
|
||||||
|
|
||||||
return $this->handleChatRecords($rowsSqlObj->get()->toArray());
|
return container()->get(FormatMessageService::class)->handleChatRecords($rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -302,6 +198,10 @@ class TalkService extends BaseService
|
||||||
$result->is_revoke = 1;
|
$result->is_revoke = 1;
|
||||||
$result->save();
|
$result->save();
|
||||||
|
|
||||||
|
MessageProducer::publish(MessageProducer::create(TalkMessageEvent::EVENT_REVOKE_TALK, [
|
||||||
|
'record_id' => $result->id
|
||||||
|
]));
|
||||||
|
|
||||||
return [true, '消息已撤回', $result->toArray()];
|
return [true, '消息已撤回', $result->toArray()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,6 +476,8 @@ class TalkService extends BaseService
|
||||||
}
|
}
|
||||||
|
|
||||||
$rows = $rowsSqlObj->orderBy('talk_records.id', 'desc')->forPage($page, $page_size)->get()->toArray();
|
$rows = $rowsSqlObj->orderBy('talk_records.id', 'desc')->forPage($page, $page_size)->get()->toArray();
|
||||||
return $this->getPagingRows($this->handleChatRecords($rows), $count, $page, $page_size);
|
$rows = container()->get(FormatMessageService::class)->handleChatRecords($rows);
|
||||||
|
|
||||||
|
return $this->getPagingRows($rows, $count, $page, $page_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue