| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- namespace Admin.NET.Plugin.AiDOP.SmartOps;
- /// <summary>
- /// KPI 原子聚合规则注册表(全局 S1-S9):指标如何从原子层二次聚合,以及支持哪些筛选字段。
- /// </summary>
- public static class SmartOpsKpiAggregateRuleRegistry
- {
- public const string DomainOrderDelivery = "order_delivery";
- public const string DomainWorkSchedule = "work_schedule";
- public const string DomainSupplyPurchase = "supply_purchase";
- public const string DomainInventory = "inventory";
- public const string AggSum = "sum";
- public const string AggRatio = "ratio";
- public const string AggAvg = "avg";
- public const string AggMin = "min";
- public const string AggMax = "max";
- public const string FilterFull = "filterable_full";
- public const string FilterPartial = "filterable_partial";
- public const string FilterSummaryOnly = "summary_only";
- private static readonly string[] OrderDeliveryFilters =
- ["dateStart", "dateEnd", "customer", "product", "orderNo", "productionLine"];
- private static readonly string[] WorkScheduleFilters =
- ["dateStart", "dateEnd", "product", "orderNo", "productionLine", "workOrder", "equipment"];
- private static readonly string[] SupplyPurchaseFilters =
- ["dateStart", "dateEnd", "supplier", "material", "poNo"];
- private static readonly string[] InventoryFilters =
- ["dateStart", "dateEnd", "warehouse", "material", "workOrder", "outboundNo"];
- public static SmartOpsKpiAggregateRule? TryGet(string? metricCode)
- {
- if (string.IsNullOrWhiteSpace(metricCode)) return null;
- return ResolveByPattern(metricCode.Trim());
- }
- public static bool SupportsFilter(string metricCode, SmartOpsDashboardFilter filter)
- {
- var rule = TryGet(metricCode);
- if (rule == null || rule.FilterMode == FilterSummaryOnly) return false;
- if (filter.IsEmpty) return true;
- var active = GetActiveFilterKeys(filter);
- if (active.Count == 0) return true;
- return active.All(k => rule.SupportedFilters.Contains(k, StringComparer.OrdinalIgnoreCase));
- }
- public static IReadOnlyList<string> GetUnsupportedFilters(string metricCode, SmartOpsDashboardFilter filter)
- {
- var rule = TryGet(metricCode);
- if (rule == null || filter.IsEmpty) return Array.Empty<string>();
- return GetActiveFilterKeys(filter)
- .Where(k => !rule.SupportedFilters.Contains(k, StringComparer.OrdinalIgnoreCase))
- .ToList();
- }
- public static IEnumerable<string> GetDomainsForModule(string moduleCode)
- {
- return moduleCode.ToUpperInvariant() switch
- {
- "S1" or "S7" => new[] { DomainOrderDelivery, DomainInventory },
- "S2" or "S6" => new[] { DomainWorkSchedule },
- "S3" or "S4" => new[] { DomainSupplyPurchase },
- "S5" => new[] { DomainInventory, DomainSupplyPurchase },
- "S9" => new[] { DomainOrderDelivery, DomainWorkSchedule, DomainSupplyPurchase, DomainInventory },
- _ => Array.Empty<string>()
- };
- }
- public static string ResolveFilterMode(string metricCode, SmartOpsDashboardFilter filter)
- {
- var rule = TryGet(metricCode);
- if (rule == null || rule.FilterMode == FilterSummaryOnly) return FilterSummaryOnly;
- if (filter.IsEmpty) return FilterSummaryOnly;
- if (SupportsFilter(metricCode, filter)) return FilterFull;
- return FilterPartial;
- }
- private static SmartOpsKpiAggregateRule? ResolveByPattern(string metricCode)
- {
- var parts = metricCode.Split('_', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
- if (parts.Length < 3) return null;
- var module = parts[0].ToUpperInvariant();
- if (module == "S8") return SummaryRule(metricCode);
- var domain = ResolveDomain(module, metricCode);
- if (domain == null) return SummaryRule(metricCode);
- var suffix = parts[^1];
- var aggregation = ResolveAggregation(suffix, metricCode);
- var filters = ResolveFilters(domain);
- return new SmartOpsKpiAggregateRule(metricCode, domain, aggregation, FilterPartial, filters);
- }
- private static string? ResolveDomain(string module, string metricCode)
- {
- if (module == "S9")
- {
- return metricCode.ToUpperInvariant() switch
- {
- var c when c.StartsWith("S9_L1_001", StringComparison.OrdinalIgnoreCase) => null,
- var c when c.StartsWith("S9_L1_002", StringComparison.OrdinalIgnoreCase) ||
- c.StartsWith("S9_L1_003", StringComparison.OrdinalIgnoreCase) => DomainOrderDelivery,
- var c when c.StartsWith("S9_L1_004", StringComparison.OrdinalIgnoreCase) => DomainWorkSchedule,
- var c when c.StartsWith("S9_L1_005", StringComparison.OrdinalIgnoreCase) => DomainInventory,
- _ => ResolveDomainByModule(module)
- };
- }
- return ResolveDomainByModule(module);
- }
- private static string? ResolveDomainByModule(string module) => module switch
- {
- "S1" or "S7" => DomainOrderDelivery,
- "S2" or "S6" => DomainWorkSchedule,
- "S3" or "S4" => DomainSupplyPurchase,
- "S5" => DomainInventory,
- _ => null
- };
- private static string ResolveAggregation(string suffix, string metricCode)
- {
- if (metricCode.Contains("数量", StringComparison.Ordinal) ||
- metricCode.EndsWith("_001", StringComparison.Ordinal) && metricCode.StartsWith("S8", StringComparison.OrdinalIgnoreCase))
- {
- return AggSum;
- }
- return suffix switch
- {
- "001" => AggAvg,
- "002" => AggRatio,
- "003" => AggAvg,
- "004" => AggAvg,
- "005" => AggAvg,
- _ => AggAvg
- };
- }
- private static string[] ResolveFilters(string domain) => domain switch
- {
- DomainOrderDelivery => OrderDeliveryFilters,
- DomainWorkSchedule => WorkScheduleFilters,
- DomainSupplyPurchase => SupplyPurchaseFilters,
- DomainInventory => InventoryFilters,
- _ => Array.Empty<string>()
- };
- private static SmartOpsKpiAggregateRule SummaryRule(string metricCode) =>
- new(metricCode, string.Empty, AggAvg, FilterSummaryOnly, Array.Empty<string>());
- private static List<string> GetActiveFilterKeys(SmartOpsDashboardFilter filter)
- {
- var keys = new List<string>();
- if (filter.DateStart.HasValue || filter.DateEnd.HasValue) keys.Add("dateStart");
- if (!string.IsNullOrWhiteSpace(filter.Product)) keys.Add("product");
- if (!string.IsNullOrWhiteSpace(filter.OrderNo)) keys.Add("orderNo");
- if (!string.IsNullOrWhiteSpace(filter.ProductionLine)) keys.Add("productionLine");
- if (!string.IsNullOrWhiteSpace(filter.Customer)) keys.Add("customer");
- if (!string.IsNullOrWhiteSpace(filter.Supplier)) keys.Add("supplier");
- if (!string.IsNullOrWhiteSpace(filter.Material)) keys.Add("material");
- if (!string.IsNullOrWhiteSpace(filter.PoNo)) keys.Add("poNo");
- if (!string.IsNullOrWhiteSpace(filter.Warehouse)) keys.Add("warehouse");
- if (!string.IsNullOrWhiteSpace(filter.WorkOrder)) keys.Add("workOrder");
- if (!string.IsNullOrWhiteSpace(filter.Equipment)) keys.Add("equipment");
- if (!string.IsNullOrWhiteSpace(filter.OutboundNo)) keys.Add("outboundNo");
- return keys;
- }
- }
- public sealed record SmartOpsKpiAggregateRule(
- string MetricCode,
- string DomainCode,
- string AggregationType,
- string FilterMode,
- string[] SupportedFilters);
|