feat: add configurable payment amount precision

- add system.amount_precision setting with 2-6 validation
This commit is contained in:
line-6000
2026-05-11 17:11:43 +08:00
parent 1c805ed061
commit 8d2ddbd045
178 changed files with 532 additions and 273 deletions
+29 -1
View File
@@ -1,6 +1,8 @@
package admin
import (
"fmt"
"strconv"
"strings"
"github.com/GMWalletApp/epusdt/model/dao"
@@ -48,6 +50,7 @@ import (
//
// - group=system:
// system.order_expiration_time (int) — order expiry in minutes
// system.amount_precision (int) — payment amount precision, 2-6 decimals (default 2)
type SettingUpsertItem struct {
Group string `json:"group" enums:"brand,rate,system,epay,okpay" example:"epay"`
Key string `json:"key" example:"epay.default_network"`
@@ -91,7 +94,7 @@ func (c *BaseAdminController) ListSettings(ctx echo.Context) error {
// @Description okpay group keys: okpay.enabled, okpay.shop_id, okpay.shop_token, okpay.api_url, okpay.callback_url, okpay.return_url, okpay.timeout_seconds, okpay.allow_tokens.
// @Description rate group keys: rate.forced_usdt_rate (>0 overrides USDT/CNY; <=0 uses rate.api_url), rate.api_url, rate.adjust_percent, rate.okx_c2c_enabled.
// @Description brand group keys: brand.checkout_name, brand.logo_url, brand.site_title, brand.success_copy, brand.support_url, brand.background_color, brand.background_image_url. Legacy aliases brand.site_name, brand.page_title and brand.pay_success_text are also supported.
// @Description system group keys: system.order_expiration_time.
// @Description system group keys: system.order_expiration_time, system.amount_precision (int, 2-6, default 2).
// @Tags Admin Settings
// @Security AdminJWT
// @Accept json
@@ -120,6 +123,14 @@ func (c *BaseAdminController) UpsertSettings(ctx echo.Context) error {
out = append(out, result{Key: item.Key, OK: false, Error: "key required"})
continue
}
if err := validateSettingItem(item.Group, key, item.Value); err != nil {
out = append(out, result{Key: key, OK: false, Error: err.Error()})
continue
}
if key == mdb.SettingKeyAmountPrecision {
item.Group = mdb.SettingGroupSystem
item.Type = mdb.SettingTypeInt
}
if err := data.SetSetting(item.Group, key, item.Value, item.Type); err != nil {
out = append(out, result{Key: key, OK: false, Error: err.Error()})
continue
@@ -148,6 +159,23 @@ func (c *BaseAdminController) UpsertSettings(ctx echo.Context) error {
return c.SucJson(ctx, out)
}
func validateSettingItem(group, key, value string) error {
switch key {
case mdb.SettingKeyAmountPrecision:
if strings.ToLower(strings.TrimSpace(group)) != mdb.SettingGroupSystem {
return fmt.Errorf("%s must use group %s", key, mdb.SettingGroupSystem)
}
precision, err := strconv.Atoi(strings.TrimSpace(value))
if err != nil {
return fmt.Errorf("%s must be an integer", key)
}
if precision < data.MinAmountPrecision || precision > data.MaxAmountPrecision {
return fmt.Errorf("%s must be between %d and %d", key, data.MinAmountPrecision, data.MaxAmountPrecision)
}
}
return nil
}
// DeleteSetting removes one row. The next read of that key will fall
// back to the hardcoded default (see settings_data.GetSetting*).
// @Summary Delete setting