This commit is contained in:
Yvan
2026-08-18 15:04:07 +08:00
parent 10ccc005be
commit 1ef8ecb7b2
42 changed files with 3027 additions and 296 deletions
+75 -22
View File
@@ -263,27 +263,8 @@ func (r *menuRepo) SetAuthorityMenus(ctx context.Context, id uint, ids []uint) e
if err := r.data.gormDB.WithContext(ctx).Where("authority_id = ?", id).First(&authorityPO{}).Error; err != nil {
return err
}
config := r.data.runtime.Admin()
if actor, ok := biz.ActorFromContext(ctx); ok && config != nil && config.System != nil && config.System.UseStrictAuth {
var authority authorityPO
if err := r.data.gormDB.WithContext(ctx).Where("authority_id = ?", actor.AuthorityID).First(&authority).Error; err != nil {
return err
}
if authority.ParentID != nil && *authority.ParentID != 0 {
var allowedIDs []uint
if err := r.data.gormDB.WithContext(ctx).Model(&authorityMenuPO{}).Where("sys_authority_authority_id = ?", actor.AuthorityID).Pluck("sys_base_menu_id", &allowedIDs).Error; err != nil {
return err
}
allowed := make(map[uint]bool, len(allowedIDs))
for _, menuID := range allowedIDs {
allowed[menuID] = true
}
for _, menuID := range ids {
if !allowed[menuID] {
return errors.New("添加失败,请勿跨级操作")
}
}
}
if err := r.checkMenuAssignmentAuth(ctx, ids); err != nil {
return err
}
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Where("sys_authority_authority_id = ?", id).Delete(&authorityMenuPO{}).Error; err != nil {
@@ -346,8 +327,29 @@ func (r *menuRepo) DefaultRouterRoleIDs(ctx context.Context, id uint) ([]uint, e
}
func (r *menuRepo) SetMenuRoles(ctx context.Context, id uint, ids []uint) error {
access := &authorityAccessRepo{data: r.data}
_, allowedAuthorities, strict, err := access.strictAuthorityAccess(ctx)
if err != nil {
return err
}
if err := r.checkMenuAssignmentAuth(ctx, []uint{id}); err != nil {
return err
}
if strict {
for _, authorityID := range ids {
if !allowedAuthorities[authorityID] {
return errors.New("您提交的角色ID不合法")
}
}
}
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Where("sys_base_menu_id = ?", id).Delete(&authorityMenuPO{}).Error; err != nil {
if strict {
if len(allowedAuthorities) > 0 {
if err := tx.Where("sys_base_menu_id = ? AND sys_authority_authority_id IN ?", id, authorityIDs(allowedAuthorities)).Delete(&authorityMenuPO{}).Error; err != nil {
return err
}
}
} else if err := tx.Where("sys_base_menu_id = ?", id).Delete(&authorityMenuPO{}).Error; err != nil {
return err
}
links := make([]authorityMenuPO, 0, len(ids))
@@ -360,3 +362,54 @@ func (r *menuRepo) SetMenuRoles(ctx context.Context, id uint, ids []uint) error
return nil
})
}
func authorityIDs(allowed map[uint]bool) []uint {
ids := make([]uint, 0, len(allowed))
for id := range allowed {
ids = append(ids, id)
}
return ids
}
func (r *menuRepo) checkMenuAssignmentAuth(ctx context.Context, menuIDs []uint) error {
actor, allowedAuthorities, strict, err := (&authorityAccessRepo{data: r.data}).strictAuthorityAccess(ctx)
if err != nil || !strict {
return err
}
return checkMenuAssignment(r.data.gormDB.WithContext(ctx), actor.AuthorityID, allowedAuthorities[actor.AuthorityID], menuIDs)
}
func checkMenuAssignment(db *gorm.DB, actorID uint, root bool, menuIDs []uint) error {
if len(menuIDs) == 0 {
return nil
}
unique := make(map[uint]struct{}, len(menuIDs))
for _, menuID := range menuIDs {
unique[menuID] = struct{}{}
}
if root {
var count int64
if err := db.Model(&menuPO{}).Where("id IN ?", menuIDs).Count(&count).Error; err != nil {
return err
}
if count != int64(len(unique)) {
return errors.New("添加失败,菜单不存在")
}
return nil
}
var allowedIDs []uint
if err := db.Model(&authorityMenuPO{}).
Where("sys_authority_authority_id = ?", actorID).Pluck("sys_base_menu_id", &allowedIDs).Error; err != nil {
return err
}
allowed := make(map[uint]bool, len(allowedIDs))
for _, menuID := range allowedIDs {
allowed[menuID] = true
}
for menuID := range unique {
if !allowed[menuID] {
return errors.New("添加失败,请勿跨级操作")
}
}
return nil
}