CSharp: Recursion Algorithm

CSharp: Recursion Algorithm /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Recursion Algorithm # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/07/04 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : PermConstant.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.Recursion { /// summary /// 权限常量配置 /// /summary public static class PermConstant { /// summary /// 权限Key-中文名称映射 /// /summary public static readonly Dictionarystring, string PermissionMap new Dictionarystring, string() { {sale_view, 销售单据查看}, {sale_create, 开单销售}, {stock_view, 库存查询}, {stock_inout, 金饰玉石出入库}, {member_manage, 会员管理}, {finance_stat, 财务报表}, {cost_allocate, 区域成本分摊}, {gold_price_edit, 金价调整}, {custom_declare, 海外报关}, {foreign_exchange, 外币对账}, {oversea_tax, 境外税务核算}, {org_mgr, 组织架构编辑}, {role_global, 全局角色配置}, {data_export_all, 全集团数据导出} }; /// summary /// 海外专属权限集合 /// /summary public static readonly HashSetstring OverseaPermSet new HashSetstring() { custom_declare, foreign_exchange, oversea_tax }; } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Recursion Algorithm # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/07/04 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : Role.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.Recursion { /// summary /// 角色实体 /// /summary public class Role { public string RoleId { get; set; } public string RoleName { get; set; } public HashSetstring Perms { get; set; } public Role(string rid, string rname, Liststring permKeys) { RoleId rid; RoleName rname; Perms new HashSetstring(permKeys); } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Recursion Algorithm # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/07/04 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : OrgNode.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.Recursion { /// summary /// 组织树节点 /// /summary public class OrgNode { public string OrgId { get; set; } public string OrgName { get; set; } public string OrgType { get; set; } public string ParentId { get; set; } public bool IsJoin { get; set; } // 加盟门店隔离标记 public ListOrgNode Children { get; set; } public HashSetstring Perms { get; set; } // 本组织自有权限 public ListRole BindRoles { get; set; } // 绑定角色 public OrgNode(string oid, string oname, string otype, string pid, bool isJoin) { OrgId oid; OrgName oname; OrgType otype; ParentId pid; IsJoin isJoin; Children new ListOrgNode(); Perms new HashSetstring(); BindRoles new ListRole(); } public void AddChild(OrgNode child) Children.Add(child); public void AddPerm(string permKey) { if (PermConstant.PermissionMap.ContainsKey(permKey)) Perms.Add(permKey); } public void BindRole(Role role) BindRoles.Add(role); } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Recursion Algorithm # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/07/04 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : Staff.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.Recursion { /// summary /// 员工用户 /// /summary public class Staff { public string Uid { get; set; } public string Name { get; set; } public string BindOrgId { get; set; } public HashSetstring RolePerms { get; set; } public Staff(string uid, string name, string bindOid) { Uid uid; Name name; BindOrgId bindOid; RolePerms new HashSetstring(); } public void AssignPerm(string permKey) { if (PermConstant.PermissionMap.ContainsKey(permKey)) RolePerms.Add(permKey); } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Recursion Algorithm # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/07/04 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : SaleOrder.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.Recursion { /// summary /// 销售订单行级过滤 /// /summary public class SaleOrder { public string OrderId { get; set; } public string ShopOrgId { get; set; } public double Amount { get; set; } public SaleOrder(string oid, string shopId, double amt) { OrderId oid; ShopOrgId shopId; Amount amt; } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Recursion Algorithm # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/07/04 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : AuditRow.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.Recursion { /// summary /// 审计报表行 /// /summary public class AuditRow { public int Level { get; set; } public string OrgName { get; set; } public bool IsJoin { get; set; } public Liststring OwnPermNames { get; set; } public Liststring BindRoleNames { get; set; } } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Recursion Algorithm # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/07/04 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : OrgRecursionUtil.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.Recursion { /// summary /// 递归工具类 /// /summary public class OrgRecursionUtil { #region 基础递归查找 /// summary /// 递归查找指定组织节点 /// /summary /// param nameroot/param /// param nametargetId/param /// returns/returns public OrgNode FindNode(OrgNode root, string targetId) { if (root.OrgId targetId) return root; foreach (var child in root.Children) { var res FindNode(child, targetId); if (res ! null) return res; } return null; } /// summary /// 向下递归获取所有下级加盟门店终止递归 /// /summary /// param nameroot/param /// param nametargetId/param /// returns/returns public ListOrgNode GetAllSubOrgs(OrgNode root, string targetId) { var target FindNode(root, targetId); var list new ListOrgNode(); if (target null) return list; DfsSub(target, list); return list; } /// summary /// /// /summary /// param namenode/param /// param namelist/param private void DfsSub(OrgNode node, ListOrgNode list) { list.Add(node); if (node.IsJoin) return; foreach (var c in node.Children) DfsSub(c, list); } /// summary /// 向上递归获取整条父级链路 /// /summary /// param nameroot/param /// param nametargetId/param /// param namenodeMap/param /// returns/returns public ListOrgNode GetParentChain(OrgNode root, string targetId, Dictionarystring, OrgNode nodeMap) { var target FindNode(root, targetId); var parents new ListOrgNode(); if (target null || string.IsNullOrEmpty(target.ParentId)) return parents; UpRecur(target, nodeMap, parents); return parents; } /// summary /// /// /summary /// param namenode/param /// param namenodeMap/param /// param nameparents/param private void UpRecur(OrgNode node, Dictionarystring, OrgNode nodeMap, ListOrgNode parents) { var pid node.ParentId; if (string.IsNullOrEmpty(pid)) return; if (nodeMap.TryGetValue(pid, out var pNode)) { parents.Add(pNode); UpRecur(pNode, nodeMap, parents); } } #endregion #region 五大扩展功能 /// summary /// 扩展1角色递归下发全集团 /// /summary /// param namenode/param /// param namerole/param public void RoleSyncRecursive(OrgNode node, Role role) { node.BindRole(role); foreach (var child in node.Children) RoleSyncRecursive(child, role); } /// summary /// 扩展2销售订单行级递归过滤 /// /summary /// param nameroot/param /// param nameuser/param /// param nameallOrders/param /// returns/returns public ListSaleOrder FilterSaleOrders(OrgNode root, Staff user, ListSaleOrder allOrders) { var subs GetAllSubOrgs(root, user.BindOrgId); var allowIds subs.Select(o o.OrgId).ToHashSet(); return allOrders.Where(o allowIds.Contains(o.ShopOrgId)).ToList(); } /// summary /// 核心汇总用户完整权限父级自身下级 海外权限隔离 /// /summary /// param nameroot/param /// param nameuser/param /// param namenodeMap/param /// returns/returns public HashSetstring GetUserTotalPerms(OrgNode root, Staff user, Dictionarystring, OrgNode nodeMap) { var total new HashSetstring(user.RolePerms); var targetNode FindNode(root, user.BindOrgId); if (targetNode null) return total; var parents GetParentChain(root, user.BindOrgId, nodeMap); var subs GetAllSubOrgs(root, user.BindOrgId); var allOrgs parents.Concat(subs).ToList(); foreach (var org in allOrgs) { var tempPerm new HashSetstring(org.Perms); // 国内组织剔除海外权限 if (org.OrgType ! 海外子公司 !org.OrgType.StartsWith(海外)) { foreach (var op in PermConstant.OverseaPermSet) tempPerm.Remove(op); } foreach (var p in tempPerm) total.Add(p); } return total; } /// summary /// 递归打印组织树 /// /summary /// param namenode/param /// param namelevel/param public void PrintTree(OrgNode node, int level 0) { string indent new string( , level * 4); string tag node.IsJoin ? [加盟] : ; Console.WriteLine(${indent}[{node.OrgType}]{tag} {node.OrgName} (ID:{node.OrgId})); foreach (var child in node.Children) PrintTree(child, level 1); } /// summary /// 递归批量回收权限 /// /summary /// param namenode/param /// param namepermKey/param public void RevokePermRecursive(OrgNode node, string permKey) { node.Perms.Remove(permKey); foreach (var child in node.Children) RevokePermRecursive(child, permKey); } /// summary /// 扩展5递归导出审计权限报表 /// /summary /// param namenode/param /// param namereport/param /// param namelevel/param public void ExportReport(OrgNode node, ListAuditRow report, int level 0) { var ownPermNames node.Perms .Select(k PermConstant.PermissionMap[k]) .OrderBy(x x) .ToList(); var roleNames node.BindRoles.Select(r r.RoleName).ToList(); report.Add(new AuditRow { Level level, OrgName node.OrgName, IsJoin node.IsJoin, OwnPermNames ownPermNames, BindRoleNames roleNames }); if (node.IsJoin) return; foreach (var child in node.Children) ExportReport(child, report, level 1); } #endregion } } /* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Recursion Algorithm # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/07/04 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : JewelryGroupBuilder.cs */ using System; using System.Collections.Generic; using System.Text; namespace CSharpAlgorithms.Recursion { /// summary /// 构建珠宝集团完整组织树 /// /summary public static class JewelryGroupBuilder { /// summary /// /// /summary /// returns/returns public static (OrgNode Root, Dictionarystring, OrgNode NodeMap) Build() { var nodeMap new Dictionarystring, OrgNode(); // 集团总部根节点 var root new OrgNode(G001, 璀璨珠宝集团总部, 集团总部, , false); root.AddPerm(org_mgr); root.AddPerm(role_global); root.AddPerm(data_export_all); root.AddPerm(gold_price_edit); // 国内事业部 var domestic new OrgNode(D001, 国内运营事业部, 事业部, G001, false); domestic.AddPerm(finance_stat); domestic.AddPerm(cost_allocate); root.AddChild(domestic); // 华南分公司 var huanan new OrgNode(D001-1, 华南分公司, 国内分公司, D001, false); huanan.AddPerm(stock_inout); domestic.AddChild(huanan); var szShop new OrgNode(SH-SZ01, 深圳旗舰店, 线下门店, D001-1, false); szShop.AddPerm(sale_view); szShop.AddPerm(sale_create); huanan.AddChild(szShop); var joinShop new OrgNode(SH-J001, 东莞加盟门店, 加盟门店, D001-1, true); joinShop.AddPerm(sale_view); huanan.AddChild(joinShop); // 华东分公司 var huadong new OrgNode(D001-2, 华东分公司, 国内分公司, D001, false); var shShop new OrgNode(SH-SH01, 上海总店, 线下门店, D001-2, false); shShop.AddPerm(sale_create); huadong.AddChild(shShop); domestic.AddChild(huadong); // 海外事业部 var oversea new OrgNode(O001, 海外国际事业部, 事业部, G001, false); oversea.AddPerm(foreign_exchange); root.AddChild(oversea); // 新加坡子公司 var sgCompany new OrgNode(O001-1, 新加坡子公司, 海外子公司, O001, false); sgCompany.AddPerm(custom_declare); var sgShop new OrgNode(SH-SG01, 新加坡乌节路门店, 海外门店, O001-1, false); sgShop.AddPerm(sale_view); sgCompany.AddChild(sgShop); oversea.AddChild(sgCompany); // 洛杉矶子公司 var usCompany new OrgNode(O001-2, 洛杉矶子公司, 海外子公司, O001, false); usCompany.AddPerm(oversea_tax); var usShop new OrgNode(SH-US01, 洛杉矶门店, 海外门店, O001-2, false); usShop.AddPerm(sale_view); usCompany.AddChild(usShop); oversea.AddChild(usCompany); // 递归收集所有节点存入Map void Collect(OrgNode n) { nodeMap[n.OrgId] n; foreach (var c in n.Children) Collect(c); } Collect(root); return (root, nodeMap); } } }调用/* # encoding: utf-8 # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看言語成了邀功盡責的功臣還需要行爲每日來值班嗎 # 描述Recursion Algorithm # Author : geovindu,Geovin Du 涂聚文. # IDE : vs2026 c# .net 10 # os : windows 10 # database : mysql 9.0 sql server 2019, postgreSQL 17.0 Oracle 21c Neo4j # Datetime : 2026/07/04 22:16 # User : geovindu # Product : Visual Studio 2026 # Project : CSharpDesignPattern # File : RecursionBll.cs */ using System; using System.Collections.Generic; using System.Text; using CSharpAlgorithms.Recursion; namespace CSharpAlgorithms.Bll { /// summary /// /// /summary public class RecursionBll { public void Demo() { var (root, nodeMap) JewelryGroupBuilder.Build(); var util new OrgRecursionUtil(); Console.WriteLine( 1. 完整组织树含加盟门店标记 ); util.PrintTree(root); // 扩展1角色递归下发全集团 var globalSaleRole new Role(R001, 集团通用销售角色, new Liststring { sale_view, stock_view }); util.RoleSyncRecursive(root, globalSaleRole); Console.WriteLine(\n 【扩展1】角色递归下发完成全集团绑定销售角色 ); // 模拟销售订单 var allOrders new ListSaleOrder() { new SaleOrder(OD001, SH-SZ01, 12800), new SaleOrder(OD002, SH-J001, 6500), new SaleOrder(OD003, SH-SH01, 23000), new SaleOrder(OD004, SH-SG01, 9600) }; // 华南分公司管理员 var southAdmin new Staff(U2001, 华南运营总监, D001-1); // 扩展2行级订单过滤 Console.WriteLine(\n 【扩展2】华南管理员行级过滤后的销售订单 ); var filterOrd util.FilterSaleOrders(root, southAdmin, allOrders); foreach (var o in filterOrd) Console.WriteLine($订单{o.OrderId} 门店ID:{o.ShopOrgId} 金额:{o.Amount:F0}); // 扩展3/4权限汇总国内屏蔽海外权限 Console.WriteLine(\n 【扩展3/4】华南管理员权限无海外报关/外币权限 ); var southPerm util.GetUserTotalPerms(root, southAdmin, nodeMap) .Select(k PermConstant.PermissionMap[k]) .OrderBy(x x) .ToList(); foreach (var p in southPerm) Console.WriteLine($- {p}); // 新加坡海外管理员 var sgAdmin new Staff(U3001, 新加坡负责人, O001-1); Console.WriteLine(\n 海外子公司管理员权限包含海外专属权限 ); var sgPerm util.GetUserTotalPerms(root, sgAdmin, nodeMap) .Select(k PermConstant.PermissionMap[k]) .OrderBy(x x) .ToList(); foreach (var p in sgPerm) Console.WriteLine($- {p}); // 扩展5递归导出审计报表 Console.WriteLine(\n 【扩展5】递归导出集团审计权限报表 ); var auditReport new ListAuditRow(); util.ExportReport(root, auditReport); foreach (var row in auditReport) { string indent new string( , row.Level * 4); string joinTag row.IsJoin ? 【加盟】 : ; Console.WriteLine(${indent}{joinTag}{row.OrgName} | 自有权限:[{string.Join(,, row.OwnPermNames)}] | 绑定角色:[{string.Join(,, row.BindRoleNames)}]); } Console.ReadKey(); } } }输出代码实现了一个珠宝集团的组织权限管理系统主要功能包括构建多层级组织架构树包含总部、事业部、分公司、门店等节点实现权限管理功能定义常量权限映射表支持组织节点自有权限配置支持角色绑定和递归下发提供5个核心递归算法角色递归下发全集团销售订单行级递归过滤用户权限递归汇总含海外权限隔离递归打印组织树递归导出审计报表系统特点支持加盟门店特殊处理实现国内/海外权限隔离提供完整的权限审计功能使用递归算法处理树形结构数据代码采用C#实现包含完整的实体类和工具类展示了递归算法在企业管理系统中的典型应用场景。