aeus-admin/server.go

146 lines
3.8 KiB
Go

package aeusadmin
import (
"context"
"path"
"git.nobla.cn/golang/aeus-admin/defaults"
"git.nobla.cn/golang/aeus-admin/models"
"git.nobla.cn/golang/aeus/pkg/errors"
"git.nobla.cn/golang/rest"
"git.nobla.cn/golang/rest/inflector"
"git.nobla.cn/golang/rest/types"
"gorm.io/gorm"
)
// getModels 获取预定义的模型列表
func getModels() []any {
return []any{
&models.User{},
&models.Role{},
&models.Menu{},
&models.Department{},
&models.Permission{},
&models.RolePermission{},
}
}
// checkModelMenu 检查模型菜单
func checkModelMenu(db *gorm.DB, viewPath string, model *rest.Model, translate Translate) (value *models.Menu, err error) {
menuName := inflector.Camelize(model.Naming().ModuleName) + inflector.Camelize(model.Naming().Singular)
value = &models.Menu{}
if err = db.Where("name = ?", menuName).First(value).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
value.Name = menuName
value.ParentId = 0
value.ViewPath = path.Join(viewPath, model.ModuleName(), model.Naming().Singular, "Index.vue")
value.Label = inflector.Camel2words(model.Naming().Pluralize)
if translate != nil {
value.Label = translate.Menu(model, value.Label)
}
value.Uri = model.Uri(types.ScenarioList)
err = db.Create(value).Error
}
}
return
}
// checkModelPermission 检查模型权限是否写入到数据库
func checkModelPermission(db *gorm.DB, menuId int64, scene string, model *rest.Model, translate Translate) (permissionModel *models.Permission, err error) {
permissionModel = &models.Permission{}
permission := model.Permission(scene)
if err = db.Where("permission = ?", permission).First(permissionModel).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
permissionModel.MenuId = menuId
permissionModel.Label = scene
if translate != nil {
permissionModel.Label = translate.Permission(model, scene, permissionModel.Label)
}
permissionModel.Permission = permission
err = db.Create(permissionModel).Error
}
}
return
}
// checkModel 检查模型
func checkModel(opts *options, model *rest.Model) (err error) {
var (
menuModel *models.Menu
)
tx := opts.db.Begin()
if menuModel, err = checkModelMenu(tx, opts.viewPath, model, opts.translate); err != nil {
tx.Rollback()
return
}
for _, s := range defaultScenarios {
if model.HasScenario(s) {
if _, err = checkModelPermission(tx, menuModel.Id, s, model, opts.translate); err != nil {
tx.Rollback()
return
}
}
}
tx.Commit()
return
}
// initREST 初始化REST模块
func initREST(ctx context.Context, o *options) (err error) {
tx := o.db
if tx == nil {
return errors.ErrUnavailable
}
opts := make([]rest.Option, 0)
opts = append(opts, o.restOpts...)
opts = append(opts, rest.WithDB(tx))
if err = rest.Init(opts...); err != nil {
return
}
if err = tx.AutoMigrate(getModels()...); err != nil {
return
}
return
}
// initRBAC 初始化权限控制, 用于生成角色权限相关的信息
func initRBAC(ctx context.Context, o *options) (err error) {
var mv *rest.Model
for _, v := range getModels() {
if mv, err = rest.AutoMigrate(ctx, v); err != nil {
return
} else {
if err = checkModel(o, mv); err != nil {
return
}
}
}
return
}
// AutoMigrate 自动生成一个模型的schema和权限的定义
func AutoMigrate(ctx context.Context, db *gorm.DB, model any, cbs ...Option) (err error) {
var (
mv *rest.Model
)
opts := newOptions(cbs...)
if mv, err = rest.AutoMigrate(ctx, model); err != nil {
return
}
err = checkModel(opts, mv)
return
}
// Init 初始化模块
func Init(ctx context.Context, cbs ...Option) (err error) {
opts := newOptions(cbs...)
if err = initREST(ctx, opts); err != nil {
return
}
if err = initRBAC(ctx, opts); err != nil {
return
}
err = defaults.Init(opts.db)
return
}