ソースを参照

fix:优化对话信息的渲染逻辑

yangyi 5 ヶ月 前
コミット
b9fc2f90fb

+ 1 - 2
src/api/conversation.ts

@@ -116,9 +116,8 @@ export const sendMessage = async (
   while (true) {
     const { value, done } = await reader.read();
     if (done) break;
-    console.log(buffer)
-    buffer += decoder.decode(value, { stream: true });
     
+    buffer += decoder.decode(value, { stream: true });
     // 按行解析 SSE
     const lines = buffer.split("\n");
     buffer = lines.pop() || ""; // 保留未完整解析的部分

+ 6 - 0
src/components/common/ai/MessageBubble.vue

@@ -24,6 +24,7 @@
 <script setup lang="ts">
 import { computed } from 'vue';
 import MarkdownRenderer from './MarkdownRenderer.vue'
+import {render} from '@/utils/render'
 
 const props = defineProps<{
   message: {
@@ -33,6 +34,11 @@ const props = defineProps<{
   }
 }>()
 const isUser = computed(() => props.message.sender === 'user')
+const renderHandler = (content:string)=>{
+  console.log(content);
+  let html = render(JSON.parse(content));
+  return html;
+}
 </script>
 
 <style scoped>

+ 6 - 0
src/types/chatConversation.ts

@@ -18,3 +18,9 @@ export interface ChatConversationState extends ConversationState {
   conversationList: ChatConversationItem[];
   currentConversationMessages: Message[];
 }
+
+export interface ResultData{
+  conclusion:string;//结论
+  data:string;//数据代码,table的代码或者echarts的option配置对象代码
+  status:1|2;//1:table的代码;2:echarts的option配置对象代码
+}

+ 49 - 0
src/utils/render.ts

@@ -0,0 +1,49 @@
+import { marked } from 'marked'
+import * as echarts from 'echarts';
+import { ResultData } from '@/types/chatConversation';
+//渲染markdown
+export const renderMarkDown = (text:string)=>{
+    let html = undefined;
+    try{
+        html = marked.parse(text);
+    }catch(e){
+        return text;
+    }
+    
+    return html;
+}
+//渲染echarts图表
+export const renderEcharts = (optionJson:string)=>{
+    let option = undefined;
+    try{
+        option = JSON.parse(optionJson);
+    }catch(e){
+        return optionJson;
+    }
+    
+    if(option.option){
+        //防止套了两层
+        option = option.option;
+    }
+    let div = document.createElement('div');
+    let echart = echarts.init(div);
+    echart.dispose();
+    echart.setOption(option);
+    //获取html代码
+    let html = div;
+    return html;
+}
+//渲染
+export const render = (result:ResultData)=>{
+    let html = result.conclusion;
+    html += '<br>'
+    if(result.status === 1){
+        //表格
+        let table = renderMarkDown(result.data);
+        html += table;
+    }else{
+        let charts = renderEcharts(result.data);
+        html += charts;
+    }
+    return html;
+}

+ 21 - 40
src/views/main/ChatView.vue

@@ -7,8 +7,8 @@ import { abortConversation, getConversationHistory, sendMessage, SSEData } from
 import useConversationStore from '@/stores/chatConversation';
 import { useRoute, useRouter } from 'vue-router';
 import formatDate from '@/utils/formatDate';
-import { marked } from 'marked'
-import * as echarts from 'echarts';
+import { ResultData } from '@/types/chatConversation';
+import {render} from '@/utils/render'
 const router = useRouter()
 const route = useRoute()
 const conversationStore = useConversationStore()
@@ -49,11 +49,19 @@ watch(() => route.query.conversationId, async (newVal) => {
 
         // 获取会话消息
         const messagesRes = await getConversationMessages(newVal) as Message1[];
-        const filteredMessages = messagesRes.map((item) => ({
+        const filteredMessages = messagesRes.map((item) => {
+            
+            let message = {
             text: item.content,
             sender: item.role === 1 ? "user":"ai",
             sentAt: item.timestamp
-        }));
+            }
+            if(item.role != 1){
+                //渲染ai返回的信息
+                message.text = render(JSON.parse(item.content));
+            }
+        return message;
+        });
         // 更新会话消息
         conversationStore.currentConversationMessages = filteredMessages;
 
@@ -81,11 +89,6 @@ interface Message1 {
     conversationId: string;
 
 }
-interface ResultData{
-            conclusion:string;//结论
-            data:string;//数据代码,table的代码或者echarts的option配置对象代码
-            status:1|2;//1:table的代码;2:echarts的option配置对象代码
-        }
 
 
 // 组件状态
@@ -155,7 +158,7 @@ const handleEnterPress = async (e: KeyboardEvent) => {
         return // Shift + Enter 换行
     }
     // console.log(inputMessage.value.trim());
-    console.log(e);
+    
 
     //业务逻辑有问题:输入第二个字符后就发送了 :solved
     if (inputMessage.value.trim() && e.key === "Enter") {
@@ -295,12 +298,19 @@ const handleUserMessage = async (text: string) => {
                 if(sseData.status != 0){
                     //进度提示信息
                     newAiMessage.value.text += sseData.content + '<br>'
+                    // let result:ResultData = {
+                    //     conclusion:
+                    // }
                 }else{
                     //最终结果
-                let result:ResultData = JSON.parse(sseData.content);
+                    console.log(sseData.content,2);
+                    let result:ResultData = JSON.parse(sseData.content);
+                    console.log(result,4);
                     let html = render(result);
+                    console.log(html,3)
                     newAiMessage.value.text = html;
                     // newAiMessage.value.text = result.conclusion;
+                    // newAiMessage.value.text = sseData.content;
                 }
                 
                 await scrollToBottom()
@@ -347,35 +357,6 @@ const showInp = computed(() => {
         return false
     }
 })
-//渲染markdown
-const renderMarkDown = (text:string)=>{
-    let html = marked.parse(text);
-    return html;
-}
-//渲染echarts图表
-const renderEcharts = (optionJson:string)=>{
-    let option = JSON.parse(optionJson);
-    let div = document.createElement('div');
-    let echart = echarts.init(div);
-    echart.dispose();
-    echart.setOption(JSON.parse(option));
-    //获取html代码
-    let html = div;
-    return html;
-}
-//渲染
-const render = (result:ResultData)=>{
-    let html = result.conclusion;
-    if(result.status === 1){
-        //表格
-        let table = renderMarkDown(result.data);
-        html += table;
-    }else{
-        let charts = renderEcharts(result.data);
-        html += charts;
-    }
-    return html;
-}
 </script>
 
 <template>