支持获取pdf展示体检同意书
This commit is contained in:
1
src/assets/testPdfBase64
Normal file
1
src/assets/testPdfBase64
Normal file
File diff suppressed because one or more lines are too long
@@ -1,4 +1,5 @@
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { pdfjs } from "react-pdf";
|
||||
import "./UI7.css";
|
||||
import "../../assets/css/basic.css";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@@ -7,7 +8,20 @@ import ConfirmButton from "../../components/ConfirmButton";
|
||||
import DecorLine from "../../components/DecorLine";
|
||||
import WaitButton from "../../components/WaitButton";
|
||||
|
||||
const UI6: React.FC = () => {
|
||||
// @ts-ignore - Vite 会处理 ?raw 导入
|
||||
import testPdfBase64Raw from "../../assets/testPdfBase64?raw";
|
||||
const testPdfBase64 = testPdfBase64Raw.trim();
|
||||
|
||||
// 配置 PDF.js worker
|
||||
const workerPath = new URL("pdf.worker.min.js", document.baseURI).href;
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = workerPath;
|
||||
|
||||
if (window.electronAPI) {
|
||||
window.electronAPI.log("info", `[UI7] PDF Worker 路径: ${workerPath}`);
|
||||
}
|
||||
|
||||
|
||||
const UI7: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const [countdown, setCountdown] = useState(5);
|
||||
const [showWaitButton, setShowWaitButton] = useState(true);
|
||||
@@ -15,6 +29,95 @@ const UI6: React.FC = () => {
|
||||
const [isDrawing, setIsDrawing] = useState(false);
|
||||
const dprRef = useRef<number>(1);
|
||||
const lastPointRef = useRef<{ x: number; y: number } | null>(null);
|
||||
|
||||
// PDF 文本提取相关状态
|
||||
const [pdfText, setPdfText] = useState<string>("");
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [error, setError] = useState<string>("");
|
||||
|
||||
// 从 PDF 中提取文本
|
||||
useEffect(() => {
|
||||
const extractTextFromPdf = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
window.electronAPI?.log("info", "[UI7] 开始从 PDF 提取文本");
|
||||
|
||||
// 清理 base64 字符串(移除可能的换行和空格)
|
||||
const cleanBase64 = testPdfBase64.replace(/\s/g, "");
|
||||
window.electronAPI?.log("info", `[UI7] Base64 长度: ${cleanBase64.length}`);
|
||||
|
||||
// 将 base64 转换为 Uint8Array
|
||||
const binaryString = atob(cleanBase64);
|
||||
const bytes = new Uint8Array(binaryString.length);
|
||||
for (let i = 0; i < binaryString.length; i++) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
}
|
||||
|
||||
window.electronAPI?.log("info", `[UI7] 转换为 Uint8Array,长度: ${bytes.length}`);
|
||||
|
||||
// 加载 PDF 文档(使用 Uint8Array)
|
||||
const loadingTask = pdfjs.getDocument({ data: bytes });
|
||||
const pdf = await loadingTask.promise;
|
||||
|
||||
window.electronAPI?.log("info", `[UI7] PDF 加载成功,共 ${pdf.numPages} 页`);
|
||||
|
||||
// 提取所有页面的文本
|
||||
let allText = "";
|
||||
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
|
||||
const page = await pdf.getPage(pageNum);
|
||||
const textContent = await page.getTextContent();
|
||||
|
||||
// 将文本项合并为字符串,保留换行信息
|
||||
let pageText = "";
|
||||
let lastY = null;
|
||||
|
||||
for (let i = 0; i < textContent.items.length; i++) {
|
||||
const item = textContent.items[i] as any;
|
||||
const currentY = item.transform ? item.transform[5] : null; // Y 坐标
|
||||
|
||||
// 如果 Y 坐标变化较大(超过行高的一半),认为是新行
|
||||
if (lastY !== null && currentY !== null && Math.abs(currentY - lastY) > 5) {
|
||||
pageText += "\n";
|
||||
}
|
||||
|
||||
pageText += item.str;
|
||||
|
||||
// 如果当前项后面有空格标记,添加空格
|
||||
if (item.hasEOL) {
|
||||
pageText += "\n";
|
||||
} else if (i < textContent.items.length - 1) {
|
||||
const nextItem = textContent.items[i + 1] as any;
|
||||
const nextX = nextItem.transform ? nextItem.transform[4] : null;
|
||||
const currentX = item.transform ? item.transform[4] : null;
|
||||
const currentWidth = item.width || 0;
|
||||
|
||||
// 如果下一个文本项距离较远,添加空格
|
||||
if (currentX !== null && nextX !== null && (nextX - (currentX + currentWidth)) > 2) {
|
||||
pageText += " ";
|
||||
}
|
||||
}
|
||||
|
||||
lastY = currentY;
|
||||
}
|
||||
|
||||
allText += pageText + "\n\n";
|
||||
}
|
||||
|
||||
window.electronAPI?.log("info", `[UI7] PDF 文本提取完成,长度: ${allText.length}`);
|
||||
setPdfText(allText.trim());
|
||||
setLoading(false);
|
||||
setError("");
|
||||
} catch (err) {
|
||||
const errorMsg = `PDF文本提取失败: ${err}`;
|
||||
console.error(errorMsg);
|
||||
window.electronAPI?.log("error", `[UI7] ${errorMsg}`);
|
||||
setError("PDF 文本提取失败,请检查文件");
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
extractTextFromPdf();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (countdown > 0) {
|
||||
@@ -191,62 +294,19 @@ const UI6: React.FC = () => {
|
||||
|
||||
<div className="ui7-text-wrapper">
|
||||
<div className="ui7-text-content">
|
||||
<span className="paragraph_1">
|
||||
尊敬的受检者:
|
||||
<br />
|
||||
<br />
|
||||
欢迎您参加本次健康体检!为保障您的合法权益,现就体检相关事项告知如下,请您认真阅读并确认签署。
|
||||
<br />
|
||||
一、体检目的
|
||||
<br />
|
||||
<br />
|
||||
本次健康体检旨在通过常规医学检查,了解您的身体健康状况,发现潜在的疾病风险,供您及医生进行健康指导与干预。
|
||||
<br />
|
||||
1.
|
||||
<br />
|
||||
体检结果仅供参考,不等同于临床诊断。如发现异常,请及时到相关专科医院进一步检查与治疗。
|
||||
<br />
|
||||
2.
|
||||
<br />
|
||||
二、体检须知
|
||||
<br />
|
||||
3.
|
||||
<br />
|
||||
空腹要求:抽血、腹部B超等项目需空腹8小时以上。
|
||||
<br />
|
||||
4.
|
||||
<br />
|
||||
女性注意事项:经期及妊娠期女性请提前告知医护人员,避免放射类检查(如胸片、CT等)。
|
||||
<br />
|
||||
5.
|
||||
<br />
|
||||
贵重物品:请妥善保管个人物品,中心不承担遗失责任。
|
||||
<br />
|
||||
身体状况告知:如有重大疾病史、药物过敏史、手术史等,请提前告知医护人员。
|
||||
<br />
|
||||
体检安全:如在体检过程中出现不适,应立即告知现场医护人员。
|
||||
<br />
|
||||
<br />
|
||||
三、隐私与信息保护
|
||||
<br />
|
||||
1.
|
||||
<br />
|
||||
体检机构将严格遵守国家相关法律法规,对您的个人信息和体检资料予以保密,未经本人授权,不会向第三方泄露。
|
||||
<br />
|
||||
2.
|
||||
<br />
|
||||
四、体检风险告知
|
||||
<br />
|
||||
3.
|
||||
<br />
|
||||
部分检查(如抽血、X射线、CT、宫颈刮片等)可能带来轻微不适或风险。
|
||||
<br />
|
||||
体检结果可能存在一定误差,需结合临床进一步判断。
|
||||
<br />
|
||||
若因个人隐瞒病史或未遵守体检要求导致结果偏差,责任由受检者自
|
||||
{loading && <div style={{ padding: "20px", textAlign: "center" }}>PDF文本提取中...</div>}
|
||||
{error && <div style={{ padding: "20px", color: "red", textAlign: "center" }}>{error}</div>}
|
||||
{!loading && !error && pdfText && (
|
||||
<span className="paragraph_1">
|
||||
{pdfText.split("\n").map((line, index) => (
|
||||
<React.Fragment key={index}>
|
||||
{line}
|
||||
{index < pdfText.split("\n").length - 1 && <br />}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<span className="ui7-text_4">请阅读后在下方签名确认</span>
|
||||
@@ -282,4 +342,4 @@ const UI6: React.FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default UI6;
|
||||
export default UI7;
|
||||
|
||||
Reference in New Issue
Block a user