添加百度OCR支持,更新OCR源选择和设置界面

This commit is contained in:
skestar
2025-08-03 00:19:09 +08:00
parent aef6e2abef
commit 6afe56c816
7 changed files with 480 additions and 31 deletions

View File

@@ -1053,10 +1053,33 @@ class SnapSolver {
this.extractTextBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i><span>提取中...</span>';
const settings = window.settingsManager.getSettings();
// 根据用户设置的OCR源进行选择
const ocrSource = settings.ocrSource || 'auto';
const baiduApiKey = window.settingsManager.apiKeyValues.BaiduApiKey;
const baiduSecretKey = window.settingsManager.apiKeyValues.BaiduSecretKey;
const mathpixApiKey = settings.mathpixApiKey;
if (!mathpixApiKey || mathpixApiKey === ':') {
window.uiManager.showToast('请在设置中输入Mathpix API凭据', 'error');
const hasBaiduOCR = baiduApiKey && baiduSecretKey;
const hasMathpix = mathpixApiKey && mathpixApiKey !== ':';
// 根据OCR源配置检查可用性
let canProceed = false;
let missingOCRMessage = '';
if (ocrSource === 'baidu') {
canProceed = hasBaiduOCR;
missingOCRMessage = '请在设置中配置百度OCR API密钥';
} else if (ocrSource === 'mathpix') {
canProceed = hasMathpix;
missingOCRMessage = '请在设置中配置Mathpix API密钥';
} else { // auto
canProceed = hasBaiduOCR || hasMathpix;
missingOCRMessage = '请在设置中配置OCR API密钥百度OCR推荐或Mathpix';
}
if (!canProceed) {
window.uiManager.showToast(missingOCRMessage, 'error');
document.getElementById('settingsPanel').classList.add('active');
this.extractTextBtn.disabled = false;
this.extractTextBtn.innerHTML = '<i class="fas fa-font"></i><span>提取文本</span>';
@@ -1076,7 +1099,7 @@ class SnapSolver {
this.socket.emit('extract_text', {
image: this.croppedImage.split(',')[1],
settings: {
mathpixApiKey: mathpixApiKey
ocrSource: settings.ocrSource || 'auto'
}
});

View File

@@ -374,6 +374,9 @@ class SettingsManager {
// 模型选择器对象
this.modelSelector = null;
// OCR源配置
this.ocrSource = 'auto'; // 默认自动选择
// 存储API密钥的对象
this.apiKeyValues = {
'AnthropicApiKey': '',
@@ -382,6 +385,8 @@ class SettingsManager {
'AlibabaApiKey': '',
'GoogleApiKey': '',
'DoubaoApiKey': '',
'BaiduApiKey': '',
'BaiduSecretKey': '',
'MathpixAppId': '',
'MathpixAppKey': ''
};
@@ -626,6 +631,14 @@ class SettingsManager {
this.proxyPortInput.value = settings.proxyPort;
}
// Load OCR source setting
if (settings.ocrSource) {
this.ocrSource = settings.ocrSource;
if (this.ocrSourceSelect) {
this.ocrSourceSelect.value = settings.ocrSource;
}
}
// Update UI based on model type
this.updateUIBasedOnModelType();
@@ -786,7 +799,8 @@ class SettingsManager {
currentPromptId: this.currentPromptId,
proxyEnabled: this.proxyEnabledInput.checked,
proxyHost: this.proxyHostInput.value,
proxyPort: this.proxyPortInput.value
proxyPort: this.proxyPortInput.value,
ocrSource: this.ocrSource // 添加OCR源配置保存
};
// 保存设置到localStorage
@@ -888,6 +902,7 @@ class SettingsManager {
proxyHost: this.proxyHostInput.value,
proxyPort: this.proxyPortInput.value,
mathpixApiKey: mathpixApiKey,
ocrSource: this.ocrSource, // 添加OCR源配置
modelInfo: {
supportsMultimodal: modelInfo.supportsMultimodal || false,
isReasoning: modelInfo.isReasoning || false,
@@ -1128,6 +1143,20 @@ class SettingsManager {
this.saveSettings();
});
// OCR源选择器事件监听
if (this.ocrSourceSelect) {
this.ocrSourceSelect.addEventListener('change', (e) => {
// 阻止事件冒泡
e.stopPropagation();
// 更新OCR源配置
this.ocrSource = e.target.value;
this.saveSettings();
console.log('OCR源已切换为:', this.ocrSource);
});
}
// Panel visibility
if (this.settingsToggle) {
this.settingsToggle.addEventListener('click', () => {
@@ -2219,6 +2248,9 @@ class SettingsManager {
this.mathpixAppIdInput = document.getElementById('mathpixAppId');
this.mathpixAppKeyInput = document.getElementById('mathpixAppKey');
// OCR源选择器
this.ocrSourceSelect = document.getElementById('ocrSourceSelect');
// API Key elements - 所有的密钥输入框
this.apiKeyInputs = {
'AnthropicApiKey': document.getElementById('AnthropicApiKey'),
@@ -2268,6 +2300,8 @@ class SettingsManager {
'AlibabaApiKey': '',
'GoogleApiKey': '',
'DoubaoApiKey': '',
'BaiduApiKey': '',
'BaiduSecretKey': '',
'MathpixAppId': '',
'MathpixAppKey': ''
};

View File

@@ -2174,6 +2174,82 @@ button:disabled {
transition: all 0.2s ease-in-out;
}
/* OCR设置样式 */
.ocr-settings {
margin-bottom: 1.5rem;
}
.ocr-source-control {
display: flex;
flex-direction: column;
gap: 12px;
}
.ocr-source-selector {
position: relative;
}
.ocr-source-select {
width: 100%;
padding: 10px 14px;
border: 1px solid var(--border-color);
border-radius: 8px;
background: var(--surface);
color: var(--text-primary);
font-size: 0.9rem;
transition: all 0.2s ease;
}
.ocr-source-select:hover {
border-color: var(--primary-color);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.ocr-source-select:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.1);
}
.ocr-source-description {
display: flex;
flex-direction: column;
gap: 8px;
padding: 12px;
background: rgba(0, 0, 0, 0.02);
border-radius: 8px;
border: 1px solid var(--border-color);
}
.ocr-desc-item {
display: flex;
align-items: flex-start;
gap: 8px;
font-size: 0.85rem;
line-height: 1.4;
color: var(--text-secondary);
}
.ocr-desc-item i {
color: var(--primary-color);
margin-top: 2px;
flex-shrink: 0;
}
.ocr-desc-item strong {
color: var(--text-primary);
}
/* 暗色主题下的OCR设置样式 */
[data-theme="dark"] .ocr-source-description {
background: rgba(255, 255, 255, 0.02);
}
[data-theme="dark"] .ocr-source-select {
background: var(--surface);
border-color: var(--border-color);
}
/* 新增的推理控制组件样式 */
.reasoning-control {
display: flex;