重构优化套餐数据结构,修复提取计数问题

This commit is contained in:
2025-12-10 20:07:33 +08:00
parent c8c86081d9
commit 05fba68b3e
11 changed files with 310 additions and 250 deletions

View File

@@ -2,9 +2,11 @@ package services
import (
"context"
"errors"
"fmt"
"math/rand/v2"
"net/netip"
"platform/pkg/u"
"platform/web/core"
g "platform/web/globals"
m "platform/web/models"
@@ -66,7 +68,7 @@ func genPassPair() (string, string) {
}
// 查找资源
func findResource(resourceId int32) (*ResourceView, error) {
func findResource(resourceId int32, now time.Time) (*ResourceView, error) {
resource, err := q.Resource.
Preload(field.Associations).
Where(
@@ -82,57 +84,43 @@ func findResource(resourceId int32) (*ResourceView, error) {
}
var info = &ResourceView{
Id: resource.ID,
User: *resource.User,
Active: resource.Active,
Type: resource.Type,
User: *resource.User,
}
switch resource.Type {
case m.ResourceTypeShort:
var sub = resource.Short
var dailyLast = time.Time{}
if sub.DailyLast != nil {
dailyLast = time.Time(*sub.DailyLast)
}
var expire = time.Time{}
if sub.Expire != nil {
expire = time.Time(*sub.Expire)
}
var quota int32
if sub.Quota != nil {
quota = *sub.Quota
}
info.Mode = sub.Type
info.ShortId = &sub.ID
info.ExpireAt = sub.ExpireAt
info.Live = time.Duration(sub.Live) * time.Second
info.DailyLimit = sub.DailyLimit
info.DailyUsed = sub.DailyUsed
info.DailyLast = dailyLast
info.Expire = expire
info.Quota = quota
info.Mode = sub.Type
info.Quota = sub.Quota
info.Used = sub.Used
info.Daily = sub.Daily
info.LastAt = sub.LastAt
if sub.LastAt != nil && u.IsSameDate(*sub.LastAt, now) {
info.Today = int(sub.Daily)
}
case m.ResourceTypeLong:
var sub = resource.Long
var dailyLast = time.Time{}
if sub.DailyLast != nil {
dailyLast = time.Time(*sub.DailyLast)
}
var expire = time.Time{}
if sub.Expire != nil {
expire = time.Time(*sub.Expire)
}
var quota int32
if sub.Quota != nil {
quota = *sub.Quota
}
info.LongId = &sub.ID
info.ExpireAt = sub.ExpireAt
info.Live = time.Duration(sub.Live) * time.Hour
info.Mode = sub.Type
info.Live = time.Duration(sub.Live) * time.Hour * 24
info.DailyLimit = sub.DailyLimit
info.DailyUsed = sub.DailyUsed
info.DailyLast = dailyLast
info.Expire = expire
info.Quota = quota
info.Quota = sub.Quota
info.Used = sub.Used
info.Daily = sub.Daily
info.LastAt = sub.LastAt
if sub.LastAt != nil && u.IsSameDate(*sub.LastAt, now) {
info.Today = int(sub.Daily)
}
}
if info.Mode == m.ResourceModeTime && info.ExpireAt == nil {
return nil, errors.New("检查套餐获取时间失败")
}
return info, nil
@@ -140,18 +128,20 @@ func findResource(resourceId int32) (*ResourceView, error) {
// ResourceView 套餐数据的简化视图,便于直接获取主要数据
type ResourceView struct {
Id int32
Active bool
Type m.ResourceType
Mode m.ResourceMode
Live time.Duration
DailyLimit int32
DailyUsed int32
DailyLast time.Time
Quota int32
Used int32
Expire time.Time
User m.User
Id int32
User m.User
Active bool
Type m.ResourceType
ShortId *int32
LongId *int32
Live time.Duration
Mode m.ResourceMode
Quota int32
ExpireAt *time.Time
Used int32
Daily int32
LastAt *time.Time
Today int // 今日用量
}
// 检查用户是否可提取
@@ -161,7 +151,7 @@ func ensure(now time.Time, source netip.Addr, resourceId int32, count int) (*Res
}
// 获取用户套餐
resource, err := findResource(resourceId)
resource, err := findResource(resourceId, now)
if err != nil {
return nil, nil, err
}
@@ -200,16 +190,11 @@ func ensure(now time.Time, source netip.Addr, resourceId int32, count int) (*Res
// 包时
case m.ResourceModeTime:
// 检查过期时间
if resource.Expire.Before(now) {
if resource.ExpireAt.Before(now) {
return nil, nil, ErrResourceExpired
}
// 检查每日限额
used := 0
if now.Format("2006-01-02") == resource.DailyLast.Format("2006-01-02") {
used = int(resource.DailyUsed)
}
excess := used+count > int(resource.DailyLimit)
if excess {
if count+resource.Today > int(resource.Quota) {
return nil, nil, ErrResourceDailyLimit
}