package operationsreport import ( "time" "github.com/break/junhong_cmp_fiber/pkg/constants" ) // ExpiredMainUsage 是一条到期事实:快照日(上海自然日)等于其到期日的主套餐使用记录。 type ExpiredMainUsage struct { UsageID uint AssetType string AssetID uint ExpiresAt time.Time } // MainUsageCandidate 是同资产上参与续费判定的主套餐记录投影。 // 调用方必须只传入未退款(refund_id IS NULL)的主套餐(master_usage_id IS NULL)记录。 type MainUsageCandidate struct { UsageID uint Status int ActivatedAt *time.Time } // IsRenewed 判定该到期事实是否已续费(设计 D9): // 存在**另一条**未退款主套餐记录,其生效时间晚于本条到期时间,或处于待生效状态。 // // 候选中属于本条记录自身的项不参与判定;判定的结果挂在到期行上, // 使续费资产集合恒为到期资产集合的子集,续费率不超过 100% 由构造保证,不做任何截断或钳制。 func IsRenewed(expired ExpiredMainUsage, candidates []MainUsageCandidate) bool { for _, candidate := range candidates { if candidate.UsageID == expired.UsageID { continue } if candidate.Status == constants.PackageUsageStatusPending { return true } if candidate.ActivatedAt != nil && candidate.ActivatedAt.After(expired.ExpiresAt) { return true } } return false }