This commit is contained in:
2025-09-01 11:54:56 +08:00
parent 0e1870c9fa
commit d7e5b1f312

View File

@@ -25,38 +25,6 @@
background-color: #f5f5f5; background-color: #f5f5f5;
} }
.tab-container {
display: flex;
border-bottom: 1px solid #ccc;
margin-bottom: 20px;
}
.tab-button {
padding: 10px 20px;
border: none;
background: #f1f1f1;
cursor: pointer;
transition: all 0.3s ease;
}
.tab-button.active {
background: #4CAF50;
color: white;
}
.tab-button:hover:not(.active) {
background: #ddd;
}
.tab-content {
display: none;
padding: 10px;
}
.tab-content.active {
display: block;
}
.container { .container {
max-width: 1200px; max-width: 1200px;
margin: 0 auto; margin: 0 auto;
@@ -213,7 +181,6 @@
background-color: #f9f9f9; background-color: #f9f9f9;
line-height: 1.8; /* 优化行高 */ line-height: 1.8; /* 优化行高 */
} }
.option-item { .option-item {
margin: 8px 0; /* 为选项添加上下间距 */ margin: 8px 0; /* 为选项添加上下间距 */
background-color: #f9f9f9; background-color: #f9f9f9;
@@ -257,19 +224,14 @@
position: relative; /* 关键:作为动画容器的定位基准 */ position: relative; /* 关键:作为动画容器的定位基准 */
overflow: hidden; /* 防止动画溢出 */ overflow: hidden; /* 防止动画溢出 */
} }
.option-item { .option-item {
margin: 8px 0; /* 为选项添加上下间距 */ margin: 8px 0; /* 为选项添加上下间距 */
background-color: #f9f9f9; background-color: #f9f9f9;
} }
@keyframes spin { @keyframes spin {
0% { 0% { transform: rotate(0deg); }
transform: rotate(0deg); 100% { transform: rotate(360deg); }
}
100% {
transform: rotate(360deg);
}
} }
/* 图片模态框样式 */ /* 图片模态框样式 */
@@ -283,7 +245,7 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: auto; overflow: auto;
background-color: rgba(0, 0, 0, 0.9); background-color: rgba(0,0,0,0.9);
} }
.modal-content { .modal-content {
@@ -314,51 +276,58 @@
<h1>教育场景识别</h1> <h1>教育场景识别</h1>
<div class="tab-container"> <div class="tab-container">
<button class="tab-button active" data-tab="formula" onclick="switchTab('formula')">公式识别</button> <button class="tab-button active" onclick="switchTab('formula')">公式识别</button>
<button class="tab-button" data-tab="question" onclick="switchTab('question')">试题识别</button> <button class="tab-button" onclick="switchTab('question')">试题识别</button>
<button class="tab-button" data-tab="handwriting" onclick="switchTab('handwriting')">手写识别</button>
</div> </div>
<!-- 标签内容区域 --> <!-- 公式识别标签页 -->
<div id="formula-content" class="tab-content active">公式识别内容...</div> <div id="formula-tab" class="tab-content active">
<div id="question-content" class="tab-content">试题识别内容...</div> <div class="example-section">
<div id="handwriting-content" class="tab-content">手写识别内容...</div> <h2>示例公式图片</h2>
<div class="example-images">
<div class="example-image-card">
<img src="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/Backup/GongShi.jpg" alt="公式示例1">
<div class="description">数学公式示例</div>
</div>
</div>
</div>
<div class="example-section"> <div class="recognize-section">
<h2>示例公式图片</h2> <h2>公式识别</h2>
<div class="example-images"> <div class="input-area">
<div class="example-image-card"> <div class="input-group">
<img src="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/Backup/GongShi.jpg" alt="公式示例1" <input type="text" id="formulaImageUrl" placeholder="请输入图片URL或使用示例图片" value="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/Backup/GongShi.jpg">
onclick="openModal(this.src)"> <button onclick="recognizeFormula()">识别公式</button>
<div class="description">数学公式示例</div> </div>
<div id="formulaResult" class="result-area">
<div style="color:#666; text-align:center; padding:20px;">识别结果将在此处显示</div>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="recognize-section"> <!-- 试题识别标签页 -->
<h2>公式识别</h2> <div id="question-tab" class="tab-content">
<div class="input-area"> <div class="example-section">
<div class="input-group"> <h2>示例试题图片</h2>
<input type="text" id="formulaImageUrl" placeholder="请输入图片URL或使用示例图片" <div class="example-images">
value="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/Backup/GongShi.jpg"> <div class="example-image-card">
<button onclick="recognizeFormula()">识别公式</button> <img src="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/Backup/ShiTi.jpg" alt="试题示例1">
</div> <div class="description">试题示例</div>
<div id="formulaResult" class="result-area"> </div>
<div style="color:#666; text-align:center; padding:20px;">识别结果将在此处显示</div>
</div> </div>
</div> </div>
</div>
<div class="recognize-section"> <div class="recognize-section">
<h2>试题识别</h2> <h2>试题识别</h2>
<div class="input-area"> <div class="input-area">
<div class="input-group"> <div class="input-group">
<input type="text" id="questionImageUrl" placeholder="请输入图片URL或使用示例图片" <input type="text" id="questionImageUrl" placeholder="请输入图片URL或使用示例图片" value="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/Backup/ShiTi.jpg">
value="https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/Backup/ShiTi.jpg"> <button onclick="recognizeQuestion()">识别试题</button>
<button onclick="recognizeQuestion()">识别试题</button> </div>
</div> <div id="questionResult" class="result-area">
<div id="questionResult" class="result-area"> <div style="color:#666; text-align:center; padding:20px;">识别结果将在此处显示</div>
<div style="color:#666; text-align:center; padding:20px;">识别结果将在此处显示</div> </div>
</div> </div>
</div> </div>
</div> </div>
@@ -381,13 +350,13 @@
processEscapes: true, processEscapes: true,
packages: {'[+]': ['ams']} packages: {'[+]': ['ams']}
}, },
svg: {fontCache: 'global'}, svg: { fontCache: 'global' },
startup: {pageReady: pageReady} startup: { pageReady: pageReady }
}; };
// MathJax 加载完成后执行 // MathJax 加载完成后执行
function pageReady() { function pageReady() {
return MathJax.startup.defaultPageReady().then(function () { return MathJax.startup.defaultPageReady().then(function() {
console.log('MathJax 3 加载完成'); console.log('MathJax 3 加载完成');
}); });
} }
@@ -398,36 +367,15 @@
<script> <script>
// 切换标签页 // 切换标签页
function switchTab(tabName) { function switchTab(tabName) {
console.log('切换到标签页:', tabName); document.querySelectorAll('.tab-button').forEach(button => button.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
// 移除所有标签按钮的active类 if (tabName === 'formula') {
document.querySelectorAll('.tab-button').forEach(button => { document.querySelectorAll('.tab-button')[0].classList.add('active');
button.classList.remove('active'); document.getElementById('formula-tab').classList.add('active');
console.log('移除按钮active类:', button.textContent);
});
// 移除所有标签内容的active类
document.querySelectorAll('.tab-content').forEach(content => {
content.classList.remove('active');
console.log('移除内容active类:', content.id);
});
// 添加active类到当前标签按钮
const targetButton = document.querySelector(`.tab-button[data-tab="${tabName}"]`);
if (targetButton) {
targetButton.classList.add('active');
console.log('添加按钮active类成功:', tabName);
} else { } else {
console.error('未找到标签按钮:', tabName); document.querySelectorAll('.tab-button')[1].classList.add('active');
} document.getElementById('question-tab').classList.add('active');
// 添加active类到当前标签内容
const targetContent = document.getElementById(`${tabName}-content`);
if (targetContent) {
targetContent.classList.add('active');
console.log('添加内容active类成功:', tabName);
} else {
console.error('未找到标签内容:', tabName);
} }
} }
@@ -436,10 +384,7 @@
const imageUrl = document.getElementById('formulaImageUrl').value.trim(); const imageUrl = document.getElementById('formulaImageUrl').value.trim();
const resultArea = document.getElementById('formulaResult'); const resultArea = document.getElementById('formulaResult');
if (!imageUrl) { if (!imageUrl) { alert('请输入图片URL'); return; }
alert('请输入图片URL');
return;
}
resultArea.innerHTML = '<div class="loading-animation"><div class="spinner"></div><div>正在识别公式...</div></div>'; resultArea.innerHTML = '<div class="loading-animation"><div class="spinner"></div><div>正在识别公式...</div></div>';
@@ -447,36 +392,30 @@
setTimeout(() => { setTimeout(() => {
// 读取本地JSON文件 // 读取本地JSON文件
fetch('Formula.json') fetch('Formula.json')
.then(response => { .then(response => {
console.log('JSON请求响应:', response); console.log('JSON请求响应:', response);
if (!response.ok) throw new Error('无法加载本地JSON文件'); if (!response.ok) throw new Error('无法加载本地JSON文件');
return response.json(); return response.json();
}) })
.then(data => { .then(data => {
if (data.error) { if (data.error) { resultArea.innerHTML = `<div style="color:red">识别失败: ${data.error}</div>`; return; }
resultArea.innerHTML = `<div style="color:red">识别失败: ${data.error}</div>`;
return;
}
const content = data.Data?.content || ''; const content = data.Data?.content || '';
if (!content) { if (!content) { resultArea.innerHTML = '<div>未识别到公式内容</div>'; return; }
resultArea.innerHTML = '<div>未识别到公式内容</div>';
return;
}
try { try {
resultArea.innerHTML = `<div class="tex2jax_process">$$${content}$$</div>`; resultArea.innerHTML = `<div class="tex2jax_process">$$${content}$$</div>`;
renderWithMathJax(resultArea); renderWithMathJax(resultArea);
} catch (error) { } catch (error) {
console.error('公式处理错误:', error); console.error('公式处理错误:', error);
resultArea.innerHTML = `<div style="color:red">公式处理失败: ${error.message}</div>`; resultArea.innerHTML = `<div style="color:red">公式处理失败: ${error.message}</div>`;
} }
}) })
.catch(error => { .catch(error => {
console.error('请求错误:', error); console.error('请求错误:', error);
const errorMsg = '加载本地JSON失败: ' + error.message; const errorMsg = '加载本地JSON失败: ' + error.message;
resultArea.innerHTML = `<div style="color:red">${errorMsg}</div>`; resultArea.innerHTML = `<div style="color:red">${errorMsg}</div>`;
}); });
}, 1000); // 1秒延迟 }, 1000); // 1秒延迟
} }
@@ -485,10 +424,7 @@
const imageUrl = document.getElementById('questionImageUrl').value.trim(); const imageUrl = document.getElementById('questionImageUrl').value.trim();
const resultArea = document.getElementById('questionResult'); const resultArea = document.getElementById('questionResult');
if (!imageUrl) { if (!imageUrl) { alert('请输入图片URL'); return; }
alert('请输入图片URL');
return;
}
// 立即显示加载动画(关键修复) // 立即显示加载动画(关键修复)
console.log('显示加载动画'); console.log('显示加载动画');
@@ -498,56 +434,53 @@
setTimeout(() => { setTimeout(() => {
// 读取本地JSON文件 // 读取本地JSON文件
fetch('ShiTi.json') fetch('ShiTi.json')
.then(response => { .then(response => {
console.log('JSON请求响应:', response); console.log('JSON请求响应:', response);
if (!response.ok) throw new Error('无法加载本地JSON文件'); if (!response.ok) throw new Error('无法加载本地JSON文件');
return response.json(); return response.json();
}) })
.then(data => { .then(data => {
if (data.error) { if (data.error) { resultArea.innerHTML = `<div style="color:red">识别失败: ${data.error}</div>`; return; }
resultArea.innerHTML = `<div style="color:red">识别失败: ${data.error}</div>`;
return;
}
let content = data.Data?.content || ''; let content = data.Data?.content || '';
console.log("处理前:" + content); console.log("处理前:"+content);
try { try {
// 彻底修复选项标签闭合问题 - 采用分而治之策略 // 彻底修复选项标签闭合问题 - 采用分而治之策略
// 1. 首先拆分所有选项为独立数组 // 1. 首先拆分所有选项为独立数组
const options = content.split(/(?=[A-D]\s*\.)/); const options = content.split(/(?=[A-D]\s*\.)/);
// 2. 逐个处理每个选项确保标签完整 // 2. 逐个处理每个选项确保标签完整
content = options.map(option => { content = options.map(option => {
// 仅处理以选项标签开头的部分 // 仅处理以选项标签开头的部分
if (/^[A-D]\s*\./.test(option)) { if (/^[A-D]\s*\./.test(option)) {
return `<span class="option-item">$${option}$</span>`; // 添加$符号 return `<span class="option-item">$${option}$</span>`; // 添加$符号
} }
return option; return option;
}).join(''); }).join('');
// 3. 清理可能的空标签 // 3. 清理可能的空标签
content = content.replace(/<span class="option-item"><\/span>/g, ''); content = content.replace(/<span class="option-item"><\/span>/g, '');
if (!content.includes('<span class="option-item">')) { if (!content.includes('<span class="option-item">')) {
content = content.replace(/((?:[A-D]\s*\.\s*[^.]+)+)/g, '<span class="option-item">$1</span>'); content = content.replace(/((?:[A-D]\s*\.\s*[^.]+)+)/g, '<span class="option-item">$1</span>');
}
// 添加选项间的分隔处理
content = content.replace(/<\/span>\s*<span class="option-item">/g, '</span>\n<span class="option-item">');
const latexContainer = document.createElement('div');
latexContainer.className = 'tex2jax_process';
latexContainer.innerHTML = content;
console.log('预处理后的内容:', latexContainer.innerHTML);
resultArea.innerHTML = '';
resultArea.appendChild(latexContainer);
renderWithMathJax(resultArea);
} catch (error) {
console.error('试题处理错误:', error);
resultArea.innerHTML = `<div style="color:red">试题处理失败: ${error.message}</div>`;
} }
}) // 添加选项间的分隔处理
.catch(error => { content = content.replace(/<\/span>\s*<span class="option-item">/g, '</span>\n<span class="option-item">');
console.error('请求错误:', error); const latexContainer = document.createElement('div');
const errorMsg = '加载本地JSON失败: ' + error.message; latexContainer.className = 'tex2jax_process';
resultArea.innerHTML = `<div style="color:red">${errorMsg}</div>`; latexContainer.innerHTML = content;
}); console.log('预处理后的内容:', latexContainer.innerHTML);
resultArea.innerHTML = '';
resultArea.appendChild(latexContainer);
renderWithMathJax(resultArea);
} catch (error) {
console.error('试题处理错误:', error);
resultArea.innerHTML = `<div style="color:red">试题处理失败: ${error.message}</div>`;
}
})
.catch(error => {
console.error('请求错误:', error);
const errorMsg = '加载本地JSON失败: ' + error.message;
resultArea.innerHTML = `<div style="color:red">${errorMsg}</div>`;
});
}, 1000); // 1秒延迟 }, 1000); // 1秒延迟
} }
@@ -586,38 +519,4 @@
div.textContent = text; div.textContent = text;
return div.innerHTML; return div.innerHTML;
} }
</script>
// 等待DOM加载完成
document.addEventListener('DOMContentLoaded', function () {
// 初始化第一个标签为活动状态
document.querySelector('.tab-button[data-tab="formula"]').classList.add('active');
document.getElementById('formula-content').classList.add('active');
// 为所有标签按钮添加点击事件
document.querySelectorAll('.tab-button').forEach(button => {
button.addEventListener('click', function () {
const tabName = this.getAttribute('data-tab');
// 移除所有活动状态
document.querySelectorAll('.tab-button').forEach(btn => btn.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
// 设置当前标签为活动状态
this.classList.add('active');
document.getElementById(`${tabName}-content`).classList.add('active');
});
});
});
// 图片模态框控制函数
function openModal(imageSrc) {
const modal = document.getElementById('imageModal');
const modalImg = document.getElementById('modalImage');
modal.style.display = 'block';
modalImg.src = imageSrc;
}
function closeModal() {
document.getElementById('imageModal').style.display = 'none';
}
</script>