From d0cb45f4570254a8f249dbecbfbb78bf6bf98247 Mon Sep 17 00:00:00 2001 From: iven Date: Mon, 11 May 2026 12:59:56 +0800 Subject: [PATCH] =?UTF-8?q?refactor(health):=20=E6=8B=86=E5=88=86=20module?= =?UTF-8?q?.rs=20=E8=B7=AF=E7=94=B1=E6=B3=A8=E5=86=8C=E4=B8=BA=2013=20?= =?UTF-8?q?=E4=B8=AA=E5=AD=90=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit protected_routes (800+ 行) 按业务域拆分为 routes/ 目录下 13 个文件: patient / health_data / follow_up / appointment / consultation / article / points / stats / alert / device / media / care / admin。 module.rs 从 1595 行降至 798 行,路由注册逻辑更清晰。 --- crates/erp-health/src/lib.rs | 1 + crates/erp-health/src/module.rs | 833 +------------------ crates/erp-health/src/routes/admin.rs | 47 ++ crates/erp-health/src/routes/alert.rs | 75 ++ crates/erp-health/src/routes/appointment.rs | 37 + crates/erp-health/src/routes/article.rs | 70 ++ crates/erp-health/src/routes/care.rs | 86 ++ crates/erp-health/src/routes/consultation.rs | 61 ++ crates/erp-health/src/routes/device.rs | 62 ++ crates/erp-health/src/routes/follow_up.rs | 55 ++ crates/erp-health/src/routes/health_data.rs | 131 +++ crates/erp-health/src/routes/media.rs | 60 ++ crates/erp-health/src/routes/mod.rs | 13 + crates/erp-health/src/routes/patient.rs | 78 ++ crates/erp-health/src/routes/points.rs | 109 +++ crates/erp-health/src/routes/stats.rs | 68 ++ 16 files changed, 975 insertions(+), 811 deletions(-) create mode 100644 crates/erp-health/src/routes/admin.rs create mode 100644 crates/erp-health/src/routes/alert.rs create mode 100644 crates/erp-health/src/routes/appointment.rs create mode 100644 crates/erp-health/src/routes/article.rs create mode 100644 crates/erp-health/src/routes/care.rs create mode 100644 crates/erp-health/src/routes/consultation.rs create mode 100644 crates/erp-health/src/routes/device.rs create mode 100644 crates/erp-health/src/routes/follow_up.rs create mode 100644 crates/erp-health/src/routes/health_data.rs create mode 100644 crates/erp-health/src/routes/media.rs create mode 100644 crates/erp-health/src/routes/mod.rs create mode 100644 crates/erp-health/src/routes/patient.rs create mode 100644 crates/erp-health/src/routes/points.rs create mode 100644 crates/erp-health/src/routes/stats.rs diff --git a/crates/erp-health/src/lib.rs b/crates/erp-health/src/lib.rs index addc959..d9e217b 100644 --- a/crates/erp-health/src/lib.rs +++ b/crates/erp-health/src/lib.rs @@ -9,6 +9,7 @@ pub mod handler; pub mod health_provider_impl; pub mod module; pub mod oauth; +pub mod routes; pub mod service; pub mod state; diff --git a/crates/erp-health/src/module.rs b/crates/erp-health/src/module.rs index 4166cd6..ccca0a1 100644 --- a/crates/erp-health/src/module.rs +++ b/crates/erp-health/src/module.rs @@ -5,16 +5,7 @@ use erp_core::error::AppResult; use erp_core::events::EventBus; use erp_core::module::{ErpModule, PermissionDescriptor}; -use crate::handler::{ - action_inbox_handler, alert_handler, alert_rule_handler, appointment_handler, - article_category_handler, article_handler, article_tag_handler, banner_handler, - ble_gateway_handler, care_plan_handler, consent_handler, consultation_handler, - critical_alert_handler, critical_value_threshold_handler, daily_monitoring_handler, - device_handler, device_reading_handler, diagnosis_handler, doctor_handler, - family_proxy_handler, follow_up_handler, follow_up_template_handler, health_data_handler, - media_handler, medication_record_handler, medication_reminder_handler, patient_handler, - points_handler, shift_handler, stats_handler, vital_signs_daily_handler, -}; +use crate::handler::{article_handler, banner_handler, ble_gateway_handler}; pub struct HealthModule; @@ -157,10 +148,18 @@ impl HealthModule { "/public/banners", axum::routing::get(banner_handler::list_public_banners), ) + .route( + "/public/banner-image/{banner_id}", + axum::routing::get(banner_handler::serve_banner_image), + ) .route( "/public/articles", axum::routing::get(article_handler::list_public_articles), ) + .route( + "/public/articles/{id}", + axum::routing::get(article_handler::get_public_article), + ) } /// FHIR R4 只读路由(使用 OAuth client_credentials 认证) @@ -240,807 +239,19 @@ impl HealthModule { S: Clone + Send + Sync + 'static, { Router::new() - // 患者管理 - .route( - "/health/patients", - axum::routing::get(patient_handler::list_patients) - .post(patient_handler::create_patient), - ) - .route( - "/health/patients/{id}", - axum::routing::get(patient_handler::get_patient) - .put(patient_handler::update_patient) - .delete(patient_handler::delete_patient), - ) - .route( - "/health/patients/{id}/tags", - axum::routing::post(patient_handler::manage_patient_tags), - ) - .route( - "/health/patient-tags", - axum::routing::get(patient_handler::list_tags).post(patient_handler::create_tag), - ) - .route( - "/health/patient-tags/{id}", - axum::routing::put(patient_handler::update_tag).delete(patient_handler::delete_tag), - ) - .route( - "/health/patients/{id}/health-summary", - axum::routing::get(patient_handler::get_health_summary), - ) - .route( - "/health/patients/{id}/family-members", - axum::routing::get(patient_handler::list_family_members) - .post(patient_handler::create_family_member), - ) - .route( - "/health/patients/{id}/family-members/{fid}", - axum::routing::put(patient_handler::update_family_member) - .delete(patient_handler::delete_family_member), - ) - .route( - "/health/patients/{id}/doctors", - axum::routing::post(patient_handler::assign_doctor), - ) - // 家庭成员健康代理 — 管理端 - .route( - "/health/patients/{patient_id}/family-members/{family_member_id}/grant-access", - axum::routing::post(family_proxy_handler::grant_family_access), - ) - .route( - "/health/patients/{patient_id}/family-members/{family_member_id}/revoke-access", - axum::routing::put(family_proxy_handler::revoke_family_access), - ) - // 家庭成员健康代理 — 患者端(小程序) - .route( - "/health/family/patients", - axum::routing::get(family_proxy_handler::list_my_family_patients), - ) - .route( - "/health/family/patients/{patient_id}/health-summary", - axum::routing::get(family_proxy_handler::get_family_health_summary), - ) - .route( - "/health/family/members/{family_member_id}/link-user", - axum::routing::post(family_proxy_handler::link_family_member_user), - ) - .route( - "/health/patients/{id}/doctors/{did}", - axum::routing::delete(patient_handler::remove_doctor), - ) - // 健康数据 - .route( - "/health/patients/{id}/vital-signs", - axum::routing::get(health_data_handler::list_vital_signs) - .post(health_data_handler::create_vital_signs), - ) - // 诊断记录 - .route( - "/health/patients/{id}/diagnoses", - axum::routing::get(diagnosis_handler::list_diagnoses) - .post(diagnosis_handler::create_diagnosis), - ) - .route( - "/health/diagnoses/{id}", - axum::routing::put(diagnosis_handler::update_diagnosis) - .delete(diagnosis_handler::delete_diagnosis), - ) - // 用药记录 - .route( - "/health/patients/{id}/medications", - axum::routing::get(medication_record_handler::list_medications), - ) - .route( - "/health/medications", - axum::routing::post(medication_record_handler::create_medication), - ) - .route( - "/health/medications/{id}", - axum::routing::get(medication_record_handler::get_medication) - .put(medication_record_handler::update_medication) - .delete(medication_record_handler::delete_medication), - ) - // 药物提醒 CRUD - .route( - "/health/patients/{id}/medication-reminders", - axum::routing::get(medication_reminder_handler::list_reminders), - ) - .route( - "/health/medication-reminders", - axum::routing::post(medication_reminder_handler::create_reminder), - ) - .route( - "/health/medication-reminders/{id}", - axum::routing::put(medication_reminder_handler::update_reminder) - .delete(medication_reminder_handler::delete_reminder), - ) - .route( - "/health/patients/{id}/vital-signs/{vid}", - axum::routing::put(health_data_handler::update_vital_signs) - .delete(health_data_handler::delete_vital_signs), - ) - .route( - "/health/patients/{id}/lab-reports", - axum::routing::get(health_data_handler::list_lab_reports) - .post(health_data_handler::create_lab_report), - ) - .route( - "/health/patients/{id}/lab-reports/{rid}", - axum::routing::put(health_data_handler::update_lab_report) - .delete(health_data_handler::delete_lab_report), - ) - .route( - "/health/patients/{id}/health-records", - axum::routing::get(health_data_handler::list_health_records) - .post(health_data_handler::create_health_record), - ) - .route( - "/health/patients/{id}/health-records/{rid}", - axum::routing::put(health_data_handler::update_health_record) - .delete(health_data_handler::delete_health_record), - ) - .route( - "/health/patients/{id}/trends", - axum::routing::get(health_data_handler::list_trends), - ) - .route( - "/health/patients/{id}/trends/generate", - axum::routing::post(health_data_handler::generate_trend), - ) - .route( - "/health/patients/{id}/trends/{indicator}", - axum::routing::get(health_data_handler::get_indicator_timeseries), - ) - // 小程序趋势查询(通过 JWT user_id 关联 patient,无需传 patient_id) - .route( - "/health/vital-signs/trend", - axum::routing::get(health_data_handler::get_mini_trend), - ) - // 小程序今日体征摘要 - .route( - "/health/vital-signs/today", - axum::routing::get(health_data_handler::get_mini_today), - ) - // 随访模板 - .route( - "/health/follow-up-templates", - axum::routing::get(follow_up_template_handler::list_templates) - .post(follow_up_template_handler::create_template), - ) - .route( - "/health/follow-up-templates/{id}", - axum::routing::get(follow_up_template_handler::get_template) - .put(follow_up_template_handler::update_template) - .delete(follow_up_template_handler::delete_template), - ) - // 日常监测 - .route( - "/health/patients/{id}/daily-monitoring", - axum::routing::get(daily_monitoring_handler::list_daily_monitoring), - ) - .route( - "/health/daily-monitoring", - axum::routing::post(daily_monitoring_handler::create_daily_monitoring), - ) - .route( - "/health/daily-monitoring/{id}", - axum::routing::get(daily_monitoring_handler::get_daily_monitoring) - .put(daily_monitoring_handler::update_daily_monitoring) - .delete(daily_monitoring_handler::delete_daily_monitoring), - ) - // 化验报告审阅 - .route( - "/health/patients/{id}/lab-reports/{rid}/review", - axum::routing::put(health_data_handler::review_lab_report), - ) - // 预约排班 - .route( - "/health/appointments", - axum::routing::get(appointment_handler::list_appointments) - .post(appointment_handler::create_appointment), - ) - .route( - "/health/appointments/{id}/status", - axum::routing::put(appointment_handler::update_appointment_status), - ) - .route( - "/health/appointments/{id}", - axum::routing::get(appointment_handler::get_appointment), - ) - .route( - "/health/doctor-schedules", - axum::routing::get(appointment_handler::list_schedules) - .post(appointment_handler::create_schedule), - ) - .route( - "/health/doctor-schedules/{id}", - axum::routing::put(appointment_handler::update_schedule), - ) - .route( - "/health/doctor-schedules/calendar", - axum::routing::get(appointment_handler::calendar_view), - ) - // 随访管理 - .route( - "/health/follow-up-tasks", - axum::routing::get(follow_up_handler::list_tasks) - .post(follow_up_handler::create_task), - ) - .route( - "/health/follow-up-tasks/{id}", - axum::routing::get(follow_up_handler::get_task) - .put(follow_up_handler::update_task) - .delete(follow_up_handler::delete_task), - ) - .route( - "/health/follow-up-tasks/{id}/records", - axum::routing::post(follow_up_handler::create_record), - ) - .route( - "/health/follow-up-records", - axum::routing::get(follow_up_handler::list_records), - ) - // 随访批量操作 - .route( - "/health/follow-up-tasks/batch-create", - axum::routing::post(follow_up_handler::batch_create_tasks), - ) - .route( - "/health/follow-up-tasks/batch-assign", - axum::routing::post(follow_up_handler::batch_assign_tasks), - ) - .route( - "/health/follow-up-tasks/batch-complete", - axum::routing::post(follow_up_handler::batch_complete_tasks), - ) - // 咨询管理 - .route( - "/health/consultation-sessions", - axum::routing::get(consultation_handler::list_sessions) - .post(consultation_handler::create_session), - ) - .route( - "/health/consultation-sessions/export", - axum::routing::get(consultation_handler::export_sessions), - ) - .route( - "/health/consultation-sessions/{id}", - axum::routing::get(consultation_handler::get_session), - ) - .route( - "/health/consultation-sessions/{id}/messages", - axum::routing::get(consultation_handler::list_messages), - ) - .route( - "/health/consultation-sessions/{id}/messages/poll", - axum::routing::get(consultation_handler::poll_messages), - ) - .route( - "/health/consultation-sessions/{id}/close", - axum::routing::put(consultation_handler::close_session), - ) - .route( - "/health/consultation-sessions/{id}/read", - axum::routing::put(consultation_handler::mark_session_read), - ) - .route( - "/health/consultation-messages", - axum::routing::post(consultation_handler::create_message), - ) - // 医生仪表盘 - .route( - "/health/doctor/dashboard", - axum::routing::get(consultation_handler::get_doctor_dashboard), - ) - // 医护管理 - .route( - "/health/doctors", - axum::routing::get(doctor_handler::list_doctors) - .post(doctor_handler::create_doctor), - ) - .route( - "/health/doctors/{id}", - axum::routing::get(doctor_handler::get_doctor) - .put(doctor_handler::update_doctor) - .delete(doctor_handler::delete_doctor), - ) - // 健康资讯 - .route( - "/health/articles", - axum::routing::get(article_handler::list_articles) - .post(article_handler::create_article), - ) - .route( - "/health/articles/{id}", - axum::routing::get(article_handler::get_article) - .put(article_handler::update_article) - .delete(article_handler::delete_article), - ) - // 资讯审核工作流 - .route( - "/health/articles/{id}/submit", - axum::routing::post(article_handler::submit_article), - ) - .route( - "/health/articles/{id}/approve", - axum::routing::post(article_handler::approve_article), - ) - .route( - "/health/articles/{id}/reject", - axum::routing::post(article_handler::reject_article), - ) - .route( - "/health/articles/{id}/unpublish", - axum::routing::post(article_handler::unpublish_article), - ) - .route( - "/health/articles/{id}/view", - axum::routing::post(article_handler::view_article), - ) - .route( - "/health/articles/{id}/revisions", - axum::routing::get(article_handler::list_revisions), - ) - // 资讯分类 - .route( - "/health/article-categories", - axum::routing::get(article_category_handler::list_categories) - .post(article_category_handler::create_category), - ) - .route( - "/health/article-categories/{id}", - axum::routing::put(article_category_handler::update_category) - .delete(article_category_handler::delete_category), - ) - // 资讯标签 - .route( - "/health/article-tags", - axum::routing::get(article_tag_handler::list_tags) - .post(article_tag_handler::create_tag), - ) - .route( - "/health/article-tags/{id}", - axum::routing::put(article_tag_handler::update_tag) - .delete(article_tag_handler::delete_tag), - ) - // 积分商城 — 患者端 - .route( - "/health/points/account", - axum::routing::get(points_handler::get_my_account), - ) - .route( - "/health/points/checkin", - axum::routing::post(points_handler::daily_checkin), - ) - .route( - "/health/points/checkin/status", - axum::routing::get(points_handler::get_checkin_status), - ) - .route( - "/health/points/transactions", - axum::routing::get(points_handler::list_my_transactions), - ) - .route( - "/health/points/products", - axum::routing::get(points_handler::list_products), - ) - .route( - "/health/points/products/{id}", - axum::routing::get(points_handler::get_product), - ) - .route( - "/health/points/exchange", - axum::routing::post(points_handler::exchange_product), - ) - .route( - "/health/points/orders", - axum::routing::get(points_handler::list_my_orders), - ) - // 线下活动 — 患者端 - .route( - "/health/offline-events", - axum::routing::get(points_handler::list_offline_events), - ) - .route( - "/health/offline-events/{id}/register", - axum::routing::post(points_handler::register_event), - ) - // 积分商城 — 管理端 - .route( - "/health/points/verify", - axum::routing::post(points_handler::verify_order), - ) - .route( - "/health/admin/points/rules", - axum::routing::get(points_handler::list_rules).post(points_handler::create_rule), - ) - .route( - "/health/admin/points/rules/{id}", - axum::routing::put(points_handler::update_rule).delete(points_handler::delete_rule), - ) - .route( - "/health/admin/points/products", - axum::routing::get(points_handler::admin_list_products) - .post(points_handler::admin_create_product), - ) - .route( - "/health/admin/points/products/{id}", - axum::routing::put(points_handler::admin_update_product) - .delete(points_handler::admin_delete_product), - ) - .route( - "/health/admin/points/orders", - axum::routing::get(points_handler::admin_list_orders), - ) - // 积分账户 — 管理端按患者查询 - .route( - "/health/admin/points/patients/{patient_id}/account", - axum::routing::get(points_handler::admin_get_patient_account), - ) - .route( - "/health/admin/points/patients/{patient_id}/transactions", - axum::routing::get(points_handler::admin_list_patient_transactions), - ) - // 线下活动 — 管理端 - .route( - "/health/admin/offline-events", - axum::routing::get(points_handler::admin_list_events) - .post(points_handler::admin_create_event), - ) - .route( - "/health/admin/offline-events/{id}", - axum::routing::put(points_handler::admin_update_event) - .delete(points_handler::admin_delete_event), - ) - .route( - "/health/admin/offline-events/{id}/checkin", - axum::routing::post(points_handler::admin_checkin_event), - ) - // 积分统计 — 管理端 - .route( - "/health/admin/points/statistics", - axum::routing::get(points_handler::get_points_statistics), - ) - // 统计数据 — 管理端 - .route( - "/health/admin/statistics/patients", - axum::routing::get(stats_handler::get_patient_stats), - ) - .route( - "/health/admin/statistics/consultations", - axum::routing::get(stats_handler::get_consultation_stats), - ) - .route( - "/health/admin/statistics/follow-ups", - axum::routing::get(stats_handler::get_follow_up_stats), - ) - .route( - "/health/admin/statistics/dashboard", - axum::routing::get(stats_handler::get_dashboard_stats), - ) - .route( - "/health/admin/statistics/lab-reports", - axum::routing::get(stats_handler::get_lab_report_stats), - ) - .route( - "/health/admin/statistics/appointments", - axum::routing::get(stats_handler::get_appointment_stats), - ) - .route( - "/health/admin/statistics/vital-signs-report-rate", - axum::routing::get(stats_handler::get_vital_signs_report_rate), - ) - .route( - "/health/admin/statistics/health-data", - axum::routing::get(stats_handler::get_health_data_stats), - ) - .route( - "/health/admin/statistics/personal-stats", - axum::routing::get(stats_handler::get_personal_stats), - ) - // 工作台管理统计 API - .route( - "/health/admin/system-health", - axum::routing::get(stats_handler::get_system_health), - ) - .route( - "/health/admin/user-activity", - axum::routing::get(stats_handler::get_user_activity), - ) - .route( - "/health/admin/modules", - axum::routing::get(stats_handler::get_module_status), - ) - .route( - "/health/points/recent-activity", - axum::routing::get(stats_handler::get_points_recent_activity), - ) - .route( - "/health/articles/stats", - axum::routing::get(stats_handler::get_article_stats), - ) - // 危急值阈值配置 - .route( - "/health/critical-value-thresholds", - axum::routing::get(critical_value_threshold_handler::list_thresholds) - .post(critical_value_threshold_handler::create_threshold), - ) - .route( - "/health/critical-value-thresholds/{id}", - 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", - axum::routing::get(consent_handler::list_consents), - ) - .route( - "/health/consents", - axum::routing::post(consent_handler::grant_consent), - ) - .route( - "/health/consents/{consent_id}/revoke", - axum::routing::put(consent_handler::revoke_consent), - ) - // 设备数据采集 - .route( - "/health/patients/{patient_id}/device-readings/batch", - axum::routing::post(device_reading_handler::batch_create), - ) - .route( - "/health/patients/{patient_id}/device-readings", - axum::routing::get(device_reading_handler::list_readings), - ) - .route( - "/health/patients/{patient_id}/device-readings/hourly", - axum::routing::get(device_reading_handler::list_hourly), - ) - // 日聚合查询 - .route( - "/health/vital-signs/daily", - axum::routing::get(vital_signs_daily_handler::get_daily_aggregations), - ) - // 告警路由 - .route( - "/health/alerts", - axum::routing::get(alert_handler::list_alerts), - ) - .route( - "/health/alerts/{id}", - axum::routing::get(alert_handler::get_alert), - ) - .route( - "/health/alerts/{id}/acknowledge", - axum::routing::put(alert_handler::acknowledge), - ) - .route( - "/health/alerts/{id}/dismiss", - axum::routing::put(alert_handler::dismiss), - ) - .route( - "/health/alerts/{id}/resolve", - axum::routing::put(alert_handler::resolve), - ) - // 危急值告警路由 - .route( - "/health/critical-alerts", - axum::routing::get(critical_alert_handler::list_critical_alerts), - ) - .route( - "/health/critical-alerts/{id}", - axum::routing::get(critical_alert_handler::get_critical_alert), - ) - .route( - "/health/critical-alerts/{id}/acknowledge", - axum::routing::post(critical_alert_handler::acknowledge_critical_alert), - ) - .route( - "/health/alert-rules", - axum::routing::get(alert_rule_handler::list_rules).post(alert_rule_handler::create), - ) - .route( - "/health/alert-rules/{id}", - axum::routing::put(alert_rule_handler::update), - ) - .route( - "/health/alert-rules/{id}/deactivate", - axum::routing::put(alert_rule_handler::deactivate), - ) - // 设备管理 - .route( - "/health/devices", - axum::routing::get(device_handler::list_devices), - ) - .route( - "/health/devices/{id}", - axum::routing::delete(device_handler::unbind_device), - ) - // 行动收件箱 - .route( - "/health/action-inbox", - axum::routing::get(action_inbox_handler::list_action_inbox), - ) - .route( - "/health/action-inbox/stats", - axum::routing::get(action_inbox_handler::get_workbench_stats), - ) - .route( - "/health/action-inbox/team", - axum::routing::get(action_inbox_handler::get_team_overview), - ) - .route( - "/health/action-inbox/{source_ref}/thread", - axum::routing::get(action_inbox_handler::get_action_thread), - ) - .route( - "/health/action-inbox/my-patients", - axum::routing::get(action_inbox_handler::get_nurse_patients), - ) - // OAuth 合作方管理 - .route( - "/health/oauth/clients", - axum::routing::get(crate::oauth::handler::list_clients) - .post(crate::oauth::handler::create_client), - ) - .route( - "/health/oauth/clients/{id}", - axum::routing::put(crate::oauth::handler::update_client) - .delete(crate::oauth::handler::delete_client), - ) - .route( - "/health/oauth/clients/{id}/regenerate-secret", - axum::routing::post(crate::oauth::handler::regenerate_secret), - ) - // 媒体库 - .route( - "/health/media", - axum::routing::get(media_handler::list_media), - ) - .route( - "/health/media/upload", - axum::routing::post(media_handler::upload_media), - ) - .route( - "/health/media/batch-delete", - axum::routing::post(media_handler::batch_delete_media), - ) - .route( - "/health/media/{id}", - axum::routing::get(media_handler::get_media) - .put(media_handler::update_media) - .delete(media_handler::delete_media), - ) - .route( - "/health/media/{id}/move", - axum::routing::post(media_handler::move_media), - ) - .route( - "/health/media/{id}/crop", - axum::routing::post(media_handler::crop_media), - ) - // 媒体文件夹 - .route( - "/health/media-folders", - axum::routing::get(media_handler::list_folders).post(media_handler::create_folder), - ) - .route( - "/health/media-folders/{id}", - axum::routing::put(media_handler::update_folder) - .delete(media_handler::delete_folder), - ) - // 轮播图管理 - .route( - "/health/banners", - axum::routing::get(banner_handler::list_banners) - .post(banner_handler::create_banner), - ) - .route( - "/health/banners/sort", - axum::routing::put(banner_handler::sort_banners), - ) - .route( - "/health/banners/{id}", - axum::routing::put(banner_handler::update_banner) - .delete(banner_handler::delete_banner), - ) - // 护理计划 - .route( - "/health/care-plans", - axum::routing::get(care_plan_handler::list_care_plans) - .post(care_plan_handler::create_care_plan), - ) - .route( - "/health/care-plans/{id}", - axum::routing::get(care_plan_handler::get_care_plan) - .put(care_plan_handler::update_care_plan) - .delete(care_plan_handler::delete_care_plan), - ) - .route( - "/health/care-plans/{plan_id}/items", - axum::routing::get(care_plan_handler::list_care_plan_items) - .post(care_plan_handler::create_care_plan_item), - ) - .route( - "/health/care-plans/{plan_id}/items/{item_id}", - axum::routing::put(care_plan_handler::update_care_plan_item) - .delete(care_plan_handler::delete_care_plan_item), - ) - .route( - "/health/care-plans/{plan_id}/outcomes", - axum::routing::get(care_plan_handler::list_care_plan_outcomes) - .post(care_plan_handler::create_care_plan_outcome), - ) - .route( - "/health/care-plans/{plan_id}/outcomes/{outcome_id}", - axum::routing::put(care_plan_handler::update_care_plan_outcome) - .delete(care_plan_handler::delete_care_plan_outcome), - ) - // 班次管理 - .route( - "/health/shifts", - axum::routing::get(shift_handler::list_shifts).post(shift_handler::create_shift), - ) - .route( - "/health/shifts/{shift_id}", - axum::routing::get(shift_handler::get_shift) - .put(shift_handler::update_shift) - .delete(shift_handler::delete_shift), - ) - .route( - "/health/shifts/{shift_id}/assignments", - axum::routing::get(shift_handler::list_assignments) - .post(shift_handler::create_assignment), - ) - .route( - "/health/shifts/{shift_id}/assignments/batch", - axum::routing::post(shift_handler::batch_assign), - ) - .route( - "/health/shifts/{shift_id}/assignments/{assignment_id}", - axum::routing::put(shift_handler::update_assignment) - .delete(shift_handler::delete_assignment), - ) - // 交接记录 - .route( - "/health/handoff-logs", - axum::routing::get(shift_handler::list_handoffs) - .post(shift_handler::create_handoff), - ) - // BLE 网关管理 - .route( - "/health/ble-gateways", - axum::routing::get(ble_gateway_handler::list_gateways) - .post(ble_gateway_handler::create_gateway), - ) - .route( - "/health/ble-gateways/{gateway_id}", - axum::routing::get(ble_gateway_handler::get_gateway) - .put(ble_gateway_handler::update_gateway) - .delete(ble_gateway_handler::delete_gateway), - ) - .route( - "/health/ble-gateways/{gateway_id}/regenerate-key", - axum::routing::post(ble_gateway_handler::regenerate_api_key), - ) - .route( - "/health/ble-gateways/{gateway_id}/bindings", - axum::routing::get(ble_gateway_handler::list_bindings) - .post(ble_gateway_handler::bind_patient), - ) - .route( - "/health/ble-gateways/{gateway_id}/bindings/batch", - axum::routing::post(ble_gateway_handler::batch_bind), - ) - .route( - "/health/ble-gateways/{gateway_id}/bindings/{binding_id}", - axum::routing::delete(ble_gateway_handler::unbind_patient), - ) + .merge(crate::routes::patient::routes()) + .merge(crate::routes::health_data::routes()) + .merge(crate::routes::follow_up::routes()) + .merge(crate::routes::appointment::routes()) + .merge(crate::routes::consultation::routes()) + .merge(crate::routes::article::routes()) + .merge(crate::routes::points::routes()) + .merge(crate::routes::stats::routes()) + .merge(crate::routes::alert::routes()) + .merge(crate::routes::device::routes()) + .merge(crate::routes::media::routes()) + .merge(crate::routes::care::routes()) + .merge(crate::routes::admin::routes()) } /// BLE 网关数据接入路由(裸路由,需在 erp-server 层配合 gateway_auth 中间件使用) diff --git a/crates/erp-health/src/routes/admin.rs b/crates/erp-health/src/routes/admin.rs new file mode 100644 index 0000000..9b92e9b --- /dev/null +++ b/crates/erp-health/src/routes/admin.rs @@ -0,0 +1,47 @@ +use axum::Router; + +use crate::handler::action_inbox_handler; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + // 行动收件箱 + .route( + "/health/action-inbox", + axum::routing::get(action_inbox_handler::list_action_inbox), + ) + .route( + "/health/action-inbox/stats", + axum::routing::get(action_inbox_handler::get_workbench_stats), + ) + .route( + "/health/action-inbox/team", + axum::routing::get(action_inbox_handler::get_team_overview), + ) + .route( + "/health/action-inbox/{source_ref}/thread", + axum::routing::get(action_inbox_handler::get_action_thread), + ) + .route( + "/health/action-inbox/my-patients", + axum::routing::get(action_inbox_handler::get_nurse_patients), + ) + // OAuth 合作方管理 + .route( + "/health/oauth/clients", + axum::routing::get(crate::oauth::handler::list_clients) + .post(crate::oauth::handler::create_client), + ) + .route( + "/health/oauth/clients/{id}", + axum::routing::put(crate::oauth::handler::update_client) + .delete(crate::oauth::handler::delete_client), + ) + .route( + "/health/oauth/clients/{id}/regenerate-secret", + axum::routing::post(crate::oauth::handler::regenerate_secret), + ) +} diff --git a/crates/erp-health/src/routes/alert.rs b/crates/erp-health/src/routes/alert.rs new file mode 100644 index 0000000..92c2ff3 --- /dev/null +++ b/crates/erp-health/src/routes/alert.rs @@ -0,0 +1,75 @@ +use axum::Router; + +use crate::handler::{ + alert_handler, alert_rule_handler, critical_alert_handler, critical_value_threshold_handler, +}; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + // 告警路由 + .route( + "/health/alerts", + axum::routing::get(alert_handler::list_alerts), + ) + .route( + "/health/alerts/{id}", + axum::routing::get(alert_handler::get_alert), + ) + .route( + "/health/alerts/{id}/acknowledge", + axum::routing::put(alert_handler::acknowledge), + ) + .route( + "/health/alerts/{id}/dismiss", + axum::routing::put(alert_handler::dismiss), + ) + .route( + "/health/alerts/{id}/resolve", + axum::routing::put(alert_handler::resolve), + ) + // 危急值告警路由 + .route( + "/health/critical-alerts", + axum::routing::get(critical_alert_handler::list_critical_alerts), + ) + .route( + "/health/critical-alerts/{id}", + axum::routing::get(critical_alert_handler::get_critical_alert), + ) + .route( + "/health/critical-alerts/{id}/acknowledge", + axum::routing::post(critical_alert_handler::acknowledge_critical_alert), + ) + .route( + "/health/alert-rules", + axum::routing::get(alert_rule_handler::list_rules).post(alert_rule_handler::create), + ) + .route( + "/health/alert-rules/{id}", + axum::routing::put(alert_rule_handler::update), + ) + .route( + "/health/alert-rules/{id}/deactivate", + axum::routing::put(alert_rule_handler::deactivate), + ) + // 危急值阈值配置 + .route( + "/health/critical-value-thresholds", + axum::routing::get(critical_value_threshold_handler::list_thresholds) + .post(critical_value_threshold_handler::create_threshold), + ) + .route( + "/health/critical-value-thresholds/{id}", + 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), + ) +} diff --git a/crates/erp-health/src/routes/appointment.rs b/crates/erp-health/src/routes/appointment.rs new file mode 100644 index 0000000..a946152 --- /dev/null +++ b/crates/erp-health/src/routes/appointment.rs @@ -0,0 +1,37 @@ +use axum::Router; + +use crate::handler::appointment_handler; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + .route( + "/health/appointments", + axum::routing::get(appointment_handler::list_appointments) + .post(appointment_handler::create_appointment), + ) + .route( + "/health/appointments/{id}/status", + axum::routing::put(appointment_handler::update_appointment_status), + ) + .route( + "/health/appointments/{id}", + axum::routing::get(appointment_handler::get_appointment), + ) + .route( + "/health/doctor-schedules", + axum::routing::get(appointment_handler::list_schedules) + .post(appointment_handler::create_schedule), + ) + .route( + "/health/doctor-schedules/{id}", + axum::routing::put(appointment_handler::update_schedule), + ) + .route( + "/health/doctor-schedules/calendar", + axum::routing::get(appointment_handler::calendar_view), + ) +} diff --git a/crates/erp-health/src/routes/article.rs b/crates/erp-health/src/routes/article.rs new file mode 100644 index 0000000..cef4c2b --- /dev/null +++ b/crates/erp-health/src/routes/article.rs @@ -0,0 +1,70 @@ +use axum::Router; + +use crate::handler::{article_category_handler, article_handler, article_tag_handler}; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + // 健康资讯 + .route( + "/health/articles", + axum::routing::get(article_handler::list_articles) + .post(article_handler::create_article), + ) + .route( + "/health/articles/{id}", + axum::routing::get(article_handler::get_article) + .put(article_handler::update_article) + .delete(article_handler::delete_article), + ) + // 资讯审核工作流 + .route( + "/health/articles/{id}/submit", + axum::routing::post(article_handler::submit_article), + ) + .route( + "/health/articles/{id}/approve", + axum::routing::post(article_handler::approve_article), + ) + .route( + "/health/articles/{id}/reject", + axum::routing::post(article_handler::reject_article), + ) + .route( + "/health/articles/{id}/unpublish", + axum::routing::post(article_handler::unpublish_article), + ) + .route( + "/health/articles/{id}/view", + axum::routing::post(article_handler::view_article), + ) + .route( + "/health/articles/{id}/revisions", + axum::routing::get(article_handler::list_revisions), + ) + // 资讯分类 + .route( + "/health/article-categories", + axum::routing::get(article_category_handler::list_categories) + .post(article_category_handler::create_category), + ) + .route( + "/health/article-categories/{id}", + axum::routing::put(article_category_handler::update_category) + .delete(article_category_handler::delete_category), + ) + // 资讯标签 + .route( + "/health/article-tags", + axum::routing::get(article_tag_handler::list_tags) + .post(article_tag_handler::create_tag), + ) + .route( + "/health/article-tags/{id}", + axum::routing::put(article_tag_handler::update_tag) + .delete(article_tag_handler::delete_tag), + ) +} diff --git a/crates/erp-health/src/routes/care.rs b/crates/erp-health/src/routes/care.rs new file mode 100644 index 0000000..96c9f8e --- /dev/null +++ b/crates/erp-health/src/routes/care.rs @@ -0,0 +1,86 @@ +use axum::Router; + +use crate::handler::{care_plan_handler, consent_handler, shift_handler}; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + // 护理计划 + .route( + "/health/care-plans", + axum::routing::get(care_plan_handler::list_care_plans) + .post(care_plan_handler::create_care_plan), + ) + .route( + "/health/care-plans/{id}", + axum::routing::get(care_plan_handler::get_care_plan) + .put(care_plan_handler::update_care_plan) + .delete(care_plan_handler::delete_care_plan), + ) + .route( + "/health/care-plans/{plan_id}/items", + axum::routing::get(care_plan_handler::list_care_plan_items) + .post(care_plan_handler::create_care_plan_item), + ) + .route( + "/health/care-plans/{plan_id}/items/{item_id}", + axum::routing::put(care_plan_handler::update_care_plan_item) + .delete(care_plan_handler::delete_care_plan_item), + ) + .route( + "/health/care-plans/{plan_id}/outcomes", + axum::routing::get(care_plan_handler::list_care_plan_outcomes) + .post(care_plan_handler::create_care_plan_outcome), + ) + .route( + "/health/care-plans/{plan_id}/outcomes/{outcome_id}", + axum::routing::put(care_plan_handler::update_care_plan_outcome) + .delete(care_plan_handler::delete_care_plan_outcome), + ) + // 班次管理 + .route( + "/health/shifts", + axum::routing::get(shift_handler::list_shifts).post(shift_handler::create_shift), + ) + .route( + "/health/shifts/{shift_id}", + axum::routing::get(shift_handler::get_shift) + .put(shift_handler::update_shift) + .delete(shift_handler::delete_shift), + ) + .route( + "/health/shifts/{shift_id}/assignments", + axum::routing::get(shift_handler::list_assignments) + .post(shift_handler::create_assignment), + ) + .route( + "/health/shifts/{shift_id}/assignments/batch", + axum::routing::post(shift_handler::batch_assign), + ) + .route( + "/health/shifts/{shift_id}/assignments/{assignment_id}", + axum::routing::put(shift_handler::update_assignment) + .delete(shift_handler::delete_assignment), + ) + // 交接记录 + .route( + "/health/handoff-logs", + axum::routing::get(shift_handler::list_handoffs).post(shift_handler::create_handoff), + ) + // 知情同意记录 + .route( + "/health/patients/{patient_id}/consents", + axum::routing::get(consent_handler::list_consents), + ) + .route( + "/health/consents", + axum::routing::post(consent_handler::grant_consent), + ) + .route( + "/health/consents/{consent_id}/revoke", + axum::routing::put(consent_handler::revoke_consent), + ) +} diff --git a/crates/erp-health/src/routes/consultation.rs b/crates/erp-health/src/routes/consultation.rs new file mode 100644 index 0000000..64549da --- /dev/null +++ b/crates/erp-health/src/routes/consultation.rs @@ -0,0 +1,61 @@ +use axum::Router; + +use crate::handler::{consultation_handler, doctor_handler}; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + // 咨询管理 + .route( + "/health/consultation-sessions", + axum::routing::get(consultation_handler::list_sessions) + .post(consultation_handler::create_session), + ) + .route( + "/health/consultation-sessions/export", + axum::routing::get(consultation_handler::export_sessions), + ) + .route( + "/health/consultation-sessions/{id}", + axum::routing::get(consultation_handler::get_session), + ) + .route( + "/health/consultation-sessions/{id}/messages", + axum::routing::get(consultation_handler::list_messages), + ) + .route( + "/health/consultation-sessions/{id}/messages/poll", + axum::routing::get(consultation_handler::poll_messages), + ) + .route( + "/health/consultation-sessions/{id}/close", + axum::routing::put(consultation_handler::close_session), + ) + .route( + "/health/consultation-sessions/{id}/read", + axum::routing::put(consultation_handler::mark_session_read), + ) + .route( + "/health/consultation-messages", + axum::routing::post(consultation_handler::create_message), + ) + // 医生仪表盘 + .route( + "/health/doctor/dashboard", + axum::routing::get(consultation_handler::get_doctor_dashboard), + ) + // 医护管理 + .route( + "/health/doctors", + axum::routing::get(doctor_handler::list_doctors).post(doctor_handler::create_doctor), + ) + .route( + "/health/doctors/{id}", + axum::routing::get(doctor_handler::get_doctor) + .put(doctor_handler::update_doctor) + .delete(doctor_handler::delete_doctor), + ) +} diff --git a/crates/erp-health/src/routes/device.rs b/crates/erp-health/src/routes/device.rs new file mode 100644 index 0000000..6014751 --- /dev/null +++ b/crates/erp-health/src/routes/device.rs @@ -0,0 +1,62 @@ +use axum::Router; + +use crate::handler::{ble_gateway_handler, device_handler, device_reading_handler}; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + // 设备数据采集 + .route( + "/health/patients/{patient_id}/device-readings/batch", + axum::routing::post(device_reading_handler::batch_create), + ) + .route( + "/health/patients/{patient_id}/device-readings", + axum::routing::get(device_reading_handler::list_readings), + ) + .route( + "/health/patients/{patient_id}/device-readings/hourly", + axum::routing::get(device_reading_handler::list_hourly), + ) + // 设备管理 + .route( + "/health/devices", + axum::routing::get(device_handler::list_devices), + ) + .route( + "/health/devices/{id}", + axum::routing::delete(device_handler::unbind_device), + ) + // BLE 网关管理 + .route( + "/health/ble-gateways", + axum::routing::get(ble_gateway_handler::list_gateways) + .post(ble_gateway_handler::create_gateway), + ) + .route( + "/health/ble-gateways/{gateway_id}", + axum::routing::get(ble_gateway_handler::get_gateway) + .put(ble_gateway_handler::update_gateway) + .delete(ble_gateway_handler::delete_gateway), + ) + .route( + "/health/ble-gateways/{gateway_id}/regenerate-key", + axum::routing::post(ble_gateway_handler::regenerate_api_key), + ) + .route( + "/health/ble-gateways/{gateway_id}/bindings", + axum::routing::get(ble_gateway_handler::list_bindings) + .post(ble_gateway_handler::bind_patient), + ) + .route( + "/health/ble-gateways/{gateway_id}/bindings/batch", + axum::routing::post(ble_gateway_handler::batch_bind), + ) + .route( + "/health/ble-gateways/{gateway_id}/bindings/{binding_id}", + axum::routing::delete(ble_gateway_handler::unbind_patient), + ) +} diff --git a/crates/erp-health/src/routes/follow_up.rs b/crates/erp-health/src/routes/follow_up.rs new file mode 100644 index 0000000..dabb149 --- /dev/null +++ b/crates/erp-health/src/routes/follow_up.rs @@ -0,0 +1,55 @@ +use axum::Router; + +use crate::handler::{follow_up_handler, follow_up_template_handler}; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + // 随访模板 + .route( + "/health/follow-up-templates", + axum::routing::get(follow_up_template_handler::list_templates) + .post(follow_up_template_handler::create_template), + ) + .route( + "/health/follow-up-templates/{id}", + axum::routing::get(follow_up_template_handler::get_template) + .put(follow_up_template_handler::update_template) + .delete(follow_up_template_handler::delete_template), + ) + // 随访管理 + .route( + "/health/follow-up-tasks", + axum::routing::get(follow_up_handler::list_tasks).post(follow_up_handler::create_task), + ) + .route( + "/health/follow-up-tasks/{id}", + axum::routing::get(follow_up_handler::get_task) + .put(follow_up_handler::update_task) + .delete(follow_up_handler::delete_task), + ) + .route( + "/health/follow-up-tasks/{id}/records", + axum::routing::post(follow_up_handler::create_record), + ) + .route( + "/health/follow-up-records", + axum::routing::get(follow_up_handler::list_records), + ) + // 随访批量操作 + .route( + "/health/follow-up-tasks/batch-create", + axum::routing::post(follow_up_handler::batch_create_tasks), + ) + .route( + "/health/follow-up-tasks/batch-assign", + axum::routing::post(follow_up_handler::batch_assign_tasks), + ) + .route( + "/health/follow-up-tasks/batch-complete", + axum::routing::post(follow_up_handler::batch_complete_tasks), + ) +} diff --git a/crates/erp-health/src/routes/health_data.rs b/crates/erp-health/src/routes/health_data.rs new file mode 100644 index 0000000..5ac7c29 --- /dev/null +++ b/crates/erp-health/src/routes/health_data.rs @@ -0,0 +1,131 @@ +use axum::Router; + +use crate::handler::{ + daily_monitoring_handler, diagnosis_handler, health_data_handler, medication_record_handler, + medication_reminder_handler, vital_signs_daily_handler, +}; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + // 健康数据 + .route( + "/health/patients/{id}/vital-signs", + axum::routing::get(health_data_handler::list_vital_signs) + .post(health_data_handler::create_vital_signs), + ) + .route( + "/health/patients/{id}/vital-signs/{vid}", + axum::routing::put(health_data_handler::update_vital_signs) + .delete(health_data_handler::delete_vital_signs), + ) + .route( + "/health/patients/{id}/lab-reports", + axum::routing::get(health_data_handler::list_lab_reports) + .post(health_data_handler::create_lab_report), + ) + .route( + "/health/patients/{id}/lab-reports/{rid}", + axum::routing::put(health_data_handler::update_lab_report) + .delete(health_data_handler::delete_lab_report), + ) + .route( + "/health/patients/{id}/lab-reports/{rid}/review", + axum::routing::put(health_data_handler::review_lab_report), + ) + .route( + "/health/patients/{id}/health-records", + axum::routing::get(health_data_handler::list_health_records) + .post(health_data_handler::create_health_record), + ) + .route( + "/health/patients/{id}/health-records/{rid}", + axum::routing::put(health_data_handler::update_health_record) + .delete(health_data_handler::delete_health_record), + ) + .route( + "/health/patients/{id}/trends", + axum::routing::get(health_data_handler::list_trends), + ) + .route( + "/health/patients/{id}/trends/generate", + axum::routing::post(health_data_handler::generate_trend), + ) + .route( + "/health/patients/{id}/trends/{indicator}", + axum::routing::get(health_data_handler::get_indicator_timeseries), + ) + // 小程序趋势查询(通过 JWT user_id 关联 patient,无需传 patient_id) + .route( + "/health/vital-signs/trend", + axum::routing::get(health_data_handler::get_mini_trend), + ) + // 小程序今日体征摘要 + .route( + "/health/vital-signs/today", + axum::routing::get(health_data_handler::get_mini_today), + ) + // 日聚合查询 + .route( + "/health/vital-signs/daily", + axum::routing::get(vital_signs_daily_handler::get_daily_aggregations), + ) + // 日常监测 + .route( + "/health/patients/{id}/daily-monitoring", + axum::routing::get(daily_monitoring_handler::list_daily_monitoring), + ) + .route( + "/health/daily-monitoring", + axum::routing::post(daily_monitoring_handler::create_daily_monitoring), + ) + .route( + "/health/daily-monitoring/{id}", + axum::routing::get(daily_monitoring_handler::get_daily_monitoring) + .put(daily_monitoring_handler::update_daily_monitoring) + .delete(daily_monitoring_handler::delete_daily_monitoring), + ) + // 诊断记录 + .route( + "/health/patients/{id}/diagnoses", + axum::routing::get(diagnosis_handler::list_diagnoses) + .post(diagnosis_handler::create_diagnosis), + ) + .route( + "/health/diagnoses/{id}", + axum::routing::put(diagnosis_handler::update_diagnosis) + .delete(diagnosis_handler::delete_diagnosis), + ) + // 用药记录 + .route( + "/health/patients/{id}/medications", + axum::routing::get(medication_record_handler::list_medications), + ) + .route( + "/health/medications", + axum::routing::post(medication_record_handler::create_medication), + ) + .route( + "/health/medications/{id}", + axum::routing::get(medication_record_handler::get_medication) + .put(medication_record_handler::update_medication) + .delete(medication_record_handler::delete_medication), + ) + // 药物提醒 CRUD + .route( + "/health/patients/{id}/medication-reminders", + axum::routing::get(medication_reminder_handler::list_reminders), + ) + .route( + "/health/medication-reminders", + axum::routing::post(medication_reminder_handler::create_reminder), + ) + .route( + "/health/medication-reminders/{id}", + axum::routing::put(medication_reminder_handler::update_reminder) + .delete(medication_reminder_handler::delete_reminder), + ) +} diff --git a/crates/erp-health/src/routes/media.rs b/crates/erp-health/src/routes/media.rs new file mode 100644 index 0000000..b172b21 --- /dev/null +++ b/crates/erp-health/src/routes/media.rs @@ -0,0 +1,60 @@ +use axum::Router; + +use crate::handler::{banner_handler, media_handler}; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + // 媒体库 + .route( + "/health/media", + axum::routing::get(media_handler::list_media), + ) + .route( + "/health/media/upload", + axum::routing::post(media_handler::upload_media), + ) + .route( + "/health/media/batch-delete", + axum::routing::post(media_handler::batch_delete_media), + ) + .route( + "/health/media/{id}", + axum::routing::get(media_handler::get_media) + .put(media_handler::update_media) + .delete(media_handler::delete_media), + ) + .route( + "/health/media/{id}/move", + axum::routing::post(media_handler::move_media), + ) + .route( + "/health/media/{id}/crop", + axum::routing::post(media_handler::crop_media), + ) + // 媒体文件夹 + .route( + "/health/media-folders", + axum::routing::get(media_handler::list_folders).post(media_handler::create_folder), + ) + .route( + "/health/media-folders/{id}", + axum::routing::put(media_handler::update_folder).delete(media_handler::delete_folder), + ) + // 轮播图管理 + .route( + "/health/banners", + axum::routing::get(banner_handler::list_banners).post(banner_handler::create_banner), + ) + .route( + "/health/banners/sort", + axum::routing::put(banner_handler::sort_banners), + ) + .route( + "/health/banners/{id}", + axum::routing::put(banner_handler::update_banner).delete(banner_handler::delete_banner), + ) +} diff --git a/crates/erp-health/src/routes/mod.rs b/crates/erp-health/src/routes/mod.rs new file mode 100644 index 0000000..44c7885 --- /dev/null +++ b/crates/erp-health/src/routes/mod.rs @@ -0,0 +1,13 @@ +pub mod admin; +pub mod alert; +pub mod appointment; +pub mod article; +pub mod care; +pub mod consultation; +pub mod device; +pub mod follow_up; +pub mod health_data; +pub mod media; +pub mod patient; +pub mod points; +pub mod stats; diff --git a/crates/erp-health/src/routes/patient.rs b/crates/erp-health/src/routes/patient.rs new file mode 100644 index 0000000..277d6d7 --- /dev/null +++ b/crates/erp-health/src/routes/patient.rs @@ -0,0 +1,78 @@ +use axum::Router; + +use crate::handler::{family_proxy_handler, patient_handler}; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + .route( + "/health/patients", + axum::routing::get(patient_handler::list_patients) + .post(patient_handler::create_patient), + ) + .route( + "/health/patients/{id}", + axum::routing::get(patient_handler::get_patient) + .put(patient_handler::update_patient) + .delete(patient_handler::delete_patient), + ) + .route( + "/health/patients/{id}/tags", + axum::routing::post(patient_handler::manage_patient_tags), + ) + .route( + "/health/patient-tags", + axum::routing::get(patient_handler::list_tags).post(patient_handler::create_tag), + ) + .route( + "/health/patient-tags/{id}", + axum::routing::put(patient_handler::update_tag).delete(patient_handler::delete_tag), + ) + .route( + "/health/patients/{id}/health-summary", + axum::routing::get(patient_handler::get_health_summary), + ) + .route( + "/health/patients/{id}/family-members", + axum::routing::get(patient_handler::list_family_members) + .post(patient_handler::create_family_member), + ) + .route( + "/health/patients/{id}/family-members/{fid}", + axum::routing::put(patient_handler::update_family_member) + .delete(patient_handler::delete_family_member), + ) + .route( + "/health/patients/{id}/doctors", + axum::routing::post(patient_handler::assign_doctor), + ) + .route( + "/health/patients/{id}/doctors/{did}", + axum::routing::delete(patient_handler::remove_doctor), + ) + // 家庭成员健康代理 — 管理端 + .route( + "/health/patients/{patient_id}/family-members/{family_member_id}/grant-access", + axum::routing::post(family_proxy_handler::grant_family_access), + ) + .route( + "/health/patients/{patient_id}/family-members/{family_member_id}/revoke-access", + axum::routing::put(family_proxy_handler::revoke_family_access), + ) + // 家庭成员健康代理 — 患者端(小程序) + .route( + "/health/family/patients", + axum::routing::get(family_proxy_handler::list_my_family_patients), + ) + .route( + "/health/family/patients/{patient_id}/health-summary", + axum::routing::get(family_proxy_handler::get_family_health_summary), + ) + .route( + "/health/family/members/{family_member_id}/link-user", + axum::routing::post(family_proxy_handler::link_family_member_user), + ) +} diff --git a/crates/erp-health/src/routes/points.rs b/crates/erp-health/src/routes/points.rs new file mode 100644 index 0000000..3faef72 --- /dev/null +++ b/crates/erp-health/src/routes/points.rs @@ -0,0 +1,109 @@ +use axum::Router; + +use crate::handler::points_handler; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + // 积分商城 — 患者端 + .route( + "/health/points/account", + axum::routing::get(points_handler::get_my_account), + ) + .route( + "/health/points/checkin", + axum::routing::post(points_handler::daily_checkin), + ) + .route( + "/health/points/checkin/status", + axum::routing::get(points_handler::get_checkin_status), + ) + .route( + "/health/points/transactions", + axum::routing::get(points_handler::list_my_transactions), + ) + .route( + "/health/points/products", + axum::routing::get(points_handler::list_products), + ) + .route( + "/health/points/products/{id}", + axum::routing::get(points_handler::get_product), + ) + .route( + "/health/points/exchange", + axum::routing::post(points_handler::exchange_product), + ) + .route( + "/health/points/orders", + axum::routing::get(points_handler::list_my_orders), + ) + // 线下活动 — 患者端 + .route( + "/health/offline-events", + axum::routing::get(points_handler::list_offline_events), + ) + .route( + "/health/offline-events/{id}/register", + axum::routing::post(points_handler::register_event), + ) + // 积分商城 — 管理端 + .route( + "/health/points/verify", + axum::routing::post(points_handler::verify_order), + ) + .route( + "/health/admin/points/rules", + axum::routing::get(points_handler::list_rules).post(points_handler::create_rule), + ) + .route( + "/health/admin/points/rules/{id}", + axum::routing::put(points_handler::update_rule).delete(points_handler::delete_rule), + ) + .route( + "/health/admin/points/products", + axum::routing::get(points_handler::admin_list_products) + .post(points_handler::admin_create_product), + ) + .route( + "/health/admin/points/products/{id}", + axum::routing::put(points_handler::admin_update_product) + .delete(points_handler::admin_delete_product), + ) + .route( + "/health/admin/points/orders", + axum::routing::get(points_handler::admin_list_orders), + ) + // 积分账户 — 管理端按患者查询 + .route( + "/health/admin/points/patients/{patient_id}/account", + axum::routing::get(points_handler::admin_get_patient_account), + ) + .route( + "/health/admin/points/patients/{patient_id}/transactions", + axum::routing::get(points_handler::admin_list_patient_transactions), + ) + // 线下活动 — 管理端 + .route( + "/health/admin/offline-events", + axum::routing::get(points_handler::admin_list_events) + .post(points_handler::admin_create_event), + ) + .route( + "/health/admin/offline-events/{id}", + axum::routing::put(points_handler::admin_update_event) + .delete(points_handler::admin_delete_event), + ) + .route( + "/health/admin/offline-events/{id}/checkin", + axum::routing::post(points_handler::admin_checkin_event), + ) + // 积分统计 — 管理端 + .route( + "/health/admin/points/statistics", + axum::routing::get(points_handler::get_points_statistics), + ) +} diff --git a/crates/erp-health/src/routes/stats.rs b/crates/erp-health/src/routes/stats.rs new file mode 100644 index 0000000..1a76368 --- /dev/null +++ b/crates/erp-health/src/routes/stats.rs @@ -0,0 +1,68 @@ +use axum::Router; + +use crate::handler::stats_handler; + +pub fn routes() -> Router +where + crate::state::HealthState: axum::extract::FromRef, + S: Clone + Send + Sync + 'static, +{ + Router::new() + .route( + "/health/admin/statistics/patients", + axum::routing::get(stats_handler::get_patient_stats), + ) + .route( + "/health/admin/statistics/consultations", + axum::routing::get(stats_handler::get_consultation_stats), + ) + .route( + "/health/admin/statistics/follow-ups", + axum::routing::get(stats_handler::get_follow_up_stats), + ) + .route( + "/health/admin/statistics/dashboard", + axum::routing::get(stats_handler::get_dashboard_stats), + ) + .route( + "/health/admin/statistics/lab-reports", + axum::routing::get(stats_handler::get_lab_report_stats), + ) + .route( + "/health/admin/statistics/appointments", + axum::routing::get(stats_handler::get_appointment_stats), + ) + .route( + "/health/admin/statistics/vital-signs-report-rate", + axum::routing::get(stats_handler::get_vital_signs_report_rate), + ) + .route( + "/health/admin/statistics/health-data", + axum::routing::get(stats_handler::get_health_data_stats), + ) + .route( + "/health/admin/statistics/personal-stats", + axum::routing::get(stats_handler::get_personal_stats), + ) + // 工作台管理统计 API + .route( + "/health/admin/system-health", + axum::routing::get(stats_handler::get_system_health), + ) + .route( + "/health/admin/user-activity", + axum::routing::get(stats_handler::get_user_activity), + ) + .route( + "/health/admin/modules", + axum::routing::get(stats_handler::get_module_status), + ) + .route( + "/health/points/recent-activity", + axum::routing::get(stats_handler::get_points_recent_activity), + ) + .route( + "/health/articles/stats", + axum::routing::get(stats_handler::get_article_stats), + ) +}