512 lines
15 KiB
Go
512 lines
15 KiB
Go
package handlers
|
|
|
|
import (
|
|
"awesomeProject/internal/common"
|
|
"awesomeProject/internal/models"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// AdminProductHandler 管理端商品处理器
|
|
type AdminProductHandler struct{}
|
|
|
|
// CreateProductCategoryRequest 创建商品分类请求结构体
|
|
type CreateProductCategoryRequest struct {
|
|
CategoryName string `json:"category_name" binding:"required"`
|
|
CategoryIcon string `json:"category_icon"`
|
|
SortOrder int `json:"sort_order"`
|
|
Status uint8 `json:"status"`
|
|
}
|
|
|
|
// UpdateProductCategoryRequest 更新商品分类请求结构体
|
|
type UpdateProductCategoryRequest struct {
|
|
CategoryName string `json:"category_name"`
|
|
CategoryIcon string `json:"category_icon"`
|
|
SortOrder int `json:"sort_order"`
|
|
Status uint8 `json:"status"`
|
|
}
|
|
|
|
// GetProductCategories 获取商品分类列表
|
|
func (h *AdminProductHandler) GetProductCategories(c *gin.Context) {
|
|
var categories []models.ProductCategory
|
|
|
|
err := common.GetDB().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))
|
|
}
|
|
|
|
// CreateProductCategory 创建商品分类(仅管理员)
|
|
func (h *AdminProductHandler) CreateProductCategory(c *gin.Context) {
|
|
currentUser, _ := c.Get("current_user")
|
|
user := currentUser.(models.User)
|
|
|
|
// 只有管理员可以创建分类
|
|
if user.SystemRole != 0 {
|
|
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
|
|
return
|
|
}
|
|
|
|
var req CreateProductCategoryRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "参数错误: "+err.Error()))
|
|
return
|
|
}
|
|
|
|
// 创建分类对象
|
|
newCategory := models.ProductCategory{
|
|
CategoryName: req.CategoryName,
|
|
CategoryIcon: req.CategoryIcon,
|
|
SortOrder: req.SortOrder,
|
|
Status: req.Status,
|
|
}
|
|
|
|
// 保存分类
|
|
if err := common.GetDB().Create(&newCategory).Error; err != nil {
|
|
c.JSON(http.StatusOK, common.Error(500, "创建商品分类失败"))
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(newCategory))
|
|
}
|
|
|
|
// UpdateProductCategory 更新商品分类(仅管理员)
|
|
func (h *AdminProductHandler) UpdateProductCategory(c *gin.Context) {
|
|
currentUser, _ := c.Get("current_user")
|
|
user := currentUser.(models.User)
|
|
|
|
// 只有管理员可以更新分类
|
|
if user.SystemRole != 0 {
|
|
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
|
|
return
|
|
}
|
|
|
|
categoryID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "分类ID无效"))
|
|
return
|
|
}
|
|
|
|
var req UpdateProductCategoryRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "参数错误: "+err.Error()))
|
|
return
|
|
}
|
|
|
|
// 检查分类是否存在
|
|
var existCategory models.ProductCategory
|
|
if err := common.GetDB().First(&existCategory, uint(categoryID)).Error; err != nil {
|
|
c.JSON(http.StatusOK, common.Error(404, "商品分类不存在"))
|
|
return
|
|
}
|
|
|
|
// 准备更新数据
|
|
updateData := models.ProductCategory{
|
|
CategoryName: req.CategoryName,
|
|
CategoryIcon: req.CategoryIcon,
|
|
SortOrder: req.SortOrder,
|
|
Status: req.Status,
|
|
}
|
|
|
|
// 更新分类信息
|
|
updateData.ID = uint(categoryID)
|
|
if err := common.GetDB().Model(&existCategory).Updates(&updateData).Error; err != nil {
|
|
c.JSON(http.StatusOK, common.Error(500, "更新商品分类失败"))
|
|
return
|
|
}
|
|
|
|
// 返回更新后的分类信息
|
|
var updatedCategory models.ProductCategory
|
|
common.GetDB().First(&updatedCategory, uint(categoryID))
|
|
|
|
c.JSON(http.StatusOK, common.Success(updatedCategory))
|
|
}
|
|
|
|
// DeleteProductCategory 删除商品分类(仅管理员)
|
|
func (h *AdminProductHandler) DeleteProductCategory(c *gin.Context) {
|
|
currentUser, _ := c.Get("current_user")
|
|
user := currentUser.(models.User)
|
|
|
|
// 只有管理员可以删除分类
|
|
if user.SystemRole != 0 {
|
|
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
|
|
return
|
|
}
|
|
|
|
categoryID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "分类ID无效"))
|
|
return
|
|
}
|
|
|
|
// 检查分类下是否有商品
|
|
var productCount int64
|
|
common.GetDB().Model(&models.PrimaryProduct{}).Where("category_id = ?", categoryID).Count(&productCount)
|
|
if productCount > 0 {
|
|
c.JSON(http.StatusOK, common.Error(400, "该分类下还有商品,无法删除"))
|
|
return
|
|
}
|
|
|
|
// 删除分类
|
|
if err := common.GetDB().Delete(&models.ProductCategory{}, uint(categoryID)).Error; err != nil {
|
|
c.JSON(http.StatusOK, common.Error(500, "删除商品分类失败"))
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(nil))
|
|
}
|
|
|
|
// GetPrimaryProducts 获取一级商品列表
|
|
func (h *AdminProductHandler) 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 > 100 {
|
|
pageSize = 10
|
|
}
|
|
|
|
// 搜索参数
|
|
categoryID := c.Query("category_id")
|
|
productName := c.Query("product_name")
|
|
status := c.Query("status")
|
|
|
|
db := common.GetDB()
|
|
var products []models.PrimaryProduct
|
|
var total int64
|
|
|
|
// 构建查询条件
|
|
query := db.Model(&models.PrimaryProduct{}).Preload("Category")
|
|
|
|
// 添加搜索条件
|
|
if categoryID != "" {
|
|
query = query.Where("category_id = ?", categoryID)
|
|
}
|
|
if productName != "" {
|
|
query = query.Where("product_name LIKE ?", "%"+productName+"%")
|
|
}
|
|
if status != "" {
|
|
query = query.Where("status = ?", status)
|
|
}
|
|
|
|
// 获取总数
|
|
query.Count(&total)
|
|
|
|
// 分页查询
|
|
offset := (page - 1) * pageSize
|
|
err := query.Offset(offset).Limit(pageSize).Order("sort_order ASC, created_at DESC").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 *AdminProductHandler) 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().Preload("Category").First(&product, uint(productID)).Error
|
|
if err != nil {
|
|
if err == gorm.ErrRecordNotFound {
|
|
c.JSON(http.StatusOK, common.Error(404, "商品不存在"))
|
|
} else {
|
|
c.JSON(http.StatusOK, common.Error(500, "查询商品详情失败"))
|
|
}
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(product))
|
|
}
|
|
|
|
// CreatePrimaryProductRequest 创建一级商品请求结构体
|
|
type CreatePrimaryProductRequest struct {
|
|
CategoryID uint `json:"category_id" binding:"required"`
|
|
ProductName string `json:"product_name" binding:"required"`
|
|
ProductDescription string `json:"product_description"`
|
|
ProductImages string `json:"product_images"`
|
|
OriginalPrice float64 `json:"original_price" binding:"required"`
|
|
CurrentPrice float64 `json:"current_price" binding:"required"`
|
|
StockQuantity int `json:"stock_quantity"`
|
|
SortOrder int `json:"sort_order"`
|
|
Status uint8 `json:"status"`
|
|
IsHot int8 `json:"is_hot"`
|
|
}
|
|
|
|
// CreatePrimaryProduct 创建一级商品(仅管理员)
|
|
func (h *AdminProductHandler) CreatePrimaryProduct(c *gin.Context) {
|
|
currentUser, _ := c.Get("current_user")
|
|
user := currentUser.(models.User)
|
|
|
|
// 只有管理员可以创建商品
|
|
if user.SystemRole != 0 {
|
|
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
|
|
return
|
|
}
|
|
|
|
var req CreatePrimaryProductRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "参数错误: "+err.Error()))
|
|
return
|
|
}
|
|
|
|
// 检查分类是否存在
|
|
var category models.ProductCategory
|
|
if err := common.GetDB().First(&category, req.CategoryID).Error; err != nil {
|
|
c.JSON(http.StatusOK, common.Error(404, "商品分类不存在"))
|
|
return
|
|
}
|
|
|
|
// 创建商品对象
|
|
newProduct := models.PrimaryProduct{
|
|
CategoryID: req.CategoryID,
|
|
ProductName: req.ProductName,
|
|
ProductDescription: req.ProductDescription,
|
|
ProductImages: req.ProductImages,
|
|
OriginalPrice: req.OriginalPrice,
|
|
CurrentPrice: req.CurrentPrice,
|
|
StockQuantity: req.StockQuantity,
|
|
SortOrder: req.SortOrder,
|
|
Status: req.Status,
|
|
IsHot: req.IsHot,
|
|
}
|
|
|
|
// 保存商品
|
|
if err := common.GetDB().Create(&newProduct).Error; err != nil {
|
|
c.JSON(http.StatusOK, common.Error(500, "创建商品失败"))
|
|
return
|
|
}
|
|
|
|
// 返回创建的商品(包含分类信息)
|
|
var createdProduct models.PrimaryProduct
|
|
common.GetDB().Preload("Category").First(&createdProduct, newProduct.ID)
|
|
|
|
c.JSON(http.StatusOK, common.Success(createdProduct))
|
|
}
|
|
|
|
// UpdatePrimaryProductRequest 更新一级商品请求结构体
|
|
type UpdatePrimaryProductRequest struct {
|
|
CategoryID uint `json:"category_id"`
|
|
ProductName string `json:"product_name"`
|
|
ProductDescription string `json:"product_description"`
|
|
ProductImages string `json:"product_images"`
|
|
OriginalPrice float64 `json:"original_price"`
|
|
CurrentPrice float64 `json:"current_price"`
|
|
StockQuantity int `json:"stock_quantity"`
|
|
SortOrder int `json:"sort_order"`
|
|
Status uint8 `json:"status"`
|
|
IsHot int8 `json:"is_hot"`
|
|
}
|
|
|
|
// UpdatePrimaryProduct 更新一级商品(仅管理员)
|
|
func (h *AdminProductHandler) UpdatePrimaryProduct(c *gin.Context) {
|
|
currentUser, _ := c.Get("current_user")
|
|
user := currentUser.(models.User)
|
|
|
|
// 只有管理员可以更新商品
|
|
if user.SystemRole != 0 {
|
|
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
|
|
return
|
|
}
|
|
|
|
productID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "商品ID无效"))
|
|
return
|
|
}
|
|
|
|
var req UpdatePrimaryProductRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "参数错误: "+err.Error()))
|
|
return
|
|
}
|
|
|
|
// 检查商品是否存在
|
|
var existProduct models.PrimaryProduct
|
|
if err := common.GetDB().First(&existProduct, uint(productID)).Error; err != nil {
|
|
c.JSON(http.StatusOK, common.Error(404, "商品不存在"))
|
|
return
|
|
}
|
|
|
|
// 如果更新了分类,检查分类是否存在
|
|
if req.CategoryID != 0 {
|
|
var category models.ProductCategory
|
|
if err := common.GetDB().First(&category, req.CategoryID).Error; err != nil {
|
|
c.JSON(http.StatusOK, common.Error(404, "商品分类不存在"))
|
|
return
|
|
}
|
|
}
|
|
|
|
// 准备更新数据
|
|
updateData := models.PrimaryProduct{
|
|
CategoryID: req.CategoryID,
|
|
ProductName: req.ProductName,
|
|
ProductDescription: req.ProductDescription,
|
|
ProductImages: req.ProductImages,
|
|
OriginalPrice: req.OriginalPrice,
|
|
CurrentPrice: req.CurrentPrice,
|
|
StockQuantity: req.StockQuantity,
|
|
SortOrder: req.SortOrder,
|
|
Status: req.Status,
|
|
IsHot: req.IsHot,
|
|
}
|
|
fmt.Println(updateData.IsHot)
|
|
// 更新商品信息
|
|
updateData.ID = uint(productID)
|
|
if err := common.GetDB().Model(&existProduct).Updates(&updateData).Error; err != nil {
|
|
c.JSON(http.StatusOK, common.Error(500, "更新商品失败"))
|
|
return
|
|
}
|
|
common.GetDB().Model(&existProduct).Select("status", "is_hot").
|
|
Updates(models.PrimaryProduct{IsHot: req.IsHot, Status: req.Status})
|
|
// 返回更新后的商品信息
|
|
var updatedProduct models.PrimaryProduct
|
|
common.GetDB().Preload("Category").First(&updatedProduct, uint(productID))
|
|
|
|
c.JSON(http.StatusOK, common.Success(updatedProduct))
|
|
}
|
|
|
|
// DeletePrimaryProduct 删除一级商品(仅管理员)
|
|
func (h *AdminProductHandler) DeletePrimaryProduct(c *gin.Context) {
|
|
currentUser, _ := c.Get("current_user")
|
|
user := currentUser.(models.User)
|
|
|
|
// 只有管理员可以删除商品
|
|
if user.SystemRole != 0 {
|
|
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
|
|
return
|
|
}
|
|
|
|
productID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "商品ID无效"))
|
|
return
|
|
}
|
|
|
|
// 检查商品是否存在
|
|
var existProduct models.PrimaryProduct
|
|
if err := common.GetDB().First(&existProduct, uint(productID)).Error; err != nil {
|
|
c.JSON(http.StatusOK, common.Error(404, "商品不存在"))
|
|
return
|
|
}
|
|
|
|
// 删除商品
|
|
if err := common.GetDB().Delete(&existProduct).Error; err != nil {
|
|
c.JSON(http.StatusOK, common.Error(500, "删除商品失败"))
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(nil))
|
|
}
|
|
|
|
// GetSecondaryProducts 获取二级商品列表
|
|
func (h *AdminProductHandler) 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 > 100 {
|
|
pageSize = 10
|
|
}
|
|
|
|
// 搜索参数
|
|
sellerID := c.Query("seller_id")
|
|
productName := c.Query("product_name")
|
|
status := c.Query("status")
|
|
|
|
db := common.GetDB()
|
|
var products []models.SecondaryProduct
|
|
var total int64
|
|
|
|
// 构建查询条件
|
|
query := db.Model(&models.SecondaryProduct{}).Preload("Seller")
|
|
|
|
// 添加搜索条件
|
|
if sellerID != "" {
|
|
query = query.Where("seller_id = ?", sellerID)
|
|
}
|
|
if productName != "" {
|
|
query = query.Where("product_name LIKE ?", "%"+productName+"%")
|
|
}
|
|
if status != "" {
|
|
query = query.Where("status = ?", status)
|
|
}
|
|
|
|
// 获取总数
|
|
query.Count(&total)
|
|
|
|
// 分页查询
|
|
offset := (page - 1) * pageSize
|
|
err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").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))
|
|
}
|
|
|
|
// GetProductStats 获取商品统计信息
|
|
func (h *AdminProductHandler) GetProductStats(c *gin.Context) {
|
|
db := common.GetDB()
|
|
stats := make(map[string]interface{})
|
|
|
|
// 一级商品统计
|
|
var totalPrimaryProducts int64
|
|
var onSalePrimaryProducts int64
|
|
db.Model(&models.PrimaryProduct{}).Count(&totalPrimaryProducts)
|
|
db.Model(&models.PrimaryProduct{}).Where("status = 1").Count(&onSalePrimaryProducts)
|
|
|
|
stats["total_primary_products"] = totalPrimaryProducts
|
|
stats["on_sale_primary_products"] = onSalePrimaryProducts
|
|
|
|
// 二级商品统计
|
|
var totalSecondaryProducts int64
|
|
var onSaleSecondaryProducts int64
|
|
db.Model(&models.SecondaryProduct{}).Count(&totalSecondaryProducts)
|
|
db.Model(&models.SecondaryProduct{}).Where("status = 1").Count(&onSaleSecondaryProducts)
|
|
|
|
stats["total_secondary_products"] = totalSecondaryProducts
|
|
stats["on_sale_secondary_products"] = onSaleSecondaryProducts
|
|
|
|
// 商品分类数量
|
|
var totalCategories int64
|
|
db.Model(&models.ProductCategory{}).Count(&totalCategories)
|
|
stats["total_categories"] = totalCategories
|
|
|
|
c.JSON(http.StatusOK, common.Success(stats))
|
|
}
|