排行榜活动

dev
mofangmin 1 year ago
parent 2bbef647e9
commit 02acc3095f
  1. 53
      call/config.go
  2. 1
      call/mail.go
  3. 19
      call/reload.go
  4. 243
      call/robot.go
  5. 8
      call/share.go
  6. 2
      common/activity.go
  7. 6
      common/config.go
  8. 1
      common/currency.go
  9. 27
      common/share.go
  10. 2
      db/redis/redis.go
  11. 11
      modules/backend/handler/gm/gm.go
  12. 2
      modules/backend/migrate.go
  13. 2
      modules/backend/routers/routers_gm.go
  14. 4
      modules/backend/values/gm.go
  15. 1
      modules/web/app/activity.go
  16. 14
      modules/web/handler/activity.go
  17. 6
      modules/web/handler/share.go
  18. 1
      modules/web/middleware/token.go
  19. 118
      modules/web/timer.go
  20. 24
      modules/web/values/activity.go

@ -66,6 +66,8 @@ var (
configActivityPopup []*common.ConfigActivityPopup configActivityPopup []*common.ConfigActivityPopup
configDiscountTicket []common.ConfigDiscountTicket configDiscountTicket []common.ConfigDiscountTicket
configRtp []common.ConfigRtp configRtp []common.ConfigRtp
configRankReward []common.ConfigShareRankReward
configRankRule []common.ConfigShareRankRule
// 客服 // 客服
configCustomerRobot []*common.ConfigCustomerRobot configCustomerRobot []*common.ConfigCustomerRobot
customerOrderLabel []*common.CustomerOrderLabel customerOrderLabel []*common.CustomerOrderLabel
@ -247,14 +249,15 @@ func GetConfigActivityAll() []*common.ConfigActivity {
func GetConfigActivityActiveAll(uid int) []*common.ConfigActivity { func GetConfigActivityActiveAll(uid int) []*common.ConfigActivity {
ret := []*common.ConfigActivity{} ret := []*common.ConfigActivity{}
for _, v := range configActivity { for _, v := range configActivity {
v.IsOpen = true
if !v.IsValid() { if !v.IsValid() {
continue v.IsOpen = false
} }
if v.ActivityID == common.ActivityIDFirstRechargeBack && !ShouldShowActivityFirstRechargeBack(uid) { if v.ActivityID == common.ActivityIDFirstRechargeBack && !ShouldShowActivityFirstRechargeBack(uid) {
continue continue
} }
if v.Push != 1 { if v.Push != 1 {
continue v.IsOpen = false
} }
ret = append(ret, v) ret = append(ret, v)
} }
@ -1625,3 +1628,49 @@ func GetConfigRTPByAmount(amount int64) (ret common.ConfigRtp) {
} }
return return
} }
func LoadConfigRobotRankReward() (err error) {
var list []common.ConfigShareRankReward
if _, err = db.Mysql().QueryAll("", "", &common.ConfigShareRankReward{}, &list); err != nil {
log.Error("err:%v", err)
return err
}
configRankReward = list
return nil
}
func GetConfigRobotRankReward() []common.ConfigShareRankReward {
return configRankReward
}
func GetConfigRobotRankRewardByRank(rank int) (ret common.ConfigShareRankReward) {
for _, conf := range configRankReward {
if conf.StartLevel <= rank && conf.EndLevel >= rank {
return conf
}
}
return
}
func LoadConfigRobotRankRule() (err error) {
var list []common.ConfigShareRankRule
if _, err = db.Mysql().QueryAll("", "", &common.ConfigShareRankRule{}, &list); err != nil {
log.Error("err:%v", err)
return err
}
configRankRule = list
return nil
}
func GetConfigRobotRankRule() []common.ConfigShareRankRule {
return configRankRule
}
func GetConfigRobotRankRuleByDay(day int) (ret common.ConfigShareRankRule) {
for _, rule := range configRankRule {
if rule.Day == day {
return rule
}
}
return
}

@ -17,6 +17,7 @@ var (
EmailWithdrawFail = "Your order %v, Amount: $%v\nYour withdrawal failed due to incorrect information. Please verify or change your withdrawal details and resubmit" EmailWithdrawFail = "Your order %v, Amount: $%v\nYour withdrawal failed due to incorrect information. Please verify or change your withdrawal details and resubmit"
EmailShareWithdrawFail = "Your friend's invitation reward withdrawal order: %v, Amount: %v\nYour withdrawal failed due to incorrect information. Please verify or change your withdrawal details and resubmit.\n" EmailShareWithdrawFail = "Your friend's invitation reward withdrawal order: %v, Amount: %v\nYour withdrawal failed due to incorrect information. Please verify or change your withdrawal details and resubmit.\n"
EmailDiscount = "Congratulations, you have received a $%v coupon for a top-up of $%v or more." EmailDiscount = "Congratulations, you have received a $%v coupon for a top-up of $%v or more."
EmailShareRank = "Congratulations on achieving Rank %v in the million giveaway event. You have received a bonus of ₹%v. Thank you for participating!"
) )
func checkMail(uid int, red *common.PlayerRed) { func checkMail(uid int, red *common.PlayerRed) {

@ -486,6 +486,25 @@ func CommonReload(c map[int][]func(*pb.ReloadGameConfig) error) {
return nil return nil
}} }}
} }
if _, ok := c[common.ReloadConfigRankReward]; !ok {
c[common.ReloadConfigRankReward] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error {
if err := LoadConfigRobotRankReward(); err != nil {
log.Error("error : [%s]", err.Error())
return err
}
return nil
}}
}
if _, ok := c[common.ReloadConfigRankRule]; !ok {
c[common.ReloadConfigRankRule] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error {
if err := LoadConfigRobotRankRule(); err != nil {
log.Error("error : [%s]", err.Error())
return err
}
return nil
}}
}
// 客服 // 客服
if _, ok := c[common.ReloadConfigCustomerRobot]; !ok { if _, ok := c[common.ReloadConfigCustomerRobot]; !ok {
c[common.ReloadConfigCustomerRobot] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error { c[common.ReloadConfigCustomerRobot] = []func(*pb.ReloadGameConfig) error{func(rgc *pb.ReloadGameConfig) error {

@ -0,0 +1,243 @@
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))
}
}
}
}

