Files
hms/crates/erp-health/src/handler/ble_gateway_handler.rs
iven d70b027f20 fix(health): 全 handler page_size 上限 100 防止 DoS
22 个 handler 文件统一添加 .min(100) 限制分页大小
2026-05-21 22:38:29 +08:00

231 lines
7.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use axum::Extension;
use axum::extract::{FromRef, Json, Path, Query, State};
use erp_core::error::AppError;
use erp_core::rbac::require_permission;
use erp_core::types::{ApiResponse, TenantContext};
use uuid::Uuid;
use crate::dto::DeleteWithVersion;
use crate::dto::ble_gateway_dto::*;
use crate::gateway_auth::GatewayAuthContext;
use crate::service::ble_gateway_service;
use crate::state::HealthState;
// ---------------------------------------------------------------------------
// Gateway 管理(需要用户 JWT 认证)
// ---------------------------------------------------------------------------
pub async fn list_gateways<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
Query(params): Query<ListBleGatewaysParams>,
) -> Result<Json<ApiResponse<erp_core::types::PaginatedResponse<BleGatewayResp>>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.ble-gateways.list")?;
let result = ble_gateway_service::list_gateways(&state, ctx.tenant_id, &params).await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn get_gateway<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
Path(gateway_id): Path<Uuid>,
) -> Result<Json<ApiResponse<BleGatewayResp>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.ble-gateways.list")?;
let result = ble_gateway_service::get_gateway(&state, ctx.tenant_id, gateway_id).await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn create_gateway<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
Json(body): Json<CreateBleGatewayReq>,
) -> Result<Json<ApiResponse<BleGatewayResp>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.ble-gateways.manage")?;
let result =
ble_gateway_service::create_gateway(&state, ctx.tenant_id, Some(ctx.user_id), body).await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn update_gateway<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
Path(gateway_id): Path<Uuid>,
Json(body): Json<UpdateBleGatewayWithVersion>,
) -> Result<Json<ApiResponse<BleGatewayResp>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.ble-gateways.manage")?;
let result = ble_gateway_service::update_gateway(
&state,
ctx.tenant_id,
gateway_id,
Some(ctx.user_id),
body,
)
.await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn delete_gateway<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
Path(gateway_id): Path<Uuid>,
Query(params): Query<DeleteWithVersion>,
) -> Result<Json<ApiResponse<()>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.ble-gateways.manage")?;
ble_gateway_service::delete_gateway(
&state,
ctx.tenant_id,
gateway_id,
Some(ctx.user_id),
params.version,
)
.await?;
Ok(Json(ApiResponse::ok(())))
}
pub async fn regenerate_api_key<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
Path(gateway_id): Path<Uuid>,
) -> Result<Json<ApiResponse<BleGatewayResp>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.ble-gateways.manage")?;
let result = ble_gateway_service::regenerate_api_key(
&state,
ctx.tenant_id,
gateway_id,
Some(ctx.user_id),
)
.await?;
Ok(Json(ApiResponse::ok(result)))
}
// ---------------------------------------------------------------------------
// Binding 管理(需要用户 JWT 认证)
// ---------------------------------------------------------------------------
pub async fn list_bindings<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
Path(gateway_id): Path<Uuid>,
Query(params): Query<crate::handler::shift_handler::PaginationParams>,
) -> Result<Json<ApiResponse<erp_core::types::PaginatedResponse<GatewayBindingResp>>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.ble-gateways.list")?;
let page = params.page.unwrap_or(1);
let page_size = params.page_size.unwrap_or(20).min(100);
let result =
ble_gateway_service::list_bindings(&state, ctx.tenant_id, gateway_id, page, page_size)
.await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn bind_patient<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
Path(gateway_id): Path<Uuid>,
Json(body): Json<CreateBindingReq>,
) -> Result<Json<ApiResponse<GatewayBindingResp>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.ble-gateways.manage")?;
let result = ble_gateway_service::bind_patient(
&state,
ctx.tenant_id,
gateway_id,
Some(ctx.user_id),
body,
)
.await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn batch_bind<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
Path(gateway_id): Path<Uuid>,
Json(body): Json<BatchBindReq>,
) -> Result<Json<ApiResponse<Vec<GatewayBindingResp>>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.ble-gateways.manage")?;
let result =
ble_gateway_service::batch_bind(&state, ctx.tenant_id, gateway_id, Some(ctx.user_id), body)
.await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn unbind_patient<S>(
State(state): State<HealthState>,
Extension(ctx): Extension<TenantContext>,
Path((gateway_id, binding_id)): Path<(Uuid, Uuid)>,
Query(params): Query<DeleteWithVersion>,
) -> Result<Json<ApiResponse<()>>, AppError>
where
HealthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "health.ble-gateways.manage")?;
ble_gateway_service::unbind_patient(
&state,
ctx.tenant_id,
gateway_id,
binding_id,
Some(ctx.user_id),
params.version,
)
.await?;
Ok(Json(ApiResponse::ok(())))
}
// ---------------------------------------------------------------------------
// 网关端点API Key 认证,无需用户 JWT
// ---------------------------------------------------------------------------
pub async fn gateway_upload(
State(state): State<HealthState>,
Extension(ctx): Extension<GatewayAuthContext>,
Json(body): Json<GatewayUploadReq>,
) -> Result<Json<ApiResponse<GatewayUploadResp>>, AppError> {
let result = ble_gateway_service::gateway_upload(&state, &ctx, body).await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn gateway_heartbeat(
State(state): State<HealthState>,
Extension(ctx): Extension<GatewayAuthContext>,
Json(body): Json<HeartbeatReq>,
) -> Result<Json<ApiResponse<()>>, AppError> {
ble_gateway_service::heartbeat(&state, &ctx, body).await?;
Ok(Json(ApiResponse::ok(())))
}