Files
backend/cloudprint-backend/internal/repository/order_repository.go
2026-04-28 20:26:52 +08:00

163 lines
4.7 KiB
Go

package repository
import (
"context"
"errors"
"fmt"
"time"
"github.com/cloudprint/cloudprint-backend/internal/model"
"gorm.io/gorm"
)
type OrderRepository struct {
db *gorm.DB
}
func NewOrderRepository(db *gorm.DB) *OrderRepository {
return &OrderRepository{db: db}
}
func (r *OrderRepository) Create(ctx context.Context, order *model.Order) error {
return r.db.WithContext(ctx).Create(order).Error
}
func (r *OrderRepository) CreateWithItems(ctx context.Context, order *model.Order, items []*model.OrderItem) error {
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Create(order).Error; err != nil {
return err
}
for _, item := range items {
item.OrderID = order.ID
if err := tx.Create(item).Error; err != nil {
return err
}
}
return nil
})
}
func (r *OrderRepository) GetByID(ctx context.Context, id int32) (*model.Order, error) {
var order model.Order
err := r.db.WithContext(ctx).Preload("Items").Preload("Items.File").Preload("Payment").
First(&order, id).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &order, nil
}
func (r *OrderRepository) GetByOrderNo(ctx context.Context, orderNo string) (*model.Order, error) {
var order model.Order
err := r.db.WithContext(ctx).Preload("Items").Preload("Items.File").Preload("Items.Printer").Preload("Payment").
Where("order_no = ?", orderNo).First(&order).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &order, nil
}
func (r *OrderRepository) GetListByUserID(ctx context.Context, userID int32, status int8, page, pageSize int) ([]*model.Order, int64, error) {
var orders []*model.Order
var total int64
query := r.db.WithContext(ctx).Model(&model.Order{}).Where("user_id = ?", userID)
if status >= 0 {
query = query.Where("status = ?", status)
}
err := query.Count(&total).Error
if err != nil {
return nil, 0, err
}
offset := (page - 1) * pageSize
err = query.Preload("Items").Preload("Items.File").
Offset(offset).Limit(pageSize).Order("created_at DESC").
Find(&orders).Error
if err != nil {
return nil, 0, err
}
return orders, total, nil
}
func (r *OrderRepository) UpdateStatus(ctx context.Context, orderNo string, status int8) error {
updates := map[string]interface{}{
"status": status,
}
if status == model.OrderStatusPaid {
now := time.Now()
updates["paid_at"] = &now
}
return r.db.WithContext(ctx).Model(&model.Order{}).
Where("order_no = ?", orderNo).Updates(updates).Error
}
func (r *OrderRepository) GetStatistics(ctx context.Context) (totalUsers, totalOrders, todayOrders int64, todayRevenue float64, pendingOrders int64, err error) {
// 总用户数
if err = r.db.WithContext(ctx).Model(&model.User{}).Count(&totalUsers).Error; err != nil {
return 0, 0, 0, 0, 0, fmt.Errorf("count users failed: %w", err)
}
// 总订单数
if err = r.db.WithContext(ctx).Model(&model.Order{}).Count(&totalOrders).Error; err != nil {
return 0, 0, 0, 0, 0, fmt.Errorf("count orders failed: %w", err)
}
// 待处理订单数
if err = r.db.WithContext(ctx).Model(&model.Order{}).Where("status IN ?", []int8{0, 1, 2}).Count(&pendingOrders).Error; err != nil {
return 0, 0, 0, 0, 0, fmt.Errorf("count pending orders failed: %w", err)
}
// 今日订单数
today := time.Now().Format("2006-01-02")
if err = r.db.WithContext(ctx).Model(&model.Order{}).
Where("created_at::date = ? AND status = ?", today, model.OrderStatusPaid).
Count(&todayOrders).Error; err != nil {
return 0, 0, 0, 0, 0, fmt.Errorf("count today orders failed: %w", err)
}
// 今日收入
if err = r.db.WithContext(ctx).Model(&model.Order{}).
Select("COALESCE(SUM(total_amount), 0)").
Where("created_at::date = ? AND status = ?", today, model.OrderStatusPaid).
Scan(&todayRevenue).Error; err != nil {
return 0, 0, 0, 0, 0, fmt.Errorf("sum today revenue failed: %w", err)
}
return
}
type OrderItemRepository struct {
db *gorm.DB
}
func NewOrderItemRepository(db *gorm.DB) *OrderItemRepository {
return &OrderItemRepository{db: db}
}
func (r *OrderItemRepository) GetByID(ctx context.Context, id int32) (*model.OrderItem, error) {
var item model.OrderItem
err := r.db.WithContext(ctx).Preload("File").First(&item, id).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return &item, nil
}
func (r *OrderItemRepository) Create(ctx context.Context, item *model.OrderItem) error {
return r.db.WithContext(ctx).Create(item).Error
}
func (r *OrderItemRepository) GetByOrderID(ctx context.Context, orderID int32) ([]*model.OrderItem, error) {
var items []*model.OrderItem
err := r.db.WithContext(ctx).Where("order_id = ?", orderID).Find(&items).Error
return items, err
}