diff --git a/crates/erp-health/src/dto/consultation_dto.rs b/crates/erp-health/src/dto/consultation_dto.rs index 8b09a2a..0beb09f 100644 --- a/crates/erp-health/src/dto/consultation_dto.rs +++ b/crates/erp-health/src/dto/consultation_dto.rs @@ -8,6 +8,8 @@ pub struct SessionResp { pub id: Uuid, pub patient_id: Uuid, pub doctor_id: Option, + pub patient_name: Option, + pub doctor_name: Option, pub consultation_type: String, pub status: String, pub last_message_at: Option>, diff --git a/crates/erp-health/src/dto/follow_up_dto.rs b/crates/erp-health/src/dto/follow_up_dto.rs index d1e6ce0..379dea9 100644 --- a/crates/erp-health/src/dto/follow_up_dto.rs +++ b/crates/erp-health/src/dto/follow_up_dto.rs @@ -49,6 +49,7 @@ pub struct FollowUpTaskResp { pub id: Uuid, pub patient_id: Uuid, pub assigned_to: Option, + pub patient_name: Option, pub follow_up_type: String, pub planned_date: NaiveDate, pub status: String, diff --git a/crates/erp-health/src/service/consultation_service.rs b/crates/erp-health/src/service/consultation_service.rs index 62661f3..1788069 100644 --- a/crates/erp-health/src/service/consultation_service.rs +++ b/crates/erp-health/src/service/consultation_service.rs @@ -12,7 +12,7 @@ use erp_core::error::check_version; use erp_core::types::PaginatedResponse; use crate::dto::consultation_dto::*; -use crate::entity::{consultation_message, consultation_session, patient}; +use crate::entity::{consultation_message, consultation_session, doctor_profile, patient}; use crate::error::{HealthError, HealthResult}; use crate::service::validation::{validate_sender_role, validate_content_type, validate_consultation_type}; use crate::state::HealthState; @@ -25,6 +25,7 @@ use erp_core::crypto as pii; fn model_to_session_resp(m: consultation_session::Model) -> SessionResp { SessionResp { id: m.id, patient_id: m.patient_id, doctor_id: m.doctor_id, + patient_name: None, doctor_name: None, consultation_type: m.consultation_type, status: m.status, last_message_at: m.last_message_at, unread_count_patient: m.unread_count_patient, @@ -216,8 +217,43 @@ pub async fn export_sessions( .all(&state.db) .await?; + // 批量查询 patient_name 和 doctor_name + let patient_ids: std::collections::HashSet = models.iter().map(|m| m.patient_id).collect(); + let doctor_ids: std::collections::HashSet = models.iter().filter_map(|m| m.doctor_id).collect(); + + let patient_names: std::collections::HashMap = if !patient_ids.is_empty() { + patient::Entity::find() + .filter(patient::Column::Id.is_in(patient_ids)) + .filter(patient::Column::TenantId.eq(tenant_id)) + .all(&state.db) + .await? + .into_iter() + .map(|p| (p.id, p.name)) + .collect() + } else { + std::collections::HashMap::new() + }; + + let doctor_names: std::collections::HashMap = if !doctor_ids.is_empty() { + doctor_profile::Entity::find() + .filter(doctor_profile::Column::Id.is_in(doctor_ids)) + .filter(doctor_profile::Column::TenantId.eq(tenant_id)) + .all(&state.db) + .await? + .into_iter() + .map(|d| (d.id, d.name)) + .collect() + } else { + std::collections::HashMap::new() + }; + let total_pages = total.div_ceil(limit.max(1)); - let data = models.into_iter().map(model_to_session_resp).collect(); + let data = models.into_iter().map(|m| { + let mut resp = model_to_session_resp(m.clone()); + resp.patient_name = patient_names.get(&m.patient_id).cloned(); + resp.doctor_name = m.doctor_id.and_then(|did| doctor_names.get(&did).cloned()); + resp + }).collect(); Ok(PaginatedResponse { data, total, page: page_num, page_size: limit, total_pages }) } diff --git a/crates/erp-health/src/service/follow_up_service.rs b/crates/erp-health/src/service/follow_up_service.rs index 7db742f..49d02af 100644 --- a/crates/erp-health/src/service/follow_up_service.rs +++ b/crates/erp-health/src/service/follow_up_service.rs @@ -13,6 +13,7 @@ use erp_core::types::PaginatedResponse; use crate::dto::follow_up_dto::*; use crate::entity::{follow_up_record, follow_up_task, patient}; +use std::collections::{HashMap, HashSet}; use crate::error::{HealthError, HealthResult}; use crate::service::validation::validate_follow_up_type; use crate::state::HealthState; @@ -51,8 +52,25 @@ pub async fn list_tasks( .await?; let total_pages = total.div_ceil(limit.max(1)); + + // 批量查询 patient_name + let patient_ids: HashSet = models.iter().map(|m| m.patient_id).collect(); + let patient_names: HashMap = if !patient_ids.is_empty() { + patient::Entity::find() + .filter(patient::Column::Id.is_in(patient_ids)) + .filter(patient::Column::TenantId.eq(tenant_id)) + .all(&state.db) + .await? + .into_iter() + .map(|p| (p.id, p.name)) + .collect() + } else { + HashMap::new() + }; + let data = models.into_iter().map(|m| FollowUpTaskResp { id: m.id, patient_id: m.patient_id, assigned_to: m.assigned_to, + patient_name: patient_names.get(&m.patient_id).cloned(), follow_up_type: m.follow_up_type, planned_date: m.planned_date, status: m.status, content_template: m.content_template, related_appointment_id: m.related_appointment_id, @@ -77,6 +95,7 @@ pub async fn get_task( Ok(FollowUpTaskResp { id: m.id, patient_id: m.patient_id, assigned_to: m.assigned_to, + patient_name: None, follow_up_type: m.follow_up_type, planned_date: m.planned_date, status: m.status, content_template: m.content_template, related_appointment_id: m.related_appointment_id, @@ -137,6 +156,7 @@ pub async fn create_task( Ok(FollowUpTaskResp { id: m.id, patient_id: m.patient_id, assigned_to: m.assigned_to, + patient_name: None, follow_up_type: m.follow_up_type, planned_date: m.planned_date, status: m.status, content_template: m.content_template, related_appointment_id: m.related_appointment_id, @@ -207,6 +227,7 @@ pub async fn update_task( Ok(FollowUpTaskResp { id: m.id, patient_id: m.patient_id, assigned_to: m.assigned_to, + patient_name: None, follow_up_type: m.follow_up_type, planned_date: m.planned_date, status: m.status, content_template: m.content_template, related_appointment_id: m.related_appointment_id,