feat(health): 体征增加体温/SpO2/血糖类型字段
- 迁移 079: vital_signs 表新增 body_temperature/spo2/blood_sugar_type 列 - Entity/DTO/Service 全链路支持新字段 - blood_sugar_type: fasting/postprandial/random/ogtt - daily_monitoring 兼容层补全新字段为 None
This commit is contained in:
@@ -20,6 +20,10 @@ pub struct CreateVitalSignsReq {
|
||||
pub heart_rate: Option<i32>,
|
||||
pub weight: Option<Decimal>,
|
||||
pub blood_sugar: Option<Decimal>,
|
||||
pub body_temperature: Option<Decimal>,
|
||||
pub spo2: Option<i32>,
|
||||
/// fasting / postprandial / random / ogtt
|
||||
pub blood_sugar_type: Option<String>,
|
||||
pub water_intake_ml: Option<i32>,
|
||||
pub urine_output_ml: Option<i32>,
|
||||
pub notes: Option<String>,
|
||||
@@ -42,6 +46,9 @@ pub struct UpdateVitalSignsReq {
|
||||
pub heart_rate: Option<i32>,
|
||||
pub weight: Option<Decimal>,
|
||||
pub blood_sugar: Option<Decimal>,
|
||||
pub body_temperature: Option<Decimal>,
|
||||
pub spo2: Option<i32>,
|
||||
pub blood_sugar_type: Option<String>,
|
||||
pub water_intake_ml: Option<i32>,
|
||||
pub urine_output_ml: Option<i32>,
|
||||
pub notes: Option<String>,
|
||||
@@ -66,6 +73,9 @@ pub struct VitalSignsResp {
|
||||
pub heart_rate: Option<i32>,
|
||||
pub weight: Option<Decimal>,
|
||||
pub blood_sugar: Option<Decimal>,
|
||||
pub body_temperature: Option<Decimal>,
|
||||
pub spo2: Option<i32>,
|
||||
pub blood_sugar_type: Option<String>,
|
||||
pub water_intake_ml: Option<i32>,
|
||||
pub urine_output_ml: Option<i32>,
|
||||
pub notes: Option<String>,
|
||||
|
||||
@@ -24,6 +24,12 @@ pub struct Model {
|
||||
#[sea_orm(skip_serializing_if = "Option::is_none")]
|
||||
pub blood_sugar: Option<Decimal>,
|
||||
#[sea_orm(skip_serializing_if = "Option::is_none")]
|
||||
pub body_temperature: Option<Decimal>,
|
||||
#[sea_orm(skip_serializing_if = "Option::is_none")]
|
||||
pub spo2: Option<i32>,
|
||||
#[sea_orm(skip_serializing_if = "Option::is_none")]
|
||||
pub blood_sugar_type: Option<String>,
|
||||
#[sea_orm(skip_serializing_if = "Option::is_none")]
|
||||
pub water_intake_ml: Option<i32>,
|
||||
#[sea_orm(skip_serializing_if = "Option::is_none")]
|
||||
pub urine_output_ml: Option<i32>,
|
||||
|
||||
@@ -83,6 +83,9 @@ pub async fn create_daily_monitoring(
|
||||
heart_rate: None,
|
||||
weight: req.weight,
|
||||
blood_sugar: req.blood_sugar,
|
||||
body_temperature: None,
|
||||
spo2: None,
|
||||
blood_sugar_type: None,
|
||||
water_intake_ml: req.fluid_intake,
|
||||
urine_output_ml: req.urine_output,
|
||||
notes: req.notes,
|
||||
@@ -121,6 +124,9 @@ pub async fn update_daily_monitoring(
|
||||
heart_rate: None,
|
||||
weight: req.weight,
|
||||
blood_sugar: req.blood_sugar,
|
||||
body_temperature: None,
|
||||
spo2: None,
|
||||
blood_sugar_type: None,
|
||||
water_intake_ml: req.fluid_intake,
|
||||
urine_output_ml: req.urine_output,
|
||||
notes: req.notes,
|
||||
|
||||
@@ -59,6 +59,9 @@ pub async fn list_vital_signs(
|
||||
heart_rate: m.heart_rate,
|
||||
weight: m.weight.map(|d| d.to_f64().unwrap_or(0.0)),
|
||||
blood_sugar: m.blood_sugar.map(|d| d.to_f64().unwrap_or(0.0)),
|
||||
body_temperature: m.body_temperature.map(|d| d.to_f64().unwrap_or(0.0)),
|
||||
spo2: m.spo2,
|
||||
blood_sugar_type: m.blood_sugar_type,
|
||||
water_intake_ml: m.water_intake_ml,
|
||||
urine_output_ml: m.urine_output_ml,
|
||||
notes: m.notes,
|
||||
@@ -100,6 +103,9 @@ pub async fn create_vital_signs(
|
||||
heart_rate: Set(req.heart_rate),
|
||||
weight: Set(req.weight.map(|v| sea_orm::prelude::Decimal::from_f64_retain(v).unwrap_or_default())),
|
||||
blood_sugar: Set(req.blood_sugar.map(|v| sea_orm::prelude::Decimal::from_f64_retain(v).unwrap_or_default())),
|
||||
body_temperature: Set(req.body_temperature.map(|v| sea_orm::prelude::Decimal::from_f64_retain(v).unwrap_or_default())),
|
||||
spo2: Set(req.spo2),
|
||||
blood_sugar_type: Set(req.blood_sugar_type),
|
||||
water_intake_ml: Set(req.water_intake_ml),
|
||||
urine_output_ml: Set(req.urine_output_ml),
|
||||
notes: Set(req.notes),
|
||||
@@ -131,6 +137,9 @@ pub async fn create_vital_signs(
|
||||
heart_rate: m.heart_rate,
|
||||
weight: m.weight.map(|d| d.to_f64().unwrap_or(0.0)),
|
||||
blood_sugar: m.blood_sugar.map(|d| d.to_f64().unwrap_or(0.0)),
|
||||
body_temperature: m.body_temperature.map(|d| d.to_f64().unwrap_or(0.0)),
|
||||
spo2: m.spo2,
|
||||
blood_sugar_type: m.blood_sugar_type,
|
||||
water_intake_ml: m.water_intake_ml, urine_output_ml: m.urine_output_ml,
|
||||
notes: m.notes, created_at: m.created_at, updated_at: m.updated_at, version: m.version,
|
||||
})
|
||||
@@ -178,6 +187,9 @@ pub async fn update_vital_signs(
|
||||
if let Some(v) = req.heart_rate { active.heart_rate = Set(Some(v)); }
|
||||
if let Some(v) = req.weight { active.weight = Set(Some(sea_orm::prelude::Decimal::from_f64_retain(v).unwrap_or_default())); }
|
||||
if let Some(v) = req.blood_sugar { active.blood_sugar = Set(Some(sea_orm::prelude::Decimal::from_f64_retain(v).unwrap_or_default())); }
|
||||
if let Some(v) = req.body_temperature { active.body_temperature = Set(Some(sea_orm::prelude::Decimal::from_f64_retain(v).unwrap_or_default())); }
|
||||
if let Some(v) = req.spo2 { active.spo2 = Set(Some(v)); }
|
||||
if let Some(v) = req.blood_sugar_type { active.blood_sugar_type = Set(Some(v)); }
|
||||
if let Some(v) = req.water_intake_ml { active.water_intake_ml = Set(Some(v)); }
|
||||
if let Some(v) = req.urine_output_ml { active.urine_output_ml = Set(Some(v)); }
|
||||
if let Some(v) = req.notes { active.notes = Set(Some(v)); }
|
||||
@@ -210,6 +222,9 @@ pub async fn update_vital_signs(
|
||||
heart_rate: m.heart_rate,
|
||||
weight: m.weight.map(|d| d.to_f64().unwrap_or(0.0)),
|
||||
blood_sugar: m.blood_sugar.map(|d| d.to_f64().unwrap_or(0.0)),
|
||||
body_temperature: m.body_temperature.map(|d| d.to_f64().unwrap_or(0.0)),
|
||||
spo2: m.spo2,
|
||||
blood_sugar_type: m.blood_sugar_type.clone(),
|
||||
water_intake_ml: m.water_intake_ml,
|
||||
urine_output_ml: m.urine_output_ml,
|
||||
notes: m.notes.clone(),
|
||||
@@ -232,6 +247,9 @@ pub async fn update_vital_signs(
|
||||
heart_rate: m.heart_rate,
|
||||
weight: m.weight.map(|d| d.to_f64().unwrap_or(0.0)),
|
||||
blood_sugar: m.blood_sugar.map(|d| d.to_f64().unwrap_or(0.0)),
|
||||
body_temperature: m.body_temperature.map(|d| d.to_f64().unwrap_or(0.0)),
|
||||
spo2: m.spo2,
|
||||
blood_sugar_type: m.blood_sugar_type,
|
||||
water_intake_ml: m.water_intake_ml, urine_output_ml: m.urine_output_ml,
|
||||
notes: m.notes, created_at: m.created_at, updated_at: m.updated_at, version: m.version,
|
||||
})
|
||||
|
||||
@@ -78,6 +78,7 @@ mod m20260426_000075_create_patient_devices;
|
||||
mod m20260426_000076_create_alert_rules;
|
||||
mod m20260426_000077_create_alerts;
|
||||
mod m20260427_000078_normalize_follow_up_types;
|
||||
mod m20260427_000079_add_vital_signs_fields;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
@@ -163,6 +164,7 @@ impl MigratorTrait for Migrator {
|
||||
Box::new(m20260426_000076_create_alert_rules::Migration),
|
||||
Box::new(m20260426_000077_create_alerts::Migration),
|
||||
Box::new(m20260427_000078_normalize_follow_up_types::Migration),
|
||||
Box::new(m20260427_000079_add_vital_signs_fields::Migration),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
use sea_orm_migration::prelude::*;
|
||||
|
||||
pub struct Migration;
|
||||
|
||||
impl MigrationName for Migration {
|
||||
fn name(&self) -> &str {
|
||||
"m20260427_000079_add_vital_signs_fields"
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
let conn = manager.get_connection();
|
||||
|
||||
conn.execute_unprepared(
|
||||
"ALTER TABLE vital_signs ADD COLUMN IF NOT EXISTS body_temperature DECIMAL(4,1)",
|
||||
)
|
||||
.await?;
|
||||
|
||||
conn.execute_unprepared(
|
||||
"ALTER TABLE vital_signs ADD COLUMN IF NOT EXISTS spo2 INTEGER",
|
||||
)
|
||||
.await?;
|
||||
|
||||
conn.execute_unprepared(
|
||||
"ALTER TABLE vital_signs ADD COLUMN IF NOT EXISTS blood_sugar_type VARCHAR(20) DEFAULT 'fasting'",
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
let conn = manager.get_connection();
|
||||
|
||||
conn.execute_unprepared(
|
||||
"ALTER TABLE vital_signs DROP COLUMN IF EXISTS blood_sugar_type",
|
||||
)
|
||||
.await?;
|
||||
|
||||
conn.execute_unprepared(
|
||||
"ALTER TABLE vital_signs DROP COLUMN IF EXISTS spo2",
|
||||
)
|
||||
.await?;
|
||||
|
||||
conn.execute_unprepared(
|
||||
"ALTER TABLE vital_signs DROP COLUMN IF EXISTS body_temperature",
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user