diff --git a/pages_tool/ai-chat/ai-chat-message.vue b/pages_tool/ai-chat/ai-chat-message.vue index 7f6d66b..9c8add5 100644 --- a/pages_tool/ai-chat/ai-chat-message.vue +++ b/pages_tool/ai-chat/ai-chat-message.vue @@ -2402,17 +2402,20 @@ _handleStreamError(msg) { return m + 'm' + (s < 10 ? '0' + s : s) + 's' }, - // 滚动到底部 - 统一使用 scroll-into-view + // 滚动到底部 - 流式长回答时持续跟随最新文字 + // 关键: 之前用 scroll-into-view 把最后一条消息滚入视野, 但流式过程中 AI 消息 id 不变, + // scroll-into-view 只在 id 变化/重新赋值时触发, 且会把元素"顶到顶部对齐"而非贴底, + // 导致长回答越写越长时, 最新文字被挤出可视区、看不到(你反馈的问题)。 + // 改法: 改用 scroll-top 赋一个不断递增且恒大于内容高度的值, 强制滚动条贴底, + // 每个新文字块到达都重设 → 视口随答案增长缓缓上移, 始终显示 AI 最新回复。 scrollToBottom() { if (this.messages.length === 0) return - // 取真实最后一条消息(包括空内容的流式消息) - const lastMsg = this.messages[this.messages.length - 1] - const lastIndex = this.messages.length - 1 - const key = lastMsg.id || lastMsg.timestamp || lastIndex - // 先清空再设置,确保 scroll-into-view 重新触发 + // 取消可能冲突的 scroll-into-view (搜索跳转用, 不走这里) this.scrollIntoViewId = '' this.$nextTick(() => { - this.scrollIntoViewId = 'msg-' + key + '-' + lastIndex + // 递增超大值: 保证每次调用都触发重新滚动(同值在部分平台不重排), 且恒大于内容高度=贴底 + this._bottomCounter = (this._bottomCounter || 0) + 100000 + this.scrollTop = this._bottomCounter }) },