127 lines
3.7 KiB
Go
127 lines
3.7 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"
|
|
)
|
|
|
|
// RegisterDeviceRoutes 注册设备路由
|
|
func RegisterDeviceRoutes(rg *gin.RouterGroup, db *gorm.DB) {
|
|
rg.GET("/devices", middleware.RequirePermission(db, "device:read"), listDevices(db))
|
|
rg.GET("/devices/:id", middleware.RequirePermission(db, "device:read"), getDevice(db))
|
|
rg.POST("/devices", middleware.RequirePermission(db, "room:write"), createDevice(db))
|
|
rg.PATCH("/devices/:id", middleware.RequirePermission(db, "room:write"), updateDevice(db))
|
|
rg.DELETE("/devices/:id", middleware.RequirePermission(db, "room:write"), deleteDevice(db))
|
|
}
|
|
|
|
// listDevices 设备列表
|
|
func listDevices(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
var devices []model.Device
|
|
query := applyRoomScope(db.Model(&model.Device{}), c, "room_id").Order("created_at DESC")
|
|
if kind := c.Query("kind"); kind != "" {
|
|
query = query.Where("kind = ?", kind)
|
|
}
|
|
query.Find(&devices)
|
|
c.JSON(http.StatusOK, devices)
|
|
}
|
|
}
|
|
|
|
// getDevice 设备详情
|
|
func getDevice(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
id := c.Param("id")
|
|
if !requireObjectAccess(c, db, "device", id) {
|
|
return
|
|
}
|
|
var device model.Device
|
|
if db.Where("id = ?", id).First(&device).Error != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "device not found"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, device)
|
|
}
|
|
}
|
|
|
|
// createDevice 新建设备(检查 deviceKey 唯一)
|
|
func createDevice(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
var device model.Device
|
|
if err := c.ShouldBindJSON(&device); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if device.DeviceKey == "" {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "deviceKey 不能为空"})
|
|
return
|
|
}
|
|
// 检查 deviceKey 是否已存在
|
|
var existing model.Device
|
|
if db.Where("device_key = ?", device.DeviceKey).First(&existing).Error == nil {
|
|
c.JSON(http.StatusConflict, gin.H{"error": "deviceKey already exists"})
|
|
return
|
|
}
|
|
device.ID = "" // 让数据库自动生成
|
|
if !canAccessRoom(db, c, &device.RoomID) {
|
|
c.JSON(http.StatusForbidden, gin.H{"error": "无权在该蚕房下新建设备"})
|
|
return
|
|
}
|
|
if err := db.Create(&device).Error; err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "创建失败"})
|
|
return
|
|
}
|
|
c.JSON(http.StatusCreated, device)
|
|
}
|
|
}
|
|
|
|
// updateDevice 更新设备
|
|
func updateDevice(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
id := c.Param("id")
|
|
if !requireObjectAccess(c, db, "device", id) {
|
|
return
|
|
}
|
|
var device model.Device
|
|
if db.Where("id = ?", id).First(&device).Error != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "device not found"})
|
|
return
|
|
}
|
|
updates, err := bindUpdates(c)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
if roomID, ok := updates["room_id"].(string); ok && !canAccessRoom(db, c, &roomID) {
|
|
c.JSON(http.StatusForbidden, gin.H{"error": "无权迁移设备到指定蚕房"})
|
|
return
|
|
}
|
|
if len(updates) > 0 {
|
|
db.Model(&model.Device{}).Where("id = ?", id).Updates(updates)
|
|
}
|
|
db.Where("id = ?", id).First(&device)
|
|
c.JSON(http.StatusOK, device)
|
|
}
|
|
}
|
|
|
|
// deleteDevice 删除设备
|
|
func deleteDevice(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
id := c.Param("id")
|
|
if !requireObjectAccess(c, db, "device", id) {
|
|
return
|
|
}
|
|
var device model.Device
|
|
if db.Where("id = ?", id).First(&device).Error != nil {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "device not found"})
|
|
return
|
|
}
|
|
db.Where("id = ?", id).Delete(&model.Device{})
|
|
c.JSON(http.StatusOK, gin.H{"id": id})
|
|
}
|
|
}
|