339 lines
16 KiB
Python
339 lines
16 KiB
Python
"""
|
||
models.py
|
||
数据模型模块:使用 Pydantic 定义请求/响应的数据结构。
|
||
FastAPI 会自动用这些模型做参数校验和文档生成。
|
||
"""
|
||
|
||
from pydantic import BaseModel, Field
|
||
from typing import Optional, List
|
||
from datetime import datetime
|
||
|
||
|
||
# ═══════════════════════════════════════════════════════════════
|
||
# 设备相关模型
|
||
# ═══════════════════════════════════════════════════════════════
|
||
|
||
class DeviceCheckRequest(BaseModel):
|
||
"""设备校验请求:APP 启动时携带 SN 进行合法性校验"""
|
||
sn: str = Field(..., min_length=5, description="设备序列号,如 GD30-20260507-001")
|
||
|
||
|
||
class LicenseGenerateRequest(BaseModel):
|
||
"""生成授权文件请求:管理后台为某台设备创建授权"""
|
||
sn: str = Field(..., description="目标设备 SN")
|
||
modules: List[str] = Field(default=[], description="激活的模块列表,如 ['1D', '2D']")
|
||
valid_days: int = Field(default=365, ge=1, le=3650, description="授权有效期(天),默认一年")
|
||
config_id: Optional[int] = Field(None, description="关联的配置文件 ID,授权文件中会嵌入该配置")
|
||
|
||
|
||
class ActivateReportRequest(BaseModel):
|
||
"""上报激活状态请求:设备主机首次联网后回传激活结果"""
|
||
sn: str = Field(..., description="设备序列号")
|
||
status: str = Field(..., pattern="^(已激活|激活失败)$", description="上报状态:已激活 或 激活失败")
|
||
|
||
|
||
class DeviceInfo(BaseModel):
|
||
"""设备信息响应"""
|
||
sn: str
|
||
status: str
|
||
activated_at: Optional[str] = None
|
||
created_at: str
|
||
|
||
|
||
class CheckResponse(BaseModel):
|
||
"""设备校验响应:告诉 APP 这台设备是否合法、是否已激活"""
|
||
valid: bool = Field(..., description="SN 是否存在于平台")
|
||
activated: bool = Field(..., description="是否已激活")
|
||
message: str = Field(..., description="给 APP 的提示信息")
|
||
|
||
|
||
class LicenseData(BaseModel):
|
||
"""授权文件内的业务数据结构(未加密前)"""
|
||
version: str = Field(default="1.0", description="授权文件版本")
|
||
device_sn: str = Field(..., description="绑定的设备 SN")
|
||
generated_at: str = Field(..., description="生成时间 ISO8601")
|
||
valid_until: str = Field(..., description="有效期截止时间")
|
||
modules: List[str] = Field(default=[], description="授权模块列表")
|
||
status: str = Field(default="active", description="授权状态")
|
||
|
||
|
||
class LicenseResponse(BaseModel):
|
||
"""生成授权文件响应:返回加密后的授权文件字符串"""
|
||
success: bool
|
||
encrypted_license: Optional[str] = Field(None, description="Base64 编码的加密授权文件")
|
||
raw_license: Optional[dict] = Field(None, description="明文授权文件(仅调试用,生产环境可去掉)")
|
||
message: str
|
||
|
||
|
||
class ActivateResponse(BaseModel):
|
||
"""上报激活状态响应"""
|
||
success: bool
|
||
sn: str
|
||
new_status: str
|
||
activated_at: Optional[str] = None
|
||
message: str
|
||
|
||
|
||
# ═══════════════════════════════════════════════════════════════
|
||
# 配置文件相关模型
|
||
# ═══════════════════════════════════════════════════════════════
|
||
|
||
class ConfigFileCreateRequest(BaseModel):
|
||
"""创建配置文件请求"""
|
||
name: str = Field(..., description="配置名称,如 GD30-2024-标准参数")
|
||
model: str = Field(..., description="适用设备型号,如 GD30-2024")
|
||
version: str = Field(default="v1.0", description="配置版本号")
|
||
status: str = Field(default="生效", description="状态:生效/失效")
|
||
# 发射参数
|
||
max_tx_voltage: Optional[str] = Field(None, description="最大发射电压,如 1200V / 1500V")
|
||
max_tx_current: Optional[str] = Field(None, description="最大发射电流,如 6A / 10A")
|
||
tx_waveform: Optional[str] = Field(None, description="发射波形,如 0+0- / +0-0 / +-")
|
||
tx_pulse_width: Optional[str] = Field(None, description="发射脉宽,如 0.25s/0.5s/1s/2s/4s/8s/16s")
|
||
# 采集参数
|
||
acq_channels: Optional[str] = Field(None, description="支持通道数,如 1 / 6 / 12")
|
||
acq_sample_rate: Optional[str] = Field(None, description="采样率,如 50Hz/60Hz/100Hz/1000Hz")
|
||
acq_voltage_range: Optional[str] = Field(None, description="电压测量量程,如 ±2.5V/±80V / ±80V/±600V")
|
||
full_waveform_capture: Optional[str] = Field(None, description="全波形采集,如 支持 / 不支持")
|
||
# 网络参数
|
||
ssid_prefix: Optional[str] = Field(None, description="WiFi SSID前缀,如 GD30-AP")
|
||
|
||
|
||
class ConfigFileUpdateRequest(BaseModel):
|
||
"""更新配置文件请求"""
|
||
name: Optional[str] = Field(None, description="配置名称")
|
||
model: Optional[str] = Field(None, description="适用设备型号")
|
||
version: Optional[str] = Field(None, description="配置版本号")
|
||
status: Optional[str] = Field(None, description="状态:生效/失效")
|
||
# 发射参数
|
||
max_tx_voltage: Optional[str] = Field(None, description="最大发射电压")
|
||
max_tx_current: Optional[str] = Field(None, description="最大发射电流")
|
||
tx_waveform: Optional[str] = Field(None, description="发射波形")
|
||
tx_pulse_width: Optional[str] = Field(None, description="发射脉宽")
|
||
# 采集参数
|
||
acq_channels: Optional[str] = Field(None, description="支持通道数")
|
||
acq_sample_rate: Optional[str] = Field(None, description="采样率")
|
||
acq_voltage_range: Optional[str] = Field(None, description="电压测量量程")
|
||
full_waveform_capture: Optional[str] = Field(None, description="全波形采集")
|
||
# 网络参数
|
||
ssid_prefix: Optional[str] = Field(None, description="WiFi SSID前缀")
|
||
|
||
|
||
class ConfigFileInfo(BaseModel):
|
||
"""配置文件信息响应"""
|
||
id: int
|
||
name: str
|
||
model: str
|
||
version: str
|
||
status: str
|
||
# 发射参数
|
||
max_tx_voltage: Optional[str] = None
|
||
max_tx_current: Optional[str] = None
|
||
tx_waveform: Optional[str] = None
|
||
tx_pulse_width: Optional[str] = None
|
||
# 采集参数
|
||
acq_channels: Optional[str] = None
|
||
acq_sample_rate: Optional[str] = None
|
||
acq_voltage_range: Optional[str] = None
|
||
full_waveform_capture: Optional[str] = None
|
||
# 网络参数
|
||
ssid_prefix: Optional[str] = None
|
||
created_at: Optional[str] = None
|
||
updated_at: Optional[str] = None
|
||
|
||
|
||
# ═══════════════════════════════════════════════════════════════
|
||
# 校准文件相关模型
|
||
# ═══════════════════════════════════════════════════════════════
|
||
|
||
class CalibChannelData(BaseModel):
|
||
"""校准通道数据"""
|
||
ChannelId: int = Field(..., description="通道ID")
|
||
factor_80v: float = Field(..., description="80V量程校准系数")
|
||
offset_80v: float = Field(..., description="80V量程偏移量")
|
||
factor_2_5v: float = Field(..., description="2.5V量程校准系数")
|
||
offset_2_5v: float = Field(..., description="2.5V量程偏移量")
|
||
|
||
|
||
class CalibrationUploadRequest(BaseModel):
|
||
"""校准文件上传请求(JSON格式,由Windows校准软件调用)"""
|
||
SN: str = Field(..., description="校准文件中的SN")
|
||
UID: str = Field(..., description="校准文件中的UID")
|
||
CalibrateFactor: List[dict] = Field(..., description="各通道校准系数数组")
|
||
|
||
|
||
class CalibrationFileInfo(BaseModel):
|
||
"""校准文件信息响应"""
|
||
id: int
|
||
material_sn: str = Field(..., description="关联物料SN")
|
||
sn: Optional[str] = Field(None, description="校准SN")
|
||
uid: Optional[str] = Field(None, description="校准UID")
|
||
file_name: Optional[str] = Field(None, description="文件名")
|
||
file_size: Optional[int] = Field(None, description="文件大小(字节)")
|
||
md5: Optional[str] = Field(None, description="文件MD5")
|
||
result: Optional[str] = Field(None, description="校准结果:合格/不合格")
|
||
operator: Optional[str] = Field(None, description="操作员")
|
||
remark: Optional[str] = Field(None, description="备注")
|
||
upload_time: Optional[str] = Field(None, description="上传时间")
|
||
channels_count: Optional[int] = Field(None, description="通道数量")
|
||
channels: Optional[List[dict]] = Field(None, description="通道详细数据")
|
||
|
||
|
||
class CalibrationUpdateRequest(BaseModel):
|
||
"""校准文件更新请求"""
|
||
operator: Optional[str] = Field(None, description="操作员")
|
||
remark: Optional[str] = Field(None, description="备注")
|
||
result: Optional[str] = Field(None, description="校准结果")
|
||
|
||
|
||
# ═══════════════════════════════════════════════════════════════
|
||
# APP 版本相关模型
|
||
# ═══════════════════════════════════════════════════════════════
|
||
|
||
class AppVersionCreateRequest(BaseModel):
|
||
"""创建 APP 版本请求"""
|
||
app_name: str = Field(..., description="应用名称,如 GeoData Mobile")
|
||
package_name: Optional[str] = Field(None, description="包名,如 com.geomative.geodata")
|
||
platform_type: int = Field(default=2, description="平台类型:1=iOS, 2=Android")
|
||
version_name: str = Field(..., description="版本号名称,如 1.2.0")
|
||
major_version: int = Field(default=1, ge=0)
|
||
minor_version: int = Field(default=0, ge=0)
|
||
patch_version: int = Field(default=0, ge=0)
|
||
file_type: str = Field(default="apk", description="文件类型:apk / ipa")
|
||
distribution_type: str = Field(default="direct", description="分发方式:direct / appstore")
|
||
os_min_version: Optional[str] = Field(None, description="最低系统版本要求")
|
||
is_force_update: bool = Field(default=False, description="是否强制更新")
|
||
changelog: Optional[List[str]] = Field(None, description="更新日志列表")
|
||
status: int = Field(default=1, description="状态:0=草稿, 1=已发布, 2=已下架")
|
||
|
||
|
||
class AppVersionUpdateRequest(BaseModel):
|
||
"""更新 APP 版本请求"""
|
||
app_name: Optional[str] = Field(None, description="应用名称")
|
||
package_name: Optional[str] = Field(None, description="包名")
|
||
version_name: Optional[str] = Field(None, description="版本号")
|
||
platform_type: Optional[int] = Field(None, description="平台类型")
|
||
os_min_version: Optional[str] = Field(None, description="最低系统版本")
|
||
is_force_update: Optional[bool] = Field(None, description="是否强制更新")
|
||
changelog: Optional[List[str]] = Field(None, description="更新日志")
|
||
status: Optional[int] = Field(None, description="状态:0=草稿, 1=已发布, 2=已下架")
|
||
|
||
|
||
class AppVersionInfo(BaseModel):
|
||
"""APP 版本信息响应"""
|
||
id: int
|
||
app_name: str
|
||
package_name: Optional[str] = None
|
||
platform_type: int
|
||
version_name: str
|
||
major_version: int
|
||
minor_version: int
|
||
patch_version: int
|
||
file_name: Optional[str] = None
|
||
file_size: Optional[int] = None
|
||
file_type: Optional[str] = None
|
||
distribution_type: Optional[str] = None
|
||
primary_url: Optional[str] = None
|
||
os_min_version: Optional[str] = None
|
||
is_force_update: bool = False
|
||
changelog: Optional[str] = None
|
||
status: int
|
||
created_at: Optional[str] = None
|
||
updated_at: Optional[str] = None
|
||
|
||
|
||
class AppDownloadQuery(BaseModel):
|
||
"""APP 下载查询参数"""
|
||
app_name: Optional[str] = Field(None, description="应用名称")
|
||
platform_type: Optional[int] = Field(None, description="平台类型:1=iOS, 2=Android")
|
||
version_name: Optional[str] = Field(None, description="指定版本号")
|
||
|
||
|
||
class AppCheckUpdateRequest(BaseModel):
|
||
"""APP 检查更新请求"""
|
||
app_name: str = Field(..., description="应用名称")
|
||
platform_type: int = Field(..., description="平台类型:1=iOS, 2=Android")
|
||
current_version: str = Field(..., description="当前版本号,如 1.1.0")
|
||
|
||
|
||
class AppCheckUpdateResponse(BaseModel):
|
||
"""APP 检查更新响应"""
|
||
has_update: bool = Field(..., description="是否有更新")
|
||
force_update: bool = Field(..., description="是否强制更新")
|
||
version_name: Optional[str] = Field(None, description="最新版本号")
|
||
download_url: Optional[str] = Field(None, description="下载地址")
|
||
changelog: Optional[List[str]] = Field(None, description="更新日志")
|
||
file_size: Optional[int] = Field(None, description="文件大小")
|
||
|
||
|
||
# ═══════════════════════════════════════════════════════════════
|
||
# 固件版本相关模型
|
||
# ═══════════════════════════════════════════════════════════════
|
||
|
||
class FirmwareCreateRequest(BaseModel):
|
||
"""创建固件版本请求"""
|
||
version: str = Field(..., description="固件版本号,如 v3.2.1")
|
||
firmware_type: str = Field(..., description="固件类型:采集板/发射板/主协板/主机服务")
|
||
board_model: Optional[str] = Field(None, description="板卡型号,如 GD30-ACQ-01")
|
||
device_model: Optional[str] = Field(None, description="设备型号,如 GD30-2024")
|
||
hw_range: Optional[str] = Field(None, description="硬件适用范围")
|
||
upgrade_type: str = Field(default="可选", description="升级类型:强制/可选")
|
||
signed: bool = Field(default=False, description="是否已签名")
|
||
notes: Optional[List[str]] = Field(None, description="更新说明列表")
|
||
status: str = Field(default="已发布", description="状态:草稿/已发布/已下架/兼容")
|
||
|
||
|
||
class FirmwareUpdateRequest(BaseModel):
|
||
"""更新固件版本请求"""
|
||
version: Optional[str] = Field(None, description="版本号")
|
||
firmware_type: Optional[str] = Field(None, description="固件类型")
|
||
board_model: Optional[str] = Field(None, description="板卡型号")
|
||
device_model: Optional[str] = Field(None, description="设备型号")
|
||
hw_range: Optional[str] = Field(None, description="硬件适用范围")
|
||
upgrade_type: Optional[str] = Field(None, description="升级类型")
|
||
signed: Optional[bool] = Field(None, description="是否已签名")
|
||
notes: Optional[List[str]] = Field(None, description="更新说明")
|
||
status: Optional[str] = Field(None, description="状态")
|
||
|
||
|
||
class FirmwareInfo(BaseModel):
|
||
"""固件版本信息响应"""
|
||
id: int
|
||
version: str
|
||
firmware_type: str
|
||
board_model: Optional[str] = None
|
||
device_model: Optional[str] = None
|
||
file_name: Optional[str] = None
|
||
file_size: Optional[int] = None
|
||
hw_range: Optional[str] = None
|
||
upgrade_type: Optional[str] = None
|
||
signed: bool = False
|
||
notes: Optional[str] = None
|
||
status: str
|
||
created_at: Optional[str] = None
|
||
updated_at: Optional[str] = None
|
||
|
||
|
||
class FirmwareDownloadQuery(BaseModel):
|
||
"""固件下载查询参数"""
|
||
firmware_type: str = Field(..., description="固件类型")
|
||
device_model: Optional[str] = Field(None, description="设备型号")
|
||
board_model: Optional[str] = Field(None, description="板卡型号")
|
||
|
||
|
||
class FirmwareCheckUpdateRequest(BaseModel):
|
||
"""固件检查更新请求"""
|
||
firmware_type: str = Field(..., description="固件类型")
|
||
device_model: Optional[str] = Field(None, description="设备型号")
|
||
board_model: Optional[str] = Field(None, description="板卡型号")
|
||
current_version: str = Field(..., description="当前版本号")
|
||
|
||
|
||
class FirmwareCheckUpdateResponse(BaseModel):
|
||
"""固件检查更新响应"""
|
||
has_update: bool = Field(..., description="是否有更新")
|
||
force_update: bool = Field(..., description="是否强制更新")
|
||
version: Optional[str] = Field(None, description="最新版本号")
|
||
download_url: Optional[str] = Field(None, description="下载地址")
|
||
notes: Optional[List[str]] = Field(None, description="更新说明")
|
||
file_size: Optional[int] = Field(None, description="文件大小")
|