package web
import (
"context"
"fmt"
"math/rand"
"server/call"
"server/common"
"server/config"
"server/db"
"server/modules/web/values"
"server/util"
"strconv"
"time"
"github.com/liangdas/mqant/log"
)
func FetchDatas ( ) {
GetShareData ( )
// GetActivitySlotsRank()
RobotRank ( )
}
var (
FetchInterval = 5 * 60
ShareDataRankNum = 20 // 排行榜显示8个
ActivitySlotsRankNum = 10 // slots活动排行榜数目
)
// 分享数据
func GetShareData ( ) {
values . ShareTotalInviteReward = db . Mysql ( ) . Sum ( & common . ShareInfo { } , "" , "invite_reward" )
values . ShareTotalBetReward = db . Mysql ( ) . Sum ( & common . ShareInfo { } , "" , "bet_reward" )
ranks := [ ] * values . OneShareRank { }
err := db . Mysql ( ) . C ( ) . Raw ( fmt . Sprintf ( "select uid,invite_reward + bet_reward as reward from share_info order by reward desc limit %d" , ShareDataRankNum ) ) . Scan ( & ranks ) . Error
if err != nil {
log . Error ( "err:%v" , err )
}
for _ , v := range ranks {
robot := call . GetConfigShareRobotByID ( v . UID )
if robot != nil {
v . Avatar = robot . Avatar
v . Nick = robot . Nick
} else {
p , _ := call . GetUserXInfo ( v . UID , "mobile" , "avatar" )
v . Avatar = p . Avatar
v . Nick = p . Mobile
}
v . Nick = "*******" + v . Nick [ len ( v . Nick ) - 3 : ]
}
values . ShareRank = ranks
time . AfterFunc ( time . Duration ( FetchInterval ) * time . Second , GetShareData )
}
// slots活动排行榜
func GetActivitySlotsRank ( ) {
list := [ ] * common . ActivitySlotsData { }
str := "time2"
numberStr := "best_number2"
order := "best_number2 desc,time2 asc"
if call . IsActivitySingleDay ( common . ActivityIDSlots ) {
order = "best_number1 desc,time1 asc"
str = "time1"
numberStr = "best_number1"
}
db . Mysql ( ) . QueryList ( 0 , 10 , fmt . Sprintf ( "%s >= %d and %s > 0" , str , util . GetZeroTime ( time . Now ( ) ) . Unix ( ) , numberStr ) , order , & common . ActivitySlotsData { } , & list )
values . ActivitySlotsRank = list
interval := FetchInterval
if ! config . GetBase ( ) . Release {
interval = int ( util . GetNext5MinUnix ( ) - time . Now ( ) . Unix ( ) )
}
time . AfterFunc ( time . Duration ( interval ) * time . Second , GetActivitySlotsRank )
for _ , v := range values . ActivitySlotsRank {
log . Debug ( "ActivitySlotsRank:%+v" , v )
}
}
func RobotRank ( ) {
now := time . Now ( )
activity := call . GetConfigActivityByID ( common . ActivityIDInviteRank )
key := call . GetRedisRankKey ( )
log . Info ( "key:%v,rank checking" , key )
// 活动未开始
if activity . IsRelease != 2 || activity . Start > now . Unix ( ) {
time . AfterFunc ( time . Minute , RobotRank )
return
} else if activity . End < now . Unix ( ) && activity . End > 0 {
rewardKey := call . GetRedisRankRewardKey ( )
res , _ := db . Redis ( ) . GetString ( rewardKey )
if res == "1" {
// 一分钟重试
log . Info ( "key:%v,checking" , key )
time . AfterFunc ( time . Minute , RobotRank )
return
}
// 过期后判断占榜是否有问题
call . RiskControl ( )
// 发放奖励
call . SendReward ( )
// 记录已经发奖
db . Redis ( ) . SetNX ( rewardKey , "1" )
time . AfterFunc ( time . Minute , RobotRank )
log . Info ( "key:%v,checking" , key )
return
}
startTime := time . Unix ( activity . Start , 0 )
endTime := time . Unix ( activity . End , 0 )
// 总天数
totalDay := int ( endTime . Sub ( startTime ) . Hours ( ) / 24 )
// 今天是第几天一个小时算一天
day := int ( now . Sub ( startTime ) . Hours ( ) / 24 ) + 1
// 获取占榜规则
rule := call . GetConfigRobotRankRuleByDay ( day )
if rule . ID == 0 {
log . Error ( "day:%v rule err" , day )
}
// 增长人数
num := rule . IncrNum
rdb := db . Redis ( ) . GetRedis ( )
ctx := context . Background ( )
robots := call . Robots
log . Info ( "totalDay:%v,day:%v,rule:%+v" , totalDay , day , rule )
if day == totalDay {
log . Debug ( "最后一天增长逻辑" )
robotRank := int64 ( 0 )
// 获取机器人排名
for i := 0 ; i < len ( robots ) ; i ++ {
result , err := rdb . ZRevRangeWithScores ( ctx , key , robotRank , robotRank ) . Result ( )
if err != nil {
log . Error ( "Error:" , err )
continue
}
_ , topRankScore := result [ 0 ] . Member , result [ 0 ] . Score
lastRankScore , _ := rdb . ZScore ( ctx , key , strconv . Itoa ( robots [ len ( robots ) - 1 ] . RobotID ) ) . Result ( )
growth := int64 ( topRankScore - lastRankScore ) / 5
times := rand . Int63n ( rule . EndIncrTimes - rule . StartIncrTimes ) + rule . StartIncrTimes
call . TodayLogic ( key , robots [ i ] . RobotID , growth , times )
}
} else if day >= totalDay * 2 / 3 {
log . Debug ( "倒数3/2天的增长逻辑" )
robotRank := int64 ( 0 )
for _ , robot := range robots {
rank , err := rdb . ZRevRank ( ctx , key , strconv . Itoa ( robot . RobotID ) ) . Result ( )
if err != nil {
fmt . Println ( "Error:" , err )
continue
}
if rank > 2 {
// 如果机器人不在前三名
result , err := rdb . ZRevRangeWithScores ( ctx , key , robotRank , robotRank ) . Result ( )
if err != nil {
log . Error ( "Error:" , err )
continue
}
_ , inviteCount := result [ 0 ] . Member , result [ 0 ] . Score
robotScore , err := rdb . ZScore ( ctx , key , strconv . Itoa ( robot . RobotID ) ) . Result ( )
if err != nil {
log . Error ( "Error:" , err )
continue
}
// 计算差值 N
N := rand . Int63n ( int64 ( inviteCount - robotScore ) ) / 5
if inviteCount - robotScore <= 5 {
N = int64 ( inviteCount - robotScore )
}
times := rand . Int63n ( rule . EndIncrTimes - rule . StartIncrTimes ) + rule . StartIncrTimes
call . TodayLogic ( key , robot . RobotID , N , times )
} else {
// 如果机器人在前三名,使用正常增长逻辑
times := rand . Int63n ( rule . EndIncrTimes - rule . StartIncrTimes ) + rule . StartIncrTimes
call . TodayLogic ( key , robot . RobotID , num , times )
}
}
} else {
for _ , robot := range robots {
times := rand . Int63n ( rule . EndIncrTimes - rule . StartIncrTimes ) + rule . StartIncrTimes
call . TodayLogic ( key , robot . RobotID , num , times )
}
}
// 随机出增长间隔 增长人数 增长次数
interval := rand . Int63n ( rule . EndInterval - rule . StartInterval ) + rule . StartInterval
interval = int64 ( time . Duration ( interval ) * time . Hour / 100 )
log . Info ( "%v小时后执行" , time . Duration ( interval ) / time . Hour )
if now . Unix ( ) + interval > activity . End {
interval = activity . End - now . Unix ( )
}
time . AfterFunc ( time . Duration ( interval ) , RobotRank )
}