实现套餐生效条件覆盖与购买快照

This commit is contained in:
2026-07-22 20:51:12 +09:00
parent c7f8b4c702
commit 9818537239
30 changed files with 1092 additions and 149 deletions

View File

@@ -113,18 +113,22 @@ func (s *ActivationService) ActivateByRealname(ctx context.Context, carrierType
}
}
// REALNAME-04: 按 ExpiryBase 选择激活计时基准
terms, termsErr := ResolveUsageTerms(usage, &pkg, s.logger)
if termsErr != nil {
return termsErr
}
// REALNAME-04: 按购买快照选择激活计时基准
// from_purchase购买时起算用 PackageUsage 创建时间;否则用实名触发当前时刻
var activatedAt time.Time
if pkg.ExpiryBase == "from_purchase" {
if terms.ExpiryBase == constants.PackageExpiryBaseFromPurchase {
activatedAt = usage.CreatedAt
} else {
activatedAt = now
}
expiresAt := CalculateExpiryTime(pkg.CalendarType, activatedAt, pkg.DurationMonths, pkg.DurationDays)
expiresAt := CalculateExpiryTime(terms.CalendarType, activatedAt, terms.DurationMonths, terms.DurationDays)
// 计算下次重置时间
nextResetAt := CalculateNextResetTime(pkg.DataResetCycle, pkg.CalendarType, now, activatedAt)
nextResetAt := CalculateNextResetTime(pkg.DataResetCycle, terms.CalendarType, now, activatedAt)
// 更新套餐使用记录
updates := map[string]interface{}{
@@ -552,20 +556,24 @@ func (s *ActivationService) isCarrierRealnamed(ctx context.Context, tx *gorm.DB,
}
func (s *ActivationService) activatePendingUsage(ctx context.Context, tx *gorm.DB, usage *model.PackageUsage, pkg *model.Package, carrierType string, carrierID uint, now time.Time, logMessage string) error {
terms, err := ResolveUsageTerms(usage, pkg, s.logger)
if err != nil {
return err
}
// ExpiryBase=from_purchase 只用于"等待实名激活"场景REALNAME-04套餐已购买但资产未实名
// 计时基准按购买时间算,实名只是解锁使用权。此函数同时被"前一个主套餐到期后排队顺延"场景复用,
// 这种情况下 usage.PendingRealnameActivation 为 false不应该套用购买时间否则排队等待的天数会
// 从到期时间里被扣掉。只有当这条记录确实是因为等实名才被搁置时,才按 ExpiryBase 选基准。
var activatedAt time.Time
if usage.PendingRealnameActivation && pkg.ExpiryBase == "from_purchase" {
if usage.PendingRealnameActivation && terms.ExpiryBase == constants.PackageExpiryBaseFromPurchase {
activatedAt = usage.CreatedAt
} else {
activatedAt = now
}
expiresAt := CalculateExpiryTime(pkg.CalendarType, activatedAt, pkg.DurationMonths, pkg.DurationDays)
expiresAt := CalculateExpiryTime(terms.CalendarType, activatedAt, terms.DurationMonths, terms.DurationDays)
// 计算下次重置时间
nextResetAt := CalculateNextResetTime(pkg.DataResetCycle, pkg.CalendarType, now, activatedAt)
nextResetAt := CalculateNextResetTime(pkg.DataResetCycle, terms.CalendarType, now, activatedAt)
// 更新套餐使用记录
updates := map[string]interface{}{