feat: add transaction
This commit is contained in:
parent
14082dc5f5
commit
1282c1e1a1
|
@ -90,6 +90,8 @@ type UserWalletService interface {
|
|||
GetOrderBalance(ctx context.Context, orderID string) (entity.Transaction, error)
|
||||
// GetOrderBalanceForUpdate 查詢某筆交易(訂單),詳情寫入本地暫存 (FOR UPDATE)
|
||||
GetOrderBalanceForUpdate(ctx context.Context, orderID string) (entity.Transaction, error)
|
||||
// AddOrderBalance order 加入本地塊曲中
|
||||
AddOrderBalance(ctx context.Context, orderID string, amount decimal.Decimal) error
|
||||
// ClearCache 清空本地所有暫存
|
||||
ClearCache()
|
||||
}
|
||||
|
|
|
@ -232,9 +232,24 @@ func (use *WalletUseCase) AppendFreeze(ctx context.Context, tx usecase.WalletTra
|
|||
})
|
||||
}
|
||||
|
||||
// UnFreeze 解凍
|
||||
// 1. 新增一筆解凍交易
|
||||
// 2. 減少order餘額
|
||||
// 3. 錢包減少凍結餘額
|
||||
// 4. 錢包變化新增一筆減少凍結餘額資料
|
||||
func (use *WalletUseCase) UnFreeze(ctx context.Context, tx usecase.WalletTransferRequest) error {
|
||||
//TODO implement me
|
||||
panic("implement me")
|
||||
// 確認錢包新增或減少的餘額是否正確
|
||||
if !tx.Amount.IsPositive() {
|
||||
return errs.InvalidRange("failed to get correct amount")
|
||||
}
|
||||
|
||||
tx.TxType = wallet.UnFreeze
|
||||
|
||||
return use.ProcessTransaction(ctx, tx, userWalletFlow{
|
||||
UID: tx.FromUID,
|
||||
Asset: tx.Asset,
|
||||
Actions: []walletActionOption{use.withSubOrder(nil), use.withLockFreeze(), use.withSubFreeze()},
|
||||
})
|
||||
}
|
||||
|
||||
func (use *WalletUseCase) RollbackFreeze(ctx context.Context, tx usecase.WalletTransferRequest) error {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package usecase
|
||||
|
||||
import (
|
||||
"code.30cm.net/digimon/app-cloudep-wallet-service/pkg/domain/entity"
|
||||
"code.30cm.net/digimon/app-cloudep-wallet-service/pkg/domain/repository"
|
||||
"code.30cm.net/digimon/app-cloudep-wallet-service/pkg/domain/usecase"
|
||||
"code.30cm.net/digimon/app-cloudep-wallet-service/pkg/domain/wallet"
|
||||
|
@ -187,6 +188,67 @@ func (use *WalletUseCase) withAppendFreeze() walletActionOption {
|
|||
}
|
||||
}
|
||||
|
||||
func (use *WalletUseCase) withSubOrder(fTx func(*usecase.WalletTransferRequest, entity.Transaction)) walletActionOption {
|
||||
return func(ctx context.Context, tx *usecase.WalletTransferRequest, w repository.UserWalletService) error {
|
||||
order, err := w.GetOrderBalance(ctx, tx.ReferenceOrderID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 檢查order wallet 餘額<=0
|
||||
if !order.Amount.IsPositive() {
|
||||
return err
|
||||
}
|
||||
|
||||
// 以id來做lock更可以確保只lock到該筆,而不會因為index關係lock到多筆導致死鎖
|
||||
// 而且先不lock把資料先拉出來判斷餘額是否足夠,在不足夠時可以直接return而不用lock減少開銷
|
||||
order, err = w.GetOrderBalanceForUpdate(ctx, order.OrderID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx.Asset = order.Asset
|
||||
tx.FromUID = order.UID
|
||||
|
||||
//// 解凍BusinessType,必須跟建立凍結訂單的BusinessType一致
|
||||
//if tx.Business != domain.SystemTransferCommissionBusinessTypeBusinessName {
|
||||
// // 只有系統劃轉會有轉入錢包不同的狀況
|
||||
// tx.BusinessType = domain.BusinessTypeToString(order.BusinessType)
|
||||
//}
|
||||
|
||||
if fTx != nil {
|
||||
fTx(tx, order)
|
||||
}
|
||||
|
||||
if err := w.AddOrderBalance(ctx, order.OrderID, tx.Amount.Neg()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (use *WalletUseCase) withLockFreeze() walletActionOption {
|
||||
return func(ctx context.Context, tx *usecase.WalletTransferRequest, w repository.UserWalletService) error {
|
||||
_, err := w.GetBalancesForUpdate(ctx, []wallet.Types{wallet.TypeFreeze})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (use *WalletUseCase) withSubFreeze() walletActionOption {
|
||||
return func(ctx context.Context, tx *usecase.WalletTransferRequest, w repository.UserWalletService) error {
|
||||
if err := w.DecreaseBalance(wallet.TypeFreeze, tx.ReferenceOrderID, tx.Amount); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//// withSubFreeze 減少用戶凍結餘額
|
||||
//func (use *WalletUseCase) withSubFreeze() walletActionOption {
|
||||
// return func(_ context.Context, tx *usecase.Transaction, wallet repository.UserWallet) error {
|
||||
|
|
Loading…
Reference in New Issue