paper-burner/js/history/history_detail_scripts.js
2026-03-09 17:39:29 +08:00

271 lines
7.8 KiB
JavaScript
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.

// history_detail_scripts.js - 从 history_detail.html 中提取的 JavaScript 代码
// 这个文件包含了历史详情页面的主要 JavaScript 逻辑
window.addEventListener('storage', function(e) {
if (e.key === 'paperBurnerSettings') {
// 重新加载设置并刷新 chatbot 配置
if (window.ChatbotCore && typeof window.ChatbotCore.getChatbotConfig === 'function') {
// 你可以强制刷新 Chatbot UI 或重载配置
window.ChatbotUI && window.ChatbotUI.updateChatbotUI && window.ChatbotUI.updateChatbotUI();
}
}
});
/**
* 将 exact 文本转为模糊正则,允许空格、换行模糊匹配,大小写不敏感
* @param {string} exact
* @returns {RegExp}
*/
function escapeRegExp(string) {
// 更安全地转义所有正则特殊字符
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
function fuzzyRegFromExact(exact) {
// 先转义所有正则特殊字符
let pattern = escapeRegExp(exact);
// 将所有空白替换为 \s+,允许跨行、多个空格
pattern = pattern.replace(/\s+/g, '\\s+');
// 可选:忽略前后空白
pattern = '\\s*' + pattern + '\\s*';
return new RegExp(pattern, 'gi');
}
/**
* 检查是否有OCR数据
* @returns {boolean}
*/
function hasOcrData() {
return window.data && window.data.ocr && window.data.ocr.trim() !== '';
}
/**
* 检查是否有翻译数据
* @returns {boolean}
*/
function hasTranslationData() {
return window.data && window.data.translation && window.data.translation.trim() !== '';
}
/**
* 检查是否有原始PDF数据
* @returns {boolean}
*/
function hasOriginalPdfData() {
return window.data && window.data.metadata && window.data.metadata.originalPdfBase64;
}
/**
* 创建确认对话框
* @param {string} title - 对话框标题
* @param {string} message - 对话框消息
* @param {string} confirmText - 确认按钮文本
* @param {string} cancelText - 取消按钮文本
* @returns {Promise<boolean>} 用户是否确认
*/
function showConfirmDialog(title, message, confirmText = '确认', cancelText = '取消') {
return new Promise((resolve) => {
// 创建对话框容器
const dialogOverlay = document.createElement('div');
dialogOverlay.id = 'pbx-confirm-dialog-overlay';
dialogOverlay.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 10000;
`;
const dialogBox = document.createElement('div');
dialogBox.style.cssText = `
background: white;
border-radius: 12px;
padding: 24px;
max-width: 400px;
width: 90%;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
`;
dialogBox.innerHTML = `
<h3 style="margin: 0 0 16px 0; font-size: 18px; color: #1a1a1a;">${title}</h3>
<p style="margin: 0 0 24px 0; font-size: 14px; color: #666; line-height: 1.6;">${message}</p>
<div style="display: flex; gap: 12px; justify-content: flex-end;">
<button id="pbx-dialog-cancel" style="
padding: 10px 20px;
border: 1px solid #ddd;
background: white;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
color: #666;
">${cancelText}</button>
<button id="pbx-dialog-confirm" style="
padding: 10px 20px;
border: none;
background: #4f46e5;
color: white;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
">${confirmText}</button>
</div>
`;
dialogOverlay.appendChild(dialogBox);
document.body.appendChild(dialogOverlay);
// 按钮事件
const confirmBtn = dialogBox.querySelector('#pbx-dialog-confirm');
const cancelBtn = dialogBox.querySelector('#pbx-dialog-cancel');
const cleanup = () => {
document.body.removeChild(dialogOverlay);
};
confirmBtn.onclick = () => {
cleanup();
resolve(true);
};
cancelBtn.onclick = () => {
cleanup();
resolve(false);
};
// 点击遮罩层关闭
dialogOverlay.onclick = (e) => {
if (e.target === dialogOverlay) {
cleanup();
resolve(false);
}
};
// ESC 键关闭
const handleEsc = (e) => {
if (e.key === 'Escape') {
cleanup();
resolve(false);
document.removeEventListener('keydown', handleEsc);
}
};
document.addEventListener('keydown', handleEsc);
});
}
/**
* 触发重新处理文档OCR和/或翻译)
* @param {boolean} includeTranslation - 是否包含翻译
*/
async function triggerReprocess(includeTranslation) {
const docId = window.docIdForLocalStorage;
const docName = window.data ? window.data.name : '未知文档';
if (!docId) {
alert('无法获取文档ID请刷新页面重试。');
return;
}
// 保存处理模式到 localStorage以便主页面读取
const reprocessConfig = {
docId: docId,
docName: docName,
includeTranslation: includeTranslation,
timestamp: Date.now()
};
localStorage.setItem('pbx_reprocess_config', JSON.stringify(reprocessConfig));
// 跳转到主页面
const baseUrl = window.location.pathname.replace('/views/history/history_detail.html', '/');
window.location.href = baseUrl + '?reprocess=1';
}
/**
* 处理"Word文档"标签点击
* 如果没有OCR数据询问用户是否需要生成
*/
async function handleOcrTabClick() {
// 如果已有OCR数据直接显示
if (hasOcrData()) {
showTab('ocr');
return;
}
// 检查是否有原始PDF
if (!hasOriginalPdfData()) {
alert('当前记录没有保存原始PDF数据无法重新处理。');
return;
}
// 弹出确认对话框
const confirmed = await showConfirmDialog(
'生成Word文档',
'当前文档尚未进行OCR处理。是否需要启动OCR处理生成Word文档\n\n处理完成后可在本页面查看和导出。',
'启动OCR',
'取消'
);
if (confirmed) {
await triggerReprocess(false); // 仅OCR不翻译
}
}
/**
* 处理"仅翻译"标签点击
* 如果没有翻译数据,询问用户是否需要生成翻译对照文档
*/
async function handleTranslationTabClick() {
// 如果已有翻译数据,直接显示
if (hasTranslationData()) {
showTab('translation');
return;
}
// 检查是否有原始PDF
if (!hasOriginalPdfData()) {
alert('当前记录没有保存原始PDF数据无法重新处理。');
return;
}
// 弹出确认对话框
const confirmed = await showConfirmDialog(
'生成翻译对照文档',
'当前文档尚未进行翻译处理。是否需要启动OCR+翻译处理?\n\n这将生成原文Word文档和翻译对照文档处理完成后可在本页面查看和导出。',
'启动OCR+翻译',
'取消'
);
if (confirmed) {
await triggerReprocess(true); // OCR + 翻译
}
}
// 绑定 tab 按钮点击事件
document.addEventListener('DOMContentLoaded', function() {
if (document.getElementById('tab-ocr')) {
document.getElementById('tab-ocr').onclick = handleOcrTabClick;
}
if (document.getElementById('tab-translation')) {
document.getElementById('tab-translation').onclick = handleTranslationTabClick;
}
if (document.getElementById('tab-chunk-compare')) {
document.getElementById('tab-chunk-compare').onclick = function() { showTab('chunk-compare'); };
}
if (document.getElementById('tab-pdf-compare')) {
document.getElementById('tab-pdf-compare').onclick = function() { showTab('pdf-compare'); };
}
if (document.getElementById('tab-original-file')) {
document.getElementById('tab-original-file').onclick = function() { showTab('original-file'); };
}
// 页面加载后渲染详情
if (typeof renderDetail === 'function') {
renderDetail();
}
});