mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-07 09:57:47 +08:00
fix(wallet): 修复余额不足后重复消费
- 有限钱包结算允许扣成负数,先扣充值余额再扣赠送余额,缺口回写到充值余额 - 日额度钱包补扣路径在存在钱包时不再把余额不足标成 insufficient_quota - 补充内存和 SQLite 结算回归覆盖,三种数据库实现保持一致 验证: - cargo fmt --all --check - cargo clippy -p aether-data --all-targets -- -D warnings - cargo clippy -p aether-gateway --all-targets -- -D warnings - cargo clippy --workspace --exclude aether-gateway --exclude aether-data --all-targets -- -D warnings - cargo nextest run -p aether-gateway - cargo nextest run -p aether-data - cargo nextest run --workspace --exclude aether-gateway --exclude aether-data - cargo test -p aether-data sqlite --lib - Postgres/MySQL data_db_smoke commands from rust-ci.yml
This commit is contained in:
@@ -312,6 +312,7 @@ async fn consume_daily_quota_postgres(
|
||||
request_id: &str,
|
||||
total_cost_usd: f64,
|
||||
wallet_available_usd: Option<f64>,
|
||||
wallet_can_overdraft: bool,
|
||||
) -> Result<DailyQuotaDebitResult, DataLayerError> {
|
||||
if total_cost_usd <= 0.0 {
|
||||
return Ok(DailyQuotaDebitResult::default());
|
||||
@@ -379,6 +380,7 @@ WHERE user_entitlement_id = $1
|
||||
});
|
||||
}
|
||||
if allow_wallet_overage
|
||||
&& !wallet_can_overdraft
|
||||
&& wallet_available_usd.is_some_and(|available| {
|
||||
total_remaining + available + SETTLEMENT_EPSILON_USD < total_cost_usd
|
||||
})
|
||||
@@ -560,6 +562,7 @@ LIMIT 1
|
||||
None
|
||||
};
|
||||
|
||||
let wallet_can_overdraft = wallet_row.is_some();
|
||||
let wallet_available_usd = match wallet_row.as_ref() {
|
||||
Some(row) => {
|
||||
let limit_mode: String =
|
||||
@@ -600,6 +603,7 @@ LIMIT 1
|
||||
&input.request_id,
|
||||
input.total_cost_usd,
|
||||
wallet_available_usd,
|
||||
wallet_can_overdraft,
|
||||
)
|
||||
.await?;
|
||||
if quota.insufficient {
|
||||
@@ -646,16 +650,8 @@ LIMIT 1
|
||||
before_gift,
|
||||
wallet_debit_cost_usd,
|
||||
);
|
||||
if debit_plan.covered_usd() + SETTLEMENT_EPSILON_USD
|
||||
< wallet_debit_cost_usd
|
||||
{
|
||||
final_billing_status = "insufficient_quota".to_string();
|
||||
settlement.billing_status = final_billing_status.clone();
|
||||
} else {
|
||||
after_recharge =
|
||||
before_recharge - debit_plan.recharge_deduction;
|
||||
after_gift = before_gift - debit_plan.gift_deduction;
|
||||
}
|
||||
(after_recharge, after_gift) =
|
||||
debit_plan.after_balances(before_recharge, before_gift);
|
||||
}
|
||||
if final_billing_status == "settled" {
|
||||
sqlx::query(
|
||||
|
||||
Reference in New Issue
Block a user