148 lines
4.0 KiB
Go
148 lines
4.0 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"silk-server-go/internal/middleware"
|
|
"silk-server-go/internal/model"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// RegisterConsumableRoutes 注册耗材路由
|
|
func RegisterConsumableRoutes(rg *gin.RouterGroup, db *gorm.DB) {
|
|
read := middleware.RequirePermission(db, "consumable:read")
|
|
write := middleware.RequirePermission(db, "consumable:write")
|
|
rg.GET("/consumables", read, listConsumables(db))
|
|
rg.POST("/consumables", write, createConsumable(db))
|
|
rg.PATCH("/consumables/:id", write, updateConsumable(db))
|
|
rg.DELETE("/consumables/:id", write, deleteConsumable(db))
|
|
rg.GET("/consumables/alerts", read, consumableAlerts(db))
|
|
rg.GET("/consumables/purchase-suggestions", read, purchaseSuggestions(db))
|
|
}
|
|
|
|
// listConsumables 耗材列表(category 过滤)
|
|
func listConsumables(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
q := db.Model(&model.Consumable{})
|
|
if cat := c.Query("category"); cat != "" {
|
|
q = q.Where("category = ?", cat)
|
|
}
|
|
var list []model.Consumable
|
|
q.Order("name ASC").Find(&list)
|
|
c.JSON(http.StatusOK, list)
|
|
}
|
|
}
|
|
|
|
func createConsumable(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
var item model.Consumable
|
|
if err := c.ShouldBindJSON(&item); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
item.ID = ""
|
|
if item.Name == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "耗材名称不能为空"})
|
|
return
|
|
}
|
|
if item.Category == "" {
|
|
item.Category = "other"
|
|
}
|
|
if err := db.Create(&item).Error; err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "创建失败"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusCreated, item)
|
|
}
|
|
}
|
|
|
|
func updateConsumable(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
id := c.Param("id")
|
|
var item model.Consumable
|
|
if db.Where("id = ?", id).First(&item).Error != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "consumable not found"})
|
|
return
|
|
}
|
|
updates, err := bindUpdates(c)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if len(updates) > 0 {
|
|
db.Model(&model.Consumable{}).Where("id = ?", id).Updates(updates)
|
|
}
|
|
db.Where("id = ?", id).First(&item)
|
|
c.JSON(http.StatusOK, item)
|
|
}
|
|
}
|
|
|
|
func deleteConsumable(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
id := c.Param("id")
|
|
var item model.Consumable
|
|
if db.Where("id = ?", id).First(&item).Error != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "consumable not found"})
|
|
return
|
|
}
|
|
db.Where("id = ?", id).Delete(&model.Consumable{})
|
|
c.JSON(http.StatusOK, gin.H{"id": id})
|
|
}
|
|
}
|
|
|
|
// consumableAlerts 低库存 + 临期/过期预警(30 天窗口)
|
|
func consumableAlerts(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
var list []model.Consumable
|
|
db.Find(&list)
|
|
result := make([]gin.H, 0)
|
|
for _, item := range list {
|
|
alertType := ""
|
|
if item.LowStockAlert() {
|
|
alertType = "low_stock"
|
|
}
|
|
if item.ExpiringAlert(30) {
|
|
alertType = "expiring"
|
|
}
|
|
if alertType != "" {
|
|
result = append(result, gin.H{
|
|
"id": item.ID,
|
|
"name": item.Name,
|
|
"category": item.Category,
|
|
"quantity": item.Quantity,
|
|
"unit": item.Unit,
|
|
"minQuantity": item.MinQuantity,
|
|
"expiryDate": item.ExpiryDate,
|
|
"alertType": alertType,
|
|
})
|
|
}
|
|
}
|
|
c.JSON(http.StatusOK, result)
|
|
}
|
|
}
|
|
|
|
// purchaseSuggestions 低于安全阈值的采购建议
|
|
func purchaseSuggestions(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
var list []model.Consumable
|
|
db.Find(&list)
|
|
result := make([]gin.H, 0)
|
|
for _, item := range list {
|
|
if s := item.PurchaseSuggestion(); s > 0 {
|
|
result = append(result, gin.H{
|
|
"id": item.ID,
|
|
"name": item.Name,
|
|
"category": item.Category,
|
|
"quantity": item.Quantity,
|
|
"unit": item.Unit,
|
|
"minQuantity": item.MinQuantity,
|
|
"suggest": s,
|
|
})
|
|
}
|
|
}
|
|
c.JSON(http.StatusOK, result)
|
|
}
|
|
}
|