feat(esppOrderLoader): изменено журналирвоание
This commit is contained in:
@@ -14,6 +14,8 @@ namespace PARR.BLL.Services.Implementations
|
|||||||
|
|
||||||
public async Task IntervalInitAsync(IntervalHandlerDelegate intervalHandler, TimeSpan interval)
|
public async Task IntervalInitAsync(IntervalHandlerDelegate intervalHandler, TimeSpan interval)
|
||||||
{
|
{
|
||||||
|
logger.LogInformation("Инициализация интервального сервиса с интервалом: {Interval}", interval);
|
||||||
|
|
||||||
var nextStart = DateTimeOffset.UtcNow;
|
var nextStart = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
@@ -22,20 +24,32 @@ namespace PARR.BLL.Services.Implementations
|
|||||||
|
|
||||||
logger.LogInformation("Запуск по расписанию. Интервал: {interval}, дата: {nextStart}", interval, nextStart);
|
logger.LogInformation("Запуск по расписанию. Интервал: {interval}, дата: {nextStart}", interval, nextStart);
|
||||||
|
|
||||||
await intervalHandler.Invoke();
|
try
|
||||||
|
{
|
||||||
|
await intervalHandler.Invoke();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "Ошибка при выполнении интервального обработчика");
|
||||||
|
}
|
||||||
|
|
||||||
nextStart = nextStart.Add(interval);
|
nextStart = nextStart.Add(interval);
|
||||||
|
|
||||||
logger.LogInformation("Следующая дата запуска: {nextStart}. Интервал: {interval}.", nextStart, interval);
|
logger.LogInformation("Следующая дата запуска: {NextStart}. Интервал: {Interval}.", nextStart, interval);
|
||||||
|
|
||||||
var intervalOffset = nextStart - DateTimeOffset.UtcNow;
|
var intervalOffset = nextStart - DateTimeOffset.UtcNow;
|
||||||
if (intervalOffset < TimeSpan.Zero)
|
if (intervalOffset < TimeSpan.Zero)
|
||||||
{
|
{
|
||||||
intervalOffset = TimeSpan.Zero;
|
intervalOffset = TimeSpan.Zero;
|
||||||
logger.LogWarning("Время следующего запуска изменено на сейчас. Так как рассчитанное время запуска меньше чем сейчас, {nextStart}<{now}. " +
|
logger.LogWarning(
|
||||||
$"Это произошло потому что время выполнения основного метода больше чем заданный интервал повторений.", nextStart, DateTimeOffset.UtcNow);
|
"Время следующего запуска изменено на текущее время. Рассчитанное время запуска ({NextStart}) меньше текущего времени ({Now}). " +
|
||||||
|
"Это произошло потому что время выполнения основного метода больше чем заданный интервал повторений.",
|
||||||
|
nextStart,
|
||||||
|
DateTimeOffset.UtcNow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.LogDebug("Ожидание {Delay} перед следующим запуском", intervalOffset);
|
||||||
|
|
||||||
await Task.Delay(intervalOffset);
|
await Task.Delay(intervalOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ namespace PARR.DAL.Contracts
|
|||||||
{
|
{
|
||||||
// При добавлении свойств, добавлять в миграцию: PARR.DAL.Context.DataContext
|
// При добавлении свойств, добавлять в миграцию: PARR.DAL.Context.DataContext
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Инициатор регламентной работы, указывается при создании шаблона в ЕСПП.
|
/// Инициатор регламентной работы, указывается при создании шаблона в ЕСПП.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -51,8 +50,9 @@ namespace PARR.DAL.Contracts
|
|||||||
{
|
{
|
||||||
return JsonSerializer.Deserialize<List<TemplateNameConstantPart>>(TemplateNameConstantParts) ?? new List<TemplateNameConstantPart>();
|
return JsonSerializer.Deserialize<List<TemplateNameConstantPart>>(TemplateNameConstantParts) ?? new List<TemplateNameConstantPart>();
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
// В будущем можно добавить логирование ошибки десериализации
|
||||||
return new List<TemplateNameConstantPart>();
|
return new List<TemplateNameConstantPart>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,6 @@ namespace PARR.DAL.Contracts
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Количество попыток выполнения задания роботом
|
/// Количество попыток выполнения задания роботом
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -77,21 +76,6 @@ namespace PARR.DAL.Contracts
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public TimeSpan RobotWaitTime { get; set; }
|
public TimeSpan RobotWaitTime { get; set; }
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Расписание регламентной работы - В каком часовом поясе
|
|
||||||
///// </summary>
|
|
||||||
//public string ScheduleTimezone { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Расписание регламентной работы - Тип исключения
|
|
||||||
///// </summary>
|
|
||||||
//public string ScheduleExcludeType { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Расписание регламентной работы - Календарь
|
|
||||||
///// </summary>
|
|
||||||
//public string ScheduleExcludeCalendar { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Расписание регламентной работы - Диапазон повторов
|
/// Расписание регламентной работы - Диапазон повторов
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -126,7 +110,5 @@ namespace PARR.DAL.Contracts
|
|||||||
/// Зона ответственности для получения тайм зоны по умолчанию для расписаний
|
/// Зона ответственности для получения тайм зоны по умолчанию для расписаний
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DefaultResponseAreaToTimeOffset { get; set; } = string.Empty;
|
public string DefaultResponseAreaToTimeOffset { get; set; } = string.Empty;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@ namespace PARR.DAL.DomainServices.UnitFilterService;
|
|||||||
internal class UnitFilterService : IUnitFilterService
|
internal class UnitFilterService : IUnitFilterService
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
private readonly Guid targetUnitId = Guid.Parse("87fc4c36-1ea8-4163-983f-1605fee1de99");
|
private readonly Guid targetUnitId = Guid.Parse("ca9b4a9f-df74-48e1-95dc-588e36e3d5aa");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private readonly ILogger<UnitFilterService> logger;
|
private readonly ILogger<UnitFilterService> logger;
|
||||||
|
|||||||
@@ -25,29 +25,38 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
|
|
||||||
public virtual async Task<bool> AddRangeAsync(List<T> objs)
|
public virtual async Task<bool> AddRangeAsync(List<T> objs)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Начинаю добавление диапазона объектов типа {EntityType}, количество: {Count}",
|
||||||
|
typeof(T).Name, objs.Count);
|
||||||
|
|
||||||
objs.ForEach(item => item.DateCreated = DateTimeOffset.UtcNow);
|
objs.ForEach(item => item.DateCreated = DateTimeOffset.UtcNow);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await EntitySet.AddRangeAsync(objs);
|
await EntitySet.AddRangeAsync(objs);
|
||||||
|
logger.LogDebug("Успешно добавлено {Count} объектов типа {EntityType}",
|
||||||
|
objs.Count, typeof(T).Name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "Ошибка при добавлении диапазона в БД.");
|
logger.LogError(ex, "Ошибка при добавлении диапазона объектов типа {EntityType}", typeof(T).Name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> CommitAsync(IHistoryInitiator? initiator = null)
|
public async Task<bool> CommitAsync(IHistoryInitiator? initiator = null)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Начинаю сохранение изменений в БД для объектов типа {EntityType}", typeof(T).Name);
|
||||||
|
|
||||||
#region Изменения
|
#region Изменения
|
||||||
var modifiedEntrities = EntitiContext.ChangeTracker.Entries()
|
var modifiedEntrities = EntitiContext.ChangeTracker.Entries()
|
||||||
.Where(t => t.State == EntityState.Modified/* || t.State == EntityState.Deleted*/);
|
.Where(t => t.State == EntityState.Modified/* || t.State == EntityState.Deleted*/);
|
||||||
|
|
||||||
|
logger.LogDebug("Найдено {Count} измененных сущностей для обработки истории", modifiedEntrities.Count());
|
||||||
|
|
||||||
foreach (var obj in modifiedEntrities)
|
foreach (var obj in modifiedEntrities)
|
||||||
{
|
{
|
||||||
// Если нунжо, обновляем дату изменения
|
// Если нужно, обновляем дату изменения
|
||||||
DateModifiedResolver(obj);
|
DateModifiedResolver(obj);
|
||||||
|
|
||||||
//Если нужно, пишем историю
|
//Если нужно, пишем историю
|
||||||
@@ -59,12 +68,14 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await EntitiContext.SaveChangesAsync();
|
var changedCount = await EntitiContext.SaveChangesAsync();
|
||||||
|
logger.LogInformation("Успешно сохранено {ChangedCount} изменений в БД для объектов типа {EntityType}",
|
||||||
|
changedCount, typeof(T).Name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "Ошибка при Commit");
|
logger.LogError(ex, "Ошибка при сохранении изменений в БД для объектов типа {EntityType}", typeof(T).Name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,10 +87,15 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
/// <param name="initiator"></param>
|
/// <param name="initiator"></param>
|
||||||
private void SetInitiator(IHistoryInitiator? initiator)
|
private void SetInitiator(IHistoryInitiator? initiator)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Устанавливаю инициатора для изменений");
|
||||||
|
|
||||||
// Задаем инициатора только для новых и измененных записей
|
// Задаем инициатора только для новых и измененных записей
|
||||||
var entrities = EntitiContext.ChangeTracker.Entries()
|
var entrities = EntitiContext.ChangeTracker.Entries()
|
||||||
.Where(t => t.State == EntityState.Modified || t.State == EntityState.Added);
|
.Where(t => t.State == EntityState.Modified || t.State == EntityState.Added);
|
||||||
|
|
||||||
|
var entityCount = entrities.Count();
|
||||||
|
logger.LogDebug("Найдено {Count} сущностей для установки инициатора", entityCount);
|
||||||
|
|
||||||
// смотрим есть ли у объекта интерфейс IHistoryInitiator, если есть, задаём значения
|
// смотрим есть ли у объекта интерфейс IHistoryInitiator, если есть, задаём значения
|
||||||
foreach (var obj in entrities)
|
foreach (var obj in entrities)
|
||||||
{
|
{
|
||||||
@@ -89,6 +105,8 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
(obj.Entity as IHistoryInitiator)!.InitiatorIp = initiator?.InitiatorIp ?? null;
|
(obj.Entity as IHistoryInitiator)!.InitiatorIp = initiator?.InitiatorIp ?? null;
|
||||||
(obj.Entity as IHistoryInitiator)!.InitiatorParrComponentId = initiator?.InitiatorParrComponentId ?? null;
|
(obj.Entity as IHistoryInitiator)!.InitiatorParrComponentId = initiator?.InitiatorParrComponentId ?? null;
|
||||||
(obj.Entity as IHistoryInitiator)!.InitiatorComment = initiator?.InitiatorComment ?? null;
|
(obj.Entity as IHistoryInitiator)!.InitiatorComment = initiator?.InitiatorComment ?? null;
|
||||||
|
|
||||||
|
logger.LogDebug("Установлен инициатор для сущности типа {EntityType}", obj.Entity.GetType().Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,11 +118,11 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
/// <param name="obj"></param>
|
/// <param name="obj"></param>
|
||||||
private void DateModifiedResolver(EntityEntry obj)
|
private void DateModifiedResolver(EntityEntry obj)
|
||||||
{
|
{
|
||||||
//if (obj.Entity is IBase)
|
|
||||||
// (obj.Entity as IBase)!.DateModified = DateTimeOffset.UtcNow;
|
|
||||||
|
|
||||||
if (obj.Entity is IBaseDateModified)
|
if (obj.Entity is IBaseDateModified)
|
||||||
|
{
|
||||||
|
logger.LogDebug("Обновляю DateModified для сущности типа {EntityType}", obj.Entity.GetType().Name);
|
||||||
(obj.Entity as IBaseDateModified)!.DateModified = DateTimeOffset.UtcNow;
|
(obj.Entity as IBaseDateModified)!.DateModified = DateTimeOffset.UtcNow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -113,6 +131,8 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
/// <param name="obj"></param>
|
/// <param name="obj"></param>
|
||||||
private void TableHistoryResolver(EntityEntry obj)
|
private void TableHistoryResolver(EntityEntry obj)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Проверяю необходимость создания истории для сущности типа {EntityType}", obj.Entity.GetType().Name);
|
||||||
|
|
||||||
var myHistoryInterface = obj.Entity.GetType().GetInterfaces()
|
var myHistoryInterface = obj.Entity.GetType().GetInterfaces()
|
||||||
.Where(t => t.IsGenericType)
|
.Where(t => t.IsGenericType)
|
||||||
.Where(t => t.GetGenericTypeDefinition() == typeof(IMyHistory<>))
|
.Where(t => t.GetGenericTypeDefinition() == typeof(IMyHistory<>))
|
||||||
@@ -120,7 +140,10 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
|
|
||||||
// у этого объекта нет интерфейса IMyHistory<>. Не ведем историю
|
// у этого объекта нет интерфейса IMyHistory<>. Не ведем историю
|
||||||
if (myHistoryInterface == null)
|
if (myHistoryInterface == null)
|
||||||
|
{
|
||||||
|
logger.LogDebug("Сущность типа {EntityType} не требует ведения истории", obj.Entity.GetType().Name);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// !!! Эта таблица хочет хранить историю !!!
|
// !!! Эта таблица хочет хранить историю !!!
|
||||||
|
|
||||||
@@ -128,10 +151,13 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
var historyType = myHistoryInterface.GetGenericArguments().First();
|
var historyType = myHistoryInterface.GetGenericArguments().First();
|
||||||
var historyProps = historyType.GetProperties(/*BindingFlags.DeclaredOnly | */ /*BindingFlags.Public*/).ToList();
|
var historyProps = historyType.GetProperties(/*BindingFlags.DeclaredOnly | */ /*BindingFlags.Public*/).ToList();
|
||||||
|
|
||||||
|
logger.LogDebug("Создаю историю для сущности типа {EntityType}, тип истории: {HistoryType}",
|
||||||
|
obj.Entity.GetType().Name, historyType.Name);
|
||||||
|
|
||||||
var historyInstance = Activator.CreateInstance(historyType);
|
var historyInstance = Activator.CreateInstance(historyType);
|
||||||
if (historyInstance == null)
|
if (historyInstance == null)
|
||||||
{
|
{
|
||||||
logger.LogError($"Не смог создать инстанс для ведения истории {historyType.Name}");
|
logger.LogError("Не смог создать инстанс для ведения истории {HistoryType}", historyType.Name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,10 +173,11 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
EntitiContext.Add(historyInstance);
|
EntitiContext.Add(historyInstance);
|
||||||
|
logger.LogDebug("История добавлена для сущности типа {EntityType}", obj.Entity.GetType().Name);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, $"Ошибка при добавлении объекта в историю {historyType.Name}");
|
logger.LogError(ex, "Ошибка при добавлении объекта в историю {HistoryType}", historyType.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,6 +190,8 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
/// <param name="propsList"></param>
|
/// <param name="propsList"></param>
|
||||||
private void FillHistoryProps(EntityEntry originalObj, ref object historyInstance, List<PropertyInfo> propsList)
|
private void FillHistoryProps(EntityEntry originalObj, ref object historyInstance, List<PropertyInfo> propsList)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Заполняю историю для сущности типа {EntityType}", originalObj.Entity.GetType().Name);
|
||||||
|
|
||||||
foreach (var prop in propsList)
|
foreach (var prop in propsList)
|
||||||
{
|
{
|
||||||
if (originalObj.OriginalValues.Properties.FirstOrDefault(t => t.Name == prop.Name) == null)
|
if (originalObj.OriginalValues.Properties.FirstOrDefault(t => t.Name == prop.Name) == null)
|
||||||
@@ -185,6 +214,8 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
var origValues = originalObj.Property(prop.Name).OriginalValue;
|
var origValues = originalObj.Property(prop.Name).OriginalValue;
|
||||||
histProp.SetValue(historyInstance, origValues);
|
histProp.SetValue(historyInstance, origValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.LogDebug("Завершено заполнение истории для сущности типа {EntityType}", originalObj.Entity.GetType().Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -200,14 +231,15 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
var histProp = instanceObj.GetType().GetProperty(propName);
|
var histProp = instanceObj.GetType().GetProperty(propName);
|
||||||
if (histProp == null)
|
if (histProp == null)
|
||||||
{
|
{
|
||||||
logger.LogError($"При изменении объекта для БД, не найдено свойство ${propName}");
|
logger.LogError("При изменении объекта для БД, не найдено свойство {PropertyName}", propName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// сравним типы
|
// сравним типы
|
||||||
if (histProp.PropertyType != typeof(TValue))
|
if (histProp.PropertyType != typeof(TValue))
|
||||||
{
|
{
|
||||||
logger.LogError($"При изменении объекта для БД, не совпадают типы у свойства {propName}, {histProp.PropertyType.Name}!={typeof(TValue).Name}");
|
logger.LogError("При изменении объекта для БД, не совпадают типы у свойства {PropertyName}, {PropertyType}!={ValueType}",
|
||||||
|
propName, histProp.PropertyType.Name, typeof(TValue).Name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,70 +305,81 @@ namespace PARR.DAL.Services.Abstracts
|
|||||||
|
|
||||||
public virtual async Task<bool> CreateAsync(T obj)
|
public virtual async Task<bool> CreateAsync(T obj)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Начинаю создание объекта типа {EntityType}", typeof(T).Name);
|
||||||
|
|
||||||
obj.DateCreated = DateTimeOffset.UtcNow;
|
obj.DateCreated = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await EntitySet.AddAsync(obj);
|
await EntitySet.AddAsync(obj);
|
||||||
|
logger.LogDebug("Объект типа {EntityType} добавлен в контекст", typeof(T).Name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "Ошибка при добавлении в БД.");
|
logger.LogError(ex, "Ошибка при добавлении объекта типа {EntityType} в БД", typeof(T).Name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool Delete(T obj)
|
public virtual bool Delete(T obj)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Начинаю удаление объекта типа {EntityType}", obj.GetType().Name);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
EntitySet.Remove(obj);
|
EntitySet.Remove(obj);
|
||||||
|
logger.LogDebug("Объект типа {EntityType} удален из контекста", obj.GetType().Name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "Ошибка при удалении из БД.");
|
logger.LogError(ex, "Ошибка при удалении объекта типа {EntityType} из БД", obj.GetType().Name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<bool> DeleteAsync(Guid id)
|
public virtual async Task<bool> DeleteAsync(Guid id)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Начинаю удаление объекта типа {EntityType} по ID: {Id}", typeof(T).Name, id);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var exist = await GetAsync(id);
|
var exist = await GetAsync(id);
|
||||||
if (exist == null)
|
if (exist == null)
|
||||||
{
|
{
|
||||||
logger.LogError($"Ошибка при удалении из БД. Не найдена запись в БД с id: {id}");
|
logger.LogError("Ошибка при удалении из БД. Не найдена запись в БД типа {EntityType} с id: {Id}",
|
||||||
|
typeof(T).Name, id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntitySet.Remove(exist);
|
EntitySet.Remove(exist);
|
||||||
|
logger.LogDebug("Объект типа {EntityType} с ID {Id} удален из контекста", typeof(T).Name, id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
logger.LogError(ex, "Ошибка при удалении из БД.");
|
logger.LogError(ex, "Ошибка при удалении объекта типа {EntityType} из БД по ID: {Id}", typeof(T).Name, id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IQueryable<T> Get()
|
public virtual IQueryable<T> Get()
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Получаю набор объектов типа {EntityType}", typeof(T).Name);
|
||||||
return EntitySet;
|
return EntitySet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task<T?> GetAsync(Guid id)
|
public virtual async Task<T?> GetAsync(Guid id)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Получаю объект типа {EntityType} по ID: {Id}", typeof(T).Name, id);
|
||||||
return await EntitySet.FirstOrDefaultAsync(t => t.Id == id);
|
return await EntitySet.FirstOrDefaultAsync(t => t.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IQueryable<T> GetPage(IQueryable<T> query, PaginationFilter paginationFilter)
|
public virtual IQueryable<T> GetPage(IQueryable<T> query, PaginationFilter paginationFilter)
|
||||||
{
|
{
|
||||||
//if (paginationFilter.IsDisabledPagination)
|
logger.LogDebug("Получаю страницу объектов типа {EntityType}, страница: {PageNumber}, размер: {PageSize}",
|
||||||
// return query;
|
typeof(T).Name, paginationFilter.PageNumber, paginationFilter.PageSize);
|
||||||
|
|
||||||
|
|
||||||
int skip = (paginationFilter.PageNumber - 1) * paginationFilter.PageSize;
|
int skip = (paginationFilter.PageNumber - 1) * paginationFilter.PageSize;
|
||||||
|
|
||||||
|
|||||||
@@ -19,26 +19,36 @@ namespace PARR.DAL.Services.Implementations
|
|||||||
|
|
||||||
public IQueryable<OrderStatus> Get()
|
public IQueryable<OrderStatus> Get()
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Получаю набор статусов нарядов");
|
||||||
return dataContext.OrderStatuses;
|
return dataContext.OrderStatuses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public OrderStatusEnum GetOrderStatusByName(string statusName)
|
public OrderStatusEnum GetOrderStatusByName(string statusName)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Поиск статуса наряда по имени: {StatusName}", statusName);
|
||||||
|
|
||||||
switch (statusName.Trim())
|
switch (statusName.Trim())
|
||||||
{
|
{
|
||||||
case "1-Направлен в группу":
|
case "1-Направлен в группу":
|
||||||
|
logger.LogDebug("Найден статус: {StatusEnum}", OrderStatusEnum.New);
|
||||||
return OrderStatusEnum.New;
|
return OrderStatusEnum.New;
|
||||||
case "2-В работе":
|
case "2-В работе":
|
||||||
|
logger.LogDebug("Найден статус: {StatusEnum}", OrderStatusEnum.InWork);
|
||||||
return OrderStatusEnum.InWork;
|
return OrderStatusEnum.InWork;
|
||||||
case "3-Приостановлен":
|
case "3-Приостановлен":
|
||||||
|
logger.LogDebug("Найден статус: {StatusEnum}", OrderStatusEnum.Stop);
|
||||||
return OrderStatusEnum.Stop;
|
return OrderStatusEnum.Stop;
|
||||||
case "4-Выполнен":
|
case "4-Выполнен":
|
||||||
|
logger.LogDebug("Найден статус: {StatusEnum}", OrderStatusEnum.Complete);
|
||||||
return OrderStatusEnum.Complete;
|
return OrderStatusEnum.Complete;
|
||||||
case "5-Закрыт":
|
case "5-Закрыт":
|
||||||
|
logger.LogDebug("Найден статус: {StatusEnum}", OrderStatusEnum.Closed);
|
||||||
return OrderStatusEnum.Closed;
|
return OrderStatusEnum.Closed;
|
||||||
default:
|
default:
|
||||||
logger.LogWarning($"Не смог распознать статус наряда, вернул значение по умполчанию: {OrderStatusEnum.New.ToString()}, входящее значение: {statusName}");
|
logger.LogWarning(
|
||||||
|
"Не смог распознать статус наряда, вернул значение по умолчанию: {DefaultStatus}, входящее значение: {InputStatus}",
|
||||||
|
OrderStatusEnum.New, statusName);
|
||||||
return OrderStatusEnum.New;
|
return OrderStatusEnum.New;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,13 +28,28 @@ namespace PARR.DAL.Services.Implementations
|
|||||||
|
|
||||||
public async Task<Template?> GetTemplateByNameAsync(string name)
|
public async Task<Template?> GetTemplateByNameAsync(string name)
|
||||||
{
|
{
|
||||||
return await GetWithIncludes()
|
logger.LogDebug("Поиск шаблона по имени: {TemplateName}", name);
|
||||||
|
|
||||||
|
var template = await GetWithIncludes()
|
||||||
.Include(t => t.RobotConfigurations)
|
.Include(t => t.RobotConfigurations)
|
||||||
.FirstOrDefaultAsync(t => t.Name == name);
|
.FirstOrDefaultAsync(t => t.Name == name);
|
||||||
|
|
||||||
|
if (template != null)
|
||||||
|
{
|
||||||
|
logger.LogDebug("Шаблон найден: {TemplateId}, имя: {TemplateName}", template.Id, template.Name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.LogDebug("Шаблон с именем {TemplateName} не найден", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQueryable<Template> GetWithIncludes()
|
public IQueryable<Template> GetWithIncludes()
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Получаю шаблоны с include связями");
|
||||||
|
|
||||||
return Get()
|
return Get()
|
||||||
.Include(h => h.Unit)
|
.Include(h => h.Unit)
|
||||||
.ThenInclude(t => t!.UnitValues)
|
.ThenInclude(t => t!.UnitValues)
|
||||||
@@ -57,6 +72,8 @@ namespace PARR.DAL.Services.Implementations
|
|||||||
|
|
||||||
public override Task<bool> CreateAsync(Template obj)
|
public override Task<bool> CreateAsync(Template obj)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Создание шаблона: {TemplateName}", obj.Name);
|
||||||
|
|
||||||
// добавление роботов для шаблона
|
// добавление роботов для шаблона
|
||||||
obj.RobotConfigurations = new List<RobotConfiguration>
|
obj.RobotConfigurations = new List<RobotConfiguration>
|
||||||
{
|
{
|
||||||
@@ -86,12 +103,16 @@ namespace PARR.DAL.Services.Implementations
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
logger.LogDebug("Добавлены роботы для шаблона {TemplateName}", obj.Name);
|
||||||
|
|
||||||
return base.CreateAsync(obj);
|
return base.CreateAsync(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<Guid?> ReserveUnusedTemplateAsync(Guid newUnitId, HistoryInitiator initiator)
|
public async Task<Guid?> ReserveUnusedTemplateAsync(Guid newUnitId, HistoryInitiator initiator)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Резервирую неиспользуемый шаблон для UnitId: {UnitId}", newUnitId);
|
||||||
|
|
||||||
var sql = @"
|
var sql = @"
|
||||||
UPDATE ""Templates""
|
UPDATE ""Templates""
|
||||||
SET ""StatusTypeId"" = @NewStatus,
|
SET ""StatusTypeId"" = @NewStatus,
|
||||||
@@ -111,23 +132,43 @@ namespace PARR.DAL.Services.Implementations
|
|||||||
|
|
||||||
var parameters = new[]
|
var parameters = new[]
|
||||||
{
|
{
|
||||||
new NpgsqlParameter("@NewStatus", (int)TemplateStatusTypeEnum.Updating),
|
new NpgsqlParameter("@NewStatus", (int)TemplateStatusTypeEnum.Updating),
|
||||||
new NpgsqlParameter("@DateModified", DateTimeOffset.UtcNow),
|
new NpgsqlParameter("@DateModified", DateTimeOffset.UtcNow),
|
||||||
new NpgsqlParameter("@InitiatorIp", initiator.InitiatorIp ?? (object)DBNull.Value),
|
new NpgsqlParameter("@InitiatorIp", initiator.InitiatorIp ?? (object)DBNull.Value),
|
||||||
new NpgsqlParameter("@InitiatorComponent",
|
new NpgsqlParameter("@InitiatorComponent",
|
||||||
initiator.InitiatorParrComponentId.HasValue
|
initiator.InitiatorParrComponentId.HasValue
|
||||||
? (object)(int)initiator.InitiatorParrComponentId.Value
|
? (object)(int)initiator.InitiatorParrComponentId.Value
|
||||||
: DBNull.Value),
|
: DBNull.Value),
|
||||||
new NpgsqlParameter("@InitiatorComment", initiator.InitiatorComment ?? (object)DBNull.Value),
|
new NpgsqlParameter("@InitiatorComment", initiator.InitiatorComment ?? (object)DBNull.Value),
|
||||||
new NpgsqlParameter("@OldStatus", (int)TemplateStatusTypeEnum.Unused),
|
new NpgsqlParameter("@OldStatus", (int)TemplateStatusTypeEnum.Unused),
|
||||||
new NpgsqlParameter("@NewUnitId", newUnitId)
|
new NpgsqlParameter("@NewUnitId", newUnitId)
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = await dataContext.Database
|
try
|
||||||
.SqlQueryRaw<Guid>(sql, parameters)
|
{
|
||||||
.ToListAsync();
|
var result = await dataContext.Database
|
||||||
|
.SqlQueryRaw<Guid>(sql, parameters)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
return result.FirstOrDefault();
|
var reservedTemplateId = result.FirstOrDefault();
|
||||||
|
|
||||||
|
if (reservedTemplateId != default(Guid))
|
||||||
|
{
|
||||||
|
logger.LogInformation("Успешно зарезервирован шаблон с ID: {TemplateId} для UnitId: {UnitId}",
|
||||||
|
reservedTemplateId, newUnitId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.LogDebug("Не удалось зарезервировать шаблон для UnitId: {UnitId}", newUnitId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return reservedTemplateId;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "Ошибка при резервировании шаблона для UnitId: {UnitId}", newUnitId);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,14 +24,16 @@ namespace PARR.EsppApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Task<EsppResultBase<EsppResponse>> SetStatusInWorkAsync(string recordId, string resultMsg)//TODO упростить можно без RecordIdQuery
|
public Task<EsppResultBase<EsppResponse>> SetStatusInWorkAsync(string recordId, string resultMsg)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Установка статуса 'В работе' для наряда {RecordId}", recordId);
|
||||||
return SetStatusAsync(recordId, "2-В работе", resultMsg);
|
return SetStatusAsync(recordId, "2-В работе", resultMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Task<EsppResultBase<EsppResponse>> SetStatusIsDoneAsync(string recordId, string resultMsg, EsppOrderClosingCodeEnum closingCode)//TODO упростить можно без RecordIdQuery
|
public Task<EsppResultBase<EsppResponse>> SetStatusIsDoneAsync(string recordId, string resultMsg, EsppOrderClosingCodeEnum closingCode)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Установка статуса 'Выполнен' для наряда {RecordId} с кодом закрытия {ClosingCode}", recordId, closingCode);
|
||||||
return SetStatusAsync(recordId, "4-Выполнен", resultMsg, closingCode);
|
return SetStatusAsync(recordId, "4-Выполнен", resultMsg, closingCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,6 +45,8 @@ namespace PARR.EsppApi
|
|||||||
EsppOrderClosingCodeEnum? closingCode = null
|
EsppOrderClosingCodeEnum? closingCode = null
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Выполнение запроса на изменение статуса для наряда {RecordId} в статус {NewStatus}", recordId, newStatusStr);
|
||||||
|
|
||||||
var request = new SetStatusRequest(closingCode ?? EsppOrderClosingCodeEnum.Complete)
|
var request = new SetStatusRequest(closingCode ?? EsppOrderClosingCodeEnum.Complete)
|
||||||
{
|
{
|
||||||
recordid = recordId,
|
recordid = recordId,
|
||||||
@@ -56,28 +60,40 @@ namespace PARR.EsppApi
|
|||||||
var result = await esppHttpService.SendAsync<EsppResponse>(GenerateRequest(EsppOperationsEnum.SaveTask, request));
|
var result = await esppHttpService.SendAsync<EsppResponse>(GenerateRequest(EsppOperationsEnum.SaveTask, request));
|
||||||
|
|
||||||
if (result.Data != null && result.Data.ErrorCode != "0")
|
if (result.Data != null && result.Data.ErrorCode != "0")
|
||||||
|
{
|
||||||
|
logger.LogError("Ошибка при установке статуса для наряда {RecordId}: {ErrorMessage}", recordId, result.Data.Message);
|
||||||
return new EsppResultBase<EsppResponse>(null, false, new Exception(result.Data.Message));
|
return new EsppResultBase<EsppResponse>(null, false, new Exception(result.Data.Message));
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.LogDebug("Статус для наряда {RecordId} успешно установлен", recordId);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<EsppResultBase<EsppOrder>> FindOrderByRecordIdAsync(string recordId)
|
public async Task<EsppResultBase<EsppOrder>> FindOrderByRecordIdAsync(string recordId)
|
||||||
{
|
{
|
||||||
//TODO упростить можно без RecordIdQuery
|
logger.LogDebug("Поиск наряда по ID: {RecordId}", recordId);
|
||||||
//var query = $"<ROOT operation=\"GetTask\" returnFormat=\"json\">\r\n{{\"recordid\":\"{recordId}\"}}\r\n</ROOT>";
|
|
||||||
|
|
||||||
//var result = await esppHttpService.SendAsync<EsppOrder>(QuerySanitize(query));
|
|
||||||
|
|
||||||
var request = new GetTaskRequest { recordid = recordId };
|
var request = new GetTaskRequest { recordid = recordId };
|
||||||
var result = await esppHttpService.SendAsync<EsppOrder>(GenerateRequest(EsppOperationsEnum.GetTask, request));
|
var result = await esppHttpService.SendAsync<EsppOrder>(GenerateRequest(EsppOperationsEnum.GetTask, request));
|
||||||
|
|
||||||
|
if (result.IsSuccess)
|
||||||
|
{
|
||||||
|
logger.LogDebug("Наряд {RecordId} успешно найден", recordId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.LogWarning("Наряд {RecordId} не найден", recordId);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<EsppResultBase<IEnumerable<EsppOrder>>> FindOrdersAsync(FindOrdersQuery query)
|
public async Task<EsppResultBase<IEnumerable<EsppOrder>>> FindOrdersAsync(FindOrdersQuery query)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Поиск нарядов в ЕСПП с фильтром");
|
||||||
|
|
||||||
DateTime? generateDateStartWOTimeZone = query.GenerateDateStart.HasValue ? query.GenerateDateStart.Value.AddHours(esppOrderSettings.EsppUserTimeZone) : null;
|
DateTime? generateDateStartWOTimeZone = query.GenerateDateStart.HasValue ? query.GenerateDateStart.Value.AddHours(esppOrderSettings.EsppUserTimeZone) : null;
|
||||||
DateTime? generateDateEndWOTimeZone = query.GenerateDateEnd.HasValue ? query.GenerateDateEnd.Value.AddHours(esppOrderSettings.EsppUserTimeZone) : null;
|
DateTime? generateDateEndWOTimeZone = query.GenerateDateEnd.HasValue ? query.GenerateDateEnd.Value.AddHours(esppOrderSettings.EsppUserTimeZone) : null;
|
||||||
|
|
||||||
@@ -88,27 +104,20 @@ namespace PARR.EsppApi
|
|||||||
|
|
||||||
if (!string.IsNullOrEmpty(query.DescriptionContains))
|
if (!string.IsNullOrEmpty(query.DescriptionContains))
|
||||||
conditions.Add($"description like \"*{query.DescriptionContains}*\"");
|
conditions.Add($"description like \"*{query.DescriptionContains}*\"");
|
||||||
//if (!string.IsNullOrEmpty(query.TemplateNameContains))
|
|
||||||
// conditions.Add($"templateName like \"*{query.TemplateNameContains}*\"");
|
|
||||||
|
|
||||||
if (generateDateStartWOTimeZone.HasValue)
|
if (generateDateStartWOTimeZone.HasValue)
|
||||||
//conditions.Add($"open.time>='{generateDateStartWOTimeZone.Value.Day}/{generateDateStartWOTimeZone.Value.Month}/{generateDateStartWOTimeZone.Value.Year}" +
|
|
||||||
// $" {generateDateStartWOTimeZone.Value.Hour}:{generateDateStartWOTimeZone.Value.Minute}:{generateDateStartWOTimeZone.Value.Second}'");
|
|
||||||
conditions.Add($"open.time>='{generateDateStartWOTimeZone.Value.ToString(@"dd\/MM\/yyyy HH:mm:ss")}'");
|
conditions.Add($"open.time>='{generateDateStartWOTimeZone.Value.ToString(@"dd\/MM\/yyyy HH:mm:ss")}'");
|
||||||
|
|
||||||
if (generateDateEndWOTimeZone.HasValue)
|
if (generateDateEndWOTimeZone.HasValue)
|
||||||
//conditions.Add($"open.time<='{generateDateEndWOTimeZone.Value.Day}/{generateDateEndWOTimeZone.Value.Month}/{generateDateEndWOTimeZone.Value.Year}" +
|
|
||||||
// $" {generateDateEndWOTimeZone.Value.Hour}:{generateDateEndWOTimeZone.Value.Minute}:{generateDateEndWOTimeZone.Value.Second}'");
|
|
||||||
conditions.Add($"open.time<='{generateDateEndWOTimeZone.Value.ToString(@"dd\/MM\/yyyy HH:mm:ss")}'");
|
conditions.Add($"open.time<='{generateDateEndWOTimeZone.Value.ToString(@"dd\/MM\/yyyy HH:mm:ss")}'");
|
||||||
|
|
||||||
if (!conditions.Any())
|
if (!conditions.Any())
|
||||||
{
|
{
|
||||||
logger.LogDebug("Пришёл пустой запрос в EsppHttpService.FindOrdersAsync");
|
logger.LogWarning("Пустой запрос в EsppApiService.FindOrdersAsync - все условия фильтрации пустые");
|
||||||
return new EsppResultBase<IEnumerable<EsppOrder>>(null, false);
|
return new EsppResultBase<IEnumerable<EsppOrder>>(null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//var request = $"<ROOT operation=\"GetTaskList\" returnFormat=\"json\">{{\"VIEW_QUERY\":\"{string.Join(" and ", conditions)}\"}}</ROOT>";
|
logger.LogDebug("Формирование запроса к ЕСПП с условиями: {Conditions}", string.Join(" and ", conditions));
|
||||||
//var result = await esppHttpService.SendAsync<IEnumerable<EsppOrder>>(QuerySanitize(request));
|
|
||||||
|
|
||||||
var request = new GetTaskListRequest { VIEW_QUERY = string.Join(" and ", conditions) };
|
var request = new GetTaskListRequest { VIEW_QUERY = string.Join(" and ", conditions) };
|
||||||
|
|
||||||
@@ -116,20 +125,23 @@ namespace PARR.EsppApi
|
|||||||
var viewQueryStr = $"{{\"VIEW_QUERY\":\"{request.VIEW_QUERY}\"}}";
|
var viewQueryStr = $"{{\"VIEW_QUERY\":\"{request.VIEW_QUERY}\"}}";
|
||||||
var result = await esppHttpService.SendAsync<IEnumerable<EsppOrder>>(GenerateRequest(EsppOperationsEnum.GetTaskList, viewQueryStr));
|
var result = await esppHttpService.SendAsync<IEnumerable<EsppOrder>>(GenerateRequest(EsppOperationsEnum.GetTaskList, viewQueryStr));
|
||||||
|
|
||||||
//var result = await esppHttpService.SendAsync<IEnumerable<EsppOrder>>(GenerateRequest(EsppOperationsEnum.GetTaskList, request));
|
if (result.IsSuccess)
|
||||||
|
{
|
||||||
|
var count = result.Data?.Count() ?? 0;
|
||||||
|
logger.LogInformation("Успешно получено {Count} нарядов из ЕСПП", count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.LogError(result.Exception, "Ошибка при получении нарядов из ЕСПП");
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<EsppResultBase<EsppResponse>> AddMTnkAsync(AddMtnkQuery mtnk)
|
public async Task<EsppResultBase<EsppResponse>> AddMTnkAsync(AddMtnkQuery mtnk)
|
||||||
{
|
{
|
||||||
//var query = $"<ROOT operation=\"AddMTNK\" returnFormat=\"json\">{{\"recordid\":\"{mtnk.RecordId}\"," +
|
logger.LogDebug("Добавление МТНК для наряда {RecordId}", mtnk.RecordId);
|
||||||
// $"\"joboperation\":\"{mtnk.JobOperation}\",\"time\":\"{mtnk.Time}\",\"workscope\":\"{mtnk.Workspace}\"" +
|
|
||||||
// $"}}</ROOT>";
|
|
||||||
|
|
||||||
//var result = await esppHttpService.SendAsync<EsppResponse>(QuerySanitize(query));
|
|
||||||
|
|
||||||
var request = new AddMTNKRequest
|
var request = new AddMTNKRequest
|
||||||
{
|
{
|
||||||
@@ -138,11 +150,16 @@ namespace PARR.EsppApi
|
|||||||
time = mtnk.Time,
|
time = mtnk.Time,
|
||||||
workscope = mtnk.Workspace.ToString()
|
workscope = mtnk.Workspace.ToString()
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = await esppHttpService.SendAsync<EsppResponse>(GenerateRequest(EsppOperationsEnum.AddMTNK, request));
|
var result = await esppHttpService.SendAsync<EsppResponse>(GenerateRequest(EsppOperationsEnum.AddMTNK, request));
|
||||||
|
|
||||||
if (result.Data != null && result.Data.ErrorCode != "0")
|
if (result.Data != null && result.Data.ErrorCode != "0")
|
||||||
|
{
|
||||||
|
logger.LogError("Ошибка при добавлении МТНК для наряда {RecordId}: {ErrorMessage}", mtnk.RecordId, result.Data.Message);
|
||||||
return new EsppResultBase<EsppResponse>(null, false, new Exception(result.Data.Message));
|
return new EsppResultBase<EsppResponse>(null, false, new Exception(result.Data.Message));
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.LogDebug("МТНК успешно добавлена для наряда {RecordId}", mtnk.RecordId);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +172,8 @@ namespace PARR.EsppApi
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private string GenerateRequest(EsppOperationsEnum operation, string query)
|
private string GenerateRequest(EsppOperationsEnum operation, string query)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Генерация запроса к ЕСПП: операция {Operation}", operation);
|
||||||
|
|
||||||
var baseRequest = $"<ROOT operation=\"operationValue\" returnFormat=\"json\">requestValue</ROOT>";
|
var baseRequest = $"<ROOT operation=\"operationValue\" returnFormat=\"json\">requestValue</ROOT>";
|
||||||
|
|
||||||
return baseRequest.Replace("operationValue", operation.ToString()).Replace("requestValue", query);
|
return baseRequest.Replace("operationValue", operation.ToString()).Replace("requestValue", query);
|
||||||
@@ -170,6 +189,8 @@ namespace PARR.EsppApi
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private string GenerateRequest<T>(EsppOperationsEnum operation, T jsonQuery)
|
private string GenerateRequest<T>(EsppOperationsEnum operation, T jsonQuery)
|
||||||
{
|
{
|
||||||
|
logger.LogDebug("Генерация JSON-запроса к ЕСПП: операция {Operation}", operation);
|
||||||
|
|
||||||
var jsonOptions = new JsonSerializerOptions { Encoder = JavaScriptEncoder.Create(UnicodeRanges.All, UnicodeRanges.Cyrillic) };
|
var jsonOptions = new JsonSerializerOptions { Encoder = JavaScriptEncoder.Create(UnicodeRanges.All, UnicodeRanges.Cyrillic) };
|
||||||
var strQuery = JsonSerializer.Serialize(jsonQuery, jsonOptions);
|
var strQuery = JsonSerializer.Serialize(jsonQuery, jsonOptions);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using PARR.Constants;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using PARR.Constants;
|
||||||
using PARR.EsppApi.Settings;
|
using PARR.EsppApi.Settings;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
@@ -35,16 +36,16 @@ namespace PARR.EsppApi.Models
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var dateTime = DateTime.ParseExact(ExpirationDate, "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture);
|
var dateTime = DateTime.ParseExact(ExpirationDate, "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture);
|
||||||
var utc = dateTime.AddHours(-EsppUserTimeZoneSettings.TimeZone);
|
var utc = dateTime.AddHours(-EsppUserTimeZoneSettings.TimeZone);
|
||||||
|
|
||||||
//TODO: костыль!!!
|
//TODO: костыль!!!
|
||||||
// странное поведение даты, разница с еспп 13 часов.
|
// странное поведение даты, разница с еспп 13 часов.
|
||||||
// считаем часовой пояс УЗ ЕСПП 10 часов ЮТС
|
// считаем часовой пояс УЗ ЕСПП 10 часов ЮТС
|
||||||
// в качестве костыля прибавляем 3
|
// в качестве костыля прибавляем 3
|
||||||
utc = dateTime.AddHours(-3);
|
utc = dateTime.AddHours(-3);
|
||||||
|
|
||||||
return new DateTimeOffset(utc, new TimeSpan(0));
|
return new DateTimeOffset(utc, new TimeSpan(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,11 +69,9 @@ namespace PARR.EsppApi.Models
|
|||||||
case "5-Закрыт":
|
case "5-Закрыт":
|
||||||
return OrderStatusEnum.Closed;
|
return OrderStatusEnum.Closed;
|
||||||
default:
|
default:
|
||||||
//logger.LogWarning($"Не смог распознать статус наряда, вернул значение по умполчанию: {OrderStatusEnum.New.ToString()}, входящее значение: {statusName}");
|
|
||||||
return OrderStatusEnum.New;
|
return OrderStatusEnum.New;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Статус наряда равен
|
/// Статус наряда равен
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? StatusIs { get; set; }
|
public string? StatusIs { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Дата сначала которой выбирать созданные наряды, UTC
|
/// Дата сначала которой выбирать созданные наряды, UTC
|
||||||
|
|||||||
@@ -41,74 +41,116 @@ namespace PARR.EsppOrderLoader
|
|||||||
{
|
{
|
||||||
logger.LogInformation("Запуск сервиса загрузки нарядов из ЕСПП.");
|
logger.LogInformation("Запуск сервиса загрузки нарядов из ЕСПП.");
|
||||||
|
|
||||||
await intervalService.IntervalInitAsync(DownloadOrdersAsync, settings.RepeatEvery);
|
try
|
||||||
|
{
|
||||||
//var nextStart = DateTime.Now;
|
await intervalService.IntervalInitAsync(DownloadOrdersAsync, settings.RepeatEvery);
|
||||||
|
logger.LogDebug("Сервис загрузки нарядов из ЕСПП успешно запущен с интервалом {RepeatEvery}", settings.RepeatEvery);
|
||||||
//while (true)
|
}
|
||||||
//{
|
catch (Exception ex)
|
||||||
// if (nextStart.Hour == DateTime.Now.Hour && nextStart.Minute == DateTime.Now.Minute)
|
{
|
||||||
// {
|
logger.LogError(ex, "Ошибка при инициализации интервального сервиса загрузки нарядов из ЕСПП");
|
||||||
// logger.LogInformation("Загрузка списка нарядов из ЕСПП.");
|
throw;
|
||||||
|
}
|
||||||
// await DownloadOrdersAsync();
|
|
||||||
|
|
||||||
// nextStart = DateTime.Now.Add(settings.RepeatEvery);
|
|
||||||
// logger.LogInformation($"Следующая дата загрузки: {nextStart}");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Каждую минуту
|
|
||||||
// await Task.Delay(60 * 1000);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Получаю список нарядов из еспп
|
//Получаю список нарядов из еспп
|
||||||
//проверяю есть ли наряд в бд
|
//проверяю есть ли наряд в бд
|
||||||
//если нет, ище шаблон в бд, затем сохраняю наряд в бд с привязанным шаблоном (если шаблон не нашел, тоже сохраняю)
|
//если нет, ищу шаблон в бд, затем сохраняю наряд в бд с привязанным шаблоном (если шаблон не нашел, тоже сохраняю)
|
||||||
|
|
||||||
private async Task DownloadOrdersAsync()
|
private async Task DownloadOrdersAsync()
|
||||||
{
|
{
|
||||||
var esppObjs = await GetOrdersAsync();
|
logger.LogDebug("Начинаю процесс загрузки нарядов из ЕСПП");
|
||||||
|
|
||||||
if (esppObjs == null)
|
try
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var item in esppObjs)
|
|
||||||
{
|
{
|
||||||
using (var scope = serviceProvider.CreateScope())
|
var esppObjs = await GetOrdersAsync();
|
||||||
{
|
|
||||||
var orderItemService = scope.ServiceProvider.GetService<IOrderItemService>();
|
|
||||||
if (orderItemService == null)
|
|
||||||
throw new Exception("Не смог получить серивс IOrderItemService, scope.ServiceProvider.GetService<IOrderItemService>()");
|
|
||||||
|
|
||||||
await orderItemService.WriteOrderAsync(item);
|
if (esppObjs == null || !esppObjs.Any())
|
||||||
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var item in esppObjs)
|
||||||
|
{
|
||||||
|
using (var scope = serviceProvider.CreateScope())
|
||||||
|
{
|
||||||
|
var orderItemService = scope.ServiceProvider.GetService<IOrderItemService>();
|
||||||
|
if (orderItemService == null)
|
||||||
|
throw new Exception("Не смог получить сервис IOrderItemService, scope.ServiceProvider.GetService<IOrderItemService>()");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logger.LogDebug("Обработка наряда {OrderNumber}", item.Number);
|
||||||
|
await orderItemService.WriteOrderAsync(item);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(
|
||||||
|
ex,
|
||||||
|
"Ошибка при обработке наряда {OrderNumber} из ЕСПП",
|
||||||
|
item?.Number ?? "неизвестно");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.LogDebug("Завершена обработка нарядов из ЕСПП");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "Критическая ошибка при загрузке нарядов из ЕСПП");
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task<IEnumerable<EsppOrder>?> GetOrdersAsync()
|
private async Task<IEnumerable<EsppOrder>?> GetOrdersAsync()
|
||||||
{
|
{
|
||||||
var searchQuery = new FindOrdersQuery
|
logger.LogDebug("Выполняю поиск нарядов в ЕСПП");
|
||||||
{
|
|
||||||
DescriptionContains = settingsFromDb.TemplatePrefixWithoutVariable,
|
|
||||||
GenerateDateStart = DateTimeOffset.UtcNow.DateTime.Add(-settingsFromDb.OrderSearchDeltaDate),
|
|
||||||
GenerateDateEnd = DateTimeOffset.UtcNow.DateTime
|
|
||||||
};
|
|
||||||
|
|
||||||
var downloadResult = await esppApiService.FindOrdersAsync(searchQuery);
|
try
|
||||||
|
|
||||||
if (!downloadResult.IsSuccess)
|
|
||||||
{
|
{
|
||||||
logger.LogError(downloadResult.Exception, "Ошибка загрузки списка нарядов из ЕСПП");
|
var searchQuery = new FindOrdersQuery
|
||||||
|
{
|
||||||
|
DescriptionContains = settingsFromDb.TemplatePrefixWithoutVariable,
|
||||||
|
GenerateDateStart = DateTimeOffset.UtcNow.DateTime.Add(-settingsFromDb.OrderSearchDeltaDate),
|
||||||
|
GenerateDateEnd = DateTimeOffset.UtcNow.DateTime
|
||||||
|
};
|
||||||
|
|
||||||
|
var downloadResult = await esppApiService.FindOrdersAsync(searchQuery);
|
||||||
|
|
||||||
|
logger.LogDebug("Результат запроса к ЕСПП: IsSuccess={IsSuccess}, Data={Data}",
|
||||||
|
downloadResult.IsSuccess,
|
||||||
|
downloadResult.Data?.Count() ?? 0);
|
||||||
|
|
||||||
|
if (!downloadResult.IsSuccess)
|
||||||
|
{
|
||||||
|
logger.LogError(
|
||||||
|
downloadResult.Exception,
|
||||||
|
"Ошибка загрузки списка нарядов из ЕСПП. Ошибка: {ErrorMessage}",
|
||||||
|
downloadResult.Exception?.Message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = downloadResult.Data;
|
||||||
|
var count = data?.Count() ?? 0;
|
||||||
|
|
||||||
|
if (data != null && count > 0)
|
||||||
|
{
|
||||||
|
logger.LogInformation("Успешно получено нарядов из ЕСПП: {Count}", count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.LogDebug("Успешно выполнен запрос к ЕСПП, но наряды отсутствуют. Количество: {Count}", count);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError(ex, "Критическая ошибка при выполнении запроса на получение нарядов из ЕСПП");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.LogInformation($"Получено нарядов из ЕСПП: {downloadResult.Data?.Count()}");
|
|
||||||
|
|
||||||
return downloadResult.Data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,74 +26,92 @@ namespace PARR.EsppOrderLoader.Services
|
|||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task WriteOrderAsync(EsppOrder esppOrder)
|
public async Task WriteOrderAsync(EsppOrder esppOrder)
|
||||||
{
|
{
|
||||||
var existOrder = await orderService.Get().FirstOrDefaultAsync(t => t.Number.ToLower() == esppOrder.Number.ToLower());
|
try
|
||||||
if (existOrder != null)
|
|
||||||
{
|
{
|
||||||
logger.LogInformation($"Наряд {esppOrder.Number} уже есть в БД. Пропускаю.");
|
logger.LogDebug("Начинаю обработку наряда {EsppOrderNumber}", esppOrder.Number);
|
||||||
return;
|
|
||||||
|
var existOrder = await orderService.Get()
|
||||||
|
.FirstOrDefaultAsync(t => t.Number.ToLower() == esppOrder.Number.ToLower());
|
||||||
|
|
||||||
|
if (existOrder != null)
|
||||||
|
{
|
||||||
|
logger.LogInformation("Наряд {EsppOrderNumber} уже существует в БД. Пропускаю.", esppOrder.Number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.LogDebug("Поиск шаблона для наряда {EsppOrderNumber}", esppOrder.Number);
|
||||||
|
|
||||||
|
var template = await templateService.Get()
|
||||||
|
.Include(t => t.Job)
|
||||||
|
.FirstOrDefaultAsync(t => t.Name.ToLower() == esppOrder.TemplateName.ToLower());
|
||||||
|
|
||||||
|
if (template == null)
|
||||||
|
{
|
||||||
|
logger.LogWarning(
|
||||||
|
"Не найден шаблон для наряда {EsppOrderNumber} с именем шаблона {TemplateName}. " +
|
||||||
|
"Краткое описание: {ShortName}, рабочая группа: {WorkGroup}",
|
||||||
|
esppOrder.Number,
|
||||||
|
esppOrder.TemplateName,
|
||||||
|
esppOrder.ShortName,
|
||||||
|
esppOrder.WorkGroup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.LogDebug(
|
||||||
|
"Найден шаблон {TemplateId} для наряда {EsppOrderNumber}",
|
||||||
|
template.Id,
|
||||||
|
esppOrder.Number);
|
||||||
|
}
|
||||||
|
|
||||||
|
var statusCode = (int)orderStatusService.GetOrderStatusByName(esppOrder.Status);
|
||||||
|
|
||||||
|
var newOrder = new Order
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid(),
|
||||||
|
Number = esppOrder.Number,
|
||||||
|
WorkGroup = esppOrder.WorkGroup,
|
||||||
|
ShortName = esppOrder.ShortName,
|
||||||
|
TemplateId = template?.Id,
|
||||||
|
StatusCode = statusCode,
|
||||||
|
GenerateDate = template == null
|
||||||
|
? null
|
||||||
|
: CalcGenerationDate(template.NextRun, template.LastRun),
|
||||||
|
ExpirationDate = esppOrder.ExpirationDateUTC,
|
||||||
|
DateCreated = DateTimeOffset.UtcNow
|
||||||
|
};
|
||||||
|
|
||||||
|
logger.LogDebug("Создание нового наряда {OrderNumber} в БД", esppOrder.Number);
|
||||||
|
|
||||||
|
var createResult = await orderService.CreateAsync(newOrder);
|
||||||
|
var commitResult = await orderService.CommitAsync();
|
||||||
|
|
||||||
|
if (!createResult || !commitResult)
|
||||||
|
{
|
||||||
|
logger.LogError(
|
||||||
|
"Ошибка при добавлении нового наряда в БД. " +
|
||||||
|
"Номер наряда: {EsppOrderNumber}, рабочая группа: {WorkGroup}, " +
|
||||||
|
"краткое описание: {ShortName}",
|
||||||
|
esppOrder.Number,
|
||||||
|
esppOrder.WorkGroup,
|
||||||
|
esppOrder.ShortName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.LogInformation(
|
||||||
|
"Успешно добавлен наряд в БД: {EsppOrderNumber}, краткое описание: {ShortName}",
|
||||||
|
esppOrder.Number,
|
||||||
|
esppOrder.ShortName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
var template = await templateService.Get()
|
|
||||||
.Include(t => t.Job)
|
|
||||||
.FirstOrDefaultAsync(t => t.Name.ToLower() == esppOrder.TemplateName.ToLower());
|
|
||||||
|
|
||||||
if (template == null)
|
|
||||||
logger.LogWarning($"Не найден шаблон для наряда {esppOrder.Number}, краткое описание наряда: {esppOrder.ShortName}. {esppOrder.WorkGroup}");
|
|
||||||
|
|
||||||
var newOrder = new Order
|
|
||||||
{
|
{
|
||||||
Id = Guid.NewGuid(),
|
logger.LogError(
|
||||||
Number = esppOrder.Number,
|
ex,
|
||||||
WorkGroup = esppOrder.WorkGroup,
|
"Произошла ошибка при обработке наряда {EsppOrderNumber}",
|
||||||
ShortName = esppOrder.ShortName,
|
esppOrder?.Number ?? "неизвестно");
|
||||||
TemplateId = template?.Id,
|
throw;
|
||||||
StatusCode = (int)orderStatusService.GetOrderStatusByName(esppOrder.Status),
|
|
||||||
GenerateDate = template == null ?
|
|
||||||
null
|
|
||||||
//: CalcGenerationDate(template.ApplicationsInWork!.NextRun, template.ApplicationsInWork!.LastRun),
|
|
||||||
: CalcGenerationDate(template.NextRun, template.LastRun),
|
|
||||||
//CalcGenerationDate(esppOrder.ExpirationDateUTC, template.ApplicationsInWork!.TemplateDurationTimeSpan),
|
|
||||||
ExpirationDate = esppOrder.ExpirationDateUTC
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!await orderService.CreateAsync(newOrder) || !await orderService.CommitAsync())
|
|
||||||
logger.LogError($"Ошибка при добавлении новой записи наряда в БД. {esppOrder.Number}, {esppOrder.WorkGroup}, {esppOrder.ShortName}");
|
|
||||||
else
|
|
||||||
logger.LogInformation($"Добавлен наряд в БД: {esppOrder.Number}, {esppOrder.ShortName}");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Рассчет GenerationDate относительно templateDuration
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="expirationDateUTC"></param>
|
|
||||||
/// <param name="templateDuration"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private DateTimeOffset? CalcGenerationDate(DateTimeOffset expirationDateUTC, TimeSpan? templateDuration)
|
|
||||||
{
|
|
||||||
//TimeSpan duration;
|
|
||||||
|
|
||||||
//try
|
|
||||||
//{
|
|
||||||
// //ЕСПП кривоногие, они почему-то таймспан пишут так "7 00:00:00", а правильно так: "7:00:00:00"
|
|
||||||
// var durationWithTimeSpanFormat = templateDuration.Replace(" ", ":");
|
|
||||||
// duration = TimeSpan.Parse(durationWithTimeSpanFormat);
|
|
||||||
//}
|
|
||||||
//catch (Exception e)
|
|
||||||
//{
|
|
||||||
// logger.LogError(e, $"Ошибка при конвертации templateDuration в TimeSpan, исходное значение: {templateDuration}");
|
|
||||||
// return null;
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (templateDuration.HasValue)
|
|
||||||
return expirationDateUTC.Add(-templateDuration.Value);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.LogError($"templateDuration = null.");
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,17 +119,22 @@ namespace PARR.EsppOrderLoader.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Рассчет GenerationDate относительно текущей даты и nextRun из ApplicationInWorks
|
/// Рассчет GenerationDate относительно текущей даты и nextRun из ApplicationInWorks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <param name="nextRun">Следующее время запуска</param>
|
||||||
|
/// <param name="lastRun">Последнее время запуска</param>
|
||||||
|
/// <returns>Рассчитанная дата генерации</returns>
|
||||||
private DateTimeOffset? CalcGenerationDate(DateTimeOffset nextRun, DateTimeOffset? lastRun)
|
private DateTimeOffset? CalcGenerationDate(DateTimeOffset nextRun, DateTimeOffset? lastRun)
|
||||||
{
|
{
|
||||||
if (DateTimeOffset.UtcNow > nextRun)
|
if (DateTimeOffset.UtcNow > nextRun)
|
||||||
|
{
|
||||||
return nextRun;
|
return nextRun;
|
||||||
|
}
|
||||||
|
|
||||||
if (lastRun.HasValue)
|
if (lastRun.HasValue)
|
||||||
|
{
|
||||||
return lastRun.Value;
|
return lastRun.Value;
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,12 +16,6 @@ namespace PARR.EsppOrderLoaderWorker
|
|||||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||||
{
|
{
|
||||||
await esppOrderLoader.StartAsync();
|
await esppOrderLoader.StartAsync();
|
||||||
//_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
|
|
||||||
////while (!stoppingToken.IsCancellationRequested)
|
|
||||||
////{
|
|
||||||
//// _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
|
|
||||||
//// await Task.Delay(1000, stoppingToken);
|
|
||||||
////}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,29 +1,24 @@
|
|||||||
{
|
{
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"RedisConnection": "10.99.253.216:6379,password=ParrP@ssPtk202MMdevDvs"
|
"RedisConnection": "10.99.253.216:6379,password=ParrP@ssPtk202MMdevDvs"
|
||||||
},
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft.Hosting.Lifetime": "Information"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Serilog": {
|
|
||||||
"MinimumLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Override": {
|
|
||||||
"Microsoft": "Warning",
|
|
||||||
"Microsoft.Hosting.Lifetime": "Information"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"WriteTo": [
|
"Serilog": {
|
||||||
{
|
"MinimumLevel": {
|
||||||
"Name": "File",
|
"Default": "Debug",
|
||||||
"Args": {
|
"Override": {
|
||||||
"path": "log/log-.txt",
|
"Microsoft": "Debug",
|
||||||
"rollingInterval": "Day"
|
"Microsoft.Hosting.Lifetime": "Debug",
|
||||||
}
|
"Microsoft.Extensions.Http.DefaultHttpClientFactory": "Warning"
|
||||||
}
|
}
|
||||||
]
|
},
|
||||||
}
|
"WriteTo": [
|
||||||
|
{
|
||||||
|
"Name": "File",
|
||||||
|
"Args": {
|
||||||
|
"path": "log/log-.txt",
|
||||||
|
"rollingInterval": "Day"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,16 +34,23 @@ namespace PARR.TemplateMatcher
|
|||||||
|
|
||||||
public async Task StartAsync()
|
public async Task StartAsync()
|
||||||
{
|
{
|
||||||
|
logger.LogInformation("Запускаем обработчик TemplateMatcher для очереди {QueueName}", mqSettings.TemplateMatcher.QueueName);
|
||||||
|
|
||||||
var isConnected = await mqService.InitConsumerAsync(mqSettings.TemplateMatcher, HandleMessageAsync);
|
var isConnected = await mqService.InitConsumerAsync(mqSettings.TemplateMatcher, HandleMessageAsync);
|
||||||
|
|
||||||
if (!isConnected)
|
if (!isConnected)
|
||||||
|
{
|
||||||
|
logger.LogError("Ошибка при подключении к RabbitMq для очереди {QueueName}", mqSettings.TemplateMatcher.QueueName);
|
||||||
throw new Exception("Ошибка при подключении к RabbitMq");
|
throw new Exception("Ошибка при подключении к RabbitMq");
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.LogInformation("Успешно подключились к RabbitMq для очереди {QueueName}", mqSettings.TemplateMatcher.QueueName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task HandleMessageAsync(string msg)
|
private async Task HandleMessageAsync(string msg)
|
||||||
{
|
{
|
||||||
logger.LogInformation($"Получили запрос: {msg}");
|
logger.LogDebug("Получили запрос: {Message}", msg);
|
||||||
|
|
||||||
var query = transformService.GetModelFromJson<TemplateMatcherMq>(msg);
|
var query = transformService.GetModelFromJson<TemplateMatcherMq>(msg);
|
||||||
if (query == null)
|
if (query == null)
|
||||||
@@ -52,6 +59,9 @@ namespace PARR.TemplateMatcher
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.LogTrace("Обрабатываем сообщение: EntityId={EntityId}, EntityType={EntityType}, Action={Action}",
|
||||||
|
query.Id, query.EntityType, query.Action);
|
||||||
|
|
||||||
await using (var scope = serviceProvider.CreateAsyncScope())
|
await using (var scope = serviceProvider.CreateAsyncScope())
|
||||||
{
|
{
|
||||||
var templateMatcherService = GetServiceInScope<ITemplateMatcher>(scope);
|
var templateMatcherService = GetServiceInScope<ITemplateMatcher>(scope);
|
||||||
@@ -66,6 +76,8 @@ namespace PARR.TemplateMatcher
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.LogDebug("Сущность {EntityType} с Id {Id} прошла валидацию", query.EntityType, query.Id);
|
||||||
|
|
||||||
switch (query.Action)
|
switch (query.Action)
|
||||||
{
|
{
|
||||||
case TemplateMatcherActionEnum.Sync:
|
case TemplateMatcherActionEnum.Sync:
|
||||||
@@ -90,6 +102,8 @@ namespace PARR.TemplateMatcher
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.LogDebug("Сущность {EntityType} с Id {Id} прошла валидацию", query.EntityType, query.Id);
|
||||||
|
|
||||||
switch (query.Action)
|
switch (query.Action)
|
||||||
{
|
{
|
||||||
case TemplateMatcherActionEnum.Sync:
|
case TemplateMatcherActionEnum.Sync:
|
||||||
@@ -115,12 +129,16 @@ namespace PARR.TemplateMatcher
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.LogDebug("Обработка сообщения завершена: {Message}", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task StopAsync()
|
public async Task StopAsync()
|
||||||
{
|
{
|
||||||
|
logger.LogInformation("Останавливаем обработчик TemplateMatcher");
|
||||||
await mqService.DisposeAsync();
|
await mqService.DisposeAsync();
|
||||||
|
logger.LogInformation("Обработчик TemplateMatcher остановлен");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user