package call
import (
"context"
"encoding/json"
"errors"
"fmt"
jsoniter "github.com/json-iterator/go"
"gorm.io/gorm/clause"
"io/ioutil"
"math/rand"
"net/http"
"server/common"
"server/config"
"server/db"
"server/natsClient"
"server/pb"
"server/util"
"sort"
"time"
"github.com/gogo/protobuf/proto"
"github.com/liangdas/mqant/log"
mqrpc "github.com/liangdas/mqant/rpc"
"gorm.io/gorm"
)
func GetRechargeInfo ( uid int ) * common . RechargeInfo {
info := & common . RechargeInfo { UID : uid }
db . Mysql ( ) . Get ( info )
if info . ID == 0 {
db . Mysql ( ) . Create ( info )
}
now := time . Now ( ) . Unix ( )
if ! util . IsSameDayTimeStamp ( now , info . LastRecharge ) {
info . DayRecharge = 0
}
if ! util . IsSameDayTimeStamp ( time . Now ( ) . Unix ( ) , info . LastWithdraw ) {
info . WithdrawCount = 0
}
if info . BuyAmountData != "" {
jsoniter . UnmarshalFromString ( info . BuyAmountData , & info . BuyAmountDataMap )
}
if info . BuyAmountDataMap == nil {
info . BuyAmountDataMap = make ( map [ string ] int )
}
return info
}
// Recharge 内部充值调用
func Recharge ( data * pb . InnerRechargeReq ) ( * pb . InnerRechargeResp , error ) {
to , cancel := context . WithTimeout ( context . Background ( ) , 10 * time . Second )
defer cancel ( )
module := "pay"
if data . PaySource == common . PaySourceBlockPay {
module = "blockpay"
}
data . Amount = data . Amount / common . DecimalDigits
ret , err := GetCaller ( ) . GetApp ( ) . Call ( to , module , "recharge" , mqrpc . Param ( data ) )
if err != "" {
return nil , errors . New ( err )
}
retData := new ( pb . InnerRechargeResp )
if err := proto . Unmarshal ( ret . ( [ ] byte ) , retData ) ; err != nil {
log . Error ( "err:%v" , err )
return nil , err
}
return retData , nil
}
// Withdraw 内部退出调用
func Withdraw ( data * pb . InnerWithdrawReq ) ( * pb . InnerWithdrawResp , error ) {
log . Debug ( "withdraw req:%+v" , * data )
to , cancel := context . WithTimeout ( context . Background ( ) , 5 * time . Second )
defer cancel ( )
module := "pay"
if data . PaySource == common . PaySourceBlockPay {
module = "blockpay"
}
ret , err := GetCaller ( ) . GetApp ( ) . Call ( to , module , "withdraw" , mqrpc . Param ( data ) )
retData := new ( pb . InnerWithdrawResp )
if data , ok := ret . ( [ ] byte ) ; ok {
if err := proto . Unmarshal ( data , retData ) ; err != nil {
log . Error ( "err:%v" , err )
}
}
if err != "" {
return retData , errors . New ( err )
}
return retData , nil
}
// CheckUserBet 检测玩家余额
func CheckUserBet ( uid int , t common . CurrencyType ) {
cash := GetUserCurrency ( uid , t )
if cash < GetConfigPlatform ( ) . MiniAmount {
_ , err := db . Mysql ( ) . UpdateRes ( & common . PlayerProfile { UID : uid } , map [ string ] interface { } { "need_bet" : 0 } )
if err != nil {
log . Error ( "err:%v" , err )
}
}
}
// RechargeCallback 充值回调
func RechargeCallback ( r * common . RechargeOrder , success bool , payAccount , extra string ) ( err error ) {
log . Info ( "RechargeCallback:%+v,%v,%v,%v," , r , success , payAccount , extra )
if r == nil {
return errors . New ( "order invalid" )
}
if ! success {
ro := & common . RechargeOrder { OrderID : r . OrderID , Status : common . StatusROrderCreate }
return db . Mysql ( ) . Update ( ro , & common . RechargeOrder { Status : common . StatusROrderFail } )
}
uid := r . UID
re := GetRechargeInfo ( uid )
CheckUserBet ( uid , r . CurrencyType )
amount := r . Amount
notCharge := re . TotalRecharge == 0
topThree := r . Times > 0
re . TotalRecharge += amount
now := time . Now ( ) . Unix ( )
// var dayR, weekR bool
var dayR bool
if util . IsSameDayTimeStamp ( re . LastRecharge , now ) || re . LastRecharge == 0 {
dayR = true
re . DayRecharge += amount
}
re . LastRecharge = now
re . TotalRechargeCount ++
tx := db . Mysql ( ) . Begin ( )
defer func ( ) {
if err == nil {
if err := tx . Commit ( ) . Error ; err != nil {
tx . Rollback ( )
return
}
} else {
log . Error ( "err:%v" , err )
tx . Rollback ( )
return
}
} ( )
// 第一步,更新订单状态
updates := common . RechargeOrder { Status : common . StatusROrderPay , APIPayID : r . APIPayID , PayAccount : payAccount , Extra : extra , CallbackTime : now }
dbtx := tx . Table ( "recharge_order" ) . Where ( fmt . Sprintf ( "orderid = '%v' and status <> %v" , r . OrderID , common . StatusROrderPay ) ) . Updates ( updates )
if dbtx . Error != nil {
return fmt . Errorf ( "update order err:%v" , dbtx . Error )
}
// 已处理的单不返回错误了
if dbtx . RowsAffected == 0 {
return nil
}
// 第二步,更新recharge_info
payData := & common . ESPlayerPayData { UID : uid , Channel : r . ChannelID , Type : 1 , CurrencyType : r . CurrencyType }
if topThree {
re . BuyAmountDataMap [ fmt . Sprintf ( "%d" , r . Amount ) ] ++
}
amountCountByte , _ := json . Marshal ( re . BuyAmountDataMap )
amountCountData := string ( amountCountByte )
if re . ID == 0 {
if topThree {
re . BuyAmountData = amountCountData
}
err = tx . Model ( re ) . Create ( re ) . Error
if err != nil {
// 说明数据库出问题或者两单并发回调,一分钟后重试
time . AfterFunc ( 1 * time . Minute , func ( ) {
RechargeCallback ( r , success , payAccount , extra )
} )
log . Error ( "err:%v" , err )
return
}
payData . FirstAmount = amount
} else {
updates := map [ string ] interface { } {
"total_recharge_count" : gorm . Expr ( "total_recharge_count + 1" ) ,
"total_recharge" : gorm . Expr ( "total_recharge + ?" , amount ) ,
"last_recharge" : now ,
"first_recharge" : gorm . Expr ( "CASE WHEN first_recharge = 0 THEN ? ELSE first_recharge END" , now ) ,
}
if r . Times > 0 {
updates [ "buy_amount_data" ] = amountCountData
}
if dayR {
updates [ "day_recharge" ] = gorm . Expr ( "day_recharge + ?" , amount )
} else {
updates [ "day_recharge" ] = amount
}
err = tx . Model ( re ) . Where ( "uid=?" , re . UID ) . Updates ( updates ) . Error
}
if err != nil {
log . Error ( "recharge err:%v" , err )
return err
}
// 第三步,给玩家发货
// 正常商城充值
var bonus = r . Bonus
discountOriginAmount := r . Amount // 折扣前的价格
if r . ProductID != 0 {
amount := PayExtra ( r ) // 判断特殊购买,如优惠券
if amount == 0 {
amount = r . Amount
} else {
discountOriginAmount = amount
}
t := common . CurrencyResourceRecharge
if bonus > 0 {
if topThree {
switch r . Times {
case 1 :
t = common . CurrencyResourceFirstRecharge
case 2 :
t = common . CurrencyResourceSecondRecharge
case 3 :
t = common . CurrencyResourceThirdRecharge
}
} else {
t = common . CurrencyResourceRechargeWithBonus
}
}
var needBet int64
if r . ActivityID != 0 {
needBet = GetConfigCurrencyResourceNeedBetByActId ( r . ActivityID , amount )
}
if needBet == 0 {
needBet = GetConfigCurrencyResourceNeedBet ( t , amount + bonus )
}
cb := & common . CurrencyBalance {
UID : r . UID ,
Type : r . CurrencyType ,
Value : amount + bonus ,
Event : common . CurrencyEvent ( r . Event ) ,
Exs1 : r . OrderID ,
Exi1 : int ( amount ) , // 充值金额传递
Exi2 : r . ProductID ,
NeedBet : needBet ,
}
err = UpdateCurrencyProReal ( & common . UpdateCurrency {
CurrencyBalance : cb ,
} ) . Err
if err != nil {
return
}
}
// 以上逻辑为处理订单,更新玩家充值信息,给玩家加钱。
// 下面逻辑处理活动,数据统计等,不影响以上效率,接下来逻辑并发执行
util . Go ( func ( ) {
SendNR ( r . UID , int ( pb . ServerCommonResp_CommonUserInfoResp ) , & pb . PlayerBalanceResp { } , "common" )
// 更新活动数据上传
if bonus > 0 {
UploadActivityData ( uid , common . ActivityIDRecharge , common . ActivityDataJoin , bonus )
}
if r . ProductID == 0 {
ticket := GetConfigDiscountTicketByAmount ( discountOriginAmount )
log . Info ( "ticket:%v" , ticket )
if ticket . ID > 0 {
// 赠送优惠券
tickets := GetConfigDiscountTicket ( )
sort . Slice ( tickets , func ( i , j int ) bool {
return tickets [ i ] . RechargeAmount < tickets [ j ] . RechargeAmount
} )
// 获取下一档
nextIdx := - 1
for idx , product := range tickets {
if product . RechargeAmount == discountOriginAmount {
nextIdx = idx + 1
}
}
var nextTicket = ticket
if len ( tickets ) > nextIdx && nextIdx != - 1 {
nextTicket = tickets [ nextIdx ]
}
log . Info ( "nextTicket:%v" , nextTicket )
count := ticket . CurProb + ticket . NextProb
if count > 0 {
val := rand . Intn ( count )
log . Info ( "val:%v" , val )
if val < ticket . CurProb {
AddUserDiscountTicket ( uid , ticket . DiscountAmount , ticket . RechargeAmount , - 1 , 0 , true )
SendMailWithContent ( uid , SystemTitle , fmt . Sprintf ( EmailDiscount , ticket . DiscountAmount / common . DecimalDigits , ticket . RechargeAmount / common . DecimalDigits ) )
} else if nextTicket . ID > 0 {
AddUserDiscountTicket ( uid , nextTicket . DiscountAmount , nextTicket . RechargeAmount , - 1 , 1 , true )
SendMailWithContent ( uid , SystemTitle , fmt . Sprintf ( EmailDiscount , nextTicket . DiscountAmount / common . DecimalDigits , nextTicket . RechargeAmount / common . DecimalDigits ) )
}
}
}
}
user , _ := GetUserInfo ( uid )
PayActivity ( r , notCharge , user )
if r . Event != int ( common . CurrencyEventGMRecharge ) {
payData . Amount = amount
WritePlayerPayData ( payData )
}
var uploads [ ] func ( )
uploads = append ( uploads , func ( ) { UploadAdjust ( common . AdjustEventAllPay , user , nil ) } )
// 24小时内注册的用户所有付费事件上报
if now - user . Birth <= 24 * 60 * 60 {
uploads = append ( uploads , func ( ) {
UploadAdjust ( common . AdjustEventNewPay , user , map [ string ] string { "revenue" : util . RoundFloat ( float64 ( amount ) / 100 , 2 ) , "currency" : "INR" } )
} )
// 上报fb
UploadFB ( uid , FBEventPurchase , amount / common . DecimalDigits )
UploadKwai ( uid , KwaiEventPay , amount )
}
for _ , f := range uploads {
f ( )
}
} )
return nil
}
func WithdrawCallback ( order * common . WithdrawOrder ) error {
uid := order . UID
amount := order . Amount
var err error
// 不成功退款
if order . Status == common . StatusROrderFail {
err = ReturnBackWithdraw ( order , common . StatusROrderFinish , common . StatusROrderFail )
} else {
tx := db . Mysql ( ) . Begin ( )
or := new ( common . WithdrawOrder )
or . ID = order . ID
or . Status = uint8 ( common . StatusROrderFinish )
or . CallbackTime = time . Now ( ) . Unix ( )
or . APIPayID = order . APIPayID
or . FailReason = order . FailReason
if len ( or . FailReason ) > 200 {
or . FailReason = or . FailReason [ : 200 ]
}
res := tx . Model ( or ) . Where ( "id = ? and status <> ?" , or . ID , common . StatusROrderFinish ) . Updates ( or )
if res . Error != nil {
log . Error ( "Withdraw callback err:%v" , res . Error )
tx . Rollback ( )
return err
}
// 已处理的情况不返回错误了
if res . RowsAffected == 0 {
log . Error ( "Withdraw callback order:%v done" , order . OrderID )
tx . Rollback ( )
return nil
}
rei := & common . RechargeInfo { UID : uid }
db . Mysql ( ) . Get ( rei )
payData := & common . ESPlayerPayData { UID : uid , Channel : order . ChannelID , Amount : amount , Type : 2 }
if rei . TotalWithdrawCount == 0 {
payData . FirstAmount = amount
}
WritePlayerPayData ( payData )
u := map [ string ] interface { } {
"total_withdraw_count" : gorm . Expr ( "total_withdraw_count + ?" , 1 ) ,
"total_withdraw" : gorm . Expr ( "total_withdraw + ?" , order . Amount ) ,
"total_withdrawing" : gorm . Expr ( "total_withdrawing - ?" , amount ) ,
"withdrawing_cash" : gorm . Expr ( "withdrawing_cash - ?" , order . WithdrawCash ) ,
}
err = tx . Model ( rei ) . Where ( "uid = ?" , uid ) . Updates ( u ) . Error
if err != nil {
log . Error ( "BaseWithdraw err :%v" , err )
tx . Rollback ( )
return err
}
// err = UpdatePlayerRechargeInfoCurrency(uid, order.CurrencyType, map[string]interface{}{
// "total_withdrawing": gorm.Expr("total_withdrawing - ?", order.WithdrawCash),
// "total_withdraw": gorm.Expr("total_withdraw + ?", order.Amount),
// }, tx)
// if err != nil {
// log.Error("BaseWithdraw err :%v", err)
// tx.Rollback()
// return err
// }
if err := tx . Commit ( ) . Error ; err != nil {
log . Error ( "ZYWithdraw callback err:%v" , err )
tx . Rollback ( )
return err
}
PublishWarn ( WarnTypeWithdraw , 2 , [ ] int64 { int64 ( order . ChannelID ) , int64 ( order . UID ) } )
con := GetBroadcastConfigWithID ( common . BrocastIDWithdraw )
if con != nil {
up := con . ConditionUp
down := con . ConditionDown
if ( amount <= int64 ( up ) || up <= 0 ) && amount >= int64 ( down ) {
BroadcastReq ( con , fmt . Sprintf ( con . Content , uid , amount ) )
}
}
// util.Go(func() {
// SendRealWithdrawMail(order)
// })
}
if err != nil {
return err
}
Publish ( natsClient . TopicInnerPlayerWithdraw , & pb . InnerWithdrawCallback { UID : uint32 ( uid ) } )
return nil
}
// ReturnBackWithdraw 退出被拒绝或者失败,返还金币
func ReturnBackWithdraw ( or * common . WithdrawOrder , originStatus , status uint8 , payChannel ... int ) error {
log . Info ( "ReturnBackWithdraw orderid:%v,originStatus:%v,status:%v" , or . OrderID , originStatus , status )
order := & common . WithdrawOrder { }
order . ID = or . ID
tx := db . Mysql ( ) . Begin ( )
// 打款失败的单,重新挂起到后台进入人工审核,不再返还金币给玩家
u := map [ string ] interface { } {
"status" : status ,
"fail_reason" : or . FailReason ,
"callback_time" : time . Now ( ) . Unix ( ) ,
}
if status == common . StatusROrderFail {
status = common . StatusROrderCreate
u [ "status" ] = status
u [ "callback_time" ] = 0
}
if len ( payChannel ) > 0 {
u [ "pay_channel" ] = payChannel [ 0 ]
}
if len ( or . APIPayID ) > 0 {
u [ "apipayid" ] = or . APIPayID
}
update := tx . Model ( order ) . Where ( "status <= ?" , originStatus ) . Updates ( u )
if update . Error != nil {
log . Error ( "err:%v" , update . Error )
tx . Rollback ( )
return update . Error
}
// 已处理的情况不返回错误了
if update . RowsAffected == 0 {
err := fmt . Errorf ( "update fail:%+v" , or )
log . Error ( "err:%v" , err )
tx . Rollback ( )
return nil
}
uid := or . UID
re := new ( common . RechargeInfo )
re . UID = uid
updateRe := map [ string ] interface { } { }
if status != common . StatusROrderCreate {
updateRe = map [ string ] interface { } {
"withdrawing_cash" : gorm . Expr ( "withdrawing_cash - ?" , or . WithdrawCash ) ,
"total_withdrawing" : gorm . Expr ( "total_withdrawing - ?" , or . Amount ) ,
"day_withdraw" : gorm . Expr ( "day_withdraw - ?" , or . Amount ) ,
}
}
if status == common . StatusROrderFail || status == common . StatusROrderRefuse {
updateRe [ "withdraw_count" ] = gorm . Expr ( "withdraw_count + ?" , - 1 )
}
err := tx . Model ( re ) . Where ( "uid = ? and withdrawing_cash >= ? and total_withdrawing >= ?" , or . UID , or . WithdrawCash , or . Amount ) .
Updates ( updateRe ) . Error
if err != nil {
log . Error ( "err :%v" , err )
tx . Rollback ( )
return err
}
if status != common . StatusROrderCreate {
if or . Extra != "share" {
if err := UpdateCurrency ( & common . UpdateCurrency {
CurrencyBalance : & common . CurrencyBalance {
UID : or . UID ,
Type : or . CurrencyType ,
Value : or . WithdrawCash ,
Event : common . CurrencyEventWithDrawBack ,
Exs1 : or . OrderID ,
} ,
} , tx ) ; err != nil {
log . Error ( "Withdraw callback err:%v" , err )
tx . Rollback ( )
return err
}
} else {
db . Mysql ( ) . Update ( & common . ShareInfo { UID : or . UID } , map [ string ] interface { } {
"available_reward" : gorm . Expr ( "available_reward + ?" , or . WithdrawCash ) ,
} )
}
}
// 退还代付券
// if or.Extra == "useFreeWithdraw" {
// if err := tx.Model(&common.PlayerItems{UID: uid}).Updates(map[string]interface{}{"free_withdraw": gorm.Expr("free_withdraw + 1")}).Error; err != nil {
// log.Error("err:%v", err)
// tx.Rollback()
// return err
// }
// }
if err := tx . Commit ( ) . Error ; err != nil {
log . Error ( "err:%v" , err )
tx . Rollback ( )
return err
}
return nil
}
func WritePlayerPayData ( data * common . ESPlayerPayData ) {
data . Time = time . Now ( ) . Unix ( )
ret , _ := GetUserXInfo ( data . UID , "birth" )
data . IsNew = IsNewPlayer ( ret . Birth )
data . IsNew = util . IsSameDayTimeStamp ( ret . Birth , data . Time )
db . ES ( ) . InsertToESGO ( common . ESIndexBackPlayerPayData , data )
}
// PayExtra 支付extra字段判断
func PayExtra ( r * common . RechargeOrder ) ( amount int64 ) {
if len ( r . Extra ) == 0 {
return
}
extraData := & common . ActivityRechargeData { }
json . Unmarshal ( [ ] byte ( r . Extra ) , extraData )
switch extraData . ID {
case common . ItemDiscountTicket :
list := GetUserItemByExi1 ( r . UID , common . ItemDiscountTicket , extraData . I1 )
if len ( list ) == 0 {
return
}
item := list [ 0 ]
rows , err := db . Mysql ( ) . UpdateRes ( & common . PlayerItems { ID : item . ID , Status : common . ItemStatusNormal } ,
map [ string ] interface { } { "status" : common . ItemStatusInvalid } )
if err != nil || rows == 0 {
log . Error ( "err:%v" , err )
return
}
amount = extraData . I2
}
return
}
// PayActivity 支付活动
func PayActivity ( r * common . RechargeOrder , notCharge bool , user * common . PlayerDBInfo ) ( err error ) {
// VIP
UpdateVip ( r . UID , r . Amount , 0 , 0 )
// 检查任务
CheckTask ( Task { Uid : r . UID , Value : r . Amount , Types : [ ] common . TaskType { common . TaskTypeOnceRecharge } } )
// 检查所有活动
CheckAllActivity ( r )
// 更新loginrecord
if notCharge {
InsertLoginRecord ( r . UID , r . ChannelID , user . IP , user . Birth , user . Platform )
}
// todo
util . Go ( func ( ) {
// 分享活动
UpdateShare ( r . UID , 2 , r . Amount )
shareInfo := common . ShareInfo { UID : user . Id }
err = db . Mysql ( ) . Get ( & shareInfo )
if err != nil {
log . Error ( "get share info err, %s" , err . Error ( ) )
return
}
if shareInfo . UP1 != 0 {
err = db . Mysql ( ) . C ( ) . Model ( & common . PddDataNew { } ) . Where ( "uid = ?" , shareInfo . UP1 ) .
Updates ( map [ string ] interface { } {
"inviter_amount" : gorm . Expr ( "inviter_amount + ?" , r . Amount ) ,
} ) . Error
if err != nil {
log . Error ( "update inviter_amount err, %s" , err . Error ( ) )
return
}
}
} )
return nil
}
func ActivityFirstRechargeBack ( r * common . RechargeOrder ) {
if IsActivityValid ( common . ActivityIDFirstRechargeBack ) {
conf := GetConfigActivityFirstRechargeBack ( )
p , _ := GetUserXInfo ( r . UID , "birth" )
rechargeBackData := GetUserFirstRechargeBackData ( r . UID )
now := time . Now ( ) . Unix ( )
// 注册多少时间内
if now <= p . Birth + conf . CD {
if rechargeBackData . Amount == 0 {
data := & common . ActivityFirstRechargeBackData { UID : r . UID , Amount : r . Amount }
if r . Amount >= conf . MinRecharge {
data . RechargeTime = now
}
db . Mysql ( ) . Create ( data )
} else {
update := map [ string ] interface { } {
"amount" : gorm . Expr ( "amount + ?" , r . Amount ) ,
}
if rechargeBackData . Amount + r . Amount >= conf . MinRecharge {
update [ "recharge_time" ] = time . Now ( ) . Unix ( )
}
err := db . Mysql ( ) . Update ( & common . ActivityFirstRechargeBackData { UID : r . UID } , update )
if err != nil {
log . Error ( "err:%v" , err )
}
}
}
}
}
func CheckAllActivity ( r * common . RechargeOrder ) {
// 首充返还活动
ActivityFirstRechargeBack ( r )
var product * common . ConfigPayProduct
if r . ProductID > 0 {
product = GetConfigPayProductByID ( r . ProductID )
}
//// slots奖池活动
//ActivitySlots(r, product)
//if product == nil {
// return
//}
switch r . ActivityID {
case common . ActivityIDWeekCard :
ActivityWeekCard ( r , product )
//case common.ActivityIDBreakGift:
// ActivityBreakGift(r, product)
//case common.ActivityIDLuckyShop:
// ActivityLuckyShop(r, product)
//case common.ActivityIDSevenDayBox:
// ActivitySevenDayBox(r, product)
//case common.ActivityIDSuper:
// ActivitySuper(r, product)
}
}
func ActivityBreakGift ( r * common . RechargeOrder , product * common . ConfigPayProduct ) {
payData := GetPlayerPayData ( r . UID )
gift := GetConfigActivityBreakGiftByProductID ( r . ProductID )
if util . SliceContain ( payData . SubBreakGift , gift . Level ) {
return
}
payData . SubBreakGift = append ( payData . SubBreakGift , gift . Level )
str , _ := json . Marshal ( payData . SubBreakGift )
rows , err := db . Mysql ( ) . UpdateRes ( & common . PlayerPayData { UID : r . UID , BreakGift : payData . BreakGift } , map [ string ] interface { } { "break_gift" : string ( str ) } )
if rows == 0 || err != nil {
log . Error ( "err:%v" , err )
return
}
// ok
UpdateCurrencyPro ( & common . UpdateCurrency {
CurrencyBalance : & common . CurrencyBalance {
UID : r . UID ,
Value : product . Value ,
Event : common . CurrencyEventActivityBreakGift ,
Type : common . CurrencyINR ,
NeedBet : GetConfigCurrencyResourceNeedBet ( common . CurrencyResourceBonus , product . Value ) ,
ChannelID : r . ChannelID ,
Exi1 : product . ProductID ,
} ,
} )
UploadActivityData ( r . UID , common . ActivityIDBreakGift , common . ActivityDataJoin , product . Value )
}
func ActivityLuckyShop ( r * common . RechargeOrder , product * common . ConfigPayProduct ) {
rows , err := db . Mysql ( ) . UpdateResW ( & common . ActivityLuckyShopData { } , map [ string ] interface { } { "buy" : 1 } ,
fmt . Sprintf ( "uid = %d and product_id = %d and buy = 0" , r . UID , product . ProductID ) )
value := product . Value
if rows == 0 || err != nil {
// 直接给玩家按商品原价加钱
value = r . Amount
}
UpdateCurrencyProReal ( & common . UpdateCurrency {
CurrencyBalance : & common . CurrencyBalance {
UID : r . UID ,
Type : r . CurrencyType ,
Value : value ,
Event : common . CurrencyEvent ( r . Event ) ,
Exs1 : r . OrderID ,
Exi1 : int ( r . Amount ) , // 充值金额传递
Exi2 : r . ProductID ,
NeedBet : GetConfigCurrencyResourceNeedBet ( common . CurrencyResourceBonus , value ) ,
} ,
} )
UploadActivityData ( r . UID , common . ActivityIDLuckyShop , common . ActivityDataJoin , product . Value )
}
func ActivitySlots ( r * common . RechargeOrder , product * common . ConfigPayProduct ) {
if ! IsActivityValid ( common . ActivityIDSlots ) {
return
}
if product != nil && product . ActivityID == common . ActivityIDSlots {
if product . Exi > 0 {
UpdateUserActivitySlotsData ( r . UID , int ( product . Exi ) )
}
UpdateCurrencyProReal ( & common . UpdateCurrency {
CurrencyBalance : & common . CurrencyBalance {
UID : r . UID ,
Type : r . CurrencyType ,
Value : product . Value ,
Event : common . CurrencyEvent ( r . Event ) ,
Exs1 : r . OrderID ,
Exi1 : int ( r . Amount ) , // 充值金额传递
Exi2 : r . ProductID ,
NeedBet : GetConfigCurrencyResourceNeedBet ( common . CurrencyResourceBonus , product . Value ) ,
} ,
} )
return
}
count := r . Amount / 1000000000
if count >= 1 {
UpdateUserActivitySlotsData ( r . UID , int ( count ) )
}
}
func ActivitySevenDayBox ( r * common . RechargeOrder , product * common . ConfigPayProduct ) {
data := & common . ActivitySevenDayBoxData { UID : r . UID }
db . Mysql ( ) . Get ( data )
now := time . Now ( ) . Unix ( )
value := product . Value
if util . IsSameDayTimeStamp ( now , data . Time ) { // 一天只能买一次
value = r . Amount
} else {
if data . ID == 0 {
data . Time = now
data . Count = 1
err := db . Mysql ( ) . Create ( data )
if err != nil {
value = r . Amount
}
} else {
rows , err := db . Mysql ( ) . UpdateResW ( & common . ActivitySevenDayBoxData { } , map [ string ] interface { } { "count" : gorm . Expr ( "count + 1" ) , "time" : now } ,
fmt . Sprintf ( "uid = %d and count = %d and time = %d" , r . UID , data . Count , data . Time ) )
if rows == 0 || err != nil {
// 直接给玩家按商品原价加钱
value = r . Amount
}
}
}
if value > 0 {
UpdateCurrencyProReal ( & common . UpdateCurrency {
CurrencyBalance : & common . CurrencyBalance {
UID : r . UID ,
Type : r . CurrencyType ,
Value : value ,
Event : common . CurrencyEvent ( r . Event ) ,
Exs1 : r . OrderID ,
Exi1 : int ( r . Amount ) , // 充值金额传递
Exi2 : r . ProductID ,
NeedBet : GetConfigCurrencyResourceNeedBet ( common . CurrencyResourceBonus , value ) ,
} ,
} )
}
}
func ActivitySuper ( r * common . RechargeOrder , product * common . ConfigPayProduct ) {
data := GetUserActivitySuperData ( r . UID )
value := product . Value
if ! data . CanBuy {
value = r . Amount
} else {
rows , err := db . Mysql ( ) . UpdateResW ( & common . ActivitySuperData { } , map [ string ] interface { } { "open" : 0 , "time" : time . Now ( ) . Unix ( ) } ,
fmt . Sprintf ( "uid = %d and time = %d" , r . UID , data . Time ) )
if rows == 0 || err != nil {
log . Error ( "err:%v" , err )
value = r . Amount
}
}
if value > 0 {
UpdateCurrencyProReal ( & common . UpdateCurrency {
CurrencyBalance : & common . CurrencyBalance {
UID : r . UID ,
Type : r . CurrencyType ,
Value : value ,
Event : common . CurrencyEvent ( r . Event ) ,
Exs1 : r . OrderID ,
Exi1 : int ( r . Amount ) , // 充值金额传递
Exi2 : r . ProductID ,
NeedBet : GetConfigCurrencyResourceNeedBet ( common . CurrencyResourceBonus , value ) ,
} ,
} )
}
}
type IFSCRet struct {
Ifsc string ` json:"IFSC" `
}
func CheckIFSC ( ifsc string ) bool {
ret := & IFSCRet { }
client := http . Client {
Timeout : 2 * time . Second ,
}
url := config . GetConfig ( ) . Web . IFSCURL + "/" + ifsc
log . Debug ( "url:%v" , url )
resp , err := client . Get ( url )
if err != nil {
log . Error ( "get err:%v" , err )
return true
}
// if resp.StatusCode != http.StatusOK {
// log.Error("req fail err code:%v", resp.StatusCode)
// return true
// }
defer resp . Body . Close ( )
data , err := ioutil . ReadAll ( resp . Body )
if err != nil {
log . Error ( "read err %v" , err )
return true
}
json . Unmarshal ( data , ret )
return ret . Ifsc != ""
}
func GetTotalRechargePer ( thisWithdraw int64 ) int64 {
zero := util . GetZeroTime ( time . Now ( ) ) . Unix ( )
recharge := db . Mysql ( ) . Sum ( & common . RechargeOrder { } , fmt . Sprintf ( "create_time >= %d and event = %d and status = %d" , zero , common . CurrencyEventReCharge , common . StatusROrderPay ) , "amount" )
withdraw := db . Mysql ( ) . Sum ( & common . WithdrawOrder { } , fmt . Sprintf ( "create_time >= %d and event = %d and status = %d" , zero , common . CurrencyEventWithDraw , common . StatusROrderFinish ) , "amount" )
withdraw += thisWithdraw
if recharge == 0 {
return withdraw * 100 / common . DecimalDigits
}
return withdraw * 100 / recharge
}
func WithdrawInfoGet ( uid int ) ( withdrawInfo common . WithdrawInfo , err error ) {
err = db . Mysql ( ) . C ( ) . Model ( & common . WithdrawInfo { } ) . Where ( "uid = ?" , uid ) . Find ( & withdrawInfo ) . Error
if err != nil {
return
}
return
}
func ActivityWeekCard ( r * common . RechargeOrder , product * common . ConfigPayProduct ) {
con := GetConfigWeekCard ( )
if con == nil {
return
}
now := time . Now ( )
weekCardData := common . WeekCardData {
UID : r . UID ,
BeginAt : now . Unix ( ) ,
CardPrice : int ( product . Amount / common . DecimalDigits ) ,
AwardTimes : 1 ,
AwardAt : now . Unix ( ) ,
AwardTotal : int ( product . Amount ) ,
AwardTotalHistory : int ( product . Amount ) ,
BuyCardTimes : 1 ,
}
err := db . Mysql ( ) . C ( ) . Model ( & common . WeekCardData { } ) . Clauses ( clause . OnConflict {
Columns : [ ] clause . Column { { Name : "uid" } } ,
DoUpdates : clause . Assignments ( map [ string ] interface { } {
"begin_at" : weekCardData . BeginAt ,
"card_price" : weekCardData . CardPrice ,
"award_times" : weekCardData . AwardTimes ,
"award_at" : weekCardData . AwardAt ,
"award_total" : weekCardData . AwardTotal ,
"award_total_history" : gorm . Expr ( "`award_total_history` + ?" , weekCardData . AwardTotalHistory ) ,
"buy_card_times" : gorm . Expr ( "`buy_card_times` + ?" , weekCardData . BuyCardTimes ) ,
} ) ,
} ) . Create ( & weekCardData ) . Error
if err != nil {
log . Error ( "update week card err:%v" , err . Error ( ) )
return
}
PushRed ( r . UID , pb . RedPointModule_RedPointWeekCard , 1 )
}