diff --git a/src/api/his.ts b/src/api/his.ts index 166e3ad..bd08f4b 100644 --- a/src/api/his.ts +++ b/src/api/his.ts @@ -18,6 +18,8 @@ import type { TongyishuGetResponse, InputTongyishuSignSubmit, TongyishuSignSubmitResponse, + InputDaojiandanInfo, + DaojiandanGetResponse, InputDaojiandanSignSubmit, DaojiandanSignSubmitResponse, InputCustomerDetailEdit, @@ -240,6 +242,18 @@ export const checkNativePaymentStatus = ( ).then(res => res.data); }; +/** + * 获取体检导检单PDF + */ +export const getDaojiandanPdf = ( + data: InputDaojiandanInfo +): Promise => { + return request.post( + `${MEDICAL_EXAM_BASE_PATH}/daojiandan-get`, + data + ).then(res => res.data); +}; + /** * 提交体检签名生成导检单PDF */ diff --git a/src/api/types.ts b/src/api/types.ts index 065e120..975c467 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -346,6 +346,31 @@ export interface OutputTongyishuSignInfo { */ export type TongyishuSignSubmitResponse = CommonActionResult; +/** + * 获取体检导检单PDF入参 + */ +export interface InputDaojiandanInfo { + /** 体检ID */ + exam_id: number; +} + +/** + * 获取体检导检单PDF出参 + */ +export interface OutputDaojiandanInfo { + /** 导检单文件名称 */ + pdf_name?: string | null; + /** 导检单PDF文件地址 */ + pdf_url?: string | null; + /** 提示信息 */ + message?: string | null; +} + +/** + * 获取体检导检单PDF响应 + */ +export type DaojiandanGetResponse = CommonActionResult; + /** * 提交体检签名生成导检单PDF入参 */ diff --git a/src/components/exam/ExamPrintPanel.tsx b/src/components/exam/ExamPrintPanel.tsx index 731eb39..cb1ed5f 100644 --- a/src/components/exam/ExamPrintPanel.tsx +++ b/src/components/exam/ExamPrintPanel.tsx @@ -1,8 +1,8 @@ import { useEffect, useRef, useState } from 'react'; -import { submitDaojiandanSign } from '../../api'; +import { getDaojiandanPdf as getDaojiandanPdfApi, submitDaojiandanSign } from '../../api'; import type { ExamClient } from '../../data/mockData'; -import { setExamActionRecord } from '../../utils/examActions'; +import { setExamActionRecord, setDaojiandanPdf, getDaojiandanPdf } from '../../utils/examActions'; import type { SignaturePadHandle } from '../ui'; import { Button, SignaturePad } from '../ui'; @@ -15,6 +15,8 @@ export const ExamPrintPanel = ({ client }: { client: ExamClient }) => { const [signatureSubmitted, setSignatureSubmitted] = useState(false); const [submitLoading, setSubmitLoading] = useState(false); const [submitMessage, setSubmitMessage] = useState(null); + const [showPreview, setShowPreview] = useState(false); + const [fetchLoading, setFetchLoading] = useState(false); const signaturePadRef = useRef(null); const printRef = useRef(null); const iframeRef = useRef(null); @@ -47,7 +49,14 @@ export const ExamPrintPanel = ({ client }: { client: ExamClient }) => { if (res.Status === 200 && res.Data?.pdf_url) { setSubmitMessage('签名提交成功,正在加载导检单...'); setSignatureSubmitted(true); - setPdfUrl(res.Data.pdf_url); + const pdfUrlValue = res.Data.pdf_url; + const pdfNameValue = res.Data.pdf_name || '导检单'; + setPdfUrl(pdfUrlValue); + // 保存导检单PDF信息到localStorage + setDaojiandanPdf(examId, { + pdf_name: pdfNameValue, + pdf_url: pdfUrlValue, + }); // 记录打印导检单是否签名操作 setExamActionRecord(examId, 'printSign', true); } else { @@ -61,6 +70,62 @@ export const ExamPrintPanel = ({ client }: { client: ExamClient }) => { } }; + // 组件加载时检查localStorage,如果有则直接展示 + useEffect(() => { + const examId = Number(client.id); + if (!examId) return; + + const storedPdf = getDaojiandanPdf(examId); + if (storedPdf && storedPdf.pdf_url) { + setPdfUrl(storedPdf.pdf_url); + setShowPreview(true); + } + }, [client.id]); + + // 获取导检单PDF(优先使用localStorage,没有则调用接口) + const handleFetchPdf = async () => { + const examId = Number(client.id); + if (!examId) { + setError('无效的体检ID'); + return; + } + + setFetchLoading(true); + setError(null); + + try { + // 先尝试从localStorage获取 + const storedPdf = getDaojiandanPdf(examId); + if (storedPdf && storedPdf.pdf_url) { + setPdfUrl(storedPdf.pdf_url); + setShowPreview(true); + setFetchLoading(false); + return; + } + + // 如果没有存储的,则调用接口获取 + const res = await getDaojiandanPdfApi({ exam_id: examId }); + if (res.Status === 200 && res.Data?.pdf_url) { + const pdfUrlValue = res.Data.pdf_url; + const pdfNameValue = res.Data.pdf_name || '导检单'; + setPdfUrl(pdfUrlValue); + // 保存到localStorage + setDaojiandanPdf(examId, { + pdf_name: pdfNameValue, + pdf_url: pdfUrlValue, + }); + setShowPreview(true); + } else { + setError(res.Message || '获取导检单失败'); + } + } catch (err) { + console.error('获取导检单失败', err); + setError('获取导检单失败,请稍后重试'); + } finally { + setFetchLoading(false); + } + }; + useEffect(() => { if (!pdfUrl) return; @@ -110,7 +175,7 @@ export const ExamPrintPanel = ({ client }: { client: ExamClient }) => {
圆和医疗体检中心 · 导检单预览
- {signatureSubmitted + {signatureSubmitted || showPreview ? '此为预览页面,实际打印效果以院内打印机为准。' : '请先完成签名,签名后将生成导检单PDF'}
@@ -120,6 +185,38 @@ export const ExamPrintPanel = ({ client }: { client: ExamClient }) => {
体检号:{client.id}
日期:{new Date().toLocaleDateString('zh-CN')}
+ {!showPreview && !signatureSubmitted && ( + + )} + {showPreview && !signatureSubmitted && ( + <> + + + + )} {signatureSubmitted && ( + ) : fetchLoading ? ( +
+
正在加载导检单...
+
) : loading ? (
正在加载PDF...
@@ -176,17 +277,30 @@ export const ExamPrintPanel = ({ client }: { client: ExamClient }) => { ) : error ? (
{error}
- + {signatureSubmitted ? ( + + ) : ( + + )}
) : pdfUrl ? (
diff --git a/src/utils/clean.ts b/src/utils/clean.ts index 4305a5d..95cb6b4 100644 --- a/src/utils/clean.ts +++ b/src/utils/clean.ts @@ -14,6 +14,7 @@ const CLEAN_LAST_TIME_KEY = 'yh_local_clean_last_time'; * - yh_tongyishu_pdf_list_2025-12-24_100057962 * - yh_exam_actions_2025-12-24_100057962 * - yh_signed_consents_2025-12-24 + * - yh_daojiandan_pdf_2025-12-24_100057962 */ export const cleanLocalStorageIfNeeded = (): void => { if (typeof window === 'undefined' || !window.localStorage) return; @@ -62,6 +63,16 @@ export const cleanLocalStorageIfNeeded = (): void => { } continue; } + + // 匹配 yh_daojiandan_pdf_YYYY-MM-DD_xxx + const matchDaojiandan = key.match(/^yh_daojiandan_pdf_(\d{4}-\d{2}-\d{2})_/); + if (matchDaojiandan) { + const date = matchDaojiandan[1]; + if (date !== today) { + keysToRemove.push(key); + } + continue; + } } // 执行删除 diff --git a/src/utils/examActions.ts b/src/utils/examActions.ts index d12936e..ac1799e 100644 --- a/src/utils/examActions.ts +++ b/src/utils/examActions.ts @@ -138,3 +138,53 @@ export const getTongyishuPdfList = (examId: string | number): TongyishuPdfInfo[] } }; +/** + * 导检单PDF信息 + */ +export interface DaojiandanPdfInfo { + /** PDF文件名称 */ + pdf_name: string; + /** PDF文件地址 */ + pdf_url: string; +} + +/** + * 获取导检单PDF的存储 key + */ +export const getDaojiandanPdfKey = (examId: string | number): string => { + const today = getTodayString(); + return `yh_daojiandan_pdf_${today}_${examId}`; +}; + +/** + * 存储导检单PDF信息 + */ +export const setDaojiandanPdf = ( + examId: string | number, + pdfInfo: DaojiandanPdfInfo +): void => { + if (typeof window === 'undefined') return; + + const key = getDaojiandanPdfKey(examId); + localStorage.setItem(key, JSON.stringify(pdfInfo)); +}; + +/** + * 获取导检单PDF信息 + */ +export const getDaojiandanPdf = (examId: string | number): DaojiandanPdfInfo | null => { + if (typeof window === 'undefined') return null; + + const key = getDaojiandanPdfKey(examId); + const raw = localStorage.getItem(key); + if (!raw) return null; + + try { + const parsed = JSON.parse(raw); + return parsed as DaojiandanPdfInfo; + } catch (err) { + console.warn('导检单PDF信息解析失败', err); + return null; + } +}; +