from pydantic import BaseModel, Field from app.schemas.common import NaiveDatetime, NaiveDatetimeOptional from app.schemas.resource_capacity import ResourceCapacityUsageOut class CreditAdjustRequest(BaseModel): amount: float = Field(..., ge=-9999999.99, le=9999999.99, multiple_of=0.01) description: str = Field(..., max_length=256) class ModelConfigCreate(BaseModel): name: str = Field(..., max_length=64) provider: str = Field(..., max_length=32) api_base: str = Field(..., max_length=512) api_key: str = Field(..., max_length=256) model_name: str = Field(..., max_length=128) weight: int = Field(default=1, ge=0) max_tokens: int = Field(default=4096, ge=1) temperature: float = Field(default=0.7, ge=0, le=2) is_active: bool = True priority: int = 0 class ModelConfigOut(ModelConfigCreate): id: str created_at: NaiveDatetime model_config = {"from_attributes": True} class SystemConfigUpdate(BaseModel): value: str | int | float class SystemConfigOut(BaseModel): id: str key: str value: str description: str | None = None model_config = {"from_attributes": True} class AdminUserOut(BaseModel): id: str username: str email: str | None = None phone: str | None = None credits: float is_active: bool is_admin: bool user_type: str = "frontend" frontend_user_kind: str = "external" team_id: str | None = None team_name: str | None = None created_at: NaiveDatetime last_login_at: NaiveDatetimeOptional = None allowed_menus: list | None = None resource_capacity: ResourceCapacityUsageOut | None = None model_config = {"from_attributes": True} class CreateUserRequest(BaseModel): username: str | None = Field(None, max_length=64) password: str = Field(..., min_length=6, max_length=128) email: str | None = None phone: str | None = None credits: float = 0.0 user_type: str = Field(default="frontend", pattern="^(frontend|admin)$") frontend_user_kind: str = Field(default="external", pattern="^(internal|external)$") allowed_menus: list | None = None class UpdateFrontendUserKindRequest(BaseModel): frontend_user_kind: str = Field(..., pattern="^(internal|external)$") class UpdateMenusRequest(BaseModel): allowed_menus: list | None = None class ResetPasswordRequest(BaseModel): new_password: str = Field(..., min_length=6, max_length=128) class OperationLogOut(BaseModel): id: str user_id: str username: str action: str method: str path: str detail: str | None = None ip: str | None = None created_at: NaiveDatetime model_config = {"from_attributes": True} class AdminStatsOut(BaseModel): total_users: int total_projects: int total_generations: int total_records: int total_revenue: float credits_consumed_today: float today_alipay_revenue: float today_wechat_revenue: float last_period_users: int = 0 last_period_projects: int = 0 last_period_generations: int = 0 last_period_records: int = 0 last_period_revenue: float = 0.0 last_period_credits_consumed: float = 0.0 class AdminCreditRecordSummaryOut(BaseModel): total_recharge: float = 0.0 total_consume: float = 0.0 total_refund: float = 0.0 transaction_count: int = 0 generation_count: int = 0 generation_attempt_count: int = 0 image_generation_count: int = 0 video_generation_count: int = 0 image_consume: float = 0.0 video_consume: float = 0.0 text_consume: float = 0.0 analysis_consume: float = 0.0 total_tokens: int = 0 input_tokens: int = 0 output_tokens: int = 0 class AdminCreditRecordOut(BaseModel): id: str user_id: str username: str | None = None phone: str | None = None email: str | None = None user_type: str | None = None user_type_label: str | None = None frontend_user_kind: str | None = None frontend_user_kind_label: str | None = None team_id_snapshot: str | None = None team_name_snapshot: str | None = None type: str record_type: str record_type_label: str | None = None amount: float balance_after: float description: str | None = None related_id: str | None = None biz_key: str | None = None refund_for_biz_key: str | None = None owner_type: str | None = None owner_id: str | None = None owner_deleted: bool = False owner_deleted_at: str | None = None attempt_no: int | None = None charge_kind: str | None = None charge_kind_label: str | None = None charge_action: str | None = None credit_subject: str | None = None credit_subject_label: str | None = None media_type: str | None = None media_type_label: str | None = None billing_scene: str | None = None billing_scene_label: str | None = None source_module: str | None = None source_module_label: str | None = None source_project_id: str | None = None source_step_id: str | None = None source_step_code: str | None = None source_step_code_label: str | None = None token_usage_id: str | None = None input_tokens: int = 0 output_tokens: int = 0 total_tokens: int = 0 engine_type: str | None = None engine_id: str | None = None engine_name: str | None = None engine_provider: str | None = None engine_model_name: str | None = None created_at: str | None = None class AdminCreditRecordListOut(BaseModel): items: list[AdminCreditRecordOut] total: int summary: AdminCreditRecordSummaryOut