优化表结构,重构模型,重新实现基于白银网关的提取节点流程

This commit is contained in:
2025-11-24 18:44:06 +08:00
parent 9a574f55cb
commit cb2a963a37
142 changed files with 6528 additions and 5808 deletions

View File

@@ -5,11 +5,7 @@ import (
"fmt"
"platform/pkg/u"
"platform/web/core"
bill2 "platform/web/domains/bill"
resource2 "platform/web/domains/resource"
trade2 "platform/web/domains/trade"
g "platform/web/globals"
"platform/web/globals/orm"
m "platform/web/models"
q "platform/web/queries"
"time"
@@ -24,7 +20,7 @@ type resourceService struct{}
func (s *resourceService) CreateResourceByBalance(uid int32, now time.Time, data *CreateResourceData) error {
return g.Redsync.WithLock(userBalanceKey(uid), func() error {
return q.Q.Transaction(func(q *q.Query) error {
// 检查用户
// 找到用户
user, err := q.User.
Where(q.User.ID.Eq(uid)).
Take()
@@ -38,22 +34,22 @@ func (s *resourceService) CreateResourceByBalance(uid int32, now time.Time, data
return ErrBalanceNotEnough
}
// 更新用户余额
_, err = q.User.
Where(q.User.ID.Eq(uid), q.User.Balance.Eq(user.Balance)).
UpdateSimple(q.User.Balance.Value(amount))
if err != nil {
return core.NewServErr("更新用户余额失败", err)
}
// 保存套餐
resource, err := createResource(q, uid, now, data)
if err != nil {
return core.NewServErr("创建套餐失败", err)
}
// 更新用户余额
_, err = q.User.
Where(q.User.ID.Eq(uid)).
UpdateSimple(q.User.Balance.Value(amount))
if err != nil {
return core.NewServErr("更新用户余额失败", err)
}
// 生成账单
err = q.Bill.Create(bill2.NewForConsume(uid, Bill.GenNo(), data.GetSubject(), data.GetAmount(), resource))
err = q.Bill.Create(newForConsume(uid, Bill.GenNo(), data.GetSubject(), data.GetAmount(), resource))
if err != nil {
return core.NewServErr("生成账单失败", err)
}
@@ -73,7 +69,7 @@ func (s *resourceService) CreateResourceByTrade(uid int32, now time.Time, data *
}
// 生成账单
err = q.Bill.Create(bill2.NewForConsume(uid, Bill.GenNo(), data.GetSubject(), data.GetAmount(), resource, trade))
err = q.Bill.Create(newForConsume(uid, Bill.GenNo(), data.GetSubject(), data.GetAmount(), resource, trade))
if err != nil {
return core.NewServErr("生成账单失败", err)
}
@@ -89,38 +85,37 @@ func createResource(q *q.Query, uid int32, now time.Time, data *CreateResourceDa
UserID: uid,
ResourceNo: u.P(ID.GenReadable("res")),
Active: true,
Type: data.Type,
}
switch data.Type {
// 短效套餐
case resource2.TypeShort:
case m.ResourceTypeShort:
var short = data.Short
if short == nil {
return nil, core.NewBizErr("短效套餐数据不能为空")
}
var duration = time.Duration(short.Expire) * 24 * time.Hour
resource.Type = int32(resource2.TypeShort)
resource.Short = &m.ResourceShort{
Type: short.Mode,
Live: short.Live,
Quota: &short.Quota,
Expire: u.P(orm.LocalDateTime(now.Add(duration))),
Expire: u.P(now.Add(duration)),
DailyLimit: short.DailyLimit,
}
// 长效套餐
case resource2.TypeLong:
case m.ResourceTypeLong:
var long = data.Long
if long == nil {
return nil, core.NewBizErr("长效套餐数据不能为空")
}
var duration = time.Duration(long.Expire) * 24 * time.Hour
resource.Type = int32(resource2.TypeLong)
resource.Long = &m.ResourceLong{
Type: long.Mode,
Live: long.Live,
Quota: &long.Quota,
Expire: u.P(orm.LocalDateTime(now.Add(duration))),
Expire: u.P(now.Add(duration)),
DailyLimit: long.DailyLimit,
}
default:
@@ -136,42 +131,42 @@ func createResource(q *q.Query, uid int32, now time.Time, data *CreateResourceDa
}
type CreateResourceData struct {
Type resource2.Type `json:"type" validate:"required"`
Type m.ResourceType `json:"type" validate:"required"`
Short *CreateShortResourceData `json:"short,omitempty"`
Long *CreateLongResourceData `json:"long,omitempty"`
}
type CreateShortResourceData struct {
Live int32 `json:"live" validate:"required,min=180"`
Mode int32 `json:"mode" validate:"required"`
Expire int32 `json:"expire"`
DailyLimit int32 `json:"daily_limit" validate:"min=2000"`
Quota int32 `json:"quota" validate:"min=10000"`
Live int32 `json:"live" validate:"required,min=180"`
Mode m.ResourceMode `json:"mode" validate:"required"`
Expire int32 `json:"expire"`
DailyLimit int32 `json:"daily_limit" validate:"min=2000"`
Quota int32 `json:"quota" validate:"min=10000"`
name string
price *decimal.Decimal
}
type CreateLongResourceData struct {
Live int32 `json:"live" validate:"required,oneof=1 4 8 12 24"`
Mode int32 `json:"mode" validate:"required,oneof=1 2"`
Expire int32 `json:"expire"`
DailyLimit int32 `json:"daily_limit" validate:"min=100"`
Quota int32 `json:"quota" validate:"min=500"`
Live int32 `json:"live" validate:"required,oneof=1 4 8 12 24"`
Mode m.ResourceMode `json:"mode" validate:"required,oneof=1 2"`
Expire int32 `json:"expire"`
DailyLimit int32 `json:"daily_limit" validate:"min=100"`
Quota int32 `json:"quota" validate:"min=500"`
name string
price *decimal.Decimal
}
func (c *CreateResourceData) GetType() trade2.Type {
return trade2.TypePurchase
func (c *CreateResourceData) GetType() m.TradeType {
return m.TradeTypePurchase
}
func (c *CreateResourceData) GetSubject() string {
switch c.Type {
case resource2.TypeShort:
case m.ResourceTypeShort:
return c.Short.GetSubject()
case resource2.TypeLong:
case m.ResourceTypeLong:
return c.Long.GetSubject()
}
panic("类型对应的数据为空")
@@ -179,9 +174,9 @@ func (c *CreateResourceData) GetSubject() string {
func (c *CreateResourceData) GetAmount() decimal.Decimal {
switch c.Type {
case resource2.TypeShort:
case m.ResourceTypeShort:
return c.Short.GetAmount()
case resource2.TypeLong:
case m.ResourceTypeLong:
return c.Long.GetAmount()
}
panic("类型对应的数据为空")
@@ -250,11 +245,11 @@ func (data *CreateLongResourceData) GetSubject() string {
func (data *CreateLongResourceData) GetAmount() decimal.Decimal {
if data.price == nil {
var factor int32 = 0
switch resource2.Mode(data.Mode) {
switch data.Mode {
case resource2.ModeTime:
case m.ResourceModeTime:
factor = data.Expire * data.DailyLimit
case resource2.ModeCount:
case m.ResourceModeQuota:
factor = data.Quota
}
@@ -283,14 +278,14 @@ func (data *CreateLongResourceData) GetAmount() decimal.Decimal {
type ResourceOnTradeComplete struct{}
func (r ResourceOnTradeComplete) Check(t trade2.Type) (trade2.ProductInfo, bool) {
if t == trade2.TypePurchase {
func (r ResourceOnTradeComplete) Check(t m.TradeType) (ProductInfo, bool) {
if t == m.TradeTypePurchase {
return &CreateResourceData{}, true
}
return nil, false
}
func (r ResourceOnTradeComplete) OnTradeComplete(info trade2.ProductInfo, trade *m.Trade) error {
func (r ResourceOnTradeComplete) OnTradeComplete(info ProductInfo, trade *m.Trade) error {
return Resource.CreateResourceByTrade(trade.UserID, time.Time(*trade.CompletedAt), info.(*CreateResourceData), trade)
}