|
@@ -0,0 +1,183 @@
|
|
|
+package shanghu
|
|
|
+
|
|
|
+import (
|
|
|
+ "duoduo/apis/common"
|
|
|
+ "duoduo/apis/shanghu/models"
|
|
|
+ "duoduo/models/shanghu"
|
|
|
+ "duoduo/tools/app"
|
|
|
+ "errors"
|
|
|
+ "fmt"
|
|
|
+ "github.com/gin-gonic/gin"
|
|
|
+ "github.com/go-pay/gopay"
|
|
|
+ "github.com/shopspring/decimal"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+func ActiveCashOut(c *gin.Context) {
|
|
|
+ var inData models.PayCashOutRequest
|
|
|
+ var merchantAccountSql shanghu.MerchantAccount
|
|
|
+ var clientAccountSql shanghu.MerchantClientAccount
|
|
|
+ var cashOut shanghu.CashOut
|
|
|
+ var trans []models.TransferDetailList
|
|
|
+ var transDetail models.TransferDetailList
|
|
|
+
|
|
|
+ err := c.ShouldBindJSON(&inData)
|
|
|
+ if err != nil {
|
|
|
+ app.Error(c, 400, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ _, ok := GlobalCashOutMap[inData.OpenId]
|
|
|
+ if ok {
|
|
|
+ app.OK(c, nil, "正在提现中...")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ GlobalCashOutMap[inData.OpenId] = 1
|
|
|
+ defer func() {
|
|
|
+ delete(GlobalCashOutMap, inData.OpenId)
|
|
|
+ }()
|
|
|
+ if inData.Appid == "" { //appid 不能为空
|
|
|
+ app.Error(c, 400, errors.New("AppID不能为空"), "AppID不能为空")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if inData.Amount.Cmp(decimal.NewFromInt(500)) > 0 {
|
|
|
+ app.Error(c, 400, errors.New("单笔金额不能大于500"), "单笔金额不能大于500")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if inData.Amount.Cmp(decimal.NewFromInt(1)) < 0 {
|
|
|
+ app.Error(c, 400, errors.New("单笔金额不能小于1"), "单笔金额不能大于1")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ cashOut.OpenID = inData.OpenId
|
|
|
+ cashOut.AppID = inData.Appid
|
|
|
+ cashOut.Status = 1 //提现中
|
|
|
+ status := []int{1, 3} //提现中、金额待扣减
|
|
|
+
|
|
|
+ cashNum := cashOut.GetCashOutByStatusNum(status)
|
|
|
+ if cashNum > 0 {
|
|
|
+ app.Error(c, 400, errors.New("有一笔交易正在提现中"), "有一笔交易正在提现中")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //校验金额是否够
|
|
|
+ if inData.AccountType == "client" {
|
|
|
+ clientAccountSql.ClientOpenID = inData.OpenId
|
|
|
+ clientAccountInfo, err := clientAccountSql.GetClientAccount()
|
|
|
+ if err != nil {
|
|
|
+ app.Error(c, 400, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if inData.Amount.Cmp(clientAccountInfo.Amount) > 0 {
|
|
|
+ app.Error(c, 400, errors.New("账号余额不够"), "账号余额不够")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var client shanghu.MerchantClientUser
|
|
|
+ client.Code = "7jb6"
|
|
|
+ clientInfo, _ := client.GetUserInfoByCode()
|
|
|
+ if clientInfo.ClientOpenID == inData.OpenId {
|
|
|
+ cashOut.Fee = decimal.NewFromInt(0)
|
|
|
+ } else {
|
|
|
+ cashOut.Fee = inData.Amount.Mul(decimal.NewFromFloat32(0.05))
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if inData.AccountType == "merchant" {
|
|
|
+ merchantAccountSql.MerchantOpenID = inData.OpenId
|
|
|
+ merchantAccountInfo, err := merchantAccountSql.GetMerchantAccount()
|
|
|
+ if err != nil {
|
|
|
+ app.Error(c, 400, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if inData.Amount.Cmp(merchantAccountInfo.Amount) > 0 {
|
|
|
+ app.Error(c, 400, errors.New("账号余额不够"), "账号余额不够")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ cashOut.Fee = decimal.NewFromInt(0)
|
|
|
+ } else {
|
|
|
+ app.Error(c, 400, errors.New("账户类型错误"), "账户类型错误")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ clientV3, err := NewWechatServiceV3(inData.Appid)
|
|
|
+ if err != nil {
|
|
|
+ app.Error(c, 400, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ userName, err := clientV3.V3EncryptText(inData.UserName)
|
|
|
+ if err != nil {
|
|
|
+ app.Error(c, 400, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ transDetail.OutDetailNo = common.GetRandomString(32)
|
|
|
+ transDetail.TransferAmount = inData.Amount.Sub(cashOut.Fee).Mul(decimal.NewFromInt(100)).IntPart()
|
|
|
+ transDetail.UserName = userName
|
|
|
+ transDetail.Openid = inData.OpenId
|
|
|
+ transDetail.TransferRemark = "提现"
|
|
|
+
|
|
|
+ trans = append(trans, transDetail)
|
|
|
+
|
|
|
+ partnerTradeNo := common.GetRandomString(32)
|
|
|
+ var cashOutCreate shanghu.CashOut
|
|
|
+ //创建提现记录
|
|
|
+ cashOutCreate.AppID = inData.Appid
|
|
|
+ cashOutCreate.Status = 1 //提现中
|
|
|
+ cashOutCreate.OpenID = inData.OpenId
|
|
|
+ cashOutCreate.Amount = inData.Amount
|
|
|
+ cashOutCreate.CreatedAt = time.Now()
|
|
|
+ cashOutCreate.UpdatedAt = time.Now()
|
|
|
+ cashOutCreate.PartnerTradeNo = partnerTradeNo
|
|
|
+ cashOutCreate.Fee = cashOut.Fee
|
|
|
+ cashOutInfo, err := cashOutCreate.Create()
|
|
|
+ if err != nil {
|
|
|
+ app.Error(c, 400, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ var bMap []gopay.BodyMap
|
|
|
+ bm := make(gopay.BodyMap)
|
|
|
+
|
|
|
+ bm.Set("appid", inData.Appid)
|
|
|
+ bm.Set("out_batch_no", partnerTradeNo)
|
|
|
+ bm.Set("batch_name", "提现")
|
|
|
+ bm.Set("batch_remark", "提现")
|
|
|
+ bm.Set("total_amount", inData.Amount.Sub(cashOut.Fee).Mul(decimal.NewFromInt(100)).IntPart())
|
|
|
+ bm.Set("total_num", 1)
|
|
|
+ bMap = append(bMap, structToMap(&transDetail))
|
|
|
+
|
|
|
+ bm.Set("transfer_detail_list", bMap)
|
|
|
+ bm.Set("transfer_scene_id", "1001")
|
|
|
+
|
|
|
+ fmt.Println(bm.JsonBody())
|
|
|
+
|
|
|
+ reply, err := clientV3.V3Transfer(c, bm)
|
|
|
+ if err != nil {
|
|
|
+ cashOut.ID = cashOutInfo.ID
|
|
|
+ cashOut.FailRes = err.Error()
|
|
|
+ cashOut.Status = 2 //提现失败
|
|
|
+ cashOut.UpdateMerchantStatus()
|
|
|
+ app.Error(c, 500, err, err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if reply.Code != 0 {
|
|
|
+ cashOut.ID = cashOutInfo.ID
|
|
|
+ cashOut.FailRes = reply.Error
|
|
|
+ cashOut.Status = 2 //提现失败
|
|
|
+ cashOut.UpdateMerchantStatus()
|
|
|
+ app.Error(c, 500, errors.New(reply.Error), reply.Error)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ cashOut.WxPartnerTradeNo = reply.Response.BatchId
|
|
|
+ cashOut.PartnerTradeNo = reply.Response.OutBatchNo
|
|
|
+ cashOut.UpdateCashOutWxBachNo()
|
|
|
+
|
|
|
+ app.OK(c, nil, app.Success)
|
|
|
+
|
|
|
+}
|