Files
huangguo_server/app/service/activityclient/hongbao_countdown.go
T
rootandClaude Opus 5 8679200f41 Initial commit
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 13:57:10 +08:00

71 lines
2.2 KiB
Go

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
}