You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

343 lines
11 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<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;
margin: 0;
padding: 0;
background-color: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
h1 {
color: #333;
text-align: center;
}
.data-area {
background-color: white;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.input-area {
background-color: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
textarea {
width: 100%;
height: 40px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
resize: none;
margin-bottom: 10px;
margin-right: 20px;
}
button {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
margin-right: 10px;
}
button:hover {
background-color: #45a049;
}
#clearBtn {
background-color: #f44336;
}
#clearBtn:hover {
background-color: #d32f2f;
}
#saveWordBtn {
background-color: #2196F3;
}
.icon {
margin-right: 5px;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.doc-links {
display: flex;
gap: 20px;
margin: 20px 0;
align-items: center;
}
.doc-checkboxes {
display: flex;
gap: 20px;
margin-bottom: 10px;
}
.doc-checkboxes label {
display: flex;
align-items: center;
gap: 5px;
cursor: pointer;
}
.examples {
margin: 20px 0;
}
.example-category {
margin-bottom: 15px;
}
.example-category h3 {
margin-bottom: 10px;
color: #333;
}
.example-list {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.example-item {
padding: 8px 12px;
background-color: #e9f5ff;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
}
.example-item:hover {
background-color: #d0e3fa;
}
.input-area textarea#questionInput {
margin-right: 10px !important;
width: calc(100% - 10px);
box-sizing: border-box;
}
#answerArea {
min-height: 240px;
height: auto;
overflow-y: auto;
}
.loading-animation {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 200px;
color: #666;
}
.spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="container">
<h1>【几何】教学大模型</h1>
<div class="data-area" id="answerArea">
<div style="color:#666; padding:20px; text-align:center;">
<p>请在下方输入您的问题,答案将在此处显示</p>
<p>您也可以点击"示例问题"快速体验</p>
</div>
</div>
<div class="input-area">
<label for="questionInput"></label><textarea id="questionInput" placeholder="请输入您的问题..."></textarea>
<div class="examples">
<div class="example-category">
<h3>已收集问题示例</h3>
<div class="example-list">
<div class="example-item" onclick="fillExample('三角形中两边之和大于第三边的证明')">
三角形中两边之和大于第三边的证明?
</div>
<div class="example-item"
onclick="fillExample('求证在三角形ABC中P为其内部任意一点。请证明∠BPC > ∠A。')">
求证在三角形ABC中P为其内部任意一点。请证明∠BPC > ∠A。
</div>
</div>
</div>
</div>
<button id="submitBtn" onclick="submitQuestion()"><span class="icon">💡</span>提问</button>
<button id="clearBtn" onclick="clearAll()"><span class="icon">🗑️</span>清空</button>
</div>
<script>
// 在页面加载时显示加载动画
document.addEventListener('DOMContentLoaded', function () {
const answerArea = document.getElementById('answerArea');
answerArea.innerHTML = '<div class="loading-animation"><div class="spinner"></div><div>正在加载资源...</div></div>';
// 禁用所有按钮
const buttons = document.querySelectorAll('button');
buttons.forEach(btn => btn.disabled = true);
});
MathJax = {
loader: {load: ['[tex]/mhchem']},
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']],
displayMath: [['$$', '$$'], ['\\[', '\\]']],
packages: {'[+]': ['mhchem']}
},
options: {
enableMenu: false,
processHtmlClass: 'tex2jax_process',
ignoreHtmlClass: 'tex2jax_ignore'
},
svg: {
fontCache: 'global'
},
startup: {
pageReady: () => {
return MathJax.startup.defaultPageReady().then(() => {
console.log('MathJax initialized');
// 移除加载动画并启用所有按钮
const answerArea = document.getElementById('answerArea');
answerArea.innerHTML = '<div style="color:#666; padding:20px; text-align:center;"><p>请在下方输入您的问题,答案将在此处显示</p><p>您也可以点击"示例问题"快速体验</p></div>';
const buttons = document.querySelectorAll('button');
buttons.forEach(btn => btn.disabled = false);
return MathJax.typesetPromise();
});
}
}
};
// marked配置
const markedOptions = {
mangle: false,
headerIds: false
};
function fillExample(question) {
document.getElementById('questionInput').value = question;
}
function submitQuestion() {
const question = document.getElementById('questionInput').value.trim();
const answerArea = document.getElementById('answerArea');
if (!question) {
alert('请输入问题!');
return;
}
// 添加加载动画
answerArea.innerHTML = '<div class="loading-animation"><div class="spinner"></div><div>思考中...</div></div>';
fetch('/api/rag', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'text/event-stream'
},
body: JSON.stringify({
query: question,
topic: 'JiHe'
})
})
.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) 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, markedOptions);
MathJax.typesetPromise();
// 自动滚动到底部
answerArea.scrollTop = answerArea.scrollHeight;
}
} catch (e) {
console.log('忽略解析错误:', e);
}
}
}
}
return processChunk().then(() => {
// 在流处理完成后保存完整的markdown内容
localStorage.setItem('lastMarkdownContent', accumulatedContent);
});
});
}
return processChunk();
})
.catch(error => {
// 移除加载动画
answerArea.innerHTML = '';
console.error('Error:', error);
// 出错时也移除加载动画
answerArea.innerHTML = '<div style="color:red">请求出错,请重试</div>';
});
}
function clearAll() {
document.getElementById('questionInput').value = '';
document.getElementById('answerArea').innerHTML = '';
}
</script>
<script src="/static/mathjax/es5/tex-mml-chtml.js" id="MathJax-script" async></script>
<script src="/static/js/marked.min.js"></script>
</body>
</html>