feat(聊天页面): 改进消息列表加载和滚动体验

This commit is contained in:
yangzhe 2025-12-17 16:27:08 +08:00
parent 99ca3faefe
commit 3afd93a79e
1 changed files with 51 additions and 29 deletions

View File

@ -14,7 +14,7 @@
scroll-y scroll-y
:scroll-into-view="scrollToView" :scroll-into-view="scrollToView"
:scroll-top="scrollTop" :scroll-top="scrollTop"
scroll-with-animation :scroll-with-animation="!isLoading"
:upper-threshold="20" :upper-threshold="20"
@scroll="handleScroll" @scroll="handleScroll"
@scrolltoupper="handleScrollToUpper" @scrolltoupper="handleScrollToUpper"
@ -47,6 +47,19 @@
</div> </div>
</div> </div>
<!-- 上拉刷新loading -->
<view class="loading-more" v-if="isLoading">
<u-loading mode="circle" color="#4370fe"></u-loading>
</view>
<!-- 到顶部提示 -->
<view
class="no-more-data"
v-if="noMoreData && vuex_msgList && vuex_msgList.length"
>
<text>已经到顶了</text>
</view>
<view <view
v-for="(message, index) in vuex_msgList" v-for="(message, index) in vuex_msgList"
:key="message.id" :key="message.id"
@ -171,8 +184,8 @@ export default {
PageIndex: 1, PageIndex: 1,
PageSize: 20, PageSize: 20,
isLoadingHistory: false, isLoading: false,
noMoreHistory: false, noMoreData: false,
}; };
}, },
@ -215,7 +228,7 @@ export default {
// ID // ID
lastMsgId(val) { lastMsgId(val) {
if (!val) return; if (!val) return;
if (this.isLoadingHistory) return; if (this.isLoading) return;
this.$nextTick(() => { this.$nextTick(() => {
this.scrollToBottom(); this.scrollToBottom();
}); });
@ -283,11 +296,22 @@ export default {
// //
getMsgList() { getMsgList() {
return this.$store.dispatch("fetchChatRecord", { return this.$store
dialogueManagementId: this.vuex_msgUser.dialogueManagementId, .dispatch("fetchChatRecord", {
PageIndex: this.PageIndex, dialogueManagementId: this.vuex_msgUser.dialogueManagementId,
PageSize: this.PageSize, PageIndex: this.PageIndex,
}); PageSize: this.PageSize,
})
.then((list) => {
console.log(list.length, "加载对话消息");
const len = Array.isArray(list) ? list.length : 0;
if (len === 0 && len < this.PageSize) {
this.noMoreData = true;
console.log("没有更多数据了", this.noMoreData);
}
return list;
});
}, },
handleScroll(e) { handleScroll(e) {
@ -298,25 +322,26 @@ export default {
// //
handleScrollToUpper() { handleScrollToUpper() {
if (this.isLoadingHistory || this.noMoreHistory) return; if (this.isLoading || this.noMoreData) return;
this.isLoadingHistory = true; this.isLoading = true;
const beforeTop = this.currentScrollTop || 0; const beforeTop = this.currentScrollTop || 0;
const beforeHeight = this.currentScrollHeight || 0; const beforeHeight = this.currentScrollHeight || 0;
this.PageIndex += 1; const nextPageIndex = this.PageIndex + 1;
this.scrollToView = ""; this.scrollToView = "";
this.$store this.$store
.dispatch("fetchChatRecordNextPage", { .dispatch("fetchChatRecordNextPage", {
dialogueManagementId: this.vuex_msgUser.dialogueManagementId, dialogueManagementId: this.vuex_msgUser.dialogueManagementId,
PageIndex: this.PageIndex, PageIndex: nextPageIndex,
PageSize: this.PageSize, PageSize: this.PageSize,
}) })
.then((list) => { .then((list) => {
if (!list || !list.length) { if (!list || !list.length) {
this.noMoreHistory = true; this.noMoreData = true;
return; return;
} }
this.PageIndex = nextPageIndex;
this.$nextTick(() => { this.$nextTick(() => {
const query = uni.createSelectorQuery().in(this); const query = uni.createSelectorQuery().in(this);
query query
@ -331,12 +356,9 @@ export default {
.exec(); .exec();
}); });
}) })
.catch(() => {
this.PageIndex = Math.max(1, this.PageIndex - 1);
})
.finally(() => { .finally(() => {
setTimeout(() => { setTimeout(() => {
this.isLoadingHistory = false; this.isLoading = false;
}, 50); }, 50);
}); });
}, },
@ -448,18 +470,18 @@ export default {
height: 100%; height: 100%;
overflow-y: scroll; overflow-y: scroll;
// .loading-more { .loading-more {
// text-align: center; text-align: center;
// margin-bottom: 32rpx; margin-bottom: 32rpx;
// } }
// .no-more-data { .no-more-data {
// text-align: center; text-align: center;
// font-size: 24rpx; font-size: 24rpx;
// color: #999; color: #999;
// margin-bottom: 32rpx; margin-bottom: 32rpx;
// padding: 10rpx 0; padding: 10rpx 0;
// } }
.teacher-info-card { .teacher-info-card {
background-color: #ffffff; background-color: #ffffff;