app-cloudep-trade-service/internal/model/mongo/order_model.go

239 lines
6.6 KiB
Go
Raw Permalink Normal View History

2024-10-25 16:42:58 +00:00
package model
import (
2024-10-25 17:17:32 +00:00
"app-cloudep-trade-service/internal/domain"
"context"
"errors"
2024-10-27 14:23:37 +00:00
"time"
2024-10-25 16:42:58 +00:00
"github.com/zeromicro/go-zero/core/stores/mon"
2024-10-25 17:17:32 +00:00
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
2024-10-25 16:42:58 +00:00
)
var _ OrderModel = (*customOrderModel)(nil)
type (
// OrderModel is an interface to be customized, add more methods here,
// and implement the added methods in customOrderModel.
OrderModel interface {
orderModel
2024-10-25 17:17:32 +00:00
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)
2024-10-25 16:42:58 +00:00
}
customOrderModel struct {
*defaultOrderModel
}
2024-10-25 17:17:32 +00:00
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"`
2024-10-27 14:23:37 +00:00
DirectionType []int64 `json:"direction_type"`
OrderStatus []int64 `json:"order_status"`
2024-10-25 17:17:32 +00:00
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"`
}
2024-10-25 16:42:58 +00:00
)
// NewOrderModel returns a model for the mongo.
func NewOrderModel(url, db, collection string, opts ...mon.Option) OrderModel {
conn := mon.MustNewModel(url, db, collection, opts...)
return &customOrderModel{
defaultOrderModel: newDefaultOrderModel(conn),
}
}
2024-10-25 17:17:32 +00:00
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
}