feat: add configurable verification and redemption codes

This commit is contained in:
237899745
2026-07-25 13:57:39 +08:00
parent d1f093685d
commit c6e96464d3
32 changed files with 2108 additions and 261 deletions

View File

@@ -791,49 +791,7 @@ async fn charge_one_unit(
bytes_in: u64,
bytes_out: u64,
) -> Result<(), AppError> {
// Ensure usage period row exists.
sqlx::query(
r#"
INSERT INTO usage_periods (user_id, subscription_id, period_start, period_end)
VALUES ($1, $2, $3, $4)
ON CONFLICT (user_id, period_start, period_end) DO NOTHING
"#,
)
.bind(billing.user_id)
.bind(billing.subscription_id)
.bind(billing.period_start)
.bind(billing.period_end)
.execute(&mut **tx)
.await
.map_err(|err| AppError::new(ErrorCode::Internal, "初始化用量周期失败").with_source(err))?;
let updated: Option<i32> = sqlx::query_scalar(
r#"
UPDATE usage_periods
SET used_units = used_units + 1,
bytes_in = bytes_in + $1,
bytes_out = bytes_out + $2,
updated_at = NOW()
WHERE user_id = $3
AND period_start = $4
AND period_end = $5
AND used_units + 1 <= $6 + bonus_units
RETURNING used_units
"#,
)
.bind(bytes_in as i64)
.bind(bytes_out as i64)
.bind(billing.user_id)
.bind(billing.period_start)
.bind(billing.period_end)
.bind(billing.plan.included_units_per_period)
.fetch_optional(&mut **tx)
.await
.map_err(|err| AppError::new(ErrorCode::Internal, "扣减配额失败").with_source(err))?;
if updated.is_none() {
return Err(AppError::new(ErrorCode::QuotaExceeded, "当期配额已用完"));
}
quota::consume_user_unit(tx, billing, bytes_in, bytes_out).await?;
sqlx::query(
r#"