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)
|
GetOrderBalance(ctx context.Context, orderID string) (entity.Transaction, error)
|
||||||
// GetOrderBalanceForUpdate 查詢某筆交易(訂單),詳情寫入本地暫存 (FOR UPDATE)
|
// GetOrderBalanceForUpdate 查詢某筆交易(訂單),詳情寫入本地暫存 (FOR UPDATE)
|
||||||
GetOrderBalanceForUpdate(ctx context.Context, orderID string) (entity.Transaction, error)
|
GetOrderBalanceForUpdate(ctx context.Context, orderID string) (entity.Transaction, error)
|
||||||
|
// AddOrderBalance order 加入本地塊曲中
|
||||||
|
AddOrderBalance(ctx context.Context, orderID string, amount decimal.Decimal) error
|
||||||
// ClearCache 清空本地所有暫存
|
// ClearCache 清空本地所有暫存
|
||||||
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 {
|
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 {
|
func (use *WalletUseCase) RollbackFreeze(ctx context.Context, tx usecase.WalletTransferRequest) error {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package usecase
|
package usecase
|
||||||
|
|
||||||
import (
|
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/repository"
|
||||||
"code.30cm.net/digimon/app-cloudep-wallet-service/pkg/domain/usecase"
|
"code.30cm.net/digimon/app-cloudep-wallet-service/pkg/domain/usecase"
|
||||||
"code.30cm.net/digimon/app-cloudep-wallet-service/pkg/domain/wallet"
|
"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 減少用戶凍結餘額
|
//// withSubFreeze 減少用戶凍結餘額
|
||||||
//func (use *WalletUseCase) withSubFreeze() walletActionOption {
|
//func (use *WalletUseCase) withSubFreeze() walletActionOption {
|
||||||
// return func(_ context.Context, tx *usecase.Transaction, wallet repository.UserWallet) error {
|
// return func(_ context.Context, tx *usecase.Transaction, wallet repository.UserWallet) error {
|
||||||
|
|
Loading…
Reference in New Issue