package handler import ( "net/http" "strconv" "github.com/gin-gonic/gin" "gorm.io/gorm" "github.com/wangjia/jiu/backend/internal/middleware" "github.com/wangjia/jiu/backend/internal/model" ) type ProductHandler struct { db *gorm.DB } func NewProductHandler(db *gorm.DB) *ProductHandler { return &ProductHandler{db: db} } // List GET /api/v1/products func (h *ProductHandler) List(c *gin.Context) { hotelID := middleware.GetHotelID(c) page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) keyword := c.Query("keyword") categoryID := c.Query("category_id") query := h.db.Model(&model.Product{}). Where("hotel_id = ? AND deleted_at IS NULL", hotelID) if keyword != "" { query = query.Where("name LIKE ? OR code LIKE ? OR barcode LIKE ?", "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%") } if categoryID != "" { query = query.Where("category_id = ?", categoryID) } var total int64 query.Count(&total) var products []model.Product offset := (page - 1) * pageSize query.Preload("Category").Offset(offset).Limit(pageSize). Order("id DESC").Find(&products) c.JSON(http.StatusOK, gin.H{ "data": products, "total": total, "page": page, "page_size": pageSize, }) } // Create POST /api/v1/products func (h *ProductHandler) Create(c *gin.Context) { hotelID := middleware.GetHotelID(c) var product model.Product if err := c.ShouldBindJSON(&product); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } product.HotelID = hotelID if err := h.db.Create(&product).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, gin.H{"data": product}) } // Update PUT /api/v1/products/:id func (h *ProductHandler) Update(c *gin.Context) { hotelID := middleware.GetHotelID(c) id := c.Param("id") var product model.Product if err := h.db.Where("id = ? AND hotel_id = ? AND deleted_at IS NULL", id, hotelID). First(&product).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "not found"}) return } if err := c.ShouldBindJSON(&product); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } product.HotelID = hotelID // 防止篡改 if err := h.db.Save(&product).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"data": product}) } // Delete DELETE /api/v1/products/:id (软删除) func (h *ProductHandler) Delete(c *gin.Context) { hotelID := middleware.GetHotelID(c) id := c.Param("id") now := timeNow() result := h.db.Model(&model.Product{}). Where("id = ? AND hotel_id = ? AND deleted_at IS NULL", id, hotelID). Update("deleted_at", now) if result.RowsAffected == 0 { c.JSON(http.StatusNotFound, gin.H{"error": "not found"}) return } c.JSON(http.StatusOK, gin.H{"message": "deleted"}) }