【新增】mall 客服消息下拉加载,有新消息提醒

pull/474/head
puhui999 2024-07-08 17:53:56 +08:00
parent e9bb9403b4
commit 848bc60612
2 changed files with 110 additions and 35 deletions

View File

@ -4,9 +4,16 @@
<div class="kefu-title">{{ keFuConversation.userNickname }}</div>
</el-header>
<el-main class="kefu-content" style="overflow: visible">
<el-scrollbar ref="scrollbarRef" always height="calc(100vh - 495px)">
<div
v-show="loadingMore"
class="loadingMore flex justify-center items-center cursor-pointer"
@click="handleOldMessage"
>
加载更多
</div>
<el-scrollbar ref="scrollbarRef" always height="calc(100vh - 495px)" @scroll="handleScroll">
<div ref="innerRef" class="w-[100%] pb-3px">
<div v-for="(item, index) in messageList" :key="item.id" class="w-[100%]">
<div v-for="(item, index) in getMessageList0" :key="item.id" class="w-[100%]">
<div class="flex justify-center items-center mb-20px">
<!-- 日期 -->
<div
@ -58,6 +65,14 @@
</div>
</div>
</el-scrollbar>
<div
v-show="showNewMessageTip"
class="newMessageTip flex items-center cursor-pointer"
@click="handleToNewMessage"
>
<span>有新消息</span>
<Icon class="ml-5px" icon="ep:bottom" />
</div>
</el-main>
<el-footer height="230px">
<div class="h-[100%]">
@ -101,23 +116,47 @@ const messageTool = useMessage()
const message = ref('') //
const messageList = ref<KeFuMessageRespVO[]>([]) //
const keFuConversation = ref<KeFuConversationRespVO>({} as KeFuConversationRespVO) //
// TODO puhui999:
const showNewMessageTip = ref(false) //
const queryParams = reactive({
pageNo: 1,
conversationId: 0
})
const total = ref(0) //
//
const getMessageList = async (conversation: KeFuConversationRespVO) => {
keFuConversation.value = conversation
const { list } = await KeFuMessageApi.getKeFuMessagePage({
pageNo: 1,
conversationId: conversation.id
})
messageList.value = list.reverse()
// TODO puhui999:
queryParams.conversationId = conversation.id
const messageTotal = messageList.value.length
if (total.value > 0 && messageTotal > 0 && messageTotal === total.value) {
return
}
const res = await KeFuMessageApi.getKeFuMessagePage(queryParams)
total.value = res.total
for (const item of res.list) {
if (messageList.value.some((val) => val.id === item.id)) {
continue
}
messageList.value.push(item)
}
await scrollToBottom()
}
const getMessageList0 = computed(() => {
messageList.value.sort((a: any, b: any) => a.createTime - b.createTime)
return messageList.value
})
//
const refreshMessageList = () => {
const refreshMessageList = async () => {
if (!keFuConversation.value) {
return
}
getMessageList(keFuConversation.value)
queryParams.pageNo = 1
await getMessageList(keFuConversation.value)
if (loadHistory.value) {
//
showNewMessageTip.value = true
}
}
defineExpose({ getMessageList, refreshMessageList })
//
@ -140,7 +179,7 @@ const handleSendPicture = async (picUrl: string) => {
const handleSendMessage = async () => {
// 1.
if (isEmpty(unref(message.value))) {
messageTool.warning('请输入消息后再发送哦!')
messageTool.notifyWarning('请输入消息后再发送哦!')
return
}
// 2.
@ -167,12 +206,41 @@ const innerRef = ref<HTMLDivElement>()
const scrollbarRef = ref<InstanceType<typeof ElScrollbarType>>()
//
const scrollToBottom = async () => {
// 1.
// 1.
if (loadHistory.value) {
return
}
// 2.1
await nextTick()
scrollbarRef.value!.setScrollTop(innerRef.value!.clientHeight)
// 2.
showNewMessageTip.value = false
// 2.2
await KeFuMessageApi.updateKeFuMessageReadStatus(keFuConversation.value.id)
}
//
const handleToNewMessage = async () => {
loadHistory.value = false
await scrollToBottom()
}
const loadingMore = ref(false) //
const loadHistory = ref(false) //
const handleScroll = async ({ scrollTop }) => {
const messageTotal = messageList.value.length
if (total.value > 0 && messageTotal > 0 && messageTotal === total.value) {
return
}
// 20
loadingMore.value = scrollTop < 20
}
const handleOldMessage = async () => {
loadHistory.value = true
//
queryParams.pageNo += 1
await getMessageList(keFuConversation.value)
loadingMore.value = false
// TODO puhui999:
}
/**
* 是否显示时间
* @param {*} item - 数据
@ -196,6 +264,32 @@ const showTime = computed(() => (item: KeFuMessageRespVO, index: number) => {
}
&-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 {
position: absolute;
bottom: 35px;
right: 35px;
background-color: #fff;
padding: 10px;
border-radius: 30px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 阴影效果 */
}
.ss-row-left {
justify-content: flex-start;

View File

@ -74,7 +74,7 @@
<script lang="ts" setup>
import { KeFuConversationApi, KeFuConversationRespVO } from '@/api/mall/promotion/kefu/conversation'
import { useEmoji } from './tools/emoji'
import { formatDate, getNowDateTime } from '@/utils/formatTime'
import { formatDate } from '@/utils/formatTime'
import { KeFuMessageContentTypeEnum } from './tools/constants'
defineOptions({ name: 'KeFuConversationBox' })
@ -84,24 +84,6 @@ const activeConversationIndex = ref(-1) // 选中的会话
const conversationList = ref<KeFuConversationRespVO[]>([]) //
const getConversationList = async () => {
conversationList.value = await KeFuConversationApi.getConversationList()
//
for (let i = 0; i < 5; i++) {
conversationList.value.push({
id: 1,
userId: 283,
userAvatar:
'https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKMezSxtOImrC9lbhwHiazYwck3xwrEcO7VJfG6WQo260whaeVNoByE5RreiaGsGfOMlIiaDhSaA991w/132',
userNickname: '辉辉鸭' + i,
lastMessageTime: getNowDateTime(),
lastMessageContent:
'[爱心][爱心]你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇你好哇',
lastMessageContentType: 1,
adminPinned: false,
userDeleted: false,
adminDeleted: false,
adminUnreadMessageCount: i
})
}
}
defineExpose({ getConversationList })
const emits = defineEmits<{
@ -157,8 +139,7 @@ const updateConversationPinned = async (adminPinned: boolean) => {
id: selectedConversation.value.id,
adminPinned
})
// TODO puhui999:
message.success(adminPinned ? '置顶成功' : '取消置顶成功')
message.notifySuccess(adminPinned ? '置顶成功' : '取消置顶成功')
// 2.
closeRightMenu()
await getConversationList()