app-cloudep-trade-service/internal/repository/user_wallet.go

96 lines
2.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package repository
import (
"app-cloudep-trade-service/internal/domain/repository"
"app-cloudep-trade-service/internal/domain/wallet"
"app-cloudep-trade-service/internal/model"
"context"
"github.com/shopspring/decimal"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
// 用戶某個幣種餘額
type userLocalWallet struct {
wm model.WalletModel
txConn sqlx.SqlConn
uid string
currency string
// local wallet 相關計算的餘額存在這裡
walletBalance map[wallet.BalanceType]model.Wallet
// local order wallet 相關計算的餘額存在這裡
localOrderBalance map[int64]decimal.Decimal
// local wallet 內所有餘額變化紀錄
transactions []model.WalletJournal
}
// GetBalancesByID 使用 Wallet ID 取得餘額,如果需要上鎖,可以在 option 內加上 tx 以及 lock可以參考 TestBalanceUseCase
func (use *userLocalWallet) GetBalancesByID(ctx context.Context, ids []int64, opts ...repository.WalletOperatorOption) ([]model.Wallet, error) {
o := repository.ApplyOptions(opts...)
tx := use.txConn
if o.Tx != nil {
tx = *o.Tx
}
wallets, err := use.wm.BalancesByIDs(ctx, ids, o.WithLock, tx)
if err != nil {
return nil, err
}
for _, w := range wallets {
use.walletBalance[w.WalletType] = w
}
return wallets, nil
}
// LocalBalance 內存餘額
func (use *userLocalWallet) LocalBalance(BalanceType wallet.BalanceType) decimal.Decimal {
w, ok := use.walletBalance[BalanceType]
if !ok {
return decimal.Zero
}
return w.Balance
}
// Balances 取得餘額如果需要上鎖可以在option 內加上 tx 以及 lock可以參考 TestBalanceUseCase
func (use *userLocalWallet) Balances(ctx context.Context, balanceType []wallet.BalanceType, opts ...repository.WalletOperatorOption) ([]model.Wallet, error) {
o := repository.ApplyOptions(opts...)
tx := use.txConn
if o.Tx != nil {
tx = *o.Tx
}
wallets, err := use.wm.Balances(ctx, model.BalanceReq{
UID: []string{use.uid},
Currency: []string{use.currency},
Kind: balanceType,
}, o.WithLock, tx)
if err != nil {
return nil, err
}
for _, wallet := range wallets {
use.walletBalance[wallet.WalletType] = wallet
}
return wallets, nil
}
func NewUserWalletOperator(uid, currency string, wm model.WalletModel, txConn sqlx.SqlConn) repository.UserWalletOperator {
return &userLocalWallet{
wm: wm,
txConn: txConn,
uid: uid,
currency: currency,
walletBalance: make(map[wallet.BalanceType]model.Wallet, len(wallet.AllBalanceTypes)),
localOrderBalance: make(map[int64]decimal.Decimal, len(wallet.AllBalanceTypes)),
}
}