产品套餐状态管理

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, code text not null unique,
name text not null, name text not null,
price decimal not null, price decimal not null,
status int not null default 1,
created_at timestamptz default current_timestamp, created_at timestamptz default current_timestamp,
updated_at timestamptz default current_timestamp, updated_at timestamptz default current_timestamp,
deleted_at timestamptz 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.code is 'SKU 代码:格式为 key=value,key=value,...其中key:value 是 SKU 的属性,多个属性用逗号分隔';
comment on column product_sku.name is 'SKU 可读名称'; comment on column product_sku.name is 'SKU 可读名称';
comment on column product_sku.price is '定价'; 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.created_at is '创建时间';
comment on column product_sku.updated_at is '更新时间'; comment on column product_sku.updated_at is '更新时间';
comment on column product_sku.deleted_at is '删除时间'; comment on column product_sku.deleted_at is '删除时间';

View File

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

View File

@@ -181,6 +181,32 @@ func UpdateProductSku(c *fiber.Ctx) error {
return nil 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 { func BatchUpdateProductSkuDiscount(c *fiber.Ctx) error {
_, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuWrite) _, err := auth.GetAuthCtx(c).PermitAdmin(core.ScopeProductSkuWrite)
if err != nil { 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 的属性,多个属性用逗号分隔 Code string `json:"code" gorm:"column:code"` // SSKU 代码:格式为 key=value,key=value,...其中key:value 是 SKU 的属性,多个属性用逗号分隔
Name string `json:"name" gorm:"column:name"` // SKU 可读名称 Name string `json:"name" gorm:"column:name"` // SKU 可读名称
Price decimal.Decimal `json:"price" gorm:"column:price"` // 定价 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"` Product *Product `json:"product,omitempty" gorm:"foreignKey:ProductID"`
Discount *ProductDiscount `json:"discount,omitempty" gorm:"foreignKey:DiscountId"` 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.Code = field.NewString(tableName, "code")
_productSku.Name = field.NewString(tableName, "name") _productSku.Name = field.NewString(tableName, "name")
_productSku.Price = field.NewField(tableName, "price") _productSku.Price = field.NewField(tableName, "price")
_productSku.Status = field.NewInt32(tableName, "status")
_productSku.Product = productSkuBelongsToProduct{ _productSku.Product = productSkuBelongsToProduct{
db: db.Session(&gorm.Session{}), db: db.Session(&gorm.Session{}),
@@ -66,6 +67,7 @@ type productSku struct {
Code field.String Code field.String
Name field.String Name field.String
Price field.Field Price field.Field
Status field.Int32
Product productSkuBelongsToProduct Product productSkuBelongsToProduct
Discount productSkuBelongsToDiscount Discount productSkuBelongsToDiscount
@@ -94,6 +96,7 @@ func (p *productSku) updateTableName(table string) *productSku {
p.Code = field.NewString(table, "code") p.Code = field.NewString(table, "code")
p.Name = field.NewString(table, "name") p.Name = field.NewString(table, "name")
p.Price = field.NewField(table, "price") p.Price = field.NewField(table, "price")
p.Status = field.NewInt32(table, "status")
p.fillFieldMap() p.fillFieldMap()
@@ -110,7 +113,7 @@ func (p *productSku) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
} }
func (p *productSku) fillFieldMap() { 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["id"] = p.ID
p.fieldMap["created_at"] = p.CreatedAt p.fieldMap["created_at"] = p.CreatedAt
p.fieldMap["updated_at"] = p.UpdatedAt p.fieldMap["updated_at"] = p.UpdatedAt
@@ -120,6 +123,7 @@ func (p *productSku) fillFieldMap() {
p.fieldMap["code"] = p.Code p.fieldMap["code"] = p.Code
p.fieldMap["name"] = p.Name p.fieldMap["name"] = p.Name
p.fieldMap["price"] = p.Price 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/page", handlers.PageProductSkuByAdmin)
product.Post("/sku/create", handlers.CreateProductSku) product.Post("/sku/create", handlers.CreateProductSku)
product.Post("/sku/update", handlers.UpdateProductSku) product.Post("/sku/update", handlers.UpdateProductSku)
product.Post("/sku/update/status", handlers.UpdateProductStatusSku)
product.Post("/sku/remove", handlers.DeleteProductSku) product.Post("/sku/remove", handlers.DeleteProductSku)
product.Post("/sku/update/discount/batch", handlers.BatchUpdateProductSkuDiscount) 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 { if update.Name != nil {
do = append(do, q.ProductSku.Name.Value(*update.Name)) 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...) _, err = q.ProductSku.Where(q.ProductSku.ID.Eq(update.ID)).UpdateSimple(do...)
return err return err
@@ -89,6 +92,7 @@ type UpdateProductSkuData struct {
Code *string `json:"code"` Code *string `json:"code"`
Name *string `json:"name"` Name *string `json:"name"`
Price *string `json:"price"` Price *string `json:"price"`
Status *int32 `json:"status"`
} }
func (s *productSkuService) Delete(id int32) (err error) { 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. sku, err := q.ProductSku.
Joins(q.ProductSku.Discount). Joins(q.ProductSku.Discount).
Where(q.ProductSku.Code.Eq(skuCode)). Where(q.ProductSku.Code.Eq(skuCode), q.ProductSku.Status.Eq(int32(m.SkuStatusEnabled))).
Take() Take()
if err != nil { if err != nil {
return nil, nil, nil, decimal.Zero, decimal.Zero, core.NewServErr("产品不可用", err) return nil, nil, nil, decimal.Zero, decimal.Zero, core.NewServErr("产品不可用", err)