active.cash.out.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package shanghu
  2. import (
  3. "duoduo/apis/common"
  4. "duoduo/apis/shanghu/models"
  5. "duoduo/models/shanghu"
  6. "duoduo/tools/app"
  7. "errors"
  8. "fmt"
  9. "github.com/gin-gonic/gin"
  10. "github.com/go-pay/gopay"
  11. "github.com/shopspring/decimal"
  12. "time"
  13. )
  14. func ActiveCashOut(c *gin.Context) {
  15. var inData models.PayCashOutRequest
  16. var clientAccountSql shanghu.ActiveClientAccount
  17. var cashOut shanghu.CashOut
  18. var trans []models.TransferDetailList
  19. var transDetail models.TransferDetailList
  20. err := c.ShouldBindJSON(&inData)
  21. if err != nil {
  22. app.Error(c, 400, err, err.Error())
  23. return
  24. }
  25. _, ok := GlobalCashOutMap[inData.OpenId]
  26. if ok {
  27. app.OK(c, nil, "正在提现中...")
  28. return
  29. }
  30. GlobalCashOutMap[inData.OpenId] = 1
  31. defer func() {
  32. delete(GlobalCashOutMap, inData.OpenId)
  33. }()
  34. if inData.Appid == "" { //appid 不能为空
  35. app.Error(c, 400, errors.New("AppID不能为空"), "AppID不能为空")
  36. return
  37. }
  38. if inData.Amount.Cmp(decimal.NewFromInt(500)) > 0 {
  39. app.Error(c, 400, errors.New("单笔金额不能大于500"), "单笔金额不能大于500")
  40. return
  41. }
  42. if inData.Amount.Cmp(decimal.NewFromInt(1)) < 0 {
  43. app.Error(c, 400, errors.New("单笔金额不能小于1"), "单笔金额不能大于1")
  44. return
  45. }
  46. //
  47. cashOut.OpenID = inData.OpenId
  48. cashOut.AppID = inData.Appid
  49. cashOut.Status = 1 //提现中
  50. status := []int{1, 3} //提现中、金额待扣减
  51. cashNum := cashOut.GetCashOutByStatusNum(status)
  52. if cashNum > 0 {
  53. app.Error(c, 400, errors.New("有一笔交易正在提现中"), "有一笔交易正在提现中")
  54. return
  55. }
  56. //校验金额是否够
  57. if inData.AccountType == "client" {
  58. clientAccountSql.ClientOpenID = inData.OpenId
  59. clientAccountInfo, err := clientAccountSql.GetActiveAccount()
  60. if err != nil {
  61. app.Error(c, 400, err, err.Error())
  62. return
  63. }
  64. if inData.Amount.Cmp(clientAccountInfo.Amount) > 0 {
  65. app.Error(c, 400, errors.New("账号余额不够"), "账号余额不够")
  66. return
  67. }
  68. var client shanghu.ActiveUser
  69. client.Code = "7jb6"
  70. clientInfo, _ := client.GetUserInfoByCode()
  71. if clientInfo.OpenID == inData.OpenId {
  72. cashOut.Fee = decimal.NewFromInt(0)
  73. } else {
  74. cashOut.Fee = inData.Amount.Mul(decimal.NewFromFloat32(0.05))
  75. }
  76. } else {
  77. app.Error(c, 400, errors.New("账户类型错误"), "账户类型错误")
  78. return
  79. }
  80. clientV3, err := NewWechatServiceV3(inData.Appid)
  81. if err != nil {
  82. app.Error(c, 400, err, err.Error())
  83. return
  84. }
  85. userName, err := clientV3.V3EncryptText(inData.UserName)
  86. if err != nil {
  87. app.Error(c, 400, err, err.Error())
  88. return
  89. }
  90. transDetail.OutDetailNo = common.GetRandomString(32)
  91. transDetail.TransferAmount = inData.Amount.Sub(cashOut.Fee).Mul(decimal.NewFromInt(100)).IntPart()
  92. transDetail.UserName = userName
  93. transDetail.Openid = inData.OpenId
  94. transDetail.TransferRemark = "活动提现"
  95. trans = append(trans, transDetail)
  96. partnerTradeNo := common.GetRandomString(32)
  97. var cashOutCreate shanghu.CashOut
  98. //创建提现记录
  99. cashOutCreate.AppID = inData.Appid
  100. cashOutCreate.Status = 1 //提现中
  101. cashOutCreate.OpenID = inData.OpenId
  102. cashOutCreate.Amount = inData.Amount
  103. cashOutCreate.CreatedAt = time.Now()
  104. cashOutCreate.UpdatedAt = time.Now()
  105. cashOutCreate.PartnerTradeNo = partnerTradeNo
  106. cashOutCreate.Fee = cashOut.Fee
  107. cashOutInfo, err := cashOutCreate.Create()
  108. if err != nil {
  109. app.Error(c, 400, err, err.Error())
  110. return
  111. }
  112. var bMap []gopay.BodyMap
  113. bm := make(gopay.BodyMap)
  114. bm.Set("appid", inData.Appid)
  115. bm.Set("out_batch_no", partnerTradeNo)
  116. bm.Set("batch_name", "活动提现")
  117. bm.Set("batch_remark", "活动提现")
  118. bm.Set("total_amount", inData.Amount.Sub(cashOut.Fee).Mul(decimal.NewFromInt(100)).IntPart())
  119. bm.Set("total_num", 1)
  120. bMap = append(bMap, structToMap(&transDetail))
  121. bm.Set("transfer_detail_list", bMap)
  122. bm.Set("transfer_scene_id", "1001")
  123. fmt.Println(bm.JsonBody())
  124. reply, err := clientV3.V3Transfer(c, bm)
  125. if err != nil {
  126. cashOut.ID = cashOutInfo.ID
  127. cashOut.FailRes = err.Error()
  128. cashOut.Status = 2 //提现失败
  129. cashOut.UpdateMerchantStatus()
  130. app.Error(c, 500, err, err.Error())
  131. return
  132. }
  133. if reply.Code != 0 {
  134. cashOut.ID = cashOutInfo.ID
  135. cashOut.FailRes = reply.Error
  136. cashOut.Status = 2 //提现失败
  137. cashOut.UpdateMerchantStatus()
  138. app.Error(c, 500, errors.New(reply.Error), reply.Error)
  139. return
  140. }
  141. cashOut.WxPartnerTradeNo = reply.Response.BatchId
  142. cashOut.PartnerTradeNo = reply.Response.OutBatchNo
  143. cashOut.UpdateCashOutWxBachNo()
  144. app.OK(c, nil, app.Success)
  145. }