261 lines
6.6 KiB
Go
261 lines
6.6 KiB
Go
package dao
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"gitee.com/red-future---jilin-g/common/mongo"
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
"order/consts"
|
|
"order/model/entity"
|
|
)
|
|
|
|
// Init 初始化DAO
|
|
func Init() error {
|
|
return nil
|
|
}
|
|
|
|
type order struct{}
|
|
|
|
// Order 订单数据访问对象
|
|
var Order = &order{}
|
|
|
|
// 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, 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, 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, pageSize int) (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, filter, collection)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
// 分页查询(暂时忽略排序和分页,因为 mongo.Find 不支持这些参数)
|
|
// TODO: 需要在 common/mongo 中添加支持排序和分页的 Find 方法
|
|
|
|
// 根据状态返回对应的订单类型
|
|
switch status {
|
|
case consts.OrderStatusPending:
|
|
var orders []entity.OrderPending
|
|
if err := mongo.Find(ctx, filter, &orders, collection); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
return orders, total, nil
|
|
case consts.OrderStatusPaid:
|
|
var orders []entity.OrderPaid
|
|
if err := mongo.Find(ctx, filter, &orders, collection); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
return orders, total, nil
|
|
case consts.OrderStatusShipped:
|
|
var orders []entity.OrderShipped
|
|
if err := mongo.Find(ctx, filter, &orders, collection); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
return orders, total, nil
|
|
case consts.OrderStatusCompleted:
|
|
var orders []entity.OrderCompleted
|
|
if err := mongo.Find(ctx, filter, &orders, collection); err != nil {
|
|
return nil, 0, err
|
|
}
|
|
return orders, total, nil
|
|
default:
|
|
return nil, 0, errors.New("unsupported order status")
|
|
}
|
|
}
|
|
|
|
// GetExpiredPendingOrders 获取过期的待支付订单
|
|
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, 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
|
|
}
|