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.
1016 lines
31 KiB
1016 lines
31 KiB
package call |
|
|
|
import ( |
|
"context" |
|
"fmt" |
|
"gorm.io/gorm/clause" |
|
"reflect" |
|
"server/common" |
|
"server/db" |
|
"server/pb" |
|
"server/util" |
|
"strings" |
|
"sync" |
|
"time" |
|
|
|
"github.com/liangdas/mqant/log" |
|
"gorm.io/gorm" |
|
) |
|
|
|
func GetShareInfo(uid int) *common.ShareInfo { |
|
shareInfo := &common.ShareInfo{UID: uid} |
|
db.Mysql().Get(shareInfo) |
|
if shareInfo.ID <= 0 { |
|
info, _ := GetUserXInfo(uid, "channel_id") |
|
shareInfo.ChannelID = info.ChannelID |
|
shareInfo.Share = util.GetShareCode(uid) |
|
shareInfo.CreateTime = time.Now().Unix() |
|
shareInfo.Level = 0 |
|
db.Mysql().Create(shareInfo) |
|
} |
|
shareInfo.UpList = []int{shareInfo.UP1, shareInfo.UP2, shareInfo.UP3, shareInfo.UP4, shareInfo.UP5} |
|
betAmountTeam := shareInfo.BetAmountTeam |
|
downCount := shareInfo.Down1 + shareInfo.Down2 + shareInfo.Down3 + shareInfo.Down4 + shareInfo.Down5 |
|
shareConfig := GetConfigShareAll() |
|
for _, v := range shareConfig { |
|
if betAmountTeam >= int64(v.BetExp) && |
|
downCount >= int64(v.InviteExp) { |
|
shareInfo.Level = v.Level |
|
} |
|
} |
|
return shareInfo |
|
} |
|
func GetShareInfoByCode(code string) *common.ShareInfo { |
|
shareInfo := &common.ShareInfo{Share: code} |
|
db.Mysql().Get(shareInfo) |
|
return shareInfo |
|
} |
|
|
|
func GetShareLink(cid, uid int) string { |
|
shareInfo := GetShareInfo(uid) |
|
channel := GetChannelByID(cid) |
|
if channel == nil { |
|
return "" |
|
} |
|
u := "" |
|
if strings.Contains(channel.ShareURL, "?") { |
|
u = channel.ShareURL + fmt.Sprintf("&shareCode=%s", shareInfo.Share) |
|
} else { |
|
u = channel.ShareURL + fmt.Sprintf("?shareCode=%s", shareInfo.Share) |
|
} |
|
if !strings.Contains(u, "app") { |
|
u += fmt.Sprintf("&app=%d", common.GetShareChannel(cid)) |
|
} |
|
return u |
|
} |
|
|
|
// 分享查询 |
|
func ShareBind(share string, isOld bool, uid, cid int) { |
|
// 分享码为空 |
|
if share == "" { |
|
return |
|
} |
|
// 获取上一级分享信息 |
|
upInfo := &common.ShareInfo{Share: share} |
|
db.Mysql().Get(upInfo) |
|
if upInfo.ID > 0 { |
|
upInfo.UID = upInfo.UID |
|
UpdateShare(upInfo.UID, 4, 0, fmt.Sprintf("%d", uid)) |
|
shareInfo := GetShareInfo(upInfo.UID) |
|
shareCfg := GetConfigShare(shareInfo.Level, 0) |
|
if shareCfg.BeInviteRebate > 0 { // 被邀请获得 |
|
UpdateCurrencyPro(&common.UpdateCurrency{ |
|
CurrencyBalance: &common.CurrencyBalance{ |
|
UID: uid, |
|
Value: shareCfg.BeInviteRebate, |
|
ChannelID: cid, |
|
Type: common.CurrencyINR, |
|
Event: common.CurrencyEventShareBeInvite, |
|
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, shareCfg.BeInviteRebate), |
|
}, |
|
}) |
|
} |
|
} else { |
|
// 一级 |
|
upInfo = &common.ShareInfo{Share: share} |
|
} |
|
if upInfo.ID <= 0 { |
|
return |
|
} |
|
if !isOld { // 新账号创建分享信息 |
|
shareInfo := &common.ShareInfo{UID: uid, UP1: upInfo.UID, UP2: upInfo.UP1, UP3: upInfo.UP2, UP4: upInfo.UP3, UP5: upInfo.UP4, CreateTime: time.Now().Unix(), ChannelID: cid, Share: util.GetShareCode(uid)} |
|
db.Mysql().Create(shareInfo) |
|
} else { // 已有账号直接走更新 |
|
err := db.Mysql().Update(&common.ShareInfo{UID: uid}, map[string]interface{}{ |
|
"up1": upInfo.UID, |
|
"up2": upInfo.UP1, |
|
"up3": upInfo.UP2, |
|
"up4": upInfo.UP3, |
|
"up5": upInfo.UP4, |
|
}) |
|
if err != nil { |
|
log.Error("ShareBind err:%v", err) |
|
} |
|
} |
|
// 更新上级的下级数 |
|
ref := reflect.ValueOf(upInfo).Elem() |
|
for i := 1; i <= 4; i++ { |
|
upUid := int(ref.FieldByName(fmt.Sprintf("UP%d", i)).Int()) |
|
if uid == 0 { |
|
break |
|
} |
|
field := fmt.Sprintf("down%d", i+1) |
|
db.Mysql().Update(&common.ShareInfo{UID: upUid}, map[string]interface{}{field: gorm.Expr(fmt.Sprintf("%s + 1", field))}) |
|
} |
|
|
|
// todo |
|
util.Go(func() { |
|
if upInfo.UID != 0 { |
|
// pdd摇奖次数 |
|
err := db.Mysql().C().Model(&common.PddDataNew{}).Where("uid = ?", upInfo.UID). |
|
Updates(map[string]interface{}{ |
|
"spin": gorm.Expr("spin + ?", 1), |
|
}).Error |
|
if err != nil { |
|
log.Error("update spin err, %s", err.Error()) |
|
return |
|
} |
|
// 裂变任务邀请人数 |
|
err = db.Mysql().C().Model(&common.ShareTaskNewData{}).Where("uid = ? and `type` = 2 and `status` = 0", upInfo.UID). |
|
Updates(map[string]interface{}{ |
|
"progress": gorm.Expr("progress + ?", 1), |
|
}).Error |
|
if err != nil { |
|
log.Error("update share invite task err, %s", err.Error()) |
|
return |
|
} |
|
} |
|
}) |
|
} |
|
|
|
//// 判断分享,发放有效用户奖励 |
|
//func CheckShare(r *common.RechargeOrder) { |
|
// shareInfo := GetShareInfo(r.UID) |
|
// // todo |
|
// if GetConfigShareSys() == nil { |
|
// return |
|
// } |
|
// reward := GetConfigShareSys().ShareReward |
|
// // 付费分享 |
|
// // CheckShareTask(shareInfo.UP1, 1, common.TaskTypePayShare) |
|
// // 发放奖励 |
|
// update := map[string]interface{}{ |
|
// "recharge_amount": gorm.Expr("recharge_amount + ?", r.Amount), |
|
// } |
|
// if shareInfo.BetAmount != -1 { |
|
// update["bet_amount"] = gorm.Expr("bet_amount + ?", r.Amount) |
|
// } |
|
// db.Mysql().Update(&common.ShareInfo{UID: r.UID}, update) |
|
// betAmount := shareInfo.BetAmount |
|
// if betAmount == -1 { |
|
// betAmount = 0 |
|
// } |
|
// if shareInfo.RechargeAmount+r.Amount < GetConfigShareSys().ShareRecharge { |
|
// return |
|
// } |
|
// if shareInfo.UP1 == 0 { |
|
// return |
|
// } |
|
// if shareInfo.BetAmount >= 0 { |
|
// db.Mysql().Update(&common.ShareInfo{UID: r.UID}, map[string]interface{}{ |
|
// "bet_amount": -1, |
|
// }) |
|
// update = map[string]interface{}{ |
|
// "invalid_invites": gorm.Expr("invalid_invites + 1"), |
|
// "invite_reward": gorm.Expr("invite_reward + ?", reward), |
|
// "available_reward": gorm.Expr("available_reward + ?", reward), |
|
// } |
|
// 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) |
|
// } |
|
//} |
|
|
|
func ShareRecharge(uid int, amount int64, typ int) { |
|
shareInfo := &common.ShareInfo{UID: uid} |
|
db.Mysql().Get(shareInfo) |
|
if shareInfo.UP1 == 0 { |
|
return |
|
} |
|
ref := reflect.ValueOf(shareInfo).Elem() |
|
// 循环查询上级 |
|
for i := 1; i <= 5; i++ { |
|
upUid := int(ref.FieldByName(fmt.Sprintf("UP%d", i)).Int()) |
|
if upUid == 0 { |
|
break |
|
} |
|
tmpShareInfo := GetShareInfo(upUid) |
|
con := GetConfigShareByLevel(tmpShareInfo.Level) |
|
if con == nil { |
|
log.Error("unknown config share level:%v", i) |
|
continue |
|
} |
|
var per int64 |
|
for _, v := range con.SubRewardTiers { |
|
if v.Tier == i { |
|
per = v.Per |
|
} |
|
} |
|
// 发奖 |
|
reward := amount * per / 1000 |
|
if reward <= 0 { |
|
continue |
|
} |
|
db.Mysql().Update(&common.ShareInfo{UID: upUid}, map[string]interface{}{ |
|
"withdrawable": gorm.Expr("withdrawable + ?", reward), |
|
}) |
|
if i == 1 { // 上一级的充值任务 |
|
err := db.Mysql().C().Model(&common.ShareTaskNewData{}).Where("uid = ? and `type` = ? and `status` = 0", |
|
upUid, common.ShareTaskNewTypeRecharge).Updates(map[string]interface{}{ |
|
"progress": gorm.Expr("progress + ?", amount), |
|
}).Error |
|
if err != nil { |
|
log.Error("update share recharge task err, %s", err.Error()) |
|
} |
|
} |
|
db.Mysql().Create(&common.ShareDetail{ |
|
UID: uid, |
|
Type: typ, |
|
Up: upUid, |
|
RechargeAmount: amount, |
|
Reward: reward, |
|
Time: time.Now().Unix(), |
|
}) |
|
} |
|
} |
|
|
|
// 投注奖励结算 |
|
func ShareSettle(d *pb.InnerAfterSettle) { |
|
//shareInfo := &common.ShareInfo{UID: int(d.UID)} |
|
//db.Mysql().Get(shareInfo) |
|
//if shareInfo.UP1 == 0 { |
|
// return |
|
//} |
|
//db.Mysql().Update(&common.ShareInfo{UID: int(d.UID)}, map[string]interface{}{"bet": gorm.Expr("bet + ?", d.TotalBet)}) |
|
// |
|
//ref := reflect.ValueOf(shareInfo).Elem() |
|
//// 循环查询上级 |
|
//for i := 1; i <= 3; i++ { |
|
// uid := int(ref.FieldByName(fmt.Sprintf("UP%d", i)).Int()) |
|
// if uid == 0 { |
|
// break |
|
// } |
|
// con := GetConfigShareByLevel(i) |
|
// if con == nil { |
|
// log.Error("unknown config share level:%v", i) |
|
// continue |
|
// } |
|
// // 发奖 |
|
// reward := d.TotalBet * con.Per / 1000 |
|
// if reward <= 0 { |
|
// continue |
|
// } |
|
// db.Mysql().Update(&common.ShareInfo{UID: uid}, map[string]interface{}{ |
|
// "bet_reward": gorm.Expr("bet_reward + ?", reward), |
|
// "available_reward": gorm.Expr("available_reward + ?", reward), |
|
// }) |
|
//} |
|
} |
|
|
|
func GetConfigShareByLevel(level int) (result *common.ConfigShare) { |
|
for _, v := range configShare { |
|
if v.Level == level { |
|
return v |
|
} |
|
} |
|
return |
|
} |
|
|
|
func PackLevelSql(uid, level int) (sql string) { |
|
if level == 0 { |
|
sql = fmt.Sprintf("up1 = %d or up2 = %d or up3 = %d", uid, uid, uid) |
|
} else { |
|
sql = fmt.Sprintf("up%d = %d", level, uid) |
|
} |
|
return |
|
} |
|
|
|
// GetUserShares 查询玩家下级数量 |
|
func GetUserShares(uid, level int) int64 { |
|
return db.Mysql().Count(&common.ShareInfo{}, PackLevelSql(uid, level)) |
|
} |
|
|
|
// GetUserShareRecharges 查询玩家下级充值人数 |
|
func GetUserShareRecharges(uid, level int) (count int64) { |
|
sql := fmt.Sprintf(`SELECT count(*) as count from |
|
(SELECT uid from share_info WHERE %s)a |
|
INNER JOIN |
|
(SELECT uid from recharge_info WHERE total_recharge > 0)b |
|
on a.uid = b.uid`, PackLevelSql(uid, level)) |
|
err := db.Mysql().C().Raw(sql).Scan(&count).Error |
|
if err != nil { |
|
log.Error("err:%v", err) |
|
} |
|
return |
|
} |
|
|
|
// GetUserShareValidRecharges 查询玩家下级有效充值人数 |
|
func GetUserShareValidRecharges(uid, level int) (count int64) { |
|
sql := fmt.Sprintf(`SELECT count(*) as count from |
|
(SELECT uid from share_info WHERE %s)a |
|
INNER JOIN |
|
(SELECT uid from recharge_info WHERE total_recharge >= %d)b |
|
on a.uid = b.uid`, PackLevelSql(uid, level), GetConfigShareSys().ShareRecharge) |
|
err := db.Mysql().C().Raw(sql).Scan(&count).Error |
|
if err != nil { |
|
log.Error("err:%v", err) |
|
} |
|
return |
|
} |
|
|
|
// GetUserShareRechargeAmount 查询玩家下级充值总额 |
|
func GetUserShareRechargeAmount(uid, level int) (count int64) { |
|
sql := fmt.Sprintf(`SELECT sum(b.total_recharge) as count from |
|
(SELECT uid from share_info WHERE %s)a |
|
INNER JOIN |
|
(SELECT uid,total_recharge from recharge_info WHERE total_recharge > 0)b |
|
on a.uid = b.uid`, PackLevelSql(uid, level)) |
|
err := db.Mysql().C().Raw(sql).Scan(&count).Error |
|
if err != nil { |
|
log.Error("err:%v", err) |
|
} |
|
return |
|
} |
|
|
|
// GetActivityShareCode 根据actid获取share code |
|
func GetActivityShareCode(uid, actId int) (code string, err error) { |
|
now := time.Now() |
|
ret := make([]*common.ShareActivityCode, 0, 1) |
|
_, err = db.Mysql().QueryList(0, 1, fmt.Sprintf("uid = %d and activity_id = %d ", uid, actId), "id", &common.ShareActivityCode{}, &ret) |
|
if err != nil { |
|
log.Error("GetActivityShareCode err:%v", err) |
|
return |
|
} |
|
expireTime := util.GetZeroTime(now.AddDate(0, 0, 1)) |
|
if len(ret) == 0 { |
|
code = util.GetShareCode(-uid - actId) |
|
err = db.Mysql().Create(&common.ShareActivityCode{ |
|
UID: uid, |
|
ShareCode: code, |
|
ActivityId: actId, |
|
ExpireAt: expireTime.Unix(), |
|
CreateAt: now.Unix(), |
|
}) |
|
if err != nil { |
|
log.Error("GetActivityShareCode err:%v", err) |
|
return |
|
} |
|
} else { |
|
code = ret[0].ShareCode |
|
_, err = db.Mysql().UpdateRes(&common.ShareActivityCode{UID: uid, ActivityId: actId}, map[string]interface{}{ |
|
"expire_at": expireTime.Unix(), |
|
}) |
|
if err != nil { |
|
log.Error("GetActivityShareCode err:%v", err) |
|
} |
|
} |
|
return |
|
} |
|
|
|
// SendShareReward 发送分享奖励 |
|
func SendShareReward(channel, uid, actId int) { |
|
log.Info("SendShareReward channel:%v,uid:%v,actId:%d", channel, uid, actId) |
|
if common.ActivityIDFreeSpin == actId { |
|
freespin := GetUserFreeSpinData(uid) |
|
now := time.Now().Unix() |
|
if freespin.LastSpin == 0 && freespin.SpinNum == 0 { |
|
// 未参与活动 |
|
p, _ := GetUserXInfo(uid, "birth") |
|
data := &common.ActivityFreeSpinData{UID: uid, SpinNum: common.DefaultFreeSpinNum} |
|
if util.IsSameDayTimeStamp(now, p.Birth) { |
|
data.LastSpin = now |
|
} |
|
err := db.Mysql().Create(data) |
|
if err != nil { |
|
log.Error("SendShareReward uid:%v,err:%v", uid, err) |
|
} |
|
} else { |
|
_, err := db.Mysql().UpdateRes(&common.ActivityFreeSpinData{UID: uid}, |
|
map[string]interface{}{"last_spin": now, "spin_num": gorm.Expr("spin_num + ?", 1)}) |
|
if err != nil { |
|
log.Error("SendShareReward uid:%v,err:%v", uid, err) |
|
} |
|
} |
|
} else if common.ActivityIDSign == actId { |
|
// 判断今日参与签到 |
|
// 如果参与就再发送奖励,同时发送邮件 |
|
list := GetConfigActivitySign() |
|
data := &common.ActivitySignData{UID: uid} |
|
db.Mysql().Get(data) |
|
first := util.GetZeroTime(time.Unix(data.Time, 0)).Unix() |
|
today := util.GetZeroTime(time.Now()).Unix() |
|
day := int((today-first)/common.OneDay) + 1 |
|
log.Info("SendShareReward day:%v", day) |
|
// 给前两天 |
|
if day > 2 { |
|
return |
|
} |
|
sign := data.Sign |
|
for i := 0; i < day; i++ { |
|
if sign&1 == 1 && day == i+1 { |
|
// 发放当日奖励 |
|
for _, v := range list { |
|
if v.Day == day { |
|
reward := v.Reward |
|
log.Info("SendShareReward reward:%v", reward) |
|
UpdateCurrencyPro(&common.UpdateCurrency{ |
|
CurrencyBalance: &common.CurrencyBalance{ |
|
UID: uid, |
|
Type: common.CurrencyINR, |
|
ChannelID: channel, |
|
Value: reward, |
|
Event: common.CurrencyEventActivitySign, |
|
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, reward), |
|
}, |
|
}) |
|
break |
|
} |
|
} |
|
break |
|
} |
|
sign >>= 1 |
|
} |
|
} |
|
} |
|
|
|
// WriteShareBalance 写入分享流水 |
|
func WriteShareBalance(b *common.ESShareBalance, shouldUpdate bool) { |
|
if b.Amount == 0 { |
|
return |
|
} |
|
now := time.Now() |
|
if (b.FriendNick == "" || b.Phone == "") && b.FriendUID > 0 { |
|
ret, _ := GetUserXInfo(b.FriendUID, "nick", "mobile") |
|
b.FriendNick = ret.Nick |
|
b.Phone = ret.Mobile |
|
} |
|
if b.RefererNick == "" { |
|
ret, _ := GetUserXInfo(b.RefererUID, "nick") |
|
b.RefererNick = ret.Nick |
|
} |
|
if b.Date == "" { |
|
b.Date = now.Format("20060102") |
|
} |
|
if b.Time == 0 { |
|
b.Time = now.Unix() |
|
} |
|
InsertToESGO(common.ESIndexShareBalance, b) |
|
|
|
if !shouldUpdate { |
|
return |
|
} |
|
|
|
// 先更新总收益 |
|
total := &common.ShareRewardData{} |
|
// totalSql := fmt.Sprintf("select * from share_reward_data where uid = %d and time = 0", b.RefererUID) |
|
db.Mysql().QueryBySql(fmt.Sprintf("select * from share_reward_data where uid = %d and time = 0", b.RefererUID), total) |
|
if total.ID == 0 { |
|
total = &common.ShareRewardData{} |
|
total.UID = b.RefererUID |
|
total.Date = "" |
|
total.Time = 0 |
|
total.SetReward(b.Event, b.Amount) |
|
db.Mysql().Create(total) |
|
} else { |
|
field := total.GetRewardName(b.Event) |
|
if field != "" { |
|
db.Mysql().UpdateW(&common.ShareRewardData{}, |
|
map[string]interface{}{ |
|
"total_reward": gorm.Expr("total_reward + ?", b.Amount), |
|
field: gorm.Expr(fmt.Sprintf("%s + %d", field, b.Amount))}, |
|
fmt.Sprintf("uid = %d and time = 0", b.RefererUID)) |
|
} |
|
} |
|
// 更新当天收益 |
|
t := util.GetZeroTime(now).Unix() |
|
today := &common.ShareRewardData{UID: b.RefererUID, Time: t} |
|
db.Mysql().Get(today) |
|
if today.ID == 0 { |
|
today = &common.ShareRewardData{UID: b.RefererUID, Time: t} |
|
today.Date = b.Date |
|
today.SetReward(b.Event, b.Amount) |
|
db.Mysql().Create(today) |
|
} else { |
|
field := today.GetRewardName(b.Event) |
|
if field != "" { |
|
db.Mysql().Update(&common.ShareRewardData{UID: b.RefererUID, Time: t}, |
|
map[string]interface{}{ |
|
"total_reward": gorm.Expr("total_reward + ?", b.Amount), |
|
field: gorm.Expr(fmt.Sprintf("%s + %d", field, b.Amount))}) |
|
} |
|
} |
|
|
|
// 更新分享者总奖励表 |
|
// one := &common.ShareTotalReward{RefererUID: b.RefererUID, FriendUID: b.FriendUID, Level: b.Level, Reward: b.Amount} |
|
// if !db.Mysql().Exist(one) { |
|
// one.Reward = b.Amount |
|
// db.Mysql().Create(one) |
|
// return |
|
// } |
|
// db.Mysql().Update(one, map[string]interface{}{"reward": gorm.Expr("reward + ?", b, b.Amount)}) |
|
// db.Mysql().UpsertMap(fmt.Sprintf("referer_uid = %v and friend_uid = %v", b.RefererUID, b.FriendUID), |
|
// one, map[string]interface{}{"reward": gorm.Expr("reward + ?", b.Amount)}) |
|
} |
|
|
|
// 计算排行榜 |
|
func CalShareRank(t int, ti int64) (list []*common.ShareRank) { |
|
data := []*OneRank{} |
|
switch t { |
|
case common.ShareRankTypeDaily: |
|
db.Mysql().QueryBySql(fmt.Sprintf("select uid as UID,total_reward as Reward from share_reward_data where time = %d ORDER BY Reward desc LIMIT %d", |
|
ti, common.ShareRankMaxNum), &data) |
|
case common.ShareRankTypeWeekly: |
|
db.Mysql().QueryBySql(fmt.Sprintf("select uid as UID,sum(total_reward) as Reward from share_reward_data where time>=%d and time<%d group by uid ORDER BY Reward desc LIMIT %d", |
|
ti, ti+7*common.OneDay, common.ShareRankMaxNum), &data) |
|
case common.ShareRankTypeMonthly: |
|
db.Mysql().QueryBySql(fmt.Sprintf("select uid as UID,sum(total_reward) as Reward from share_reward_data where time>=%d and time<%d group by uid ORDER BY Reward desc LIMIT %d", |
|
ti, util.GetLastDateOfMonth(time.Unix(ti, 0)).Unix()+common.OneDay, common.ShareRankMaxNum), &data) |
|
} |
|
for _, v := range data { |
|
one := &common.ShareRank{ |
|
UID: v.UID, |
|
Type: t, |
|
Time: ti, |
|
Level: GetShareInfo(v.UID).Level, |
|
Reward: v.Reward, |
|
} |
|
p, _ := GetUserXInfo(v.UID, "avatar", "nick") |
|
one.Avatar = p.Avatar |
|
one.Nick = p.Nick |
|
list = append(list, one) |
|
} |
|
return |
|
} |
|
|
|
func GetShareRank(t int, ti int64) (list []*common.ShareRank) { |
|
now := time.Now() |
|
switch t { |
|
case common.ShareRankTypeDaily: |
|
if util.GetZeroTime(now).Unix() == ti { // 查询今天 |
|
list = CalShareRank(t, ti) |
|
return |
|
} |
|
case common.ShareRankTypeWeekly: |
|
if util.GetWeekZeroTime(now).Unix() == ti { // 查询本周 |
|
list = CalShareRank(t, ti) |
|
return |
|
} |
|
case common.ShareRankTypeMonthly: |
|
if util.GetFirstDateOfMonth(now).Unix() == ti { // 查询本月 |
|
list = CalShareRank(t, ti) |
|
return |
|
} |
|
} |
|
db.Mysql().QueryList(0, common.ShareRankMaxNum, fmt.Sprintf("type = %d and time = %d", t, ti), "reward desc", &common.ShareRank{}, &list) |
|
return |
|
} |
|
|
|
type OneRank struct { |
|
UID int |
|
Reward int64 |
|
} |
|
|
|
func GetShareRewardData(uid, t int, ti int64) *common.ShareRank { |
|
data := &OneRank{} |
|
switch t { |
|
case common.ShareRankTypeDaily: |
|
db.Mysql().QueryBySql(fmt.Sprintf("select uid as UID,total_reward as Reward from share_reward_data where time = %d AND uid = %d", |
|
ti, uid), &data) |
|
case common.ShareRankTypeWeekly: |
|
db.Mysql().QueryBySql(fmt.Sprintf("select uid as UID,sum(total_reward) as Reward from share_reward_data where time>=%d and time<%d AND uid = %d", |
|
ti, ti+7*common.OneWeek, uid), data) |
|
case common.ShareRankTypeMonthly: |
|
db.Mysql().QueryBySql(fmt.Sprintf("select uid as UID,sum(total_reward) as Reward from share_reward_data where time>=%d and time<%d AND uid = %d", |
|
ti, util.GetLastDateOfMonth(time.Unix(ti, 0)).Unix()+common.OneDay, uid), &data) |
|
} |
|
|
|
one := &common.ShareRank{ |
|
UID: uid, |
|
Type: t, |
|
Time: ti, |
|
Level: GetShareInfo(uid).Level, |
|
Reward: data.Reward, |
|
} |
|
p, _ := GetUserXInfo(uid, "avatar", "nick") |
|
one.Avatar = p.Avatar |
|
one.Nick = p.Nick |
|
return one |
|
} |
|
|
|
func GetShareWithdrawHis(uid, page, num int) (list []*common.RechargeOrder, count int64) { |
|
count, _ = db.Mysql().QueryListW(page, num, "created_at desc", |
|
&common.RechargeOrder{UID: uid}, &list, "uid = ? and (event = ? or event = ?) and scene = ?", |
|
uid, common.CurrencyEventWithDraw, common.CurrencyEventShareWithdraw, common.ActivityIDShare) |
|
return |
|
} |
|
|
|
func ShareRankUserGet(page, pageSize int, rankAt time.Time, withCount bool) (rankUsers []common.ShareRankDataWithUser, count int64, err error) { |
|
if withCount { |
|
countQuery := db.Mysql().C(). |
|
Model(&common.ShareRankData{}). |
|
Where("rank_cycle = ? and rank_at = ?", |
|
2, rankAt.Unix()) |
|
err = countQuery.Count(&count).Error |
|
if err != nil { |
|
log.Error("get rank user count err, %s", err.Error()) |
|
return |
|
} |
|
} |
|
err = db.Mysql().C().Table("share_rank_data as srd"). |
|
Select("srd.*, u.*"). |
|
Joins("left join users as u on srd.uid = u.id"). |
|
Where("srd.rank_cycle = ? and srd.rank_at = ?", 2, rankAt.Unix()). |
|
Order("srd.rank_value desc, srd.updated_at").Offset((page - 1) * pageSize).Limit(pageSize). |
|
Find(&rankUsers).Error |
|
if err != nil { |
|
log.Error("get rank user err, %s", err.Error()) |
|
return |
|
} |
|
return |
|
} |
|
|
|
var once sync.Once |
|
|
|
func ShareRankHandler() { |
|
once.Do(func() { |
|
util.Go(func() { |
|
for { |
|
now := time.Now() |
|
nextSettleAt := util.GetWeekZeroTime(now).AddDate(0, 0, 7).Add(30 * time.Minute) |
|
|
|
if now.After(nextSettleAt) { |
|
nextSettleAt = nextSettleAt.AddDate(0, 0, 7) |
|
} |
|
timer := time.NewTimer(nextSettleAt.Sub(now)) |
|
<-timer.C |
|
|
|
shareRankAward() |
|
} |
|
}) |
|
}) |
|
} |
|
|
|
func shareRankAward() { |
|
now := time.Now() |
|
jackpot := ShareRankJackpotPreGet() |
|
lessJackpot := jackpot |
|
lastRankAt := util.GetWeekZeroTime(now).AddDate(0, 0, -7) |
|
shareRankAwards := GetConfigShareRankAwardMap() |
|
if shareRankAwards == nil { |
|
log.Error("share rank award is nil") |
|
return |
|
} |
|
var rankUsers []*common.ShareRankData |
|
err := db.Mysql().C().Model(&common.ShareRankData{}).Where("rank_at = ?", lastRankAt.Unix()).Order("rank_value desc, updated_at").Find(&rankUsers).Error |
|
if err != nil { |
|
log.Error("get share rank user err, %s", err.Error()) |
|
return |
|
} |
|
for index, rankUser := range rankUsers { |
|
var ( |
|
rank = index + 1 |
|
userAward int |
|
userAwardCount int64 |
|
) |
|
award, ok := shareRankAwards[rank] |
|
if ok { |
|
userAward = award.AwardRate |
|
userAwardCount = jackpot * int64(userAward) / 10000 |
|
lessJackpot -= userAwardCount |
|
} |
|
if lessJackpot <= 0 { |
|
userAwardCount = 0 |
|
} |
|
updateValues := map[string]interface{}{ |
|
"user_award": userAward, |
|
"user_award_count": userAwardCount, |
|
"rank": rank, |
|
"updated_at": now.Unix(), |
|
} |
|
err = db.Mysql().C().Model(&common.ShareRankData{}).Where("id = ?", rankUser.ID).Updates(updateValues).Error |
|
if err != nil { |
|
log.Error("update share rank data err, %d:%+v %s", rankUser.ID, updateValues, err.Error()) |
|
continue |
|
} |
|
if userAwardCount == 0 { |
|
continue |
|
} |
|
_, err = UpdateCurrencyPro(&common.UpdateCurrency{ |
|
CurrencyBalance: &common.CurrencyBalance{ |
|
UID: rankUser.UID, |
|
Type: common.CurrencyINR, |
|
Value: userAwardCount, |
|
Event: common.CurrencyEventShareRankAward, |
|
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, userAwardCount), |
|
}, |
|
}) |
|
if err != nil { |
|
log.Error("share rank award err, %s", err.Error()) |
|
} |
|
|
|
mail := common.Mail{ |
|
DraftID: "", |
|
Sender: "system", |
|
Receiver: rankUser.UID, |
|
Type: 1, |
|
Title: fmt.Sprintf("EARN RANKING(%s)", lastRankAt.Format("20060102")), |
|
Content: fmt.Sprintf("Well done! You ranked %dth on the invitation leaderboard and won a reward. Go claim it now!", rank), |
|
SendMethod: 1, |
|
Status: common.MailStatusNew, |
|
Time: now.Unix(), |
|
} |
|
err = db.Mysql().C().Model(&common.Mail{}).Create(&mail).Error |
|
if err != nil { |
|
log.Error("create mail err, %s, %+v", err.Error(), mail) |
|
} |
|
} |
|
preJackpotLessKey := getShareRankJackpotPreKey() + "|less" |
|
log.Debug("shareRankAward, %s, %d, less jackpot:%d", preJackpotLessKey, jackpot, lessJackpot) |
|
err = db.Redis().GetRedis().Set(context.Background(), preJackpotLessKey, lessJackpot, time.Hour*24*7*2).Err() |
|
if err != nil { |
|
log.Error("share rankAward, %s set less-jackpot err, %s", preJackpotLessKey, err.Error()) |
|
} |
|
if jackpot > 0 { |
|
_, _, _, jackpotKey := getShareRankJackpotKey() |
|
_, err = db.Redis().Incr(jackpotKey, lessJackpot) |
|
if err != nil { |
|
log.Error("incr less jackpot err, %s, %s:%d", err.Error(), jackpotKey, lessJackpot) |
|
} |
|
} |
|
} |
|
|
|
// updateType(1:下注,2:充值,3:任务,4:邀请人) |
|
func updateShareByUp(uid, upUid, uplevel, updateType int, updateValue int64, expand ...string) { |
|
shareInfo := GetShareInfo(upUid) |
|
shareCfgMap := GetConfigShareMap() |
|
shareCfg := shareCfgMap[shareInfo.Level] |
|
rewardTier, ok := shareCfg.SubRewardTiersMap[uplevel] |
|
now := time.Now() |
|
var awardCount int64 |
|
if !ok || rewardTier.Per == 0 { |
|
return |
|
} |
|
var shareReward *common.ShareReward |
|
updateValues := make(map[string]interface{}) |
|
switch updateType { |
|
case 1: // 下注返利 |
|
var winCount int64 |
|
if len(expand) > 0 { |
|
winCount = util.ToInt64(expand[0]) |
|
} |
|
if winCount < 0 { |
|
rewardCount := -winCount * rewardTier.Per / 100 |
|
shareReward = &common.ShareReward{ |
|
UID: upUid, |
|
UpLevel: uplevel, |
|
RewardType: updateType, |
|
RewardCount: rewardCount, |
|
RewardDesc: fmt.Sprintf("%d", uid), |
|
RewardAt: now.Unix(), |
|
} |
|
awardCount = rewardCount |
|
updateValues["reward"] = gorm.Expr("reward + ?", rewardCount) |
|
updateValues["withdrawable"] = gorm.Expr("withdrawable + ?", rewardCount) |
|
} |
|
|
|
betAmount := updateValue * rewardTier.Per / 100 |
|
updateValues["bet_amount_team"] = gorm.Expr("bet_amount_team + ?", betAmount) |
|
case 2: // 充值返利 |
|
rewardCount := updateValue * rewardTier.Per / 100 |
|
shareReward = &common.ShareReward{ |
|
UID: upUid, |
|
UpLevel: uplevel, |
|
RewardType: updateType, |
|
RewardCount: rewardCount, |
|
RewardDesc: fmt.Sprintf("%d", uid), |
|
RewardAt: now.Unix(), |
|
} |
|
awardCount = rewardCount |
|
updateValues["reward"] = gorm.Expr("reward + ?", rewardCount) |
|
updateValues["withdrawable"] = gorm.Expr("withdrawable + ?", rewardCount) |
|
} |
|
if shareReward != nil { |
|
err := db.Mysql().C().Create(&shareReward).Error |
|
if err != nil { |
|
log.Error("create up share reward err, %s", err.Error()) |
|
} |
|
} |
|
if len(updateValues) > 0 { |
|
err := db.Mysql().C().Model(&common.ShareInfo{}).Where("uid = ?", upUid).Updates(updateValues).Error |
|
if err != nil { |
|
log.Error("update up share info err, %s", err.Error()) |
|
} |
|
if _, ok = updateValues["reward"]; ok { // 更新排行榜 |
|
shareRankData := common.ShareRankData{ |
|
UID: shareInfo.UID, |
|
RankCycle: 2, |
|
RankAt: util.GetWeekZeroTime(now).Unix(), |
|
RankValue: awardCount, |
|
UpdatedAt: now.Unix(), |
|
} |
|
err = db.Mysql().C().Model(&common.ShareRankData{}).Clauses(clause.OnConflict{ |
|
Columns: []clause.Column{{Name: "rank_cycle"}, {Name: "rank_at"}, {Name: "uid"}}, |
|
DoUpdates: clause.Assignments(map[string]interface{}{ |
|
"rank_value": gorm.Expr("rank_value + ?", shareRankData.RankValue), |
|
"updated_at": shareRankData.UpdatedAt, |
|
}), |
|
}).Create(&shareRankData).Error |
|
if err != nil { |
|
log.Error("update up share rank data err, %s", err.Error()) |
|
} |
|
} |
|
} |
|
} |
|
|
|
// updateType(1:下注,2:充值,3:任务,4:邀请人,5:提现, 6:回滚) |
|
func UpdateShare(uid, updateType int, updateValue int64, expand ...string) (err error) { |
|
if updateType == 1 { // 直接更新下注奖池 |
|
_, _, expired, rankKey := getShareRankJackpotKey() |
|
_, err = db.Redis().Incr(rankKey, updateValue/100) |
|
if err != nil { |
|
log.Error("update rank jackpot err, %s:%s", rankKey, err.Error()) |
|
} |
|
db.Redis().Expire(rankKey, time.Duration(expired)*time.Second) |
|
if len(expand) > 0 && expand[0] == "isRobot" { |
|
return |
|
} |
|
} |
|
now := time.Now() |
|
shareInfo := GetShareInfo(uid) |
|
var shareReward *common.ShareReward |
|
updateValues := make(map[string]interface{}) |
|
var awardCount int64 |
|
var updateUp bool |
|
switch updateType { |
|
case 1: |
|
updateValues["bet_amount"] = gorm.Expr("bet_amount + ?", updateValue) |
|
updateValues["bet_amount_team"] = gorm.Expr("bet_amount_team + ?", updateValue) |
|
updateUp = true |
|
case 2: |
|
updateUp = true |
|
case 3: |
|
desc := expand[0] |
|
shareReward = &common.ShareReward{ |
|
UID: uid, |
|
RewardType: updateType, |
|
RewardCount: updateValue, |
|
RewardDesc: desc, |
|
RewardAt: now.Unix(), |
|
} |
|
awardCount = updateValue |
|
updateValues["reward"] = gorm.Expr("reward + ?", updateValue) |
|
updateValues["withdrawable"] = gorm.Expr("withdrawable + ?", updateValue) |
|
case 4: |
|
configMap := GetConfigShareMap() |
|
if config, ok := configMap[shareInfo.Level]; ok { |
|
amount := config.InviteRebate |
|
var desc string |
|
if len(expand) > 0 { |
|
desc = expand[0] |
|
} |
|
shareReward = &common.ShareReward{ |
|
UID: uid, |
|
RewardType: updateType, |
|
RewardCount: amount, |
|
RewardDesc: desc, |
|
RewardAt: now.Unix(), |
|
} |
|
awardCount = updateValue |
|
updateValues["reward"] = gorm.Expr("reward + ?", amount) |
|
updateValues["withdrawable"] = gorm.Expr("withdrawable + ?", amount) |
|
} |
|
case 5: |
|
desc := expand[0] |
|
shareReward = &common.ShareReward{ |
|
UID: uid, |
|
RewardType: updateType, |
|
RewardCount: -updateValue, |
|
RewardDesc: desc, |
|
RewardAt: now.Unix(), |
|
} |
|
updateValues["withdrawable"] = gorm.Expr("withdrawable - ?", updateValue) |
|
case 6: |
|
desc := expand[0] |
|
shareReward = &common.ShareReward{ |
|
UID: uid, |
|
RewardType: updateType, |
|
RewardCount: updateValue, |
|
RewardDesc: desc, |
|
RewardAt: now.Unix(), |
|
} |
|
updateValues["withdrawable"] = gorm.Expr("withdrawable + ?", updateValue) |
|
} |
|
if len(updateValues) > 0 { |
|
err = db.Mysql().C().Model(&common.ShareInfo{}). |
|
Where("id = ?", shareInfo.ID). |
|
Updates(updateValues).Error |
|
if err != nil { |
|
log.Error("update share err, %s", err.Error()) |
|
return |
|
} |
|
if _, ok := updateValues["reward"]; ok { // 更新排行榜 |
|
shareRankData := common.ShareRankData{ |
|
UID: shareInfo.UID, |
|
RankCycle: 2, |
|
RankAt: util.GetWeekZeroTime(now).Unix(), |
|
RankValue: awardCount, |
|
UpdatedAt: now.Unix(), |
|
} |
|
err = db.Mysql().C().Model(&common.ShareRankData{}).Clauses(clause.OnConflict{ |
|
Columns: []clause.Column{{Name: "rank_cycle"}, {Name: "rank_at"}, {Name: "uid"}}, |
|
DoUpdates: clause.Assignments(map[string]interface{}{ |
|
"rank_value": gorm.Expr("rank_value + ?", shareRankData.RankValue), |
|
"updated_at": shareRankData.UpdatedAt, |
|
}), |
|
}).Create(&shareRankData).Error |
|
if err != nil { |
|
log.Error("update share rank data err, %s", err.Error()) |
|
return |
|
} |
|
} |
|
} |
|
if shareReward != nil { |
|
err = db.Mysql().C().Create(&shareReward).Error |
|
if err != nil { |
|
log.Error("create share reward err, %s", err.Error()) |
|
return |
|
} |
|
} |
|
if updateUp { |
|
for index, upUid := range shareInfo.UpList { |
|
if upUid == 0 { |
|
continue |
|
} |
|
updateShareByUp(uid, upUid, index+1, updateType, updateValue, expand...) |
|
} |
|
} |
|
return |
|
} |
|
|
|
func getShareRankJackpotKey() (rankAt, awardAt time.Time, expired int64, key string) { |
|
now := time.Now() |
|
rankCycle := 2 |
|
key = fmt.Sprintf("share_rank_jackpot|%d", rankCycle) |
|
switch rankCycle { |
|
case 1: |
|
rankAt = util.GetZeroTime(now) |
|
awardAt = rankAt.AddDate(0, 0, 1) |
|
expired = int64(rankAt.AddDate(0, 0, 2).Sub(now).Seconds()) |
|
case 2: |
|
rankAt = util.GetWeekZeroTime(now) |
|
awardAt = rankAt.AddDate(0, 0, 7) |
|
expired = int64(rankAt.AddDate(0, 0, 14).Sub(now).Seconds()) |
|
case 3: |
|
rankAt = util.GetFirstDateOfMonth(now) |
|
awardAt = rankAt.AddDate(0, 1, 0) |
|
expired = int64(rankAt.AddDate(0, 2, 0).Sub(now).Seconds()) |
|
} |
|
key += fmt.Sprintf("|%s", rankAt.Format("20060102")) |
|
return |
|
} |
|
|
|
func getShareRankJackpotPreKey() (key string) { |
|
now := time.Now() |
|
var rankAt time.Time |
|
rankCycle := 2 |
|
key = fmt.Sprintf("share_rank_jackpot|%d", rankCycle) |
|
switch rankCycle { |
|
case 1: |
|
rankAt = util.GetZeroTime(now).AddDate(0, 0, -1) |
|
case 2: |
|
rankAt = util.GetWeekZeroTime(now).AddDate(0, 0, -7) |
|
case 3: |
|
rankAt = util.GetFirstDateOfMonth(now).AddDate(0, -1, 0) |
|
} |
|
key += fmt.Sprintf("|%s", rankAt.Format("20060102")) |
|
return |
|
} |
|
|
|
func ShareRankJackpotGet() (jackpot, rankLess int64) { |
|
_, awardAt, _, rankKey := getShareRankJackpotKey() |
|
jackpot = db.Redis().GetInt64(rankKey) |
|
rankLess = int64(awardAt.Sub(time.Now()).Seconds()) |
|
return |
|
} |
|
|
|
func ShareRankJackpotPreGet() (jackpot int64) { |
|
jackpot = db.Redis().GetInt64(getShareRankJackpotPreKey()) |
|
return |
|
} |
|
|
|
func ShareRankJackpotPreLessGet() (jackpot int64) { |
|
jackpot = db.Redis().GetInt64(getShareRankJackpotPreKey() + "|less") |
|
return |
|
}
|
|
|