| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- using System.Text.RegularExpressions;
- using Admin.NET.Plugin.AiDOP.Entity;
- using SqlSugar;
- namespace Admin.NET.Plugin.AiDOP.Infrastructure.FormulaExpr;
- /// <summary>
- /// 把结构化公式替换为人读预览:
- /// $F_S1_001 → 统计期订单总数
- /// @S1_L1_001 → 订单评审周期(天)
- /// / → ÷, * → ×
- /// </summary>
- public static class FormulaPreviewBuilder
- {
- private static readonly Regex RefRe = new(@"([@$])([A-Za-z][A-Za-z0-9_]*)", RegexOptions.Compiled);
- public static async Task<string> BuildAsync(
- ISqlSugarClient db,
- long tenantId,
- string? expr,
- FormulaParser.ParseResult? parsed = null)
- {
- if (string.IsNullOrWhiteSpace(expr)) return string.Empty;
- parsed ??= FormulaParser.Parse(expr);
- var metricMap = parsed.MetricRefs.Count == 0
- ? new Dictionary<string, string>()
- : (await db.Queryable<AdoSmartOpsKpiMaster>()
- .Where(x => x.TenantId == tenantId && parsed.MetricRefs.Contains(x.MetricCode))
- .Select(x => new { x.MetricCode, x.MetricName })
- .ToListAsync())
- .ToDictionary(x => x.MetricCode, x => x.MetricName, StringComparer.OrdinalIgnoreCase);
- var factMap = parsed.FactRefs.Count == 0
- ? new Dictionary<string, string>()
- : (await db.Queryable<AdoSmartOpsBusinessFact>()
- .Where(x => x.TenantId == tenantId && parsed.FactRefs.Contains(x.FactCode))
- .Select(x => new { x.FactCode, x.FactName })
- .ToListAsync())
- .ToDictionary(x => x.FactCode, x => x.FactName, StringComparer.OrdinalIgnoreCase);
- var preview = RefRe.Replace(expr, m =>
- {
- var sym = m.Groups[1].Value;
- var code = m.Groups[2].Value;
- if (sym == "@" && metricMap.TryGetValue(code, out var mn)) return mn ?? $"@{code}";
- if (sym == "$" && factMap.TryGetValue(code, out var fn)) return fn ?? $"${code}";
- return m.Value;
- });
- preview = preview.Replace('/', '÷').Replace('*', '×');
- // 连续空白压缩
- preview = Regex.Replace(preview, @"\s+", " ").Trim();
- return preview;
- }
- }
|