【优化】mall 客服加载历史消息时页面保持在当前正在查看的消息位置
parent
32d6ac0183
commit
fa0892980d
|
@ -73,7 +73,7 @@ import { useEmoji } from './tools/emoji'
|
||||||
import { formatDate } from '@/utils/formatTime'
|
import { formatDate } from '@/utils/formatTime'
|
||||||
import { KeFuMessageContentTypeEnum } from './tools/constants'
|
import { KeFuMessageContentTypeEnum } from './tools/constants'
|
||||||
|
|
||||||
defineOptions({ name: 'KeFuConversationBox' })
|
defineOptions({ name: 'KeFuConversationList' })
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<el-container v-if="showChatBox" class="kefu">
|
<el-container v-if="showKeFuMessageList" class="kefu">
|
||||||
<el-header>
|
<el-header>
|
||||||
<div class="kefu-title">{{ conversation.userNickname }}</div>
|
<div class="kefu-title">{{ conversation.userNickname }}</div>
|
||||||
</el-header>
|
|
||||||
<el-main class="kefu-content overflow-visible">
|
|
||||||
<!-- 加载历史消息 -->
|
<!-- 加载历史消息 -->
|
||||||
<div
|
<div
|
||||||
v-show="loadingMore"
|
v-show="loadingMore"
|
||||||
|
@ -12,6 +10,8 @@
|
||||||
>
|
>
|
||||||
加载更多
|
加载更多
|
||||||
</div>
|
</div>
|
||||||
|
</el-header>
|
||||||
|
<el-main class="kefu-content overflow-visible">
|
||||||
<el-scrollbar ref="scrollbarRef" always height="calc(100vh - 495px)" @scroll="handleScroll">
|
<el-scrollbar ref="scrollbarRef" always height="calc(100vh - 495px)" @scroll="handleScroll">
|
||||||
<div ref="innerRef" class="w-[100%] pb-3px">
|
<div ref="innerRef" class="w-[100%] pb-3px">
|
||||||
<!-- 消息列表 -->
|
<!-- 消息列表 -->
|
||||||
|
@ -119,7 +119,7 @@ import relativeTime from 'dayjs/plugin/relativeTime'
|
||||||
|
|
||||||
dayjs.extend(relativeTime)
|
dayjs.extend(relativeTime)
|
||||||
|
|
||||||
defineOptions({ name: 'KeFuMessageBox' })
|
defineOptions({ name: 'KeFuMessageList' })
|
||||||
|
|
||||||
const message = ref('') // 消息弹窗
|
const message = ref('') // 消息弹窗
|
||||||
|
|
||||||
|
@ -137,17 +137,24 @@ const total = ref(0) // 消息总条数
|
||||||
const getMessageList = async (val: KeFuConversationRespVO) => {
|
const getMessageList = async (val: KeFuConversationRespVO) => {
|
||||||
conversation.value = val
|
conversation.value = val
|
||||||
queryParams.conversationId = val.id
|
queryParams.conversationId = val.id
|
||||||
|
// 情况一:已经加载完所有消息
|
||||||
const messageTotal = messageList.value.length
|
const messageTotal = messageList.value.length
|
||||||
if (total.value > 0 && messageTotal > 0 && messageTotal === total.value) {
|
if (total.value > 0 && messageTotal > 0 && messageTotal === total.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const res = await KeFuMessageApi.getKeFuMessagePage(queryParams)
|
const res = await KeFuMessageApi.getKeFuMessagePage(queryParams)
|
||||||
total.value = res.total
|
total.value = res.total
|
||||||
for (const item of res.list) {
|
// 情况二:加载最新消息
|
||||||
if (messageList.value.some((val) => val.id === item.id)) {
|
if (queryParams.pageNo === 1) {
|
||||||
continue
|
messageList.value = res.list
|
||||||
|
} else {
|
||||||
|
// 情况三:加载历史消息
|
||||||
|
for (const item of res.list) {
|
||||||
|
if (messageList.value.some((val) => val.id === item.id)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
messageList.value.push(item)
|
||||||
}
|
}
|
||||||
messageList.value.push(item)
|
|
||||||
}
|
}
|
||||||
await scrollToBottom()
|
await scrollToBottom()
|
||||||
}
|
}
|
||||||
|
@ -167,13 +174,13 @@ const refreshMessageList = async () => {
|
||||||
queryParams.pageNo = 1
|
queryParams.pageNo = 1
|
||||||
await getMessageList(conversation.value)
|
await getMessageList(conversation.value)
|
||||||
if (loadHistory.value) {
|
if (loadHistory.value) {
|
||||||
// 有下角显示有新消息提示
|
// 右下角显示有新消息提示
|
||||||
showNewMessageTip.value = true
|
showNewMessageTip.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ getMessageList, refreshMessageList })
|
defineExpose({ getMessageList, refreshMessageList })
|
||||||
const showChatBox = computed(() => !isEmpty(conversation.value)) // 是否显示聊天区域
|
const showKeFuMessageList = computed(() => !isEmpty(conversation.value)) // 是否显示聊天区域
|
||||||
|
|
||||||
/** 处理表情选择 */
|
/** 处理表情选择 */
|
||||||
const handleEmojiSelect = (item: Emoji) => {
|
const handleEmojiSelect = (item: Emoji) => {
|
||||||
|
@ -252,12 +259,15 @@ const handleScroll = async ({ scrollTop }) => {
|
||||||
loadingMore.value = scrollTop < 20
|
loadingMore.value = scrollTop < 20
|
||||||
}
|
}
|
||||||
const handleOldMessage = async () => {
|
const handleOldMessage = async () => {
|
||||||
|
// 记录已有页面高度
|
||||||
|
const oldPageHeight = innerRef.value!.clientHeight
|
||||||
loadHistory.value = true
|
loadHistory.value = true
|
||||||
// 加载消息列表
|
// 加载消息列表
|
||||||
queryParams.pageNo += 1
|
queryParams.pageNo += 1
|
||||||
await getMessageList(conversation.value)
|
await getMessageList(conversation.value)
|
||||||
loadingMore.value = false
|
loadingMore.value = false
|
||||||
// TODO puhui999: 等页面加载完后,获得上一页最后一条消息的位置,控制滚动到它所在位置
|
// 等页面加载完后,获得上一页最后一条消息的位置,控制滚动到它所在位置
|
||||||
|
scrollbarRef.value!.setScrollTop(innerRef.value!.clientHeight - oldPageHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -283,23 +293,18 @@ const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => {
|
||||||
line-height: 60px;
|
line-height: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loadingMore {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #eee;
|
||||||
|
color: #666;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 50px;
|
||||||
|
transform: translateY(-100%);
|
||||||
|
transition: transform 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
&-content {
|
&-content {
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.loadingMore {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 50px;
|
|
||||||
background-color: #eee;
|
|
||||||
color: #666;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 50px;
|
|
||||||
transform: translateY(-100%);
|
|
||||||
transition: transform 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newMessageTip {
|
.newMessageTip {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 35px;
|
bottom: 35px;
|
||||||
|
|
Loading…
Reference in New Issue