85 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
		
			
		
	
	
			85 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
|  | import { Button, message, Modal, Spin } from "antd"; | |||
|  | import { useState } from "react"; | |||
|  | import { Document, Page, pdfjs } from "react-pdf"; | |||
|  | import { getFileUrl } from "../../utils/index"; | |||
|  | 
 | |||
|  | function Pdf(props) { | |||
|  |   const { | |||
|  |     visible = false, | |||
|  |     onCancel, | |||
|  |     file, | |||
|  |     inline = false, | |||
|  |     style = {}, | |||
|  |   } = props; | |||
|  | 
 | |||
|  |   const fileUrl = getFileUrl(); | |||
|  |   const [numPages, setNumPages] = useState(0); | |||
|  |   const [pdfWidth, setPdfWidth] = useState(600); | |||
|  |   const [loading, setLoading] = useState(true); | |||
|  | 
 | |||
|  |   pdfjs.GlobalWorkerOptions.workerSrc = new URL( | |||
|  |     "pdfjs-dist/build/pdf.worker.min.mjs", | |||
|  |     import.meta.url, | |||
|  |   ).toString(); | |||
|  | 
 | |||
|  |   const onDocumentLoadSuccess = ({ numPages }) => { | |||
|  |     setNumPages(numPages); | |||
|  |     setLoading(false); | |||
|  |   }; | |||
|  | 
 | |||
|  |   const onDocumentLoadError = () => { | |||
|  |     setLoading(false); | |||
|  |     message.error("加载 PDF 文件失败"); | |||
|  |     if (onCancel) | |||
|  |       onCancel(); | |||
|  |   }; | |||
|  | 
 | |||
|  |   const onPageLoadSuccess = ({ width }) => { | |||
|  |     setPdfWidth(width); | |||
|  |   }; | |||
|  | 
 | |||
|  |   // 内联模式的PDF内容
 | |||
|  |   const renderPdfContent = () => ( | |||
|  |     <> | |||
|  |       {loading && ( | |||
|  |         <div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "80vh" }}> | |||
|  |           <Spin size="large" /> | |||
|  |         </div> | |||
|  |       )} | |||
|  |       <div style={{ height: "88vh", overflowY: "auto", padding: "24px", ...style }}> | |||
|  |         <Document | |||
|  |           file={fileUrl + file} | |||
|  |           onLoadSuccess={onDocumentLoadSuccess} | |||
|  |           onLoadError={onDocumentLoadError} | |||
|  |         > | |||
|  |           { | |||
|  |             Array.from({ length: numPages }).map((el, index) => ( | |||
|  |               <Page key={`page_${index + 1}`} pageNumber={index + 1} onLoadSuccess={onPageLoadSuccess} /> | |||
|  |             )) | |||
|  |           } | |||
|  |         </Document> | |||
|  |       </div> | |||
|  |     </> | |||
|  |   ); | |||
|  | 
 | |||
|  |   // 如果是内联模式,直接返回PDF内容
 | |||
|  |   if (inline) { | |||
|  |     return renderPdfContent(); | |||
|  |   } | |||
|  | 
 | |||
|  |   // 默认弹窗模式
 | |||
|  |   return ( | |||
|  |     <Modal | |||
|  |       open={visible} | |||
|  |       width={pdfWidth + 100} | |||
|  |       title="PDF预览" | |||
|  |       onCancel={onCancel} | |||
|  |       footer={<Button onClick={onCancel}>关闭</Button>} | |||
|  |     > | |||
|  |       {renderPdfContent()} | |||
|  |     </Modal> | |||
|  |   ); | |||
|  | } | |||
|  | 
 | |||
|  | export default Pdf; |