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) } }