setShowSwitchMenu(false)}
+ />
{/* 最近阅读部分 */}
{recentlySelected.length > 0 && (
@@ -96,7 +115,7 @@ export function ReaderToolbar({
最近阅读
- {recentlySelected.map(paper => (
+ {recentlySelected.map((paper) => (
))}
)}
-
+
{/* 全部馆藏已下载文献 */}
全部已下载馆藏
- {library.filter(p => p.is_downloaded).length === 0 ? (
-
暂无已下载文献
+ {library.filter((p) => p.is_downloaded).length === 0 ? (
+
+ 暂无已下载文献
+
) : (
library
- .filter(p => p.is_downloaded)
- .map(paper => (
+ .filter((p) => p.is_downloaded)
+ .map((paper) => (
))
)}
@@ -196,7 +225,9 @@ export function ReaderToolbar({
type="button"
onClick={() => {
if (showPdf) {
- alert("【PDF同步滚动技术限制说明】\n\nPDF 预览采用的是浏览器原生的 PDF 插件沙箱。受底层浏览器跨域安全限制和外部插件机制影响,网页脚本无法直接读取和控制 PDF 的滚动位置,因而无法实现物理同步滚动。\n\n【强烈建议】\n点击左侧面板顶部的「显示正文」按钮切换到解析正文模式。在解析正文模式下,系统将自动激活「自适应双轨滚动同步引擎(方案三)」,提供段落级的高精度无缝对齐同步滚动体验!");
+ alert(
+ '【PDF同步滚动技术限制说明】\n\nPDF 预览采用的是浏览器原生的 PDF 插件沙箱。受底层浏览器跨域安全限制和外部插件机制影响,网页脚本无法直接读取和控制 PDF 的滚动位置,因而无法实现物理同步滚动。\n\n【强烈建议】\n点击左侧面板顶部的「显示正文」按钮切换到解析正文模式。在解析正文模式下,系统将自动激活「自适应双轨滚动同步引擎(方案三)」,提供段落级的高精度无缝对齐同步滚动体验!'
+ );
return;
}
setSyncScroll(!syncScroll);
@@ -205,13 +236,21 @@ export function ReaderToolbar({
showPdf
? 'bg-slate-50 text-slate-400 border-slate-200 cursor-not-allowed opacity-70'
: syncScroll
- ? 'bg-sky-50 text-sky-700 border-sky-200 shadow-sm'
- : 'bg-white text-slate-600 border-slate-200 hover:bg-slate-55'
+ ? 'bg-sky-50 text-sky-700 border-sky-200 shadow-sm'
+ : 'bg-white text-slate-600 border-slate-200 hover:bg-slate-55'
}`}
- title={showPdf ? 'PDF预览模式下不支持同步滚动,请点击左侧“显示正文”切换到正文模式' : '开启或关闭中英段落双轨同步滚动'}
+ title={
+ showPdf
+ ? 'PDF预览模式下不支持同步滚动,请点击左侧“显示正文”切换到正文模式'
+ : '开启或关闭中英段落双轨同步滚动'
+ }
>
-
-
同步滚动:{showPdf ? 'PDF暂不支持' : syncScroll ? '开启' : '关闭'}
+
+
+ 同步滚动:{showPdf ? 'PDF暂不支持' : syncScroll ? '开启' : '关闭'}
+
)}
@@ -222,21 +261,33 @@ export function ReaderToolbar({
disabled={parsing}
className="hidden xl:flex btn-console btn-console-primary px-4 py-2 rounded-lg text-xs font-bold items-center gap-2"
>
- {parsing ?
:
}
+ {parsing ? (
+
+ ) : (
+
+ )}
{parsing ? '正文结构解析中...' : '解析源文正文'}
) : (
)}
@@ -248,7 +299,11 @@ export function ReaderToolbar({
disabled={translating}
className="hidden xl:flex btn-console btn-console-primary px-4 py-2 rounded-lg text-xs font-bold items-center gap-2"
>
- {translating ?
:
}
+ {translating ? (
+
+ ) : (
+
+ )}
{translating ? '天文学术语对比翻译中...' : '生成智能翻译'}
)}
@@ -260,7 +315,11 @@ export function ReaderToolbar({
className="hidden xl:flex btn-console btn-console-secondary px-4 py-2 rounded-lg text-xs font-bold items-center gap-2"
title="清除翻译缓存并重新生成大模型对照翻译"
>
- {translating ?
:
}
+ {translating ? (
+
+ ) : (
+
+ )}
重新翻译
)}
@@ -273,7 +332,11 @@ export function ReaderToolbar({
className="hidden xl:flex btn-console btn-console-primary px-4 py-2 rounded-lg text-xs font-bold items-center gap-2"
title="对文献进行知识入库,以开启学术 AI 研讨"
>
- {vectorizing ?
:
}
+ {vectorizing ? (
+
+ ) : (
+
+ )}
{vectorizing ? '正在进行知识入库...' : '知识入库'}
)}
@@ -281,19 +344,27 @@ export function ReaderToolbar({
{selectedPaper.has_markdown && selectedPaper.has_vector && (
)}
-
+
{/* 移动端/平板端 折叠后的“文献操作”菜单 */}
-
+
{showActionsMenu && (
<>
-
setShowActionsMenu(false)} />
+
setShowActionsMenu(false)}
+ />
-
{/* 同步滚动 */}
{(englishText || chineseText) && viewMode === 'bilingual' && (
)}
@@ -352,9 +430,13 @@ export function ReaderToolbar({
>
)}
-
+
{/* 4. 学术助手按钮 */}
{
setShowNotesPanel(!showNotesPanel);
}}
className={`btn-console px-2 sm:px-4 py-2 rounded-lg text-xs font-bold flex items-center gap-1 sm:gap-2 transition-all cursor-pointer shrink-0 ${
- showNotesPanel ? 'bg-sky-50 text-sky-700 border-sky-200 shadow-xs' : 'btn-console-secondary'
+ showNotesPanel
+ ? 'bg-sky-50 text-sky-700 border-sky-200 shadow-xs'
+ : 'btn-console-secondary'
}`}
title="开启或关闭侧边学术助手(包含阅读手札与 AI 问答)"
>
- 学术助手助手
+ 学术助手
+ 助手
{notesCount > 0 && (
{notesCount}
diff --git a/dashboard/src/components/sync/BatchPipelineCard.tsx b/dashboard/src/components/sync/BatchPipelineCard.tsx
index 7d4533d..39129fa 100644
--- a/dashboard/src/components/sync/BatchPipelineCard.tsx
+++ b/dashboard/src/components/sync/BatchPipelineCard.tsx
@@ -1,12 +1,23 @@
// dashboard/src/components/sync/BatchPipelineCard.tsx
import React from 'react';
-import { Download, AlertTriangle, Play, StopCircle, Loader, FileText, RefreshCw, SlidersHorizontal } from 'lucide-react';
+import {
+ Download,
+ AlertTriangle,
+ Play,
+ StopCircle,
+ Loader,
+ FileText,
+ RefreshCw,
+ SlidersHorizontal,
+} from 'lucide-react';
import { CustomSelect } from '../CustomSelect';
import type { BatchStatus } from '../../hooks/useSyncState';
interface BatchPipelineCardProps {
targetPhase: 'download' | 'parse' | 'translate' | 'embed' | 'target';
- setTargetPhase: (p: 'download' | 'parse' | 'translate' | 'embed' | 'target') => void;
+ setTargetPhase: (
+ p: 'download' | 'parse' | 'translate' | 'embed' | 'target'
+ ) => void;
batchLimitCount: number;
setBatchLimitCount: (c: number) => void;
sortOrder: 'default' | 'pub_year_desc' | 'created_at_desc';
@@ -55,7 +66,8 @@ export function BatchPipelineCard({
馆藏文献批量学术流水线任务
- 针对本地馆藏中的文献,批量发起正文 PDF/HTML 下载、Markdown 结构化排版解析以及中英双语对照翻译。
+ 针对本地馆藏中的文献,批量发起正文 PDF/HTML 下载、Markdown
+ 结构化排版解析以及中英双语对照翻译。
@@ -69,11 +81,17 @@ export function BatchPipelineCard({
{/* 条件设置 */}
-
+
setTargetPhase(val as 'download' | 'parse' | 'translate' | 'embed' | 'target')}
+ onChange={(val) =>
+ setTargetPhase(
+ val as 'download' | 'parse' | 'translate' | 'embed' | 'target'
+ )
+ }
className="w-full"
options={[
{ value: 'download', label: '下载' },
@@ -86,22 +104,32 @@ export function BatchPipelineCard({
-
+
setBatchLimitCount(Math.max(1, parseInt(e.target.value) || 0))}
+ onChange={(e) =>
+ setBatchLimitCount(Math.max(1, parseInt(e.target.value) || 0))
+ }
className="w-full px-3 py-2 rounded-md bg-slate-50 border border-slate-300 text-slate-900 focus:outline-none focus:border-blueprint transition-all text-xs font-medium"
/>
-
+
setSortOrder(val as 'default' | 'pub_year_desc' | 'created_at_desc')}
+ onChange={(val) =>
+ setSortOrder(
+ val as 'default' | 'pub_year_desc' | 'created_at_desc'
+ )
+ }
className="w-full"
options={[
{ value: 'default', label: '默认(不指定)' },
@@ -114,14 +142,16 @@ export function BatchPipelineCard({
{/* 执行策略 */}
-
+