diff --git a/crates/erp-health/src/error.rs b/crates/erp-health/src/error.rs index fa0d751..4e41797 100644 --- a/crates/erp-health/src/error.rs +++ b/crates/erp-health/src/error.rs @@ -107,6 +107,9 @@ pub enum HealthError { #[error("媒体文件夹不存在")] MediaFolderNotFound, + #[error("轮播图不存在")] + BannerNotFound, + #[error("状态转换无效: {0}")] InvalidStatusTransition(String), @@ -157,7 +160,8 @@ impl From for AppError { | HealthError::PatientAssignmentNotFound | HealthError::HandoffLogNotFound | HealthError::MediaNotFound - | HealthError::MediaFolderNotFound => AppError::NotFound(err.to_string()), + | HealthError::MediaFolderNotFound + | HealthError::BannerNotFound => AppError::NotFound(err.to_string()), HealthError::ScheduleFull => AppError::Validation(err.to_string()), HealthError::InvalidStatusTransition(s) => AppError::Validation(s), HealthError::VersionMismatch => AppError::VersionMismatch, diff --git a/crates/erp-health/src/handler/banner_handler.rs b/crates/erp-health/src/handler/banner_handler.rs index d8786f3..9f418cd 100644 --- a/crates/erp-health/src/handler/banner_handler.rs +++ b/crates/erp-health/src/handler/banner_handler.rs @@ -49,6 +49,21 @@ where Ok(Json(ApiResponse::ok(result))) } +/// GET /health/banners/{id} — 获取单个轮播图 +pub async fn get_banner( + State(state): State, + Extension(ctx): Extension, + Path(id): Path, +) -> Result>, AppError> +where + HealthState: FromRef, + S: Clone + Send + Sync + 'static, +{ + require_permission(&ctx, "health.banners.list")?; + let result = banner_service::get_banner(&state, ctx.tenant_id, id).await?; + Ok(Json(ApiResponse::ok(result))) +} + /// POST /health/banners — 创建轮播图 pub async fn create_banner( State(state): State, diff --git a/crates/erp-health/src/routes/media.rs b/crates/erp-health/src/routes/media.rs index b172b21..f6c9518 100644 --- a/crates/erp-health/src/routes/media.rs +++ b/crates/erp-health/src/routes/media.rs @@ -55,6 +55,8 @@ where ) .route( "/health/banners/{id}", - axum::routing::put(banner_handler::update_banner).delete(banner_handler::delete_banner), + axum::routing::get(banner_handler::get_banner) + .put(banner_handler::update_banner) + .delete(banner_handler::delete_banner), ) } diff --git a/crates/erp-health/src/service/banner_service.rs b/crates/erp-health/src/service/banner_service.rs index a77d8e5..4261b9e 100644 --- a/crates/erp-health/src/service/banner_service.rs +++ b/crates/erp-health/src/service/banner_service.rs @@ -62,6 +62,23 @@ pub async fn list_banners( Ok(result) } +/// 获取单个轮播图 +pub async fn get_banner( + state: &HealthState, + tenant_id: Uuid, + banner_id: Uuid, +) -> HealthResult { + let b = banner::Entity::find_by_id(banner_id) + .filter(banner::Column::TenantId.eq(tenant_id)) + .filter(banner::Column::DeletedAt.is_null()) + .one(&state.db) + .await? + .ok_or(HealthError::BannerNotFound)?; + + let media_map = load_media_map(state, &[b.media_item_id]).await?; + Ok(banner_to_resp(&b, &media_map)) +} + /// 创建轮播图 pub async fn create_banner( state: &HealthState,