268 lines
7.1 KiB
Go
268 lines
7.1 KiB
Go
package withdrawser
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strconv"
|
|
"sync"
|
|
"time"
|
|
|
|
"91porn-server/app/appg"
|
|
"91porn-server/common"
|
|
"91porn-server/common/constant/redisconst"
|
|
"91porn-server/common/crypt"
|
|
"91porn-server/common/db"
|
|
"91porn-server/common/log"
|
|
"91porn-server/models/v/txnmod"
|
|
"91porn-server/models/v/usermod"
|
|
"91porn-server/models/v/walletmod"
|
|
"91porn-server/models/v/wdchannmod"
|
|
"91porn-server/models/v/wdordmod"
|
|
"91porn-server/models/v/wdtaxmod"
|
|
)
|
|
|
|
// WithDraw 提现
|
|
func WithDraw(wd *wdordmod.WithdrawOrder) (err error) {
|
|
now := time.Now()
|
|
u, err := usermod.FindUserByUID(wd.UID)
|
|
if err != nil || u == nil {
|
|
return
|
|
}
|
|
wt, err := WithdrawType(u.GetSuperUser(now), wd.PayType)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if wd.ProductType == 1 {
|
|
return errors.New("瓦力游戏已下架")
|
|
}
|
|
|
|
w, err := walletmod.GetWallet(wd.UID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if wd.Name == "" {
|
|
wd.Name = u.Name
|
|
}
|
|
if wd.DevID == "" {
|
|
wd.DevID = u.DevID
|
|
}
|
|
wd.DeviceType = u.SysType
|
|
wd.DiscDoc = u.DiscDoc
|
|
switch wd.WithdrawType {
|
|
case wdordmod.AgentWithdraw: //代理提现
|
|
wd.PayMoney = (wd.Money * (int64)(100-wt.CoinTax)) / 100
|
|
if wd.Money > w.Money {
|
|
return errors.New("Insufficient balance")
|
|
}
|
|
//开启事务
|
|
return appg.VideoDB.Trans(func(t *db.MongoTool) error {
|
|
wd.Status = wdordmod.DEFAULT
|
|
if _, err = wdordmod.InsertWithdrawOrder(t, wd); err != nil {
|
|
return err
|
|
}
|
|
_, err = walletmod.DebitMoney(t, wd.Money, wd.UID)
|
|
return err
|
|
})
|
|
default: //wdordmod.GoldWithdraw 金币提现
|
|
wd.Amount = wd.Money / 10
|
|
wd.PayMoney = (wd.Money * (int64)(100-wt.CoinTax)) / 100
|
|
if wd.Amount > w.Income {
|
|
return errors.New("Insufficient balance")
|
|
}
|
|
//开启事务
|
|
return appg.VideoDB.Trans(func(t *db.MongoTool) error {
|
|
wd.Status = wdordmod.DEFAULT
|
|
if _, err = wdordmod.InsertWithdrawOrder(t, wd); err != nil {
|
|
return err
|
|
}
|
|
wallet, err := walletmod.DebitIncome(t, wd.Amount, wd.UID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//插入收支流水
|
|
tt := txnmod.TransactionLog{
|
|
TransNo: wd.ID,
|
|
UID: wd.UID,
|
|
Amount: -wd.Amount,
|
|
TranType: txnmod.WithdrawTransfer.Key(),
|
|
TranTypeInt: int64(txnmod.WithdrawTransfer),
|
|
ChannelType: wd.PayType,
|
|
Desc: "用户提现-" + strconv.FormatInt(wd.Amount, 10),
|
|
DiscDoc: wd.DiscDoc,
|
|
SysType: wd.DeviceType,
|
|
ActualAmount: -float64(wd.Amount),
|
|
RealAmount: walletmod.GetRealAmount(wallet),
|
|
}
|
|
//插入一条支出流水
|
|
return txnmod.InsertTransactionLog(t, &tt)
|
|
})
|
|
}
|
|
}
|
|
|
|
// WithdrawType 获取提现方式
|
|
func WithdrawType(superUser bool, wType string) (res wdchannmod.WithdrawChannelRes, err error) {
|
|
var wg sync.WaitGroup
|
|
wg.Add(2)
|
|
common.Go(func() {
|
|
defer wg.Done()
|
|
wc, err := wdchannmod.GetWithdrawChannel(wType)
|
|
if err != nil {
|
|
return
|
|
}
|
|
res.WithdrawChannel = *wc
|
|
})
|
|
common.Go(func() {
|
|
defer wg.Done()
|
|
wt, err := wdtaxmod.GetWithDrawTariff()
|
|
if err != nil {
|
|
return
|
|
}
|
|
if superUser {
|
|
res.WithdrawTariff.CoinTax = wt.SuperUserCoinTax
|
|
} else {
|
|
res.WithdrawTariff.CoinTax = wt.CoinTax
|
|
}
|
|
if wt.GameTax <= 0 {
|
|
wt.GameTax = 2
|
|
}
|
|
res.WithdrawTariff.GameTax = wt.GameTax
|
|
})
|
|
wg.Wait()
|
|
return
|
|
}
|
|
|
|
// GetWithdrawCfg 获取提现配置方式
|
|
func GetWithdrawCfg() (res wdchannmod.WithdrawChannelAppRes) {
|
|
var wd []*wdchannmod.AppWithdrawChannels
|
|
var wt wdtaxmod.WithdrawTariff
|
|
var wg sync.WaitGroup
|
|
wg.Add(2)
|
|
common.Go(func() {
|
|
defer wg.Done()
|
|
str, err := appg.Redis.Get(redisconst.WithdrawCfgCacheKey())
|
|
if str != nil && err == nil {
|
|
_ = crypt.JSON2Struct(*str, &wd)
|
|
} else {
|
|
wd, err = wdchannmod.GetActiveWithdrawChannels()
|
|
if wd != nil && err == nil {
|
|
normalstr, _ := crypt.StructToStrNormal(&wd)
|
|
_ = appg.Redis.Set(redisconst.WithdrawCfgCacheKey(), normalstr, redisconst.WithdrawCfgExpire)
|
|
}
|
|
}
|
|
})
|
|
common.Go(func() {
|
|
defer wg.Done()
|
|
str, err := appg.Redis.Get(redisconst.WithdrawTariffCacheKey())
|
|
if str != nil && err == nil {
|
|
_ = crypt.JSON2Struct(*str, &wt)
|
|
} else {
|
|
wt, err = wdtaxmod.GetWithDrawTariff()
|
|
if err == nil {
|
|
normalstr, _ := crypt.StructToStrNormal(wt)
|
|
_ = appg.Redis.Set(redisconst.WithdrawTariffCacheKey(), normalstr, redisconst.WithdrawTariffExpire)
|
|
}
|
|
}
|
|
})
|
|
wg.Wait()
|
|
res.Channels = wd
|
|
res.CashTax = wt.CashTax
|
|
res.CoinTax = wt.CoinTax
|
|
return
|
|
}
|
|
|
|
// ExchgCallBack 提现回调
|
|
func ExchgCallBack(tradeNo string, oid string, money int64, status string, mark string) error {
|
|
w, err := wdordmod.FindWithdrawOrderByID(tradeNo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if w.Status == wdordmod.SUCCESS || w.Status == wdordmod.FAILURE {
|
|
return nil
|
|
}
|
|
if w.Status != wdordmod.PROCESSING && w.Status != wdordmod.UNKNOWN {
|
|
log.Error(fmt.Sprintf("Wtihdraw status error ,order:%+v:", w))
|
|
return errors.New("Wtihdraw status error")
|
|
}
|
|
if w.ProductType == 1 {
|
|
return errors.New("瓦力游戏已下架")
|
|
}
|
|
now := time.Now()
|
|
set := wdordmod.EditSelector{
|
|
OID: &oid,
|
|
}
|
|
switch status {
|
|
case "paid": //已经打款
|
|
//修改订单状态
|
|
set.PayMoney = &money
|
|
set.SuccessAt = &now
|
|
set.ReceivedAt = &now
|
|
set.Status = wdordmod.SUCCESS
|
|
set.StatusDesc = wdordmod.SUCCESSStatus
|
|
set.SuccessAt = &now
|
|
if err = wdordmod.UpdateWithPROCESSINGAndUNKNOWN(nil, tradeNo, set); err != nil {
|
|
return err
|
|
}
|
|
if w.PayType == wdordmod.TypeBankCard {
|
|
_, err = usermod.Update(w.UID, usermod.UserSelector{BankActName: &w.ActName})
|
|
return err
|
|
}
|
|
return nil
|
|
case "refused": //拒绝
|
|
return appg.VideoDB.Trans(func(t *db.MongoTool) error {
|
|
switch w.WithdrawType {
|
|
case wdordmod.GoldWithdraw:
|
|
var wallet *walletmod.Wallet
|
|
wallet, err = walletmod.CreditIncome(t, w.Amount, w.UID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//插入收支流水
|
|
tk := txnmod.TransactionLog{
|
|
TransNo: w.ID,
|
|
UID: w.UID,
|
|
Amount: w.Amount,
|
|
TranType: txnmod.WithdrawRefund.Key(),
|
|
TranTypeInt: int64(txnmod.WithdrawRefund),
|
|
ChannelType: w.PayType,
|
|
Desc: "用户提现失败,退款" + strconv.FormatInt(w.Amount, 10),
|
|
DiscDoc: w.DiscDoc,
|
|
SysType: w.DeviceType,
|
|
ActualAmount: float64(w.Amount),
|
|
RealAmount: walletmod.GetRealAmount(wallet),
|
|
}
|
|
//插入一条支出流水
|
|
if err = txnmod.InsertTransactionLog(t, &tk); err != nil {
|
|
return err
|
|
}
|
|
case wdordmod.AgentWithdraw:
|
|
if err = walletmod.CreditMoney(t, w.Money, w.UID); err != nil {
|
|
return err
|
|
}
|
|
case wdordmod.DiscWithdraw:
|
|
// err = discWirhdrawRefund(t, w, "提现被平台拒绝")
|
|
if err != nil {
|
|
log.Error("discWirhdrawRefund failed", log.E(err), log.Any("witOrd", w))
|
|
return err
|
|
}
|
|
default:
|
|
return errors.New("invalid type")
|
|
}
|
|
set.Status = wdordmod.FAILURE
|
|
set.StatusDesc = mark
|
|
set.FailureAt = &now
|
|
if err = wdordmod.UpdateWithPROCESSINGAndUNKNOWN(t, tradeNo, set); err != nil {
|
|
return err
|
|
}
|
|
//棋牌usdt兑换拒绝增加usdt可提现额度
|
|
if w.ProductType == 1 && w.PayType == wdordmod.TypeUsdt {
|
|
if _, err = walletmod.IncUsdtAmount(w.UID, money); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
default:
|
|
return nil
|
|
}
|
|
}
|