CSharp: Divide and Conquer Algorithm

项目结构:

image

 

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : Const.cs

 */
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.Constants
{


    /// <summary>
    /// 
    /// </summary>
    public static class Const
    {
        // 风控高客单阈值 10万
        public const double RiskAmountThreshold = 100000.0d;

        // 门店列表
        public static readonly List<string> ShopList = new() { "福田店", "南山店" };

        // 季度对应月份
        public static readonly Dictionary<int, int[]> QuarterMonthMap = new()
        {
            {1, new[] {1,2,3}},
            {2, new[] {4,5,6}},
            {3, new[] {7,8,9}},
            {4, new[] {10,11,12}}
        };

        // 品类
        public static readonly List<string> CategoryList = new() { "黄金", "钻石", "彩宝", "银饰" };

        // 权限常量
        public const string PermDiamondAdjust = "钻石调价";
        public const string PermExportAllShop = "全门店数据导出";
        public const string PermShopAdjust = "本店调价";
        public const string PermModifyRole = "修改角色权限";
        public const string PermViewSelfSale = "查看个人业绩";
        public const string PermViewStock = "库存盘点";
    }
}



/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : Order.cs

 */
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.Entity
{
    /// <summary>
    /// 珠宝销售订单
    /// </summary>
    public record JewelryOrder
    {
        public string OrderID { get; set; }
        public string ShopName { get; set; }
        public int SaleMonth { get; set; }
        public int Quarter { get; set; }
        public string Category { get; set; }
        public double SaleAmount { get; set; }
        public double Profit { get; set; }
        public string SellerID { get; set; }
    }

    /// <summary>
    /// 销售汇总统计,支持加法合并
    /// </summary>
    public class SaleSummary
    {
        public double TotalSales { get; set; }
        public double TotalProfit { get; set; }
        public double Gold { get; set; }
        public double Diamond { get; set; }
        public double Gem { get; set; }
        public double Silver { get; set; }

        /// <summary>
        /// 合并两份统计结果(对应分治Combine)
        /// </summary>
        public SaleSummary Add(SaleSummary other)
        {
            return new SaleSummary
            {
                TotalSales = TotalSales + other.TotalSales,
                TotalProfit = TotalProfit + other.TotalProfit,
                Gold = Gold + other.Gold,
                Diamond = Diamond + other.Diamond,
                Gem = Gem + other.Gem,
                Silver = Silver + other.Silver
            };
        }

        /// <summary>
        /// 转字典用于打印报表
        /// </summary>
        public Dictionary<string, double> ToDict()
        {
            return new Dictionary<string, double>()
            {
                {"总销售额", TotalSales},
                {"总毛利", TotalProfit},
                {"黄金", Gold},
                {"钻石", Diamond},
                {"彩宝", Gem},
                {"银饰", Silver}
            };
        }
    }

}



/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : OrderBuilder.cs

 */

