chore:智能客服聊天不乱窜了
This commit is contained in:
@@ -1,23 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="ai-chat-container">
|
<view class="ai-chat-container">
|
||||||
<!-- 聊天消息列表 -->
|
<!-- 聊天消息列表 - 统一使用 scroll-into-view -->
|
||||||
<!-- #ifdef H5 -->
|
|
||||||
<scroll-view
|
<scroll-view
|
||||||
class="chat-messages"
|
class="chat-messages"
|
||||||
scroll-y
|
scroll-y
|
||||||
:scroll-into-view="scrollIntoViewId"
|
:scroll-into-view="scrollIntoViewId"
|
||||||
:scroll-with-animation="true"
|
|
||||||
@scroll="onScroll">
|
|
||||||
<!-- #endif -->
|
|
||||||
|
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
|
||||||
<scroll-view
|
|
||||||
class="chat-messages"
|
|
||||||
scroll-y
|
|
||||||
:scroll-top="scrollTop"
|
:scroll-top="scrollTop"
|
||||||
:scroll-with-animation="true"
|
:scroll-with-animation="true"
|
||||||
@scroll="onScroll">
|
@scroll="onScroll">
|
||||||
<!-- #endif -->
|
|
||||||
|
|
||||||
<!-- 加载更多历史消息 -->
|
<!-- 加载更多历史消息 -->
|
||||||
<view class="load-more" v-if="hasMoreHistory">
|
<view class="load-more" v-if="hasMoreHistory">
|
||||||
@@ -184,13 +174,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- #ifdef H5 -->
|
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
<!-- #endif -->
|
|
||||||
|
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
|
||||||
</scroll-view>
|
|
||||||
<!-- #endif -->
|
|
||||||
|
|
||||||
<!-- 输入区域 -->
|
<!-- 输入区域 -->
|
||||||
<view class="input-area">
|
<view class="input-area">
|
||||||
@@ -497,8 +481,8 @@ export default {
|
|||||||
watch: {
|
watch: {
|
||||||
messages: {
|
messages: {
|
||||||
handler(newVal, oldVal) {
|
handler(newVal, oldVal) {
|
||||||
// 仅在新增消息时触发滚动,流式响应时由手动控制
|
// 仅当不是加载历史且不是流式响应时,执行滚底
|
||||||
if (!this.isLoadingHistory && !this.isStreaming && newVal.length !== oldVal.length) {
|
if (!this.isLoadingHistory && !this.isStreaming && newVal.length > oldVal.length) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.scrollToBottom()
|
this.scrollToBottom()
|
||||||
})
|
})
|
||||||
@@ -897,6 +881,9 @@ async loadChatHistoryIfExist() {
|
|||||||
isStreaming: true
|
isStreaming: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 标记正在流式响应
|
||||||
|
this.isStreaming = true;
|
||||||
|
|
||||||
// 移除加载状态,添加流式消息
|
// 移除加载状态,添加流式消息
|
||||||
this.messages = this.messages.filter(msg => msg.type !== 'loading');
|
this.messages = this.messages.filter(msg => msg.type !== 'loading');
|
||||||
this.shouldScrollToBottom = true;
|
this.shouldScrollToBottom = true;
|
||||||
@@ -926,6 +913,7 @@ async loadChatHistoryIfExist() {
|
|||||||
|
|
||||||
// 标记流式结束
|
// 标记流式结束
|
||||||
streamMessage.isStreaming = false;
|
streamMessage.isStreaming = false;
|
||||||
|
this.isStreaming = false;
|
||||||
|
|
||||||
// 检查内容是否为空,如果为空则移除该消息
|
// 检查内容是否为空,如果为空则移除该消息
|
||||||
if (!streamMessage.content || streamMessage.content.trim() === '') {
|
if (!streamMessage.content || streamMessage.content.trim() === '') {
|
||||||
@@ -965,6 +953,7 @@ async loadChatHistoryIfExist() {
|
|||||||
|
|
||||||
// 标记流式结束
|
// 标记流式结束
|
||||||
streamMessage.isStreaming = false;
|
streamMessage.isStreaming = false;
|
||||||
|
this.isStreaming = false;
|
||||||
|
|
||||||
// 检查内容是否为空,如果为空则移除该消息
|
// 检查内容是否为空,如果为空则移除该消息
|
||||||
if (!streamMessage.content || streamMessage.content.trim() === '') {
|
if (!streamMessage.content || streamMessage.content.trim() === '') {
|
||||||
@@ -991,6 +980,8 @@ async loadChatHistoryIfExist() {
|
|||||||
// #endif
|
// #endif
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('流式请求失败:', error);
|
console.error('流式请求失败:', error);
|
||||||
|
// 标记流式结束
|
||||||
|
this.isStreaming = false;
|
||||||
// 移除流式消息
|
// 移除流式消息
|
||||||
this.messages = this.messages.filter(msg => msg.id !== streamMessage.id);
|
this.messages = this.messages.filter(msg => msg.id !== streamMessage.id);
|
||||||
// 显示错误
|
// 显示错误
|
||||||
@@ -1074,30 +1065,24 @@ async loadChatHistoryIfExist() {
|
|||||||
return mins.toString().padStart(2, '0') + ':' + secs.toString().padStart(2, '0')
|
return mins.toString().padStart(2, '0') + ':' + secs.toString().padStart(2, '0')
|
||||||
},
|
},
|
||||||
|
|
||||||
// 滚动到底部
|
// 滚动到底部 - 统一使用 scroll-into-view
|
||||||
scrollToBottom() {
|
scrollToBottom() {
|
||||||
if (this.scrollTimer) {
|
if (this.scrollTimer) {
|
||||||
clearTimeout(this.scrollTimer);
|
clearTimeout(this.scrollTimer);
|
||||||
}
|
}
|
||||||
this.scrollTimer = setTimeout(() => {
|
this.scrollTimer = setTimeout(() => {
|
||||||
// #ifdef H5
|
|
||||||
if (this.messages.length > 0) {
|
if (this.messages.length > 0) {
|
||||||
const filteredMessages = this.messages.filter(msg => msg.content && msg.content.trim() !== '');
|
const filteredMessages = this.messages.filter(msg => msg.content && msg.content.trim() !== '');
|
||||||
if (filteredMessages.length > 0) {
|
if (filteredMessages.length > 0) {
|
||||||
const lastMessage = filteredMessages[filteredMessages.length - 1];
|
const lastMessage = filteredMessages[filteredMessages.length - 1];
|
||||||
const lastIndex = this.messages.indexOf(lastMessage);
|
const lastIndex = this.messages.indexOf(lastMessage);
|
||||||
this.scrollIntoViewId = `msg-${lastMessage.id || lastMessage.timestamp}-${lastIndex}`;
|
// 先设为空,再设置新值,确保能触发滚动
|
||||||
// 保持 scrollIntoViewId 不清除,避免频繁切换
|
this.scrollIntoViewId = null;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollIntoViewId = `msg-${lastMessage.id || lastMessage.timestamp}-${lastIndex}`;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
// 直接设置大值滚动到底部,不要重置为0
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.scrollTop = 9999999;
|
|
||||||
});
|
|
||||||
// #endif
|
|
||||||
}, 100);
|
}, 100);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user