From eca066cbd0abfdbb5513e6e6dc93a5e63d1aa510 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Wed, 8 Jun 2022 07:58:03 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=B6=88=E6=81=AF?= =?UTF-8?q?=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 | 21 ++++--- app/Models/WebSocketDialog.php | 7 ++- .../js/pages/manage/components/DialogView.vue | 13 +--- resources/assets/js/store/actions.js | 63 ++++++++++++------- resources/assets/js/store/state.js | 1 - 5 files changed, 57 insertions(+), 48 deletions(-) diff --git a/app/Http/Controllers/Api/DialogController.php b/app/Http/Controllers/Api/DialogController.php index 735c4db0c..cf3cf9979 100755 --- a/app/Http/Controllers/Api/DialogController.php +++ b/app/Http/Controllers/Api/DialogController.php @@ -85,11 +85,10 @@ class DialogController extends AbstractController ->where('web_socket_dialogs.id', $dialog_id) ->where('u.userid', $user->userid) ->first(); - if ($item) { - $item = $item->formatData($user->userid); + if (empty($item)) { + return Base::retError('会话不存在或已被删除', ['dialog_id' => $dialog_id], -4003); } - // - return Base::retSuccess('success', $item); + return Base::retSuccess('success', $item->formatData($user->userid)); } /** @@ -138,7 +137,7 @@ class DialogController extends AbstractController } /** - * @api {get} api/dialog/msg/user 04. 打开会话 + * @api {get} api/dialog/open/user 04. 打开会话 * * @apiDescription 需要token身份 * @apiVersion 1.0.0 @@ -165,9 +164,6 @@ class DialogController extends AbstractController return Base::retError('打开会话失败'); } $data = WebSocketDialog::find($dialog->id)?->formatData($user->userid); - if (empty($data)) { - return Base::retError('打开会话错误'); - } return Base::retSuccess('success', $data); } @@ -237,6 +233,11 @@ class DialogController extends AbstractController * @apiSuccess {Number} ret 返回状态码(1正确、0错误) * @apiSuccess {String} msg 返回信息(错误描述) * @apiSuccess {Object} data 返回数据 + * @apiSuccessExample {json} data: + { + "unread": 43, // 未读消息数 + "last_umid": 308 // 最新的一条未读消息ID,用于判断是否更新前端的未读数量 + } */ public function msg__unread() { @@ -246,9 +247,9 @@ class DialogController extends AbstractController if ($dialog_id > 0) { $builder->whereDialogId($dialog_id); } - $unread = $builder->count(); return Base::retSuccess('success', [ - 'unread' => $unread, + 'unread' => $builder->count(), + 'last_umid' => intval($builder->orderByDesc('msg_id')->value('msg_id')), ]); } diff --git a/app/Models/WebSocketDialog.php b/app/Models/WebSocketDialog.php index 25c0e1ac6..1dff5fc5c 100644 --- a/app/Models/WebSocketDialog.php +++ b/app/Models/WebSocketDialog.php @@ -64,7 +64,12 @@ class WebSocketDialog extends AbstractModel // 未读信息 $unreadBuilder = WebSocketDialogMsgRead::whereDialogId($this->id)->whereUserid($userid)->whereReadAt(null); $this->unread = $unreadBuilder->count(); - $this->mention = $unreadBuilder->whereMention(1)->count(); + $this->mention = 0; + $this->last_umid = 0; + if ($this->unread > 0) { + $this->mention = $unreadBuilder->clone()->whereMention(1)->count(); + $this->last_umid = intval($unreadBuilder->clone()->orderByDesc('msg_id')->value('msg_id')); + } $this->mark_unread = $this->mark_unread ?? WebSocketDialogUser::whereDialogId($this->id)->whereUserid($userid)->value('mark_unread'); // 对话人数 $builder = WebSocketDialogUser::whereDialogId($this->id); diff --git a/resources/assets/js/pages/manage/components/DialogView.vue b/resources/assets/js/pages/manage/components/DialogView.vue index 98900f33c..3f1c401c3 100644 --- a/resources/assets/js/pages/manage/components/DialogView.vue +++ b/resources/assets/js/pages/manage/components/DialogView.vue @@ -165,10 +165,6 @@ export default { } }, - activated() { - this.msgRead() - }, - beforeDestroy() { Store.set('audioSubscribe', this.msgData.id); }, @@ -266,14 +262,7 @@ export default { return; } this.msgData._r = true; - // - setTimeout(() => { - if (!this.$el.offsetParent) { - this.msgData._r = false; - return - } - this.$store.dispatch("dialogMsgRead", this.msgData); - }, 50) + this.$store.dispatch("dialogMsgRead", this.msgData); }, openReadPercentage() { diff --git a/resources/assets/js/store/actions.js b/resources/assets/js/store/actions.js index 34943e058..4e03c2d20 100644 --- a/resources/assets/js/store/actions.js +++ b/resources/assets/js/store/actions.js @@ -1905,9 +1905,15 @@ export default { dispatch("saveDialog", dialog) }); } else if ($A.isJson(data)) { - let index = state.cacheDialogs.findIndex(({id}) => id == data.id); + const index = state.cacheDialogs.findIndex(({id}) => id == data.id); if (index > -1) { - state.cacheDialogs.splice(index, 1, Object.assign({}, state.cacheDialogs[index], data)); + const original = state.cacheDialogs[index]; + if (typeof data.unread === "number" && data.unread > original.unread && data.last_umid <= original.last_umid) { + // 增加未读数时:新数据的最后一条未读消息id <= 原数据,则不更新未读数 + data.unread = original.unread; + data.mention = original.mention; + } + state.cacheDialogs.splice(index, 1, Object.assign({}, original, data)); } else { state.cacheDialogs.push(data); } @@ -1931,8 +1937,8 @@ export default { dispatch("updateDialogLastMsg", msg) }); } else if ($A.isJson(data)) { - let dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id); - if (dialog) { + const index = state.cacheDialogs.findIndex(({id}) => id == data.dialog_id); + if (index > -1) { dispatch("saveDialog", { id: data.dialog_id, last_msg: data, @@ -2190,7 +2196,6 @@ export default { dialog.loading = false; dialog.currentPage = result.data.current_page; dialog.hasMorePages = !!result.data.next_page_url; - dispatch("saveDialog", dialog); // const ids = result.data.data.map(({id}) => id) state.dialogMsgs = state.dialogMsgs.filter((item) => item.dialog_id != dialog_id || ids.includes(item.id)); @@ -2261,14 +2266,17 @@ export default { if (data.read_at) return; data.read_at = $A.formatDate(); // - let dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id); + const dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id); if (dialog && dialog.unread > 0) { - dialog.mark_unread = 0 - dialog.unread-- - if (data.mention) { - dialog.mention-- + const newData = { + id: data.dialog_id, + mark_unread: 0, } - dispatch("saveDialog", dialog) + newData.unread = dialog.unread - 1; + if (data.mention) { + newData.mention = dialog.mention - 1; + } + dispatch("saveDialog", newData) } // state.wsReadWaitList.push(data.id); @@ -2375,22 +2383,26 @@ export default { // 删除消息 dispatch("forgetDialogMsg", data.id) // - let dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id); + const dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id); if (dialog) { // 更新最后消息 - dialog.last_at = data.last_msg && data.last_msg.created_at; - dialog.last_msg = data.last_msg; + const newData = { + id: data.dialog_id, + last_at: data.last_msg && data.last_msg.created_at, + last_msg: data.last_msg, + } if (data.update_read) { // 更新未读数量 dispatch("call", { url: 'dialog/msg/unread', dialog_id: data.dialog_id }).then(result => { - dialog.unread = result.data.unread - dispatch("saveDialog", dialog) + newData.unread = result.data.unread + newData.last_umid = result.data.last_umid + dispatch("saveDialog", newData) }).catch(() => {}); } else { - dispatch("saveDialog", dialog) + dispatch("saveDialog", newData) } } break; @@ -2404,14 +2416,17 @@ export default { } if (data.userid !== state.userId) { // 更新对话新增未读数 - let dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id); - if (dialog && state.cacheUnreads[data.id] === undefined) { - state.cacheUnreads[data.id] = true; - dialog.unread++; - if (data.mention) { - dialog.mention++; + const dialog = state.cacheDialogs.find(({id}) => id == data.dialog_id); + if (dialog) { + const newData = { + id: data.dialog_id, + last_umid: data.id, } - dispatch("saveDialog", dialog) + newData.unread = dialog.unread + 1; + if (data.mention) { + newData.mention = dialog.mention + 1; + } + dispatch("saveDialog", newData) } } Store.set('dialogMsgPush', data); diff --git a/resources/assets/js/store/state.js b/resources/assets/js/store/state.js index 5ef1a883c..d51661260 100644 --- a/resources/assets/js/store/state.js +++ b/resources/assets/js/store/state.js @@ -29,7 +29,6 @@ const stateData = { // Dialog cacheDialogs: $A.getStorageArray("cacheDialogs").map(item => Object.assign(item, {loading: false})), - cacheUnreads: {}, // Project cacheProjects: $A.getStorageArray("cacheProjects"),