package handlers import ( "awesomeProject/internal/common" "awesomeProject/internal/models" "fmt" "net/http" "strconv" "time" "github.com/gin-gonic/gin" ) // UserProductHandler 用户端商品处理器 type UserProductHandler struct{} // GetHomeData 获取首页数据(轮播图、商品分类和一级商品) func (h *UserProductHandler) GetHomeData(c *gin.Context) { db := common.GetDB() // 获取启用的轮播图,按排序排列 var banners []models.Banner err := db.Where("status = ?", 1).Order("sort_order ASC, created_at DESC").Find(&banners).Error if err != nil { c.JSON(http.StatusOK, common.Error(500, "查询轮播图失败")) return } // 获取启用的商品分类,按排序排列 var categories []models.ProductCategory err = db.Where("status = ?", 1).Order("sort_order ASC, created_at DESC").Find(&categories).Error if err != nil { c.JSON(http.StatusOK, common.Error(500, "查询商品分类失败")) return } // 获取上架的一级商品,按排序排列,限制数量 var primaryProducts []models.PrimaryProduct err = db.Where("status = ?", 1). Preload("Category"). Order("is_hot desc, sort_order ASC, created_at DESC"). Find(&primaryProducts).Error if err != nil { c.JSON(http.StatusOK, common.Error(500, "查询一级商品失败")) return } // 构建返回数据 result := map[string]interface{}{ "banners": banners, "categories": categories, "primary_products": primaryProducts, } c.JSON(http.StatusOK, common.Success(result)) } // GetProductCategories 获取商品分类列表 func (h *UserProductHandler) GetProductCategories(c *gin.Context) { var categories []models.ProductCategory err := common.GetDB().Where("status = ?", 1).Order("sort_order ASC, created_at DESC").Find(&categories).Error if err != nil { c.JSON(http.StatusOK, common.Error(500, "查询商品分类失败")) return } c.JSON(http.StatusOK, common.Success(categories)) } // GetPrimaryProducts 获取一级商品列表 func (h *UserProductHandler) GetPrimaryProducts(c *gin.Context) { // 分页参数 page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10")) if page < 1 { page = 1 } if pageSize < 1 || pageSize > 50 { pageSize = 10 } // 搜索参数 categoryID := c.Query("category_id") productName := c.Query("product_name") sortType := c.DefaultQuery("sort", "default") // default, price_asc, price_desc, sales, views db := common.GetDB() var products []models.PrimaryProduct var total int64 // 构建查询条件 - 只查询上架商品 query := db.Model(&models.PrimaryProduct{}).Where("status = ?", 1).Preload("Category") // 添加搜索条件 if categoryID != "" { query = query.Where("category_id = ?", categoryID) } if productName != "" { query = query.Where("product_name LIKE ?", "%"+productName+"%") } // 获取总数 query.Count(&total) // 排序 switch sortType { case "price_asc": query = query.Order("current_price ASC") case "price_desc": query = query.Order("current_price DESC") case "sales": query = query.Order("sales_count DESC") case "views": query = query.Order("view_count DESC") default: query = query.Order("sort_order ASC, created_at DESC") } // 分页查询 offset := (page - 1) * pageSize err := query.Offset(offset).Limit(pageSize).Find(&products).Error if err != nil { c.JSON(http.StatusOK, common.Error(500, "查询商品列表失败")) return } // 构建返回数据 result := map[string]interface{}{ "list": products, "total": total, "page": page, "page_size": pageSize, } c.JSON(http.StatusOK, common.Success(result)) } // GetPrimaryProduct 获取一级商品详情 func (h *UserProductHandler) GetPrimaryProduct(c *gin.Context) { productID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { c.JSON(http.StatusOK, common.Error(400, "商品ID无效")) return } var product models.PrimaryProduct err = common.GetDB().Where("status = ?", 1).Preload("Category").First(&product, uint(productID)).Error if err != nil { c.JSON(http.StatusOK, common.Error(404, "商品不存在或已下架")) return } // 增加浏览量 common.GetDB().Model(&product).UpdateColumn("view_count", product.ViewCount+1) c.JSON(http.StatusOK, common.Success(product)) } // GetSecondaryProducts 获取二级商品列表(用户挂售的商品) func (h *UserProductHandler) GetSecondaryProducts(c *gin.Context) { // 分页参数 page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10")) if page < 1 { page = 1 } if pageSize < 1 || pageSize > 50 { pageSize = 10 } // 搜索参数 productName := c.Query("product_name") sortType := c.DefaultQuery("sort", "default") // default, price_asc, price_desc, views categoryId, _ := strconv.Atoi(c.DefaultQuery("category_id", "0")) // 地址筛选参数 province := c.Query("province") city := c.Query("city") district := c.Query("district") db := common.GetDB() var products []models.SecondaryProduct var total int64 // 构建查询条件 - 只查询上架商品,并预加载卖家信息 query := db.Model(&models.SecondaryProduct{}).Where("status = ? and quantity>0", 1). Preload("Seller") // 添加商品名称搜索条件 if productName != "" { query = query.Where("product_name LIKE ?", "%"+productName+"%") } // 添加分类筛选条件 if categoryId > 0 { query = query.Where("category_id = ?", categoryId) } // 添加地址筛选条件 - 根据卖家的默认地址筛选 if province != "" || city != "" || district != "" { // 子查询获取符合地址条件的用户ID subQuery := db.Model(&models.UserAddress{}). Select("user_id"). Where("is_default = ?", 1) if province != "" { subQuery = subQuery.Where("province = ?", province) } if city != "" { subQuery = subQuery.Where("city = ?", city) } if district != "" { subQuery = subQuery.Where("district = ?", district) } query = query.Where("seller_id IN (?)", subQuery) } // 获取总数 query.Count(&total) // 排序 switch sortType { case "price": query = query.Order("selling_price ASC") case "price_desc": query = query.Order("selling_price DESC") case "view": query = query.Order("view_count DESC") case "sales": query = query.Order("sales_count DESC") case "quantity": query = query.Order("quantity DESC") default: query = query.Order("created_at DESC") } // 分页查询 offset := (page - 1) * pageSize err := query.Offset(offset).Limit(pageSize).Find(&products).Error if err != nil { c.JSON(http.StatusOK, common.Error(500, "查询商品列表失败")) return } // 获取当前用户信息 currentUser, exists := c.Get("current_user") var userID uint if exists { user := currentUser.(models.User) userID = user.ID } // 获取系统配置limit_days var config models.SystemConfig db.Where("config_key=?", "limit_days").First(&config) limitDays, _ := strconv.Atoi(config.ConfigValue) // 为每个商品添加购买限制检查 type ProductWithPurchaseLimit struct { models.SecondaryProduct CanPurchase bool `json:"can_purchase"` PurchaseLimitMessage string `json:"purchase_limit_message"` } productList := make([]ProductWithPurchaseLimit, 0, len(products)) for _, product := range products { productWithLimit := ProductWithPurchaseLimit{ SecondaryProduct: product, CanPurchase: true, PurchaseLimitMessage: "", } // 如果用户已登录,检查购买限制 if exists && userID > 0 { // 检查是否是自己的商品 if product.SellerID == userID { productWithLimit.CanPurchase = false productWithLimit.PurchaseLimitMessage = "不能购买自己的商品" } else if limitDays > 0 { // 检查是否在限制天数内已经购买过该卖家的商品 limitDaysAgo := time.Now().AddDate(0, 0, -limitDays) var existingOrderCount int64 db.Model(&models.PurchaseOrder{}).Where( "buyer_id = ? AND seller_id = ? AND product_type = 2 AND created_at > ? AND order_status != 3", userID, product.SellerID, limitDaysAgo, ).Count(&existingOrderCount) if existingOrderCount > 0 { productWithLimit.CanPurchase = false productWithLimit.PurchaseLimitMessage = fmt.Sprintf("%v天内只能向同一个卖家购买一次商品", limitDays) } } } productList = append(productList, productWithLimit) } // 构建返回数据 result := map[string]interface{}{ "list": productList, "total": total, "page": page, "page_size": pageSize, } c.JSON(http.StatusOK, common.Success(result)) } // GetSecondaryProduct 获取二级商品详情 func (h *UserProductHandler) GetSecondaryProduct(c *gin.Context) { productID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { c.JSON(http.StatusOK, common.Error(400, "商品ID无效")) return } var product models.SecondaryProduct err = common.GetDB().Where("status = ?", 1).Preload("Seller").First(&product, uint(productID)).Error if err != nil { c.JSON(http.StatusOK, common.Error(404, "商品不存在或已下架")) return } // 增加浏览量 common.GetDB().Model(&product).UpdateColumn("view_count", product.ViewCount+1) c.JSON(http.StatusOK, common.Success(product)) }