package handler import ( "dianshang/internal/model" "dianshang/internal/service" "dianshang/pkg/response" "dianshang/pkg/utils" "fmt" "strconv" "strings" "github.com/gin-gonic/gin" ) // AdminProductHandler 管理后台商品处理器 type AdminProductHandler struct { productService *service.ProductService } // NewAdminProductHandler 创建管理后台商品处理器 func NewAdminProductHandler(productService *service.ProductService) *AdminProductHandler { return &AdminProductHandler{ productService: productService, } } // GetProductList 获取商品列表 func (h *AdminProductHandler) GetProductList(c *gin.Context) { page := utils.StringToInt(c.DefaultQuery("page", "1")) pageSize := utils.StringToInt(c.DefaultQuery("page_size", "10")) categoryID := utils.StringToUint(c.Query("category_id")) keyword := c.Query("keyword") status := c.DefaultQuery("status", "all") // 管理系统默认获取所有状态的商品 if page <= 0 { page = 1 } if pageSize <= 0 || pageSize > 100 { pageSize = 10 } // 构建查询条件 minPrice := utils.StringToFloat64(c.Query("min_price")) maxPrice := utils.StringToFloat64(c.Query("max_price")) sort := c.DefaultQuery("sort", "created_at") sortType := c.DefaultQuery("sort_type", "desc") // 获取热门、新品、推荐筛选条件 isHot := c.Query("is_hot") isNew := c.Query("is_new") isRecommend := c.Query("is_recommend") products, pagination, err := h.productService.GetProductListForAdmin(page, pageSize, categoryID, keyword, minPrice, maxPrice, sort, sortType, status, isHot, isNew, isRecommend) if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.PageQuery(c, products, pagination.Total, pagination.Page, pagination.PageSize) } // GetProductDetail 获取商品详情 func (h *AdminProductHandler) GetProductDetail(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的商品ID") return } product, err := h.productService.GetProductDetail(uint(id)) if err != nil { response.ErrorWithMessage(c, response.ERROR, "商品不存在") return } response.Success(c, product) } // CreateProduct 创建商品 func (h *AdminProductHandler) CreateProduct(c *gin.Context) { var product model.Product if err := c.ShouldBindJSON(&product); err != nil { response.BadRequest(c, "请求参数错误") return } // 商品创建时间会自动设置 if err := h.productService.CreateProduct(&product); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, product) } // UpdateProduct 更新商品 func (h *AdminProductHandler) UpdateProduct(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的商品ID") return } var updates map[string]interface{} if err := c.ShouldBindJSON(&updates); err != nil { response.BadRequest(c, "请求参数错误") return } // 处理 category_id 字段:转换为 JSONUintSlice 类型 if categoryIDRaw, ok := updates["category_id"]; ok { switch v := categoryIDRaw.(type) { case []interface{}: var categoryIDs []uint for _, item := range v { switch id := item.(type) { case float64: categoryIDs = append(categoryIDs, uint(id)) case int: categoryIDs = append(categoryIDs, uint(id)) } } updates["category_id"] = model.JSONUintSlice(categoryIDs) case []uint: updates["category_id"] = model.JSONUintSlice(v) } } // 商品更新时间会自动设置 if err := h.productService.UpdateProduct(uint(id), updates); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, nil) } // DeleteProduct 删除商品 func (h *AdminProductHandler) DeleteProduct(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的商品ID") return } if err := h.productService.DeleteProduct(uint(id)); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, nil) } // UpdateStock 更新商品库存 func (h *AdminProductHandler) UpdateStock(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的商品ID") return } var req struct { Quantity int `json:"quantity" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误") return } if err := h.productService.UpdateStock(uint(id), req.Quantity); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, nil) } // BatchUpdateStatus 批量更新商品状态 func (h *AdminProductHandler) BatchUpdateStatus(c *gin.Context) { var req struct { ProductIDs []uint `json:"product_ids" binding:"required"` Status uint8 `json:"status" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误") return } // 批量更新状态 for _, productID := range req.ProductIDs { updates := map[string]interface{}{ "status": req.Status, } if adminID, exists := c.Get("user_id"); exists { updates["updated_by"] = adminID.(uint) } if err := h.productService.UpdateProduct(productID, updates); err != nil { response.ErrorWithMessage(c, response.ERROR, "更新商品状态失败") return } } response.Success(c, nil) } // GetCategories 获取分类列表 func (h *AdminProductHandler) GetCategories(c *gin.Context) { categories, err := h.productService.GetCategories() if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.SuccessWithMessage(c, "", categories) } // CreateCategory 创建分类 func (h *AdminProductHandler) CreateCategory(c *gin.Context) { var category model.Category if err := c.ShouldBindJSON(&category); err != nil { response.BadRequest(c, "请求参数错误") return } // 创建分类 if err := h.productService.CreateCategory(&category); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, category) } // UpdateCategory 更新分类 func (h *AdminProductHandler) UpdateCategory(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的分类ID") return } var updates map[string]interface{} if err := c.ShouldBindJSON(&updates); err != nil { response.BadRequest(c, "请求参数错误") return } // 处理 platform 字段:转换为 JSONSlice 类型 if platformRaw, ok := updates["platform"]; ok { switch v := platformRaw.(type) { case []interface{}: // 前端传来的是数组 var platforms []string for _, item := range v { if str, ok := item.(string); ok { platforms = append(platforms, str) } } updates["platform"] = model.JSONSlice(platforms) case string: // 前端传来的是单个字符串,转为数组 updates["platform"] = model.JSONSlice([]string{v}) default: // 其他类型,删除该字段 delete(updates, "platform") } } // 删除只读字段,避免更新时出错 readonlyFields := []string{"id", "created_at", "updated_at", "children", "hasChildren", "level"} for _, field := range readonlyFields { delete(updates, field) } // 删除不存在的字段 nonExistFields := []string{"is_show", "keywords"} for _, field := range nonExistFields { delete(updates, field) } // 更新分类基本信息 if err := h.productService.UpdateCategory(uint(id), updates); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, nil) } // DeleteCategory 删除分类 func (h *AdminProductHandler) DeleteCategory(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的分类ID") return } if err := h.productService.DeleteCategory(uint(id)); err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, nil) } // GetProductSKUs 获取商品SKU列表 func (h *AdminProductHandler) GetProductSKUs(c *gin.Context) { idStr := c.Param("id") productID, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的商品ID") return } skus, err := h.productService.GetProductSKUs(uint(productID)) if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, skus) } // GetProductReviews 获取商品评价列表 func (h *AdminProductHandler) GetProductReviews(c *gin.Context) { idStr := c.Param("id") productID, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的商品ID") return } page := utils.StringToInt(c.DefaultQuery("page", "1")) pageSize := utils.StringToInt(c.DefaultQuery("page_size", "10")) if page <= 0 { page = 1 } if pageSize <= 0 || pageSize > 100 { pageSize = 10 } reviews, pagination, err := h.productService.GetProductReviews(uint(productID), page, pageSize) if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, gin.H{ "list": reviews, "pagination": pagination, }) } // GetStores 获取店铺列表 func (h *AdminProductHandler) GetStores(c *gin.Context) { stores, err := h.productService.GetStores() if err != nil { response.ErrorWithMessage(c, response.ERROR, err.Error()) return } response.Success(c, stores) } // BatchUpdateProductStatus 批量更新商品状态 func (h *AdminProductHandler) BatchUpdateProductStatus(c *gin.Context) { var req struct { IDs []uint `json:"ids" binding:"required"` Status int `json:"status" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } if err := h.productService.BatchUpdateProductStatus(req.IDs, req.Status); err != nil { c.JSON(500, gin.H{"error": "批量更新商品状态失败"}) return } c.JSON(200, gin.H{"message": "批量更新商品状态成功"}) } // BatchUpdateProductPrice 批量更新商品价格 func (h *AdminProductHandler) BatchUpdateProductPrice(c *gin.Context) { var req struct { Updates []map[string]interface{} `json:"updates" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } if err := h.productService.BatchUpdateProductPrice(req.Updates); err != nil { c.JSON(500, gin.H{"error": "批量更新商品价格失败"}) return } c.JSON(200, gin.H{"message": "批量更新商品价格成功"}) } // BatchDeleteProducts 批量删除商品 func (h *AdminProductHandler) BatchDeleteProducts(c *gin.Context) { var req struct { IDs []uint `json:"ids" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误") return } if err := h.productService.BatchDeleteProducts(req.IDs); err != nil { response.ErrorWithMessage(c, response.ERROR, "批量删除商品失败") return } response.SuccessWithMessage(c, "批量删除商品成功", nil) } // CreateProductSKU 创建商品SKU func (h *AdminProductHandler) CreateProductSKU(c *gin.Context) { var req struct { ProductID uint `json:"product_id" binding:"required"` SpecValues string `json:"spec_values" binding:"required"` Price float64 `json:"price" binding:"required"` OriginalPrice float64 `json:"original_price"` // 划线价 Stock int `json:"stock" binding:"required"` SKUCode string `json:"sku_code" binding:"required"` Image string `json:"image"` Weight float64 `json:"weight"` Volume float64 `json:"volume"` Sort int `json:"sort"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } // 将SpecValues字符串转换为JSONMap specValuesMap := make(model.JSONMap) if req.SpecValues != "" { // 这里简化处理,实际应该解析JSON字符串 specValuesMap["spec"] = req.SpecValues } sku := &model.ProductSKU{ ProductID: req.ProductID, SpecValues: specValuesMap, Price: req.Price, OriginalPrice: req.OriginalPrice, Stock: req.Stock, SKUCode: req.SKUCode, Image: req.Image, Weight: req.Weight, } err := h.productService.CreateProductSKU(sku) if err != nil { c.JSON(500, gin.H{"error": "创建商品SKU失败"}) return } c.JSON(200, gin.H{ "message": "创建商品SKU成功", "data": sku, }) } // UpdateProductSKU 更新商品SKU func (h *AdminProductHandler) UpdateProductSKU(c *gin.Context) { id := c.Param("id") skuID, err := strconv.ParseUint(id, 10, 32) if err != nil { c.JSON(400, gin.H{"error": "无效的SKU ID"}) return } var req struct { SpecValues *string `json:"spec_values"` Price *float64 `json:"price"` OriginalPrice *float64 `json:"original_price"` // 划线价 Stock *int `json:"stock"` SKUCode *string `json:"sku_code"` Image *string `json:"image"` Weight *float64 `json:"weight"` Volume *float64 `json:"volume"` Sort *int `json:"sort"` Status *int `json:"status"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } updates := make(map[string]interface{}) if req.SpecValues != nil { updates["spec_values"] = *req.SpecValues } if req.Price != nil { updates["price"] = *req.Price } if req.OriginalPrice != nil { updates["original_price"] = *req.OriginalPrice } if req.Stock != nil { updates["stock"] = *req.Stock } if req.SKUCode != nil { updates["sku_code"] = *req.SKUCode } if req.Image != nil { updates["image"] = *req.Image } if req.Weight != nil { updates["weight"] = *req.Weight } if req.Status != nil { updates["status"] = *req.Status } if err := h.productService.UpdateProductSKU(uint(skuID), updates); err != nil { c.JSON(500, gin.H{"error": "更新商品SKU失败"}) return } c.JSON(200, gin.H{"message": "更新商品SKU成功"}) } // DeleteProductSKU 删除商品SKU func (h *AdminProductHandler) DeleteProductSKU(c *gin.Context) { id := c.Param("id") skuID, err := strconv.ParseUint(id, 10, 32) if err != nil { c.JSON(400, gin.H{"error": "无效的SKU ID"}) return } if err := h.productService.DeleteProductSKU(uint(skuID)); err != nil { c.JSON(500, gin.H{"error": "删除商品SKU失败"}) return } c.JSON(200, gin.H{"message": "删除商品SKU成功"}) } // GetProductImages 获取商品图片列表 func (h *AdminProductHandler) GetProductImages(c *gin.Context) { id := c.Param("id") productID, err := strconv.ParseUint(id, 10, 32) if err != nil { c.JSON(400, gin.H{"error": "无效的商品ID"}) return } images, err := h.productService.GetProductImages(uint(productID)) if err != nil { c.JSON(500, gin.H{"error": "获取商品图片失败"}) return } c.JSON(200, gin.H{ "message": "获取商品图片成功", "data": images, }) } // CreateProductImage 创建商品图片 func (h *AdminProductHandler) CreateProductImage(c *gin.Context) { var req struct { ProductID uint `json:"product_id" binding:"required"` ImageURL string `json:"image_url" binding:"required"` Sort int `json:"sort"` Type int `json:"type"` // 0:普通图片 1:主图 } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } productImage := &model.ProductImage{ ProductID: req.ProductID, ImageURL: req.ImageURL, Sort: req.Sort, } err := h.productService.CreateProductImage(productImage) if err != nil { c.JSON(500, gin.H{"error": "创建商品图片失败"}) return } c.JSON(200, gin.H{ "message": "创建商品图片成功", "data": productImage, }) } // UpdateProductImageSort 更新商品图片排序 func (h *AdminProductHandler) UpdateProductImageSort(c *gin.Context) { id := c.Param("id") imageID, err := strconv.ParseUint(id, 10, 32) if err != nil { c.JSON(400, gin.H{"error": "无效的图片ID"}) return } var req struct { Sort int `json:"sort" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } if err := h.productService.UpdateProductImageSort(uint(imageID), req.Sort); err != nil { c.JSON(500, gin.H{"error": "更新图片排序失败"}) return } c.JSON(200, gin.H{"message": "更新图片排序成功"}) } // DeleteProductImage 删除商品图片 func (h *AdminProductHandler) DeleteProductImage(c *gin.Context) { id := c.Param("id") imageID, err := strconv.ParseUint(id, 10, 32) if err != nil { c.JSON(400, gin.H{"error": "无效的图片ID"}) return } if err := h.productService.DeleteProductImage(uint(imageID)); err != nil { c.JSON(500, gin.H{"error": "删除商品图片失败"}) return } c.JSON(200, gin.H{"message": "删除商品图片成功"}) } // CreateProductSpec 创建商品规格 func (h *AdminProductHandler) CreateProductSpec(c *gin.Context) { var req struct { ProductID uint `json:"product_id" binding:"required"` Name string `json:"name" binding:"required"` Values string `json:"values" binding:"required"` Sort int `json:"sort"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } productSpec := &model.ProductSpec{ ProductID: req.ProductID, Name: req.Name, Value: req.Values, Sort: req.Sort, } err := h.productService.CreateProductSpec(productSpec) if err != nil { c.JSON(500, gin.H{"error": "创建商品规格失败"}) return } c.JSON(200, gin.H{ "message": "创建商品规格成功", "data": productSpec, }) } // UpdateProductSpec 更新商品规格 func (h *AdminProductHandler) UpdateProductSpec(c *gin.Context) { id := c.Param("id") specID, err := strconv.ParseUint(id, 10, 32) if err != nil { c.JSON(400, gin.H{"error": "无效的规格ID"}) return } var req struct { Name *string `json:"name"` Values *string `json:"values"` Sort *int `json:"sort"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } updates := make(map[string]interface{}) if req.Name != nil { updates["name"] = *req.Name } if req.Values != nil { updates["value"] = *req.Values } if req.Sort != nil { updates["sort"] = *req.Sort } if err := h.productService.UpdateProductSpec(uint(specID), updates); err != nil { c.JSON(500, gin.H{"error": "更新商品规格失败"}) return } c.JSON(200, gin.H{"message": "更新商品规格成功"}) } // DeleteProductSpec 删除商品规格 func (h *AdminProductHandler) DeleteProductSpec(c *gin.Context) { id := c.Param("id") specID, err := strconv.ParseUint(id, 10, 32) if err != nil { c.JSON(400, gin.H{"error": "无效的规格ID"}) return } if err := h.productService.DeleteProductSpec(uint(specID)); err != nil { c.JSON(500, gin.H{"error": "删除商品规格失败"}) return } c.JSON(200, gin.H{"message": "删除商品规格成功"}) } // GetProductSpecs 获取商品规格列表 func (h *AdminProductHandler) GetProductSpecs(c *gin.Context) { id := c.Param("id") productID, err := strconv.ParseUint(id, 10, 32) if err != nil { c.JSON(400, gin.H{"error": "无效的商品ID"}) return } specs, err := h.productService.GetProductSpecs(uint(productID)) if err != nil { c.JSON(500, gin.H{"error": "获取商品规格失败"}) return } c.JSON(200, gin.H{ "message": "获取商品规格成功", "data": specs, }) } // CreateProductTag 创建商品标签 func (h *AdminProductHandler) CreateProductTag(c *gin.Context) { var req struct { Name string `json:"name" binding:"required"` Color string `json:"color"` Sort int `json:"sort"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } productTag := &model.ProductTag{ Name: req.Name, Color: req.Color, Sort: req.Sort, } err := h.productService.CreateProductTag(productTag) if err != nil { c.JSON(500, gin.H{"error": "创建商品标签失败"}) return } c.JSON(200, gin.H{ "message": "创建商品标签成功", "data": productTag, }) } // UpdateProductTag 更新商品标签 func (h *AdminProductHandler) UpdateProductTag(c *gin.Context) { id := c.Param("id") tagID, err := strconv.ParseUint(id, 10, 32) if err != nil { c.JSON(400, gin.H{"error": "无效的标签ID"}) return } var req struct { Name *string `json:"name"` Color *string `json:"color"` Sort *int `json:"sort"` Status *int `json:"status"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } updates := make(map[string]interface{}) if req.Name != nil { updates["name"] = *req.Name } if req.Color != nil { updates["color"] = *req.Color } if req.Sort != nil { updates["sort"] = *req.Sort } if req.Status != nil { updates["status"] = *req.Status } if err := h.productService.UpdateProductTag(uint(tagID), updates); err != nil { c.JSON(500, gin.H{"error": "更新商品标签失败"}) return } c.JSON(200, gin.H{"message": "更新商品标签成功"}) } // DeleteProductTag 删除商品标签 func (h *AdminProductHandler) DeleteProductTag(c *gin.Context) { id := c.Param("id") tagID, err := strconv.ParseUint(id, 10, 32) if err != nil { c.JSON(400, gin.H{"error": "无效的标签ID"}) return } if err := h.productService.DeleteProductTag(uint(tagID)); err != nil { c.JSON(500, gin.H{"error": "删除商品标签失败"}) return } c.JSON(200, gin.H{"message": "删除商品标签成功"}) } // AssignTagsToProduct 为商品分配标签 func (h *AdminProductHandler) AssignTagsToProduct(c *gin.Context) { id := c.Param("id") productID, err := strconv.ParseUint(id, 10, 32) if err != nil { c.JSON(400, gin.H{"error": "无效的商品ID"}) return } var req struct { TagIDs []uint `json:"tag_ids" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } if err := h.productService.AssignTagsToProduct(uint(productID), req.TagIDs); err != nil { c.JSON(500, gin.H{"error": "分配商品标签失败"}) return } c.JSON(200, gin.H{"message": "分配商品标签成功"}) } // GetLowStockProducts 获取低库存商品 func (h *AdminProductHandler) GetLowStockProducts(c *gin.Context) { threshold := 10 // 默认阈值 if t := c.Query("threshold"); t != "" { if th, err := strconv.Atoi(t); err == nil { threshold = th } } products, err := h.productService.GetLowStockProducts(threshold) if err != nil { c.JSON(500, gin.H{"error": "获取低库存商品失败"}) return } c.JSON(200, gin.H{ "message": "获取低库存商品成功", "data": products, }) } // GetInventoryStatistics 获取库存统计 func (h *AdminProductHandler) GetInventoryStatistics(c *gin.Context) { stats, err := h.productService.GetInventoryStatistics() if err != nil { c.JSON(500, gin.H{"error": "获取库存统计失败"}) return } c.JSON(200, gin.H{ "message": "获取库存统计成功", "data": stats, }) } // ExportProducts 导出商品数据 func (h *AdminProductHandler) ExportProducts(c *gin.Context) { // 获取查询条件 conditions := make(map[string]interface{}) if categoryID := c.Query("category_id"); categoryID != "" { if id, err := strconv.ParseUint(categoryID, 10, 32); err == nil { conditions["category_id"] = uint(id) } } if status := c.Query("status"); status != "" { if s, err := strconv.Atoi(status); err == nil { conditions["status"] = s } } if keyword := c.Query("keyword"); keyword != "" { conditions["keyword"] = keyword } // 导出商品数据 products, err := h.productService.ExportProducts(conditions) if err != nil { c.JSON(500, gin.H{"error": "导出商品数据失败"}) return } // TODO: 这里需要实现将products转换为Excel文件并保存的逻辑 // 暂时直接返回产品数据 c.JSON(200, gin.H{ "message": "导出商品数据成功", "data": products, }) } // ImportProducts 导入商品数据 func (h *AdminProductHandler) ImportProducts(c *gin.Context) { file, header, err := c.Request.FormFile("file") if err != nil { c.JSON(400, gin.H{"error": "获取上传文件失败"}) return } defer file.Close() // 检查文件类型 if !strings.HasSuffix(header.Filename, ".xlsx") && !strings.HasSuffix(header.Filename, ".xls") { c.JSON(400, gin.H{"error": "文件格式不支持,请上传Excel文件"}) return } // TODO: 这里需要实现Excel文件解析逻辑,将文件内容解析为[]model.Product // 暂时返回错误,提示功能未实现 c.JSON(500, gin.H{"error": "导入功能暂未实现,需要添加Excel文件解析逻辑"}) } // SyncProductStock 同步单个商品库存 func (h *AdminProductHandler) SyncProductStock(c *gin.Context) { id := c.Param("id") productID, err := strconv.ParseUint(id, 10, 32) if err != nil { c.JSON(400, gin.H{"error": "无效的商品ID"}) return } if err := h.productService.SyncProductStock(uint(productID)); err != nil { c.JSON(500, gin.H{"error": "同步商品库存失败: " + err.Error()}) return } c.JSON(200, gin.H{"message": "同步商品库存成功"}) } // SyncAllProductsStock 同步所有商品库存 func (h *AdminProductHandler) SyncAllProductsStock(c *gin.Context) { if err := h.productService.SyncAllProductsStock(); err != nil { c.JSON(500, gin.H{"error": "同步所有商品库存失败: " + err.Error()}) return } c.JSON(200, gin.H{"message": "同步所有商品库存成功"}) } // BatchUpdateOrigPrice 批量更新SPU划线价 func (h *AdminProductHandler) BatchUpdateOrigPrice(c *gin.Context) { var req struct { Products []struct { ID uint `json:"id" binding:"required"` OrigPrice float64 `json:"orig_price" binding:"required"` } `json:"products" binding:"required,min=1"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误: "+err.Error()) return } // 批量更新 successCount := 0 failedCount := 0 var errors []string for _, item := range req.Products { updates := map[string]interface{}{ "orig_price": item.OrigPrice, } if err := h.productService.UpdateProduct(item.ID, updates); err != nil { failedCount++ errors = append(errors, fmt.Sprintf("商品ID %d 更新失败: %v", item.ID, err)) } else { successCount++ } } response.Success(c, gin.H{ "message": fmt.Sprintf("批量更新完成,成功 %d 个,失败 %d 个", successCount, failedCount), "success_count": successCount, "failed_count": failedCount, "errors": errors, }) } // BatchUpdateSKUOrigPrice 批量更新SKU划线价 func (h *AdminProductHandler) BatchUpdateSKUOrigPrice(c *gin.Context) { var req struct { SKUs []struct { ID uint `json:"id" binding:"required"` OriginalPrice float64 `json:"original_price" binding:"required"` } `json:"skus" binding:"required,min=1"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误: "+err.Error()) return } // 批量更新 successCount := 0 failedCount := 0 var errors []string for _, item := range req.SKUs { updates := map[string]interface{}{ "original_price": item.OriginalPrice, } if err := h.productService.UpdateProductSKU(item.ID, updates); err != nil { failedCount++ errors = append(errors, fmt.Sprintf("SKU ID %d 更新失败: %v", item.ID, err)) } else { successCount++ } } response.Success(c, gin.H{ "message": fmt.Sprintf("批量更新完成,成功 %d 个,失败 %d 个", successCount, failedCount), "success_count": successCount, "failed_count": failedCount, "errors": errors, }) } // UpdateProductOrigPrice 更新单个商品SPU划线价 func (h *AdminProductHandler) UpdateProductOrigPrice(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 32) if err != nil { response.BadRequest(c, "无效的商品ID") return } var req struct { OrigPrice float64 `json:"orig_price" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { response.BadRequest(c, "请求参数错误") return } updates := map[string]interface{}{ "orig_price": req.OrigPrice, } if err := h.productService.UpdateProduct(uint(id), updates); err != nil { response.ErrorWithMessage(c, response.ERROR, "更新划线价失败: "+err.Error()) return } response.SuccessWithMessage(c, "更新划线价成功", nil) }