2024-10-06 07:02:30 +00:00
|
|
|
package orderservicelogic
|
|
|
|
|
|
|
|
import (
|
2024-10-12 09:49:58 +00:00
|
|
|
"app-cloudep-order-server/internal/domain"
|
|
|
|
model "app-cloudep-order-server/internal/model/mongo"
|
2024-10-06 07:02:30 +00:00
|
|
|
"context"
|
2024-10-12 09:49:58 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
ers "code.30cm.net/digimon/library-go/errs"
|
|
|
|
"github.com/shopspring/decimal"
|
2024-10-06 07:02:30 +00:00
|
|
|
|
|
|
|
"app-cloudep-order-server/gen_result/pb/tweeting"
|
|
|
|
"app-cloudep-order-server/internal/svc"
|
|
|
|
|
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
|
|
)
|
|
|
|
|
|
|
|
type CreateOrderLogic struct {
|
|
|
|
ctx context.Context
|
|
|
|
svcCtx *svc.ServiceContext
|
|
|
|
logx.Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewCreateOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateOrderLogic {
|
|
|
|
return &CreateOrderLogic{
|
|
|
|
ctx: ctx,
|
|
|
|
svcCtx: svcCtx,
|
|
|
|
Logger: logx.WithContext(ctx),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-12 09:49:58 +00:00
|
|
|
type createOrderReq struct { // 訂單ID
|
|
|
|
BusinessID string `json:"business_id" validate:"required"` // 訂單業務流水號
|
|
|
|
OrderType int8 `json:"order_type" validate:"required"` // 訂單類型
|
|
|
|
OrderStatus int8 `json:"order_status" validate:"required,oneof=0 1 2 3 4 5 6 7 8 9 10 11"` // 訂單狀態
|
|
|
|
Brand string `json:"brand" validate:"required"` // 下單平台
|
|
|
|
OrderUID string `json:"order_uid" validate:"required"` // 下單用戶 UID
|
|
|
|
ReferenceID string `json:"reference_id" validate:"required"` // 訂單來源
|
|
|
|
Count decimal.Decimal `json:"count" validate:"required,gt=0"` // 訂單數量
|
|
|
|
OrderFee decimal.Decimal `json:"order_fee" validate:"required,gte=0"` // 訂單手續費
|
|
|
|
Amount decimal.Decimal `json:"amount" validate:"required,gte=0"` // 單價
|
|
|
|
ReferenceBrand *string `json:"reference_brand,omitempty" validate:"omitempty"` // 訂單來源平台
|
|
|
|
ReferenceUID *string `json:"reference_uid,omitempty" validate:"omitempty"` // 訂單來源用戶 UID
|
|
|
|
WalletStatus *int64 `json:"wallet_status,omitempty" validate:"omitempty,oneof=1 2 3 4 5 6 7"` // 交易金額狀態
|
|
|
|
ThreePartyStatus *int64 `json:"three_party_status,omitempty" validate:"omitempty,oneof=1 2 3"` // 三方請求狀態
|
|
|
|
DirectionType *int64 `json:"direction_type,omitempty" validate:"omitempty,oneof=1 2"` // 交易方向
|
|
|
|
CryptoType *string `json:"crypto_type,omitempty" validate:"omitempty"` // 交易幣種
|
|
|
|
ThirdPartyFee *decimal.Decimal `json:"third_party_fee,omitempty" validate:"omitempty,gte=0"` // 第三方手續費
|
|
|
|
CryptoToUSDTRate *decimal.Decimal `json:"crypto_to_usdt_rate,omitempty" validate:"omitempty,gte=0"` // 交易幣種對 USDT 匯率
|
|
|
|
FiatToUSDRate *decimal.Decimal `json:"fiat_to_usd_rate,omitempty" validate:"omitempty,gte=0"` // 法幣對 USD 匯率
|
|
|
|
FeeCryptoToUSDTRate *decimal.Decimal `json:"fee_crypto_to_usdt_rate,omitempty" validate:"omitempty,gte=0"` // 手續費幣種對 USDT 匯率
|
|
|
|
USDTToCryptoTypeRate *decimal.Decimal `json:"usdt_to_crypto_type_rate,omitempty" validate:"omitempty,gte=0"` // USDT 對交易幣種匯率
|
|
|
|
PaymentFiat *string `json:"payment_fiat,omitempty" validate:"omitempty"` // 支付法幣
|
|
|
|
PaymentUnitPrice *decimal.Decimal `json:"payment_unit_price,omitempty" validate:"omitempty,gte=0"` // crypto 單價
|
|
|
|
PaymentTemplateID *string `json:"payment_template_id,omitempty" validate:"omitempty"` // 支付方式配置 ID
|
|
|
|
OrderArrivalTime *int64 `json:"order_arrival_time,omitempty" validate:"omitempty"` // 訂單到帳時間
|
|
|
|
OrderPaymentTime *int64 `json:"order_payment_time,omitempty" validate:"omitempty"` // 訂單付款時間
|
|
|
|
UnpaidTimeoutSecond *int64 `json:"unpaid_timeout_second,omitempty" validate:"omitempty,gte=0"` // 支付期限秒數
|
|
|
|
ChainType *string `json:"chain_type,omitempty" validate:"omitempty"` // 主網類型
|
|
|
|
TxHash *string `json:"tx_hash,omitempty" validate:"omitempty"` // 交易哈希
|
|
|
|
FromAddress *string `json:"from_address,omitempty" validate:"omitempty"` // 來源地址
|
|
|
|
ToAddress *string `json:"to_address,omitempty" validate:"omitempty"` // 目標地址
|
|
|
|
ChainFee *decimal.Decimal `json:"chain_fee,omitempty" validate:"omitempty,gte=0"` // 鏈上交易手續費
|
|
|
|
ChainFeeCrypto *string `json:"chain_fee_crypto,omitempty" validate:"omitempty"` // 鏈上手續費使用幣別
|
|
|
|
Memo *string `json:"memo,omitempty" validate:"omitempty"` // 鏈上備註
|
|
|
|
OrderNote *string `json:"order_note,omitempty" validate:"omitempty"`
|
|
|
|
}
|
|
|
|
|
2024-10-06 07:02:30 +00:00
|
|
|
// CreateOrder 建立訂單
|
2024-10-12 09:49:58 +00:00
|
|
|
func (l *CreateOrderLogic) CreateOrder(in *tweeting.CreateOrderReq) (*tweeting.OKResp, error) {
|
|
|
|
req, err := buildCreateOrderReq(in)
|
|
|
|
if err != nil {
|
|
|
|
// 錯誤代碼 06-011-00
|
|
|
|
return nil, ers.InvalidFormat(err.Error())
|
|
|
|
}
|
|
|
|
// 驗證資料
|
|
|
|
if err := l.svcCtx.Validate.ValidateAll(&req); err != nil {
|
|
|
|
// 錯誤代碼 06-011-00
|
|
|
|
return nil, ers.InvalidFormat(err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
now := time.Now().UTC().UnixNano()
|
|
|
|
// 插入資料庫
|
|
|
|
o := &model.Order{
|
|
|
|
UpdateTime: now,
|
|
|
|
CreateTime: now,
|
|
|
|
BusinessID: req.BusinessID,
|
|
|
|
OrderType: req.OrderType,
|
|
|
|
OrderStatus: req.OrderStatus,
|
|
|
|
Brand: req.Brand,
|
|
|
|
OrderUID: req.OrderUID,
|
|
|
|
ReferenceID: req.ReferenceID,
|
|
|
|
Count: req.Count,
|
|
|
|
OrderFee: req.OrderFee,
|
|
|
|
Amount: req.Amount,
|
|
|
|
// 下面的是未來擴充用,加密貨幣用,或者幣別轉換用,普通訂單用不到
|
|
|
|
ReferenceBrand: req.ReferenceBrand,
|
|
|
|
ReferenceUID: req.ReferenceUID,
|
|
|
|
WalletStatus: req.WalletStatus,
|
|
|
|
ThreePartyStatus: req.ThreePartyStatus,
|
|
|
|
DirectionType: req.DirectionType,
|
|
|
|
CryptoType: req.CryptoType,
|
|
|
|
ThirdPartyFee: req.ThirdPartyFee,
|
|
|
|
CryptoToUSDTRate: req.CryptoToUSDTRate,
|
|
|
|
FiatToUSDRate: req.FiatToUSDRate,
|
|
|
|
FeeCryptoToUSDTRate: req.FeeCryptoToUSDTRate,
|
|
|
|
USDTToCryptoTypeRate: req.USDTToCryptoTypeRate,
|
|
|
|
PaymentFiat: req.PaymentFiat,
|
|
|
|
PaymentUnitPrice: req.PaymentUnitPrice,
|
|
|
|
PaymentTemplateID: req.PaymentTemplateID,
|
|
|
|
OrderArrivalTime: req.OrderArrivalTime,
|
|
|
|
OrderPaymentTime: req.OrderPaymentTime,
|
|
|
|
UnpaidTimeoutSecond: req.UnpaidTimeoutSecond,
|
|
|
|
ChainType: req.ChainType,
|
|
|
|
TxHash: req.TxHash,
|
|
|
|
FromAddress: req.FromAddress,
|
|
|
|
ToAddress: req.ToAddress,
|
|
|
|
ChainFee: req.ChainFee,
|
|
|
|
ChainFeeCrypto: req.ChainFeeCrypto,
|
|
|
|
Memo: req.Memo,
|
|
|
|
OrderNote: req.OrderNote,
|
|
|
|
}
|
|
|
|
err = l.svcCtx.OrderModel.Insert(l.ctx, o)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
// 錯誤代碼 06-021-01
|
|
|
|
e := domain.CommentErrorL(
|
|
|
|
domain.CreateOrderErrorCode,
|
|
|
|
logx.WithContext(l.ctx),
|
|
|
|
[]logx.LogField{
|
|
|
|
{Key: "req", Value: in},
|
|
|
|
{Key: "func", Value: "OrderModel.Insert"},
|
|
|
|
{Key: "err", Value: err},
|
|
|
|
},
|
|
|
|
"failed to insert order into mongo:").Wrap(err)
|
|
|
|
|
|
|
|
return nil, e
|
|
|
|
}
|
|
|
|
|
|
|
|
return &tweeting.OKResp{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func buildCreateOrderReq(in *tweeting.CreateOrderReq) (*createOrderReq, error) {
|
|
|
|
createOrderReq := &createOrderReq{
|
|
|
|
BusinessID: in.BusinessId,
|
|
|
|
OrderType: int8(in.OrderType),
|
|
|
|
OrderStatus: int8(in.OrderStatus),
|
|
|
|
Brand: in.Brand,
|
|
|
|
OrderUID: in.OrderUid,
|
|
|
|
ReferenceID: in.ReferenceId,
|
|
|
|
}
|
|
|
|
|
|
|
|
var err error
|
|
|
|
// 只有當 Count, OrderFee, Amount 不為空時才進行轉換和設置
|
|
|
|
if in.Count != "" {
|
|
|
|
createOrderReq.Count, err = decimal.NewFromString(in.Count)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if in.OrderFee != "" {
|
|
|
|
createOrderReq.OrderFee, err = decimal.NewFromString(in.OrderFee)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if in.Amount != "" {
|
|
|
|
createOrderReq.Amount, err = decimal.NewFromString(in.Amount)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 判斷可選字段,只有不為 nil 才設置
|
|
|
|
if in.ReferenceBrand != nil {
|
|
|
|
createOrderReq.ReferenceBrand = in.ReferenceBrand
|
|
|
|
}
|
|
|
|
if in.ReferenceUid != nil {
|
|
|
|
createOrderReq.ReferenceUID = in.ReferenceUid
|
|
|
|
}
|
|
|
|
if in.WalletStatus != nil {
|
|
|
|
createOrderReq.WalletStatus = in.WalletStatus
|
|
|
|
}
|
|
|
|
if in.ThreePartyStatus != nil {
|
|
|
|
createOrderReq.ThreePartyStatus = in.ThreePartyStatus
|
|
|
|
}
|
|
|
|
if in.DirectionType != nil {
|
|
|
|
createOrderReq.DirectionType = in.DirectionType
|
|
|
|
}
|
|
|
|
if in.CryptoType != nil {
|
|
|
|
createOrderReq.CryptoType = in.CryptoType
|
|
|
|
}
|
|
|
|
if in.ThirdPartyFee != nil && *in.ThirdPartyFee != "" {
|
|
|
|
createOrderReq.ThirdPartyFee = decimalPtrFromString(*in.ThirdPartyFee)
|
|
|
|
}
|
|
|
|
if in.CryptoToUsdtRate != nil && *in.CryptoToUsdtRate != "" {
|
|
|
|
createOrderReq.CryptoToUSDTRate = decimalPtrFromString(*in.CryptoToUsdtRate)
|
|
|
|
}
|
|
|
|
if in.FiatToUsdRate != nil && *in.FiatToUsdRate != "" {
|
|
|
|
createOrderReq.FiatToUSDRate = decimalPtrFromString(*in.FiatToUsdRate)
|
|
|
|
}
|
|
|
|
if in.FeeCryptoToUsdtRate != nil && *in.FeeCryptoToUsdtRate != "" {
|
|
|
|
createOrderReq.FeeCryptoToUSDTRate = decimalPtrFromString(*in.FeeCryptoToUsdtRate)
|
|
|
|
}
|
|
|
|
if in.UsdtToCryptoTypeRate != nil && *in.UsdtToCryptoTypeRate != "" {
|
|
|
|
createOrderReq.USDTToCryptoTypeRate = decimalPtrFromString(*in.UsdtToCryptoTypeRate)
|
|
|
|
}
|
|
|
|
if in.PaymentFiat != nil {
|
|
|
|
createOrderReq.PaymentFiat = in.PaymentFiat
|
|
|
|
}
|
|
|
|
if in.PaymentUnitPrice != nil && *in.PaymentUnitPrice != "" {
|
|
|
|
createOrderReq.PaymentUnitPrice = decimalPtrFromString(*in.PaymentUnitPrice)
|
|
|
|
}
|
|
|
|
if in.PaymentTemplateId != nil {
|
|
|
|
createOrderReq.PaymentTemplateID = in.PaymentTemplateId
|
|
|
|
}
|
|
|
|
if in.OrderArrivalTime != nil {
|
|
|
|
createOrderReq.OrderArrivalTime = in.OrderArrivalTime
|
|
|
|
}
|
|
|
|
if in.OrderPaymentTime != nil {
|
|
|
|
createOrderReq.OrderPaymentTime = in.OrderPaymentTime
|
|
|
|
}
|
|
|
|
if in.UnpaidTimeoutSecond != nil {
|
|
|
|
createOrderReq.UnpaidTimeoutSecond = in.UnpaidTimeoutSecond
|
|
|
|
}
|
|
|
|
if in.ChainType != nil {
|
|
|
|
createOrderReq.ChainType = in.ChainType
|
|
|
|
}
|
|
|
|
if in.TxHash != nil {
|
|
|
|
createOrderReq.TxHash = in.TxHash
|
|
|
|
}
|
|
|
|
if in.FromAddress != nil {
|
|
|
|
createOrderReq.FromAddress = in.FromAddress
|
|
|
|
}
|
|
|
|
if in.ToAddress != nil {
|
|
|
|
createOrderReq.ToAddress = in.ToAddress
|
|
|
|
}
|
|
|
|
if in.ChainFee != nil && *in.ChainFee != "" {
|
|
|
|
createOrderReq.ChainFee = decimalPtrFromString(*in.ChainFee)
|
|
|
|
}
|
|
|
|
if in.ChainFeeCrypto != nil {
|
|
|
|
createOrderReq.ChainFeeCrypto = in.ChainFeeCrypto
|
|
|
|
}
|
|
|
|
if in.Memo != nil {
|
|
|
|
createOrderReq.Memo = in.Memo
|
|
|
|
}
|
|
|
|
if in.OrderNote != nil {
|
|
|
|
createOrderReq.OrderNote = in.OrderNote
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2024-10-06 07:02:30 +00:00
|
|
|
|
2024-10-12 09:49:58 +00:00
|
|
|
return &dec
|
2024-10-06 07:02:30 +00:00
|
|
|
}
|