You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
5.9 KiB
243 lines
5.9 KiB
package call |
|
|
|
import ( |
|
"context" |
|
"fmt" |
|
"math/rand" |
|
"server/common" |
|
"server/db" |
|
"strconv" |
|
"time" |
|
|
|
"github.com/liangdas/mqant/log" |
|
) |
|
|
|
const ( |
|
RankNum = 20 |
|
) |
|
|
|
var ( |
|
Robots = []*common.ConfigShareRobot{{ |
|
RobotID: 21891253, |
|
}, { |
|
RobotID: 23923560, |
|
}, { |
|
RobotID: 25956230, |
|
}} |
|
) |
|
|
|
// RankInfo 机器人结构 |
|
type RankInfo struct { |
|
Rank int |
|
InviteCount int64 |
|
Avtar int |
|
UserName string |
|
} |
|
|
|
func IsRobot(uid int) bool { |
|
for _, robot := range Robots { |
|
if robot.RobotID == uid { |
|
return true |
|
} |
|
} |
|
if db.Mysql().Exist(&common.ConfigShareRobot{RobotID: uid}) { |
|
return true |
|
} |
|
return false |
|
} |
|
|
|
// 获取排行榜key |
|
func GetRedisRankKey() string { |
|
activity := GetConfigActivityByID(common.ActivityIDInviteRank) |
|
if activity == nil { |
|
log.Error("GetRedisRankKey ==nil") |
|
return "" |
|
} |
|
return fmt.Sprintf("robot_ranking:%v", activity.Start) |
|
} |
|
|
|
func GetRedisRankRobotKey(uid int) string { |
|
today := time.Now().Format("20060102") |
|
activity := GetConfigActivityByID(common.ActivityIDInviteRank) |
|
if activity == nil { |
|
log.Error("GetRedisRankKey ==nil") |
|
return "" |
|
} |
|
return fmt.Sprintf("robot_ranking:%v:robot:%v:%v", activity.Start, uid, today) |
|
} |
|
|
|
func GetRedisRankRewardKey() string { |
|
activity := GetConfigActivityByID(common.ActivityIDInviteRank) |
|
if activity == nil { |
|
log.Error("GetRedisRankKey ==nil") |
|
return "" |
|
} |
|
return fmt.Sprintf("robot_ranking:%v:reward", activity.Start) |
|
} |
|
|
|
func TodayLogic(key string, uid int, num, times int64) { |
|
robotKey := GetRedisRankRobotKey(uid) |
|
timesCount := db.Redis().HGetInt(robotKey, "times_count") |
|
// timesUse := db.Redis().HGetInt(robotKey, "times_use") |
|
if timesCount == 0 { |
|
err := db.Redis().HSet(robotKey, map[string]interface{}{ |
|
"times_count": times, |
|
"times_use": 1, |
|
"num": 1, |
|
}) |
|
if err != nil { |
|
log.Error("err:%v", err) |
|
return |
|
} |
|
timesCount = int(times) |
|
} else { |
|
err := db.Redis().HIncrBy(robotKey, "times_use", 1) |
|
if err != nil { |
|
log.Error("err:%v", err) |
|
return |
|
} |
|
if err = db.Redis().HIncrBy(robotKey, "num", num); err != nil { |
|
log.Error("err:%v", err) |
|
return |
|
} |
|
} |
|
// if timesUse < timesCount { |
|
IncreaseInviteCount(fmt.Sprintf("%v", uid), num, true) |
|
// } |
|
} |
|
|
|
// IncreaseInviteCount 增长机器人邀请人数 |
|
func IncreaseInviteCount(robotName string, increment int64, isRobot bool) { |
|
if increment > 0 { |
|
ctx := context.Background() |
|
rdb := db.Redis().GetRedis() |
|
key := GetRedisRankKey() |
|
newScore, err := rdb.ZIncrBy(ctx, key, float64(increment), robotName).Result() |
|
if err != nil { |
|
log.Error("增长失败: %v", err) |
|
} else { |
|
log.Info("机器人 %s 增长 %d 人,新的邀请人数为 %d", robotName, increment, int64(newScore)) |
|
} |
|
} |
|
} |
|
|
|
func GetUserRank(uid int) (ret RankInfo) { |
|
ctx := context.Background() |
|
rdb := db.Redis().GetRedis() |
|
key := GetRedisRankKey() |
|
member := fmt.Sprintf("%v", uid) |
|
score, err := rdb.ZScore(ctx, key, member).Result() |
|
if err != nil { |
|
log.Error("Error:", err) |
|
return |
|
} else { |
|
log.Info("Score of %s: %f", member, score) |
|
} |
|
|
|
// 获取指定成员的排名 (从小到大) |
|
rank, err := rdb.ZRevRank(ctx, key, member).Result() |
|
if err != nil { |
|
log.Error("Error:", err) |
|
return |
|
} else { |
|
log.Info("Rank of %s (ascending): %d", member, rank) |
|
} |
|
user, _ := GetUserXInfo(uid, "avatar") |
|
if user != nil { |
|
ret.Avtar, _ = strconv.Atoi(user.Avatar) |
|
} |
|
ret.Rank = int(rank) + 1 |
|
ret.InviteCount = int64(score) |
|
ret.UserName = fmt.Sprintf("User%v", uid) |
|
return |
|
} |
|
|
|
func GetTopShareRank(rank int64) (ret []RankInfo) { |
|
ctx := context.Background() |
|
rdb := db.Redis().GetRedis() |
|
key := GetRedisRankKey() |
|
rankList, err := rdb.ZRevRangeWithScores(ctx, key, 0, rank-1).Result() |
|
if err != nil { |
|
log.Error("获取排名失败: %v", err) |
|
return nil |
|
} |
|
for idx, robot := range rankList { |
|
username := fmt.Sprintf("%v", robot.Member) |
|
uid, _ := strconv.Atoi(username) |
|
|
|
log.Debug("用户: %s,邀请人数: %d", robot.Member, int(robot.Score)) |
|
info := RankInfo{ |
|
Rank: idx + 1, |
|
UserName: fmt.Sprintf("%v", robot.Member), |
|
InviteCount: int64(robot.Score), |
|
Avtar: rand.Intn(28) + 1, |
|
} |
|
if !IsRobot(uid) { |
|
user, _ := GetUserXInfo(uid, "avatar") |
|
info.Avtar, _ = strconv.Atoi(user.Avatar) |
|
|
|
} |
|
ret = append(ret, info) |
|
} |
|
return |
|
} |
|
|
|
// RiskControl 风控逻辑 |
|
func RiskControl() { |
|
rankList := GetTopShareRank(RankNum) |
|
log.Info("rishControl:%v", rankList) |
|
playerMap := make([]RankInfo, 0, 10) |
|
robotMap := make([]RankInfo, 0, 10) |
|
for _, rankInfo := range rankList { |
|
uid, _ := strconv.Atoi(rankInfo.UserName) |
|
// 判断是否为机器人 |
|
if !IsRobot(uid) { |
|
playerMap = append(playerMap, rankInfo) |
|
} else { |
|
robotMap = append(robotMap, rankInfo) |
|
} |
|
} |
|
log.Debug("playerMap:%+v", playerMap) |
|
log.Debug("robotMap:%+v", robotMap) |
|
for idx, robot := range robotMap { |
|
if idx < 3 { |
|
player := playerMap[0] |
|
log.Debug("player:%v,robot:%v", player, robot) |
|
if robot.InviteCount < player.InviteCount { |
|
IncreaseInviteCount(robot.UserName, player.InviteCount-robot.InviteCount+rand.Int63n(15), true) |
|
} |
|
} |
|
} |
|
} |
|
|
|
func SendReward() { |
|
rankList := GetTopShareRank(RankNum) |
|
log.Info("SendReward:%v", rankList) |
|
for _, rankInfo := range rankList { |
|
if rankInfo.InviteCount > 0 { |
|
uid, err := strconv.Atoi(rankInfo.UserName) |
|
if err != nil { |
|
log.Error("err:%v", err) |
|
continue |
|
} |
|
if rankInfo.Rank <= 3 && !IsRobot(uid) { |
|
// 强制修改成第四名 |
|
rankInfo.Rank = 4 |
|
} |
|
conf := GetConfigRobotRankRewardByRank(rankInfo.Rank) |
|
if conf.Reward > 0 { |
|
UpdateCurrencyPro(&common.UpdateCurrency{ |
|
CurrencyBalance: &common.CurrencyBalance{ |
|
UID: uid, |
|
Event: common.CurrencyEventActivityShareRank, |
|
Type: common.CurrencyINR, |
|
Value: conf.Reward, |
|
// NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, conf.Reward), |
|
}, |
|
}) |
|
SendMailWithContent(uid, SystemTitle, fmt.Sprintf(EmailShareRank, rankInfo.Rank, conf.Reward/common.DecimalDigits)) |
|
} |
|
} |
|
|
|
} |
|
}
|
|
|