- 新增 ble_gateways + gateway_patient_bindings 表迁移 (000113) - 网关 CRUD:注册/编辑/删除/重生成 API Key,含患者绑定管理 - API Key 认证中间件(SHA-256 hash + prefix 快速查找) - 网关数据上报端点:多患者批量读数,复用 device_reading_service 管道 - 网关心跳端点:固件版本/IP 更新 + last_heartbeat_at - 10 个管理端路由(JWT)+ 2 个网关端路由(API Key) - health.ble-gateways.list/manage 权限声明 - 修复 000112 迁移 ForeignKey 借用错误
142 lines
4.0 KiB
Rust
142 lines
4.0 KiB
Rust
use serde::{Deserialize, Serialize};
|
||
use uuid::Uuid;
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// BLE Gateway DTOs
|
||
// ---------------------------------------------------------------------------
|
||
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct BleGatewayResp {
|
||
pub id: Uuid,
|
||
pub tenant_id: Uuid,
|
||
pub gateway_id: String,
|
||
pub name: String,
|
||
pub status: String,
|
||
pub firmware_version: Option<String>,
|
||
pub ip_address: Option<String>,
|
||
pub last_heartbeat_at: Option<chrono::DateTime<chrono::Utc>>,
|
||
pub metadata: Option<serde_json::Value>,
|
||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||
pub version: i32,
|
||
/// 网关 API Key(仅在创建时返回一次)
|
||
pub api_key: Option<String>,
|
||
/// 绑定的患者数量
|
||
pub patient_count: Option<i64>,
|
||
}
|
||
|
||
#[derive(Debug, Clone, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct CreateBleGatewayReq {
|
||
pub gateway_id: String,
|
||
pub name: String,
|
||
pub firmware_version: Option<String>,
|
||
pub metadata: Option<serde_json::Value>,
|
||
}
|
||
|
||
#[derive(Debug, Clone, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct UpdateBleGatewayReq {
|
||
pub name: Option<String>,
|
||
pub status: Option<String>,
|
||
pub firmware_version: Option<String>,
|
||
pub metadata: Option<serde_json::Value>,
|
||
}
|
||
|
||
#[derive(Debug, Clone, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct UpdateBleGatewayWithVersion {
|
||
pub version: i32,
|
||
pub data: UpdateBleGatewayReq,
|
||
}
|
||
|
||
#[derive(Debug, Clone, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct ListBleGatewaysParams {
|
||
pub status: Option<String>,
|
||
pub page: Option<u64>,
|
||
pub page_size: Option<u64>,
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// GatewayPatientBinding DTOs
|
||
// ---------------------------------------------------------------------------
|
||
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct GatewayBindingResp {
|
||
pub id: Uuid,
|
||
pub tenant_id: Uuid,
|
||
pub gateway_id_fk: Uuid,
|
||
pub patient_id: Uuid,
|
||
pub peripheral_mac: Option<String>,
|
||
pub device_type: Option<String>,
|
||
pub status: String,
|
||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||
pub version: i32,
|
||
}
|
||
|
||
#[derive(Debug, Clone, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct CreateBindingReq {
|
||
pub patient_id: Uuid,
|
||
pub peripheral_mac: Option<String>,
|
||
pub device_type: Option<String>,
|
||
}
|
||
|
||
#[derive(Debug, Clone, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct BatchBindReq {
|
||
pub bindings: Vec<CreateBindingReq>,
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// 网关数据上报 DTOs
|
||
// ---------------------------------------------------------------------------
|
||
|
||
/// 网关多患者批量上报请求
|
||
#[derive(Debug, Clone, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct GatewayUploadReq {
|
||
pub readings: Vec<PatientReadingBatch>,
|
||
}
|
||
|
||
/// 单个患者的读数批次
|
||
#[derive(Debug, Clone, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct PatientReadingBatch {
|
||
pub patient_id: Uuid,
|
||
pub device_id: String,
|
||
pub device_model: Option<String>,
|
||
pub readings: Vec<ReadingEntry>,
|
||
}
|
||
|
||
/// 单条读数
|
||
#[derive(Debug, Clone, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct ReadingEntry {
|
||
pub device_type: String,
|
||
pub values: serde_json::Value,
|
||
pub measured_at: String,
|
||
}
|
||
|
||
/// 网关上报结果
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct GatewayUploadResp {
|
||
pub total_patients: u64,
|
||
pub total_readings: u64,
|
||
pub total_duplicates: u64,
|
||
pub errors: Vec<String>,
|
||
}
|
||
|
||
/// 网关心跳请求
|
||
#[derive(Debug, Clone, Deserialize)]
|
||
#[serde(rename_all = "camelCase")]
|
||
pub struct HeartbeatReq {
|
||
pub firmware_version: Option<String>,
|
||
pub ip_address: Option<String>,
|
||
}
|