会员积分改版V7

This commit is contained in:
2026-08-11 13:23:22 +08:00
parent 809ff47120
commit a49ed802f4
14 changed files with 137 additions and 29 deletions
@@ -239,7 +239,7 @@ def product_to_dict(
"activity_end_at": product.activity_end_at,
"renewal_enabled": bool(product.renewal_enabled),
"grant_credits": float(product.grant_credits or 0),
"validity_months": 1 if product.is_credit_addon else None,
"validity_months": int(product.validity_months or 1) if product.is_credit_addon else None,
"price": float(user_price if user_price is not None else product.price),
"current_price": float(user_price if user_price is not None else product.price),
"target_price": float(target_price) if target_price is not None else None,
@@ -57,6 +57,7 @@ def _product_snapshot(product: CreditProduct) -> dict:
"regular_price": float(product.regular_price or 0),
"activity_price": float(product.activity_price) if product.activity_price is not None else None,
"grant_credits": float(product.grant_credits or 0),
"validity_months": int(product.validity_months or 1) if product.is_credit_addon else None,
"credit_level": product.credit_level,
"features": product.features_json or [],
}
@@ -83,6 +84,24 @@ def _snapshot_decimal(snapshot: dict, key: str) -> Decimal:
return to_credit_decimal(snapshot.get(key) or 0)
def _snapshot_validity_months(snapshot: dict) -> int:
raw_value = snapshot.get("validity_months")
if raw_value is None:
# 兼容历史订单快照:旧版本增值包固定为1个自然月。
return 1
if isinstance(raw_value, bool):
raise ValueError("积分增值包有效期快照无效")
try:
months = int(raw_value)
except (TypeError, ValueError) as exc:
raise ValueError("积分增值包有效期快照无效") from exc
if isinstance(raw_value, float) and not raw_value.is_integer():
raise ValueError("积分增值包有效期快照无效")
if not 1 <= months <= 36:
raise ValueError("积分增值包有效期必须为1-36个月")
return months
async def _create_subscription(
db: AsyncSession,
*,
@@ -489,7 +508,7 @@ async def fulfill_payment_product(
description=f"购买积分增值包:{order.product_name_snapshot or snapshot.get('name') or '积分增值包'}",
source_type=CreditBalanceSourceType.CREDIT_ADDON.value,
valid_from=checked_at,
expires_at=add_natural_months(checked_at, 1),
expires_at=add_natural_months(checked_at, _snapshot_validity_months(snapshot)),
credit_level=str(snapshot.get("credit_level") or "general"),
source_id=order.id,
product_id=order.product_id,