@ -114,11 +114,14 @@ func CheckShare(r *common.RechargeOrder) {
"available_reward": gorm.Expr("available_reward + ?", reward), "available_reward": gorm.Expr("available_reward + ?", reward),
} }
db.Mysql().Update(&common.ShareInfo{UID: shareInfo.UP1}, update) db.Mysql().Update(&common.ShareInfo{UID: shareInfo.UP1}, update)
ShareRecharge(r.UID, r.Amount+betAmount, 1)
IncreaseInviteCount(fmt.Sprintf("%v", shareInfo.UP1), 1, false)
} else {
ShareRecharge(r.UID, r.Amount+betAmount, 2)
} }
ShareRecharge(r.UID, r.Amount+betAmount)
} }
func ShareRecharge(uid int, amount int64) { func ShareRecharge(uid int, amount int64, typ int) {
shareInfo := &common.ShareInfo{UID: uid} shareInfo := &common.ShareInfo{UID: uid}
db.Mysql().Get(shareInfo) db.Mysql().Get(shareInfo)
if shareInfo.UP1 == 0 { if shareInfo.UP1 == 0 {
@ -147,6 +150,7 @@ func ShareRecharge(uid int, amount int64) {
}) })
db.Mysql().Create(&common.ShareDetail{ db.Mysql().Create(&common.ShareDetail{
UID: uid, UID: uid,
Type: typ,
Up: upUid, Up: upUid,
RechargeAmount: amount, RechargeAmount: amount,
Reward: reward, Reward: reward,

@ -23,6 +23,7 @@ const (
ActivityIDSevenDayBox // 7日签到宝箱 ActivityIDSevenDayBox // 7日签到宝箱
ActivityIDSuper // 超级1+2 ActivityIDSuper // 超级1+2
ActivityIDBetDraw // 下注抽奖活动 ActivityIDBetDraw // 下注抽奖活动
ActivityIDInviteRank // 邀请排行榜
) )
@ -75,6 +76,7 @@ type ConfigActivity struct {
Data string `gorm:"column:data;type:varchar(255);comment:跳转数据" json:"Data" web:"data"` Data string `gorm:"column:data;type:varchar(255);comment:跳转数据" json:"Data" web:"data"`
Content string `gorm:"column:content;type:varchar(255);comment:文案内容" json:"Content" web:"content"` Content string `gorm:"column:content;type:varchar(255);comment:文案内容" json:"Content" web:"content"`
Text string `gorm:"column:text;type:varchar(255);comment:按钮内容" json:"Text" web:"text"` Text string `gorm:"column:text;type:varchar(255);comment:按钮内容" json:"Text" web:"text"`
IsOpen bool `gorm:"-"`
} }
func (a *ConfigActivity) TableName() string { func (a *ConfigActivity) TableName() string {

@ -54,6 +54,8 @@ const (
ReloadConfigActivityPopup // 活动弹窗 ReloadConfigActivityPopup // 活动弹窗
ReloadConfigDiscountTicket // 折扣券 ReloadConfigDiscountTicket // 折扣券
ReloadConfigRTP // rtp配置 ReloadConfigRTP // rtp配置
ReloadConfigRankReward // 排行榜奖励
ReloadConfigRankRule // 规则
ReloadConfigCustomerRobot // 客服系统机器人配置 ReloadConfigCustomerRobot // 客服系统机器人配置
ReloadConfigCustomerLabel // 客服系统订单标签 ReloadConfigCustomerLabel // 客服系统订单标签
ReloadConfigCustomer // 客服系统订单标签 ReloadConfigCustomer // 客服系统订单标签
@ -152,6 +154,10 @@ func GetConfigStructByType(t int) (interface{}, interface{}) {
return &ConfigDiscountTicket{}, &[]ConfigDiscountTicket{} return &ConfigDiscountTicket{}, &[]ConfigDiscountTicket{}
case ReloadConfigRTP: case ReloadConfigRTP:
return &ConfigRtp{}, &[]ConfigRtp{} return &ConfigRtp{}, &[]ConfigRtp{}
case ReloadConfigRankReward:
return &ConfigShareRankReward{}, &[]ConfigShareRankReward{}
case ReloadConfigRankRule:
return &ConfigShareRankRule{}, &[]ConfigShareRankRule{}
default: default:
return nil, nil return nil, nil
} }

@ -101,6 +101,7 @@ const (
CurrencyEventActivitySuper // 超级1+2 CurrencyEventActivitySuper // 超级1+2
CurrencyEventActivityBetDraw // 下注抽奖 CurrencyEventActivityBetDraw // 下注抽奖
CurrencyEventActivityShareBind // 分享绑定 CurrencyEventActivityShareBind // 分享绑定
CurrencyEventActivityShareRank // 分享排行榜
CurrencyEventAll CurrencyEventAll
CurrencyEventGM = 1000 // 后台修改货币 CurrencyEventGM = 1000 // 后台修改货币

@ -53,6 +53,7 @@ func (a *ShareInfo) TableName() string {
type ShareDetail struct { type ShareDetail struct {
ID int `gorm:"primarykey"` ID int `gorm:"primarykey"`
Type int `gorm:"column:type;not null;default:0;type:int(11);"`
UID int `gorm:"column:uid;not null;type:int(11);"` UID int `gorm:"column:uid;not null;type:int(11);"`
Up int `gorm:"column:up;type:int(11);default:0;comment:上级"` Up int `gorm:"column:up;type:int(11);default:0;comment:上级"`
Reward int64 `gorm:"column:reward;type:bigint(20);default:0;comment:获取奖励"` Reward int64 `gorm:"column:reward;type:bigint(20);default:0;comment:获取奖励"`
@ -138,3 +139,29 @@ type ConfigShareRobot struct {
func (c *ConfigShareRobot) TableName() string { func (c *ConfigShareRobot) TableName() string {
return "config_share_robot" return "config_share_robot"
} }
type ConfigShareRankReward struct {
ID int `gorm:"primarykey"`
StartLevel int `gorm:"column:start_level;type:int(11);default:0;comment:开始等级" web:"start_level"`
EndLevel int `gorm:"column:end_level;type:int(11);default:0;comment:结束等级" web:"end_level"`
Reward int64 `gorm:"column:reward;type:bigint(20);default:0;comment:奖励金额" web:"reward"`
isOpen int `gorm:"column:is_open;type:int(11);default:0;comment:是否外放" web:"is_open"`
}
func (c *ConfigShareRankReward) TableName() string {
return "config_share_rank_reward"
}
type ConfigShareRankRule struct {
ID int `gorm:"primarykey"`
Day int `gorm:"column:day;type:int(11);default:0;comment:天数" web:"day"`
StartInterval int64 `gorm:"column:start_interval;type:bigint(20);default:0;comment:开始间隔" web:"start_interval"`
EndInterval int64 `gorm:"column:end_interval;type:bigint(20);default:0;comment:结束间隔" web:"end_interval"`
IncrNum int64 `gorm:"column:incr_num;type:bigint(20);default:0;comment:增长人数" web:"incr_num"`
StartIncrTimes int64 `gorm:"column:start_incr_times;type:bigint(20);default:0;comment:增长次数" web:"start_incr_times"`
EndIncrTimes int64 `gorm:"column:end_incr_times;type:bigint(20);default:0;comment:增长次数" web:"end_incr_times"`
}
func (c *ConfigShareRankRule) TableName() string {
return "config_share_rank_rule"
}

@ -130,6 +130,8 @@ func (r *RedisClient) HSet(key string, data ...interface{}) error {
return err return err
} }
return r.GetRedis().HSet(context.Background(), key, out).Err() return r.GetRedis().HSet(context.Background(), key, out).Err()
} else if tmp.Kind() == reflect.Map {
return r.GetRedis().HSet(context.Background(), key, data[0]).Err()
} }
return r.GetRedis().HSet(context.Background(), key, data).Err() return r.GetRedis().HSet(context.Background(), key, data).Err()
} }

@ -266,3 +266,14 @@ func OptPlayerDisconnect(c *gin.Context) {
} }
} }
func GMDelShareRank(c *gin.Context) {
a := app.NewApp(c)
defer func() {
a.Response()
}()
// 过期后判断占榜是否有问题
call.RiskControl()
// 发放奖励
call.SendReward()
}

@ -120,6 +120,8 @@ func MigrateDB() {
new(common.ConfigRtp), new(common.ConfigRtp),
new(common.PlayerRtpData), new(common.PlayerRtpData),
new(common.ShareDetail), new(common.ShareDetail),
new(common.ConfigShareRankRule),
new(common.ConfigShareRankReward),
) )
if err != nil { if err != nil {
panic("Migrate db fail") panic("Migrate db fail")

@ -23,7 +23,7 @@ func gmHandle(e *gin.Engine) {
e.POST("/gm/recharge", handler.GMRecharge) e.POST("/gm/recharge", handler.GMRecharge)
e.POST("/gm/bindPhone", handler.GMBindPhone) e.POST("/gm/bindPhone", handler.GMBindPhone)
e.POST("/gm/unbindPhone", handler.GMUnBindPhone) e.POST("/gm/unbindPhone", handler.GMUnBindPhone)
e.POST("/gm/deleteShareRank", handler.GMDelShareRank)
// 后台强制玩家掉线 // 后台强制玩家掉线
e.POST("/gm/player/OptPlayerDisconnect", handler.OptPlayerDisconnect) e.POST("/gm/player/OptPlayerDisconnect", handler.OptPlayerDisconnect)
} }

@ -166,6 +166,10 @@ func GetControlType(path string) int {
return common.ReloadConfigDiscountTicket return common.ReloadConfigDiscountTicket
case "configRtp": case "configRtp":
return common.ReloadConfigRTP return common.ReloadConfigRTP
case "configShareRankReward":
return common.ReloadConfigRankReward
case "configShareRankRule":
return common.ReloadConfigRankRule
default: default:
return 0 return 0
} }

@ -16,6 +16,7 @@ func (g *Gin) CheckActivityExpire(id int) (pass bool) {
pass = act.IsValid() pass = act.IsValid()
if !pass { if !pass {
g.Code = values.CodeActivityExpire g.Code = values.CodeActivityExpire
g.Msg = "The event has expired."
} }
return return
} }

