From eb2a09b82ff30980179df154a8d1965c98c3d99f Mon Sep 17 00:00:00 2001 From: MT-Mint <798521692@qq.com> Date: Fri, 20 Mar 2026 14:28:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20PDF=E5=AF=B9=E7=85=A7=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E7=A7=BB=E6=A4=8D=E8=BF=9B=E6=B2=89=E6=B5=B8=E5=BC=8F=E5=B8=83?= =?UTF-8?q?=E5=B1=80=EF=BC=8C=E4=BA=A4=E4=BA=92=E4=BC=98=E5=8C=96=E4=B8=8E?= =?UTF-8?q?=E5=A4=9A=E9=A1=B9=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PDF对照视图:只在有结构化翻译数据时隐藏AI助手,修复确认框弹出时tab栏被隐藏 - 修复翻译模型名称错误(tongyi -> aliyun) - 仅阅读功能:添加延迟确保IndexedDB事务提交后再跳转 - triggerReprocessWithMinerU完成后自动跳转到PDF对照视图 - 重置renderingTab防抖锁解决界面卡住问题 - 永久隐藏沉浸模式切换按钮 - 删除未使用的logo SVG文件 --- css/history_detail/02-layout/immersive.css | 5 +- index.html | 14 +- index.html.backup | 2126 -------------------- js/app.js | 5 + js/chatbot/ui/chatbot-message-renderer.js | 11 +- js/history/history_detail_scripts.js | 29 +- js/history/history_detail_show_tab.js | 16 +- js/ui/ocr-settings.js | 22 +- js/ui/sidebar-integration.js | 8 +- js/ui/ui_model_ocr_config.js | 8 +- public/h_with_name.svg | 1 - public/pure.svg | 1 - public/with_name.svg | 1 - views/drawio/drawio.html | 1 - views/history/history_detail.html | 18 +- views/landing/landing-page.html | 7 +- views/mindmap/mindmap.html | 1 - 17 files changed, 68 insertions(+), 2206 deletions(-) delete mode 100644 index.html.backup delete mode 100644 public/h_with_name.svg delete mode 100644 public/pure.svg delete mode 100644 public/with_name.svg diff --git a/css/history_detail/02-layout/immersive.css b/css/history_detail/02-layout/immersive.css index 177d2c8..561a075 100644 --- a/css/history_detail/02-layout/immersive.css +++ b/css/history_detail/02-layout/immersive.css @@ -494,6 +494,7 @@ body.toc-dock-resizing #toc-vs-dock-resize-handle { /* ==================== 8. 沉浸模式切换按钮 ==================== */ #toggle-immersive-btn { + display: none !important; /* 永久隐藏 */ position: fixed !important; top: var(--spacing-md) !important; right: var(--spacing-md) !important; @@ -673,9 +674,9 @@ body.immersive-active #immersive-main-content-area .container { flex-direction: column !important; } -/* 沉浸模式下隐藏 PDF 对照按钮 */ +/* 沉浸模式下显示 PDF 对照按钮(用户要求在沉浸模式中也能使用) */ body.immersive-active #tab-pdf-compare { - display: none !important; + display: flex !important; } /* Modal 和右键菜单的 z-index 提升 */ diff --git a/index.html b/index.html index 2fe5837..53d56bf 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,6 @@ Paper Burner X - AI文献阅读与智能分析平台 - @@ -238,12 +237,11 @@ bottom: -40px; width: 300px; height: 300px; - background-image: url('public/pure.svg'); background-repeat: no-repeat; background-position: center; background-size: contain; 极低透明度,仅作纹理 - opacity: 0.07; + opacity: 0.07; transform: rotate(-10deg); pointer-events: none; } */ @@ -582,7 +580,6 @@
-
+
@@ -1937,19 +1934,14 @@ // Desktop Sidebar Collapse Logic const sidebarToggleBtn = document.getElementById('sidebarToggleBtn'); const sidebarToggleIcon = document.getElementById('sidebarToggleIcon'); - const sidebarLogo = document.getElementById('sidebarLogo'); - const LOGO_FULL = 'public/h_with_name.svg'; - const LOGO_PURE = 'public/pure.svg'; function setSidebarState(collapsed) { if (collapsed) { appSidebar.classList.add('collapsed'); if (sidebarToggleIcon) sidebarToggleIcon.setAttribute('icon', 'carbon:side-panel-open'); - if (sidebarLogo) sidebarLogo.src = LOGO_PURE; } else { appSidebar.classList.remove('collapsed'); if (sidebarToggleIcon) sidebarToggleIcon.setAttribute('icon', 'carbon:side-panel-close'); - if (sidebarLogo) sidebarLogo.src = LOGO_FULL; } localStorage.setItem('pbx_sidebar_collapsed', collapsed); } diff --git a/index.html.backup b/index.html.backup deleted file mode 100644 index d415a9c..0000000 --- a/index.html.backup +++ /dev/null @@ -1,2126 +0,0 @@ - - - - - - - Paper Burner X - AI文献阅读与智能分析平台 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - -
- - - -
-
- - - - - - - - - -
- -
- - - - - - - - - - - - - - - - - - - -
-
-

