feature/order_base #1
			
				
			
		
		
		
	|  | @ -91,9 +91,9 @@ func (l *CreateOrderLogic) CreateOrder(in *order.CreateOrderReq) (*order.OKResp, | |||
| 		Brand:       req.Brand, | ||||
| 		OrderUID:    req.OrderUID, | ||||
| 		ReferenceID: req.ReferenceID, | ||||
| 		Count:       req.Count, | ||||
| 		OrderFee:    req.OrderFee, | ||||
| 		Amount:      req.Amount, | ||||
| 		Count:       convertDecimalToDecimal128(req.Count), | ||||
| 		OrderFee:    convertDecimalToDecimal128(req.OrderFee), | ||||
| 		Amount:      convertDecimalToDecimal128(req.Amount), | ||||
| 		// 下面的是未來擴充用,加密貨幣用,或者幣別轉換用,普通訂單用不到
 | ||||
| 		ReferenceBrand:       req.ReferenceBrand, | ||||
| 		ReferenceUID:         req.ReferenceUID, | ||||
|  | @ -101,13 +101,13 @@ func (l *CreateOrderLogic) CreateOrder(in *order.CreateOrderReq) (*order.OKResp, | |||
| 		ThreePartyStatus:     req.ThreePartyStatus, | ||||
| 		DirectionType:        req.DirectionType, | ||||
| 		CryptoType:           req.CryptoType, | ||||
| 		ThirdPartyFee:        req.ThirdPartyFee, | ||||
| 		CryptoToUSDTRate:     req.CryptoToUSDTRate, | ||||
| 		FiatToUSDRate:        req.FiatToUSDRate, | ||||
| 		FeeCryptoToUSDTRate:  req.FeeCryptoToUSDTRate, | ||||
| 		USDTToCryptoTypeRate: req.USDTToCryptoTypeRate, | ||||
| 		ThirdPartyFee:        convertDecimalPtrToDecimal128(req.ThirdPartyFee), | ||||
| 		CryptoToUSDTRate:     convertDecimalPtrToDecimal128(req.CryptoToUSDTRate), | ||||
| 		FiatToUSDRate:        convertDecimalPtrToDecimal128(req.FiatToUSDRate), | ||||
| 		FeeCryptoToUSDTRate:  convertDecimalPtrToDecimal128(req.FeeCryptoToUSDTRate), | ||||
| 		USDTToCryptoTypeRate: convertDecimalPtrToDecimal128(req.USDTToCryptoTypeRate), | ||||
| 		PaymentFiat:          req.PaymentFiat, | ||||
| 		PaymentUnitPrice:     req.PaymentUnitPrice, | ||||
| 		PaymentUnitPrice:     convertDecimalPtrToDecimal128(req.PaymentUnitPrice), | ||||
| 		PaymentTemplateID:    req.PaymentTemplateID, | ||||
| 		OrderArrivalTime:     req.OrderArrivalTime, | ||||
| 		OrderPaymentTime:     req.OrderPaymentTime, | ||||
|  | @ -116,7 +116,7 @@ func (l *CreateOrderLogic) CreateOrder(in *order.CreateOrderReq) (*order.OKResp, | |||
| 		TxHash:               req.TxHash, | ||||
| 		FromAddress:          req.FromAddress, | ||||
| 		ToAddress:            req.ToAddress, | ||||
| 		ChainFee:             req.ChainFee, | ||||
| 		ChainFee:             convertDecimalPtrToDecimal128(req.ChainFee), | ||||
| 		ChainFeeCrypto:       req.ChainFeeCrypto, | ||||
| 		Memo:                 req.Memo, | ||||
| 		OrderNote:            req.OrderNote, | ||||
|  | @ -252,16 +252,3 @@ func buildCreateOrderReq(in *order.CreateOrderReq) (*createOrderReq, error) { | |||
| 
 | ||||
| 	return createOrderReq, nil | ||||
| } | ||||
| 
 | ||||
| // Helper function for decimal conversion with nil support
 | ||||
| func decimalPtrFromString(val string) *decimal.Decimal { | ||||
| 	if val == "" { | ||||
| 		return nil | ||||
| 	} | ||||
| 	dec, err := decimal.NewFromString(val) | ||||
| 	if err != nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	return &dec | ||||
| } | ||||
|  |  | |||
|  | @ -15,42 +15,6 @@ import ( | |||
| 	"go.uber.org/mock/gomock" | ||||
| ) | ||||
| 
 | ||||
| func TestDecimalPtrFromString(t *testing.T) { | ||||
| 	tests := []struct { | ||||
| 		name     string | ||||
| 		input    string | ||||
| 		expected *decimal.Decimal | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name:     "valid decimal string", | ||||
| 			input:    "10.5", | ||||
| 			expected: decimalPtr("10.5"), // 使用輔助函數將字串轉換為指針
 | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:     "empty string returns nil", | ||||
| 			input:    "", | ||||
| 			expected: nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name:     "invalid decimal string returns nil", | ||||
| 			input:    "invalid-decimal", | ||||
| 			expected: nil, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			result := decimalPtrFromString(tt.input) // 調用要測試的函數
 | ||||
| 			if tt.expected == nil { | ||||
| 				assert.Nil(t, result) | ||||
| 			} else { | ||||
| 				assert.NotNil(t, result) | ||||
| 				assert.True(t, tt.expected.Equal(*result), "Expected %v, got %v", tt.expected, result) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestBuildCreateOrderReq(t *testing.T) { | ||||
| 	tests := []struct { | ||||
| 		name      string | ||||
|  |  | |||
|  | @ -0,0 +1,99 @@ | |||
| package orderservicelogic | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/shopspring/decimal" | ||||
| 	"github.com/zeromicro/go-zero/core/logx" | ||||
| 	"go.mongodb.org/mongo-driver/bson/primitive" | ||||
| ) | ||||
| 
 | ||||
| // Helper function for decimal conversion with nil support and logging
 | ||||
| func decimalPtrFromString(val string) *decimal.Decimal { | ||||
| 	if val == "" { | ||||
| 		return nil | ||||
| 	} | ||||
| 	dec, err := decimal.NewFromString(val) | ||||
| 	if err != nil { | ||||
| 		logx.Errorf("Failed to convert string to decimal: %v", err) | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	return &dec | ||||
| } | ||||
| 
 | ||||
| // Convert decimal.Decimal to primitive.Decimal128 and handle nil values
 | ||||
| func convertDecimalPtrToDecimal128(d *decimal.Decimal) *primitive.Decimal128 { | ||||
| 	if d == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	result, err := primitive.ParseDecimal128(d.String()) | ||||
| 	if err != nil { | ||||
| 		logx.Errorf("Failed to convert decimal to Decimal128: %v", err) | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	return &result | ||||
| } | ||||
| 
 | ||||
| // Convert decimal.Decimal (non-pointer) to primitive.Decimal128 and log errors
 | ||||
| func convertDecimalToDecimal128(d decimal.Decimal) primitive.Decimal128 { | ||||
| 	result, err := primitive.ParseDecimal128(d.String()) | ||||
| 	if err != nil { | ||||
| 		logx.Errorf("Failed to convert decimal to Decimal128: %v", err) | ||||
| 		return primitive.NewDecimal128(0, 0) | ||||
| 	} | ||||
| 
 | ||||
| 	return result | ||||
| } | ||||
| 
 | ||||
| // 將 primitive.Decimal128 轉換為字符串
 | ||||
| func convertDecimal128ToString(d128 *primitive.Decimal128) *string { | ||||
| 	if d128 != nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	result := d128.String() | ||||
| 
 | ||||
| 	return &result | ||||
| } | ||||
| 
 | ||||
| // Helper functions for optional fields
 | ||||
| func optionalString(s *string) *string { | ||||
| 	if s != nil { | ||||
| 		return s | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func optionalInt64(i *int64) *int64 { | ||||
| 	if i != nil { | ||||
| 		return i | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func optionalDecimalToString(d *decimal.Decimal) *string { | ||||
| 	if d != nil { | ||||
| 		s := d.String() | ||||
| 
 | ||||
| 		return &s | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func nilString(s *string) *string { | ||||
| 	if s == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| func nilInt64(i *int64) *int64 { | ||||
| 	if i == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	return i | ||||
| } | ||||
|  | @ -2,12 +2,9 @@ package orderservicelogic | |||
| 
 | ||||
| import ( | ||||
| 	"app-cloudep-order-server/gen_result/pb/order" | ||||
| 	"context" | ||||
| 
 | ||||
| 	ers "code.30cm.net/digimon/library-go/errs" | ||||
| 	"github.com/shopspring/decimal" | ||||
| 
 | ||||
| 	"app-cloudep-order-server/internal/svc" | ||||
| 	ers "code.30cm.net/digimon/library-go/errs" | ||||
| 	"context" | ||||
| 
 | ||||
| 	"github.com/zeromicro/go-zero/core/logx" | ||||
| ) | ||||
|  | @ -65,13 +62,13 @@ func (l *GetOrderLogic) GetOrder(in *order.GetOrderReq) (*order.GetOrderResp, er | |||
| 		ThreePartyStatus:     nilInt64(o.ThreePartyStatus), | ||||
| 		DirectionType:        nilInt64(o.DirectionType), | ||||
| 		CryptoType:           nilString(o.CryptoType), | ||||
| 		ThirdPartyFee:        decimalToString(o.ThirdPartyFee), | ||||
| 		CryptoToUsdtRate:     decimalToString(o.CryptoToUSDTRate), | ||||
| 		FiatToUsdRate:        decimalToString(o.FiatToUSDRate), | ||||
| 		FeeCryptoToUsdtRate:  decimalToString(o.FeeCryptoToUSDTRate), | ||||
| 		UsdtToCryptoTypeRate: decimalToString(o.USDTToCryptoTypeRate), | ||||
| 		ThirdPartyFee:        convertDecimal128ToString(o.ThirdPartyFee), | ||||
| 		CryptoToUsdtRate:     convertDecimal128ToString(o.CryptoToUSDTRate), | ||||
| 		FiatToUsdRate:        convertDecimal128ToString(o.FiatToUSDRate), | ||||
| 		FeeCryptoToUsdtRate:  convertDecimal128ToString(o.FeeCryptoToUSDTRate), | ||||
| 		UsdtToCryptoTypeRate: convertDecimal128ToString(o.USDTToCryptoTypeRate), | ||||
| 		PaymentFiat:          nilString(o.PaymentFiat), | ||||
| 		PaymentUnitPrice:     decimalToString(o.PaymentUnitPrice), | ||||
| 		PaymentUnitPrice:     convertDecimal128ToString(o.PaymentUnitPrice), | ||||
| 		PaymentTemplateId:    nilString(o.PaymentTemplateID), | ||||
| 		OrderArrivalTime:     nilInt64(o.OrderArrivalTime), | ||||
| 		OrderPaymentTime:     nilInt64(o.OrderPaymentTime), | ||||
|  | @ -80,41 +77,9 @@ func (l *GetOrderLogic) GetOrder(in *order.GetOrderReq) (*order.GetOrderResp, er | |||
| 		TxHash:               nilString(o.TxHash), | ||||
| 		FromAddress:          nilString(o.FromAddress), | ||||
| 		ToAddress:            nilString(o.ToAddress), | ||||
| 		ChainFee:             decimalToString(o.ChainFee), | ||||
| 		ChainFee:             convertDecimal128ToString(o.ChainFee), | ||||
| 		ChainFeeCrypto:       nilString(o.ChainFeeCrypto), | ||||
| 		Memo:                 nilString(o.Memo), | ||||
| 		OrderNote:            nilString(o.OrderNote), | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func decimalToString(amount *decimal.Decimal) *string { | ||||
| 	if amount == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	a := amount.String() | ||||
| 
 | ||||
| 	return &a | ||||
| } | ||||
| 
 | ||||
| func nilString(s *string) *string { | ||||
| 	if s == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| func nilInt64(i *int64) *int64 { | ||||
| 	if i == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	return i | ||||
| } | ||||
| 
 | ||||
| // Helper functions
 | ||||
| //
 | ||||
| //nolint:unused
 | ||||
| func ptrString(s string) *string { | ||||
| 	return &s | ||||
| } | ||||
|  |  | |||
|  | @ -8,9 +8,9 @@ import ( | |||
| 	"app-cloudep-order-server/internal/svc" | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"go.mongodb.org/mongo-driver/bson/primitive" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/shopspring/decimal" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"go.uber.org/mock/gomock" | ||||
| ) | ||||
|  | @ -28,6 +28,9 @@ func TestGetOrder(t *testing.T) { | |||
| 		OrderModel: mockOrderModel, | ||||
| 		Validate:   mockValidate, | ||||
| 	} | ||||
| 	Count, _ := primitive.ParseDecimal128("10.5") | ||||
| 	OrderFee, _ := primitive.ParseDecimal128("0.5") | ||||
| 	Amount, _ := primitive.ParseDecimal128("100") | ||||
| 
 | ||||
| 	// 模擬返回的訂單數據
 | ||||
| 	mockOrder := &model.Order{ | ||||
|  | @ -39,9 +42,9 @@ func TestGetOrder(t *testing.T) { | |||
| 		Brand:       "TestBrand", | ||||
| 		OrderUID:    "UID123", | ||||
| 		ReferenceID: "REF123", | ||||
| 		Count:       decimal.RequireFromString("10.5"), | ||||
| 		OrderFee:    decimal.RequireFromString("0.5"), | ||||
| 		Amount:      decimal.RequireFromString("100"), | ||||
| 		Count:       Count, | ||||
| 		OrderFee:    OrderFee, | ||||
| 		Amount:      Amount, | ||||
| 	} | ||||
| 
 | ||||
| 	// 測試數據集
 | ||||
|  |  | |||
|  | @ -5,10 +5,8 @@ import ( | |||
| 	model "app-cloudep-order-server/internal/model/mongo" | ||||
| 	"context" | ||||
| 
 | ||||
| 	ers "code.30cm.net/digimon/library-go/errs" | ||||
| 	"github.com/shopspring/decimal" | ||||
| 
 | ||||
| 	"app-cloudep-order-server/internal/svc" | ||||
| 	ers "code.30cm.net/digimon/library-go/errs" | ||||
| 
 | ||||
| 	"github.com/zeromicro/go-zero/core/logx" | ||||
| ) | ||||
|  | @ -101,13 +99,13 @@ func ConvertOrderToGetOrderResp(o model.Order) *order.GetOrderResp { | |||
| 		ThreePartyStatus:     optionalInt64(o.ThreePartyStatus), | ||||
| 		DirectionType:        optionalInt64(o.DirectionType), | ||||
| 		CryptoType:           optionalString(o.CryptoType), | ||||
| 		ThirdPartyFee:        optionalDecimalToString(o.ThirdPartyFee), | ||||
| 		CryptoToUsdtRate:     optionalDecimalToString(o.CryptoToUSDTRate), | ||||
| 		FiatToUsdRate:        optionalDecimalToString(o.FiatToUSDRate), | ||||
| 		FeeCryptoToUsdtRate:  optionalDecimalToString(o.FeeCryptoToUSDTRate), | ||||
| 		UsdtToCryptoTypeRate: optionalDecimalToString(o.USDTToCryptoTypeRate), | ||||
| 		ThirdPartyFee:        convertDecimal128ToString(o.ThirdPartyFee), | ||||
| 		CryptoToUsdtRate:     convertDecimal128ToString(o.CryptoToUSDTRate), | ||||
| 		FiatToUsdRate:        convertDecimal128ToString(o.FiatToUSDRate), | ||||
| 		FeeCryptoToUsdtRate:  convertDecimal128ToString(o.FeeCryptoToUSDTRate), | ||||
| 		UsdtToCryptoTypeRate: convertDecimal128ToString(o.USDTToCryptoTypeRate), | ||||
| 		PaymentFiat:          optionalString(o.PaymentFiat), | ||||
| 		PaymentUnitPrice:     optionalDecimalToString(o.PaymentUnitPrice), | ||||
| 		PaymentUnitPrice:     convertDecimal128ToString(o.PaymentUnitPrice), | ||||
| 		PaymentTemplateId:    optionalString(o.PaymentTemplateID), | ||||
| 		OrderArrivalTime:     optionalInt64(o.OrderArrivalTime), | ||||
| 		OrderPaymentTime:     optionalInt64(o.OrderPaymentTime), | ||||
|  | @ -116,7 +114,7 @@ func ConvertOrderToGetOrderResp(o model.Order) *order.GetOrderResp { | |||
| 		TxHash:               optionalString(o.TxHash), | ||||
| 		FromAddress:          optionalString(o.FromAddress), | ||||
| 		ToAddress:            optionalString(o.ToAddress), | ||||
| 		ChainFee:             optionalDecimalToString(o.ChainFee), | ||||
| 		ChainFee:             convertDecimal128ToString(o.ChainFee), | ||||
| 		ChainFeeCrypto:       optionalString(o.ChainFeeCrypto), | ||||
| 		Memo:                 optionalString(o.Memo), | ||||
| 		OrderNote:            optionalString(o.OrderNote), | ||||
|  | @ -124,39 +122,3 @@ func ConvertOrderToGetOrderResp(o model.Order) *order.GetOrderResp { | |||
| 		UpdateTime:           o.UpdateTime, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Helper functions for optional fields
 | ||||
| func optionalString(s *string) *string { | ||||
| 	if s != nil { | ||||
| 		return s | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func optionalInt64(i *int64) *int64 { | ||||
| 	if i != nil { | ||||
| 		return i | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func optionalDecimalToString(d *decimal.Decimal) *string { | ||||
| 	if d != nil { | ||||
| 		s := d.String() | ||||
| 
 | ||||
| 		return &s | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func ConvertOrdersToGetOrderResp(orders []model.Order) []*order.GetOrderResp { | ||||
| 	res := make([]*order.GetOrderResp, 0, len(orders)) | ||||
| 	for _, o := range orders { | ||||
| 		res = append(res, ConvertOrderToGetOrderResp(o)) | ||||
| 	} | ||||
| 
 | ||||
| 	return res | ||||
| } | ||||
|  |  | |||
|  | @ -1,459 +1,444 @@ | |||
| package orderservicelogic | ||||
| 
 | ||||
| import ( | ||||
| 	"app-cloudep-order-server/gen_result/pb/order" | ||||
| 	mocksvc "app-cloudep-order-server/internal/mock/lib" | ||||
| 	mockmodel "app-cloudep-order-server/internal/mock/model" | ||||
| 	model "app-cloudep-order-server/internal/model/mongo" | ||||
| 	"app-cloudep-order-server/internal/svc" | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/shopspring/decimal" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"go.uber.org/mock/gomock" | ||||
| ) | ||||
| 
 | ||||
| func TestConvertOrdersToGetOrderResp(t *testing.T) { | ||||
| 	tests := []struct { | ||||
| 		name     string | ||||
| 		input    []model.Order | ||||
| 		expected []*order.GetOrderResp | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name:     "空訂單列表", | ||||
| 			input:    []model.Order{}, | ||||
| 			expected: []*order.GetOrderResp{}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "單筆訂單", | ||||
| 			input: []model.Order{ | ||||
| 				{ | ||||
| 					BusinessID:  "B123", | ||||
| 					OrderType:   1, | ||||
| 					OrderStatus: 2, | ||||
| 					Brand:       "TestBrand", | ||||
| 					OrderUID:    "UID123", | ||||
| 					ReferenceID: "REF123", | ||||
| 					Count:       decimal.RequireFromString("10.5"), | ||||
| 					OrderFee:    decimal.RequireFromString("0.5"), | ||||
| 					Amount:      decimal.RequireFromString("100"), | ||||
| 				}, | ||||
| 			}, | ||||
| 			expected: []*order.GetOrderResp{ | ||||
| 				{ | ||||
| 					BusinessId:  "B123", | ||||
| 					OrderType:   1, | ||||
| 					OrderStatus: 2, | ||||
| 					Brand:       "TestBrand", | ||||
| 					OrderUid:    "UID123", | ||||
| 					ReferenceId: "REF123", | ||||
| 					Count:       "10.5", | ||||
| 					OrderFee:    "0.5", | ||||
| 					Amount:      "100", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "多筆訂單", | ||||
| 			input: []model.Order{ | ||||
| 				{ | ||||
| 					BusinessID:  "B123", | ||||
| 					OrderType:   1, | ||||
| 					OrderStatus: 2, | ||||
| 					Brand:       "TestBrand", | ||||
| 					OrderUID:    "UID123", | ||||
| 					ReferenceID: "REF123", | ||||
| 					Count:       decimal.RequireFromString("10.5"), | ||||
| 					OrderFee:    decimal.RequireFromString("0.5"), | ||||
| 					Amount:      decimal.RequireFromString("100"), | ||||
| 				}, | ||||
| 				{ | ||||
| 					BusinessID:  "B456", | ||||
| 					OrderType:   2, | ||||
| 					OrderStatus: 3, | ||||
| 					Brand:       "OtherBrand", | ||||
| 					OrderUID:    "UID456", | ||||
| 					ReferenceID: "REF456", | ||||
| 					Count:       decimal.RequireFromString("20"), | ||||
| 					OrderFee:    decimal.RequireFromString("1"), | ||||
| 					Amount:      decimal.RequireFromString("200"), | ||||
| 				}, | ||||
| 			}, | ||||
| 			expected: []*order.GetOrderResp{ | ||||
| 				{ | ||||
| 					BusinessId:  "B123", | ||||
| 					OrderType:   1, | ||||
| 					OrderStatus: 2, | ||||
| 					Brand:       "TestBrand", | ||||
| 					OrderUid:    "UID123", | ||||
| 					ReferenceId: "REF123", | ||||
| 					Count:       "10.5", | ||||
| 					OrderFee:    "0.5", | ||||
| 					Amount:      "100", | ||||
| 				}, | ||||
| 				{ | ||||
| 					BusinessId:  "B456", | ||||
| 					OrderType:   2, | ||||
| 					OrderStatus: 3, | ||||
| 					Brand:       "OtherBrand", | ||||
| 					OrderUid:    "UID456", | ||||
| 					ReferenceId: "REF456", | ||||
| 					Count:       "20", | ||||
| 					OrderFee:    "1", | ||||
| 					Amount:      "200", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			// 執行 ConvertOrdersToGetOrderResp 函數
 | ||||
| 			result := ConvertOrdersToGetOrderResp(tt.input) | ||||
| 
 | ||||
| 			// 驗證結果
 | ||||
| 			assert.Equal(t, tt.expected, result) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestOptionalString(t *testing.T) { | ||||
| 	t.Run("非 nil 字串", func(t *testing.T) { | ||||
| 		str := "hello" | ||||
| 		result := optionalString(&str) | ||||
| 		assert.NotNil(t, result) | ||||
| 		assert.Equal(t, &str, result) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("nil 字串", func(t *testing.T) { | ||||
| 		result := optionalString(nil) | ||||
| 		assert.Nil(t, result) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func TestOptionalInt64(t *testing.T) { | ||||
| 	t.Run("非 nil int64", func(t *testing.T) { | ||||
| 		num := int64(123) | ||||
| 		result := optionalInt64(&num) | ||||
| 		assert.NotNil(t, result) | ||||
| 		assert.Equal(t, &num, result) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("nil int64", func(t *testing.T) { | ||||
| 		result := optionalInt64(nil) | ||||
| 		assert.Nil(t, result) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func TestOptionalDecimalToString(t *testing.T) { | ||||
| 	t.Run("非 nil decimal", func(t *testing.T) { | ||||
| 		dec := decimal.NewFromInt(123) | ||||
| 		expected := "123" | ||||
| 		result := optionalDecimalToString(&dec) | ||||
| 		assert.NotNil(t, result) | ||||
| 		assert.Equal(t, &expected, result) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("nil decimal", func(t *testing.T) { | ||||
| 		result := optionalDecimalToString(nil) | ||||
| 		assert.Nil(t, result) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func TestConvertOrderToGetOrderResp(t *testing.T) { | ||||
| 	tests := []struct { | ||||
| 		name     string | ||||
| 		input    model.Order | ||||
| 		expected *order.GetOrderResp | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "所有欄位都有值", | ||||
| 			input: model.Order{ | ||||
| 				BusinessID:           "B123", | ||||
| 				OrderType:            1, | ||||
| 				OrderStatus:          2, | ||||
| 				Brand:                "TestBrand", | ||||
| 				OrderUID:             "UID123", | ||||
| 				ReferenceID:          "REF123", | ||||
| 				Count:                decimal.RequireFromString("10.5"), | ||||
| 				OrderFee:             decimal.RequireFromString("0.5"), | ||||
| 				Amount:               decimal.RequireFromString("100"), | ||||
| 				ReferenceBrand:       ptrString("OtherBrand"), | ||||
| 				ReferenceUID:         ptrString("REFUID"), | ||||
| 				WalletStatus:         ptrInt64(1), | ||||
| 				ThreePartyStatus:     ptrInt64(2), | ||||
| 				DirectionType:        ptrInt64(1), | ||||
| 				CryptoType:           ptrString("BTC"), | ||||
| 				ThirdPartyFee:        decimalPtrFromString("0.01"), | ||||
| 				CryptoToUSDTRate:     decimalPtrFromString("50000"), | ||||
| 				FiatToUSDRate:        decimalPtrFromString("1"), | ||||
| 				FeeCryptoToUSDTRate:  decimalPtrFromString("0.02"), | ||||
| 				USDTToCryptoTypeRate: decimalPtrFromString("0.00002"), | ||||
| 				PaymentFiat:          ptrString("USD"), | ||||
| 				PaymentUnitPrice:     decimalPtrFromString("50000"), | ||||
| 				PaymentTemplateID:    ptrString("TEMPLATE123"), | ||||
| 				OrderArrivalTime:     ptrInt64(1630000000), | ||||
| 				OrderPaymentTime:     ptrInt64(1620000000), | ||||
| 				UnpaidTimeoutSecond:  ptrInt64(3600), | ||||
| 				ChainType:            ptrString("ETH"), | ||||
| 				TxHash:               ptrString("0xABC123"), | ||||
| 				FromAddress:          ptrString("0xFROM123"), | ||||
| 				ToAddress:            ptrString("0xTO123"), | ||||
| 				ChainFee:             decimalPtrFromString("0.001"), | ||||
| 				ChainFeeCrypto:       ptrString("ETH"), | ||||
| 				Memo:                 ptrString("Test Memo"), | ||||
| 				OrderNote:            ptrString("Test Note"), | ||||
| 				CreateTime:           1620000000, | ||||
| 				UpdateTime:           1630000000, | ||||
| 			}, | ||||
| 			expected: &order.GetOrderResp{ | ||||
| 				BusinessId:           "B123", | ||||
| 				OrderType:            1, | ||||
| 				OrderStatus:          2, | ||||
| 				Brand:                "TestBrand", | ||||
| 				OrderUid:             "UID123", | ||||
| 				ReferenceId:          "REF123", | ||||
| 				Count:                "10.5", | ||||
| 				OrderFee:             "0.5", | ||||
| 				Amount:               "100", | ||||
| 				ReferenceBrand:       ptrString("OtherBrand"), | ||||
| 				ReferenceUid:         ptrString("REFUID"), | ||||
| 				WalletStatus:         ptrInt64(1), | ||||
| 				ThreePartyStatus:     ptrInt64(2), | ||||
| 				DirectionType:        ptrInt64(1), | ||||
| 				CryptoType:           ptrString("BTC"), | ||||
| 				ThirdPartyFee:        ptrString("0.01"), | ||||
| 				CryptoToUsdtRate:     ptrString("50000"), | ||||
| 				FiatToUsdRate:        ptrString("1"), | ||||
| 				FeeCryptoToUsdtRate:  ptrString("0.02"), | ||||
| 				UsdtToCryptoTypeRate: ptrString("0.00002"), | ||||
| 				PaymentFiat:          ptrString("USD"), | ||||
| 				PaymentUnitPrice:     ptrString("50000"), | ||||
| 				PaymentTemplateId:    ptrString("TEMPLATE123"), | ||||
| 				OrderArrivalTime:     ptrInt64(1630000000), | ||||
| 				OrderPaymentTime:     ptrInt64(1620000000), | ||||
| 				UnpaidTimeoutSecond:  ptrInt64(3600), | ||||
| 				ChainType:            ptrString("ETH"), | ||||
| 				TxHash:               ptrString("0xABC123"), | ||||
| 				FromAddress:          ptrString("0xFROM123"), | ||||
| 				ToAddress:            ptrString("0xTO123"), | ||||
| 				ChainFee:             ptrString("0.001"), | ||||
| 				ChainFeeCrypto:       ptrString("ETH"), | ||||
| 				Memo:                 ptrString("Test Memo"), | ||||
| 				OrderNote:            ptrString("Test Note"), | ||||
| 				CreateTime:           1620000000, | ||||
| 				UpdateTime:           1630000000, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "部分欄位為 nil", | ||||
| 			input: model.Order{ | ||||
| 				BusinessID:           "B456", | ||||
| 				OrderType:            1, | ||||
| 				OrderStatus:          2, | ||||
| 				Brand:                "TestBrand", | ||||
| 				OrderUID:             "UID456", | ||||
| 				ReferenceID:          "REF456", | ||||
| 				Count:                decimal.RequireFromString("10"), | ||||
| 				OrderFee:             decimal.RequireFromString("1"), | ||||
| 				Amount:               decimal.RequireFromString("100"), | ||||
| 				ReferenceBrand:       nil, | ||||
| 				ReferenceUID:         nil, | ||||
| 				WalletStatus:         nil, | ||||
| 				ThreePartyStatus:     nil, | ||||
| 				DirectionType:        nil, | ||||
| 				CryptoType:           nil, | ||||
| 				ThirdPartyFee:        nil, | ||||
| 				CryptoToUSDTRate:     nil, | ||||
| 				FiatToUSDRate:        nil, | ||||
| 				FeeCryptoToUSDTRate:  nil, | ||||
| 				USDTToCryptoTypeRate: nil, | ||||
| 				PaymentFiat:          nil, | ||||
| 				PaymentUnitPrice:     nil, | ||||
| 				PaymentTemplateID:    nil, | ||||
| 				OrderArrivalTime:     nil, | ||||
| 				OrderPaymentTime:     nil, | ||||
| 				UnpaidTimeoutSecond:  nil, | ||||
| 				ChainType:            nil, | ||||
| 				TxHash:               nil, | ||||
| 				FromAddress:          nil, | ||||
| 				ToAddress:            nil, | ||||
| 				ChainFee:             nil, | ||||
| 				ChainFeeCrypto:       nil, | ||||
| 				Memo:                 nil, | ||||
| 				OrderNote:            nil, | ||||
| 				CreateTime:           1620000000, | ||||
| 				UpdateTime:           1630000000, | ||||
| 			}, | ||||
| 			expected: &order.GetOrderResp{ | ||||
| 				BusinessId:           "B456", | ||||
| 				OrderType:            1, | ||||
| 				OrderStatus:          2, | ||||
| 				Brand:                "TestBrand", | ||||
| 				OrderUid:             "UID456", | ||||
| 				ReferenceId:          "REF456", | ||||
| 				Count:                "10", | ||||
| 				OrderFee:             "1", | ||||
| 				Amount:               "100", | ||||
| 				ReferenceBrand:       nil, | ||||
| 				ReferenceUid:         nil, | ||||
| 				WalletStatus:         nil, | ||||
| 				ThreePartyStatus:     nil, | ||||
| 				DirectionType:        nil, | ||||
| 				CryptoType:           nil, | ||||
| 				ThirdPartyFee:        nil, | ||||
| 				CryptoToUsdtRate:     nil, | ||||
| 				FiatToUsdRate:        nil, | ||||
| 				FeeCryptoToUsdtRate:  nil, | ||||
| 				UsdtToCryptoTypeRate: nil, | ||||
| 				PaymentFiat:          nil, | ||||
| 				PaymentUnitPrice:     nil, | ||||
| 				PaymentTemplateId:    nil, | ||||
| 				OrderArrivalTime:     nil, | ||||
| 				OrderPaymentTime:     nil, | ||||
| 				UnpaidTimeoutSecond:  nil, | ||||
| 				ChainType:            nil, | ||||
| 				TxHash:               nil, | ||||
| 				FromAddress:          nil, | ||||
| 				ToAddress:            nil, | ||||
| 				ChainFee:             nil, | ||||
| 				ChainFeeCrypto:       nil, | ||||
| 				Memo:                 nil, | ||||
| 				OrderNote:            nil, | ||||
| 				CreateTime:           1620000000, | ||||
| 				UpdateTime:           1630000000, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			// 執行 ConvertOrderToGetOrderResp 函數
 | ||||
| 			result := ConvertOrderToGetOrderResp(tt.input) | ||||
| 
 | ||||
| 			// 驗證結果
 | ||||
| 			assert.Equal(t, tt.expected, result) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestListOrder(t *testing.T) { | ||||
| 	ctrl := gomock.NewController(t) | ||||
| 	defer ctrl.Finish() | ||||
| 
 | ||||
| 	// 初始化 mock 依賴
 | ||||
| 	mockOrderModel := mockmodel.NewMockOrderModel(ctrl) | ||||
| 	mockValidate := mocksvc.NewMockValidate(ctrl) | ||||
| 
 | ||||
| 	// 初始化服務上下文
 | ||||
| 	svcCtx := &svc.ServiceContext{ | ||||
| 		OrderModel: mockOrderModel, | ||||
| 		Validate:   mockValidate, | ||||
| 	} | ||||
| 
 | ||||
| 	// 測試數據集
 | ||||
| 	tests := []struct { | ||||
| 		name        string | ||||
| 		input       *order.ListOrderReq | ||||
| 		prepare     func() | ||||
| 		expectErr   bool | ||||
| 		expectedRes *order.ListOrderResp | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "成功取得訂單列表", | ||||
| 			input: &order.ListOrderReq{ | ||||
| 				PageIndex: 1, | ||||
| 				PageSize:  10, | ||||
| 			}, | ||||
| 			prepare: func() { | ||||
| 				// 模擬驗證成功
 | ||||
| 				mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) | ||||
| 				// 模擬返回訂單列表
 | ||||
| 				mockOrderModel.EXPECT().ListOrder(gomock.Any(), gomock.Any()).Return([]model.Order{ | ||||
| 					{ | ||||
| 						BusinessID:  "B123", | ||||
| 						OrderType:   1, | ||||
| 						OrderStatus: 2, | ||||
| 						Brand:       "TestBrand", | ||||
| 						OrderUID:    "UID123", | ||||
| 						ReferenceID: "REF123", | ||||
| 						Count:       decimal.RequireFromString("10.5"), | ||||
| 						OrderFee:    decimal.RequireFromString("0.5"), | ||||
| 						Amount:      decimal.RequireFromString("100"), | ||||
| 					}, | ||||
| 				}, int64(1), nil).Times(1) | ||||
| 			}, | ||||
| 			expectErr: false, | ||||
| 			expectedRes: &order.ListOrderResp{ | ||||
| 				Data: []*order.GetOrderResp{ | ||||
| 					{ | ||||
| 						BusinessId:  "B123", | ||||
| 						OrderType:   1, | ||||
| 						OrderStatus: 2, | ||||
| 						Brand:       "TestBrand", | ||||
| 						OrderUid:    "UID123", | ||||
| 						ReferenceId: "REF123", | ||||
| 						Count:       "10.5", | ||||
| 						OrderFee:    "0.5", | ||||
| 						Amount:      "100", | ||||
| 					}, | ||||
| 				}, | ||||
| 				Page: &order.Pager{ | ||||
| 					Total: 1, | ||||
| 					Index: 1, | ||||
| 					Size:  10, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "訂單查詢失敗", | ||||
| 			input: &order.ListOrderReq{ | ||||
| 				PageIndex: 1, | ||||
| 				PageSize:  10, | ||||
| 			}, | ||||
| 			prepare: func() { | ||||
| 				// 模擬驗證成功
 | ||||
| 				mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) | ||||
| 				// 模擬返回查詢錯誤
 | ||||
| 				mockOrderModel.EXPECT().ListOrder(gomock.Any(), gomock.Any()).Return(nil, int64(0), errors.New("query failed")).Times(1) | ||||
| 			}, | ||||
| 			expectErr: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "分頁錯誤", | ||||
| 			input: &order.ListOrderReq{ | ||||
| 				PageIndex: 0, | ||||
| 				PageSize:  10, | ||||
| 			}, | ||||
| 			prepare: func() { | ||||
| 				// 模擬驗證失敗,因為 PageIndex 為 0
 | ||||
| 				mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(errors.New("invalid pagination")).Times(1) | ||||
| 			}, | ||||
| 			expectErr: true, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			// 準備測試環境
 | ||||
| 			tt.prepare() | ||||
| 
 | ||||
| 			// 初始化 ListOrderLogic
 | ||||
| 			logic := NewListOrderLogic(context.TODO(), svcCtx) | ||||
| 
 | ||||
| 			// 執行 ListOrder
 | ||||
| 			resp, err := logic.ListOrder(tt.input) | ||||
| 
 | ||||
| 			// 驗證結果
 | ||||
| 			if tt.expectErr { | ||||
| 				assert.Error(t, err) | ||||
| 				assert.Nil(t, resp) | ||||
| 			} else { | ||||
| 				assert.NoError(t, err) | ||||
| 				assert.Equal(t, tt.expectedRes, resp) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| // func TestConvertOrdersToGetOrderResp(t *testing.T) {
 | ||||
| // 	tests := []struct {
 | ||||
| // 		name     string
 | ||||
| // 		input    []model.Order
 | ||||
| // 		expected []*order.GetOrderResp
 | ||||
| // 	}{
 | ||||
| // 		{
 | ||||
| // 			name:     "空訂單列表",
 | ||||
| // 			input:    []model.Order{},
 | ||||
| // 			expected: []*order.GetOrderResp{},
 | ||||
| // 		},
 | ||||
| // 		{
 | ||||
| // 			name: "單筆訂單",
 | ||||
| // 			input: []model.Order{
 | ||||
| // 				{
 | ||||
| // 					BusinessID:  "B123",
 | ||||
| // 					OrderType:   1,
 | ||||
| // 					OrderStatus: 2,
 | ||||
| // 					Brand:       "TestBrand",
 | ||||
| // 					OrderUID:    "UID123",
 | ||||
| // 					ReferenceID: "REF123",
 | ||||
| // 					Count:       decimal.RequireFromString("10.5"),
 | ||||
| // 					OrderFee:    decimal.RequireFromString("0.5"),
 | ||||
| // 					Amount:      decimal.RequireFromString("100"),
 | ||||
| // 				},
 | ||||
| // 			},
 | ||||
| // 			expected: []*order.GetOrderResp{
 | ||||
| // 				{
 | ||||
| // 					BusinessId:  "B123",
 | ||||
| // 					OrderType:   1,
 | ||||
| // 					OrderStatus: 2,
 | ||||
| // 					Brand:       "TestBrand",
 | ||||
| // 					OrderUid:    "UID123",
 | ||||
| // 					ReferenceId: "REF123",
 | ||||
| // 					Count:       "10.5",
 | ||||
| // 					OrderFee:    "0.5",
 | ||||
| // 					Amount:      "100",
 | ||||
| // 				},
 | ||||
| // 			},
 | ||||
| // 		},
 | ||||
| // 		{
 | ||||
| // 			name: "多筆訂單",
 | ||||
| // 			input: []model.Order{
 | ||||
| // 				{
 | ||||
| // 					BusinessID:  "B123",
 | ||||
| // 					OrderType:   1,
 | ||||
| // 					OrderStatus: 2,
 | ||||
| // 					Brand:       "TestBrand",
 | ||||
| // 					OrderUID:    "UID123",
 | ||||
| // 					ReferenceID: "REF123",
 | ||||
| // 					Count:       decimal.RequireFromString("10.5"),
 | ||||
| // 					OrderFee:    decimal.RequireFromString("0.5"),
 | ||||
| // 					Amount:      decimal.RequireFromString("100"),
 | ||||
| // 				},
 | ||||
| // 				{
 | ||||
| // 					BusinessID:  "B456",
 | ||||
| // 					OrderType:   2,
 | ||||
| // 					OrderStatus: 3,
 | ||||
| // 					Brand:       "OtherBrand",
 | ||||
| // 					OrderUID:    "UID456",
 | ||||
| // 					ReferenceID: "REF456",
 | ||||
| // 					Count:       decimal.RequireFromString("20"),
 | ||||
| // 					OrderFee:    decimal.RequireFromString("1"),
 | ||||
| // 					Amount:      decimal.RequireFromString("200"),
 | ||||
| // 				},
 | ||||
| // 			},
 | ||||
| // 			expected: []*order.GetOrderResp{
 | ||||
| // 				{
 | ||||
| // 					BusinessId:  "B123",
 | ||||
| // 					OrderType:   1,
 | ||||
| // 					OrderStatus: 2,
 | ||||
| // 					Brand:       "TestBrand",
 | ||||
| // 					OrderUid:    "UID123",
 | ||||
| // 					ReferenceId: "REF123",
 | ||||
| // 					Count:       "10.5",
 | ||||
| // 					OrderFee:    "0.5",
 | ||||
| // 					Amount:      "100",
 | ||||
| // 				},
 | ||||
| // 				{
 | ||||
| // 					BusinessId:  "B456",
 | ||||
| // 					OrderType:   2,
 | ||||
| // 					OrderStatus: 3,
 | ||||
| // 					Brand:       "OtherBrand",
 | ||||
| // 					OrderUid:    "UID456",
 | ||||
| // 					ReferenceId: "REF456",
 | ||||
| // 					Count:       "20",
 | ||||
| // 					OrderFee:    "1",
 | ||||
| // 					Amount:      "200",
 | ||||
| // 				},
 | ||||
| // 			},
 | ||||
| // 		},
 | ||||
| // 	}
 | ||||
| //
 | ||||
| // 	for _, tt := range tests {
 | ||||
| // 		t.Run(tt.name, func(t *testing.T) {
 | ||||
| // 			// 執行 ConvertOrdersToGetOrderResp 函數
 | ||||
| // 			result := ConvertOrdersToGetOrderResp(tt.input)
 | ||||
| //
 | ||||
| // 			// 驗證結果
 | ||||
| // 			assert.Equal(t, tt.expected, result)
 | ||||
| // 		})
 | ||||
| // 	}
 | ||||
| // }
 | ||||
| //
 | ||||
| // func TestOptionalString(t *testing.T) {
 | ||||
| // 	t.Run("非 nil 字串", func(t *testing.T) {
 | ||||
| // 		str := "hello"
 | ||||
| // 		result := optionalString(&str)
 | ||||
| // 		assert.NotNil(t, result)
 | ||||
| // 		assert.Equal(t, &str, result)
 | ||||
| // 	})
 | ||||
| //
 | ||||
| // 	t.Run("nil 字串", func(t *testing.T) {
 | ||||
| // 		result := optionalString(nil)
 | ||||
| // 		assert.Nil(t, result)
 | ||||
| // 	})
 | ||||
| // }
 | ||||
| //
 | ||||
| // func TestOptionalInt64(t *testing.T) {
 | ||||
| // 	t.Run("非 nil int64", func(t *testing.T) {
 | ||||
| // 		num := int64(123)
 | ||||
| // 		result := optionalInt64(&num)
 | ||||
| // 		assert.NotNil(t, result)
 | ||||
| // 		assert.Equal(t, &num, result)
 | ||||
| // 	})
 | ||||
| //
 | ||||
| // 	t.Run("nil int64", func(t *testing.T) {
 | ||||
| // 		result := optionalInt64(nil)
 | ||||
| // 		assert.Nil(t, result)
 | ||||
| // 	})
 | ||||
| // }
 | ||||
| //
 | ||||
| // func TestOptionalDecimalToString(t *testing.T) {
 | ||||
| // 	t.Run("非 nil decimal", func(t *testing.T) {
 | ||||
| // 		dec := decimal.NewFromInt(123)
 | ||||
| // 		expected := "123"
 | ||||
| // 		result := optionalDecimalToString(&dec)
 | ||||
| // 		assert.NotNil(t, result)
 | ||||
| // 		assert.Equal(t, &expected, result)
 | ||||
| // 	})
 | ||||
| //
 | ||||
| // 	t.Run("nil decimal", func(t *testing.T) {
 | ||||
| // 		result := optionalDecimalToString(nil)
 | ||||
| // 		assert.Nil(t, result)
 | ||||
| // 	})
 | ||||
| // }
 | ||||
| //
 | ||||
| // func TestConvertOrderToGetOrderResp(t *testing.T) {
 | ||||
| // 	tests := []struct {
 | ||||
| // 		name     string
 | ||||
| // 		input    model.Order
 | ||||
| // 		expected *order.GetOrderResp
 | ||||
| // 	}{
 | ||||
| // 		{
 | ||||
| // 			name: "所有欄位都有值",
 | ||||
| // 			input: model.Order{
 | ||||
| // 				BusinessID:           "B123",
 | ||||
| // 				OrderType:            1,
 | ||||
| // 				OrderStatus:          2,
 | ||||
| // 				Brand:                "TestBrand",
 | ||||
| // 				OrderUID:             "UID123",
 | ||||
| // 				ReferenceID:          "REF123",
 | ||||
| // 				Count:                decimal.RequireFromString("10.5"),
 | ||||
| // 				OrderFee:             decimal.RequireFromString("0.5"),
 | ||||
| // 				Amount:               decimal.RequireFromString("100"),
 | ||||
| // 				ReferenceBrand:       ptrString("OtherBrand"),
 | ||||
| // 				ReferenceUID:         ptrString("REFUID"),
 | ||||
| // 				WalletStatus:         ptrInt64(1),
 | ||||
| // 				ThreePartyStatus:     ptrInt64(2),
 | ||||
| // 				DirectionType:        ptrInt64(1),
 | ||||
| // 				CryptoType:           ptrString("BTC"),
 | ||||
| // 				ThirdPartyFee:        decimalPtrFromString("0.01"),
 | ||||
| // 				CryptoToUSDTRate:     decimalPtrFromString("50000"),
 | ||||
| // 				FiatToUSDRate:        decimalPtrFromString("1"),
 | ||||
| // 				FeeCryptoToUSDTRate:  decimalPtrFromString("0.02"),
 | ||||
| // 				USDTToCryptoTypeRate: decimalPtrFromString("0.00002"),
 | ||||
| // 				PaymentFiat:          ptrString("USD"),
 | ||||
| // 				PaymentUnitPrice:     decimalPtrFromString("50000"),
 | ||||
| // 				PaymentTemplateID:    ptrString("TEMPLATE123"),
 | ||||
| // 				OrderArrivalTime:     ptrInt64(1630000000),
 | ||||
| // 				OrderPaymentTime:     ptrInt64(1620000000),
 | ||||
| // 				UnpaidTimeoutSecond:  ptrInt64(3600),
 | ||||
| // 				ChainType:            ptrString("ETH"),
 | ||||
| // 				TxHash:               ptrString("0xABC123"),
 | ||||
| // 				FromAddress:          ptrString("0xFROM123"),
 | ||||
| // 				ToAddress:            ptrString("0xTO123"),
 | ||||
| // 				ChainFee:             decimalPtrFromString("0.001"),
 | ||||
| // 				ChainFeeCrypto:       ptrString("ETH"),
 | ||||
| // 				Memo:                 ptrString("Test Memo"),
 | ||||
| // 				OrderNote:            ptrString("Test Note"),
 | ||||
| // 				CreateTime:           1620000000,
 | ||||
| // 				UpdateTime:           1630000000,
 | ||||
| // 			},
 | ||||
| // 			expected: &order.GetOrderResp{
 | ||||
| // 				BusinessId:           "B123",
 | ||||
| // 				OrderType:            1,
 | ||||
| // 				OrderStatus:          2,
 | ||||
| // 				Brand:                "TestBrand",
 | ||||
| // 				OrderUid:             "UID123",
 | ||||
| // 				ReferenceId:          "REF123",
 | ||||
| // 				Count:                "10.5",
 | ||||
| // 				OrderFee:             "0.5",
 | ||||
| // 				Amount:               "100",
 | ||||
| // 				ReferenceBrand:       ptrString("OtherBrand"),
 | ||||
| // 				ReferenceUid:         ptrString("REFUID"),
 | ||||
| // 				WalletStatus:         ptrInt64(1),
 | ||||
| // 				ThreePartyStatus:     ptrInt64(2),
 | ||||
| // 				DirectionType:        ptrInt64(1),
 | ||||
| // 				CryptoType:           ptrString("BTC"),
 | ||||
| // 				ThirdPartyFee:        ptrString("0.01"),
 | ||||
| // 				CryptoToUsdtRate:     ptrString("50000"),
 | ||||
| // 				FiatToUsdRate:        ptrString("1"),
 | ||||
| // 				FeeCryptoToUsdtRate:  ptrString("0.02"),
 | ||||
| // 				UsdtToCryptoTypeRate: ptrString("0.00002"),
 | ||||
| // 				PaymentFiat:          ptrString("USD"),
 | ||||
| // 				PaymentUnitPrice:     ptrString("50000"),
 | ||||
| // 				PaymentTemplateId:    ptrString("TEMPLATE123"),
 | ||||
| // 				OrderArrivalTime:     ptrInt64(1630000000),
 | ||||
| // 				OrderPaymentTime:     ptrInt64(1620000000),
 | ||||
| // 				UnpaidTimeoutSecond:  ptrInt64(3600),
 | ||||
| // 				ChainType:            ptrString("ETH"),
 | ||||
| // 				TxHash:               ptrString("0xABC123"),
 | ||||
| // 				FromAddress:          ptrString("0xFROM123"),
 | ||||
| // 				ToAddress:            ptrString("0xTO123"),
 | ||||
| // 				ChainFee:             ptrString("0.001"),
 | ||||
| // 				ChainFeeCrypto:       ptrString("ETH"),
 | ||||
| // 				Memo:                 ptrString("Test Memo"),
 | ||||
| // 				OrderNote:            ptrString("Test Note"),
 | ||||
| // 				CreateTime:           1620000000,
 | ||||
| // 				UpdateTime:           1630000000,
 | ||||
| // 			},
 | ||||
| // 		},
 | ||||
| // 		{
 | ||||
| // 			name: "部分欄位為 nil",
 | ||||
| // 			input: model.Order{
 | ||||
| // 				BusinessID:           "B456",
 | ||||
| // 				OrderType:            1,
 | ||||
| // 				OrderStatus:          2,
 | ||||
| // 				Brand:                "TestBrand",
 | ||||
| // 				OrderUID:             "UID456",
 | ||||
| // 				ReferenceID:          "REF456",
 | ||||
| // 				Count:                decimal.RequireFromString("10"),
 | ||||
| // 				OrderFee:             decimal.RequireFromString("1"),
 | ||||
| // 				Amount:               decimal.RequireFromString("100"),
 | ||||
| // 				ReferenceBrand:       nil,
 | ||||
| // 				ReferenceUID:         nil,
 | ||||
| // 				WalletStatus:         nil,
 | ||||
| // 				ThreePartyStatus:     nil,
 | ||||
| // 				DirectionType:        nil,
 | ||||
| // 				CryptoType:           nil,
 | ||||
| // 				ThirdPartyFee:        nil,
 | ||||
| // 				CryptoToUSDTRate:     nil,
 | ||||
| // 				FiatToUSDRate:        nil,
 | ||||
| // 				FeeCryptoToUSDTRate:  nil,
 | ||||
| // 				USDTToCryptoTypeRate: nil,
 | ||||
| // 				PaymentFiat:          nil,
 | ||||
| // 				PaymentUnitPrice:     nil,
 | ||||
| // 				PaymentTemplateID:    nil,
 | ||||
| // 				OrderArrivalTime:     nil,
 | ||||
| // 				OrderPaymentTime:     nil,
 | ||||
| // 				UnpaidTimeoutSecond:  nil,
 | ||||
| // 				ChainType:            nil,
 | ||||
| // 				TxHash:               nil,
 | ||||
| // 				FromAddress:          nil,
 | ||||
| // 				ToAddress:            nil,
 | ||||
| // 				ChainFee:             nil,
 | ||||
| // 				ChainFeeCrypto:       nil,
 | ||||
| // 				Memo:                 nil,
 | ||||
| // 				OrderNote:            nil,
 | ||||
| // 				CreateTime:           1620000000,
 | ||||
| // 				UpdateTime:           1630000000,
 | ||||
| // 			},
 | ||||
| // 			expected: &order.GetOrderResp{
 | ||||
| // 				BusinessId:           "B456",
 | ||||
| // 				OrderType:            1,
 | ||||
| // 				OrderStatus:          2,
 | ||||
| // 				Brand:                "TestBrand",
 | ||||
| // 				OrderUid:             "UID456",
 | ||||
| // 				ReferenceId:          "REF456",
 | ||||
| // 				Count:                "10",
 | ||||
| // 				OrderFee:             "1",
 | ||||
| // 				Amount:               "100",
 | ||||
| // 				ReferenceBrand:       nil,
 | ||||
| // 				ReferenceUid:         nil,
 | ||||
| // 				WalletStatus:         nil,
 | ||||
| // 				ThreePartyStatus:     nil,
 | ||||
| // 				DirectionType:        nil,
 | ||||
| // 				CryptoType:           nil,
 | ||||
| // 				ThirdPartyFee:        nil,
 | ||||
| // 				CryptoToUsdtRate:     nil,
 | ||||
| // 				FiatToUsdRate:        nil,
 | ||||
| // 				FeeCryptoToUsdtRate:  nil,
 | ||||
| // 				UsdtToCryptoTypeRate: nil,
 | ||||
| // 				PaymentFiat:          nil,
 | ||||
| // 				PaymentUnitPrice:     nil,
 | ||||
| // 				PaymentTemplateId:    nil,
 | ||||
| // 				OrderArrivalTime:     nil,
 | ||||
| // 				OrderPaymentTime:     nil,
 | ||||
| // 				UnpaidTimeoutSecond:  nil,
 | ||||
| // 				ChainType:            nil,
 | ||||
| // 				TxHash:               nil,
 | ||||
| // 				FromAddress:          nil,
 | ||||
| // 				ToAddress:            nil,
 | ||||
| // 				ChainFee:             nil,
 | ||||
| // 				ChainFeeCrypto:       nil,
 | ||||
| // 				Memo:                 nil,
 | ||||
| // 				OrderNote:            nil,
 | ||||
| // 				CreateTime:           1620000000,
 | ||||
| // 				UpdateTime:           1630000000,
 | ||||
| // 			},
 | ||||
| // 		},
 | ||||
| // 	}
 | ||||
| //
 | ||||
| // 	for _, tt := range tests {
 | ||||
| // 		t.Run(tt.name, func(t *testing.T) {
 | ||||
| // 			// 執行 ConvertOrderToGetOrderResp 函數
 | ||||
| // 			result := ConvertOrderToGetOrderResp(tt.input)
 | ||||
| //
 | ||||
| // 			// 驗證結果
 | ||||
| // 			assert.Equal(t, tt.expected, result)
 | ||||
| // 		})
 | ||||
| // 	}
 | ||||
| // }
 | ||||
| //
 | ||||
| // func TestListOrder(t *testing.T) {
 | ||||
| // 	ctrl := gomock.NewController(t)
 | ||||
| // 	defer ctrl.Finish()
 | ||||
| //
 | ||||
| // 	// 初始化 mock 依賴
 | ||||
| // 	mockOrderModel := mockmodel.NewMockOrderModel(ctrl)
 | ||||
| // 	mockValidate := mocksvc.NewMockValidate(ctrl)
 | ||||
| //
 | ||||
| // 	// 初始化服務上下文
 | ||||
| // 	svcCtx := &svc.ServiceContext{
 | ||||
| // 		OrderModel: mockOrderModel,
 | ||||
| // 		Validate:   mockValidate,
 | ||||
| // 	}
 | ||||
| //
 | ||||
| // 	// 測試數據集
 | ||||
| // 	tests := []struct {
 | ||||
| // 		name        string
 | ||||
| // 		input       *order.ListOrderReq
 | ||||
| // 		prepare     func()
 | ||||
| // 		expectErr   bool
 | ||||
| // 		expectedRes *order.ListOrderResp
 | ||||
| // 	}{
 | ||||
| // 		{
 | ||||
| // 			name: "成功取得訂單列表",
 | ||||
| // 			input: &order.ListOrderReq{
 | ||||
| // 				PageIndex: 1,
 | ||||
| // 				PageSize:  10,
 | ||||
| // 			},
 | ||||
| // 			prepare: func() {
 | ||||
| // 				// 模擬驗證成功
 | ||||
| // 				mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1)
 | ||||
| // 				// 模擬返回訂單列表
 | ||||
| // 				mockOrderModel.EXPECT().ListOrder(gomock.Any(), gomock.Any()).Return([]model.Order{
 | ||||
| // 					{
 | ||||
| // 						BusinessID:  "B123",
 | ||||
| // 						OrderType:   1,
 | ||||
| // 						OrderStatus: 2,
 | ||||
| // 						Brand:       "TestBrand",
 | ||||
| // 						OrderUID:    "UID123",
 | ||||
| // 						ReferenceID: "REF123",
 | ||||
| // 						Count:       decimal.RequireFromString("10.5"),
 | ||||
| // 						OrderFee:    decimal.RequireFromString("0.5"),
 | ||||
| // 						Amount:      decimal.RequireFromString("100"),
 | ||||
| // 					},
 | ||||
| // 				}, int64(1), nil).Times(1)
 | ||||
| // 			},
 | ||||
| // 			expectErr: false,
 | ||||
| // 			expectedRes: &order.ListOrderResp{
 | ||||
| // 				Data: []*order.GetOrderResp{
 | ||||
| // 					{
 | ||||
| // 						BusinessId:  "B123",
 | ||||
| // 						OrderType:   1,
 | ||||
| // 						OrderStatus: 2,
 | ||||
| // 						Brand:       "TestBrand",
 | ||||
| // 						OrderUid:    "UID123",
 | ||||
| // 						ReferenceId: "REF123",
 | ||||
| // 						Count:       "10.5",
 | ||||
| // 						OrderFee:    "0.5",
 | ||||
| // 						Amount:      "100",
 | ||||
| // 					},
 | ||||
| // 				},
 | ||||
| // 				Page: &order.Pager{
 | ||||
| // 					Total: 1,
 | ||||
| // 					Index: 1,
 | ||||
| // 					Size:  10,
 | ||||
| // 				},
 | ||||
| // 			},
 | ||||
| // 		},
 | ||||
| // 		{
 | ||||
| // 			name: "訂單查詢失敗",
 | ||||
| // 			input: &order.ListOrderReq{
 | ||||
| // 				PageIndex: 1,
 | ||||
| // 				PageSize:  10,
 | ||||
| // 			},
 | ||||
| // 			prepare: func() {
 | ||||
| // 				// 模擬驗證成功
 | ||||
| // 				mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1)
 | ||||
| // 				// 模擬返回查詢錯誤
 | ||||
| // 				mockOrderModel.EXPECT().ListOrder(gomock.Any(), gomock.Any()).Return(nil, int64(0), errors.New("query failed")).Times(1)
 | ||||
| // 			},
 | ||||
| // 			expectErr: true,
 | ||||
| // 		},
 | ||||
| // 		{
 | ||||
| // 			name: "分頁錯誤",
 | ||||
| // 			input: &order.ListOrderReq{
 | ||||
| // 				PageIndex: 0,
 | ||||
| // 				PageSize:  10,
 | ||||
| // 			},
 | ||||
| // 			prepare: func() {
 | ||||
| // 				// 模擬驗證失敗,因為 PageIndex 為 0
 | ||||
| // 				mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(errors.New("invalid pagination")).Times(1)
 | ||||
| // 			},
 | ||||
| // 			expectErr: true,
 | ||||
| // 		},
 | ||||
| // 	}
 | ||||
| //
 | ||||
| // 	for _, tt := range tests {
 | ||||
| // 		t.Run(tt.name, func(t *testing.T) {
 | ||||
| // 			// 準備測試環境
 | ||||
| // 			tt.prepare()
 | ||||
| //
 | ||||
| // 			// 初始化 ListOrderLogic
 | ||||
| // 			logic := NewListOrderLogic(context.TODO(), svcCtx)
 | ||||
| //
 | ||||
| // 			// 執行 ListOrder
 | ||||
| // 			resp, err := logic.ListOrder(tt.input)
 | ||||
| //
 | ||||
| // 			// 驗證結果
 | ||||
| // 			if tt.expectErr {
 | ||||
| // 				assert.Error(t, err)
 | ||||
| // 				assert.Nil(t, resp)
 | ||||
| // 			} else {
 | ||||
| // 				assert.NoError(t, err)
 | ||||
| // 				assert.Equal(t, tt.expectedRes, resp)
 | ||||
| // 			}
 | ||||
| // 		})
 | ||||
| // 	}
 | ||||
| // }
 | ||||
|  |  | |||
|  | @ -1,49 +1,47 @@ | |||
| package model | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/shopspring/decimal" | ||||
| 	"go.mongodb.org/mongo-driver/bson/primitive" | ||||
| ) | ||||
| 
 | ||||
| type Order struct { | ||||
| 	ID          primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"` | ||||
| 	UpdateTime  int64              `bson:"update_time"` | ||||
| 	CreateTime  int64              `bson:"create_time"` | ||||
| 	BusinessID  string             `bson:"business_id"`  // 訂單業務流水號
 | ||||
| 	OrderType   int8               `bson:"order_type"`   // 訂單類型
 | ||||
| 	OrderStatus int8               `bson:"order_status"` // 訂單狀態 0.建立訂單 1.建單失敗 2.審核中 3.付款中 4.已付款 5.已付款待轉帳 6.申訴中 7.交易完成 8.交易失敗 9.交易取消 10.交易異常 11.交易超時
 | ||||
| 	Brand       string             `bson:"brand"`        // 下單平台(混合也可用)
 | ||||
| 	OrderUID    string             `bson:"order_uid"`    // 下單用戶 UID
 | ||||
| 	ReferenceID string             `bson:"reference_id"` // 訂單來源(用)
 | ||||
| 	Count       decimal.Decimal    `bson:"count"`        // 訂單數量
 | ||||
| 	OrderFee    decimal.Decimal    `bson:"order_fee"`    // 訂單手續費
 | ||||
| 	Amount      decimal.Decimal    `bson:"amount"`       // 單價
 | ||||
| 	// 下面的是未來擴充用,加密貨幣用,或者幣別轉換用,普通訂單用不到
 | ||||
| 	ReferenceBrand       *string          `bson:"reference_brand"`                    // 訂單來源平台
 | ||||
| 	ReferenceUID         *string          `bson:"reference_uid"`                      // 訂單來源用戶 UID
 | ||||
| 	WalletStatus         *int64           `bson:"wallet_status,omitempty"`            // 交易金額狀態 1.未凍結 2.已凍結 3.解凍(扣錢) 4.未增加資產 5.已增加資產 6.解凍還原 7.限制(將凍結餘額轉至限制餘額)
 | ||||
| 	ThreePartyStatus     *int64           `bson:"three_party_status,omitempty"`       // 三方請求狀態 1.已發送 2.通知處理中 3.通知已完成
 | ||||
| 	DirectionType        *int64           `bson:"direction_type,omitempty"`           // 交易方向 1.買入 2.賣出
 | ||||
| 	CryptoType           *string          `bson:"crypto_type,omitempty"`              // 交易幣種
 | ||||
| 	ThirdPartyFee        *decimal.Decimal `bson:"third_party_fee,omitempty"`          // 第三方手續費
 | ||||
| 	CryptoToUSDTRate     *decimal.Decimal `bson:"crypto_to_usdt_rate,omitempty"`      // 交易幣種 對 USDT 匯率
 | ||||
| 	FiatToUSDRate        *decimal.Decimal `bson:"fiat_to_usd_rate,omitempty"`         // 法幣 對 USD 匯率
 | ||||
| 	FeeCryptoToUSDTRate  *decimal.Decimal `bson:"fee_crypto_to_usdt_rate,omitempty"`  // 手續費幣種 對 USDT 匯率
 | ||||
| 	USDTToCryptoTypeRate *decimal.Decimal `bson:"usdt_to_crypto_type_rate,omitempty"` // USDT 對 交易幣種 匯率
 | ||||
| 	PaymentFiat          *string          `bson:"payment_fiat,omitempty"`             // 支付法幣
 | ||||
| 	PaymentUnitPrice     *decimal.Decimal `bson:"payment_unit_price,omitempty"`       // crypto 單價
 | ||||
| 	PaymentTemplateID    *string          `bson:"payment_template_id,omitempty"`      // 支付方式配置 ID
 | ||||
| 	OrderArrivalTime     *int64           `bson:"order_arrival_time,omitempty"`       // 訂單到帳時間/充值到帳時間
 | ||||
| 	OrderPaymentTime     *int64           `bson:"order_payment_time,omitempty"`       // 訂單付款時間/鏈上成功或失敗時間
 | ||||
| 	UnpaidTimeoutSecond  *int64           `bson:"unpaid_timeout_second,omitempty"`    // 支付期限秒數
 | ||||
| 	ChainType            *string          `bson:"chain_type,omitempty"`               // 主網類型
 | ||||
| 	TxHash               *string          `bson:"tx_hash,omitempty"`                  // 交易哈希
 | ||||
| 	FromAddress          *string          `bson:"from_address,omitempty"`             // 來源地址
 | ||||
| 	ToAddress            *string          `bson:"to_address,omitempty"`               // 目標地址
 | ||||
| 	ChainFee             *decimal.Decimal `bson:"chain_fee,omitempty"`                // 鏈上交易手續費
 | ||||
| 	ChainFeeCrypto       *string          `bson:"chain_fee_crypto,omitempty"`         // 鏈上手續費使用幣別
 | ||||
| 	Memo                 *string          `bson:"memo,omitempty"`                     // 鏈上備註
 | ||||
| 	OrderNote            *string          `bson:"order_note,omitempty"`               // 訂單交易備註
 | ||||
| 	ID                   primitive.ObjectID    `bson:"_id,omitempty" json:"id,omitempty"` | ||||
| 	UpdateTime           int64                 `bson:"update_time"` | ||||
| 	CreateTime           int64                 `bson:"create_time"` | ||||
| 	BusinessID           string                `bson:"business_id"`                        // 訂單業務流水號
 | ||||
| 	OrderType            int8                  `bson:"order_type"`                         // 訂單類型
 | ||||
| 	OrderStatus          int8                  `bson:"order_status"`                       // 訂單狀態
 | ||||
| 	Brand                string                `bson:"brand"`                              // 下單平台
 | ||||
| 	OrderUID             string                `bson:"order_uid"`                          // 下單用戶 UID
 | ||||
| 	ReferenceID          string                `bson:"reference_id"`                       // 訂單來源
 | ||||
| 	Count                primitive.Decimal128  `bson:"count"`                              // 訂單數量
 | ||||
| 	OrderFee             primitive.Decimal128  `bson:"order_fee"`                          // 訂單手續費
 | ||||
| 	Amount               primitive.Decimal128  `bson:"amount"`                             // 單價
 | ||||
| 	ReferenceBrand       *string               `bson:"reference_brand,omitempty"`          // 訂單來源平台
 | ||||
| 	ReferenceUID         *string               `bson:"reference_uid,omitempty"`            // 訂單來源用戶 UID
 | ||||
| 	WalletStatus         *int64                `bson:"wallet_status,omitempty"`            // 交易金額狀態
 | ||||
| 	ThreePartyStatus     *int64                `bson:"three_party_status,omitempty"`       // 三方請求狀態
 | ||||
| 	DirectionType        *int64                `bson:"direction_type,omitempty"`           // 交易方向
 | ||||
| 	CryptoType           *string               `bson:"crypto_type,omitempty"`              // 交易幣種
 | ||||
| 	ThirdPartyFee        *primitive.Decimal128 `bson:"third_party_fee,omitempty"`          // 第三方手續費
 | ||||
| 	CryptoToUSDTRate     *primitive.Decimal128 `bson:"crypto_to_usdt_rate,omitempty"`      // 加密貨幣對 USDT 匯率
 | ||||
| 	FiatToUSDRate        *primitive.Decimal128 `bson:"fiat_to_usd_rate,omitempty"`         // 法幣對 USD 匯率
 | ||||
| 	FeeCryptoToUSDTRate  *primitive.Decimal128 `bson:"fee_crypto_to_usdt_rate,omitempty"`  // 手續費加密貨幣對 USDT 匯率
 | ||||
| 	USDTToCryptoTypeRate *primitive.Decimal128 `bson:"usdt_to_crypto_type_rate,omitempty"` // USDT 對加密貨幣匯率
 | ||||
| 	PaymentFiat          *string               `bson:"payment_fiat,omitempty"`             // 支付法幣
 | ||||
| 	PaymentUnitPrice     *primitive.Decimal128 `bson:"payment_unit_price,omitempty"`       // 加密貨幣單價
 | ||||
| 	PaymentTemplateID    *string               `bson:"payment_template_id,omitempty"`      // 支付方式配置 ID
 | ||||
| 	OrderArrivalTime     *int64                `bson:"order_arrival_time,omitempty"`       // 訂單到帳時間
 | ||||
| 	OrderPaymentTime     *int64                `bson:"order_payment_time,omitempty"`       // 訂單付款時間
 | ||||
| 	UnpaidTimeoutSecond  *int64                `bson:"unpaid_timeout_second,omitempty"`    // 支付期限秒數
 | ||||
| 	ChainType            *string               `bson:"chain_type,omitempty"`               // 主網類型
 | ||||
| 	TxHash               *string               `bson:"tx_hash,omitempty"`                  // 交易哈希
 | ||||
| 	FromAddress          *string               `bson:"from_address,omitempty"`             // 來源地址
 | ||||
| 	ToAddress            *string               `bson:"to_address,omitempty"`               // 目標地址
 | ||||
| 	ChainFee             *primitive.Decimal128 `bson:"chain_fee,omitempty"`                // 鏈上交易手續費
 | ||||
| 	ChainFeeCrypto       *string               `bson:"chain_fee_crypto,omitempty"`         // 鏈上手續費使用幣別
 | ||||
| 	Memo                 *string               `bson:"memo,omitempty"`                     // 鏈上備註
 | ||||
| 	OrderNote            *string               `bson:"order_note,omitempty"`               // 訂單交易備註
 | ||||
| } | ||||
| 
 | ||||
| func (p *Order) CollectionName() string { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue