增加了AI chat中对markdown内容的渲染

This commit is contained in:
2025-01-15 05:28:49 +00:00
parent f67a6b23fd
commit d4084afb6b
+45 -14
View File
@@ -1178,7 +1178,7 @@
<div class="d-flex align-items-start">
<div class="me-2">🤖</div>
<div class="bg-primary bg-opacity-10 rounded p-2 flex-grow-1">
${chat.answer}
<pre><code>${processMarkdownContent(chat.answer)}</code></pre>
</div>
</div>
<div class="text-end text-muted small mt-1">
@@ -1187,7 +1187,6 @@
</div>
`).join('');
// Scroll to bottom
chatHistory.scrollTop = chatHistory.scrollHeight;
} catch (error) {
@@ -1196,6 +1195,35 @@
}
}
function processMarkdownContent(content) {
try {
// 如果内容是JSON字符串,先解析它
if (typeof content === 'string' && content.startsWith('"') && content.endsWith('"')) {
content = JSON.parse(content);
}
// 处理可能的嵌套代码块缩进,但不添加最外层的markdown包装
content = content.replace(/```(\w+)\n([\s\S]*?)```/g, (match, lang, code) => {
// 为代码块添加缩进
const indentedCode = code.split('\n').map(line => line).join('\n');
return '```' + lang + '\n' + indentedCode + '\n```';
});
// 转义HTML特殊字符以正确显示
content = content
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
return content;
} catch (e) {
console.error('Error processing markdown content:', e);
return content;
}
}
// Send question function
async function sendQuestion(referenceId) {
const input = document.getElementById('questionInput');
@@ -1209,12 +1237,10 @@
const sendButton = input.nextElementSibling;
try {
// 清空输入并禁用输入框和发送按钮
input.value = '';
input.disabled = true;
sendButton.disabled = true;
// First, add the user's question to chat history
const questionDiv = document.createElement('div');
questionDiv.className = 'mb-3';
questionDiv.innerHTML = `
@@ -1227,7 +1253,6 @@
`;
chatHistory.appendChild(questionDiv);
// Then add the loading indicator
const loadingDiv = document.createElement('div');
loadingDiv.className = 'd-flex align-items-start mb-3';
loadingDiv.innerHTML = `
@@ -1245,7 +1270,6 @@
chatHistory.appendChild(loadingDiv);
chatHistory.scrollTop = chatHistory.scrollHeight;
// 发送问题并获取任务ID
const response = await fetch(`${API_BASE_URL}/references/${referenceId}/qa`, {
method: 'POST',
headers: {
@@ -1261,7 +1285,6 @@
const { task_id } = await response.json();
// 轮询获取任务结果
let result;
while (true) {
const taskResponse = await fetch(`${API_BASE_URL}/task/${task_id}`, {
@@ -1283,24 +1306,20 @@
throw new Error(taskResult.error || 'Task failed');
}
// 等待1秒后再次查询
await new Promise(resolve => setTimeout(resolve, 1000));
}
// Remove loading indicator
loadingDiv.remove();
// Add AI's answer
const answerDiv = document.createElement('div');
answerDiv.className = 'd-flex align-items-start mb-3';
answerDiv.innerHTML = `
<div class="me-2">🤖</div>
<div class="bg-primary bg-opacity-10 rounded p-2 flex-grow-1">
${result.answer}
<pre><code>${processMarkdownContent(result.answer)}</code></pre>
</div>
`;
// Add timestamp
const timestampDiv = document.createElement('div');
timestampDiv.className = 'text-end text-muted small mt-1 mb-3';
timestampDiv.textContent = new Date().toLocaleString();
@@ -1322,15 +1341,27 @@
chatHistory.appendChild(errorDiv);
chatHistory.scrollTop = chatHistory.scrollHeight;
} finally {
// 重新启用输入框和发送按钮
input.disabled = false;
sendButton.disabled = false;
// 将焦点返回到输入框,但不强制聚焦
if (document.activeElement === document.body) {
input.focus();
}
}
}
// 添加一些基本的样式
const style = document.createElement('style');
style.textContent = `
pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
}
code {
font-family: Consolas, Monaco, 'Andale Mono', monospace;
}
`;
document.head.appendChild(style);
</script>
</body>
</html>