From d149dbc91f335667db0d74a2054500eca047ab19 Mon Sep 17 00:00:00 2001 From: erio Date: Wed, 15 Apr 2026 01:11:49 +0800 Subject: [PATCH] fix(payment): enhance fee rate input validation and UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backend: - Validate recharge_fee_rate: 0 ≤ rate ≤ 100, max 2 decimal places Frontend settings: - Add % suffix icon to fee rate input - Enforce max=100, min=0, step=0.01 with 2 decimal precision --- backend/internal/service/payment_config_service.go | 9 +++++++-- frontend/src/views/admin/SettingsView.vue | 5 ++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/backend/internal/service/payment_config_service.go b/backend/internal/service/payment_config_service.go index 2f040292..d8c47804 100644 --- a/backend/internal/service/payment_config_service.go +++ b/backend/internal/service/payment_config_service.go @@ -272,8 +272,13 @@ func (s *PaymentConfigService) UpdatePaymentConfig(ctx context.Context, req Upda } } if req.RechargeFeeRate != nil { - if math.IsNaN(*req.RechargeFeeRate) || math.IsInf(*req.RechargeFeeRate, 0) || *req.RechargeFeeRate < 0 { - return infraerrors.BadRequest("INVALID_RECHARGE_FEE_RATE", "recharge fee rate must be >= 0") + v := *req.RechargeFeeRate + if math.IsNaN(v) || math.IsInf(v, 0) || v < 0 || v > 100 { + return infraerrors.BadRequest("INVALID_RECHARGE_FEE_RATE", "recharge fee rate must be between 0 and 100") + } + // Enforce max 2 decimal places + if math.Round(v*100) != v*100 { + return infraerrors.BadRequest("INVALID_RECHARGE_FEE_RATE", "recharge fee rate allows at most 2 decimal places") } } m := map[string]string{ diff --git a/frontend/src/views/admin/SettingsView.vue b/frontend/src/views/admin/SettingsView.vue index cbd4d284..ee6a4c6d 100644 --- a/frontend/src/views/admin/SettingsView.vue +++ b/frontend/src/views/admin/SettingsView.vue @@ -2383,7 +2383,10 @@
- +
+ + % +

{{ t('admin.settings.payment.rechargeFeeRateHint') }}

{{ t('admin.settings.payment.rechargeFeePreview', { fee: (Number(form.payment_recharge_fee_rate) || 0).toFixed(2) }) }}