From 8e64675fddb72ef1c73c380699dd6550fc7165ce Mon Sep 17 00:00:00 2001 From: lq Date: Tue, 23 Dec 2025 11:04:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=81=8A=E5=A4=A9=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=9C=A8=E6=9C=80=E5=BA=95=E9=83=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- subPackages/chat/chat.vue | 41 +++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/subPackages/chat/chat.vue b/subPackages/chat/chat.vue index b650a9d..69907a9 100644 --- a/subPackages/chat/chat.vue +++ b/subPackages/chat/chat.vue @@ -54,6 +54,12 @@ @scroll="onScroll" > + + + + 加载历史消息... + + 没有更多历史消息了 @@ -420,11 +426,6 @@ - - - - 加载历史消息... - @@ -605,6 +606,7 @@ export default { hasMore: true, loading: false, isEmpty: false, + isLoadHistory: false, // 标记是否为触顶加载(而非初始化加载) // 预置数据结构 (用于发送) prescriptionData: { @@ -827,15 +829,25 @@ export default { /** * 历史消息加载成功回调 * type: 1=滚动到底部, 0=保持位置 + * 修复:确保触顶加载时 type 始终为 0,只在初始化时传 type=1 */ handLoadMessageList(type = 0) { this.loading = false; if (typeof ChatManager !== 'undefined') { this.messages = ChatManager.roomMessages[this.doctorUserInfo.room_id] || []; } - if (type === 1) { + + // 修复:如果是触顶加载(isLoadHistory=true),强制 type 为 0,保持滚动位置 + // 只有在初始化加载时才滚动到底部(type=1 且 isLoadHistory=false) + const isHistoryLoad = this.isLoadHistory; + this.isLoadHistory = false; // 重置标记 + + const shouldScrollToBottom = type === 1 && !isHistoryLoad; + + if (shouldScrollToBottom) { this.scrollToBottom(); } else { + // 触顶加载时保持位置 this.scrollToOldLastMessage(); } }, @@ -1087,6 +1099,9 @@ export default { // Fix: Optimistic UI update - Add message locally immediately this.addMessage(fullMessage); + + // 发送消息后立即滚动到底部 + this.scrollToBottom(); // 注意:不调用 ChatManager.addMessageToRoom,避免触发 new-room-message 事件导致消息重复 // 服务器返回的消息会通过 WebSocket 触发 handleNewRoomMessage,由去重逻辑处理 @@ -1273,7 +1288,7 @@ export default { /** * 滚动到底部 - * 优化:先清空 scroll-into-view,使用 $nextTick 和适当延时,再设置 scroll-into-view + * 修复:优化滚动逻辑,确保 scroll-into-view 正确设置,增加延时确保 DOM 完全更新 * 根据文档,scroll-into-view 优先级高于 scroll-top,需要避免同时设置 */ scrollToBottom() { @@ -1286,7 +1301,14 @@ export default { setTimeout(() => { // 设置 scroll-into-view 为底部锚点,触发滚动 this.scrollIntoView = 'chat-bottom-anchor'; - }, 200); // 增加延时,等待图片等资源加载完成 + + // 如果第一次设置失败,再次尝试(确保滚动成功) + setTimeout(() => { + if (this.scrollIntoView !== 'chat-bottom-anchor') { + this.scrollIntoView = 'chat-bottom-anchor'; + } + }, 100); + }, 300); // 增加延时,确保 DOM 完全更新和图片等资源加载完成 }); }, @@ -1322,6 +1344,9 @@ export default { // 在加载历史消息前,记录当前滚动高度 this.getScrollHeight(); + // 标记为触顶加载 + this.isLoadHistory = true; + this.loading = true; try { if (typeof ChatManager !== 'undefined') {