from __future__ import annotations from decimal import Decimal from pydantic import BaseModel, Field, field_validator, model_validator from app.enums.resource_capacity import ResourceCapacitySourceEnum, ResourceCapacityUnitEnum class ResourceCapacityConfigUpdate(BaseModel): enabled: bool = Field( ..., description="是否开启容量管控。true=开启,false=关闭。全局配置关闭表示全局不限制;用户配置关闭表示该用户个人明确关闭限制,优先级高于全局。", examples=[True], ) limit_value: Decimal | None = Field( None, description="容量数值,最小1,不能为负数,最多3位小数。例如:1、10、10.5、10.500。enabled=true 时必填。", examples=["10.500"], ) limit_unit: ResourceCapacityUnitEnum | None = Field( None, description="容量单位枚举:MB=1024*1024字节,GB=1024*1024*1024字节,TB=1024*1024*1024*1024字节。enabled=true 时必填。", examples=[ResourceCapacityUnitEnum.GB.value], ) @field_validator("limit_value") @classmethod def validate_limit_value(cls, value: Decimal | None) -> Decimal | None: if value is None: return value if value < Decimal("1"): raise ValueError("容量数值不能小于1") if value.as_tuple().exponent < -3: raise ValueError("容量数值最多支持3位小数") return value @model_validator(mode="after") def validate_enabled_payload(self) -> "ResourceCapacityConfigUpdate": if self.enabled: if self.limit_value is None: raise ValueError("开启容量管控时必须填写容量数值") if self.limit_unit is None: raise ValueError("开启容量管控时必须选择容量单位:MB、GB、TB") return self class ResourceCapacityConfigOut(BaseModel): enabled: bool = Field(..., description="是否开启容量管控") limit_value: str = Field(..., description="容量数值字符串,最多3位小数") limit_unit: ResourceCapacityUnitEnum = Field(..., description="容量单位枚举:MB、GB、TB") limit_bytes: int = Field(..., ge=0, description="按单位换算后的字节数") class ResourceCapacityUsageOut(BaseModel): enabled: bool = Field(..., description="当前用户最终是否启用容量管控") source: ResourceCapacitySourceEnum = Field(..., description="最终配置来源:user=用户个人配置,global=全局配置,disabled=容量管控未开启") has_user_config: bool = Field(..., description="该用户是否存在个人容量配置记录。注意:存在且 enabled=false 表示用户个人明确关闭限制") used_bytes: int = Field(..., ge=0, description="当前用户已用有效资源容量,来自 UserResourceTotalStat.active_size_bytes") available_bytes: int | None = Field(None, description="当前用户可用容量字节数。未开启容量管控时为 null") total_bytes: int | None = Field(None, description="当前用户总容量字节数。未开启容量管控时为 null") usage_percent: float | None = Field(None, description="当前用户容量使用百分比,未开启容量管控时为 null") exceeded: bool = Field(..., description="是否已超额。判断规则:enabled=true 且 used_bytes >= total_bytes") limit_value: str | None = Field(None, description="最终生效容量数值。未开启容量管控时为 null") limit_unit: ResourceCapacityUnitEnum | None = Field(None, description="最终生效容量单位。未开启容量管控时为 null") class AdminUserResourceCapacityOut(BaseModel): has_user_config: bool = Field(..., description="该用户是否已单独设置容量配置") user_config: ResourceCapacityConfigOut | None = Field(None, description="用户个人容量配置。未单独设置时为 null") global_config: ResourceCapacityConfigOut = Field(..., description="当前全局容量配置") effective: ResourceCapacityUsageOut = Field(..., description="该用户最终生效的容量使用数据")