// Package package 提供套餐生命周期领域规则。 package packagedomain import ( "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/errors" ) // TermsSnapshot 套餐购买时不可变计时条款。 type TermsSnapshot struct { ExpiryBase string CalendarType string DurationMonths int DurationDays int } // ResolveTermsSnapshot 解析并校验套餐购买时计时条款。 func ResolveTermsSnapshot(pkg *model.Package, allocation *model.ShopPackageAllocation) (TermsSnapshot, error) { if pkg == nil { return TermsSnapshot{}, errors.New(errors.CodeInvalidParam, "套餐计时条款缺失") } expiryBase := pkg.ExpiryBase if allocation != nil && allocation.ExpiryBaseOverride != nil { expiryBase = *allocation.ExpiryBaseOverride } if expiryBase != constants.PackageExpiryBaseFromActivation && expiryBase != constants.PackageExpiryBaseFromPurchase { return TermsSnapshot{}, errors.New(errors.CodeInvalidParam, "套餐生效条件无效") } if pkg.CalendarType == constants.PackageCalendarTypeNaturalMonth { if pkg.DurationMonths <= 0 { return TermsSnapshot{}, errors.New(errors.CodeInvalidParam, "套餐自然月时长无效") } return TermsSnapshot{ExpiryBase: expiryBase, CalendarType: pkg.CalendarType, DurationMonths: pkg.DurationMonths}, nil } if pkg.CalendarType == constants.PackageCalendarTypeByDay && pkg.DurationDays > 0 { return TermsSnapshot{ExpiryBase: expiryBase, CalendarType: pkg.CalendarType, DurationDays: pkg.DurationDays}, nil } return TermsSnapshot{}, errors.New(errors.CodeInvalidParam, "套餐按天时长无效") } // Apply 将计时条款写入套餐使用记录。 func (s TermsSnapshot) Apply(usage *model.PackageUsage) { usage.ExpiryBaseSnapshot = s.ExpiryBase usage.CalendarTypeSnapshot = s.CalendarType usage.DurationMonthsSnapshot = s.DurationMonths usage.DurationDaysSnapshot = s.DurationDays } // IsValid 判断快照是否完整有效。 func (s TermsSnapshot) IsValid() bool { if s.ExpiryBase != constants.PackageExpiryBaseFromActivation && s.ExpiryBase != constants.PackageExpiryBaseFromPurchase { return false } return (s.CalendarType == constants.PackageCalendarTypeNaturalMonth && s.DurationMonths > 0) || (s.CalendarType == constants.PackageCalendarTypeByDay && s.DurationDays > 0) } // TermsSnapshotFromUsage 从使用记录读取计时条款。 func TermsSnapshotFromUsage(usage *model.PackageUsage) TermsSnapshot { return TermsSnapshot{ ExpiryBase: usage.ExpiryBaseSnapshot, CalendarType: usage.CalendarTypeSnapshot, DurationMonths: usage.DurationMonthsSnapshot, DurationDays: usage.DurationDaysSnapshot, } }