package call
import (
"fmt"
"reflect"
"server/common"
"server/db"
"server/pb"
"server/util"
"strings"
"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 = 1
db . Mysql ( ) . Create ( shareInfo )
}
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
// todo ?发送奖励?
//util.Go(func() {
// SendShareReward(cid, codeInfo.UID, codeInfo.ActivityId)
//})
} 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 更新上级邀请玩家数量?
CheckTask ( Task { Uid : upInfo . UID , Value : 1 , Types : [ ] common . TaskType { common . TaskTypeInvite } } )
// 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
}