From e8ee441ae1a740cc1033f6922c40d46a4c3342c9 Mon Sep 17 00:00:00 2001 From: iven Date: Sat, 2 May 2026 11:37:21 +0800 Subject: [PATCH] =?UTF-8?q?feat(health):=20Track=203=20=E5=8C=BB=E7=96=97?= =?UTF-8?q?=E9=98=88=E5=80=BC=20=E2=80=94=20warning=20=E7=A7=8D=E5=AD=90?= =?UTF-8?q?=20+=20=E6=82=A3=E8=80=85=E7=AB=AF=E5=8F=AA=E8=AF=BB=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 6 条 warning 级别阈值种子数据(血压/心率/血糖参考范围) - 新增 GET /health/critical-value-thresholds/public 患者端只读接口 - 扩展 indicator 验证支持 blood_sugar_fasting/postprandial 等新指标 --- .../critical_value_threshold_handler.rs | 13 +++++ crates/erp-health/src/module.rs | 5 ++ .../critical_value_threshold_service.rs | 11 +++- crates/erp-server/migration/src/lib.rs | 2 + ...20260502_000102_seed_warning_thresholds.rs | 56 +++++++++++++++++++ 5 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 crates/erp-server/migration/src/m20260502_000102_seed_warning_thresholds.rs diff --git a/crates/erp-health/src/handler/critical_value_threshold_handler.rs b/crates/erp-health/src/handler/critical_value_threshold_handler.rs index 1a432d9..2d004dd 100644 --- a/crates/erp-health/src/handler/critical_value_threshold_handler.rs +++ b/crates/erp-health/src/handler/critical_value_threshold_handler.rs @@ -109,3 +109,16 @@ where .await?; Ok(Json(ApiResponse::ok(()))) } + +/// 患者端只读接口 — 返回当前租户所有活跃阈值,仅需认证。 +pub async fn list_public_thresholds( + State(state): State, + Extension(ctx): Extension, +) -> Result>>, AppError> +where + HealthState: FromRef, + S: Clone + Send + Sync + 'static, +{ + let list = critical_value_threshold_service::find_thresholds(&state.db, ctx.tenant_id).await?; + Ok(Json(ApiResponse::ok(list))) +} diff --git a/crates/erp-health/src/module.rs b/crates/erp-health/src/module.rs index 26764e1..356e840 100644 --- a/crates/erp-health/src/module.rs +++ b/crates/erp-health/src/module.rs @@ -608,6 +608,11 @@ impl HealthModule { axum::routing::put(critical_value_threshold_handler::update_threshold) .delete(critical_value_threshold_handler::delete_threshold), ) + // 患者端只读阈值(仅需认证) + .route( + "/health/critical-value-thresholds/public", + axum::routing::get(critical_value_threshold_handler::list_public_thresholds), + ) // 知情同意记录 .route( "/health/patients/{patient_id}/consents", diff --git a/crates/erp-health/src/service/critical_value_threshold_service.rs b/crates/erp-health/src/service/critical_value_threshold_service.rs index cb6ac1c..b29c929 100644 --- a/crates/erp-health/src/service/critical_value_threshold_service.rs +++ b/crates/erp-health/src/service/critical_value_threshold_service.rs @@ -186,7 +186,16 @@ fn validate_direction(direction: &str) -> HealthResult<()> { } fn validate_indicator(indicator: &str) -> HealthResult<()> { - let valid = ["systolic_bp", "diastolic_bp", "heart_rate", "blood_sugar"]; + let valid = [ + "systolic_bp", + "diastolic_bp", + "heart_rate", + "blood_sugar", + "blood_sugar_fasting", + "blood_sugar_postprandial", + "blood_oxygen", + "temperature", + ]; if valid.contains(&indicator) { Ok(()) } else { diff --git a/crates/erp-server/migration/src/lib.rs b/crates/erp-server/migration/src/lib.rs index 708009d..06e7cf5 100644 --- a/crates/erp-server/migration/src/lib.rs +++ b/crates/erp-server/migration/src/lib.rs @@ -101,6 +101,7 @@ mod m20260501_000098_create_ai_suggestion; mod m20260501_000099_create_ai_risk_threshold; mod m20260501_000100_seed_action_inbox_menu; mod m20260502_000101_seed_health_dictionaries; +mod m20260502_000102_seed_warning_thresholds; pub struct Migrator; @@ -209,6 +210,7 @@ impl MigratorTrait for Migrator { Box::new(m20260501_000099_create_ai_risk_threshold::Migration), Box::new(m20260501_000100_seed_action_inbox_menu::Migration), Box::new(m20260502_000101_seed_health_dictionaries::Migration), + Box::new(m20260502_000102_seed_warning_thresholds::Migration), ] } } diff --git a/crates/erp-server/migration/src/m20260502_000102_seed_warning_thresholds.rs b/crates/erp-server/migration/src/m20260502_000102_seed_warning_thresholds.rs new file mode 100644 index 0000000..dc6d924 --- /dev/null +++ b/crates/erp-server/migration/src/m20260502_000102_seed_warning_thresholds.rs @@ -0,0 +1,56 @@ +//! 补充 warning 级别危急值阈值种子数据 + +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + let db = manager.get_connection(); + + let result = db + .query_one(sea_orm::Statement::from_string( + sea_orm::DatabaseBackend::Postgres, + "SELECT id::text FROM tenant LIMIT 1".to_string(), + )) + .await?; + + let tid = match result { + Some(row) => row.try_get_by_index::(0).unwrap_or_default(), + None => return Ok(()), + }; + + // warning 级别阈值 — 用于小程序体征参考范围 + let sql = format!( + r#" + INSERT INTO critical_value_threshold (id, tenant_id, indicator, direction, threshold_value, level, is_active, created_at, updated_at) + VALUES + (gen_random_uuid(), '{tid}', 'systolic_bp', 'high', 140, 'warning', true, now(), now()), + (gen_random_uuid(), '{tid}', 'diastolic_bp', 'high', 90, 'warning', true, now(), now()), + (gen_random_uuid(), '{tid}', 'heart_rate', 'high', 100, 'warning', true, now(), now()), + (gen_random_uuid(), '{tid}', 'heart_rate', 'low', 60, 'warning', true, now(), now()), + (gen_random_uuid(), '{tid}', 'blood_sugar_fasting', 'high', 6.1, 'warning', true, now(), now()), + (gen_random_uuid(), '{tid}', 'blood_sugar_postprandial','high', 7.8, 'warning', true, now(), now()) + "# + ); + db.execute(sea_orm::Statement::from_string( + sea_orm::DatabaseBackend::Postgres, + sql, + )) + .await?; + + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + let db = manager.get_connection(); + db.execute(sea_orm::Statement::from_string( + sea_orm::DatabaseBackend::Postgres, + "DELETE FROM critical_value_threshold WHERE level = 'warning'".to_string(), + )) + .await?; + Ok(()) + } +}