feat: 添加上拉刷新功能,优化聊天历史加载逻辑及状态管理
This commit is contained in:
parent
a4a9a6c566
commit
71345b7bf4
|
@ -21,7 +21,8 @@
|
||||||
></image>
|
></image>
|
||||||
|
|
||||||
<text class="message-text"
|
<text class="message-text"
|
||||||
>Hi~ 我是源小新,你们的AI校园助手,非常高兴认识您,我可以为你答疑解惑。</text
|
>Hi~
|
||||||
|
我是源小新,你们的AI校园助手,非常高兴认识您,我可以为你答疑解惑。</text
|
||||||
>
|
>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
@ -85,6 +86,7 @@
|
||||||
:scroll-top="scrollTop"
|
:scroll-top="scrollTop"
|
||||||
:show-scrollbar="true"
|
:show-scrollbar="true"
|
||||||
@scrolltolower="onScrollToLower"
|
@scrolltolower="onScrollToLower"
|
||||||
|
@scrolltoupper="onScrollToUpper"
|
||||||
>
|
>
|
||||||
<!-- 头部卡片 -->
|
<!-- 头部卡片 -->
|
||||||
<!-- 后端让先注释 -->
|
<!-- 后端让先注释 -->
|
||||||
|
@ -112,6 +114,16 @@
|
||||||
|
|
||||||
<!-- 对话内容区域 -->
|
<!-- 对话内容区域 -->
|
||||||
<view class="chat-content">
|
<view class="chat-content">
|
||||||
|
<!-- 上拉刷新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">
|
||||||
|
<text>已经到顶了</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 消息循环渲染 -->
|
<!-- 消息循环渲染 -->
|
||||||
<block
|
<block
|
||||||
v-for="(message, index) in messageGroups"
|
v-for="(message, index) in messageGroups"
|
||||||
|
@ -261,6 +273,14 @@ export default {
|
||||||
currentConversationId: "",
|
currentConversationId: "",
|
||||||
advicePhoneShow: false,
|
advicePhoneShow: false,
|
||||||
perfectInfoShow: false,
|
perfectInfoShow: false,
|
||||||
|
isLoading: false, // loadingMore
|
||||||
|
isLoadingMore: false, // 是否正在加载更多的标志位
|
||||||
|
noMoreData: false, // 是否已加载全部历史消息
|
||||||
|
|
||||||
|
pageQuery: {
|
||||||
|
PageIndex: 1,
|
||||||
|
PageSize: 20,
|
||||||
|
},
|
||||||
|
|
||||||
questionList: [
|
questionList: [
|
||||||
"学习哪些专业比较好?",
|
"学习哪些专业比较好?",
|
||||||
|
@ -360,7 +380,10 @@ export default {
|
||||||
// 确保消息更新后自动滚动到底部
|
// 确保消息更新后自动滚动到底部
|
||||||
messageGroups: {
|
messageGroups: {
|
||||||
handler() {
|
handler() {
|
||||||
this.scrollToBottom();
|
// 只有在不是加载更多的情况下才滚动到底部
|
||||||
|
if (!this.isLoadingMore) {
|
||||||
|
this.scrollToBottom();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
deep: true,
|
deep: true,
|
||||||
},
|
},
|
||||||
|
@ -376,18 +399,7 @@ export default {
|
||||||
deep: true,
|
deep: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {},
|
||||||
// 预加载背景图
|
|
||||||
// uni.getImageInfo({
|
|
||||||
// src: '/static/common/images/images_bg.png',
|
|
||||||
// success: () => {
|
|
||||||
// console.log('背景图预加载成功');
|
|
||||||
// },
|
|
||||||
// fail: (err) => {
|
|
||||||
// console.error('背景图预加载失败', err);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
handleLeftClick() {
|
handleLeftClick() {
|
||||||
this.$u.api.GetConversationPage().then((res) => {
|
this.$u.api.GetConversationPage().then((res) => {
|
||||||
|
@ -414,32 +426,30 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
scrollToBottom() {
|
scrollToBottom() {
|
||||||
|
// 如果正在加载更多,不执行滚动
|
||||||
|
if (this.isLoadingMore) return;
|
||||||
|
|
||||||
// 使用nextTick确保DOM已更新
|
// 使用nextTick确保DOM已更新
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
// setTimeout(() => {
|
// setTimeout(() => {
|
||||||
const query = uni.createSelectorQuery().in(this);
|
const query = uni.createSelectorQuery().in(this);
|
||||||
query
|
query
|
||||||
.select(".chat-content")
|
.select(".chat-content")
|
||||||
.boundingClientRect((data) => {
|
.boundingClientRect((data) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
console.log("chat-content高度:", data.height);
|
console.log("chat-content高度:", data.height);
|
||||||
// 使用pageScrollTo滚动到底部
|
|
||||||
// uni.pageScrollTo({
|
|
||||||
// scrollTop: 99999,
|
|
||||||
// duration: 100,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// 同时设置scrollTop和scrollToView
|
// 同时设置scrollTop和scrollToView
|
||||||
this.scrollTop = data.height + 200;
|
this.scrollTop = data.height + 200;
|
||||||
// if (this.messageGroups.length > 0) {
|
// if (this.messageGroups.length > 0) {
|
||||||
// const lastMessage =
|
// const lastMessage =
|
||||||
// this.messageGroups[this.messageGroups.length - 1];
|
// this.messageGroups[this.messageGroups.length - 1];
|
||||||
// this.scrollToView = "msg-" + lastMessage.id;
|
// this.scrollToView = "msg-" + lastMessage.id;
|
||||||
// console.log("设置scrollToView:", this.scrollToView);
|
// console.log("设置scrollToView:", this.scrollToView);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.exec();
|
.exec();
|
||||||
// }, 300);
|
// }, 300);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -463,6 +473,9 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重置加载更多标志位
|
||||||
|
this.isLoadingMore = false;
|
||||||
|
|
||||||
const sendMessage = this.messageValue;
|
const sendMessage = this.messageValue;
|
||||||
console.log("发送消息", sendMessage);
|
console.log("发送消息", sendMessage);
|
||||||
|
|
||||||
|
@ -528,19 +541,21 @@ export default {
|
||||||
|
|
||||||
console.log("选中的对话:", data);
|
console.log("选中的对话:", data);
|
||||||
// 根据conversationId加载对应的对话内容
|
// 根据conversationId加载对应的对话内容
|
||||||
const conversationId = data.conversationId;
|
this.currentConversationId = data.conversationId;
|
||||||
|
|
||||||
this.currentConversationId = conversationId;
|
|
||||||
|
|
||||||
this.isChat = true;
|
this.isChat = true;
|
||||||
|
|
||||||
|
// 重置消息列表和分页相关状态
|
||||||
this.messageGroups = [];
|
this.messageGroups = [];
|
||||||
|
this.pageQuery.PageIndex = 1;
|
||||||
|
this.isLoadingMore = false;
|
||||||
|
this.noMoreData = false;
|
||||||
|
|
||||||
this.$u.api
|
this.$u.api
|
||||||
.GetConversationDetail({
|
.GetConversationDetail({
|
||||||
"Item1.Id": conversationId,
|
"Item1.Id": this.currentConversationId,
|
||||||
PageIndex: "1",
|
PageIndex: this.pageQuery.PageIndex,
|
||||||
PageSize: "20",
|
PageSize: this.pageQuery.PageSize,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log("GetConversationDetail.....", res.item2);
|
console.log("GetConversationDetail.....", res.item2);
|
||||||
|
@ -561,24 +576,96 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 在开始新对话或选择对话时重置相关状态
|
||||||
handleCreateConversation() {
|
handleCreateConversation() {
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
this.popupShow = false;
|
this.popupShow = false;
|
||||||
this.isChat = true;
|
this.isChat = true;
|
||||||
this.currentConversationId = "";
|
this.currentConversationId = "";
|
||||||
this.messageGroups = [];
|
this.messageGroups = [];
|
||||||
|
|
||||||
|
// 重置分页和加载状态
|
||||||
|
this.pageQuery.PageIndex = 1;
|
||||||
|
this.isLoadingMore = false;
|
||||||
|
this.noMoreData = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 开始新对话
|
||||||
handleStartChat() {
|
handleStartChat() {
|
||||||
this.isChat = true;
|
this.isChat = true;
|
||||||
this.currentConversationId = "";
|
this.currentConversationId = "";
|
||||||
this.messageGroups = [];
|
this.messageGroups = [];
|
||||||
|
|
||||||
|
// 重置分页和加载状态
|
||||||
|
this.pageQuery.PageIndex = 1;
|
||||||
|
this.isLoadingMore = false;
|
||||||
|
this.noMoreData = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 滚动到底部事件处理
|
// 滚动到底部事件处理
|
||||||
onScrollToLower() {
|
onScrollToLower() {
|
||||||
console.log("已滚动到底部");
|
console.log("已滚动到底部");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 滚动到顶部事件处理
|
||||||
|
onScrollToUpper() {
|
||||||
|
console.log("触发上拉刷新");
|
||||||
|
|
||||||
|
// 如果已经没有更多数据,不再触发上拉刷新
|
||||||
|
if (this.noMoreData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置加载标志位为true,防止触发滚动到底部
|
||||||
|
this.isLoadingMore = true;
|
||||||
|
this.isLoading = true;
|
||||||
|
|
||||||
|
this.pageQuery.PageIndex++;
|
||||||
|
this.$u.api
|
||||||
|
.GetConversationDetail({
|
||||||
|
"Item1.Id": this.currentConversationId,
|
||||||
|
PageIndex: this.pageQuery.PageIndex,
|
||||||
|
PageSize: this.pageQuery.PageSize,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
console.log("GetConversationDetail.....", res.item2);
|
||||||
|
|
||||||
|
// 如果返回的数据为空数组,说明没有更多历史消息了
|
||||||
|
if (!res.item2 || res.item2.length === 0) {
|
||||||
|
this.noMoreData = true; // 设置标记,不再触发上拉刷新
|
||||||
|
this.$refs.uToast.show({
|
||||||
|
title: "已经到顶了",
|
||||||
|
type: "warning",
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将消息按sendDate升序排列,时间相同时用户消息(interactMode=0)排在前面
|
||||||
|
const nextPageMessageGroups = res.item2.sort((a, b) => {
|
||||||
|
const timeA = new Date(a.sendDate).getTime();
|
||||||
|
const timeB = new Date(b.sendDate).getTime();
|
||||||
|
|
||||||
|
// 如果时间相同,按interactMode排序(0排在前,1排在后)
|
||||||
|
if (timeA === timeB) {
|
||||||
|
return a.interactMode - b.interactMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 否则按时间升序排列
|
||||||
|
return timeA - timeB;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.messageGroups = [
|
||||||
|
...nextPageMessageGroups,
|
||||||
|
...this.messageGroups,
|
||||||
|
];
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -836,6 +923,19 @@ export default {
|
||||||
padding: 20rpx 0;
|
padding: 20rpx 0;
|
||||||
margin-bottom: 150rpx;
|
margin-bottom: 150rpx;
|
||||||
|
|
||||||
|
.loading-more {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-more-data {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-bottom: 32rpx;
|
||||||
|
padding: 10rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
.message-time {
|
.message-time {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
|
|
Loading…
Reference in New Issue