feat: 调整
This commit is contained in:
@@ -124,7 +124,8 @@ const lookDetailAction = () => {
|
||||
} catch (e) {}
|
||||
});
|
||||
|
||||
uni.navigateTo({ url: `/pages/long-answer/index?streamId=${encodeURIComponent(streamId)}` });
|
||||
// 传递 finished 参数,完成状态下不自动滚到底部
|
||||
uni.navigateTo({ url: `/pages/long-answer/index?streamId=${encodeURIComponent(streamId)}&finished=${props.finish ? '1' : '0'}` });
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -49,14 +49,23 @@ const SCROLL_THRESHOLD = 150; // px
|
||||
const userInteracting = ref(false);
|
||||
let interactionTimer = null;
|
||||
|
||||
/** 是否已完成(从 URL 参数判断),完成状态下不初始初自动滚到底部 */
|
||||
let isFinishedOnInit = false;
|
||||
|
||||
/** ✅ 防抖 */
|
||||
let scrollTimer = null;
|
||||
|
||||
const measureScrollViewHeight = () => {
|
||||
try {
|
||||
const sys = uni.getSystemInfoSync() || {};
|
||||
// 使用窗口高度作为 scroll-view 可视高度的近似,兼容小程序环境
|
||||
scrollViewHeight.value = sys.windowHeight || 0;
|
||||
// 使用 uni.createSelectorQuery 获取 scroll-view 的准确高度
|
||||
uni.createSelectorQuery()
|
||||
.select(".chat-scroll")
|
||||
.boundingClientRect((rect) => {
|
||||
if (rect && rect.height) {
|
||||
scrollViewHeight.value = rect.height;
|
||||
}
|
||||
})
|
||||
.exec();
|
||||
} catch (e) { }
|
||||
}
|
||||
|
||||
@@ -69,31 +78,36 @@ const computeTitle = (text = "") => {
|
||||
const onScroll = (e) => {
|
||||
try {
|
||||
const { scrollTop = 0, scrollHeight = 0 } = e.detail || {};
|
||||
// 标记为用户主动滚动,短时内不触发自动滚动
|
||||
userInteracting.value = true;
|
||||
clearTimeout(interactionTimer);
|
||||
interactionTimer = setTimeout(() => (userInteracting.value = false), 1200);
|
||||
|
||||
// 更新距离底部的判断(使用 windowHeight 作为近似)
|
||||
const distanceToBottom = scrollHeight - (scrollTop + (scrollViewHeight.value || uni.getSystemInfoSync().windowHeight || 0));
|
||||
isNearBottom.value = distanceToBottom <= SCROLL_THRESHOLD;
|
||||
|
||||
// 计算距离底部的距离(使用准确的 scroll-view 高度)
|
||||
const viewHeight = scrollViewHeight.value;
|
||||
const distanceToBottom = scrollHeight - scrollTop - viewHeight;
|
||||
|
||||
// 判断是否在底部附近(允许 SCROLL_THRESHOLD 的误差范围)
|
||||
// 注意:只更新 isNearBottom,不在滚动时强制改变 userInteracting
|
||||
const atBottom = distanceToBottom <= SCROLL_THRESHOLD;
|
||||
isNearBottom.value = atBottom;
|
||||
} catch (e) { }
|
||||
}
|
||||
|
||||
const onTouchStart = () => {
|
||||
// 触摸开始时,立即标记为用户交互状态
|
||||
userInteracting.value = true;
|
||||
clearTimeout(interactionTimer);
|
||||
}
|
||||
|
||||
const onTouchEnd = () => {
|
||||
// 触摸结束后延迟一段时间再取消交互状态
|
||||
// 这样即使用户快速滚动,也不会被中途打断
|
||||
clearTimeout(interactionTimer);
|
||||
interactionTimer = setTimeout(() => {
|
||||
userInteracting.value = false;
|
||||
}, 800);
|
||||
}, 600);
|
||||
}
|
||||
|
||||
const scrollToBottom = () => {
|
||||
if (scrollTimer) return;
|
||||
if (isFinishedOnInit) return;
|
||||
|
||||
scrollTimer = setTimeout(() => {
|
||||
// ❗关键:强制触发滚动(小程序必须这样)
|
||||
@@ -118,7 +132,17 @@ const scrollToBottom = () => {
|
||||
}, 100);
|
||||
}
|
||||
|
||||
onLoad(({ message = "", streamId = "" }) => {
|
||||
onLoad(({ message = "", streamId = "", finished = "0" }) => {
|
||||
// 记录初始完成状态
|
||||
isFinishedOnInit = finished === "1";
|
||||
|
||||
console.log("LongAnswer onLoad with params:", { message, streamId, finished });
|
||||
|
||||
// 初次测量 scroll-view 高度
|
||||
nextTick(() => {
|
||||
measureScrollViewHeight();
|
||||
});
|
||||
|
||||
if (streamId) {
|
||||
// ✅ 流式数据
|
||||
unsubscribe = StreamManager.subscribe(
|
||||
@@ -128,10 +152,15 @@ onLoad(({ message = "", streamId = "" }) => {
|
||||
title.value = computeTitle(answerText.value);
|
||||
|
||||
nextTick(() => {
|
||||
// 仅在用户处于接近底部时自动滚动,避免每次流式更新都打断用户阅读
|
||||
// 每次接收数据都重新测量高度(content size 可能变化,比如加载图)
|
||||
measureScrollViewHeight();
|
||||
|
||||
// 流式完成时强制滚动到底部
|
||||
if (finished) {
|
||||
scrollToBottom();
|
||||
} else if (isNearBottom.value) {
|
||||
}
|
||||
// 流式中的数据更新:只有在用户未交互且接近底部时才自动滚动
|
||||
else if (!userInteracting.value && isNearBottom.value) {
|
||||
scrollToBottom();
|
||||
}
|
||||
});
|
||||
@@ -143,13 +172,10 @@ onLoad(({ message = "", streamId = "" }) => {
|
||||
title.value = computeTitle(answerText.value);
|
||||
|
||||
nextTick(() => {
|
||||
// 初始非流式情况仍保持自动滚动
|
||||
// 只有在初始化为非完成状态时才自动滚到底部
|
||||
scrollToBottom();
|
||||
});
|
||||
}
|
||||
|
||||
// 初次测量 scroll-view 高度
|
||||
nextTick(() => measureScrollViewHeight());
|
||||
});
|
||||
|
||||
onUnload(() => {
|
||||
|
||||
Reference in New Issue
Block a user