package vidhelpser import ( "time" "91porn-server/app/service/sys_config" "91porn-server/models/cache/sysconfdata" "91porn-server/models/v/sysconfmod" "91porn-server/models/v/usermod" "91porn-server/models/v/vidmod" ) // FreeTrialBadgeContext 是一次视频列表组装过程中复用的用户免费观看上下文。 type FreeTrialBadgeContext struct { uid uint64 enabled bool remaining uint64 canShow bool canUse bool } // NewFreeTrialBadgeContext 构造免费观看上下文。 // remaining 会按系统配置的总次数截断,避免历史异常数据透传给前端。 func NewFreeTrialBadgeContext(uid, total, remaining uint64, isVIP, enabled bool) FreeTrialBadgeContext { if total == 0 || uid == 0 { remaining = 0 } else if remaining > total { remaining = total } canShow := uid > 0 && total > 0 && !isVIP return FreeTrialBadgeContext{ uid: uid, enabled: enabled, remaining: remaining, canShow: canShow, canUse: canShow && remaining > 0, } } // LoadFreeTrialBadgeContext 加载用户和后台角标开关。 func LoadFreeTrialBadgeContext(uid uint64) FreeTrialBadgeContext { if uid == 0 { return FreeTrialBadgeContext{} } user, err := usermod.FindUserByUID(uid) if err != nil || user == nil { return FreeTrialBadgeContext{} } return FreeTrialBadgeContextForUser(uid, user) } // FreeTrialBadgeContextForUser 使用已查询的用户构造上下文,避免列表组装重复查询用户。 func FreeTrialBadgeContextForUser(uid uint64, user *usermod.User) FreeTrialBadgeContext { if uid == 0 || user == nil { return FreeTrialBadgeContext{} } enabled := false if value, err := sysconfdata.GetBoolFromSharedCache(sysconfmod.VCodeFreeTrialBadgeEnabled); err == nil { enabled = value } return NewFreeTrialBadgeContext( uid, sys_config.GetTotalWatchCount(), user.WatchCount, user.IsVIP(time.Now()), enabled, ) } // Fields 返回当前视频的角标字段。 func (c FreeTrialBadgeContext) Fields( newsType string, originCoins int64, freeArea bool, publisherID uint64, ) (show bool, remaining uint64, canUse bool) { remaining = c.remaining eligible := isVIPVideoForFreeTrial(newsType, originCoins, freeArea) && publisherID != c.uid canUse = c.canUse && eligible show = c.enabled && canUse return } func isVIPVideoForFreeTrial(newsType string, originCoins int64, freeArea bool) bool { if originCoins != 0 || freeArea { return false } return newsType == vidmod.SP || newsType == vidmod.SHORT } // ApplyFreeTrialBadgeToVideoInfos 设置标准视频列表/详情对象的角标字段。 func ApplyFreeTrialBadgeToVideoInfos(ctx FreeTrialBadgeContext, videos []*vidmod.VideoInfo) { for _, video := range videos { if video == nil { continue } video.ShowFreeTrialBadge, video.FreeTrialRemaining, video.CanUseFreeTrial = ctx.Fields( video.NewsType, video.OriginCoins, video.FreeArea, video.UInfo.UID, ) } } // ApplyFreeTrialBadgeToVideoInfoResps 设置无状态视频列表对象的角标字段。 func ApplyFreeTrialBadgeToVideoInfoResps(ctx FreeTrialBadgeContext, videos []*vidmod.VideoInfoResp) { for _, video := range videos { if video == nil { continue } video.ShowFreeTrialBadge, video.FreeTrialRemaining, video.CanUseFreeTrial = ctx.Fields( video.NewsType, video.OriginCoins, video.FreeArea, video.UInfo.UID, ) } }