Files
ai_dianshang/server/internal/handler/product.go

366 lines
9.5 KiB
Go
Raw Normal View History

2025-11-17 13:32:54 +08:00
package handler
import (
"dianshang/internal/model"
"dianshang/internal/service"
"dianshang/pkg/response"
"dianshang/pkg/utils"
"strconv"
"github.com/gin-gonic/gin"
)
// ProductHandler 浜у搧澶勭悊鍣?
type ProductHandler struct {
productService *service.ProductService
}
// NewProductHandler 鍒涘缓浜у搧澶勭悊鍣?
func NewProductHandler(productService *service.ProductService) *ProductHandler {
return &ProductHandler{
productService: productService,
}
}
// GetProductList 鑾峰彇浜у搧鍒楄〃
func (h *ProductHandler) GetProductList(c *gin.Context) {
page := utils.StringToInt(c.DefaultQuery("page", "1"))
pageSize := utils.StringToInt(c.DefaultQuery("page_size", "20"))
categoryID := utils.StringToUint(c.Query("category_id"))
keyword := c.Query("keyword")
minPrice, _ := strconv.ParseFloat(c.Query("min_price"), 64)
maxPrice, _ := strconv.ParseFloat(c.Query("max_price"), 64)
// 处理排序参数:将前端传递的数字参数转换为后端期望的字符串参数
sortParam := c.Query("sort")
sortTypeParam := c.Query("sortType")
var sort, sortType string
// 如果sort=1表示按价格排序
if sortParam == "1" {
sort = "price"
// sortType: 0=升序(asc), 1=降序(desc)
if sortTypeParam == "0" {
sortType = "asc"
} else {
sortType = "desc"
}
} else {
// 默认排序或其他排序方式
sort = "default"
sortType = "desc"
}
products, pagination, err := h.productService.GetProductList(page, pageSize, categoryID, keyword, minPrice, maxPrice, sort, sortType)
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Page(c, products, pagination.Total, pagination.Page, pagination.PageSize)
}
// GetProductDetail 鑾峰彇浜у搧璇︽儏
func (h *ProductHandler) GetProductDetail(c *gin.Context) {
idStr := c.Param("id")
id := utils.StringToUint(idStr)
if id == 0 {
response.BadRequest(c, "鏃犳晥鐨勪骇鍝両D")
return
}
product, err := h.productService.GetProductDetail(id)
if err != nil {
response.ErrorWithMessage(c, response.ERROR_PRODUCT_NOT_FOUND, "产品不存在")
return
}
response.Success(c, product)
}
// CreateProduct 鍒涘缓浜у搧
func (h *ProductHandler) CreateProduct(c *gin.Context) {
var product model.Product
if err := c.ShouldBindJSON(&product); err != nil {
response.BadRequest(c, "鍙傛暟閿欒: "+err.Error())
return
}
if err := h.productService.CreateProduct(&product); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, product)
}
// UpdateProduct 鏇存柊浜у搧
func (h *ProductHandler) UpdateProduct(c *gin.Context) {
idStr := c.Param("id")
id := utils.StringToUint(idStr)
if id == 0 {
response.BadRequest(c, "鏃犳晥鐨勪骇鍝両D")
return
}
var updates map[string]interface{}
if err := c.ShouldBindJSON(&updates); err != nil {
response.BadRequest(c, "鍙傛暟閿欒: "+err.Error())
return
}
if err := h.productService.UpdateProduct(id, updates); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// DeleteProduct 鍒犻櫎浜у搧
func (h *ProductHandler) DeleteProduct(c *gin.Context) {
idStr := c.Param("id")
id := utils.StringToUint(idStr)
if id == 0 {
response.BadRequest(c, "鏃犳晥鐨勪骇鍝両D")
return
}
if err := h.productService.DeleteProduct(id); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// GetCategories 鑾峰彇鍒嗙被鍒楄〃
func (h *ProductHandler) GetCategories(c *gin.Context) {
categories, err := h.productService.GetCategories()
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, categories)
}
// CreateCategory 鍒涘缓鍒嗙被
func (h *ProductHandler) CreateCategory(c *gin.Context) {
var category model.Category
if err := c.ShouldBindJSON(&category); err != nil {
response.BadRequest(c, "鍙傛暟閿欒: "+err.Error())
return
}
if err := h.productService.CreateCategory(&category); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, category)
}
// UpdateCategory 鏇存柊鍒嗙被
func (h *ProductHandler) UpdateCategory(c *gin.Context) {
idStr := c.Param("id")
id := utils.StringToUint(idStr)
if id == 0 {
response.BadRequest(c, "鏃犳晥鐨勫垎绫籌D")
return
}
var updates map[string]interface{}
if err := c.ShouldBindJSON(&updates); err != nil {
response.BadRequest(c, "鍙傛暟閿欒: "+err.Error())
return
}
if err := h.productService.UpdateCategory(id, updates); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// DeleteCategory 鍒犻櫎鍒嗙被
func (h *ProductHandler) DeleteCategory(c *gin.Context) {
idStr := c.Param("id")
id := utils.StringToUint(idStr)
if id == 0 {
response.BadRequest(c, "鏃犳晥鐨勫垎绫籌D")
return
}
if err := h.productService.DeleteCategory(id); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, nil)
}
// GetProductReviews 鑾峰彇浜у搧璇勪环鍒楄〃
func (h *ProductHandler) GetProductReviews(c *gin.Context) {
idStr := c.Param("id")
productID := utils.StringToUint(idStr)
if productID == 0 {
response.BadRequest(c, "鏃犳晥鐨勪骇鍝両D")
return
}
page := utils.StringToInt(c.DefaultQuery("page", "1"))
pageSize := utils.StringToInt(c.DefaultQuery("page_size", "20"))
reviews, pagination, err := h.productService.GetProductReviews(productID, page, pageSize)
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Page(c, reviews, pagination.Total, pagination.Page, pagination.PageSize)
}
// CreateReview 鍒涘缓璇勪环
func (h *ProductHandler) CreateReview(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
response.Unauthorized(c)
return
}
var review model.ProductReview
if err := c.ShouldBindJSON(&review); err != nil {
response.BadRequest(c, "鍙傛暟閿欒: "+err.Error())
return
}
if err := h.productService.CreateReview(userID.(uint), &review); err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, review)
}
// SearchProducts 鎼滅储浜у搧
func (h *ProductHandler) SearchProducts(c *gin.Context) {
keyword := c.Query("keyword")
if keyword == "" {
response.BadRequest(c, "璇疯緭鍏ユ悳绱㈠叧閿瘝")
return
}
page := utils.StringToInt(c.DefaultQuery("page", "1"))
pageSize := utils.StringToInt(c.DefaultQuery("page_size", "20"))
// 价格筛选(后端以“元”存储,参数按“元”传递)
minPrice := utils.StringToFloat64(c.Query("min_price"))
maxPrice := utils.StringToFloat64(c.Query("max_price"))
// 排序参数(搜索页使用 sort_by / sort_order
sort := c.DefaultQuery("sort_by", "default")
sortType := c.DefaultQuery("sort_order", "desc")
// 兼容其它命名(若存在)
if s := c.Query("sort"); s != "" {
sort = s
}
if st := c.Query("sortType"); st != "" {
sortType = st
}
products, pagination, err := h.productService.SearchProducts(keyword, page, pageSize, minPrice, maxPrice, sort, sortType)
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Page(c, products, pagination.Total, pagination.Page, pagination.PageSize)
}
// GetHotProducts 鑾峰彇鐑棬浜у搧
func (h *ProductHandler) GetHotProducts(c *gin.Context) {
limit := utils.StringToInt(c.DefaultQuery("limit", "10"))
products, err := h.productService.GetHotProducts(limit)
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, products)
}
// GetRecommendProducts 获取推荐产品
func (h *ProductHandler) GetRecommendProducts(c *gin.Context) {
limit := utils.StringToInt(c.DefaultQuery("limit", "10"))
products, err := h.productService.GetRecommendProducts(limit)
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, products)
}
// GetProductSKUs 获取产品SKU列表
func (h *ProductHandler) GetProductSKUs(c *gin.Context) {
idStr := c.Param("id")
productID := utils.StringToUint(idStr)
if productID == 0 {
response.BadRequest(c, "无效的产品ID")
return
}
skus, err := h.productService.GetProductSKUs(productID)
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, skus)
}
// GetProductTags 获取产品标签列表
func (h *ProductHandler) GetProductTags(c *gin.Context) {
tags, err := h.productService.GetProductTags()
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, tags)
}
// GetStores 获取店铺列表
func (h *ProductHandler) GetStores(c *gin.Context) {
stores, err := h.productService.GetStores()
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, stores)
}
// GetProductReviewCount 获取产品评价统计
func (h *ProductHandler) GetProductReviewCount(c *gin.Context) {
idStr := c.Param("id")
productID := utils.StringToUint(idStr)
if productID == 0 {
response.BadRequest(c, "无效的产品ID")
return
}
reviewCount, err := h.productService.GetProductReviewCount(productID)
if err != nil {
response.ErrorWithMessage(c, response.ERROR, err.Error())
return
}
response.Success(c, reviewCount)
}