feat(notify): add percentage threshold type for balance low notification
- Add threshold_type field (fixed/percentage) to system and user settings - Add total_recharged field to users table, auto-incremented on balance credit - Percentage mode: effective threshold = total_recharged × percentage / 100 - User-level threshold_type inherits from system default when not set - Update admin settings UI with radio selector (fixed amount / percentage) - Migration: 102_add_balance_notify_threshold_type.sql
This commit is contained in:
parent
d0674e0ff9
commit
f694afbbf4
@ -1079,8 +1079,10 @@ var (
|
|||||||
{Name: "totp_enabled", Type: field.TypeBool, Default: false},
|
{Name: "totp_enabled", Type: field.TypeBool, Default: false},
|
||||||
{Name: "totp_enabled_at", Type: field.TypeTime, Nullable: true},
|
{Name: "totp_enabled_at", Type: field.TypeTime, Nullable: true},
|
||||||
{Name: "balance_notify_enabled", Type: field.TypeBool, Default: true},
|
{Name: "balance_notify_enabled", Type: field.TypeBool, Default: true},
|
||||||
|
{Name: "balance_notify_threshold_type", Type: field.TypeString, Default: "fixed"},
|
||||||
{Name: "balance_notify_threshold", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
{Name: "balance_notify_threshold", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||||
{Name: "balance_notify_extra_emails", Type: field.TypeString, Default: "[]", SchemaType: map[string]string{"postgres": "text"}},
|
{Name: "balance_notify_extra_emails", Type: field.TypeString, Default: "[]", SchemaType: map[string]string{"postgres": "text"}},
|
||||||
|
{Name: "total_recharged", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||||
}
|
}
|
||||||
// UsersTable holds the schema information for the "users" table.
|
// UsersTable holds the schema information for the "users" table.
|
||||||
UsersTable = &schema.Table{
|
UsersTable = &schema.Table{
|
||||||
|
|||||||
@ -28211,9 +28211,12 @@ type UserMutation struct {
|
|||||||
totp_enabled *bool
|
totp_enabled *bool
|
||||||
totp_enabled_at *time.Time
|
totp_enabled_at *time.Time
|
||||||
balance_notify_enabled *bool
|
balance_notify_enabled *bool
|
||||||
|
balance_notify_threshold_type *string
|
||||||
balance_notify_threshold *float64
|
balance_notify_threshold *float64
|
||||||
addbalance_notify_threshold *float64
|
addbalance_notify_threshold *float64
|
||||||
balance_notify_extra_emails *string
|
balance_notify_extra_emails *string
|
||||||
|
total_recharged *float64
|
||||||
|
addtotal_recharged *float64
|
||||||
clearedFields map[string]struct{}
|
clearedFields map[string]struct{}
|
||||||
api_keys map[int64]struct{}
|
api_keys map[int64]struct{}
|
||||||
removedapi_keys map[int64]struct{}
|
removedapi_keys map[int64]struct{}
|
||||||
@ -28967,6 +28970,42 @@ func (m *UserMutation) ResetBalanceNotifyEnabled() {
|
|||||||
m.balance_notify_enabled = nil
|
m.balance_notify_enabled = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field.
|
||||||
|
func (m *UserMutation) SetBalanceNotifyThresholdType(s string) {
|
||||||
|
m.balance_notify_threshold_type = &s
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdType returns the value of the "balance_notify_threshold_type" field in the mutation.
|
||||||
|
func (m *UserMutation) BalanceNotifyThresholdType() (r string, exists bool) {
|
||||||
|
v := m.balance_notify_threshold_type
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldBalanceNotifyThresholdType returns the old "balance_notify_threshold_type" field's value of the User entity.
|
||||||
|
// If the User object wasn't provided to the builder, the object is fetched from the database.
|
||||||
|
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||||
|
func (m *UserMutation) OldBalanceNotifyThresholdType(ctx context.Context) (v string, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldBalanceNotifyThresholdType is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldBalanceNotifyThresholdType requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldBalanceNotifyThresholdType: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.BalanceNotifyThresholdType, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetBalanceNotifyThresholdType resets all changes to the "balance_notify_threshold_type" field.
|
||||||
|
func (m *UserMutation) ResetBalanceNotifyThresholdType() {
|
||||||
|
m.balance_notify_threshold_type = nil
|
||||||
|
}
|
||||||
|
|
||||||
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
||||||
func (m *UserMutation) SetBalanceNotifyThreshold(f float64) {
|
func (m *UserMutation) SetBalanceNotifyThreshold(f float64) {
|
||||||
m.balance_notify_threshold = &f
|
m.balance_notify_threshold = &f
|
||||||
@ -29073,6 +29112,62 @@ func (m *UserMutation) ResetBalanceNotifyExtraEmails() {
|
|||||||
m.balance_notify_extra_emails = nil
|
m.balance_notify_extra_emails = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTotalRecharged sets the "total_recharged" field.
|
||||||
|
func (m *UserMutation) SetTotalRecharged(f float64) {
|
||||||
|
m.total_recharged = &f
|
||||||
|
m.addtotal_recharged = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TotalRecharged returns the value of the "total_recharged" field in the mutation.
|
||||||
|
func (m *UserMutation) TotalRecharged() (r float64, exists bool) {
|
||||||
|
v := m.total_recharged
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldTotalRecharged returns the old "total_recharged" field's value of the User entity.
|
||||||
|
// If the User object wasn't provided to the builder, the object is fetched from the database.
|
||||||
|
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||||
|
func (m *UserMutation) OldTotalRecharged(ctx context.Context) (v float64, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldTotalRecharged is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldTotalRecharged requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldTotalRecharged: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.TotalRecharged, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTotalRecharged adds f to the "total_recharged" field.
|
||||||
|
func (m *UserMutation) AddTotalRecharged(f float64) {
|
||||||
|
if m.addtotal_recharged != nil {
|
||||||
|
*m.addtotal_recharged += f
|
||||||
|
} else {
|
||||||
|
m.addtotal_recharged = &f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddedTotalRecharged returns the value that was added to the "total_recharged" field in this mutation.
|
||||||
|
func (m *UserMutation) AddedTotalRecharged() (r float64, exists bool) {
|
||||||
|
v := m.addtotal_recharged
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetTotalRecharged resets all changes to the "total_recharged" field.
|
||||||
|
func (m *UserMutation) ResetTotalRecharged() {
|
||||||
|
m.total_recharged = nil
|
||||||
|
m.addtotal_recharged = nil
|
||||||
|
}
|
||||||
|
|
||||||
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by ids.
|
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by ids.
|
||||||
func (m *UserMutation) AddAPIKeyIDs(ids ...int64) {
|
func (m *UserMutation) AddAPIKeyIDs(ids ...int64) {
|
||||||
if m.api_keys == nil {
|
if m.api_keys == nil {
|
||||||
@ -29647,7 +29742,7 @@ func (m *UserMutation) Type() string {
|
|||||||
// order to get all numeric fields that were incremented/decremented, call
|
// order to get all numeric fields that were incremented/decremented, call
|
||||||
// AddedFields().
|
// AddedFields().
|
||||||
func (m *UserMutation) Fields() []string {
|
func (m *UserMutation) Fields() []string {
|
||||||
fields := make([]string, 0, 17)
|
fields := make([]string, 0, 19)
|
||||||
if m.created_at != nil {
|
if m.created_at != nil {
|
||||||
fields = append(fields, user.FieldCreatedAt)
|
fields = append(fields, user.FieldCreatedAt)
|
||||||
}
|
}
|
||||||
@ -29693,12 +29788,18 @@ func (m *UserMutation) Fields() []string {
|
|||||||
if m.balance_notify_enabled != nil {
|
if m.balance_notify_enabled != nil {
|
||||||
fields = append(fields, user.FieldBalanceNotifyEnabled)
|
fields = append(fields, user.FieldBalanceNotifyEnabled)
|
||||||
}
|
}
|
||||||
|
if m.balance_notify_threshold_type != nil {
|
||||||
|
fields = append(fields, user.FieldBalanceNotifyThresholdType)
|
||||||
|
}
|
||||||
if m.balance_notify_threshold != nil {
|
if m.balance_notify_threshold != nil {
|
||||||
fields = append(fields, user.FieldBalanceNotifyThreshold)
|
fields = append(fields, user.FieldBalanceNotifyThreshold)
|
||||||
}
|
}
|
||||||
if m.balance_notify_extra_emails != nil {
|
if m.balance_notify_extra_emails != nil {
|
||||||
fields = append(fields, user.FieldBalanceNotifyExtraEmails)
|
fields = append(fields, user.FieldBalanceNotifyExtraEmails)
|
||||||
}
|
}
|
||||||
|
if m.total_recharged != nil {
|
||||||
|
fields = append(fields, user.FieldTotalRecharged)
|
||||||
|
}
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29737,10 +29838,14 @@ func (m *UserMutation) Field(name string) (ent.Value, bool) {
|
|||||||
return m.TotpEnabledAt()
|
return m.TotpEnabledAt()
|
||||||
case user.FieldBalanceNotifyEnabled:
|
case user.FieldBalanceNotifyEnabled:
|
||||||
return m.BalanceNotifyEnabled()
|
return m.BalanceNotifyEnabled()
|
||||||
|
case user.FieldBalanceNotifyThresholdType:
|
||||||
|
return m.BalanceNotifyThresholdType()
|
||||||
case user.FieldBalanceNotifyThreshold:
|
case user.FieldBalanceNotifyThreshold:
|
||||||
return m.BalanceNotifyThreshold()
|
return m.BalanceNotifyThreshold()
|
||||||
case user.FieldBalanceNotifyExtraEmails:
|
case user.FieldBalanceNotifyExtraEmails:
|
||||||
return m.BalanceNotifyExtraEmails()
|
return m.BalanceNotifyExtraEmails()
|
||||||
|
case user.FieldTotalRecharged:
|
||||||
|
return m.TotalRecharged()
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
@ -29780,10 +29885,14 @@ func (m *UserMutation) OldField(ctx context.Context, name string) (ent.Value, er
|
|||||||
return m.OldTotpEnabledAt(ctx)
|
return m.OldTotpEnabledAt(ctx)
|
||||||
case user.FieldBalanceNotifyEnabled:
|
case user.FieldBalanceNotifyEnabled:
|
||||||
return m.OldBalanceNotifyEnabled(ctx)
|
return m.OldBalanceNotifyEnabled(ctx)
|
||||||
|
case user.FieldBalanceNotifyThresholdType:
|
||||||
|
return m.OldBalanceNotifyThresholdType(ctx)
|
||||||
case user.FieldBalanceNotifyThreshold:
|
case user.FieldBalanceNotifyThreshold:
|
||||||
return m.OldBalanceNotifyThreshold(ctx)
|
return m.OldBalanceNotifyThreshold(ctx)
|
||||||
case user.FieldBalanceNotifyExtraEmails:
|
case user.FieldBalanceNotifyExtraEmails:
|
||||||
return m.OldBalanceNotifyExtraEmails(ctx)
|
return m.OldBalanceNotifyExtraEmails(ctx)
|
||||||
|
case user.FieldTotalRecharged:
|
||||||
|
return m.OldTotalRecharged(ctx)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("unknown User field %s", name)
|
return nil, fmt.Errorf("unknown User field %s", name)
|
||||||
}
|
}
|
||||||
@ -29898,6 +30007,13 @@ func (m *UserMutation) SetField(name string, value ent.Value) error {
|
|||||||
}
|
}
|
||||||
m.SetBalanceNotifyEnabled(v)
|
m.SetBalanceNotifyEnabled(v)
|
||||||
return nil
|
return nil
|
||||||
|
case user.FieldBalanceNotifyThresholdType:
|
||||||
|
v, ok := value.(string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetBalanceNotifyThresholdType(v)
|
||||||
|
return nil
|
||||||
case user.FieldBalanceNotifyThreshold:
|
case user.FieldBalanceNotifyThreshold:
|
||||||
v, ok := value.(float64)
|
v, ok := value.(float64)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -29912,6 +30028,13 @@ func (m *UserMutation) SetField(name string, value ent.Value) error {
|
|||||||
}
|
}
|
||||||
m.SetBalanceNotifyExtraEmails(v)
|
m.SetBalanceNotifyExtraEmails(v)
|
||||||
return nil
|
return nil
|
||||||
|
case user.FieldTotalRecharged:
|
||||||
|
v, ok := value.(float64)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetTotalRecharged(v)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown User field %s", name)
|
return fmt.Errorf("unknown User field %s", name)
|
||||||
}
|
}
|
||||||
@ -29929,6 +30052,9 @@ func (m *UserMutation) AddedFields() []string {
|
|||||||
if m.addbalance_notify_threshold != nil {
|
if m.addbalance_notify_threshold != nil {
|
||||||
fields = append(fields, user.FieldBalanceNotifyThreshold)
|
fields = append(fields, user.FieldBalanceNotifyThreshold)
|
||||||
}
|
}
|
||||||
|
if m.addtotal_recharged != nil {
|
||||||
|
fields = append(fields, user.FieldTotalRecharged)
|
||||||
|
}
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29943,6 +30069,8 @@ func (m *UserMutation) AddedField(name string) (ent.Value, bool) {
|
|||||||
return m.AddedConcurrency()
|
return m.AddedConcurrency()
|
||||||
case user.FieldBalanceNotifyThreshold:
|
case user.FieldBalanceNotifyThreshold:
|
||||||
return m.AddedBalanceNotifyThreshold()
|
return m.AddedBalanceNotifyThreshold()
|
||||||
|
case user.FieldTotalRecharged:
|
||||||
|
return m.AddedTotalRecharged()
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
@ -29973,6 +30101,13 @@ func (m *UserMutation) AddField(name string, value ent.Value) error {
|
|||||||
}
|
}
|
||||||
m.AddBalanceNotifyThreshold(v)
|
m.AddBalanceNotifyThreshold(v)
|
||||||
return nil
|
return nil
|
||||||
|
case user.FieldTotalRecharged:
|
||||||
|
v, ok := value.(float64)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.AddTotalRecharged(v)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown User numeric field %s", name)
|
return fmt.Errorf("unknown User numeric field %s", name)
|
||||||
}
|
}
|
||||||
@ -30072,12 +30207,18 @@ func (m *UserMutation) ResetField(name string) error {
|
|||||||
case user.FieldBalanceNotifyEnabled:
|
case user.FieldBalanceNotifyEnabled:
|
||||||
m.ResetBalanceNotifyEnabled()
|
m.ResetBalanceNotifyEnabled()
|
||||||
return nil
|
return nil
|
||||||
|
case user.FieldBalanceNotifyThresholdType:
|
||||||
|
m.ResetBalanceNotifyThresholdType()
|
||||||
|
return nil
|
||||||
case user.FieldBalanceNotifyThreshold:
|
case user.FieldBalanceNotifyThreshold:
|
||||||
m.ResetBalanceNotifyThreshold()
|
m.ResetBalanceNotifyThreshold()
|
||||||
return nil
|
return nil
|
||||||
case user.FieldBalanceNotifyExtraEmails:
|
case user.FieldBalanceNotifyExtraEmails:
|
||||||
m.ResetBalanceNotifyExtraEmails()
|
m.ResetBalanceNotifyExtraEmails()
|
||||||
return nil
|
return nil
|
||||||
|
case user.FieldTotalRecharged:
|
||||||
|
m.ResetTotalRecharged()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown User field %s", name)
|
return fmt.Errorf("unknown User field %s", name)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1297,10 +1297,18 @@ func init() {
|
|||||||
userDescBalanceNotifyEnabled := userFields[11].Descriptor()
|
userDescBalanceNotifyEnabled := userFields[11].Descriptor()
|
||||||
// user.DefaultBalanceNotifyEnabled holds the default value on creation for the balance_notify_enabled field.
|
// user.DefaultBalanceNotifyEnabled holds the default value on creation for the balance_notify_enabled field.
|
||||||
user.DefaultBalanceNotifyEnabled = userDescBalanceNotifyEnabled.Default.(bool)
|
user.DefaultBalanceNotifyEnabled = userDescBalanceNotifyEnabled.Default.(bool)
|
||||||
|
// userDescBalanceNotifyThresholdType is the schema descriptor for balance_notify_threshold_type field.
|
||||||
|
userDescBalanceNotifyThresholdType := userFields[12].Descriptor()
|
||||||
|
// user.DefaultBalanceNotifyThresholdType holds the default value on creation for the balance_notify_threshold_type field.
|
||||||
|
user.DefaultBalanceNotifyThresholdType = userDescBalanceNotifyThresholdType.Default.(string)
|
||||||
// userDescBalanceNotifyExtraEmails is the schema descriptor for balance_notify_extra_emails field.
|
// userDescBalanceNotifyExtraEmails is the schema descriptor for balance_notify_extra_emails field.
|
||||||
userDescBalanceNotifyExtraEmails := userFields[13].Descriptor()
|
userDescBalanceNotifyExtraEmails := userFields[14].Descriptor()
|
||||||
// user.DefaultBalanceNotifyExtraEmails holds the default value on creation for the balance_notify_extra_emails field.
|
// user.DefaultBalanceNotifyExtraEmails holds the default value on creation for the balance_notify_extra_emails field.
|
||||||
user.DefaultBalanceNotifyExtraEmails = userDescBalanceNotifyExtraEmails.Default.(string)
|
user.DefaultBalanceNotifyExtraEmails = userDescBalanceNotifyExtraEmails.Default.(string)
|
||||||
|
// userDescTotalRecharged is the schema descriptor for total_recharged field.
|
||||||
|
userDescTotalRecharged := userFields[15].Descriptor()
|
||||||
|
// user.DefaultTotalRecharged holds the default value on creation for the total_recharged field.
|
||||||
|
user.DefaultTotalRecharged = userDescTotalRecharged.Default.(float64)
|
||||||
userallowedgroupFields := schema.UserAllowedGroup{}.Fields()
|
userallowedgroupFields := schema.UserAllowedGroup{}.Fields()
|
||||||
_ = userallowedgroupFields
|
_ = userallowedgroupFields
|
||||||
// userallowedgroupDescCreatedAt is the schema descriptor for created_at field.
|
// userallowedgroupDescCreatedAt is the schema descriptor for created_at field.
|
||||||
|
|||||||
@ -76,6 +76,8 @@ func (User) Fields() []ent.Field {
|
|||||||
// 余额不足通知
|
// 余额不足通知
|
||||||
field.Bool("balance_notify_enabled").
|
field.Bool("balance_notify_enabled").
|
||||||
Default(true),
|
Default(true),
|
||||||
|
field.String("balance_notify_threshold_type").
|
||||||
|
Default("fixed"), // "fixed" | "percentage"
|
||||||
field.Float("balance_notify_threshold").
|
field.Float("balance_notify_threshold").
|
||||||
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}).
|
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}).
|
||||||
Optional().
|
Optional().
|
||||||
@ -83,6 +85,9 @@ func (User) Fields() []ent.Field {
|
|||||||
field.String("balance_notify_extra_emails").
|
field.String("balance_notify_extra_emails").
|
||||||
SchemaType(map[string]string{dialect.Postgres: "text"}).
|
SchemaType(map[string]string{dialect.Postgres: "text"}).
|
||||||
Default("[]"),
|
Default("[]"),
|
||||||
|
field.Float("total_recharged").
|
||||||
|
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}).
|
||||||
|
Default(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -47,10 +47,14 @@ type User struct {
|
|||||||
TotpEnabledAt *time.Time `json:"totp_enabled_at,omitempty"`
|
TotpEnabledAt *time.Time `json:"totp_enabled_at,omitempty"`
|
||||||
// BalanceNotifyEnabled holds the value of the "balance_notify_enabled" field.
|
// BalanceNotifyEnabled holds the value of the "balance_notify_enabled" field.
|
||||||
BalanceNotifyEnabled bool `json:"balance_notify_enabled,omitempty"`
|
BalanceNotifyEnabled bool `json:"balance_notify_enabled,omitempty"`
|
||||||
|
// BalanceNotifyThresholdType holds the value of the "balance_notify_threshold_type" field.
|
||||||
|
BalanceNotifyThresholdType string `json:"balance_notify_threshold_type,omitempty"`
|
||||||
// BalanceNotifyThreshold holds the value of the "balance_notify_threshold" field.
|
// BalanceNotifyThreshold holds the value of the "balance_notify_threshold" field.
|
||||||
BalanceNotifyThreshold *float64 `json:"balance_notify_threshold,omitempty"`
|
BalanceNotifyThreshold *float64 `json:"balance_notify_threshold,omitempty"`
|
||||||
// BalanceNotifyExtraEmails holds the value of the "balance_notify_extra_emails" field.
|
// BalanceNotifyExtraEmails holds the value of the "balance_notify_extra_emails" field.
|
||||||
BalanceNotifyExtraEmails string `json:"balance_notify_extra_emails,omitempty"`
|
BalanceNotifyExtraEmails string `json:"balance_notify_extra_emails,omitempty"`
|
||||||
|
// TotalRecharged holds the value of the "total_recharged" field.
|
||||||
|
TotalRecharged float64 `json:"total_recharged,omitempty"`
|
||||||
// Edges holds the relations/edges for other nodes in the graph.
|
// Edges holds the relations/edges for other nodes in the graph.
|
||||||
// The values are being populated by the UserQuery when eager-loading is set.
|
// The values are being populated by the UserQuery when eager-loading is set.
|
||||||
Edges UserEdges `json:"edges"`
|
Edges UserEdges `json:"edges"`
|
||||||
@ -192,11 +196,11 @@ func (*User) scanValues(columns []string) ([]any, error) {
|
|||||||
switch columns[i] {
|
switch columns[i] {
|
||||||
case user.FieldTotpEnabled, user.FieldBalanceNotifyEnabled:
|
case user.FieldTotpEnabled, user.FieldBalanceNotifyEnabled:
|
||||||
values[i] = new(sql.NullBool)
|
values[i] = new(sql.NullBool)
|
||||||
case user.FieldBalance, user.FieldBalanceNotifyThreshold:
|
case user.FieldBalance, user.FieldBalanceNotifyThreshold, user.FieldTotalRecharged:
|
||||||
values[i] = new(sql.NullFloat64)
|
values[i] = new(sql.NullFloat64)
|
||||||
case user.FieldID, user.FieldConcurrency:
|
case user.FieldID, user.FieldConcurrency:
|
||||||
values[i] = new(sql.NullInt64)
|
values[i] = new(sql.NullInt64)
|
||||||
case user.FieldEmail, user.FieldPasswordHash, user.FieldRole, user.FieldStatus, user.FieldUsername, user.FieldNotes, user.FieldTotpSecretEncrypted, user.FieldBalanceNotifyExtraEmails:
|
case user.FieldEmail, user.FieldPasswordHash, user.FieldRole, user.FieldStatus, user.FieldUsername, user.FieldNotes, user.FieldTotpSecretEncrypted, user.FieldBalanceNotifyThresholdType, user.FieldBalanceNotifyExtraEmails:
|
||||||
values[i] = new(sql.NullString)
|
values[i] = new(sql.NullString)
|
||||||
case user.FieldCreatedAt, user.FieldUpdatedAt, user.FieldDeletedAt, user.FieldTotpEnabledAt:
|
case user.FieldCreatedAt, user.FieldUpdatedAt, user.FieldDeletedAt, user.FieldTotpEnabledAt:
|
||||||
values[i] = new(sql.NullTime)
|
values[i] = new(sql.NullTime)
|
||||||
@ -314,6 +318,12 @@ func (_m *User) assignValues(columns []string, values []any) error {
|
|||||||
} else if value.Valid {
|
} else if value.Valid {
|
||||||
_m.BalanceNotifyEnabled = value.Bool
|
_m.BalanceNotifyEnabled = value.Bool
|
||||||
}
|
}
|
||||||
|
case user.FieldBalanceNotifyThresholdType:
|
||||||
|
if value, ok := values[i].(*sql.NullString); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field balance_notify_threshold_type", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
_m.BalanceNotifyThresholdType = value.String
|
||||||
|
}
|
||||||
case user.FieldBalanceNotifyThreshold:
|
case user.FieldBalanceNotifyThreshold:
|
||||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||||
return fmt.Errorf("unexpected type %T for field balance_notify_threshold", values[i])
|
return fmt.Errorf("unexpected type %T for field balance_notify_threshold", values[i])
|
||||||
@ -327,6 +337,12 @@ func (_m *User) assignValues(columns []string, values []any) error {
|
|||||||
} else if value.Valid {
|
} else if value.Valid {
|
||||||
_m.BalanceNotifyExtraEmails = value.String
|
_m.BalanceNotifyExtraEmails = value.String
|
||||||
}
|
}
|
||||||
|
case user.FieldTotalRecharged:
|
||||||
|
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field total_recharged", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
_m.TotalRecharged = value.Float64
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
_m.selectValues.Set(columns[i], values[i])
|
_m.selectValues.Set(columns[i], values[i])
|
||||||
}
|
}
|
||||||
@ -469,6 +485,9 @@ func (_m *User) String() string {
|
|||||||
builder.WriteString("balance_notify_enabled=")
|
builder.WriteString("balance_notify_enabled=")
|
||||||
builder.WriteString(fmt.Sprintf("%v", _m.BalanceNotifyEnabled))
|
builder.WriteString(fmt.Sprintf("%v", _m.BalanceNotifyEnabled))
|
||||||
builder.WriteString(", ")
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("balance_notify_threshold_type=")
|
||||||
|
builder.WriteString(_m.BalanceNotifyThresholdType)
|
||||||
|
builder.WriteString(", ")
|
||||||
if v := _m.BalanceNotifyThreshold; v != nil {
|
if v := _m.BalanceNotifyThreshold; v != nil {
|
||||||
builder.WriteString("balance_notify_threshold=")
|
builder.WriteString("balance_notify_threshold=")
|
||||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||||
@ -476,6 +495,9 @@ func (_m *User) String() string {
|
|||||||
builder.WriteString(", ")
|
builder.WriteString(", ")
|
||||||
builder.WriteString("balance_notify_extra_emails=")
|
builder.WriteString("balance_notify_extra_emails=")
|
||||||
builder.WriteString(_m.BalanceNotifyExtraEmails)
|
builder.WriteString(_m.BalanceNotifyExtraEmails)
|
||||||
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("total_recharged=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", _m.TotalRecharged))
|
||||||
builder.WriteByte(')')
|
builder.WriteByte(')')
|
||||||
return builder.String()
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,10 +45,14 @@ const (
|
|||||||
FieldTotpEnabledAt = "totp_enabled_at"
|
FieldTotpEnabledAt = "totp_enabled_at"
|
||||||
// FieldBalanceNotifyEnabled holds the string denoting the balance_notify_enabled field in the database.
|
// FieldBalanceNotifyEnabled holds the string denoting the balance_notify_enabled field in the database.
|
||||||
FieldBalanceNotifyEnabled = "balance_notify_enabled"
|
FieldBalanceNotifyEnabled = "balance_notify_enabled"
|
||||||
|
// FieldBalanceNotifyThresholdType holds the string denoting the balance_notify_threshold_type field in the database.
|
||||||
|
FieldBalanceNotifyThresholdType = "balance_notify_threshold_type"
|
||||||
// FieldBalanceNotifyThreshold holds the string denoting the balance_notify_threshold field in the database.
|
// FieldBalanceNotifyThreshold holds the string denoting the balance_notify_threshold field in the database.
|
||||||
FieldBalanceNotifyThreshold = "balance_notify_threshold"
|
FieldBalanceNotifyThreshold = "balance_notify_threshold"
|
||||||
// FieldBalanceNotifyExtraEmails holds the string denoting the balance_notify_extra_emails field in the database.
|
// FieldBalanceNotifyExtraEmails holds the string denoting the balance_notify_extra_emails field in the database.
|
||||||
FieldBalanceNotifyExtraEmails = "balance_notify_extra_emails"
|
FieldBalanceNotifyExtraEmails = "balance_notify_extra_emails"
|
||||||
|
// FieldTotalRecharged holds the string denoting the total_recharged field in the database.
|
||||||
|
FieldTotalRecharged = "total_recharged"
|
||||||
// EdgeAPIKeys holds the string denoting the api_keys edge name in mutations.
|
// EdgeAPIKeys holds the string denoting the api_keys edge name in mutations.
|
||||||
EdgeAPIKeys = "api_keys"
|
EdgeAPIKeys = "api_keys"
|
||||||
// EdgeRedeemCodes holds the string denoting the redeem_codes edge name in mutations.
|
// EdgeRedeemCodes holds the string denoting the redeem_codes edge name in mutations.
|
||||||
@ -168,8 +172,10 @@ var Columns = []string{
|
|||||||
FieldTotpEnabled,
|
FieldTotpEnabled,
|
||||||
FieldTotpEnabledAt,
|
FieldTotpEnabledAt,
|
||||||
FieldBalanceNotifyEnabled,
|
FieldBalanceNotifyEnabled,
|
||||||
|
FieldBalanceNotifyThresholdType,
|
||||||
FieldBalanceNotifyThreshold,
|
FieldBalanceNotifyThreshold,
|
||||||
FieldBalanceNotifyExtraEmails,
|
FieldBalanceNotifyExtraEmails,
|
||||||
|
FieldTotalRecharged,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -228,8 +234,12 @@ var (
|
|||||||
DefaultTotpEnabled bool
|
DefaultTotpEnabled bool
|
||||||
// DefaultBalanceNotifyEnabled holds the default value on creation for the "balance_notify_enabled" field.
|
// DefaultBalanceNotifyEnabled holds the default value on creation for the "balance_notify_enabled" field.
|
||||||
DefaultBalanceNotifyEnabled bool
|
DefaultBalanceNotifyEnabled bool
|
||||||
|
// DefaultBalanceNotifyThresholdType holds the default value on creation for the "balance_notify_threshold_type" field.
|
||||||
|
DefaultBalanceNotifyThresholdType string
|
||||||
// DefaultBalanceNotifyExtraEmails holds the default value on creation for the "balance_notify_extra_emails" field.
|
// DefaultBalanceNotifyExtraEmails holds the default value on creation for the "balance_notify_extra_emails" field.
|
||||||
DefaultBalanceNotifyExtraEmails string
|
DefaultBalanceNotifyExtraEmails string
|
||||||
|
// DefaultTotalRecharged holds the default value on creation for the "total_recharged" field.
|
||||||
|
DefaultTotalRecharged float64
|
||||||
)
|
)
|
||||||
|
|
||||||
// OrderOption defines the ordering options for the User queries.
|
// OrderOption defines the ordering options for the User queries.
|
||||||
@ -315,6 +325,11 @@ func ByBalanceNotifyEnabled(opts ...sql.OrderTermOption) OrderOption {
|
|||||||
return sql.OrderByField(FieldBalanceNotifyEnabled, opts...).ToFunc()
|
return sql.OrderByField(FieldBalanceNotifyEnabled, opts...).ToFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ByBalanceNotifyThresholdType orders the results by the balance_notify_threshold_type field.
|
||||||
|
func ByBalanceNotifyThresholdType(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldBalanceNotifyThresholdType, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
// ByBalanceNotifyThreshold orders the results by the balance_notify_threshold field.
|
// ByBalanceNotifyThreshold orders the results by the balance_notify_threshold field.
|
||||||
func ByBalanceNotifyThreshold(opts ...sql.OrderTermOption) OrderOption {
|
func ByBalanceNotifyThreshold(opts ...sql.OrderTermOption) OrderOption {
|
||||||
return sql.OrderByField(FieldBalanceNotifyThreshold, opts...).ToFunc()
|
return sql.OrderByField(FieldBalanceNotifyThreshold, opts...).ToFunc()
|
||||||
@ -325,6 +340,11 @@ func ByBalanceNotifyExtraEmails(opts ...sql.OrderTermOption) OrderOption {
|
|||||||
return sql.OrderByField(FieldBalanceNotifyExtraEmails, opts...).ToFunc()
|
return sql.OrderByField(FieldBalanceNotifyExtraEmails, opts...).ToFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ByTotalRecharged orders the results by the total_recharged field.
|
||||||
|
func ByTotalRecharged(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldTotalRecharged, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
// ByAPIKeysCount orders the results by api_keys count.
|
// ByAPIKeysCount orders the results by api_keys count.
|
||||||
func ByAPIKeysCount(opts ...sql.OrderTermOption) OrderOption {
|
func ByAPIKeysCount(opts ...sql.OrderTermOption) OrderOption {
|
||||||
return func(s *sql.Selector) {
|
return func(s *sql.Selector) {
|
||||||
|
|||||||
@ -130,6 +130,11 @@ func BalanceNotifyEnabled(v bool) predicate.User {
|
|||||||
return predicate.User(sql.FieldEQ(FieldBalanceNotifyEnabled, v))
|
return predicate.User(sql.FieldEQ(FieldBalanceNotifyEnabled, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdType applies equality check predicate on the "balance_notify_threshold_type" field. It's identical to BalanceNotifyThresholdTypeEQ.
|
||||||
|
func BalanceNotifyThresholdType(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldEQ(FieldBalanceNotifyThresholdType, v))
|
||||||
|
}
|
||||||
|
|
||||||
// BalanceNotifyThreshold applies equality check predicate on the "balance_notify_threshold" field. It's identical to BalanceNotifyThresholdEQ.
|
// BalanceNotifyThreshold applies equality check predicate on the "balance_notify_threshold" field. It's identical to BalanceNotifyThresholdEQ.
|
||||||
func BalanceNotifyThreshold(v float64) predicate.User {
|
func BalanceNotifyThreshold(v float64) predicate.User {
|
||||||
return predicate.User(sql.FieldEQ(FieldBalanceNotifyThreshold, v))
|
return predicate.User(sql.FieldEQ(FieldBalanceNotifyThreshold, v))
|
||||||
@ -140,6 +145,11 @@ func BalanceNotifyExtraEmails(v string) predicate.User {
|
|||||||
return predicate.User(sql.FieldEQ(FieldBalanceNotifyExtraEmails, v))
|
return predicate.User(sql.FieldEQ(FieldBalanceNotifyExtraEmails, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalRecharged applies equality check predicate on the "total_recharged" field. It's identical to TotalRechargedEQ.
|
||||||
|
func TotalRecharged(v float64) predicate.User {
|
||||||
|
return predicate.User(sql.FieldEQ(FieldTotalRecharged, v))
|
||||||
|
}
|
||||||
|
|
||||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||||
func CreatedAtEQ(v time.Time) predicate.User {
|
func CreatedAtEQ(v time.Time) predicate.User {
|
||||||
return predicate.User(sql.FieldEQ(FieldCreatedAt, v))
|
return predicate.User(sql.FieldEQ(FieldCreatedAt, v))
|
||||||
@ -885,6 +895,71 @@ func BalanceNotifyEnabledNEQ(v bool) predicate.User {
|
|||||||
return predicate.User(sql.FieldNEQ(FieldBalanceNotifyEnabled, v))
|
return predicate.User(sql.FieldNEQ(FieldBalanceNotifyEnabled, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeEQ applies the EQ predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeEQ(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldEQ(FieldBalanceNotifyThresholdType, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeNEQ applies the NEQ predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeNEQ(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldNEQ(FieldBalanceNotifyThresholdType, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeIn applies the In predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeIn(vs ...string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldIn(FieldBalanceNotifyThresholdType, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeNotIn applies the NotIn predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeNotIn(vs ...string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldNotIn(FieldBalanceNotifyThresholdType, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeGT applies the GT predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeGT(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldGT(FieldBalanceNotifyThresholdType, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeGTE applies the GTE predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeGTE(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldGTE(FieldBalanceNotifyThresholdType, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeLT applies the LT predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeLT(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldLT(FieldBalanceNotifyThresholdType, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeLTE applies the LTE predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeLTE(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldLTE(FieldBalanceNotifyThresholdType, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeContains applies the Contains predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeContains(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldContains(FieldBalanceNotifyThresholdType, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeHasPrefix applies the HasPrefix predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeHasPrefix(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldHasPrefix(FieldBalanceNotifyThresholdType, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeHasSuffix applies the HasSuffix predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeHasSuffix(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldHasSuffix(FieldBalanceNotifyThresholdType, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeEqualFold applies the EqualFold predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeEqualFold(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldEqualFold(FieldBalanceNotifyThresholdType, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// BalanceNotifyThresholdTypeContainsFold applies the ContainsFold predicate on the "balance_notify_threshold_type" field.
|
||||||
|
func BalanceNotifyThresholdTypeContainsFold(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldContainsFold(FieldBalanceNotifyThresholdType, v))
|
||||||
|
}
|
||||||
|
|
||||||
// BalanceNotifyThresholdEQ applies the EQ predicate on the "balance_notify_threshold" field.
|
// BalanceNotifyThresholdEQ applies the EQ predicate on the "balance_notify_threshold" field.
|
||||||
func BalanceNotifyThresholdEQ(v float64) predicate.User {
|
func BalanceNotifyThresholdEQ(v float64) predicate.User {
|
||||||
return predicate.User(sql.FieldEQ(FieldBalanceNotifyThreshold, v))
|
return predicate.User(sql.FieldEQ(FieldBalanceNotifyThreshold, v))
|
||||||
@ -1000,6 +1075,46 @@ func BalanceNotifyExtraEmailsContainsFold(v string) predicate.User {
|
|||||||
return predicate.User(sql.FieldContainsFold(FieldBalanceNotifyExtraEmails, v))
|
return predicate.User(sql.FieldContainsFold(FieldBalanceNotifyExtraEmails, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TotalRechargedEQ applies the EQ predicate on the "total_recharged" field.
|
||||||
|
func TotalRechargedEQ(v float64) predicate.User {
|
||||||
|
return predicate.User(sql.FieldEQ(FieldTotalRecharged, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TotalRechargedNEQ applies the NEQ predicate on the "total_recharged" field.
|
||||||
|
func TotalRechargedNEQ(v float64) predicate.User {
|
||||||
|
return predicate.User(sql.FieldNEQ(FieldTotalRecharged, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TotalRechargedIn applies the In predicate on the "total_recharged" field.
|
||||||
|
func TotalRechargedIn(vs ...float64) predicate.User {
|
||||||
|
return predicate.User(sql.FieldIn(FieldTotalRecharged, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TotalRechargedNotIn applies the NotIn predicate on the "total_recharged" field.
|
||||||
|
func TotalRechargedNotIn(vs ...float64) predicate.User {
|
||||||
|
return predicate.User(sql.FieldNotIn(FieldTotalRecharged, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TotalRechargedGT applies the GT predicate on the "total_recharged" field.
|
||||||
|
func TotalRechargedGT(v float64) predicate.User {
|
||||||
|
return predicate.User(sql.FieldGT(FieldTotalRecharged, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TotalRechargedGTE applies the GTE predicate on the "total_recharged" field.
|
||||||
|
func TotalRechargedGTE(v float64) predicate.User {
|
||||||
|
return predicate.User(sql.FieldGTE(FieldTotalRecharged, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TotalRechargedLT applies the LT predicate on the "total_recharged" field.
|
||||||
|
func TotalRechargedLT(v float64) predicate.User {
|
||||||
|
return predicate.User(sql.FieldLT(FieldTotalRecharged, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TotalRechargedLTE applies the LTE predicate on the "total_recharged" field.
|
||||||
|
func TotalRechargedLTE(v float64) predicate.User {
|
||||||
|
return predicate.User(sql.FieldLTE(FieldTotalRecharged, v))
|
||||||
|
}
|
||||||
|
|
||||||
// HasAPIKeys applies the HasEdge predicate on the "api_keys" edge.
|
// HasAPIKeys applies the HasEdge predicate on the "api_keys" edge.
|
||||||
func HasAPIKeys() predicate.User {
|
func HasAPIKeys() predicate.User {
|
||||||
return predicate.User(func(s *sql.Selector) {
|
return predicate.User(func(s *sql.Selector) {
|
||||||
|
|||||||
@ -225,6 +225,20 @@ func (_c *UserCreate) SetNillableBalanceNotifyEnabled(v *bool) *UserCreate {
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field.
|
||||||
|
func (_c *UserCreate) SetBalanceNotifyThresholdType(v string) *UserCreate {
|
||||||
|
_c.mutation.SetBalanceNotifyThresholdType(v)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field if the given value is not nil.
|
||||||
|
func (_c *UserCreate) SetNillableBalanceNotifyThresholdType(v *string) *UserCreate {
|
||||||
|
if v != nil {
|
||||||
|
_c.SetBalanceNotifyThresholdType(*v)
|
||||||
|
}
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
||||||
func (_c *UserCreate) SetBalanceNotifyThreshold(v float64) *UserCreate {
|
func (_c *UserCreate) SetBalanceNotifyThreshold(v float64) *UserCreate {
|
||||||
_c.mutation.SetBalanceNotifyThreshold(v)
|
_c.mutation.SetBalanceNotifyThreshold(v)
|
||||||
@ -253,6 +267,20 @@ func (_c *UserCreate) SetNillableBalanceNotifyExtraEmails(v *string) *UserCreate
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTotalRecharged sets the "total_recharged" field.
|
||||||
|
func (_c *UserCreate) SetTotalRecharged(v float64) *UserCreate {
|
||||||
|
_c.mutation.SetTotalRecharged(v)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableTotalRecharged sets the "total_recharged" field if the given value is not nil.
|
||||||
|
func (_c *UserCreate) SetNillableTotalRecharged(v *float64) *UserCreate {
|
||||||
|
if v != nil {
|
||||||
|
_c.SetTotalRecharged(*v)
|
||||||
|
}
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs.
|
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs.
|
||||||
func (_c *UserCreate) AddAPIKeyIDs(ids ...int64) *UserCreate {
|
func (_c *UserCreate) AddAPIKeyIDs(ids ...int64) *UserCreate {
|
||||||
_c.mutation.AddAPIKeyIDs(ids...)
|
_c.mutation.AddAPIKeyIDs(ids...)
|
||||||
@ -486,10 +514,18 @@ func (_c *UserCreate) defaults() error {
|
|||||||
v := user.DefaultBalanceNotifyEnabled
|
v := user.DefaultBalanceNotifyEnabled
|
||||||
_c.mutation.SetBalanceNotifyEnabled(v)
|
_c.mutation.SetBalanceNotifyEnabled(v)
|
||||||
}
|
}
|
||||||
|
if _, ok := _c.mutation.BalanceNotifyThresholdType(); !ok {
|
||||||
|
v := user.DefaultBalanceNotifyThresholdType
|
||||||
|
_c.mutation.SetBalanceNotifyThresholdType(v)
|
||||||
|
}
|
||||||
if _, ok := _c.mutation.BalanceNotifyExtraEmails(); !ok {
|
if _, ok := _c.mutation.BalanceNotifyExtraEmails(); !ok {
|
||||||
v := user.DefaultBalanceNotifyExtraEmails
|
v := user.DefaultBalanceNotifyExtraEmails
|
||||||
_c.mutation.SetBalanceNotifyExtraEmails(v)
|
_c.mutation.SetBalanceNotifyExtraEmails(v)
|
||||||
}
|
}
|
||||||
|
if _, ok := _c.mutation.TotalRecharged(); !ok {
|
||||||
|
v := user.DefaultTotalRecharged
|
||||||
|
_c.mutation.SetTotalRecharged(v)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,9 +592,15 @@ func (_c *UserCreate) check() error {
|
|||||||
if _, ok := _c.mutation.BalanceNotifyEnabled(); !ok {
|
if _, ok := _c.mutation.BalanceNotifyEnabled(); !ok {
|
||||||
return &ValidationError{Name: "balance_notify_enabled", err: errors.New(`ent: missing required field "User.balance_notify_enabled"`)}
|
return &ValidationError{Name: "balance_notify_enabled", err: errors.New(`ent: missing required field "User.balance_notify_enabled"`)}
|
||||||
}
|
}
|
||||||
|
if _, ok := _c.mutation.BalanceNotifyThresholdType(); !ok {
|
||||||
|
return &ValidationError{Name: "balance_notify_threshold_type", err: errors.New(`ent: missing required field "User.balance_notify_threshold_type"`)}
|
||||||
|
}
|
||||||
if _, ok := _c.mutation.BalanceNotifyExtraEmails(); !ok {
|
if _, ok := _c.mutation.BalanceNotifyExtraEmails(); !ok {
|
||||||
return &ValidationError{Name: "balance_notify_extra_emails", err: errors.New(`ent: missing required field "User.balance_notify_extra_emails"`)}
|
return &ValidationError{Name: "balance_notify_extra_emails", err: errors.New(`ent: missing required field "User.balance_notify_extra_emails"`)}
|
||||||
}
|
}
|
||||||
|
if _, ok := _c.mutation.TotalRecharged(); !ok {
|
||||||
|
return &ValidationError{Name: "total_recharged", err: errors.New(`ent: missing required field "User.total_recharged"`)}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,6 +688,10 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
|
|||||||
_spec.SetField(user.FieldBalanceNotifyEnabled, field.TypeBool, value)
|
_spec.SetField(user.FieldBalanceNotifyEnabled, field.TypeBool, value)
|
||||||
_node.BalanceNotifyEnabled = value
|
_node.BalanceNotifyEnabled = value
|
||||||
}
|
}
|
||||||
|
if value, ok := _c.mutation.BalanceNotifyThresholdType(); ok {
|
||||||
|
_spec.SetField(user.FieldBalanceNotifyThresholdType, field.TypeString, value)
|
||||||
|
_node.BalanceNotifyThresholdType = value
|
||||||
|
}
|
||||||
if value, ok := _c.mutation.BalanceNotifyThreshold(); ok {
|
if value, ok := _c.mutation.BalanceNotifyThreshold(); ok {
|
||||||
_spec.SetField(user.FieldBalanceNotifyThreshold, field.TypeFloat64, value)
|
_spec.SetField(user.FieldBalanceNotifyThreshold, field.TypeFloat64, value)
|
||||||
_node.BalanceNotifyThreshold = &value
|
_node.BalanceNotifyThreshold = &value
|
||||||
@ -654,6 +700,10 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
|
|||||||
_spec.SetField(user.FieldBalanceNotifyExtraEmails, field.TypeString, value)
|
_spec.SetField(user.FieldBalanceNotifyExtraEmails, field.TypeString, value)
|
||||||
_node.BalanceNotifyExtraEmails = value
|
_node.BalanceNotifyExtraEmails = value
|
||||||
}
|
}
|
||||||
|
if value, ok := _c.mutation.TotalRecharged(); ok {
|
||||||
|
_spec.SetField(user.FieldTotalRecharged, field.TypeFloat64, value)
|
||||||
|
_node.TotalRecharged = value
|
||||||
|
}
|
||||||
if nodes := _c.mutation.APIKeysIDs(); len(nodes) > 0 {
|
if nodes := _c.mutation.APIKeysIDs(); len(nodes) > 0 {
|
||||||
edge := &sqlgraph.EdgeSpec{
|
edge := &sqlgraph.EdgeSpec{
|
||||||
Rel: sqlgraph.O2M,
|
Rel: sqlgraph.O2M,
|
||||||
@ -1068,6 +1118,18 @@ func (u *UserUpsert) UpdateBalanceNotifyEnabled() *UserUpsert {
|
|||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field.
|
||||||
|
func (u *UserUpsert) SetBalanceNotifyThresholdType(v string) *UserUpsert {
|
||||||
|
u.Set(user.FieldBalanceNotifyThresholdType, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field to the value that was provided on create.
|
||||||
|
func (u *UserUpsert) UpdateBalanceNotifyThresholdType() *UserUpsert {
|
||||||
|
u.SetExcluded(user.FieldBalanceNotifyThresholdType)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
||||||
func (u *UserUpsert) SetBalanceNotifyThreshold(v float64) *UserUpsert {
|
func (u *UserUpsert) SetBalanceNotifyThreshold(v float64) *UserUpsert {
|
||||||
u.Set(user.FieldBalanceNotifyThreshold, v)
|
u.Set(user.FieldBalanceNotifyThreshold, v)
|
||||||
@ -1104,6 +1166,24 @@ func (u *UserUpsert) UpdateBalanceNotifyExtraEmails() *UserUpsert {
|
|||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTotalRecharged sets the "total_recharged" field.
|
||||||
|
func (u *UserUpsert) SetTotalRecharged(v float64) *UserUpsert {
|
||||||
|
u.Set(user.FieldTotalRecharged, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTotalRecharged sets the "total_recharged" field to the value that was provided on create.
|
||||||
|
func (u *UserUpsert) UpdateTotalRecharged() *UserUpsert {
|
||||||
|
u.SetExcluded(user.FieldTotalRecharged)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTotalRecharged adds v to the "total_recharged" field.
|
||||||
|
func (u *UserUpsert) AddTotalRecharged(v float64) *UserUpsert {
|
||||||
|
u.Add(user.FieldTotalRecharged, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateNewValues updates the mutable fields using the new values that were set on create.
|
// UpdateNewValues updates the mutable fields using the new values that were set on create.
|
||||||
// Using this option is equivalent to using:
|
// Using this option is equivalent to using:
|
||||||
//
|
//
|
||||||
@ -1380,6 +1460,20 @@ func (u *UserUpsertOne) UpdateBalanceNotifyEnabled() *UserUpsertOne {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field.
|
||||||
|
func (u *UserUpsertOne) SetBalanceNotifyThresholdType(v string) *UserUpsertOne {
|
||||||
|
return u.Update(func(s *UserUpsert) {
|
||||||
|
s.SetBalanceNotifyThresholdType(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field to the value that was provided on create.
|
||||||
|
func (u *UserUpsertOne) UpdateBalanceNotifyThresholdType() *UserUpsertOne {
|
||||||
|
return u.Update(func(s *UserUpsert) {
|
||||||
|
s.UpdateBalanceNotifyThresholdType()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
||||||
func (u *UserUpsertOne) SetBalanceNotifyThreshold(v float64) *UserUpsertOne {
|
func (u *UserUpsertOne) SetBalanceNotifyThreshold(v float64) *UserUpsertOne {
|
||||||
return u.Update(func(s *UserUpsert) {
|
return u.Update(func(s *UserUpsert) {
|
||||||
@ -1422,6 +1516,27 @@ func (u *UserUpsertOne) UpdateBalanceNotifyExtraEmails() *UserUpsertOne {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTotalRecharged sets the "total_recharged" field.
|
||||||
|
func (u *UserUpsertOne) SetTotalRecharged(v float64) *UserUpsertOne {
|
||||||
|
return u.Update(func(s *UserUpsert) {
|
||||||
|
s.SetTotalRecharged(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTotalRecharged adds v to the "total_recharged" field.
|
||||||
|
func (u *UserUpsertOne) AddTotalRecharged(v float64) *UserUpsertOne {
|
||||||
|
return u.Update(func(s *UserUpsert) {
|
||||||
|
s.AddTotalRecharged(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTotalRecharged sets the "total_recharged" field to the value that was provided on create.
|
||||||
|
func (u *UserUpsertOne) UpdateTotalRecharged() *UserUpsertOne {
|
||||||
|
return u.Update(func(s *UserUpsert) {
|
||||||
|
s.UpdateTotalRecharged()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Exec executes the query.
|
// Exec executes the query.
|
||||||
func (u *UserUpsertOne) Exec(ctx context.Context) error {
|
func (u *UserUpsertOne) Exec(ctx context.Context) error {
|
||||||
if len(u.create.conflict) == 0 {
|
if len(u.create.conflict) == 0 {
|
||||||
@ -1864,6 +1979,20 @@ func (u *UserUpsertBulk) UpdateBalanceNotifyEnabled() *UserUpsertBulk {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field.
|
||||||
|
func (u *UserUpsertBulk) SetBalanceNotifyThresholdType(v string) *UserUpsertBulk {
|
||||||
|
return u.Update(func(s *UserUpsert) {
|
||||||
|
s.SetBalanceNotifyThresholdType(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field to the value that was provided on create.
|
||||||
|
func (u *UserUpsertBulk) UpdateBalanceNotifyThresholdType() *UserUpsertBulk {
|
||||||
|
return u.Update(func(s *UserUpsert) {
|
||||||
|
s.UpdateBalanceNotifyThresholdType()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
||||||
func (u *UserUpsertBulk) SetBalanceNotifyThreshold(v float64) *UserUpsertBulk {
|
func (u *UserUpsertBulk) SetBalanceNotifyThreshold(v float64) *UserUpsertBulk {
|
||||||
return u.Update(func(s *UserUpsert) {
|
return u.Update(func(s *UserUpsert) {
|
||||||
@ -1906,6 +2035,27 @@ func (u *UserUpsertBulk) UpdateBalanceNotifyExtraEmails() *UserUpsertBulk {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTotalRecharged sets the "total_recharged" field.
|
||||||
|
func (u *UserUpsertBulk) SetTotalRecharged(v float64) *UserUpsertBulk {
|
||||||
|
return u.Update(func(s *UserUpsert) {
|
||||||
|
s.SetTotalRecharged(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTotalRecharged adds v to the "total_recharged" field.
|
||||||
|
func (u *UserUpsertBulk) AddTotalRecharged(v float64) *UserUpsertBulk {
|
||||||
|
return u.Update(func(s *UserUpsert) {
|
||||||
|
s.AddTotalRecharged(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTotalRecharged sets the "total_recharged" field to the value that was provided on create.
|
||||||
|
func (u *UserUpsertBulk) UpdateTotalRecharged() *UserUpsertBulk {
|
||||||
|
return u.Update(func(s *UserUpsert) {
|
||||||
|
s.UpdateTotalRecharged()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Exec executes the query.
|
// Exec executes the query.
|
||||||
func (u *UserUpsertBulk) Exec(ctx context.Context) error {
|
func (u *UserUpsertBulk) Exec(ctx context.Context) error {
|
||||||
if u.create.err != nil {
|
if u.create.err != nil {
|
||||||
|
|||||||
@ -257,6 +257,20 @@ func (_u *UserUpdate) SetNillableBalanceNotifyEnabled(v *bool) *UserUpdate {
|
|||||||
return _u
|
return _u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field.
|
||||||
|
func (_u *UserUpdate) SetBalanceNotifyThresholdType(v string) *UserUpdate {
|
||||||
|
_u.mutation.SetBalanceNotifyThresholdType(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field if the given value is not nil.
|
||||||
|
func (_u *UserUpdate) SetNillableBalanceNotifyThresholdType(v *string) *UserUpdate {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetBalanceNotifyThresholdType(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
||||||
func (_u *UserUpdate) SetBalanceNotifyThreshold(v float64) *UserUpdate {
|
func (_u *UserUpdate) SetBalanceNotifyThreshold(v float64) *UserUpdate {
|
||||||
_u.mutation.ResetBalanceNotifyThreshold()
|
_u.mutation.ResetBalanceNotifyThreshold()
|
||||||
@ -298,6 +312,27 @@ func (_u *UserUpdate) SetNillableBalanceNotifyExtraEmails(v *string) *UserUpdate
|
|||||||
return _u
|
return _u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTotalRecharged sets the "total_recharged" field.
|
||||||
|
func (_u *UserUpdate) SetTotalRecharged(v float64) *UserUpdate {
|
||||||
|
_u.mutation.ResetTotalRecharged()
|
||||||
|
_u.mutation.SetTotalRecharged(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableTotalRecharged sets the "total_recharged" field if the given value is not nil.
|
||||||
|
func (_u *UserUpdate) SetNillableTotalRecharged(v *float64) *UserUpdate {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetTotalRecharged(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTotalRecharged adds value to the "total_recharged" field.
|
||||||
|
func (_u *UserUpdate) AddTotalRecharged(v float64) *UserUpdate {
|
||||||
|
_u.mutation.AddTotalRecharged(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs.
|
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs.
|
||||||
func (_u *UserUpdate) AddAPIKeyIDs(ids ...int64) *UserUpdate {
|
func (_u *UserUpdate) AddAPIKeyIDs(ids ...int64) *UserUpdate {
|
||||||
_u.mutation.AddAPIKeyIDs(ids...)
|
_u.mutation.AddAPIKeyIDs(ids...)
|
||||||
@ -804,6 +839,9 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
|||||||
if value, ok := _u.mutation.BalanceNotifyEnabled(); ok {
|
if value, ok := _u.mutation.BalanceNotifyEnabled(); ok {
|
||||||
_spec.SetField(user.FieldBalanceNotifyEnabled, field.TypeBool, value)
|
_spec.SetField(user.FieldBalanceNotifyEnabled, field.TypeBool, value)
|
||||||
}
|
}
|
||||||
|
if value, ok := _u.mutation.BalanceNotifyThresholdType(); ok {
|
||||||
|
_spec.SetField(user.FieldBalanceNotifyThresholdType, field.TypeString, value)
|
||||||
|
}
|
||||||
if value, ok := _u.mutation.BalanceNotifyThreshold(); ok {
|
if value, ok := _u.mutation.BalanceNotifyThreshold(); ok {
|
||||||
_spec.SetField(user.FieldBalanceNotifyThreshold, field.TypeFloat64, value)
|
_spec.SetField(user.FieldBalanceNotifyThreshold, field.TypeFloat64, value)
|
||||||
}
|
}
|
||||||
@ -816,6 +854,12 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
|||||||
if value, ok := _u.mutation.BalanceNotifyExtraEmails(); ok {
|
if value, ok := _u.mutation.BalanceNotifyExtraEmails(); ok {
|
||||||
_spec.SetField(user.FieldBalanceNotifyExtraEmails, field.TypeString, value)
|
_spec.SetField(user.FieldBalanceNotifyExtraEmails, field.TypeString, value)
|
||||||
}
|
}
|
||||||
|
if value, ok := _u.mutation.TotalRecharged(); ok {
|
||||||
|
_spec.SetField(user.FieldTotalRecharged, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.AddedTotalRecharged(); ok {
|
||||||
|
_spec.AddField(user.FieldTotalRecharged, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
if _u.mutation.APIKeysCleared() {
|
if _u.mutation.APIKeysCleared() {
|
||||||
edge := &sqlgraph.EdgeSpec{
|
edge := &sqlgraph.EdgeSpec{
|
||||||
Rel: sqlgraph.O2M,
|
Rel: sqlgraph.O2M,
|
||||||
@ -1518,6 +1562,20 @@ func (_u *UserUpdateOne) SetNillableBalanceNotifyEnabled(v *bool) *UserUpdateOne
|
|||||||
return _u
|
return _u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field.
|
||||||
|
func (_u *UserUpdateOne) SetBalanceNotifyThresholdType(v string) *UserUpdateOne {
|
||||||
|
_u.mutation.SetBalanceNotifyThresholdType(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableBalanceNotifyThresholdType sets the "balance_notify_threshold_type" field if the given value is not nil.
|
||||||
|
func (_u *UserUpdateOne) SetNillableBalanceNotifyThresholdType(v *string) *UserUpdateOne {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetBalanceNotifyThresholdType(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
// SetBalanceNotifyThreshold sets the "balance_notify_threshold" field.
|
||||||
func (_u *UserUpdateOne) SetBalanceNotifyThreshold(v float64) *UserUpdateOne {
|
func (_u *UserUpdateOne) SetBalanceNotifyThreshold(v float64) *UserUpdateOne {
|
||||||
_u.mutation.ResetBalanceNotifyThreshold()
|
_u.mutation.ResetBalanceNotifyThreshold()
|
||||||
@ -1559,6 +1617,27 @@ func (_u *UserUpdateOne) SetNillableBalanceNotifyExtraEmails(v *string) *UserUpd
|
|||||||
return _u
|
return _u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTotalRecharged sets the "total_recharged" field.
|
||||||
|
func (_u *UserUpdateOne) SetTotalRecharged(v float64) *UserUpdateOne {
|
||||||
|
_u.mutation.ResetTotalRecharged()
|
||||||
|
_u.mutation.SetTotalRecharged(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableTotalRecharged sets the "total_recharged" field if the given value is not nil.
|
||||||
|
func (_u *UserUpdateOne) SetNillableTotalRecharged(v *float64) *UserUpdateOne {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetTotalRecharged(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTotalRecharged adds value to the "total_recharged" field.
|
||||||
|
func (_u *UserUpdateOne) AddTotalRecharged(v float64) *UserUpdateOne {
|
||||||
|
_u.mutation.AddTotalRecharged(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs.
|
// AddAPIKeyIDs adds the "api_keys" edge to the APIKey entity by IDs.
|
||||||
func (_u *UserUpdateOne) AddAPIKeyIDs(ids ...int64) *UserUpdateOne {
|
func (_u *UserUpdateOne) AddAPIKeyIDs(ids ...int64) *UserUpdateOne {
|
||||||
_u.mutation.AddAPIKeyIDs(ids...)
|
_u.mutation.AddAPIKeyIDs(ids...)
|
||||||
@ -2095,6 +2174,9 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) {
|
|||||||
if value, ok := _u.mutation.BalanceNotifyEnabled(); ok {
|
if value, ok := _u.mutation.BalanceNotifyEnabled(); ok {
|
||||||
_spec.SetField(user.FieldBalanceNotifyEnabled, field.TypeBool, value)
|
_spec.SetField(user.FieldBalanceNotifyEnabled, field.TypeBool, value)
|
||||||
}
|
}
|
||||||
|
if value, ok := _u.mutation.BalanceNotifyThresholdType(); ok {
|
||||||
|
_spec.SetField(user.FieldBalanceNotifyThresholdType, field.TypeString, value)
|
||||||
|
}
|
||||||
if value, ok := _u.mutation.BalanceNotifyThreshold(); ok {
|
if value, ok := _u.mutation.BalanceNotifyThreshold(); ok {
|
||||||
_spec.SetField(user.FieldBalanceNotifyThreshold, field.TypeFloat64, value)
|
_spec.SetField(user.FieldBalanceNotifyThreshold, field.TypeFloat64, value)
|
||||||
}
|
}
|
||||||
@ -2107,6 +2189,12 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) {
|
|||||||
if value, ok := _u.mutation.BalanceNotifyExtraEmails(); ok {
|
if value, ok := _u.mutation.BalanceNotifyExtraEmails(); ok {
|
||||||
_spec.SetField(user.FieldBalanceNotifyExtraEmails, field.TypeString, value)
|
_spec.SetField(user.FieldBalanceNotifyExtraEmails, field.TypeString, value)
|
||||||
}
|
}
|
||||||
|
if value, ok := _u.mutation.TotalRecharged(); ok {
|
||||||
|
_spec.SetField(user.FieldTotalRecharged, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.AddedTotalRecharged(); ok {
|
||||||
|
_spec.AddField(user.FieldTotalRecharged, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
if _u.mutation.APIKeysCleared() {
|
if _u.mutation.APIKeysCleared() {
|
||||||
edge := &sqlgraph.EdgeSpec{
|
edge := &sqlgraph.EdgeSpec{
|
||||||
Rel: sqlgraph.O2M,
|
Rel: sqlgraph.O2M,
|
||||||
|
|||||||
@ -176,6 +176,10 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
|
|||||||
EnableMetadataPassthrough: settings.EnableMetadataPassthrough,
|
EnableMetadataPassthrough: settings.EnableMetadataPassthrough,
|
||||||
EnableCCHSigning: settings.EnableCCHSigning,
|
EnableCCHSigning: settings.EnableCCHSigning,
|
||||||
WebSearchEmulationEnabled: settings.WebSearchEmulationEnabled,
|
WebSearchEmulationEnabled: settings.WebSearchEmulationEnabled,
|
||||||
|
BalanceLowNotifyEnabled: settings.BalanceLowNotifyEnabled,
|
||||||
|
BalanceLowNotifyThresholdType: settings.BalanceLowNotifyThresholdType,
|
||||||
|
BalanceLowNotifyThreshold: settings.BalanceLowNotifyThreshold,
|
||||||
|
AccountQuotaNotifyEmails: settings.AccountQuotaNotifyEmails,
|
||||||
PaymentEnabled: paymentCfg.Enabled,
|
PaymentEnabled: paymentCfg.Enabled,
|
||||||
PaymentMinAmount: paymentCfg.MinAmount,
|
PaymentMinAmount: paymentCfg.MinAmount,
|
||||||
PaymentMaxAmount: paymentCfg.MaxAmount,
|
PaymentMaxAmount: paymentCfg.MaxAmount,
|
||||||
@ -305,6 +309,12 @@ type UpdateSettingsRequest struct {
|
|||||||
EnableMetadataPassthrough *bool `json:"enable_metadata_passthrough"`
|
EnableMetadataPassthrough *bool `json:"enable_metadata_passthrough"`
|
||||||
EnableCCHSigning *bool `json:"enable_cch_signing"`
|
EnableCCHSigning *bool `json:"enable_cch_signing"`
|
||||||
|
|
||||||
|
// Balance low notification
|
||||||
|
BalanceLowNotifyEnabled *bool `json:"balance_low_notify_enabled"`
|
||||||
|
BalanceLowNotifyThresholdType *string `json:"balance_low_notify_threshold_type"`
|
||||||
|
BalanceLowNotifyThreshold *float64 `json:"balance_low_notify_threshold"`
|
||||||
|
AccountQuotaNotifyEmails *[]string `json:"account_quota_notify_emails"`
|
||||||
|
|
||||||
// Payment configuration (integrated into settings, full replace)
|
// Payment configuration (integrated into settings, full replace)
|
||||||
PaymentEnabled *bool `json:"payment_enabled"`
|
PaymentEnabled *bool `json:"payment_enabled"`
|
||||||
PaymentMinAmount *float64 `json:"payment_min_amount"`
|
PaymentMinAmount *float64 `json:"payment_min_amount"`
|
||||||
@ -882,6 +892,30 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
return previousSettings.EnableCCHSigning
|
return previousSettings.EnableCCHSigning
|
||||||
}(),
|
}(),
|
||||||
|
BalanceLowNotifyEnabled: func() bool {
|
||||||
|
if req.BalanceLowNotifyEnabled != nil {
|
||||||
|
return *req.BalanceLowNotifyEnabled
|
||||||
|
}
|
||||||
|
return previousSettings.BalanceLowNotifyEnabled
|
||||||
|
}(),
|
||||||
|
BalanceLowNotifyThresholdType: func() string {
|
||||||
|
if req.BalanceLowNotifyThresholdType != nil {
|
||||||
|
return *req.BalanceLowNotifyThresholdType
|
||||||
|
}
|
||||||
|
return previousSettings.BalanceLowNotifyThresholdType
|
||||||
|
}(),
|
||||||
|
BalanceLowNotifyThreshold: func() float64 {
|
||||||
|
if req.BalanceLowNotifyThreshold != nil {
|
||||||
|
return *req.BalanceLowNotifyThreshold
|
||||||
|
}
|
||||||
|
return previousSettings.BalanceLowNotifyThreshold
|
||||||
|
}(),
|
||||||
|
AccountQuotaNotifyEmails: func() []string {
|
||||||
|
if req.AccountQuotaNotifyEmails != nil {
|
||||||
|
return *req.AccountQuotaNotifyEmails
|
||||||
|
}
|
||||||
|
return previousSettings.AccountQuotaNotifyEmails
|
||||||
|
}(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.settingService.UpdateSettings(c.Request.Context(), settings); err != nil {
|
if err := h.settingService.UpdateSettings(c.Request.Context(), settings); err != nil {
|
||||||
@ -1028,6 +1062,10 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
|
|||||||
EnableFingerprintUnification: updatedSettings.EnableFingerprintUnification,
|
EnableFingerprintUnification: updatedSettings.EnableFingerprintUnification,
|
||||||
EnableMetadataPassthrough: updatedSettings.EnableMetadataPassthrough,
|
EnableMetadataPassthrough: updatedSettings.EnableMetadataPassthrough,
|
||||||
EnableCCHSigning: updatedSettings.EnableCCHSigning,
|
EnableCCHSigning: updatedSettings.EnableCCHSigning,
|
||||||
|
BalanceLowNotifyEnabled: updatedSettings.BalanceLowNotifyEnabled,
|
||||||
|
BalanceLowNotifyThresholdType: updatedSettings.BalanceLowNotifyThresholdType,
|
||||||
|
BalanceLowNotifyThreshold: updatedSettings.BalanceLowNotifyThreshold,
|
||||||
|
AccountQuotaNotifyEmails: updatedSettings.AccountQuotaNotifyEmails,
|
||||||
PaymentEnabled: updatedPaymentCfg.Enabled,
|
PaymentEnabled: updatedPaymentCfg.Enabled,
|
||||||
PaymentMinAmount: updatedPaymentCfg.MinAmount,
|
PaymentMinAmount: updatedPaymentCfg.MinAmount,
|
||||||
PaymentMaxAmount: updatedPaymentCfg.MaxAmount,
|
PaymentMaxAmount: updatedPaymentCfg.MaxAmount,
|
||||||
|
|||||||
@ -13,19 +13,21 @@ func UserFromServiceShallow(u *service.User) *User {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &User{
|
return &User{
|
||||||
ID: u.ID,
|
ID: u.ID,
|
||||||
Email: u.Email,
|
Email: u.Email,
|
||||||
Username: u.Username,
|
Username: u.Username,
|
||||||
Role: u.Role,
|
Role: u.Role,
|
||||||
Balance: u.Balance,
|
Balance: u.Balance,
|
||||||
Concurrency: u.Concurrency,
|
Concurrency: u.Concurrency,
|
||||||
Status: u.Status,
|
Status: u.Status,
|
||||||
AllowedGroups: u.AllowedGroups,
|
AllowedGroups: u.AllowedGroups,
|
||||||
CreatedAt: u.CreatedAt,
|
CreatedAt: u.CreatedAt,
|
||||||
UpdatedAt: u.UpdatedAt,
|
UpdatedAt: u.UpdatedAt,
|
||||||
BalanceNotifyEnabled: u.BalanceNotifyEnabled,
|
BalanceNotifyEnabled: u.BalanceNotifyEnabled,
|
||||||
BalanceNotifyThreshold: u.BalanceNotifyThreshold,
|
BalanceNotifyThresholdType: u.BalanceNotifyThresholdType,
|
||||||
BalanceNotifyExtraEmails: u.BalanceNotifyExtraEmails,
|
BalanceNotifyThreshold: u.BalanceNotifyThreshold,
|
||||||
|
BalanceNotifyExtraEmails: u.BalanceNotifyExtraEmails,
|
||||||
|
TotalRecharged: u.TotalRecharged,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -150,9 +150,10 @@ type SystemSettings struct {
|
|||||||
PaymentCancelRateLimitMode string `json:"payment_cancel_rate_limit_window_mode"`
|
PaymentCancelRateLimitMode string `json:"payment_cancel_rate_limit_window_mode"`
|
||||||
|
|
||||||
// Balance low notification
|
// Balance low notification
|
||||||
BalanceLowNotifyEnabled bool `json:"balance_low_notify_enabled"`
|
BalanceLowNotifyEnabled bool `json:"balance_low_notify_enabled"`
|
||||||
BalanceLowNotifyThreshold float64 `json:"balance_low_notify_threshold"`
|
BalanceLowNotifyThresholdType string `json:"balance_low_notify_threshold_type"`
|
||||||
AccountQuotaNotifyEmails []string `json:"account_quota_notify_emails"`
|
BalanceLowNotifyThreshold float64 `json:"balance_low_notify_threshold"`
|
||||||
|
AccountQuotaNotifyEmails []string `json:"account_quota_notify_emails"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DefaultSubscriptionSetting struct {
|
type DefaultSubscriptionSetting struct {
|
||||||
|
|||||||
@ -19,9 +19,11 @@ type User struct {
|
|||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
|
||||||
// 余额不足通知
|
// 余额不足通知
|
||||||
BalanceNotifyEnabled bool `json:"balance_notify_enabled"`
|
BalanceNotifyEnabled bool `json:"balance_notify_enabled"`
|
||||||
BalanceNotifyThreshold *float64 `json:"balance_notify_threshold"`
|
BalanceNotifyThresholdType string `json:"balance_notify_threshold_type"`
|
||||||
BalanceNotifyExtraEmails []string `json:"balance_notify_extra_emails"`
|
BalanceNotifyThreshold *float64 `json:"balance_notify_threshold"`
|
||||||
|
BalanceNotifyExtraEmails []string `json:"balance_notify_extra_emails"`
|
||||||
|
TotalRecharged float64 `json:"total_recharged"`
|
||||||
|
|
||||||
APIKeys []APIKey `json:"api_keys,omitempty"`
|
APIKeys []APIKey `json:"api_keys,omitempty"`
|
||||||
Subscriptions []UserSubscription `json:"subscriptions,omitempty"`
|
Subscriptions []UserSubscription `json:"subscriptions,omitempty"`
|
||||||
|
|||||||
@ -33,9 +33,10 @@ type ChangePasswordRequest struct {
|
|||||||
|
|
||||||
// UpdateProfileRequest represents the update profile request payload
|
// UpdateProfileRequest represents the update profile request payload
|
||||||
type UpdateProfileRequest struct {
|
type UpdateProfileRequest struct {
|
||||||
Username *string `json:"username"`
|
Username *string `json:"username"`
|
||||||
BalanceNotifyEnabled *bool `json:"balance_notify_enabled"`
|
BalanceNotifyEnabled *bool `json:"balance_notify_enabled"`
|
||||||
BalanceNotifyThreshold *float64 `json:"balance_notify_threshold"`
|
BalanceNotifyThresholdType *string `json:"balance_notify_threshold_type"`
|
||||||
|
BalanceNotifyThreshold *float64 `json:"balance_notify_threshold"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetProfile handles getting user profile
|
// GetProfile handles getting user profile
|
||||||
@ -100,9 +101,10 @@ func (h *UserHandler) UpdateProfile(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
svcReq := service.UpdateProfileRequest{
|
svcReq := service.UpdateProfileRequest{
|
||||||
Username: req.Username,
|
Username: req.Username,
|
||||||
BalanceNotifyEnabled: req.BalanceNotifyEnabled,
|
BalanceNotifyEnabled: req.BalanceNotifyEnabled,
|
||||||
BalanceNotifyThreshold: req.BalanceNotifyThreshold,
|
BalanceNotifyThresholdType: req.BalanceNotifyThresholdType,
|
||||||
|
BalanceNotifyThreshold: req.BalanceNotifyThreshold,
|
||||||
}
|
}
|
||||||
updatedUser, err := h.userService.UpdateProfile(c.Request.Context(), subject.UserID, svcReq)
|
updatedUser, err := h.userService.UpdateProfile(c.Request.Context(), subject.UserID, svcReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -641,22 +641,24 @@ func userEntityToService(u *dbent.User) *service.User {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
out := &service.User{
|
out := &service.User{
|
||||||
ID: u.ID,
|
ID: u.ID,
|
||||||
Email: u.Email,
|
Email: u.Email,
|
||||||
Username: u.Username,
|
Username: u.Username,
|
||||||
Notes: u.Notes,
|
Notes: u.Notes,
|
||||||
PasswordHash: u.PasswordHash,
|
PasswordHash: u.PasswordHash,
|
||||||
Role: u.Role,
|
Role: u.Role,
|
||||||
Balance: u.Balance,
|
Balance: u.Balance,
|
||||||
Concurrency: u.Concurrency,
|
Concurrency: u.Concurrency,
|
||||||
Status: u.Status,
|
Status: u.Status,
|
||||||
TotpSecretEncrypted: u.TotpSecretEncrypted,
|
TotpSecretEncrypted: u.TotpSecretEncrypted,
|
||||||
TotpEnabled: u.TotpEnabled,
|
TotpEnabled: u.TotpEnabled,
|
||||||
TotpEnabledAt: u.TotpEnabledAt,
|
TotpEnabledAt: u.TotpEnabledAt,
|
||||||
BalanceNotifyEnabled: u.BalanceNotifyEnabled,
|
BalanceNotifyEnabled: u.BalanceNotifyEnabled,
|
||||||
BalanceNotifyThreshold: u.BalanceNotifyThreshold,
|
BalanceNotifyThresholdType: u.BalanceNotifyThresholdType,
|
||||||
CreatedAt: u.CreatedAt,
|
BalanceNotifyThreshold: u.BalanceNotifyThreshold,
|
||||||
UpdatedAt: u.UpdatedAt,
|
TotalRecharged: u.TotalRecharged,
|
||||||
|
CreatedAt: u.CreatedAt,
|
||||||
|
UpdatedAt: u.UpdatedAt,
|
||||||
}
|
}
|
||||||
// Parse extra emails JSON array
|
// Parse extra emails JSON array
|
||||||
if u.BalanceNotifyExtraEmails != "" && u.BalanceNotifyExtraEmails != "[]" {
|
if u.BalanceNotifyExtraEmails != "" && u.BalanceNotifyExtraEmails != "[]" {
|
||||||
|
|||||||
@ -148,6 +148,7 @@ func (r *userRepository) Update(ctx context.Context, userIn *service.User) error
|
|||||||
SetConcurrency(userIn.Concurrency).
|
SetConcurrency(userIn.Concurrency).
|
||||||
SetStatus(userIn.Status).
|
SetStatus(userIn.Status).
|
||||||
SetBalanceNotifyEnabled(userIn.BalanceNotifyEnabled).
|
SetBalanceNotifyEnabled(userIn.BalanceNotifyEnabled).
|
||||||
|
SetBalanceNotifyThresholdType(userIn.BalanceNotifyThresholdType).
|
||||||
SetNillableBalanceNotifyThreshold(userIn.BalanceNotifyThreshold).
|
SetNillableBalanceNotifyThreshold(userIn.BalanceNotifyThreshold).
|
||||||
SetBalanceNotifyExtraEmails(marshalExtraEmails(userIn.BalanceNotifyExtraEmails))
|
SetBalanceNotifyExtraEmails(marshalExtraEmails(userIn.BalanceNotifyExtraEmails))
|
||||||
if userIn.BalanceNotifyThreshold == nil {
|
if userIn.BalanceNotifyThreshold == nil {
|
||||||
@ -389,7 +390,12 @@ func (r *userRepository) filterUsersByAttributes(ctx context.Context, attrs map[
|
|||||||
|
|
||||||
func (r *userRepository) UpdateBalance(ctx context.Context, id int64, amount float64) error {
|
func (r *userRepository) UpdateBalance(ctx context.Context, id int64, amount float64) error {
|
||||||
client := clientFromContext(ctx, r.client)
|
client := clientFromContext(ctx, r.client)
|
||||||
n, err := client.User.Update().Where(dbuser.IDEQ(id)).AddBalance(amount).Save(ctx)
|
update := client.User.Update().Where(dbuser.IDEQ(id)).AddBalance(amount)
|
||||||
|
// Track cumulative recharge amount for percentage-based notifications
|
||||||
|
if amount > 0 {
|
||||||
|
update = update.AddTotalRecharged(amount)
|
||||||
|
}
|
||||||
|
n, err := update.Save(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return translatePersistenceError(err, service.ErrUserNotFound, nil)
|
return translatePersistenceError(err, service.ErrUserNotFound, nil)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,30 +47,21 @@ func (s *BalanceNotifyService) CheckBalanceAfterDeduction(ctx context.Context, u
|
|||||||
if user == nil || s.emailService == nil || s.settingRepo == nil {
|
if user == nil || s.emailService == nil || s.settingRepo == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check user-level switch
|
|
||||||
if !user.BalanceNotifyEnabled {
|
if !user.BalanceNotifyEnabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check global switch
|
globalEnabled, globalThresholdType, globalThresholdValue := s.getBalanceNotifyConfig(ctx)
|
||||||
globalEnabled, threshold := s.getBalanceNotifyConfig(ctx)
|
|
||||||
if !globalEnabled {
|
if !globalEnabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// User custom threshold overrides system default
|
threshold := s.resolveEffectiveThreshold(user, globalThresholdType, globalThresholdValue)
|
||||||
if user.BalanceNotifyThreshold != nil {
|
|
||||||
threshold = *user.BalanceNotifyThreshold
|
|
||||||
}
|
|
||||||
|
|
||||||
if threshold <= 0 {
|
if threshold <= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
newBalance := oldBalance - cost
|
newBalance := oldBalance - cost
|
||||||
|
|
||||||
// Only notify on first crossing
|
|
||||||
if oldBalance >= threshold && newBalance < threshold {
|
if oldBalance >= threshold && newBalance < threshold {
|
||||||
siteName := s.getSiteName(ctx)
|
siteName := s.getSiteName(ctx)
|
||||||
recipients := s.collectBalanceNotifyRecipients(user)
|
recipients := s.collectBalanceNotifyRecipients(user)
|
||||||
@ -85,6 +76,30 @@ func (s *BalanceNotifyService) CheckBalanceAfterDeduction(ctx context.Context, u
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resolveEffectiveThreshold computes the actual USD threshold based on type and user settings.
|
||||||
|
func (s *BalanceNotifyService) resolveEffectiveThreshold(user *User, globalType string, globalValue float64) float64 {
|
||||||
|
// User-level override takes full precedence
|
||||||
|
if user.BalanceNotifyThreshold != nil {
|
||||||
|
thresholdType := user.BalanceNotifyThresholdType
|
||||||
|
if thresholdType == "" {
|
||||||
|
thresholdType = globalType
|
||||||
|
}
|
||||||
|
return computeThreshold(thresholdType, *user.BalanceNotifyThreshold, user.TotalRecharged)
|
||||||
|
}
|
||||||
|
return computeThreshold(globalType, globalValue, user.TotalRecharged)
|
||||||
|
}
|
||||||
|
|
||||||
|
// computeThreshold converts a threshold value to USD based on type.
|
||||||
|
func computeThreshold(thresholdType string, value, totalRecharged float64) float64 {
|
||||||
|
if thresholdType == ThresholdTypePercentage {
|
||||||
|
if totalRecharged <= 0 {
|
||||||
|
return 0 // no recharge history → skip percentage check
|
||||||
|
}
|
||||||
|
return totalRecharged * value / 100
|
||||||
|
}
|
||||||
|
return value // fixed USD amount
|
||||||
|
}
|
||||||
|
|
||||||
// quotaDim describes one quota dimension for notification checking.
|
// quotaDim describes one quota dimension for notification checking.
|
||||||
type quotaDim struct {
|
type quotaDim struct {
|
||||||
name string
|
name string
|
||||||
@ -139,13 +154,21 @@ func (s *BalanceNotifyService) asyncSendQuotaAlert(adminEmails []string, account
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getBalanceNotifyConfig reads global balance notification settings.
|
// getBalanceNotifyConfig reads global balance notification settings.
|
||||||
func (s *BalanceNotifyService) getBalanceNotifyConfig(ctx context.Context) (enabled bool, threshold float64) {
|
func (s *BalanceNotifyService) getBalanceNotifyConfig(ctx context.Context) (enabled bool, thresholdType string, threshold float64) {
|
||||||
keys := []string{SettingKeyBalanceLowNotifyEnabled, SettingKeyBalanceLowNotifyThreshold}
|
keys := []string{
|
||||||
|
SettingKeyBalanceLowNotifyEnabled,
|
||||||
|
SettingKeyBalanceLowNotifyThresholdType,
|
||||||
|
SettingKeyBalanceLowNotifyThreshold,
|
||||||
|
}
|
||||||
settings, err := s.settingRepo.GetMultiple(ctx, keys)
|
settings, err := s.settingRepo.GetMultiple(ctx, keys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, 0
|
return false, ThresholdTypeFixed, 0
|
||||||
}
|
}
|
||||||
enabled = settings[SettingKeyBalanceLowNotifyEnabled] == "true"
|
enabled = settings[SettingKeyBalanceLowNotifyEnabled] == "true"
|
||||||
|
thresholdType = settings[SettingKeyBalanceLowNotifyThresholdType]
|
||||||
|
if thresholdType == "" {
|
||||||
|
thresholdType = ThresholdTypeFixed
|
||||||
|
}
|
||||||
if v := settings[SettingKeyBalanceLowNotifyThreshold]; v != "" {
|
if v := settings[SettingKeyBalanceLowNotifyThreshold]; v != "" {
|
||||||
if f, err := strconv.ParseFloat(v, 64); err == nil {
|
if f, err := strconv.ParseFloat(v, 64); err == nil {
|
||||||
threshold = f
|
threshold = f
|
||||||
|
|||||||
@ -251,8 +251,13 @@ const (
|
|||||||
SettingKeyEnableCCHSigning = "enable_cch_signing"
|
SettingKeyEnableCCHSigning = "enable_cch_signing"
|
||||||
|
|
||||||
// Balance Low Notification
|
// Balance Low Notification
|
||||||
SettingKeyBalanceLowNotifyEnabled = "balance_low_notify_enabled" // 全局开关
|
SettingKeyBalanceLowNotifyEnabled = "balance_low_notify_enabled" // 全局开关
|
||||||
SettingKeyBalanceLowNotifyThreshold = "balance_low_notify_threshold" // 默认阈值(USD)
|
SettingKeyBalanceLowNotifyThresholdType = "balance_low_notify_threshold_type" // "fixed" | "percentage"
|
||||||
|
SettingKeyBalanceLowNotifyThreshold = "balance_low_notify_threshold" // 默认阈值(USD 或百分比)
|
||||||
|
|
||||||
|
// Threshold type constants
|
||||||
|
ThresholdTypeFixed = "fixed"
|
||||||
|
ThresholdTypePercentage = "percentage"
|
||||||
|
|
||||||
// Account Quota Notification
|
// Account Quota Notification
|
||||||
SettingKeyAccountQuotaNotifyEmails = "account_quota_notify_emails" // 管理员通知邮箱列表(JSON 数组)
|
SettingKeyAccountQuotaNotifyEmails = "account_quota_notify_emails" // 管理员通知邮箱列表(JSON 数组)
|
||||||
|
|||||||
@ -597,6 +597,11 @@ func (s *SettingService) UpdateSettings(ctx context.Context, settings *SystemSet
|
|||||||
|
|
||||||
// Balance low notification
|
// Balance low notification
|
||||||
updates[SettingKeyBalanceLowNotifyEnabled] = strconv.FormatBool(settings.BalanceLowNotifyEnabled)
|
updates[SettingKeyBalanceLowNotifyEnabled] = strconv.FormatBool(settings.BalanceLowNotifyEnabled)
|
||||||
|
thresholdType := settings.BalanceLowNotifyThresholdType
|
||||||
|
if thresholdType == "" {
|
||||||
|
thresholdType = ThresholdTypeFixed
|
||||||
|
}
|
||||||
|
updates[SettingKeyBalanceLowNotifyThresholdType] = thresholdType
|
||||||
updates[SettingKeyBalanceLowNotifyThreshold] = strconv.FormatFloat(settings.BalanceLowNotifyThreshold, 'f', 8, 64)
|
updates[SettingKeyBalanceLowNotifyThreshold] = strconv.FormatFloat(settings.BalanceLowNotifyThreshold, 'f', 8, 64)
|
||||||
accountQuotaNotifyEmailsJSON, err := json.Marshal(settings.AccountQuotaNotifyEmails)
|
accountQuotaNotifyEmailsJSON, err := json.Marshal(settings.AccountQuotaNotifyEmails)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1228,6 +1233,10 @@ func (s *SettingService) parseSettings(settings map[string]string) *SystemSettin
|
|||||||
|
|
||||||
// Balance low notification
|
// Balance low notification
|
||||||
result.BalanceLowNotifyEnabled = settings[SettingKeyBalanceLowNotifyEnabled] == "true"
|
result.BalanceLowNotifyEnabled = settings[SettingKeyBalanceLowNotifyEnabled] == "true"
|
||||||
|
result.BalanceLowNotifyThresholdType = settings[SettingKeyBalanceLowNotifyThresholdType]
|
||||||
|
if result.BalanceLowNotifyThresholdType == "" {
|
||||||
|
result.BalanceLowNotifyThresholdType = ThresholdTypeFixed
|
||||||
|
}
|
||||||
if v, err := strconv.ParseFloat(settings[SettingKeyBalanceLowNotifyThreshold], 64); err == nil && v >= 0 {
|
if v, err := strconv.ParseFloat(settings[SettingKeyBalanceLowNotifyThreshold], 64); err == nil && v >= 0 {
|
||||||
result.BalanceLowNotifyThreshold = v
|
result.BalanceLowNotifyThreshold = v
|
||||||
}
|
}
|
||||||
|
|||||||
@ -108,8 +108,9 @@ type SystemSettings struct {
|
|||||||
EnableCCHSigning bool // 是否对 billing header cch 进行签名(默认 false)
|
EnableCCHSigning bool // 是否对 billing header cch 进行签名(默认 false)
|
||||||
|
|
||||||
// Balance low notification
|
// Balance low notification
|
||||||
BalanceLowNotifyEnabled bool
|
BalanceLowNotifyEnabled bool
|
||||||
BalanceLowNotifyThreshold float64
|
BalanceLowNotifyThresholdType string // "fixed" (default) | "percentage"
|
||||||
|
BalanceLowNotifyThreshold float64
|
||||||
|
|
||||||
// Account quota notification
|
// Account quota notification
|
||||||
AccountQuotaNotifyEmails []string
|
AccountQuotaNotifyEmails []string
|
||||||
|
|||||||
@ -31,9 +31,11 @@ type User struct {
|
|||||||
TotpEnabledAt *time.Time // TOTP 启用时间
|
TotpEnabledAt *time.Time // TOTP 启用时间
|
||||||
|
|
||||||
// 余额不足通知
|
// 余额不足通知
|
||||||
BalanceNotifyEnabled bool
|
BalanceNotifyEnabled bool
|
||||||
BalanceNotifyThreshold *float64
|
BalanceNotifyThresholdType string // "fixed" (default) | "percentage"
|
||||||
BalanceNotifyExtraEmails []string
|
BalanceNotifyThreshold *float64
|
||||||
|
BalanceNotifyExtraEmails []string
|
||||||
|
TotalRecharged float64
|
||||||
|
|
||||||
APIKeys []APIKey
|
APIKeys []APIKey
|
||||||
Subscriptions []UserSubscription
|
Subscriptions []UserSubscription
|
||||||
|
|||||||
@ -62,11 +62,12 @@ type UserRepository interface {
|
|||||||
|
|
||||||
// UpdateProfileRequest 更新用户资料请求
|
// UpdateProfileRequest 更新用户资料请求
|
||||||
type UpdateProfileRequest struct {
|
type UpdateProfileRequest struct {
|
||||||
Email *string `json:"email"`
|
Email *string `json:"email"`
|
||||||
Username *string `json:"username"`
|
Username *string `json:"username"`
|
||||||
Concurrency *int `json:"concurrency"`
|
Concurrency *int `json:"concurrency"`
|
||||||
BalanceNotifyEnabled *bool `json:"balance_notify_enabled"`
|
BalanceNotifyEnabled *bool `json:"balance_notify_enabled"`
|
||||||
BalanceNotifyThreshold *float64 `json:"balance_notify_threshold"`
|
BalanceNotifyThresholdType *string `json:"balance_notify_threshold_type"`
|
||||||
|
BalanceNotifyThreshold *float64 `json:"balance_notify_threshold"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangePasswordRequest 修改密码请求
|
// ChangePasswordRequest 修改密码请求
|
||||||
@ -143,6 +144,9 @@ func (s *UserService) UpdateProfile(ctx context.Context, userID int64, req Updat
|
|||||||
if req.BalanceNotifyEnabled != nil {
|
if req.BalanceNotifyEnabled != nil {
|
||||||
user.BalanceNotifyEnabled = *req.BalanceNotifyEnabled
|
user.BalanceNotifyEnabled = *req.BalanceNotifyEnabled
|
||||||
}
|
}
|
||||||
|
if req.BalanceNotifyThresholdType != nil {
|
||||||
|
user.BalanceNotifyThresholdType = *req.BalanceNotifyThresholdType
|
||||||
|
}
|
||||||
if req.BalanceNotifyThreshold != nil {
|
if req.BalanceNotifyThreshold != nil {
|
||||||
if *req.BalanceNotifyThreshold <= 0 {
|
if *req.BalanceNotifyThreshold <= 0 {
|
||||||
user.BalanceNotifyThreshold = nil // clear to system default
|
user.BalanceNotifyThreshold = nil // clear to system default
|
||||||
|
|||||||
@ -0,0 +1,4 @@
|
|||||||
|
-- Add threshold type support (fixed / percentage) to balance notification
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS balance_notify_threshold_type VARCHAR(10) NOT NULL DEFAULT 'fixed';
|
||||||
|
-- Track cumulative recharge amount for percentage threshold calculation
|
||||||
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS total_recharged DECIMAL(20,8) NOT NULL DEFAULT 0;
|
||||||
@ -137,6 +137,7 @@ export interface SystemSettings {
|
|||||||
|
|
||||||
// Balance & quota notification
|
// Balance & quota notification
|
||||||
balance_low_notify_enabled: boolean
|
balance_low_notify_enabled: boolean
|
||||||
|
balance_low_notify_threshold_type: 'fixed' | 'percentage'
|
||||||
balance_low_notify_threshold: number
|
balance_low_notify_threshold: number
|
||||||
account_quota_notify_emails: string[]
|
account_quota_notify_emails: string[]
|
||||||
}
|
}
|
||||||
@ -240,6 +241,7 @@ export interface UpdateSettingsRequest {
|
|||||||
payment_cancel_rate_limit_window_mode?: string
|
payment_cancel_rate_limit_window_mode?: string
|
||||||
// Balance & quota notification
|
// Balance & quota notification
|
||||||
balance_low_notify_enabled?: boolean
|
balance_low_notify_enabled?: boolean
|
||||||
|
balance_low_notify_threshold_type?: 'fixed' | 'percentage'
|
||||||
balance_low_notify_threshold?: number
|
balance_low_notify_threshold?: number
|
||||||
account_quota_notify_emails?: string[]
|
account_quota_notify_emails?: string[]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4633,8 +4633,12 @@ export default {
|
|||||||
title: 'Balance Low Notification',
|
title: 'Balance Low Notification',
|
||||||
description: 'Send email notification when user balance falls below threshold',
|
description: 'Send email notification when user balance falls below threshold',
|
||||||
enabled: 'Enable Balance Low Notification',
|
enabled: 'Enable Balance Low Notification',
|
||||||
|
thresholdType: 'Threshold Type',
|
||||||
|
typeFixed: 'Fixed Amount',
|
||||||
|
typePercentage: 'Percentage of Recharged',
|
||||||
threshold: 'Default Threshold',
|
threshold: 'Default Threshold',
|
||||||
thresholdHint: 'Used when user has not set a custom value',
|
thresholdHint: 'Used when user has not set a custom value',
|
||||||
|
percentageHint: 'Notify when balance falls below this percentage of total recharged amount',
|
||||||
thresholdPlaceholder: 'Enter amount',
|
thresholdPlaceholder: 'Enter amount',
|
||||||
},
|
},
|
||||||
quotaNotify: {
|
quotaNotify: {
|
||||||
|
|||||||
@ -4797,8 +4797,12 @@ export default {
|
|||||||
title: '余额不足提醒',
|
title: '余额不足提醒',
|
||||||
description: '当用户余额低于阈值时发送邮件提醒',
|
description: '当用户余额低于阈值时发送邮件提醒',
|
||||||
enabled: '启用余额不足提醒',
|
enabled: '启用余额不足提醒',
|
||||||
threshold: '默认提醒阈值',
|
thresholdType: '阈值类型',
|
||||||
|
typeFixed: '固定金额',
|
||||||
|
typePercentage: '充值百分比',
|
||||||
|
threshold: '提醒阈值',
|
||||||
thresholdHint: '用户未自定义时使用此值',
|
thresholdHint: '用户未自定义时使用此值',
|
||||||
|
percentageHint: '当余额低于累计充值额的此百分比时提醒',
|
||||||
thresholdPlaceholder: '输入金额',
|
thresholdPlaceholder: '输入金额',
|
||||||
},
|
},
|
||||||
quotaNotify: {
|
quotaNotify: {
|
||||||
|
|||||||
@ -2660,6 +2660,90 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Balance Low Notification -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="border-b border-gray-100 px-6 py-4 dark:border-dark-700">
|
||||||
|
<h3 class="text-base font-medium text-gray-900 dark:text-white">
|
||||||
|
{{ t('admin.settings.balanceNotify.title') }}
|
||||||
|
</h3>
|
||||||
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
|
{{ t('admin.settings.balanceNotify.description') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="px-6 py-6 space-y-4">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<label class="mb-0 block text-sm font-medium text-gray-700 dark:text-gray-300">{{ t('admin.settings.balanceNotify.enabled') }}</label>
|
||||||
|
<Toggle v-model="form.balance_low_notify_enabled" />
|
||||||
|
</div>
|
||||||
|
<div v-if="form.balance_low_notify_enabled" class="space-y-3">
|
||||||
|
<!-- Threshold type selector -->
|
||||||
|
<div>
|
||||||
|
<label class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300">{{ t('admin.settings.balanceNotify.thresholdType') }}</label>
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<label class="flex items-center gap-1.5 text-sm cursor-pointer">
|
||||||
|
<input type="radio" v-model="form.balance_low_notify_threshold_type" value="fixed" class="accent-primary-500" />
|
||||||
|
{{ t('admin.settings.balanceNotify.typeFixed') }}
|
||||||
|
</label>
|
||||||
|
<label class="flex items-center gap-1.5 text-sm cursor-pointer">
|
||||||
|
<input type="radio" v-model="form.balance_low_notify_threshold_type" value="percentage" class="accent-primary-500" />
|
||||||
|
{{ t('admin.settings.balanceNotify.typePercentage') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Threshold value -->
|
||||||
|
<div>
|
||||||
|
<label class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300">{{ t('admin.settings.balanceNotify.threshold') }}</label>
|
||||||
|
<div class="relative">
|
||||||
|
<span class="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400">
|
||||||
|
{{ form.balance_low_notify_threshold_type === 'percentage' ? '%' : '$' }}
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
v-model.number="form.balance_low_notify_threshold"
|
||||||
|
type="number"
|
||||||
|
:min="0"
|
||||||
|
:max="form.balance_low_notify_threshold_type === 'percentage' ? 100 : undefined"
|
||||||
|
:step="form.balance_low_notify_threshold_type === 'percentage' ? 1 : 0.01"
|
||||||
|
class="input pl-7"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||||
|
{{ form.balance_low_notify_threshold_type === 'percentage'
|
||||||
|
? t('admin.settings.balanceNotify.percentageHint')
|
||||||
|
: t('admin.settings.balanceNotify.thresholdHint') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Account Quota Notification -->
|
||||||
|
<div class="card">
|
||||||
|
<div class="border-b border-gray-100 px-6 py-4 dark:border-dark-700">
|
||||||
|
<h3 class="text-base font-medium text-gray-900 dark:text-white">
|
||||||
|
{{ t('admin.settings.quotaNotify.title') }}
|
||||||
|
</h3>
|
||||||
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
|
{{ t('admin.settings.quotaNotify.description') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="px-6 py-6 space-y-4">
|
||||||
|
<div>
|
||||||
|
<label class="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300">{{ t('admin.settings.quotaNotify.emails') }}</label>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<div v-for="(_, index) in (form.account_quota_notify_emails || [])" :key="index" class="flex items-center gap-2">
|
||||||
|
<input v-model="form.account_quota_notify_emails[index]" type="email" class="input flex-1" />
|
||||||
|
<button @click="form.account_quota_notify_emails.splice(index, 1)" class="btn btn-secondary px-2" type="button">
|
||||||
|
<Icon name="x" size="xs" class="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<button @click="addQuotaNotifyEmail" class="btn btn-secondary btn-sm" type="button">
|
||||||
|
+ {{ t('admin.settings.quotaNotify.addEmail') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">{{ t('admin.settings.quotaNotify.emailsHint') }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div><!-- /Tab: Email -->
|
</div><!-- /Tab: Email -->
|
||||||
|
|
||||||
<!-- Tab: Backup -->
|
<!-- Tab: Backup -->
|
||||||
@ -2939,7 +3023,12 @@ const form = reactive<SettingsForm>({
|
|||||||
// Gateway forwarding behavior
|
// Gateway forwarding behavior
|
||||||
enable_fingerprint_unification: true,
|
enable_fingerprint_unification: true,
|
||||||
enable_metadata_passthrough: false,
|
enable_metadata_passthrough: false,
|
||||||
enable_cch_signing: false
|
enable_cch_signing: false,
|
||||||
|
// Balance & quota notification
|
||||||
|
balance_low_notify_enabled: false,
|
||||||
|
balance_low_notify_threshold_type: 'fixed' as 'fixed' | 'percentage',
|
||||||
|
balance_low_notify_threshold: 0,
|
||||||
|
account_quota_notify_emails: [] as string[]
|
||||||
})
|
})
|
||||||
|
|
||||||
// Proxies for web search emulation ProxySelector
|
// Proxies for web search emulation ProxySelector
|
||||||
@ -3149,6 +3238,14 @@ function handleRegistrationEmailSuffixWhitelistPaste(event: ClipboardEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quota notify email helpers
|
||||||
|
const addQuotaNotifyEmail = () => {
|
||||||
|
if (!form.account_quota_notify_emails) {
|
||||||
|
form.account_quota_notify_emails = []
|
||||||
|
}
|
||||||
|
form.account_quota_notify_emails.push('')
|
||||||
|
}
|
||||||
|
|
||||||
// LinuxDo OAuth redirect URL suggestion
|
// LinuxDo OAuth redirect URL suggestion
|
||||||
const linuxdoRedirectUrlSuggestion = computed(() => {
|
const linuxdoRedirectUrlSuggestion = computed(() => {
|
||||||
if (typeof window === 'undefined') return ''
|
if (typeof window === 'undefined') return ''
|
||||||
@ -3488,6 +3585,11 @@ async function saveSettings() {
|
|||||||
payment_cancel_rate_limit_window: Number(form.payment_cancel_rate_limit_window) || 1,
|
payment_cancel_rate_limit_window: Number(form.payment_cancel_rate_limit_window) || 1,
|
||||||
payment_cancel_rate_limit_unit: form.payment_cancel_rate_limit_unit,
|
payment_cancel_rate_limit_unit: form.payment_cancel_rate_limit_unit,
|
||||||
payment_cancel_rate_limit_window_mode: form.payment_cancel_rate_limit_window_mode,
|
payment_cancel_rate_limit_window_mode: form.payment_cancel_rate_limit_window_mode,
|
||||||
|
// Balance & quota notification
|
||||||
|
balance_low_notify_enabled: form.balance_low_notify_enabled,
|
||||||
|
balance_low_notify_threshold_type: form.balance_low_notify_threshold_type,
|
||||||
|
balance_low_notify_threshold: Number(form.balance_low_notify_threshold) || 0,
|
||||||
|
account_quota_notify_emails: (form.account_quota_notify_emails || []).filter((e: string) => e.trim() !== ''),
|
||||||
}
|
}
|
||||||
|
|
||||||
const updated = await adminAPI.settings.updateSettings(payload)
|
const updated = await adminAPI.settings.updateSettings(payload)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user