353 lines
8.6 KiB
Go
353 lines
8.6 KiB
Go
package service
|
||
|
||
import (
|
||
"errors"
|
||
|
||
"github.com/go-admin-team/go-admin-core/sdk/config"
|
||
"gorm.io/gorm/clause"
|
||
|
||
"github.com/casbin/casbin/v2"
|
||
|
||
"github.com/go-admin-team/go-admin-core/sdk/service"
|
||
"gorm.io/gorm"
|
||
|
||
"go-admin/app/admin/models"
|
||
"go-admin/app/admin/service/dto"
|
||
cDto "go-admin/common/dto"
|
||
)
|
||
|
||
type SysRole struct {
|
||
service.Service
|
||
}
|
||
|
||
// GetPage 获取SysRole列表
|
||
func (e *SysRole) GetPage(c *dto.SysRoleGetPageReq, list *[]models.SysRole, count *int64) error {
|
||
var err error
|
||
var data models.SysRole
|
||
|
||
err = e.Orm.Model(&data).Preload("SysMenu").
|
||
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 *SysRole) 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 *SysRole) 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.SysMenu = 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 *SysRole) Update(c *dto.SysRoleUpdateReq, cb *casbin.SyncedEnforcer) 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("SysMenu").First(&model, c.GetId())
|
||
tx.Preload("SysApi").Where("menu_id in ?", c.MenuIds).Find(&mlist)
|
||
err = tx.Model(&model).Association("SysMenu").Delete(model.SysMenu)
|
||
if err != nil {
|
||
e.Log.Errorf("delete policy error:%s", err)
|
||
return err
|
||
}
|
||
c.Generate(&model)
|
||
model.SysMenu = &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 *SysRole) Remove(c *dto.SysRoleDeleteReq, cb *casbin.SyncedEnforcer) 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("SysMenu").Preload("SysDept").First(&model, c.GetId())
|
||
//删除 SysRole 时,同时删除角色所有 关联其它表 记录 (SysMenu 和 SysMenu)
|
||
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
|
||
}
|
||
|
||
// GetRoleMenuId 获取角色对应的菜单ids
|
||
func (e *SysRole) GetRoleMenuId(roleId int) ([]int, error) {
|
||
menuIds := make([]int, 0)
|
||
model := models.SysRole{}
|
||
model.RoleId = roleId
|
||
if err := e.Orm.Model(&model).Preload("SysMenu").First(&model).Error; err != nil {
|
||
return nil, err
|
||
}
|
||
l := *model.SysMenu
|
||
for i := 0; i < len(l); i++ {
|
||
menuIds = append(menuIds, l[i].MenuId)
|
||
}
|
||
return menuIds, nil
|
||
}
|
||
|
||
func (e *SysRole) UpdateDataScope(c *dto.RoleDataScopeReq) *SysRole {
|
||
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.SysDept, 0)
|
||
var model = models.SysRole{}
|
||
tx.Preload("SysDept").First(&model, c.RoleId)
|
||
tx.Where("dept_id in ?", c.DeptIds).Find(&dlist)
|
||
// 删除SysRole 和 SysDept 的关联关系
|
||
err = tx.Model(&model).Association("SysDept").Delete(model.SysDept)
|
||
if err != nil {
|
||
e.Log.Errorf("delete SysDept error:%s", err)
|
||
_ = e.AddError(err)
|
||
return e
|
||
}
|
||
c.Generate(&model)
|
||
model.SysDept = 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 *SysRole) 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 *SysRole) GetWithName(d *dto.SysRoleByName, model *models.SysRole) *SysRole {
|
||
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 *SysRole) GetById(roleId int) ([]string, error) {
|
||
permissions := make([]string, 0)
|
||
model := models.SysRole{}
|
||
model.RoleId = roleId
|
||
if err := e.Orm.Model(&model).Preload("SysMenu").First(&model).Error; err != nil {
|
||
return nil, err
|
||
}
|
||
l := *model.SysMenu
|
||
for i := 0; i < len(l); i++ {
|
||
if l[i].Permission != "" {
|
||
permissions = append(permissions, l[i].Permission)
|
||
}
|
||
}
|
||
return permissions, nil
|
||
}
|