Files
sub2api/backend/ent/schema/subscription_plan.go
T
turingcatandClaude Fable 5 2bbdd47002 feat(payment): 订阅套餐支持币种标注,区分 $ 符号对应币种
后台配置与用户端展示的套餐价格统一使用 $ 符号,而实际扣款币种随
支付渠道配置漂移(如 Stripe 配置 NZD 时按新西兰元扣款),用户易
误认为美元。本次为套餐新增可选的展示性币种标注:

- SubscriptionPlan 新增 currency 字段(ISO 4217 三字母码,默认空)
- 空值不展示任何标注,存量套餐行为完全不变
- 非空值复用 payment.NormalizePaymentCurrency 校验并规范化为大写
- 后台套餐编辑弹窗新增可选币种输入,列表价格列展示币种小字
- 用户端套餐卡片价格与划线原价旁展示币种小字
- 纯展示性质,不影响任何支付/扣款逻辑

Closes #4315

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 11:17:45 +08:00

81 lines
2.1 KiB
Go

package schema
import (
"time"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/entsql"
"entgo.io/ent/schema"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
)
// SubscriptionPlan holds the schema definition for the SubscriptionPlan entity.
//
// 删除策略:硬删除
// SubscriptionPlan 使用硬删除而非软删除,原因如下:
// - 套餐为管理员维护的商品配置,删除即表示下架移除
// - 通过 for_sale 字段控制是否在售,删除仅用于彻底移除
// - 已购买的订阅记录保存在 UserSubscription 中,不受套餐删除影响
type SubscriptionPlan struct {
ent.Schema
}
func (SubscriptionPlan) Annotations() []schema.Annotation {
return []schema.Annotation{
entsql.Annotation{Table: "subscription_plans"},
}
}
func (SubscriptionPlan) Fields() []ent.Field {
return []ent.Field{
field.Int64("group_id"),
field.String("name").
MaxLen(100).
NotEmpty(),
field.String("description").
SchemaType(map[string]string{dialect.Postgres: "text"}).
Default(""),
field.Float("price").
SchemaType(map[string]string{dialect.Postgres: "decimal(20,2)"}),
field.Float("original_price").
SchemaType(map[string]string{dialect.Postgres: "decimal(20,2)"}).
Optional().
Nillable(),
field.String("currency").
MaxLen(3).
Default(""),
field.Int("validity_days").
Default(30),
field.String("validity_unit").
MaxLen(10).
Default("day"),
field.String("features").
SchemaType(map[string]string{dialect.Postgres: "text"}).
Default(""),
field.String("product_name").
MaxLen(100).
Default(""),
field.Bool("for_sale").
Default(true),
field.Int("sort_order").
Default(0),
field.Time("created_at").
Immutable().
Default(time.Now).
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
field.Time("updated_at").
Default(time.Now).
UpdateDefault(time.Now).
SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
}
}
func (SubscriptionPlan) Indexes() []ent.Index {
return []ent.Index{
index.Fields("group_id"),
index.Fields("for_sale"),
}
}