diff --git a/crates/erp-health/src/dto/appointment_dto.rs b/crates/erp-health/src/dto/appointment_dto.rs index f3b2f5c..1097ce6 100644 --- a/crates/erp-health/src/dto/appointment_dto.rs +++ b/crates/erp-health/src/dto/appointment_dto.rs @@ -38,6 +38,8 @@ pub struct AppointmentResp { pub id: Uuid, pub patient_id: Uuid, pub doctor_id: Option, + pub patient_name: Option, + pub doctor_name: Option, pub appointment_type: String, pub appointment_date: NaiveDate, pub start_time: NaiveTime, diff --git a/crates/erp-health/src/service/appointment_service.rs b/crates/erp-health/src/service/appointment_service.rs index f94642a..0e69ec3 100644 --- a/crates/erp-health/src/service/appointment_service.rs +++ b/crates/erp-health/src/service/appointment_service.rs @@ -14,6 +14,7 @@ use erp_core::types::PaginatedResponse; use crate::dto::appointment_dto::*; use crate::entity::{appointment, doctor_profile, doctor_schedule, patient}; use crate::error::{HealthError, HealthResult}; +use std::collections::{HashMap, HashSet}; use crate::service::validation::{ validate_appointment_status_transition, validate_appointment_type, validate_period_type, validate_schedule_status, @@ -54,9 +55,41 @@ pub async fn list_appointments( .all(&state.db) .await?; + // 批量查询 patient_name 和 doctor_name + let patient_ids: HashSet = models.iter().map(|m| m.patient_id).collect(); + let doctor_ids: HashSet = models.iter().filter_map(|m| m.doctor_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 doctor_names: 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 { + HashMap::new() + }; + let total_pages = total.div_ceil(limit.max(1)); let data = models.into_iter().map(|m| AppointmentResp { id: m.id, patient_id: m.patient_id, doctor_id: m.doctor_id, + patient_name: patient_names.get(&m.patient_id).cloned(), + doctor_name: m.doctor_id.and_then(|did| doctor_names.get(&did).cloned()), appointment_type: m.appointment_type, appointment_date: m.appointment_date, start_time: m.start_time, end_time: m.end_time, status: m.status, cancel_reason: m.cancel_reason, notes: m.notes, @@ -81,6 +114,7 @@ pub async fn get_appointment( Ok(AppointmentResp { id: m.id, patient_id: m.patient_id, doctor_id: m.doctor_id, + patient_name: None, doctor_name: None, appointment_type: m.appointment_type, appointment_date: m.appointment_date, start_time: m.start_time, end_time: m.end_time, status: m.status, cancel_reason: m.cancel_reason, notes: m.notes, @@ -189,6 +223,7 @@ pub async fn create_appointment( Ok(AppointmentResp { id: m.id, patient_id: m.patient_id, doctor_id: m.doctor_id, + patient_name: None, doctor_name: None, appointment_type: m.appointment_type, appointment_date: m.appointment_date, start_time: m.start_time, end_time: m.end_time, status: m.status, cancel_reason: m.cancel_reason, notes: m.notes, @@ -280,6 +315,7 @@ pub async fn update_appointment_status( Ok(AppointmentResp { id: m.id, patient_id: m.patient_id, doctor_id: m.doctor_id, + patient_name: None, doctor_name: None, appointment_type: m.appointment_type, appointment_date: m.appointment_date, start_time: m.start_time, end_time: m.end_time, status: m.status, cancel_reason: m.cancel_reason, notes: m.notes,