@ -2205,9 +2205,21 @@ func InviteRankInfo(c *gin.Context) {
defer func() { defer func() {
a.Response() a.Response()
}() }()
if !a.CheckActivityExpire(common.ActivityIDBetDraw) { if !a.CheckActivityExpire(common.ActivityIDInviteRank) {
return return
} }
a.GetUID()
resp := new(values.InviteInfoResp) resp := new(values.InviteInfoResp)
a.Data = resp a.Data = resp
resp.ActivityConf = call.GetConfigActivityByID(common.ActivityIDInviteRank)
resp.RankInfoList = call.GetTopShareRank(call.RankNum)
for _, rankInfo := range resp.RankInfoList {
rankInfo.UserName = rankInfo.UserName[:7]
rankInfo.UserName = rankInfo.UserName[:4] + "***"
rankInfo.UserName = "User" + rankInfo.UserName
}
resp.RewardRankConfig = call.GetConfigRobotRankReward()
if a.UID > 0 {
resp.MyRank = call.GetUserRank(a.UID)
}
} }

@ -132,7 +132,7 @@ func ShareList(c *gin.Context) {
if err != nil { if err != nil {
log.Error("err:%v", err) log.Error("err:%v", err)
} }
err = db.Mysql().QueryBySql(fmt.Sprintf("SELECT UID, SUM(reward) AS total_reward, SUM(recharge_amount) AS total_recharge FROM share_detail WHERE up = %d and FROM_UNIXTIME(Time, '%%Y-%%m-%%d') = CURDATE() GROUP BY UID ORDER BY total_reward DESC limit %d,%d", a.UID, req.Page, req.Size), &ret) err = db.Mysql().QueryBySql(fmt.Sprintf("SELECT UID, SUM(reward) AS total_reward, SUM(recharge_amount) AS total_recharge FROM share_detail WHERE up = %d and FROM_UNIXTIME(Time, '%%Y-%%m-%%d') = CURDATE() GROUP BY UID ORDER BY total_reward DESC limit %d,%d", a.UID, req.Page*req.Size, req.Size), &ret)
if err != nil { if err != nil {
log.Error("err:%v", err) log.Error("err:%v", err)
} }
@ -147,7 +147,7 @@ func ShareList(c *gin.Context) {
if err != nil { if err != nil {
log.Error("err:%v", err) log.Error("err:%v", err)
} }
err = db.Mysql().QueryBySql(fmt.Sprintf("SELECT UID, SUM(reward) AS total_reward, SUM(recharge_amount) AS total_recharge FROM share_detail where up = %d GROUP BY UID ORDER BY total_reward DESC limit %d,%d", a.UID, req.Page, req.Size), &ret) err = db.Mysql().QueryBySql(fmt.Sprintf("SELECT UID, SUM(reward) AS total_reward, SUM(recharge_amount) AS total_recharge FROM share_detail where up = %d GROUP BY UID ORDER BY total_reward DESC limit %d,%d", a.UID, req.Page*req.Size, req.Size), &ret)
if err != nil { if err != nil {
log.Error("err:%v", err) log.Error("err:%v", err)
} }
@ -162,7 +162,7 @@ func ShareList(c *gin.Context) {
if err != nil { if err != nil {
log.Error("err:%v", err) log.Error("err:%v", err)
} }
err = db.Mysql().QueryBySql(fmt.Sprintf("SELECT UID, SUM(reward) AS total_reward, SUM(recharge_amount) AS total_recharge FROM share_detail where up = %d GROUP BY UID ORDER BY total_recharge DESC limit %d,%d", a.UID, req.Page, req.Size), &ret) err = db.Mysql().QueryBySql(fmt.Sprintf("SELECT UID, SUM(reward) AS total_reward, SUM(recharge_amount) AS total_recharge FROM share_detail where up = %d GROUP BY UID ORDER BY total_recharge DESC limit %d,%d", a.UID, req.Page*req.Size, req.Size), &ret)
if err != nil { if err != nil {
log.Error("err:%v", err) log.Error("err:%v", err)
} }

@ -58,6 +58,7 @@ var (
"/customer/image/download": {}, "/customer/image/download": {},
"/activity/firstRechargeBack/info": {}, "/activity/firstRechargeBack/info": {},
"/activity/weekCard/info": {}, "/activity/weekCard/info": {},
"/activity/inviteRank/info": {},
} }
) )

