package activityclient import ( "net/url" "time" ) // LinkTypeHongbaoRain 跳转链接中标识红包雨活动的 type 参数值 const LinkTypeHongbaoRain = "hongbaoRain" // ResolveCountdownByLink 根据跳转链接的 type 参数推导倒计时类型和场次时间。 // 适用于 link 自身携带活动类型标识、但 DB 未单独建 countdownType 字段的业务(如任务列表)。 // // 返回值约定: // - link 含 type=hongbaoRain 且有可用红包雨场次:返回 (场次开始, 场次结束, 1, true) // - link 含 type=hongbaoRain 但无可用场次:返回 (零, 零, 1, false),调用方据此过滤该条目 // - 其他情况:返回 (零, 零, 0, true),无倒计时 func ResolveCountdownByLink(link string) (start, end time.Time, countdownType int, ok bool) { if linkType(link) != LinkTypeHongbaoRain { return time.Time{}, time.Time{}, 0, true } s, e, hit := NextHongbaoSession(time.Now()) if !hit { return time.Time{}, time.Time{}, 1, false } return s, e, 1, true } // linkType 提取链接 query 中的 type 参数,解析失败返回空串 func linkType(link string) string { if link == "" { return "" } u, err := url.Parse(link) if err != nil { return "" } return u.Query().Get("type") } // NextHongbaoSession 取一场用于倒计时展示的红包雨场次: // - 当前已处于某场次内(StartTime <= now < EndTime):返回该场次 // - 否则返回最近一场未来未过期场次 // - 无任何未过期场次:返回 (零值, 零值, false) func NextHongbaoSession(now time.Time) (start, end time.Time, ok bool) { data := GetHongbaoUpcoming() var ( nearestStart time.Time nearestEnd time.Time ) for _, s := range data.List { // 跳过已结束场次 if !s.EndTime.IsZero() && !s.EndTime.After(now) { continue } // 当前已在场次内,直接返回 if !s.StartTime.After(now) { return s.StartTime, s.EndTime, true } // 未来场次,取开始时间最早的 if nearestStart.IsZero() || s.StartTime.Before(nearestStart) { nearestStart = s.StartTime nearestEnd = s.EndTime } } if nearestStart.IsZero() { return time.Time{}, time.Time{}, false } return nearestStart, nearestEnd, true }