feat: hightlight pdf

This commit is contained in:
billchen 2024-03-01 16:37:11 +08:00
parent 25187b1ad7
commit a14c14ee4c
5 changed files with 60 additions and 7 deletions

View file

@ -1,4 +1,5 @@
import { useSize } from 'ahooks';
import { CustomTextRenderer } from 'node_modules/react-pdf/dist/esm/shared/types';
import { useCallback, useEffect, useState } from 'react';
export const useDocumentResizeObserver = () => {
@ -18,3 +19,27 @@ export const useDocumentResizeObserver = () => {
return { containerWidth, setContainerRef };
};
function highlightPattern(text: string, pattern: string, pageNumber: number) {
const finalText = '';
console.info(text);
if (pageNumber === 2) {
return `<mark>${text}</mark>`;
}
if (text.trim() !== '' && pattern.match(text)) {
// return pattern.replace(text, (value) => `<mark>${value}</mark>`);
return `<mark>${text}</mark>`;
}
return text.replace(pattern, (value) => `<mark>${value}</mark>`);
}
export const useHighlightText = (searchText: string = '') => {
const textRenderer: CustomTextRenderer = useCallback(
(textItem) => {
return highlightPattern(textItem.str, searchText, textItem.pageNumber);
},
[searchText],
);
return textRenderer;
};

View file

@ -5,8 +5,10 @@ import { Document, Page, pdfjs } from 'react-pdf';
import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
import 'react-pdf/dist/esm/Page/TextLayer.css';
import { useDocumentResizeObserver } from './hooks';
import { useDocumentResizeObserver, useHighlightText } from './hooks';
import { Spin } from 'antd';
import { useGetSelectedChunk } from '../../hooks';
import styles from './index.less';
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
@ -14,10 +16,17 @@ pdfjs.GlobalWorkerOptions.workerSrc = new URL(
import.meta.url,
).toString();
const DocumentPreview = () => {
interface IProps {
selectedChunkId: string;
}
const DocumentPreview = ({ selectedChunkId }: IProps) => {
const [numPages, setNumPages] = useState<number>();
const { documentId } = useGetKnowledgeSearchParams();
const { containerWidth, setContainerRef } = useDocumentResizeObserver();
const selectedChunk = useGetSelectedChunk(selectedChunkId);
console.info(selectedChunk?.content_with_weight);
const textRenderer = useHighlightText(selectedChunk?.content_with_weight);
function onDocumentLoadSuccess({ numPages }: { numPages: number }): void {
setNumPages(numPages);
@ -29,12 +38,17 @@ const DocumentPreview = () => {
return (
<div ref={setContainerRef} className={styles.documentContainer}>
<Document file={url} onLoadSuccess={onDocumentLoadSuccess}>
<Document
file={url}
onLoadSuccess={onDocumentLoadSuccess}
loading={<Spin></Spin>}
>
{Array.from(new Array(numPages), (el, index) => (
<Page
key={`page_${index + 1}`}
pageNumber={index + 1}
width={containerWidth}
customTextRenderer={textRenderer}
/>
))}
</Document>

View file

@ -1,4 +1,4 @@
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
import { IChunk, IKnowledgeFile } from '@/interfaces/database/knowledge';
import { useCallback, useState } from 'react';
import { useSelector } from 'umi';
@ -9,6 +9,13 @@ export const useSelectDocumentInfo = () => {
return documentInfo;
};
export const useSelectChunkList = () => {
const chunkList: IChunk[] = useSelector(
(state: any) => state.chunkModel.data,
);
return chunkList;
};
export const useHandleChunkCardClick = () => {
const [selectedChunkId, setSelectedChunkId] = useState<string>('');
@ -18,3 +25,8 @@ export const useHandleChunkCardClick = () => {
return { handleChunkCardClick, selectedChunkId };
};
export const useGetSelectedChunk = (selectedChunkId: string) => {
const chunkList: IChunk[] = useSelectChunkList();
return chunkList.find((x) => x.chunk_id === selectedChunkId);
};

View file

@ -205,7 +205,9 @@ const Chunk = () => {
{documentInfo.type === 'pdf' && (
<section className={styles.documentPreview}>
<DocumentPreview></DocumentPreview>
<DocumentPreview
selectedChunkId={selectedChunkId}
></DocumentPreview>
</section>
)}
</Flex>

View file

@ -1,5 +1,5 @@
import { BaseState } from '@/interfaces/common';
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
import { IChunk, IKnowledgeFile } from '@/interfaces/database/knowledge';
import kbService from '@/services/kbService';
import { message } from 'antd';
import { pick } from 'lodash';
@ -7,7 +7,7 @@ import { pick } from 'lodash';
import { DvaModel } from 'umi';
export interface ChunkModelState extends BaseState {
data: any[];
data: IChunk[];
total: number;
isShowCreateModal: boolean;
chunk_id: string;