From 416df14b8caff12dae98de6629706fdf6c2c262e Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 17 Jul 2024 11:25:26 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E4=BC=98=E5=8C=96=E3=80=91=E5=AE=A2?= =?UTF-8?q?=E6=9C=8D=E9=87=8D=E6=9E=84=E6=B6=88=E6=81=AF=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kefu/components/KeFuMessageList.vue | 80 ++++++++++++------- src/views/mall/promotion/kefu/index.vue | 4 +- 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/views/mall/promotion/kefu/components/KeFuMessageList.vue b/src/views/mall/promotion/kefu/components/KeFuMessageList.vue index a43ab0ec..bdcab5dc 100644 --- a/src/views/mall/promotion/kefu/components/KeFuMessageList.vue +++ b/src/views/mall/promotion/kefu/components/KeFuMessageList.vue @@ -108,6 +108,7 @@ import { UserTypeEnum } from '@/utils/constants' import { formatDate } from '@/utils/formatTime' import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' +import { debounce } from 'lodash-es' dayjs.extend(relativeTime) @@ -127,17 +128,7 @@ const queryParams = reactive({ const total = ref(0) // 消息总条数 const refreshContent = ref(false) // 内容刷新,主要解决会话消息页面高度不一致导致的滚动功能精度失效 /** 获得消息列表 */ -const getMessageList = async (val: KeFuConversationRespVO, conversationChange: boolean) => { - // 会话切换,重置相关参数 - if (conversationChange) { - queryParams.pageNo = 1 - messageList.value = [] - total.value = 0 - loadHistory.value = false - refreshContent.value = false - } - conversation.value = val - queryParams.conversationId = val.id +const getMessageList = async () => { const res = await KeFuMessageApi.getKeFuMessagePage(queryParams) total.value = res.total // 情况一:加载最新消息 @@ -146,14 +137,20 @@ const getMessageList = async (val: KeFuConversationRespVO, conversationChange: b } else { // 情况二:加载历史消息 for (const item of res.list) { - if (messageList.value.some((val) => val.id === item.id)) { - continue - } - messageList.value.push(item) + pushMessage(item) } } refreshContent.value = true - await scrollToBottom() +} +/** 添加消息 */ +const pushMessage = (message: any) => { + if (message.conversationId !== conversation.value.id) { + return + } + if (messageList.value.some((val) => val.id === message.id)) { + return + } + messageList.value.push(message) } /** 按照时间倒序,获取消息列表 */ @@ -163,20 +160,40 @@ const getMessageList0 = computed(() => { }) /** 刷新消息列表 */ -const refreshMessageList = async () => { +const refreshMessageList = async (message?: any) => { if (!conversation.value) { return } - queryParams.pageNo = 1 - await getMessageList(conversation.value, false) + if (typeof message !== 'undefined') { + pushMessage(message) + } else { + queryParams.pageNo = 1 + await getMessageList() + } + if (loadHistory.value) { // 右下角显示有新消息提示 showNewMessageTip.value = true + } else { + // 滚动到最新消息处 + await handleToNewMessage() } } - -defineExpose({ getMessageList, refreshMessageList }) +const getNewMessageList = async (val: KeFuConversationRespVO) => { + // 会话切换,重置相关参数 + queryParams.pageNo = 1 + messageList.value = [] + total.value = 0 + loadHistory.value = false + refreshContent.value = false + // 设置会话相关属性 + conversation.value = val + queryParams.conversationId = val.id + // 获取消息 + await refreshMessageList() +} +defineExpose({ getNewMessageList, refreshMessageList }) const showKeFuMessageList = computed(() => !isEmpty(conversation.value)) // 是否显示聊天区域 const skipGetMessageList = computed(() => { // 已加载到最后一页的话则不触发新的消息获取 @@ -221,9 +238,7 @@ const sendMessage = async (msg: any) => { await KeFuMessageApi.sendKeFuMessage(msg) message.value = '' // 加载消息列表 - await getMessageList(conversation.value, false) - // 滚动到最新消息处 - await scrollToBottom() + await refreshMessageList() } /** 滚动到底部 */ @@ -248,17 +263,24 @@ const handleToNewMessage = async () => { await scrollToBottom() } -/** 加载历史消息 */ const loadHistory = ref(false) // 加载历史消息 -const handleScroll = async ({ scrollTop }) => { +/** 处理消息列表滚动事件(debounce 限流) */ +const handleScroll = debounce(({ scrollTop }) => { if (skipGetMessageList.value) { return } // 触顶自动加载下一页数据 if (scrollTop === 0) { - await handleOldMessage() + handleOldMessage() } -} + const wrap = scrollbarRef.value?.wrapRef + // 触底重置 + if (Math.abs(wrap!.scrollHeight - wrap!.clientHeight - wrap!.scrollTop) < 1) { + loadHistory.value = false + refreshMessageList() + } +}, 200) +/** 加载历史消息 */ const handleOldMessage = async () => { // 记录已有页面高度 const oldPageHeight = innerRef.value?.clientHeight @@ -268,7 +290,7 @@ const handleOldMessage = async () => { loadHistory.value = true // 加载消息列表 queryParams.pageNo += 1 - await getMessageList(conversation.value, false) + await getMessageList() // 等页面加载完后,获得上一页最后一条消息的位置,控制滚动到它所在位置 scrollbarRef.value!.setScrollTop(innerRef.value!.clientHeight - oldPageHeight) } diff --git a/src/views/mall/promotion/kefu/index.vue b/src/views/mall/promotion/kefu/index.vue index fae88d71..06a6f02b 100644 --- a/src/views/mall/promotion/kefu/index.vue +++ b/src/views/mall/promotion/kefu/index.vue @@ -60,7 +60,7 @@ watchEffect(() => { // 刷新会话列表 getConversationList() // 刷新消息列表 - keFuChatBoxRef.value?.refreshMessageList() + keFuChatBoxRef.value?.refreshMessageList(JSON.parse(jsonMessage.content)) return } // 2.3 消息类型:KEFU_MESSAGE_ADMIN_READ @@ -82,7 +82,7 @@ const getConversationList = () => { /** 加载指定会话的消息列表 */ const keFuChatBoxRef = ref>() const handleChange = (conversation: KeFuConversationRespVO) => { - keFuChatBoxRef.value?.getMessageList(conversation, true) + keFuChatBoxRef.value?.getNewMessageList(conversation) } /** 初始化 */