From c7a37e681617a1e45b370c5c28ed92095d591bc7 Mon Sep 17 00:00:00 2001 From: zoujing Date: Wed, 4 Mar 2026 22:20:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B6=88=E6=81=AF=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E7=9A=84=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 2 +- src/renderer/views/home/ChatBox.vue | 5 ++-- .../views/home/components/ChatRoleAI.vue | 23 ++++++++++++++++++- src/renderer/views/home/model/ChatModel.ts | 4 ++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 8576aba..21d952d 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ diff --git a/src/renderer/views/home/ChatBox.vue b/src/renderer/views/home/ChatBox.vue index 0fbe242..b391c1d 100644 --- a/src/renderer/views/home/ChatBox.vue +++ b/src/renderer/views/home/ChatBox.vue @@ -417,7 +417,6 @@ const handleWebSocketMessage = (data: any) => { } if (data.type === 'heartbeat') { - console.log("收到心跳消息:", data); return; } @@ -467,10 +466,12 @@ const handleWebSocketMessage = (data: any) => { if (chatMsgList.value[aiMsgIndex].isLoading) { // 首次收到内容:替换“加载中”文案并取消 loading 状态(恢复原始渲染逻辑) chatMsgList.value[aiMsgIndex].messageContent = data.content; + chatMsgList.value[aiMsgIndex].messageContentList = [data.content]; chatMsgList.value[aiMsgIndex].isLoading = false; } else { // 后续流式内容追加 chatMsgList.value[aiMsgIndex].messageContent += data.content; + chatMsgList.value[aiMsgIndex].messageContentList.push(data.content); } nextTick(() => scrollToBottom()); } @@ -492,7 +493,7 @@ const handleWebSocketMessage = (data: any) => { chatMsgList.value[aiMsgIndex].messageContent = ""; } } - + // 处理toolCall if (data.toolCall) { chatMsgList.value[aiMsgIndex].toolCall = data.toolCall; diff --git a/src/renderer/views/home/components/ChatRoleAI.vue b/src/renderer/views/home/components/ChatRoleAI.vue index 3ddac92..01b70eb 100644 --- a/src/renderer/views/home/components/ChatRoleAI.vue +++ b/src/renderer/views/home/components/ChatRoleAI.vue @@ -1,10 +1,16 @@ @@ -23,6 +29,9 @@ interface Props { const { msg } = defineProps() const md = new MarkdownIt({ + html: true, + linkify: true, + typographer: true, highlight: function (str: string, lang: string) { if (lang && hljs.getLanguage(lang)) { try { @@ -33,6 +42,18 @@ const md = new MarkdownIt({ return hljs.highlightAuto(str).value; } }); + const compiledMarkdown = computed(() => md.render(msg.messageContent)) +const compiledList = computed(() => { + return (msg.messageContentList || []).map((m: string) => md.render(m || '')) +}) + +const compiledAt = (index: number): string => { + const list: string[] = (compiledList as any).value || [] + if (list[index]) return list[index] + const raw = msg?.messageContentList?.[index] || '' + return md.render(raw || '') +} + \ No newline at end of file diff --git a/src/renderer/views/home/model/ChatModel.ts b/src/renderer/views/home/model/ChatModel.ts index 2955c9c..3354c76 100644 --- a/src/renderer/views/home/model/ChatModel.ts +++ b/src/renderer/views/home/model/ChatModel.ts @@ -16,6 +16,8 @@ export class ChatMessage { messageRole: MessageRole; // 消息内容 messageContent: string; + // 消息内容列表(用于流式更新) + messageContentList: string[]; // 是否加载中 isLoading?: boolean; // 是否完成 @@ -31,6 +33,7 @@ export class ChatMessage { messageId: string, messageRole: MessageRole, messageContent: string, + messageContentList: string[] = [], isLoading: boolean = false, finished: boolean = false, toolCall?: any, @@ -40,6 +43,7 @@ export class ChatMessage { this.messageId = messageId; this.messageRole = messageRole; this.messageContent = messageContent; + this.messageContentList = messageContentList; this.isLoading = isLoading; this.finished = finished; this.toolCall = toolCall;