Files
kra-oa/internal/data/authority.go
T

284 lines
9.8 KiB
Go

package data
import (
"context"
"errors"
"strconv"
"strings"
"kra/internal/biz"
"gorm.io/gorm"
)
func (r *accessRepo) CreateAuthority(ctx context.Context, value *biz.Authority) error {
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
var count int64
if err := tx.Model(&authorityPO{}).Where("authority_id = ?", value.AuthorityID).Count(&count).Error; err != nil {
return err
}
if count > 0 {
return errors.New("存在相同角色id")
}
if value.DefaultRouter == "" {
value.DefaultRouter = "dashboard"
}
if err := tx.Create(&authorityPO{AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, DataScope: value.DataScope, DefaultRouter: value.DefaultRouter}).Error; err != nil {
return err
}
var dashboard menuPO
if err := tx.Where("name = ?", "dashboard").First(&dashboard).Error; err == nil {
if err = tx.Create(&authorityMenuPO{SysAuthorityAuthorityID: value.AuthorityID, SysBaseMenuID: dashboard.ID}).Error; err != nil {
return err
}
}
defaults := []struct{ path, method string }{{"/menu/getMenu", "POST"}, {"/jwt/jsonInBlacklist", "POST"}, {"/user/changePassword", "POST"}, {"/user/setUserAuthority", "POST"}, {"/user/getUserInfo", "GET"}, {"/user/setSelfInfo", "PUT"}, {"/fileUploadAndDownload/upload", "POST"}, {"/sysDictionary/findSysDictionary", "GET"}}
for _, item := range defaults {
var api apiPO
if err := tx.Where("path = ? AND method = ?", item.path, item.method).First(&api).Error; err == nil {
if err = tx.Create(&authorityAPIPO{AuthorityID: value.AuthorityID, APIID: api.ID}).Error; err != nil {
return err
}
}
}
return nil
})
}
func (r *accessRepo) CopyAuthority(ctx context.Context, sourceID uint, value *biz.Authority) error {
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
var count int64
if err := tx.Model(&authorityPO{}).Where("authority_id = ?", value.AuthorityID).Count(&count).Error; err != nil {
return err
}
if count != 0 {
return errors.New("存在相同角色id")
}
if err := tx.Create(&authorityPO{AuthorityID: value.AuthorityID, AuthorityName: value.AuthorityName, ParentID: value.ParentID, DataScope: value.DataScope, DefaultRouter: value.DefaultRouter}).Error; err != nil {
return err
}
copyLinks := func(table string, destination any, columns map[string]any) error {
return tx.Table(table).Where(columns).Find(destination).Error
}
var menus []authorityMenuPO
if err := copyLinks("sys_authority_menus", &menus, map[string]any{"sys_authority_authority_id": sourceID}); err != nil {
return err
}
for i := range menus {
menus[i].SysAuthorityAuthorityID = value.AuthorityID
}
if len(menus) > 0 {
if err := tx.Create(&menus).Error; err != nil {
return err
}
}
var apis []authorityAPIPO
if err := copyLinks("sys_authority_apis", &apis, map[string]any{"authority_id": sourceID}); err != nil {
return err
}
for i := range apis {
apis[i].AuthorityID = value.AuthorityID
}
if len(apis) > 0 {
if err := tx.Create(&apis).Error; err != nil {
return err
}
}
var buttons []authorityButtonPO
if err := copyLinks("sys_authority_btns", &buttons, map[string]any{"authority_id": sourceID}); err != nil {
return err
}
for i := range buttons {
buttons[i].AuthorityID = value.AuthorityID
}
if len(buttons) > 0 {
if err := tx.Create(&buttons).Error; err != nil {
return err
}
}
var departments []authorityDepartmentPO
if err := copyLinks("sys_authority_departments", &departments, map[string]any{"authority_id": sourceID}); err != nil {
return err
}
for i := range departments {
departments[i].AuthorityID = value.AuthorityID
}
if len(departments) > 0 {
return tx.Create(&departments).Error
}
return nil
})
}
func (r *accessRepo) UpdateAuthority(ctx context.Context, value *biz.Authority) error {
return r.data.gormDB.WithContext(ctx).Model(&authorityPO{}).Where("authority_id = ?", value.AuthorityID).Updates(map[string]any{"authority_name": value.AuthorityName, "parent_id": value.ParentID, "data_scope": value.DataScope, "default_router": value.DefaultRouter}).Error
}
func (r *accessRepo) DeleteAuthority(ctx context.Context, id uint) error {
if id == 888 {
return errors.New("不能删除超级管理员")
}
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
var users, children int64
if err := tx.Model(&userAuthorityPO{}).Where("sys_authority_authority_id = ?", id).Count(&users).Error; err != nil {
return err
}
if users > 0 {
return errors.New("此角色有用户正在使用禁止删除")
}
if err := tx.Model(&userPO{}).Where("authority_id = ?", id).Count(&users).Error; err != nil {
return err
}
if users > 0 {
return errors.New("此角色有用户正在使用禁止删除")
}
if err := tx.Model(&authorityPO{}).Where("parent_id = ?", id).Count(&children).Error; err != nil {
return err
}
if children > 0 {
return errors.New("此角色存在子角色不允许删除")
}
if err := tx.Where("sys_authority_authority_id = ?", id).Delete(&authorityMenuPO{}).Error; err != nil {
return err
}
if err := tx.Where("authority_id = ?", id).Delete(&authorityAPIPO{}).Error; err != nil {
return err
}
if err := tx.Where("authority_id = ?", id).Delete(&authorityButtonPO{}).Error; err != nil {
return err
}
if err := tx.Where("authority_id = ?", id).Delete(&authorityDepartmentPO{}).Error; err != nil {
return err
}
return tx.Delete(&authorityPO{}, "authority_id = ?", id).Error
})
}
func (r *accessRepo) ListAuthorities(ctx context.Context) ([]*biz.Authority, error) {
var pos []authorityPO
if err := r.data.gormDB.WithContext(ctx).Order("authority_id").Find(&pos).Error; err != nil {
return nil, err
}
out := make([]*biz.Authority, 0, len(pos))
for _, po := range pos {
v := toBizAuthority(po)
out = append(out, &v)
}
return out, nil
}
func (r *accessRepo) SetAuthorityUsers(ctx context.Context, id uint, ids []uint) error {
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
var oldIDs []uint
if err := tx.Model(&userAuthorityPO{}).Where("sys_authority_authority_id = ?", id).Pluck("sys_user_id", &oldIDs).Error; err != nil {
return err
}
if err := tx.Where("sys_authority_authority_id = ?", id).Delete(&userAuthorityPO{}).Error; err != nil {
return err
}
links := make([]userAuthorityPO, 0, len(ids))
for _, uid := range ids {
links = append(links, userAuthorityPO{SysUserID: uid, SysAuthorityAuthorityID: id})
}
if len(links) > 0 {
if err := tx.Create(&links).Error; err != nil {
return err
}
}
selected := map[uint]bool{}
for _, uid := range ids {
selected[uid] = true
}
for _, uid := range oldIDs {
if selected[uid] {
continue
}
var user userPO
if err := tx.First(&user, uid).Error; err == nil && user.AuthorityID == id {
if err = tx.Model(&user).Update("authority_id", 888).Error; err != nil {
return err
}
fallback := userAuthorityPO{SysUserID: uid, SysAuthorityAuthorityID: 888}
if err = tx.FirstOrCreate(&fallback, fallback).Error; err != nil {
return err
}
}
}
return nil
})
}
func (r *accessRepo) AuthorityUserIDs(ctx context.Context, id uint) ([]uint, error) {
var ids []uint
err := r.data.gormDB.WithContext(ctx).Model(&userAuthorityPO{}).Where("sys_authority_authority_id = ?", id).Pluck("sys_user_id", &ids).Error
return ids, err
}
func (r *accessRepo) SetDataScope(ctx context.Context, id uint, scope int, deptIDs []uint) error {
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
if err := tx.Model(&authorityPO{}).Where("authority_id = ?", id).Update("data_scope", scope).Error; err != nil {
return err
}
if err := tx.Where("authority_id = ?", id).Delete(&authorityDepartmentPO{}).Error; err != nil {
return err
}
links := make([]authorityDepartmentPO, 0, len(deptIDs))
for _, did := range deptIDs {
links = append(links, authorityDepartmentPO{AuthorityID: id, DepartmentID: did})
}
if len(links) > 0 {
return tx.Create(&links).Error
}
return nil
})
}
func (r *accessRepo) DataScopeDepartmentIDs(ctx context.Context, id uint) ([]uint, error) {
var ids []uint
err := r.data.gormDB.WithContext(ctx).Model(&authorityDepartmentPO{}).Where("authority_id = ?", id).Pluck("department_id", &ids).Error
return ids, err
}
func (r *accessRepo) ResolveDataScope(ctx context.Context, authorityID, userID uint) (biz.DataScope, error) {
if authorityID == 888 {
return biz.DataScope{All: true}, nil
}
var authority authorityPO
if err := r.data.gormDB.WithContext(ctx).First(&authority, "authority_id = ?", authorityID).Error; err != nil {
return biz.DataScope{}, err
}
if authority.DataScope == 1 {
return biz.DataScope{All: true}, nil
}
if authority.DataScope == 4 {
return biz.DataScope{OwnerUserID: userID}, nil
}
var ids []uint
if authority.DataScope == 5 {
var err error
ids, err = r.DataScopeDepartmentIDs(ctx, authorityID)
if err != nil {
return biz.DataScope{}, err
}
} else {
if err := r.data.gormDB.WithContext(ctx).Model(&userDepartmentPO{}).Where("sys_user_id = ?", userID).Pluck("sys_department_id", &ids).Error; err != nil {
return biz.DataScope{}, err
}
if authority.DataScope == 2 && len(ids) > 0 {
var departments []departmentPO
if err := r.data.gormDB.WithContext(ctx).Find(&departments).Error; err != nil {
return biz.DataScope{}, err
}
selected := make(map[uint]bool, len(ids))
for _, id := range ids {
selected[id] = true
}
for _, department := range departments {
for _, part := range strings.Split(department.Ancestors, ",") {
value, _ := strconv.ParseUint(part, 10, 64)
if selected[uint(value)] {
selected[department.ID] = true
break
}
}
}
ids = ids[:0]
for id := range selected {
ids = append(ids, id)
}
}
}
return biz.DataScope{DepartmentIDs: ids}, nil
}