package service import ( "errors" "IotAdmin/core/sdk/config" "gorm.io/gorm/clause" "github.com/casbin/casbin/v2" "IotAdmin/core/sdk/service" "gorm.io/gorm" "IotAdmin/app/system/models" "IotAdmin/app/system/service/dto" cDto "IotAdmin/common/dto" ) type SysRoleService struct { service.Service } // GetPage 获取SysRole列表 func (e *SysRoleService) GetPage(c *dto.SysRoleGetPageReq, list *[]models.SysRole, count *int64) error { var err error var data models.SysRole err = e.Orm.Model(&data). Scopes( cDto.MakeCondition(c.GetNeedSearch()), cDto.Paginate(c.GetPageSize(), c.GetPageIndex()), ). Find(list).Limit(-1).Offset(-1). Count(count).Error if err != nil { e.Log.Errorf("db error:%s", err) return err } return nil } // Get 获取SysRole对象 func (e *SysRoleService) Get(d *dto.SysRoleGetReq, model *models.SysRole) error { var err error db := e.Orm.First(model, d.GetId()) err = db.Error if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { err = errors.New("查看对象不存在或无权查看") e.Log.Errorf("db error:%s", err) return err } if err != nil { e.Log.Errorf("db error:%s", err) return err } model.MenuIds, err = e.GetRoleMenuId(model.RoleId) if err != nil { e.Log.Errorf("get menuIds error, %s", err.Error()) return err } return nil } // Insert 创建SysRole对象 func (e *SysRoleService) Insert(c *dto.SysRoleInsertReq, cb *casbin.SyncedEnforcer) error { var err error var data models.SysRole var dataMenu []models.SysMenu err = e.Orm.Preload("SysApi").Where("menu_id in ?", c.MenuIds).Find(&dataMenu).Error if err != nil { e.Log.Errorf("db error:%s", err) return err } c.Menus = dataMenu c.Generate(&data) tx := e.Orm if config.DatabaseConfig.Driver != "sqlite3" { tx := e.Orm.Begin() defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() } var count int64 err = tx.Model(&data).Where("role_key = ?", c.RoleKey).Count(&count).Error if err != nil { e.Log.Errorf("db error:%s", err) return err } if count > 0 { err = errors.New("roleKey已存在,需更换在提交!") e.Log.Errorf("db error:%s", err) return err } err = tx.Create(&data).Error if err != nil { e.Log.Errorf("db error:%s", err) return err } mp := make(map[string]interface{}, 0) polices := make([][]string, 0) for _, menu := range dataMenu { for _, api := range menu.SysApi { if mp[data.RoleKey+"-"+api.Path+"-"+api.Action] != "" { mp[data.RoleKey+"-"+api.Path+"-"+api.Action] = "" polices = append(polices, []string{data.RoleKey, api.Path, api.Action}) } } } if len(polices) <= 0 { return nil } // 写入 sys_casbin_rule 权限表里 当前角色数据的记录 _, err = cb.AddNamedPolicies("p", polices) if err != nil { return err } return nil } // Update 修改SysRole对象 func (e *SysRoleService) Update(c *dto.SysRoleUpdateReq, cb *casbin.SyncedEnforcer, roleKey string) error { var err error tx := e.Orm if config.DatabaseConfig.Driver != "sqlite3" { tx := e.Orm.Begin() defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() } var model = models.SysRole{} var mList = make([]models.SysMenu, 0) tx.Preload("Menus").First(&model, c.GetId()) if err = checkRoleAllowed(model, roleKey); err != nil { return err } tx.Preload("SysApi").Where("menu_id in ?", c.MenuIds).Find(&mList) err = tx.Model(&model).Association("Menus").Delete(model.Menus) if err != nil { e.Log.Errorf("delete policy error:%s", err) return err } c.Generate(&model) model.Menus = &mList // 更新关联的数据,使用 FullSaveAssociations 模式 db := tx.Session(&gorm.Session{FullSaveAssociations: true}).Debug().Save(&model) if err = db.Error; err != nil { e.Log.Errorf("db error:%s", err) return err } if db.RowsAffected == 0 { return errors.New("无权更新该数据") } // 清除 sys_casbin_rule 权限表里 当前角色的所有记录 _, err = cb.RemoveFilteredPolicy(0, model.RoleKey) if err != nil { e.Log.Errorf("delete policy error:%s", err) return err } mp := make(map[string]interface{}, 0) polices := make([][]string, 0) for _, menu := range mList { for _, api := range menu.SysApi { if mp[model.RoleKey+"-"+api.Path+"-"+api.Action] != "" { mp[model.RoleKey+"-"+api.Path+"-"+api.Action] = "" //_, err = cb.AddNamedPolicy("p", model.RoleKey, api.Path, api.Action) polices = append(polices, []string{model.RoleKey, api.Path, api.Action}) } } } if len(polices) <= 0 { return nil } // 写入 sys_casbin_rule 权限表里 当前角色数据的记录 _, err = cb.AddNamedPolicies("p", polices) if err != nil { return err } return nil } // Remove 删除SysRole func (e *SysRoleService) Remove(c *dto.SysRoleDeleteReq, cb *casbin.SyncedEnforcer, roleKey string) error { var err error tx := e.Orm if config.DatabaseConfig.Driver != "sqlite3" { tx := e.Orm.Begin() defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() } var model = models.SysRole{} tx.Preload("Menus").Preload("Orgs").First(&model, c.GetId()) if err = checkRoleAllowed(model, roleKey); err != nil { return err } //删除 SysRoleService 时,同时删除角色所有 关联其它表 记录 (Menus 和 Orgs) db := tx.Select(clause.Associations).Delete(&model) if err = db.Error; err != nil { e.Log.Errorf("db error:%s", err) return err } if db.RowsAffected == 0 { return errors.New("无权更新该数据") } // 清除 sys_casbin_rule 权限表里 当前角色的所有记录 _, _ = cb.RemoveFilteredPolicy(0, model.RoleKey) return nil } // 检查是否可以操作role func checkRoleAllowed(role models.SysRole, roleKey string) error { if role.RoleKey == "admin" { return errors.New("不能修改删除admin角色") } if role.Flag == "static" && roleKey != "admin" { return errors.New("内置角色不能修改删除") } return nil } // GetRoleMenuId 获取角色对应的菜单ids func (e *SysRoleService) GetRoleMenuId(roleId int) ([]int, error) { menuIds := make([]int, 0) model := models.SysRole{} model.RoleId = roleId if err := e.Orm.Model(&model).Preload("Menus").First(&model).Error; err != nil { return nil, err } l := *model.Menus for i := 0; i < len(l); i++ { menuIds = append(menuIds, l[i].MenuId) } return menuIds, nil } func (e *SysRoleService) UpdateDataScope(c *dto.RoleDataScopeReq) *SysRoleService { var err error tx := e.Orm if config.DatabaseConfig.Driver != "sqlite3" { tx := e.Orm.Begin() defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() } var dList = make([]models.SysOrg, 0) var model = models.SysRole{} tx.Preload("Orgs").First(&model, c.RoleId) tx.Where("org_id in ?", c.OrgIds).Find(&dList) // 删除SysRole 和 SysOrgService 的关联关系 err = tx.Model(&model).Association("Orgs").Delete(model.Orgs) if err != nil { e.Log.Errorf("delete Orgs error:%s", err) _ = e.AddError(err) return e } c.Generate(&model) model.Orgs = &dList // 更新关联的数据,使用 FullSaveAssociations 模式 db := tx.Model(&model).Session(&gorm.Session{FullSaveAssociations: true}).Debug().Save(&model) if err = db.Error; err != nil { e.Log.Errorf("db error:%s", err) _ = e.AddError(err) return e } if db.RowsAffected == 0 { _ = e.AddError(errors.New("无权更新该数据")) return e } return e } // UpdateStatus 修改SysRole对象status func (e *SysRoleService) UpdateStatus(c *dto.UpdateStatusReq) error { var err error tx := e.Orm if config.DatabaseConfig.Driver != "sqlite3" { tx := e.Orm.Begin() defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() } var model = models.SysRole{} tx.First(&model, c.GetId()) c.Generate(&model) // 更新关联的数据,使用 FullSaveAssociations 模式 db := tx.Session(&gorm.Session{FullSaveAssociations: true}).Debug().Save(&model) if err = db.Error; err != nil { e.Log.Errorf("db error:%s", err) return err } if db.RowsAffected == 0 { return errors.New("无权更新该数据") } return nil } // GetWithName 获取SysRole对象 func (e *SysRoleService) GetWithName(d *dto.SysRoleByName, model *models.SysRole) *SysRoleService { var err error db := e.Orm.Where("role_name = ?", d.RoleName).First(model) err = db.Error if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { err = errors.New("查看对象不存在或无权查看") e.Log.Errorf("db error:%s", err) _ = e.AddError(err) return e } if err != nil { e.Log.Errorf("db error:%s", err) _ = e.AddError(err) return e } model.MenuIds, err = e.GetRoleMenuId(model.RoleId) if err != nil { e.Log.Errorf("get menuIds error, %s", err.Error()) _ = e.AddError(err) return e } return e } // GetById 获取SysRole对象 func (e *SysRoleService) GetById(roleId int) ([]string, error) { permissions := make([]string, 0) model := models.SysRole{} model.RoleId = roleId if err := e.Orm.Model(&model).Preload("Menus").First(&model).Error; err != nil { return nil, err } l := *model.Menus for i := 0; i < len(l); i++ { if l[i].Permission != "" { permissions = append(permissions, l[i].Permission) } } return permissions, nil }