feat: 初始化 vps-manager 资产管理系统(Asset/VPSDetail/DomainDetail/AIAccount 模型 + FastAPI 骨架)

This commit is contained in:
gouki
2026-08-01 13:18:04 +00:00
commit e6047e36d5
9 changed files with 225 additions and 0 deletions
+136
View File
@@ -0,0 +1,136 @@
"""资产数据库模型
包含四种核心资产模型:
- Asset: 资产主表(统一登记 VPS/域名/AI 账号/Cloudflare 等一切资产)
- VPSDetail: VPS 资产详情(与 Asset 一对一关联)
- DomainDetail: 域名资产详情(与 Asset 一对一关联)
- AIAccount: AI Agent 账号详情(与 Asset 一对一关联)
"""
from datetime import date, datetime
from enum import Enum
from typing import Optional
from sqlmodel import Field, SQLModel
class AssetType(str, Enum):
"""资产类型"""
VPS = "vps" # 云服务器
DOMAIN = "domain" # 域名
AI_AGENT = "ai_agent" # AI Agent 账号(OpenAI/Kimi/DeepSeek 等)
CLOUDFLARE = "cloudflare" # Cloudflare 账号/子资产(DNS/Workers/R2/Tunnel
OTHER = "other" # 其他
class AssetStatus(str, Enum):
"""资产运行状态"""
ACTIVE = "active" # 正常使用中
EXPIRED = "expired" # 已过期
STOPPED = "stopped" # 已停止(不再使用)
CANCELLED = "cancelled" # 已注销
UNKNOWN = "unknown" # 未知(待确认)
class Asset(SQLModel, table=True):
"""资产主表:所有资产在此统一登记,用于续费提醒与状态总览"""
__tablename__ = "assets"
id: Optional[int] = Field(default=None, primary_key=True)
name: str = Field(index=True, description="资产名称,如:博客主站 VPS")
asset_type: AssetType = Field(index=True, description="资产类型")
provider: str = Field(index=True, description="服务商,如 aliyun/vultr/namesilo/openai")
account: Optional[str] = Field(
default=None, description="所属账号标识(如 Cloudflare 账号邮箱)"
)
expiry_date: Optional[date] = Field(
default=None, index=True, description="到期/续费日期,用于续费提醒"
)
auto_renew: bool = Field(default=False, description="是否自动续费")
cost: float = Field(default=0, description="单次续费费用")
currency: str = Field(default="USD", description="币种(USD/CNY/JPY")
status: AssetStatus = Field(default=AssetStatus.ACTIVE, index=True, description="运行状态")
is_archived: bool = Field(
default=False, description="已归档:不再使用但可能仍在续费,需重点排查"
)
remark: Optional[str] = Field(default=None, description="备注")
created_at: datetime = Field(default_factory=datetime.utcnow, description="创建时间")
updated_at: datetime = Field(
default_factory=datetime.utcnow,
sa_column_kwargs={"onupdate": datetime.utcnow},
description="更新时间",
)
class VPSDetail(SQLModel, table=True):
"""VPS 资产详情(一对一关联 Asset)"""
__tablename__ = "vps_details"
id: Optional[int] = Field(default=None, primary_key=True)
asset_id: int = Field(
foreign_key="assets.id", unique=True, index=True, description="关联资产 ID"
)
ip_address: str = Field(index=True, description="公网 IP")
tailscale_ip: Optional[str] = Field(default=None, description="Tailscale 内网 IP")
region: Optional[str] = Field(default=None, description="机房区域,如 Japan/US West")
os: Optional[str] = Field(default=None, description="操作系统,如 Debian 12")
cpu_cores: int = Field(default=1, description="CPU 核数")
memory_gb: float = Field(default=1, description="内存大小(GB")
disk_gb: int = Field(default=20, description="磁盘大小(GB")
bandwidth_gb: Optional[int] = Field(default=None, description="月流量配额(GB")
ssh_port: int = Field(default=22, description="SSH 端口")
panel_url: Optional[str] = Field(default=None, description="服务商管理面板 URL")
class DomainDetail(SQLModel, table=True):
"""域名资产详情(一对一关联 Asset"""
__tablename__ = "domain_details"
id: Optional[int] = Field(default=None, primary_key=True)
asset_id: int = Field(
foreign_key="assets.id", unique=True, index=True, description="关联资产 ID"
)
domain_name: str = Field(index=True, description="域名,如 example.com")
registrar: Optional[str] = Field(
default=None, description="注册商:namesilo/新网/腾讯/阿里/dynadot/cloudflare"
)
dns_provider: Optional[str] = Field(
default=None, description="DNS 托管商:cloudflare/阿里云/注册商默认"
)
cloudflare_account: Optional[str] = Field(
default=None, description="归属的 Cloudflare 账号标识"
)
is_using: bool = Field(default=True, description="是否仍在实际使用")
redirect_target: Optional[str] = Field(
default=None, description="若为跳转用途域名,填写目标地址"
)
class AIAccount(SQLModel, table=True):
"""AI Agent 账号资产详情(一对一关联 Asset)"""
__tablename__ = "ai_accounts"
id: Optional[int] = Field(default=None, primary_key=True)
asset_id: int = Field(
foreign_key="assets.id", unique=True, index=True, description="关联资产 ID"
)
provider: str = Field(
index=True, description="服务商:openai/minimax/kimi/agnes/deepseek"
)
api_key: Optional[str] = Field(
default=None, description="API Key(后续版本将改为加密存储)"
)
plan: Optional[str] = Field(default=None, description="订阅计划,如 ChatGPT Plus")
balance: Optional[float] = Field(default=None, description="当前余额")
currency: str = Field(default="USD", description="币种")
monthly_usage: Optional[float] = Field(default=None, description="本月用量")
monthly_limit: Optional[float] = Field(default=None, description="月度限额")
last_synced_at: Optional[datetime] = Field(
default=None, description="最近一次自动同步余额/用量的时间"
)