feat(health): FHIR 模块类型定义 + converter 依赖
This commit is contained in:
5
crates/erp-health/src/fhir/mod.rs
Normal file
5
crates/erp-health/src/fhir/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
pub mod converter;
|
||||
pub mod handler;
|
||||
pub mod types;
|
||||
|
||||
pub use types::*;
|
||||
97
crates/erp-health/src/fhir/types.rs
Normal file
97
crates/erp-health/src/fhir/types.rs
Normal file
@@ -0,0 +1,97 @@
|
||||
use serde::Serialize;
|
||||
|
||||
/// FHIR 搜索参数
|
||||
#[derive(Debug, serde::Deserialize, utoipa::IntoParams)]
|
||||
pub struct FhirSearchParams {
|
||||
#[serde(rename = "_id")]
|
||||
pub id: Option<String>,
|
||||
#[serde(rename = "_count")]
|
||||
pub count: Option<u64>,
|
||||
#[serde(rename = "_offset")]
|
||||
pub offset: Option<u64>,
|
||||
pub patient: Option<String>,
|
||||
pub category: Option<String>,
|
||||
pub code: Option<String>,
|
||||
pub date: Option<String>,
|
||||
pub name: Option<String>,
|
||||
pub identifier: Option<String>,
|
||||
pub status: Option<String>,
|
||||
}
|
||||
|
||||
/// HMS device_type → FHIR Observation LOINC 映射
|
||||
pub fn device_type_to_loinc(device_type: &str) -> Option<(&'static str, &'static str)> {
|
||||
match device_type {
|
||||
"heart_rate" => Some(("8867-4", "Heart rate")),
|
||||
"blood_oxygen" => Some(("2708-6", "Oxygen saturation in Arterial blood")),
|
||||
"blood_pressure" => Some(("85354-9", "Blood pressure panel")),
|
||||
"blood_glucose" => Some(("2339-0", "Glucose in Blood")),
|
||||
"temperature" => Some(("8310-5", "Body temperature")),
|
||||
"steps" => Some(("55423-8", "Number of steps in 24 hours")),
|
||||
"sleep" => Some(("93832-4", "Sleep duration")),
|
||||
"stress" => Some(("80319-1", "Stress level")),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// HMS device_type → FHIR Observation category
|
||||
pub fn device_type_to_category(device_type: &str) -> &'static str {
|
||||
match device_type {
|
||||
"heart_rate" | "blood_oxygen" | "blood_pressure" | "temperature" => "vital-signs",
|
||||
"steps" | "sleep" | "stress" => "activity",
|
||||
"blood_glucose" => "laboratory",
|
||||
_ => "survey",
|
||||
}
|
||||
}
|
||||
|
||||
/// HMS device_type → FHIR UCUM unit
|
||||
pub fn device_type_to_unit(device_type: &str) -> (&'static str, &'static str) {
|
||||
match device_type {
|
||||
"heart_rate" => ("beats/minute", "/min"),
|
||||
"blood_oxygen" => ("%", "%"),
|
||||
"blood_pressure" => ("mmHg", "mm[Hg]"),
|
||||
"blood_glucose" => ("mg/dL", "mg/dL"),
|
||||
"temperature" => ("\u{00b0}C", "Cel"),
|
||||
"steps" => ("steps", "{steps}"),
|
||||
"sleep" => ("hours", "h"),
|
||||
"stress" => ("score", "{score}"),
|
||||
_ => ("unknown", "unknown"),
|
||||
}
|
||||
}
|
||||
|
||||
/// OperationOutcome(错误响应)
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct OperationOutcomeResource {
|
||||
pub resource_type: String,
|
||||
pub issue: Vec<OperationOutcomeIssue>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct OperationOutcomeIssue {
|
||||
pub severity: String,
|
||||
pub code: String,
|
||||
pub diagnostics: Option<String>,
|
||||
}
|
||||
|
||||
/// LOINC code → device_type 反向映射
|
||||
pub fn loinc_to_device_type(loinc: &str) -> Option<&'static str> {
|
||||
match loinc {
|
||||
"8867-4" => Some("heart_rate"),
|
||||
"2708-6" => Some("blood_oxygen"),
|
||||
"85354-9" | "8480-6" | "8462-4" => Some("blood_pressure"),
|
||||
"2339-0" => Some("blood_glucose"),
|
||||
"8310-5" => Some("temperature"),
|
||||
"55423-8" => Some("steps"),
|
||||
"93832-4" => Some("sleep"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// FHIR category → device_type 列表
|
||||
pub fn category_to_device_types(category: &str) -> Vec<&'static str> {
|
||||
match category {
|
||||
"vital-signs" => vec!["heart_rate", "blood_oxygen", "blood_pressure", "temperature"],
|
||||
"laboratory" => vec!["blood_glucose"],
|
||||
"activity" => vec!["steps", "sleep", "stress"],
|
||||
_ => vec![],
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user