This commit is contained in:
2026-04-22 17:49:20 +08:00
parent a2fad4a095
commit f545aee45e
15 changed files with 268 additions and 140 deletions

View File

@@ -1,14 +1,14 @@
package agent
import (
"context"
"database/sql"
"fmt"
"time"
"bdrp-server/app/main/model"
"bdrp-server/common/ctxdata"
"bdrp-server/common/xerr"
"bdrp-server/pkg/lzkit/lzUtils"
"context"
"database/sql"
"fmt"
"time"
"github.com/cenkalti/backoff/v4"
"github.com/pkg/errors"
@@ -56,6 +56,8 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
agentID int64
)
var finalWithdrawAmount float64 // 实际到账金额
withdrawAmount := roundMoney(req.Amount)
// 使用事务处理核心操作
err := l.svcCtx.AgentModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
userID, err := ctxdata.GetUidFromCtx(l.ctx)
@@ -89,7 +91,7 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
}
// 校验可提现金额
if req.Amount > agentWallet.Balance {
if withdrawAmount > roundMoney(agentWallet.Balance) {
return errors.Wrapf(xerr.NewErrMsg("您可提现的余额不足"), "获取用户ID失败")
}
@@ -97,7 +99,7 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
outBizNo = "W_" + l.svcCtx.AlipayService.GenerateOutTradeNo()
// 冻结资金(事务内操作)
if err = l.freezeFunds(session, agentWallet, req.Amount); err != nil {
if err = l.freezeFunds(session, agentWallet, withdrawAmount); err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "资金冻结失败: %v", err)
}
yearMonth := int64(time.Now().Year()*100 + int(time.Now().Month()))
@@ -111,14 +113,14 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
)
// 统一扣税逻辑所有提现都按6%收取税收
exemptionAmount = 0 // 免税金额 = 0
TaxStatus = model.TaxStatusPending // 扣税状态 = 待扣税
taxDeductionPart = req.Amount // 应税金额 = 提现金额
taxAmount = taxDeductionPart * taxRate // 应缴税费 = 应税金额 * 税率
finalWithdrawAmount = req.Amount - taxAmount // 实际到账金额 = 提现金额 - 应缴税费
exemptionAmount = 0 // 免税金额 = 0
TaxStatus = model.TaxStatusPending // 扣税状态 = 待扣税
taxDeductionPart = withdrawAmount // 应税金额 = 提现金额
taxAmount = roundMoney(taxDeductionPart * taxRate) // 应缴税费 = 应税金额 * 税率
finalWithdrawAmount = roundMoney(withdrawAmount - taxAmount) // 实际到账金额 = 提现金额 - 应缴税费
// 创建提现记录(初始状态为处理中)
withdrawalID, err := l.createWithdrawalRecord(session, agentModel.Id, req.PayeeAccount, req.PayeeName, req.Amount, finalWithdrawAmount, taxAmount, outBizNo)
withdrawalID, err := l.createWithdrawalRecord(session, agentModel.Id, req.PayeeAccount, req.PayeeName, withdrawAmount, finalWithdrawAmount, taxAmount, outBizNo)
if err != nil {
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建提现记录失败: %v", err)
}
@@ -127,7 +129,7 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
AgentId: agentModel.Id,
YearMonth: yearMonth,
WithdrawalId: withdrawalID,
WithdrawalAmount: req.Amount,
WithdrawalAmount: withdrawAmount,
ExemptionAmount: exemptionAmount,
TaxableAmount: taxDeductionPart,
TaxRate: taxRate,
@@ -153,7 +155,7 @@ func (l *AgentWithdrawalLogic) AgentWithdrawal(req *types.WithdrawalReq) (*types
withdrawRes.Status = WithdrawStatusProcessing
withdrawRes.FailMsg = ""
l.Logger.Infof("支付宝提现申请成功 outBizNo:%s agentId:%d amount:%f", outBizNo, agentID, req.Amount)
l.Logger.Infof("支付宝提现申请成功 outBizNo:%s agentId:%d amount:%f", outBizNo, agentID, withdrawAmount)
return withdrawRes, nil
}
@@ -193,6 +195,7 @@ func (l *AgentWithdrawalLogic) mapAlipayError(code string) string {
if msg, ok := errorMapping[code]; ok {
return msg
}
l.Logger.Infof("未匹配到支付宝错误码 code:%s", code)
return "系统错误,请联系客服"
}
@@ -204,9 +207,9 @@ func (l *AgentWithdrawalLogic) createWithdrawalRecord(session sqlx.Session, agen
WithdrawNo: outBizNo,
PayeeAccount: payeeAccount,
PayeeName: sql.NullString{String: payeeName, Valid: true}, // 设置收款人姓名
Amount: amount,
ActualAmount: finalWithdrawAmount,
TaxAmount: taxAmount,
Amount: roundMoney(amount),
ActualAmount: roundMoney(finalWithdrawAmount),
TaxAmount: roundMoney(taxAmount),
Status: StatusProcessing,
}
@@ -219,8 +222,8 @@ func (l *AgentWithdrawalLogic) createWithdrawalRecord(session sqlx.Session, agen
// 冻结资金(事务内操作)
func (l *AgentWithdrawalLogic) freezeFunds(session sqlx.Session, wallet *model.AgentWallet, amount float64) error {
wallet.Balance -= amount
wallet.FrozenBalance += amount
wallet.Balance = roundMoney(wallet.Balance - amount)
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance + amount)
err := l.svcCtx.AgentWalletModel.UpdateWithVersion(l.ctx, session, wallet)
if err != nil {
return err
@@ -296,8 +299,8 @@ func (l *AgentWithdrawalLogic) updateWithdrawalStatus(outBizNo string, status in
return err
}
wallet.Balance += record.Amount
wallet.FrozenBalance -= record.Amount
wallet.Balance = roundMoney(wallet.Balance + record.Amount)
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance - record.Amount)
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
return err
}
@@ -320,7 +323,7 @@ func (l *AgentWithdrawalLogic) updateWithdrawalStatus(outBizNo string, status in
return err
}
wallet.FrozenBalance -= record.Amount
wallet.FrozenBalance = roundMoney(wallet.FrozenBalance - record.Amount)
if err := l.svcCtx.AgentWalletModel.UpdateWithVersion(ctx, session, wallet); err != nil {
return err
}