| | | 1 | | using System.Text.Json; |
| | | 2 | | |
| | | 3 | | namespace OzonOrdersWeb.WebServices.Orders.Grid; |
| | | 4 | | |
| | | 5 | | public interface IOrdersGridComputedResolver |
| | | 6 | | { |
| | | 7 | | /// <summary>Перевод формулы вычисляемого столбца пользователя в SQL-выражение; null — столбца нет или он непереводи |
| | | 8 | | Task<OrdersGridFormulaTranslator.Translation?> ResolveAsync(string userId, string colId, CancellationToken cancellat |
| | | 9 | | } |
| | | 10 | | |
| | | 11 | | /// <summary>Читает computedColumns пользователя один раз на запрос и переводит нужные формулы (с кэшем на время запроса |
| | 0 | 12 | | public sealed class OrdersGridComputedResolver(IOrdersGridUserSettingsService settings) : IOrdersGridComputedResolver |
| | | 13 | | { |
| | | 14 | | private Dictionary<string, string>? _formulas; |
| | 0 | 15 | | private readonly Dictionary<string, OrdersGridFormulaTranslator.Translation?> _cache = new(StringComparer.OrdinalIgn |
| | | 16 | | |
| | | 17 | | public async Task<OrdersGridFormulaTranslator.Translation?> ResolveAsync(string userId, string colId, CancellationTo |
| | | 18 | | { |
| | 0 | 19 | | if (_cache.TryGetValue(colId, out var cached)) return cached; |
| | 0 | 20 | | _formulas ??= ParseFormulas((await settings.GetAllAsync(userId, cancellationToken)).GetValueOrDefault("computedC |
| | 0 | 21 | | OrdersGridFormulaTranslator.Translation? result = null; |
| | 0 | 22 | | if (_formulas.TryGetValue(colId, out var formula) && OrdersGridFormulaTranslator.TryTranslate(formula, out var t |
| | | 23 | | { |
| | 0 | 24 | | result = t; |
| | | 25 | | } |
| | | 26 | | |
| | 0 | 27 | | _cache[colId] = result; |
| | 0 | 28 | | return result; |
| | 0 | 29 | | } |
| | | 30 | | |
| | | 31 | | /// <summary>id столбца → формула из JSON настройки.</summary> |
| | | 32 | | public static Dictionary<string, string> ParseFormulas(string? json) |
| | | 33 | | { |
| | 0 | 34 | | var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); |
| | 0 | 35 | | if (string.IsNullOrWhiteSpace(json)) return map; |
| | | 36 | | try |
| | | 37 | | { |
| | 0 | 38 | | using var doc = JsonDocument.Parse(json); |
| | 0 | 39 | | if (doc.RootElement.ValueKind != JsonValueKind.Array) return map; |
| | 0 | 40 | | foreach (var item in doc.RootElement.EnumerateArray()) |
| | | 41 | | { |
| | 0 | 42 | | if (item.ValueKind != JsonValueKind.Object) continue; |
| | 0 | 43 | | var id = item.TryGetProperty("id", out var i) && i.ValueKind == JsonValueKind.String ? i.GetString() : n |
| | 0 | 44 | | var formula = item.TryGetProperty("formula", out var f) && f.ValueKind == JsonValueKind.String ? f.GetSt |
| | 0 | 45 | | if (!string.IsNullOrEmpty(id) && !string.IsNullOrEmpty(formula)) map[id] = formula; |
| | | 46 | | } |
| | 0 | 47 | | } |
| | 0 | 48 | | catch (JsonException) { /* битые настройки — без формул */ } |
| | 0 | 49 | | return map; |
| | 0 | 50 | | } |
| | | 51 | | } |