Compare commits
2 Commits
9e667c83f3
...
799fc0bf9d
Author | SHA1 | Date |
---|---|---|
|
799fc0bf9d | |
|
495994708e |
|
@ -0,0 +1,45 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
|
"code.30cm.net/digimon/library-go/errs/code"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ErrorCode uint32
|
||||||
|
|
||||||
|
func (e ErrorCode) ToUint32() uint32 {
|
||||||
|
return uint32(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error Code 統一這邊改
|
||||||
|
const (
|
||||||
|
_ = iota
|
||||||
|
CreateOrderErrorCode ErrorCode = iota
|
||||||
|
CancelOrderErrorCode
|
||||||
|
ModifyOrderErrorCode
|
||||||
|
TimeoutOrderErrorCode
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ ErrorCode = 10 + iota
|
||||||
|
DataNotFoundErrorCode
|
||||||
|
)
|
||||||
|
|
||||||
|
func CommentError(ec ErrorCode, s ...string) *ers.LibError {
|
||||||
|
return ers.NewError(code.CloudEPOrder, code.DBError, ec.ToUint32(), strings.Join(s, " "))
|
||||||
|
}
|
||||||
|
|
||||||
|
func CommentErrorL(ec ErrorCode,
|
||||||
|
l logx.Logger, filed []logx.LogField, s ...string) *ers.LibError {
|
||||||
|
e := CommentError(ec, s...)
|
||||||
|
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotFoundError(ec ErrorCode, s ...string) *ers.LibError {
|
||||||
|
return ers.NewError(code.CloudEPOrder, code.ResourceNotFound, ec.ToUint32(), strings.Join(s, " "))
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
type OrderStatus int64
|
||||||
|
|
||||||
|
func (o *OrderStatus) ToInt() int {
|
||||||
|
return int(*o)
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
OrderStatusCreated OrderStatus = 0 // 建立訂單
|
||||||
|
OrderStatusFailed OrderStatus = 1 // 建單失敗
|
||||||
|
OrderStatusReviewing OrderStatus = 2 // 審核中
|
||||||
|
OrderStatusPaying OrderStatus = 3 // 付款中
|
||||||
|
OrderStatusPaid OrderStatus = 4 // 已付款
|
||||||
|
OrderStatusPendingTransfer OrderStatus = 5 // 已付款待轉帳
|
||||||
|
OrderStatusDisputing OrderStatus = 6 // 申訴中
|
||||||
|
OrderStatusCompleted OrderStatus = 7 // 交易完成
|
||||||
|
OrderStatusFailedTrade OrderStatus = 8 // 交易失敗
|
||||||
|
OrderStatusCancelled OrderStatus = 9 // 交易取消
|
||||||
|
OrderStatusAbnormal OrderStatus = 10 // 交易異常
|
||||||
|
OrderStatusTimeout OrderStatus = 11 // 交易超時
|
||||||
|
)
|
|
@ -1,7 +1,14 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-trade-service/internal/domain"
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ OrderModel = (*customOrderModel)(nil)
|
var _ OrderModel = (*customOrderModel)(nil)
|
||||||
|
@ -11,11 +18,49 @@ type (
|
||||||
// and implement the added methods in customOrderModel.
|
// and implement the added methods in customOrderModel.
|
||||||
OrderModel interface {
|
OrderModel interface {
|
||||||
orderModel
|
orderModel
|
||||||
|
UpdateStatus(ctx context.Context, data UpdateStatusReq) (*mongo.UpdateResult, error)
|
||||||
|
UpdateTimeoutOrder(ctx context.Context, req UpdateTimeoutReq) (*mongo.UpdateResult, error)
|
||||||
|
DeleteByBusinessID(ctx context.Context, id string) (*mongo.UpdateResult, error)
|
||||||
|
FindOneBusinessID(ctx context.Context, id string) (*Order, error)
|
||||||
|
ListOrder(ctx context.Context, req GetOrderListReq) ([]Order, int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
customOrderModel struct {
|
customOrderModel struct {
|
||||||
*defaultOrderModel
|
*defaultOrderModel
|
||||||
}
|
}
|
||||||
|
UpdateStatusReq struct {
|
||||||
|
BusinessID string
|
||||||
|
Status int64
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateTimeoutReq struct {
|
||||||
|
CreateTimeBefore int64
|
||||||
|
}
|
||||||
|
|
||||||
|
GetOrderListReq struct {
|
||||||
|
PageIndex int64 `json:"page_index" validate:"required"`
|
||||||
|
PageSize int64 `json:"page_size" validate:"required"`
|
||||||
|
|
||||||
|
ReferenceID string `json:"reference_id"`
|
||||||
|
ReferenceUID string `json:"reference_uid"`
|
||||||
|
BusinessID string `json:"business_id"`
|
||||||
|
UID string `json:"uid"`
|
||||||
|
OrderType int `json:"order_type"`
|
||||||
|
DirectionType []int32 `json:"direction_type"`
|
||||||
|
OrderStatus []int32 `json:"order_status"`
|
||||||
|
|
||||||
|
StartCreateTime int64 `json:"start_create_time"`
|
||||||
|
EndCreateTime int64 `json:"end_create_time"`
|
||||||
|
StartUpdateTime int64 `json:"start_update_time"`
|
||||||
|
EndUpdateTime int64 `json:"end_update_time"`
|
||||||
|
StartOrderArrivalTime int64 `json:"start_order_arrival_time"`
|
||||||
|
EndOrderArrivalTime int64 `json:"end_order_arrival_time"`
|
||||||
|
StartOrderPaymentTime int64 `json:"start_order_payment_time"`
|
||||||
|
EndOrderPaymentTime int64 `json:"end_order_payment_time"`
|
||||||
|
|
||||||
|
CryptoType string `json:"crypto_type"`
|
||||||
|
TxHash string `json:"tx_hash"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewOrderModel returns a model for the mongo.
|
// NewOrderModel returns a model for the mongo.
|
||||||
|
@ -25,3 +70,168 @@ func NewOrderModel(url, db, collection string, opts ...mon.Option) OrderModel {
|
||||||
defaultOrderModel: newDefaultOrderModel(conn),
|
defaultOrderModel: newDefaultOrderModel(conn),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *customOrderModel) UpdateStatus(ctx context.Context, data UpdateStatusReq) (*mongo.UpdateResult, error) {
|
||||||
|
// 初始化 updates map
|
||||||
|
updates := make(map[string]any)
|
||||||
|
|
||||||
|
// 更新 update_time 和 status
|
||||||
|
updates["update_time"] = time.Now().UTC().UnixNano()
|
||||||
|
updates["order_status"] = data.Status
|
||||||
|
|
||||||
|
// 使用 updates map 作為 $set 的內容
|
||||||
|
res, err := m.conn.UpdateOne(ctx,
|
||||||
|
bson.M{
|
||||||
|
"business_id": data.BusinessID,
|
||||||
|
"$or": []bson.M{
|
||||||
|
{"delete_time": bson.M{"$exists": false}},
|
||||||
|
{"delete_time": 0},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
bson.M{"$set": updates}, // 使用 updates 而不是整個 data
|
||||||
|
)
|
||||||
|
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customOrderModel) UpdateTimeoutOrder(ctx context.Context, req UpdateTimeoutReq) (*mongo.UpdateResult, error) {
|
||||||
|
// 構建過濾條件,選擇創建時間在指定時間之前且狀態為 0 (創建) 的項目
|
||||||
|
filter := bson.M{
|
||||||
|
"create_time": bson.M{"$lt": req.CreateTimeBefore},
|
||||||
|
"status": domain.OrderStatusCreated,
|
||||||
|
"$or": []bson.M{
|
||||||
|
{"delete_time": bson.M{"$exists": false}},
|
||||||
|
{"delete_time": 0},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新內容,將狀態設置為 11,並更新 update_time
|
||||||
|
updates := bson.M{
|
||||||
|
"$set": bson.M{
|
||||||
|
"status": domain.OrderStatusTimeout,
|
||||||
|
"update_time": time.Now().UTC().UnixNano(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 執行更新操作
|
||||||
|
res, err := m.conn.UpdateOne(ctx, filter, updates)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customOrderModel) DeleteByBusinessID(ctx context.Context, id string) (*mongo.UpdateResult, error) {
|
||||||
|
filter := bson.M{
|
||||||
|
"business_id": id,
|
||||||
|
"$or": []bson.M{
|
||||||
|
{"delete_time": bson.M{"$exists": false}},
|
||||||
|
{"delete_time": 0},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
updates := bson.M{
|
||||||
|
"$set": bson.M{
|
||||||
|
"delete_time": time.Now().UTC().UnixNano(),
|
||||||
|
"update_time": time.Now().UTC().UnixNano(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// 執行更新操作
|
||||||
|
res, err := m.conn.UpdateOne(ctx, filter, updates)
|
||||||
|
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultOrderModel) FindOneBusinessID(ctx context.Context, id string) (*Order, error) {
|
||||||
|
var data Order
|
||||||
|
filter := bson.M{"delete_time": bson.M{"$in": []any{0, nil}}}
|
||||||
|
filter["business_id"] = id
|
||||||
|
|
||||||
|
err := m.conn.FindOne(ctx, &data, filter)
|
||||||
|
switch {
|
||||||
|
case err == nil:
|
||||||
|
return &data, nil
|
||||||
|
case errors.Is(err, mon.ErrNotFound):
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customOrderModel) ListOrder(ctx context.Context, req GetOrderListReq) ([]Order, int64, error) {
|
||||||
|
// 定義查詢過濾器
|
||||||
|
filter := bson.M{
|
||||||
|
"delete_time": bson.M{"$in": []any{0, nil}},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加查詢條件
|
||||||
|
if req.ReferenceID != "" {
|
||||||
|
filter["reference_id"] = req.ReferenceID
|
||||||
|
}
|
||||||
|
if req.ReferenceUID != "" {
|
||||||
|
filter["reference_uid"] = req.ReferenceUID
|
||||||
|
}
|
||||||
|
if req.BusinessID != "" {
|
||||||
|
filter["business_id"] = req.BusinessID
|
||||||
|
}
|
||||||
|
if req.UID != "" {
|
||||||
|
filter["order_uid"] = req.UID
|
||||||
|
}
|
||||||
|
if req.OrderType != 0 {
|
||||||
|
filter["order_type"] = req.OrderType
|
||||||
|
}
|
||||||
|
if len(req.DirectionType) > 0 {
|
||||||
|
filter["direction_type"] = bson.M{"$in": req.DirectionType}
|
||||||
|
}
|
||||||
|
if len(req.OrderStatus) > 0 {
|
||||||
|
filter["order_status"] = bson.M{"$in": req.OrderStatus}
|
||||||
|
}
|
||||||
|
// 處理時間範圍
|
||||||
|
if req.StartCreateTime != 0 {
|
||||||
|
filter["create_time"] = bson.M{"$gte": req.StartCreateTime}
|
||||||
|
}
|
||||||
|
if req.EndCreateTime != 0 {
|
||||||
|
filter["create_time"] = bson.M{"$lte": req.EndCreateTime}
|
||||||
|
}
|
||||||
|
if req.StartUpdateTime != 0 {
|
||||||
|
filter["update_time"] = bson.M{"$gte": req.StartUpdateTime}
|
||||||
|
}
|
||||||
|
if req.EndUpdateTime != 0 {
|
||||||
|
filter["update_time"] = bson.M{"$lte": req.EndUpdateTime}
|
||||||
|
}
|
||||||
|
if req.StartOrderArrivalTime != 0 {
|
||||||
|
filter["order_arrival_time"] = bson.M{"$gte": req.StartOrderArrivalTime}
|
||||||
|
}
|
||||||
|
if req.EndOrderArrivalTime != 0 {
|
||||||
|
filter["order_arrival_time"] = bson.M{"$lte": req.EndOrderArrivalTime}
|
||||||
|
}
|
||||||
|
if req.StartOrderPaymentTime != 0 {
|
||||||
|
filter["order_payment_time"] = bson.M{"$gte": req.StartOrderPaymentTime}
|
||||||
|
}
|
||||||
|
if req.EndOrderPaymentTime != 0 {
|
||||||
|
filter["order_payment_time"] = bson.M{"$lte": req.EndOrderPaymentTime}
|
||||||
|
}
|
||||||
|
if req.CryptoType != "" {
|
||||||
|
filter["crypto_type"] = req.CryptoType
|
||||||
|
}
|
||||||
|
if req.TxHash != "" {
|
||||||
|
filter["tx_hash"] = req.TxHash
|
||||||
|
}
|
||||||
|
|
||||||
|
// 計算符合條件的總數量
|
||||||
|
totalCount, err := m.conn.CountDocuments(ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 設定查詢選項,包含分頁
|
||||||
|
findOptions := options.Find()
|
||||||
|
findOptions.SetSkip((req.PageIndex - 1) * req.PageSize)
|
||||||
|
findOptions.SetLimit(req.PageSize)
|
||||||
|
|
||||||
|
// 執行查詢
|
||||||
|
var orders []Order
|
||||||
|
err = m.conn.Find(ctx, &orders, filter, findOptions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return orders, totalCount, nil
|
||||||
|
}
|
||||||
|
|
|
@ -28,9 +28,10 @@ func newDefaultOrderModel(conn *mon.Model) *defaultOrderModel {
|
||||||
|
|
||||||
func (m *defaultOrderModel) Insert(ctx context.Context, data *Order) error {
|
func (m *defaultOrderModel) Insert(ctx context.Context, data *Order) error {
|
||||||
if data.ID.IsZero() {
|
if data.ID.IsZero() {
|
||||||
|
now := time.Now().UTC().UnixNano()
|
||||||
data.ID = primitive.NewObjectID()
|
data.ID = primitive.NewObjectID()
|
||||||
data.CreateAt = time.Now()
|
data.CreateTime = now
|
||||||
data.UpdateAt = time.Now()
|
data.UpdateTime = now
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := m.conn.InsertOne(ctx, data)
|
_, err := m.conn.InsertOne(ctx, data)
|
||||||
|
@ -57,7 +58,7 @@ func (m *defaultOrderModel) FindOne(ctx context.Context, id string) (*Order, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *defaultOrderModel) Update(ctx context.Context, data *Order) (*mongo.UpdateResult, error) {
|
func (m *defaultOrderModel) Update(ctx context.Context, data *Order) (*mongo.UpdateResult, error) {
|
||||||
data.UpdateAt = time.Now()
|
data.UpdateTime = time.Now().UTC().UnixNano()
|
||||||
|
|
||||||
res, err := m.conn.UpdateOne(ctx, bson.M{"_id": data.ID}, bson.M{"$set": data})
|
res, err := m.conn.UpdateOne(ctx, bson.M{"_id": data.ID}, bson.M{"$set": data})
|
||||||
return res, err
|
return res, err
|
||||||
|
|
|
@ -1,16 +1,49 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"github.com/shopspring/decimal"
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Order struct {
|
type Order struct {
|
||||||
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
|
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
|
||||||
// TODO: Fill your own fields
|
UpdateTime int64 `bson:"update_time"`
|
||||||
UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"`
|
CreateTime int64 `bson:"create_time"`
|
||||||
CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"`
|
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 decimal.Decimal `bson:"count"` // 訂單數量
|
||||||
|
OrderFee decimal.Decimal `bson:"order_fee"` // 訂單手續費
|
||||||
|
Amount decimal.Decimal `bson:"amount"` // 單價
|
||||||
|
WalletStatus int64 `bson:"wallet_status,omitempty"` // 交易金額狀態
|
||||||
|
DirectionType int64 `bson:"direction_type,omitempty"` // 交易方向
|
||||||
|
// 以上為必要欄位,下面是區塊鏈時才需要
|
||||||
|
ReferenceBrand *string `bson:"reference_brand,omitempty"` // 訂單來源平台
|
||||||
|
ReferenceUID *string `bson:"reference_uid,omitempty"` // 訂單來源用戶 UID
|
||||||
|
ThreePartyStatus *int64 `bson:"three_party_status,omitempty"` // 三方請求狀態
|
||||||
|
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"` // 加密貨幣單價
|
||||||
|
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"` // 訂單交易備註
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Order) CollectionName() string {
|
func (p *Order) CollectionName() string {
|
||||||
|
|
Loading…
Reference in New Issue