fix(payment): enhance fee rate input validation and UI
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
This commit is contained in:
@@ -272,8 +272,13 @@ func (s *PaymentConfigService) UpdatePaymentConfig(ctx context.Context, req Upda
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if req.RechargeFeeRate != nil {
|
if req.RechargeFeeRate != nil {
|
||||||
if math.IsNaN(*req.RechargeFeeRate) || math.IsInf(*req.RechargeFeeRate, 0) || *req.RechargeFeeRate < 0 {
|
v := *req.RechargeFeeRate
|
||||||
return infraerrors.BadRequest("INVALID_RECHARGE_FEE_RATE", "recharge fee rate must be >= 0")
|
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{
|
m := map[string]string{
|
||||||
|
|||||||
@@ -2383,7 +2383,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="input-label">{{ t('admin.settings.payment.rechargeFeeRate') }}</label>
|
<label class="input-label">{{ t('admin.settings.payment.rechargeFeeRate') }}</label>
|
||||||
<input :value="form.payment_recharge_fee_rate || ''" @input="form.payment_recharge_fee_rate = parseFloat(($event.target as HTMLInputElement).value) || 0" type="number" step="0.01" min="0" class="input" />
|
<div class="relative">
|
||||||
|
<input :value="form.payment_recharge_fee_rate ?? ''" @input="form.payment_recharge_fee_rate = Math.min(100, Math.max(0, Math.round(parseFloat(($event.target as HTMLInputElement).value || '0') * 100) / 100))" type="number" step="0.01" min="0" max="100" class="input pr-8" />
|
||||||
|
<span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400">%</span>
|
||||||
|
</div>
|
||||||
<p class="mt-0.5 text-xs text-gray-400">{{ t('admin.settings.payment.rechargeFeeRateHint') }}</p>
|
<p class="mt-0.5 text-xs text-gray-400">{{ t('admin.settings.payment.rechargeFeeRateHint') }}</p>
|
||||||
<p v-if="(Number(form.payment_recharge_fee_rate) || 0) > 0" class="mt-1 text-xs font-medium text-primary-600 dark:text-primary-400">{{ t('admin.settings.payment.rechargeFeePreview', { fee: (Number(form.payment_recharge_fee_rate) || 0).toFixed(2) }) }}</p>
|
<p v-if="(Number(form.payment_recharge_fee_rate) || 0) > 0" class="mt-1 text-xs font-medium text-primary-600 dark:text-primary-400">{{ t('admin.settings.payment.rechargeFeePreview', { fee: (Number(form.payment_recharge_fee_rate) || 0).toFixed(2) }) }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user