using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.Entity
{

    /// <summary>
    /// 
    /// </summary>
    public static class OrderBuilder
    {
        /// <summary>
        /// 单条订单构建最小汇总Conquer结果
        /// </summary>
        public static SaleSummary BuildSingleSummary(JewelryOrder order)
        {
            var s = new SaleSummary
            {
                TotalSales = order.SaleAmount,
                TotalProfit = order.Profit
            };
            switch (order.Category)
            {
                case "黄金": s.Gold = order.SaleAmount; break;
                case "钻石": s.Diamond = order.SaleAmount; break;
                case "彩宝": s.Gem = order.SaleAmount; break;
                case "银饰": s.Silver = order.SaleAmount; break;
            }
            return s;
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : Role.cs

 */

using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.Entity
{
    /// <summary>
    /// 权限二叉树节点
    /// </summary>
    public class JewelryRoleNode
    {
        public string RoleName { get; set; }
        public List<string> Permissions { get; set; } = new();
        public JewelryRoleNode? Left { get; set; }
        public JewelryRoleNode? Right { get; set; }
    }
}

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : OrderRepo.cs

 */

using CSharpAlgorithms.DivideConquer.Constants;
using CSharpAlgorithms.DivideConquer.Entity;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.Repository
{

    /// <summary>
    /// 
    /// </summary>
    public class OrderRepository
    {
        private readonly List<JewelryOrder> _data = new();

        public void Add(JewelryOrder order) => _data.Add(order);

        public void BatchAdd(List<JewelryOrder> orders) => _data.AddRange(orders);

        public List<JewelryOrder> GetAll() => new List<JewelryOrder>(_data);

        /// <summary>
        /// Divide:按门店拆分订单
        /// </summary>
        public Dictionary<string, List<JewelryOrder>> SplitByShop()
        {
            var splitMap = new Dictionary<string, List<JewelryOrder>>();
            foreach (var shop in Const.ShopList)
                splitMap[shop] = new List<JewelryOrder>();

            foreach (var o in _data)
            {
                if (splitMap.ContainsKey(o.ShopName))
                    splitMap[o.ShopName].Add(o);
            }
            return splitMap;
        }

        /// <summary>
        /// Divide:按月份拆分订单
        /// </summary>
        public Dictionary<int, List<JewelryOrder>> SplitByMonth()
        {
            var splitMap = new Dictionary<int, List<JewelryOrder>>();
            for (int m = 1; m <= 12; m++)
                splitMap[m] = new List<JewelryOrder>();

            foreach (var o in _data)
                splitMap[o.SaleMonth].Add(o);
            return splitMap;
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : RoleRepo.cs

 */

using CSharpAlgorithms.DivideConquer.Entity;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.Repository
{

    /// <summary>
    /// 
    /// </summary>
    public class RoleRepository
    {
        private JewelryRoleNode? _root;

        public void SetRoot(JewelryRoleNode root) => _root = root;

        public JewelryRoleNode? GetRoot() => _root;
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : Util.cs

 */

using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.Utils
{

    /// <summary>
    /// 
    /// </summary>
    public static class Util
    {
        /// <summary>
        /// 金额保留两位小数
        /// </summary>
        public static string FormatFloat(double val)
        {
            return val.ToString("0.00");
        }

        /// <summary>
        /// 多线程并行批量执行任务
        /// </summary>
        public static List<object> ParallelBatchExecute(List<Func<object>> tasks)
        {
            var results = new List<object>();
            Parallel.ForEach(tasks, t =>
            {
                lock (results)
                {
                    results.Add(t.Invoke());
                }
            });
            return results;
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : BaseDAC.cs

 */

using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.DAC
{
    /// <summary>
    /// 通用分治标准接口 Divide-Conquer-Combine
    /// TInput:单条输入元素
    /// TOutput:子问题输出结果
    /// 泛型分治抽象接口
    /// </summary>
    public interface IBaseDAC<TInput, TOutput>
    {
        TOutput Conquer(TInput data);
        TOutput Combine(TOutput left, TOutput right);
    }
    /// <summary>
    /// 
    /// </summary>
    public static class DACHelper
    {
        /// <summary>
        /// 通用递归分治入口
        /// </summary>
        public static TOutput RecursiveDAC<TInput, TOutput>(IBaseDAC<TInput, TOutput> dac, List<TInput> data, int l, int r)
        {
            if (l == r)
                return dac.Conquer(data[l]);

            int mid = (l + r) / 2;
            var leftRes = RecursiveDAC(dac, data, l, mid);
            var rightRes = RecursiveDAC(dac, data, mid + 1, r);
            return dac.Combine(leftRes, rightRes);
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      :PermDAC.cs

 */

using CSharpAlgorithms.DivideConquer.Entity;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.DAC
{


    /// <summary>
    /// 权限树分治 + 数据过滤分治
    /// </summary>
    public class PermissionDAC
    {
        /// <summary>
        /// 二叉树分治校验功能权限
        /// </summary>
        public bool CheckPerm(JewelryRoleNode? root, string targetPerm)
        {
            if (root == null) return false;
            if (root.Permissions.Contains(targetPerm))
                return true;

            bool leftOk = CheckPerm(root.Left, targetPerm);
            bool rightOk = CheckPerm(root.Right, targetPerm);
            return leftOk || rightOk;
        }

        /// <summary>
        /// 分治二分过滤当前角色可见订单(数据权限隔离)
        /// </summary>
        public List<JewelryOrder> FilterOrderByPerm(List<JewelryOrder> orders, List<string> rolePerms, string sellerId)
        {
            List<JewelryOrder> DacFilter(int l, int r)
            {
                if (l == r)
                {
                    var ord = orders[l];
                    bool hasSelfView = rolePerms.Contains(Constants.Const.PermViewSelfSale);
                    if (hasSelfView && ord.SellerID != sellerId)
                        return new List<JewelryOrder>();
                    return new List<JewelryOrder> { ord };
                }
                int mid = (l + r) / 2;
                var left = DacFilter(l, mid);
                var right = DacFilter(mid + 1, r);
                left.AddRange(right);
                return left;
            }

            if (orders.Count == 0)
                return new List<JewelryOrder>();
            return DacFilter(0, orders.Count - 1);
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : RiskDAC.cs

 */

using CSharpAlgorithms.DivideConquer.Entity;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.DAC
{

    /// <summary>
    /// 高客单风控分治
    /// </summary>
    public class RiskOrderDAC : IBaseDAC<JewelryOrder, List<JewelryOrder>>
    {
        public double Threshold { get; set; }

        public RiskOrderDAC(double threshold)
        {
            Threshold = threshold;
        }

        public List<JewelryOrder> Conquer(JewelryOrder data)
        {
            if (data.SaleAmount > Threshold)
                return new List<JewelryOrder> { data };
            return new List<JewelryOrder>();
        }

        public List<JewelryOrder> Combine(List<JewelryOrder> left, List<JewelryOrder> right)
        {
            left.AddRange(right);
            return left;
        }

        public List<JewelryOrder> ScanRisk(List<JewelryOrder> data)
        {
            if (data.Count == 0)
                return new List<JewelryOrder>();
            return DACHelper.RecursiveDAC(this, data, 0, data.Count - 1);
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : StatDAC.cs

 */

using CSharpAlgorithms.DivideConquer.Entity;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.DAC
{

    /// <summary>
    /// 销售统计分治实现
    /// </summary>
    public class SaleStatDAC : IBaseDAC<JewelryOrder, SaleSummary>
    {
        public SaleSummary Conquer(JewelryOrder data)
        {
            return OrderBuilder.BuildSingleSummary(data);
        }

        public SaleSummary Combine(SaleSummary left, SaleSummary right)
        {
            return left.Add(right);
        }

        public SaleSummary CalcTotal(List<JewelryOrder> data)
        {
            if (data.Count == 0)
                return new SaleSummary();
            return DACHelper.RecursiveDAC(this, data, 0, data.Count - 1);
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : PermissionService.cs

 */

using CSharpAlgorithms.DivideConquer.DAC;
using CSharpAlgorithms.DivideConquer.Entity;
using CSharpAlgorithms.DivideConquer.Repository;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.Service
{

    /// <summary>
    /// 
    /// </summary>
    public class PermissionService
    {
        private readonly RoleRepository _repo;
        private readonly PermissionDAC _dac;

        public PermissionService(RoleRepository repo)
        {
            _repo = repo;
            _dac = new PermissionDAC();
        }

        public bool HasPermission(string permKey)
        {
            var root = _repo.GetRoot();
            return _dac.CheckPerm(root, permKey);
        }

        public List<JewelryOrder> GetVisibleOrders(List<JewelryOrder> allOrders, string sellerId)
        {
            var root = _repo.GetRoot();
            if (root == null) return new List<JewelryOrder>();
            return _dac.FilterOrderByPerm(allOrders, root.Permissions, sellerId);
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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   : CSharpAlgorithms
# File      : RiskScreenService.cs

 */
using CSharpAlgorithms.DivideConquer.DAC;
using CSharpAlgorithms.DivideConquer.Entity;
using CSharpAlgorithms.DivideConquer.Repository;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.Service
{

    /// <summary>
    /// 
    /// </summary>
    public class RiskScreenService
    {
        private readonly OrderRepository _repo;
        private readonly RiskOrderDAC _dac;

        public RiskScreenService(OrderRepository repo, double threshold)
        {
            _repo = repo;
            _dac = new RiskOrderDAC(threshold);
        }

        public List<JewelryOrder> ScanHighAmountOrders()
        {
            var all = _repo.GetAll();
            return _dac.ScanRisk(all);
        }

        public void ModifyThreshold(double newVal)
        {
            _dac.Threshold = newVal;
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : SaleStatService.cs

 */

using CSharpAlgorithms.DivideConquer.Constants;
using CSharpAlgorithms.DivideConquer.DAC;
using CSharpAlgorithms.DivideConquer.Entity;
using CSharpAlgorithms.DivideConquer.Repository;
using CSharpAlgorithms.DivideConquer.Utils;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.Service
{

    /// <summary>
    /// 
    /// </summary>
    public class SaleStatService
    {
        private readonly OrderRepository _repo;
        private readonly SaleStatDAC _dac;

        public SaleStatService(OrderRepository repo)
        {
            _repo = repo;
            _dac = new SaleStatDAC();
        }

        /// <summary>
        /// 多线程并行分治统计各门店业绩
        /// </summary>
        public Dictionary<string, SaleSummary> StatByShopParallel()
        {
            var shopSplit = _repo.SplitByShop();
            var tasks = new List<Func<object>>();
            var shopNames = new List<string>();

            foreach (var kv in shopSplit)
            {
                shopNames.Add(kv.Key);
                var ords = kv.Value;
                tasks.Add(() => _dac.CalcTotal(ords));
            }

            var resList = Util.ParallelBatchExecute(tasks);
            var shopResult = new Dictionary<string, SaleSummary>();
            var totalAll = new SaleSummary();

            for (int i = 0; i < shopNames.Count; i++)
            {
                var sum = (SaleSummary)resList[i];
                shopResult[shopNames[i]] = sum;
                totalAll = totalAll.Add(sum);
            }
            shopResult["集团全部门店合计"] = totalAll;
            return shopResult;
        }

        /// <summary>
        /// 按月分治,合并季度、年度报表
        /// </summary>
        public Dictionary<string, object> StatByTime()
        {
            var monthSplit = _repo.SplitByMonth();
            var monthSummary = new Dictionary<int, SaleSummary>();
            foreach (var kv in monthSplit)
                monthSummary[kv.Key] = _dac.CalcTotal(kv.Value);

            var quarterSummary = new Dictionary<int, SaleSummary>()
            {
                {1, new SaleSummary()},
                {2, new SaleSummary()},
                {3, new SaleSummary()},
                {4, new SaleSummary()}
            };

            var yearTotal = new SaleSummary();
            foreach (var qKv in Const.QuarterMonthMap)
            {
                foreach (int m in qKv.Value)
                    quarterSummary[qKv.Key] = quarterSummary[qKv.Key].Add(monthSummary[m]);
            }
            foreach (var mSum in monthSummary.Values)
                yearTotal = yearTotal.Add(mSum);

            var monthDict = new Dictionary<string, SaleSummary>();
            for (int m = 1; m <= 12; m++)
                monthDict[$"{m}月"] = monthSummary[m];

            return new Dictionary<string, object>()
            {
                {"月度明细", monthDict},
                {"季度汇总", quarterSummary},
                {"年度总报表", yearTotal}
            };
        }
    }
}


/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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   : CSharpAlgorithms
# File      : JewelryDACApp.cs

 */


using CSharpAlgorithms.DivideConquer.Constants;
using CSharpAlgorithms.DivideConquer.Entity;
using CSharpAlgorithms.DivideConquer.Repository;
using CSharpAlgorithms.DivideConquer.Service;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.DivideConquer.App
{


    /// <summary>
    /// 
    /// </summary>
    public class JewelryDACApp
    {
        private readonly OrderRepository _orderRepo;
        private readonly RoleRepository _roleRepo;

        public PermissionService PermSvc { get; }
        public SaleStatService SaleStatSvc { get; }
        public RiskScreenService RiskSvc { get; }

        public JewelryDACApp()
        {
            _orderRepo = new OrderRepository();
            _roleRepo = new RoleRepository();

            PermSvc = new PermissionService(_roleRepo);
            SaleStatSvc = new SaleStatService(_orderRepo);
            RiskSvc = new RiskScreenService(_orderRepo, Const.RiskAmountThreshold);
        }

        /// <summary>
        /// 订单仓储代理
        /// </summary>
        /// <param name="o"></param>
        public void AddOrder(JewelryOrder o) => _orderRepo.Add(o);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="orders"></param>
        public void BatchAddOrders(List<JewelryOrder> orders) => _orderRepo.BatchAdd(orders);

        /// <summary>
        /// 权限树构建
        /// </summary>
        /// <param name="root"></param>
        public void BuildPermissionTree(JewelryRoleNode root) => _roleRepo.SetRoot(root);

        /// <summary>
        /// 对外业务接口
        /// </summary>
        /// <param name="permKey"></param>
        /// <returns></returns>
        public bool CheckPermission(string permKey) => PermSvc.HasPermission(permKey);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sellerId"></param>
        /// <returns></returns>
        public List<JewelryOrder> GetUserVisibleOrders(string sellerId)
        {
            var all = _orderRepo.GetAll();
            return PermSvc.GetVisibleOrders(all, sellerId);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, SaleSummary> QueryShopSalesStat()
            => SaleStatSvc.StatByShopParallel();
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, object> QueryTimeSalesStat()
            => SaleStatSvc.StatByTime();
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public List<JewelryOrder> QueryRiskOrders()
            => RiskSvc.ScanHighAmountOrders();
    }
}

  

调用:

/*
 # encoding: utf-8 
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Divide and Conquer  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/05 22:16 
# User      :  geovindu
# Product   : Visual Studio 2026
# Project   : CSharpAlgorithms
# File      : DivideConquerBll.cs

 */

using CSharpAlgorithms.DivideConquer.App;
using CSharpAlgorithms.DivideConquer.Constants;
using CSharpAlgorithms.DivideConquer.Entity;
using CSharpAlgorithms.DivideConquer.Utils;
using System;
using System.Collections.Generic;
using System.Text;

namespace CSharpAlgorithms.Bll
{


    /// <summary>
    /// 
    /// </summary>
    public class DivideConquerBll
    {

        public void Demo()
        {

            var app = new JewelryDACApp();

            // 模拟测试订单
            var mockOrders = new List<JewelryOrder>()
            {
                new JewelryOrder
                {
                    OrderID = "O001", ShopName = "福田店", SaleMonth = 2, Quarter = 1,
                    Category = "黄金", SaleAmount = 6280, Profit = 1300, SellerID = "S001"
                },
                new JewelryOrder
                {
                    OrderID = "O002", ShopName = "福田店", SaleMonth = 3, Quarter = 1,
                    Category = "钻石", SaleAmount = 128600, Profit = 48000, SellerID = "S001"
                },
                new JewelryOrder
                {
                    OrderID = "O003", ShopName = "南山店", SaleMonth = 5, Quarter = 2,
                    Category = "彩宝", SaleAmount = 8900, Profit = 3600, SellerID = "S002"
                },
                new JewelryOrder
                {
                    OrderID = "O004", ShopName = "南山店", SaleMonth = 6, Quarter = 2,
                    Category = "钻石", SaleAmount = 96000, Profit = 39000, SellerID = "S002"
                },
                new JewelryOrder
                {
                    OrderID = "O005", ShopName = "福田店", SaleMonth = 9, Quarter = 3,
                    Category = "银饰", SaleAmount = 499, Profit = 220, SellerID = "S003"
                },
                new JewelryOrder
                {
                    OrderID = "O006", ShopName = "南山店", SaleMonth = 11, Quarter = 4,
                    Category = "钻石", SaleAmount = 156000, Profit = 62000, SellerID = "S004"
                },
                new JewelryOrder
                {
                    OrderID = "O007", ShopName = "福田店", SaleMonth = 12, Quarter = 4,
                    Category = "黄金", SaleAmount = 8600, Profit = 1800, SellerID = "S003"
                }
            };
            app.BatchAddOrders(mockOrders);

            // 构建权限二叉树
            var guide = new JewelryRoleNode
            {
                RoleName = "门店导购",
                Permissions = new List<string> { Const.PermViewSelfSale }
            };
            var keeper = new JewelryRoleNode
            {
                RoleName = "仓管",
                Permissions = new List<string> { Const.PermViewStock }
            };
            var shopMgr = new JewelryRoleNode
            {
                RoleName = "门店店长",
                Permissions = new List<string> { Const.PermShopAdjust },
                Left = guide,
                Right = keeper
            };
            var areaMgr = new JewelryRoleNode
            {
                RoleName = "华南区域经理",
                Permissions = new List<string> { Const.PermDiamondAdjust },
                Left = shopMgr
            };
            var groupAdmin = new JewelryRoleNode
            {
                RoleName = "集团管理员",
                Permissions = new List<string> { Const.PermExportAllShop, Const.PermModifyRole },
                Left = areaMgr
            };
            app.BuildPermissionTree(groupAdmin);

            // 1. 并行分治门店业绩
            Console.WriteLine("======= 【并行分治-门店业绩汇总】 =======");
            var shopStat = app.QueryShopSalesStat();
            foreach (var kv in shopStat)
            {
                Console.WriteLine($"\n【{kv.Key}】");
                var map = kv.Value.ToDict();
                foreach (var d in map)
                {
                    Console.WriteLine($"{d.Key}: {Util.FormatFloat(d.Value)}");
                }
            }

            // 2. 时间分治报表
            Console.WriteLine("\n======= 【时间分治-年度经营报表】 =======");
            var timeStat = app.QueryTimeSalesStat();
            var yearSum = (SaleSummary)timeStat["年度总报表"];
            Console.WriteLine($"全年总销售额:{Util.FormatFloat(yearSum.TotalSales)},全年毛利:{Util.FormatFloat(yearSum.TotalProfit)}");
            Console.WriteLine("\n季度汇总:");
            var quarterMap = (Dictionary<int, SaleSummary>)timeStat["季度汇总"];
            foreach (var q in quarterMap)
            {
                Console.WriteLine($"Q{q.Key} 销售总额:{Util.FormatFloat(q.Value.TotalSales)}");
            }

            // 3. 风控高客单
            Console.WriteLine("\n======= 【风控分治-超10万异常订单】 =======");
            var riskList = app.QueryRiskOrders();
            if (riskList.Count > 0)
            {
                foreach (var item in riskList)
                {
                    Console.WriteLine($"订单{item.OrderID} | {item.ShopName} | {item.Category} | {Util.FormatFloat(item.SaleAmount)}元");
                }
            }
            else
            {
                Console.WriteLine("无风险订单");
            }

            // 4. 权限校验
            Console.WriteLine("\n======= 【树形分治权限校验】 =======");
            Console.WriteLine($"区域经理是否可钻石调价:{app.CheckPermission(Const.PermDiamondAdjust)}");
            Console.WriteLine($"店长是否可导出全门店数据:{app.CheckPermission(Const.PermExportAllShop)}");
            Console.WriteLine($"集团是否可修改角色权限:{app.CheckPermission(Const.PermModifyRole)}");

            // 5. 导购数据权限过滤
            Console.WriteLine("\n======= 【分治数据权限过滤-导购S001可见订单】 =======");
            var userOrders = app.GetUserVisibleOrders("S001");
            foreach (var o in userOrders)
            {
                Console.WriteLine($"{o.OrderID} | 开单人:{o.SellerID} | {Util.FormatFloat(o.SaleAmount)}");
            }

        }

    }
}

  

输出:

33f9f2dc35e9af5239a64f295adbd5f1

 

posted @ 2026-07-19 16:22  ®Geovin Du Dream Park™  阅读(7)  评论(0)    收藏  举报