-
- -
- 文件上传 -

- -
- - -
- - - -
- -
-

点击或拖拽文件到此处

-

- 支持 PDF, Markdown, Word, PowerPoint, HTML, EPUB 等常见文档格式 -

- -
- - -
-
- - | - -
-
- - - - - - -
- - - - - -
- -
-
- - - - -
- - - - - - - - - - -
-

- 注意:AI 模型翻译结果仅供参考,最终内容请以原文为准 -

-
-
-
-
-
- -
- - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/js/app.js b/js/app.js index e22ae8c..03f2eb3 100644 --- a/js/app.js +++ b/js/app.js @@ -2264,6 +2264,11 @@ async function handleReadClick() { return; } + // 添加短暂延迟确保 IndexedDB 事务完全提交 + await new Promise(resolve => setTimeout(resolve, 100)); + + console.log('[仅阅读] 数据已保存,准备跳转...'); + // 跳转到历史详情页面 window.location.href = `views/history/history_detail.html?id=${encodeURIComponent(recordId)}`; } catch (error) { diff --git a/js/chatbot/ui/chatbot-message-renderer.js b/js/chatbot/ui/chatbot-message-renderer.js index 54fa76f..2d959a6 100644 --- a/js/chatbot/ui/chatbot-message-renderer.js +++ b/js/chatbot/ui/chatbot-message-renderer.js @@ -276,12 +276,9 @@ window.ChatbotMessageRenderer = { const isPurelyEmpty = (!m.content || String(m.content).trim() === '') && !m.reasoningContent && !m.toolCallHtml; if (m.role === 'assistant' && isPurelyEmpty) { - // Determine the correct path for the logo based on the current page - const isHistoryDetail = window.location.pathname.includes('/history_detail.html'); - const logoPath = isHistoryDetail ? '../../public/pure.svg' : 'public/pure.svg'; renderedContent = `
- +
`; } else { @@ -525,15 +522,11 @@ window.ChatbotMessageRenderer = { * @returns {string} HTML字符串。 */ renderTypingIndicator: function() { - // Determine the correct path for the logo based on the current page - const isHistoryDetail = window.location.pathname.includes('/history_detail.html'); - const logoPath = isHistoryDetail ? '../../public/pure.svg' : 'public/pure.svg'; - return `
- +
diff --git a/js/history/history_detail_scripts.js b/js/history/history_detail_scripts.js index 66cdbc4..220bd77 100644 --- a/js/history/history_detail_scripts.js +++ b/js/history/history_detail_scripts.js @@ -729,7 +729,7 @@ async function triggerReprocessWithMinerU() { pdfFile, null, // mistralKeyObject - 使用 MinerU 不需要 null, // translationKeyObject - 使用后端代理不需要 - 'tongyi', // 使用通义模型,后端代理会处理 + 'aliyun', // 使用阿里云百炼(后端代理会处理) null, // translationModelConfig settings.maxTokensPerChunk || 2000, settings.targetLanguage || 'Chinese', @@ -766,16 +766,21 @@ async function triggerReprocessWithMinerU() { await saveResultToDB(window.data); } - showToast('处理完成!', 'success'); + showToast('处理完成!正在加载 PDF 对照视图...', 'success'); + + // 重置渲染锁 + if (typeof renderingTab !== 'undefined') renderingTab = null; // 刷新页面显示 if (typeof renderDetail === 'function') { - renderDetail(); + await renderDetail(); } - // 自动跳转到原始文件标签页 - if (typeof showTab === 'function') { - showTab('original-file'); + // 自动跳转到 PDF 对照视图 + if (typeof showTabImmediate === 'function') { + showTabImmediate('pdf-compare'); + } else if (typeof showTab === 'function') { + showTab('pdf-compare'); } } catch (error) { @@ -976,9 +981,17 @@ async function executeMinerUStructuredTranslation() { addLog(`注意: 有 ${failedItems.length} 个片段翻译失败`); } - addLog('正在加载 PDF 对照视图...'); + addLog('正在刷新界面...'); - // 短暂延迟后显示 PDF 对照视图 + // 重置渲染锁,确保后续 showTab 可以执行 + if (typeof renderingTab !== 'undefined') renderingTab = null; + + // 刷新界面 + if (typeof renderDetail === 'function') { + await renderDetail(); // await async 函数 + } + + // 延迟后显示 PDF 对照视图 setTimeout(() => { if (typeof showTabImmediate === 'function') { showTabImmediate('pdf-compare'); diff --git a/js/history/history_detail_show_tab.js b/js/history/history_detail_show_tab.js index 21ec246..c00dd51 100644 --- a/js/history/history_detail_show_tab.js +++ b/js/history/history_detail_show_tab.js @@ -150,6 +150,10 @@ function showTabImmediate(tab) { if (DOM_CACHE.layout.meta) DOM_CACHE.layout.meta.style.display = ''; if (DOM_CACHE.layout.tabsContainer) DOM_CACHE.layout.tabsContainer.style.display = ''; + // 恢复 AI 智能助手显示(退出 PDF 对照模式时) + const chatbotArea = document.getElementById('immersive-chatbot-area'); + if (chatbotArea) chatbotArea.style.display = ''; + let html = ''; let contentContainerId = ''; // 用于 applyAnnotationsToContent let activeContentElement = null; // 用于 applyAnnotationsToContent @@ -295,11 +299,6 @@ function showTabImmediate(tab) { // ========== MinerU PDF 对照视图 ========== if (DOM_CACHE.tabs.pdfCompare) DOM_CACHE.tabs.pdfCompare.classList.add('active'); - // 隐藏顶部区域以获得更大空间 - 使用缓存 - if (DOM_CACHE.layout.title) DOM_CACHE.layout.title.style.display = 'none'; - if (DOM_CACHE.layout.meta) DOM_CACHE.layout.meta.style.display = 'none'; - if (DOM_CACHE.layout.tabsContainer) DOM_CACHE.layout.tabsContainer.style.display = 'none'; - // 检查是否有必要的结构化翻译数据 const hasStructuredData = data.metadata && data.metadata.originalPdfBase64 && data.metadata.contentListJson && data.metadata.translatedContentList; @@ -311,6 +310,13 @@ function showTabImmediate(tab) { return; } + // 有结构化数据时,隐藏顶部区域和 AI 智能助手以获得更大空间 + if (DOM_CACHE.layout.title) DOM_CACHE.layout.title.style.display = 'none'; + if (DOM_CACHE.layout.meta) DOM_CACHE.layout.meta.style.display = 'none'; + if (DOM_CACHE.layout.tabsContainer) DOM_CACHE.layout.tabsContainer.style.display = 'none'; + const chatbotArea = document.getElementById('immersive-chatbot-area'); + if (chatbotArea) chatbotArea.style.display = 'none'; + // 设置 HTML 容器 document.getElementById('tabContent').innerHTML = '
'; diff --git a/js/ui/ocr-settings.js b/js/ui/ocr-settings.js index 8b1a3c3..13de7e2 100644 --- a/js/ui/ocr-settings.js +++ b/js/ui/ocr-settings.js @@ -125,7 +125,7 @@ class OcrSettingsManager { this.elements.mineruToken.value = localStorage.getItem(this.keys.mineruToken) || ''; } if (this.elements.mineruWorkerUrl) { - this.elements.mineruWorkerUrl.value = localStorage.getItem(this.keys.mineruWorkerUrl) || ''; + this.elements.mineruWorkerUrl.value = localStorage.getItem(this.keys.mineruWorkerUrl) || 'http://localhost:3456'; } if (this.elements.mineruEnableOcr) { this.elements.mineruEnableOcr.checked = localStorage.getItem(this.keys.mineruEnableOcr) !== 'false'; @@ -151,7 +151,7 @@ class OcrSettingsManager { this.elements.doc2xToken.value = localStorage.getItem(this.keys.doc2xToken) || ''; } if (this.elements.doc2xWorkerUrl) { - this.elements.doc2xWorkerUrl.value = localStorage.getItem(this.keys.doc2xWorkerUrl) || ''; + this.elements.doc2xWorkerUrl.value = localStorage.getItem(this.keys.doc2xWorkerUrl) || 'http://localhost:3456'; } if (this.elements.doc2xFormulaMode) { this.elements.doc2xFormulaMode.value = localStorage.getItem(this.keys.doc2xFormulaMode) || 'dollar'; @@ -240,7 +240,7 @@ class OcrSettingsManager { localStorage.setItem(this.keys.mineruWorkerUrl, (cfg.workerUrl || '').replace(/\/+$/, '')); localStorage.setItem(this.keys.mineruToken, cfg.token || ''); localStorage.setItem(this.keys.workerAuthKey, cfg.authKey || ''); - localStorage.setItem(this.keys.mineruTokenMode, cfg.tokenMode || 'frontend'); + localStorage.setItem(this.keys.mineruTokenMode, cfg.tokenMode || 'backend'); // 默认后端转发模式 localStorage.setItem(this.keys.mineruEnableOcr, cfg.enableOcr !== false); localStorage.setItem(this.keys.mineruEnableFormula, cfg.enableFormula !== false); localStorage.setItem(this.keys.mineruEnableTable, cfg.enableTable !== false); @@ -249,7 +249,7 @@ class OcrSettingsManager { localStorage.setItem(this.keys.doc2xWorkerUrl, (cfg.workerUrl || '').replace(/\/+$/, '')); localStorage.setItem(this.keys.doc2xToken, cfg.token || ''); localStorage.setItem(this.keys.workerAuthKey, cfg.authKey || ''); - localStorage.setItem(this.keys.doc2xTokenMode, cfg.tokenMode || 'frontend'); + localStorage.setItem(this.keys.doc2xTokenMode, cfg.tokenMode || 'backend'); // 默认后端转发模式 localStorage.setItem(this.keys.doc2xFormulaMode, cfg.formulaMode || 'dollar'); localStorage.setItem(this.keys.doc2xExportFormat, cfg.exportFormat || ''); } @@ -517,9 +517,9 @@ class OcrSettingsManager { return { engine: 'mineru', token: localStorage.getItem(this.keys.mineruToken) || '', - workerUrl: (localStorage.getItem(this.keys.mineruWorkerUrl) || '').replace(/\/+$/, ''), // 去掉末尾斜杠 + workerUrl: (localStorage.getItem(this.keys.mineruWorkerUrl) || 'http://localhost:3456').replace(/\/+$/, ''), // 去掉末尾斜杠 authKey: localStorage.getItem(this.keys.workerAuthKey) || '', - tokenMode: localStorage.getItem(this.keys.mineruTokenMode) || 'frontend', + tokenMode: localStorage.getItem(this.keys.mineruTokenMode) || 'backend', // 默认后端转发模式 enableOcr: localStorage.getItem(this.keys.mineruEnableOcr) !== 'false', enableFormula: localStorage.getItem(this.keys.mineruEnableFormula) !== 'false', enableTable: localStorage.getItem(this.keys.mineruEnableTable) !== 'false', @@ -530,9 +530,9 @@ class OcrSettingsManager { return { engine: 'doc2x', token: localStorage.getItem(this.keys.doc2xToken) || '', - workerUrl: (localStorage.getItem(this.keys.doc2xWorkerUrl) || '').replace(/\/+$/, ''), // 去掉末尾斜杠 + workerUrl: (localStorage.getItem(this.keys.doc2xWorkerUrl) || 'http://localhost:3456').replace(/\/+$/, ''), // 去掉末尾斜杠 authKey: localStorage.getItem(this.keys.workerAuthKey) || '', - tokenMode: localStorage.getItem(this.keys.doc2xTokenMode) || 'frontend', + tokenMode: localStorage.getItem(this.keys.doc2xTokenMode) || 'backend', // 默认后端转发模式 formulaMode: localStorage.getItem(this.keys.doc2xFormulaMode) || 'dollar', exportFormat: localStorage.getItem(this.keys.doc2xExportFormat) || '' }; @@ -563,17 +563,17 @@ class OcrSettingsManager { break; case 'mineru': - // 前端透传模式需要 Token,Worker 配置模式不需要 + // 后端转发模式(tokenMode 不是 'frontend')不需要前端配置 Token if (config.tokenMode === 'frontend' && !config.token) { return { valid: false, message: '请配置 MinerU Token(前端透传模式)' }; } - if (!config.workerUrl) { + if (config.tokenMode === 'frontend' && !config.workerUrl) { return { valid: false, message: '请配置 MinerU Worker URL' }; } break; case 'doc2x': - // 前端透传模式需要 Token,Worker 配置模式不需要 + // 后端转发模式(tokenMode 不是 'frontend')不需要前端配置 Token if (config.tokenMode === 'frontend' && !config.token) { return { valid: false, message: '请配置 Doc2X Token(前端透传模式)' }; } diff --git a/js/ui/sidebar-integration.js b/js/ui/sidebar-integration.js index c311118..7af842e 100644 --- a/js/ui/sidebar-integration.js +++ b/js/ui/sidebar-integration.js @@ -66,10 +66,6 @@ // Settings Link originalSettingsLink: '#settings-link' - }, - logos: { - full: '../../public/h_with_name.svg', - pure: '../../public/pure.svg' } }; @@ -146,18 +142,16 @@ * @param {boolean} collapsed - 是否折叠 */ function setSidebarCollapsed(collapsed) { - if (!elements.appSidebar || !elements.sidebarLogo) return; + if (!elements.appSidebar) return; if (collapsed) { elements.appSidebar.classList.add('collapsed'); - elements.sidebarLogo.src = CONFIG.logos.pure; // 切换图标为"打开"图标 if (elements.sidebarToggleIcon) { elements.sidebarToggleIcon.setAttribute('icon', 'carbon:side-panel-open'); } } else { elements.appSidebar.classList.remove('collapsed'); - elements.sidebarLogo.src = CONFIG.logos.full; // 切换图标为"关闭"图标 if (elements.sidebarToggleIcon) { elements.sidebarToggleIcon.setAttribute('icon', 'carbon:side-panel-close'); diff --git a/js/ui/ui_model_ocr_config.js b/js/ui/ui_model_ocr_config.js index 1751d87..a9175b7 100644 --- a/js/ui/ui_model_ocr_config.js +++ b/js/ui/ui_model_ocr_config.js @@ -60,9 +60,9 @@ */ function renderMinerUConfig(container) { // 从 localStorage 加载配置 - const workerUrl = localStorage.getItem('ocrMinerUWorkerUrl') || ''; + const workerUrl = localStorage.getItem('ocrMinerUWorkerUrl') || 'http://localhost:3456'; const authKey = localStorage.getItem('ocrWorkerAuthKey') || ''; - const tokenMode = localStorage.getItem('ocrMinerUTokenMode') || 'frontend'; + const tokenMode = localStorage.getItem('ocrMinerUTokenMode') || 'backend'; const token = localStorage.getItem('ocrMinerUToken') || ''; const configDiv = document.createElement('div'); @@ -336,9 +336,9 @@ */ function renderDoc2XConfig(container) { // 从 localStorage 加载配置 - const workerUrl = localStorage.getItem('ocrDoc2XWorkerUrl') || ''; + const workerUrl = localStorage.getItem('ocrDoc2XWorkerUrl') || 'http://localhost:3456'; const authKey = localStorage.getItem('ocrWorkerAuthKey') || ''; - const tokenMode = localStorage.getItem('ocrDoc2XTokenMode') || 'frontend'; + const tokenMode = localStorage.getItem('ocrDoc2XTokenMode') || 'backend'; const token = localStorage.getItem('ocrDoc2XToken') || ''; const configDiv = document.createElement('div'); diff --git a/public/h_with_name.svg b/public/h_with_name.svg deleted file mode 100644 index 41316a0..0000000 --- a/public/h_with_name.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/pure.svg b/public/pure.svg deleted file mode 100644 index 47f9fad..0000000 --- a/public/pure.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/with_name.svg b/public/with_name.svg deleted file mode 100644 index 840084c..0000000 --- a/public/with_name.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/views/drawio/drawio.html b/views/drawio/drawio.html index 71c20a4..59cca83 100644 --- a/views/drawio/drawio.html +++ b/views/drawio/drawio.html @@ -4,7 +4,6 @@ 配图编辑器 - draw.io -