Skip to content

Commit d92f386

Browse files
committed
fix: 解决流程图输出闪烁的问题
1 parent dd8b398 commit d92f386

File tree

2 files changed

+39
-22
lines changed

2 files changed

+39
-22
lines changed

src/chatPanel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ export class ChatPanel {
261261

262262
private async callModelApi(message: any, webviewOutputChannel: WebviewOutputChannel): Promise<string | null> {
263263
const tools = message.webSearch ? [apiTools.searchTool] : null;
264-
const normalSystemPrompt = "用markdown输出。数学公式要用$$包裹,每条一行不要换行。流程图(Mermaid)里的每个字符串都要用引号包裹。";
264+
const normalSystemPrompt = "用markdown输出。如果有数学公式要用$$包裹,每条一行不要换行。如果有流程图(Mermaid)里的每个字符串都要用引号包裹。";
265265
const systemPrompt = message.webSearch
266266
? "每次回答问题前,一定要先上网搜索一下再回答。" + normalSystemPrompt
267267
: normalSystemPrompt;

src/resources/chatPanelScript.js

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -73,38 +73,55 @@ function fnRenderDisplayMath(webviewDiv) {
7373
webviewDiv.innerHTML = strReplacedHtml;
7474
}
7575

76-
// 渲染 Mermaid 图表
76+
// 全局 Mermaid 缓存
77+
window.mermaidCache = window.mermaidCache || [];
78+
7779
async function renderMermaid(webviewDiv) {
7880
const codeBlocks = webviewDiv.querySelectorAll('pre code.language-mermaid');
79-
let counter = 0; // 使用计数器确保唯一性
8081

81-
for (const codeBlock of codeBlocks) {
82+
// 创建渲染承诺数组
83+
const renderPromises = Array.from(codeBlocks).map(async (codeBlock, index) => {
8284
const parentPre = codeBlock.closest('pre');
8385
const mermaidCode = codeBlock.textContent;
8486
try {
85-
const diagramId = `mermaid-diagram-${counter++}-${performance.now()}`;
87+
const diagramId = `mermaid-diagram-${index}`;
8688
const { svg } = await mermaid.render(diagramId, mermaidCode);
87-
const mermaidDiv = document.createElement('div');
88-
mermaidDiv.className = 'mermaid';
89-
mermaidDiv.innerHTML = svg;
89+
// 更新全局缓存
90+
window.mermaidCache[index] = svg;
91+
return { index, svg, mermaidCode, parentPre };
92+
} catch (err) {
93+
console.error('Mermaid 渲染错误,索引', index, ':', err);
94+
// 使用缓存中的 SVG(如果存在)
95+
const cachedSvg = window.mermaidCache[index] || null;
96+
return { index, svg: cachedSvg, mermaidCode, parentPre };
97+
}
98+
});
9099

91-
const rawDiv = document.createElement('div');
92-
rawDiv.className = 'mermaid-raw';
93-
rawDiv.innerHTML = `<pre><code class="language-mermaid">${mermaidCode}</code></pre>`;
100+
// 等待所有渲染尝试完成
101+
const results = await Promise.all(renderPromises);
94102

95-
const container = document.createElement('div');
96-
container.className = 'mermaid-container';
97-
container.appendChild(mermaidDiv);
98-
container.appendChild(rawDiv);
103+
// 批量处理结果并更新 DOM
104+
for (const result of results) {
105+
const { svg, mermaidCode, parentPre } = result;
106+
const container = document.createElement('div');
107+
container.className = 'mermaid-container';
99108

100-
parentPre.replaceWith(container);
101-
} catch (err) {
102-
console.error('Mermaid render error:', err);
103-
const errorDiv = document.createElement('div');
104-
errorDiv.className = 'mermaid-error';
105-
errorDiv.textContent = 'Failed to render Mermaid diagram';
106-
parentPre.replaceWith(errorDiv);
109+
// 始终显示原始代码
110+
const rawDiv = document.createElement('div');
111+
rawDiv.className = 'mermaid-raw';
112+
rawDiv.innerHTML = `<pre><code class="language-mermaid">${mermaidCode}</code></pre>`;
113+
container.appendChild(rawDiv);
114+
115+
// 如果有 SVG(渲染成功或缓存),则添加
116+
if (svg) {
117+
const mermaidDiv = document.createElement('div');
118+
mermaidDiv.className = 'mermaid';
119+
mermaidDiv.innerHTML = svg;
120+
container.insertBefore(mermaidDiv, rawDiv);
107121
}
122+
123+
// 替换原始 pre 标签
124+
parentPre.replaceWith(container);
108125
}
109126
}
110127

0 commit comments

Comments
 (0)