feat: 品牌重命名 Sub2API -> TianShuAPI
- 前端: 所有界面显示、i18n 文本、组件中的品牌名称 - 后端: 服务层、设置默认值、邮件模板、安装向导 - 数据库: 迁移脚本注释 - 保持功能完全一致,仅更改品牌名称 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,124 +1,124 @@
|
||||
package service
|
||||
|
||||
import "time"
|
||||
|
||||
type UserSubscription struct {
|
||||
ID int64
|
||||
UserID int64
|
||||
GroupID int64
|
||||
|
||||
StartsAt time.Time
|
||||
ExpiresAt time.Time
|
||||
Status string
|
||||
|
||||
DailyWindowStart *time.Time
|
||||
WeeklyWindowStart *time.Time
|
||||
MonthlyWindowStart *time.Time
|
||||
|
||||
DailyUsageUSD float64
|
||||
WeeklyUsageUSD float64
|
||||
MonthlyUsageUSD float64
|
||||
|
||||
AssignedBy *int64
|
||||
AssignedAt time.Time
|
||||
Notes string
|
||||
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
|
||||
User *User
|
||||
Group *Group
|
||||
AssignedByUser *User
|
||||
}
|
||||
|
||||
func (s *UserSubscription) IsActive() bool {
|
||||
return s.Status == SubscriptionStatusActive && time.Now().Before(s.ExpiresAt)
|
||||
}
|
||||
|
||||
func (s *UserSubscription) IsExpired() bool {
|
||||
return time.Now().After(s.ExpiresAt)
|
||||
}
|
||||
|
||||
func (s *UserSubscription) DaysRemaining() int {
|
||||
if s.IsExpired() {
|
||||
return 0
|
||||
}
|
||||
return int(time.Until(s.ExpiresAt).Hours() / 24)
|
||||
}
|
||||
|
||||
func (s *UserSubscription) IsWindowActivated() bool {
|
||||
return s.DailyWindowStart != nil || s.WeeklyWindowStart != nil || s.MonthlyWindowStart != nil
|
||||
}
|
||||
|
||||
func (s *UserSubscription) NeedsDailyReset() bool {
|
||||
if s.DailyWindowStart == nil {
|
||||
return false
|
||||
}
|
||||
return time.Since(*s.DailyWindowStart) >= 24*time.Hour
|
||||
}
|
||||
|
||||
func (s *UserSubscription) NeedsWeeklyReset() bool {
|
||||
if s.WeeklyWindowStart == nil {
|
||||
return false
|
||||
}
|
||||
return time.Since(*s.WeeklyWindowStart) >= 7*24*time.Hour
|
||||
}
|
||||
|
||||
func (s *UserSubscription) NeedsMonthlyReset() bool {
|
||||
if s.MonthlyWindowStart == nil {
|
||||
return false
|
||||
}
|
||||
return time.Since(*s.MonthlyWindowStart) >= 30*24*time.Hour
|
||||
}
|
||||
|
||||
func (s *UserSubscription) DailyResetTime() *time.Time {
|
||||
if s.DailyWindowStart == nil {
|
||||
return nil
|
||||
}
|
||||
t := s.DailyWindowStart.Add(24 * time.Hour)
|
||||
return &t
|
||||
}
|
||||
|
||||
func (s *UserSubscription) WeeklyResetTime() *time.Time {
|
||||
if s.WeeklyWindowStart == nil {
|
||||
return nil
|
||||
}
|
||||
t := s.WeeklyWindowStart.Add(7 * 24 * time.Hour)
|
||||
return &t
|
||||
}
|
||||
|
||||
func (s *UserSubscription) MonthlyResetTime() *time.Time {
|
||||
if s.MonthlyWindowStart == nil {
|
||||
return nil
|
||||
}
|
||||
t := s.MonthlyWindowStart.Add(30 * 24 * time.Hour)
|
||||
return &t
|
||||
}
|
||||
|
||||
func (s *UserSubscription) CheckDailyLimit(group *Group, additionalCost float64) bool {
|
||||
if !group.HasDailyLimit() {
|
||||
return true
|
||||
}
|
||||
return s.DailyUsageUSD+additionalCost <= *group.DailyLimitUSD
|
||||
}
|
||||
|
||||
func (s *UserSubscription) CheckWeeklyLimit(group *Group, additionalCost float64) bool {
|
||||
if !group.HasWeeklyLimit() {
|
||||
return true
|
||||
}
|
||||
return s.WeeklyUsageUSD+additionalCost <= *group.WeeklyLimitUSD
|
||||
}
|
||||
|
||||
func (s *UserSubscription) CheckMonthlyLimit(group *Group, additionalCost float64) bool {
|
||||
if !group.HasMonthlyLimit() {
|
||||
return true
|
||||
}
|
||||
return s.MonthlyUsageUSD+additionalCost <= *group.MonthlyLimitUSD
|
||||
}
|
||||
|
||||
func (s *UserSubscription) CheckAllLimits(group *Group, additionalCost float64) (daily, weekly, monthly bool) {
|
||||
daily = s.CheckDailyLimit(group, additionalCost)
|
||||
weekly = s.CheckWeeklyLimit(group, additionalCost)
|
||||
monthly = s.CheckMonthlyLimit(group, additionalCost)
|
||||
return
|
||||
}
|
||||
package service
|
||||
|
||||
import "time"
|
||||
|
||||
type UserSubscription struct {
|
||||
ID int64
|
||||
UserID int64
|
||||
GroupID int64
|
||||
|
||||
StartsAt time.Time
|
||||
ExpiresAt time.Time
|
||||
Status string
|
||||
|
||||
DailyWindowStart *time.Time
|
||||
WeeklyWindowStart *time.Time
|
||||
MonthlyWindowStart *time.Time
|
||||
|
||||
DailyUsageUSD float64
|
||||
WeeklyUsageUSD float64
|
||||
MonthlyUsageUSD float64
|
||||
|
||||
AssignedBy *int64
|
||||
AssignedAt time.Time
|
||||
Notes string
|
||||
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
|
||||
User *User
|
||||
Group *Group
|
||||
AssignedByUser *User
|
||||
}
|
||||
|
||||
func (s *UserSubscription) IsActive() bool {
|
||||
return s.Status == SubscriptionStatusActive && time.Now().Before(s.ExpiresAt)
|
||||
}
|
||||
|
||||
func (s *UserSubscription) IsExpired() bool {
|
||||
return time.Now().After(s.ExpiresAt)
|
||||
}
|
||||
|
||||
func (s *UserSubscription) DaysRemaining() int {
|
||||
if s.IsExpired() {
|
||||
return 0
|
||||
}
|
||||
return int(time.Until(s.ExpiresAt).Hours() / 24)
|
||||
}
|
||||
|
||||
func (s *UserSubscription) IsWindowActivated() bool {
|
||||
return s.DailyWindowStart != nil || s.WeeklyWindowStart != nil || s.MonthlyWindowStart != nil
|
||||
}
|
||||
|
||||
func (s *UserSubscription) NeedsDailyReset() bool {
|
||||
if s.DailyWindowStart == nil {
|
||||
return false
|
||||
}
|
||||
return time.Since(*s.DailyWindowStart) >= 24*time.Hour
|
||||
}
|
||||
|
||||
func (s *UserSubscription) NeedsWeeklyReset() bool {
|
||||
if s.WeeklyWindowStart == nil {
|
||||
return false
|
||||
}
|
||||
return time.Since(*s.WeeklyWindowStart) >= 7*24*time.Hour
|
||||
}
|
||||
|
||||
func (s *UserSubscription) NeedsMonthlyReset() bool {
|
||||
if s.MonthlyWindowStart == nil {
|
||||
return false
|
||||
}
|
||||
return time.Since(*s.MonthlyWindowStart) >= 30*24*time.Hour
|
||||
}
|
||||
|
||||
func (s *UserSubscription) DailyResetTime() *time.Time {
|
||||
if s.DailyWindowStart == nil {
|
||||
return nil
|
||||
}
|
||||
t := s.DailyWindowStart.Add(24 * time.Hour)
|
||||
return &t
|
||||
}
|
||||
|
||||
func (s *UserSubscription) WeeklyResetTime() *time.Time {
|
||||
if s.WeeklyWindowStart == nil {
|
||||
return nil
|
||||
}
|
||||
t := s.WeeklyWindowStart.Add(7 * 24 * time.Hour)
|
||||
return &t
|
||||
}
|
||||
|
||||
func (s *UserSubscription) MonthlyResetTime() *time.Time {
|
||||
if s.MonthlyWindowStart == nil {
|
||||
return nil
|
||||
}
|
||||
t := s.MonthlyWindowStart.Add(30 * 24 * time.Hour)
|
||||
return &t
|
||||
}
|
||||
|
||||
func (s *UserSubscription) CheckDailyLimit(group *Group, additionalCost float64) bool {
|
||||
if !group.HasDailyLimit() {
|
||||
return true
|
||||
}
|
||||
return s.DailyUsageUSD+additionalCost <= *group.DailyLimitUSD
|
||||
}
|
||||
|
||||
func (s *UserSubscription) CheckWeeklyLimit(group *Group, additionalCost float64) bool {
|
||||
if !group.HasWeeklyLimit() {
|
||||
return true
|
||||
}
|
||||
return s.WeeklyUsageUSD+additionalCost <= *group.WeeklyLimitUSD
|
||||
}
|
||||
|
||||
func (s *UserSubscription) CheckMonthlyLimit(group *Group, additionalCost float64) bool {
|
||||
if !group.HasMonthlyLimit() {
|
||||
return true
|
||||
}
|
||||
return s.MonthlyUsageUSD+additionalCost <= *group.MonthlyLimitUSD
|
||||
}
|
||||
|
||||
func (s *UserSubscription) CheckAllLimits(group *Group, additionalCost float64) (daily, weekly, monthly bool) {
|
||||
daily = s.CheckDailyLimit(group, additionalCost)
|
||||
weekly = s.CheckWeeklyLimit(group, additionalCost)
|
||||
monthly = s.CheckMonthlyLimit(group, additionalCost)
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user