From b5aaf1989719123d2cf579c3bd9b1b7957595dec Mon Sep 17 00:00:00 2001 From: xianyi Date: Wed, 10 Dec 2025 17:55:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0iPad=E7=AD=BE=E5=88=B0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/his.ts | 14 ++++ src/api/types.ts | 21 ++++++ src/components/exam/ExamModal.tsx | 120 ++++++++++++++++++++++++------ 3 files changed, 133 insertions(+), 22 deletions(-) diff --git a/src/api/his.ts b/src/api/his.ts index ee65be7..6aba385 100644 --- a/src/api/his.ts +++ b/src/api/his.ts @@ -12,6 +12,8 @@ import type { PhysicalExamProgressDetailResponse, InputCustomerDetail, CustomerDetailResponse, + InputMedicalExamCenterSignIn, + PhysicalExamSignInResponse, } from './types'; /** @@ -98,3 +100,15 @@ export const getCustomerDetail = ( ).then(res => res.data); }; +/** + * iPad 体检中心签到 + */ +export const signInMedicalExamCenter = ( + data: InputMedicalExamCenterSignIn +): Promise => { + return request.post( + `${MEDICAL_EXAM_BASE_PATH}/sign-in`, + data + ).then(res => res.data); +}; + diff --git a/src/api/types.ts b/src/api/types.ts index 4a47b19..fc5dea5 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -251,3 +251,24 @@ export interface OutputCustomerDetail { */ export type CustomerDetailResponse = CommonActionResult; +/** + * 体检中心签到入参 + */ +export interface InputMedicalExamCenterSignIn { + /** 身份证号 */ + id_no: string; +} + +/** + * 体检中心签到出参 + */ +export interface OutputPhysicalExamSignIn { + /** 是否签到成功(0-成功 1-失败) */ + is_success?: number | null; +} + +/** + * 体检中心签到响应 + */ +export type PhysicalExamSignInResponse = CommonActionResult; + diff --git a/src/components/exam/ExamModal.tsx b/src/components/exam/ExamModal.tsx index 634f4fb..dc525d8 100644 --- a/src/components/exam/ExamModal.tsx +++ b/src/components/exam/ExamModal.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useState } from 'react'; +import { useEffect, useMemo, useRef, useState } from 'react'; import type { ExamClient, ExamModalTab } from '../../data/mockData'; import type { @@ -7,7 +7,7 @@ import type { CustomerInfo, PhysicalExamProgressItem, } from '../../api'; -import { getCustomerDetail, getPhysicalExamProgressDetail } from '../../api'; +import { getCustomerDetail, getPhysicalExamProgressDetail, signInMedicalExamCenter } from '../../api'; import { Button, Input } from '../ui'; interface ExamModalProps { @@ -175,28 +175,104 @@ export const ExamModal = ({ client, tab, onTabChange, onClose }: ExamModalProps) ); }; -const ExamSignPanel = () => ( -
-
-
身份证上传
-
支持身份证正反面拍照或读取设备,自动识别姓名、证件号等信息。
-
- - +const ExamSignPanel = () => { + const [idNo, setIdNo] = useState(''); + const [ocrLoading, setOcrLoading] = useState(false); + const [signLoading, setSignLoading] = useState(false); + const [message, setMessage] = useState(null); + const fileInputRef = useRef(null); + + const handlePickFile = () => { + fileInputRef.current?.click(); + }; + + const mockOcr = async (file: File) => { + // 简单模拟 OCR:提取文件名中的数字,或返回示例身份证 + const match = file.name.match(/\d{6,18}/); + await new Promise((r) => setTimeout(r, 600)); + return match?.[0] || '440101199001010010'; + }; + + const handleFileChange = async (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return; + setOcrLoading(true); + setMessage(null); + try { + const ocrId = await mockOcr(file); + setIdNo(ocrId); + } catch (err) { + console.error(err); + setMessage('OCR 识别失败,请重试或手动输入'); + } finally { + setOcrLoading(false); + e.target.value = ''; + } + }; + + const handleSign = async () => { + const trimmed = idNo.trim(); + if (!trimmed) { + setMessage('请输入身份证号'); + return; + } + setSignLoading(true); + setMessage(null); + try { + const res = await signInMedicalExamCenter({ id_no: trimmed }); + const ok = res.Status === 200 && res.Data?.is_success === 0; + setMessage(ok ? '签到成功' : res.Message || '签到失败'); + } catch (err) { + console.error(err); + setMessage('签到请求失败,请稍后重试'); + } finally { + setSignLoading(false); + } + }; + + return ( +
+
+
身份证扫描与签到
+
+ 支持扫描身份证识别证号,确认后再点击签到。 +
+
+ + + setIdNo(e.target.value)} + className='flex-1' + /> + +
+ {message &&
{message}
} +
如识别不准,可手动修改后再签到。
+
+
+
体检知情同意书
+
点击后弹出知情同意书全文及签名区域,签署完成后回到签到页面。
+
-
上传后进入预览界面,确认无误后返回签到界面。
-
-
体检知情同意书
-
点击后弹出知情同意书全文及签名区域,签署完成后回到签到页面。
- {/*
- 阅读记录 - 签名图片 -
*/} - -
-
-); + ); +}; interface AddonTag { title: string;