From 006fc434986eccb755a4e153556851ddcee72046 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Sun, 17 Mar 2024 15:18:51 +0900 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/DialogController.php | 10 ++-- app/Models/WebSocketDialog.php | 33 ++++-------- app/Models/WebSocketDialogMsg.php | 14 +++--- app/Models/WebSocketDialogUser.php | 17 +++++++ app/Observers/WebSocketDialogUserObserver.php | 13 +++++ app/Tasks/BotReceiveMsgTask.php | 4 +- ...04_add_web_socket_dialog_users_last_at.php | 50 +++++++++++++++++++ ...4_03_17_160641_add_index_some_20240317.php | 31 ++++++++++++ 8 files changed, 134 insertions(+), 38 deletions(-) create mode 100644 database/migrations/2024_03_17_142904_add_web_socket_dialog_users_last_at.php create mode 100644 database/migrations/2024_03_17_160641_add_index_some_20240317.php diff --git a/app/Http/Controllers/Api/DialogController.php b/app/Http/Controllers/Api/DialogController.php index ed5011423..6735e1aa3 100755 --- a/app/Http/Controllers/Api/DialogController.php +++ b/app/Http/Controllers/Api/DialogController.php @@ -108,12 +108,12 @@ class DialogController extends AbstractController return Base::retError('请输入搜索关键词'); } // 搜索会话 - $dialogs = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at']) + $dialogs = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.last_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at']) ->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id') ->where('web_socket_dialogs.name', 'LIKE', "%{$key}%") ->where('u.userid', $user->userid) ->orderByDesc('u.top_at') - ->orderByDesc('web_socket_dialogs.last_at') + ->orderByDesc('u.last_at') ->take(20) ->get(); $dialogs->transform(function (WebSocketDialog $item) use ($user) { @@ -145,7 +145,7 @@ class DialogController extends AbstractController } // 搜索消息会话 if (count($list) < 20) { - $msgs = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at', 'm.id as search_msg_id']) + $msgs = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.last_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at', 'm.id as search_msg_id']) ->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id') ->join('web_socket_dialog_msgs as m', 'web_socket_dialogs.id', '=', 'm.dialog_id') ->where('u.userid', $user->userid) @@ -178,7 +178,7 @@ class DialogController extends AbstractController { $user = User::auth(); // 搜索会话 - $msgs = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at', 'm.id as search_msg_id']) + $msgs = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.last_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at', 'm.id as search_msg_id']) ->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id') ->join('web_socket_dialog_msgs as m', 'web_socket_dialogs.id', '=', 'm.dialog_id') ->where('u.userid', $user->userid) @@ -213,7 +213,7 @@ class DialogController extends AbstractController // $dialog_id = intval(Request::input('dialog_id')); // - $item = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at']) + $item = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.last_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at']) ->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id') ->where('web_socket_dialogs.id', $dialog_id) ->where('u.userid', $user->userid) diff --git a/app/Models/WebSocketDialog.php b/app/Models/WebSocketDialog.php index 58996344c..68a18fd0a 100644 --- a/app/Models/WebSocketDialog.php +++ b/app/Models/WebSocketDialog.php @@ -20,9 +20,9 @@ use Illuminate\Support\Facades\DB; * @property string|null $group_type 聊天室类型 * @property string|null $name 对话名称 * @property string $avatar 头像(群) - * @property string|null $last_at 最后消息时间 * @property int|null $owner_id 群主用户ID * @property int|null $link_id 关联id + * @property int|null $top_userid 置顶的用户ID * @property int|null $top_msg_id 置顶的消息ID * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at @@ -38,11 +38,11 @@ use Illuminate\Support\Facades\DB; * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereDeletedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereGroupType($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereId($value) - * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereLastAt($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereLinkId($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereName($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereOwnerId($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereTopMsgId($value) + * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereTopUserid($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereType($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog withTrashed() @@ -81,7 +81,7 @@ class WebSocketDialog extends AbstractModel */ public static function getDialogList($userid, $updated = "", $deleted = "") { - $builder = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at']) + $builder = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.last_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at']) ->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id') ->where('u.userid', $userid); if ($updated) { @@ -89,7 +89,7 @@ class WebSocketDialog extends AbstractModel } $list = $builder ->orderByDesc('u.top_at') - ->orderByDesc('web_socket_dialogs.last_at') + ->orderByDesc('u.last_at') ->paginate(Base::getPaginate(100, 50)); $list->transform(function (WebSocketDialog $item) use ($userid) { return $item->formatData($userid); @@ -112,15 +112,15 @@ class WebSocketDialog extends AbstractModel public static function getDialogUnread($userid, $beforeAt, $take = 20) { DB::statement("SET SQL_MODE=''"); - $list = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at']) + $list = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.last_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at']) ->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id') ->join('web_socket_dialog_msg_reads as r', 'web_socket_dialogs.id', '=', 'r.dialog_id') ->where('u.userid', $userid) ->where('r.userid', $userid) ->where('r.silence', 0) ->where('r.read_at') - ->where('web_socket_dialogs.last_at', '>', $beforeAt) - ->groupBy('web_socket_dialogs.id') + ->where('u.last_at', '>', $beforeAt) + ->groupBy('u.dialog_id') ->take(min(100, $take)) ->get(); $list->transform(function (WebSocketDialog $item) use ($userid) { @@ -149,6 +149,7 @@ class WebSocketDialog extends AbstractModel $time = Carbon::parse($this->user_at ?? $dialogUserFun('updated_at')); $this->hide = $this->hide ?? $dialogUserFun('hide'); $this->top_at = $this->top_at ?? $dialogUserFun('top_at'); + $this->last_at = $this->last_at ?? $dialogUserFun('last_at'); $this->user_at = $time->toDateTimeString('millisecond'); $this->user_ms = $time->valueOf(); // @@ -552,20 +553,6 @@ class WebSocketDialog extends AbstractModel Task::deliver($task); } - /** - * 更新对话最后消息时间 - * @return WebSocketDialogMsg|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|object|null - */ - public function updateMsgLastAt() - { - $lastMsg = WebSocketDialogMsg::whereDialogId($this->id)->orderByDesc('id')->first(); - if ($lastMsg) { - $this->last_at = $lastMsg->created_at; - $this->save(); - } - return $lastMsg; - } - /** * 获取对话(同时检验对话身份) * @param $dialog_id @@ -622,7 +609,6 @@ class WebSocketDialog extends AbstractModel 'name' => $name ?: '', 'group_type' => $group_type, 'owner_id' => $owner_id, - 'last_at' => in_array($group_type, ['user', 'department', 'all']) ? Carbon::now() : null, ]); $dialog->save(); foreach (is_array($userid) ? $userid : [$userid] as $value) { @@ -630,7 +616,8 @@ class WebSocketDialog extends AbstractModel WebSocketDialogUser::createInstance([ 'dialog_id' => $dialog->id, 'userid' => $value, - 'important' => !in_array($group_type, ['user', 'all']) + 'important' => !in_array($group_type, ['user', 'all']), + 'last_at' => in_array($group_type, ['user', 'department', 'all']) ? Carbon::now() : null, ])->save(); } } diff --git a/app/Models/WebSocketDialogMsg.php b/app/Models/WebSocketDialogMsg.php index 85795cfe7..82f8c614f 100644 --- a/app/Models/WebSocketDialogMsg.php +++ b/app/Models/WebSocketDialogMsg.php @@ -458,9 +458,8 @@ class WebSocketDialogMsg extends AbstractModel WebSocketDialogMsgTodo::whereIn('msg_id', $ids)->delete(); self::whereIn('id', $ids)->delete(); // - $dialogDatas = WebSocketDialog::whereIn('id', $dialogIds)->get(); - foreach ($dialogDatas as $dialogData) { - $dialogData->updateMsgLastAt(); + foreach ($dialogIds as $dialogId) { + WebSocketDialogUser::updateMsgLastAt($dialogId); } foreach ($replyIds as $id) { self::whereId($id)->update(['reply_num' => self::whereReplyId($id)->count()]); @@ -501,7 +500,7 @@ class WebSocketDialogMsg extends AbstractModel 'data' => [ 'id' => $this->id, 'dialog_id' => $this->dialog_id, - 'last_msg' => $dialogData->updateMsgLastAt(), + 'last_msg' => WebSocketDialogUser::updateMsgLastAt($this->dialog_id), 'update_read' => $deleteRead ? 1 : 0 ], ] @@ -923,15 +922,14 @@ class WebSocketDialogMsg extends AbstractModel 'forward_id' => $forward_id, 'forward_show' => $forward_id ? $match[1] : 1, ]); - AbstractModel::transaction(function () use ($dialog, $dialogMsg) { - $dialog->last_at = Carbon::now(); - $dialog->save(); + AbstractModel::transaction(function () use ($dialogMsg) { $dialogMsg->send = 1; $dialogMsg->key = $dialogMsg->generateMsgKey(); $dialogMsg->save(); // - WebSocketDialogUser::whereDialogId($dialog->id)->change([ + WebSocketDialogUser::whereDialogId($dialogMsg->dialog_id)->change([ 'hide' => 0, // 有新消息时,显示会话(会话内所有会员) + 'last_at' => Carbon::now(), 'updated_at' => Carbon::now()->toDateTimeString('millisecond'), ]); }); diff --git a/app/Models/WebSocketDialogUser.php b/app/Models/WebSocketDialogUser.php index 888011d20..af5d976d2 100644 --- a/app/Models/WebSocketDialogUser.php +++ b/app/Models/WebSocketDialogUser.php @@ -11,8 +11,10 @@ use Carbon\Carbon; * @property int|null $dialog_id 对话ID * @property int|null $userid 会员ID * @property string|null $top_at 置顶时间 + * @property string|null $last_at 最后消息时间 * @property int|null $mark_unread 是否标记为未读:0否,1是 * @property int|null $silence 是否免打扰:0否,1是 + * @property int|null $hide 不显示会话:0否,1是 * @property int|null $inviter 邀请人 * @property int|null $important 是否不可移出(项目、任务人员) * @property string|null $color 颜色 @@ -25,9 +27,11 @@ use Carbon\Carbon; * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereColor($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereCreatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereDialogId($value) + * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereHide($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereId($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereImportant($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereInviter($value) + * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereLastAt($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereMarkUnread($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereSilence($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereTopAt($value) @@ -46,4 +50,17 @@ class WebSocketDialogUser extends AbstractModel { return $this->hasOne(WebSocketDialog::class, 'id', 'dialog_id'); } + + /** + * 更新对话最后消息时间 + * @return WebSocketDialogMsg|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|object|null + */ + public static function updateMsgLastAt($dialogId) + { + $lastMsg = WebSocketDialogMsg::whereDialogId($dialogId)->orderByDesc('id')->first(); + if ($lastMsg) { + WebSocketDialogUser::whereDialogId($dialogId)->change(['last_at' => $lastMsg->created_at]); + } + return $lastMsg; + } } diff --git a/app/Observers/WebSocketDialogUserObserver.php b/app/Observers/WebSocketDialogUserObserver.php index ae9b8eade..c76391004 100644 --- a/app/Observers/WebSocketDialogUserObserver.php +++ b/app/Observers/WebSocketDialogUserObserver.php @@ -4,6 +4,7 @@ namespace App\Observers; use App\Models\Deleted; use App\Models\WebSocketDialogUser; +use Carbon\Carbon; class WebSocketDialogUserObserver { @@ -15,6 +16,18 @@ class WebSocketDialogUserObserver */ public function created(WebSocketDialogUser $webSocketDialogUser) { + if (!$webSocketDialogUser->last_at) { + if (in_array($webSocketDialogUser->webSocketDialog?->group_type, ['user', 'department', 'all'])) { + $webSocketDialogUser->last_at = Carbon::now(); + $webSocketDialogUser->save(); + } else { + $item = WebSocketDialogUser::whereDialogId($webSocketDialogUser->dialog_id)->orderByDesc('last_at')->first(); + if ($item?->last_at) { + $webSocketDialogUser->last_at = $item->last_at; + $webSocketDialogUser->save(); + } + } + } Deleted::forget('dialog', $webSocketDialogUser->dialog_id, $webSocketDialogUser->userid); } diff --git a/app/Tasks/BotReceiveMsgTask.php b/app/Tasks/BotReceiveMsgTask.php index ad4f56780..e48bc3a94 100644 --- a/app/Tasks/BotReceiveMsgTask.php +++ b/app/Tasks/BotReceiveMsgTask.php @@ -316,12 +316,12 @@ class BotReceiveMsgTask extends AbstractTask $nameKey = $isManager ? $array[2] : $array[1]; $data = $this->botManagerOne($botId, $msg->userid); if ($data) { - $list = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at']) + $list = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.last_at', 'u.mark_unread', 'u.silence', 'u.hide', 'u.color', 'u.updated_at as user_at']) ->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id') ->where('web_socket_dialogs.name', 'LIKE', "%{$nameKey}%") ->where('u.userid', $data->userid) ->orderByDesc('u.top_at') - ->orderByDesc('web_socket_dialogs.last_at') + ->orderByDesc('u.last_at') ->take(20) ->get(); if ($list->isEmpty()) { diff --git a/database/migrations/2024_03_17_142904_add_web_socket_dialog_users_last_at.php b/database/migrations/2024_03_17_142904_add_web_socket_dialog_users_last_at.php new file mode 100644 index 000000000..50a73a395 --- /dev/null +++ b/database/migrations/2024_03_17_142904_add_web_socket_dialog_users_last_at.php @@ -0,0 +1,50 @@ +timestamp('last_at')->nullable()->after('top_at')->comment('最后消息时间'); + } + }); + if ($isAdd) { + // 更新数据 + WebSocketDialog::chunk(100, function ($dialogs) { + /** @var WebSocketDialog $dialog */ + foreach ($dialogs as $dialog) { + WebSocketDialogUser::whereDialogId($dialog->id)->update(['last_at' => $dialog->last_at]); + } + }); + + // 删除表字段 + Schema::table('web_socket_dialogs', function (Blueprint $table) { + $table->dropColumn("last_at"); + }); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // 回滚数据 - 无法回滚 + } +} diff --git a/database/migrations/2024_03_17_160641_add_index_some_20240317.php b/database/migrations/2024_03_17_160641_add_index_some_20240317.php new file mode 100644 index 000000000..028b2e797 --- /dev/null +++ b/database/migrations/2024_03_17_160641_add_index_some_20240317.php @@ -0,0 +1,31 @@ +dropIndex(['userid']); + $table->index(['userid', 'dialog_id']); + }); + } + + /** + * Reverse the migrations. + * + * @return voidw + */ + public function down() + { + // 回滚数据 - 无法回滚 + } +}