产品套餐状态管理

This commit is contained in:
2026-04-07 13:22:37 +08:00
parent 62c624c88e
commit c684523cb8
8 changed files with 52 additions and 5 deletions

View File

@@ -757,6 +757,7 @@ create table product_sku (
code text not null unique,
name text not null,
price decimal not null,
status int not null default 1,
created_at timestamptz default current_timestamp,
updated_at timestamptz default current_timestamp,
deleted_at timestamptz
@@ -773,6 +774,7 @@ comment on column product_sku.discount_id is '折扣ID';
comment on column product_sku.code is 'SKU 代码:格式为 key=value,key=value,...其中key:value 是 SKU 的属性,多个属性用逗号分隔';
comment on column product_sku.name is 'SKU 可读名称';
comment on column product_sku.price is '定价';
comment on column product_sku.status is 'SKU状态0-禁用1-正常';
comment on column product_sku.created_at is '创建时间';
comment on column product_sku.updated_at is '更新时间';
comment on column product_sku.deleted_at is '删除时间';

View File

@@ -17,9 +17,10 @@ const (
ScopeProductRead = string("product:read") // 读取产品列表
ScopeProductWrite = string("product:write") // 写入产品
ScopeProductSku = string("product_sku") // 产品套餐
ScopeProductSkuRead = string("product_sku:read") // 读取产品套餐列表
ScopeProductSkuWrite = string("product_sku:write") // 写入产品套餐
ScopeProductSku = string("product_sku") // 产品套餐
ScopeProductSkuRead = string("product_sku:read") // 读取产品套餐列表
ScopeProductSkuWrite = string("product_sku:write") // 写入产品套餐
ScopeProductSkuWriteStatus = string("product_sku:write:status") // 更改产品套餐状态
ScopeDiscount = string("discount") // 折扣
ScopeDiscountRead = string("discount:read") // 读取折扣列表

View File

@@ -181,6 +181,32 @@ func UpdateProductSku(c *fiber.Ctx) error {
return nil
}
func UpdateProductStatusSku(c *fiber.Ctx) error {
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuWrite)
if err != nil {
return err
}
type Params struct {
ID int32 `json:"id"`
Status int32 `json:"status"`
}
var req Params
if err := g.Validator.ParseBody(c, &req); err != nil {
return err
}
err = s.ProductSku.Update(s.UpdateProductSkuData{
ID: req.ID,
Status: &req.Status,
})
if err != nil {
return err
}
return nil
}
func BatchUpdateProductSkuDiscount(c *fiber.Ctx) error {
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuWrite)
if err != nil {

View File

@@ -14,7 +14,16 @@ type ProductSku struct {
Code string `json:"code" gorm:"column:code"` // SSKU 代码:格式为 key=value,key=value,...其中key:value 是 SKU 的属性,多个属性用逗号分隔
Name string `json:"name" gorm:"column:name"` // SKU 可读名称
Price decimal.Decimal `json:"price" gorm:"column:price"` // 定价
Status SkuStatus `json:"status" gorm:"column:status"` // SKU 状态0-禁用1-正常
Product *Product `json:"product,omitempty" gorm:"foreignKey:ProductID"`
Discount *ProductDiscount `json:"discount,omitempty" gorm:"foreignKey:DiscountId"`
}
// SkuStatus SKU 状态
type SkuStatus int32
const (
SkuStatusDisabled SkuStatus = 0 // 禁用
SkuStatusEnabled SkuStatus = 1 // 正常
)

View File

@@ -36,6 +36,7 @@ func newProductSku(db *gorm.DB, opts ...gen.DOOption) productSku {
_productSku.Code = field.NewString(tableName, "code")
_productSku.Name = field.NewString(tableName, "name")
_productSku.Price = field.NewField(tableName, "price")
_productSku.Status = field.NewInt32(tableName, "status")
_productSku.Product = productSkuBelongsToProduct{
db: db.Session(&gorm.Session{}),
@@ -66,6 +67,7 @@ type productSku struct {
Code field.String
Name field.String
Price field.Field
Status field.Int32
Product productSkuBelongsToProduct
Discount productSkuBelongsToDiscount
@@ -94,6 +96,7 @@ func (p *productSku) updateTableName(table string) *productSku {
p.Code = field.NewString(table, "code")
p.Name = field.NewString(table, "name")
p.Price = field.NewField(table, "price")
p.Status = field.NewInt32(table, "status")
p.fillFieldMap()
@@ -110,7 +113,7 @@ func (p *productSku) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (p *productSku) fillFieldMap() {
p.fieldMap = make(map[string]field.Expr, 11)
p.fieldMap = make(map[string]field.Expr, 12)
p.fieldMap["id"] = p.ID
p.fieldMap["created_at"] = p.CreatedAt
p.fieldMap["updated_at"] = p.UpdatedAt
@@ -120,6 +123,7 @@ func (p *productSku) fillFieldMap() {
p.fieldMap["code"] = p.Code
p.fieldMap["name"] = p.Name
p.fieldMap["price"] = p.Price
p.fieldMap["status"] = p.Status
}

View File

@@ -200,6 +200,7 @@ func adminRouter(api fiber.Router) {
product.Post("/sku/page", handlers.PageProductSkuByAdmin)
product.Post("/sku/create", handlers.CreateProductSku)
product.Post("/sku/update", handlers.UpdateProductSku)
product.Post("/sku/update/status", handlers.UpdateProductStatusSku)
product.Post("/sku/remove", handlers.DeleteProductSku)
product.Post("/sku/update/discount/batch", handlers.BatchUpdateProductSkuDiscount)

View File

@@ -78,6 +78,9 @@ func (s *productSkuService) Update(update UpdateProductSkuData) (err error) {
if update.Name != nil {
do = append(do, q.ProductSku.Name.Value(*update.Name))
}
if update.Status != nil {
do = append(do, q.ProductSku.Status.Value(*update.Status))
}
_, err = q.ProductSku.Where(q.ProductSku.ID.Eq(update.ID)).UpdateSimple(do...)
return err
@@ -89,6 +92,7 @@ type UpdateProductSkuData struct {
Code *string `json:"code"`
Name *string `json:"name"`
Price *string `json:"price"`
Status *int32 `json:"status"`
}
func (s *productSkuService) Delete(id int32) (err error) {

View File

@@ -148,7 +148,7 @@ func (s *resourceService) CalcPrice(skuCode string, count int32, user *m.User, c
sku, err := q.ProductSku.
Joins(q.ProductSku.Discount).
Where(q.ProductSku.Code.Eq(skuCode)).
Where(q.ProductSku.Code.Eq(skuCode), q.ProductSku.Status.Eq(int32(m.SkuStatusEnabled))).
Take()
if err != nil {
return nil, nil, nil, decimal.Zero, decimal.Zero, core.NewServErr("产品不可用", err)