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 }