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.
896 lines
27 KiB
896 lines
27 KiB
package call |
|
|
|
import ( |
|
"context" |
|
"encoding/json" |
|
"errors" |
|
"fmt" |
|
jsoniter "github.com/json-iterator/go" |
|
"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, |
|
} |
|
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 |
|
} |
|
} |
|
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 product.ActivityID { |
|
case common.ActivityIDBreakGift: |
|
ActivityBreakGift(r, product) |
|
case common.ActivityIDWeekCard: |
|
ActivityWeekCard(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 ActivityWeekCard(r *common.RechargeOrder, product *common.ConfigPayProduct) { |
|
con := GetConfigWeekCard() |
|
if con == nil { |
|
return |
|
} |
|
rows, err := db.Mysql().UpdateRes(&common.ActivityWeekCardData{UID: r.UID}, map[string]interface{}{ |
|
"recharge_time": time.Now().Unix(), "day": 0, "recharge_amount": r.Amount, "rewards": ""}) |
|
if err != nil || rows == 0 { |
|
log.Error("err:%v", err) |
|
return |
|
} |
|
// ok |
|
UpdateCurrencyPro(&common.UpdateCurrency{ |
|
CurrencyBalance: &common.CurrencyBalance{ |
|
UID: r.UID, |
|
Value: product.Value, |
|
Event: common.CurrencyEventActivityWeekCard, |
|
Type: common.CurrencyINR, |
|
NeedBet: GetConfigCurrencyResourceNeedBet(common.CurrencyResourceBonus, product.Value), |
|
ChannelID: r.ChannelID, |
|
Exi1: product.ProductID, |
|
}, |
|
}) |
|
UploadActivityData(r.UID, common.ActivityIDWeekCard, common.ActivityDataJoin, product.Value) |
|
// 自动领第一天的 |
|
cons := GetConfigWeekCard() |
|
cardInfo := GetUserWeekCard(r.UID) |
|
var rewardList []int64 |
|
_ = rewardList |
|
_ = cons |
|
//rewardList, err = util.GenerateRandomSequence(cons.RewardAmount, cons.MiniLimit, 5) |
|
//if err != nil { |
|
// log.Error("err:%v", err) |
|
//} |
|
//rewardList = append([]int64{cons.DayOneReward}, rewardList...) |
|
//rewardList = append(rewardList, 0) |
|
//if cardInfo.ID <= 0 || len(cardInfo.Rewards) == 0 { |
|
// cardInfo.Day = 0 |
|
// rewardList, err = util.GenerateRandomSequence(cons.RewardAmount, cons.MiniLimit, 5) |
|
// if err != nil { |
|
// log.Error("err:%v", err) |
|
// } |
|
// rewardList = append([]int64{cons.DayOneReward}, rewardList...) |
|
// rewardList = append(rewardList, 0) |
|
// cardInfo.Rewards = strings.Join(util.Int64SliceToStringSlice(rewardList), ",") |
|
// db.Mysql().Update(&common.ActivityWeekCardData{UID: r.UID}, map[string]interface{}{ |
|
// "rewards": cardInfo.Rewards, |
|
// }) |
|
//} |
|
rewards, _ := util.StringToInt64Slice(cardInfo.Rewards, ",") |
|
if cardInfo.Day >= len(rewards) { |
|
log.Error("The weekly card has been collected") |
|
return |
|
} |
|
now := time.Now() |
|
rows, err = db.Mysql().UpdateRes(&common.ActivityWeekCardData{UID: r.UID}, |
|
map[string]interface{}{"day": gorm.Expr("day + 1"), "last_draw": now.Unix()}) |
|
if rows == 0 || err != nil { |
|
log.Error("err:%v", err) |
|
return |
|
} |
|
var reward int64 |
|
if cardInfo.Day < 6 { |
|
reward = rewards[cardInfo.Day] * common.DecimalDigits |
|
} |
|
resource := common.CurrencyResourceWeekCard |
|
if cardInfo.Day > 0 { |
|
resource = common.CurrencyResourceBonus |
|
} |
|
if reward > 0 { |
|
UpdateCurrencyPro(&common.UpdateCurrency{ |
|
CurrencyBalance: &common.CurrencyBalance{ |
|
UID: r.UID, |
|
Type: common.CurrencyINR, |
|
Value: reward, |
|
Event: common.CurrencyEventActivityWeekCard, |
|
ChannelID: r.ChannelID, |
|
NeedBet: GetConfigCurrencyResourceNeedBet(resource, reward), |
|
}, |
|
}) |
|
} |
|
} |
|
|
|
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 |
|
}
|
|
|