添加图标
This commit is contained in:
@@ -3,8 +3,9 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>DocuTranslate - 交互式文档翻译</title>
|
||||
|
||||
<title>DocuTranslate - 交互式文档翻译</title>
|
||||
<link rel="icon" href="/static/favicon.ico" type="image/x-icon">
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="/static/bootstrap.css" rel="stylesheet" crossorigin="anonymous">
|
||||
<!-- Bootstrap Icons -->
|
||||
@@ -60,17 +61,21 @@
|
||||
transition: all 0.2s ease-in-out;
|
||||
background-color: var(--bs-body-bg);
|
||||
}
|
||||
|
||||
.file-drop-area.drag-over {
|
||||
border-color: var(--bs-primary);
|
||||
background-color: var(--bs-secondary-bg);
|
||||
}
|
||||
|
||||
.file-drop-area.file-selected {
|
||||
border-style: solid;
|
||||
border-color: var(--bs-success);
|
||||
}
|
||||
|
||||
.file-drop-area.input-error {
|
||||
border-color: var(--bs-danger);
|
||||
}
|
||||
|
||||
.file-name-display.input-error-text {
|
||||
color: var(--bs-danger);
|
||||
font-weight: bold;
|
||||
@@ -85,6 +90,7 @@
|
||||
#previewModal .modal-dialog {
|
||||
max-width: 95vw;
|
||||
}
|
||||
|
||||
#previewModal .modal-body {
|
||||
height: 80vh;
|
||||
}
|
||||
@@ -95,6 +101,7 @@
|
||||
border: 1px solid var(--bs-border-color);
|
||||
border-radius: .375rem;
|
||||
}
|
||||
|
||||
.preview-pane iframe, .preview-pane pre {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -135,7 +142,8 @@
|
||||
<!-- Parsing Engine Settings -->
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="headingOne">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne">
|
||||
<strong><i class="bi bi-file-earmark-binary me-2"></i>解析配置</strong>
|
||||
</button>
|
||||
</h2>
|
||||
@@ -151,9 +159,11 @@
|
||||
<div class="mb-3" id="mineruTokenGroup">
|
||||
<label for="mineru_token" class="form-label">
|
||||
Mineru Token
|
||||
<a href="https://mineru.net/apiManage/token" target="_blank" class="ms-1" title="获取Mineru Token"><i class="bi bi-box-arrow-up-right"></i></a>
|
||||
<a href="https://mineru.net/apiManage/token" target="_blank" class="ms-1"
|
||||
title="获取Mineru Token"><i class="bi bi-box-arrow-up-right"></i></a>
|
||||
</label>
|
||||
<input type="password" class="form-control" id="mineru_token" name="mineru_token" placeholder="使用Mineru引擎时需要">
|
||||
<input type="password" class="form-control" id="mineru_token"
|
||||
name="mineru_token" placeholder="使用Mineru引擎时需要">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -162,7 +172,8 @@
|
||||
<!-- AI Settings -->
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="headingTwo">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
|
||||
<strong><i class="bi bi-robot me-2"></i>翻译模型</strong>
|
||||
</button>
|
||||
</h2>
|
||||
@@ -175,7 +186,9 @@
|
||||
<option value="https://api.openai.com/v1">OpenAI</option>
|
||||
<option value="https://open.bigmodel.cn/api/paas/v4">智谱AI</option>
|
||||
<option value="https://api.deepseek.com/v1">DeepSeek</option>
|
||||
<option value="https://dashscope.aliyuncs.com/compatible-mode/v1">阿里云百炼</option>
|
||||
<option value="https://dashscope.aliyuncs.com/compatible-mode/v1">
|
||||
阿里云百炼
|
||||
</option>
|
||||
<option value="https://www.dmxapi.cn/v1">DMXAPI</option>
|
||||
<option value="https://openrouter.ai/api/v1">OpenRouter</option>
|
||||
<option value="https://ark.cn-beijing.volces.com/api/v3">火山引擎</option>
|
||||
@@ -189,13 +202,16 @@
|
||||
<div class="mb-3">
|
||||
<label for="apikey" class="form-label">
|
||||
API Key
|
||||
<a href="#" target="_blank" class="ms-1" id="api_href" title="获取API Key"><i class="bi bi-box-arrow-up-right"></i></a>
|
||||
<a href="#" target="_blank" class="ms-1" id="api_href"
|
||||
title="获取API Key"><i class="bi bi-box-arrow-up-right"></i></a>
|
||||
</label>
|
||||
<input type="password" class="form-control" id="apikey" name="apikey" required placeholder="请输入您的API Key">
|
||||
<input type="password" class="form-control" id="apikey" name="apikey" required
|
||||
placeholder="请输入您的API Key">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="model_id" class="form-label">模型 ID</label>
|
||||
<input type="text" class="form-control" id="model_id" name="model_id" required placeholder="例如: gpt-4o, glm-4">
|
||||
<input type="text" class="form-control" id="model_id" name="model_id" required
|
||||
placeholder="例如: gpt-4o, glm-4">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -204,7 +220,9 @@
|
||||
<!-- Translation Settings -->
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="headingThree">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseThree" aria-expanded="false"
|
||||
aria-controls="collapseThree">
|
||||
<strong><i class="bi bi-translate me-2"></i>翻译配置</strong>
|
||||
</button>
|
||||
</h2>
|
||||
@@ -221,19 +239,26 @@
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="custom_prompt_translate" class="form-label">自定义Prompt</label>
|
||||
<textarea class="form-control" id="custom_prompt_translate" name="custom_prompt_translate" rows="3" placeholder="可选,如“人名保持原文不翻译”"></textarea>
|
||||
<textarea class="form-control" id="custom_prompt_translate"
|
||||
name="custom_prompt_translate" rows="3"
|
||||
placeholder="可选,如“人名保持原文不翻译”"></textarea>
|
||||
</div>
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="formula_ocr" name="formula_ocr" checked>
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="formula_ocr"
|
||||
name="formula_ocr" checked>
|
||||
<label class="form-check-label" for="formula_ocr">公式识别</label>
|
||||
</div>
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="code_ocr" name="code_ocr" checked>
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="code_ocr"
|
||||
name="code_ocr" checked>
|
||||
<label class="form-check-label" for="code_ocr">代码识别</label>
|
||||
</div>
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="refine_markdown" name="refine_markdown">
|
||||
<label class="form-check-label" for="refine_markdown">Markdown修复<span class="d-inline-block" tabindex="0" data-bs-toggle="tooltip" title="使用ai对解析后的文本先修复再翻译,现不推荐开启">
|
||||
<input class="form-check-input" type="checkbox" role="switch"
|
||||
id="refine_markdown" name="refine_markdown">
|
||||
<label class="form-check-label" for="refine_markdown">Markdown修复<span
|
||||
class="d-inline-block" tabindex="0" data-bs-toggle="tooltip"
|
||||
title="使用ai对解析后的文本先修复再翻译,现不推荐开启">
|
||||
<i class="bi bi-question-circle"></i>
|
||||
</span></label>
|
||||
|
||||
@@ -245,32 +270,49 @@
|
||||
<!-- Other Settings -->
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="headingFour">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#collapseFour" aria-expanded="false"
|
||||
aria-controls="collapseFour">
|
||||
<strong><i class="bi bi-sliders me-2"></i>高级参数</strong>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapseFour" class="accordion-collapse collapse" aria-labelledby="headingFour">
|
||||
<div class="accordion-body">
|
||||
<div class="mb-3">
|
||||
<label for="chunk-size-slider" class="form-label d-flex justify-content-between">
|
||||
<label for="chunk-size-slider"
|
||||
class="form-label d-flex justify-content-between">
|
||||
<span>分块大小: <span id="chunk-size-display"></span></span>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary py-0 px-1 slider-reset-btn" id="chunk-size-reset">重置</button>
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-outline-secondary py-0 px-1 slider-reset-btn"
|
||||
id="chunk-size-reset">重置
|
||||
</button>
|
||||
</label>
|
||||
<input type="range" class="form-range" min="1000" max="6000" step="100" id="chunk-size-slider" name="chunk_size">
|
||||
<input type="range" class="form-range" min="1000" max="6000" step="100"
|
||||
id="chunk-size-slider" name="chunk_size">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="concurrent-slider" class="form-label d-flex justify-content-between">
|
||||
<label for="concurrent-slider"
|
||||
class="form-label d-flex justify-content-between">
|
||||
<span>并发数: <span id="concurrent-display"></span></span>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary py-0 px-1 slider-reset-btn" id="concurrent-reset">重置</button>
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-outline-secondary py-0 px-1 slider-reset-btn"
|
||||
id="concurrent-reset">重置
|
||||
</button>
|
||||
</label>
|
||||
<input type="range" class="form-range" min="1" max="60" step="1" id="concurrent-slider" name="concurrent">
|
||||
<input type="range" class="form-range" min="1" max="60" step="1"
|
||||
id="concurrent-slider" name="concurrent">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="temperature-slider" class="form-label d-flex justify-content-between">
|
||||
<label for="temperature-slider"
|
||||
class="form-label d-flex justify-content-between">
|
||||
<span>Temperature: <span id="temperature-display"></span></span>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary py-0 px-1 slider-reset-btn" id="temperature-reset">重置</button>
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-outline-secondary py-0 px-1 slider-reset-btn"
|
||||
id="temperature-reset">重置
|
||||
</button>
|
||||
</label>
|
||||
<input type="range" class="form-range" min="0" max="2" step="0.1" id="temperature-slider" name="temperature">
|
||||
<input type="range" class="form-range" min="0" max="2" step="0.1"
|
||||
id="temperature-slider" name="temperature">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -297,7 +339,8 @@
|
||||
<div class="task-area" id="task-area-container">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h4 class="mb-0"><i class="bi bi-list-task me-2"></i>任务列表</h4>
|
||||
<button class="btn btn-primary" id="addNewTaskBtn"><i class="bi bi-plus-circle-fill me-2"></i>新建任务</button>
|
||||
<button class="btn btn-primary" id="addNewTaskBtn"><i class="bi bi-plus-circle-fill me-2"></i>新建任务
|
||||
</button>
|
||||
</div>
|
||||
<div id="task-container">
|
||||
<!-- Task cards will be injected here -->
|
||||
@@ -336,7 +379,8 @@
|
||||
<span class="status-message small text-muted">等待上传文件...</span>
|
||||
</div>
|
||||
<div class="progress mt-1" role="progressbar" style="height: 5px; display: none;">
|
||||
<div class="progress-bar progress-bar-striped progress-bar-animated" style="width: 100%"></div>
|
||||
<div class="progress-bar progress-bar-striped progress-bar-animated"
|
||||
style="width: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -345,19 +389,26 @@
|
||||
<div class="card-footer d-flex justify-content-between align-items-center">
|
||||
<div class="download-buttons" style="display: none;">
|
||||
<button class="btn btn-sm btn-success preview-html-btn"><i class="bi bi-eye-fill me-1"></i>预览</button>
|
||||
<button class="btn btn-sm btn-info download-pdf-btn"><i class="bi bi-file-earmark-pdf-fill me-1"></i>下载 PDF</button>
|
||||
<button class="btn btn-sm btn-info download-pdf-btn"><i class="bi bi-file-earmark-pdf-fill me-1"></i>下载
|
||||
PDF
|
||||
</button>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-sm btn-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<button type="button" class="btn btn-sm btn-secondary dropdown-toggle" data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<i class="bi bi-download me-1"></i>下载其他格式
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item download-html-link" href="#"><i class="bi bi-filetype-html me-2"></i>HTML</a></li>
|
||||
<li><a class="dropdown-item download-markdown-link" href="#"><i class="bi bi-markdown-fill me-2"></i>Markdown(嵌图)</a></li>
|
||||
<li><a class="dropdown-item download-markdown-zip-link" href="#"><i class="bi bi-file-zip-fill me-2"></i>Markdown压缩包</a></li>
|
||||
<li><a class="dropdown-item download-html-link" href="#"><i
|
||||
class="bi bi-filetype-html me-2"></i>HTML</a></li>
|
||||
<li><a class="dropdown-item download-markdown-link" href="#"><i
|
||||
class="bi bi-markdown-fill me-2"></i>Markdown(嵌图)</a></li>
|
||||
<li><a class="dropdown-item download-markdown-zip-link" href="#"><i
|
||||
class="bi bi-file-zip-fill me-2"></i>Markdown压缩包</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-primary start-translate-btn ms-auto"><i class="bi bi-play-fill me-1"></i>开始翻译</button>
|
||||
<button class="btn btn-primary start-translate-btn ms-auto"><i class="bi bi-play-fill me-1"></i>开始翻译
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -370,7 +421,8 @@
|
||||
<h5 class="modal-title" id="previewModalTitle">双语预览</h5>
|
||||
<div class="btn-group me-auto ms-4" role="group">
|
||||
<button type="button" class="btn btn-sm btn-primary" id="setBilingualViewBtn">双语</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" id="setTranslatedOnlyViewBtn">仅译文</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" id="setTranslatedOnlyViewBtn">仅译文
|
||||
</button>
|
||||
</div>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
@@ -390,7 +442,9 @@
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
|
||||
<button type="button" class="btn btn-primary" id="printFromPreview"><i class="bi bi-printer-fill me-2"></i>打印/保存为PDF</button>
|
||||
<button type="button" class="btn btn-primary" id="printFromPreview"><i
|
||||
class="bi bi-printer-fill me-2"></i>打印/保存为PDF
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -401,13 +455,26 @@
|
||||
|
||||
<!-- Theme Switcher -->
|
||||
<div class="dropdown theme-switch">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="theme-switcher" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="theme-switcher" data-bs-toggle="dropdown"
|
||||
aria-expanded="false">
|
||||
<i class="bi bi-circle-half"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="theme-switcher">
|
||||
<li><button class="dropdown-item" type="button" data-bs-theme-value="light"><i class="bi bi-sun-fill me-2"></i> Light</button></li>
|
||||
<li><button class="dropdown-item" type="button" data-bs-theme-value="dark"><i class="bi bi-moon-stars-fill me-2"></i> Dark</button></li>
|
||||
<li><button class="dropdown-item active" type="button" data-bs-theme-value="auto"><i class="bi bi-circle-half me-2"></i> Auto</button></li>
|
||||
<li>
|
||||
<button class="dropdown-item" type="button" data-bs-theme-value="light"><i class="bi bi-sun-fill me-2"></i>
|
||||
Light
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="dropdown-item" type="button" data-bs-theme-value="dark"><i
|
||||
class="bi bi-moon-stars-fill me-2"></i> Dark
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="dropdown-item active" type="button" data-bs-theme-value="auto"><i
|
||||
class="bi bi-circle-half me-2"></i> Auto
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -481,8 +548,21 @@
|
||||
|
||||
// --- Utility Functions ---
|
||||
const generateTaskId = () => Math.random().toString(36).substring(2, 10);
|
||||
const saveToStorage = (key, value) => { try { localStorage.setItem(key, value); } catch (e) { console.warn("Save to storage failed:", e); } };
|
||||
const getFromStorage = (key, defaultValue = '') => { try { return localStorage.getItem(key) || defaultValue; } catch (e) { console.warn("Read from storage failed:", e); return defaultValue; } };
|
||||
const saveToStorage = (key, value) => {
|
||||
try {
|
||||
localStorage.setItem(key, value);
|
||||
} catch (e) {
|
||||
console.warn("Save to storage failed:", e);
|
||||
}
|
||||
};
|
||||
const getFromStorage = (key, defaultValue = '') => {
|
||||
try {
|
||||
return localStorage.getItem(key) || defaultValue;
|
||||
} catch (e) {
|
||||
console.warn("Read from storage failed:", e);
|
||||
return defaultValue;
|
||||
}
|
||||
};
|
||||
|
||||
function fileToBase64(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -941,7 +1021,9 @@
|
||||
try {
|
||||
translatedPreviewFrame.contentWindow.focus();
|
||||
translatedPreviewFrame.contentWindow.print();
|
||||
} catch(e) { alert('打印失败,请使用浏览器打印功能。'); }
|
||||
} catch (e) {
|
||||
alert('打印失败,请使用浏览器打印功能。');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1075,7 +1157,9 @@
|
||||
platformSelect.addEventListener('change', updatePlatformUI);
|
||||
apikeyInput.addEventListener('input', e => saveToStorage(`translator_platform_${platformSelect.value}_apikey`, e.target.value));
|
||||
modelInput.addEventListener('input', e => saveToStorage(`translator_platform_${platformSelect.value}_model_id`, e.target.value));
|
||||
baseUrlInput.addEventListener('input', e => { if (platformSelect.value === 'custom') saveToStorage('translator_platform_custom_base_url', e.target.value); });
|
||||
baseUrlInput.addEventListener('input', e => {
|
||||
if (platformSelect.value === 'custom') saveToStorage('translator_platform_custom_base_url', e.target.value);
|
||||
});
|
||||
convertEnginSelect.addEventListener('change', updateConvertEnginUI);
|
||||
mineruTokenInput.addEventListener('input', e => saveToStorage('translator_mineru_token', e.target.value));
|
||||
toLangSelect.addEventListener('change', e => saveToStorage('translator_to_lang', e.target.value));
|
||||
|
||||
Reference in New Issue
Block a user