|
|
|
@ -4,6 +4,7 @@
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<title>东师理想教学大模型</title>
|
|
|
|
|
<link rel="icon" href="data:,">
|
|
|
|
|
<style>
|
|
|
|
|
body {
|
|
|
|
|
font-family: 'Microsoft YaHei', sans-serif;
|
|
|
|
@ -281,48 +282,83 @@
|
|
|
|
|
function submitQuestion() {
|
|
|
|
|
const question = document.getElementById('questionInput').value.trim();
|
|
|
|
|
const checkboxes = document.querySelectorAll('input[name="tags"]:checked');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!question) {
|
|
|
|
|
alert('请输入问题!');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (checkboxes.length === 0) {
|
|
|
|
|
alert('请至少选择一个原稿!');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const selectedDocs = Array.from(checkboxes).map(cb => cb.value);
|
|
|
|
|
const loader = document.getElementById('loader');
|
|
|
|
|
const answerArea = document.getElementById('answerArea');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
answerArea.innerHTML = '';
|
|
|
|
|
loader.style.display = 'block';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
|
query: question,
|
|
|
|
|
tags: selectedDocs
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
fetch('/api/rag', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
'Accept': 'text/event-stream'
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
query: question,
|
|
|
|
|
tags: selectedDocs
|
|
|
|
|
})
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
})
|
|
|
|
|
.then(response => response.json())
|
|
|
|
|
.then(data => {
|
|
|
|
|
if (data.reply) {
|
|
|
|
|
answerArea.innerHTML = marked.parse(data.reply);
|
|
|
|
|
MathJax.typeset();
|
|
|
|
|
localStorage.setItem('lastMarkdownContent', data.reply);
|
|
|
|
|
.then(response => {
|
|
|
|
|
const reader = response.body.getReader();
|
|
|
|
|
const decoder = new TextDecoder();
|
|
|
|
|
let buffer = '';
|
|
|
|
|
let accumulatedContent = '';
|
|
|
|
|
|
|
|
|
|
function processChunk() {
|
|
|
|
|
return reader.read().then(({done, value}) => {
|
|
|
|
|
if (done) {
|
|
|
|
|
loader.style.display = 'none';
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buffer += decoder.decode(value, {stream: true});
|
|
|
|
|
const lines = buffer.split('\n');
|
|
|
|
|
buffer = lines.pop();
|
|
|
|
|
|
|
|
|
|
for (const line of lines) {
|
|
|
|
|
if (line.includes('data:')) {
|
|
|
|
|
const jsonStr = line.replace(/^data:\s*/, '').replace(/^data:\s*/, '').trim();
|
|
|
|
|
if (jsonStr) {
|
|
|
|
|
try {
|
|
|
|
|
const data = JSON.parse(jsonStr);
|
|
|
|
|
if (data.reply) {
|
|
|
|
|
accumulatedContent += data.reply;
|
|
|
|
|
answerArea.innerHTML = marked.parse(accumulatedContent);
|
|
|
|
|
MathJax.typesetPromise();
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log('忽略解析错误:', e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return processChunk();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
loader.style.display = 'none';
|
|
|
|
|
|
|
|
|
|
return processChunk();
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
console.error('Error:', error);
|
|
|
|
|
loader.style.display = 'none';
|
|
|
|
|
});
|
|
|
|
|
}ai.html
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function clearAll() {
|
|
|
|
|
document.getElementById('questionInput').value = '';
|
|
|
|
|