feat: 实现注册优惠码功能

- 支持创建/编辑/删除优惠码,设置赠送金额和使用限制
  - 注册页面实时验证优惠码并显示赠送金额
  - 支持 URL 参数自动填充 (?promo=CODE)
  - 添加优惠码验证接口速率限制
  - 使用数据库行锁防止并发超限
  - 新增后台优惠码管理页面,支持复制注册链接
This commit is contained in:
long
2026-01-10 13:14:35 +08:00
parent 7d1fe818be
commit d2fc14fb97
79 changed files with 17045 additions and 54 deletions

View File

@@ -13,6 +13,7 @@ import (
"entgo.io/ent/schema/field"
"github.com/Wei-Shaw/sub2api/ent/apikey"
"github.com/Wei-Shaw/sub2api/ent/group"
"github.com/Wei-Shaw/sub2api/ent/promocodeusage"
"github.com/Wei-Shaw/sub2api/ent/redeemcode"
"github.com/Wei-Shaw/sub2api/ent/usagelog"
"github.com/Wei-Shaw/sub2api/ent/user"
@@ -271,6 +272,21 @@ func (_c *UserCreate) AddAttributeValues(v ...*UserAttributeValue) *UserCreate {
return _c.AddAttributeValueIDs(ids...)
}
// AddPromoCodeUsageIDs adds the "promo_code_usages" edge to the PromoCodeUsage entity by IDs.
func (_c *UserCreate) AddPromoCodeUsageIDs(ids ...int64) *UserCreate {
_c.mutation.AddPromoCodeUsageIDs(ids...)
return _c
}
// AddPromoCodeUsages adds the "promo_code_usages" edges to the PromoCodeUsage entity.
func (_c *UserCreate) AddPromoCodeUsages(v ...*PromoCodeUsage) *UserCreate {
ids := make([]int64, len(v))
for i := range v {
ids[i] = v[i].ID
}
return _c.AddPromoCodeUsageIDs(ids...)
}
// Mutation returns the UserMutation object of the builder.
func (_c *UserCreate) Mutation() *UserMutation {
return _c.mutation
@@ -593,6 +609,22 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
}
_spec.Edges = append(_spec.Edges, edge)
}
if nodes := _c.mutation.PromoCodeUsagesIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: user.PromoCodeUsagesTable,
Columns: []string{user.PromoCodeUsagesColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(promocodeusage.FieldID, field.TypeInt64),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges = append(_spec.Edges, edge)
}
return _node, _spec
}