浏览代码

【优化】客服重构消息列表加载逻辑

puhui999 11 月之前
父节点
当前提交
416df14b8c
共有 2 个文件被更改,包括 53 次插入31 次删除
  1. 51 29
      src/views/mall/promotion/kefu/components/KeFuMessageList.vue
  2. 2 2
      src/views/mall/promotion/kefu/index.vue

+ 51 - 29
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)
 }

+ 2 - 2
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<InstanceType<typeof KeFuMessageList>>()
 const handleChange = (conversation: KeFuConversationRespVO) => {
-  keFuChatBoxRef.value?.getMessageList(conversation, true)
+  keFuChatBoxRef.value?.getNewMessageList(conversation)
 }
 
 /** 初始化 */