235 lines
6.5 KiB
Go
235 lines
6.5 KiB
Go
package model
|
||
|
||
import (
|
||
"app-cloudep-order-server/internal/domain"
|
||
"context"
|
||
"errors"
|
||
"go.mongodb.org/mongo-driver/mongo/options"
|
||
"time"
|
||
|
||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||
"go.mongodb.org/mongo-driver/bson"
|
||
"go.mongodb.org/mongo-driver/mongo"
|
||
)
|
||
|
||
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
|
||
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 {
|
||
*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 []int64 `json:"direction_type"`
|
||
OrderStatus []int64 `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.
|
||
func NewOrderModel(url, db, collection string) OrderModel {
|
||
conn := mon.MustNewModel(url, db, collection)
|
||
return &customOrderModel{
|
||
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["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
|
||
|
||
err := m.conn.FindOne(ctx, &data, bson.M{"business_id": id})
|
||
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{}
|
||
|
||
// 添加查詢條件
|
||
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
|
||
}
|