package handler import ( "encoding/json" "server/call" "server/config" "server/db" "server/modules/web/app" "server/pb" "server/util" "time" "server/common" "server/modules/web/values" "github.com/gin-gonic/gin" "github.com/liangdas/mqant/log" "github.com/olivere/elastic/v7" ) func CheckRechargeOrder(c *gin.Context) { a := app.NewApp(c) defer func() { a.Response() }() req := new(values.RechargeOrderReq) if !a.S(req) { return } // log.Debug("req:%+v", *req) one := &common.RechargeOrder{OrderID: req.OrderID} db.Mysql().Get(one) resp := values.RechargeOrderResp{ Status: int(one.Status), Amount: one.Amount, } a.Data = resp // log.Debug("resp:%+v", resp) } func RechargeInfoFirst(c *gin.Context) { a := app.NewApp(c) defer func() { a.Response() }() resp := &values.RechargeInfoFirstResp{} a.Data = resp a.GetUID() resp.List = make([]values.PayInfo, 0, len(call.GetConfigFirstPay())) rechargeInfo := call.GetRechargeInfo(a.UID) for _, v := range call.GetConfigFirstPay() { var bonus int64 _, per, _ := call.GetConfigFirstPayByCount(a.UID, v.Amount, rechargeInfo.BuyAmountDataMap) if per > 0 { bonus = v.Amount * per / 100 } var productId int if product := call.GetConfigPayProductByAmount(v.Amount); product != nil { productId = product.ProductID } resp.List = append(resp.List, values.PayInfo{ Amount: v.Amount, Bonus: bonus, ProductId: productId, }) } } func RechargeInfo(c *gin.Context) { a := app.NewApp(c) defer func() { a.Response() }() list := call.GetConfigPayProductByActivityID(0) resp := &values.RechargeInfoResp{Tips: call.GetConfigPlatform().PayTips, SelectID: config.GetConfig().Web.SelectID} a.Data = resp resp.Channels = call.GetConfigPayChannels() // payData := call.GetPlayerPayData(a.UID) a.GetUID() re := &common.RechargeInfo{} if a.UID > 0 { re = call.GetRechargeInfo(a.UID) } for _, v := range call.GetConfigFirstPay() { one := values.OneConfigPayBonus{ Amount: v.Amount, } if re.TotalRecharge > 0 { one.Per = v.Per } else { one.Per = v.FirstPer } resp.ConfigPayBonus = append(resp.ConfigPayBonus, one) } data := common.CurrencyBalance{} q := elastic.NewBoolQuery() q.Filter(elastic.NewMatchQuery("uid", a.UID)) q.Filter(elastic.NewMatchQuery("value", 100*common.DecimalDigits)) q.Filter(elastic.NewMatchQuery("event", common.CurrencyEventReCharge)) db.ES().QueryOne(common.ESIndexBalance, q, &data, "id", false) log.Info("data:%+v", data) rechargeInfo := call.GetRechargeInfo(a.UID) for _, v := range list { one := *v if v.IfSell == 2 { continue } if v.Type == common.CurrencyUSDT { for _, j := range resp.Channels { if j.CurrencyType == common.CurrencyUSDT { if j.PayDown <= v.Amount && j.PayUp >= v.Amount { one.Channels = append(one.Channels, j.ChannelID) } } } resp.List = append(resp.List, one) } else if v.Type == common.CurrencyINR { for _, j := range resp.Channels { if j.CurrencyType == common.CurrencyINR { if j.PayDown <= v.Amount && j.PayUp >= v.Amount { one.Channels = append(one.Channels, j.ChannelID) } } } if _, bonus, _ := call.GetConfigFirstPayByCount(a.UID, one.Amount, rechargeInfo.BuyAmountDataMap); bonus > 0 { one.Bonus = bonus * one.Amount / 100 } resp.List = append(resp.List, one) } } if a.UID > 0 { // 判断是否有折扣券 tickets := call.GetUserValidItems(a.UID, common.ItemDiscountTicket) for _, v := range tickets { diff := v.Time - time.Now().Unix() if v.Time != -1 && diff <= 0 { id := v.ID util.Go(func() { db.Mysql().Update(&common.PlayerItems{ID: id}, map[string]interface{}{"status": common.ItemStatusInvalid}) }) continue } resp.DiscountTicket = append(resp.DiscountTicket, &values.DiscountTicket{ Id: v.ID, Discount: v.Exi1, TimeLeft: v.Time, Amount: v.Exi2, }) } } for _, channel := range resp.Channels { channel.PayStatus = call.GetChannelStatus(channel.ChannelID) } resp.NeedBet = call.GetUserNeedBet(a.UID) resp.Cash = call.GetUserCurrencyTotal(a.UID, common.CurrencyType(0)) if resp.NeedBet == 0 { resp.CanWithdraw = resp.Cash } } func RechargeHistory(c *gin.Context) { a := app.NewApp(c) defer func() { a.Response() }() req := new(values.RechargeHistoryReq) if !a.S(req) { return } resp := &values.RechargeHistoryResp{} a.Data = resp now := time.Now() switch req.Tag { case 0: req.StartAt = now.AddDate(0, 0, -1).Unix() req.EndAt = now.Unix() case 1: req.StartAt = now.AddDate(0, 0, -7).Unix() req.EndAt = now.Unix() case 2: req.StartAt = now.AddDate(0, 0, -30).Unix() req.EndAt = now.Unix() } var err error mdb := db.Mysql().C().Model(&common.RechargeOrder{}).Where("uid = ? and event = ? and create_time >= ? and create_time <= ? ", a.UID, common.CurrencyEventReCharge, req.StartAt, req.EndAt) err = mdb.Count(&resp.Count).Error if err != nil { log.Error("get recharge order count err, %s", err.Error()) } err = mdb.Order("create_time desc").Offset(req.Page * req.PageSize).Limit(req.PageSize).Find(&resp.List).Error if err != nil { log.Error("get recharge order list err, %s", err.Error()) a.Code = values.CodeRetry return } for index, v := range resp.List { switch v.Status { case 1, 2: resp.List[index].Status = 0 case 3: resp.List[index].Status = 1 case 4, 5: resp.List[index].Status = 2 } } a.Data = resp } func PlayerRecharge(c *gin.Context) { a := app.NewApp(c) defer func() { a.Response() }() req := new(values.RechargeReq) if !a.S(req) { a.Code = values.CodeParam return } log.Debug("player %v recharge:%+v", a.UID, *req) if req.CurrencyType == 0 { req.CurrencyType = common.CurrencyINR } if req.ProductID > 0 { product := call.GetConfigPayProductByID(req.ProductID) if product == nil { a.Code = values.CodeRetry return } req.Amount = product.Amount req.ActivityID = product.ActivityID if product.ActivityID > 0 { can, _ := a.CanBuyProduct(req.ActivityID, req.ProductID) if !can { a.Code = values.CodeRetry a.Msg = "Buy limit" return } req.Bonus = false } } else { req.Amount = common.RoundCurrency(req.CurrencyType, req.Amount) } payCount, _ := db.Redis().GetInt(common.GetRedisKeyPlayerPayCount(a.UID)) // 判断充值间隔 同渠道限制3秒拉一单 30秒限制4单 if db.Redis().Exist(common.GetRedisKeyPlayerChannelPayInterval(req.PayChannel, a.UID)) && payCount >= 4 { a.Code = values.CodeParam a.Msg = "Requests are too frequent, please try again later" return } call.AddChannel(req.PayChannel, false) if req.UserPhone == "" { req.UserPhone = util.CheckPhone(req.UserPhone) } payImp := NewRechargeImp(req, a.UID, a.Channel, a.GetRemoteIP()) if payImp == nil { a.Code = values.CodeRetry a.Msg = "channel unavailable" log.Error("req params err:%v", req) return } code := payImp.Recharge() if code != values.CodeOK { a.Code = code a.Msg = "channel unavailable" return } // ok a.Data = payImp.Data a.Msg = payImp.Order.OrderID log.Debug("player %v recharge resp:%v,msg:%v", a.UID, a.Data, a.Msg) uid := a.UID util.Go(func() { db.Redis().SetData(common.GetRedisKeyPlayerChannelPayInterval(req.PayChannel, uid), 1, 3*time.Second) db.Redis().Incr(common.GetRedisKeyPlayerPayCount(a.UID), 1) if payCount == 0 { db.Redis().Expire(common.GetRedisKeyPlayerPayCount(a.UID), 30*time.Second) } }) if !config.GetBase().Release { util.Go(func() { call.RechargeCallback(payImp.Order, true, "", "") }) } } func NewRechargeImp(req *values.RechargeReq, uid, cid int, ip string) *RechargeImp { r := new(RechargeImp) r.Channel = call.GetChannelByID(cid) if r.Channel == nil { log.Error("invalid cid:%v", cid) return nil } order := &common.RechargeOrder{ CreateTime: time.Now().Unix(), CurrencyType: req.CurrencyType, Amount: req.Amount, ChannelID: cid, UID: uid, Status: common.StatusROrderCreate, Event: int(common.CurrencyEventReCharge), UPI: req.PayChannel, ProductID: req.ProductID, ActivityID: req.ActivityID, } if req.ActivityID > 0 { switch req.ActivityID { case common.ActivityIDWeekCard: order.Event = int(common.CurrencyEventActivityWeekCard) if weekCard := call.GetConfigWeekCard(); weekCard != nil { order.Bonus = int64(weekCard.AwardDetails[1].AwardLower*common.DecimalDigits) - req.Amount } } } // 只有商城购买才能使用优惠券 // todo activityId为0才是商城购买 if req.ProductID == 0 && req.DiscountTicketId > 0 { // 判断是否有折扣券 ticket := call.GetItem(req.DiscountTicketId) if ticket != nil && req.Amount >= ticket.Exi2 { ticketData := common.ActivityRechargeData{ID: common.ItemDiscountTicket, I1: int(ticket.Exi1), I2: req.Amount} ticketByte, _ := json.Marshal(ticketData) order.Extra = string(ticketByte) req.Amount = common.RoundCurrency(common.CurrencyINR, req.Amount-ticket.Exi1) order.Amount = req.Amount } } re := call.GetRechargeInfo(uid) //notCharge := re.TotalRecharge == 0 //per := call.GetConfigFirstPayPerByAmount(notCharge, order.Amount) var times int if req.Bonus && req.ActivityID == 0 { buyCount, per, topThree := call.GetConfigFirstPayByCount(order.UID, order.Amount, re.BuyAmountDataMap) if per > 0 { order.Bonus = order.Amount * per / 100 } times = buyCount if topThree { times++ } else { times = 0 } } r.UID = uid info, _ := call.GetUserXInfo(uid, "mobile") p := new(PayImp) p.CurrencyType = req.CurrencyType p.req = new(pb.InnerRechargeReq) p.req.Phone = req.UserPhone p.req.Amount = req.Amount p.req.PlayerChannel = uint32(cid) if req.CurrencyType == common.CurrencyINR { // 判断黑名单 if call.BlackListAndKick(uid, &common.BlackList{Phone: info.Mobile}) { return nil } pinfo := &common.PayInfo{UID: uid} db.Mysql().Get(pinfo) // if req.UserName == nil { // log.Error("invalid param:%+v", req) // return nil // } p.req.Name = util.GenerateRandomString(5) p.req.Phone = pinfo.Mobile p.req.IP = ip p.req.Number = pinfo.BankCardNo if info.Mobile != "" { p.req.Phone = info.Mobile } if pinfo.AccountName != "" { p.req.Name = pinfo.AccountName } if pinfo.Email != "" { p.req.Email = pinfo.Email } } order.Times = times r.Order = order p.base = r r.RechargeIn = p r.PayChannel = req.PayChannel return r } type RechargeIn interface { Recharge() int } // RechargeImp 新充值对象 type RechargeImp struct { Data interface{} RechargeIn Order *common.RechargeOrder // product *common.ConfigPayProduct // tx *gorm.DB UID int Channel *common.Channel PayChannel int } func (r *RechargeImp) CreateRecharge() error { if r.Order.OrderID == "" { r.Order.OrderID = util.NewOrderID(r.UID, config.GetBase().ServerFlag) } // r.Order.UID = r.UID // r.Order.Status = common.StatusROrderCreate // r.Order.Event = int(common.CurrencyEventReCharge) // r.Order.ChannelID = int(r.Channel.ChannelID) if err := db.Mysql().C().Model(r.Order).Create(r.Order).Error; err != nil { log.Error("create order err:%v", err) return err } return nil } // pay模块支付 type PayImp struct { base *RechargeImp req *pb.InnerRechargeReq CurrencyType common.CurrencyType } func (p *PayImp) Recharge() int { orderID := util.NewOrderID(p.base.UID, config.GetBase().ServerFlag) // product := p.base.product var resp *pb.InnerRechargeResp var err error if p.CurrencyType == common.CurrencyINR { req := &pb.InnerRechargeReq{OrderID: orderID, Amount: p.req.Amount, Phone: p.req.Phone, Name: p.req.Name, UID: uint32(p.base.UID), Channel: uint32(p.base.PayChannel), IsPersonalCard: false, PaySource: common.PaySourceModulePay} p.base.Order.PaySource = common.PaySourceModulePay if p.base.PayChannel < 0 { req.IsPersonalCard = true } resp, err = call.Recharge(req) if err != nil { log.Error("err:%v", err) return values.CodeRetry } log.Debug("recharge resp, %+v", *resp) if resp.IsReplace { p.base.Order.IsReplace = 1 } p.base.Order.PayChannel = int(resp.Channel) } else { orderID = "USDT" + orderID req := &pb.InnerRechargeReq{OrderID: orderID, Amount: p.req.Amount, UID: uint32(p.base.UID), Channel: uint32(p.base.PayChannel), PaySource: common.PaySourceBlockPay} p.base.Order.PaySource = common.PaySourceBlockPay resp, err = call.Recharge(req) if err != nil { log.Error("err:%v", err) return values.CodeRetry } p.base.Order.Extra = resp.URL } p.base.Data = values.PayResp{OrderID: orderID, Addr: resp.URL} p.base.Order.OrderID = orderID p.base.Order.APIPayID = resp.APIOrderID err = p.base.CreateRecharge() if err != nil { return values.CodeRetry } return values.CodeOK }