重构U1页面身份证读取逻辑:优化状态管理,增强错误处理和日志记录

This commit is contained in:
yuchenglong
2025-12-02 16:43:55 +08:00
parent b8c1a39806
commit c204a45ad3

View File

@@ -16,140 +16,111 @@ const U1: React.FC = () => {
const [reading, setReading] = useState(false);
const [countdown, setCountdown] = useState(6);
const [errorMsg, setErrorMsg] = useState("");
const [idCardNo, setIdCardNo] = useState<string>("");
const timerRef = useRef<number | null>(null);
const intervalRef = useRef<number | null>(null);
const errorTimerRef = useRef<number | null>(null);
const isMountedRef = useRef(true);
const isProcessingRef = useRef(false);
// 实时监听身份证读取 - 只负责接收并保存身份证信息
// 实时监听身份证读取
useEffect(() => {
console.log("[U1] 页面加载,准备启动身份证监听");
window.electronAPI.log("info", "[U1] 页面加载,准备启动身份证监听");
// 重置挂载标志
isMountedRef.current = true;
window.electronAPI.startIdCardListen().catch((e: any) => {
console.error("[U1] 启动身份证监听失败", e);
window.electronAPI.log("error", `[U1] 启动身份证监听失败: ${e}`);
console.error("start_idcard_listen failed", e);
window.electronAPI.log("error", `start_idcard_listen failed: ${e}`);
});
window.electronAPI.onIdCardData((e: any) => {
const payload = e.payload;
console.log("[U1] 接收到身份证数据", payload);
window.electronAPI.log(
"info",
`[U1] 接收到身份证数据: 姓名=${payload.name}, 身份证号=${payload.id_card_no}`
);
// 如果正在处理中,忽略新的数据
if (isProcessingRef.current) return;
isProcessingRef.current = true;
setReading(true); // 更新 UI 为读取中状态
const payload = e.payload;
try {
if (payload?.id_card_no) {
// 只有在当前页面才更新状态
if (isMountedRef.current) {
console.log("[U1] 当前在U1页面,保存身份证信息到localStorage和状态");
window.electronAPI.log(
"info",
`[U1] 保存身份证号: ${payload.id_card_no}`
);
localStorage.setItem("lastIdCardNo", payload.id_card_no);
setIdCardNo(payload.id_card_no); // 更新身份证号状态
} else {
console.log("[U1] 已离开U1页面,忽略身份证数据更新");
window.electronAPI.log(
"info",
"[U1] 已离开U1页面,忽略身份证数据更新"
);
}
} else {
console.warn("[U1] 身份证数据中未找到身份证号");
window.electronAPI.log("warn", "[U1] 身份证数据中未找到身份证号");
localStorage.setItem("lastIdCardNo", payload.id_card_no);
}
} catch (err) {
console.error("[U1] 保存身份证信息失败", err);
window.electronAPI.log(
"error",
`[U1] 保存身份证信息到localStorage失败: ${err}`
);
console.warn("localStorage.setItem failed", err);
}
console.log("[idcard-data]", payload);
window.electronAPI.log("info", `[idcard-data] received`);
window.electronAPI.log(
"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;
}
// 重置监听的辅助函数
const resetListening = () => {
window.electronAPI
.stopIdCardListen()
.then(() => {
setTimeout(() => {
window.electronAPI
.startIdCardListen()
.catch((e: any) => console.error(e));
}, 1000);
})
.catch(() => {});
};
// 先验证档案信息,查询到才跳转
const idCardNo = payload.id_card_no;
if (!idCardNo) {
setErrorMsg("未读取到身份证号");
setReading(false);
isProcessingRef.current = false;
resetListening();
return;
}
getPatientInfo(idCardNo)
.then((res) => {
if (res.Status === 200 && res.Data) {
// 查询成功,跳转到 u2
window.electronAPI.stopIdCardListen().catch(() => {});
setReading(false);
isProcessingRef.current = false;
navigate("/u2");
} else {
// 未查询到档案信息,显示错误提示,不跳转
setErrorMsg("未查询到您的档案信息,请联系前台工作人员");
setReading(false);
isProcessingRef.current = false;
resetListening();
}
})
.catch((err) => {
console.error("getPatientInfo error", err);
setErrorMsg("获取用户信息异常,请联系前台工作人员");
setReading(false);
isProcessingRef.current = false;
resetListening();
});
});
window.electronAPI.onIdCardError((e: any) => {
console.error("[U1] 身份证读取错误", e.payload);
window.electronAPI.log("error", `[U1] 身份证读取错误: ${e.payload}`);
console.error("[idcard-error]", e.payload);
window.electronAPI.log("error", `[idcard-error] ${e.payload}`);
});
return () => {
console.log("[U1] 页面卸载,清理监听器和定时器");
window.electronAPI.log("info", "[U1] 页面卸载,标记为已离开并清理资源");
isMountedRef.current = false;
window.electronAPI.stopIdCardListen().catch(() => {});
window.electronAPI.removeIdCardListeners();
if (timerRef.current) clearTimeout(timerRef.current);
if (intervalRef.current) clearInterval(intervalRef.current);
if (errorTimerRef.current) clearTimeout(errorTimerRef.current);
};
}, []);
// 监听身份证号变化 - 处理业务逻辑
useEffect(() => {
if (!idCardNo) return;
console.log(`[U1] 身份证号变化,开始查询患者档案信息: ${idCardNo}`);
window.electronAPI?.log(
"info",
`[U1] 身份证号变化,开始查询患者档案信息: ${idCardNo}`
);
// 验证档案信息,查询到才跳转
getPatientInfo(idCardNo)
.then((res) => {
console.log("[U1] 患者档案查询返回", res);
if (res.Status === 200 && res.Data) {
// 查询成功,跳转到 u2
console.log(`[U1] 查询成功,找到患者信息: ${res.Data.name}`);
window.electronAPI?.log(
"info",
`[U1] 查询成功 - 姓名: ${res.Data.name}, 身份证号: ${idCardNo}, 准备跳转到U2页面`
);
// 清理倒计时
if (timerRef.current) {
clearTimeout(timerRef.current);
timerRef.current = null;
console.log("[U1] 清理超时定时器");
}
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
console.log("[U1] 清理倒计时定时器");
}
setReading(false);
console.log("[U1] 即将跳转到U2页面,保持身份证监听器活跃");
window.electronAPI?.log("info", "[U1] 跳转到U2页面(监听器保持活跃)");
navigate("/u2");
} else {
// 未查询到档案信息,显示错误提示
console.warn(
`[U1] 未查询到档案信息 - 身份证号: ${idCardNo}, Status: ${res.Status}`
);
window.electronAPI?.log(
"warn",
`[U1] 未查询到档案信息 - 身份证号: ${idCardNo}, 返回状态: ${res.Status}`
);
setErrorMsg("未查询到您的档案信息,请联系前台工作人员");
}
})
.catch((err) => {
console.error("[U1] 查询患者档案信息异常", err);
window.electronAPI?.log(
"error",
`[U1] 查询患者档案信息异常 - 身份证号: ${idCardNo}, 错误: ${
err.message || err
}`
);
// 接口异常,仅显示错误提示
setErrorMsg("获取用户信息异常,请联系前台工作人员");
});
}, [idCardNo, navigate]);
}, [navigate]);
// 错误信息 10 秒后自动消失
useEffect(() => {
@@ -169,15 +140,9 @@ const U1: React.FC = () => {
}, [errorMsg]);
const handleStart = () => {
if (reading) {
console.log("[U1] 按钮已在读取状态,忽略重复点击");
return; // 避免重复点击
}
console.log("[U1] 用户点击开始签到按钮");
window.electronAPI.log("info", "[U1] 用户点击开始签到按钮,启动6秒倒计时");
if (reading) return; // 避免重复点击
setReading(true);
// isProcessingRef.current = true; // 不需要手动设置,等待读卡数据
setCountdown(6);
setErrorMsg(""); // 清空之前的错误信息
@@ -199,12 +164,9 @@ const U1: React.FC = () => {
timerRef.current = null;
}
timerRef.current = window.setTimeout(() => {
console.warn("[U1] 6秒倒计时结束,未读取到身份证信息,恢复初始状态");
window.electronAPI.log(
"warn",
"[U1] 6秒倒计时结束,未读取到身份证信息,恢复初始状态"
);
console.warn("未在 6 秒内读取到身份证信息恢复初始状态");
setReading(false);
// isProcessingRef.current = false;
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;