2025-10-22 17:54:38 +08:00
|
|
|
|
import { Button, message, Modal, Spin } from "antd";
|
|
|
|
|
|
import { useState } from "react";
|
|
|
|
|
|
import { Document, Page, pdfjs } from "react-pdf";
|
|
|
|
|
|
import { getFileUrl } from "../../utils/index";
|
|
|
|
|
|
|
2025-10-28 15:16:58 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* PDF查看组件
|
|
|
|
|
|
*/
|
2025-10-22 17:54:38 +08:00
|
|
|
|
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;
|