80 lines
2.2 KiB
Go
80 lines
2.2 KiB
Go
package usecase
|
|
|
|
import (
|
|
"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"
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
type uidAssetKey struct {
|
|
uid string
|
|
asset string
|
|
}
|
|
|
|
// walletActionOption 表示一個「錢包操作函式」,可在錢包流程中插入自定義動作(例如:扣款、加值、凍結)
|
|
type walletActionOption func(
|
|
ctx context.Context,
|
|
tx *usecase.WalletTransferRequest,
|
|
wallet repository.UserWalletService,
|
|
) error
|
|
|
|
// withLockAvailable 鎖定用戶可用餘額
|
|
func (use *WalletUseCase) withLockAvailable() walletActionOption {
|
|
return func(ctx context.Context, tx *usecase.WalletTransferRequest, w repository.UserWalletService) error {
|
|
uidAsset := uidAssetKey{
|
|
uid: tx.FromUID,
|
|
asset: tx.Asset,
|
|
}
|
|
|
|
if !use.checkWalletExistence(uidAsset) {
|
|
// 找不到錢包存不存在
|
|
wStatus, err := w.HasAvailableBalance(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to check wallet: %w", err)
|
|
}
|
|
// 錢包不存在要做新增
|
|
if !wStatus {
|
|
//// 是合約模擬交易或帳變且錢包不存在才建立錢包
|
|
//if !(tx.Business == wa.ContractSimulationBusinessTypeBusinessName || tx.BusinessType == domain.DistributionBusinessTypeBusinessName) {
|
|
// // 新增錢包有命中 UK 不需要額外上鎖
|
|
// return use.translateError(err)
|
|
//}
|
|
|
|
if _, err := w.InitializeWallets(ctx, tx.Brand); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
use.markWalletAsExisting(uidAsset)
|
|
}
|
|
|
|
_, err := w.GetBalancesForUpdate(ctx, []wallet.Types{wallet.TypeAvailable})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// subAvailable 減少用戶可用餘額
|
|
func (use *WalletUseCase) withSubAvailable() walletActionOption {
|
|
return func(_ context.Context, tx *usecase.WalletTransferRequest, w repository.UserWalletService) error {
|
|
if err := w.DecreaseBalance(wallet.TypeAvailable, tx.ReferenceOrderID, tx.Amount); err != nil {
|
|
if errors.Is(err, repository.ErrBalanceInsufficient) {
|
|
// todo 錯誤要看怎麼給(餘額不足)
|
|
return fmt.Errorf("balance insufficient")
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|