3.9 KiB
3.9 KiB
根据你的需求(PDF 内容精确引用到思维导图节点,且支持双向跳转),结合项目技术栈(Next.js + TypeScript),推荐以下 PDF 组件方案:
推荐组件:@react-pdf-viewer/core(搭配 @react-pdf-viewer/selection-mode 插件)
核心优势:
- 精确内容选取:支持页面级、文本片段级选择,可获取选中内容的页码、坐标、文本内容
- 双向链接能力:可生成带定位信息的锚点(如
#page=3&selection=xxx),实现思维导图点击跳转 - React 生态适配:完美兼容 Next.js 15 和 TypeScript,支持 SSR/SSG
- 轻量可扩展:核心包体积小,按需加载插件(如文本选择、搜索、缩放)
实现思路:
- PDF 查看器集成
// components/PDFViewer.tsx
import { Viewer, Worker } from '@react-pdf-viewer/core';
import { selectionModePlugin } from '@react-pdf-viewer/selection-mode';
import '@react-pdf-viewer/core/lib/styles/index.css';
import '@react-pdf-viewer/selection-mode/lib/styles/index.css';
const selectionMode = selectionModePlugin();
const { SelectionMode } = selectionMode;
interface PDFViewerProps {
fileUrl: string;
onSelect: (data: {
text: string;
pageNumber: number;
position: { x: number; y: number };
}) => void;
}
export default function PDFViewer({ fileUrl, onSelect }: PDFViewerProps) {
return (
<Worker workerUrl="https://unpkg.com/pdfjs-dist@3.4.120/build/pdf.worker.min.js">
<SelectionMode
onSelect={(args) => {
if (args.selectionText) {
onSelect({
text: args.selectionText,
pageNumber: args.pageIndex + 1, // 页码从1开始
position: args.selectionRects[0]?.position || { x: 0, y: 0 },
});
}
}}
>
<Viewer fileUrl={fileUrl} plugins={[selectionMode]} />
</SelectionMode>
</Worker>
);
}
- 思维导图节点与 PDF 引用绑定
// 思维导图节点数据结构扩展
interface MindMapNode {
id: string;
text: string;
pdfReference?: {
fileId: string; // 关联的PDF文件ID
pageNumber: number;
text: string; // 引用的文本内容
position?: { x: number; y: number }; // 可选:更精确的定位
};
}
// 点击节点跳转PDF
const handleNodeClick = (node: MindMapNode) => {
if (node.pdfReference) {
// 导航到PDF查看页并定位
router.push(`/documents/${node.pdfReference.fileId}?page=${node.pdfReference.pageNumber}`);
}
};
- PDF 选择内容插入思维导图
// 在PDF查看页中使用
const PDFDocumentPage = ({ params }) => {
const [mindMapNodes, setMindMapNodes] = useState<MindMapNode[]>([]);
const handlePDFSelect = (data) => {
// 创建新节点并关联PDF引用
const newNode: MindMapNode = {
id: uuidv4(),
text: data.text.substring(0, 50) + '...', // 截断显示
pdfReference: {
fileId: params.id,
pageNumber: data.pageNumber,
text: data.text,
position: data.position,
},
};
setMindMapNodes([...mindMapNodes, newNode]);
};
return <PDFViewer fileUrl={pdfUrl} onSelect={handlePDFSelect} />;
};
- 双向跳转优化
- 在 PDF 查看页加载时,通过 URL 参数自动定位到指定页:
const { page } = useSearchParams(); const defaultPage = page ? parseInt(page.toString()) : 1; // 传递defaultPage给Viewer组件 - 思维导图节点显示引用标识(如 📄3 表示引用第3页),增强可视化关联
备选方案:
如果需要更强大的 PDF 处理能力(如 MinerU 提取后的结构化内容引用),可结合:
- 后端:MinerU 提取 PDF 时记录「文本块-页码」映射关系
- 前端:通过
@react-pdf-viewer定位到 MinerU 识别的文本块位置
该方案完全符合项目前后端分离架构,且能无缝集成到现有的思维导图(simple-mind-map)和文档系统中。