From 9a90c95be15763f75e902726db8b4cb8bb3dca3b Mon Sep 17 00:00:00 2001 From: guosl Date: Wed, 31 Jul 2024 17:26:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=88=E6=9D=83=E7=BB=84=E7=BB=87=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/sql/init/user.sql | 3 +- internal/models/role/request.go | 6 +- internal/repo/role.go | 49 +++- internal/service/organization/organization.go | 3 +- internal/service/organization/util.go | 273 +++++++++--------- internal/service/role/role.go | 117 +++++++- internal/service/role/util.go | 135 +++++++++ internal/service/util/organizaiton.go | 141 +++++++++ server/role/role.go | 4 + 9 files changed, 586 insertions(+), 145 deletions(-) create mode 100644 internal/service/role/util.go create mode 100644 internal/service/util/organizaiton.go diff --git a/deploy/sql/init/user.sql b/deploy/sql/init/user.sql index d6a7214..042c90e 100644 --- a/deploy/sql/init/user.sql +++ b/deploy/sql/init/user.sql @@ -107,7 +107,8 @@ CREATE TABLE IF NOT EXISTS `organization_role_author`( `modified_on` DATETIME DEFAULT CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP COMMENT '记录修改时间', PRIMARY KEY (`id`), KEY `idx_org_id`(`org_id`), - KEY `idx_role_id`(`role_id`) + KEY `idx_role_id`(`role_id`), + UNIQUE KEY `udx_role_org`(`org_id`,`role_id`) )ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COMMENT='组织角色授权表'; -- 应用表 diff --git a/internal/models/role/request.go b/internal/models/role/request.go index c4297fd..d745497 100644 --- a/internal/models/role/request.go +++ b/internal/models/role/request.go @@ -63,11 +63,13 @@ type OrgAuthorBrief struct { } type AddOrgsReq struct { - Orgs []OrgAuthorBrief `json:"orgs"` + Orgs []OrgAuthorBrief `json:"orgs"` + RoleId uint `json:"role_id"` } type RemoveOrgsReq struct { - Ids []uint `json:"ids"` + Ids []uint `json:"ids"` + RoleId uint `json:"role_id"` } type RoleUsersReq struct { diff --git a/internal/repo/role.go b/internal/repo/role.go index 21b8555..a2eef3d 100644 --- a/internal/repo/role.go +++ b/internal/repo/role.go @@ -44,7 +44,15 @@ type RoleRepo interface{ // 组织角色 GetOrgRolesByIDs(ctx context.Context,ids []uint)([]Role,error) + + GetOrgAuthors(ctx context.Context,roleid uint,orgIds []uint)([]OrganizationRoleAuthor,error) + GetRoleAllOrgAuthorsByRoleId(ctx context.Context,roleid uint)([]OrganizationRoleAuthor,error) + CreateOrgAuthor(ctx context.Context,authors []OrganizationRoleAuthor)error + DeleteOrgAuthor(ctx context.Context,roleId uint,orgIds []uint)error + CreateOrgRole(ctx context.Context,orgRoles []OrganizationRole)error + DeleteOrgRole(ctx context.Context,roleId uint,orgIds []uint)error + GetOrgRolesByRoleOrgId(ctx context.Context,roleId uint,orgIds []uint)([]OrganizationRole,error) } type roleRepo struct{ @@ -128,4 +136,43 @@ func (r *roleRepo)RemoveUserRole(ctx context.Context,items []UserRole)error{ } return nil -} \ No newline at end of file +} + +func (r *roleRepo) GetOrgAuthors(ctx context.Context,roleid uint,orgIds []uint)([]OrganizationRoleAuthor,error){ + authors := make([]OrganizationRoleAuthor,0) + err := r.db.Where("role_id = ? and org_id in ?",roleid,orgIds).Find(&authors).Error + return authors,err +} + +func (r *roleRepo) CreateOrgAuthor(ctx context.Context,authors []OrganizationRoleAuthor)error{ + err := r.db.Create(&authors).Error + return err +} + +func (r *roleRepo) DeleteOrgAuthor(ctx context.Context,roleId uint,orgIds []uint)error{ + err := r.db.Where("role_id = ? and org_id in ?",roleId,orgIds).Delete(&OrganizationRoleAuthor{}).Error + return err +} + +func (r *roleRepo) CreateOrgRole(ctx context.Context,orgRoles []OrganizationRole)error{ + err := r.db.Create(&orgRoles).Error + return err +} + +func (r *roleRepo)DeleteOrgRole(ctx context.Context,roleId uint,orgIds []uint)error{ + err := r.db.Where("role_id = ? and org_id in ?",roleId,orgIds).Delete(&OrganizationRole{}).Error + return err +} + +func (r *roleRepo)GetOrgRolesByRoleOrgId(ctx context.Context,roleId uint,orgIds []uint)([]OrganizationRole,error){ + orgRoles := make([]OrganizationRole,0) + err := r.db.Where("role_id = ? and org_id in ?",roleId,orgIds).Find(&orgRoles).Error + return orgRoles,err +} + +func (r *roleRepo)GetRoleAllOrgAuthorsByRoleId(ctx context.Context,roleid uint)([]OrganizationRoleAuthor,error){ + authors := make([]OrganizationRoleAuthor,0) + err := r.db.Where("role_id = ?",roleid).Find(&authors).Error + return authors,err +} + diff --git a/internal/service/organization/organization.go b/internal/service/organization/organization.go index 4249fd3..2f79866 100644 --- a/internal/service/organization/organization.go +++ b/internal/service/organization/organization.go @@ -4,6 +4,7 @@ import ( "busniess-user-center/config" orgModel "busniess-user-center/internal/models/organization" "busniess-user-center/internal/repo" + "busniess-user-center/internal/service/util" "busniess-user-center/pkg/redis" "context" "encoding/json" @@ -169,7 +170,7 @@ func (o *organizationService) OrganizationTree(ctx context.Context) (orgModel.Or return nil, err } - tree := getOrgTree(dbOrgs) + tree := util.GetOrgTree(dbOrgs) return tree, nil } diff --git a/internal/service/organization/util.go b/internal/service/organization/util.go index 17e9bcb..0415b1f 100644 --- a/internal/service/organization/util.go +++ b/internal/service/organization/util.go @@ -1,176 +1,173 @@ package organization import ( - orgModel "busniess-user-center/internal/models/organization" - "busniess-user-center/internal/repo" "context" "fmt" - "sort" ) -func getOrgParentsWihtSelf(orgId uint, allOrgs []repo.Organization) (orgs []repo.Organization) { - orgMap := make(map[uint]repo.Organization, 0) - orgChildMap := make(map[uint][]repo.Organization, 0) - for _, org := range allOrgs { - if org.Status == 1 { - orgMap[org.ID] = org - orgChildMap[org.ParentID] = append(orgChildMap[org.ParentID], org) - } - } +// func getOrgParentsWihtSelf(orgId uint, allOrgs []repo.Organization) (orgs []repo.Organization) { +// orgMap := make(map[uint]repo.Organization, 0) +// orgChildMap := make(map[uint][]repo.Organization, 0) +// for _, org := range allOrgs { +// if org.Status == 1 { +// orgMap[org.ID] = org +// orgChildMap[org.ParentID] = append(orgChildMap[org.ParentID], org) +// } +// } - orgs = getParents(orgId, orgMap) +// orgs = getParents(orgId, orgMap) - if org, ok := orgMap[orgId]; ok { - orgs = append(orgs, org) - } +// if org, ok := orgMap[orgId]; ok { +// orgs = append(orgs, org) +// } - return -} +// return +// } -func getOrgParents(orgId uint, allOrgs []repo.Organization) (orgs []repo.Organization) { - orgMap := make(map[uint]repo.Organization, 0) - orgChildMap := make(map[uint][]repo.Organization, 0) - for _, org := range allOrgs { - if org.Status == 1 { - orgMap[org.ID] = org - orgChildMap[org.ParentID] = append(orgChildMap[org.ParentID], org) - } - } +// func getOrgParents(orgId uint, allOrgs []repo.Organization) (orgs []repo.Organization) { +// orgMap := make(map[uint]repo.Organization, 0) +// orgChildMap := make(map[uint][]repo.Organization, 0) +// for _, org := range allOrgs { +// if org.Status == 1 { +// orgMap[org.ID] = org +// orgChildMap[org.ParentID] = append(orgChildMap[org.ParentID], org) +// } +// } - orgs = getParents(orgId, orgMap) - return -} +// orgs = getParents(orgId, orgMap) +// return +// } -func getParents(orgId uint, orgParentMap map[uint]repo.Organization) (orgs []repo.Organization) { - org, ok := orgParentMap[orgId] - if !ok { - return - } +// func getParents(orgId uint, orgParentMap map[uint]repo.Organization) (orgs []repo.Organization) { +// org, ok := orgParentMap[orgId] +// if !ok { +// return +// } - if org.ParentID == 0 { - return - } +// if org.ParentID == 0 { +// return +// } - parentOrg, ok := orgParentMap[org.ParentID] - if ok { - orgs = append(orgs, parentOrg) - orgs = append(orgs, getParents(parentOrg.ID, orgParentMap)...) - } +// parentOrg, ok := orgParentMap[org.ParentID] +// if ok { +// orgs = append(orgs, parentOrg) +// orgs = append(orgs, getParents(parentOrg.ID, orgParentMap)...) +// } - return -} +// return +// } -func getOrgMap(allOrgs []repo.Organization) map[uint]repo.Organization { - orgMap := make(map[uint]repo.Organization, 0) +// func getOrgMap(allOrgs []repo.Organization) map[uint]repo.Organization { +// orgMap := make(map[uint]repo.Organization, 0) - for _, org := range allOrgs { - if org.Status == 1 { - orgMap[org.ID] = org - } - } +// for _, org := range allOrgs { +// if org.Status == 1 { +// orgMap[org.ID] = org +// } +// } - return orgMap -} +// return orgMap +// } -func getOrgChildrenWithSelf(orgId uint, allOrgs []repo.Organization) (orgs []repo.Organization) { - orgMap := make(map[uint]repo.Organization, 0) - orgChildMap := make(map[uint][]repo.Organization, 0) - for _, org := range allOrgs { - if org.Status == 1 { - orgMap[org.ID] = org - orgChildMap[org.ParentID] = append(orgChildMap[org.ParentID], org) - } - } +// func getOrgChildrenWithSelf(orgId uint, allOrgs []repo.Organization) (orgs []repo.Organization) { +// orgMap := make(map[uint]repo.Organization, 0) +// orgChildMap := make(map[uint][]repo.Organization, 0) +// for _, org := range allOrgs { +// if org.Status == 1 { +// orgMap[org.ID] = org +// orgChildMap[org.ParentID] = append(orgChildMap[org.ParentID], org) +// } +// } - orgs = getChildren(orgId, orgChildMap) +// orgs = getChildren(orgId, orgChildMap) - if org, ok := orgMap[orgId]; ok { - orgs = append(orgs, org) - } +// if org, ok := orgMap[orgId]; ok { +// orgs = append(orgs, org) +// } - return -} +// return +// } -func getOrgChildren(orgId uint, allOrgs []repo.Organization) (orgs []repo.Organization) { - orgMap := make(map[uint]repo.Organization, 0) - orgChildMap := make(map[uint][]repo.Organization, 0) - for _, org := range allOrgs { - if org.Status == 1 { - orgMap[org.ID] = org - orgChildMap[org.ParentID] = append(orgChildMap[org.ParentID], org) - } - } +// func getOrgChildren(orgId uint, allOrgs []repo.Organization) (orgs []repo.Organization) { +// orgMap := make(map[uint]repo.Organization, 0) +// orgChildMap := make(map[uint][]repo.Organization, 0) +// for _, org := range allOrgs { +// if org.Status == 1 { +// orgMap[org.ID] = org +// orgChildMap[org.ParentID] = append(orgChildMap[org.ParentID], org) +// } +// } - orgs = getChildren(orgId, orgChildMap) - return -} +// orgs = getChildren(orgId, orgChildMap) +// return +// } -func getChildren(orgId uint, orgChildrenMap map[uint][]repo.Organization) (orgs []repo.Organization) { - if children, ok := orgChildrenMap[orgId]; ok { - for _, child := range children { - orgs = append(orgs, getChildren(child.ID, orgChildrenMap)...) - orgs = append(orgs, child) - } - } +// func getChildren(orgId uint, orgChildrenMap map[uint][]repo.Organization) (orgs []repo.Organization) { +// if children, ok := orgChildrenMap[orgId]; ok { +// for _, child := range children { +// orgs = append(orgs, getChildren(child.ID, orgChildrenMap)...) +// orgs = append(orgs, child) +// } +// } - return -} +// return +// } -func getOrgTree(orgs []*repo.Organization) orgModel.OrgTree { - // top - topOrgs := []*orgModel.Organization{} - parentMap := make(map[uint][]*orgModel.Organization) - for _, org := range orgs { - mOrg := convertOrgDTM(org) - if org.ParentID == 0 { - topOrgs = append(topOrgs, mOrg) - } else { - if _, ok := parentMap[org.ParentID]; !ok { - parentMap[org.ParentID] = []*orgModel.Organization{mOrg} - } else { - parentMap[org.ParentID] = append(parentMap[org.ParentID], mOrg) - } - } - } +// func getOrgTree(orgs []*repo.Organization) orgModel.OrgTree { +// // top +// topOrgs := []*orgModel.Organization{} +// parentMap := make(map[uint][]*orgModel.Organization) +// for _, org := range orgs { +// mOrg := convertOrgDTM(org) +// if org.ParentID == 0 { +// topOrgs = append(topOrgs, mOrg) +// } else { +// if _, ok := parentMap[org.ParentID]; !ok { +// parentMap[org.ParentID] = []*orgModel.Organization{mOrg} +// } else { +// parentMap[org.ParentID] = append(parentMap[org.ParentID], mOrg) +// } +// } +// } - for _, subOrgs := range parentMap { - for _, org := range subOrgs { - children := parentMap[org.ID] - sort.Slice(children, func(i, j int) bool { - return children[i].Sort < children[j].Sort - }) +// for _, subOrgs := range parentMap { +// for _, org := range subOrgs { +// children := parentMap[org.ID] +// sort.Slice(children, func(i, j int) bool { +// return children[i].Sort < children[j].Sort +// }) - org.Children = children - } - } +// org.Children = children +// } +// } - for _, org := range topOrgs { - children := parentMap[org.ID] - sort.Slice(children, func(i, j int) bool { - return children[i].Sort < children[j].Sort - }) +// for _, org := range topOrgs { +// children := parentMap[org.ID] +// sort.Slice(children, func(i, j int) bool { +// return children[i].Sort < children[j].Sort +// }) - org.Children = children - } +// org.Children = children +// } - sort.Slice(topOrgs, func(i, j int) bool { - return topOrgs[i].Sort < topOrgs[j].Sort - }) +// sort.Slice(topOrgs, func(i, j int) bool { +// return topOrgs[i].Sort < topOrgs[j].Sort +// }) - return topOrgs -} +// return topOrgs +// } -func convertOrgDTM(org *repo.Organization) *orgModel.Organization { - return &orgModel.Organization{ - ID: org.ID, // id - Name: org.Name, // 组织名 - ParentID: org.ParentID, // 上级组织id - Sort: org.Sort, // 层级序号 - Status: org.Status, // 状态:0-无效,1-有效 - Path: org.Path, // 全路径 - CreatedOn: org.CreatedOn, // 记录创建时间 - } -} +// func convertOrgDTM(org *repo.Organization) *orgModel.Organization { +// return &orgModel.Organization{ +// ID: org.ID, // id +// Name: org.Name, // 组织名 +// ParentID: org.ParentID, // 上级组织id +// Sort: org.Sort, // 层级序号 +// Status: org.Status, // 状态:0-无效,1-有效 +// Path: org.Path, // 全路径 +// CreatedOn: org.CreatedOn, // 记录创建时间 +// } +// } func (o *organizationService) verfyUsers(ctx context.Context, accounts []string) error { for _, account := range accounts { diff --git a/internal/service/role/role.go b/internal/service/role/role.go index 4b2a11a..fbed82c 100644 --- a/internal/service/role/role.go +++ b/internal/service/role/role.go @@ -32,6 +32,7 @@ type roleService struct { roleRepo repo.RoleRepo conf *config.AppConfig userService user.UserService + orgRepo repo.OrganizationRepo } func NewRoleService(i *do.Injector) (RoleService, error) { @@ -40,6 +41,7 @@ func NewRoleService(i *do.Injector) (RoleService, error) { roleRepo: do.MustInvoke[repo.RoleRepo](i), conf: do.MustInvoke[*config.AppConfig](i), userService: do.MustInvoke[user.UserService](i), + orgRepo: do.MustInvoke[repo.OrganizationRepo](i), }, nil } @@ -200,11 +202,122 @@ func (o *roleService) RemoveUsers(ctx context.Context, info *roleModel.RemoveUse return nil } -func (u *roleService) AddOrgs(ctx context.Context, info *roleModel.AddOrgsReq) error { +func (o *roleService) AddOrgs(ctx context.Context, info *roleModel.AddOrgsReq) error { + _, err := o.roleRepo.GetById(ctx, info.RoleId) + if err != nil && err != gorm.ErrRecordNotFound { + return err + } + + if err == gorm.ErrRecordNotFound { + return fmt.Errorf("角色%d不存在", info.RoleId) + } + + // 判断权限 + session, err := contextUtil.GetSession(ctx) + if err != nil { + return err + } + + perssion, err := o.hasPerssion(ctx, session) + if err != nil { + return err + } + + if !perssion { + return fmt.Errorf("没有权限") + } + + // 判断组织是否存在 + orgIds := make([]uint, 0) + for _, item := range info.Orgs { + orgIds = append(orgIds, item.Id) + } + + dbAuthors, err := o.roleRepo.GetOrgAuthors(ctx, info.RoleId, orgIds) + if err != nil { + return err + } + + dbOrgRoles, err := o.roleRepo.GetOrgRolesByRoleOrgId(ctx, info.RoleId, orgIds) + if err != nil { + return err + } + + allOrgs, err := o.orgRepo.GetOrgs(ctx) + if err != nil { + return err + } + + orgAuthor, orgRole := getOrgAuthorAndRole(info.RoleId, info.Orgs, allOrgs) + iOrgAuthor, iOrgRole := filterOrgAuthorRole(orgAuthor, dbAuthors, orgRole, dbOrgRoles) + + if err = o.roleRepo.CreateOrgRole(ctx, iOrgRole); err != nil { + return err + } + + if err = o.roleRepo.CreateOrgAuthor(ctx, iOrgAuthor); err != nil { + return err + } + return nil } -func (u *roleService) RemoveOrgs(ctx context.Context, info *roleModel.RemoveOrgsReq) error { +func (o *roleService) RemoveOrgs(ctx context.Context, info *roleModel.RemoveOrgsReq) error { + _, err := o.roleRepo.GetById(ctx, info.RoleId) + if err != nil && err != gorm.ErrRecordNotFound { + return err + } + + if err == gorm.ErrRecordNotFound { + return fmt.Errorf("角色%d不存在", info.RoleId) + } + + // 判断权限 + session, err := contextUtil.GetSession(ctx) + if err != nil { + return err + } + + perssion, err := o.hasPerssion(ctx, session) + if err != nil { + return err + } + + if !perssion { + return fmt.Errorf("没有权限") + } + + dbAuthors, err := o.roleRepo.GetRoleAllOrgAuthorsByRoleId(ctx, info.RoleId) + if err != nil { + return err + } + + allOrgs, err := o.orgRepo.GetOrgs(ctx) + if err != nil { + return err + } + + orgAuthor, orgRole := genRemoveOrgAuthorAndRole(info.RoleId, info.Ids, allOrgs, dbAuthors) + roleOrgIds := make([]uint, 0) + for _, item := range orgRole { + roleOrgIds = append(roleOrgIds, item.OrgID) + } + + err = o.roleRepo.DeleteOrgRole(ctx, info.RoleId, roleOrgIds) + if err != nil { + return err + } + + orgAuthroIds := make([]uint, 0) + for _, item := range orgAuthor { + orgAuthroIds = append(orgAuthroIds, item.OrgID) + } + + err = o.roleRepo.DeleteOrgAuthor(ctx, info.RoleId, orgAuthroIds) + if err != nil { + return err + } + return nil } diff --git a/internal/service/role/util.go b/internal/service/role/util.go new file mode 100644 index 0000000..7fe6195 --- /dev/null +++ b/internal/service/role/util.go @@ -0,0 +1,135 @@ +package role + +import ( + roleModel "busniess-user-center/internal/models/role" + "busniess-user-center/internal/repo" + "busniess-user-center/internal/service/util" + "strconv" +) + +func getOrgAuthorAndRole(roleId uint, authorOrgs []roleModel.OrgAuthorBrief, allOrg []*repo.Organization) (authors []repo.OrganizationRoleAuthor, orgRole []repo.OrganizationRole) { + _, orgchildrenMaps := util.GetOrgMap(allOrg) + + for _, item := range authorOrgs { + orgRole = append(orgRole, genOrgRole(roleId, item.Id)) + authors = append(authors, genOrgAuthor(roleId, item)) + + if item.Type == roleModel.IncludeChildrenOrgAuthor { + childOrgs := util.GetChildren(item.Id, orgchildrenMaps) + for _, child := range childOrgs { + orgRole = append(orgRole, genOrgRole(roleId, child.ID)) + } + } + } + + return +} + +func genOrgRole(roleId, orgId uint) repo.OrganizationRole { + return repo.OrganizationRole{ + OrgID: orgId, + RoleID: roleId, + } +} + +func genOrgAuthor(roleId uint, orgAuthor roleModel.OrgAuthorBrief) repo.OrganizationRoleAuthor { + return repo.OrganizationRoleAuthor{ + OrgID: orgAuthor.Id, + Option: int(orgAuthor.Type), + RoleID: roleId, + } +} + +func filterOrgAuthorRole(authors, dbAuthors []repo.OrganizationRoleAuthor, orgRole, dbOrgRoles []repo.OrganizationRole) (fAuthors []repo.OrganizationRoleAuthor, fOrgRole []repo.OrganizationRole) { + dbAuthorMap := make(map[string]repo.OrganizationRoleAuthor, 0) + dbOrgRoleMap := make(map[string]repo.OrganizationRole, 0) + + for _, item := range dbAuthors { + key := strconv.FormatUint(uint64(item.RoleID), 10) + strconv.FormatUint(uint64(item.OrgID), 10) + dbAuthorMap[key] = item + } + + for _, item := range dbOrgRoles { + key := strconv.FormatUint(uint64(item.RoleID), 10) + strconv.FormatUint(uint64(item.OrgID), 10) + dbOrgRoleMap[key] = item + } + + for _, item := range authors { + key := strconv.FormatUint(uint64(item.RoleID), 10) + strconv.FormatUint(uint64(item.OrgID), 10) + if _, ok := dbAuthorMap[key]; !ok { + fAuthors = append(fAuthors, item) + } + } + + for _, item := range orgRole { + key := strconv.FormatUint(uint64(item.RoleID), 10) + strconv.FormatUint(uint64(item.OrgID), 10) + if _, ok := dbOrgRoleMap[key]; !ok { + fOrgRole = append(fOrgRole, item) + } + } + + return +} + +func genRemoveOrgAuthorAndRole(roleId uint, orgIds []uint, allOrg []*repo.Organization, allAuthor []repo.OrganizationRoleAuthor) (authors []repo.OrganizationRoleAuthor, orgRole []repo.OrganizationRole) { + orgMaps, orgchildrenMaps := util.GetOrgMap(allOrg) + authorMaps := make(map[string]repo.OrganizationRoleAuthor, 0) + for _, item := range allAuthor { + key := strconv.FormatUint(uint64(item.RoleID), 10) + strconv.FormatUint(uint64(item.OrgID), 10) + authorMaps[key] = item + } + + for _, orgId := range orgIds { + // 判断是否移除当前组织的角色权限:1 父级组织没有包含子类的授权 2 组织自己没有记录 满足着两条可以删除组织角色权限 + key := strconv.FormatUint(uint64(roleId), 10) + strconv.FormatUint(uint64(orgId), 10) + if author, ok := authorMaps[key]; ok { + authors = append(authors, repo.OrganizationRoleAuthor{ + OrgID: orgId, + RoleID: roleId, + }) + + if whetherRemoveOrgRole(false, author, authorMaps, orgMaps) { + orgRole = append(orgRole, repo.OrganizationRole{ + OrgID: orgId, + RoleID: roleId, + }) + } + + if roleModel.OrgAuthorRoleType(author.Option) == roleModel.IncludeChildrenOrgAuthor { + childOrgs := util.GetChildren(orgId, orgchildrenMaps) + + for _, child := range childOrgs { + if whetherRemoveOrgRole(true, author, authorMaps, orgMaps) { + orgRole = append(orgRole, genOrgRole(roleId, child.ID)) + } + } + } + } + } + + return +} + +func whetherRemoveOrgRole(child bool, author repo.OrganizationRoleAuthor, authorMaps map[string]repo.OrganizationRoleAuthor, orgMaps map[uint]*repo.Organization) bool { + if !child { + // 如果是要删除组织自己就不用判断自己是否授权过,如果是要删除组织的子组织,则需要判断子组织是否添加 + key := strconv.FormatUint(uint64(author.RoleID), 10) + strconv.FormatUint(uint64(author.OrgID), 10) + if _, ok := authorMaps[key]; ok { + return false + } + } + + // 判断父级是否添加 + parentOrg := util.GetParents(author.OrgID, orgMaps) + for _, org := range parentOrg { + key := strconv.FormatUint(uint64(author.RoleID), 10) + strconv.FormatUint(uint64(org.ID), 10) + + if pAuthor, ok := authorMaps[key]; ok { + if pAuthor.Option == int(roleModel.IncludeChildrenOrgAuthor) { + return false + } + } + } + + return true +} diff --git a/internal/service/util/organizaiton.go b/internal/service/util/organizaiton.go new file mode 100644 index 0000000..d195fa6 --- /dev/null +++ b/internal/service/util/organizaiton.go @@ -0,0 +1,141 @@ +package util + +import ( + orgModel "busniess-user-center/internal/models/organization" + "busniess-user-center/internal/repo" + "sort" +) + +func GetOrgParentsWihtSelf(orgId uint, allOrgs []*repo.Organization) (orgs []*repo.Organization) { + orgMap, _ := GetOrgMap(allOrgs) + orgs = GetParents(orgId, orgMap) + + if org, ok := orgMap[orgId]; ok { + orgs = append(orgs, org) + } + + return +} + +func GetOrgParents(orgId uint, allOrgs []*repo.Organization) (orgs []*repo.Organization) { + orgMap, _ := GetOrgMap(allOrgs) + orgs = GetParents(orgId, orgMap) + return +} + +func GetParents(orgId uint, orgParentMap map[uint]*repo.Organization) (orgs []*repo.Organization) { + org, ok := orgParentMap[orgId] + if !ok { + return + } + + if org.ParentID == 0 { + return + } + + parentOrg, ok := orgParentMap[org.ParentID] + if ok { + orgs = append(orgs, parentOrg) + orgs = append(orgs, GetParents(parentOrg.ID, orgParentMap)...) + } + + return +} + +func GetOrgMap(allOrgs []*repo.Organization) (map[uint]*repo.Organization, map[uint][]*repo.Organization) { + orgMap := make(map[uint]*repo.Organization, 0) + orgChildMap := make(map[uint][]*repo.Organization, 0) + for _, org := range allOrgs { + if org.Status == 1 { + orgMap[org.ID] = org + orgChildMap[org.ParentID] = append(orgChildMap[org.ParentID], org) + } + } + + return orgMap, orgChildMap +} + +func GetOrgChildrenWithSelf(orgId uint, allOrgs []*repo.Organization) (orgs []*repo.Organization) { + orgMap, orgChildMap := GetOrgMap(allOrgs) + orgs = GetChildren(orgId, orgChildMap) + + if org, ok := orgMap[orgId]; ok { + orgs = append(orgs, org) + } + + return +} + +func GetOrgChildren(orgId uint, allOrgs []*repo.Organization) (orgs []*repo.Organization) { + _, orgChildMap := GetOrgMap(allOrgs) + orgs = GetChildren(orgId, orgChildMap) + + return +} + +func GetChildren(orgId uint, orgChildrenMap map[uint][]*repo.Organization) (orgs []*repo.Organization) { + if children, ok := orgChildrenMap[orgId]; ok { + for _, child := range children { + orgs = append(orgs, GetChildren(child.ID, orgChildrenMap)...) + orgs = append(orgs, child) + } + } + + return +} + +func GetOrgTree(orgs []*repo.Organization) orgModel.OrgTree { + // top + topOrgs := []*orgModel.Organization{} + parentMap := make(map[uint][]*orgModel.Organization) + for _, org := range orgs { + mOrg := convertOrgDTM(org) + if org.ParentID == 0 { + topOrgs = append(topOrgs, mOrg) + } else { + if _, ok := parentMap[org.ParentID]; !ok { + parentMap[org.ParentID] = []*orgModel.Organization{mOrg} + } else { + parentMap[org.ParentID] = append(parentMap[org.ParentID], mOrg) + } + } + } + + for _, subOrgs := range parentMap { + for _, org := range subOrgs { + children := parentMap[org.ID] + sort.Slice(children, func(i, j int) bool { + return children[i].Sort < children[j].Sort + }) + + org.Children = children + } + } + + for _, org := range topOrgs { + children := parentMap[org.ID] + sort.Slice(children, func(i, j int) bool { + return children[i].Sort < children[j].Sort + }) + + org.Children = children + } + + sort.Slice(topOrgs, func(i, j int) bool { + return topOrgs[i].Sort < topOrgs[j].Sort + }) + + return topOrgs +} + +func convertOrgDTM(org *repo.Organization) *orgModel.Organization { + return &orgModel.Organization{ + ID: org.ID, // id + Name: org.Name, // 组织名 + ParentID: org.ParentID, // 上级组织id + Sort: org.Sort, // 层级序号 + Status: org.Status, // 状态:0-无效,1-有效 + Path: org.Path, // 全路径 + CreatedOn: org.CreatedOn, // 记录创建时间 + } +} diff --git a/server/role/role.go b/server/role/role.go index 870aaa0..c16dcb7 100644 --- a/server/role/role.go +++ b/server/role/role.go @@ -38,6 +38,10 @@ func RegisterRoute(api *gin.RouterGroup) { api.GET("/search", ginUtil.Wrap(server.Search)) api.POST("/adduser", ginUtil.WrapNoRsp(server.AddUsers)) api.DELETE("/removeuser", ginUtil.WrapNoRsp(server.RemoveUsers)) + api.POST("/addorg", ginUtil.WrapNoRsp(server.AddOrgs)) + api.DELETE("/removeorg", ginUtil.WrapNoRsp(server.RemoveOrgs)) + api.GET("/users", ginUtil.Wrap(server.RoleUsers)) + api.GET("/orgs", ginUtil.Wrap(server.RoleOrgs)) } func (u *RoleServer) Create(ctx context.Context, req *roleModel.CreateReq) (err error) {