Revert "Revert "Implementers""

This reverts commit de0c8651fe.
This commit is contained in:
Евгений Эгов 2023-02-25 20:07:50 +04:00
parent de0c8651fe
commit 9c47e69781
17 changed files with 535 additions and 0 deletions

View File

@ -0,0 +1,35 @@
using AbstractShopContracts.BindingModels;
using AbstractShopContracts.BusinessLogicsContracts;
using AbstractShopContracts.SearchModels;
using AbstractShopContracts.ViewModels;
namespace AbstractShopBusinessLogic.BusinessLogics
{
public class ImplementerLogic : IImplementerLogic
{
public bool Create(ImplementerBindingModel model)
{
throw new NotImplementedException();
}
public bool Delete(ImplementerBindingModel model)
{
throw new NotImplementedException();
}
public ImplementerViewModel? ReadElement(ImplementerSearchModel model)
{
throw new NotImplementedException();
}
public List<ImplementerViewModel>? ReadList(ImplementerSearchModel? model)
{
throw new NotImplementedException();
}
public bool Update(ImplementerBindingModel model)
{
throw new NotImplementedException();
}
}
}

View File

@ -22,6 +22,11 @@ namespace AbstractShopBusinessLogic.BusinessLogics
throw new NotImplementedException();
}
public OrderViewModel? ReadElement(OrderSearchModel model)
{
throw new NotImplementedException();
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
throw new NotImplementedException();

View File

@ -0,0 +1,143 @@
using AbstractShopContracts.BindingModels;
using AbstractShopContracts.BusinessLogicsContracts;
using AbstractShopContracts.SearchModels;
using AbstractShopContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace AbstractShopBusinessLogic.BusinessLogics
{
public class WorkModeling : IWorkProcess
{
private readonly ILogger _logger;
private readonly Random _rnd;
private IOrderLogic? _orderLogic;
public WorkModeling(ILogger<WorkModeling> logger)
{
_logger = logger;
_rnd = new Random(1000);
}
public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic)
{
_orderLogic = orderLogic;
var implementers = implementerLogic.ReadList(null);
if (implementers == null)
{
_logger.LogWarning("DoWork. Implementers is null");
return;
}
var orders = _orderLogic.ReadList(new OrderSearchModel { /*Status = OrderStatus.Принят*/ });
if (orders == null || orders.Count == 0)
{
_logger.LogWarning("DoWork. Orders is null or empty");
return;
}
_logger.LogDebug("DoWork for {Count} orders", orders.Count);
foreach (var implementer in implementers)
{
Task.Run(() => WorkerWorkAsync(implementer, orders));
}
}
/// <summary>
/// Иммитация работы исполнителя
/// </summary>
/// <param name="implementer"></param>
/// <param name="orders"></param>
private async Task WorkerWorkAsync(ImplementerViewModel implementer, List<OrderViewModel> orders)
{
if (_orderLogic == null || implementer == null)
{
return;
}
await RunOrderInWork(implementer);
await Task.Run(() =>
{
foreach (var order in orders)
{
try
{
_logger.LogDebug("DoWork. Worker {Id} try get order {Order}", implementer.Id, order.Id);
// пытаемся назначить заказ на исполнителя
_orderLogic.TakeOrderInWork(new OrderBindingModel
{
Id = order.Id,
// ImplementerId = implementer.Id
});
// делаем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = order.Id
});
}
// кто-то мог уже перехватить заказ, игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// заканчиваем выполнение имитации в случае иной ошибки
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
// отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
});
}
/// <summary>
/// Ищем заказ, которые уже в работе (вдруг исполнителя прервали)
/// </summary>
/// <param name="implementer"></param>
/// <returns></returns>
private async Task RunOrderInWork(ImplementerViewModel implementer)
{
if (_orderLogic == null || implementer == null)
{
return;
}
try
{
var runOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
{
// ImplementerId = implementer.Id,
// Status = OrderStatus.Выполняется
}));
if (runOrder == null)
{
return;
}
_logger.LogDebug("DoWork. Worker {Id} back to order {Order}", implementer.Id, runOrder.Id);
// доделываем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, runOrder.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = runOrder.Id
});
// отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
// заказа может не быть, просто игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// а может возникнуть иная ошибка, тогда просто заканчиваем выполнение имитации
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
}
}

View File

@ -0,0 +1,20 @@
using AbstractShopDataModels.Models;
namespace AbstractShopContracts.BindingModels
{
/// <summary>
/// Исполнитель, выполняющий заказы
/// </summary>
public class ImplementerBindingModel : IImplementerModel
{
public int Id { get; set; }
public string ImplementerFIO { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public int WorkExperience { get; set; }
public int Qualification { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using AbstractShopContracts.BindingModels;
using AbstractShopContracts.SearchModels;
using AbstractShopContracts.ViewModels;
namespace AbstractShopContracts.BusinessLogicsContracts
{
public interface IImplementerLogic
{
List<ImplementerViewModel>? ReadList(ImplementerSearchModel? model);
ImplementerViewModel? ReadElement(ImplementerSearchModel model);
bool Create(ImplementerBindingModel model);
bool Update(ImplementerBindingModel model);
bool Delete(ImplementerBindingModel model);
}
}

View File

@ -8,6 +8,8 @@ namespace AbstractShopContracts.BusinessLogicsContracts
{
List<OrderViewModel>? ReadList(OrderSearchModel? model);
OrderViewModel? ReadElement(OrderSearchModel model);
bool CreateOrder(OrderBindingModel model);
bool TakeOrderInWork(OrderBindingModel model);

View File

@ -0,0 +1,10 @@
namespace AbstractShopContracts.BusinessLogicsContracts
{
public interface IWorkProcess
{
/// <summary>
/// Запуск работ
/// </summary>
void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic);
}
}

View File

@ -0,0 +1,11 @@
namespace AbstractShopContracts.SearchModels
{
public class ImplementerSearchModel
{
public int? Id { get; set; }
public string? ImplementerFIO { get; set; }
public string? Password { get; set; }
}
}

View File

@ -0,0 +1,21 @@
using AbstractShopContracts.BindingModels;
using AbstractShopContracts.SearchModels;
using AbstractShopContracts.ViewModels;
namespace AbstractShopContracts.StoragesContracts
{
public interface IImplementerStorage
{
List<ImplementerViewModel> GetFullList();
List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model);
ImplementerViewModel? GetElement(ImplementerSearchModel model);
ImplementerViewModel? Insert(ImplementerBindingModel model);
ImplementerViewModel? Update(ImplementerBindingModel model);
ImplementerViewModel? Delete(ImplementerBindingModel model);
}
}

View File

@ -0,0 +1,25 @@
using AbstractShopDataModels.Models;
using System.ComponentModel;
namespace AbstractShopContracts.ViewModels
{
/// <summary>
/// Исполнитель, выполняющий заказы
/// </summary>
public class ImplementerViewModel : IImplementerModel
{
public int Id { get; set; }
[DisplayName("ФИО исполнителя")]
public string ImplementerFIO { get; set; } = string.Empty;
[DisplayName("Пароль")]
public string Password { get; set; } = string.Empty;
[DisplayName("Стаж работы")]
public int WorkExperience { get; set; }
[DisplayName("Квалификация")]
public int Qualification { get; set; }
}
}

View File

@ -0,0 +1,13 @@
namespace AbstractShopDataModels.Models
{
public interface IImplementerModel : IId
{
string ImplementerFIO { get; }
string Password { get; }
int WorkExperience { get; }
int Qualification { get; }
}
}

View File

@ -0,0 +1,40 @@
using AbstractShopContracts.BindingModels;
using AbstractShopContracts.SearchModels;
using AbstractShopContracts.StoragesContracts;
using AbstractShopContracts.ViewModels;
namespace AbstractShopDatabaseImplement.Implements
{
public class ImplementerStorage : IImplementerStorage
{
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
throw new NotImplementedException();
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
throw new NotImplementedException();
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
throw new NotImplementedException();
}
public List<ImplementerViewModel> GetFullList()
{
throw new NotImplementedException();
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
throw new NotImplementedException();
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,40 @@
using AbstractShopContracts.BindingModels;
using AbstractShopContracts.SearchModels;
using AbstractShopContracts.StoragesContracts;
using AbstractShopContracts.ViewModels;
namespace AbstractShopFileImplement.Implements
{
public class ImplementerStorage : IImplementerStorage
{
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
throw new NotImplementedException();
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
throw new NotImplementedException();
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
throw new NotImplementedException();
}
public List<ImplementerViewModel> GetFullList()
{
throw new NotImplementedException();
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
throw new NotImplementedException();
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,40 @@
using AbstractShopContracts.BindingModels;
using AbstractShopContracts.SearchModels;
using AbstractShopContracts.StoragesContracts;
using AbstractShopContracts.ViewModels;
namespace AbstractShopListImplement.Implements
{
public class ImplementerStorage : IImplementerStorage
{
public ImplementerViewModel? Delete(ImplementerBindingModel model)
{
throw new NotImplementedException();
}
public ImplementerViewModel? GetElement(ImplementerSearchModel model)
{
throw new NotImplementedException();
}
public List<ImplementerViewModel> GetFilteredList(ImplementerSearchModel model)
{
throw new NotImplementedException();
}
public List<ImplementerViewModel> GetFullList()
{
throw new NotImplementedException();
}
public ImplementerViewModel? Insert(ImplementerBindingModel model)
{
throw new NotImplementedException();
}
public ImplementerViewModel? Update(ImplementerBindingModel model)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,106 @@
using AbstractShopContracts.BindingModels;
using AbstractShopContracts.BusinessLogicsContracts;
using AbstractShopContracts.SearchModels;
using AbstractShopContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace AbstractShopRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ImplementerController : Controller
{
private readonly ILogger _logger;
private readonly IOrderLogic _order;
private readonly IImplementerLogic _logic;
public ImplementerController(IOrderLogic order, IImplementerLogic logic, ILogger<ImplementerController> logger)
{
_logger = logger;
_order = order;
_logic = logic;
}
[HttpGet]
public ImplementerViewModel? Login(string login, string password)
{
try
{
return _logic.ReadElement(new ImplementerSearchModel
{
ImplementerFIO = login,
Password = password
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка авторизации сотрудника");
throw;
}
}
[HttpGet]
public List<OrderViewModel>? GetNewOrders()
{
try
{
return _order.ReadList(new OrderSearchModel
{
//Status = OrderStatus.Принят
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения новых заказов");
throw;
}
}
[HttpGet]
public OrderViewModel? GetImplementerOrder(int implementerId)
{
try
{
return _order.ReadElement(new OrderSearchModel
{
//ImplementerId = implementerId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения текущего заказа исполнителя");
throw;
}
}
[HttpPost]
public void TakeOrderInWork(OrderBindingModel model)
{
try
{
_order.TakeOrderInWork(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка перевода заказа с №{Id} в работу", model.Id);
throw;
}
}
[HttpPost]
public void FinishOrder(OrderBindingModel model)
{
try
{
_order.FinishOrder(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о готовности заказа с №{Id}", model.Id);
throw;
}
}
}
}

View File

@ -11,10 +11,12 @@ builder.Logging.AddLog4Net("log4net.config");
// Add services to the container.
builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IProductStorage, ProductStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IProductLogic, ProductLogic>();

View File

@ -36,14 +36,17 @@ namespace AbstractShopView
});
services.AddTransient<IClientStorage, ClientStorage>();
services.AddTransient<IComponentStorage, ComponentStorage>();
services.AddTransient<IImplementerStorage, ImplementerStorage>();
services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<IProductStorage, ProductStorage>();
services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<IComponentLogic, ComponentLogic>();
services.AddTransient<IImplementerLogic, ImplementerLogic>();
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<IProductLogic, ProductLogic>();
services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<IWorkProcess, WorkModeling>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToWord, SaveToWord>();