添加canvas签名
This commit is contained in:
@@ -5,10 +5,12 @@ import type {
|
||||
CustomerAppointmentInfo,
|
||||
CustomerExamAddItem,
|
||||
CustomerInfo,
|
||||
OutputTongyishuFileInfo,
|
||||
PhysicalExamProgressItem,
|
||||
} from '../../api';
|
||||
import { getCustomerDetail, getPhysicalExamProgressDetail, signInMedicalExamCenter, getTongyishuPdf } from '../../api';
|
||||
import { Button, Input } from '../ui';
|
||||
import type { SignaturePadHandle } from '../ui';
|
||||
import { Button, Input, SignaturePad } from '../ui';
|
||||
|
||||
interface ExamModalProps {
|
||||
client: ExamClient;
|
||||
@@ -164,7 +166,7 @@ export const ExamModal = ({ client, tab, onTabChange, onClose }: ExamModalProps)
|
||||
loading={detailLoading}
|
||||
/>
|
||||
)}
|
||||
{tab === 'sign' && <ExamSignPanel />}
|
||||
{tab === 'sign' && <ExamSignPanel examId={Number(client.id)} />}
|
||||
{tab === 'addon' && <ExamAddonPanel client={client} />}
|
||||
{tab === 'print' && <ExamPrintPanel client={client} />}
|
||||
{tab === 'delivery' && <ExamDeliveryPanel client={client} />}
|
||||
@@ -175,12 +177,18 @@ export const ExamModal = ({ client, tab, onTabChange, onClose }: ExamModalProps)
|
||||
);
|
||||
};
|
||||
|
||||
const ExamSignPanel = () => {
|
||||
const ExamSignPanel = ({ examId }: { examId?: number }) => {
|
||||
const [idNo, setIdNo] = useState('');
|
||||
const [ocrLoading, setOcrLoading] = useState(false);
|
||||
const [signLoading, setSignLoading] = useState(false);
|
||||
const [message, setMessage] = useState<string | null>(null);
|
||||
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
||||
const [consentList, setConsentList] = useState<OutputTongyishuFileInfo[]>([]);
|
||||
const [consentLoading, setConsentLoading] = useState(false);
|
||||
const [consentMessage, setConsentMessage] = useState<string | null>(null);
|
||||
const [previewPdf, setPreviewPdf] = useState<OutputTongyishuFileInfo | null>(null);
|
||||
const [showSignature, setShowSignature] = useState(false);
|
||||
const signaturePadRef = useRef<SignaturePadHandle | null>(null);
|
||||
|
||||
const handlePickFile = () => {
|
||||
fileInputRef.current?.click();
|
||||
@@ -230,6 +238,29 @@ const ExamSignPanel = () => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!examId) {
|
||||
setConsentList([]);
|
||||
setConsentMessage('缺少体检ID,无法获取知情同意书');
|
||||
return;
|
||||
}
|
||||
setConsentLoading(true);
|
||||
setConsentMessage(null);
|
||||
getTongyishuPdf({ exam_id: examId })
|
||||
.then((res) => {
|
||||
const list = res.Data?.list_pdf_url || [];
|
||||
setConsentList(list);
|
||||
if (!list.length) {
|
||||
setConsentMessage(res.Data?.message || '暂无知情同意书');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('获取知情同意书失败', err);
|
||||
setConsentMessage('知情同意书加载失败,请稍后重试');
|
||||
})
|
||||
.finally(() => setConsentLoading(false));
|
||||
}, [examId]);
|
||||
|
||||
return (
|
||||
<div className='grid grid-cols-2 gap-4 text-sm'>
|
||||
<div className='p-4 rounded-2xl border bg-gray-50/60 flex flex-col gap-3'>
|
||||
@@ -268,8 +299,82 @@ const ExamSignPanel = () => {
|
||||
<div className='p-4 rounded-2xl border bg-gray-50/60 flex flex-col gap-3'>
|
||||
<div className='font-medium'>体检知情同意书</div>
|
||||
<div className='text-xs text-gray-500'>点击后弹出知情同意书全文及签名区域,签署完成后回到签到页面。</div>
|
||||
<Button className='py-1.5 px-3'>打开知情同意书并签署</Button>
|
||||
<div className='flex flex-col gap-2'>
|
||||
{consentLoading && <div className='text-xs text-gray-500'>加载中...</div>}
|
||||
{!consentLoading && consentMessage && (
|
||||
<div className='text-xs text-amber-600'>{consentMessage}</div>
|
||||
)}
|
||||
{!consentLoading && consentList.length > 0 && (
|
||||
<div className='space-y-2'>
|
||||
{consentList.map((item) => (
|
||||
<div
|
||||
key={item.pdf_url || item.pdf_name}
|
||||
className='flex items-center justify-between gap-3 p-3 rounded-xl border bg-white shadow-sm'
|
||||
>
|
||||
<div className='text-sm text-gray-800 truncate'>{item.pdf_name}</div>
|
||||
<Button className='py-1.5 px-3' onClick={() => setPreviewPdf(item)}>
|
||||
查看
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{previewPdf && (
|
||||
<div className='fixed inset-0 z-[60] bg-black/75 flex flex-col'>
|
||||
<div className='flex items-center justify-between p-4 text-white bg-gray-900/80'>
|
||||
<div className='text-sm font-medium truncate pr-3'>{previewPdf.pdf_name}</div>
|
||||
<div className='flex items-center gap-2'>
|
||||
<Button
|
||||
className='py-1 px-3'
|
||||
onClick={() => setShowSignature(true)}
|
||||
>
|
||||
签到
|
||||
</Button>
|
||||
<Button className='py-1 px-3' onClick={() => setPreviewPdf(null)}>
|
||||
关闭
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex-1 bg-gray-100'>
|
||||
<iframe
|
||||
src={previewPdf.pdf_url}
|
||||
title={previewPdf.pdf_name}
|
||||
className='w-full h-full'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{showSignature && (
|
||||
<div className='fixed inset-0 z-[70] bg-black/80 flex items-center justify-center px-6'>
|
||||
<div className='bg-white rounded-2xl w-full max-w-3xl shadow-2xl p-4 flex flex-col gap-4'>
|
||||
<div className='flex items-center justify-between'>
|
||||
<div className='text-base font-semibold text-gray-900'>签署知情同意书</div>
|
||||
<div className='flex items-center gap-2'>
|
||||
<Button className='py-1 px-3' onClick={() => setShowSignature(false)}>
|
||||
关闭
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='ui7-signature-wrapper border rounded-xl overflow-hidden bg-gray-50'>
|
||||
<SignaturePad
|
||||
ref={signaturePadRef}
|
||||
className='ui7-signature-canvas w-full h-72 bg-white touch-none'
|
||||
/>
|
||||
<div className='flex items-center justify-between px-3 py-2 bg-gray-50 border-t'>
|
||||
<div className='text-xs text-gray-500'>请在上方区域签名完成签到</div>
|
||||
<Button
|
||||
className='ui7-clear-button py-1 px-3'
|
||||
onClick={() => signaturePadRef.current?.clear()}
|
||||
>
|
||||
清除
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user