fix: gofmt formatting across all Go source files
This commit is contained in:
@@ -310,11 +310,11 @@ type UpdateSettingsRequest struct {
|
||||
EnableCCHSigning *bool `json:"enable_cch_signing"`
|
||||
|
||||
// Balance low notification
|
||||
BalanceLowNotifyEnabled *bool `json:"balance_low_notify_enabled"`
|
||||
BalanceLowNotifyThreshold *float64 `json:"balance_low_notify_threshold"`
|
||||
BalanceLowNotifyRechargeURL *string `json:"balance_low_notify_recharge_url"`
|
||||
AccountQuotaNotifyEnabled *bool `json:"account_quota_notify_enabled"`
|
||||
AccountQuotaNotifyEmails *[]dto.NotifyEmailEntry `json:"account_quota_notify_emails"`
|
||||
BalanceLowNotifyEnabled *bool `json:"balance_low_notify_enabled"`
|
||||
BalanceLowNotifyThreshold *float64 `json:"balance_low_notify_threshold"`
|
||||
BalanceLowNotifyRechargeURL *string `json:"balance_low_notify_recharge_url"`
|
||||
AccountQuotaNotifyEnabled *bool `json:"account_quota_notify_enabled"`
|
||||
AccountQuotaNotifyEmails *[]dto.NotifyEmailEntry `json:"account_quota_notify_emails"`
|
||||
|
||||
// Payment configuration (integrated into settings, full replace)
|
||||
PaymentEnabled *bool `json:"payment_enabled"`
|
||||
|
||||
@@ -150,11 +150,11 @@ type SystemSettings struct {
|
||||
PaymentCancelRateLimitMode string `json:"payment_cancel_rate_limit_window_mode"`
|
||||
|
||||
// Balance low notification
|
||||
BalanceLowNotifyEnabled bool `json:"balance_low_notify_enabled"`
|
||||
BalanceLowNotifyThreshold float64 `json:"balance_low_notify_threshold"`
|
||||
BalanceLowNotifyRechargeURL string `json:"balance_low_notify_recharge_url"`
|
||||
AccountQuotaNotifyEnabled bool `json:"account_quota_notify_enabled"`
|
||||
AccountQuotaNotifyEmails []NotifyEmailEntry `json:"account_quota_notify_emails"`
|
||||
BalanceLowNotifyEnabled bool `json:"balance_low_notify_enabled"`
|
||||
BalanceLowNotifyThreshold float64 `json:"balance_low_notify_threshold"`
|
||||
BalanceLowNotifyRechargeURL string `json:"balance_low_notify_recharge_url"`
|
||||
AccountQuotaNotifyEnabled bool `json:"account_quota_notify_enabled"`
|
||||
AccountQuotaNotifyEmails []NotifyEmailEntry `json:"account_quota_notify_emails"`
|
||||
}
|
||||
|
||||
type DefaultSubscriptionSetting struct {
|
||||
|
||||
@@ -19,11 +19,11 @@ type User struct {
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// 余额不足通知
|
||||
BalanceNotifyEnabled bool `json:"balance_notify_enabled"`
|
||||
BalanceNotifyThresholdType string `json:"balance_notify_threshold_type"`
|
||||
BalanceNotifyThreshold *float64 `json:"balance_notify_threshold"`
|
||||
BalanceNotifyEnabled bool `json:"balance_notify_enabled"`
|
||||
BalanceNotifyThresholdType string `json:"balance_notify_threshold_type"`
|
||||
BalanceNotifyThreshold *float64 `json:"balance_notify_threshold"`
|
||||
BalanceNotifyExtraEmails []NotifyEmailEntry `json:"balance_notify_extra_emails"`
|
||||
TotalRecharged float64 `json:"total_recharged"`
|
||||
TotalRecharged float64 `json:"total_recharged"`
|
||||
|
||||
APIKeys []APIKey `json:"api_keys,omitempty"`
|
||||
Subscriptions []UserSubscription `json:"subscriptions,omitempty"`
|
||||
|
||||
@@ -242,7 +242,7 @@ func TestFilterByLimits(t *testing.T) {
|
||||
wantIDs: nil,
|
||||
},
|
||||
{
|
||||
name: "empty candidates returns empty",
|
||||
name: "empty candidates returns empty",
|
||||
candidates: nil,
|
||||
paymentType: "alipay",
|
||||
orderAmount: 10,
|
||||
|
||||
@@ -98,9 +98,9 @@ func TestNewAlipay(t *testing.T) {
|
||||
errSubstr: "privateKey",
|
||||
},
|
||||
{
|
||||
name: "nil config map returns error for appId",
|
||||
config: map[string]string{},
|
||||
wantErr: true,
|
||||
name: "nil config map returns error for appId",
|
||||
config: map[string]string{},
|
||||
wantErr: true,
|
||||
errSubstr: "appId",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1533,39 +1533,48 @@ func (a *Account) QuotaNotifyConfig(dim string) (enabled bool, threshold float64
|
||||
}
|
||||
|
||||
func (a *Account) GetQuotaNotifyDailyEnabled() bool {
|
||||
e, _, _ := a.QuotaNotifyConfig(quotaDimDaily); return e
|
||||
e, _, _ := a.QuotaNotifyConfig(quotaDimDaily)
|
||||
return e
|
||||
}
|
||||
|
||||
func (a *Account) GetQuotaNotifyDailyThreshold() float64 {
|
||||
_, t, _ := a.QuotaNotifyConfig(quotaDimDaily); return t
|
||||
_, t, _ := a.QuotaNotifyConfig(quotaDimDaily)
|
||||
return t
|
||||
}
|
||||
|
||||
func (a *Account) GetQuotaNotifyDailyThresholdType() string {
|
||||
_, _, tt := a.QuotaNotifyConfig(quotaDimDaily); return tt
|
||||
_, _, tt := a.QuotaNotifyConfig(quotaDimDaily)
|
||||
return tt
|
||||
}
|
||||
|
||||
func (a *Account) GetQuotaNotifyWeeklyEnabled() bool {
|
||||
e, _, _ := a.QuotaNotifyConfig(quotaDimWeekly); return e
|
||||
e, _, _ := a.QuotaNotifyConfig(quotaDimWeekly)
|
||||
return e
|
||||
}
|
||||
|
||||
func (a *Account) GetQuotaNotifyWeeklyThreshold() float64 {
|
||||
_, t, _ := a.QuotaNotifyConfig(quotaDimWeekly); return t
|
||||
_, t, _ := a.QuotaNotifyConfig(quotaDimWeekly)
|
||||
return t
|
||||
}
|
||||
|
||||
func (a *Account) GetQuotaNotifyWeeklyThresholdType() string {
|
||||
_, _, tt := a.QuotaNotifyConfig(quotaDimWeekly); return tt
|
||||
_, _, tt := a.QuotaNotifyConfig(quotaDimWeekly)
|
||||
return tt
|
||||
}
|
||||
|
||||
func (a *Account) GetQuotaNotifyTotalEnabled() bool {
|
||||
e, _, _ := a.QuotaNotifyConfig(quotaDimTotal); return e
|
||||
e, _, _ := a.QuotaNotifyConfig(quotaDimTotal)
|
||||
return e
|
||||
}
|
||||
|
||||
func (a *Account) GetQuotaNotifyTotalThreshold() float64 {
|
||||
_, t, _ := a.QuotaNotifyConfig(quotaDimTotal); return t
|
||||
_, t, _ := a.QuotaNotifyConfig(quotaDimTotal)
|
||||
return t
|
||||
}
|
||||
|
||||
func (a *Account) GetQuotaNotifyTotalThresholdType() string {
|
||||
_, _, tt := a.QuotaNotifyConfig(quotaDimTotal); return tt
|
||||
_, _, tt := a.QuotaNotifyConfig(quotaDimTotal)
|
||||
return tt
|
||||
}
|
||||
|
||||
// nextFixedDailyReset 计算在 after 之后的下一个每日固定重置时间点
|
||||
|
||||
@@ -65,15 +65,15 @@ func TestBuildBalanceLowEmailBody_NoRechargeURLOmitsButton(t *testing.T) {
|
||||
func TestBuildQuotaAlertEmailBody_AllFieldsPresent(t *testing.T) {
|
||||
s := &BalanceNotifyService{}
|
||||
body := s.buildQuotaAlertEmailBody(
|
||||
42, // accountID
|
||||
"acc-foo", // accountName
|
||||
"anthropic", // platform
|
||||
"日限额 / Daily", // dimLabel
|
||||
750.50, // used
|
||||
1000.0, // limit
|
||||
249.50, // remaining
|
||||
"$249.50", // thresholdDisplay
|
||||
"MySite", // siteName
|
||||
42, // accountID
|
||||
"acc-foo", // accountName
|
||||
"anthropic", // platform
|
||||
"日限额 / Daily", // dimLabel
|
||||
750.50, // used
|
||||
1000.0, // limit
|
||||
249.50, // remaining
|
||||
"$249.50", // thresholdDisplay
|
||||
"MySite", // siteName
|
||||
)
|
||||
|
||||
require.Contains(t, body, "MySite")
|
||||
|
||||
@@ -251,8 +251,8 @@ const (
|
||||
SettingKeyEnableCCHSigning = "enable_cch_signing"
|
||||
|
||||
// Balance Low Notification
|
||||
SettingKeyBalanceLowNotifyEnabled = "balance_low_notify_enabled" // 全局开关
|
||||
SettingKeyBalanceLowNotifyThreshold = "balance_low_notify_threshold" // 默认阈值(USD)
|
||||
SettingKeyBalanceLowNotifyEnabled = "balance_low_notify_enabled" // 全局开关
|
||||
SettingKeyBalanceLowNotifyThreshold = "balance_low_notify_threshold" // 默认阈值(USD)
|
||||
SettingKeyBalanceLowNotifyRechargeURL = "balance_low_notify_recharge_url" // 充值页面 URL
|
||||
|
||||
// Account Quota Notification
|
||||
|
||||
@@ -131,9 +131,9 @@ func TestValidatePlanPatch_NilOriginalPrice(t *testing.T) {
|
||||
|
||||
// --- validatePlanPatch: other fields ---
|
||||
|
||||
func ptrStr(s string) *string { return &s }
|
||||
func ptrInt(i int) *int { return &i }
|
||||
func ptrInt64(i int64) *int64 { return &i }
|
||||
func ptrStr(s string) *string { return &s }
|
||||
func ptrInt(i int) *int { return &i }
|
||||
func ptrInt64(i int64) *int64 { return &i }
|
||||
func ptrFloat(f float64) *float64 { return &f }
|
||||
|
||||
func TestValidatePlanPatch_EmptyName(t *testing.T) {
|
||||
|
||||
@@ -22,16 +22,17 @@ func (s *PaymentConfigService) ListProviderInstances(ctx context.Context) ([]*db
|
||||
|
||||
// ProviderInstanceResponse is the API response for a provider instance.
|
||||
type ProviderInstanceResponse struct {
|
||||
ID int64 `json:"id"`
|
||||
ProviderKey string `json:"provider_key"`
|
||||
Name string `json:"name"`
|
||||
Config map[string]string `json:"config"`
|
||||
SupportedTypes []string `json:"supported_types"`
|
||||
Limits string `json:"limits"`
|
||||
Enabled bool `json:"enabled"`
|
||||
RefundEnabled bool `json:"refund_enabled"`
|
||||
SortOrder int `json:"sort_order"`
|
||||
PaymentMode string `json:"payment_mode"`
|
||||
ID int64 `json:"id"`
|
||||
ProviderKey string `json:"provider_key"`
|
||||
Name string `json:"name"`
|
||||
Config map[string]string `json:"config"`
|
||||
SupportedTypes []string `json:"supported_types"`
|
||||
Limits string `json:"limits"`
|
||||
Enabled bool `json:"enabled"`
|
||||
RefundEnabled bool `json:"refund_enabled"`
|
||||
AllowUserRefund bool `json:"allow_user_refund"`
|
||||
SortOrder int `json:"sort_order"`
|
||||
PaymentMode string `json:"payment_mode"`
|
||||
}
|
||||
|
||||
// ListProviderInstancesWithConfig returns provider instances with decrypted config.
|
||||
@@ -46,8 +47,8 @@ func (s *PaymentConfigService) ListProviderInstancesWithConfig(ctx context.Conte
|
||||
resp := ProviderInstanceResponse{
|
||||
ID: int64(inst.ID), ProviderKey: inst.ProviderKey, Name: inst.Name,
|
||||
SupportedTypes: splitTypes(inst.SupportedTypes), Limits: inst.Limits,
|
||||
Enabled: inst.Enabled, RefundEnabled: inst.RefundEnabled, SortOrder: inst.SortOrder,
|
||||
PaymentMode: inst.PaymentMode,
|
||||
Enabled: inst.Enabled, RefundEnabled: inst.RefundEnabled, AllowUserRefund: inst.AllowUserRefund,
|
||||
SortOrder: inst.SortOrder, PaymentMode: inst.PaymentMode,
|
||||
}
|
||||
resp.Config, err = s.decryptAndMaskConfig(inst.Config)
|
||||
if err != nil {
|
||||
@@ -110,10 +111,12 @@ func (s *PaymentConfigService) CreateProviderInstance(ctx context.Context, req C
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
allowUserRefund := req.AllowUserRefund && req.RefundEnabled
|
||||
return s.entClient.PaymentProviderInstance.Create().
|
||||
SetProviderKey(req.ProviderKey).SetName(req.Name).SetConfig(enc).
|
||||
SetSupportedTypes(typesStr).SetEnabled(req.Enabled).SetPaymentMode(req.PaymentMode).
|
||||
SetSortOrder(req.SortOrder).SetLimits(req.Limits).SetRefundEnabled(req.RefundEnabled).
|
||||
SetAllowUserRefund(allowUserRefund).
|
||||
Save(ctx)
|
||||
}
|
||||
|
||||
@@ -221,6 +224,21 @@ func (s *PaymentConfigService) UpdateProviderInstance(ctx context.Context, id in
|
||||
}
|
||||
if req.RefundEnabled != nil {
|
||||
u.SetRefundEnabled(*req.RefundEnabled)
|
||||
// Cascade: turning off refund_enabled also disables allow_user_refund
|
||||
if !*req.RefundEnabled {
|
||||
u.SetAllowUserRefund(false)
|
||||
}
|
||||
}
|
||||
if req.AllowUserRefund != nil {
|
||||
// Only allow enabling when refund_enabled is true
|
||||
if *req.AllowUserRefund {
|
||||
inst, err := s.entClient.PaymentProviderInstance.Get(ctx, id)
|
||||
if err == nil && inst.RefundEnabled {
|
||||
u.SetAllowUserRefund(true)
|
||||
}
|
||||
} else {
|
||||
u.SetAllowUserRefund(false)
|
||||
}
|
||||
}
|
||||
if req.PaymentMode != nil {
|
||||
u.SetPaymentMode(*req.PaymentMode)
|
||||
@@ -228,6 +246,23 @@ func (s *PaymentConfigService) UpdateProviderInstance(ctx context.Context, id in
|
||||
return u.Save(ctx)
|
||||
}
|
||||
|
||||
// GetUserRefundEligibleInstanceIDs returns provider instance IDs that allow user refund.
|
||||
func (s *PaymentConfigService) GetUserRefundEligibleInstanceIDs(ctx context.Context) ([]string, error) {
|
||||
instances, err := s.entClient.PaymentProviderInstance.Query().
|
||||
Where(
|
||||
paymentproviderinstance.AllowUserRefundEQ(true),
|
||||
paymentproviderinstance.RefundEnabledEQ(true),
|
||||
).Select(paymentproviderinstance.FieldID).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ids := make([]string, 0, len(instances))
|
||||
for _, inst := range instances {
|
||||
ids = append(ids, strconv.FormatInt(int64(inst.ID), 10))
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (s *PaymentConfigService) mergeConfig(ctx context.Context, id int64, newConfig map[string]string) (map[string]string, error) {
|
||||
inst, err := s.entClient.PaymentProviderInstance.Get(ctx, id)
|
||||
if err != nil {
|
||||
|
||||
@@ -101,7 +101,7 @@ func TestIsSensitiveConfigField(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
field string
|
||||
field string
|
||||
wantSen bool
|
||||
}{
|
||||
// Sensitive fields (contain key/secret/private/password/pkey patterns)
|
||||
|
||||
@@ -105,26 +105,28 @@ type MethodLimitsResponse struct {
|
||||
}
|
||||
|
||||
type CreateProviderInstanceRequest struct {
|
||||
ProviderKey string `json:"provider_key"`
|
||||
Name string `json:"name"`
|
||||
Config map[string]string `json:"config"`
|
||||
SupportedTypes []string `json:"supported_types"`
|
||||
Enabled bool `json:"enabled"`
|
||||
PaymentMode string `json:"payment_mode"`
|
||||
SortOrder int `json:"sort_order"`
|
||||
Limits string `json:"limits"`
|
||||
RefundEnabled bool `json:"refund_enabled"`
|
||||
ProviderKey string `json:"provider_key"`
|
||||
Name string `json:"name"`
|
||||
Config map[string]string `json:"config"`
|
||||
SupportedTypes []string `json:"supported_types"`
|
||||
Enabled bool `json:"enabled"`
|
||||
PaymentMode string `json:"payment_mode"`
|
||||
SortOrder int `json:"sort_order"`
|
||||
Limits string `json:"limits"`
|
||||
RefundEnabled bool `json:"refund_enabled"`
|
||||
AllowUserRefund bool `json:"allow_user_refund"`
|
||||
}
|
||||
|
||||
type UpdateProviderInstanceRequest struct {
|
||||
Name *string `json:"name"`
|
||||
Config map[string]string `json:"config"`
|
||||
SupportedTypes []string `json:"supported_types"`
|
||||
Enabled *bool `json:"enabled"`
|
||||
PaymentMode *string `json:"payment_mode"`
|
||||
SortOrder *int `json:"sort_order"`
|
||||
Limits *string `json:"limits"`
|
||||
RefundEnabled *bool `json:"refund_enabled"`
|
||||
Name *string `json:"name"`
|
||||
Config map[string]string `json:"config"`
|
||||
SupportedTypes []string `json:"supported_types"`
|
||||
Enabled *bool `json:"enabled"`
|
||||
PaymentMode *string `json:"payment_mode"`
|
||||
SortOrder *int `json:"sort_order"`
|
||||
Limits *string `json:"limits"`
|
||||
RefundEnabled *bool `json:"refund_enabled"`
|
||||
AllowUserRefund *bool `json:"allow_user_refund"`
|
||||
}
|
||||
type CreatePlanRequest struct {
|
||||
GroupID int64 `json:"group_id"`
|
||||
|
||||
@@ -66,7 +66,7 @@ func TestSettingService_GetPublicSettings_ExposesRegistrationEmailSuffixWhitelis
|
||||
func TestSettingService_GetPublicSettings_ExposesTablePreferences(t *testing.T) {
|
||||
repo := &settingPublicRepoStub{
|
||||
values: map[string]string{
|
||||
SettingKeyTableDefaultPageSize: "50",
|
||||
SettingKeyTableDefaultPageSize: "50",
|
||||
SettingKeyTablePageSizeOptions: "[20,50,100]",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ func TestSettingService_UpdateSettings_TablePreferences(t *testing.T) {
|
||||
svc := NewSettingService(repo, &config.Config{})
|
||||
|
||||
err := svc.UpdateSettings(context.Background(), &SystemSettings{
|
||||
TableDefaultPageSize: 50,
|
||||
TableDefaultPageSize: 50,
|
||||
TablePageSizeOptions: []int{20, 50, 100},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -216,7 +216,7 @@ func TestSettingService_UpdateSettings_TablePreferences(t *testing.T) {
|
||||
require.Equal(t, "[20,50,100]", repo.updates[SettingKeyTablePageSizeOptions])
|
||||
|
||||
err = svc.UpdateSettings(context.Background(), &SystemSettings{
|
||||
TableDefaultPageSize: 1000,
|
||||
TableDefaultPageSize: 1000,
|
||||
TablePageSizeOptions: []int{20, 100},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -108,8 +108,8 @@ type SystemSettings struct {
|
||||
EnableCCHSigning bool // 是否对 billing header cch 进行签名(默认 false)
|
||||
|
||||
// Balance low notification
|
||||
BalanceLowNotifyEnabled bool
|
||||
BalanceLowNotifyThreshold float64
|
||||
BalanceLowNotifyEnabled bool
|
||||
BalanceLowNotifyThreshold float64
|
||||
BalanceLowNotifyRechargeURL string
|
||||
|
||||
// Account quota notification
|
||||
@@ -155,10 +155,10 @@ type PublicSettings struct {
|
||||
OIDCOAuthProviderName string
|
||||
Version string
|
||||
|
||||
BalanceLowNotifyEnabled bool
|
||||
AccountQuotaNotifyEnabled bool
|
||||
BalanceLowNotifyThreshold float64
|
||||
BalanceLowNotifyRechargeURL string
|
||||
BalanceLowNotifyEnabled bool
|
||||
AccountQuotaNotifyEnabled bool
|
||||
BalanceLowNotifyThreshold float64
|
||||
BalanceLowNotifyRechargeURL string
|
||||
}
|
||||
|
||||
// StreamTimeoutSettings 流超时处理配置(仅控制超时后的处理方式,超时判定由网关配置控制)
|
||||
|
||||
@@ -100,9 +100,22 @@ func valueOrZero(v *int64) int64 {
|
||||
return *v
|
||||
}
|
||||
|
||||
// AccountQuotaState holds the post-increment quota state returned by the DB transaction.
|
||||
// All values are post-update (i.e., already include the increment).
|
||||
type AccountQuotaState struct {
|
||||
TotalUsed float64
|
||||
TotalLimit float64
|
||||
DailyUsed float64
|
||||
DailyLimit float64
|
||||
WeeklyUsed float64
|
||||
WeeklyLimit float64
|
||||
}
|
||||
|
||||
type UsageBillingApplyResult struct {
|
||||
Applied bool
|
||||
APIKeyQuotaExhausted bool
|
||||
NewBalance *float64 // post-deduction balance (nil = no balance deduction)
|
||||
QuotaState *AccountQuotaState // post-increment quota state (nil = no quota increment)
|
||||
}
|
||||
|
||||
type UsageBillingRepository interface {
|
||||
|
||||
@@ -32,7 +32,7 @@ type User struct {
|
||||
|
||||
// 余额不足通知
|
||||
BalanceNotifyEnabled bool
|
||||
BalanceNotifyThresholdType string // "fixed" (default) | "percentage"
|
||||
BalanceNotifyThresholdType string // "fixed" (default) | "percentage"
|
||||
BalanceNotifyThreshold *float64
|
||||
BalanceNotifyExtraEmails []NotifyEmailEntry
|
||||
TotalRecharged float64
|
||||
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUserNotFound = infraerrors.NotFound("USER_NOT_FOUND", "user not found")
|
||||
ErrPasswordIncorrect = infraerrors.BadRequest("PASSWORD_INCORRECT", "current password is incorrect")
|
||||
ErrInsufficientPerms = infraerrors.Forbidden("INSUFFICIENT_PERMISSIONS", "insufficient permissions")
|
||||
ErrUserNotFound = infraerrors.NotFound("USER_NOT_FOUND", "user not found")
|
||||
ErrPasswordIncorrect = infraerrors.BadRequest("PASSWORD_INCORRECT", "current password is incorrect")
|
||||
ErrInsufficientPerms = infraerrors.Forbidden("INSUFFICIENT_PERMISSIONS", "insufficient permissions")
|
||||
ErrNotifyCodeUserRateLimit = infraerrors.TooManyRequests("NOTIFY_CODE_USER_RATE_LIMIT", "too many verification codes requested, please try again later")
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user