From 87b3f8e539be2c1c5c7f78717d1cea7c1c634e76 Mon Sep 17 00:00:00 2001 From: yuchenglong Date: Fri, 28 Nov 2025 10:36:20 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=BA=AB=E4=BB=BD?= =?UTF-8?q?=E8=AF=81=E8=AF=BB=E5=8F=96=E9=80=BB=E8=BE=91=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=80=92=E8=AE=A1=E6=97=B6=E5=8A=9F=E8=83=BD=E5=B9=B6?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/U1/u1.tsx | 95 +++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 37 deletions(-) diff --git a/src/pages/U1/u1.tsx b/src/pages/U1/u1.tsx index 01ce539..f57c084 100644 --- a/src/pages/U1/u1.tsx +++ b/src/pages/U1/u1.tsx @@ -13,40 +13,18 @@ const U1: React.FC = () => { const navigate = useNavigate(); const [reading, setReading] = useState(false); + const [countdown, setCountdown] = useState(6); const timerRef = useRef(null); + const intervalRef = useRef(null); - const handleStart = () => { - // localStorage.setItem("lastIdCardNo", "31010919571209004X"); - // navigate("/u2"); - if (reading) return; // 避免重复点击 - setReading(true); - // 启动后端监听;如果启动失败立即恢复 UI 状态 + // 实时监听身份证读取 + useEffect(() => { + // 启动后端监听 window.electronAPI.startIdCardListen().catch((e: any) => { console.error("start_idcard_listen failed", e); window.electronAPI.log("error", `start_idcard_listen failed: ${e}`); - setReading(false); }); - // 6 秒超时恢复 - if (timerRef.current) { - clearTimeout(timerRef.current); - timerRef.current = null; - } - timerRef.current = window.setTimeout(() => { - console.warn("未在 6 秒内读取到身份证信息,恢复初始状态"); - window.electronAPI.log( - "warn", - "未在 6 秒内读取到身份证信息,恢复初始状态" - ); - setReading(false); - window.electronAPI.stopIdCardListen().catch(() => {}); - timerRef.current = null; - }, 6000); - }; - - useEffect(() => { - if (!reading) return; - // 监听数据 window.electronAPI.onIdCardData((e: any) => { const payload = e.payload; @@ -64,11 +42,18 @@ const U1: React.FC = () => { "info", `Read IDCard success: ${payload.name} ${payload.id_card_no}` ); - // 成功:清理定时器,停止监听 + + // 无论是否点击了开始签到,只要读到卡就跳转 + // 清理定时器 if (timerRef.current) { clearTimeout(timerRef.current); timerRef.current = null; } + if (intervalRef.current) { + clearInterval(intervalRef.current); + intervalRef.current = null; + } + // 停止监听(跳转后不再需要监听) window.electronAPI.stopIdCardListen().catch(() => {}); setReading(false); navigate("/u2"); @@ -78,20 +63,54 @@ const U1: React.FC = () => { window.electronAPI.onIdCardError((e: any) => { console.error("[idcard-error]", e.payload); window.electronAPI.log("error", `[idcard-error] ${e.payload}`); - // 发生错误时立即恢复 UI 状态 - if (timerRef.current) { - clearTimeout(timerRef.current); - timerRef.current = null; + // 错误不停止监听,继续等待下一次读取,除非是严重错误? + // 这里仅记录日志,或者在 reading 状态下提示用户 + if (reading) { + // 如果正在倒计时中出错,可以选择停止倒计时或者忽略 + // 目前保持监听 } - setReading(false); - window.electronAPI.stopIdCardListen().catch(() => {}); - alert(`读取身份证失败: ${e.payload}`); }); return () => { + window.electronAPI.stopIdCardListen().catch(() => {}); window.electronAPI.removeIdCardListeners(); + if (timerRef.current) clearTimeout(timerRef.current); + if (intervalRef.current) clearInterval(intervalRef.current); }; - }, [reading, navigate]); + }, [navigate, reading]); + + const handleStart = () => { + if (reading) return; // 避免重复点击 + setReading(true); + setCountdown(6); + + // 6 秒倒计时逻辑 + if (intervalRef.current) clearInterval(intervalRef.current); + intervalRef.current = window.setInterval(() => { + setCountdown((prev) => { + if (prev <= 1) { + if (intervalRef.current) clearInterval(intervalRef.current); + return 0; + } + return prev - 1; + }); + }, 1000); + + // 6 秒超时恢复 + if (timerRef.current) { + clearTimeout(timerRef.current); + timerRef.current = null; + } + timerRef.current = window.setTimeout(() => { + console.warn("未在 6 秒内读取到身份证信息,恢复初始状态"); + setReading(false); + if (intervalRef.current) { + clearInterval(intervalRef.current); + intervalRef.current = null; + } + timerRef.current = null; + }, 6000); + }; return (
@@ -105,7 +124,9 @@ const U1: React.FC = () => { 请放置身份证在读卡区域 start button {!reading && } - {reading && } + {reading && ( + + )}
); }; From f4cff05c1f9bdab99d6c05d75a23778c58f1de6c Mon Sep 17 00:00:00 2001 From: yuchenglong Date: Fri, 28 Nov 2025 11:39:07 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=82=A3=E8=80=85?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E6=9C=89=E6=95=88=E6=80=A7=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E7=95=8C=E9=9D=A2=E5=B8=83=E5=B1=80?= =?UTF-8?q?=E5=92=8C=E9=94=99=E8=AF=AF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/hisApi.ts | 1 + src/pages/U2/u2.css | 18 ++++++++- src/pages/U2/u2.tsx | 96 ++++++++++++++++++++++++++++----------------- 3 files changed, 79 insertions(+), 36 deletions(-) diff --git a/src/api/hisApi.ts b/src/api/hisApi.ts index fbfdb81..fa620ca 100644 --- a/src/api/hisApi.ts +++ b/src/api/hisApi.ts @@ -28,6 +28,7 @@ export interface PatientInfo { phone: string; marital: number; marital_name: string; + is_valid_exam: number; } // VIP认证结果 diff --git a/src/pages/U2/u2.css b/src/pages/U2/u2.css index f9e6722..4bcb4b6 100644 --- a/src/pages/U2/u2.css +++ b/src/pages/U2/u2.css @@ -27,10 +27,26 @@ background: url(../../assets/u2-card.png) 100% no-repeat; background-size: 100% 100%; box-sizing: border-box; + display: flex; + flex-direction: column; + padding: 40px 48px; +} + +.u2-info-top { display: flex; flex-direction: row; align-items: center; - padding: 40px 48px; + width: 100%; + flex: 1; +} + +.u2-error-msg { + width: 100%; + text-align: center; + color: red; + font-size: 28px; + font-weight: bold; + margin-top: 10px; } .u2-avatar-container { diff --git a/src/pages/U2/u2.tsx b/src/pages/U2/u2.tsx index 4db0cc8..09f7c23 100644 --- a/src/pages/U2/u2.tsx +++ b/src/pages/U2/u2.tsx @@ -70,6 +70,11 @@ const U2: React.FC = () => { }; const handleConfirm = () => { + // 判断是否为有效签到 + if (!patientInfo?.is_valid_exam || patientInfo.is_valid_exam !== 1) { + // alert("当前签到无效,请联系前台工作人员处理"); + return; + } if (!idCardNo) { alert("未获取到身份证号,请重新刷卡"); navigate("/"); @@ -130,7 +135,7 @@ const U2: React.FC = () => { else if (genderName === "女") title = "女士"; return `尊敬的${ firstChar ? `${firstChar}${title}` : title - },欢迎您的到来:`; + },请确认您的个人信息:`; }; // 返回头像地址:使用 gender_name 字段("女" 显示女性头像),忽略 photo_path @@ -147,6 +152,17 @@ const U2: React.FC = () => { return genderName; }; + // 脱敏证件号:保留前6后4,其余替换为* + const maskIdCard = (id?: string | null) => { + if (!id) return "---"; + const s = String(id).trim(); + if (s.length <= 10) return s.replace(/.(?!.{4})/g, "*"); + const head = s.slice(0, 6); + const tail = s.slice(-4); + const middleLen = s.length - 10; + return head + "*".repeat(middleLen) + tail; + }; + // 在数据加载时显示占位,加载完成后再渲染完整内容 if (loading) { return <>; @@ -157,52 +173,62 @@ const U2: React.FC = () => { {getGreeting()}
-
- avatar -
-
-
-
-
- 姓名:{loading ? "" : patientInfo?.name || "---"} -
+
+
+ avatar
- -
-
-
- 性别:{loading ? "" : getGenderLabel()} +
+
+
+
+ 姓名:{loading ? "" : patientInfo?.name || "---"} +
-
-
-
-
- 年龄:{loading ? "" : patientInfo?.age || "---"} +
+
+
+ 性别:{loading ? "" : getGenderLabel()} +
-
-
-
-
- 证件号:{idCardNo || patientInfo?.IdCard || "---"} +
+
+
+ 年龄:{loading ? "" : patientInfo?.age || "---"} +
-
-
-
-
- 手机号:{loading ? "" : patientInfo?.phone || "---"} +
+
+
+ 证件号: + {loading ? "" : maskIdCard(idCardNo || patientInfo?.IdCard)} +
-
-
-
-
- 婚姻状况:{loading ? "" : patientInfo?.marital_name || "---"} +
+
+
+ 手机号:{loading ? "" : patientInfo?.phone || "---"} +
+
+ +
+
+
+ 婚姻状况:{loading ? "" : patientInfo?.marital_name || "---"} +
+ {!patientInfo?.is_valid_exam || patientInfo.is_valid_exam !== 1 ? ( +
+ 未查询到您当日的体检预约信息,建议核对预约日期! +
+ ) : ( + "" + )}
* 如信息有误,请联系前台 From 291a4beb945bfa68614f65dbd1324a7beb864a2a Mon Sep 17 00:00:00 2001 From: yuchenglong Date: Fri, 28 Nov 2025 11:43:03 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E4=BF=A1=E6=81=AF=EF=BC=8C=E6=98=8E=E7=A1=AE?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=81=94=E7=B3=BB=E5=89=8D=E5=8F=B0=E7=9A=84?= =?UTF-8?q?=E6=8C=87=E5=BC=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/U2/u2.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/U2/u2.tsx b/src/pages/U2/u2.tsx index 09f7c23..3e29f05 100644 --- a/src/pages/U2/u2.tsx +++ b/src/pages/U2/u2.tsx @@ -32,7 +32,8 @@ const U2: React.FC = () => { localStorage.setItem("name", res.Data.name); localStorage.setItem("gender", res.Data.gender_name); } else { - alert(`${res.Message},请联系前台`); + alert(`未查询到您的档案信息,请联系前台工作人员`); + navigate("/"); } }) .catch((err) => {