88 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.1 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";
 | ||
| 
 | ||
| /**
 | ||
|  * PDF查看组件
 | ||
|  */
 | ||
| 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;
 |