Files
yuanhe-checkin-electron/src/pages/U2/u2.tsx

217 lines
7.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useEffect, useState } from "react";
import "./u2.css";
import { useNavigate } from "react-router-dom";
import DecorLine from "../../components/DecorLine";
import avatar from "../../assets/avatar.png";
import semicircle from "../../assets/semicircle.png";
import BackButton from "../../components/BackButton";
import ConfirmButton from "../../components/ConfirmButton";
import {
getPatientInfo,
getVipStatus,
getOptionalItemList,
PatientInfo,
} from "../../api/hisApi";
const U2: React.FC = () => {
const navigate = useNavigate();
const idCardNo = localStorage.getItem("lastIdCardNo");
const [patientInfo, setPatientInfo] = useState<PatientInfo | null>(null);
const [loading, setLoading] = useState<boolean>(() => !!idCardNo);
const [isVip, setIsVip] = useState<number | null>(null);
const vipCalledRef = React.useRef(false);
useEffect(() => {
if (idCardNo) {
setLoading(true);
getPatientInfo(idCardNo)
.then((res) => {
if (res.Status === 200 && res.Data) {
setPatientInfo(res.Data);
localStorage.setItem("name", res.Data.name);
localStorage.setItem("gender", res.Data.gender_name);
} else {
alert(`${res.Message},请联系前台`);
}
})
.catch((err) => {
console.error(err);
alert(`获取用户信息异常: ${err.message}`);
})
.finally(() => {
setLoading(false);
});
}
}, [idCardNo]);
// 获取 VIP 状态,避免重复请求
useEffect(() => {
if (!idCardNo) return;
if (vipCalledRef.current) return;
vipCalledRef.current = true;
getVipStatus(idCardNo)
.then((res) => {
if (res.Status === 200) {
setIsVip(res.Data?.is_vip ?? 0);
} else {
console.warn("获取 VIP 状态失败:", res.Message);
setIsVip(0);
}
})
.catch((err) => {
console.error("getVipStatus error", err);
setIsVip(0);
});
}, [idCardNo]);
const handleBack = () => {
navigate(-1);
};
const handleConfirm = () => {
if (!idCardNo) {
alert("未获取到身份证号,请重新刷卡");
navigate("/");
return;
}
// 判断是否为 VIP 客户0 否1 是)
if (isVip === 1) {
navigate("/u3");
return;
} else {
// 调用接口判断是否有可选套餐
getOptionalItemList(idCardNo)
.then((res) => {
if (res.Status === 200) {
localStorage.setItem(
"selectedExamId",
res.Data.packageInfo.physical_exam_id.toString() || ""
);
const isPackageUndecided =
res.Data?.packageInfo?.is_optional_package === 1 &&
res.Data?.packageInfo.registration_time?.length > 0;
if (isPackageUndecided) {
navigate("/u4", { state: { optionalData: res.Data } });
} else {
// 如果没有可选套餐,检查是否有错误消息需要提示
if (!res.Data?.packageInfo && res.Message) {
alert(res.Message);
} else {
navigate("/UI6");
}
}
} else {
if (res.Message) {
alert(res.Message);
} else {
navigate("/UI6");
}
}
})
.catch((err) => {
console.error("getOptionalItemList error", err);
navigate("/UI6");
});
}
};
// 根据性别和姓名生成问候称呼:取姓名第一个字 + (先生|女士|先生/女士)
const getGreeting = () => {
// 在加载中或没有姓名时不返回欢迎语,避免先渲染空的问候
if (loading || !patientInfo?.name) return "";
const name = patientInfo.name.trim();
const firstChar = name ? name.charAt(0) : "";
const genderName = (patientInfo?.gender_name || "").trim();
const sex = (patientInfo as any)?.sex;
let title = "";
if (genderName === "男" || sex === "1" || sex === 1) title = "先生";
else if (genderName === "女" || sex === "2" || sex === 2) title = "女士";
return `尊敬的${
firstChar ? `${firstChar} ${title}` : title
},欢迎您的到来:`;
};
// 返回头像地址优先使用读到的本地照片路径file:///),否则使用默认 avatar
const getAvatarSrc = () => {
const photoPath = (patientInfo as any)?.photo_path || "";
if (!photoPath) return avatar;
// 如果已经是 file:// 协议,直接返回
if (photoPath.startsWith("file://")) return photoPath;
// 将 Windows 路径转换为 file:/// 格式(把反斜杠改为斜杠)
const normalized = photoPath.replace(/\\/g, "/").replace(/\\/g, "/");
return `file:///${normalized}`;
};
// 在数据加载时显示占位,加载完成后再渲染完整内容
if (loading) {
return <></>;
}
return (
<div className="u2-root">
<span className="u2-title">{getGreeting()}</span>
<DecorLine />
<div className="u2-info-card">
<div className="u2-avatar-container">
<img className="u2-avatar" src={getAvatarSrc()} alt="avatar" />
</div>
<div className="u2-details-list">
<div className="u2-detail-row">
<div className="u2-detail-bar" />
<div className="u2-detail-text">
{loading ? "" : patientInfo?.name || "---"}
</div>
</div>
<div className="u2-detail-row">
<div className="u2-detail-bar" />
<div className="u2-detail-text">
{loading ? "" : patientInfo?.gender_name || "---"}
</div>
</div>
<div className="u2-detail-row">
<div className="u2-detail-bar" />
<div className="u2-detail-text">
{loading ? "" : patientInfo?.age || "---"}
</div>
</div>
<div className="u2-detail-row">
<div className="u2-detail-bar" />
<div className="u2-detail-text">
{idCardNo || patientInfo?.IdCard || "---"}
</div>
</div>
<div className="u2-detail-row">
<div className="u2-detail-bar" />
<div className="u2-detail-text">
{loading ? "" : patientInfo?.phone || "---"}
</div>
</div>
<div className="u2-detail-row">
<div className="u2-detail-bar" />
<div className="u2-detail-text">
{loading ? "" : patientInfo?.marital_name || "---"}
</div>
</div>
</div>
</div>
<span className="u2-instruction">
<span className="u2-asterisk">*</span>
</span>
<img className="u2-semicircle" alt="start button" src={semicircle} />
<div className="u2-confirm-section">
<BackButton text="返回" onClick={handleBack} />
<ConfirmButton text="确认" onClick={handleConfirm} />
</div>
</div>
);
};
export default U2;