Files
huangguo_server/app/service/vidhelpser/free_trial.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

121 lines
3.3 KiB
Go

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,
)
}
}