
/** * encoding: utf-8 * 版权所有 2026 ©涂聚文有限公司 ® * 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 * 描述Recursion Algorithm * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2026 - 2026/7/17 - 22:57 * User : geovindu * Product : IntelliJ IDEA * Project : JavaAlgorithms * File : PermConstant.java * explain : 学习 类 **/ package Recursion; import java.util.*; import java.util.stream.Collectors; /** * 权限常量映射 */ public class PermConstant { public static final MapString, String PERMISSION_MAP; public static final SetString OVERSEA_PERM_SET; static { PERMISSION_MAP new HashMap(); // 门店基础权限 PERMISSION_MAP.put(sale_view, 销售单据查看); PERMISSION_MAP.put(sale_create, 开单销售); PERMISSION_MAP.put(stock_view, 库存查询); PERMISSION_MAP.put(stock_inout, 金饰玉石出入库); PERMISSION_MAP.put(member_manage, 会员管理); // 国内财务权限 PERMISSION_MAP.put(finance_stat, 财务报表); PERMISSION_MAP.put(cost_allocate, 区域成本分摊); PERMISSION_MAP.put(gold_price_edit, 金价调整); // 海外专属权限 PERMISSION_MAP.put(custom_declare, 海外报关); PERMISSION_MAP.put(foreign_exchange, 外币对账); PERMISSION_MAP.put(oversea_tax, 境外税务核算); // 集团顶层权限 PERMISSION_MAP.put(org_mgr, 组织架构编辑); PERMISSION_MAP.put(role_global, 全局角色配置); PERMISSION_MAP.put(data_export_all, 全集团数据导出); OVERSEA_PERM_SET new HashSet(); OVERSEA_PERM_SET.add(custom_declare); OVERSEA_PERM_SET.add(foreign_exchange); OVERSEA_PERM_SET.add(oversea_tax); } } /** * encoding: utf-8 * 版权所有 2026 ©涂聚文有限公司 ® * 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 * 描述Recursion Algorithm * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2026 - 2026/7/17 - 22:58 * User : geovindu * Product : IntelliJ IDEA * Project : JavaAlgorithms * File : Role.java * explain : 学习 类 **/ package Recursion; import java.util.*; import java.util.stream.Collectors; /** * 角色模型 */ public class Role { private String roleId; private String roleName; private SetString perms; public Role(String roleId, String roleName, ListString permKeys) { this.roleId roleId; this.roleName roleName; this.perms new HashSet(permKeys); } public String getRoleName() { return roleName; } public SetString getPerms() { return perms; } } /** * encoding: utf-8 * 版权所有 2026 ©涂聚文有限公司 ® * 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 * 描述Recursion Algorithm * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2026 - 2026/7/17 - 22:59 * User : geovindu * Product : IntelliJ IDEA * Project : JavaAlgorithms * File : OrgNode.java * explain : 学习 类 **/ package Recursion; import java.util.*; import java.util.stream.Collectors; /** * 组织树节点 */ public class OrgNode { private String orgId; private String orgName; private String orgType; private String parentId; private boolean isJoin; // 是否加盟门店递归隔离标记 private ListOrgNode children new ArrayList(); private SetString perms new HashSet(); private ListRole bindRoles new ArrayList(); public OrgNode(String orgId, String orgName, String orgType, String parentId, boolean isJoin) { this.orgId orgId; this.orgName orgName; this.orgType orgType; this.parentId parentId; this.isJoin isJoin; } // 添加子节点 public void addChild(OrgNode child) { this.children.add(child); } // 添加组织自有权限 public void addPerm(String permKey) { if (PermConstant.PERMISSION_MAP.containsKey(permKey)) { this.perms.add(permKey); } } // 绑定角色 public void bindRole(Role role) { this.bindRoles.add(role); } // Getter public String getOrgId() { return orgId; } public String getOrgName() { return orgName; } public String getOrgType() { return orgType; } public String getParentId() { return parentId; } public boolean isJoin() { return isJoin; } public ListOrgNode getChildren() { return children; } public SetString getPerms() { return perms; } public ListRole getBindRoles() { return bindRoles; } } /** * encoding: utf-8 * 版权所有 2026 ©涂聚文有限公司 ® * 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 * 描述Recursion Algorithm * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2026 - 2026/7/17 - 23:00 * User : geovindu * Product : IntelliJ IDEA * Project : JavaAlgorithms * File : Staff.java * explain : 学习 类 **/ package Recursion; import java.util.*; import java.util.stream.Collectors; /** * 员工用户 */ public class Staff { private String uid; private String name; private String bindOrgId; private SetString rolePerms new HashSet(); public Staff(String uid, String name, String bindOrgId) { this.uid uid; this.name name; this.bindOrgId bindOrgId; } public void assignPerm(String permKey) { if (PermConstant.PERMISSION_MAP.containsKey(permKey)) { this.rolePerms.add(permKey); } } public String getBindOrgId() { return bindOrgId; } public SetString getRolePerms() { return rolePerms; } } /** * encoding: utf-8 * 版权所有 2026 ©涂聚文有限公司 ® * 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 * 描述Recursion Algorithm * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2026 - 2026/7/17 - 23:00 * User : geovindu * Product : IntelliJ IDEA * Project : JavaAlgorithms * File : SaleOrder.java * explain : 学习 类 **/ package Recursion; /** * 销售订单行级数据过滤 */ public class SaleOrder { private String orderId; private String shopOrgId; private double amount; public SaleOrder(String orderId, String shopOrgId, double amount) { this.orderId orderId; this.shopOrgId shopOrgId; this.amount amount; } public String getOrderId() { return orderId; } public String getShopOrgId() { return shopOrgId; } public double getAmount() { return amount; } } /** * encoding: utf-8 * 版权所有 2026 ©涂聚文有限公司 ® * 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 * 描述Recursion Algorithm * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2026 - 2026/7/17 - 23:01 * User : geovindu * Product : IntelliJ IDEA * Project : JavaAlgorithms * File : AuditRow.java * explain : 学习 类 **/ package Recursion; import java.util.*; import java.util.stream.Collectors; /** * 审计报表行实体 */ public class AuditRow { private int level; private String orgName; private boolean isJoin; private ListString ownPermNames; private ListString bindRoleNames; public AuditRow(int level, String orgName, boolean isJoin, ListString ownPermNames, ListString bindRoleNames) { this.level level; this.orgName orgName; this.isJoin isJoin; this.ownPermNames ownPermNames; this.bindRoleNames bindRoleNames; } public int getLevel() { return level; } public String getOrgName() { return orgName; } public boolean isJoin() { return isJoin; } public ListString getOwnPermNames() { return ownPermNames; } public ListString getBindRoleNames() { return bindRoleNames; } } /** * encoding: utf-8 * 版权所有 2026 ©涂聚文有限公司 ® * 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 * 描述Recursion Algorithm * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2026 - 2026/7/17 - 23:02 * User : geovindu * Product : IntelliJ IDEA * Project : JavaAlgorithms * File : OrgRecursionUtil.java * explain : 学习 类 **/ package Recursion; import java.util.*; import java.util.stream.Collectors; /** * 递归工具核心类 */ public class OrgRecursionUtil { // 1. 递归查找指定ID组织节点 public OrgNode findNode(OrgNode root, String targetId) { if (root.getOrgId().equals(targetId)) { return root; } for (OrgNode child : root.getChildren()) { OrgNode res findNode(child, targetId); if (res ! null) { return res; } } return null; } // 2. 向下递归获取所有下级加盟门店终止递归隔离分支 public ListOrgNode getAllSubOrgs(OrgNode root, String targetId) { OrgNode target findNode(root, targetId); ListOrgNode list new ArrayList(); if (target null) return list; dfsSub(target, list); return list; } private void dfsSub(OrgNode node, ListOrgNode list) { list.add(node); if (node.isJoin()) return; for (OrgNode child : node.getChildren()) { dfsSub(child, list); } } // 3. 向上递归获取整条父级链路 public ListOrgNode getParentChain(OrgNode root, String targetId, MapString, OrgNode nodeMap) { OrgNode target findNode(root, targetId); ListOrgNode parents new ArrayList(); if (target null || target.getParentId().isEmpty()) return parents; upRecur(target, nodeMap, parents); return parents; } private void upRecur(OrgNode node, MapString, OrgNode nodeMap, ListOrgNode parents) { String pid node.getParentId(); if (pid.isEmpty()) return; OrgNode pNode nodeMap.get(pid); if (pNode ! null) { parents.add(pNode); upRecur(pNode, nodeMap, parents); } } // 扩展1角色递归下发至所有子组织 public void roleSyncRecursive(OrgNode node, Role role) { node.bindRole(role); for (OrgNode child : node.getChildren()) { roleSyncRecursive(child, role); } } // 扩展2销售订单行级递归过滤 public ListSaleOrder filterSaleOrders(OrgNode root, Staff user, ListSaleOrder allOrders) { ListOrgNode subList getAllSubOrgs(root, user.getBindOrgId()); SetString allowShopIds subList.stream().map(OrgNode::getOrgId).collect(Collectors.toSet()); return allOrders.stream() .filter(ord - allowShopIds.contains(ord.getShopOrgId())) .collect(Collectors.toList()); } // 核心汇总用户完整权限父级自身下级海外权限隔离 public SetString getUserTotalPerms(OrgNode root, Staff user, MapString, OrgNode nodeMap) { SetString totalPerm new HashSet(user.getRolePerms()); OrgNode targetNode findNode(root, user.getBindOrgId()); if (targetNode null) return totalPerm; ListOrgNode parentList getParentChain(root, user.getBindOrgId(), nodeMap); ListOrgNode subList getAllSubOrgs(root, user.getBindOrgId()); ListOrgNode allOrgs new ArrayList(); allOrgs.addAll(parentList); allOrgs.addAll(subList); for (OrgNode org : allOrgs) { SetString tempPerm new HashSet(org.getPerms()); // 国内组织剔除海外权限 if (!org.getOrgType().equals(海外子公司) !org.getOrgType().startsWith(海外)) { tempPerm.removeAll(PermConstant.OVERSEA_PERM_SET); } totalPerm.addAll(tempPerm); } return totalPerm; } // 递归打印组织树 public void printTree(OrgNode node, int level) { StringBuilder indent new StringBuilder(); for (int i 0; i level; i) indent.append( ); String tag node.isJoin() ? [加盟] : ; System.out.printf(%s[%s]%s %s (ID:%s)%n, indent, node.getOrgType(), tag, node.getOrgName(), node.getOrgId()); for (OrgNode child : node.getChildren()) { printTree(child, level 1); } } // 递归回收权限 public void revokePermRecursive(OrgNode node, String permKey) { node.getPerms().remove(permKey); for (OrgNode child : node.getChildren()) { revokePermRecursive(child, permKey); } } // 扩展5递归导出审计报表 public void exportReport(OrgNode node, ListAuditRow report, int level) { ListString permNames node.getPerms().stream() .map(k - PermConstant.PERMISSION_MAP.get(k)) .sorted() .collect(Collectors.toList()); ListString roleNames node.getBindRoles().stream() .map(Role::getRoleName) .collect(Collectors.toList()); AuditRow row new AuditRow(level, node.getOrgName(), node.isJoin(), permNames, roleNames); report.add(row); if (node.isJoin()) return; for (OrgNode child : node.getChildren()) { exportReport(child, report, level 1); } } }调用/** * encoding: utf-8 * 版权所有 2026 ©涂聚文有限公司 ® * 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 * 描述Recursion Algorithm * Author : geovindu,Geovin Du 涂聚文. * IDE : IntelliJ IDEA 2024.3.6 Java 17 * # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j * # OS : window10 * Datetime : 2026 - 2026/7/17 - 23:04 * User : geovindu * Product : IntelliJ IDEA * Project : JavaAlgorithms * File : RecursionBll.java * explain : 学习 类 **/ package Bll; import java.util.*; import java.util.stream.Collectors; import Recursion.*; /** * 珠宝集团组织构建工具 */ class JewelryGroupBuilder { public MapString, OrgNode nodeMap new HashMap(); public OrgNode build() { // 根节点集团总部 OrgNode root new OrgNode(G001, 璀璨珠宝集团总部, 集团总部, , false); root.addPerm(org_mgr); root.addPerm(role_global); root.addPerm(data_export_all); root.addPerm(gold_price_edit); // 国内事业部 OrgNode domestic new OrgNode(D001, 国内运营事业部, 事业部, G001, false); domestic.addPerm(finance_stat); domestic.addPerm(cost_allocate); root.addChild(domestic); // 华南分公司 OrgNode huanan new OrgNode(D001-1, 华南分公司, 国内分公司, D001, false); huanan.addPerm(stock_inout); domestic.addChild(huanan); OrgNode szShop new OrgNode(SH-SZ01, 深圳旗舰店, 线下门店, D001-1, false); szShop.addPerm(sale_view); szShop.addPerm(sale_create); huanan.addChild(szShop); OrgNode joinShop new OrgNode(SH-J001, 东莞加盟门店, 加盟门店, D001-1, true); joinShop.addPerm(sale_view); huanan.addChild(joinShop); // 华东分公司 OrgNode huadong new OrgNode(D001-2, 华东分公司, 国内分公司, D001, false); OrgNode shShop new OrgNode(SH-SH01, 上海总店, 线下门店, D001-2, false); shShop.addPerm(sale_create); huadong.addChild(shShop); domestic.addChild(huadong); // 海外事业部 OrgNode oversea new OrgNode(O001, 海外国际事业部, 事业部, G001, false); oversea.addPerm(foreign_exchange); root.addChild(oversea); // 新加坡子公司 OrgNode sgCompany new OrgNode(O001-1, 新加坡子公司, 海外子公司, O001, false); sgCompany.addPerm(custom_declare); OrgNode sgShop new OrgNode(SH-SG01, 新加坡乌节路门店, 海外门店, O001-1, false); sgShop.addPerm(sale_view); sgCompany.addChild(sgShop); oversea.addChild(sgCompany); // 洛杉矶子公司 OrgNode usCompany new OrgNode(O001-2, 洛杉矶子公司, 海外子公司, O001, false); usCompany.addPerm(oversea_tax); OrgNode usShop new OrgNode(SH-US01, 洛杉矶门店, 海外门店, O001-2, false); usShop.addPerm(sale_view); usCompany.addChild(usShop); oversea.addChild(usCompany); // 递归填充ID映射表 collectNode(root); return root; } private void collectNode(OrgNode node) { nodeMap.put(node.getOrgId(), node); for (OrgNode child : node.getChildren()) { collectNode(child); } } } public class RecursionBll { public void Demo() { JewelryGroupBuilder builder new JewelryGroupBuilder(); OrgNode root builder.build(); MapString, OrgNode nodeMap builder.nodeMap; OrgRecursionUtil util new OrgRecursionUtil(); System.out.println( 1. 完整组织树含加盟门店标记 ); util.printTree(root, 0); // 扩展1角色递归下发全集团 Role globalSaleRole new Role(R001, 集团通用销售角色, Arrays.asList(sale_view, stock_view)); util.roleSyncRecursive(root, globalSaleRole); System.out.println(\n 【扩展1】角色递归下发完成全集团绑定销售角色 ); // 模拟销售订单 ListSaleOrder allOrders Arrays.asList( new SaleOrder(OD001, SH-SZ01, 12800), new SaleOrder(OD002, SH-J001, 6500), new SaleOrder(OD003, SH-SH01, 23000), new SaleOrder(OD004, SH-SG01, 9600) ); // 华南分公司管理员 Staff southAdmin new Staff(U2001, 华南运营总监, D001-1); // 扩展2行级订单过滤 System.out.println(\n 【扩展2】华南管理员行级过滤后的销售订单 ); ListSaleOrder filterOrders util.filterSaleOrders(root, southAdmin, allOrders); for (SaleOrder o : filterOrders) { System.out.printf(订单%s 门店ID:%s 金额:%.0f%n, o.getOrderId(), o.getShopOrgId(), o.getAmount()); } // 扩展3/4权限汇总国内屏蔽海外权限 System.out.println(\n 【扩展3/4】华南管理员权限无海外报关/外币权限 ); SetString southPermSet util.getUserTotalPerms(root, southAdmin, nodeMap); ListString southPermList southPermSet.stream() .map(k - PermConstant.PERMISSION_MAP.get(k)) .sorted() .collect(Collectors.toList()); for (String p : southPermList) { System.out.println(- p); } // 新加坡海外管理员 Staff sgAdmin new Staff(U3001, 新加坡负责人, O001-1); System.out.println(\n 海外子公司管理员权限包含海外专属权限 ); SetString sgPermSet util.getUserTotalPerms(root, sgAdmin, nodeMap); ListString sgPermList sgPermSet.stream() .map(k - PermConstant.PERMISSION_MAP.get(k)) .sorted() .collect(Collectors.toList()); for (String p : sgPermList) { System.out.println(- p); } // 扩展5递归导出审计报表 System.out.println(\n 【扩展5】递归导出集团审计权限报表 ); ListAuditRow auditReport new ArrayList(); util.exportReport(root, auditReport, 0); for (AuditRow row : auditReport) { StringBuilder indent new StringBuilder(); for (int i 0; i row.getLevel(); i) indent.append( ); String joinTag row.isJoin() ? 【加盟】 : ; System.out.printf(%s%s%s | 自有权限:%s | 绑定角色:%s%n, indent, joinTag, row.getOrgName(), row.getOwnPermNames(), row.getBindRoleNames()); } } }输出