Files
planManage/app/models.py
锦麟 王 61ce809634 feat: 多平台 Coding Plan 统一管理系统初始实现
- 支持 MiniMax/OpenAI/Google Gemini/智谱/Kimi 五个平台
- 插件化 Provider 架构,自动发现注册
- 多维度 QuotaRule 额度追踪(固定间隔/自然周期/API同步/手动)
- OpenAI + Anthropic 兼容 API 代理,SSE 流式转发
- Model 路由表 + 额度耗尽自动 fallback
- 多媒体任务队列(图片/语音/视频)
- Vue3 + Tailwind 单文件 Web 仪表盘
- Docker 一键部署

Made-with: Cursor
2026-03-31 15:50:42 +08:00

166 lines
4.5 KiB
Python

"""Pydantic 数据模型 -- API 请求/响应 + 数据库行映射"""
from __future__ import annotations
from datetime import datetime
from enum import Enum
from typing import Any
from pydantic import BaseModel, Field
# ── 枚举 ──────────────────────────────────────────────
class RefreshType(str, Enum):
FIXED_INTERVAL = "fixed_interval"
CALENDAR_CYCLE = "calendar_cycle"
MANUAL = "manual"
API_SYNC = "api_sync"
class TaskStatus(str, Enum):
PENDING = "pending"
RUNNING = "running"
COMPLETED = "completed"
FAILED = "failed"
CANCELLED = "cancelled"
# ── Plan ──────────────────────────────────────────────
class PlanBase(BaseModel):
name: str
provider_name: str
api_base: str = ""
plan_type: str = "coding"
supported_models: list[str] = Field(default_factory=list)
extra_headers: dict[str, str] = Field(default_factory=dict)
extra_config: dict[str, Any] = Field(default_factory=dict)
enabled: bool = True
class PlanCreate(PlanBase):
api_key: str = ""
class PlanUpdate(BaseModel):
name: str | None = None
api_key: str | None = None
api_base: str | None = None
plan_type: str | None = None
supported_models: list[str] | None = None
extra_headers: dict[str, str] | None = None
extra_config: dict[str, Any] | None = None
enabled: bool | None = None
class PlanOut(PlanBase):
id: str
created_at: datetime
updated_at: datetime
# ── QuotaRule ─────────────────────────────────────────
class QuotaRuleBase(BaseModel):
rule_name: str
quota_total: int
quota_unit: str = "requests"
refresh_type: RefreshType = RefreshType.CALENDAR_CYCLE
interval_hours: float | None = None
calendar_unit: str | None = None
calendar_anchor: dict[str, Any] | None = None
enabled: bool = True
class QuotaRuleCreate(QuotaRuleBase):
plan_id: str
class QuotaRuleUpdate(BaseModel):
rule_name: str | None = None
quota_total: int | None = None
quota_unit: str | None = None
refresh_type: RefreshType | None = None
interval_hours: float | None = None
calendar_unit: str | None = None
calendar_anchor: dict[str, Any] | None = None
enabled: bool | None = None
class QuotaRuleOut(QuotaRuleBase):
id: str
plan_id: str
quota_used: int = 0
last_refresh_at: datetime | None = None
next_refresh_at: datetime | None = None
# ── QuotaSnapshot ─────────────────────────────────────
class QuotaSnapshotOut(BaseModel):
id: str
rule_id: str
quota_used: int
quota_remaining: int
checked_at: datetime
# ── Model Route ───────────────────────────────────────
class ModelRouteBase(BaseModel):
model_name: str
plan_id: str
priority: int = 0
class ModelRouteOut(ModelRouteBase):
id: str
# ── Task Queue ────────────────────────────────────────
class TaskCreate(BaseModel):
plan_id: str | None = None
task_type: str
request_payload: dict[str, Any] = Field(default_factory=dict)
priority: int = 0
max_retries: int = 3
callback_url: str | None = None
class TaskOut(BaseModel):
id: str
plan_id: str | None
task_type: str
status: TaskStatus
request_payload: dict[str, Any]
response_payload: dict[str, Any] | None = None
result_file_path: str | None = None
result_mime_type: str | None = None
priority: int
retry_count: int
max_retries: int
callback_url: str | None = None
created_at: datetime
started_at: datetime | None = None
completed_at: datetime | None = None
# ── 聚合视图 ──────────────────────────────────────────
class PlanWithRules(PlanOut):
"""Plan + 所有 QuotaRule 的聚合返回"""
quota_rules: list[QuotaRuleOut] = Field(default_factory=list)
class DashboardPlan(BaseModel):
"""仪表盘用的精简视图"""
id: str
name: str
provider_name: str
plan_type: str
enabled: bool
quota_rules: list[QuotaRuleOut]
all_available: bool = True # 所有 Rule 均有余量