163 lines
4.7 KiB
Go
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 int32, todayRevenue float64, pendingOrders int32, 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("DATE(created_at) = ? 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("DATE(created_at) = ? 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
|
|
}
|