app-cloudep-wallet-service/pkg/domain/repository/wallet.go

90 lines
4.8 KiB
Go
Raw 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 (
"code.30cm.net/digimon/app-cloudep-wallet-service/pkg/domain/entity"
"code.30cm.net/digimon/app-cloudep-wallet-service/pkg/domain/wallet"
"context"
"github.com/shopspring/decimal"
"gorm.io/gorm"
)
type Wallet struct {
Brand string // 品牌/平台(區分多租戶、多品牌情境)
UID string // 使用者 UID
Asset string // 資產代號,可為 BTC、ETH、GEM_RED、GEM_BLUE、POINTS ,USD, TWD 等....
Balance decimal.Decimal // 餘額(使用高精度 decimal 避免浮點誤差)
Type wallet.Types // 錢包類型
}
// WalletRepository 是錢包的總入口,負責查詢、初始化與跨帳戶查詢邏輯
type WalletRepository interface {
// NewDB 建立新的 DB 實例(提供給需要操作 tx 的場景)
NewDB() *gorm.DB
// Session 取得單一使用者資產的錢包服務(非交易模式)
//📌 使用場景:
// 用在 不需要交易機制的場景,例如:
// 純查詢錢包餘額查詢快取、Log、統計報表非敏感資料更新失敗可以重試的情境
// ✅ 優點:
// 簡單快速、使用預設的資料庫連線
// 不用包 Transaction ,沒有 Rollback 負擔
Session(uid, asset string) UserWalletService
// SessionWithTx 在資料庫交易內取得錢包服務
// 📌 使用場景:
// 用在 資料需要一致性與原子性保證的邏輯中,例如:
// 加值與扣款(同時操作多個錢包)檢查餘額後立刻寫入交易記錄,綁定訂單與錢包扣款的行為
// 所有與 Add/Commit 有關的處理與其他模組訂單、KYC共用一個 transaction
// ✅ 優點:
// 保障操作過程中不被其他並發操作影響
// 可控制 rollback 行為避免中間失敗導致不一致
// 可組合複雜操作(如:更新錢包同時寫入交易紀錄)
SessionWithTx(db *gorm.DB, uid, asset string) UserWalletService
// Transaction 資料庫交易包裝器(確保交易一致性)
Transaction(fn func(db *gorm.DB) error) error
// InitWallets 初始化使用者的所有錢包類型(如可用、凍結等)
InitWallets(ctx context.Context, param []Wallet) error
// QueryBalances 查詢特定資產的錢包餘額
QueryBalances(ctx context.Context, req BalanceQuery) ([]entity.Wallet, error)
// QueryBalancesByUIDs 查詢多個使用者在特定資產下的錢包餘額
QueryBalancesByUIDs(ctx context.Context, uids []string, req BalanceQuery) ([]entity.Wallet, error)
//// GetDailyTxAmount 查詢使用者今日交易總金額(指定類型與業務)
//GetDailyTxAmount(ctx context.Context, uid string, txTypes []domain.TxType, business wallet.BusinessName) ([]entity.Wallet, error)
}
// BalanceQuery 是查詢餘額時的篩選條件
type BalanceQuery struct {
UID string // 使用者 ID
Asset string // 資產類型Crypto、寶石等
Kinds []wallet.Types // 錢包類型(如可用、凍結等)
}
// UserWalletService 定義了一個「單一使用者、單一資產」的錢包操作合約
type UserWalletService interface {
// InitializeWallets 為新使用者初始化所有錢包類型並寫入資料庫
InitializeWallets(ctx context.Context, brand string) ([]entity.Wallet, error)
// GetAllBalances 查詢此使用者此資產下所有錢包類型的當前餘額
GetAllBalances(ctx context.Context) ([]entity.Wallet, error)
// GetBalancesForTypes 查詢指定錢包類型的一組餘額(不加鎖)
GetBalancesForTypes(ctx context.Context, kinds []wallet.Types) ([]entity.Wallet, error)
// GetBalancesForUpdate 查詢並鎖定指定錢包類型FOR UPDATE
GetBalancesForUpdate(ctx context.Context, kinds []wallet.Types) ([]entity.Wallet, error)
// CurrentBalance 從本地緩存取得某種錢包類型的餘額
CurrentBalance(kind wallet.Types) decimal.Decimal
// IncreaseBalance 增加指定錢包類型的餘額,並累積一筆交易紀錄
IncreaseBalance(kind wallet.Types, orderID string, amount decimal.Decimal) error
// DecreaseBalance 減少指定錢包類型的餘額(等同於 IncreaseBalance 的負數版本)
DecreaseBalance(kind wallet.Types, orderID string, amount decimal.Decimal) error
// PrepareTransactions 為所有暫存交易紀錄填上 TXID/OrderID/Brand/BusinessType並回傳可落庫的切片
PrepareTransactions(
txID int64,
orderID, brand string,
businessType wallet.BusinessName,
) []entity.WalletTransaction
// PersistBalances 將本地緩存中所有錢包最終餘額批次寫入資料庫
PersistBalances(ctx context.Context) error
// PersistOrderBalances 將本地緩存中所有訂單相關餘額批次寫入 transaction 表
PersistOrderBalances(ctx context.Context) error
// HasAvailableBalance 確認此使用者此資產是否已有可用餘額錢包
HasAvailableBalance(ctx context.Context) (bool, error)
}