package service import ( "errors" "fmt" "time" "affiliate_dash/internal/model" "gorm.io/gorm" ) type OrderService struct { db *gorm.DB } func NewOrderService(db *gorm.DB) *OrderService { return &OrderService{db: db} } type OrderListQuery struct { Page int Size int Status string DistributorID *uint } type CreateOrderInput struct { SkinID uint DistributorID uint BuyerName string Remark string } func (s *OrderService) List(q OrderListQuery) ([]model.Order, int64, error) { if q.Page < 1 { q.Page = 1 } if q.Size < 1 || q.Size > 100 { q.Size = 20 } tx := s.db.Model(&model.Order{}) if q.Status != "" { tx = tx.Where("status = ?", q.Status) } if q.DistributorID != nil { tx = tx.Where("distributor_id = ?", *q.DistributorID) } var total int64 if err := tx.Count(&total).Error; err != nil { return nil, 0, err } var list []model.Order err := tx.Preload("Skin").Preload("Distributor"). Order("id DESC"). Offset((q.Page - 1) * q.Size).Limit(q.Size). Find(&list).Error return list, total, err } func (s *OrderService) Create(in CreateOrderInput) (*model.Order, error) { var skin model.Skin if err := s.db.First(&skin, in.SkinID).Error; err != nil { return nil, errors.New("皮肤不存在") } if skin.Status != 1 { return nil, errors.New("皮肤已下架") } if skin.Stock == 0 { return nil, errors.New("库存不足") } order := &model.Order{ OrderNo: generateOrderNo(), SkinID: in.SkinID, DistributorID: in.DistributorID, BuyerName: in.BuyerName, Amount: skin.Price, CommissionAmt: skin.Price * skin.Commission, Status: model.OrderStatusPending, Remark: in.Remark, } err := s.db.Transaction(func(tx *gorm.DB) error { if skin.Stock > 0 { res := tx.Model(&model.Skin{}). Where("id = ? AND stock > 0", skin.ID). Update("stock", gorm.Expr("stock - 1")) if res.Error != nil { return res.Error } if res.RowsAffected == 0 { return errors.New("库存不足") } } return tx.Create(order).Error }) if err != nil { return nil, err } return order, nil } func (s *OrderService) UpdateStatus(id uint, status string) error { allowed := map[string]bool{ model.OrderStatusPending: true, model.OrderStatusPaid: true, model.OrderStatusDelivered: true, model.OrderStatusCancelled: true, } if !allowed[status] { return errors.New("无效的订单状态") } res := s.db.Model(&model.Order{}).Where("id = ?", id).Update("status", status) if res.Error != nil { return res.Error } if res.RowsAffected == 0 { return errors.New("订单不存在") } return nil } type DashboardStats struct { SkinCount int64 `json:"skin_count"` DistributorCount int64 `json:"distributor_count"` OrderCount int64 `json:"order_count"` TotalSales float64 `json:"total_sales"` TotalCommission float64 `json:"total_commission"` PendingOrderCount int64 `json:"pending_order_count"` } func (s *OrderService) Dashboard() (*DashboardStats, error) { stats := &DashboardStats{} s.db.Model(&model.Skin{}).Count(&stats.SkinCount) s.db.Model(&model.User{}).Where("role = ?", model.RoleDistributor).Count(&stats.DistributorCount) s.db.Model(&model.Order{}).Count(&stats.OrderCount) s.db.Model(&model.Order{}).Where("status = ?", model.OrderStatusPending).Count(&stats.PendingOrderCount) s.db.Model(&model.Order{}). Where("status IN ?", []string{model.OrderStatusPaid, model.OrderStatusDelivered}). Select("COALESCE(SUM(amount),0)").Scan(&stats.TotalSales) s.db.Model(&model.Order{}). Where("status IN ?", []string{model.OrderStatusPaid, model.OrderStatusDelivered}). Select("COALESCE(SUM(commission_amt),0)").Scan(&stats.TotalCommission) return stats, nil } func generateOrderNo() string { return fmt.Sprintf("O%s%04d", time.Now().Format("20060102150405"), time.Now().Nanosecond()%10000) }