mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-03-30 10:16:52 +00:00
Merge PR #166: feat: 图片生成计费功能
This commit is contained in:
@@ -105,7 +105,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
|
|||||||
concurrencyCache := repository.ProvideConcurrencyCache(redisClient, configConfig)
|
concurrencyCache := repository.ProvideConcurrencyCache(redisClient, configConfig)
|
||||||
concurrencyService := service.NewConcurrencyService(concurrencyCache)
|
concurrencyService := service.NewConcurrencyService(concurrencyCache)
|
||||||
crsSyncService := service.NewCRSSyncService(accountRepository, proxyRepository, oAuthService, openAIOAuthService, geminiOAuthService, configConfig)
|
crsSyncService := service.NewCRSSyncService(accountRepository, proxyRepository, oAuthService, openAIOAuthService, geminiOAuthService, configConfig)
|
||||||
accountHandler := admin.NewAccountHandler(adminService, oAuthService, openAIOAuthService, geminiOAuthService, rateLimitService, accountUsageService, accountTestService, concurrencyService, crsSyncService)
|
accountHandler := admin.NewAccountHandler(adminService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, rateLimitService, accountUsageService, accountTestService, concurrencyService, crsSyncService)
|
||||||
oAuthHandler := admin.NewOAuthHandler(oAuthService)
|
oAuthHandler := admin.NewOAuthHandler(oAuthService)
|
||||||
openAIOAuthHandler := admin.NewOpenAIOAuthHandler(openAIOAuthService, adminService)
|
openAIOAuthHandler := admin.NewOpenAIOAuthHandler(openAIOAuthService, adminService)
|
||||||
geminiOAuthHandler := admin.NewGeminiOAuthHandler(geminiOAuthService)
|
geminiOAuthHandler := admin.NewGeminiOAuthHandler(geminiOAuthService)
|
||||||
|
|||||||
@@ -45,6 +45,12 @@ type Group struct {
|
|||||||
MonthlyLimitUsd *float64 `json:"monthly_limit_usd,omitempty"`
|
MonthlyLimitUsd *float64 `json:"monthly_limit_usd,omitempty"`
|
||||||
// DefaultValidityDays holds the value of the "default_validity_days" field.
|
// DefaultValidityDays holds the value of the "default_validity_days" field.
|
||||||
DefaultValidityDays int `json:"default_validity_days,omitempty"`
|
DefaultValidityDays int `json:"default_validity_days,omitempty"`
|
||||||
|
// ImagePrice1k holds the value of the "image_price_1k" field.
|
||||||
|
ImagePrice1k *float64 `json:"image_price_1k,omitempty"`
|
||||||
|
// ImagePrice2k holds the value of the "image_price_2k" field.
|
||||||
|
ImagePrice2k *float64 `json:"image_price_2k,omitempty"`
|
||||||
|
// ImagePrice4k holds the value of the "image_price_4k" field.
|
||||||
|
ImagePrice4k *float64 `json:"image_price_4k,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 GroupQuery when eager-loading is set.
|
// The values are being populated by the GroupQuery when eager-loading is set.
|
||||||
Edges GroupEdges `json:"edges"`
|
Edges GroupEdges `json:"edges"`
|
||||||
@@ -153,7 +159,7 @@ func (*Group) scanValues(columns []string) ([]any, error) {
|
|||||||
switch columns[i] {
|
switch columns[i] {
|
||||||
case group.FieldIsExclusive:
|
case group.FieldIsExclusive:
|
||||||
values[i] = new(sql.NullBool)
|
values[i] = new(sql.NullBool)
|
||||||
case group.FieldRateMultiplier, group.FieldDailyLimitUsd, group.FieldWeeklyLimitUsd, group.FieldMonthlyLimitUsd:
|
case group.FieldRateMultiplier, group.FieldDailyLimitUsd, group.FieldWeeklyLimitUsd, group.FieldMonthlyLimitUsd, group.FieldImagePrice1k, group.FieldImagePrice2k, group.FieldImagePrice4k:
|
||||||
values[i] = new(sql.NullFloat64)
|
values[i] = new(sql.NullFloat64)
|
||||||
case group.FieldID, group.FieldDefaultValidityDays:
|
case group.FieldID, group.FieldDefaultValidityDays:
|
||||||
values[i] = new(sql.NullInt64)
|
values[i] = new(sql.NullInt64)
|
||||||
@@ -271,6 +277,27 @@ func (_m *Group) assignValues(columns []string, values []any) error {
|
|||||||
} else if value.Valid {
|
} else if value.Valid {
|
||||||
_m.DefaultValidityDays = int(value.Int64)
|
_m.DefaultValidityDays = int(value.Int64)
|
||||||
}
|
}
|
||||||
|
case group.FieldImagePrice1k:
|
||||||
|
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field image_price_1k", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
_m.ImagePrice1k = new(float64)
|
||||||
|
*_m.ImagePrice1k = value.Float64
|
||||||
|
}
|
||||||
|
case group.FieldImagePrice2k:
|
||||||
|
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field image_price_2k", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
_m.ImagePrice2k = new(float64)
|
||||||
|
*_m.ImagePrice2k = value.Float64
|
||||||
|
}
|
||||||
|
case group.FieldImagePrice4k:
|
||||||
|
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field image_price_4k", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
_m.ImagePrice4k = new(float64)
|
||||||
|
*_m.ImagePrice4k = value.Float64
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
_m.selectValues.Set(columns[i], values[i])
|
_m.selectValues.Set(columns[i], values[i])
|
||||||
}
|
}
|
||||||
@@ -398,6 +425,21 @@ func (_m *Group) String() string {
|
|||||||
builder.WriteString(", ")
|
builder.WriteString(", ")
|
||||||
builder.WriteString("default_validity_days=")
|
builder.WriteString("default_validity_days=")
|
||||||
builder.WriteString(fmt.Sprintf("%v", _m.DefaultValidityDays))
|
builder.WriteString(fmt.Sprintf("%v", _m.DefaultValidityDays))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
if v := _m.ImagePrice1k; v != nil {
|
||||||
|
builder.WriteString("image_price_1k=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||||
|
}
|
||||||
|
builder.WriteString(", ")
|
||||||
|
if v := _m.ImagePrice2k; v != nil {
|
||||||
|
builder.WriteString("image_price_2k=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||||
|
}
|
||||||
|
builder.WriteString(", ")
|
||||||
|
if v := _m.ImagePrice4k; v != nil {
|
||||||
|
builder.WriteString("image_price_4k=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||||
|
}
|
||||||
builder.WriteByte(')')
|
builder.WriteByte(')')
|
||||||
return builder.String()
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ const (
|
|||||||
FieldMonthlyLimitUsd = "monthly_limit_usd"
|
FieldMonthlyLimitUsd = "monthly_limit_usd"
|
||||||
// FieldDefaultValidityDays holds the string denoting the default_validity_days field in the database.
|
// FieldDefaultValidityDays holds the string denoting the default_validity_days field in the database.
|
||||||
FieldDefaultValidityDays = "default_validity_days"
|
FieldDefaultValidityDays = "default_validity_days"
|
||||||
|
// FieldImagePrice1k holds the string denoting the image_price_1k field in the database.
|
||||||
|
FieldImagePrice1k = "image_price_1k"
|
||||||
|
// FieldImagePrice2k holds the string denoting the image_price_2k field in the database.
|
||||||
|
FieldImagePrice2k = "image_price_2k"
|
||||||
|
// FieldImagePrice4k holds the string denoting the image_price_4k field in the database.
|
||||||
|
FieldImagePrice4k = "image_price_4k"
|
||||||
// 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.
|
||||||
@@ -132,6 +138,9 @@ var Columns = []string{
|
|||||||
FieldWeeklyLimitUsd,
|
FieldWeeklyLimitUsd,
|
||||||
FieldMonthlyLimitUsd,
|
FieldMonthlyLimitUsd,
|
||||||
FieldDefaultValidityDays,
|
FieldDefaultValidityDays,
|
||||||
|
FieldImagePrice1k,
|
||||||
|
FieldImagePrice2k,
|
||||||
|
FieldImagePrice4k,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -267,6 +276,21 @@ func ByDefaultValidityDays(opts ...sql.OrderTermOption) OrderOption {
|
|||||||
return sql.OrderByField(FieldDefaultValidityDays, opts...).ToFunc()
|
return sql.OrderByField(FieldDefaultValidityDays, opts...).ToFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ByImagePrice1k orders the results by the image_price_1k field.
|
||||||
|
func ByImagePrice1k(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldImagePrice1k, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByImagePrice2k orders the results by the image_price_2k field.
|
||||||
|
func ByImagePrice2k(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldImagePrice2k, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByImagePrice4k orders the results by the image_price_4k field.
|
||||||
|
func ByImagePrice4k(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldImagePrice4k, 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) {
|
||||||
|
|||||||
@@ -125,6 +125,21 @@ func DefaultValidityDays(v int) predicate.Group {
|
|||||||
return predicate.Group(sql.FieldEQ(FieldDefaultValidityDays, v))
|
return predicate.Group(sql.FieldEQ(FieldDefaultValidityDays, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImagePrice1k applies equality check predicate on the "image_price_1k" field. It's identical to ImagePrice1kEQ.
|
||||||
|
func ImagePrice1k(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldEQ(FieldImagePrice1k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2k applies equality check predicate on the "image_price_2k" field. It's identical to ImagePrice2kEQ.
|
||||||
|
func ImagePrice2k(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldEQ(FieldImagePrice2k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4k applies equality check predicate on the "image_price_4k" field. It's identical to ImagePrice4kEQ.
|
||||||
|
func ImagePrice4k(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldEQ(FieldImagePrice4k, 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.Group {
|
func CreatedAtEQ(v time.Time) predicate.Group {
|
||||||
return predicate.Group(sql.FieldEQ(FieldCreatedAt, v))
|
return predicate.Group(sql.FieldEQ(FieldCreatedAt, v))
|
||||||
@@ -830,6 +845,156 @@ func DefaultValidityDaysLTE(v int) predicate.Group {
|
|||||||
return predicate.Group(sql.FieldLTE(FieldDefaultValidityDays, v))
|
return predicate.Group(sql.FieldLTE(FieldDefaultValidityDays, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImagePrice1kEQ applies the EQ predicate on the "image_price_1k" field.
|
||||||
|
func ImagePrice1kEQ(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldEQ(FieldImagePrice1k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice1kNEQ applies the NEQ predicate on the "image_price_1k" field.
|
||||||
|
func ImagePrice1kNEQ(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldNEQ(FieldImagePrice1k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice1kIn applies the In predicate on the "image_price_1k" field.
|
||||||
|
func ImagePrice1kIn(vs ...float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldIn(FieldImagePrice1k, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice1kNotIn applies the NotIn predicate on the "image_price_1k" field.
|
||||||
|
func ImagePrice1kNotIn(vs ...float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldNotIn(FieldImagePrice1k, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice1kGT applies the GT predicate on the "image_price_1k" field.
|
||||||
|
func ImagePrice1kGT(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldGT(FieldImagePrice1k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice1kGTE applies the GTE predicate on the "image_price_1k" field.
|
||||||
|
func ImagePrice1kGTE(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldGTE(FieldImagePrice1k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice1kLT applies the LT predicate on the "image_price_1k" field.
|
||||||
|
func ImagePrice1kLT(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldLT(FieldImagePrice1k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice1kLTE applies the LTE predicate on the "image_price_1k" field.
|
||||||
|
func ImagePrice1kLTE(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldLTE(FieldImagePrice1k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice1kIsNil applies the IsNil predicate on the "image_price_1k" field.
|
||||||
|
func ImagePrice1kIsNil() predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldIsNull(FieldImagePrice1k))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice1kNotNil applies the NotNil predicate on the "image_price_1k" field.
|
||||||
|
func ImagePrice1kNotNil() predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldNotNull(FieldImagePrice1k))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2kEQ applies the EQ predicate on the "image_price_2k" field.
|
||||||
|
func ImagePrice2kEQ(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldEQ(FieldImagePrice2k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2kNEQ applies the NEQ predicate on the "image_price_2k" field.
|
||||||
|
func ImagePrice2kNEQ(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldNEQ(FieldImagePrice2k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2kIn applies the In predicate on the "image_price_2k" field.
|
||||||
|
func ImagePrice2kIn(vs ...float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldIn(FieldImagePrice2k, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2kNotIn applies the NotIn predicate on the "image_price_2k" field.
|
||||||
|
func ImagePrice2kNotIn(vs ...float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldNotIn(FieldImagePrice2k, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2kGT applies the GT predicate on the "image_price_2k" field.
|
||||||
|
func ImagePrice2kGT(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldGT(FieldImagePrice2k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2kGTE applies the GTE predicate on the "image_price_2k" field.
|
||||||
|
func ImagePrice2kGTE(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldGTE(FieldImagePrice2k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2kLT applies the LT predicate on the "image_price_2k" field.
|
||||||
|
func ImagePrice2kLT(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldLT(FieldImagePrice2k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2kLTE applies the LTE predicate on the "image_price_2k" field.
|
||||||
|
func ImagePrice2kLTE(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldLTE(FieldImagePrice2k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2kIsNil applies the IsNil predicate on the "image_price_2k" field.
|
||||||
|
func ImagePrice2kIsNil() predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldIsNull(FieldImagePrice2k))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2kNotNil applies the NotNil predicate on the "image_price_2k" field.
|
||||||
|
func ImagePrice2kNotNil() predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldNotNull(FieldImagePrice2k))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4kEQ applies the EQ predicate on the "image_price_4k" field.
|
||||||
|
func ImagePrice4kEQ(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldEQ(FieldImagePrice4k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4kNEQ applies the NEQ predicate on the "image_price_4k" field.
|
||||||
|
func ImagePrice4kNEQ(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldNEQ(FieldImagePrice4k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4kIn applies the In predicate on the "image_price_4k" field.
|
||||||
|
func ImagePrice4kIn(vs ...float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldIn(FieldImagePrice4k, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4kNotIn applies the NotIn predicate on the "image_price_4k" field.
|
||||||
|
func ImagePrice4kNotIn(vs ...float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldNotIn(FieldImagePrice4k, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4kGT applies the GT predicate on the "image_price_4k" field.
|
||||||
|
func ImagePrice4kGT(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldGT(FieldImagePrice4k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4kGTE applies the GTE predicate on the "image_price_4k" field.
|
||||||
|
func ImagePrice4kGTE(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldGTE(FieldImagePrice4k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4kLT applies the LT predicate on the "image_price_4k" field.
|
||||||
|
func ImagePrice4kLT(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldLT(FieldImagePrice4k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4kLTE applies the LTE predicate on the "image_price_4k" field.
|
||||||
|
func ImagePrice4kLTE(v float64) predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldLTE(FieldImagePrice4k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4kIsNil applies the IsNil predicate on the "image_price_4k" field.
|
||||||
|
func ImagePrice4kIsNil() predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldIsNull(FieldImagePrice4k))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4kNotNil applies the NotNil predicate on the "image_price_4k" field.
|
||||||
|
func ImagePrice4kNotNil() predicate.Group {
|
||||||
|
return predicate.Group(sql.FieldNotNull(FieldImagePrice4k))
|
||||||
|
}
|
||||||
|
|
||||||
// HasAPIKeys applies the HasEdge predicate on the "api_keys" edge.
|
// HasAPIKeys applies the HasEdge predicate on the "api_keys" edge.
|
||||||
func HasAPIKeys() predicate.Group {
|
func HasAPIKeys() predicate.Group {
|
||||||
return predicate.Group(func(s *sql.Selector) {
|
return predicate.Group(func(s *sql.Selector) {
|
||||||
|
|||||||
@@ -216,6 +216,48 @@ func (_c *GroupCreate) SetNillableDefaultValidityDays(v *int) *GroupCreate {
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImagePrice1k sets the "image_price_1k" field.
|
||||||
|
func (_c *GroupCreate) SetImagePrice1k(v float64) *GroupCreate {
|
||||||
|
_c.mutation.SetImagePrice1k(v)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImagePrice1k sets the "image_price_1k" field if the given value is not nil.
|
||||||
|
func (_c *GroupCreate) SetNillableImagePrice1k(v *float64) *GroupCreate {
|
||||||
|
if v != nil {
|
||||||
|
_c.SetImagePrice1k(*v)
|
||||||
|
}
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice2k sets the "image_price_2k" field.
|
||||||
|
func (_c *GroupCreate) SetImagePrice2k(v float64) *GroupCreate {
|
||||||
|
_c.mutation.SetImagePrice2k(v)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImagePrice2k sets the "image_price_2k" field if the given value is not nil.
|
||||||
|
func (_c *GroupCreate) SetNillableImagePrice2k(v *float64) *GroupCreate {
|
||||||
|
if v != nil {
|
||||||
|
_c.SetImagePrice2k(*v)
|
||||||
|
}
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice4k sets the "image_price_4k" field.
|
||||||
|
func (_c *GroupCreate) SetImagePrice4k(v float64) *GroupCreate {
|
||||||
|
_c.mutation.SetImagePrice4k(v)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImagePrice4k sets the "image_price_4k" field if the given value is not nil.
|
||||||
|
func (_c *GroupCreate) SetNillableImagePrice4k(v *float64) *GroupCreate {
|
||||||
|
if v != nil {
|
||||||
|
_c.SetImagePrice4k(*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 *GroupCreate) AddAPIKeyIDs(ids ...int64) *GroupCreate {
|
func (_c *GroupCreate) AddAPIKeyIDs(ids ...int64) *GroupCreate {
|
||||||
_c.mutation.AddAPIKeyIDs(ids...)
|
_c.mutation.AddAPIKeyIDs(ids...)
|
||||||
@@ -516,6 +558,18 @@ func (_c *GroupCreate) createSpec() (*Group, *sqlgraph.CreateSpec) {
|
|||||||
_spec.SetField(group.FieldDefaultValidityDays, field.TypeInt, value)
|
_spec.SetField(group.FieldDefaultValidityDays, field.TypeInt, value)
|
||||||
_node.DefaultValidityDays = value
|
_node.DefaultValidityDays = value
|
||||||
}
|
}
|
||||||
|
if value, ok := _c.mutation.ImagePrice1k(); ok {
|
||||||
|
_spec.SetField(group.FieldImagePrice1k, field.TypeFloat64, value)
|
||||||
|
_node.ImagePrice1k = &value
|
||||||
|
}
|
||||||
|
if value, ok := _c.mutation.ImagePrice2k(); ok {
|
||||||
|
_spec.SetField(group.FieldImagePrice2k, field.TypeFloat64, value)
|
||||||
|
_node.ImagePrice2k = &value
|
||||||
|
}
|
||||||
|
if value, ok := _c.mutation.ImagePrice4k(); ok {
|
||||||
|
_spec.SetField(group.FieldImagePrice4k, field.TypeFloat64, value)
|
||||||
|
_node.ImagePrice4k = &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,
|
||||||
@@ -888,6 +942,78 @@ func (u *GroupUpsert) AddDefaultValidityDays(v int) *GroupUpsert {
|
|||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImagePrice1k sets the "image_price_1k" field.
|
||||||
|
func (u *GroupUpsert) SetImagePrice1k(v float64) *GroupUpsert {
|
||||||
|
u.Set(group.FieldImagePrice1k, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImagePrice1k sets the "image_price_1k" field to the value that was provided on create.
|
||||||
|
func (u *GroupUpsert) UpdateImagePrice1k() *GroupUpsert {
|
||||||
|
u.SetExcluded(group.FieldImagePrice1k)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice1k adds v to the "image_price_1k" field.
|
||||||
|
func (u *GroupUpsert) AddImagePrice1k(v float64) *GroupUpsert {
|
||||||
|
u.Add(group.FieldImagePrice1k, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice1k clears the value of the "image_price_1k" field.
|
||||||
|
func (u *GroupUpsert) ClearImagePrice1k() *GroupUpsert {
|
||||||
|
u.SetNull(group.FieldImagePrice1k)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice2k sets the "image_price_2k" field.
|
||||||
|
func (u *GroupUpsert) SetImagePrice2k(v float64) *GroupUpsert {
|
||||||
|
u.Set(group.FieldImagePrice2k, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImagePrice2k sets the "image_price_2k" field to the value that was provided on create.
|
||||||
|
func (u *GroupUpsert) UpdateImagePrice2k() *GroupUpsert {
|
||||||
|
u.SetExcluded(group.FieldImagePrice2k)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice2k adds v to the "image_price_2k" field.
|
||||||
|
func (u *GroupUpsert) AddImagePrice2k(v float64) *GroupUpsert {
|
||||||
|
u.Add(group.FieldImagePrice2k, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice2k clears the value of the "image_price_2k" field.
|
||||||
|
func (u *GroupUpsert) ClearImagePrice2k() *GroupUpsert {
|
||||||
|
u.SetNull(group.FieldImagePrice2k)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice4k sets the "image_price_4k" field.
|
||||||
|
func (u *GroupUpsert) SetImagePrice4k(v float64) *GroupUpsert {
|
||||||
|
u.Set(group.FieldImagePrice4k, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImagePrice4k sets the "image_price_4k" field to the value that was provided on create.
|
||||||
|
func (u *GroupUpsert) UpdateImagePrice4k() *GroupUpsert {
|
||||||
|
u.SetExcluded(group.FieldImagePrice4k)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice4k adds v to the "image_price_4k" field.
|
||||||
|
func (u *GroupUpsert) AddImagePrice4k(v float64) *GroupUpsert {
|
||||||
|
u.Add(group.FieldImagePrice4k, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice4k clears the value of the "image_price_4k" field.
|
||||||
|
func (u *GroupUpsert) ClearImagePrice4k() *GroupUpsert {
|
||||||
|
u.SetNull(group.FieldImagePrice4k)
|
||||||
|
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:
|
||||||
//
|
//
|
||||||
@@ -1185,6 +1311,90 @@ func (u *GroupUpsertOne) UpdateDefaultValidityDays() *GroupUpsertOne {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImagePrice1k sets the "image_price_1k" field.
|
||||||
|
func (u *GroupUpsertOne) SetImagePrice1k(v float64) *GroupUpsertOne {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.SetImagePrice1k(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice1k adds v to the "image_price_1k" field.
|
||||||
|
func (u *GroupUpsertOne) AddImagePrice1k(v float64) *GroupUpsertOne {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.AddImagePrice1k(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImagePrice1k sets the "image_price_1k" field to the value that was provided on create.
|
||||||
|
func (u *GroupUpsertOne) UpdateImagePrice1k() *GroupUpsertOne {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.UpdateImagePrice1k()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice1k clears the value of the "image_price_1k" field.
|
||||||
|
func (u *GroupUpsertOne) ClearImagePrice1k() *GroupUpsertOne {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.ClearImagePrice1k()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice2k sets the "image_price_2k" field.
|
||||||
|
func (u *GroupUpsertOne) SetImagePrice2k(v float64) *GroupUpsertOne {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.SetImagePrice2k(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice2k adds v to the "image_price_2k" field.
|
||||||
|
func (u *GroupUpsertOne) AddImagePrice2k(v float64) *GroupUpsertOne {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.AddImagePrice2k(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImagePrice2k sets the "image_price_2k" field to the value that was provided on create.
|
||||||
|
func (u *GroupUpsertOne) UpdateImagePrice2k() *GroupUpsertOne {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.UpdateImagePrice2k()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice2k clears the value of the "image_price_2k" field.
|
||||||
|
func (u *GroupUpsertOne) ClearImagePrice2k() *GroupUpsertOne {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.ClearImagePrice2k()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice4k sets the "image_price_4k" field.
|
||||||
|
func (u *GroupUpsertOne) SetImagePrice4k(v float64) *GroupUpsertOne {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.SetImagePrice4k(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice4k adds v to the "image_price_4k" field.
|
||||||
|
func (u *GroupUpsertOne) AddImagePrice4k(v float64) *GroupUpsertOne {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.AddImagePrice4k(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImagePrice4k sets the "image_price_4k" field to the value that was provided on create.
|
||||||
|
func (u *GroupUpsertOne) UpdateImagePrice4k() *GroupUpsertOne {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.UpdateImagePrice4k()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice4k clears the value of the "image_price_4k" field.
|
||||||
|
func (u *GroupUpsertOne) ClearImagePrice4k() *GroupUpsertOne {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.ClearImagePrice4k()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Exec executes the query.
|
// Exec executes the query.
|
||||||
func (u *GroupUpsertOne) Exec(ctx context.Context) error {
|
func (u *GroupUpsertOne) Exec(ctx context.Context) error {
|
||||||
if len(u.create.conflict) == 0 {
|
if len(u.create.conflict) == 0 {
|
||||||
@@ -1648,6 +1858,90 @@ func (u *GroupUpsertBulk) UpdateDefaultValidityDays() *GroupUpsertBulk {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImagePrice1k sets the "image_price_1k" field.
|
||||||
|
func (u *GroupUpsertBulk) SetImagePrice1k(v float64) *GroupUpsertBulk {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.SetImagePrice1k(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice1k adds v to the "image_price_1k" field.
|
||||||
|
func (u *GroupUpsertBulk) AddImagePrice1k(v float64) *GroupUpsertBulk {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.AddImagePrice1k(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImagePrice1k sets the "image_price_1k" field to the value that was provided on create.
|
||||||
|
func (u *GroupUpsertBulk) UpdateImagePrice1k() *GroupUpsertBulk {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.UpdateImagePrice1k()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice1k clears the value of the "image_price_1k" field.
|
||||||
|
func (u *GroupUpsertBulk) ClearImagePrice1k() *GroupUpsertBulk {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.ClearImagePrice1k()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice2k sets the "image_price_2k" field.
|
||||||
|
func (u *GroupUpsertBulk) SetImagePrice2k(v float64) *GroupUpsertBulk {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.SetImagePrice2k(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice2k adds v to the "image_price_2k" field.
|
||||||
|
func (u *GroupUpsertBulk) AddImagePrice2k(v float64) *GroupUpsertBulk {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.AddImagePrice2k(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImagePrice2k sets the "image_price_2k" field to the value that was provided on create.
|
||||||
|
func (u *GroupUpsertBulk) UpdateImagePrice2k() *GroupUpsertBulk {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.UpdateImagePrice2k()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice2k clears the value of the "image_price_2k" field.
|
||||||
|
func (u *GroupUpsertBulk) ClearImagePrice2k() *GroupUpsertBulk {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.ClearImagePrice2k()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice4k sets the "image_price_4k" field.
|
||||||
|
func (u *GroupUpsertBulk) SetImagePrice4k(v float64) *GroupUpsertBulk {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.SetImagePrice4k(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice4k adds v to the "image_price_4k" field.
|
||||||
|
func (u *GroupUpsertBulk) AddImagePrice4k(v float64) *GroupUpsertBulk {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.AddImagePrice4k(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImagePrice4k sets the "image_price_4k" field to the value that was provided on create.
|
||||||
|
func (u *GroupUpsertBulk) UpdateImagePrice4k() *GroupUpsertBulk {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.UpdateImagePrice4k()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice4k clears the value of the "image_price_4k" field.
|
||||||
|
func (u *GroupUpsertBulk) ClearImagePrice4k() *GroupUpsertBulk {
|
||||||
|
return u.Update(func(s *GroupUpsert) {
|
||||||
|
s.ClearImagePrice4k()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Exec executes the query.
|
// Exec executes the query.
|
||||||
func (u *GroupUpsertBulk) Exec(ctx context.Context) error {
|
func (u *GroupUpsertBulk) Exec(ctx context.Context) error {
|
||||||
if u.create.err != nil {
|
if u.create.err != nil {
|
||||||
|
|||||||
@@ -273,6 +273,87 @@ func (_u *GroupUpdate) AddDefaultValidityDays(v int) *GroupUpdate {
|
|||||||
return _u
|
return _u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImagePrice1k sets the "image_price_1k" field.
|
||||||
|
func (_u *GroupUpdate) SetImagePrice1k(v float64) *GroupUpdate {
|
||||||
|
_u.mutation.ResetImagePrice1k()
|
||||||
|
_u.mutation.SetImagePrice1k(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImagePrice1k sets the "image_price_1k" field if the given value is not nil.
|
||||||
|
func (_u *GroupUpdate) SetNillableImagePrice1k(v *float64) *GroupUpdate {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetImagePrice1k(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice1k adds value to the "image_price_1k" field.
|
||||||
|
func (_u *GroupUpdate) AddImagePrice1k(v float64) *GroupUpdate {
|
||||||
|
_u.mutation.AddImagePrice1k(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice1k clears the value of the "image_price_1k" field.
|
||||||
|
func (_u *GroupUpdate) ClearImagePrice1k() *GroupUpdate {
|
||||||
|
_u.mutation.ClearImagePrice1k()
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice2k sets the "image_price_2k" field.
|
||||||
|
func (_u *GroupUpdate) SetImagePrice2k(v float64) *GroupUpdate {
|
||||||
|
_u.mutation.ResetImagePrice2k()
|
||||||
|
_u.mutation.SetImagePrice2k(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImagePrice2k sets the "image_price_2k" field if the given value is not nil.
|
||||||
|
func (_u *GroupUpdate) SetNillableImagePrice2k(v *float64) *GroupUpdate {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetImagePrice2k(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice2k adds value to the "image_price_2k" field.
|
||||||
|
func (_u *GroupUpdate) AddImagePrice2k(v float64) *GroupUpdate {
|
||||||
|
_u.mutation.AddImagePrice2k(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice2k clears the value of the "image_price_2k" field.
|
||||||
|
func (_u *GroupUpdate) ClearImagePrice2k() *GroupUpdate {
|
||||||
|
_u.mutation.ClearImagePrice2k()
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice4k sets the "image_price_4k" field.
|
||||||
|
func (_u *GroupUpdate) SetImagePrice4k(v float64) *GroupUpdate {
|
||||||
|
_u.mutation.ResetImagePrice4k()
|
||||||
|
_u.mutation.SetImagePrice4k(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImagePrice4k sets the "image_price_4k" field if the given value is not nil.
|
||||||
|
func (_u *GroupUpdate) SetNillableImagePrice4k(v *float64) *GroupUpdate {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetImagePrice4k(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice4k adds value to the "image_price_4k" field.
|
||||||
|
func (_u *GroupUpdate) AddImagePrice4k(v float64) *GroupUpdate {
|
||||||
|
_u.mutation.AddImagePrice4k(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice4k clears the value of the "image_price_4k" field.
|
||||||
|
func (_u *GroupUpdate) ClearImagePrice4k() *GroupUpdate {
|
||||||
|
_u.mutation.ClearImagePrice4k()
|
||||||
|
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 *GroupUpdate) AddAPIKeyIDs(ids ...int64) *GroupUpdate {
|
func (_u *GroupUpdate) AddAPIKeyIDs(ids ...int64) *GroupUpdate {
|
||||||
_u.mutation.AddAPIKeyIDs(ids...)
|
_u.mutation.AddAPIKeyIDs(ids...)
|
||||||
@@ -642,6 +723,33 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
|||||||
if value, ok := _u.mutation.AddedDefaultValidityDays(); ok {
|
if value, ok := _u.mutation.AddedDefaultValidityDays(); ok {
|
||||||
_spec.AddField(group.FieldDefaultValidityDays, field.TypeInt, value)
|
_spec.AddField(group.FieldDefaultValidityDays, field.TypeInt, value)
|
||||||
}
|
}
|
||||||
|
if value, ok := _u.mutation.ImagePrice1k(); ok {
|
||||||
|
_spec.SetField(group.FieldImagePrice1k, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.AddedImagePrice1k(); ok {
|
||||||
|
_spec.AddField(group.FieldImagePrice1k, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if _u.mutation.ImagePrice1kCleared() {
|
||||||
|
_spec.ClearField(group.FieldImagePrice1k, field.TypeFloat64)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.ImagePrice2k(); ok {
|
||||||
|
_spec.SetField(group.FieldImagePrice2k, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.AddedImagePrice2k(); ok {
|
||||||
|
_spec.AddField(group.FieldImagePrice2k, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if _u.mutation.ImagePrice2kCleared() {
|
||||||
|
_spec.ClearField(group.FieldImagePrice2k, field.TypeFloat64)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.ImagePrice4k(); ok {
|
||||||
|
_spec.SetField(group.FieldImagePrice4k, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.AddedImagePrice4k(); ok {
|
||||||
|
_spec.AddField(group.FieldImagePrice4k, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if _u.mutation.ImagePrice4kCleared() {
|
||||||
|
_spec.ClearField(group.FieldImagePrice4k, field.TypeFloat64)
|
||||||
|
}
|
||||||
if _u.mutation.APIKeysCleared() {
|
if _u.mutation.APIKeysCleared() {
|
||||||
edge := &sqlgraph.EdgeSpec{
|
edge := &sqlgraph.EdgeSpec{
|
||||||
Rel: sqlgraph.O2M,
|
Rel: sqlgraph.O2M,
|
||||||
@@ -1195,6 +1303,87 @@ func (_u *GroupUpdateOne) AddDefaultValidityDays(v int) *GroupUpdateOne {
|
|||||||
return _u
|
return _u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImagePrice1k sets the "image_price_1k" field.
|
||||||
|
func (_u *GroupUpdateOne) SetImagePrice1k(v float64) *GroupUpdateOne {
|
||||||
|
_u.mutation.ResetImagePrice1k()
|
||||||
|
_u.mutation.SetImagePrice1k(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImagePrice1k sets the "image_price_1k" field if the given value is not nil.
|
||||||
|
func (_u *GroupUpdateOne) SetNillableImagePrice1k(v *float64) *GroupUpdateOne {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetImagePrice1k(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice1k adds value to the "image_price_1k" field.
|
||||||
|
func (_u *GroupUpdateOne) AddImagePrice1k(v float64) *GroupUpdateOne {
|
||||||
|
_u.mutation.AddImagePrice1k(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice1k clears the value of the "image_price_1k" field.
|
||||||
|
func (_u *GroupUpdateOne) ClearImagePrice1k() *GroupUpdateOne {
|
||||||
|
_u.mutation.ClearImagePrice1k()
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice2k sets the "image_price_2k" field.
|
||||||
|
func (_u *GroupUpdateOne) SetImagePrice2k(v float64) *GroupUpdateOne {
|
||||||
|
_u.mutation.ResetImagePrice2k()
|
||||||
|
_u.mutation.SetImagePrice2k(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImagePrice2k sets the "image_price_2k" field if the given value is not nil.
|
||||||
|
func (_u *GroupUpdateOne) SetNillableImagePrice2k(v *float64) *GroupUpdateOne {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetImagePrice2k(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice2k adds value to the "image_price_2k" field.
|
||||||
|
func (_u *GroupUpdateOne) AddImagePrice2k(v float64) *GroupUpdateOne {
|
||||||
|
_u.mutation.AddImagePrice2k(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice2k clears the value of the "image_price_2k" field.
|
||||||
|
func (_u *GroupUpdateOne) ClearImagePrice2k() *GroupUpdateOne {
|
||||||
|
_u.mutation.ClearImagePrice2k()
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice4k sets the "image_price_4k" field.
|
||||||
|
func (_u *GroupUpdateOne) SetImagePrice4k(v float64) *GroupUpdateOne {
|
||||||
|
_u.mutation.ResetImagePrice4k()
|
||||||
|
_u.mutation.SetImagePrice4k(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImagePrice4k sets the "image_price_4k" field if the given value is not nil.
|
||||||
|
func (_u *GroupUpdateOne) SetNillableImagePrice4k(v *float64) *GroupUpdateOne {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetImagePrice4k(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice4k adds value to the "image_price_4k" field.
|
||||||
|
func (_u *GroupUpdateOne) AddImagePrice4k(v float64) *GroupUpdateOne {
|
||||||
|
_u.mutation.AddImagePrice4k(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice4k clears the value of the "image_price_4k" field.
|
||||||
|
func (_u *GroupUpdateOne) ClearImagePrice4k() *GroupUpdateOne {
|
||||||
|
_u.mutation.ClearImagePrice4k()
|
||||||
|
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 *GroupUpdateOne) AddAPIKeyIDs(ids ...int64) *GroupUpdateOne {
|
func (_u *GroupUpdateOne) AddAPIKeyIDs(ids ...int64) *GroupUpdateOne {
|
||||||
_u.mutation.AddAPIKeyIDs(ids...)
|
_u.mutation.AddAPIKeyIDs(ids...)
|
||||||
@@ -1594,6 +1783,33 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error)
|
|||||||
if value, ok := _u.mutation.AddedDefaultValidityDays(); ok {
|
if value, ok := _u.mutation.AddedDefaultValidityDays(); ok {
|
||||||
_spec.AddField(group.FieldDefaultValidityDays, field.TypeInt, value)
|
_spec.AddField(group.FieldDefaultValidityDays, field.TypeInt, value)
|
||||||
}
|
}
|
||||||
|
if value, ok := _u.mutation.ImagePrice1k(); ok {
|
||||||
|
_spec.SetField(group.FieldImagePrice1k, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.AddedImagePrice1k(); ok {
|
||||||
|
_spec.AddField(group.FieldImagePrice1k, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if _u.mutation.ImagePrice1kCleared() {
|
||||||
|
_spec.ClearField(group.FieldImagePrice1k, field.TypeFloat64)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.ImagePrice2k(); ok {
|
||||||
|
_spec.SetField(group.FieldImagePrice2k, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.AddedImagePrice2k(); ok {
|
||||||
|
_spec.AddField(group.FieldImagePrice2k, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if _u.mutation.ImagePrice2kCleared() {
|
||||||
|
_spec.ClearField(group.FieldImagePrice2k, field.TypeFloat64)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.ImagePrice4k(); ok {
|
||||||
|
_spec.SetField(group.FieldImagePrice4k, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.AddedImagePrice4k(); ok {
|
||||||
|
_spec.AddField(group.FieldImagePrice4k, field.TypeFloat64, value)
|
||||||
|
}
|
||||||
|
if _u.mutation.ImagePrice4kCleared() {
|
||||||
|
_spec.ClearField(group.FieldImagePrice4k, field.TypeFloat64)
|
||||||
|
}
|
||||||
if _u.mutation.APIKeysCleared() {
|
if _u.mutation.APIKeysCleared() {
|
||||||
edge := &sqlgraph.EdgeSpec{
|
edge := &sqlgraph.EdgeSpec{
|
||||||
Rel: sqlgraph.O2M,
|
Rel: sqlgraph.O2M,
|
||||||
|
|||||||
@@ -216,6 +216,9 @@ var (
|
|||||||
{Name: "weekly_limit_usd", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
{Name: "weekly_limit_usd", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||||
{Name: "monthly_limit_usd", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
{Name: "monthly_limit_usd", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||||
{Name: "default_validity_days", Type: field.TypeInt, Default: 30},
|
{Name: "default_validity_days", Type: field.TypeInt, Default: 30},
|
||||||
|
{Name: "image_price_1k", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||||
|
{Name: "image_price_2k", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||||
|
{Name: "image_price_4k", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||||
}
|
}
|
||||||
// GroupsTable holds the schema information for the "groups" table.
|
// GroupsTable holds the schema information for the "groups" table.
|
||||||
GroupsTable = &schema.Table{
|
GroupsTable = &schema.Table{
|
||||||
@@ -368,6 +371,8 @@ var (
|
|||||||
{Name: "stream", Type: field.TypeBool, Default: false},
|
{Name: "stream", Type: field.TypeBool, Default: false},
|
||||||
{Name: "duration_ms", Type: field.TypeInt, Nullable: true},
|
{Name: "duration_ms", Type: field.TypeInt, Nullable: true},
|
||||||
{Name: "first_token_ms", Type: field.TypeInt, Nullable: true},
|
{Name: "first_token_ms", Type: field.TypeInt, Nullable: true},
|
||||||
|
{Name: "image_count", Type: field.TypeInt, Default: 0},
|
||||||
|
{Name: "image_size", Type: field.TypeString, Nullable: true, Size: 10},
|
||||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||||
{Name: "api_key_id", Type: field.TypeInt64},
|
{Name: "api_key_id", Type: field.TypeInt64},
|
||||||
{Name: "account_id", Type: field.TypeInt64},
|
{Name: "account_id", Type: field.TypeInt64},
|
||||||
@@ -383,31 +388,31 @@ var (
|
|||||||
ForeignKeys: []*schema.ForeignKey{
|
ForeignKeys: []*schema.ForeignKey{
|
||||||
{
|
{
|
||||||
Symbol: "usage_logs_api_keys_usage_logs",
|
Symbol: "usage_logs_api_keys_usage_logs",
|
||||||
Columns: []*schema.Column{UsageLogsColumns[21]},
|
Columns: []*schema.Column{UsageLogsColumns[23]},
|
||||||
RefColumns: []*schema.Column{APIKeysColumns[0]},
|
RefColumns: []*schema.Column{APIKeysColumns[0]},
|
||||||
OnDelete: schema.NoAction,
|
OnDelete: schema.NoAction,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Symbol: "usage_logs_accounts_usage_logs",
|
Symbol: "usage_logs_accounts_usage_logs",
|
||||||
Columns: []*schema.Column{UsageLogsColumns[22]},
|
Columns: []*schema.Column{UsageLogsColumns[24]},
|
||||||
RefColumns: []*schema.Column{AccountsColumns[0]},
|
RefColumns: []*schema.Column{AccountsColumns[0]},
|
||||||
OnDelete: schema.NoAction,
|
OnDelete: schema.NoAction,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Symbol: "usage_logs_groups_usage_logs",
|
Symbol: "usage_logs_groups_usage_logs",
|
||||||
Columns: []*schema.Column{UsageLogsColumns[23]},
|
Columns: []*schema.Column{UsageLogsColumns[25]},
|
||||||
RefColumns: []*schema.Column{GroupsColumns[0]},
|
RefColumns: []*schema.Column{GroupsColumns[0]},
|
||||||
OnDelete: schema.SetNull,
|
OnDelete: schema.SetNull,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Symbol: "usage_logs_users_usage_logs",
|
Symbol: "usage_logs_users_usage_logs",
|
||||||
Columns: []*schema.Column{UsageLogsColumns[24]},
|
Columns: []*schema.Column{UsageLogsColumns[26]},
|
||||||
RefColumns: []*schema.Column{UsersColumns[0]},
|
RefColumns: []*schema.Column{UsersColumns[0]},
|
||||||
OnDelete: schema.NoAction,
|
OnDelete: schema.NoAction,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Symbol: "usage_logs_user_subscriptions_usage_logs",
|
Symbol: "usage_logs_user_subscriptions_usage_logs",
|
||||||
Columns: []*schema.Column{UsageLogsColumns[25]},
|
Columns: []*schema.Column{UsageLogsColumns[27]},
|
||||||
RefColumns: []*schema.Column{UserSubscriptionsColumns[0]},
|
RefColumns: []*schema.Column{UserSubscriptionsColumns[0]},
|
||||||
OnDelete: schema.SetNull,
|
OnDelete: schema.SetNull,
|
||||||
},
|
},
|
||||||
@@ -416,32 +421,32 @@ var (
|
|||||||
{
|
{
|
||||||
Name: "usagelog_user_id",
|
Name: "usagelog_user_id",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{UsageLogsColumns[24]},
|
Columns: []*schema.Column{UsageLogsColumns[26]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "usagelog_api_key_id",
|
Name: "usagelog_api_key_id",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{UsageLogsColumns[21]},
|
Columns: []*schema.Column{UsageLogsColumns[23]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "usagelog_account_id",
|
Name: "usagelog_account_id",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{UsageLogsColumns[22]},
|
Columns: []*schema.Column{UsageLogsColumns[24]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "usagelog_group_id",
|
Name: "usagelog_group_id",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{UsageLogsColumns[23]},
|
Columns: []*schema.Column{UsageLogsColumns[25]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "usagelog_subscription_id",
|
Name: "usagelog_subscription_id",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{UsageLogsColumns[25]},
|
Columns: []*schema.Column{UsageLogsColumns[27]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "usagelog_created_at",
|
Name: "usagelog_created_at",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{UsageLogsColumns[20]},
|
Columns: []*schema.Column{UsageLogsColumns[22]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "usagelog_model",
|
Name: "usagelog_model",
|
||||||
@@ -456,12 +461,12 @@ var (
|
|||||||
{
|
{
|
||||||
Name: "usagelog_user_id_created_at",
|
Name: "usagelog_user_id_created_at",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{UsageLogsColumns[24], UsageLogsColumns[20]},
|
Columns: []*schema.Column{UsageLogsColumns[26], UsageLogsColumns[22]},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "usagelog_api_key_id_created_at",
|
Name: "usagelog_api_key_id_created_at",
|
||||||
Unique: false,
|
Unique: false,
|
||||||
Columns: []*schema.Column{UsageLogsColumns[21], UsageLogsColumns[20]},
|
Columns: []*schema.Column{UsageLogsColumns[23], UsageLogsColumns[22]},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3457,6 +3457,12 @@ type GroupMutation struct {
|
|||||||
addmonthly_limit_usd *float64
|
addmonthly_limit_usd *float64
|
||||||
default_validity_days *int
|
default_validity_days *int
|
||||||
adddefault_validity_days *int
|
adddefault_validity_days *int
|
||||||
|
image_price_1k *float64
|
||||||
|
addimage_price_1k *float64
|
||||||
|
image_price_2k *float64
|
||||||
|
addimage_price_2k *float64
|
||||||
|
image_price_4k *float64
|
||||||
|
addimage_price_4k *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{}
|
||||||
@@ -4251,6 +4257,216 @@ func (m *GroupMutation) ResetDefaultValidityDays() {
|
|||||||
m.adddefault_validity_days = nil
|
m.adddefault_validity_days = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImagePrice1k sets the "image_price_1k" field.
|
||||||
|
func (m *GroupMutation) SetImagePrice1k(f float64) {
|
||||||
|
m.image_price_1k = &f
|
||||||
|
m.addimage_price_1k = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice1k returns the value of the "image_price_1k" field in the mutation.
|
||||||
|
func (m *GroupMutation) ImagePrice1k() (r float64, exists bool) {
|
||||||
|
v := m.image_price_1k
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldImagePrice1k returns the old "image_price_1k" field's value of the Group entity.
|
||||||
|
// If the Group 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 *GroupMutation) OldImagePrice1k(ctx context.Context) (v *float64, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldImagePrice1k is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldImagePrice1k requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldImagePrice1k: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.ImagePrice1k, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice1k adds f to the "image_price_1k" field.
|
||||||
|
func (m *GroupMutation) AddImagePrice1k(f float64) {
|
||||||
|
if m.addimage_price_1k != nil {
|
||||||
|
*m.addimage_price_1k += f
|
||||||
|
} else {
|
||||||
|
m.addimage_price_1k = &f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddedImagePrice1k returns the value that was added to the "image_price_1k" field in this mutation.
|
||||||
|
func (m *GroupMutation) AddedImagePrice1k() (r float64, exists bool) {
|
||||||
|
v := m.addimage_price_1k
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice1k clears the value of the "image_price_1k" field.
|
||||||
|
func (m *GroupMutation) ClearImagePrice1k() {
|
||||||
|
m.image_price_1k = nil
|
||||||
|
m.addimage_price_1k = nil
|
||||||
|
m.clearedFields[group.FieldImagePrice1k] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice1kCleared returns if the "image_price_1k" field was cleared in this mutation.
|
||||||
|
func (m *GroupMutation) ImagePrice1kCleared() bool {
|
||||||
|
_, ok := m.clearedFields[group.FieldImagePrice1k]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetImagePrice1k resets all changes to the "image_price_1k" field.
|
||||||
|
func (m *GroupMutation) ResetImagePrice1k() {
|
||||||
|
m.image_price_1k = nil
|
||||||
|
m.addimage_price_1k = nil
|
||||||
|
delete(m.clearedFields, group.FieldImagePrice1k)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice2k sets the "image_price_2k" field.
|
||||||
|
func (m *GroupMutation) SetImagePrice2k(f float64) {
|
||||||
|
m.image_price_2k = &f
|
||||||
|
m.addimage_price_2k = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2k returns the value of the "image_price_2k" field in the mutation.
|
||||||
|
func (m *GroupMutation) ImagePrice2k() (r float64, exists bool) {
|
||||||
|
v := m.image_price_2k
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldImagePrice2k returns the old "image_price_2k" field's value of the Group entity.
|
||||||
|
// If the Group 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 *GroupMutation) OldImagePrice2k(ctx context.Context) (v *float64, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldImagePrice2k is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldImagePrice2k requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldImagePrice2k: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.ImagePrice2k, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice2k adds f to the "image_price_2k" field.
|
||||||
|
func (m *GroupMutation) AddImagePrice2k(f float64) {
|
||||||
|
if m.addimage_price_2k != nil {
|
||||||
|
*m.addimage_price_2k += f
|
||||||
|
} else {
|
||||||
|
m.addimage_price_2k = &f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddedImagePrice2k returns the value that was added to the "image_price_2k" field in this mutation.
|
||||||
|
func (m *GroupMutation) AddedImagePrice2k() (r float64, exists bool) {
|
||||||
|
v := m.addimage_price_2k
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice2k clears the value of the "image_price_2k" field.
|
||||||
|
func (m *GroupMutation) ClearImagePrice2k() {
|
||||||
|
m.image_price_2k = nil
|
||||||
|
m.addimage_price_2k = nil
|
||||||
|
m.clearedFields[group.FieldImagePrice2k] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice2kCleared returns if the "image_price_2k" field was cleared in this mutation.
|
||||||
|
func (m *GroupMutation) ImagePrice2kCleared() bool {
|
||||||
|
_, ok := m.clearedFields[group.FieldImagePrice2k]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetImagePrice2k resets all changes to the "image_price_2k" field.
|
||||||
|
func (m *GroupMutation) ResetImagePrice2k() {
|
||||||
|
m.image_price_2k = nil
|
||||||
|
m.addimage_price_2k = nil
|
||||||
|
delete(m.clearedFields, group.FieldImagePrice2k)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImagePrice4k sets the "image_price_4k" field.
|
||||||
|
func (m *GroupMutation) SetImagePrice4k(f float64) {
|
||||||
|
m.image_price_4k = &f
|
||||||
|
m.addimage_price_4k = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4k returns the value of the "image_price_4k" field in the mutation.
|
||||||
|
func (m *GroupMutation) ImagePrice4k() (r float64, exists bool) {
|
||||||
|
v := m.image_price_4k
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldImagePrice4k returns the old "image_price_4k" field's value of the Group entity.
|
||||||
|
// If the Group 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 *GroupMutation) OldImagePrice4k(ctx context.Context) (v *float64, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldImagePrice4k is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldImagePrice4k requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldImagePrice4k: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.ImagePrice4k, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImagePrice4k adds f to the "image_price_4k" field.
|
||||||
|
func (m *GroupMutation) AddImagePrice4k(f float64) {
|
||||||
|
if m.addimage_price_4k != nil {
|
||||||
|
*m.addimage_price_4k += f
|
||||||
|
} else {
|
||||||
|
m.addimage_price_4k = &f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddedImagePrice4k returns the value that was added to the "image_price_4k" field in this mutation.
|
||||||
|
func (m *GroupMutation) AddedImagePrice4k() (r float64, exists bool) {
|
||||||
|
v := m.addimage_price_4k
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImagePrice4k clears the value of the "image_price_4k" field.
|
||||||
|
func (m *GroupMutation) ClearImagePrice4k() {
|
||||||
|
m.image_price_4k = nil
|
||||||
|
m.addimage_price_4k = nil
|
||||||
|
m.clearedFields[group.FieldImagePrice4k] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImagePrice4kCleared returns if the "image_price_4k" field was cleared in this mutation.
|
||||||
|
func (m *GroupMutation) ImagePrice4kCleared() bool {
|
||||||
|
_, ok := m.clearedFields[group.FieldImagePrice4k]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetImagePrice4k resets all changes to the "image_price_4k" field.
|
||||||
|
func (m *GroupMutation) ResetImagePrice4k() {
|
||||||
|
m.image_price_4k = nil
|
||||||
|
m.addimage_price_4k = nil
|
||||||
|
delete(m.clearedFields, group.FieldImagePrice4k)
|
||||||
|
}
|
||||||
|
|
||||||
// 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 *GroupMutation) AddAPIKeyIDs(ids ...int64) {
|
func (m *GroupMutation) AddAPIKeyIDs(ids ...int64) {
|
||||||
if m.api_keys == nil {
|
if m.api_keys == nil {
|
||||||
@@ -4609,7 +4825,7 @@ func (m *GroupMutation) 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 *GroupMutation) Fields() []string {
|
func (m *GroupMutation) Fields() []string {
|
||||||
fields := make([]string, 0, 14)
|
fields := make([]string, 0, 17)
|
||||||
if m.created_at != nil {
|
if m.created_at != nil {
|
||||||
fields = append(fields, group.FieldCreatedAt)
|
fields = append(fields, group.FieldCreatedAt)
|
||||||
}
|
}
|
||||||
@@ -4652,6 +4868,15 @@ func (m *GroupMutation) Fields() []string {
|
|||||||
if m.default_validity_days != nil {
|
if m.default_validity_days != nil {
|
||||||
fields = append(fields, group.FieldDefaultValidityDays)
|
fields = append(fields, group.FieldDefaultValidityDays)
|
||||||
}
|
}
|
||||||
|
if m.image_price_1k != nil {
|
||||||
|
fields = append(fields, group.FieldImagePrice1k)
|
||||||
|
}
|
||||||
|
if m.image_price_2k != nil {
|
||||||
|
fields = append(fields, group.FieldImagePrice2k)
|
||||||
|
}
|
||||||
|
if m.image_price_4k != nil {
|
||||||
|
fields = append(fields, group.FieldImagePrice4k)
|
||||||
|
}
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4688,6 +4913,12 @@ func (m *GroupMutation) Field(name string) (ent.Value, bool) {
|
|||||||
return m.MonthlyLimitUsd()
|
return m.MonthlyLimitUsd()
|
||||||
case group.FieldDefaultValidityDays:
|
case group.FieldDefaultValidityDays:
|
||||||
return m.DefaultValidityDays()
|
return m.DefaultValidityDays()
|
||||||
|
case group.FieldImagePrice1k:
|
||||||
|
return m.ImagePrice1k()
|
||||||
|
case group.FieldImagePrice2k:
|
||||||
|
return m.ImagePrice2k()
|
||||||
|
case group.FieldImagePrice4k:
|
||||||
|
return m.ImagePrice4k()
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
@@ -4725,6 +4956,12 @@ func (m *GroupMutation) OldField(ctx context.Context, name string) (ent.Value, e
|
|||||||
return m.OldMonthlyLimitUsd(ctx)
|
return m.OldMonthlyLimitUsd(ctx)
|
||||||
case group.FieldDefaultValidityDays:
|
case group.FieldDefaultValidityDays:
|
||||||
return m.OldDefaultValidityDays(ctx)
|
return m.OldDefaultValidityDays(ctx)
|
||||||
|
case group.FieldImagePrice1k:
|
||||||
|
return m.OldImagePrice1k(ctx)
|
||||||
|
case group.FieldImagePrice2k:
|
||||||
|
return m.OldImagePrice2k(ctx)
|
||||||
|
case group.FieldImagePrice4k:
|
||||||
|
return m.OldImagePrice4k(ctx)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("unknown Group field %s", name)
|
return nil, fmt.Errorf("unknown Group field %s", name)
|
||||||
}
|
}
|
||||||
@@ -4832,6 +5069,27 @@ func (m *GroupMutation) SetField(name string, value ent.Value) error {
|
|||||||
}
|
}
|
||||||
m.SetDefaultValidityDays(v)
|
m.SetDefaultValidityDays(v)
|
||||||
return nil
|
return nil
|
||||||
|
case group.FieldImagePrice1k:
|
||||||
|
v, ok := value.(float64)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetImagePrice1k(v)
|
||||||
|
return nil
|
||||||
|
case group.FieldImagePrice2k:
|
||||||
|
v, ok := value.(float64)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetImagePrice2k(v)
|
||||||
|
return nil
|
||||||
|
case group.FieldImagePrice4k:
|
||||||
|
v, ok := value.(float64)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetImagePrice4k(v)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown Group field %s", name)
|
return fmt.Errorf("unknown Group field %s", name)
|
||||||
}
|
}
|
||||||
@@ -4855,6 +5113,15 @@ func (m *GroupMutation) AddedFields() []string {
|
|||||||
if m.adddefault_validity_days != nil {
|
if m.adddefault_validity_days != nil {
|
||||||
fields = append(fields, group.FieldDefaultValidityDays)
|
fields = append(fields, group.FieldDefaultValidityDays)
|
||||||
}
|
}
|
||||||
|
if m.addimage_price_1k != nil {
|
||||||
|
fields = append(fields, group.FieldImagePrice1k)
|
||||||
|
}
|
||||||
|
if m.addimage_price_2k != nil {
|
||||||
|
fields = append(fields, group.FieldImagePrice2k)
|
||||||
|
}
|
||||||
|
if m.addimage_price_4k != nil {
|
||||||
|
fields = append(fields, group.FieldImagePrice4k)
|
||||||
|
}
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4873,6 +5140,12 @@ func (m *GroupMutation) AddedField(name string) (ent.Value, bool) {
|
|||||||
return m.AddedMonthlyLimitUsd()
|
return m.AddedMonthlyLimitUsd()
|
||||||
case group.FieldDefaultValidityDays:
|
case group.FieldDefaultValidityDays:
|
||||||
return m.AddedDefaultValidityDays()
|
return m.AddedDefaultValidityDays()
|
||||||
|
case group.FieldImagePrice1k:
|
||||||
|
return m.AddedImagePrice1k()
|
||||||
|
case group.FieldImagePrice2k:
|
||||||
|
return m.AddedImagePrice2k()
|
||||||
|
case group.FieldImagePrice4k:
|
||||||
|
return m.AddedImagePrice4k()
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
@@ -4917,6 +5190,27 @@ func (m *GroupMutation) AddField(name string, value ent.Value) error {
|
|||||||
}
|
}
|
||||||
m.AddDefaultValidityDays(v)
|
m.AddDefaultValidityDays(v)
|
||||||
return nil
|
return nil
|
||||||
|
case group.FieldImagePrice1k:
|
||||||
|
v, ok := value.(float64)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.AddImagePrice1k(v)
|
||||||
|
return nil
|
||||||
|
case group.FieldImagePrice2k:
|
||||||
|
v, ok := value.(float64)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.AddImagePrice2k(v)
|
||||||
|
return nil
|
||||||
|
case group.FieldImagePrice4k:
|
||||||
|
v, ok := value.(float64)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.AddImagePrice4k(v)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown Group numeric field %s", name)
|
return fmt.Errorf("unknown Group numeric field %s", name)
|
||||||
}
|
}
|
||||||
@@ -4940,6 +5234,15 @@ func (m *GroupMutation) ClearedFields() []string {
|
|||||||
if m.FieldCleared(group.FieldMonthlyLimitUsd) {
|
if m.FieldCleared(group.FieldMonthlyLimitUsd) {
|
||||||
fields = append(fields, group.FieldMonthlyLimitUsd)
|
fields = append(fields, group.FieldMonthlyLimitUsd)
|
||||||
}
|
}
|
||||||
|
if m.FieldCleared(group.FieldImagePrice1k) {
|
||||||
|
fields = append(fields, group.FieldImagePrice1k)
|
||||||
|
}
|
||||||
|
if m.FieldCleared(group.FieldImagePrice2k) {
|
||||||
|
fields = append(fields, group.FieldImagePrice2k)
|
||||||
|
}
|
||||||
|
if m.FieldCleared(group.FieldImagePrice4k) {
|
||||||
|
fields = append(fields, group.FieldImagePrice4k)
|
||||||
|
}
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4969,6 +5272,15 @@ func (m *GroupMutation) ClearField(name string) error {
|
|||||||
case group.FieldMonthlyLimitUsd:
|
case group.FieldMonthlyLimitUsd:
|
||||||
m.ClearMonthlyLimitUsd()
|
m.ClearMonthlyLimitUsd()
|
||||||
return nil
|
return nil
|
||||||
|
case group.FieldImagePrice1k:
|
||||||
|
m.ClearImagePrice1k()
|
||||||
|
return nil
|
||||||
|
case group.FieldImagePrice2k:
|
||||||
|
m.ClearImagePrice2k()
|
||||||
|
return nil
|
||||||
|
case group.FieldImagePrice4k:
|
||||||
|
m.ClearImagePrice4k()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown Group nullable field %s", name)
|
return fmt.Errorf("unknown Group nullable field %s", name)
|
||||||
}
|
}
|
||||||
@@ -5019,6 +5331,15 @@ func (m *GroupMutation) ResetField(name string) error {
|
|||||||
case group.FieldDefaultValidityDays:
|
case group.FieldDefaultValidityDays:
|
||||||
m.ResetDefaultValidityDays()
|
m.ResetDefaultValidityDays()
|
||||||
return nil
|
return nil
|
||||||
|
case group.FieldImagePrice1k:
|
||||||
|
m.ResetImagePrice1k()
|
||||||
|
return nil
|
||||||
|
case group.FieldImagePrice2k:
|
||||||
|
m.ResetImagePrice2k()
|
||||||
|
return nil
|
||||||
|
case group.FieldImagePrice4k:
|
||||||
|
m.ResetImagePrice4k()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown Group field %s", name)
|
return fmt.Errorf("unknown Group field %s", name)
|
||||||
}
|
}
|
||||||
@@ -7786,6 +8107,9 @@ type UsageLogMutation struct {
|
|||||||
addduration_ms *int
|
addduration_ms *int
|
||||||
first_token_ms *int
|
first_token_ms *int
|
||||||
addfirst_token_ms *int
|
addfirst_token_ms *int
|
||||||
|
image_count *int
|
||||||
|
addimage_count *int
|
||||||
|
image_size *string
|
||||||
created_at *time.Time
|
created_at *time.Time
|
||||||
clearedFields map[string]struct{}
|
clearedFields map[string]struct{}
|
||||||
user *int64
|
user *int64
|
||||||
@@ -9139,6 +9463,111 @@ func (m *UsageLogMutation) ResetFirstTokenMs() {
|
|||||||
delete(m.clearedFields, usagelog.FieldFirstTokenMs)
|
delete(m.clearedFields, usagelog.FieldFirstTokenMs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImageCount sets the "image_count" field.
|
||||||
|
func (m *UsageLogMutation) SetImageCount(i int) {
|
||||||
|
m.image_count = &i
|
||||||
|
m.addimage_count = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageCount returns the value of the "image_count" field in the mutation.
|
||||||
|
func (m *UsageLogMutation) ImageCount() (r int, exists bool) {
|
||||||
|
v := m.image_count
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldImageCount returns the old "image_count" field's value of the UsageLog entity.
|
||||||
|
// If the UsageLog 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 *UsageLogMutation) OldImageCount(ctx context.Context) (v int, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldImageCount is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldImageCount requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldImageCount: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.ImageCount, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImageCount adds i to the "image_count" field.
|
||||||
|
func (m *UsageLogMutation) AddImageCount(i int) {
|
||||||
|
if m.addimage_count != nil {
|
||||||
|
*m.addimage_count += i
|
||||||
|
} else {
|
||||||
|
m.addimage_count = &i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddedImageCount returns the value that was added to the "image_count" field in this mutation.
|
||||||
|
func (m *UsageLogMutation) AddedImageCount() (r int, exists bool) {
|
||||||
|
v := m.addimage_count
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetImageCount resets all changes to the "image_count" field.
|
||||||
|
func (m *UsageLogMutation) ResetImageCount() {
|
||||||
|
m.image_count = nil
|
||||||
|
m.addimage_count = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImageSize sets the "image_size" field.
|
||||||
|
func (m *UsageLogMutation) SetImageSize(s string) {
|
||||||
|
m.image_size = &s
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSize returns the value of the "image_size" field in the mutation.
|
||||||
|
func (m *UsageLogMutation) ImageSize() (r string, exists bool) {
|
||||||
|
v := m.image_size
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldImageSize returns the old "image_size" field's value of the UsageLog entity.
|
||||||
|
// If the UsageLog 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 *UsageLogMutation) OldImageSize(ctx context.Context) (v *string, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldImageSize is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldImageSize requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldImageSize: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.ImageSize, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImageSize clears the value of the "image_size" field.
|
||||||
|
func (m *UsageLogMutation) ClearImageSize() {
|
||||||
|
m.image_size = nil
|
||||||
|
m.clearedFields[usagelog.FieldImageSize] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeCleared returns if the "image_size" field was cleared in this mutation.
|
||||||
|
func (m *UsageLogMutation) ImageSizeCleared() bool {
|
||||||
|
_, ok := m.clearedFields[usagelog.FieldImageSize]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetImageSize resets all changes to the "image_size" field.
|
||||||
|
func (m *UsageLogMutation) ResetImageSize() {
|
||||||
|
m.image_size = nil
|
||||||
|
delete(m.clearedFields, usagelog.FieldImageSize)
|
||||||
|
}
|
||||||
|
|
||||||
// SetCreatedAt sets the "created_at" field.
|
// SetCreatedAt sets the "created_at" field.
|
||||||
func (m *UsageLogMutation) SetCreatedAt(t time.Time) {
|
func (m *UsageLogMutation) SetCreatedAt(t time.Time) {
|
||||||
m.created_at = &t
|
m.created_at = &t
|
||||||
@@ -9344,7 +9773,7 @@ func (m *UsageLogMutation) 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 *UsageLogMutation) Fields() []string {
|
func (m *UsageLogMutation) Fields() []string {
|
||||||
fields := make([]string, 0, 25)
|
fields := make([]string, 0, 27)
|
||||||
if m.user != nil {
|
if m.user != nil {
|
||||||
fields = append(fields, usagelog.FieldUserID)
|
fields = append(fields, usagelog.FieldUserID)
|
||||||
}
|
}
|
||||||
@@ -9417,6 +9846,12 @@ func (m *UsageLogMutation) Fields() []string {
|
|||||||
if m.first_token_ms != nil {
|
if m.first_token_ms != nil {
|
||||||
fields = append(fields, usagelog.FieldFirstTokenMs)
|
fields = append(fields, usagelog.FieldFirstTokenMs)
|
||||||
}
|
}
|
||||||
|
if m.image_count != nil {
|
||||||
|
fields = append(fields, usagelog.FieldImageCount)
|
||||||
|
}
|
||||||
|
if m.image_size != nil {
|
||||||
|
fields = append(fields, usagelog.FieldImageSize)
|
||||||
|
}
|
||||||
if m.created_at != nil {
|
if m.created_at != nil {
|
||||||
fields = append(fields, usagelog.FieldCreatedAt)
|
fields = append(fields, usagelog.FieldCreatedAt)
|
||||||
}
|
}
|
||||||
@@ -9476,6 +9911,10 @@ func (m *UsageLogMutation) Field(name string) (ent.Value, bool) {
|
|||||||
return m.DurationMs()
|
return m.DurationMs()
|
||||||
case usagelog.FieldFirstTokenMs:
|
case usagelog.FieldFirstTokenMs:
|
||||||
return m.FirstTokenMs()
|
return m.FirstTokenMs()
|
||||||
|
case usagelog.FieldImageCount:
|
||||||
|
return m.ImageCount()
|
||||||
|
case usagelog.FieldImageSize:
|
||||||
|
return m.ImageSize()
|
||||||
case usagelog.FieldCreatedAt:
|
case usagelog.FieldCreatedAt:
|
||||||
return m.CreatedAt()
|
return m.CreatedAt()
|
||||||
}
|
}
|
||||||
@@ -9535,6 +9974,10 @@ func (m *UsageLogMutation) OldField(ctx context.Context, name string) (ent.Value
|
|||||||
return m.OldDurationMs(ctx)
|
return m.OldDurationMs(ctx)
|
||||||
case usagelog.FieldFirstTokenMs:
|
case usagelog.FieldFirstTokenMs:
|
||||||
return m.OldFirstTokenMs(ctx)
|
return m.OldFirstTokenMs(ctx)
|
||||||
|
case usagelog.FieldImageCount:
|
||||||
|
return m.OldImageCount(ctx)
|
||||||
|
case usagelog.FieldImageSize:
|
||||||
|
return m.OldImageSize(ctx)
|
||||||
case usagelog.FieldCreatedAt:
|
case usagelog.FieldCreatedAt:
|
||||||
return m.OldCreatedAt(ctx)
|
return m.OldCreatedAt(ctx)
|
||||||
}
|
}
|
||||||
@@ -9714,6 +10157,20 @@ func (m *UsageLogMutation) SetField(name string, value ent.Value) error {
|
|||||||
}
|
}
|
||||||
m.SetFirstTokenMs(v)
|
m.SetFirstTokenMs(v)
|
||||||
return nil
|
return nil
|
||||||
|
case usagelog.FieldImageCount:
|
||||||
|
v, ok := value.(int)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetImageCount(v)
|
||||||
|
return nil
|
||||||
|
case usagelog.FieldImageSize:
|
||||||
|
v, ok := value.(string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetImageSize(v)
|
||||||
|
return nil
|
||||||
case usagelog.FieldCreatedAt:
|
case usagelog.FieldCreatedAt:
|
||||||
v, ok := value.(time.Time)
|
v, ok := value.(time.Time)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -9777,6 +10234,9 @@ func (m *UsageLogMutation) AddedFields() []string {
|
|||||||
if m.addfirst_token_ms != nil {
|
if m.addfirst_token_ms != nil {
|
||||||
fields = append(fields, usagelog.FieldFirstTokenMs)
|
fields = append(fields, usagelog.FieldFirstTokenMs)
|
||||||
}
|
}
|
||||||
|
if m.addimage_count != nil {
|
||||||
|
fields = append(fields, usagelog.FieldImageCount)
|
||||||
|
}
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9817,6 +10277,8 @@ func (m *UsageLogMutation) AddedField(name string) (ent.Value, bool) {
|
|||||||
return m.AddedDurationMs()
|
return m.AddedDurationMs()
|
||||||
case usagelog.FieldFirstTokenMs:
|
case usagelog.FieldFirstTokenMs:
|
||||||
return m.AddedFirstTokenMs()
|
return m.AddedFirstTokenMs()
|
||||||
|
case usagelog.FieldImageCount:
|
||||||
|
return m.AddedImageCount()
|
||||||
}
|
}
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
@@ -9938,6 +10400,13 @@ func (m *UsageLogMutation) AddField(name string, value ent.Value) error {
|
|||||||
}
|
}
|
||||||
m.AddFirstTokenMs(v)
|
m.AddFirstTokenMs(v)
|
||||||
return nil
|
return nil
|
||||||
|
case usagelog.FieldImageCount:
|
||||||
|
v, ok := value.(int)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.AddImageCount(v)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown UsageLog numeric field %s", name)
|
return fmt.Errorf("unknown UsageLog numeric field %s", name)
|
||||||
}
|
}
|
||||||
@@ -9958,6 +10427,9 @@ func (m *UsageLogMutation) ClearedFields() []string {
|
|||||||
if m.FieldCleared(usagelog.FieldFirstTokenMs) {
|
if m.FieldCleared(usagelog.FieldFirstTokenMs) {
|
||||||
fields = append(fields, usagelog.FieldFirstTokenMs)
|
fields = append(fields, usagelog.FieldFirstTokenMs)
|
||||||
}
|
}
|
||||||
|
if m.FieldCleared(usagelog.FieldImageSize) {
|
||||||
|
fields = append(fields, usagelog.FieldImageSize)
|
||||||
|
}
|
||||||
return fields
|
return fields
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9984,6 +10456,9 @@ func (m *UsageLogMutation) ClearField(name string) error {
|
|||||||
case usagelog.FieldFirstTokenMs:
|
case usagelog.FieldFirstTokenMs:
|
||||||
m.ClearFirstTokenMs()
|
m.ClearFirstTokenMs()
|
||||||
return nil
|
return nil
|
||||||
|
case usagelog.FieldImageSize:
|
||||||
|
m.ClearImageSize()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unknown UsageLog nullable field %s", name)
|
return fmt.Errorf("unknown UsageLog nullable field %s", name)
|
||||||
}
|
}
|
||||||
@@ -10064,6 +10539,12 @@ func (m *UsageLogMutation) ResetField(name string) error {
|
|||||||
case usagelog.FieldFirstTokenMs:
|
case usagelog.FieldFirstTokenMs:
|
||||||
m.ResetFirstTokenMs()
|
m.ResetFirstTokenMs()
|
||||||
return nil
|
return nil
|
||||||
|
case usagelog.FieldImageCount:
|
||||||
|
m.ResetImageCount()
|
||||||
|
return nil
|
||||||
|
case usagelog.FieldImageSize:
|
||||||
|
m.ResetImageSize()
|
||||||
|
return nil
|
||||||
case usagelog.FieldCreatedAt:
|
case usagelog.FieldCreatedAt:
|
||||||
m.ResetCreatedAt()
|
m.ResetCreatedAt()
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -521,8 +521,16 @@ func init() {
|
|||||||
usagelogDescStream := usagelogFields[21].Descriptor()
|
usagelogDescStream := usagelogFields[21].Descriptor()
|
||||||
// usagelog.DefaultStream holds the default value on creation for the stream field.
|
// usagelog.DefaultStream holds the default value on creation for the stream field.
|
||||||
usagelog.DefaultStream = usagelogDescStream.Default.(bool)
|
usagelog.DefaultStream = usagelogDescStream.Default.(bool)
|
||||||
|
// usagelogDescImageCount is the schema descriptor for image_count field.
|
||||||
|
usagelogDescImageCount := usagelogFields[24].Descriptor()
|
||||||
|
// usagelog.DefaultImageCount holds the default value on creation for the image_count field.
|
||||||
|
usagelog.DefaultImageCount = usagelogDescImageCount.Default.(int)
|
||||||
|
// usagelogDescImageSize is the schema descriptor for image_size field.
|
||||||
|
usagelogDescImageSize := usagelogFields[25].Descriptor()
|
||||||
|
// usagelog.ImageSizeValidator is a validator for the "image_size" field. It is called by the builders before save.
|
||||||
|
usagelog.ImageSizeValidator = usagelogDescImageSize.Validators[0].(func(string) error)
|
||||||
// usagelogDescCreatedAt is the schema descriptor for created_at field.
|
// usagelogDescCreatedAt is the schema descriptor for created_at field.
|
||||||
usagelogDescCreatedAt := usagelogFields[24].Descriptor()
|
usagelogDescCreatedAt := usagelogFields[26].Descriptor()
|
||||||
// usagelog.DefaultCreatedAt holds the default value on creation for the created_at field.
|
// usagelog.DefaultCreatedAt holds the default value on creation for the created_at field.
|
||||||
usagelog.DefaultCreatedAt = usagelogDescCreatedAt.Default.(func() time.Time)
|
usagelog.DefaultCreatedAt = usagelogDescCreatedAt.Default.(func() time.Time)
|
||||||
userMixin := schema.User{}.Mixin()
|
userMixin := schema.User{}.Mixin()
|
||||||
|
|||||||
@@ -72,6 +72,20 @@ func (Group) Fields() []ent.Field {
|
|||||||
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
|
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
|
||||||
field.Int("default_validity_days").
|
field.Int("default_validity_days").
|
||||||
Default(30),
|
Default(30),
|
||||||
|
|
||||||
|
// 图片生成计费配置(antigravity 和 gemini 平台使用)
|
||||||
|
field.Float("image_price_1k").
|
||||||
|
Optional().
|
||||||
|
Nillable().
|
||||||
|
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
|
||||||
|
field.Float("image_price_2k").
|
||||||
|
Optional().
|
||||||
|
Nillable().
|
||||||
|
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
|
||||||
|
field.Float("image_price_4k").
|
||||||
|
Optional().
|
||||||
|
Nillable().
|
||||||
|
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,14 @@ func (UsageLog) Fields() []ent.Field {
|
|||||||
Optional().
|
Optional().
|
||||||
Nillable(),
|
Nillable(),
|
||||||
|
|
||||||
|
// 图片生成字段(仅 gemini-3-pro-image 等图片模型使用)
|
||||||
|
field.Int("image_count").
|
||||||
|
Default(0),
|
||||||
|
field.String("image_size").
|
||||||
|
MaxLen(10).
|
||||||
|
Optional().
|
||||||
|
Nillable(),
|
||||||
|
|
||||||
// 时间戳(只有 created_at,日志不可修改)
|
// 时间戳(只有 created_at,日志不可修改)
|
||||||
field.Time("created_at").
|
field.Time("created_at").
|
||||||
Default(time.Now).
|
Default(time.Now).
|
||||||
|
|||||||
@@ -70,6 +70,10 @@ type UsageLog struct {
|
|||||||
DurationMs *int `json:"duration_ms,omitempty"`
|
DurationMs *int `json:"duration_ms,omitempty"`
|
||||||
// FirstTokenMs holds the value of the "first_token_ms" field.
|
// FirstTokenMs holds the value of the "first_token_ms" field.
|
||||||
FirstTokenMs *int `json:"first_token_ms,omitempty"`
|
FirstTokenMs *int `json:"first_token_ms,omitempty"`
|
||||||
|
// ImageCount holds the value of the "image_count" field.
|
||||||
|
ImageCount int `json:"image_count,omitempty"`
|
||||||
|
// ImageSize holds the value of the "image_size" field.
|
||||||
|
ImageSize *string `json:"image_size,omitempty"`
|
||||||
// CreatedAt holds the value of the "created_at" field.
|
// CreatedAt holds the value of the "created_at" field.
|
||||||
CreatedAt time.Time `json:"created_at,omitempty"`
|
CreatedAt time.Time `json:"created_at,omitempty"`
|
||||||
// Edges holds the relations/edges for other nodes in the graph.
|
// Edges holds the relations/edges for other nodes in the graph.
|
||||||
@@ -159,9 +163,9 @@ func (*UsageLog) scanValues(columns []string) ([]any, error) {
|
|||||||
values[i] = new(sql.NullBool)
|
values[i] = new(sql.NullBool)
|
||||||
case usagelog.FieldInputCost, usagelog.FieldOutputCost, usagelog.FieldCacheCreationCost, usagelog.FieldCacheReadCost, usagelog.FieldTotalCost, usagelog.FieldActualCost, usagelog.FieldRateMultiplier:
|
case usagelog.FieldInputCost, usagelog.FieldOutputCost, usagelog.FieldCacheCreationCost, usagelog.FieldCacheReadCost, usagelog.FieldTotalCost, usagelog.FieldActualCost, usagelog.FieldRateMultiplier:
|
||||||
values[i] = new(sql.NullFloat64)
|
values[i] = new(sql.NullFloat64)
|
||||||
case usagelog.FieldID, usagelog.FieldUserID, usagelog.FieldAPIKeyID, usagelog.FieldAccountID, usagelog.FieldGroupID, usagelog.FieldSubscriptionID, usagelog.FieldInputTokens, usagelog.FieldOutputTokens, usagelog.FieldCacheCreationTokens, usagelog.FieldCacheReadTokens, usagelog.FieldCacheCreation5mTokens, usagelog.FieldCacheCreation1hTokens, usagelog.FieldBillingType, usagelog.FieldDurationMs, usagelog.FieldFirstTokenMs:
|
case usagelog.FieldID, usagelog.FieldUserID, usagelog.FieldAPIKeyID, usagelog.FieldAccountID, usagelog.FieldGroupID, usagelog.FieldSubscriptionID, usagelog.FieldInputTokens, usagelog.FieldOutputTokens, usagelog.FieldCacheCreationTokens, usagelog.FieldCacheReadTokens, usagelog.FieldCacheCreation5mTokens, usagelog.FieldCacheCreation1hTokens, usagelog.FieldBillingType, usagelog.FieldDurationMs, usagelog.FieldFirstTokenMs, usagelog.FieldImageCount:
|
||||||
values[i] = new(sql.NullInt64)
|
values[i] = new(sql.NullInt64)
|
||||||
case usagelog.FieldRequestID, usagelog.FieldModel:
|
case usagelog.FieldRequestID, usagelog.FieldModel, usagelog.FieldImageSize:
|
||||||
values[i] = new(sql.NullString)
|
values[i] = new(sql.NullString)
|
||||||
case usagelog.FieldCreatedAt:
|
case usagelog.FieldCreatedAt:
|
||||||
values[i] = new(sql.NullTime)
|
values[i] = new(sql.NullTime)
|
||||||
@@ -334,6 +338,19 @@ func (_m *UsageLog) assignValues(columns []string, values []any) error {
|
|||||||
_m.FirstTokenMs = new(int)
|
_m.FirstTokenMs = new(int)
|
||||||
*_m.FirstTokenMs = int(value.Int64)
|
*_m.FirstTokenMs = int(value.Int64)
|
||||||
}
|
}
|
||||||
|
case usagelog.FieldImageCount:
|
||||||
|
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field image_count", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
_m.ImageCount = int(value.Int64)
|
||||||
|
}
|
||||||
|
case usagelog.FieldImageSize:
|
||||||
|
if value, ok := values[i].(*sql.NullString); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field image_size", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
_m.ImageSize = new(string)
|
||||||
|
*_m.ImageSize = value.String
|
||||||
|
}
|
||||||
case usagelog.FieldCreatedAt:
|
case usagelog.FieldCreatedAt:
|
||||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||||
return fmt.Errorf("unexpected type %T for field created_at", values[i])
|
return fmt.Errorf("unexpected type %T for field created_at", values[i])
|
||||||
@@ -481,6 +498,14 @@ func (_m *UsageLog) String() string {
|
|||||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||||
}
|
}
|
||||||
builder.WriteString(", ")
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("image_count=")
|
||||||
|
builder.WriteString(fmt.Sprintf("%v", _m.ImageCount))
|
||||||
|
builder.WriteString(", ")
|
||||||
|
if v := _m.ImageSize; v != nil {
|
||||||
|
builder.WriteString("image_size=")
|
||||||
|
builder.WriteString(*v)
|
||||||
|
}
|
||||||
|
builder.WriteString(", ")
|
||||||
builder.WriteString("created_at=")
|
builder.WriteString("created_at=")
|
||||||
builder.WriteString(_m.CreatedAt.Format(time.ANSIC))
|
builder.WriteString(_m.CreatedAt.Format(time.ANSIC))
|
||||||
builder.WriteByte(')')
|
builder.WriteByte(')')
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ const (
|
|||||||
FieldDurationMs = "duration_ms"
|
FieldDurationMs = "duration_ms"
|
||||||
// FieldFirstTokenMs holds the string denoting the first_token_ms field in the database.
|
// FieldFirstTokenMs holds the string denoting the first_token_ms field in the database.
|
||||||
FieldFirstTokenMs = "first_token_ms"
|
FieldFirstTokenMs = "first_token_ms"
|
||||||
|
// FieldImageCount holds the string denoting the image_count field in the database.
|
||||||
|
FieldImageCount = "image_count"
|
||||||
|
// FieldImageSize holds the string denoting the image_size field in the database.
|
||||||
|
FieldImageSize = "image_size"
|
||||||
// FieldCreatedAt holds the string denoting the created_at field in the database.
|
// FieldCreatedAt holds the string denoting the created_at field in the database.
|
||||||
FieldCreatedAt = "created_at"
|
FieldCreatedAt = "created_at"
|
||||||
// EdgeUser holds the string denoting the user edge name in mutations.
|
// EdgeUser holds the string denoting the user edge name in mutations.
|
||||||
@@ -140,6 +144,8 @@ var Columns = []string{
|
|||||||
FieldStream,
|
FieldStream,
|
||||||
FieldDurationMs,
|
FieldDurationMs,
|
||||||
FieldFirstTokenMs,
|
FieldFirstTokenMs,
|
||||||
|
FieldImageCount,
|
||||||
|
FieldImageSize,
|
||||||
FieldCreatedAt,
|
FieldCreatedAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,6 +194,10 @@ var (
|
|||||||
DefaultBillingType int8
|
DefaultBillingType int8
|
||||||
// DefaultStream holds the default value on creation for the "stream" field.
|
// DefaultStream holds the default value on creation for the "stream" field.
|
||||||
DefaultStream bool
|
DefaultStream bool
|
||||||
|
// DefaultImageCount holds the default value on creation for the "image_count" field.
|
||||||
|
DefaultImageCount int
|
||||||
|
// ImageSizeValidator is a validator for the "image_size" field. It is called by the builders before save.
|
||||||
|
ImageSizeValidator func(string) error
|
||||||
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||||
DefaultCreatedAt func() time.Time
|
DefaultCreatedAt func() time.Time
|
||||||
)
|
)
|
||||||
@@ -320,6 +330,16 @@ func ByFirstTokenMs(opts ...sql.OrderTermOption) OrderOption {
|
|||||||
return sql.OrderByField(FieldFirstTokenMs, opts...).ToFunc()
|
return sql.OrderByField(FieldFirstTokenMs, opts...).ToFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ByImageCount orders the results by the image_count field.
|
||||||
|
func ByImageCount(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldImageCount, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByImageSize orders the results by the image_size field.
|
||||||
|
func ByImageSize(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldImageSize, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
// ByCreatedAt orders the results by the created_at field.
|
// ByCreatedAt orders the results by the created_at field.
|
||||||
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||||
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||||
|
|||||||
@@ -175,6 +175,16 @@ func FirstTokenMs(v int) predicate.UsageLog {
|
|||||||
return predicate.UsageLog(sql.FieldEQ(FieldFirstTokenMs, v))
|
return predicate.UsageLog(sql.FieldEQ(FieldFirstTokenMs, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImageCount applies equality check predicate on the "image_count" field. It's identical to ImageCountEQ.
|
||||||
|
func ImageCount(v int) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldEQ(FieldImageCount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSize applies equality check predicate on the "image_size" field. It's identical to ImageSizeEQ.
|
||||||
|
func ImageSize(v string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldEQ(FieldImageSize, v))
|
||||||
|
}
|
||||||
|
|
||||||
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
|
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
|
||||||
func CreatedAt(v time.Time) predicate.UsageLog {
|
func CreatedAt(v time.Time) predicate.UsageLog {
|
||||||
return predicate.UsageLog(sql.FieldEQ(FieldCreatedAt, v))
|
return predicate.UsageLog(sql.FieldEQ(FieldCreatedAt, v))
|
||||||
@@ -1100,6 +1110,121 @@ func FirstTokenMsNotNil() predicate.UsageLog {
|
|||||||
return predicate.UsageLog(sql.FieldNotNull(FieldFirstTokenMs))
|
return predicate.UsageLog(sql.FieldNotNull(FieldFirstTokenMs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImageCountEQ applies the EQ predicate on the "image_count" field.
|
||||||
|
func ImageCountEQ(v int) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldEQ(FieldImageCount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageCountNEQ applies the NEQ predicate on the "image_count" field.
|
||||||
|
func ImageCountNEQ(v int) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldNEQ(FieldImageCount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageCountIn applies the In predicate on the "image_count" field.
|
||||||
|
func ImageCountIn(vs ...int) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldIn(FieldImageCount, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageCountNotIn applies the NotIn predicate on the "image_count" field.
|
||||||
|
func ImageCountNotIn(vs ...int) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldNotIn(FieldImageCount, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageCountGT applies the GT predicate on the "image_count" field.
|
||||||
|
func ImageCountGT(v int) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldGT(FieldImageCount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageCountGTE applies the GTE predicate on the "image_count" field.
|
||||||
|
func ImageCountGTE(v int) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldGTE(FieldImageCount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageCountLT applies the LT predicate on the "image_count" field.
|
||||||
|
func ImageCountLT(v int) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldLT(FieldImageCount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageCountLTE applies the LTE predicate on the "image_count" field.
|
||||||
|
func ImageCountLTE(v int) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldLTE(FieldImageCount, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeEQ applies the EQ predicate on the "image_size" field.
|
||||||
|
func ImageSizeEQ(v string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldEQ(FieldImageSize, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeNEQ applies the NEQ predicate on the "image_size" field.
|
||||||
|
func ImageSizeNEQ(v string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldNEQ(FieldImageSize, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeIn applies the In predicate on the "image_size" field.
|
||||||
|
func ImageSizeIn(vs ...string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldIn(FieldImageSize, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeNotIn applies the NotIn predicate on the "image_size" field.
|
||||||
|
func ImageSizeNotIn(vs ...string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldNotIn(FieldImageSize, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeGT applies the GT predicate on the "image_size" field.
|
||||||
|
func ImageSizeGT(v string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldGT(FieldImageSize, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeGTE applies the GTE predicate on the "image_size" field.
|
||||||
|
func ImageSizeGTE(v string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldGTE(FieldImageSize, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeLT applies the LT predicate on the "image_size" field.
|
||||||
|
func ImageSizeLT(v string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldLT(FieldImageSize, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeLTE applies the LTE predicate on the "image_size" field.
|
||||||
|
func ImageSizeLTE(v string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldLTE(FieldImageSize, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeContains applies the Contains predicate on the "image_size" field.
|
||||||
|
func ImageSizeContains(v string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldContains(FieldImageSize, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeHasPrefix applies the HasPrefix predicate on the "image_size" field.
|
||||||
|
func ImageSizeHasPrefix(v string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldHasPrefix(FieldImageSize, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeHasSuffix applies the HasSuffix predicate on the "image_size" field.
|
||||||
|
func ImageSizeHasSuffix(v string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldHasSuffix(FieldImageSize, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeIsNil applies the IsNil predicate on the "image_size" field.
|
||||||
|
func ImageSizeIsNil() predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldIsNull(FieldImageSize))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeNotNil applies the NotNil predicate on the "image_size" field.
|
||||||
|
func ImageSizeNotNil() predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldNotNull(FieldImageSize))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeEqualFold applies the EqualFold predicate on the "image_size" field.
|
||||||
|
func ImageSizeEqualFold(v string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldEqualFold(FieldImageSize, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImageSizeContainsFold applies the ContainsFold predicate on the "image_size" field.
|
||||||
|
func ImageSizeContainsFold(v string) predicate.UsageLog {
|
||||||
|
return predicate.UsageLog(sql.FieldContainsFold(FieldImageSize, 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.UsageLog {
|
func CreatedAtEQ(v time.Time) predicate.UsageLog {
|
||||||
return predicate.UsageLog(sql.FieldEQ(FieldCreatedAt, v))
|
return predicate.UsageLog(sql.FieldEQ(FieldCreatedAt, v))
|
||||||
|
|||||||
@@ -323,6 +323,34 @@ func (_c *UsageLogCreate) SetNillableFirstTokenMs(v *int) *UsageLogCreate {
|
|||||||
return _c
|
return _c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImageCount sets the "image_count" field.
|
||||||
|
func (_c *UsageLogCreate) SetImageCount(v int) *UsageLogCreate {
|
||||||
|
_c.mutation.SetImageCount(v)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImageCount sets the "image_count" field if the given value is not nil.
|
||||||
|
func (_c *UsageLogCreate) SetNillableImageCount(v *int) *UsageLogCreate {
|
||||||
|
if v != nil {
|
||||||
|
_c.SetImageCount(*v)
|
||||||
|
}
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImageSize sets the "image_size" field.
|
||||||
|
func (_c *UsageLogCreate) SetImageSize(v string) *UsageLogCreate {
|
||||||
|
_c.mutation.SetImageSize(v)
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImageSize sets the "image_size" field if the given value is not nil.
|
||||||
|
func (_c *UsageLogCreate) SetNillableImageSize(v *string) *UsageLogCreate {
|
||||||
|
if v != nil {
|
||||||
|
_c.SetImageSize(*v)
|
||||||
|
}
|
||||||
|
return _c
|
||||||
|
}
|
||||||
|
|
||||||
// SetCreatedAt sets the "created_at" field.
|
// SetCreatedAt sets the "created_at" field.
|
||||||
func (_c *UsageLogCreate) SetCreatedAt(v time.Time) *UsageLogCreate {
|
func (_c *UsageLogCreate) SetCreatedAt(v time.Time) *UsageLogCreate {
|
||||||
_c.mutation.SetCreatedAt(v)
|
_c.mutation.SetCreatedAt(v)
|
||||||
@@ -457,6 +485,10 @@ func (_c *UsageLogCreate) defaults() {
|
|||||||
v := usagelog.DefaultStream
|
v := usagelog.DefaultStream
|
||||||
_c.mutation.SetStream(v)
|
_c.mutation.SetStream(v)
|
||||||
}
|
}
|
||||||
|
if _, ok := _c.mutation.ImageCount(); !ok {
|
||||||
|
v := usagelog.DefaultImageCount
|
||||||
|
_c.mutation.SetImageCount(v)
|
||||||
|
}
|
||||||
if _, ok := _c.mutation.CreatedAt(); !ok {
|
if _, ok := _c.mutation.CreatedAt(); !ok {
|
||||||
v := usagelog.DefaultCreatedAt()
|
v := usagelog.DefaultCreatedAt()
|
||||||
_c.mutation.SetCreatedAt(v)
|
_c.mutation.SetCreatedAt(v)
|
||||||
@@ -535,6 +567,14 @@ func (_c *UsageLogCreate) check() error {
|
|||||||
if _, ok := _c.mutation.Stream(); !ok {
|
if _, ok := _c.mutation.Stream(); !ok {
|
||||||
return &ValidationError{Name: "stream", err: errors.New(`ent: missing required field "UsageLog.stream"`)}
|
return &ValidationError{Name: "stream", err: errors.New(`ent: missing required field "UsageLog.stream"`)}
|
||||||
}
|
}
|
||||||
|
if _, ok := _c.mutation.ImageCount(); !ok {
|
||||||
|
return &ValidationError{Name: "image_count", err: errors.New(`ent: missing required field "UsageLog.image_count"`)}
|
||||||
|
}
|
||||||
|
if v, ok := _c.mutation.ImageSize(); ok {
|
||||||
|
if err := usagelog.ImageSizeValidator(v); err != nil {
|
||||||
|
return &ValidationError{Name: "image_size", err: fmt.Errorf(`ent: validator failed for field "UsageLog.image_size": %w`, err)}
|
||||||
|
}
|
||||||
|
}
|
||||||
if _, ok := _c.mutation.CreatedAt(); !ok {
|
if _, ok := _c.mutation.CreatedAt(); !ok {
|
||||||
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "UsageLog.created_at"`)}
|
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "UsageLog.created_at"`)}
|
||||||
}
|
}
|
||||||
@@ -650,6 +690,14 @@ func (_c *UsageLogCreate) createSpec() (*UsageLog, *sqlgraph.CreateSpec) {
|
|||||||
_spec.SetField(usagelog.FieldFirstTokenMs, field.TypeInt, value)
|
_spec.SetField(usagelog.FieldFirstTokenMs, field.TypeInt, value)
|
||||||
_node.FirstTokenMs = &value
|
_node.FirstTokenMs = &value
|
||||||
}
|
}
|
||||||
|
if value, ok := _c.mutation.ImageCount(); ok {
|
||||||
|
_spec.SetField(usagelog.FieldImageCount, field.TypeInt, value)
|
||||||
|
_node.ImageCount = value
|
||||||
|
}
|
||||||
|
if value, ok := _c.mutation.ImageSize(); ok {
|
||||||
|
_spec.SetField(usagelog.FieldImageSize, field.TypeString, value)
|
||||||
|
_node.ImageSize = &value
|
||||||
|
}
|
||||||
if value, ok := _c.mutation.CreatedAt(); ok {
|
if value, ok := _c.mutation.CreatedAt(); ok {
|
||||||
_spec.SetField(usagelog.FieldCreatedAt, field.TypeTime, value)
|
_spec.SetField(usagelog.FieldCreatedAt, field.TypeTime, value)
|
||||||
_node.CreatedAt = value
|
_node.CreatedAt = value
|
||||||
@@ -1199,6 +1247,42 @@ func (u *UsageLogUpsert) ClearFirstTokenMs() *UsageLogUpsert {
|
|||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImageCount sets the "image_count" field.
|
||||||
|
func (u *UsageLogUpsert) SetImageCount(v int) *UsageLogUpsert {
|
||||||
|
u.Set(usagelog.FieldImageCount, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImageCount sets the "image_count" field to the value that was provided on create.
|
||||||
|
func (u *UsageLogUpsert) UpdateImageCount() *UsageLogUpsert {
|
||||||
|
u.SetExcluded(usagelog.FieldImageCount)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImageCount adds v to the "image_count" field.
|
||||||
|
func (u *UsageLogUpsert) AddImageCount(v int) *UsageLogUpsert {
|
||||||
|
u.Add(usagelog.FieldImageCount, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImageSize sets the "image_size" field.
|
||||||
|
func (u *UsageLogUpsert) SetImageSize(v string) *UsageLogUpsert {
|
||||||
|
u.Set(usagelog.FieldImageSize, v)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImageSize sets the "image_size" field to the value that was provided on create.
|
||||||
|
func (u *UsageLogUpsert) UpdateImageSize() *UsageLogUpsert {
|
||||||
|
u.SetExcluded(usagelog.FieldImageSize)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImageSize clears the value of the "image_size" field.
|
||||||
|
func (u *UsageLogUpsert) ClearImageSize() *UsageLogUpsert {
|
||||||
|
u.SetNull(usagelog.FieldImageSize)
|
||||||
|
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:
|
||||||
//
|
//
|
||||||
@@ -1720,6 +1804,48 @@ func (u *UsageLogUpsertOne) ClearFirstTokenMs() *UsageLogUpsertOne {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImageCount sets the "image_count" field.
|
||||||
|
func (u *UsageLogUpsertOne) SetImageCount(v int) *UsageLogUpsertOne {
|
||||||
|
return u.Update(func(s *UsageLogUpsert) {
|
||||||
|
s.SetImageCount(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImageCount adds v to the "image_count" field.
|
||||||
|
func (u *UsageLogUpsertOne) AddImageCount(v int) *UsageLogUpsertOne {
|
||||||
|
return u.Update(func(s *UsageLogUpsert) {
|
||||||
|
s.AddImageCount(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImageCount sets the "image_count" field to the value that was provided on create.
|
||||||
|
func (u *UsageLogUpsertOne) UpdateImageCount() *UsageLogUpsertOne {
|
||||||
|
return u.Update(func(s *UsageLogUpsert) {
|
||||||
|
s.UpdateImageCount()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImageSize sets the "image_size" field.
|
||||||
|
func (u *UsageLogUpsertOne) SetImageSize(v string) *UsageLogUpsertOne {
|
||||||
|
return u.Update(func(s *UsageLogUpsert) {
|
||||||
|
s.SetImageSize(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImageSize sets the "image_size" field to the value that was provided on create.
|
||||||
|
func (u *UsageLogUpsertOne) UpdateImageSize() *UsageLogUpsertOne {
|
||||||
|
return u.Update(func(s *UsageLogUpsert) {
|
||||||
|
s.UpdateImageSize()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImageSize clears the value of the "image_size" field.
|
||||||
|
func (u *UsageLogUpsertOne) ClearImageSize() *UsageLogUpsertOne {
|
||||||
|
return u.Update(func(s *UsageLogUpsert) {
|
||||||
|
s.ClearImageSize()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Exec executes the query.
|
// Exec executes the query.
|
||||||
func (u *UsageLogUpsertOne) Exec(ctx context.Context) error {
|
func (u *UsageLogUpsertOne) Exec(ctx context.Context) error {
|
||||||
if len(u.create.conflict) == 0 {
|
if len(u.create.conflict) == 0 {
|
||||||
@@ -2407,6 +2533,48 @@ func (u *UsageLogUpsertBulk) ClearFirstTokenMs() *UsageLogUpsertBulk {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImageCount sets the "image_count" field.
|
||||||
|
func (u *UsageLogUpsertBulk) SetImageCount(v int) *UsageLogUpsertBulk {
|
||||||
|
return u.Update(func(s *UsageLogUpsert) {
|
||||||
|
s.SetImageCount(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImageCount adds v to the "image_count" field.
|
||||||
|
func (u *UsageLogUpsertBulk) AddImageCount(v int) *UsageLogUpsertBulk {
|
||||||
|
return u.Update(func(s *UsageLogUpsert) {
|
||||||
|
s.AddImageCount(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImageCount sets the "image_count" field to the value that was provided on create.
|
||||||
|
func (u *UsageLogUpsertBulk) UpdateImageCount() *UsageLogUpsertBulk {
|
||||||
|
return u.Update(func(s *UsageLogUpsert) {
|
||||||
|
s.UpdateImageCount()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImageSize sets the "image_size" field.
|
||||||
|
func (u *UsageLogUpsertBulk) SetImageSize(v string) *UsageLogUpsertBulk {
|
||||||
|
return u.Update(func(s *UsageLogUpsert) {
|
||||||
|
s.SetImageSize(v)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateImageSize sets the "image_size" field to the value that was provided on create.
|
||||||
|
func (u *UsageLogUpsertBulk) UpdateImageSize() *UsageLogUpsertBulk {
|
||||||
|
return u.Update(func(s *UsageLogUpsert) {
|
||||||
|
s.UpdateImageSize()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImageSize clears the value of the "image_size" field.
|
||||||
|
func (u *UsageLogUpsertBulk) ClearImageSize() *UsageLogUpsertBulk {
|
||||||
|
return u.Update(func(s *UsageLogUpsert) {
|
||||||
|
s.ClearImageSize()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Exec executes the query.
|
// Exec executes the query.
|
||||||
func (u *UsageLogUpsertBulk) Exec(ctx context.Context) error {
|
func (u *UsageLogUpsertBulk) Exec(ctx context.Context) error {
|
||||||
if u.create.err != nil {
|
if u.create.err != nil {
|
||||||
|
|||||||
@@ -504,6 +504,47 @@ func (_u *UsageLogUpdate) ClearFirstTokenMs() *UsageLogUpdate {
|
|||||||
return _u
|
return _u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImageCount sets the "image_count" field.
|
||||||
|
func (_u *UsageLogUpdate) SetImageCount(v int) *UsageLogUpdate {
|
||||||
|
_u.mutation.ResetImageCount()
|
||||||
|
_u.mutation.SetImageCount(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImageCount sets the "image_count" field if the given value is not nil.
|
||||||
|
func (_u *UsageLogUpdate) SetNillableImageCount(v *int) *UsageLogUpdate {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetImageCount(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImageCount adds value to the "image_count" field.
|
||||||
|
func (_u *UsageLogUpdate) AddImageCount(v int) *UsageLogUpdate {
|
||||||
|
_u.mutation.AddImageCount(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImageSize sets the "image_size" field.
|
||||||
|
func (_u *UsageLogUpdate) SetImageSize(v string) *UsageLogUpdate {
|
||||||
|
_u.mutation.SetImageSize(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImageSize sets the "image_size" field if the given value is not nil.
|
||||||
|
func (_u *UsageLogUpdate) SetNillableImageSize(v *string) *UsageLogUpdate {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetImageSize(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImageSize clears the value of the "image_size" field.
|
||||||
|
func (_u *UsageLogUpdate) ClearImageSize() *UsageLogUpdate {
|
||||||
|
_u.mutation.ClearImageSize()
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
// SetUser sets the "user" edge to the User entity.
|
// SetUser sets the "user" edge to the User entity.
|
||||||
func (_u *UsageLogUpdate) SetUser(v *User) *UsageLogUpdate {
|
func (_u *UsageLogUpdate) SetUser(v *User) *UsageLogUpdate {
|
||||||
return _u.SetUserID(v.ID)
|
return _u.SetUserID(v.ID)
|
||||||
@@ -603,6 +644,11 @@ func (_u *UsageLogUpdate) check() error {
|
|||||||
return &ValidationError{Name: "model", err: fmt.Errorf(`ent: validator failed for field "UsageLog.model": %w`, err)}
|
return &ValidationError{Name: "model", err: fmt.Errorf(`ent: validator failed for field "UsageLog.model": %w`, err)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if v, ok := _u.mutation.ImageSize(); ok {
|
||||||
|
if err := usagelog.ImageSizeValidator(v); err != nil {
|
||||||
|
return &ValidationError{Name: "image_size", err: fmt.Errorf(`ent: validator failed for field "UsageLog.image_size": %w`, err)}
|
||||||
|
}
|
||||||
|
}
|
||||||
if _u.mutation.UserCleared() && len(_u.mutation.UserIDs()) > 0 {
|
if _u.mutation.UserCleared() && len(_u.mutation.UserIDs()) > 0 {
|
||||||
return errors.New(`ent: clearing a required unique edge "UsageLog.user"`)
|
return errors.New(`ent: clearing a required unique edge "UsageLog.user"`)
|
||||||
}
|
}
|
||||||
@@ -738,6 +784,18 @@ func (_u *UsageLogUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
|||||||
if _u.mutation.FirstTokenMsCleared() {
|
if _u.mutation.FirstTokenMsCleared() {
|
||||||
_spec.ClearField(usagelog.FieldFirstTokenMs, field.TypeInt)
|
_spec.ClearField(usagelog.FieldFirstTokenMs, field.TypeInt)
|
||||||
}
|
}
|
||||||
|
if value, ok := _u.mutation.ImageCount(); ok {
|
||||||
|
_spec.SetField(usagelog.FieldImageCount, field.TypeInt, value)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.AddedImageCount(); ok {
|
||||||
|
_spec.AddField(usagelog.FieldImageCount, field.TypeInt, value)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.ImageSize(); ok {
|
||||||
|
_spec.SetField(usagelog.FieldImageSize, field.TypeString, value)
|
||||||
|
}
|
||||||
|
if _u.mutation.ImageSizeCleared() {
|
||||||
|
_spec.ClearField(usagelog.FieldImageSize, field.TypeString)
|
||||||
|
}
|
||||||
if _u.mutation.UserCleared() {
|
if _u.mutation.UserCleared() {
|
||||||
edge := &sqlgraph.EdgeSpec{
|
edge := &sqlgraph.EdgeSpec{
|
||||||
Rel: sqlgraph.M2O,
|
Rel: sqlgraph.M2O,
|
||||||
@@ -1375,6 +1433,47 @@ func (_u *UsageLogUpdateOne) ClearFirstTokenMs() *UsageLogUpdateOne {
|
|||||||
return _u
|
return _u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetImageCount sets the "image_count" field.
|
||||||
|
func (_u *UsageLogUpdateOne) SetImageCount(v int) *UsageLogUpdateOne {
|
||||||
|
_u.mutation.ResetImageCount()
|
||||||
|
_u.mutation.SetImageCount(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImageCount sets the "image_count" field if the given value is not nil.
|
||||||
|
func (_u *UsageLogUpdateOne) SetNillableImageCount(v *int) *UsageLogUpdateOne {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetImageCount(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddImageCount adds value to the "image_count" field.
|
||||||
|
func (_u *UsageLogUpdateOne) AddImageCount(v int) *UsageLogUpdateOne {
|
||||||
|
_u.mutation.AddImageCount(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetImageSize sets the "image_size" field.
|
||||||
|
func (_u *UsageLogUpdateOne) SetImageSize(v string) *UsageLogUpdateOne {
|
||||||
|
_u.mutation.SetImageSize(v)
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillableImageSize sets the "image_size" field if the given value is not nil.
|
||||||
|
func (_u *UsageLogUpdateOne) SetNillableImageSize(v *string) *UsageLogUpdateOne {
|
||||||
|
if v != nil {
|
||||||
|
_u.SetImageSize(*v)
|
||||||
|
}
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearImageSize clears the value of the "image_size" field.
|
||||||
|
func (_u *UsageLogUpdateOne) ClearImageSize() *UsageLogUpdateOne {
|
||||||
|
_u.mutation.ClearImageSize()
|
||||||
|
return _u
|
||||||
|
}
|
||||||
|
|
||||||
// SetUser sets the "user" edge to the User entity.
|
// SetUser sets the "user" edge to the User entity.
|
||||||
func (_u *UsageLogUpdateOne) SetUser(v *User) *UsageLogUpdateOne {
|
func (_u *UsageLogUpdateOne) SetUser(v *User) *UsageLogUpdateOne {
|
||||||
return _u.SetUserID(v.ID)
|
return _u.SetUserID(v.ID)
|
||||||
@@ -1487,6 +1586,11 @@ func (_u *UsageLogUpdateOne) check() error {
|
|||||||
return &ValidationError{Name: "model", err: fmt.Errorf(`ent: validator failed for field "UsageLog.model": %w`, err)}
|
return &ValidationError{Name: "model", err: fmt.Errorf(`ent: validator failed for field "UsageLog.model": %w`, err)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if v, ok := _u.mutation.ImageSize(); ok {
|
||||||
|
if err := usagelog.ImageSizeValidator(v); err != nil {
|
||||||
|
return &ValidationError{Name: "image_size", err: fmt.Errorf(`ent: validator failed for field "UsageLog.image_size": %w`, err)}
|
||||||
|
}
|
||||||
|
}
|
||||||
if _u.mutation.UserCleared() && len(_u.mutation.UserIDs()) > 0 {
|
if _u.mutation.UserCleared() && len(_u.mutation.UserIDs()) > 0 {
|
||||||
return errors.New(`ent: clearing a required unique edge "UsageLog.user"`)
|
return errors.New(`ent: clearing a required unique edge "UsageLog.user"`)
|
||||||
}
|
}
|
||||||
@@ -1639,6 +1743,18 @@ func (_u *UsageLogUpdateOne) sqlSave(ctx context.Context) (_node *UsageLog, err
|
|||||||
if _u.mutation.FirstTokenMsCleared() {
|
if _u.mutation.FirstTokenMsCleared() {
|
||||||
_spec.ClearField(usagelog.FieldFirstTokenMs, field.TypeInt)
|
_spec.ClearField(usagelog.FieldFirstTokenMs, field.TypeInt)
|
||||||
}
|
}
|
||||||
|
if value, ok := _u.mutation.ImageCount(); ok {
|
||||||
|
_spec.SetField(usagelog.FieldImageCount, field.TypeInt, value)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.AddedImageCount(); ok {
|
||||||
|
_spec.AddField(usagelog.FieldImageCount, field.TypeInt, value)
|
||||||
|
}
|
||||||
|
if value, ok := _u.mutation.ImageSize(); ok {
|
||||||
|
_spec.SetField(usagelog.FieldImageSize, field.TypeString, value)
|
||||||
|
}
|
||||||
|
if _u.mutation.ImageSizeCleared() {
|
||||||
|
_spec.ClearField(usagelog.FieldImageSize, field.TypeString)
|
||||||
|
}
|
||||||
if _u.mutation.UserCleared() {
|
if _u.mutation.UserCleared() {
|
||||||
edge := &sqlgraph.EdgeSpec{
|
edge := &sqlgraph.EdgeSpec{
|
||||||
Rel: sqlgraph.M2O,
|
Rel: sqlgraph.M2O,
|
||||||
|
|||||||
@@ -34,15 +34,16 @@ func NewOAuthHandler(oauthService *service.OAuthService) *OAuthHandler {
|
|||||||
|
|
||||||
// AccountHandler handles admin account management
|
// AccountHandler handles admin account management
|
||||||
type AccountHandler struct {
|
type AccountHandler struct {
|
||||||
adminService service.AdminService
|
adminService service.AdminService
|
||||||
oauthService *service.OAuthService
|
oauthService *service.OAuthService
|
||||||
openaiOAuthService *service.OpenAIOAuthService
|
openaiOAuthService *service.OpenAIOAuthService
|
||||||
geminiOAuthService *service.GeminiOAuthService
|
geminiOAuthService *service.GeminiOAuthService
|
||||||
rateLimitService *service.RateLimitService
|
antigravityOAuthService *service.AntigravityOAuthService
|
||||||
accountUsageService *service.AccountUsageService
|
rateLimitService *service.RateLimitService
|
||||||
accountTestService *service.AccountTestService
|
accountUsageService *service.AccountUsageService
|
||||||
concurrencyService *service.ConcurrencyService
|
accountTestService *service.AccountTestService
|
||||||
crsSyncService *service.CRSSyncService
|
concurrencyService *service.ConcurrencyService
|
||||||
|
crsSyncService *service.CRSSyncService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAccountHandler creates a new admin account handler
|
// NewAccountHandler creates a new admin account handler
|
||||||
@@ -51,6 +52,7 @@ func NewAccountHandler(
|
|||||||
oauthService *service.OAuthService,
|
oauthService *service.OAuthService,
|
||||||
openaiOAuthService *service.OpenAIOAuthService,
|
openaiOAuthService *service.OpenAIOAuthService,
|
||||||
geminiOAuthService *service.GeminiOAuthService,
|
geminiOAuthService *service.GeminiOAuthService,
|
||||||
|
antigravityOAuthService *service.AntigravityOAuthService,
|
||||||
rateLimitService *service.RateLimitService,
|
rateLimitService *service.RateLimitService,
|
||||||
accountUsageService *service.AccountUsageService,
|
accountUsageService *service.AccountUsageService,
|
||||||
accountTestService *service.AccountTestService,
|
accountTestService *service.AccountTestService,
|
||||||
@@ -58,15 +60,16 @@ func NewAccountHandler(
|
|||||||
crsSyncService *service.CRSSyncService,
|
crsSyncService *service.CRSSyncService,
|
||||||
) *AccountHandler {
|
) *AccountHandler {
|
||||||
return &AccountHandler{
|
return &AccountHandler{
|
||||||
adminService: adminService,
|
adminService: adminService,
|
||||||
oauthService: oauthService,
|
oauthService: oauthService,
|
||||||
openaiOAuthService: openaiOAuthService,
|
openaiOAuthService: openaiOAuthService,
|
||||||
geminiOAuthService: geminiOAuthService,
|
geminiOAuthService: geminiOAuthService,
|
||||||
rateLimitService: rateLimitService,
|
antigravityOAuthService: antigravityOAuthService,
|
||||||
accountUsageService: accountUsageService,
|
rateLimitService: rateLimitService,
|
||||||
accountTestService: accountTestService,
|
accountUsageService: accountUsageService,
|
||||||
concurrencyService: concurrencyService,
|
accountTestService: accountTestService,
|
||||||
crsSyncService: crsSyncService,
|
concurrencyService: concurrencyService,
|
||||||
|
crsSyncService: crsSyncService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,6 +423,19 @@ func (h *AccountHandler) Refresh(c *gin.Context) {
|
|||||||
newCredentials[k] = v
|
newCredentials[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if account.Platform == service.PlatformAntigravity {
|
||||||
|
tokenInfo, err := h.antigravityOAuthService.RefreshAccountToken(c.Request.Context(), account)
|
||||||
|
if err != nil {
|
||||||
|
response.ErrorFrom(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
newCredentials = h.antigravityOAuthService.BuildAccountCredentials(tokenInfo)
|
||||||
|
for k, v := range account.Credentials {
|
||||||
|
if _, exists := newCredentials[k]; !exists {
|
||||||
|
newCredentials[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Use Anthropic/Claude OAuth service to refresh token
|
// Use Anthropic/Claude OAuth service to refresh token
|
||||||
tokenInfo, err := h.oauthService.RefreshAccountToken(c.Request.Context(), account)
|
tokenInfo, err := h.oauthService.RefreshAccountToken(c.Request.Context(), account)
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ type CreateGroupRequest struct {
|
|||||||
DailyLimitUSD *float64 `json:"daily_limit_usd"`
|
DailyLimitUSD *float64 `json:"daily_limit_usd"`
|
||||||
WeeklyLimitUSD *float64 `json:"weekly_limit_usd"`
|
WeeklyLimitUSD *float64 `json:"weekly_limit_usd"`
|
||||||
MonthlyLimitUSD *float64 `json:"monthly_limit_usd"`
|
MonthlyLimitUSD *float64 `json:"monthly_limit_usd"`
|
||||||
|
// 图片生成计费配置(antigravity 和 gemini 平台使用,负数表示清除配置)
|
||||||
|
ImagePrice1K *float64 `json:"image_price_1k"`
|
||||||
|
ImagePrice2K *float64 `json:"image_price_2k"`
|
||||||
|
ImagePrice4K *float64 `json:"image_price_4k"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateGroupRequest represents update group request
|
// UpdateGroupRequest represents update group request
|
||||||
@@ -47,6 +51,10 @@ type UpdateGroupRequest struct {
|
|||||||
DailyLimitUSD *float64 `json:"daily_limit_usd"`
|
DailyLimitUSD *float64 `json:"daily_limit_usd"`
|
||||||
WeeklyLimitUSD *float64 `json:"weekly_limit_usd"`
|
WeeklyLimitUSD *float64 `json:"weekly_limit_usd"`
|
||||||
MonthlyLimitUSD *float64 `json:"monthly_limit_usd"`
|
MonthlyLimitUSD *float64 `json:"monthly_limit_usd"`
|
||||||
|
// 图片生成计费配置(antigravity 和 gemini 平台使用,负数表示清除配置)
|
||||||
|
ImagePrice1K *float64 `json:"image_price_1k"`
|
||||||
|
ImagePrice2K *float64 `json:"image_price_2k"`
|
||||||
|
ImagePrice4K *float64 `json:"image_price_4k"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// List handles listing all groups with pagination
|
// List handles listing all groups with pagination
|
||||||
@@ -139,6 +147,9 @@ func (h *GroupHandler) Create(c *gin.Context) {
|
|||||||
DailyLimitUSD: req.DailyLimitUSD,
|
DailyLimitUSD: req.DailyLimitUSD,
|
||||||
WeeklyLimitUSD: req.WeeklyLimitUSD,
|
WeeklyLimitUSD: req.WeeklyLimitUSD,
|
||||||
MonthlyLimitUSD: req.MonthlyLimitUSD,
|
MonthlyLimitUSD: req.MonthlyLimitUSD,
|
||||||
|
ImagePrice1K: req.ImagePrice1K,
|
||||||
|
ImagePrice2K: req.ImagePrice2K,
|
||||||
|
ImagePrice4K: req.ImagePrice4K,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.ErrorFrom(c, err)
|
response.ErrorFrom(c, err)
|
||||||
@@ -174,6 +185,9 @@ func (h *GroupHandler) Update(c *gin.Context) {
|
|||||||
DailyLimitUSD: req.DailyLimitUSD,
|
DailyLimitUSD: req.DailyLimitUSD,
|
||||||
WeeklyLimitUSD: req.WeeklyLimitUSD,
|
WeeklyLimitUSD: req.WeeklyLimitUSD,
|
||||||
MonthlyLimitUSD: req.MonthlyLimitUSD,
|
MonthlyLimitUSD: req.MonthlyLimitUSD,
|
||||||
|
ImagePrice1K: req.ImagePrice1K,
|
||||||
|
ImagePrice2K: req.ImagePrice2K,
|
||||||
|
ImagePrice4K: req.ImagePrice4K,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.ErrorFrom(c, err)
|
response.ErrorFrom(c, err)
|
||||||
|
|||||||
@@ -78,6 +78,9 @@ func GroupFromServiceShallow(g *service.Group) *Group {
|
|||||||
DailyLimitUSD: g.DailyLimitUSD,
|
DailyLimitUSD: g.DailyLimitUSD,
|
||||||
WeeklyLimitUSD: g.WeeklyLimitUSD,
|
WeeklyLimitUSD: g.WeeklyLimitUSD,
|
||||||
MonthlyLimitUSD: g.MonthlyLimitUSD,
|
MonthlyLimitUSD: g.MonthlyLimitUSD,
|
||||||
|
ImagePrice1K: g.ImagePrice1K,
|
||||||
|
ImagePrice2K: g.ImagePrice2K,
|
||||||
|
ImagePrice4K: g.ImagePrice4K,
|
||||||
CreatedAt: g.CreatedAt,
|
CreatedAt: g.CreatedAt,
|
||||||
UpdatedAt: g.UpdatedAt,
|
UpdatedAt: g.UpdatedAt,
|
||||||
AccountCount: g.AccountCount,
|
AccountCount: g.AccountCount,
|
||||||
@@ -247,6 +250,8 @@ func UsageLogFromService(l *service.UsageLog) *UsageLog {
|
|||||||
Stream: l.Stream,
|
Stream: l.Stream,
|
||||||
DurationMs: l.DurationMs,
|
DurationMs: l.DurationMs,
|
||||||
FirstTokenMs: l.FirstTokenMs,
|
FirstTokenMs: l.FirstTokenMs,
|
||||||
|
ImageCount: l.ImageCount,
|
||||||
|
ImageSize: l.ImageSize,
|
||||||
CreatedAt: l.CreatedAt,
|
CreatedAt: l.CreatedAt,
|
||||||
User: UserFromServiceShallow(l.User),
|
User: UserFromServiceShallow(l.User),
|
||||||
APIKey: APIKeyFromService(l.APIKey),
|
APIKey: APIKeyFromService(l.APIKey),
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ type Group struct {
|
|||||||
WeeklyLimitUSD *float64 `json:"weekly_limit_usd"`
|
WeeklyLimitUSD *float64 `json:"weekly_limit_usd"`
|
||||||
MonthlyLimitUSD *float64 `json:"monthly_limit_usd"`
|
MonthlyLimitUSD *float64 `json:"monthly_limit_usd"`
|
||||||
|
|
||||||
|
// 图片生成计费配置(仅 antigravity 平台使用)
|
||||||
|
ImagePrice1K *float64 `json:"image_price_1k"`
|
||||||
|
ImagePrice2K *float64 `json:"image_price_2k"`
|
||||||
|
ImagePrice4K *float64 `json:"image_price_4k"`
|
||||||
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
|
||||||
@@ -169,6 +174,10 @@ type UsageLog struct {
|
|||||||
DurationMs *int `json:"duration_ms"`
|
DurationMs *int `json:"duration_ms"`
|
||||||
FirstTokenMs *int `json:"first_token_ms"`
|
FirstTokenMs *int `json:"first_token_ms"`
|
||||||
|
|
||||||
|
// 图片生成字段
|
||||||
|
ImageCount int `json:"image_count"`
|
||||||
|
ImageSize *string `json:"image_size"`
|
||||||
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
|
||||||
User *User `json:"user,omitempty"`
|
User *User `json:"user,omitempty"`
|
||||||
|
|||||||
@@ -67,6 +67,13 @@ type GeminiGenerationConfig struct {
|
|||||||
TopK *int `json:"topK,omitempty"`
|
TopK *int `json:"topK,omitempty"`
|
||||||
ThinkingConfig *GeminiThinkingConfig `json:"thinkingConfig,omitempty"`
|
ThinkingConfig *GeminiThinkingConfig `json:"thinkingConfig,omitempty"`
|
||||||
StopSequences []string `json:"stopSequences,omitempty"`
|
StopSequences []string `json:"stopSequences,omitempty"`
|
||||||
|
ImageConfig *GeminiImageConfig `json:"imageConfig,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GeminiImageConfig Gemini 图片生成配置(仅 gemini-3-pro-image 支持)
|
||||||
|
type GeminiImageConfig struct {
|
||||||
|
AspectRatio string `json:"aspectRatio,omitempty"` // "1:1", "16:9", "9:16", "4:3", "3:4"
|
||||||
|
ImageSize string `json:"imageSize,omitempty"` // "1K", "2K", "4K"
|
||||||
}
|
}
|
||||||
|
|
||||||
// GeminiThinkingConfig Gemini thinking 配置
|
// GeminiThinkingConfig Gemini thinking 配置
|
||||||
|
|||||||
@@ -321,6 +321,9 @@ func groupEntityToService(g *dbent.Group) *service.Group {
|
|||||||
DailyLimitUSD: g.DailyLimitUsd,
|
DailyLimitUSD: g.DailyLimitUsd,
|
||||||
WeeklyLimitUSD: g.WeeklyLimitUsd,
|
WeeklyLimitUSD: g.WeeklyLimitUsd,
|
||||||
MonthlyLimitUSD: g.MonthlyLimitUsd,
|
MonthlyLimitUSD: g.MonthlyLimitUsd,
|
||||||
|
ImagePrice1K: g.ImagePrice1k,
|
||||||
|
ImagePrice2K: g.ImagePrice2k,
|
||||||
|
ImagePrice4K: g.ImagePrice4k,
|
||||||
DefaultValidityDays: g.DefaultValidityDays,
|
DefaultValidityDays: g.DefaultValidityDays,
|
||||||
CreatedAt: g.CreatedAt,
|
CreatedAt: g.CreatedAt,
|
||||||
UpdatedAt: g.UpdatedAt,
|
UpdatedAt: g.UpdatedAt,
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ func (r *groupRepository) Create(ctx context.Context, groupIn *service.Group) er
|
|||||||
SetNillableDailyLimitUsd(groupIn.DailyLimitUSD).
|
SetNillableDailyLimitUsd(groupIn.DailyLimitUSD).
|
||||||
SetNillableWeeklyLimitUsd(groupIn.WeeklyLimitUSD).
|
SetNillableWeeklyLimitUsd(groupIn.WeeklyLimitUSD).
|
||||||
SetNillableMonthlyLimitUsd(groupIn.MonthlyLimitUSD).
|
SetNillableMonthlyLimitUsd(groupIn.MonthlyLimitUSD).
|
||||||
|
SetNillableImagePrice1k(groupIn.ImagePrice1K).
|
||||||
|
SetNillableImagePrice2k(groupIn.ImagePrice2K).
|
||||||
|
SetNillableImagePrice4k(groupIn.ImagePrice4K).
|
||||||
SetDefaultValidityDays(groupIn.DefaultValidityDays)
|
SetDefaultValidityDays(groupIn.DefaultValidityDays)
|
||||||
|
|
||||||
created, err := builder.Save(ctx)
|
created, err := builder.Save(ctx)
|
||||||
@@ -80,6 +83,9 @@ func (r *groupRepository) Update(ctx context.Context, groupIn *service.Group) er
|
|||||||
SetNillableDailyLimitUsd(groupIn.DailyLimitUSD).
|
SetNillableDailyLimitUsd(groupIn.DailyLimitUSD).
|
||||||
SetNillableWeeklyLimitUsd(groupIn.WeeklyLimitUSD).
|
SetNillableWeeklyLimitUsd(groupIn.WeeklyLimitUSD).
|
||||||
SetNillableMonthlyLimitUsd(groupIn.MonthlyLimitUSD).
|
SetNillableMonthlyLimitUsd(groupIn.MonthlyLimitUSD).
|
||||||
|
SetNillableImagePrice1k(groupIn.ImagePrice1K).
|
||||||
|
SetNillableImagePrice2k(groupIn.ImagePrice2K).
|
||||||
|
SetNillableImagePrice4k(groupIn.ImagePrice4K).
|
||||||
SetDefaultValidityDays(groupIn.DefaultValidityDays).
|
SetDefaultValidityDays(groupIn.DefaultValidityDays).
|
||||||
Save(ctx)
|
Save(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import (
|
|||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
)
|
)
|
||||||
|
|
||||||
const usageLogSelectColumns = "id, user_id, api_key_id, account_id, request_id, model, group_id, subscription_id, input_tokens, output_tokens, cache_creation_tokens, cache_read_tokens, cache_creation_5m_tokens, cache_creation_1h_tokens, input_cost, output_cost, cache_creation_cost, cache_read_cost, total_cost, actual_cost, rate_multiplier, billing_type, stream, duration_ms, first_token_ms, created_at"
|
const usageLogSelectColumns = "id, user_id, api_key_id, account_id, request_id, model, group_id, subscription_id, input_tokens, output_tokens, cache_creation_tokens, cache_read_tokens, cache_creation_5m_tokens, cache_creation_1h_tokens, input_cost, output_cost, cache_creation_cost, cache_read_cost, total_cost, actual_cost, rate_multiplier, billing_type, stream, duration_ms, first_token_ms, image_count, image_size, created_at"
|
||||||
|
|
||||||
type usageLogRepository struct {
|
type usageLogRepository struct {
|
||||||
client *dbent.Client
|
client *dbent.Client
|
||||||
@@ -109,6 +109,8 @@ func (r *usageLogRepository) Create(ctx context.Context, log *service.UsageLog)
|
|||||||
stream,
|
stream,
|
||||||
duration_ms,
|
duration_ms,
|
||||||
first_token_ms,
|
first_token_ms,
|
||||||
|
image_count,
|
||||||
|
image_size,
|
||||||
created_at
|
created_at
|
||||||
) VALUES (
|
) VALUES (
|
||||||
$1, $2, $3, $4, $5,
|
$1, $2, $3, $4, $5,
|
||||||
@@ -116,7 +118,8 @@ func (r *usageLogRepository) Create(ctx context.Context, log *service.UsageLog)
|
|||||||
$8, $9, $10, $11,
|
$8, $9, $10, $11,
|
||||||
$12, $13,
|
$12, $13,
|
||||||
$14, $15, $16, $17, $18, $19,
|
$14, $15, $16, $17, $18, $19,
|
||||||
$20, $21, $22, $23, $24, $25
|
$20, $21, $22, $23, $24,
|
||||||
|
$25, $26, $27
|
||||||
)
|
)
|
||||||
ON CONFLICT (request_id, api_key_id) DO NOTHING
|
ON CONFLICT (request_id, api_key_id) DO NOTHING
|
||||||
RETURNING id, created_at
|
RETURNING id, created_at
|
||||||
@@ -126,6 +129,7 @@ func (r *usageLogRepository) Create(ctx context.Context, log *service.UsageLog)
|
|||||||
subscriptionID := nullInt64(log.SubscriptionID)
|
subscriptionID := nullInt64(log.SubscriptionID)
|
||||||
duration := nullInt(log.DurationMs)
|
duration := nullInt(log.DurationMs)
|
||||||
firstToken := nullInt(log.FirstTokenMs)
|
firstToken := nullInt(log.FirstTokenMs)
|
||||||
|
imageSize := nullString(log.ImageSize)
|
||||||
|
|
||||||
var requestIDArg any
|
var requestIDArg any
|
||||||
if requestID != "" {
|
if requestID != "" {
|
||||||
@@ -157,6 +161,8 @@ func (r *usageLogRepository) Create(ctx context.Context, log *service.UsageLog)
|
|||||||
log.Stream,
|
log.Stream,
|
||||||
duration,
|
duration,
|
||||||
firstToken,
|
firstToken,
|
||||||
|
log.ImageCount,
|
||||||
|
imageSize,
|
||||||
createdAt,
|
createdAt,
|
||||||
}
|
}
|
||||||
if err := scanSingleRow(ctx, sqlq, query, args, &log.ID, &log.CreatedAt); err != nil {
|
if err := scanSingleRow(ctx, sqlq, query, args, &log.ID, &log.CreatedAt); err != nil {
|
||||||
@@ -1789,6 +1795,8 @@ func scanUsageLog(scanner interface{ Scan(...any) error }) (*service.UsageLog, e
|
|||||||
stream bool
|
stream bool
|
||||||
durationMs sql.NullInt64
|
durationMs sql.NullInt64
|
||||||
firstTokenMs sql.NullInt64
|
firstTokenMs sql.NullInt64
|
||||||
|
imageCount int
|
||||||
|
imageSize sql.NullString
|
||||||
createdAt time.Time
|
createdAt time.Time
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1818,6 +1826,8 @@ func scanUsageLog(scanner interface{ Scan(...any) error }) (*service.UsageLog, e
|
|||||||
&stream,
|
&stream,
|
||||||
&durationMs,
|
&durationMs,
|
||||||
&firstTokenMs,
|
&firstTokenMs,
|
||||||
|
&imageCount,
|
||||||
|
&imageSize,
|
||||||
&createdAt,
|
&createdAt,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1844,6 +1854,7 @@ func scanUsageLog(scanner interface{ Scan(...any) error }) (*service.UsageLog, e
|
|||||||
RateMultiplier: rateMultiplier,
|
RateMultiplier: rateMultiplier,
|
||||||
BillingType: int8(billingType),
|
BillingType: int8(billingType),
|
||||||
Stream: stream,
|
Stream: stream,
|
||||||
|
ImageCount: imageCount,
|
||||||
CreatedAt: createdAt,
|
CreatedAt: createdAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1866,6 +1877,9 @@ func scanUsageLog(scanner interface{ Scan(...any) error }) (*service.UsageLog, e
|
|||||||
value := int(firstTokenMs.Int64)
|
value := int(firstTokenMs.Int64)
|
||||||
log.FirstTokenMs = &value
|
log.FirstTokenMs = &value
|
||||||
}
|
}
|
||||||
|
if imageSize.Valid {
|
||||||
|
log.ImageSize = &imageSize.String
|
||||||
|
}
|
||||||
|
|
||||||
return log, nil
|
return log, nil
|
||||||
}
|
}
|
||||||
@@ -1938,6 +1952,13 @@ func nullInt(v *int) sql.NullInt64 {
|
|||||||
return sql.NullInt64{Int64: int64(*v), Valid: true}
|
return sql.NullInt64{Int64: int64(*v), Valid: true}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func nullString(v *string) sql.NullString {
|
||||||
|
if v == nil || *v == "" {
|
||||||
|
return sql.NullString{}
|
||||||
|
}
|
||||||
|
return sql.NullString{String: *v, Valid: true}
|
||||||
|
}
|
||||||
|
|
||||||
func setToSlice(set map[int64]struct{}) []int64 {
|
func setToSlice(set map[int64]struct{}) []int64 {
|
||||||
out := make([]int64, 0, len(set))
|
out := make([]int64, 0, len(set))
|
||||||
for id := range set {
|
for id := range set {
|
||||||
|
|||||||
@@ -241,6 +241,8 @@ func TestAPIContracts(t *testing.T) {
|
|||||||
"stream": true,
|
"stream": true,
|
||||||
"duration_ms": 100,
|
"duration_ms": 100,
|
||||||
"first_token_ms": 50,
|
"first_token_ms": 50,
|
||||||
|
"image_count": 0,
|
||||||
|
"image_size": null,
|
||||||
"created_at": "2025-01-02T03:04:05Z"
|
"created_at": "2025-01-02T03:04:05Z"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -98,6 +98,10 @@ type CreateGroupInput struct {
|
|||||||
DailyLimitUSD *float64 // 日限额 (USD)
|
DailyLimitUSD *float64 // 日限额 (USD)
|
||||||
WeeklyLimitUSD *float64 // 周限额 (USD)
|
WeeklyLimitUSD *float64 // 周限额 (USD)
|
||||||
MonthlyLimitUSD *float64 // 月限额 (USD)
|
MonthlyLimitUSD *float64 // 月限额 (USD)
|
||||||
|
// 图片生成计费配置(仅 antigravity 平台使用)
|
||||||
|
ImagePrice1K *float64
|
||||||
|
ImagePrice2K *float64
|
||||||
|
ImagePrice4K *float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateGroupInput struct {
|
type UpdateGroupInput struct {
|
||||||
@@ -111,6 +115,10 @@ type UpdateGroupInput struct {
|
|||||||
DailyLimitUSD *float64 // 日限额 (USD)
|
DailyLimitUSD *float64 // 日限额 (USD)
|
||||||
WeeklyLimitUSD *float64 // 周限额 (USD)
|
WeeklyLimitUSD *float64 // 周限额 (USD)
|
||||||
MonthlyLimitUSD *float64 // 月限额 (USD)
|
MonthlyLimitUSD *float64 // 月限额 (USD)
|
||||||
|
// 图片生成计费配置(仅 antigravity 平台使用)
|
||||||
|
ImagePrice1K *float64
|
||||||
|
ImagePrice2K *float64
|
||||||
|
ImagePrice4K *float64
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateAccountInput struct {
|
type CreateAccountInput struct {
|
||||||
@@ -498,6 +506,11 @@ func (s *adminServiceImpl) CreateGroup(ctx context.Context, input *CreateGroupIn
|
|||||||
weeklyLimit := normalizeLimit(input.WeeklyLimitUSD)
|
weeklyLimit := normalizeLimit(input.WeeklyLimitUSD)
|
||||||
monthlyLimit := normalizeLimit(input.MonthlyLimitUSD)
|
monthlyLimit := normalizeLimit(input.MonthlyLimitUSD)
|
||||||
|
|
||||||
|
// 图片价格:负数表示清除(使用默认价格),0 保留(表示免费)
|
||||||
|
imagePrice1K := normalizePrice(input.ImagePrice1K)
|
||||||
|
imagePrice2K := normalizePrice(input.ImagePrice2K)
|
||||||
|
imagePrice4K := normalizePrice(input.ImagePrice4K)
|
||||||
|
|
||||||
group := &Group{
|
group := &Group{
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
Description: input.Description,
|
Description: input.Description,
|
||||||
@@ -509,6 +522,9 @@ func (s *adminServiceImpl) CreateGroup(ctx context.Context, input *CreateGroupIn
|
|||||||
DailyLimitUSD: dailyLimit,
|
DailyLimitUSD: dailyLimit,
|
||||||
WeeklyLimitUSD: weeklyLimit,
|
WeeklyLimitUSD: weeklyLimit,
|
||||||
MonthlyLimitUSD: monthlyLimit,
|
MonthlyLimitUSD: monthlyLimit,
|
||||||
|
ImagePrice1K: imagePrice1K,
|
||||||
|
ImagePrice2K: imagePrice2K,
|
||||||
|
ImagePrice4K: imagePrice4K,
|
||||||
}
|
}
|
||||||
if err := s.groupRepo.Create(ctx, group); err != nil {
|
if err := s.groupRepo.Create(ctx, group); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -524,6 +540,14 @@ func normalizeLimit(limit *float64) *float64 {
|
|||||||
return limit
|
return limit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// normalizePrice 将负数转换为 nil(表示使用默认价格),0 保留(表示免费)
|
||||||
|
func normalizePrice(price *float64) *float64 {
|
||||||
|
if price == nil || *price < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return price
|
||||||
|
}
|
||||||
|
|
||||||
func (s *adminServiceImpl) UpdateGroup(ctx context.Context, id int64, input *UpdateGroupInput) (*Group, error) {
|
func (s *adminServiceImpl) UpdateGroup(ctx context.Context, id int64, input *UpdateGroupInput) (*Group, error) {
|
||||||
group, err := s.groupRepo.GetByID(ctx, id)
|
group, err := s.groupRepo.GetByID(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -563,6 +587,16 @@ func (s *adminServiceImpl) UpdateGroup(ctx context.Context, id int64, input *Upd
|
|||||||
if input.MonthlyLimitUSD != nil {
|
if input.MonthlyLimitUSD != nil {
|
||||||
group.MonthlyLimitUSD = normalizeLimit(input.MonthlyLimitUSD)
|
group.MonthlyLimitUSD = normalizeLimit(input.MonthlyLimitUSD)
|
||||||
}
|
}
|
||||||
|
// 图片生成计费配置:负数表示清除(使用默认价格)
|
||||||
|
if input.ImagePrice1K != nil {
|
||||||
|
group.ImagePrice1K = normalizePrice(input.ImagePrice1K)
|
||||||
|
}
|
||||||
|
if input.ImagePrice2K != nil {
|
||||||
|
group.ImagePrice2K = normalizePrice(input.ImagePrice2K)
|
||||||
|
}
|
||||||
|
if input.ImagePrice4K != nil {
|
||||||
|
group.ImagePrice4K = normalizePrice(input.ImagePrice4K)
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.groupRepo.Update(ctx, group); err != nil {
|
if err := s.groupRepo.Update(ctx, group); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
197
backend/internal/service/admin_service_group_test.go
Normal file
197
backend/internal/service/admin_service_group_test.go
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
//go:build unit
|
||||||
|
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// groupRepoStubForAdmin 用于测试 AdminService 的 GroupRepository Stub
|
||||||
|
type groupRepoStubForAdmin struct {
|
||||||
|
created *Group // 记录 Create 调用的参数
|
||||||
|
updated *Group // 记录 Update 调用的参数
|
||||||
|
getByID *Group // GetByID 返回值
|
||||||
|
getErr error // GetByID 返回的错误
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupRepoStubForAdmin) Create(_ context.Context, g *Group) error {
|
||||||
|
s.created = g
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupRepoStubForAdmin) Update(_ context.Context, g *Group) error {
|
||||||
|
s.updated = g
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupRepoStubForAdmin) GetByID(_ context.Context, _ int64) (*Group, error) {
|
||||||
|
if s.getErr != nil {
|
||||||
|
return nil, s.getErr
|
||||||
|
}
|
||||||
|
return s.getByID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupRepoStubForAdmin) Delete(_ context.Context, _ int64) error {
|
||||||
|
panic("unexpected Delete call")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupRepoStubForAdmin) DeleteCascade(_ context.Context, _ int64) ([]int64, error) {
|
||||||
|
panic("unexpected DeleteCascade call")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupRepoStubForAdmin) List(_ context.Context, _ pagination.PaginationParams) ([]Group, *pagination.PaginationResult, error) {
|
||||||
|
panic("unexpected List call")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupRepoStubForAdmin) ListWithFilters(_ context.Context, _ pagination.PaginationParams, _, _ string, _ *bool) ([]Group, *pagination.PaginationResult, error) {
|
||||||
|
panic("unexpected ListWithFilters call")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupRepoStubForAdmin) ListActive(_ context.Context) ([]Group, error) {
|
||||||
|
panic("unexpected ListActive call")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupRepoStubForAdmin) ListActiveByPlatform(_ context.Context, _ string) ([]Group, error) {
|
||||||
|
panic("unexpected ListActiveByPlatform call")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupRepoStubForAdmin) ExistsByName(_ context.Context, _ string) (bool, error) {
|
||||||
|
panic("unexpected ExistsByName call")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupRepoStubForAdmin) GetAccountCount(_ context.Context, _ int64) (int64, error) {
|
||||||
|
panic("unexpected GetAccountCount call")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *groupRepoStubForAdmin) DeleteAccountGroupsByGroupID(_ context.Context, _ int64) (int64, error) {
|
||||||
|
panic("unexpected DeleteAccountGroupsByGroupID call")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestAdminService_CreateGroup_WithImagePricing 测试创建分组时 ImagePrice 字段正确传递
|
||||||
|
func TestAdminService_CreateGroup_WithImagePricing(t *testing.T) {
|
||||||
|
repo := &groupRepoStubForAdmin{}
|
||||||
|
svc := &adminServiceImpl{groupRepo: repo}
|
||||||
|
|
||||||
|
price1K := 0.10
|
||||||
|
price2K := 0.15
|
||||||
|
price4K := 0.30
|
||||||
|
|
||||||
|
input := &CreateGroupInput{
|
||||||
|
Name: "test-group",
|
||||||
|
Description: "Test group",
|
||||||
|
Platform: PlatformAntigravity,
|
||||||
|
RateMultiplier: 1.0,
|
||||||
|
ImagePrice1K: &price1K,
|
||||||
|
ImagePrice2K: &price2K,
|
||||||
|
ImagePrice4K: &price4K,
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := svc.CreateGroup(context.Background(), input)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, group)
|
||||||
|
|
||||||
|
// 验证 repo 收到了正确的字段
|
||||||
|
require.NotNil(t, repo.created)
|
||||||
|
require.NotNil(t, repo.created.ImagePrice1K)
|
||||||
|
require.NotNil(t, repo.created.ImagePrice2K)
|
||||||
|
require.NotNil(t, repo.created.ImagePrice4K)
|
||||||
|
require.InDelta(t, 0.10, *repo.created.ImagePrice1K, 0.0001)
|
||||||
|
require.InDelta(t, 0.15, *repo.created.ImagePrice2K, 0.0001)
|
||||||
|
require.InDelta(t, 0.30, *repo.created.ImagePrice4K, 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestAdminService_CreateGroup_NilImagePricing 测试 ImagePrice 为 nil 时正常创建
|
||||||
|
func TestAdminService_CreateGroup_NilImagePricing(t *testing.T) {
|
||||||
|
repo := &groupRepoStubForAdmin{}
|
||||||
|
svc := &adminServiceImpl{groupRepo: repo}
|
||||||
|
|
||||||
|
input := &CreateGroupInput{
|
||||||
|
Name: "test-group",
|
||||||
|
Description: "Test group",
|
||||||
|
Platform: PlatformAntigravity,
|
||||||
|
RateMultiplier: 1.0,
|
||||||
|
// ImagePrice 字段全部为 nil
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := svc.CreateGroup(context.Background(), input)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, group)
|
||||||
|
|
||||||
|
// 验证 ImagePrice 字段为 nil
|
||||||
|
require.NotNil(t, repo.created)
|
||||||
|
require.Nil(t, repo.created.ImagePrice1K)
|
||||||
|
require.Nil(t, repo.created.ImagePrice2K)
|
||||||
|
require.Nil(t, repo.created.ImagePrice4K)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestAdminService_UpdateGroup_WithImagePricing 测试更新分组时 ImagePrice 字段正确更新
|
||||||
|
func TestAdminService_UpdateGroup_WithImagePricing(t *testing.T) {
|
||||||
|
existingGroup := &Group{
|
||||||
|
ID: 1,
|
||||||
|
Name: "existing-group",
|
||||||
|
Platform: PlatformAntigravity,
|
||||||
|
Status: StatusActive,
|
||||||
|
}
|
||||||
|
repo := &groupRepoStubForAdmin{getByID: existingGroup}
|
||||||
|
svc := &adminServiceImpl{groupRepo: repo}
|
||||||
|
|
||||||
|
price1K := 0.12
|
||||||
|
price2K := 0.18
|
||||||
|
price4K := 0.36
|
||||||
|
|
||||||
|
input := &UpdateGroupInput{
|
||||||
|
ImagePrice1K: &price1K,
|
||||||
|
ImagePrice2K: &price2K,
|
||||||
|
ImagePrice4K: &price4K,
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := svc.UpdateGroup(context.Background(), 1, input)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, group)
|
||||||
|
|
||||||
|
// 验证 repo 收到了更新后的字段
|
||||||
|
require.NotNil(t, repo.updated)
|
||||||
|
require.NotNil(t, repo.updated.ImagePrice1K)
|
||||||
|
require.NotNil(t, repo.updated.ImagePrice2K)
|
||||||
|
require.NotNil(t, repo.updated.ImagePrice4K)
|
||||||
|
require.InDelta(t, 0.12, *repo.updated.ImagePrice1K, 0.0001)
|
||||||
|
require.InDelta(t, 0.18, *repo.updated.ImagePrice2K, 0.0001)
|
||||||
|
require.InDelta(t, 0.36, *repo.updated.ImagePrice4K, 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestAdminService_UpdateGroup_PartialImagePricing 测试仅更新部分 ImagePrice 字段
|
||||||
|
func TestAdminService_UpdateGroup_PartialImagePricing(t *testing.T) {
|
||||||
|
oldPrice2K := 0.15
|
||||||
|
existingGroup := &Group{
|
||||||
|
ID: 1,
|
||||||
|
Name: "existing-group",
|
||||||
|
Platform: PlatformAntigravity,
|
||||||
|
Status: StatusActive,
|
||||||
|
ImagePrice2K: &oldPrice2K, // 已有 2K 价格
|
||||||
|
}
|
||||||
|
repo := &groupRepoStubForAdmin{getByID: existingGroup}
|
||||||
|
svc := &adminServiceImpl{groupRepo: repo}
|
||||||
|
|
||||||
|
// 只更新 1K 价格
|
||||||
|
price1K := 0.10
|
||||||
|
input := &UpdateGroupInput{
|
||||||
|
ImagePrice1K: &price1K,
|
||||||
|
// ImagePrice2K 和 ImagePrice4K 为 nil,不更新
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := svc.UpdateGroup(context.Background(), 1, input)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, group)
|
||||||
|
|
||||||
|
// 验证:1K 被更新,2K 保持原值,4K 仍为 nil
|
||||||
|
require.NotNil(t, repo.updated)
|
||||||
|
require.NotNil(t, repo.updated.ImagePrice1K)
|
||||||
|
require.InDelta(t, 0.10, *repo.updated.ImagePrice1K, 0.0001)
|
||||||
|
require.NotNil(t, repo.updated.ImagePrice2K)
|
||||||
|
require.InDelta(t, 0.15, *repo.updated.ImagePrice2K, 0.0001) // 原值保持
|
||||||
|
require.Nil(t, repo.updated.ImagePrice4K)
|
||||||
|
}
|
||||||
@@ -860,6 +860,9 @@ func (s *AntigravityGatewayService) ForwardGemini(ctx context.Context, c *gin.Co
|
|||||||
return nil, s.writeGoogleError(c, http.StatusBadRequest, "Request body is empty")
|
return nil, s.writeGoogleError(c, http.StatusBadRequest, "Request body is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 解析请求以获取 image_size(用于图片计费)
|
||||||
|
imageSize := s.extractImageSize(body)
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case "generateContent", "streamGenerateContent":
|
case "generateContent", "streamGenerateContent":
|
||||||
// ok
|
// ok
|
||||||
@@ -1059,6 +1062,13 @@ handleSuccess:
|
|||||||
usage = &ClaudeUsage{}
|
usage = &ClaudeUsage{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 判断是否为图片生成模型
|
||||||
|
imageCount := 0
|
||||||
|
if isImageGenerationModel(mappedModel) {
|
||||||
|
// Gemini 图片生成 API 每次请求只生成一张图片(API 限制)
|
||||||
|
imageCount = 1
|
||||||
|
}
|
||||||
|
|
||||||
return &ForwardResult{
|
return &ForwardResult{
|
||||||
RequestID: requestID,
|
RequestID: requestID,
|
||||||
Usage: *usage,
|
Usage: *usage,
|
||||||
@@ -1066,6 +1076,8 @@ handleSuccess:
|
|||||||
Stream: stream,
|
Stream: stream,
|
||||||
Duration: time.Since(startTime),
|
Duration: time.Since(startTime),
|
||||||
FirstTokenMs: firstTokenMs,
|
FirstTokenMs: firstTokenMs,
|
||||||
|
ImageCount: imageCount,
|
||||||
|
ImageSize: imageSize,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1572,3 +1584,36 @@ func (s *AntigravityGatewayService) handleClaudeStreamingResponse(c *gin.Context
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extractImageSize 从 Gemini 请求中提取 image_size 参数
|
||||||
|
func (s *AntigravityGatewayService) extractImageSize(body []byte) string {
|
||||||
|
var req antigravity.GeminiRequest
|
||||||
|
if err := json.Unmarshal(body, &req); err != nil {
|
||||||
|
return "2K" // 默认 2K
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.GenerationConfig != nil && req.GenerationConfig.ImageConfig != nil {
|
||||||
|
size := strings.ToUpper(strings.TrimSpace(req.GenerationConfig.ImageConfig.ImageSize))
|
||||||
|
if size == "1K" || size == "2K" || size == "4K" {
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "2K" // 默认 2K
|
||||||
|
}
|
||||||
|
|
||||||
|
// isImageGenerationModel 判断模型是否为图片生成模型
|
||||||
|
// 支持的模型:gemini-3-pro-image, gemini-3-pro-image-preview, gemini-2.5-flash-image 等
|
||||||
|
func isImageGenerationModel(model string) bool {
|
||||||
|
modelLower := strings.ToLower(model)
|
||||||
|
// 移除 models/ 前缀
|
||||||
|
modelLower = strings.TrimPrefix(modelLower, "models/")
|
||||||
|
|
||||||
|
// 精确匹配或前缀匹配
|
||||||
|
return modelLower == "gemini-3-pro-image" ||
|
||||||
|
modelLower == "gemini-3-pro-image-preview" ||
|
||||||
|
strings.HasPrefix(modelLower, "gemini-3-pro-image-") ||
|
||||||
|
modelLower == "gemini-2.5-flash-image" ||
|
||||||
|
modelLower == "gemini-2.5-flash-image-preview" ||
|
||||||
|
strings.HasPrefix(modelLower, "gemini-2.5-flash-image-")
|
||||||
|
}
|
||||||
|
|||||||
123
backend/internal/service/antigravity_image_test.go
Normal file
123
backend/internal/service/antigravity_image_test.go
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
//go:build unit
|
||||||
|
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestIsImageGenerationModel_GeminiProImage 测试 gemini-3-pro-image 识别
|
||||||
|
func TestIsImageGenerationModel_GeminiProImage(t *testing.T) {
|
||||||
|
require.True(t, isImageGenerationModel("gemini-3-pro-image"))
|
||||||
|
require.True(t, isImageGenerationModel("gemini-3-pro-image-preview"))
|
||||||
|
require.True(t, isImageGenerationModel("models/gemini-3-pro-image"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestIsImageGenerationModel_GeminiFlashImage 测试 gemini-2.5-flash-image 识别
|
||||||
|
func TestIsImageGenerationModel_GeminiFlashImage(t *testing.T) {
|
||||||
|
require.True(t, isImageGenerationModel("gemini-2.5-flash-image"))
|
||||||
|
require.True(t, isImageGenerationModel("gemini-2.5-flash-image-preview"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestIsImageGenerationModel_RegularModel 测试普通模型不被识别为图片模型
|
||||||
|
func TestIsImageGenerationModel_RegularModel(t *testing.T) {
|
||||||
|
require.False(t, isImageGenerationModel("claude-3-opus"))
|
||||||
|
require.False(t, isImageGenerationModel("claude-sonnet-4-20250514"))
|
||||||
|
require.False(t, isImageGenerationModel("gpt-4o"))
|
||||||
|
require.False(t, isImageGenerationModel("gemini-2.5-pro")) // 非图片模型
|
||||||
|
require.False(t, isImageGenerationModel("gemini-2.5-flash"))
|
||||||
|
// 验证不会误匹配包含关键词的自定义模型名
|
||||||
|
require.False(t, isImageGenerationModel("my-gemini-3-pro-image-test"))
|
||||||
|
require.False(t, isImageGenerationModel("custom-gemini-2.5-flash-image-wrapper"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestIsImageGenerationModel_CaseInsensitive 测试大小写不敏感
|
||||||
|
func TestIsImageGenerationModel_CaseInsensitive(t *testing.T) {
|
||||||
|
require.True(t, isImageGenerationModel("GEMINI-3-PRO-IMAGE"))
|
||||||
|
require.True(t, isImageGenerationModel("Gemini-3-Pro-Image"))
|
||||||
|
require.True(t, isImageGenerationModel("GEMINI-2.5-FLASH-IMAGE"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestExtractImageSize_ValidSizes 测试有效尺寸解析
|
||||||
|
func TestExtractImageSize_ValidSizes(t *testing.T) {
|
||||||
|
svc := &AntigravityGatewayService{}
|
||||||
|
|
||||||
|
// 1K
|
||||||
|
body := []byte(`{"generationConfig":{"imageConfig":{"imageSize":"1K"}}}`)
|
||||||
|
require.Equal(t, "1K", svc.extractImageSize(body))
|
||||||
|
|
||||||
|
// 2K
|
||||||
|
body = []byte(`{"generationConfig":{"imageConfig":{"imageSize":"2K"}}}`)
|
||||||
|
require.Equal(t, "2K", svc.extractImageSize(body))
|
||||||
|
|
||||||
|
// 4K
|
||||||
|
body = []byte(`{"generationConfig":{"imageConfig":{"imageSize":"4K"}}}`)
|
||||||
|
require.Equal(t, "4K", svc.extractImageSize(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestExtractImageSize_CaseInsensitive 测试大小写不敏感
|
||||||
|
func TestExtractImageSize_CaseInsensitive(t *testing.T) {
|
||||||
|
svc := &AntigravityGatewayService{}
|
||||||
|
|
||||||
|
body := []byte(`{"generationConfig":{"imageConfig":{"imageSize":"1k"}}}`)
|
||||||
|
require.Equal(t, "1K", svc.extractImageSize(body))
|
||||||
|
|
||||||
|
body = []byte(`{"generationConfig":{"imageConfig":{"imageSize":"4k"}}}`)
|
||||||
|
require.Equal(t, "4K", svc.extractImageSize(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestExtractImageSize_Default 测试无 imageConfig 返回默认 2K
|
||||||
|
func TestExtractImageSize_Default(t *testing.T) {
|
||||||
|
svc := &AntigravityGatewayService{}
|
||||||
|
|
||||||
|
// 无 generationConfig
|
||||||
|
body := []byte(`{"contents":[]}`)
|
||||||
|
require.Equal(t, "2K", svc.extractImageSize(body))
|
||||||
|
|
||||||
|
// 有 generationConfig 但无 imageConfig
|
||||||
|
body = []byte(`{"generationConfig":{"temperature":0.7}}`)
|
||||||
|
require.Equal(t, "2K", svc.extractImageSize(body))
|
||||||
|
|
||||||
|
// 有 imageConfig 但无 imageSize
|
||||||
|
body = []byte(`{"generationConfig":{"imageConfig":{}}}`)
|
||||||
|
require.Equal(t, "2K", svc.extractImageSize(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestExtractImageSize_InvalidJSON 测试非法 JSON 返回默认 2K
|
||||||
|
func TestExtractImageSize_InvalidJSON(t *testing.T) {
|
||||||
|
svc := &AntigravityGatewayService{}
|
||||||
|
|
||||||
|
body := []byte(`not valid json`)
|
||||||
|
require.Equal(t, "2K", svc.extractImageSize(body))
|
||||||
|
|
||||||
|
body = []byte(`{"broken":`)
|
||||||
|
require.Equal(t, "2K", svc.extractImageSize(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestExtractImageSize_EmptySize 测试空 imageSize 返回默认 2K
|
||||||
|
func TestExtractImageSize_EmptySize(t *testing.T) {
|
||||||
|
svc := &AntigravityGatewayService{}
|
||||||
|
|
||||||
|
body := []byte(`{"generationConfig":{"imageConfig":{"imageSize":""}}}`)
|
||||||
|
require.Equal(t, "2K", svc.extractImageSize(body))
|
||||||
|
|
||||||
|
// 空格
|
||||||
|
body = []byte(`{"generationConfig":{"imageConfig":{"imageSize":" "}}}`)
|
||||||
|
require.Equal(t, "2K", svc.extractImageSize(body))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestExtractImageSize_InvalidSize 测试无效尺寸返回默认 2K
|
||||||
|
func TestExtractImageSize_InvalidSize(t *testing.T) {
|
||||||
|
svc := &AntigravityGatewayService{}
|
||||||
|
|
||||||
|
body := []byte(`{"generationConfig":{"imageConfig":{"imageSize":"3K"}}}`)
|
||||||
|
require.Equal(t, "2K", svc.extractImageSize(body))
|
||||||
|
|
||||||
|
body = []byte(`{"generationConfig":{"imageConfig":{"imageSize":"8K"}}}`)
|
||||||
|
require.Equal(t, "2K", svc.extractImageSize(body))
|
||||||
|
|
||||||
|
body = []byte(`{"generationConfig":{"imageConfig":{"imageSize":"invalid"}}}`)
|
||||||
|
require.Equal(t, "2K", svc.extractImageSize(body))
|
||||||
|
}
|
||||||
@@ -295,3 +295,88 @@ func (s *BillingService) ForceUpdatePricing() error {
|
|||||||
}
|
}
|
||||||
return fmt.Errorf("pricing service not initialized")
|
return fmt.Errorf("pricing service not initialized")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImagePriceConfig 图片计费配置
|
||||||
|
type ImagePriceConfig struct {
|
||||||
|
Price1K *float64 // 1K 尺寸价格(nil 表示使用默认值)
|
||||||
|
Price2K *float64 // 2K 尺寸价格(nil 表示使用默认值)
|
||||||
|
Price4K *float64 // 4K 尺寸价格(nil 表示使用默认值)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CalculateImageCost 计算图片生成费用
|
||||||
|
// model: 请求的模型名称(用于获取 LiteLLM 默认价格)
|
||||||
|
// imageSize: 图片尺寸 "1K", "2K", "4K"
|
||||||
|
// imageCount: 生成的图片数量
|
||||||
|
// groupConfig: 分组配置的价格(可能为 nil,表示使用默认值)
|
||||||
|
// rateMultiplier: 费率倍数
|
||||||
|
func (s *BillingService) CalculateImageCost(model string, imageSize string, imageCount int, groupConfig *ImagePriceConfig, rateMultiplier float64) *CostBreakdown {
|
||||||
|
if imageCount <= 0 {
|
||||||
|
return &CostBreakdown{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取单价
|
||||||
|
unitPrice := s.getImageUnitPrice(model, imageSize, groupConfig)
|
||||||
|
|
||||||
|
// 计算总费用
|
||||||
|
totalCost := unitPrice * float64(imageCount)
|
||||||
|
|
||||||
|
// 应用倍率
|
||||||
|
if rateMultiplier <= 0 {
|
||||||
|
rateMultiplier = 1.0
|
||||||
|
}
|
||||||
|
actualCost := totalCost * rateMultiplier
|
||||||
|
|
||||||
|
return &CostBreakdown{
|
||||||
|
TotalCost: totalCost,
|
||||||
|
ActualCost: actualCost,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getImageUnitPrice 获取图片单价
|
||||||
|
func (s *BillingService) getImageUnitPrice(model string, imageSize string, groupConfig *ImagePriceConfig) float64 {
|
||||||
|
// 优先使用分组配置的价格
|
||||||
|
if groupConfig != nil {
|
||||||
|
switch imageSize {
|
||||||
|
case "1K":
|
||||||
|
if groupConfig.Price1K != nil {
|
||||||
|
return *groupConfig.Price1K
|
||||||
|
}
|
||||||
|
case "2K":
|
||||||
|
if groupConfig.Price2K != nil {
|
||||||
|
return *groupConfig.Price2K
|
||||||
|
}
|
||||||
|
case "4K":
|
||||||
|
if groupConfig.Price4K != nil {
|
||||||
|
return *groupConfig.Price4K
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 回退到 LiteLLM 默认价格
|
||||||
|
return s.getDefaultImagePrice(model, imageSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDefaultImagePrice 获取 LiteLLM 默认图片价格
|
||||||
|
func (s *BillingService) getDefaultImagePrice(model string, imageSize string) float64 {
|
||||||
|
basePrice := 0.0
|
||||||
|
|
||||||
|
// 从 PricingService 获取 output_cost_per_image
|
||||||
|
if s.pricingService != nil {
|
||||||
|
pricing := s.pricingService.GetModelPricing(model)
|
||||||
|
if pricing != nil && pricing.OutputCostPerImage > 0 {
|
||||||
|
basePrice = pricing.OutputCostPerImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有找到价格,使用硬编码默认值($0.134,来自 gemini-3-pro-image-preview)
|
||||||
|
if basePrice <= 0 {
|
||||||
|
basePrice = 0.134
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4K 尺寸翻倍
|
||||||
|
if imageSize == "4K" {
|
||||||
|
return basePrice * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
return basePrice
|
||||||
|
}
|
||||||
|
|||||||
149
backend/internal/service/billing_service_image_test.go
Normal file
149
backend/internal/service/billing_service_image_test.go
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
//go:build unit
|
||||||
|
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestCalculateImageCost_DefaultPricing 测试无分组配置时使用默认价格
|
||||||
|
func TestCalculateImageCost_DefaultPricing(t *testing.T) {
|
||||||
|
svc := &BillingService{} // pricingService 为 nil,使用硬编码默认值
|
||||||
|
|
||||||
|
// 2K 尺寸,默认价格 $0.134
|
||||||
|
cost := svc.CalculateImageCost("gemini-3-pro-image", "2K", 1, nil, 1.0)
|
||||||
|
require.InDelta(t, 0.134, cost.TotalCost, 0.0001)
|
||||||
|
require.InDelta(t, 0.134, cost.ActualCost, 0.0001)
|
||||||
|
|
||||||
|
// 多张图片
|
||||||
|
cost = svc.CalculateImageCost("gemini-3-pro-image", "2K", 3, nil, 1.0)
|
||||||
|
require.InDelta(t, 0.402, cost.TotalCost, 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestCalculateImageCost_GroupCustomPricing 测试分组自定义价格
|
||||||
|
func TestCalculateImageCost_GroupCustomPricing(t *testing.T) {
|
||||||
|
svc := &BillingService{}
|
||||||
|
|
||||||
|
price1K := 0.10
|
||||||
|
price2K := 0.15
|
||||||
|
price4K := 0.30
|
||||||
|
groupConfig := &ImagePriceConfig{
|
||||||
|
Price1K: &price1K,
|
||||||
|
Price2K: &price2K,
|
||||||
|
Price4K: &price4K,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1K 使用分组价格
|
||||||
|
cost := svc.CalculateImageCost("gemini-3-pro-image", "1K", 2, groupConfig, 1.0)
|
||||||
|
require.InDelta(t, 0.20, cost.TotalCost, 0.0001)
|
||||||
|
|
||||||
|
// 2K 使用分组价格
|
||||||
|
cost = svc.CalculateImageCost("gemini-3-pro-image", "2K", 1, groupConfig, 1.0)
|
||||||
|
require.InDelta(t, 0.15, cost.TotalCost, 0.0001)
|
||||||
|
|
||||||
|
// 4K 使用分组价格
|
||||||
|
cost = svc.CalculateImageCost("gemini-3-pro-image", "4K", 1, groupConfig, 1.0)
|
||||||
|
require.InDelta(t, 0.30, cost.TotalCost, 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestCalculateImageCost_4KDoublePrice 测试 4K 默认价格翻倍
|
||||||
|
func TestCalculateImageCost_4KDoublePrice(t *testing.T) {
|
||||||
|
svc := &BillingService{}
|
||||||
|
|
||||||
|
// 4K 尺寸,默认价格翻倍 $0.134 * 2 = $0.268
|
||||||
|
cost := svc.CalculateImageCost("gemini-3-pro-image", "4K", 1, nil, 1.0)
|
||||||
|
require.InDelta(t, 0.268, cost.TotalCost, 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestCalculateImageCost_RateMultiplier 测试费率倍数
|
||||||
|
func TestCalculateImageCost_RateMultiplier(t *testing.T) {
|
||||||
|
svc := &BillingService{}
|
||||||
|
|
||||||
|
// 费率倍数 1.5x
|
||||||
|
cost := svc.CalculateImageCost("gemini-3-pro-image", "2K", 1, nil, 1.5)
|
||||||
|
require.InDelta(t, 0.134, cost.TotalCost, 0.0001) // TotalCost 不变
|
||||||
|
require.InDelta(t, 0.201, cost.ActualCost, 0.0001) // ActualCost = 0.134 * 1.5
|
||||||
|
|
||||||
|
// 费率倍数 2.0x
|
||||||
|
cost = svc.CalculateImageCost("gemini-3-pro-image", "2K", 2, nil, 2.0)
|
||||||
|
require.InDelta(t, 0.268, cost.TotalCost, 0.0001)
|
||||||
|
require.InDelta(t, 0.536, cost.ActualCost, 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestCalculateImageCost_ZeroCount 测试 imageCount=0
|
||||||
|
func TestCalculateImageCost_ZeroCount(t *testing.T) {
|
||||||
|
svc := &BillingService{}
|
||||||
|
|
||||||
|
cost := svc.CalculateImageCost("gemini-3-pro-image", "2K", 0, nil, 1.0)
|
||||||
|
require.Equal(t, 0.0, cost.TotalCost)
|
||||||
|
require.Equal(t, 0.0, cost.ActualCost)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestCalculateImageCost_NegativeCount 测试 imageCount=-1
|
||||||
|
func TestCalculateImageCost_NegativeCount(t *testing.T) {
|
||||||
|
svc := &BillingService{}
|
||||||
|
|
||||||
|
cost := svc.CalculateImageCost("gemini-3-pro-image", "2K", -1, nil, 1.0)
|
||||||
|
require.Equal(t, 0.0, cost.TotalCost)
|
||||||
|
require.Equal(t, 0.0, cost.ActualCost)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestCalculateImageCost_ZeroRateMultiplier 测试费率倍数为 0 时默认使用 1.0
|
||||||
|
func TestCalculateImageCost_ZeroRateMultiplier(t *testing.T) {
|
||||||
|
svc := &BillingService{}
|
||||||
|
|
||||||
|
cost := svc.CalculateImageCost("gemini-3-pro-image", "2K", 1, nil, 0)
|
||||||
|
require.InDelta(t, 0.134, cost.TotalCost, 0.0001)
|
||||||
|
require.InDelta(t, 0.134, cost.ActualCost, 0.0001) // 0 倍率当作 1.0 处理
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestGetImageUnitPrice_GroupPriorityOverDefault 测试分组价格优先于默认价格
|
||||||
|
func TestGetImageUnitPrice_GroupPriorityOverDefault(t *testing.T) {
|
||||||
|
svc := &BillingService{}
|
||||||
|
|
||||||
|
price2K := 0.20
|
||||||
|
groupConfig := &ImagePriceConfig{
|
||||||
|
Price2K: &price2K,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分组配置了 2K 价格,应该使用分组价格而不是默认的 $0.134
|
||||||
|
cost := svc.CalculateImageCost("gemini-3-pro-image", "2K", 1, groupConfig, 1.0)
|
||||||
|
require.InDelta(t, 0.20, cost.TotalCost, 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestGetImageUnitPrice_PartialGroupConfig 测试分组部分配置时回退默认
|
||||||
|
func TestGetImageUnitPrice_PartialGroupConfig(t *testing.T) {
|
||||||
|
svc := &BillingService{}
|
||||||
|
|
||||||
|
// 只配置 1K 价格
|
||||||
|
price1K := 0.10
|
||||||
|
groupConfig := &ImagePriceConfig{
|
||||||
|
Price1K: &price1K,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1K 使用分组价格
|
||||||
|
cost := svc.CalculateImageCost("gemini-3-pro-image", "1K", 1, groupConfig, 1.0)
|
||||||
|
require.InDelta(t, 0.10, cost.TotalCost, 0.0001)
|
||||||
|
|
||||||
|
// 2K 回退默认价格 $0.134
|
||||||
|
cost = svc.CalculateImageCost("gemini-3-pro-image", "2K", 1, groupConfig, 1.0)
|
||||||
|
require.InDelta(t, 0.134, cost.TotalCost, 0.0001)
|
||||||
|
|
||||||
|
// 4K 回退默认价格 $0.268 (翻倍)
|
||||||
|
cost = svc.CalculateImageCost("gemini-3-pro-image", "4K", 1, groupConfig, 1.0)
|
||||||
|
require.InDelta(t, 0.268, cost.TotalCost, 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestGetDefaultImagePrice_FallbackHardcoded 测试 PricingService 无数据时使用硬编码默认值
|
||||||
|
func TestGetDefaultImagePrice_FallbackHardcoded(t *testing.T) {
|
||||||
|
svc := &BillingService{} // pricingService 为 nil
|
||||||
|
|
||||||
|
// 1K 和 2K 使用相同的默认价格 $0.134
|
||||||
|
cost := svc.CalculateImageCost("gemini-3-pro-image", "1K", 1, nil, 1.0)
|
||||||
|
require.InDelta(t, 0.134, cost.TotalCost, 0.0001)
|
||||||
|
|
||||||
|
cost = svc.CalculateImageCost("gemini-3-pro-image", "2K", 1, nil, 1.0)
|
||||||
|
require.InDelta(t, 0.134, cost.TotalCost, 0.0001)
|
||||||
|
}
|
||||||
@@ -104,6 +104,10 @@ type ForwardResult struct {
|
|||||||
Stream bool
|
Stream bool
|
||||||
Duration time.Duration
|
Duration time.Duration
|
||||||
FirstTokenMs *int // 首字时间(流式请求)
|
FirstTokenMs *int // 首字时间(流式请求)
|
||||||
|
|
||||||
|
// 图片生成计费字段(仅 gemini-3-pro-image 使用)
|
||||||
|
ImageCount int // 生成的图片数量
|
||||||
|
ImageSize string // 图片尺寸 "1K", "2K", "4K"
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpstreamFailoverError indicates an upstream error that should trigger account failover.
|
// UpstreamFailoverError indicates an upstream error that should trigger account failover.
|
||||||
@@ -2009,25 +2013,40 @@ func (s *GatewayService) RecordUsage(ctx context.Context, input *RecordUsageInpu
|
|||||||
account := input.Account
|
account := input.Account
|
||||||
subscription := input.Subscription
|
subscription := input.Subscription
|
||||||
|
|
||||||
// 计算费用
|
|
||||||
tokens := UsageTokens{
|
|
||||||
InputTokens: result.Usage.InputTokens,
|
|
||||||
OutputTokens: result.Usage.OutputTokens,
|
|
||||||
CacheCreationTokens: result.Usage.CacheCreationInputTokens,
|
|
||||||
CacheReadTokens: result.Usage.CacheReadInputTokens,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取费率倍数
|
// 获取费率倍数
|
||||||
multiplier := s.cfg.Default.RateMultiplier
|
multiplier := s.cfg.Default.RateMultiplier
|
||||||
if apiKey.GroupID != nil && apiKey.Group != nil {
|
if apiKey.GroupID != nil && apiKey.Group != nil {
|
||||||
multiplier = apiKey.Group.RateMultiplier
|
multiplier = apiKey.Group.RateMultiplier
|
||||||
}
|
}
|
||||||
|
|
||||||
cost, err := s.billingService.CalculateCost(result.Model, tokens, multiplier)
|
var cost *CostBreakdown
|
||||||
if err != nil {
|
|
||||||
log.Printf("Calculate cost failed: %v", err)
|
// 根据请求类型选择计费方式
|
||||||
// 使用默认费用继续
|
if result.ImageCount > 0 {
|
||||||
cost = &CostBreakdown{ActualCost: 0}
|
// 图片生成计费
|
||||||
|
var groupConfig *ImagePriceConfig
|
||||||
|
if apiKey.Group != nil {
|
||||||
|
groupConfig = &ImagePriceConfig{
|
||||||
|
Price1K: apiKey.Group.ImagePrice1K,
|
||||||
|
Price2K: apiKey.Group.ImagePrice2K,
|
||||||
|
Price4K: apiKey.Group.ImagePrice4K,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cost = s.billingService.CalculateImageCost(result.Model, result.ImageSize, result.ImageCount, groupConfig, multiplier)
|
||||||
|
} else {
|
||||||
|
// Token 计费
|
||||||
|
tokens := UsageTokens{
|
||||||
|
InputTokens: result.Usage.InputTokens,
|
||||||
|
OutputTokens: result.Usage.OutputTokens,
|
||||||
|
CacheCreationTokens: result.Usage.CacheCreationInputTokens,
|
||||||
|
CacheReadTokens: result.Usage.CacheReadInputTokens,
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
cost, err = s.billingService.CalculateCost(result.Model, tokens, multiplier)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Calculate cost failed: %v", err)
|
||||||
|
cost = &CostBreakdown{ActualCost: 0}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断计费方式:订阅模式 vs 余额模式
|
// 判断计费方式:订阅模式 vs 余额模式
|
||||||
@@ -2039,6 +2058,10 @@ func (s *GatewayService) RecordUsage(ctx context.Context, input *RecordUsageInpu
|
|||||||
|
|
||||||
// 创建使用日志
|
// 创建使用日志
|
||||||
durationMs := int(result.Duration.Milliseconds())
|
durationMs := int(result.Duration.Milliseconds())
|
||||||
|
var imageSize *string
|
||||||
|
if result.ImageSize != "" {
|
||||||
|
imageSize = &result.ImageSize
|
||||||
|
}
|
||||||
usageLog := &UsageLog{
|
usageLog := &UsageLog{
|
||||||
UserID: user.ID,
|
UserID: user.ID,
|
||||||
APIKeyID: apiKey.ID,
|
APIKeyID: apiKey.ID,
|
||||||
@@ -2060,6 +2083,8 @@ func (s *GatewayService) RecordUsage(ctx context.Context, input *RecordUsageInpu
|
|||||||
Stream: result.Stream,
|
Stream: result.Stream,
|
||||||
DurationMs: &durationMs,
|
DurationMs: &durationMs,
|
||||||
FirstTokenMs: result.FirstTokenMs,
|
FirstTokenMs: result.FirstTokenMs,
|
||||||
|
ImageCount: result.ImageCount,
|
||||||
|
ImageSize: imageSize,
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ type Group struct {
|
|||||||
MonthlyLimitUSD *float64
|
MonthlyLimitUSD *float64
|
||||||
DefaultValidityDays int
|
DefaultValidityDays int
|
||||||
|
|
||||||
|
// 图片生成计费配置(antigravity 和 gemini 平台使用)
|
||||||
|
ImagePrice1K *float64
|
||||||
|
ImagePrice2K *float64
|
||||||
|
ImagePrice4K *float64
|
||||||
|
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
|
|
||||||
@@ -47,3 +52,19 @@ func (g *Group) HasWeeklyLimit() bool {
|
|||||||
func (g *Group) HasMonthlyLimit() bool {
|
func (g *Group) HasMonthlyLimit() bool {
|
||||||
return g.MonthlyLimitUSD != nil && *g.MonthlyLimitUSD > 0
|
return g.MonthlyLimitUSD != nil && *g.MonthlyLimitUSD > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetImagePrice 根据 image_size 返回对应的图片生成价格
|
||||||
|
// 如果分组未配置价格,返回 nil(调用方应使用默认值)
|
||||||
|
func (g *Group) GetImagePrice(imageSize string) *float64 {
|
||||||
|
switch imageSize {
|
||||||
|
case "1K":
|
||||||
|
return g.ImagePrice1K
|
||||||
|
case "2K":
|
||||||
|
return g.ImagePrice2K
|
||||||
|
case "4K":
|
||||||
|
return g.ImagePrice4K
|
||||||
|
default:
|
||||||
|
// 未知尺寸默认按 2K 计费
|
||||||
|
return g.ImagePrice2K
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
92
backend/internal/service/group_test.go
Normal file
92
backend/internal/service/group_test.go
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
//go:build unit
|
||||||
|
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestGroup_GetImagePrice_1K 测试 1K 尺寸返回正确价格
|
||||||
|
func TestGroup_GetImagePrice_1K(t *testing.T) {
|
||||||
|
price := 0.10
|
||||||
|
group := &Group{
|
||||||
|
ImagePrice1K: &price,
|
||||||
|
}
|
||||||
|
|
||||||
|
result := group.GetImagePrice("1K")
|
||||||
|
require.NotNil(t, result)
|
||||||
|
require.InDelta(t, 0.10, *result, 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestGroup_GetImagePrice_2K 测试 2K 尺寸返回正确价格
|
||||||
|
func TestGroup_GetImagePrice_2K(t *testing.T) {
|
||||||
|
price := 0.15
|
||||||
|
group := &Group{
|
||||||
|
ImagePrice2K: &price,
|
||||||
|
}
|
||||||
|
|
||||||
|
result := group.GetImagePrice("2K")
|
||||||
|
require.NotNil(t, result)
|
||||||
|
require.InDelta(t, 0.15, *result, 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestGroup_GetImagePrice_4K 测试 4K 尺寸返回正确价格
|
||||||
|
func TestGroup_GetImagePrice_4K(t *testing.T) {
|
||||||
|
price := 0.30
|
||||||
|
group := &Group{
|
||||||
|
ImagePrice4K: &price,
|
||||||
|
}
|
||||||
|
|
||||||
|
result := group.GetImagePrice("4K")
|
||||||
|
require.NotNil(t, result)
|
||||||
|
require.InDelta(t, 0.30, *result, 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestGroup_GetImagePrice_UnknownSize 测试未知尺寸回退 2K
|
||||||
|
func TestGroup_GetImagePrice_UnknownSize(t *testing.T) {
|
||||||
|
price2K := 0.15
|
||||||
|
group := &Group{
|
||||||
|
ImagePrice2K: &price2K,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 未知尺寸 "3K" 应该回退到 2K
|
||||||
|
result := group.GetImagePrice("3K")
|
||||||
|
require.NotNil(t, result)
|
||||||
|
require.InDelta(t, 0.15, *result, 0.0001)
|
||||||
|
|
||||||
|
// 空字符串也回退到 2K
|
||||||
|
result = group.GetImagePrice("")
|
||||||
|
require.NotNil(t, result)
|
||||||
|
require.InDelta(t, 0.15, *result, 0.0001)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestGroup_GetImagePrice_NilValues 测试未配置时返回 nil
|
||||||
|
func TestGroup_GetImagePrice_NilValues(t *testing.T) {
|
||||||
|
group := &Group{
|
||||||
|
// 所有 ImagePrice 字段都是 nil
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Nil(t, group.GetImagePrice("1K"))
|
||||||
|
require.Nil(t, group.GetImagePrice("2K"))
|
||||||
|
require.Nil(t, group.GetImagePrice("4K"))
|
||||||
|
require.Nil(t, group.GetImagePrice("unknown"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestGroup_GetImagePrice_PartialConfig 测试部分配置
|
||||||
|
func TestGroup_GetImagePrice_PartialConfig(t *testing.T) {
|
||||||
|
price1K := 0.10
|
||||||
|
group := &Group{
|
||||||
|
ImagePrice1K: &price1K,
|
||||||
|
// ImagePrice2K 和 ImagePrice4K 未配置
|
||||||
|
}
|
||||||
|
|
||||||
|
result := group.GetImagePrice("1K")
|
||||||
|
require.NotNil(t, result)
|
||||||
|
require.InDelta(t, 0.10, *result, 0.0001)
|
||||||
|
|
||||||
|
// 2K 和 4K 返回 nil
|
||||||
|
require.Nil(t, group.GetImagePrice("2K"))
|
||||||
|
require.Nil(t, group.GetImagePrice("4K"))
|
||||||
|
}
|
||||||
@@ -34,6 +34,7 @@ type LiteLLMModelPricing struct {
|
|||||||
LiteLLMProvider string `json:"litellm_provider"`
|
LiteLLMProvider string `json:"litellm_provider"`
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
SupportsPromptCaching bool `json:"supports_prompt_caching"`
|
SupportsPromptCaching bool `json:"supports_prompt_caching"`
|
||||||
|
OutputCostPerImage float64 `json:"output_cost_per_image"` // 图片生成模型每张图片价格
|
||||||
}
|
}
|
||||||
|
|
||||||
// PricingRemoteClient 远程价格数据获取接口
|
// PricingRemoteClient 远程价格数据获取接口
|
||||||
@@ -51,6 +52,7 @@ type LiteLLMRawEntry struct {
|
|||||||
LiteLLMProvider string `json:"litellm_provider"`
|
LiteLLMProvider string `json:"litellm_provider"`
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
SupportsPromptCaching bool `json:"supports_prompt_caching"`
|
SupportsPromptCaching bool `json:"supports_prompt_caching"`
|
||||||
|
OutputCostPerImage *float64 `json:"output_cost_per_image"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PricingService 动态价格服务
|
// PricingService 动态价格服务
|
||||||
@@ -319,6 +321,9 @@ func (s *PricingService) parsePricingData(body []byte) (map[string]*LiteLLMModel
|
|||||||
if entry.CacheReadInputTokenCost != nil {
|
if entry.CacheReadInputTokenCost != nil {
|
||||||
pricing.CacheReadInputTokenCost = *entry.CacheReadInputTokenCost
|
pricing.CacheReadInputTokenCost = *entry.CacheReadInputTokenCost
|
||||||
}
|
}
|
||||||
|
if entry.OutputCostPerImage != nil {
|
||||||
|
pricing.OutputCostPerImage = *entry.OutputCostPerImage
|
||||||
|
}
|
||||||
|
|
||||||
result[modelName] = pricing
|
result[modelName] = pricing
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,10 @@ type UsageLog struct {
|
|||||||
DurationMs *int
|
DurationMs *int
|
||||||
FirstTokenMs *int
|
FirstTokenMs *int
|
||||||
|
|
||||||
|
// 图片生成字段
|
||||||
|
ImageCount int
|
||||||
|
ImageSize *string
|
||||||
|
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
|
|
||||||
User *User
|
User *User
|
||||||
|
|||||||
10
backend/migrations/028_group_image_pricing.sql
Normal file
10
backend/migrations/028_group_image_pricing.sql
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
-- 为 Antigravity 分组添加图片生成计费配置
|
||||||
|
-- 支持 gemini-3-pro-image 模型的 1K/2K/4K 分辨率按次计费
|
||||||
|
|
||||||
|
ALTER TABLE groups ADD COLUMN IF NOT EXISTS image_price_1k DECIMAL(20,8);
|
||||||
|
ALTER TABLE groups ADD COLUMN IF NOT EXISTS image_price_2k DECIMAL(20,8);
|
||||||
|
ALTER TABLE groups ADD COLUMN IF NOT EXISTS image_price_4k DECIMAL(20,8);
|
||||||
|
|
||||||
|
COMMENT ON COLUMN groups.image_price_1k IS '1K 分辨率图片生成单价 (USD),仅 antigravity 平台使用';
|
||||||
|
COMMENT ON COLUMN groups.image_price_2k IS '2K 分辨率图片生成单价 (USD),仅 antigravity 平台使用';
|
||||||
|
COMMENT ON COLUMN groups.image_price_4k IS '4K 分辨率图片生成单价 (USD),仅 antigravity 平台使用';
|
||||||
5
backend/migrations/029_usage_log_image_fields.sql
Normal file
5
backend/migrations/029_usage_log_image_fields.sql
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
-- 为使用日志添加图片生成统计字段
|
||||||
|
-- 用于记录 gemini-3-pro-image 等图片生成模型的使用情况
|
||||||
|
|
||||||
|
ALTER TABLE usage_logs ADD COLUMN IF NOT EXISTS image_count INT DEFAULT 0;
|
||||||
|
ALTER TABLE usage_logs ADD COLUMN IF NOT EXISTS image_size VARCHAR(10);
|
||||||
@@ -35,7 +35,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #cell-tokens="{ row }">
|
<template #cell-tokens="{ row }">
|
||||||
<div class="space-y-1 text-sm">
|
<!-- 图片生成请求 -->
|
||||||
|
<div v-if="row.image_count > 0" class="flex items-center gap-1.5">
|
||||||
|
<svg class="h-4 w-4 text-indigo-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||||
|
</svg>
|
||||||
|
<span class="font-medium text-gray-900 dark:text-white">{{ row.image_count }}{{ t('usage.imageUnit') }}</span>
|
||||||
|
<span class="text-gray-400">({{ row.image_size || '2K' }})</span>
|
||||||
|
</div>
|
||||||
|
<!-- Token 请求 -->
|
||||||
|
<div v-else class="space-y-1 text-sm">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<div class="inline-flex items-center gap-1">
|
<div class="inline-flex items-center gap-1">
|
||||||
<Icon name="arrowDown" size="sm" class="h-3.5 w-3.5 text-emerald-500" />
|
<Icon name="arrowDown" size="sm" class="h-3.5 w-3.5 text-emerald-500" />
|
||||||
|
|||||||
@@ -421,7 +421,8 @@ export default {
|
|||||||
exportExcelFailed: 'Failed to export usage data',
|
exportExcelFailed: 'Failed to export usage data',
|
||||||
billingType: 'Billing',
|
billingType: 'Billing',
|
||||||
balance: 'Balance',
|
balance: 'Balance',
|
||||||
subscription: 'Subscription'
|
subscription: 'Subscription',
|
||||||
|
imageUnit: ' images'
|
||||||
},
|
},
|
||||||
|
|
||||||
// Redeem
|
// Redeem
|
||||||
@@ -849,6 +850,10 @@ export default {
|
|||||||
defaultValidityDays: 'Default Validity (Days)',
|
defaultValidityDays: 'Default Validity (Days)',
|
||||||
validityHint: 'Number of days the subscription is valid when assigned to a user',
|
validityHint: 'Number of days the subscription is valid when assigned to a user',
|
||||||
noLimit: 'No limit'
|
noLimit: 'No limit'
|
||||||
|
},
|
||||||
|
imagePricing: {
|
||||||
|
title: 'Image Generation Pricing',
|
||||||
|
description: 'Configure pricing for gemini-3-pro-image model. Leave empty to use default prices.'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -418,7 +418,8 @@ export default {
|
|||||||
exportExcelFailed: '使用数据导出失败',
|
exportExcelFailed: '使用数据导出失败',
|
||||||
billingType: '消费类型',
|
billingType: '消费类型',
|
||||||
balance: '余额',
|
balance: '余额',
|
||||||
subscription: '订阅'
|
subscription: '订阅',
|
||||||
|
imageUnit: '张'
|
||||||
},
|
},
|
||||||
|
|
||||||
// Redeem
|
// Redeem
|
||||||
@@ -926,6 +927,10 @@ export default {
|
|||||||
defaultValidityDays: '默认有效期(天)',
|
defaultValidityDays: '默认有效期(天)',
|
||||||
validityHint: '分配给用户时订阅的有效天数',
|
validityHint: '分配给用户时订阅的有效天数',
|
||||||
noLimit: '无限制'
|
noLimit: '无限制'
|
||||||
|
},
|
||||||
|
imagePricing: {
|
||||||
|
title: '图片生成计费',
|
||||||
|
description: '配置 gemini-3-pro-image 模型的图片生成价格,留空则使用默认价格'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -259,6 +259,10 @@ export interface Group {
|
|||||||
daily_limit_usd: number | null
|
daily_limit_usd: number | null
|
||||||
weekly_limit_usd: number | null
|
weekly_limit_usd: number | null
|
||||||
monthly_limit_usd: number | null
|
monthly_limit_usd: number | null
|
||||||
|
// 图片生成计费配置(仅 antigravity 平台使用)
|
||||||
|
image_price_1k: number | null
|
||||||
|
image_price_2k: number | null
|
||||||
|
image_price_4k: number | null
|
||||||
account_count?: number
|
account_count?: number
|
||||||
created_at: string
|
created_at: string
|
||||||
updated_at: string
|
updated_at: string
|
||||||
@@ -561,6 +565,11 @@ export interface UsageLog {
|
|||||||
stream: boolean
|
stream: boolean
|
||||||
duration_ms: number
|
duration_ms: number
|
||||||
first_token_ms: number | null
|
first_token_ms: number | null
|
||||||
|
|
||||||
|
// 图片生成字段
|
||||||
|
image_count: number
|
||||||
|
image_size: string | null
|
||||||
|
|
||||||
created_at: string
|
created_at: string
|
||||||
|
|
||||||
user?: User
|
user?: User
|
||||||
|
|||||||
@@ -358,6 +358,51 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 图片生成计费配置(antigravity 和 gemini 平台) -->
|
||||||
|
<div v-if="createForm.platform === 'antigravity' || createForm.platform === 'gemini'" class="border-t pt-4">
|
||||||
|
<label class="block mb-2 font-medium text-gray-700 dark:text-gray-300">
|
||||||
|
{{ t('admin.groups.imagePricing.title') }}
|
||||||
|
</label>
|
||||||
|
<p class="text-xs text-gray-500 dark:text-gray-400 mb-3">
|
||||||
|
{{ t('admin.groups.imagePricing.description') }}
|
||||||
|
</p>
|
||||||
|
<div class="grid grid-cols-3 gap-3">
|
||||||
|
<div>
|
||||||
|
<label class="input-label">1K ($)</label>
|
||||||
|
<input
|
||||||
|
v-model.number="createForm.image_price_1k"
|
||||||
|
type="number"
|
||||||
|
step="0.001"
|
||||||
|
min="0"
|
||||||
|
class="input"
|
||||||
|
placeholder="0.134"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="input-label">2K ($)</label>
|
||||||
|
<input
|
||||||
|
v-model.number="createForm.image_price_2k"
|
||||||
|
type="number"
|
||||||
|
step="0.001"
|
||||||
|
min="0"
|
||||||
|
class="input"
|
||||||
|
placeholder="0.134"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="input-label">4K ($)</label>
|
||||||
|
<input
|
||||||
|
v-model.number="createForm.image_price_4k"
|
||||||
|
type="number"
|
||||||
|
step="0.001"
|
||||||
|
min="0"
|
||||||
|
class="input"
|
||||||
|
placeholder="0.268"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -558,6 +603,51 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 图片生成计费配置(antigravity 和 gemini 平台) -->
|
||||||
|
<div v-if="editForm.platform === 'antigravity' || editForm.platform === 'gemini'" class="border-t pt-4">
|
||||||
|
<label class="block mb-2 font-medium text-gray-700 dark:text-gray-300">
|
||||||
|
{{ t('admin.groups.imagePricing.title') }}
|
||||||
|
</label>
|
||||||
|
<p class="text-xs text-gray-500 dark:text-gray-400 mb-3">
|
||||||
|
{{ t('admin.groups.imagePricing.description') }}
|
||||||
|
</p>
|
||||||
|
<div class="grid grid-cols-3 gap-3">
|
||||||
|
<div>
|
||||||
|
<label class="input-label">1K ($)</label>
|
||||||
|
<input
|
||||||
|
v-model.number="editForm.image_price_1k"
|
||||||
|
type="number"
|
||||||
|
step="0.001"
|
||||||
|
min="0"
|
||||||
|
class="input"
|
||||||
|
placeholder="0.134"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="input-label">2K ($)</label>
|
||||||
|
<input
|
||||||
|
v-model.number="editForm.image_price_2k"
|
||||||
|
type="number"
|
||||||
|
step="0.001"
|
||||||
|
min="0"
|
||||||
|
class="input"
|
||||||
|
placeholder="0.134"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="input-label">4K ($)</label>
|
||||||
|
<input
|
||||||
|
v-model.number="editForm.image_price_4k"
|
||||||
|
type="number"
|
||||||
|
step="0.001"
|
||||||
|
min="0"
|
||||||
|
class="input"
|
||||||
|
placeholder="0.268"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -727,7 +817,11 @@ const createForm = reactive({
|
|||||||
subscription_type: 'standard' as SubscriptionType,
|
subscription_type: 'standard' as SubscriptionType,
|
||||||
daily_limit_usd: null as number | null,
|
daily_limit_usd: null as number | null,
|
||||||
weekly_limit_usd: null as number | null,
|
weekly_limit_usd: null as number | null,
|
||||||
monthly_limit_usd: null as number | null
|
monthly_limit_usd: null as number | null,
|
||||||
|
// 图片生成计费配置(仅 antigravity 平台使用)
|
||||||
|
image_price_1k: null as number | null,
|
||||||
|
image_price_2k: null as number | null,
|
||||||
|
image_price_4k: null as number | null
|
||||||
})
|
})
|
||||||
|
|
||||||
const editForm = reactive({
|
const editForm = reactive({
|
||||||
@@ -740,7 +834,11 @@ const editForm = reactive({
|
|||||||
subscription_type: 'standard' as SubscriptionType,
|
subscription_type: 'standard' as SubscriptionType,
|
||||||
daily_limit_usd: null as number | null,
|
daily_limit_usd: null as number | null,
|
||||||
weekly_limit_usd: null as number | null,
|
weekly_limit_usd: null as number | null,
|
||||||
monthly_limit_usd: null as number | null
|
monthly_limit_usd: null as number | null,
|
||||||
|
// 图片生成计费配置(仅 antigravity 平台使用)
|
||||||
|
image_price_1k: null as number | null,
|
||||||
|
image_price_2k: null as number | null,
|
||||||
|
image_price_4k: null as number | null
|
||||||
})
|
})
|
||||||
|
|
||||||
// 根据分组类型返回不同的删除确认消息
|
// 根据分组类型返回不同的删除确认消息
|
||||||
@@ -807,6 +905,9 @@ const closeCreateModal = () => {
|
|||||||
createForm.daily_limit_usd = null
|
createForm.daily_limit_usd = null
|
||||||
createForm.weekly_limit_usd = null
|
createForm.weekly_limit_usd = null
|
||||||
createForm.monthly_limit_usd = null
|
createForm.monthly_limit_usd = null
|
||||||
|
createForm.image_price_1k = null
|
||||||
|
createForm.image_price_2k = null
|
||||||
|
createForm.image_price_4k = null
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCreateGroup = async () => {
|
const handleCreateGroup = async () => {
|
||||||
@@ -845,6 +946,9 @@ const handleEdit = (group: Group) => {
|
|||||||
editForm.daily_limit_usd = group.daily_limit_usd
|
editForm.daily_limit_usd = group.daily_limit_usd
|
||||||
editForm.weekly_limit_usd = group.weekly_limit_usd
|
editForm.weekly_limit_usd = group.weekly_limit_usd
|
||||||
editForm.monthly_limit_usd = group.monthly_limit_usd
|
editForm.monthly_limit_usd = group.monthly_limit_usd
|
||||||
|
editForm.image_price_1k = group.image_price_1k
|
||||||
|
editForm.image_price_2k = group.image_price_2k
|
||||||
|
editForm.image_price_4k = group.image_price_4k
|
||||||
showEditModal.value = true
|
showEditModal.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -171,7 +171,26 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #cell-tokens="{ row }">
|
<template #cell-tokens="{ row }">
|
||||||
<div class="flex items-center gap-1.5">
|
<!-- 图片生成请求 -->
|
||||||
|
<div v-if="row.image_count > 0" class="flex items-center gap-1.5">
|
||||||
|
<svg
|
||||||
|
class="h-4 w-4 text-indigo-500"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<span class="font-medium text-gray-900 dark:text-white">{{ row.image_count }}{{ $t('usage.imageUnit') }}</span>
|
||||||
|
<span class="text-gray-400">({{ row.image_size || '2K' }})</span>
|
||||||
|
</div>
|
||||||
|
<!-- Token 请求 -->
|
||||||
|
<div v-else class="flex items-center gap-1.5">
|
||||||
<div class="space-y-1.5 text-sm">
|
<div class="space-y-1.5 text-sm">
|
||||||
<!-- Input / Output Tokens -->
|
<!-- Input / Output Tokens -->
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user