Files
vps-manager/app/schemas/asset.py
T

133 lines
3.6 KiB
Python

"""资产相关 Schema(请求/响应模型)
设计说明:
- *In 系列:详情表输入模型(不含 id/asset_id,由服务端填充)
- AssetCreate/AssetUpdate:主表字段 + 按类型嵌套的可选 detail
- AssetRead:完整输出,含计算字段 days_to_expiry(距到期天数)
"""
from datetime import date, datetime
from typing import Optional
from sqlmodel import SQLModel
from app.models.asset import AssetStatus, AssetType
# --------------------------------------------------------------------------- #
# 详情表输入模型
# --------------------------------------------------------------------------- #
class VPSDetailIn(SQLModel):
"""VPS 详情输入"""
ip_address: str
tailscale_ip: Optional[str] = None
region: Optional[str] = None
os: Optional[str] = None
cpu_cores: int = 1
memory_gb: float = 1
disk_gb: int = 20
bandwidth_gb: Optional[int] = None
ssh_port: int = 22
panel_url: Optional[str] = None
class DomainDetailIn(SQLModel):
"""域名详情输入"""
domain_name: str
registrar: Optional[str] = None
dns_provider: Optional[str] = None
cloudflare_account: Optional[str] = None
is_using: bool = True
redirect_target: Optional[str] = None
class AIAccountIn(SQLModel):
"""AI 账号详情输入"""
provider: str
api_key: Optional[str] = None
plan: Optional[str] = None
balance: Optional[float] = None
currency: str = "USD"
monthly_usage: Optional[float] = None
monthly_limit: Optional[float] = None
# --------------------------------------------------------------------------- #
# 资产主表模型
# --------------------------------------------------------------------------- #
class AssetBase(SQLModel):
"""资产主表公共字段"""
name: str
asset_type: AssetType
provider: str
account: Optional[str] = None
expiry_date: Optional[date] = None
auto_renew: bool = False
cost: float = 0
currency: str = "USD"
status: AssetStatus = AssetStatus.ACTIVE
is_archived: bool = False
remark: Optional[str] = None
class AssetCreate(AssetBase):
"""创建资产:按 asset_type 携带对应 detail"""
vps_detail: Optional[VPSDetailIn] = None
domain_detail: Optional[DomainDetailIn] = None
ai_detail: Optional[AIAccountIn] = None
class AssetUpdate(SQLModel):
"""更新资产:所有字段可选,仅更新传入项"""
name: Optional[str] = None
asset_type: Optional[AssetType] = None
provider: Optional[str] = None
account: Optional[str] = None
expiry_date: Optional[date] = None
auto_renew: Optional[bool] = None
cost: Optional[float] = None
currency: Optional[str] = None
status: Optional[AssetStatus] = None
is_archived: Optional[bool] = None
remark: Optional[str] = None
vps_detail: Optional[VPSDetailIn] = None
domain_detail: Optional[DomainDetailIn] = None
ai_detail: Optional[AIAccountIn] = None
# --------------------------------------------------------------------------- #
# 输出模型
# --------------------------------------------------------------------------- #
class VPSDetailRead(VPSDetailIn):
id: int
asset_id: int
class DomainDetailRead(DomainDetailIn):
id: int
asset_id: int
class AIAccountRead(AIAccountIn):
id: int
asset_id: int
last_synced_at: Optional[datetime] = None
class AssetRead(AssetBase):
"""资产完整输出"""
id: int
created_at: datetime
updated_at: datetime
days_to_expiry: Optional[int] = None
vps_detail: Optional[VPSDetailRead] = None
domain_detail: Optional[DomainDetailRead] = None
ai_detail: Optional[AIAccountRead] = None