init
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user