feat: implement priority_weighted_plus_percent pricing algorithm

This commit is contained in:
SmartUp Developer
2026-07-02 20:23:20 +08:00
parent d07ab62772
commit 8746068cd4
6 changed files with 43 additions and 6 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ class WebsiteGroupBinding(Base):
target_group_name: Mapped[str] = mapped_column(String(255), default="")
source_groups_json: Mapped[str] = mapped_column(Text, default="[]")
percent: Mapped[str] = mapped_column(String(32), default="0")
algorithm: Mapped[str] = mapped_column(String(64), default="max_plus_percent")
algorithm: Mapped[str] = mapped_column(String(64), default="priority_weighted_plus_percent")
enabled: Mapped[bool] = mapped_column(Boolean, default=True)
created_at: Mapped[datetime] = mapped_column(DateTime, default=lambda: datetime.now(timezone.utc))
updated_at: Mapped[datetime] = mapped_column(
+1 -1
View File
@@ -73,7 +73,7 @@ SENSITIVE_CREDENTIAL_KEYS = {
"aws_secret_access_key", "aws_session_token",
"service_account_json", "service_account", "private_key",
}
ALGORITHMS = {"max_plus_percent", "average_plus_percent", "min_plus_percent"}
ALGORITHMS = {"max_plus_percent", "average_plus_percent", "min_plus_percent", "priority_weighted_plus_percent"}
def _mask(cfg: dict) -> dict:
+1 -1
View File
@@ -91,7 +91,7 @@ class BindingCreate(BaseModel):
target_group_name: str = ""
source_groups: list[BindingSourceGroup] = Field(default_factory=list)
percent: float = Field(default=0, ge=0)
algorithm: str = "max_plus_percent"
algorithm: str = "priority_weighted_plus_percent"
enabled: bool = True
+21 -1
View File
@@ -65,12 +65,32 @@ def calculate_target_rate(values: list[Any], percent: Any = 0, algorithm: str =
base = min(rates)
elif algorithm == "max_plus_percent":
base = max(rates)
elif algorithm == "priority_weighted_plus_percent":
rates_sorted = sorted(rates)
N = len(rates_sorted)
if N == 1:
base = rates_sorted[0]
else:
base = Decimal("0")
remaining = Decimal("1.0")
for i in range(N):
if i == N - 1:
weight = remaining
else:
weight = remaining * Decimal("0.85")
remaining -= weight
base += rates_sorted[i] * weight
else:
raise WebsiteError(f"不支持的算法:{algorithm}")
pct = Decimal(str(percent or 0))
if pct < 0:
raise WebsiteError("百分比不能为负数")
return (base * (Decimal("1") + pct / Decimal("100"))).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
target_rate = (base * (Decimal("1") + pct / Decimal("100"))).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
if algorithm == "priority_weighted_plus_percent":
min_rate = min(rates)
if target_rate < min_rate:
target_rate = min_rate
return target_rate
def _unwrap_data(value: Any) -> Any: