fix(health): FHIR converter 身份证号脱敏处理

This commit is contained in:
iven
2026-05-06 10:20:50 +08:00
parent ced93934f1
commit f668e64266

View File

@@ -32,9 +32,15 @@ pub fn patient_to_fhir(p: &patient::Model) -> serde_json::Value {
}
if let Some(ref id_number) = p.id_number {
// 加密密文v1| 前缀)不输出,明文做脱敏处理
let display_value = if id_number.starts_with("v1|") {
"[REDACTED]".to_string()
} else {
mask_sensitive(id_number)
};
result["identifier"] = serde_json::json!([{
"system": "urn:oid:2.16.156.10011.1.3",
"value": id_number,
"value": display_value,
}]);
}
@@ -332,6 +338,15 @@ pub fn follow_up_to_fhir(t: &follow_up_task::Model) -> serde_json::Value {
})
}
/// 对敏感字符串做脱敏:保留前 1 位和后 4 位,中间用 * 替代
fn mask_sensitive(s: &str) -> String {
if s.len() <= 5 {
"*".repeat(s.len())
} else {
format!("{}{}{}", &s[..1], "*".repeat(s.len() - 5), &s[s.len() - 4..])
}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -370,7 +385,47 @@ mod tests {
assert_eq!(fhir["id"], "00000000-0000-0000-0000-000000000001");
assert_eq!(fhir["gender"], "male");
assert_eq!(fhir["birthDate"], "1968-05-15");
assert_eq!(fhir["identifier"][0]["value"], "110101196805150001");
assert_eq!(fhir["identifier"][0]["value"], "1*************0001");
}
#[test]
fn test_patient_to_fhir_encrypted_id_number_redacted() {
let p = patient::Model {
id: uuid::Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap(),
tenant_id: uuid::Uuid::now_v7(),
user_id: None,
name: "测试".into(),
gender: None,
birth_date: None,
blood_type: None,
id_number: Some("v1|encrypted_payload_here".into()),
id_number_hash: None,
allergy_history: None,
medical_history_summary: None,
emergency_contact_name: None,
emergency_contact_phone: None,
emergency_contact_phone_hash: None,
key_version: None,
status: "active".into(),
verification_status: "pending".into(),
source: None,
notes: None,
created_at: chrono::Utc::now(),
updated_at: chrono::Utc::now(),
created_by: None,
updated_by: None,
deleted_at: None,
version: 1,
};
let fhir = patient_to_fhir(&p);
assert_eq!(fhir["identifier"][0]["value"], "[REDACTED]");
}
#[test]
fn test_mask_sensitive() {
assert_eq!(mask_sensitive("110101196805150001"), "1*************0001");
assert_eq!(mask_sensitive("12345"), "*****");
assert_eq!(mask_sensitive("123456"), "1*3456");
}
#[test]