app-cloudep-trade-service/internal/usecase/order.go

311 lines
10 KiB
Go
Raw Normal View History

package usecase
import (
"app-cloudep-trade-service/internal/domain"
"app-cloudep-trade-service/internal/domain/usecase"
model "app-cloudep-trade-service/internal/model/mongo"
"context"
"errors"
"time"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/mon"
)
type OrderUseCaseParam struct {
OrderModel model.OrderModel
}
type OrderUseCase struct {
OrderModel model.OrderModel
}
func NewOrderUseCase(param OrderUseCaseParam) usecase.OrderUseCase {
return &OrderUseCase{
OrderModel: param.OrderModel,
}
}
func (o *OrderUseCase) CreateOrder(ctx context.Context, param usecase.CreateOrderReq) error {
now := time.Now().UTC().UnixNano()
// 插入資料庫
order := &model.Order{
UpdateTime: now,
CreateTime: now,
BusinessID: param.BusinessID,
OrderType: param.OrderType,
OrderStatus: param.OrderStatus,
Brand: param.Brand,
OrderUID: param.OrderUID,
ReferenceID: param.ReferenceID,
Count: param.Count,
OrderFee: param.OrderFee,
Amount: param.Amount,
ReferenceBrand: param.ReferenceBrand,
ReferenceUID: param.ReferenceUID,
WalletStatus: param.WalletStatus,
ThreePartyStatus: param.ThreePartyStatus,
DirectionType: param.DirectionType,
CryptoType: param.CryptoType,
ThirdPartyFee: param.ThirdPartyFee,
CryptoToUSDTRate: param.CryptoToUSDTRate,
FiatToUSDRate: param.FiatToUSDRate,
FeeCryptoToUSDTRate: param.FeeCryptoToUSDTRate,
USDTToCryptoTypeRate: param.USDTToCryptoTypeRate,
PaymentFiat: param.PaymentFiat,
PaymentUnitPrice: param.PaymentUnitPrice,
PaymentTemplateID: param.PaymentTemplateID,
OrderArrivalTime: param.OrderArrivalTime,
OrderPaymentTime: param.OrderPaymentTime,
UnpaidTimeoutSecond: param.UnpaidTimeoutSecond,
ChainType: param.ChainType,
TxHash: param.TxHash,
FromAddress: param.FromAddress,
ToAddress: param.ToAddress,
ChainFee: param.ChainFee,
ChainFeeCrypto: param.ChainFeeCrypto,
Memo: param.Memo,
OrderNote: param.OrderNote,
}
err := o.OrderModel.Insert(ctx, order)
if err != nil {
// 錯誤代碼 06-021-01
e := domain.CommentErrorL(
domain.CreateOrderErrorCode,
logx.WithContext(ctx),
[]logx.LogField{
{Key: "req", Value: param},
{Key: "func", Value: "OrderModel.Insert"},
{Key: "err", Value: err},
},
"failed to insert order into mongo:").Wrap(err)
return e
}
return nil
}
func (o *OrderUseCase) CancelOrder(ctx context.Context, param usecase.CancelOrderQuery) error {
_, err := o.OrderModel.UpdateStatus(ctx, model.UpdateStatusReq{
BusinessID: param.BusinessID,
Status: param.Status.ToInt64(),
})
if err != nil {
// 錯誤代碼 06-021-02
e := domain.CommentErrorL(
domain.CancelOrderErrorCode,
logx.WithContext(ctx),
[]logx.LogField{
{Key: "req", Value: param},
{Key: "func", Value: "OrderModel.UpdateStatus"},
{Key: "err", Value: err},
},
"failed to update order status:").Wrap(err)
return e
}
return nil
}
func (o *OrderUseCase) DeleteOrder(ctx context.Context, param usecase.DeleteOrderQuery) error {
_, err := o.OrderModel.DeleteByBusinessID(ctx, param.BusinessID)
if err != nil {
return err
}
return nil
}
func (o *OrderUseCase) GetOrder(ctx context.Context, param usecase.GetOrderQuery) (*usecase.GetOrderResp, error) {
order, err := o.OrderModel.FindOneBusinessID(ctx, param.BusinessID)
if err != nil {
if errors.Is(mon.ErrNotFound, err) {
return nil, domain.NotFoundError(domain.DataNotFoundErrorCode, "failed to get this order id:", param.BusinessID)
}
return nil, err
}
resp := &usecase.GetOrderResp{
UpdateTime: order.UpdateTime,
CreateTime: order.CreateTime,
BusinessID: order.BusinessID,
OrderType: order.OrderType,
OrderStatus: order.OrderStatus,
Brand: order.Brand,
OrderUID: order.OrderUID,
ReferenceID: order.ReferenceID,
Count: order.Count.String(),
OrderFee: order.OrderFee.String(),
Amount: order.Amount.String(),
ReferenceBrand: order.ReferenceBrand,
ReferenceUID: order.ReferenceUID,
WalletStatus: Int64Ptr(order.WalletStatus),
ThreePartyStatus: order.ThreePartyStatus,
DirectionType: Int64Ptr(order.DirectionType),
CryptoType: order.CryptoType,
ThirdPartyFee: DecimalToStringPtr(order.ThirdPartyFee),
CryptoToUsdtRate: DecimalToStringPtr(order.CryptoToUSDTRate),
FiatToUsdRate: DecimalToStringPtr(order.FiatToUSDRate),
FeeCryptoToUsdtRate: DecimalToStringPtr(order.FeeCryptoToUSDTRate),
UsdtToCryptoTypeRate: DecimalToStringPtr(order.USDTToCryptoTypeRate),
PaymentFiat: order.PaymentFiat,
PaymentUnitPrice: DecimalToStringPtr(order.PaymentUnitPrice),
PaymentTemplateID: order.PaymentTemplateID,
OrderArrivalTime: order.OrderArrivalTime,
OrderPaymentTime: order.OrderPaymentTime,
UnpaidTimeoutSecond: order.UnpaidTimeoutSecond,
ChainType: order.ChainType,
TxHash: order.TxHash,
FromAddress: order.FromAddress,
ToAddress: order.ToAddress,
ChainFee: DecimalToStringPtr(order.ChainFee),
ChainFeeCrypto: order.ChainFeeCrypto,
Memo: order.Memo,
OrderNote: order.OrderNote,
}
return resp, nil
}
func (o *OrderUseCase) ListOrder(ctx context.Context, param usecase.GetOrderListReq) (*usecase.ListOrderResp, error) {
// 構建查詢條件
req := model.GetOrderListReq{
PageIndex: param.PageIndex,
PageSize: param.PageSize,
ReferenceID: param.ReferenceID,
ReferenceUID: param.ReferenceUID,
BusinessID: param.BusinessID,
UID: param.UID,
OrderType: param.OrderType.ToInt(),
DirectionType: param.DirectionType,
OrderStatus: param.OrderStatus,
StartCreateTime: param.StartCreateTime,
EndCreateTime: param.EndCreateTime,
StartUpdateTime: param.StartUpdateTime,
EndUpdateTime: param.EndUpdateTime,
StartOrderArrivalTime: param.StartOrderArrivalTime,
EndOrderArrivalTime: param.EndOrderArrivalTime,
StartOrderPaymentTime: param.StartOrderPaymentTime,
EndOrderPaymentTime: param.EndOrderPaymentTime,
CryptoType: param.CryptoType,
TxHash: param.TxHash,
}
// 查詢訂單
orders, total, err := o.OrderModel.ListOrder(ctx, req)
if err != nil {
return nil, err
}
return &usecase.ListOrderResp{
Data: o.convertOrdersToResponses(orders),
Page: &usecase.Pager{
Total: total,
Index: param.PageIndex,
Size: param.PageSize,
},
}, nil
}
func (o *OrderUseCase) ModifyOrderStatus(ctx context.Context, param *usecase.ModifyOrderQuery) error {
_, err := o.OrderModel.UpdateStatus(ctx,
model.UpdateStatusReq{
BusinessID: param.BusinessID,
Status: param.Status,
})
if err != nil {
// 錯誤代碼 06-021-02
e := domain.CommentErrorL(
domain.ModifyOrderErrorCode,
logx.WithContext(ctx),
[]logx.LogField{
{Key: "req", Value: param},
{Key: "func", Value: "OrderModel.UpdateStatus"},
{Key: "err", Value: err},
},
"failed to update order status:").Wrap(err)
return e
}
return nil
}
func (o *OrderUseCase) OrderStatusTimeout(ctx context.Context) error {
now := time.Now().UTC().UnixNano()
_, err := o.OrderModel.UpdateTimeoutOrder(ctx, model.UpdateTimeoutReq{
CreateTimeBefore: now,
})
if err != nil {
// 錯誤代碼 06-021-02
e := domain.CommentErrorL(
domain.TimeoutOrderErrorCode,
logx.WithContext(ctx),
[]logx.LogField{
{Key: "now", Value: now},
{Key: "func", Value: "OrderModel.UpdateTimeoutOrder"},
{Key: "err", Value: err},
},
"failed to update timeout order").Wrap(err)
return e
}
return nil
}
// ================= 工具類區 =================
func (o *OrderUseCase) convertOrdersToResponses(orders []model.Order) []*usecase.GetOrderResp {
res := make([]*usecase.GetOrderResp, 0, len(orders))
for _, order := range orders {
resp := &usecase.GetOrderResp{
UpdateTime: order.UpdateTime,
CreateTime: order.CreateTime,
BusinessID: order.BusinessID,
OrderType: order.OrderType,
OrderStatus: order.OrderStatus,
Brand: order.Brand,
OrderUID: order.OrderUID,
ReferenceID: order.ReferenceID,
Count: order.Count.String(),
OrderFee: order.OrderFee.String(),
Amount: order.Amount.String(),
ReferenceBrand: order.ReferenceBrand,
ReferenceUID: order.ReferenceUID,
WalletStatus: Int64Ptr(order.WalletStatus),
ThreePartyStatus: order.ThreePartyStatus,
DirectionType: Int64Ptr(order.DirectionType),
CryptoType: order.CryptoType,
ThirdPartyFee: DecimalToStringPtr(order.ThirdPartyFee),
CryptoToUsdtRate: DecimalToStringPtr(order.CryptoToUSDTRate),
FiatToUsdRate: DecimalToStringPtr(order.FiatToUSDRate),
FeeCryptoToUsdtRate: DecimalToStringPtr(order.FeeCryptoToUSDTRate),
UsdtToCryptoTypeRate: DecimalToStringPtr(order.USDTToCryptoTypeRate),
PaymentFiat: order.PaymentFiat,
PaymentUnitPrice: DecimalToStringPtr(order.PaymentUnitPrice),
PaymentTemplateID: order.PaymentTemplateID,
OrderArrivalTime: order.OrderArrivalTime,
OrderPaymentTime: order.OrderPaymentTime,
UnpaidTimeoutSecond: order.UnpaidTimeoutSecond,
ChainType: order.ChainType,
TxHash: order.TxHash,
FromAddress: order.FromAddress,
ToAddress: order.ToAddress,
ChainFee: DecimalToStringPtr(order.ChainFee),
ChainFeeCrypto: order.ChainFeeCrypto,
Memo: order.Memo,
OrderNote: order.OrderNote,
}
res = append(res, resp)
}
return res
}