Преглед изворни кода

fix: confirm withdraw transfer directly

Codex пре 1 месец
родитељ
комит
c8898df8a4

+ 178 - 24
go/gopath/src/fohow.com/apps/controllers/balance_controller/balance_controller.go

@@ -3,7 +3,6 @@ package balance_controller
 import (
 	"fmt"
 	"fohow.com/apps/models/sys_config"
-	"fohow.com/libs/lib_redis"
 	"fohow.com/libs/tool"
 	"fohow.com/libs/wx_mp"
 	"github.com/astaxie/beego"
@@ -280,15 +279,187 @@ func (self *BalanceController) TakeCash() {
 		o.Count = amount - fee //实际提现金额扣取手续费
 		o.Save()
 	}
-	//提现成功加入提现处理队列
-	cashKey := lib_redis.GetAutoTakeCashList()
-	takeId := fmt.Sprintf("%d", o.Id)
-	lib_redis.ThrowInRedisList(cashKey, takeId)
+	if o == nil {
+		self.ReturnError(500, apps.ParamsError, "", nil)
+	}
+
+	ret, err := createTakeCashMerchantTransfer(o, wxUser)
+	if err != nil {
+		markTakeCashCancelled(o)
+		refundTakeCashCancel(o)
+		self.ReturnError(500, []string{"merchantTransferFailed", "微信提现发起失败,请稍后重试"}, "", nil)
+	}
+
+	self.Data["json"] = buildTakeCashConfirmResponse(o, wxUser, ret)
+	self.ServeJSON()
+}
 
-	self.Data["json"] = o
+func (self *BalanceController) CancelTakeCash() {
+	orderId := strings.TrimSpace(self.GetString("order_id"))
+	id, _ := self.GetInt64("id")
+	var order *balance_model.TakeCashOrder
+	if orderId != "" {
+		order = balance_model.GetTakeCashOrderByOId(orderId, false)
+	} else if id > 0 {
+		order = balance_model.GetTakeCashOrderById(id, false)
+	}
+	if order == nil {
+		self.ReturnError(404, apps.NoExist, "", nil)
+	}
+	wxUser := self.GetCurrentWxUser(false)
+	if wxUser == nil || order.WxUId != wxUser.Id {
+		self.ReturnError(403, apps.OrderNotExist, "", nil)
+	}
+	if order.State == 1 {
+		self.ReturnError(403, []string{"takeCashAlreadyPaid", "提现已到账,不能取消"}, "", nil)
+	}
+	if order.State == 2 {
+		self.Data["json"] = buildTakeCashConfirmResponse(order, wxUser, nil)
+		self.ServeJSON()
+		return
+	}
+	if order.TradeNo != "" || strings.Contains(order.Remark, "商家转账状态:") {
+		payCode := sys_config.GetPayConfigByDepart(wxUser.Depart, true)
+		ret, err := wx_mp.QueryMerchantTransferByOutBillNo(order.OrderId, payCode)
+		if err != nil || ret == nil {
+			beego.BeeLogger.Error("CancelTakeCash query transfer order[%s] err[%v]", order.OrderId, err)
+			self.ReturnError(500, []string{"cancelTakeCashFailed", "取消提现失败,请稍后重试"}, "", nil)
+		}
+		if ret.State == wx_mp.MerchantTransferSuccess {
+			applyTakeCashMerchantTransferResult(order, ret)
+			self.ReturnError(403, []string{"takeCashAlreadyPaid", "提现已到账,不能取消"}, "", nil)
+		}
+		if wx_mp.MerchantTransferStatePending(ret.State) && ret.State != wx_mp.MerchantTransferCanceling {
+			cancelRet, err := wx_mp.CancelMerchantTransferByOutBillNo(order.OrderId, payCode)
+			if err != nil || cancelRet == nil {
+				beego.BeeLogger.Error("CancelTakeCash cancel transfer order[%s] err[%v]", order.OrderId, err)
+				self.ReturnError(500, []string{"cancelTakeCashFailed", "取消提现失败,请稍后重试"}, "", nil)
+			}
+			ret = cancelRet
+		}
+	}
+	markTakeCashCancelled(order)
+	refundTakeCashCancel(order)
+	self.Data["json"] = buildTakeCashConfirmResponse(order, wxUser, nil)
 	self.ServeJSON()
 }
 
+type TakeCashConfirmResponse struct {
+	Id            int64  `json:"id"`
+	OrderId       string `json:"order_id"`
+	Count         int64  `json:"count"`
+	Fee           int64  `json:"fee"`
+	State         int64  `json:"pay_state"`
+	AuditState    int64  `json:"audit_state"`
+	Remark        string `json:"remark"`
+	MchId         string `json:"mch_id"`
+	AppId         string `json:"app_id"`
+	PackageInfo   string `json:"package_info"`
+	TransferState string `json:"transfer_state"`
+	CanConfirm    bool   `json:"can_confirm_transfer"`
+}
+
+func createTakeCashMerchantTransfer(order *balance_model.TakeCashOrder, wxUser *user_model.WxUser) (*wx_mp.MerchantTransferResponse, error) {
+	if order == nil || wxUser == nil {
+		return nil, fmt.Errorf("take cash order or wx user missing")
+	}
+	if order.AuditState != 1 {
+		order.AuditState = 1
+		order.Save()
+	}
+	payCode := sys_config.GetPayConfigByDepart(wxUser.Depart, true)
+	ret, err := wx_mp.MerchantTransfer(wxUser.Openid, order.Count, order.OrderId, payCode, "佣金提现")
+	if err != nil {
+		beego.BeeLogger.Error("TakeCash MerchantTransfer order[%s] err[%s]", order.OrderId, err)
+		if ret != nil && ret.Message != "" {
+			order.State = 2
+			order.Remark = truncateTakeCashRemark(ret.Message)
+			order.Save()
+		}
+		return ret, err
+	}
+	applyTakeCashMerchantTransferResult(order, ret)
+	return ret, nil
+}
+
+func buildTakeCashConfirmResponse(order *balance_model.TakeCashOrder, wxUser *user_model.WxUser, ret *wx_mp.MerchantTransferResponse) *TakeCashConfirmResponse {
+	mchId, appId, packageInfo, transferState, canConfirm := getMerchantTransferConfirmInfo(wxUser, order)
+	if ret != nil {
+		if ret.PackageInfo != "" {
+			packageInfo = ret.PackageInfo
+		}
+		if ret.State != "" {
+			transferState = ret.State
+		}
+		canConfirm = order.State == 0 && order.AuditState == 1 && packageInfo != "" && transferState == wx_mp.MerchantTransferWaitUserConfirm
+	}
+	return &TakeCashConfirmResponse{
+		Id:            order.Id,
+		OrderId:       order.OrderId,
+		Count:         order.Count,
+		Fee:           order.Fee,
+		State:         order.State,
+		AuditState:    order.AuditState,
+		Remark:        order.Remark,
+		MchId:         mchId,
+		AppId:         appId,
+		PackageInfo:   packageInfo,
+		TransferState: transferState,
+		CanConfirm:    canConfirm,
+	}
+}
+
+func applyTakeCashMerchantTransferResult(order *balance_model.TakeCashOrder, ret *wx_mp.MerchantTransferResponse) {
+	if order == nil || ret == nil {
+		return
+	}
+	if ret.TransferBillNo != "" {
+		order.TradeNo = ret.TransferBillNo
+	}
+	switch ret.State {
+	case wx_mp.MerchantTransferSuccess:
+		order.State = 1
+		order.Remark = "商家转账已成功"
+		order.PaiedAt = time.Now().Unix()
+	case wx_mp.MerchantTransferFail, wx_mp.MerchantTransferCancelled:
+		order.State = 2
+		order.Remark = truncateTakeCashRemark(firstNotEmpty(ret.FailReason, ret.Message, ret.State))
+	default:
+		if wx_mp.MerchantTransferStatePending(ret.State) {
+			order.State = 0
+			order.Remark = truncateTakeCashRemark(merchantTransferPendingRemark(ret, order.Remark))
+		} else {
+			order.State = 0
+			order.Remark = truncateTakeCashRemark(firstNotEmpty(ret.Message, ret.State, "商家转账已受理"))
+		}
+	}
+	order.Save()
+}
+
+func markTakeCashCancelled(order *balance_model.TakeCashOrder) {
+	if order == nil {
+		return
+	}
+	order.State = 2
+	order.Remark = "用户取消提现"
+	order.Save()
+}
+
+func refundTakeCashCancel(order *balance_model.TakeCashOrder) bool {
+	if order == nil {
+		return false
+	}
+	amount := order.Count + order.Fee
+	if amount <= 0 {
+		return false
+	}
+	if balance_model.GetCashBalanceBySourceAndRId(balance_model.CASH_SOURCE_TAKE_CASH_CANCEL, order.OrderId) != nil {
+		return false
+	}
+	item := new(balance_model.CashBalance).Create(order.WxUId, amount, balance_model.CASH_SOURCE_TAKE_CASH_CANCEL, order.OrderId, balance_model.CASH_SOURCE_TAKE_CASH_CANCEL_NAME)
+	return item != nil
+}
+
 // 获取提现限额
 func (self *BalanceController) GetTakeCashLimit() {
 	type LimitInfo struct {
@@ -410,24 +581,7 @@ func syncTakeCashMerchantTransfer(wxUser *user_model.WxUser, order *balance_mode
 	if err != nil || ret == nil {
 		return
 	}
-	if ret.TransferBillNo != "" {
-		order.TradeNo = ret.TransferBillNo
-	}
-	switch ret.State {
-	case wx_mp.MerchantTransferSuccess:
-		order.State = 1
-		order.Remark = "商家转账已成功"
-		order.PaiedAt = time.Now().Unix()
-	case wx_mp.MerchantTransferFail, wx_mp.MerchantTransferCancelled:
-		order.State = 2
-		order.Remark = truncateTakeCashRemark(firstNotEmpty(ret.FailReason, ret.Message, ret.State))
-	default:
-		if wx_mp.MerchantTransferStatePending(ret.State) {
-			order.State = 0
-			order.Remark = truncateTakeCashRemark(merchantTransferPendingRemark(ret, order.Remark))
-		}
-	}
-	order.Save()
+	applyTakeCashMerchantTransferResult(order, ret)
 }
 
 func getMerchantTransferState(remark string) string {

+ 2 - 2
go/gopath/src/fohow.com/apps/controllers/cron_controller/init.go

@@ -77,8 +77,8 @@ func (self *CronController) run(name string) {
 func exec(name string) {
 	switch name {
 	case "take_cash": //提现
-		//takeCash()
-		autoTakeCash() //redis队列处理
+		beego.BeeLogger.Warn("cron task take_cash auto audit is disabled")
+		return
 	case "admin_take_cash": //提现
 		takeCash()
 	case "orderReceiveAutomatically": //已发货订单7天自动收货

+ 4 - 0
go/gopath/src/fohow.com/apps/models/balance_model/cash_balance.go

@@ -41,6 +41,8 @@ const (
 	CASH_SOURCE_EXTRACT_REJECT_NAME    = "拒绝提现"           //拒绝提现
 	CASH_SOURCE_TAKE_CASH_TIMEOUT      = "take_cash_timeout"
 	CASH_SOURCE_TAKE_CASH_TIMEOUT_NAME = "提现超时退回"
+	CASH_SOURCE_TAKE_CASH_CANCEL       = "take_cash_cancel"
+	CASH_SOURCE_TAKE_CASH_CANCEL_NAME  = "取消提现退回"
 	CASH_SOURCE_PRODUCT_BENEFIT        = "product_benefit" // 一级商品佣金
 	CASH_SOURCE_PRODUCT_BENEFIT_NAME   = "商品佣金"
 	CASH_SOURCE_SHOP_BENEFIT           = "shop_benefit" // 一级商品佣金
@@ -186,6 +188,8 @@ func (self *CashBalance) GetSourceName() string {
 		sourceName = CASH_SOURCE_EXTRACT_REJECT_NAME
 	case CASH_SOURCE_TAKE_CASH_TIMEOUT:
 		sourceName = CASH_SOURCE_TAKE_CASH_TIMEOUT_NAME
+	case CASH_SOURCE_TAKE_CASH_CANCEL:
+		sourceName = CASH_SOURCE_TAKE_CASH_CANCEL_NAME
 	case CASH_SOURCE_RECHARGE_CASH:
 		sourceName = CASH_SOURCE_RECHARGE_CASH_NAME
 	case CASH_SOURCE_RECEIVE_BUYBACK:

+ 2 - 0
go/gopath/src/fohow.com/routers/routes.go

@@ -225,6 +225,8 @@ func init() {
 
 	//提现
 	beego.Router("/v1/user/takecash", &balance_controller.BalanceController{}, "post:TakeCash")
+	//取消提现
+	beego.Router("/v1/user/takecash/cancel", &balance_controller.BalanceController{}, "post:CancelTakeCash")
 	//提现流
 	beego.Router("/v1/user/takecash/flow", &balance_controller.BalanceController{}, "get:GetTakeCashOrders")
 	//提现限额