@ -1,13 +1,16 @@
package web package web
import ( import (
"context"
"fmt" "fmt"
"math/rand"
"server/call" "server/call"
"server/common" "server/common"
"server/config" "server/config"
"server/db" "server/db"
"server/modules/web/values" "server/modules/web/values"
"server/util" "server/util"
"strconv"
"time" "time"
"github.com/liangdas/mqant/log" "github.com/liangdas/mqant/log"
@ -15,7 +18,8 @@ import (
func FetchDatas() { func FetchDatas() {
GetShareData() GetShareData()
GetActivitySlotsRank() // GetActivitySlotsRank()
RobotRank()
} }
var ( var (
@ -73,3 +77,115 @@ func GetActivitySlotsRank() {
log.Debug("ActivitySlotsRank:%+v", v) 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)
}

@ -1,6 +1,9 @@
package values package values
import "server/common" import (
"server/call"
"server/common"
)
// GetPromotionsResp 促销中心 // GetPromotionsResp 促销中心
type GetPromotionsResp struct { type GetPromotionsResp struct {
@ -326,20 +329,9 @@ type DiscountTicketResp struct {
ChannelList []*common.ConfigPayChannels ChannelList []*common.ConfigPayChannels
} }
type RewardRankConfig struct {
RankMin int64
RankMax int64
Reward int64
}
type RankInfo struct {
Rank int `json:"Rank"`
Reward int `json:"Reward"`
UserName string `json:"UserName"`
}
type InviteInfoResp struct { type InviteInfoResp struct {
RewardRankConfig []RewardRankConfig RewardRankConfig []common.ConfigShareRankReward
RankInfoList []RankInfo RankInfoList []call.RankInfo
MyRank RankInfo MyRank call.RankInfo
ActivityConf *common.ConfigActivity
} }

Loading…
Cancel
Save