From 82ea4ae6df6ee4b0f9593433a7854dba5d75ca99 Mon Sep 17 00:00:00 2001 From: billchen Date: Fri, 1 Mar 2024 11:26:22 +0800 Subject: [PATCH] feat: display all pdf pages --- web/package-lock.json | 40 ++++++++++ web/package.json | 1 + .../components/document-preview/hooks.ts | 20 +++++ .../components/document-preview/index.less | 6 ++ .../components/document-preview/index.tsx | 79 +++++++++++-------- .../components/knowledge-chunk/hooks.ts | 9 +++ .../components/knowledge-chunk/index.less | 3 +- .../components/knowledge-chunk/index.tsx | 11 ++- .../components/knowledge-chunk/model.ts | 4 +- 9 files changed, 133 insertions(+), 40 deletions(-) create mode 100644 web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/hooks.ts create mode 100644 web/src/pages/add-knowledge/components/knowledge-chunk/hooks.ts diff --git a/web/package-lock.json b/web/package-lock.json index c73ffcbae..6b41aecbf 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -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", diff --git a/web/package.json b/web/package.json index 4a781bbaf..688e6b1b4 100644 --- a/web/package.json +++ b/web/package.json @@ -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", diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/hooks.ts b/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/hooks.ts new file mode 100644 index 000000000..f15990587 --- /dev/null +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/hooks.ts @@ -0,0 +1,20 @@ +import { useSize } from 'ahooks'; +import { useCallback, useEffect, useState } from 'react'; + +export const useDocumentResizeObserver = () => { + const [containerWidth, setContainerWidth] = useState(); + const [containerRef, setContainerRef] = useState(null); + const size = useSize(containerRef); + + const onResize = useCallback((width?: number) => { + if (width) { + setContainerWidth(width); + } + }, []); + + useEffect(() => { + onResize(size?.width); + }, [size?.width, onResize]); + + return { containerWidth, setContainerRef }; +}; diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/index.less b/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/index.less index e69de29bb..69a26abf7 100644 --- a/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/index.less +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/index.less @@ -0,0 +1,6 @@ +.documentContainer { + width: 100%; + height: calc(100vh - 284px); + overflow-y: auto; + overflow-x: hidden; +} diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/index.tsx b/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/index.tsx index 05241120f..aa5a8980e 100644 --- a/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/index.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/document-preview/index.tsx @@ -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(); - const [pageNumber, setPageNumber] = useState(1); const { documentId } = useGetKnowledgeSearchParams(); - const dispatch = useDispatch(); - const [file, setFile] = useState(null); + // const [file, setFile] = useState(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 ( -
- {file && ( - - - - )} - -

- Page {pageNumber} of {numPages} -

+
+ + {Array.from(new Array(numPages), (el, index) => ( + + ))} + {/* */}
); diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/hooks.ts b/web/src/pages/add-knowledge/components/knowledge-chunk/hooks.ts new file mode 100644 index 000000000..c40b07dcd --- /dev/null +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/hooks.ts @@ -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; +}; diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/index.less b/web/src/pages/add-knowledge/components/knowledge-chunk/index.less index 47205bef3..c97956dd8 100644 --- a/web/src/pages/add-knowledge/components/knowledge-chunk/index.less +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/index.less @@ -24,8 +24,7 @@ } .documentPreview { - width: 30%; - overflow: auto; + width: 40%; height: 100%; } diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/index.tsx b/web/src/pages/add-knowledge/components/knowledge-chunk/index.tsx index 23156e15a..7a5a41638 100644 --- a/web/src/pages/add-knowledge/components/knowledge-chunk/index.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/index.tsx @@ -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(); const { removeChunk } = useDeleteChunkByIds(); + const documentInfo = useSelectDocumentInfo(); const getChunkList = useCallback(() => { const payload: PayloadType = { @@ -197,9 +199,12 @@ const Chunk = () => { />
-
- -
+ + {documentInfo.type === 'pdf' && ( +
+ +
+ )} diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/model.ts b/web/src/pages/add-knowledge/components/knowledge-chunk/model.ts index 5fa2a01c8..793a53ea5 100644 --- a/web/src/pages/add-knowledge/components/knowledge-chunk/model.ts +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/model.ts @@ -13,7 +13,7 @@ export interface ChunkModelState extends BaseState { chunk_id: string; doc_id: string; chunkInfo: any; - documentInfo: Partial; + documentInfo: IKnowledgeFile; available?: number; } @@ -26,7 +26,7 @@ const model: DvaModel = { chunk_id: '', doc_id: '', chunkInfo: {}, - documentInfo: {}, + documentInfo: {} as IKnowledgeFile, pagination: { current: 1, pageSize: 10,