提交历史记录问题

master
jiangjunjie 6 days ago
parent f68c2249c5
commit 3637bac4e4
  1. 98
      src/components/chat-new.vue

@ -17,6 +17,8 @@ import imageService from '@/utils/imageService'
import { messageSend } from '@/utils/api' import { messageSend } from '@/utils/api'
import { Post } from '@/utils/https' import { Post } from '@/utils/https'
import { SJHLCmdList } from '@/utils/constant' import { SJHLCmdList } from '@/utils/constant'
import MeScroll from 'mescroll.js'
import 'mescroll.js/mescroll.min.css'
defineOptions({ defineOptions({
name: 'chat-new', name: 'chat-new',
@ -42,6 +44,9 @@ const sessionId = inject('sessionId', ref(''))
const userId = inject('userId', ref('')) const userId = inject('userId', ref(''))
const isLostMessage = inject('isLostMessage', ref(null)) const isLostMessage = inject('isLostMessage', ref(null))
const mainContainerRef = ref(null) const mainContainerRef = ref(null)
const webSocketChannel = '95460000' // 投诉直连渠道号
// mescroll 实例(非响应式)
let mescroll = null
const appraiseShow = ref(false) // 有帮助/没帮助评价弹层 const appraiseShow = ref(false) // 有帮助/没帮助评价弹层
const baseHandle = ref('') // 评价弹层基础数据(含被点按钮 event) const baseHandle = ref('') // 评价弹层基础数据(含被点按钮 event)
@ -53,7 +58,6 @@ function appraiseIsClose(val, param) {
// 参考 liics/chat-main 的 tokenExist:token 获取成功后才渲染聊天主内容 // 参考 liics/chat-main 的 tokenExist:token 获取成功后才渲染聊天主内容
const historylist = ref([]) const historylist = ref([])
const historyLoading = ref(false)
const historyReady = ref(true) const historyReady = ref(true)
const introReadyCount = ref(0) const introReadyCount = ref(0)
const businessHandleRef = ref(null) const businessHandleRef = ref(null)
@ -221,14 +225,6 @@ function getMainEl() {
return mainContainerRef.value || store?.mescrollContent || null return mainContainerRef.value || store?.mescrollContent || null
} }
function scrollMainTo(top) {
const el = getMainEl()
if (!el) return false
const value = Math.max(0, Number(top) || 0)
el.scrollTop = value
return Math.abs((el.scrollTop || 0) - value) < 2 || value === 0
}
let smoothScrollToken = 0 let smoothScrollToken = 0
function smoothScrollMainToBottom(duration = 300) { function smoothScrollMainToBottom(duration = 300) {
@ -323,10 +319,6 @@ function onMainScroll(event) {
const top = event?.target?.scrollTop const top = event?.target?.scrollTop
if (top == null) return if (top == null) return
persistScrollTop(top, { allowZero: true }) persistScrollTop(top, { allowZero: true })
// 上滑到顶部附近时加载更多历史记录
if (top <= 60 && !nolist.value && !historyLoading.value) {
getChatHistory()
}
} }
onBeforeRouteLeave(() => { onBeforeRouteLeave(() => {
@ -378,19 +370,53 @@ function getHeaderUrl(context, payload) {
}); });
}); });
} }
const getChatHistory = async (isAuto = false) => { function initMescroll() {
let isLostMessageFlag =
isLostMessage.value && (isLostMessage.value == '1' || isLostMessage.value == '3') ? true : false
// 投诉直连渠道首次进入需要刷新
const isTouSuZhiLian = store.source === webSocketChannel
isLostMessageFlag = isTouSuZhiLian ? true : isLostMessageFlag
// 创建 MeScroll 对象(下拉加载历史记录,参考 chat-main)
mescroll = new MeScroll(mainContainerRef.value, {
down: {
isBounce: false,
auto: isLostMessageFlag,
callback: getChatHistory,
htmlContent: '<p class="downwarp-progress"></p><p class="downwarp-tip">没有数据了</p>',
hardwareClass: 'mescroll-hardware',
warpClass: 'mescroll-downwarp', // 下拉刷新的布局容器样式
offset: 70, // 触发刷新的距离,默认80
mustToTop: false,
autoShowLoading: true, // 自动执行下拉回调时是否显示下拉刷新进度
textInOffset: '下拉加载历史记录', // 下拉的距离在offset范围内的提示文本
textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本
textLoading: '加载中 ...', // 加载中的提示文本
onMoving: upOnMoving,
},
up: {
use: false,
},
})
}
function upOnMoving() {
nolist.value = false
}
// 下拉回调 拉取历史记录
function getChatHistory() {
const params = { const params = {
page: pageNum.value, page: pageNum.value,
pageSize: pageSize.value, pageSize: pageSize.value,
sessionId: sessionId.value || store?.sessionId, sessionId: sessionId.value || store?.sessionId,
userId: userId.value || store?.userId, userId: userId.value || store?.userId,
} }
historyLoading.value = true
setTimeout(() => {
Post('history/chatInfo', params) Post('history/chatInfo', params)
.then((response) => { .then((response) => {
historyLoading.value = false
historyReady.value = true
if (response.code && response.code != 0) { if (response.code && response.code != 0) {
showToast(response.msg) showToast(response.msg)
return return
@ -401,6 +427,8 @@ const getChatHistory = async (isAuto = false) => {
const dataList = response.data.list const dataList = response.data.list
pageNum.value++ pageNum.value++
// 先隐藏下拉刷新的状态
mescroll && mescroll.endSuccess()
// 不满一页,说明已经无更多消息 // 不满一页,说明已经无更多消息
if (dataList.length < pageSize.value) { if (dataList.length < pageSize.value) {
@ -444,39 +472,35 @@ const getChatHistory = async (isAuto = false) => {
updateReadStatus(dataList) updateReadStatus(dataList)
nextTick(() => { nextTick(() => {
if (isAuto) { if (pageNum.value <= 2) {
// 参考 chat-main:有未读自动加载时滚到底部并提示未读
if (isLostMessage.value === 3) { if (isLostMessage.value === 3) {
showToast('您有新消息未读,请及时查看历史消息') showToast('您有新消息未读,请及时查看历史消息')
} }
setTimeout(() => { setTimeout(() => {
scrollMainTo(99999) mescroll && mescroll.scrollTo(99999, 0)
}, 150) }, 150)
} else if (topMsg) { } else if (topMsg) {
// 保持顶部消息的位置
const view = document.querySelector('#' + topMsg.VIEW_ID) const view = document.querySelector('#' + topMsg.VIEW_ID)
console.log(topMsg.VIEW_ID + ' 节点离页面顶部的距离=' + view?.offsetTop) console.log(topMsg.VIEW_ID + ' 节点离页面顶部的距离=' + view?.offsetTop)
setTimeout(() => { setTimeout(() => {
if (view) scrollMainTo(view.offsetTop - 20) if (view) mescroll.scrollTo(view.offsetTop - 20, 0)
}, 150)
} else {
// 首次手动上拉加载:停在顶部
setTimeout(() => {
scrollMainTo(0)
}, 150) }, 150)
} }
}) })
} else { } else {
mescroll && mescroll.endErr()
nolist.value = true nolist.value = true
nolistTxt.value = pageNum.value === 1 ? '当前还没有您的聊天记录' : '没有更多数据了' nolistTxt.value = pageNum.value === 1 ? '当前还没有您的聊天记录' : '没有更多数据了'
} }
}) })
.catch(() => { .catch(() => {
// 网络异常不置 nolist,用户再次上滑可重试(chat-main 靠下拉手势重置 nolist,这里等价放开)
historyLoading.value = false
historyReady.value = true
pageNum.value-- pageNum.value--
mescroll && mescroll.endErr()
nolist.value = true
}) })
}, 600)
} }
onMounted(async () => { onMounted(async () => {
getHeaderUrl() getHeaderUrl()
@ -484,16 +508,12 @@ onMounted(async () => {
if (mainContainerRef.value) { if (mainContainerRef.value) {
store?.setMescrollContent?.(mainContainerRef.value) store?.setMescrollContent?.(mainContainerRef.value)
} }
// 下拉加载历史记录初始化(有未读/投诉直连渠道时 down.auto 自动拉第一页,参考 chat-main)
initMescroll()
const persisted = readPersistedScrollTop() const persisted = readPersistedScrollTop()
if (persisted != null && persisted > 0) { if (persisted != null && persisted > 0) {
shouldRestoreScroll.value = true shouldRestoreScroll.value = true
restoreScrollPosition() restoreScrollPosition()
} else {
// 参考 chat-main 的 mescroll down.auto:有未读消息或投诉直连渠道时,进入页面自动加载历史
const hasUnread = isLostMessage.value == '1' || isLostMessage.value == '3'
if (hasUnread || store.source === '95460000') {
getChatHistory(true)
}
} }
}) })
watch( watch(
@ -512,9 +532,6 @@ watch(
<template> <template>
<div class="chat-new"> <div class="chat-new">
<div class="main-container" ref="mainContainerRef" @scroll.passive="onMainScroll"> <div class="main-container" ref="mainContainerRef" @scroll.passive="onMainScroll">
<div class="history-loading" v-if="historyLoading">
<van-loading type="spinner" size="18rem" />
</div>
<div class="empty-tips opacity" v-if="nolist">{{ nolistTxt }}</div> <div class="empty-tips opacity" v-if="nolist">{{ nolistTxt }}</div>
<div class="historicRecords" v-if="historylist.length > 0"> <div class="historicRecords" v-if="historylist.length > 0">
<chatContent <chatContent
@ -590,11 +607,6 @@ watch(
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
.history-loading {
display: flex;
justify-content: center;
}
.message-con { .message-con {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

Loading…
Cancel
Save