From 48b7f4924edbdde1d6f28ed0843b36cec36c5c8c Mon Sep 17 00:00:00 2001 From: kuaifan Date: Thu, 10 Mar 2022 14:41:29 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A0=87=E8=AE=B0=E5=B7=B2=E8=AF=BB/=E6=9C=AA=E8=AF=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/DialogController.php | 52 +++++++++++++------ app/Models/WebSocketDialog.php | 5 +- app/Models/WebSocketDialogMsg.php | 4 +- app/Models/WebSocketDialogMsgRead.php | 9 ++++ resources/assets/js/functions/web.js | 9 ++++ resources/assets/js/pages/manage.vue | 3 +- .../pages/manage/components/ProjectList.vue | 2 +- .../assets/js/pages/manage/messenger.vue | 17 +++--- resources/assets/js/store/actions.js | 1 + 9 files changed, 72 insertions(+), 30 deletions(-) diff --git a/app/Http/Controllers/Api/DialogController.php b/app/Http/Controllers/Api/DialogController.php index edea8a968..8ae57b47a 100755 --- a/app/Http/Controllers/Api/DialogController.php +++ b/app/Http/Controllers/Api/DialogController.php @@ -41,7 +41,7 @@ class DialogController extends AbstractController { $user = User::auth(); // - $list = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at']) + $list = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.is_mark_unread']) ->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id') ->where('u.userid', $user->userid) ->orderByDesc('u.top_at') @@ -74,7 +74,7 @@ class DialogController extends AbstractController // $dialog_id = intval(Request::input('dialog_id')); // - $item = WebSocketDialog::select(['web_socket_dialogs.*']) + $item = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.is_mark_unread']) ->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) @@ -524,19 +524,41 @@ class DialogController extends AbstractController if (!$dialogUser) { return Base::retError("会话不存在"); } - if ($type == 'read') { - WebSocketDialogMsgRead::whereUserid($user->userid) - ->whereReadAt(null) - ->whereDialogId($dialogId) - ->update( - [ - 'read_at' => Carbon::now() - ]); - $dialogUser->is_mark_unread = 0; - $dialogUser->save(); - } elseif ($type == 'unread') { - $dialogUser->is_mark_unread = 1; - $dialogUser->save(); + switch ($type) { + case 'read': + WebSocketDialogMsgRead::whereUserid($user->userid) + ->whereReadAt(null) + ->whereDialogId($dialogId) + ->chunkById(100, function ($list) { + /** @var WebSocketDialogMsgRead $item */ + $dialogMsg = []; + foreach ($list as $item) { + $item->read_at = Carbon::now(); + $item->save(); + if (isset($dialogMsg[$item->msg_id])) { + $dialogMsg[$item->msg_id]['re']++; + } else { + $dialogMsg[$item->msg_id] = [ + 'ob' => $item->webSocketDialogMsg, + 're' => 1 + ]; + } + } + foreach ($dialogMsg as $item) { + $item['ob']?->generatePercentage($item['re']); + } + }); + $dialogUser->is_mark_unread = 0; + $dialogUser->save(); + break; + + case 'unread': + $dialogUser->is_mark_unread = 1; + $dialogUser->save(); + break; + + default: + return Base::retError("参数错误"); } return Base::retSuccess("success"); } diff --git a/app/Models/WebSocketDialog.php b/app/Models/WebSocketDialog.php index 8134dc917..f51beec2e 100644 --- a/app/Models/WebSocketDialog.php +++ b/app/Models/WebSocketDialog.php @@ -105,9 +105,8 @@ class WebSocketDialog extends AbstractModel $last_msg = WebSocketDialogMsg::whereDialogId($dialog->id)->orderByDesc('id')->first(); $dialog->last_msg = $last_msg; // 未读信息 - $unread = WebSocketDialogMsgRead::whereDialogId($dialog->id)->whereUserid($userid)->whereReadAt(null)->count(); - $isMarkUnread = WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($userid)->whereIsMarkUnread(1)->exists(); - $dialog->unread = $unread > 0 ? $unread : ($isMarkUnread ? 1 : 0); + $dialog->unread = WebSocketDialogMsgRead::whereDialogId($dialog->id)->whereUserid($userid)->whereReadAt(null)->count(); + $dialog->is_mark_unread = $dialog->is_mark_unread ?? WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($userid)->value('is_mark_unread'); // 对话人数 $builder = WebSocketDialogUser::whereDialogId($dialog->id); $dialog->people = $builder->count(); diff --git a/app/Models/WebSocketDialogMsg.php b/app/Models/WebSocketDialogMsg.php index 0353dc7f5..b62f5c67c 100644 --- a/app/Models/WebSocketDialogMsg.php +++ b/app/Models/WebSocketDialogMsg.php @@ -96,12 +96,12 @@ class WebSocketDialogMsg extends AbstractModel /** * 获取占比 - * @param bool $increment 是否新增阅读数 + * @param bool|int $increment 是否新增阅读数 * @return int */ public function generatePercentage($increment = false) { if ($increment) { - $this->increment('read'); + $this->increment('read', is_bool($increment) ? 1 : $increment); } if ($this->read > $this->send || empty($this->send)) { return $this->appendattrs['percentage'] = 100; diff --git a/app/Models/WebSocketDialogMsgRead.php b/app/Models/WebSocketDialogMsgRead.php index c2a6be17d..6618c17b3 100644 --- a/app/Models/WebSocketDialogMsgRead.php +++ b/app/Models/WebSocketDialogMsgRead.php @@ -11,6 +11,7 @@ namespace App\Models; * @property int|null $userid 发送会员ID * @property int|null $after 在阅读之后才添加的记录 * @property string|null $read_at 阅读时间 + * @property-read \App\Models\WebSocketDialogMsg|null $webSocketDialogMsg * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead newQuery() * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead query() @@ -29,4 +30,12 @@ class WebSocketDialogMsgRead extends AbstractModel parent::__construct($attributes); $this->timestamps = false; } + + /** + * @return \Illuminate\Database\Eloquent\Relations\HasOne + */ + public function webSocketDialogMsg(): \Illuminate\Database\Eloquent\Relations\HasOne + { + return $this->hasOne(WebSocketDialogMsg::class, 'id', 'msg_id'); + } } diff --git a/resources/assets/js/functions/web.js b/resources/assets/js/functions/web.js index a204f7b65..cb9b98c41 100755 --- a/resources/assets/js/functions/web.js +++ b/resources/assets/js/functions/web.js @@ -376,6 +376,15 @@ } else { window.open(url) } + }, + + /** + * 返回对话未读数量 + * @param dialog + * @returns {*|number} + */ + getDialogUnread(dialog) { + return dialog ? (dialog.unread || dialog.is_mark_unread || 0) : 0 } }); diff --git a/resources/assets/js/pages/manage.vue b/resources/assets/js/pages/manage.vue index f61f9d7f4..50249b023 100644 --- a/resources/assets/js/pages/manage.vue +++ b/resources/assets/js/pages/manage.vue @@ -490,7 +490,8 @@ export default { msgAllUnread() { let num = 0; - this.cacheDialogs.some(({unread}) => { + this.cacheDialogs.some(dialog => { + let unread = $A.getDialogUnread(dialog); if (unread) { num += unread; } diff --git a/resources/assets/js/pages/manage/components/ProjectList.vue b/resources/assets/js/pages/manage/components/ProjectList.vue index df7ec2c72..60bf4a4d6 100644 --- a/resources/assets/js/pages/manage/components/ProjectList.vue +++ b/resources/assets/js/pages/manage/components/ProjectList.vue @@ -576,7 +576,7 @@ export default { msgUnread() { const {cacheDialogs, projectData} = this; const dialog = cacheDialogs.find(({id}) => id === projectData.dialog_id); - return dialog ? dialog.unread : 0; + return dialog ? $A.getDialogUnread(dialog) : 0; }, panelTask() { diff --git a/resources/assets/js/pages/manage/messenger.vue b/resources/assets/js/pages/manage/messenger.vue index d8323633f..912fcfd14 100644 --- a/resources/assets/js/pages/manage/messenger.vue +++ b/resources/assets/js/pages/manage/messenger.vue @@ -58,7 +58,7 @@
{{formatLastMsg(dialog.last_msg)}}
- +
    @@ -85,7 +85,7 @@ {{ $L(topOperateItem.top_at ? '取消置顶' : '置顶该聊天') }} - + {{ $L('标记已读') }} @@ -213,21 +213,22 @@ export default { return function (type) { let num = 0; this.cacheDialogs.some((dialog) => { - if (dialog.unread) { + let unread = $A.getDialogUnread(dialog); + if (unread) { switch (type) { case 'project': case 'task': if (type == dialog.group_type) { - num += dialog.unread; + num += unread; } break; case 'user': if (type == dialog.type) { - num += dialog.unread; + num += unread; } break; default: - num += dialog.unread; + num += unread; break; } } @@ -286,7 +287,7 @@ export default { onActive(type) { if (this.dialogActive == type) { // 再次点击滚动到未读条目 - const dialog = this.dialogList.find(({unread}) => unread > 0) + const dialog = this.dialogList.find(dialog => $A.getDialogUnread(dialog) > 0) if (dialog) { $A.scrollToView(this.$refs[`dialog_${dialog.id}`][0], { behavior: 'smooth', @@ -322,7 +323,7 @@ export default { }, filterDialog(dialog) { - if (dialog.unread > 0 || dialog.id == this.dialogId || dialog.top_at) { + if ($A.getDialogUnread(dialog) > 0 || dialog.id == this.dialogId || dialog.top_at) { return true } if (dialog.name === undefined) { diff --git a/resources/assets/js/store/actions.js b/resources/assets/js/store/actions.js index 079d8fde3..8d49d67ab 100644 --- a/resources/assets/js/store/actions.js +++ b/resources/assets/js/store/actions.js @@ -2085,6 +2085,7 @@ export default { let dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id); if (dialog && dialog.unread > 0) { dialog.unread-- + dialog.is_mark_unread = 0 dispatch("saveDialog", dialog) } //