1.0
This commit is contained in:
@@ -0,0 +1,330 @@
|
||||
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))
|
||||
}
|
||||
Reference in New Issue
Block a user