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 InventoryHandler struct { db *gorm.DB } func NewInventoryHandler(db *gorm.DB) *InventoryHandler { return &InventoryHandler{db: db} } // List GET /api/v1/inventory func (h *InventoryHandler) List(c *gin.Context) { shopID := middleware.GetShopID(c) page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) query := h.db.Model(&model.Inventory{}).Where("shop_id = ?", shopID) if warehouseID := c.Query("warehouse_id"); warehouseID != "" { query = query.Where("warehouse_id = ?", warehouseID) } if productID := c.Query("product_id"); productID != "" { query = query.Where("product_id = ?", productID) } if c.Query("in_stock") == "1" { query = query.Where("quantity > 0") } var total int64 query.Count(&total) var inventory []model.Inventory query.Preload("Product").Preload("Warehouse"). Offset((page - 1) * pageSize).Limit(pageSize). Find(&inventory) c.JSON(http.StatusOK, gin.H{"data": inventory, "total": total, "page": page, "page_size": pageSize}) } // Logs GET /api/v1/inventory/logs func (h *InventoryHandler) Logs(c *gin.Context) { shopID := middleware.GetShopID(c) page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) query := h.db.Model(&model.InventoryLog{}).Where("shop_id = ?", shopID) if productID := c.Query("product_id"); productID != "" { query = query.Where("product_id = ?", productID) } var total int64 query.Count(&total) var logs []model.InventoryLog query.Offset((page - 1) * pageSize).Limit(pageSize).Order("id DESC").Find(&logs) c.JSON(http.StatusOK, gin.H{"data": logs, "total": total, "page": page, "page_size": pageSize}) } // CreateCheck POST /api/v1/inventory/checks func (h *InventoryHandler) CreateCheck(c *gin.Context) { shopID := middleware.GetShopID(c) operatorID := middleware.GetUserID(c) var req model.InventoryCheck if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } req.ShopID = shopID req.OperatorID = operatorID req.Status = "draft" // 自动填入系统库存数量 for i := range req.Items { req.Items[i].ShopID = shopID var inv model.Inventory if err := h.db.Where("shop_id = ? AND warehouse_id = ? AND product_id = ?", shopID, req.WarehouseID, req.Items[i].ProductID).First(&inv).Error; err == nil { req.Items[i].SystemQty = inv.Quantity } } if err := h.db.Create(&req).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, gin.H{"data": req}) } // GetCheck GET /api/v1/inventory/checks/:id func (h *InventoryHandler) GetCheck(c *gin.Context) { shopID := middleware.GetShopID(c) var check model.InventoryCheck if err := h.db.Preload("Items.Product"). Where("id = ? AND shop_id = ?", c.Param("id"), shopID). First(&check).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "not found"}) return } c.JSON(http.StatusOK, gin.H{"data": check}) }