Files
dsProject/dsLightRag/static/Math2.html
2025-08-14 15:45:08 +08:00

357 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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('什么是命题?')">
什么是命题?
</div>
<div class="example-item" onclick="fillExample('证明三角形两边之和大于第三边。')">
证明三角形两边之和大于第三边。
</div>
<div class="example-item" onclick="fillExample('在三角形ABC中任取一点P连接BP和PC形成三角形PBC证明∠BPC∠BAG。')">
在三角形ABC中任取一点P连接BP和PC形成三角形PBC证明∠BPC∠BAG。
</div>
<div class="example-item" onclick="fillExample('在三角形ABC中任取一点P连接BP和PC形成三角形PBC证明线段BA+ACBP+PC。')">
在三角形ABC中任取一点P连接BP和PC形成三角形PBC证明线段BA+ACBP+PC。
</div>
</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: 'Math2'
})
})
.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>