bindbox-game/internal/api/admin/product_create.go
邹方成 425e64daa5 refactor: 优化订单时间字段处理及数据库模型结构调整
- 将订单的PaidAt和CancelledAt从指针类型改为值类型
- 统一时间字段的判空逻辑,使用IsZero()替代nil检查
- 调整多个数据库模型结构,添加新字段并优化字段顺序
- 为活动奖励设置、用户邀请等表添加新字段
- 更新对应的DAO层代码以匹配模型变更
2025-12-23 23:37:59 +08:00

192 lines
6.6 KiB
Go

package admin
import (
"net/http"
"strconv"
"bindbox-game/internal/code"
"bindbox-game/internal/pkg/core"
"bindbox-game/internal/pkg/validation"
prodsvc "bindbox-game/internal/service/product"
)
type createProductRequest struct {
Name string `json:"name" binding:"required"`
CategoryID int64 `json:"category_id" binding:"required"`
ImagesJSON string `json:"images_json"`
Price int64 `json:"price" binding:"required"`
Stock int64 `json:"stock" binding:"required"`
Status int32 `json:"status"`
Description string `json:"description"`
}
type createProductResponse struct {
ID int64 `json:"id"`
Message string `json:"message"`
}
// CreateProduct 创建商品
// @Summary 创建商品
// @Tags 管理端.商品
// @Accept json
// @Produce json
// @Param RequestBody body createProductRequest true "请求参数"
// @Success 200 {object} createProductResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/products [post]
// @Security LoginVerifyToken
func (h *handler) CreateProduct() core.HandlerFunc {
return func(ctx core.Context) {
req := new(createProductRequest)
res := new(createProductResponse)
if err := ctx.ShouldBindJSON(req); err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
return
}
if ctx.SessionUserInfo().IsSuper != 1 {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作"))
return
}
item, err := h.product.CreateProduct(ctx.RequestContext(), prodsvc.CreateProductInput{Name: req.Name, CategoryID: req.CategoryID, ImagesJSON: req.ImagesJSON, Price: req.Price, Stock: req.Stock, Status: req.Status, Description: req.Description})
if err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error()))
return
}
res.ID = item.ID
res.Message = "操作成功"
ctx.Payload(res)
}
}
type modifyProductRequest struct {
Name *string `json:"name"`
CategoryID *int64 `json:"category_id"`
ImagesJSON *string `json:"images_json"`
Price *int64 `json:"price"`
Stock *int64 `json:"stock"`
Status *int32 `json:"status"`
Description *string `json:"description"`
}
// ModifyProduct 修改商品
// @Summary 修改商品
// @Tags 管理端.商品
// @Accept json
// @Produce json
// @Param product_id path string true "商品ID"
// @Param RequestBody body modifyProductRequest true "请求参数"
// @Success 200 {object} pcSimpleMessage
// @Failure 400 {object} code.Failure
// @Router /api/admin/products/{product_id} [put]
// @Security LoginVerifyToken
func (h *handler) ModifyProduct() core.HandlerFunc {
return func(ctx core.Context) {
req := new(modifyProductRequest)
if err := ctx.ShouldBindJSON(req); err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
return
}
idStr := ctx.Param("product_id")
id, _ := strconv.ParseInt(idStr, 10, 64)
if ctx.SessionUserInfo().IsSuper != 1 {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作"))
return
}
if err := h.product.ModifyProduct(ctx.RequestContext(), id, prodsvc.ModifyProductInput{Name: req.Name, CategoryID: req.CategoryID, ImagesJSON: req.ImagesJSON, Price: req.Price, Stock: req.Stock, Status: req.Status, Description: req.Description}); err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error()))
return
}
ctx.Payload(pcSimpleMessage{Message: "操作成功"})
}
}
// DeleteProduct 删除商品
// @Summary 删除商品
// @Tags 管理端.商品
// @Accept json
// @Produce json
// @Param product_id path string true "商品ID"
// @Success 200 {object} pcSimpleMessage
// @Failure 400 {object} code.Failure
// @Router /api/admin/products/{product_id} [delete]
// @Security LoginVerifyToken
func (h *handler) DeleteProduct() core.HandlerFunc {
return func(ctx core.Context) {
idStr := ctx.Param("product_id")
id, _ := strconv.ParseInt(idStr, 10, 64)
if ctx.SessionUserInfo().IsSuper != 1 {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, "禁止操作"))
return
}
if err := h.product.DeleteProduct(ctx.RequestContext(), id); err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error()))
return
}
ctx.Payload(pcSimpleMessage{Message: "操作成功"})
}
}
type listProductsRequest struct {
Name string `form:"name"`
CategoryID *int64 `form:"category_id"`
Status *int32 `form:"status"`
Page int `form:"page"`
PageSize int `form:"page_size"`
}
type productItem struct {
ID int64 `json:"id"`
Name string `json:"name"`
CategoryID int64 `json:"category_id"`
ImagesJSON string `json:"images_json"`
Price int64 `json:"price"`
Stock int64 `json:"stock"`
Sales int64 `json:"sales"`
Status int32 `json:"status"`
Description string `json:"description"`
}
type listProductsResponse struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
Total int64 `json:"total"`
List []productItem `json:"list"`
}
// ListProducts 查看商品列表
// @Summary 查看商品列表
// @Tags 管理端.商品
// @Accept json
// @Produce json
// @Param name query string false "名称"
// @Param category_id query int false "分类ID"
// @Param status query int false "状态"
// @Param page query int true "页码" default(1)
// @Param page_size query int true "每页数量" default(20)
// @Success 200 {object} listProductsResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/products [get]
// @Security LoginVerifyToken
func (h *handler) ListProducts() core.HandlerFunc {
return func(ctx core.Context) {
req := new(listProductsRequest)
res := new(listProductsResponse)
if err := ctx.ShouldBindForm(req); err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
return
}
items, total, err := h.product.ListProducts(ctx.RequestContext(), prodsvc.ListProductsInput{Name: req.Name, CategoryID: req.CategoryID, Status: req.Status, Page: req.Page, PageSize: req.PageSize})
if err != nil {
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.CreateAdminError, err.Error()))
return
}
res.Page = req.Page
res.PageSize = req.PageSize
res.Total = total
res.List = make([]productItem, len(items))
for i, it := range items {
res.List[i] = productItem{ID: it.ID, Name: it.Name, CategoryID: it.CategoryID, ImagesJSON: it.ImagesJSON, Price: it.Price, Stock: it.Stock, Sales: it.Sales, Status: it.Status, Description: it.Description}
}
ctx.Payload(res)
}
}