2026-03-18 13:07:06 +08:00
|
|
|
package services
|
|
|
|
|
|
2026-03-23 17:50:47 +08:00
|
|
|
import (
|
|
|
|
|
"platform/web/core"
|
|
|
|
|
m "platform/web/models"
|
|
|
|
|
q "platform/web/queries"
|
|
|
|
|
"time"
|
|
|
|
|
|
2026-06-18 12:15:30 +08:00
|
|
|
"github.com/shopspring/decimal"
|
2026-03-23 17:50:47 +08:00
|
|
|
"gorm.io/gen/field"
|
|
|
|
|
)
|
2026-03-18 13:07:06 +08:00
|
|
|
|
|
|
|
|
var Product = &productService{}
|
|
|
|
|
|
|
|
|
|
type productService struct{}
|
|
|
|
|
|
2026-03-23 17:50:47 +08:00
|
|
|
// 获取所有产品
|
|
|
|
|
func (s *productService) AllProducts() ([]*m.Product, error) {
|
2026-03-30 14:59:35 +08:00
|
|
|
return q.Product.
|
|
|
|
|
Order(q.Product.Sort.Asc(), q.Product.CreatedAt.Desc()).
|
|
|
|
|
Find()
|
2026-03-23 17:50:47 +08:00
|
|
|
}
|
|
|
|
|
|
2026-06-18 12:15:30 +08:00
|
|
|
func (s *productService) AllProductSaleInfos() ([]any, error) {
|
2026-04-15 16:56:24 +08:00
|
|
|
products, err := q.Product.
|
2026-04-14 15:06:08 +08:00
|
|
|
Select(
|
|
|
|
|
q.Product.ID,
|
|
|
|
|
q.Product.Code,
|
|
|
|
|
q.Product.Name,
|
|
|
|
|
q.Product.Description,
|
|
|
|
|
q.Product.Sort,
|
2026-04-15 16:56:24 +08:00
|
|
|
).
|
|
|
|
|
Where(
|
|
|
|
|
q.Product.Status.Eq(int(m.ProductStatusEnabled)),
|
|
|
|
|
).
|
|
|
|
|
Order(q.Product.Sort).
|
|
|
|
|
Find()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pids := make([]int32, len(products))
|
|
|
|
|
for i, p := range products {
|
|
|
|
|
pids[i] = p.ID
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-18 12:15:30 +08:00
|
|
|
type SkuInfo struct {
|
|
|
|
|
ID int32 `json:"id"`
|
|
|
|
|
ProductID int32 `json:"product_id"`
|
|
|
|
|
Name string `json:"name"`
|
|
|
|
|
Code string `json:"code"`
|
|
|
|
|
Price decimal.Decimal `json:"price"`
|
|
|
|
|
CountMin decimal.Decimal `json:"count_min"`
|
|
|
|
|
Discount float64 `json:"discount"`
|
|
|
|
|
}
|
|
|
|
|
var skus []*SkuInfo
|
|
|
|
|
err = q.ProductSku.
|
2026-04-15 16:56:24 +08:00
|
|
|
Select(
|
2026-04-14 15:06:08 +08:00
|
|
|
q.ProductSku.ID,
|
2026-04-15 16:56:24 +08:00
|
|
|
q.ProductSku.ProductID,
|
2026-04-14 15:06:08 +08:00
|
|
|
q.ProductSku.Name,
|
2026-04-15 16:56:24 +08:00
|
|
|
q.ProductSku.Code,
|
2026-04-14 15:06:08 +08:00
|
|
|
q.ProductSku.Price,
|
2026-04-20 11:20:44 +08:00
|
|
|
q.ProductSku.CountMin,
|
2026-06-18 12:15:30 +08:00
|
|
|
q.ProductDiscount.Discount,
|
2026-04-14 15:06:08 +08:00
|
|
|
).
|
|
|
|
|
Where(
|
2026-04-15 16:56:24 +08:00
|
|
|
q.ProductSku.ProductID.In(pids...),
|
|
|
|
|
q.ProductSku.Status.Eq(int32(m.SkuStatusEnabled)),
|
2026-04-14 15:06:08 +08:00
|
|
|
).
|
2026-06-18 12:15:30 +08:00
|
|
|
LeftJoin(q.ProductDiscount, q.ProductDiscount.ID.EqCol(q.ProductSku.DiscountId)).
|
2026-04-15 16:56:24 +08:00
|
|
|
Order(q.ProductSku.Sort).
|
2026-06-18 12:15:30 +08:00
|
|
|
Scan(&skus)
|
2026-04-15 16:56:24 +08:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-18 12:15:30 +08:00
|
|
|
type ProductInfo struct {
|
|
|
|
|
m.Product
|
|
|
|
|
Skus []*SkuInfo `json:"skus,omitempty"`
|
|
|
|
|
}
|
|
|
|
|
pmap := make(map[int32]*ProductInfo, len(products))
|
2026-04-15 16:56:24 +08:00
|
|
|
for _, p := range products {
|
2026-06-18 12:15:30 +08:00
|
|
|
pmap[p.ID] = &ProductInfo{Product: *p, Skus: make([]*SkuInfo, 0)}
|
2026-04-15 16:56:24 +08:00
|
|
|
}
|
|
|
|
|
for _, s := range skus {
|
|
|
|
|
if p, ok := pmap[s.ProductID]; ok {
|
2026-06-18 12:15:30 +08:00
|
|
|
p.Skus = append(p.Skus, &SkuInfo{
|
|
|
|
|
ID: s.ID,
|
|
|
|
|
ProductID: s.ProductID,
|
|
|
|
|
Name: s.Name,
|
|
|
|
|
Code: s.Code,
|
|
|
|
|
Price: s.Price,
|
|
|
|
|
CountMin: s.CountMin,
|
|
|
|
|
Discount: s.Discount,
|
|
|
|
|
})
|
2026-04-15 16:56:24 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-18 12:15:30 +08:00
|
|
|
plist := make([]any, 0, len(pmap))
|
|
|
|
|
for _, p := range pmap {
|
|
|
|
|
plist = append(plist, p)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return plist, nil
|
2026-04-14 15:06:08 +08:00
|
|
|
}
|
|
|
|
|
|
2026-03-23 17:50:47 +08:00
|
|
|
// 新增产品
|
|
|
|
|
func (s *productService) CreateProduct(create *CreateProductData) error {
|
|
|
|
|
return q.Product.Create(&m.Product{
|
|
|
|
|
Code: create.Code,
|
|
|
|
|
Name: create.Name,
|
|
|
|
|
Description: create.Description,
|
|
|
|
|
Sort: create.Sort,
|
|
|
|
|
Status: m.ProductStatus(create.Status),
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CreateProductData struct {
|
|
|
|
|
Code string `json:"code"`
|
|
|
|
|
Name string `json:"name"`
|
|
|
|
|
Description *string `json:"description"`
|
|
|
|
|
Sort int32 `json:"sort"`
|
|
|
|
|
Status int `json:"status"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新产品
|
|
|
|
|
func (s *productService) UpdateProduct(update *UpdateProductData) error {
|
|
|
|
|
if update == nil {
|
|
|
|
|
return core.NewBizErr("更新数据不存在")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
do := make([]field.AssignExpr, 0, 5)
|
|
|
|
|
if update.Code != nil {
|
|
|
|
|
do = append(do, q.Product.Code.Value(*update.Code))
|
|
|
|
|
}
|
|
|
|
|
if update.Name != nil {
|
|
|
|
|
do = append(do, q.Product.Name.Value(*update.Name))
|
|
|
|
|
}
|
|
|
|
|
if update.Description != nil {
|
|
|
|
|
do = append(do, q.Product.Description.Value(*update.Description))
|
|
|
|
|
}
|
|
|
|
|
if update.Sort != nil {
|
|
|
|
|
do = append(do, q.Product.Sort.Value(*update.Sort))
|
|
|
|
|
}
|
|
|
|
|
if update.Status != nil {
|
|
|
|
|
do = append(do, q.Product.Status.Value(*update.Status))
|
|
|
|
|
}
|
2026-05-14 14:23:01 +08:00
|
|
|
r, err := q.Product.Where(q.Product.ID.Eq(update.Id)).UpdateSimple(do...)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if r.RowsAffected == 0 {
|
|
|
|
|
return core.NewBizErr("产品状态已过期")
|
|
|
|
|
}
|
|
|
|
|
return nil
|
2026-03-23 17:50:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type UpdateProductData struct {
|
|
|
|
|
Id int32 `json:"id"`
|
|
|
|
|
Code *string `json:"code"`
|
|
|
|
|
Name *string `json:"name"`
|
|
|
|
|
Description *string `json:"description"`
|
|
|
|
|
Sort *int32 `json:"sort"`
|
|
|
|
|
Status *int `json:"status"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除产品
|
|
|
|
|
func (s *productService) DeleteProduct(id int32) error {
|
2026-05-14 14:23:01 +08:00
|
|
|
r, err := q.Product.Where(q.Product.ID.Eq(id)).UpdateColumn(q.Product.DeletedAt, time.Now())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if r.RowsAffected == 0 {
|
|
|
|
|
return core.NewBizErr("产品状态已过期")
|
|
|
|
|
}
|
|
|
|
|
return nil
|
2026-03-23 17:50:47 +08:00
|
|
|
}
|