feat: 图片生成计费功能

- 新增 Group 图片价格配置(image_price_1k/2k/4k)
- BillingService 新增 CalculateImageCost 方法
- AntigravityGatewayService 支持识别图片生成模型并按次计费
- UsageLog 新增 image_count 和 image_size 字段
- 前端分组管理支持配置图片价格(antigravity 和 gemini 平台)
- 图片计费复用通用计费能力(余额检查、扣费、倍率、订阅限额)
This commit is contained in:
song
2026-01-05 17:07:29 +08:00
parent e78c864650
commit d4c2b723a5
41 changed files with 2747 additions and 40 deletions

View File

@@ -62,6 +62,10 @@ const (
FieldDurationMs = "duration_ms"
// FieldFirstTokenMs holds the string denoting the first_token_ms field in the database.
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 = "created_at"
// EdgeUser holds the string denoting the user edge name in mutations.
@@ -140,6 +144,8 @@ var Columns = []string{
FieldStream,
FieldDurationMs,
FieldFirstTokenMs,
FieldImageCount,
FieldImageSize,
FieldCreatedAt,
}
@@ -188,6 +194,10 @@ var (
DefaultBillingType int8
// DefaultStream holds the default value on creation for the "stream" field.
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 func() time.Time
)
@@ -320,6 +330,16 @@ func ByFirstTokenMs(opts ...sql.OrderTermOption) OrderOption {
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.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()

View File

@@ -175,6 +175,16 @@ func FirstTokenMs(v int) predicate.UsageLog {
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.
func CreatedAt(v time.Time) predicate.UsageLog {
return predicate.UsageLog(sql.FieldEQ(FieldCreatedAt, v))
@@ -1100,6 +1110,121 @@ func FirstTokenMsNotNil() predicate.UsageLog {
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.
func CreatedAtEQ(v time.Time) predicate.UsageLog {
return predicate.UsageLog(sql.FieldEQ(FieldCreatedAt, v))