Files
yovision/Sense/server/cmd/migrate/migration/version/2026081414000_device.go
T

124 lines
4.8 KiB
Go

package version
import (
"fmt"
"runtime"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"git.ilapage.cn/ila/yovision/Sense/server/app/sense/credential"
deviceModels "git.ilapage.cn/ila/yovision/Sense/server/app/sense/device/models"
"git.ilapage.cn/ila/yovision/Sense/server/cmd/migrate/migration"
migrationModels "git.ilapage.cn/ila/yovision/Sense/server/cmd/migrate/migration/models"
common "git.ilapage.cn/ila/yovision/Sense/server/common/models"
)
type deviceCasbinRule struct {
ID uint `gorm:"primaryKey;autoIncrement"`
Ptype string `gorm:"size:512;uniqueIndex:unique_index"`
V0 string `gorm:"size:512;uniqueIndex:unique_index"`
V1 string `gorm:"size:512;uniqueIndex:unique_index"`
V2 string `gorm:"size:512;uniqueIndex:unique_index"`
V3 string `gorm:"size:512;uniqueIndex:unique_index"`
V4 string `gorm:"size:512;uniqueIndex:unique_index"`
V5 string `gorm:"size:512;uniqueIndex:unique_index"`
}
func (deviceCasbinRule) TableName() string { return "casbin_rule" }
func init() {
_, fileName, _, _ := runtime.Caller(0)
migration.Migrate.SetVersion(migration.GetFilename(fileName), migrateSenseDeviceLedger)
}
func migrateSenseDeviceLedger(db *gorm.DB, version string) error {
return db.Transaction(func(tx *gorm.DB) error {
if err := tx.AutoMigrate(&deviceModels.Device{}, &credential.DeviceCredential{}, &deviceCasbinRule{}); err != nil {
return err
}
page, err := ensureDeviceMenu(tx, migrationModels.SysMenu{
MenuName: "SenseDeviceManage", Title: "设备管理", Icon: "monitor", Path: "/sense/devices",
MenuType: "C", Permission: "sense:device:list", ParentId: 0, Component: "/sense/device/index",
Sort: 5, Visible: "0", IsFrame: "1",
})
if err != nil {
return err
}
buttons := make([]migrationModels.SysMenu, 0, 4)
for index, definition := range []struct{ name, title, action, permission string }{
{"SenseDeviceAdd", "新增设备", "POST", "sense:device:add"},
{"SenseDeviceEdit", "编辑设备", "PUT", "sense:device:edit"},
{"SenseDeviceDisable", "停用设备", "PUT", "sense:device:disable"},
{"SenseDeviceCredential", "更新设备凭据", "PUT", "sense:device:credential"},
} {
button, err := ensureDeviceMenu(tx, migrationModels.SysMenu{
MenuName: definition.name, Title: definition.title, MenuType: "F", Action: definition.action,
Permission: definition.permission, ParentId: page.MenuId, Paths: fmt.Sprintf("/0/%d", page.MenuId),
Sort: index + 1, Visible: "1", IsFrame: "1",
})
if err != nil {
return err
}
buttons = append(buttons, button)
}
if err = attachDeviceRole(tx, "implementation_operator", append([]migrationModels.SysMenu{page}, buttons...)); err != nil {
return err
}
if err = attachDeviceRole(tx, "site_admin", append([]migrationModels.SysMenu{page}, buttons...)); err != nil {
return err
}
if err = attachDeviceRole(tx, "viewer", []migrationModels.SysMenu{page}); err != nil {
return err
}
readPolicies := [][2]string{{"/api/v1/devices", "GET"}, {"/api/v1/devices/:id", "GET"}}
writePolicies := [][2]string{{"/api/v1/devices", "POST"}, {"/api/v1/devices/:id", "PUT"}, {"/api/v1/devices/:id/disable", "PUT"}, {"/api/v1/devices/:id/credentials", "PUT"}}
for _, role := range []string{"implementation_operator", "site_admin", "viewer"} {
policies := append([][2]string{}, readPolicies...)
if role != "viewer" {
policies = append(policies, writePolicies...)
}
for _, policy := range policies {
rule := deviceCasbinRule{Ptype: "p", V0: role, V1: policy[0], V2: policy[1]}
if err = tx.Clauses(clause.OnConflict{DoNothing: true}).Create(&rule).Error; err != nil {
return err
}
}
}
return tx.Create(&common.Migration{Version: version}).Error
})
}
func ensureDeviceMenu(tx *gorm.DB, desired migrationModels.SysMenu) (migrationModels.SysMenu, error) {
var menu migrationModels.SysMenu
err := tx.Where("menu_name = ?", desired.MenuName).First(&menu).Error
if err != nil && err != gorm.ErrRecordNotFound {
return menu, err
}
if err == gorm.ErrRecordNotFound {
menu = desired
if err = tx.Create(&menu).Error; err != nil {
return menu, err
}
}
paths := desired.Paths
if desired.ParentId == 0 {
paths = fmt.Sprintf("/0/%d", menu.MenuId)
}
err = tx.Model(&menu).Updates(map[string]any{
"title": desired.Title, "icon": desired.Icon, "path": desired.Path, "paths": paths,
"menu_type": desired.MenuType, "action": desired.Action, "permission": desired.Permission,
"parent_id": desired.ParentId, "component": desired.Component, "sort": desired.Sort,
"visible": desired.Visible, "is_frame": desired.IsFrame,
}).Error
return menu, err
}
func attachDeviceRole(tx *gorm.DB, roleKey string, menus []migrationModels.SysMenu) error {
var role migrationModels.SysRole
if err := tx.Where("role_key = ?", roleKey).First(&role).Error; err != nil {
return err
}
return tx.Model(&role).Association("SysMenu").Append(menus)
}