Jelajahi Sumber

提现列表

k.zhang 1 tahun lalu
induk
melakukan
1bff6d6fd3

+ 1 - 1
apis/shanghu/cash.out.go

@@ -50,7 +50,7 @@ func CashOutList(c *gin.Context) {
 			cashOut.Des = "提现失败"
 		} else if cashOutList[i].Status == 3 {
 			cashOut.Des = "提现成功"
-		} else if cashOutList[i].Status == 4 {
+		} else if cashOutList[i].Status == 99 {
 			cashOut.Des = "提现完成"
 		}
 		outData = append(outData, cashOut)

+ 7 - 60
apis/shanghu/pay.go

@@ -180,6 +180,7 @@ func PayCashOut(c *gin.Context) {
 			app.Error(c, 400, errors.New("账号余额不够"), "账号余额不够")
 			return
 		}
+		cashOut.Fee = inData.Amount.Mul(decimal.NewFromFloat32(0.1))
 	} else if inData.AccountType == "merchant" {
 		merchantAccountSql.MerchantOpenID = inData.OpenId
 		merchantAccountInfo, err := merchantAccountSql.GetMerchantAccount()
@@ -191,6 +192,7 @@ func PayCashOut(c *gin.Context) {
 			app.Error(c, 400, errors.New("账号余额不够"), "账号余额不够")
 			return
 		}
+		cashOut.Fee = decimal.NewFromInt(0)
 	} else {
 		app.Error(c, 400, errors.New("账户类型错误"), "账户类型错误")
 		return
@@ -202,7 +204,6 @@ func PayCashOut(c *gin.Context) {
 		return
 	}
 
-	//clientV3.WxPublicKeyMap()
 	userName, err := clientV3.V3EncryptText(inData.UserName)
 	if err != nil {
 		app.Error(c, 400, err, err.Error())
@@ -213,16 +214,10 @@ func PayCashOut(c *gin.Context) {
 	transDetail.TransferAmount = inData.Amount.Sub(cashOut.Fee).Mul(decimal.NewFromInt(100)).IntPart()
 	transDetail.UserName = userName
 	transDetail.Openid = inData.OpenId
-	transDetail.TransferRemark = "报销"
+	transDetail.TransferRemark = "提现"
 
 	trans = append(trans, transDetail)
 
-	//transBody, err := json.Marshal(transDetail)
-	//if err != nil {
-	//	app.Error(c, 500, err, err.Error())
-	//	return
-	//}
-
 	partnerTradeNo := common.GetRandomString(32)
 	var cashOutCreate shanghu.CashOut
 	//创建提现记录
@@ -233,23 +228,21 @@ func PayCashOut(c *gin.Context) {
 	cashOutCreate.CreatedAt = time.Now()
 	cashOutCreate.UpdatedAt = time.Now()
 	cashOutCreate.PartnerTradeNo = partnerTradeNo
-	cashOutCreate.Fee = inData.Amount.Mul(decimal.NewFromFloat32(0.1))
+	cashOutCreate.Fee = cashOut.Fee
 	cashOutInfo, err := cashOutCreate.Create()
 	if err != nil {
 		app.Error(c, 400, err, err.Error())
 		return
 	}
 
-	//client := NewWechatServiceAppid(inData.Appid)
-
 	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(cashOutCreate.Fee).Mul(decimal.NewFromInt(100)).IntPart())
+	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))
 
@@ -258,24 +251,6 @@ func PayCashOut(c *gin.Context) {
 
 	fmt.Println(bm.JsonBody())
 
-	//{
-	//	"appid": "wxf636efh567hg4356",
-	//	"out_batch_no": "plfk2020042013",
-	//	"batch_name": "2019年1月深圳分部报销单",
-	//	"batch_remark": "2019年1月深圳分部报销单",
-	//	"total_amount": 4000000,
-	//	"total_num": 200,
-	//	"transfer_detail_list": [
-	//{
-	//"out_detail_no": "x23zy545Bd5436",
-	//"transfer_amount": 200000,
-	//"transfer_remark": "2020年4月报销",
-	//"openid": "o-MYE42l80oelYMDE34nYD456Xoy",
-	//"user_name": "757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45"
-	//}
-	//]
-	//}
-
 	reply, err := clientV3.V3Transfer(c, bm)
 	if err != nil {
 		cashOut.ID = cashOutInfo.ID
@@ -299,34 +274,6 @@ func PayCashOut(c *gin.Context) {
 	cashOut.PartnerTradeNo = reply.Response.OutBatchNo
 	cashOut.UpdateCashOutWxBachNo()
 
-	//wxResp, err := client.Transfer(c, bm)
-	//if err != nil {
-	//	cashOut.ID = cashOutInfo.ID
-	//	cashOut.FailRes = err.Error()
-	//	cashOut.Status = 2 //提现失败
-	//	cashOut.UpdateMerchantStatus()
-	//
-	//	app.Error(c, 400, err, "提现失败")
-	//	return
-	//}
-	//
-	//if wxResp.ReturnCode != "SUCCESS" {
-	//	cashOut.ID = cashOutInfo.ID
-	//	cashOut.FailRes = wxResp.ReturnMsg
-	//	cashOut.Status = 2 //提现失败
-	//	cashOut.UpdateMerchantStatus()
-	//	app.Error(c, 400, errors.New(wxResp.ReturnMsg), "提现")
-	//	return
-	//}
-	//if wxResp.ResultCode != "SUCCESS" {
-	//	cashOut.ID = cashOutInfo.ID
-	//	cashOut.FailRes = wxResp.ErrCode + "--" + wxResp.ErrCodeDes
-	//	cashOut.Status = 2 //提现失败
-	//	cashOut.UpdateMerchantStatus()
-	//	app.Error(c, 400, errors.New(wxResp.ErrCode+"--"+wxResp.ErrCodeDes), "提现")
-	//	return
-	//}
-
 	app.OK(c, nil, app.Success)
 
 }

+ 35 - 1
models/shanghu/cash.out.go

@@ -2,6 +2,7 @@ package shanghu
 
 import (
 	orm "duoduo/database"
+	"errors"
 	"github.com/shopspring/decimal"
 	"time"
 )
@@ -22,7 +23,8 @@ type CashOut struct {
 	DeletedAt        time.Time       `gorm:"column:deleted_at;type:datetime(3);default:null" json:"deleted_at"`      // 删除时间
 	Fee              decimal.Decimal `gorm:"column:fee;type:decimal(10,2)" json:"fee"`                               // 手续费
 	WxPartnerTradeNo string          `gorm:"column:wx_partner_trade_no;type:varchar(50)" json:"wx_partner_trade_no"` // wx商户卡提现id
-
+	AccountStatus    int32           `gorm:"column:account_status;default:0;comment:'分账状态 99-分账成功 2-分账失败 0-未分账 3-分账中'" json:"account_status"`
+	AccountFailRes   string          `gorm:"column:account_fail_res;type:varchar(255);comment:分账失败原因" json:"account_fail_res"`
 }
 
 func (m *CashOut) TableName() string {
@@ -128,6 +130,38 @@ func (m *CashOut) GetCashOutByStatus() (CashOut, error) {
 
 }
 
+func (m *CashOut) GetCashOutByAccount() (CashOut, error) {
+	var doc CashOut
+
+	table := orm.ShMysql.Table(m.TableName())
+	table = table.Where("status = ? and account_status = ?", m.Status, m.AccountStatus)
+
+	if err := table.Select("*").First(&doc).Error; err != nil {
+		return doc, err
+	}
+	return doc, nil
+
+}
+
+func (m *CashOut) UpdateCashOutAccountStatus() error {
+
+	reply := orm.ShMysql.Table(m.TableName()).Model(&m).Where("id = ? ", m.ID).Updates(
+		map[string]interface{}{
+			"account_status":   m.AccountStatus,
+			"account_fail_res": m.AccountFailRes,
+			"updated_at":       time.Now()})
+
+	if reply.Error != nil {
+		return reply.Error
+	}
+
+	if reply.RowsAffected <= 0 {
+		return errors.New("更新记录0条")
+	}
+
+	return nil
+}
+
 // list 接口使用
 func (m *CashOut) GetCashOutList(pageSize int, pageIndex int) ([]CashOut, int, error) {
 	var doc []CashOut

+ 1 - 1
models/shanghu/client.account.log.go

@@ -11,7 +11,7 @@ type MerchantClientAccountLog struct {
 	ReviewAmountPre   decimal.Decimal `gorm:"column:review_amount_pre;type:decimal(10,2)" json:"review_amount_pre"`     // 审核资金交易前
 	AmountPre         decimal.Decimal `gorm:"column:amount_pre;type:decimal(10,2)" json:"amount_pre"`                   // 交易前
 	AmountAfter       decimal.Decimal `gorm:"column:amount_after;type:decimal(10,2)" json:"amount_after"`               // 交易后
-	TransType         int             `gorm:"column:trans_type;type:int(11)" json:"trans_type"`                         // 交易类型  1-买卡入账 99-提现
+	TransType         int             `gorm:"column:trans_type;type:int(11)" json:"trans_type"`                         // 交易类型  0-买卡入账 99-提现
 	ClientOpenID      string          `gorm:"column:client_open_id;type:varchar(255)" json:"client_open_id"`            // 商户openid
 	CreateBy          int64           `gorm:"column:create_by;type:bigint(20)" json:"create_by"`                        // 创建者
 	UpdateBy          int64           `gorm:"column:update_by;type:bigint(20)" json:"update_by"`                        // 更新者

+ 1 - 1
models/shanghu/merchant.account.log.go

@@ -11,7 +11,7 @@ type MerchantAccountLog struct {
 	ReviewAmountPre   decimal.Decimal `gorm:"column:review_amount_pre;type:decimal(10,2)" json:"review_amount_pre"`     // 审核资金 交易前
 	AmountPre         decimal.Decimal `gorm:"column:amount_pre;type:decimal(10,2)" json:"amount_pre"`                   // 交易前
 	AmountAfter       decimal.Decimal `gorm:"column:amount_after;type:decimal(10,2)" json:"amount_after"`               // 交易后
-	TransType         int             `gorm:"column:trans_type;type:int(11)" json:"trans_type"`                         // 交易类型  1-买卡入账 2-资金审核入账 99-提现
+	TransType         int             `gorm:"column:trans_type;type:int(11)" json:"trans_type"`                         // 交易类型  0-买卡入账  2-提现
 	MerchantOpenID    string          `gorm:"column:merchant_open_id;type:varchar(255)" json:"merchant_open_id"`        // 商户openid
 	CreateBy          int64           `gorm:"column:create_by;type:bigint(20)" json:"create_by"`                        // 创建者
 	UpdateBy          int64           `gorm:"column:update_by;type:bigint(20)" json:"update_by"`                        // 更新者

+ 171 - 6
models/shanghu/pay.go

@@ -2,6 +2,7 @@ package shanghu
 
 import (
 	orm "duoduo/database"
+	"errors"
 	"fmt"
 	"github.com/shopspring/decimal"
 	"time"
@@ -235,12 +236,17 @@ func (m *ClientPayTrans) SettleAdd(merchantAmount, clientAmount decimal.Decimal,
 
 	//做金额加减操作并且入日志库
 	merchantAmountAdd := merchantAccount.Amount.Add(merchantAmount)
-	err = tx.Table("merchant_account").Model(&merchantAccount).Where("merchant_open_id = ? and version = ?", merchantOpenId, merchantAccount.Version).Updates(
+	result := tx.Table("merchant_account").Model(&merchantAccount).Where("merchant_open_id = ? and version = ?", merchantOpenId, merchantAccount.Version).Updates(
 		map[string]interface{}{
 			"amount":     merchantAmountAdd,
 			"version":    merchantAccount.Version + 1,
-			"updated_at": time.Now()}).Error
-	if err != nil {
+			"updated_at": time.Now()})
+
+	if result.Error != nil {
+		return result.Error
+	}
+	if result.RowsAffected <= 0 {
+		err = errors.New("rows is zero")
 		return err
 	}
 
@@ -263,12 +269,17 @@ func (m *ClientPayTrans) SettleAdd(merchantAmount, clientAmount decimal.Decimal,
 	}
 
 	clientAmountAdd := clientAccount.Amount.Add(clientAmount)
-	err = tx.Table("merchant_client_account").Model(&clientAccount).Where("client_open_id = ? and version = ?", clientOpenId, clientAccount.Version).Updates(
+	result = tx.Table("merchant_client_account").Model(&clientAccount).Where("client_open_id = ? and version = ?", clientOpenId, clientAccount.Version).Updates(
 		map[string]interface{}{
 			"amount":     clientAmountAdd,
 			"version":    clientAccount.Version + 1,
-			"updated_at": time.Now()}).Error
-	if err != nil {
+			"updated_at": time.Now()})
+	if result.Error != nil {
+		return result.Error
+	}
+
+	if result.RowsAffected <= 0 {
+		err = errors.New("rows is zero")
 		return err
 	}
 
@@ -291,3 +302,157 @@ func (m *ClientPayTrans) SettleAdd(merchantAmount, clientAmount decimal.Decimal,
 	return nil
 
 }
+
+func (m *ClientPayTrans) SettleSubClient(clientAmount decimal.Decimal, clientOpenId string, cashOutId int64) error {
+	// 使用事务 添加
+	var err error
+	var clientAccount MerchantClientAccount
+	var cashOut CashOut
+	var amountPreClient decimal.Decimal
+	tx := orm.ShMysql.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	err = tx.Table("merchant_client_account").Select("*").Where("client_open_id = ?", clientOpenId).Find(&clientAccount).Error
+	if err != nil {
+		return err
+	}
+
+	amountPreClient = clientAccount.Amount
+
+	if clientAccount.Amount.Cmp(clientAmount) < 0 {
+		err = errors.New("账户金额不够")
+		return err
+	}
+
+	clientAmountSub := clientAccount.Amount.Sub(clientAmount)
+	result := tx.Table("merchant_client_account").Model(&clientAccount).Where("client_open_id = ? and version = ?", clientOpenId, clientAccount.Version).Updates(
+		map[string]interface{}{
+			"amount":     clientAmountSub,
+			"version":    clientAccount.Version + 1,
+			"updated_at": time.Now()})
+	if result.Error != nil {
+		return result.Error
+	}
+
+	if result.RowsAffected <= 0 {
+		err = errors.New("rows is zero")
+		return err
+	}
+
+	var clientAccountLog MerchantClientAccountLog
+
+	clientAccountLog.ClientOpenID = clientOpenId
+	clientAccountLog.UpdatedAt = time.Now()
+	clientAccountLog.AmountPre = amountPreClient
+	clientAccountLog.AmountAfter = clientAmountSub
+	clientAccountLog.ReviewAmountAfter = clientAccount.ReviewAmount
+	clientAccountLog.ReviewAmountPre = clientAccount.ReviewAmount
+	clientAccountLog.Amount = clientAmount
+	clientAccountLog.PayTransId = cashOutId
+	clientAccountLog.TransType = 2
+
+	err = tx.Table("merchant_client_account_log").Create(&clientAccountLog).Error
+	if err != nil {
+		return err
+	}
+
+	result = tx.Table("cash_out").Model(&cashOut).Where("id = ? ", cashOutId).Updates(
+		map[string]interface{}{
+			"status":         99, //体现成功
+			"account_status": 99, //分账成功
+			"updated_at":     time.Now()})
+	if result.Error != nil {
+		return result.Error
+	}
+
+	if result.RowsAffected <= 0 {
+		err = errors.New("rows is zero")
+		return err
+	}
+
+	return nil
+
+}
+
+func (m *ClientPayTrans) SettleSubMerchant(merchantAmount decimal.Decimal, merchantOpenId string, cashOutId int64) error {
+	// 使用事务 添加
+	var err error
+	var merchantAccount MerchantAccount
+	var cashOut CashOut
+	var amountPreMerchant decimal.Decimal
+	tx := orm.ShMysql.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+
+	err = tx.Table("merchant_account").Select("*").Where("merchant_open_id = ?", merchantOpenId).Find(&merchantAccount).Error
+	if err != nil {
+		return err
+	}
+
+	amountPreMerchant = merchantAccount.Amount
+
+	if merchantAccount.Amount.Cmp(merchantAmount) < 0 {
+		err = errors.New("账户金额不够")
+		return err
+	}
+
+	merchantAmountSub := merchantAccount.Amount.Sub(merchantAmount)
+	result := tx.Table("merchant_account").Model(&merchantAccount).Where("merchant_open_id = ? and version = ?", merchantOpenId, merchantAccount.Version).Updates(
+		map[string]interface{}{
+			"amount":     merchantAmountSub,
+			"version":    merchantAccount.Version + 1,
+			"updated_at": time.Now()})
+	if result.Error != nil {
+		return result.Error
+	}
+
+	if result.RowsAffected <= 0 {
+		err = errors.New("rows is zero")
+		return err
+	}
+
+	var merchantAccountLog MerchantAccountLog
+
+	merchantAccountLog.MerchantOpenID = merchantOpenId
+	merchantAccountLog.UpdatedAt = time.Now()
+	merchantAccountLog.AmountPre = amountPreMerchant
+	merchantAccountLog.AmountAfter = merchantAmountSub
+	merchantAccountLog.ReviewAmountAfter = merchantAccount.ReviewAmount
+	merchantAccountLog.ReviewAmountPre = merchantAccount.ReviewAmount
+	merchantAccountLog.Amount = merchantAmount
+	merchantAccountLog.PayTransId = cashOutId
+	merchantAccountLog.TransType = 2
+
+	err = tx.Table("merchant_account_log").Create(&merchantAccountLog).Error
+	if err != nil {
+		return err
+	}
+
+	result = tx.Table("cash_out").Model(&cashOut).Where("id = ? ", cashOutId).Updates(
+		map[string]interface{}{
+			"status":         99, //体现成功
+			"account_status": 99, //分账成功
+			"updated_at":     time.Now()})
+	if result.Error != nil {
+		return result.Error
+	}
+
+	if result.RowsAffected <= 0 {
+		err = errors.New("rows is zero")
+		return err
+	}
+
+	return nil
+
+}

+ 47 - 0
report/cash.out.go

@@ -69,3 +69,50 @@ func CashOut() {
 		}
 	}
 }
+
+func CashOutAccount() {
+	for true {
+		var cashOut shanghu.CashOut
+		cashOut.AccountStatus = 0 //未分账
+		cashOut.Status = 3        //钱已到账为扣减金额
+
+		cashOutInfo, err := cashOut.GetCashOutByAccount()
+		if err != nil {
+			break
+		}
+
+		cashOut.AccountStatus = 3 //分账中
+		cashOut.ID = cashOutInfo.ID
+		err = cashOut.UpdateCashOutAccountStatus()
+		if err != nil {
+			break
+		}
+
+		if cashOutInfo.AppID == "wxef36f8713d6469b5" { //b端 商户卡
+			var account shanghu.ClientPayTrans
+			err = account.SettleSubMerchant(cashOutInfo.Amount, cashOutInfo.OpenID, cashOutInfo.ID)
+			if err != nil {
+				cashOut.AccountStatus = 2 //分账失败
+				cashOut.AccountFailRes = err.Error()
+				cashOut.ID = cashOutInfo.ID
+				cashOut.UpdateCashOutAccountStatus()
+
+				continue
+			}
+
+		} else if cashOutInfo.AppID == "wx25357518f710b8ce" { //c端 周末传媒
+			var account shanghu.ClientPayTrans
+			err = account.SettleSubClient(cashOutInfo.Amount, cashOutInfo.OpenID, cashOutInfo.ID)
+			if err != nil {
+				cashOut.AccountStatus = 2 //分账失败
+				cashOut.AccountFailRes = err.Error()
+				cashOut.ID = cashOutInfo.ID
+				cashOut.UpdateCashOutAccountStatus()
+				continue
+			}
+		} else {
+			continue
+		}
+
+	}
+}

+ 4 - 1
report/report.go

@@ -5,12 +5,15 @@ import "github.com/robfig/cron"
 const (
 	cronSettDateCutoff = "0 0 1 * * *"   //每天凌晨1:00:00
 	cronRunStart       = "0 0 17 * * *"  //凌晨一点
-	cronMinuteStart    = "0 */1 * * * *" //每10分钟
+	cronMinuteStart    = "0 */1 * * * *" //每1分钟
+	cronMinuteTwoStart = "0 */2 * * * *" //每2分钟
+
 )
 
 func SysCronStart() {
 	c := cron.New()
 	c.AddFunc(cronMinuteStart, ClientAccount) //每分钟同步一下订单
 	c.AddFunc(cronMinuteStart, CashOut)       //每分钟同步一下订单
+	c.AddFunc(cronMinuteTwoStart, CashOutAccount)
 	c.Start()
 }