feat(health): 新增小程序专用今日体征摘要端点 GET /health/vital-signs/today

This commit is contained in:
iven
2026-04-24 12:17:17 +08:00
parent 19be2a08c7
commit e7b6bdfcac
4 changed files with 162 additions and 0 deletions

View File

@@ -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,
})
}