【功能完善】客服聊天查看最新消息和回到底部

pull/146/head
puhui999 2025-05-08 17:01:57 +08:00
parent 13f674ab4b
commit 8456d0a8b3
2 changed files with 27 additions and 40 deletions

View File

@ -1,6 +1,6 @@
<template> <template>
<!-- 聊天列表使用scroll-view原生组件整体倒置 --> <!-- 聊天列表使用scroll-view原生组件整体倒置 -->
<scroll-view ref="scrollRef" :scroll-top="scroll.top" class="chat-scroll-view" scroll-y :refresher-enabled="false" <scroll-view :scroll-top="scroll.top" class="chat-scroll-view" scroll-y :refresher-enabled="false"
@scroll="onScroll" @scrolltolower="loadMoreHistory" style="transform: scaleY(-1);"> @scroll="onScroll" @scrolltolower="loadMoreHistory" style="transform: scaleY(-1);">
<!-- 消息列表容器 --> <!-- 消息列表容器 -->
<view class="message-container"> <view class="message-container">
@ -13,8 +13,7 @@
<view v-for="(item, index) in messageList" :key="item.id" class="message-item" <view v-for="(item, index) in messageList" :key="item.id" class="message-item"
style="transform: scaleY(-1);"> style="transform: scaleY(-1);">
<!-- 消息渲染 --> <!-- 消息渲染 -->
<MessageListItem :message="item" :message-index="index" <MessageListItem :message="item" :message-index="index" :message-list="messageList"></MessageListItem>
:message-list="messageList"></MessageListItem>
</view> </view>
</view> </view>
</view> </view>
@ -22,8 +21,8 @@
<!-- 底部聊天输入框 --> <!-- 底部聊天输入框 -->
<su-fixed bottom> <su-fixed bottom>
<view v-if="showNewMessageTip" :style="backToTopStyle" @click="scrollToTop"> <view v-if="showTip" class="back-top ss-flex ss-row-center ss-m-b-10" @click="scrollToTop">
<text>有新消息</text> <text class="back-top-item ss-flex ss-row-center">{{ showNewMessageTip ? '有新消息' : '回到底部' }}</text>
</view> </view>
<slot name="bottom"></slot> <slot name="bottom"></slot>
</su-fixed> </su-fixed>
@ -37,30 +36,20 @@
import { formatDate } from '@/sheep/util'; import { formatDate } from '@/sheep/util';
const messageList = ref([]); // const messageList = ref([]); //
const showTip = ref(false); //
const showNewMessageTip = ref(false); // const showNewMessageTip = ref(false); //
const refreshMessage = ref(false); // const refreshMessage = ref(false); //
const isLoading = ref(false); // const isLoading = ref(false); //
const hasMore = ref(true); // const hasMore = ref(true); //
const scrollRef = ref(null); //
const scroll = ref({ const scroll = ref({
top: 0, top: 0,
oldTop: 0, oldTop: 0,
}); }); //
const queryParams = reactive({ const queryParams = reactive({
no: 1, // no: 1,
limit: 20, limit: 20,
createTime: undefined, createTime: undefined,
}); }); //
const backToTopStyle = reactive({
height: '30px',
width: '100px',
'background-color': '#fff',
'border-radius': '30px',
'box-shadow': '0 2px 4px rgba(0, 0, 0, 0.1)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}); //
// //
const getMessageList = async () => { const getMessageList = async () => {
@ -131,6 +120,7 @@
if (typeof message !== 'undefined') { if (typeof message !== 'undefined') {
// / // /
messageList.value.unshift(message); messageList.value.unshift(message);
showNewMessageTip.value = true;
} else { } else {
queryParams.createTime = undefined; queryParams.createTime = undefined;
refreshMessage.value = true; refreshMessage.value = true;
@ -139,9 +129,9 @@
// //
if (queryParams.no > 1) { if (queryParams.no > 1) {
showNewMessageTip.value = true; showTip.value = true;
} else { } else {
onScrollToUpper(); scrollToTop();
} }
}; };
@ -150,17 +140,8 @@
scroll.value.top = scroll.value.oldTop; scroll.value.top = scroll.value.oldTop;
setTimeout(() => { setTimeout(() => {
scroll.value.top = 0; scroll.value.top = 0;
}, 200) // view }, 200); // view
showNewMessageTip.value = false; showTip.value = false;
};
/** 监听滚动到底部事件(因为 scroll 翻转了顶就是底) */
const onScrollToUpper = () => {
//
if (queryParams.no === 1) {
return;
}
showNewMessageTip.value = false;
}; };
defineExpose({ getMessageList, refreshMessageList, scrollToTop }); defineExpose({ getMessageList, refreshMessageList, scrollToTop });
@ -171,9 +152,9 @@
scroll.value.oldTop = scrollTop; scroll.value.oldTop = scrollTop;
// "" // ""
if (scrollTop > 100) { if (scrollTop > 100) {
showNewMessageTip.value = true; showTip.value = true;
} else { } else {
showNewMessageTip.value = false; showTip.value = false;
} }
}; };
@ -185,23 +166,21 @@
<style> <style>
.chat-scroll-view { .chat-scroll-view {
height: calc(100vh - 100px);
/* 减去底部输入框的高度 */ /* 减去底部输入框的高度 */
height: calc(100vh - 100px);
width: 100%; width: 100%;
position: relative; position: relative;
background-color: #f8f8f8; background-color: #f8f8f8;
z-index: 1; z-index: 1;
/* 确保层级正确 */
} }
.message-container { .message-container {
width: 100%; width: 100%;
min-height: 100vh;
/* 确保容器至少有一屏高度 */ /* 确保容器至少有一屏高度 */
min-height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-end; justify-content: flex-end;
/* 默认内容放到底部 */
} }
.message-list { .message-list {
@ -209,7 +188,6 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding-bottom: 20px; padding-bottom: 20px;
/* 底部留出一些空间 */
} }
.message-item { .message-item {
@ -225,4 +203,14 @@
color: #999; color: #999;
font-size: 14px; font-size: 14px;
} }
.back-top {
.back-top-item{
height: 30px;
width: 100px;
background-color: #fff;
border-radius: 30px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
}
</style> </style>

View File

@ -83,7 +83,6 @@
content: JSON.stringify({ text: chat.msg }), content: JSON.stringify({ text: chat.msg }),
}; };
await KeFuApi.sendKefuMessage(data); await KeFuApi.sendKefuMessage(data);
await messageListRef.value.refreshMessageList();
chat.msg = ''; chat.msg = '';
} finally { } finally {
chat.showTools = false; chat.showTools = false;