Files
YGChatCS/src/pages/long-answer/index.vue

104 lines
2.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="flex flex-col bg-liner h-screen overflow-hidden">
<!-- 顶部固定导航 -->
<view class="flex-shrink-0">
<TopNavBar :title="title" background="transparent" />
</view>
<!-- 滚动区域 -->
<scroll-view class="flex-full overflow-hidden" scroll-y :scroll-into-view="scrollIntoViewId" scroll-with-animation>
<view class="pt-12 px-12 pb-24 border-box">
<!-- 答案内容支持markdown -->
<ChatMarkdown :text="answerText" />
<!-- 底部锚点必须存在 -->
<view id="bottom-anchor"></view>
</view>
</scroll-view>
</view>
</template>
<script setup>
import TopNavBar from "@/components/TopNavBar/index.vue";
import ChatMarkdown from "../index/components/chat/ChatMarkdown/index.vue";
import { defineProps, ref, nextTick } from "vue";
import { onLoad, onUnload } from "@dcloudio/uni-app";
import StreamManager from "@/utils/StreamManager.js";
const props = defineProps({
answerText: {
type: String,
default: "",
},
});
const answerText = ref(props.answerText || "");
const title = ref("");
let unsubscribe = null;
/** ✅ scroll-into-view 控制 */
const scrollIntoViewId = ref("");
/** ✅ 防抖 */
let scrollTimer = null;
function scrollToBottom() {
if (scrollTimer) return;
scrollTimer = setTimeout(() => {
// ❗关键:强制触发滚动(小程序必须这样)
scrollIntoViewId.value = "";
nextTick(() => {
// 再次 nextTick + 延迟,兼容 markdown 渲染延迟
setTimeout(() => {
scrollIntoViewId.value = "bottom-anchor";
}, 50);
});
scrollTimer = null;
}, 100);
}
onLoad(({ message = "", streamId = "" }) => {
if (streamId) {
// ✅ 流式数据
unsubscribe = StreamManager.subscribe(
streamId,
(text = "", finished = false) => {
answerText.value = text || "";
if (answerText.value.length > 6) {
title.value = answerText.value.substring(0, 6) + "...";
}
nextTick(() => {
scrollToBottom();
});
}
);
} else {
// ✅ 非流式
answerText.value = decodeURIComponent(message || "");
if (answerText.value.length > 6) {
title.value = answerText.value.substring(0, 6) + "...";
}
nextTick(() => {
scrollToBottom();
});
}
});
onUnload(() => {
try {
unsubscribe && unsubscribe();
} catch (e) { }
});
</script>
<style scoped>
</style>