add wallet repo
This commit is contained in:
parent
8687e467c9
commit
fc748fb66f
|
@ -23,6 +23,12 @@ const (
|
|||
TimeoutOrderErrorCode
|
||||
)
|
||||
|
||||
// Error Code 統一這邊改
|
||||
const (
|
||||
_ ErrorCode = 20 + iota
|
||||
CreateWalletErrorCode
|
||||
)
|
||||
|
||||
const (
|
||||
_ ErrorCode = 10 + iota
|
||||
DataNotFoundErrorCode
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
package repository
|
||||
|
||||
// UserWalletOperator 針對使用者的錢包基本操作接口
|
||||
type UserWalletOperator interface{}
|
|
@ -0,0 +1,30 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"app-cloudep-trade-service/internal/domain"
|
||||
"app-cloudep-trade-service/internal/model"
|
||||
"context"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
// WalletRepository 錢包基礎操作(可能有平台,使用者等多元的錢包)
|
||||
type WalletRepository interface {
|
||||
// Create 建立錢包組合(某人的可用,凍結,限制三種)
|
||||
Create(ctx context.Context, uid, currency, brand string) ([]*model.Wallet, error)
|
||||
// Balances 取得某個人的餘額
|
||||
Balances(ctx context.Context, req BalanceReq) ([]model.Wallet, error)
|
||||
// GetTxDatabaseConn 取得 sql 要做 tx 的連線
|
||||
GetTxDatabaseConn() sqlx.SqlConn
|
||||
// GetUserWalletOperator 取得使用者錢包操作看使否需要使用 transaction
|
||||
GetUserWalletOperator(uid, currency string, opts ...Option) UserWalletOperator
|
||||
}
|
||||
|
||||
// BalanceReq 取得全部的,因為一個人錢包種類的不會太多,故全撈
|
||||
type BalanceReq struct {
|
||||
UID []string
|
||||
Currency []string
|
||||
Kind []domain.WalletType
|
||||
}
|
||||
|
||||
type Option func() sqlx.SqlConn
|
|
@ -1,4 +1,81 @@
|
|||
package usecase
|
||||
|
||||
type WalletUseCase interface {
|
||||
import (
|
||||
"app-cloudep-trade-service/internal/domain"
|
||||
"context"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
// WalletQueryUseCase 定義所有查詢行為(餘額查詢、檢查、歷史記錄)的行為
|
||||
type WalletQueryUseCase interface {
|
||||
// Balance 用戶餘額
|
||||
Balance(ctx context.Context, req BalanceReq) ([]Balance, error)
|
||||
// CheckBalance 根據tx檢查用戶餘額是否足夠
|
||||
CheckBalance(ctx context.Context, tx Transaction) error
|
||||
// HistoryBalance 歷史餘額變化
|
||||
HistoryBalance(ctx context.Context, req BalanceReq) ([]Balance, error)
|
||||
}
|
||||
|
||||
// WalletOperationUseCase 定義所有錢包操作(提款、充值、凍結等)的行為
|
||||
type WalletOperationUseCase interface {
|
||||
// Withdraw 提款
|
||||
Withdraw(ctx context.Context, tx Transaction) error
|
||||
// Deposit 充值
|
||||
Deposit(ctx context.Context, tx Transaction) error
|
||||
// DepositUnconfirmed 增加限制餘額
|
||||
DepositUnconfirmed(ctx context.Context, tx Transaction) error
|
||||
// Freeze 凍結
|
||||
Freeze(ctx context.Context, tx Transaction) error
|
||||
// AppendFreeze 追加凍結金額
|
||||
AppendFreeze(ctx context.Context, tx Transaction) error
|
||||
// UnFreeze 解凍
|
||||
UnFreeze(ctx context.Context, tx Transaction) error
|
||||
// RollbackFreeze Rollback 凍結,不可指定金額(剩餘order凍結金額)
|
||||
RollbackFreeze(ctx context.Context, tx Transaction) error
|
||||
// RollbackFreezeAddAvailable Rollback剩餘凍結,可指定金額(剩餘order凍結金額)
|
||||
RollbackFreezeAddAvailable(ctx context.Context, tx Transaction) error
|
||||
// CancelFreeze 取消凍結,可指定金額
|
||||
CancelFreeze(ctx context.Context, tx Transaction) error
|
||||
// Unconfirmed 增加限制
|
||||
Unconfirmed(ctx context.Context, tx Transaction) error
|
||||
}
|
||||
|
||||
// WalletUseCase 基礎操作類別
|
||||
type WalletUseCase interface {
|
||||
WalletOperationUseCase
|
||||
WalletQueryUseCase
|
||||
}
|
||||
|
||||
// Transaction 交易
|
||||
type Transaction struct {
|
||||
OrderID string // 交易訂單
|
||||
UID string // 交易發起人
|
||||
ToUID string // 交易接收人
|
||||
Currency string // 幣別
|
||||
Amount decimal.Decimal // 交易金額
|
||||
BeforeBalance decimal.Decimal // 交易前餘額
|
||||
Type domain.TxType // 交易種類
|
||||
BusinessType domain.BusinessName // 商業種類
|
||||
Brand string // 轉帳平台
|
||||
From domain.WalletType // 從哪種錢包類型
|
||||
To domain.WalletType // 到哪種錢包類型
|
||||
}
|
||||
|
||||
type BalanceReq struct {
|
||||
UID string // 用戶 UID
|
||||
Currency string // 幣值
|
||||
BeforeHour int // 在某個時段之前
|
||||
}
|
||||
|
||||
type Balance struct {
|
||||
Currency string `json:"currency"`
|
||||
Available decimal.Decimal `json:"available"`
|
||||
Unavailable UnavailableBalance `json:"unavailable"`
|
||||
UpdateTime int64 `json:"update_time"`
|
||||
}
|
||||
|
||||
type UnavailableBalance struct {
|
||||
Freeze decimal.Decimal `json:"freeze"`
|
||||
Unconfirmed decimal.Decimal `json:"unconfirmed"`
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package domain
|
||||
|
||||
// ===================交易商業邏輯種類===================
|
||||
|
||||
type BusinessName string
|
||||
|
||||
const (
|
||||
// NoBusinessName 非商業邏輯
|
||||
NoBusinessName BusinessName = ""
|
||||
// OrderBusinessTypeBusinessName order業務邏輯
|
||||
OrderBusinessTypeBusinessName BusinessName = "order"
|
||||
// SystemTransferBusinessTypeBusinessName 系統劃轉
|
||||
SystemTransferBusinessTypeBusinessName BusinessName = "system_transfer"
|
||||
)
|
||||
|
||||
const (
|
||||
// NoBusinessType 非商業邏輯
|
||||
NoBusinessType int8 = iota
|
||||
// OrderBusinessTypeBusinessType order 業務邏輯
|
||||
OrderBusinessTypeBusinessType
|
||||
// SystemTransferBusinessTypeBusinessType 系統劃轉
|
||||
SystemTransferBusinessTypeBusinessType
|
||||
)
|
||||
|
||||
// 定義兩個map用於名稱和類型的相互映射
|
||||
var nameToBusinessType = map[BusinessName]int8{
|
||||
OrderBusinessTypeBusinessName: OrderBusinessTypeBusinessType,
|
||||
SystemTransferBusinessTypeBusinessName: SystemTransferBusinessTypeBusinessType,
|
||||
}
|
||||
|
||||
var businessTypeToName = map[int8]BusinessName{
|
||||
OrderBusinessTypeBusinessType: OrderBusinessTypeBusinessName,
|
||||
SystemTransferBusinessTypeBusinessType: SystemTransferBusinessTypeBusinessName,
|
||||
}
|
||||
|
||||
// ToINT8 converts BusinessName to its corresponding int8 type
|
||||
func (b BusinessName) ToINT8() int8 {
|
||||
if val, ok := nameToBusinessType[b]; ok {
|
||||
return val
|
||||
}
|
||||
|
||||
return NoBusinessType
|
||||
}
|
||||
|
||||
// BusinessTypeToString converts an int8 type to its corresponding BusinessName
|
||||
func BusinessTypeToString(b int8) BusinessName {
|
||||
if val, ok := businessTypeToName[b]; ok {
|
||||
return val
|
||||
}
|
||||
|
||||
return NoBusinessName
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package domain
|
||||
|
||||
// ===================交易種類===================
|
||||
|
||||
type TxType int64
|
||||
|
||||
// 交易類型
|
||||
const (
|
||||
// TxDepositType 充值(增加可用餘額)
|
||||
TxDepositType TxType = iota + 1
|
||||
|
||||
// TxWithdrawType 提現(減少可用餘額)
|
||||
TxWithdrawType
|
||||
|
||||
// TxFreezeType 凍結(減少可用餘額,加在凍結餘額)
|
||||
TxFreezeType
|
||||
|
||||
// TxUnFreezeType 解凍(減少凍結餘額)
|
||||
TxUnFreezeType
|
||||
|
||||
// TxRollbackFreezeType rollback凍結(減少凍結餘額,加回可用餘額,不可指定金額)
|
||||
TxRollbackFreezeType
|
||||
|
||||
// TxUnconfirmedType 限制(減少凍結餘額,加別人限制餘額)
|
||||
TxUnconfirmedType
|
||||
|
||||
// TxCancelFreezeType 取消凍結(減少凍結餘額,加回可用餘額,,可指定金額)
|
||||
TxCancelFreezeType
|
||||
|
||||
// TxDepositUnconfirmedType 充值(增加限制餘額)
|
||||
TxDepositUnconfirmedType
|
||||
|
||||
// TxAppendFreezeType 追加凍結(減少可用餘額,加在凍結餘額)
|
||||
TxAppendFreezeType
|
||||
|
||||
// TxRollbackFreezeAddAvailableType rollback凍結(rollback凍結餘額,指定金額加回可用餘額)
|
||||
TxRollbackFreezeAddAvailableType
|
||||
|
||||
// TxDistributionType 平台分發
|
||||
TxDistributionType
|
||||
|
||||
// TxSystemTransfer 系統劃轉
|
||||
TxSystemTransfer
|
||||
)
|
||||
|
||||
func (t TxType) ToInt() int64 {
|
||||
return int64(t)
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package domain
|
||||
|
||||
// ===================錢包金額種類===================
|
||||
|
||||
type WalletType int64
|
||||
|
||||
// 錢包種類
|
||||
const (
|
||||
// WalletAvailableType 錢包可動用的金額
|
||||
WalletAvailableType WalletType = iota + 1
|
||||
|
||||
// WalletFreezeType 交易過程,錢包被凍結的金額
|
||||
WalletFreezeType
|
||||
|
||||
// WalletUnconfirmedType 已提交的交易但還未確認完成交易的金額
|
||||
WalletUnconfirmedType
|
||||
|
||||
// WalletContractAvailableType 合約/交易可用餘額
|
||||
WalletContractAvailableType
|
||||
|
||||
// WalletContractFreezeType 合約/交易凍結餘額
|
||||
WalletContractFreezeType
|
||||
)
|
||||
|
||||
var walletTypeToName = map[WalletType]string{
|
||||
WalletAvailableType: "available",
|
||||
WalletFreezeType: "freeze",
|
||||
WalletUnconfirmedType: "unconfirmed",
|
||||
WalletContractAvailableType: "contract_available",
|
||||
WalletContractFreezeType: "contract_freeze",
|
||||
}
|
||||
|
||||
var nameToWalletType = map[string]WalletType{
|
||||
"available": WalletAvailableType,
|
||||
"freeze": WalletFreezeType,
|
||||
"unconfirmed": WalletUnconfirmedType,
|
||||
"contract_available": WalletContractAvailableType,
|
||||
"contract_freeze": WalletContractFreezeType,
|
||||
}
|
||||
|
||||
// Name returns the name associated with the WalletType.
|
||||
func (w WalletType) Name() string {
|
||||
return walletTypeToName[w]
|
||||
}
|
||||
|
||||
// GetWalletTypeByName returns the WalletType associated with the given name.
|
||||
func GetWalletTypeByName(name string) WalletType {
|
||||
return nameToWalletType[name]
|
||||
}
|
||||
|
||||
var AllWalletType = []WalletType{
|
||||
WalletAvailableType, WalletFreezeType, WalletUnconfirmedType,
|
||||
WalletContractAvailableType, WalletContractFreezeType,
|
||||
}
|
|
@ -1,6 +1,18 @@
|
|||
package model
|
||||
|
||||
import "github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
import (
|
||||
"app-cloudep-trade-service/internal/domain"
|
||||
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ WalletModel = (*customWalletModel)(nil)
|
||||
|
||||
|
@ -9,11 +21,19 @@ type (
|
|||
// and implement the added methods in customWalletModel.
|
||||
WalletModel interface {
|
||||
walletModel
|
||||
InsertMany(ctx context.Context, wallets []*Wallet) (sql.Result, error)
|
||||
Balances(ctx context.Context, req BalanceReq) ([]Wallet, error)
|
||||
}
|
||||
|
||||
customWalletModel struct {
|
||||
*defaultWalletModel
|
||||
}
|
||||
|
||||
BalanceReq struct {
|
||||
UID []string
|
||||
Currency []string
|
||||
Kind []domain.WalletType
|
||||
}
|
||||
)
|
||||
|
||||
// NewWalletModel returns a model for the database table.
|
||||
|
@ -22,3 +42,75 @@ func NewWalletModel(conn sqlx.SqlConn) WalletModel {
|
|||
defaultWalletModel: newWalletModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customWalletModel) InsertMany(ctx context.Context, wallets []*Wallet) (sql.Result, error) {
|
||||
if len(wallets) == 0 {
|
||||
return nil, fmt.Errorf("no data to insert")
|
||||
}
|
||||
|
||||
// 構建多條記錄的佔位符,例如: (?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?), ...
|
||||
valueStrings := make([]string, 0, len(wallets))
|
||||
valueArgs := make([]interface{}, 0, len(wallets)*7) // 每條記錄有7個值
|
||||
|
||||
for _, wallet := range wallets {
|
||||
valueStrings = append(valueStrings, "(?, ?, ?, ?, ?, ?, ?)")
|
||||
valueArgs = append(valueArgs, wallet.Uid, wallet.Brand, wallet.Currency, wallet.Balance, wallet.WalletType, wallet.CreatedAt, wallet.UpdatedAt)
|
||||
}
|
||||
|
||||
// 構建批量插入的 SQL 語句
|
||||
query := fmt.Sprintf("insert into %s (%s) values %s", m.table, walletRowsExpectAutoSet, strings.Join(valueStrings, ","))
|
||||
|
||||
// 使用單一連線執行批量插入
|
||||
return m.conn.ExecCtx(ctx, query, valueArgs...)
|
||||
}
|
||||
|
||||
func (m *customWalletModel) Balances(ctx context.Context, req BalanceReq) ([]Wallet, error) {
|
||||
var data []Wallet
|
||||
query := fmt.Sprintf("select 'id', 'uid', 'currency', 'balance', 'type', 'update_time' from %s", m.table)
|
||||
var conditions []string
|
||||
var args []any
|
||||
|
||||
// 根據條件動態拼接 WHERE 子句
|
||||
if len(req.UID) > 0 {
|
||||
placeholders := strings.Repeat("?,", len(req.UID))
|
||||
placeholders = placeholders[:len(placeholders)-1] // 移除最後一個逗號
|
||||
conditions = append(conditions, fmt.Sprintf("uid IN (%s)", placeholders))
|
||||
args = append(args, convertSliceToInterface(req.UID)...)
|
||||
}
|
||||
if len(req.Currency) > 0 {
|
||||
placeholders := strings.Repeat("?,", len(req.Currency))
|
||||
placeholders = placeholders[:len(placeholders)-1]
|
||||
conditions = append(conditions, fmt.Sprintf("currency IN (%s)", placeholders))
|
||||
args = append(args, convertSliceToInterface(req.Currency)...)
|
||||
}
|
||||
if len(req.Kind) > 0 {
|
||||
placeholders := strings.Repeat("?,", len(req.Kind))
|
||||
placeholders = placeholders[:len(placeholders)-1]
|
||||
conditions = append(conditions, fmt.Sprintf("type IN (%s)", placeholders))
|
||||
args = append(args, convertSliceToInterface(req.Kind)...)
|
||||
}
|
||||
|
||||
// 如果有條件,則拼接 WHERE 子句
|
||||
if len(conditions) > 0 {
|
||||
query += " WHERE " + strings.Join(conditions, " AND ")
|
||||
}
|
||||
|
||||
// 執行查詢
|
||||
err := m.conn.QueryRowCtx(ctx, &data, query, args...)
|
||||
switch {
|
||||
case err == nil:
|
||||
return data, nil
|
||||
case errors.Is(err, sqlc.ErrNotFound):
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func convertSliceToInterface[T any](slice []T) []any {
|
||||
interfaces := make([]any, 0, len(slice))
|
||||
for i, v := range slice {
|
||||
interfaces[i] = v
|
||||
}
|
||||
return interfaces
|
||||
}
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"app-cloudep-trade-service/internal/domain"
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
|
@ -40,8 +43,8 @@ type (
|
|||
Uid string `db:"uid"` // 用戶ID
|
||||
Brand string `db:"brand"` // 品牌名稱
|
||||
Currency string `db:"currency"` // 幣別(或平台點數)
|
||||
Balance float64 `db:"balance"` // 錢包餘額
|
||||
WalletType int64 `db:"wallet_type"` // 錢包種類: 1=可用, 2=凍結, 3=限制(僅出金)
|
||||
Balance decimal.Decimal `db:"balance"` // 錢包餘額
|
||||
WalletType domain.WalletType `db:"wallet_type"` // 錢包種類: 1=可用, 2=凍結, 3=限制(僅出金)
|
||||
CreatedAt int64 `db:"created_at"` // 創建時間
|
||||
UpdatedAt int64 `db:"updated_at"` // 更新時間
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"app-cloudep-trade-service/internal/domain"
|
||||
"app-cloudep-trade-service/internal/domain/repository"
|
||||
"app-cloudep-trade-service/internal/model"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
// 用戶某個幣種餘額
|
||||
type userLocalWallet struct {
|
||||
wm model.WalletModel
|
||||
txConn sqlx.SqlConn
|
||||
|
||||
uid string
|
||||
crypto string
|
||||
|
||||
// local wallet 相關計算的餘額存在這裡
|
||||
walletBalance map[domain.WalletType]model.Wallet
|
||||
|
||||
// local order wallet 相關計算的餘額存在這裡
|
||||
localOrderBalance map[int64]decimal.Decimal
|
||||
|
||||
// local wallet 內所有餘額變化紀錄
|
||||
transactions []model.WalletJournal
|
||||
}
|
||||
|
||||
func NewUserWalletOperator(uid, crypto string, wm model.WalletModel, txConn sqlx.SqlConn) repository.UserWalletOperator {
|
||||
return &userLocalWallet{
|
||||
wm: wm,
|
||||
txConn: txConn,
|
||||
uid: uid,
|
||||
crypto: crypto,
|
||||
|
||||
walletBalance: make(map[domain.WalletType]model.Wallet, len(domain.AllWalletType)),
|
||||
localOrderBalance: make(map[int64]decimal.Decimal, len(domain.AllWalletType)),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"app-cloudep-trade-service/internal/domain"
|
||||
"app-cloudep-trade-service/internal/domain/repository"
|
||||
"app-cloudep-trade-service/internal/model"
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
type WalletRepositoryParam struct {
|
||||
WalletModel model.WalletModel
|
||||
TxConn sqlx.SqlConn
|
||||
}
|
||||
|
||||
type WalletRepository struct {
|
||||
WalletRepositoryParam
|
||||
}
|
||||
|
||||
// GetUserWalletOperator 取得本地操作使用者錢包的操作運算元
|
||||
func (repo *WalletRepository) GetUserWalletOperator(uid, currency string, opts ...repository.Option) repository.UserWalletOperator {
|
||||
db := repo.TxConn
|
||||
|
||||
// 看是否有最新的DB 連線要傳入,做 tx
|
||||
for _, fn := range opts {
|
||||
db = fn()
|
||||
}
|
||||
|
||||
return NewUserWalletOperator(uid, currency, repo.WalletModel, db)
|
||||
}
|
||||
|
||||
// Create 創建錢包,如果有相同的就跳過不建立
|
||||
func (repo *WalletRepository) Create(ctx context.Context, uid, currency, brand string) ([]*model.Wallet, error) {
|
||||
wallets := make([]*model.Wallet, 0, len(domain.AllWalletType))
|
||||
// 建立個人所有種類的錢包
|
||||
now := time.Now().UTC().UnixNano()
|
||||
for _, item := range domain.AllWalletType {
|
||||
balance := decimal.Zero
|
||||
wallets = append(wallets, &model.Wallet{
|
||||
Brand: brand,
|
||||
Currency: currency,
|
||||
Uid: uid,
|
||||
Balance: balance,
|
||||
WalletType: item,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
})
|
||||
}
|
||||
|
||||
_, err := repo.WalletModel.InsertMany(ctx, wallets)
|
||||
if err != nil {
|
||||
// 錯誤代碼 06-021-20
|
||||
e := domain.CommentErrorL(
|
||||
domain.CreateWalletErrorCode,
|
||||
logx.WithContext(ctx),
|
||||
[]logx.LogField{
|
||||
{Key: "param", Value: fmt.Sprintf("uid: %s, currency:%s, brand:%s", uid, currency, brand)},
|
||||
{Key: "func", Value: "WalletModel.InsertMany"},
|
||||
{Key: "err", Value: err},
|
||||
},
|
||||
"failed to insert wallet into mysql:").Wrap(err)
|
||||
|
||||
return nil, e
|
||||
}
|
||||
|
||||
return wallets, nil
|
||||
}
|
||||
|
||||
func (repo *WalletRepository) Balances(ctx context.Context, req repository.BalanceReq) ([]model.Wallet, error) {
|
||||
data, err := repo.WalletModel.Balances(ctx, model.BalanceReq{
|
||||
UID: req.UID,
|
||||
Currency: req.Currency,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// 錯誤代碼 06-021-20
|
||||
e := domain.CommentErrorL(
|
||||
domain.CreateWalletErrorCode,
|
||||
logx.WithContext(ctx),
|
||||
[]logx.LogField{
|
||||
{Key: "param", Value: req},
|
||||
{Key: "func", Value: "WalletModel.Balances"},
|
||||
{Key: "err", Value: err},
|
||||
},
|
||||
"failed to find balance into mongo:").Wrap(err)
|
||||
|
||||
return []model.Wallet{}, e
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (repo *WalletRepository) GetTxDatabaseConn() sqlx.SqlConn {
|
||||
return repo.TxConn
|
||||
}
|
||||
|
||||
func NewWalletRepository(param WalletRepositoryParam) repository.WalletRepository {
|
||||
return &WalletRepository{
|
||||
WalletRepositoryParam: param,
|
||||
}
|
||||
}
|
|
@ -2,12 +2,10 @@ package svc
|
|||
|
||||
import (
|
||||
"app-cloudep-trade-service/internal/config"
|
||||
model "app-cloudep-trade-service/internal/model"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
func mustDSN(c config.Config) string {
|
||||
|
@ -38,11 +36,3 @@ func newDatabase(c config.Config) (*sql.DB, error) {
|
|||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
// MustWalletModel 連線 wallet 時
|
||||
func MustWalletModel(db *sql.DB) model.WalletModel {
|
||||
// 創建並返回 *sqlx.SqlConn
|
||||
sqlConn := sqlx.NewSqlConnFromDB(db)
|
||||
|
||||
return model.NewWalletModel(sqlConn)
|
||||
}
|
||||
|
|
|
@ -3,9 +3,10 @@ package svc
|
|||
import (
|
||||
"app-cloudep-trade-service/internal/config"
|
||||
duc "app-cloudep-trade-service/internal/domain/usecase"
|
||||
"app-cloudep-trade-service/internal/model"
|
||||
"app-cloudep-trade-service/internal/usecase"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
|
||||
ers "code.30cm.net/digimon/library-go/errs"
|
||||
"code.30cm.net/digimon/library-go/errs/code"
|
||||
vi "code.30cm.net/digimon/library-go/validator"
|
||||
|
@ -16,7 +17,7 @@ type ServiceContext struct {
|
|||
Validate vi.Validate
|
||||
|
||||
OrderUseCase duc.OrderUseCase
|
||||
WalletModel model.WalletModel
|
||||
SQLConn sqlx.SqlConn
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
|
@ -32,6 +33,8 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
|||
if err != nil {
|
||||
panic("failed to connect to wallet")
|
||||
}
|
||||
// 創建 SQL 連線並返回
|
||||
sqlConn := sqlx.NewSqlConnFromDB(mysql)
|
||||
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
|
@ -39,8 +42,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
|||
WithDecimalGt(),
|
||||
WithDecimalGte(),
|
||||
),
|
||||
|
||||
SQLConn: sqlConn,
|
||||
OrderUseCase: orderUseCase,
|
||||
WalletModel: MustWalletModel(mysql),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue