feat: display all pdf pages
This commit is contained in:
parent
a6ae5b77d2
commit
82ea4ae6df
9 changed files with 133 additions and 40 deletions
40
web/package-lock.json
generated
40
web/package-lock.json
generated
|
|
@ -9,6 +9,7 @@
|
|||
"@ant-design/icons": "^5.2.6",
|
||||
"@ant-design/pro-components": "^2.6.46",
|
||||
"@ant-design/pro-layout": "^7.17.16",
|
||||
"ahooks": "^3.7.10",
|
||||
"antd": "^5.12.7",
|
||||
"axios": "^1.6.3",
|
||||
"classnames": "^2.5.1",
|
||||
|
|
@ -4763,6 +4764,27 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ahooks": {
|
||||
"version": "3.7.10",
|
||||
"resolved": "https://registry.npmmirror.com/ahooks/-/ahooks-3.7.10.tgz",
|
||||
"integrity": "sha512-/HLYif7sFA/5qSuWKrwvjDbf3bq+sdaMrUWS7XGCDRWdC2FrG/i+u5LZdakMYc6UIgJTMQ7tGiJCV7sdU4kSIw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"dayjs": "^1.9.1",
|
||||
"intersection-observer": "^0.12.0",
|
||||
"js-cookie": "^2.x.x",
|
||||
"lodash": "^4.17.21",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"screenfull": "^5.0.0",
|
||||
"tslib": "^2.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
|
||||
|
|
@ -9843,6 +9865,11 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/intersection-observer": {
|
||||
"version": "0.12.2",
|
||||
"resolved": "https://registry.npmmirror.com/intersection-observer/-/intersection-observer-0.12.2.tgz",
|
||||
"integrity": "sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg=="
|
||||
},
|
||||
"node_modules/intl": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmmirror.com/intl/-/intl-1.2.5.tgz",
|
||||
|
|
@ -10730,6 +10757,11 @@
|
|||
"resolved": "https://registry.npmmirror.com/js-base64/-/js-base64-3.7.5.tgz",
|
||||
"integrity": "sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA=="
|
||||
},
|
||||
"node_modules/js-cookie": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/js-cookie/-/js-cookie-2.2.1.tgz",
|
||||
"integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ=="
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
|
|
@ -15550,6 +15582,14 @@
|
|||
"node": ">= 10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/screenfull": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/screenfull/-/screenfull-5.2.0.tgz",
|
||||
"integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/scroll-into-view-if-needed": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz",
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
"@ant-design/icons": "^5.2.6",
|
||||
"@ant-design/pro-components": "^2.6.46",
|
||||
"@ant-design/pro-layout": "^7.17.16",
|
||||
"ahooks": "^3.7.10",
|
||||
"antd": "^5.12.7",
|
||||
"axios": "^1.6.3",
|
||||
"classnames": "^2.5.1",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
import { useSize } from 'ahooks';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
export const useDocumentResizeObserver = () => {
|
||||
const [containerWidth, setContainerWidth] = useState<number>();
|
||||
const [containerRef, setContainerRef] = useState<HTMLElement | null>(null);
|
||||
const size = useSize(containerRef);
|
||||
|
||||
const onResize = useCallback((width?: number) => {
|
||||
if (width) {
|
||||
setContainerWidth(width);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
onResize(size?.width);
|
||||
}, [size?.width, onResize]);
|
||||
|
||||
return { containerWidth, setContainerRef };
|
||||
};
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
.documentContainer {
|
||||
width: 100%;
|
||||
height: calc(100vh - 284px);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
|
@ -1,59 +1,72 @@
|
|||
import { useGetKnowledgeSearchParams } from '@/hooks/knowledgeHook';
|
||||
import { getDocumentFile } from '@/services/kbService';
|
||||
import { api_host } from '@/utils/api';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { Document, Page, pdfjs } from 'react-pdf';
|
||||
import { useDispatch } from 'umi';
|
||||
|
||||
type PDFFile = string | File | null;
|
||||
import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
|
||||
import 'react-pdf/dist/esm/Page/TextLayer.css';
|
||||
import { useDocumentResizeObserver } from './hooks';
|
||||
|
||||
import styles from './index.less';
|
||||
|
||||
// type PDFFile = string | File | null;
|
||||
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||
'pdfjs-dist/build/pdf.worker.min.js',
|
||||
import.meta.url,
|
||||
).toString();
|
||||
|
||||
// const options = {
|
||||
// cMapUrl: '/cmaps/',
|
||||
// standardFontDataUrl: '/standard_fonts/',
|
||||
// };
|
||||
|
||||
const DocumentPreview = () => {
|
||||
const [numPages, setNumPages] = useState<number>();
|
||||
const [pageNumber, setPageNumber] = useState<number>(1);
|
||||
const { documentId } = useGetKnowledgeSearchParams();
|
||||
const dispatch = useDispatch();
|
||||
const [file, setFile] = useState<PDFFile>(null);
|
||||
// const [file, setFile] = useState<PDFFile>(null);
|
||||
const { containerWidth, setContainerRef } = useDocumentResizeObserver();
|
||||
|
||||
function onDocumentLoadSuccess({ numPages }: { numPages: number }): void {
|
||||
setNumPages(numPages);
|
||||
}
|
||||
|
||||
const handleChange = (e: any) => {
|
||||
console.info(e.files);
|
||||
setFile(e.target.files[0] || null);
|
||||
};
|
||||
// const handleChange = (e: any) => {
|
||||
// console.info(e.files);
|
||||
// setFile(e.target.files[0] || null);
|
||||
// };
|
||||
|
||||
const url = `${api_host}/document/get/${documentId}`;
|
||||
|
||||
const fetch_document_file = useCallback(async () => {
|
||||
const ret: Blob = await getDocumentFile(documentId);
|
||||
console.info(ret);
|
||||
const f = new File([ret], 'xx.pdf', { type: ret.type });
|
||||
// console.info(f);
|
||||
setFile(f);
|
||||
const url = useMemo(() => {
|
||||
return `${api_host}/document/get/${documentId}`;
|
||||
}, [documentId]);
|
||||
|
||||
useEffect(() => {
|
||||
// dispatch({ type: 'kFModel/fetch_document_file', payload: documentId });
|
||||
fetch_document_file();
|
||||
}, [fetch_document_file]);
|
||||
// const fetch_document_file = useCallback(async () => {
|
||||
// const ret: Blob = await getDocumentFile(documentId);
|
||||
// console.info(ret);
|
||||
// const f = new File([ret], 'xx.pdf', { type: ret.type });
|
||||
// setFile(f);
|
||||
// }, [documentId]);
|
||||
|
||||
// useEffect(() => {
|
||||
// // dispatch({ type: 'kFModel/fetch_document_file', payload: documentId });
|
||||
// fetch_document_file();
|
||||
// }, [fetch_document_file]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{file && (
|
||||
<Document file={file} onLoadSuccess={onDocumentLoadSuccess}>
|
||||
<Page pageNumber={pageNumber} />
|
||||
</Document>
|
||||
)}
|
||||
|
||||
<p>
|
||||
Page {pageNumber} of {numPages}
|
||||
</p>
|
||||
<div ref={setContainerRef} className={styles.documentContainer}>
|
||||
<Document
|
||||
file={url}
|
||||
onLoadSuccess={onDocumentLoadSuccess}
|
||||
// options={options}
|
||||
>
|
||||
{Array.from(new Array(numPages), (el, index) => (
|
||||
<Page
|
||||
key={`page_${index + 1}`}
|
||||
pageNumber={index + 1}
|
||||
width={containerWidth}
|
||||
/>
|
||||
))}
|
||||
</Document>
|
||||
{/* <input type="file" onChange={handleChange} /> */}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import { useSelector } from 'umi';
|
||||
|
||||
export const useSelectDocumentInfo = () => {
|
||||
const documentInfo: IKnowledgeFile = useSelector(
|
||||
(state: any) => state.chunkModel.documentInfo,
|
||||
);
|
||||
return documentInfo;
|
||||
};
|
||||
|
|
@ -24,8 +24,7 @@
|
|||
}
|
||||
|
||||
.documentPreview {
|
||||
width: 30%;
|
||||
overflow: auto;
|
||||
width: 40%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { useDeleteChunkByIds } from '@/hooks/knowledgeHook';
|
|||
import ChunkCard from './components/chunk-card';
|
||||
import ChunkToolBar from './components/chunk-toolbar';
|
||||
import DocumentPreview from './components/document-preview';
|
||||
import { useSelectDocumentInfo } from './hooks';
|
||||
import styles from './index.less';
|
||||
import { ChunkModelState } from './model';
|
||||
|
||||
|
|
@ -34,6 +35,7 @@ const Chunk = () => {
|
|||
const documentId: string = searchParams.get('doc_id') || '';
|
||||
const [chunkId, setChunkId] = useState<string | undefined>();
|
||||
const { removeChunk } = useDeleteChunkByIds();
|
||||
const documentInfo = useSelectDocumentInfo();
|
||||
|
||||
const getChunkList = useCallback(() => {
|
||||
const payload: PayloadType = {
|
||||
|
|
@ -197,9 +199,12 @@ const Chunk = () => {
|
|||
/>
|
||||
</div>
|
||||
</Flex>
|
||||
<section className={styles.documentPreview}>
|
||||
<DocumentPreview></DocumentPreview>
|
||||
</section>
|
||||
|
||||
{documentInfo.type === 'pdf' && (
|
||||
<section className={styles.documentPreview}>
|
||||
<DocumentPreview></DocumentPreview>
|
||||
</section>
|
||||
)}
|
||||
</Flex>
|
||||
</div>
|
||||
<CreatingModal doc_id={documentId} chunkId={chunkId} />
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export interface ChunkModelState extends BaseState {
|
|||
chunk_id: string;
|
||||
doc_id: string;
|
||||
chunkInfo: any;
|
||||
documentInfo: Partial<IKnowledgeFile>;
|
||||
documentInfo: IKnowledgeFile;
|
||||
available?: number;
|
||||
}
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ const model: DvaModel<ChunkModelState> = {
|
|||
chunk_id: '',
|
||||
doc_id: '',
|
||||
chunkInfo: {},
|
||||
documentInfo: {},
|
||||
documentInfo: {} as IKnowledgeFile,
|
||||
pagination: {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue