2025-04-10 09:33:09 +00:00
|
|
|
|
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 {
|
2025-04-16 09:24:54 +00:00
|
|
|
|
Brand string // 品牌/平台(區分多租戶、多品牌情境)
|
|
|
|
|
UID string // 使用者 UID
|
|
|
|
|
Asset string // 資產代號,可為 BTC、ETH、GEM_RED、GEM_BLUE、POINTS ,USD, TWD 等....
|
|
|
|
|
Balance decimal.Decimal // 餘額(使用高精度 decimal 避免浮點誤差)
|
|
|
|
|
Type wallet.Types // 錢包類型
|
2025-04-10 09:33:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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 // 錢包類型(如可用、凍結等)
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-18 09:10:40 +00:00
|
|
|
|
// UserWalletService 定義了一個「單一使用者、單一資產」的錢包操作合約
|
2025-04-10 09:33:09 +00:00
|
|
|
|
type UserWalletService interface {
|
2025-04-18 09:10:40 +00:00
|
|
|
|
// 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(
|
2025-04-17 09:00:42 +00:00
|
|
|
|
txID int64,
|
2025-04-18 09:10:40 +00:00
|
|
|
|
orderID, brand string,
|
2025-04-17 09:00:42 +00:00
|
|
|
|
businessType wallet.BusinessName,
|
|
|
|
|
) []entity.WalletTransaction
|
2025-04-18 09:10:40 +00:00
|
|
|
|
// PersistBalances 將本地緩存中所有錢包最終餘額批次寫入資料庫
|
|
|
|
|
PersistBalances(ctx context.Context) error
|
|
|
|
|
// PersistOrderBalances 將本地緩存中所有訂單相關餘額批次寫入 transaction 表
|
|
|
|
|
PersistOrderBalances(ctx context.Context) error
|
|
|
|
|
// HasAvailableBalance 確認此使用者此資產是否已有可用餘額錢包
|
|
|
|
|
HasAvailableBalance(ctx context.Context) (bool, error)
|
2025-04-10 09:33:09 +00:00
|
|
|
|
}
|