From 4864b9b3439be5fff5eaf4ec54b57f5f3669f3e6 Mon Sep 17 00:00:00 2001 From: Mikhail Kuznetsov Date: Wed, 25 Mar 2026 11:57:09 +1000 Subject: [PATCH] =?UTF-8?q?feat(aihitSyncer):=20=D0=98=D0=B7=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B0=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B0?= =?UTF-8?q?=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BC=D0=BD=D0=BE=D0=B6=D0=B5=D1=81=D1=82=D0=B2=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D1=85=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B9,=20=D0=BF=D1=80=D0=B8=D1=88=D0=B5=D0=B4=D1=88=D0=B8?= =?UTF-8?q?=D1=85=20=D0=B8=D0=B7=20=D0=90=D0=98=D0=A5=20=D0=98=D0=A2=20?= =?UTF-8?q?=D0=B2=20=D0=BE=D0=B4=D0=BD=D0=BE=D0=BC=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D0=B5,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B0?= =?UTF-8?q?=20=D1=82=D0=B5=D0=B3=D0=BE=D0=B2.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/SyncerService.cs | 55 +++++++++++++++---- PARR.AIHITSyncerWorker/appsettings.json | 5 ++ PARR.API/appsettings.json | 4 +- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/PARR.AIHITMainSyncer/Services/SyncerService.cs b/PARR.AIHITMainSyncer/Services/SyncerService.cs index 33c27596..3519162f 100644 --- a/PARR.AIHITMainSyncer/Services/SyncerService.cs +++ b/PARR.AIHITMainSyncer/Services/SyncerService.cs @@ -55,7 +55,7 @@ namespace PARR.AIHITMainSyncer.Services logger.LogDebug("Начинаем синхронизацию Unit для объекта с именем: {UnitName}", objFromQuery.Name); //Получаем сразу словарь атрибутов, чтобы не ходить каждый раз в базу - var fieldsFromDB = await unitFieldService.Get().AsNoTracking()/*.Select(t => new FieldDto { Id = t.Id, Name = t.AihitName, IsMultipleValue = t.IsMultipleValue })*/.ToListAsync(); + var fieldsFromDB = await unitFieldService.Get().AsNoTracking().ToListAsync(); if (!objFromQuery.Properties.Any()) { @@ -84,7 +84,7 @@ namespace PARR.AIHITMainSyncer.Services var propertiesWithMultipleValues = objFromQuery.Properties.Where(t => !propertisWithSimpleValues.Any(a => t.Key.Trim() == a.Key)).ToList(); propertiesWithMultipleValues.ForEach(p => listAihitData.AddRange( - SplitValues(p).Distinct().Select(s => new KeyValuePair(s.Key.Trim(), s.Value?.Trim())) + SplitValues(p, fieldsFromDB).Distinct().Select(s => new KeyValuePair(s.Key.Trim(), s.Value?.Trim())) )); var unit = await GetUnit(objFromQuery.Name); @@ -174,21 +174,52 @@ namespace PARR.AIHITMainSyncer.Services } - private static List> SplitValues(KeyValuePair multiValueProperty) + private List> SplitValues(KeyValuePair multiValueProperty, List fieldsFromDB) { - var splitedProperties = new List>(); + var result = new List>(); - if (multiValueProperty.Value == null) - splitedProperties.Add(new KeyValuePair(multiValueProperty.Key, multiValueProperty.Value)); - else + // Обработка null или пустой строки + if (string.IsNullOrEmpty(multiValueProperty.Value)) { - var values = multiValueProperty.Value.Split(',').Select(s => s.Trim()); - - foreach (var value in values) - splitedProperties.Add(new KeyValuePair(multiValueProperty.Key, value)); + result.Add(new KeyValuePair(multiValueProperty.Key, multiValueProperty.Value)); + return result; } - return splitedProperties; + // Поиск конфигурации поля для тега + // Рекомендация: если метод вызывается в цикле, передавайте найденное поле внешним слоем + var tagUnitField = fieldsFromDB.FirstOrDefault(f => f.Code == "tag"); + bool isTagProperty = tagUnitField != null && multiValueProperty.Key == tagUnitField.AihitName; + + string[] splitValues; + + if (isTagProperty) + { + // Для тегов нормализуем разделители до пробела + var normalizedValue = multiValueProperty.Value + .Replace(';', ' ') + .Replace('.', ' ') + .Replace(',', ' '); + + splitValues = normalizedValue.Split(' ', StringSplitOptions.RemoveEmptyEntries); + } + else + { + // Для остальных полей стандартный разделитель - запятая + splitValues = multiValueProperty.Value.Split(',', StringSplitOptions.RemoveEmptyEntries); + } + + foreach (var value in splitValues) + { + var trimmedValue = value.Trim(); + + // Добавляем только непустые значения после обрезки пробелов + if (!string.IsNullOrEmpty(trimmedValue)) + { + result.Add(new KeyValuePair(multiValueProperty.Key, trimmedValue)); + } + } + + return result; } diff --git a/PARR.AIHITSyncerWorker/appsettings.json b/PARR.AIHITSyncerWorker/appsettings.json index 686bf53c..1ba9c4ca 100644 --- a/PARR.AIHITSyncerWorker/appsettings.json +++ b/PARR.AIHITSyncerWorker/appsettings.json @@ -67,6 +67,11 @@ "FieldName": "IP_АДРЕС", "OldValues": [ "null" ], "NewValue": "пусто" + }, + { + "FieldName": "ПАРР тег", + "OldValues": [ "null" ], + "NewValue": "пусто" } ] } diff --git a/PARR.API/appsettings.json b/PARR.API/appsettings.json index 4b82eb4e..7f1857f1 100644 --- a/PARR.API/appsettings.json +++ b/PARR.API/appsettings.json @@ -102,11 +102,11 @@ }, { "Name": "TemplatesExport", - "InaccessibilityTime": "01:20:00" + "InaccessibilityTime": "02:30:00" }, { "Name": "ScheduleExport", - "InaccessibilityTime": "01:20:00" + "InaccessibilityTime": "02:30:00" } ], "RabbitMq": {