2026-06-06 08:38:19 +08:00
|
|
|
|
"""
|
|
|
|
|
|
API 请求/响应数据模型
|
|
|
|
|
|
"""
|
2026-06-06 13:18:25 +08:00
|
|
|
|
from datetime import datetime
|
2026-06-14 16:41:31 +08:00
|
|
|
|
from typing import List, Optional, Dict, Any
|
2026-06-28 09:26:13 +08:00
|
|
|
|
from pydantic import BaseModel, Field, model_validator
|
2026-06-06 08:38:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ============================================================
|
|
|
|
|
|
# 暴雨预测
|
|
|
|
|
|
# ============================================================
|
|
|
|
|
|
|
|
|
|
|
|
class RainfallPredictRequest(BaseModel):
|
2026-06-28 09:26:13 +08:00
|
|
|
|
"""
|
|
|
|
|
|
暴雨灾害链预测请求
|
|
|
|
|
|
|
|
|
|
|
|
参数规则(二选一):
|
|
|
|
|
|
1. 自动推演模式:rainfall、duration、region_code 全部不传 → 从气象表自动获取,不限区域
|
|
|
|
|
|
2. 指定条件模式:rainfall、duration、region_code 全部传入 → 按指定条件预测
|
|
|
|
|
|
"""
|
2026-06-14 14:38:20 +08:00
|
|
|
|
disaster_name: str = Field(min_length=1, max_length=255)
|
2026-06-06 08:38:19 +08:00
|
|
|
|
point_ids: Optional[List[int]] = Field(None, max_length=500,
|
|
|
|
|
|
description="点位ID列表,不传则查询所有点")
|
2026-06-28 09:26:13 +08:00
|
|
|
|
region_code: Optional[str] = Field(None, description="行政区划代码(如 '610104')")
|
|
|
|
|
|
rainfall: Optional[float] = Field(None, ge=0, description="累计降雨量(mm)")
|
|
|
|
|
|
duration: Optional[float] = Field(None, ge=0, description="降雨持续时间(h)")
|
2026-06-14 16:29:01 +08:00
|
|
|
|
occurred_time: Optional[datetime] = Field(None, description="事件发生时间,不传则为当前时间")
|
2026-06-06 13:18:25 +08:00
|
|
|
|
operation_type: str = Field("模拟", min_length=1, max_length=50,
|
|
|
|
|
|
description="操作类型(如 '模拟', '实时监测', '应急评估')")
|
2026-06-06 08:38:19 +08:00
|
|
|
|
|
2026-06-28 09:26:13 +08:00
|
|
|
|
@model_validator(mode='after')
|
|
|
|
|
|
def validate_mode_exclusivity(self):
|
|
|
|
|
|
"""校验 rainfall / duration / region_code 必须要么全不传,要么全传"""
|
|
|
|
|
|
trio = (self.rainfall, self.duration, self.region_code)
|
|
|
|
|
|
none_count = sum(1 for v in trio if v is None)
|
|
|
|
|
|
if none_count not in (0, 3):
|
|
|
|
|
|
raise ValueError(
|
|
|
|
|
|
"rainfall、duration、region_code 必须全部传入或全部不传,"
|
|
|
|
|
|
"不允许只传部分参数"
|
|
|
|
|
|
)
|
|
|
|
|
|
return self
|
|
|
|
|
|
|
2026-06-06 08:38:19 +08:00
|
|
|
|
|
|
|
|
|
|
# ============================================================
|
|
|
|
|
|
# 地震预测
|
|
|
|
|
|
# ============================================================
|
|
|
|
|
|
|
|
|
|
|
|
class EarthquakePredictRequest(BaseModel):
|
|
|
|
|
|
"""地震灾害链预测请求"""
|
2026-06-14 14:38:20 +08:00
|
|
|
|
disaster_name: str = Field(min_length=1, max_length=255)
|
2026-06-06 08:38:19 +08:00
|
|
|
|
point_ids: Optional[List[int]] = Field(None, max_length=500,
|
|
|
|
|
|
description="点位ID列表,不传则查询所有点")
|
|
|
|
|
|
region_code: Optional[str] = Field(None, description="行政区划代码(如 '610104'),不传则不限区域")
|
|
|
|
|
|
magnitude: float = Field(..., ge=0, le=10, description="震级(Richter)")
|
|
|
|
|
|
depth: float = Field(10.0, gt=0, le=700, description="震源深度(km),默认10km")
|
|
|
|
|
|
epicenter_lon: float = Field(..., ge=-180, le=180, description="震中经度")
|
|
|
|
|
|
epicenter_lat: float = Field(..., ge=-90, le=90, description="震中纬度")
|
2026-06-14 16:29:01 +08:00
|
|
|
|
occurred_time: Optional[datetime] = Field(None, description="地震发生时间,不传则为当前时间")
|
2026-06-06 13:18:25 +08:00
|
|
|
|
operation_type: str = Field("模拟", min_length=1, max_length=50,
|
|
|
|
|
|
description="操作类型(如 '模拟', '实时监测', '应急评估')")
|
2026-06-19 17:04:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ============================================================
|
|
|
|
|
|
# 专题图产出
|
|
|
|
|
|
# ============================================================
|
|
|
|
|
|
class QgisMapExportRequest(BaseModel):
|
|
|
|
|
|
"""专题图导出请求"""
|
|
|
|
|
|
inferenceId: int = Field(..., description="推理结果ID(xian_inference_result.id)")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class QgisMapExportResponse(BaseModel):
|
|
|
|
|
|
"""专题图导出响应"""
|
|
|
|
|
|
code: int = Field(200, description="状态码")
|
|
|
|
|
|
message: str = Field("success", description="提示信息")
|
|
|
|
|
|
data: Optional[str] = Field(None, description="导出图片的访问路径")
|
2026-06-06 08:38:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ============================================================
|
|
|
|
|
|
# 通用响应
|
|
|
|
|
|
# ============================================================
|
|
|
|
|
|
|
2026-06-14 16:00:33 +08:00
|
|
|
|
class PredictData(BaseModel):
|
|
|
|
|
|
"""预测数据"""
|
|
|
|
|
|
record_id: Optional[int] = Field(None, description="推理结果记录ID")
|
2026-06-14 16:41:31 +08:00
|
|
|
|
list: Dict[str, Dict[str, Any]] = Field(default_factory=dict, description="预测结果列表,包含概率和经纬度")
|
2026-06-06 08:38:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PredictResponse(BaseModel):
|
|
|
|
|
|
"""预测响应"""
|
|
|
|
|
|
code: int = Field(200, description="状态码")
|
|
|
|
|
|
message: str = Field("success", description="提示信息")
|
2026-06-14 16:00:33 +08:00
|
|
|
|
data: Optional[PredictData] = Field(None, description="预测数据")
|
2026-06-06 08:38:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
2026-06-12 16:09:57 +08:00
|
|
|
|
class UpdateMonitoringTimeRequest(BaseModel):
|
|
|
|
|
|
"""更新监测时间请求"""
|
|
|
|
|
|
query_time: str = Field(..., description="查询时间,格式: YYYY-MM-DD HH:mm:ss,如 '2025-09-16 20:00:00'")
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-06-06 08:38:19 +08:00
|
|
|
|
class HealthResponse(BaseModel):
|
|
|
|
|
|
"""健康检查响应"""
|
|
|
|
|
|
status: str = "ok"
|
|
|
|
|
|
rainfall_model_loaded: bool = False
|
|
|
|
|
|
earthquake_model_loaded: bool = False
|
2026-06-28 09:26:13 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ============================================================
|
|
|
|
|
|
# 各区降雨概况
|
|
|
|
|
|
# ============================================================
|
|
|
|
|
|
|
|
|
|
|
|
class DistrictSummaryRequest(BaseModel):
|
|
|
|
|
|
"""各区降雨概况请求"""
|
|
|
|
|
|
inference_id: int = Field(..., ge=1, description="推理结果ID(xian_inference_result.id)")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DistrictSummaryItem(BaseModel):
|
|
|
|
|
|
"""单个区的降雨概况"""
|
|
|
|
|
|
district_name: str = Field(..., description="行政区名称(如 '碑林区')")
|
|
|
|
|
|
district_code: str = Field(..., description="行政区划代码(如 '610103')")
|
|
|
|
|
|
rainfall: float = Field(..., description="累计降雨量(mm)")
|
|
|
|
|
|
duration_hours: float = Field(..., description="持续降雨时间(h)")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DistrictSummaryResponse(BaseModel):
|
|
|
|
|
|
"""各区降雨概况响应"""
|
|
|
|
|
|
code: int = Field(200, description="状态码")
|
|
|
|
|
|
message: str = Field("success", description="提示信息")
|
|
|
|
|
|
data: Optional[List[DistrictSummaryItem]] = Field(None, description="各区降雨概况列表")
|