package model 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) type ( // WalletModel is an interface to be customized, add more methods here, // 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. func NewWalletModel(conn sqlx.SqlConn) WalletModel { return &customWalletModel{ 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 }