2024-10-29 08:17:31 +00:00
|
|
|
package model
|
|
|
|
|
2024-10-29 14:49:47 +00:00
|
|
|
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"
|
|
|
|
)
|
2024-10-29 08:17:31 +00:00
|
|
|
|
|
|
|
var _ WalletModel = (*customWalletModel)(nil)
|
|
|
|
|
|
|
|
type (
|
|
|
|
// WalletModel is an interface to be customized, add more methods here,
|
|
|
|
// and implement the added methods in customWalletModel.
|
|
|
|
WalletModel interface {
|
|
|
|
walletModel
|
2024-10-29 14:49:47 +00:00
|
|
|
InsertMany(ctx context.Context, wallets []*Wallet) (sql.Result, error)
|
|
|
|
Balances(ctx context.Context, req BalanceReq) ([]Wallet, error)
|
2024-10-29 08:17:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
customWalletModel struct {
|
|
|
|
*defaultWalletModel
|
|
|
|
}
|
2024-10-29 14:49:47 +00:00
|
|
|
|
|
|
|
BalanceReq struct {
|
|
|
|
UID []string
|
|
|
|
Currency []string
|
|
|
|
Kind []domain.WalletType
|
|
|
|
}
|
2024-10-29 08:17:31 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// NewWalletModel returns a model for the database table.
|
|
|
|
func NewWalletModel(conn sqlx.SqlConn) WalletModel {
|
|
|
|
return &customWalletModel{
|
|
|
|
defaultWalletModel: newWalletModel(conn),
|
|
|
|
}
|
|
|
|
}
|
2024-10-29 14:49:47 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|