From 5e21938d066a9bd3bf0d1c1e515447399de9380a Mon Sep 17 00:00:00 2001 From: zoujing Date: Fri, 3 Apr 2026 16:05:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=95=BF=E6=96=87=E6=9C=AC=E5=9C=A8?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E9=9D=A2=E4=B8=AD=E7=9A=84=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=B5=81=E5=BC=8F=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/chat/ChatMainList/index.vue | 3 +- .../module/AnswerComponent/index.vue | 37 ++++++- src/pages/long-answer/index.vue | 96 ++++++++++++++++--- src/utils/StreamManager.js | 52 ++++++++++ 4 files changed, 171 insertions(+), 17 deletions(-) create mode 100644 src/utils/StreamManager.js diff --git a/src/pages/index/components/chat/ChatMainList/index.vue b/src/pages/index/components/chat/ChatMainList/index.vue index 81a283d..6bb584d 100644 --- a/src/pages/index/components/chat/ChatMainList/index.vue +++ b/src/pages/index/components/chat/ChatMainList/index.vue @@ -10,7 +10,8 @@ :scroll-with-animation="true" @scroll="handleScroll" @scrolltolower="handleScrollToLower"> - + + diff --git a/src/pages/long-answer/index.vue b/src/pages/long-answer/index.vue index 8326c80..c39a694 100644 --- a/src/pages/long-answer/index.vue +++ b/src/pages/long-answer/index.vue @@ -1,32 +1,104 @@ + \ No newline at end of file +onUnload(() => { + try { + unsubscribe && unsubscribe(); + } catch (e) { } +}); + + + \ No newline at end of file diff --git a/src/utils/StreamManager.js b/src/utils/StreamManager.js new file mode 100644 index 0000000..b98e08b --- /dev/null +++ b/src/utils/StreamManager.js @@ -0,0 +1,52 @@ +// 简单的流式数据管理器:开启流、更新流、订阅流、关闭流 +const streams = {}; + +function openStream(id, initial = '', finished = false) { + if (!id) return; + streams[id] = streams[id] || { text: '', finished: false, subs: new Set() }; + streams[id].text = initial || ''; + streams[id].finished = !!finished; + // notify existing subscribers + streams[id].subs.forEach((cb) => cb(streams[id].text, streams[id].finished)); +} + +function updateStream(id, text, finished = false) { + if (!id || !streams[id]) return; + streams[id].text = text || ''; + streams[id].finished = !!finished; + streams[id].subs.forEach((cb) => cb(streams[id].text, streams[id].finished)); +} + +function subscribe(id, cb) { + if (!id) return () => {}; + streams[id] = streams[id] || { text: '', finished: false, subs: new Set() }; + streams[id].subs.add(cb); + // send current snapshot immediately + cb(streams[id].text, streams[id].finished); + return () => { + streams[id] && streams[id].subs.delete(cb); + // 移除空流 + if (streams[id] && streams[id].subs.size === 0 && streams[id].finished) { + delete streams[id]; + } + }; +} + +function closeStream(id) { + if (!id || !streams[id]) return; + streams[id].subs.forEach((cb) => cb(streams[id].text, true)); + delete streams[id]; +} + +function getSnapshot(id) { + if (!id || !streams[id]) return { text: '', finished: false }; + return { text: streams[id].text, finished: streams[id].finished }; +} + +export default { + openStream, + updateStream, + subscribe, + closeStream, + getSnapshot, +};