feat(health): 新增小程序专用今日体征摘要端点 GET /health/vital-signs/today
This commit is contained in:
@@ -722,3 +722,112 @@ pub async fn get_mini_trend(
|
||||
data_points,
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 小程序今日体征摘要
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// 根据参考范围计算指标状态
|
||||
fn compute_status(value: f64, low: f64, high: f64) -> &'static str {
|
||||
if value < low {
|
||||
"low"
|
||||
} else if value > high {
|
||||
"high"
|
||||
} else {
|
||||
"normal"
|
||||
}
|
||||
}
|
||||
|
||||
/// 查询今日最新体征记录并生成摘要
|
||||
pub async fn get_mini_today(
|
||||
state: &HealthState,
|
||||
tenant_id: Uuid,
|
||||
user_id: Uuid,
|
||||
) -> HealthResult<MiniTodayResp> {
|
||||
let patient_id = find_patient_by_user_id(state, tenant_id, user_id).await?;
|
||||
|
||||
let Some(patient_id) = patient_id else {
|
||||
return Ok(MiniTodayResp {
|
||||
blood_pressure: None,
|
||||
heart_rate: None,
|
||||
blood_sugar: None,
|
||||
weight: None,
|
||||
});
|
||||
};
|
||||
|
||||
let today = chrono::Local::now().date_naive();
|
||||
|
||||
// 查询今日最新体征记录
|
||||
let vital = vital_signs::Entity::find()
|
||||
.filter(vital_signs::Column::TenantId.eq(tenant_id))
|
||||
.filter(vital_signs::Column::PatientId.eq(patient_id))
|
||||
.filter(vital_signs::Column::DeletedAt.is_null())
|
||||
.filter(vital_signs::Column::RecordDate.eq(today))
|
||||
.order_by_desc(vital_signs::Column::CreatedAt)
|
||||
.one(&state.db)
|
||||
.await?;
|
||||
|
||||
let Some(v) = vital else {
|
||||
return Ok(MiniTodayResp {
|
||||
blood_pressure: None,
|
||||
heart_rate: None,
|
||||
blood_sugar: None,
|
||||
weight: None,
|
||||
});
|
||||
};
|
||||
|
||||
// 构建各指标摘要,优先使用晨间数据
|
||||
let blood_pressure = v.systolic_bp_morning.and_then(|sys| {
|
||||
v.diastolic_bp_morning.map(|dia| {
|
||||
let status = compute_status(sys as f64, 90.0, 140.0);
|
||||
IndicatorSummary {
|
||||
value: sys as f64,
|
||||
status: status.to_string(),
|
||||
reference_range: Some("90-140/60-90".to_string()),
|
||||
systolic: Some(sys as f64),
|
||||
diastolic: Some(dia as f64),
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
let heart_rate = v.heart_rate.map(|hr| {
|
||||
let status = compute_status(hr as f64, 60.0, 100.0);
|
||||
IndicatorSummary {
|
||||
value: hr as f64,
|
||||
status: status.to_string(),
|
||||
reference_range: Some("60-100".to_string()),
|
||||
systolic: None,
|
||||
diastolic: None,
|
||||
}
|
||||
});
|
||||
|
||||
let blood_sugar = v.blood_sugar.map(|bs| {
|
||||
let val = bs.to_f64().unwrap_or(0.0);
|
||||
let status = compute_status(val, 3.9, 6.1);
|
||||
IndicatorSummary {
|
||||
value: val,
|
||||
status: status.to_string(),
|
||||
reference_range: Some("3.9-6.1".to_string()),
|
||||
systolic: None,
|
||||
diastolic: None,
|
||||
}
|
||||
});
|
||||
|
||||
let weight = v.weight.map(|w| {
|
||||
let val = w.to_f64().unwrap_or(0.0);
|
||||
IndicatorSummary {
|
||||
value: val,
|
||||
status: "normal".to_string(), // 体重无通用参考范围
|
||||
reference_range: None,
|
||||
systolic: None,
|
||||
diastolic: None,
|
||||
}
|
||||
});
|
||||
|
||||
Ok(MiniTodayResp {
|
||||
blood_pressure,
|
||||
heart_rate,
|
||||
blood_sugar,
|
||||
weight,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user