Files
2026-08-14 15:23:46 +08:00

329 lines
10 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
deleted_at: NaiveDatetimeOptional = None
model_config = {"from_attributes": True}
class SystemConfigCreate(BaseModel):
key: str
value: str
description: str | None = None
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
personal_credits: float = 0
team_available_credits: float = 0
team_frozen_credits: float = 0
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
private_portrait_asset_limit: int = 50
single_device_login_override: bool | 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)$")
is_admin: bool = False
frontend_user_kind: str = Field(default="external", pattern="^(internal|external)$")
allowed_menus: list | None = None
private_portrait_asset_limit: int = Field(default=50, ge=0, le=9999, description="私域人像素材总量限制,真人/虚拟、图片/视频共用,0 表示关闭")
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 DailyCreditOut(BaseModel):
date: str
module: str
credits: float
class TeamCreditOut(BaseModel):
team_name: str
team_id: str | None
credits: float
class ModelUsageOut(BaseModel):
model_name: str
provider: str
count: int
class VideoParamOut(BaseModel):
model: str
label: str
count: int
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
# 图表数据
daily_credits_by_module: list[DailyCreditOut] = []
period_credits_by_module: list[DailyCreditOut] = []
credits_by_team: list[TeamCreditOut] = []
model_usage: list[ModelUsageOut] = []
video_resolution_usage: list[VideoParamOut] = []
video_ratio_usage: list[VideoParamOut] = []
video_duration_usage: list[VideoParamOut] = []
class AdminCreditRecordSummaryOut(BaseModel):
total_recharge: float = 0.0
total_consume: float = 0.0
total_refund: float = 0.0
# 消费类分解(仅 type=consume,不含 team_internal 团队内部转账;真实扣费 + 预扣占用 = total_consume
# - total_charge : 真实扣费 charge(含历史 NULL),对应"筛选明细类型=消费 且 action=charge/NULL"求和
# - total_hold : 预扣占用 hold
total_charge: float = 0.0
total_hold: float = 0.0
# 回退类分解(仅 type=refund;真实退款 + 预扣释放 = total_refund
# - total_refund_real : 真实退款 refund(含历史 NULL)
# - total_hold_release: 预扣释放 hold_release
total_refund_real: float = 0.0
total_hold_release: float = 0.0
# 净消耗 = max(total_consume - total_refund, 0) = 实际"用掉了"的积分
net_consume: 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 AdminCreditRecordAllocationOut(BaseModel):
id: str
credit_balance_id: str
source_allocation_id: str | None = None
allocation_action: str
allocation_action_label: str | None = None
amount: float
credit_level: str
credit_level_label: str | None = None
credit_scope: str | None = None
credit_scope_label: str | None = None
team_id: str | None = None
team_manager_id: str | None = None
subscription_id: str | None = None
subscription_no: str | None = None
product_name: str | None = None
product_type: str | None = None
product_type_label: str | None = None
tier_code: str | None = None
tier_label: str | None = None
tier_rank: int | None = None
billing_cycle: str | None = None
billing_cycle_label: str | None = None
subscription_period_id: str | None = None
period_sequence: int | None = None
period_label: str | None = None
period_valid_from: str | None = None
period_expires_at: str | None = None
seat_id: str | None = None
source_type: str
source_type_label: str | None = None
source_id: str | None = None
valid_from: str | None = None
expires_at: str | None = None
unspent_before: float = 0.0
unspent_after: float = 0.0
consumed_before: float = 0.0
consumed_after: float = 0.0
class AdminCreditRecordSubscriptionUsageOut(BaseModel):
credit_scope: str | None = None
credit_scope_label: str | None = None
subscription_id: str | None = None
subscription_no: str
product_name: str | None = None
product_type: str | None = None
product_type_label: str | None = None
tier_code: str | None = None
tier_label: str | None = None
tier_rank: int | None = None
billing_cycle: str | None = None
billing_cycle_label: str | None = None
subscription_period_id: str | None = None
period_sequence: int | None = None
period_label: str | None = None
period_valid_from: str | None = None
period_expires_at: str | None = None
amount: float = 0.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_delta: float = 0.0
expired_amount: float = 0.0
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
charge_action_label: 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
scene_name_snapshot: str | None = None
request_time: 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
llm_call_count: int = 0
llm_success_call_count: int = 0
llm_failed_call_count: int = 0
funding_scope: str = "none"
funding_scope_label: str = "无资金分摊"
team_allocation_amount: float = 0.0
personal_allocation_amount: float = 0.0
subscription_usages: list[AdminCreditRecordSubscriptionUsageOut] = Field(default_factory=list)
allocations: list[AdminCreditRecordAllocationOut] = Field(default_factory=list)
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