use async_trait::async_trait; use serde::{Deserialize, Serialize}; use uuid::Uuid; use crate::error::AppResult; /// 健康数据提供者 trait,由 erp-health 实现 /// 返回的 DTO 已脱去 PII(姓名、身份证号等),只包含年龄/性别/医疗数据 #[async_trait] pub trait HealthDataProvider: Send + Sync { /// 获取化验报告(指标列表) async fn get_lab_report(&self, tenant_id: Uuid, report_id: Uuid) -> AppResult; /// 获取生命体征趋势数据 async fn get_vital_signs( &self, tenant_id: Uuid, patient_id: Uuid, metrics: &[String], range: &TimeRange, ) -> AppResult>; /// 获取患者摘要(用于个性化方案) async fn get_patient_summary( &self, tenant_id: Uuid, patient_id: Uuid, ) -> AppResult; /// 获取完整健康报告(用于摘要生成) async fn get_full_report(&self, tenant_id: Uuid, report_id: Uuid) -> AppResult; /// 获取趋势分析预计算数据(统计摘要 + 异常检测) async fn get_trend_analysis_data( &self, tenant_id: Uuid, patient_id: Uuid, metrics: &[String], range: &TimeRange, ) -> AppResult; } // === DTO 定义 === #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TimeRange { pub start: chrono::DateTime, pub end: chrono::DateTime, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct LabReportDto { pub age_group: String, pub sex: String, pub department: String, pub report_date: String, pub items: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct LabItemDto { pub name: String, pub value: f64, pub unit: String, pub reference_range: String, pub is_abnormal: bool, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct VitalSignDto { pub metric: String, pub values: Vec<(String, f64)>, pub unit: String, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PatientSummaryDto { pub age_group: String, pub sex: String, pub chronic_conditions: Vec, pub medications: Vec, pub family_history: Vec, pub last_checkup_date: String, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct HealthReportDto { pub age_group: String, pub sex: String, pub department: String, pub report_date: String, pub sections: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ReportSectionDto { pub title: String, pub findings: Vec, pub abnormal_items: Vec, } // === 趋势分析 DTO === /// 趋势方向 #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] pub enum TrendDirection { Rising, Falling, Stable, } /// 趋势分析整体 DTO #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TrendAnalysisDto { pub patient_id: Uuid, pub period_start: String, pub period_end: String, pub metrics: Vec, } /// 单个指标的趋势分析结果 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MetricTrendAnalysis { pub metric: String, pub unit: String, pub data_point_count: usize, /// 线性回归统计(数据不足时为 None) pub regression: Option, /// 检测到的异常点 pub anomalies: Vec, } /// 线性回归统计摘要 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RegressionStats { pub slope: f64, pub intercept: f64, pub r_squared: f64, pub direction: TrendDirection, pub daily_change: f64, pub period_change: f64, } /// 异常点信息 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AnomalyInfo { pub date: String, pub value: f64, pub mean: f64, pub std_dev: f64, pub deviation: f64, }