From c55c46bfab26889331b34f890658d770c5598ff4 Mon Sep 17 00:00:00 2001 From: huangzhe Date: Mon, 4 Aug 2025 17:40:17 +0800 Subject: [PATCH] =?UTF-8?q?bug:=20md=20container=20=E5=8D=A1=E9=A1=BF?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/AI-new/components/chat-new.vue | 34 +++++++++--------- .../components/js/markdown-it-container.js | 36 ++++++++++--------- src/views/AI-new/components/js/markdown-it.js | 4 +-- src/views/AI-new/components/message.vue | 26 +++++++++----- 4 files changed, 55 insertions(+), 45 deletions(-) diff --git a/src/views/AI-new/components/chat-new.vue b/src/views/AI-new/components/chat-new.vue index 8183d96..e0ef97c 100644 --- a/src/views/AI-new/components/chat-new.vue +++ b/src/views/AI-new/components/chat-new.vue @@ -208,11 +208,8 @@ export default { axiosGetAiChat() { const abortController = new AbortController() this.requestSingle = abortController - this.messageInfo.information = this.genMessage.information || this.newMessage - - // 重置 answerMap + this.messageInfo.information = (this.genMessage && this.genMessage.information) || this.newMessage this.answerMap = '' - // this.typingQueue = [] this.currentMessage = JSON.parse(JSON.stringify(this.messageInfo)) const params = { appType: "gwcsHelper2", @@ -232,11 +229,12 @@ export default { isDisLike: false, } if (this.genMessage) { - this.$set(this.messages, this.messages.length - 1, this.genMessage = { ...this.currentMessage }) + // this.$set(this.messages, this.messages.length - 1, this.genMessage = { ...this.currentMessage }) + this.messages.push({ ...this.currentMessage }) } else { this.messages.push(this.currentMessage) } - // 如果有自定义参数 + // 自定义参数 if (this.chatData) { for (let k in this.chatData) { params[k] = this.chatData[k] @@ -291,8 +289,6 @@ export default { this.$emit('update:conversationId', data.conversation_id) if (data.answer) { - this.answerMap += data.answer - let completeInformation = {} let textContent = '' @@ -309,7 +305,7 @@ export default { textContent = text[1].trim() } - console.log(`completeInformation: ${JSON.stringify(completeInformation)}, textContent: ${textContent}`); + // console.log(`completeInformation: ${JSON.stringify(completeInformation)}, textContent: ${textContent}`); } catch (e) { console.log(e); @@ -318,10 +314,12 @@ export default { if (!completeInformation && !textContent) { return null } - + console.log(`textContent: ${textContent}`); + + this.answerMap += textContent const { information, is_complete } = completeInformation - this.messageInfo.information = information ? information : this.newMessage + this.messageInfo.information = information this.messageInfo.is_complete = is_complete && is_complete.toString() if (is_complete) { @@ -329,9 +327,8 @@ export default { this.requestIndex++ return null } + return this.updateConversationState(data) } - - return this.updateConversationState(data) } catch (error) { console.error('流数据解析失败:', error) return null @@ -360,7 +357,7 @@ export default { }, updateMessageContent(parse, requestIndex) { let { event, answer, isThink, message_id } = parse - this.currentMessageID = message_id + // this.currentMessageID = message_id if (!this.currentMessage || !answer) return if (event !== 'message') return @@ -387,20 +384,23 @@ export default { // 取出一个完整文本块 const chunk = this.typingQueue.shift() const chars = Array.from(chunk.answer) - - const isThink = chunk.isThink + // const isThink = chunk.isThink // 内部递归函数,用于逐字输出当前块 const outputChar = () => { if (chars.length === 0) { // 当前块输出完毕,继续处理下一个 - setTimeout(typeNextChar, 10) + setTimeout(typeNextChar, 100) return } const char = chars.shift() || '' + // console.log(`char`, char); + if (requestIndex === 2) { this.$set(this.genMessage, 'text', this.genMessage.text + char) + // this.$forceUpdate() } if (requestIndex === 1) { this.$set(this.currentMessage, 'text', this.currentMessage.text + char) + // this.$forceUpdate() } const delay = this.getTypingDelay(char) setTimeout(outputChar, delay) diff --git a/src/views/AI-new/components/js/markdown-it-container.js b/src/views/AI-new/components/js/markdown-it-container.js index 1df8267..170bb5e 100644 --- a/src/views/AI-new/components/js/markdown-it-container.js +++ b/src/views/AI-new/components/js/markdown-it-container.js @@ -3,9 +3,6 @@ import Vue from "vue"; import KnowledgeCard from "../card/index.vue" export function markdownContainer(markdownIt) { - // console.log(markdownIt); - // console.log(container); - container(markdownIt, "card", { validate: function (params) { // console.log(params.trim(), "title line"); @@ -14,9 +11,12 @@ export function markdownContainer(markdownIt) { }, render: function (tokens, idx) { // console.log(`tokens, idx`, tokens, idx); - return tokens[idx].content + // return tokens[idx].content + // return "
--------
" + }, content: function (tokens, idx, options, env, self) { +console.log(tokens[idx]); // console.log(`args`, tokens, idx, options, env, self); @@ -25,22 +25,24 @@ export function markdownContainer(markdownIt) { // const { markup } = tokens[idx] // console.log(`markup`, markup); - setTimeout(() => { - const dom = document.getElementById("cardTest"); - // if (dom) return - // const vm = new Vue({ - // el: "#cardTest", - // render: h => h(KnowledgeCard, { - // props: { - // content: tokens[idx] - // } - // }) - // }) - // console.log(`vue instance`, vm); - }) + // setTimeout(() => { + // const dom = document.getElementById("cardTest"); + // if (dom) return + // const vm = new Vue({ + // el: "#cardTest", + // render: h => h(KnowledgeCard, { + // props: { + // content: tokens[idx] + // } + // }) + // }) + // console.log(`vue instance`, vm); + // }) // return tokens[idx] // return "
" + // console.log(tokens[idx].markup); + return tokens[idx].markup } }) diff --git a/src/views/AI-new/components/js/markdown-it.js b/src/views/AI-new/components/js/markdown-it.js index 3bb7a93..6e71f13 100644 --- a/src/views/AI-new/components/js/markdown-it.js +++ b/src/views/AI-new/components/js/markdown-it.js @@ -4,7 +4,7 @@ import { markdownContainer } from './markdown-it-container' export const md = new MarkdownIt({ html: true, + breaks: true, linkify: true, typographer: true - }).use(markdownItKatex).use(markdownContainer) - \ No newline at end of file + }).use(markdownItKatex).use(markdownContainer) \ No newline at end of file diff --git a/src/views/AI-new/components/message.vue b/src/views/AI-new/components/message.vue index 1d9b9cc..8313057 100644 --- a/src/views/AI-new/components/message.vue +++ b/src/views/AI-new/components/message.vue @@ -48,7 +48,10 @@ // icon import { Icon } from 'vant' import TreasureBox from '@/views/AI/components/treasureBox.vue' -import { md } from './js/markdown-it' +// import { md } from './js/markdown-it' +import MarkdownIt from 'markdown-it' +import markdownItKatex from 'markdown-it-katex' +import { markdownContainer } from './js/markdown-it-container' export default { @@ -70,16 +73,21 @@ export default { }, data() { return { - md, primaryColor: '#57a6fc' } }, methods: { render(message) { - const text = this.filterVisible(message) - // console.log(`text`, text); - return md.render(text) + const md = new MarkdownIt({ + html: true, + breaks: true, + linkify: true, + typographer: true + }).use(markdownItKatex).use(markdownContainer) + + + return md.render(message.text) }, setProductName(e) { this.$emit('setProductName', e) @@ -89,15 +97,15 @@ export default { // 如果开头是中文,直接返回 // if (new RegExp('^[\u4e00-\u9fa5]+', 'g').test(text)) return text - text = text.replace(/([^<]*)(?:<\/information>)?/g, '').trim() - text = text.replace(/([^<]*)(?:<\/is_complete>)?/g, '').trim() + // text = text.replace(/([^<]*)(?:<\/information>)?/g, '').trim() + // text = text.replace(/([^<]*)(?:<\/is_complete>)?/g, '').trim() // 捕获 不包含 < 的后置标签 span> /span> a - text = text.replace(/^[/]?[a-zA-z0-9]+[]+/g, '').trim() + // text = text.replace(/^[/]?[a-zA-z0-9]+[]+/g, '').trim() // // 尝试匹配 标签 // text = text.replace(/^<\w+>/g, '').trim() // text = text.replace(/^\w+/, "").trim() - text = text.replace(/<\/?([\w\s='"]+)?(?!>)$/gi, '').trim() + // text = text.replace(/<\/?([\w\s='"]+)?(?!>)$/gi, '').trim() // console.log(`text`, text[text.length - 1]); return text