fix(wallet): enforce consistent withdrawal accounting

This commit is contained in:
david
2026-07-31 09:54:17 +08:00
parent 36a5ced1c0
commit 42a2322c8e
23 changed files with 1405 additions and 250 deletions

View File

@@ -9,6 +9,7 @@ import (
"git.apinb.com/heqiapp/platforms/backend/api/internal/logic/common"
"git.apinb.com/heqiapp/platforms/backend/api/internal/models"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
func currentWallet(ctx *gin.Context, gas models.GasBasic) (models.WalletBasic, bool) {
@@ -58,7 +59,7 @@ func ListWalletApplyCash(ctx *gin.Context) {
}
func CreateWalletApplyCash(ctx *gin.Context) {
station, ok := currentGas(ctx)
account, station, ok := CurrentGasAccount(ctx)
if !ok {
return
}
@@ -78,30 +79,31 @@ func CreateWalletApplyCash(ctx *gin.Context) {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
var pendingAmount int64
if err := impl.DBService.Model(&models.WalletApplyCash{}).
Where("wallet_basic_id = ? AND status <> ? AND apply_status = ?", wallet.ID, common.StatusArchived, common.StatusPending).
Select("COALESCE(SUM(amount), 0)").Scan(&pendingAmount).Error; err != nil ||
request.Amount > wallet.WithdrawalBalance-pendingAmount {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
}
var bankID uint64
if request.WalletBankIdentity != "" {
var bank models.WalletBank
if err := common.ActiveRecords(impl.DBService).
Where("identity = ? AND wallet_basic_id = ?", request.WalletBankIdentity, wallet.ID).First(&bank).Error; err != nil {
infra.Response.Error(ctx, errcode.ErrInvalidArgument)
return
var apply models.WalletApplyCash
err := impl.DBService.Transaction(func(tx *gorm.DB) error {
var bankID uint64
if request.WalletBankIdentity != "" {
var bank models.WalletBank
if err := common.ActiveRecords(tx).
Where("identity = ? AND wallet_basic_id = ?", request.WalletBankIdentity, wallet.ID).First(&bank).Error; err != nil {
return err
}
bankID = bank.ID
}
bankID = bank.ID
}
apply := models.WalletApplyCash{
Entity: common.NewEntity(common.StatusEnable), ApplyStatus: common.StatusPending,
WalletBasicID: wallet.ID, WalletBankID: bankID, CashNo: models.NewIdentity(),
RequestNo: request.RequestNo, Amount: request.Amount, Channel: request.Channel, Remark: request.Remark,
}
if err := impl.DBService.Create(&apply).Error; err != nil {
var createErr error
apply, _, createErr = common.CreateReservedWithdrawal(tx, common.WalletWithdrawalInput{
WalletBasicID: wallet.ID,
WalletBankID: bankID,
RequestNo: request.RequestNo,
Amount: request.Amount,
Channel: request.Channel,
Remark: request.Remark,
OperatorIdentity: account.Identity,
OperatorName: account.DisplayName,
})
return createErr
})
if err != nil {
infra.Response.Error(ctx, err)
return
}