package call import ( "context" "encoding/json" "errors" "fmt" "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} err := db.Mysql().Get(info) if err != nil { return 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 } 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" } 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 } // 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 := new(common.RechargeInfo) re.UID = uid err = db.Mysql().Get(re) if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { log.Error("get recharage info err:%v,uid:%v", err, r.UID) return err } amount := r.Amount notCharge := re.TotalRecharge == 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 re.ID == 0 { 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 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 notCharge && bonus > 0 { // 首充 t = common.CurrencyResourceFirstRecharge } else if bonus > 0 { t = common.CurrencyResourceRechargeBonus } needBet := GetConfigCurrencyResourceNeedBet(t, amount) if bonus > 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, ticket.DiscountAmount/common.DecimalDigits, ticket.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 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 } } // 退还代付券 // 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) CheckShare(r) } 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 := GetConfigActivityWeekCard() 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) } 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 }