package dao import ( "context" "errors" "fmt" "strings" "time" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo/options" "order/consts" "order/model/entity" "gitee.com/red-future---jilin-g/common/mongo" ) type order struct { NoCache bool } // Order 订单数据访问对象 var Order = &order{ NoCache: false, } func (d *order) SetNoCache() { Order.NoCache = true } // getCollection 根据订单状态获取对应的集合 func (d *order) getCollection(status consts.OrderStatus) (string, error) { switch status { case consts.OrderStatusPending: return consts.OrderPendingCollection, nil case consts.OrderStatusPaid: return consts.OrderPaidCollection, nil case consts.OrderStatusShipped: return consts.OrderShippedCollection, nil case consts.OrderStatusCompleted: return consts.OrderCompletedCollection, nil default: return "", fmt.Errorf("collection for status %s not found", status) } } // CreatePendingOrder 创建待支付订单 func (d *order) CreatePendingOrder(ctx context.Context, order *entity.OrderPending) error { collection, err := d.getCollection(consts.OrderStatusPending) if err != nil { return err } order.Id = bson.NewObjectID() order.CreatedAt = time.Now() order.UpdatedAt = time.Now() _, err = mongo.Insert(ctx, []interface{}{order}, collection) return err } // GetOrderByNo 根据订单号查询订单(自动识别状态) func (d *order) GetOrderByNo(ctx context.Context, orderNo string) (interface{}, consts.OrderStatus, error) { // 按状态优先级搜索(从最新状态开始) statuses := []consts.OrderStatus{ consts.OrderStatusCompleted, consts.OrderStatusShipped, consts.OrderStatusPaid, consts.OrderStatusPending, } for _, status := range statuses { collection, err := d.getCollection(status) if err != nil { continue } switch status { case consts.OrderStatusPending: var order entity.OrderPending if err := d.findOrderByNo(collection, ctx, orderNo, &order); err == nil { return &order, status, nil } case consts.OrderStatusPaid: var order entity.OrderPaid if err := d.findOrderByNo(collection, ctx, orderNo, &order); err == nil { return &order, status, nil } case consts.OrderStatusShipped: var order entity.OrderShipped if err := d.findOrderByNo(collection, ctx, orderNo, &order); err == nil { return &order, status, nil } case consts.OrderStatusCompleted: var order entity.OrderCompleted if err := d.findOrderByNo(collection, ctx, orderNo, &order); err == nil { return &order, status, nil } } } return nil, "", errors.New("order not found") } // findOrderByNo 通用订单查询方法 func (d *order) findOrderByNo(collection string, ctx context.Context, orderNo string, result interface{}) error { filter := bson.M{ "order_no": orderNo, } err := mongo.FindOne(ctx, d.NoCache, filter, result, collection) if err != nil { return errors.New("order not found") } return nil } // MoveOrderToStatus 将订单从一个状态移动到另一个状态 func (d *order) MoveOrderToStatus(ctx context.Context, fromStatus, toStatus consts.OrderStatus, orderNo string, updateData bson.M) error { // 获取源集合 srcCollection, err := d.getCollection(fromStatus) if err != nil { return err } // 获取目标集合 destCollection, err := d.getCollection(toStatus) if err != nil { return err } // 查找源订单 var orderData bson.M filter := bson.M{ "order_no": orderNo, } err = mongo.FindOne(ctx, d.NoCache, filter, &orderData, srcCollection) if err != nil { return err } // 更新数据 orderData["updated_at"] = time.Now() for key, value := range updateData { orderData[key] = value } // 插入到目标集合 _, err = mongo.Insert(ctx, []interface{}{orderData}, destCollection) if err != nil { return err } // 从源集合删除 _, err = mongo.Delete(ctx, filter, srcCollection) return err } // UpdatePendingOrder 更新待支付订单 func (d *order) UpdatePendingOrder(ctx context.Context, orderNo string, update bson.M) error { collection, err := d.getCollection(consts.OrderStatusPending) if err != nil { return err } update["updated_at"] = time.Now() filter := bson.M{ "order_no": orderNo, } _, err = mongo.Update(ctx, filter, bson.M{"$set": update}, collection) return err } // ListOrdersByStatus 根据状态查询订单列表 func (d *order) ListOrdersByStatus(ctx context.Context, status consts.OrderStatus, userID string, page int, pageSize int, sortFields ...string) (interface{}, int64, error) { collection, err := d.getCollection(status) if err != nil { return nil, 0, err } // 构建查询条件 filter := bson.M{} if userID != "" { filter["user_id"] = userID } // 计算总数 total, err := mongo.Count(ctx, d.NoCache, filter, collection) if err != nil { return nil, 0, err } // 设置分页参数 var findOptions []options.Lister[options.FindOptions] if page > 0 && pageSize > 0 { findOptions = append(findOptions, options.Find().SetSkip(int64((page-1)*pageSize)).SetLimit(int64(pageSize))) } // 设置排序参数 if len(sortFields) > 0 { sort := bson.D{} for _, field := range sortFields { var order int if strings.HasPrefix(field, "-") { order = -1 field = strings.TrimPrefix(field, "-") } else { order = 1 } sort = append(sort, bson.E{Key: field, Value: order}) } findOptions = append(findOptions, options.Find().SetSort(sort)) } // 根据状态返回对应的订单类型 switch status { case consts.OrderStatusPending: var orders []entity.OrderPending if err := mongo.Find(ctx, d.NoCache, filter, &orders, collection, findOptions...); err != nil { return nil, 0, err } return orders, total, nil case consts.OrderStatusPaid: var orders []entity.OrderPaid if err := mongo.Find(ctx, d.NoCache, filter, &orders, collection, findOptions...); err != nil { return nil, 0, err } return orders, total, nil case consts.OrderStatusShipped: var orders []entity.OrderShipped if err := mongo.Find(ctx, d.NoCache, filter, &orders, collection, findOptions...); err != nil { return nil, 0, err } return orders, total, nil case consts.OrderStatusCompleted: var orders []entity.OrderCompleted if err := mongo.Find(ctx, d.NoCache, filter, &orders, collection, findOptions...); err != nil { return nil, 0, err } return orders, total, nil default: return nil, 0, errors.New("unsupported order status") } } // GetExpiredPendingOrders 获取过期的待支付订单 // GetPendingOrder gets pending order by order number func (d *order) GetPendingOrder(ctx context.Context, orderNo string) (*entity.OrderPending, error) { collection, err := d.getCollection(consts.OrderStatusPending) if err != nil { return nil, err } filter := bson.M{"order_no": orderNo} var order entity.OrderPending if err := mongo.FindOne(ctx, d.NoCache, filter, &order, collection); err != nil { if err.Error() == "mongo: no documents in result" { return nil, nil } return nil, err } return &order, nil } func (d *order) GetExpiredPendingOrders(ctx context.Context) ([]entity.OrderPending, error) { collection, err := d.getCollection(consts.OrderStatusPending) if err != nil { return nil, err } filter := bson.M{ "expired_at": bson.M{"$lte": time.Now()}, } var orders []entity.OrderPending if err := mongo.Find(ctx, d.NoCache, filter, &orders, collection); err != nil { return nil, err } return orders, nil } // UpdatePayInfo 更新支付信息(待支付订单) func (d *order) UpdatePayInfo(ctx context.Context, orderNo string, payInfo entity.PayInfo) error { collection, err := d.getCollection(consts.OrderStatusPending) if err != nil { return err } filter := bson.M{ "order_no": orderNo, } update := bson.M{ "pay_info": payInfo, "updated_at": time.Now(), } _, err = mongo.Update(ctx, filter, bson.M{"$set": update}, collection) return err }