github.com/SupenBysz/gf-admin-community@v0.7.4/internal/logic/sys_permission/sys_permission.go (about) 1 package sys_permission 2 3 import ( 4 "context" 5 "fmt" 6 "github.com/SupenBysz/gf-admin-community/sys_consts" 7 "github.com/SupenBysz/gf-admin-community/sys_model" 8 "github.com/SupenBysz/gf-admin-community/sys_model/sys_dao" 9 "github.com/SupenBysz/gf-admin-community/sys_model/sys_do" 10 "github.com/SupenBysz/gf-admin-community/sys_model/sys_entity" 11 "github.com/SupenBysz/gf-admin-community/sys_service" 12 "github.com/gogf/gf/v2/container/garray" 13 "github.com/gogf/gf/v2/container/gmap" 14 "github.com/gogf/gf/v2/database/gdb" 15 "github.com/gogf/gf/v2/errors/gcode" 16 "github.com/gogf/gf/v2/errors/gerror" 17 "github.com/gogf/gf/v2/os/gtime" 18 "github.com/gogf/gf/v2/text/gstr" 19 "github.com/gogf/gf/v2/util/gconv" 20 "github.com/kysion/base-library/base_model" 21 "github.com/kysion/base-library/utility/base_permission" 22 "github.com/kysion/base-library/utility/base_tree" 23 "github.com/kysion/base-library/utility/daoctl" 24 "github.com/kysion/base-library/utility/kconv" 25 "github.com/yitter/idgenerator-go/idgen" 26 "sort" 27 ) 28 29 type sSysPermission struct { 30 //mapStrItems *kmap.HashMap[string, *sys_entity.SysPermission] 31 //mapInt64Items *kmap.HashMap[int64, *sys_entity.SysPermission] 32 } 33 34 func init() { 35 //base_permission.Factory = Factory 36 37 sys_service.RegisterSysPermission(New()) 38 } 39 40 // 41 //func Factory() base_permission.IPermission { 42 // return &sys_model.SysPermissionTree{} 43 //} 44 45 // New sSysPermission 权限控制逻辑实现 46 func New() *sSysPermission { 47 return &sSysPermission{} 48 } 49 50 // GetPermissionById 根据权限ID获取权限信息 51 func (s *sSysPermission) GetPermissionById(ctx context.Context, permissionId int64) (*sys_entity.SysPermission, error) { 52 //s.initInnerCacheItems(ctx) 53 //return s.mapInt64Items.Get(permissionId), nil 54 55 return daoctl.GetByIdWithError[sys_entity.SysPermission](sys_dao.SysPermission.Ctx(ctx), permissionId) 56 } 57 58 // GetPermissionByIdentifier 根据权限标识符Identifier获取权限信息 59 func (s *sSysPermission) GetPermissionByIdentifier(ctx context.Context, identifier string) (*sys_entity.SysPermission, error) { 60 return daoctl.ScanWithError[sys_entity.SysPermission](sys_dao.SysPermission.Ctx(ctx).Where(sys_do.SysPermission{Identifier: identifier})) 61 } 62 63 // QueryPermissionList 查询权限列表 64 func (s *sSysPermission) QueryPermissionList(ctx context.Context, info base_model.SearchParams) (*sys_model.SysPermissionInfoListRes, error) { 65 if len(info.OrderBy) != 0 { 66 hasSort := false 67 for _, item := range info.OrderBy { 68 if item.Field == sys_dao.SysPermission.Columns().Sort { 69 hasSort = true 70 break 71 } 72 } 73 74 if hasSort == false { 75 orderByData := append(make([]base_model.OrderBy, 0), base_model.OrderBy{ 76 Field: sys_dao.SysPermission.Columns().Sort, 77 Sort: "ASC", 78 }) 79 80 orderByData = append(orderByData, info.OrderBy[0:]...) 81 82 info.OrderBy = orderByData 83 84 } 85 } else { 86 info.OrderBy = append(make([]base_model.OrderBy, 0), base_model.OrderBy{ 87 Field: sys_dao.SysPermission.Columns().Sort, 88 Sort: "ASC", 89 }) 90 } 91 92 // IsExport为true,数据都放在一页,不分页返回 93 result, err := daoctl.Query[*sys_entity.SysPermission](sys_dao.SysPermission.Ctx(ctx), &info, true) 94 95 if err != nil { 96 return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "权限信息查询失败", sys_dao.SysPermission.Table()) 97 } 98 99 return (*sys_model.SysPermissionInfoListRes)(result), err 100 } 101 102 // GetPermissionsByResource 根据资源获取权限Ids, 资源一般为用户ID、角色ID,员工ID等 103 func (s *sSysPermission) GetPermissionsByResource(ctx context.Context, resource string) ([]int64, error) { 104 permissionItems, err := sys_service.Casbin().Enforcer().GetImplicitPermissionsForUser(resource, sys_consts.CasbinDomain) 105 if err != nil { 106 return make([]int64, 0), sys_service.SysLogs().ErrorSimple(ctx, err, "权限查询失败", sys_dao.SysPermission.Table()) 107 } 108 109 permissionList, err := daoctl.Query[sys_entity.SysPermission](sys_dao.SysPermission.Ctx(ctx), nil, true) 110 if err != nil { 111 return make([]int64, 0), sys_service.SysLogs().ErrorSimple(ctx, err, "权限查询失败", sys_dao.SysPermission.Table()) 112 } 113 114 permissionIds := garray.New() 115 for _, v := range permissionList.Records { 116 for _, items := range permissionItems { 117 if len(items) >= 3 { 118 if gstr.IsNumeric(items[2]) { 119 if v.Id == gconv.Int64(items[2]) { 120 permissionIds.Append(gconv.Int64(items[2])) 121 } 122 } else if v.Identifier == items[2] { 123 permissionIds.Append(v.Id) 124 } 125 } 126 } 127 } 128 129 return gconv.Int64s(permissionIds.Unique().Slice()), nil 130 } 131 132 //func (s *sSysPermission) initInnerCacheItems(ctx context.Context) { 133 // if s.mapInt64Items.Size() == s.mapStrItems.Size() && s.mapStrItems.Size() > 0 { 134 // return 135 // } 136 // 137 // items := daoctl.Scan[[]*sys_entity.SysPermission]( 138 // sys_dao.SysPermission.Ctx(ctx). 139 // OrderAsc(sys_dao.SysPermission.Columns().ParentId). 140 // OrderAsc(sys_dao.SysPermission.Columns().Sort), 141 // ) 142 // s.mapStrItems.Clear() 143 // s.mapInt64Items.Clear() 144 // for _, sysPermission := range *items { 145 // s.mapStrItems.Set(sysPermission.Identifier, sysPermission) 146 // s.mapInt64Items.Set(sysPermission.Id, sysPermission) 147 // } 148 //} 149 150 // GetPermissionList 根据ID获取下级权限信息,返回列表 151 func (s *sSysPermission) GetPermissionList(ctx context.Context, parentId int64, IsRecursive bool) ([]*sys_entity.SysPermission, error) { 152 dataArr := make([]*sys_entity.SysPermission, 0) 153 permissionList, err := daoctl.Query[sys_entity.SysPermission](sys_dao.SysPermission.Ctx(ctx).Where(sys_do.SysPermission{ParentId: parentId}), nil, true) 154 if err != nil { 155 return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "权限查询失败", sys_dao.SysPermission.Table()) 156 } 157 158 gconv.Struct(permissionList.Records, &dataArr) 159 160 // 161 //for _, v := range permissionList.Records { 162 // if v.IsShow == 1 && v.ParentId == parentId { 163 // dataArr = append(dataArr, &v) 164 // } 165 // 166 //} 167 168 // 如果需要返回下级,则递归加载 169 if IsRecursive == true && len(dataArr) > 0 { 170 for _, sysPermissionItem := range dataArr { 171 var children []*sys_entity.SysPermission 172 children, err := s.GetPermissionList(ctx, sysPermissionItem.Id, IsRecursive) 173 174 if err != nil { 175 return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "查询失败", sys_dao.SysPermission.Table()) 176 } 177 178 if children == nil || len(children) <= 0 { 179 continue 180 } 181 182 for _, sysOrganization := range children { 183 dataArr = append(dataArr, sysOrganization) 184 } 185 } 186 } 187 188 sort.Slice(dataArr, func(i, j int) bool { 189 return dataArr[i].Sort < dataArr[j].Sort 190 }) 191 192 return dataArr, nil 193 } 194 195 // GetPermissionTree 根据ID获取下级权限信息,返回列表树 196 func (s *sSysPermission) GetPermissionTree(ctx context.Context, parentId int64, permissionType ...int) ([]base_permission.IPermission, error) { 197 selectDao := sys_dao.SysPermission.Ctx(ctx) 198 if len(permissionType) > 0 && permissionType[0] != 0 { 199 selectDao = selectDao.Where(sys_do.SysPermission{Type: permissionType[0]}) 200 } 201 202 items, err := daoctl.Query[*sys_model.SysPermissionTree](selectDao, nil, true) 203 204 var itemRes []base_permission.IPermission 205 for _, record := range items.Records { 206 itemRes = append(itemRes, record) 207 } 208 209 if err != nil { 210 return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "查询失败", sys_dao.SysPermission.Table()) 211 } 212 // items.Records 代表每一项的权限List, &sys_model.SysPermissionTree{}实现了Tree接口, 213 response := base_tree.ToTree[base_permission.IPermission](itemRes, &sys_model.SysPermissionTree{}) 214 215 //result, err := s.GetPermissionList(ctx, parentId, false) 216 // 217 //if err != nil { 218 // return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "查询失败", sys_dao.SysPermission.Table()) 219 //} 220 // 221 //response := make([]*sys_model.SysPermissionTree, 0) 222 // 223 //// 有数据,则递归加载 224 //if len(result) > 0 { 225 // for _, sysPermissionItem := range result { 226 // 227 // item := &sys_model.SysPermissionTree{} 228 // gconv.Struct(sysPermissionItem, &item) 229 // 230 // item.Children, err = s.GetPermissionTree(ctx, sysPermissionItem.Id) 231 // if err != nil { 232 // //wg.Done() 233 // return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "查询失败", sys_dao.SysPermission.Table()) 234 // //return 235 // } 236 // response = append(append(make([]*sys_model.SysPermissionTree, 0), item), response...) 237 // } 238 // 239 //} 240 // 241 return response, nil 242 } 243 244 func (s *sSysPermission) CreatePermission(ctx context.Context, info sys_model.SysPermission) (*sys_entity.SysPermission, error) { 245 return s.SavePermission(ctx, info) 246 } 247 248 func (s *sSysPermission) UpdatePermission(ctx context.Context, info *sys_model.UpdateSysPermission) (*sys_entity.SysPermission, error) { 249 if info.Id <= 0 { 250 return nil, sys_service.SysLogs().ErrorSimple(ctx, gerror.NewCode(gcode.CodeNil, "ID参数错误"), "", sys_dao.SysPermission.Table()) 251 } 252 253 permission, err := s.GetPermissionById(ctx, info.Id) 254 255 if err != nil { 256 return nil, sys_service.SysLogs().ErrorSimple(ctx, gerror.NewCode(gcode.CodeNil, "权限不存在"), "", sys_dao.SysPermission.Table()) 257 } 258 259 data := kconv.Struct(info, &sys_do.SysPermission{}) 260 261 { 262 if info.Name != nil { 263 // 同一分类下,排除重名问题 264 model := sys_dao.SysPermission.Ctx(ctx). 265 Where(sys_do.SysPermission{ 266 ParentId: permission.ParentId, 267 Name: info.Name, 268 }) 269 270 if info.Id > 0 { 271 model = model.WhereNot(sys_dao.SysPermission.Columns().Id, info.Id) 272 } 273 274 count, _ := model.Count() 275 276 if count > 0 { 277 return nil, sys_service.SysLogs().ErrorSimple(ctx, gerror.NewCode(gcode.CodeNil, "名称在当前分类下已存在,请修改后再试"), "", sys_dao.SysPermission.Table()) 278 } 279 } 280 } 281 282 err = sys_dao.SysPermission.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { 283 data.UpdatedAt = gtime.Now() 284 data.ParentId = nil // 父ID不能修改 285 data.Id = nil 286 _, err = sys_dao.SysPermission.Ctx(ctx). 287 Where(sys_do.SysPermission{Id: info.Id}).OmitNilData().Update(data) 288 289 if err != nil { 290 return sys_service.SysLogs().ErrorSimple(ctx, err, "权限信息更新失败", sys_dao.SysPermission.Table()) 291 } 292 return nil 293 }) 294 295 if err != nil { 296 return nil, err 297 } 298 299 return s.GetPermissionById(ctx, info.Id) 300 } 301 302 // SetPermissionsByResource 设置资源权限 303 func (s *sSysPermission) SetPermissionsByResource(ctx context.Context, resourceIdentifier string, permissionIds []int64) (response bool, err error) { 304 var items []*sys_entity.SysPermission 305 permissionList, err := daoctl.Query[sys_entity.SysPermission](sys_dao.SysPermission.Ctx(ctx), nil, true) 306 307 if len(permissionIds) > 0 { 308 for _, id := range permissionIds { 309 for _, v := range permissionList.Records { 310 if id == v.Id { 311 items = append(items, &v) 312 break 313 } 314 } 315 } 316 } 317 318 err = sys_dao.SysCasbin.Ctx(ctx).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { 319 { 320 // 先清除资源所有权限 321 _, err = sys_service.Casbin().DeletePermissionsForUser(resourceIdentifier) 322 if len(permissionIds) <= 0 { 323 return err 324 } 325 } 326 327 // 重新赋予资源新的权限 328 for _, item := range items { 329 permissionResourceKey := gconv.String(item.Id) 330 if item.MatchMode > 0 { 331 permissionResourceKey = item.Identifier 332 } 333 ret, err := sys_service.Casbin().Enforcer().AddPermissionForUser(resourceIdentifier, sys_consts.CasbinDomain, permissionResourceKey, "allow") 334 if err != nil || ret == false { 335 return err 336 } 337 } 338 return nil 339 }) 340 if err != nil { 341 return false, sys_service.SysLogs().ErrorSimple(ctx, err, "设置用户权限失败", sys_dao.SysRole.Table()) 342 } 343 344 return true, nil 345 } 346 347 // ImportPermissionTree 导入权限,如果存在则忽略,递归导入权限 348 func (s *sSysPermission) ImportPermissionTree(ctx context.Context, permissionTreeArr []base_permission.IPermission, parent base_permission.IPermission) error { // 在项目启动处进行调用,permissionTreeArr就是权限树数组,parent是父级权限id 349 if len(permissionTreeArr) <= 0 { 350 return nil 351 } 352 353 for i, permissionTree := range permissionTreeArr { 354 if parent != nil { 355 // 设置父级ID 356 permissionTree.SetParentId(parent.GetId()) 357 // 继承父级权限类型 358 permissionTree.SetType(parent.GetType()) 359 // 继承父级权限是否显示 360 permissionTree.SetIsShow(parent.GetIsShow()) 361 // 拼接上父级权限标识符 例如(User::View ...) 362 permissionTree.SetIdentifier(parent.GetIdentifier() + "::" + permissionTree.GetIdentifier()) 363 // 拼接上父级的匹配模式 (例如:0ID匹配,1标识符匹配) 364 permissionTree.SetMatchMode(parent.GetMatchMode()) 365 } 366 // 排序字段 367 permissionTree.SetSort(i) 368 369 // 查询权限数据是否存在 370 371 identifier, _ := s.GetPermissionByIdentifier(ctx, permissionTree.GetIdentifier()) 372 has := identifier != nil 373 374 // 判断权限数据是否存在,不存在则插入数据 375 if !has { 376 if permissionTree.GetId() == 0 { 377 permissionTree.SetId(idgen.NextId()) 378 } 379 result, err := sys_dao.SysPermission.Ctx(ctx).Insert(permissionTree) 380 381 if err != nil { 382 fmt.Printf("插入权限信息:%+v\t\t失败\n%v\n\n\n", permissionTree, err) 383 } else { 384 rowsAffected, _ := result.RowsAffected() 385 if rowsAffected > 0 { 386 fmt.Printf("插入权限信息:%+v\t\t已成功\n\n\n", permissionTree) 387 } 388 } 389 } 390 391 // 有下级权限,递归插入权限 392 if len(permissionTree.GetItems()) > 0 { 393 s.ImportPermissionTree(ctx, permissionTree.GetItems(), permissionTree) 394 } 395 } 396 return nil 397 } 398 399 // SavePermission 新增/保存权限信息 400 func (s *sSysPermission) SavePermission(ctx context.Context, info sys_model.SysPermission) (*sys_entity.SysPermission, error) { 401 data := sys_do.SysPermission{} 402 gconv.Struct(info, &data) 403 404 // 如果父级ID大于0,则校验父级权限信息是否存在 405 if info.ParentId > 0 { 406 permissionInfo, err := s.GetPermissionById(ctx, info.ParentId) 407 if err != nil || permissionInfo.Id <= 0 { 408 return nil, sys_service.SysLogs().ErrorSimple(ctx, gerror.NewCode(gcode.CodeNil, "父级权限信息不存在"), "", sys_dao.SysPermission.Table()) 409 } 410 } 411 412 { 413 414 // 同一分类下,排除重名问题 415 model := sys_dao.SysPermission.Ctx(ctx). 416 Where(sys_do.SysPermission{ 417 ParentId: info.ParentId, 418 Name: info.Name, 419 }) 420 421 if info.Id > 0 { 422 model = model.WhereNot(sys_dao.SysPermission.Columns().Id, info.Id) 423 } 424 count, _ := model.Count() 425 426 if count > 0 { 427 return nil, sys_service.SysLogs().ErrorSimple(ctx, gerror.NewCode(gcode.CodeNil, "名称在当前分类下已存在,请修改后再试"), "", sys_dao.SysPermission.Table()) 428 } 429 430 } 431 432 if info.Id <= 0 { 433 data.Id = idgen.NextId() 434 data.IsShow = 1 435 data.CreatedAt = gtime.Now() 436 437 { 438 // 校验标识符是否存在 439 if v, _ := s.GetPermissionByIdentifier(ctx, info.Identifier); v != nil { 440 return nil, sys_service.SysLogs().ErrorSimple(ctx, gerror.NewCode(gcode.CodeNil, "标识符已存在,请修改后再试"), "", sys_dao.SysPermission.Table()) 441 } 442 } 443 444 _, err := sys_dao.SysPermission.Ctx(ctx).Insert(data) 445 446 if err != nil { 447 return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "新增权限信息失败", sys_dao.SysPermission.Table()) 448 } 449 } else { 450 data.UpdatedAt = gtime.Now() 451 _, err := sys_dao.SysPermission.Ctx(ctx). 452 Where(sys_do.SysPermission{Id: data.Id}).OmitNilData().Update(data) 453 454 if err != nil { 455 return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "权限信息保存失败", sys_dao.SysPermission.Table()) 456 } 457 } 458 459 return s.GetPermissionById(ctx, gconv.Int64(data.Id)) 460 } 461 462 // DeletePermission 删除权限信息 463 func (s *sSysPermission) DeletePermission(ctx context.Context, permissionId int64) (bool, error) { 464 _, err := s.GetPermissionById(ctx, permissionId) 465 466 if err != nil { 467 return false, err 468 } 469 470 _, err = sys_dao.SysPermission.Ctx(ctx).Delete(sys_do.SysPermission{Id: permissionId}) 471 472 if err != nil { 473 return false, sys_service.SysLogs().ErrorSimple(ctx, err, "删除权限信息失败", sys_dao.SysPermission.Table()) 474 } 475 476 // 删除权限定义 477 sys_dao.SysCasbin.Ctx(ctx).Delete(sys_do.SysCasbin{Ptype: "p", V2: permissionId}) 478 479 return true, nil 480 } 481 482 // GetPermissionTreeIdByUrl 根据请求URL去匹配权限树,返回权限 483 func (s *sSysPermission) GetPermissionTreeIdByUrl(ctx context.Context, path string) (*sys_entity.SysPermission, error) { 484 if path == "" { 485 return nil, gerror.New("传入的请求url为空") 486 } 487 488 result := sys_entity.SysPermission{} 489 490 // 在权限树标识中匹标识后缀,|为标识符的分隔符 491 path = "%|" + path 492 493 err := sys_dao.SysPermission.Ctx(ctx).WhereLike(sys_dao.SysPermission.Columns().Identifier, path).Scan(&result) 494 495 if err != nil { 496 return nil, err 497 } 498 499 return &result, nil 500 } 501 502 // CheckPermission 校验权限,如果多个则需要同时满足 503 func (s *sSysPermission) CheckPermission(ctx context.Context, tree ...base_permission.IPermission) (has bool, err error) { // 权限id 域 资源 方法 504 sessionUser := sys_service.SysSession().Get(ctx).JwtClaimsUser 505 506 // 如果是超级管理员或者某商管理员则直接放行 507 if sessionUser.Type == -1 || sessionUser.IsAdmin == true || sessionUser.IsSuperAdmin == true { 508 return true, nil 509 } 510 511 for _, permissionTree := range tree { 512 permissionResourceKey := gconv.String(permissionTree.GetId()) 513 if permissionTree.GetMatchMode() > 0 { 514 permissionResourceKey = permissionTree.GetIdentifier() 515 } 516 if has, err = s.CheckPermissionByIdentifier(ctx, permissionResourceKey); has == false { 517 return false, gerror.New("没有权限:" + permissionTree.GetName() + "," + permissionTree.GetDescription()) 518 } 519 } 520 return true, nil 521 } 522 523 // CheckPermissionOr 校验权限,任意一个满足则有权限 524 func (s *sSysPermission) CheckPermissionOr(ctx context.Context, tree ...base_permission.IPermission) (has bool, err error) { // 用户id 域 资源 方法 525 session := sys_service.SysSession().Get(ctx).JwtClaimsUser 526 // 如果是超级管理员或者某商管理员则直接放行 527 if session.Type == -1 || session.IsAdmin == true || session.IsSuperAdmin == true { 528 return true, nil 529 } 530 531 for _, permissionTree := range tree { 532 permissionResourceKey := gconv.String(permissionTree.GetId()) 533 if permissionTree.GetMatchMode() > 0 { 534 permissionResourceKey = permissionTree.GetIdentifier() 535 } 536 if has, err = s.CheckPermissionByIdentifier(ctx, permissionResourceKey); has == true { 537 break 538 } 539 } 540 return 541 } 542 543 // CheckPermissionByIdentifier 通过标识符校验权限 544 func (s *sSysPermission) CheckPermissionByIdentifier(ctx context.Context, identifier string) (bool, error) { 545 sessionUser := sys_service.SysSession().Get(ctx).JwtClaimsUser 546 547 // 如果是超级管理员或者某商管理员则直接放行 548 if sessionUser.Type == -1 || sessionUser.IsAdmin == true || sessionUser.IsSuperAdmin == true { 549 return true, nil 550 } 551 552 t, err := sys_service.Casbin().Enforcer().Enforce(gconv.String(sessionUser.Id), sys_consts.CasbinDomain, identifier, "allow") 553 554 if err != nil { 555 fmt.Printf("权限校验失败[%v]:%v\n", identifier, err.Error()) 556 } 557 if t != true { 558 err = gerror.New("没有权限") 559 } 560 return t, err 561 } 562 563 // PermissionTypeForm 通过枚举值取枚举类型 564 func (s *sSysPermission) PermissionTypeForm(code int64, mapItems *gmap.StrAnyMap) *sys_model.SysPermission { 565 var result *sys_model.SysPermission 566 mapItems.Iterator(func(k string, v interface{}) bool { 567 item := v.(*sys_model.SysPermission) 568 if item.Id == code { 569 result = item 570 return false 571 } 572 return true 573 }) 574 575 return result 576 }