关于常见的组织树结构实现方法

关于常见的组织树结构代码

    • 1 组织树形结构 (递归实现)
        • 1 部门组织类
        • 2 组织树形类
        • 3 树形工具类
        • 4 使用说明
    • 2 组织树形结构 (非递归实现)
        • 1 部门组织类
        • 2 树形工具类
    • 3 部门和人员的树形结构
        • 1 组织用户对象
        • 2 用户对象
        • 3 部门集合与用户集合合并代码

因关于组织树在项目中常见,且功能基本一致,故整理一下之前遇到的相关实现.

1 组织树形结构 (递归实现)

1 部门组织类
@Data
public class Org {@ApiModelProperty(value = "部门ID")private String orgId;@ApiModelProperty(value = "部门名称")private String orgName;@ApiModelProperty(value = "父部门ID")private String parentOrgId;// ... 还有其他字段如 org_path  org_level
}
2 组织树形类
@Data
public class OrgTreeNode {private String id;private String label;private String parentId;private Boolean disabled;private String isLeaf;private String isHidden;private String orgPath;private String ownerUserIds;private String ownerUserNames;private int sortNo;private Object data;private List<OrgTreeNode> children;public void addChildren(OrgTreeNode orgTree) {if (children == null) {children = new ArrayList<>();}children.add(orgTree);}public void addChildrens(List<OrgTreeNode> orgTreeList) {if (children == null) {children = new ArrayList<>();}children.addAll(orgTreeList);}}
3 树形工具类
@Slf4j
public class OrgTreeMenuUtil {/** 排序,根据order排序*/public Comparator<OrgTreeNode> order() {return (o1, o2) -> {if (o1.getSortNo() != o2.getSortNo()) {return o1.getSortNo() - o2.getSortNo();}return 0;};}public List<OrgTreeNode> findTree(List<OrgTreeNode> allMenu, String rootNode) {List<OrgTreeNode> rootMenu = new ArrayList<>();try {// 根节点for (OrgTreeNode nav : allMenu) {// rootNode为根节点if (rootNode.equals(nav.getParentId())) {rootMenu.add(nav);}}// 根据Menu类的order排序rootMenu.sort(order());// 为根菜单设置子菜单,getClild是递归调用的for (OrgTreeNode nav : rootMenu) {// 获取根节点下的所有子节点 使用getChild方法List<OrgTreeNode> childList = getChild(nav.getId(), allMenu);// 给根节点设置子节点nav.setChildren(childList);}// 输出构建好的菜单数据return rootMenu;} catch (Exception e) {log.error(e.getMessage());return Collections.emptyList();}}/*** 获取子节点* @param id 父节点id* @param allMenu 所有菜单列表* @return 每个根节点下,所有子菜单列表*/public List<OrgTreeNode> getChild(String id,List<OrgTreeNode> allMenu){// 子菜单List<OrgTreeNode> childList = new ArrayList<OrgTreeNode>();for (OrgTreeNode nav : allMenu) {// 遍历所有节点,将所有菜单的父id与传过来的根节点的id比较// 相等说明:为该根节点的子节点。if (id.equals(nav.getParentId())){childList.add(nav);}}// 递归for (OrgTreeNode nav : childList) {nav.setChildren(getChild(nav.getId(), allMenu));}// 排序childList.sort(order()); // 如果节点下没有子节点,返回一个空List(递归退出)if (CollectionUtils.isEmpty(childList)){return new ArrayList<OrgTreeNode>();}return childList;}
}
4 使用说明

首先,将所有部门信息查询出来,转换为OrgTreeNode对象, 再调用OrgTreeMenuUtil工具类的findTree方法,并传入OrgTreeNode对象和组织根节点. 工具类会使用递归,将组织结构封装.

另关于org_path和org_level的编辑时,对于子部门的修改问题, 对于org_path修改:(分隔符建议使用,尽量少用/, 如: 阿里巴巴,采购部,手机业务部)

1 先使用原路径+上一级路径, 去进行模糊查询,把所有子部门查询出来.

2 使用字符串的切割,将路径前一半去掉,拼上最新的前缀.

3 更新所有子部门的org_path字段.

对于org_level修改:(如: 阿里巴巴,采购部,手机业务部 就是第三等级部门)

1 本字段依赖于org_path字段,看org_path字段中的分隔符能拆分为几部分,即为那个等级.

2 组织树形结构 (非递归实现)

1 部门组织类
@Data
public class Org {@ApiModelProperty(value = "部门ID")private String orgId;@ApiModelProperty(value = "部门名称")private String orgName;@ApiModelProperty(value = "父部门ID")private String orgParentId;@ApiModelProperty(value = "子部门集合")private List<Org> children;// ... 还有其他字段如 org_path  org_level
}
2 树形工具类
@Slf4j
public class OrgTreeMenuUtil {/*** 生成组织树** @param list * @param root 根节点id* @return*/public List<Org> getTree(List<Org> list, String root) {List<Org> orgList = new ArrayList<>();Map<String, Org> parentObjs = new HashMap<>();// 找出所有的一级菜单for (Org org : list) { if (org.getOrgParentId().equals(root)) {orgList.add(org);}// 记录所有菜单的id及对应的实体parentObjs.put(org.getOrgId(), org);}// 把每个组织加到父组织的子集中for (Org org : list) {// 如果是一级菜单,不需要找它的父级if (org.getOrgParentId().equals(root)) {continue;}// 每个组织找到自己的直接父级,并加入到父级的子集中Org parentObj = parentObjs.get(org.getOrgParentId());// 如果还没有子组织集合,新建一个集合并添加子组织if (Objects.isNull(parentObj.getChildren())) {parentObj.setChildren(new ArrayList<>());}parentObj.getChildren().add(org);}return orgList;}}

用空间换时间的做法,不用循环递归去封装,直接通过两次遍历,完成组织树的封装.

3 部门和人员的树形结构

1 组织用户对象
@Data
public class OrgDropdownListRes {private String id;private String pId;private String isLeaf;private String value;private String title;private List<Person> persons;
}
2 用户对象
@Data
public class Person {private String id;private String username;private String password;private String orgId;private Integer gender;
}
3 部门集合与用户集合合并代码
	    private List<OrgDropdownListRes> convertOrg(List<Org> orgList, List<Person> personList) {List<OrgDropdownListRes> resList = Lists.newArrayList();orgList.forEach(o -> {OrgDropdownListRes res = new OrgDropdownListRes();res.setId(o.getOrgId());res.setPId(o.getParentOrgId());res.setValue(o.getOrgId());res.setTitle(o.getOrgName());res.setIsLeaf(SysConstants.IS_LEAF_1.equals(o.getIsLeaf()));if (!CollectionUtils.isEmpty(personList)) {Map<String, List<Person>> stringListMap = personList.stream().collect(Collectors.groupingBy(Person::getOrgId));res.setPersons(stringListMap.getOrDefault(o.getOrgId(), Collections.emptyList()));}resList.add(res);});return resList;}

查询所有部门 和 所有人员(根据部门id 和 企业id),通过Stream流将人员集合变成map结构,遍历部门,set用户数据.


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部