From 5da4a4c8b258d0db6c9c96686c9e880d23137f2f Mon Sep 17 00:00:00 2001 From: VictoriaPresnyakova Date: Mon, 17 Apr 2023 18:05:56 +0400 Subject: [PATCH] without task --- .../BusinessLogics/WorkModeling.cs | 140 +++++++++++++++++- .../BusinessLogicsContracts/IWorkProcess.cs | 7 +- .../Models/IImplementerModel.cs | 7 +- .../Controllers/ImplementerController.cs | 100 ++++++++++++- 4 files changed, 247 insertions(+), 7 deletions(-) diff --git a/JewelryStoreBusinessLogic/BusinessLogics/WorkModeling.cs b/JewelryStoreBusinessLogic/BusinessLogics/WorkModeling.cs index a3c2a8c..e969286 100644 --- a/JewelryStoreBusinessLogic/BusinessLogics/WorkModeling.cs +++ b/JewelryStoreBusinessLogic/BusinessLogics/WorkModeling.cs @@ -1,4 +1,9 @@ -using System; +using JewelryStoreContracts.BindingModels; +using JewelryStoreContracts.BusinessLogicsContracts; +using JewelryStoreContracts.SearchModels; +using JewelryStoreContracts.ViewModels; +using Microsoft.Extensions.Logging; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -6,7 +11,138 @@ using System.Threading.Tasks; namespace JewelryStoreBusinessLogic.BusinessLogics { - internal class WorkModeling + public class WorkModeling : IWorkProcess { + private readonly ILogger _logger; + + private readonly Random _rnd; + + private IOrderLogic? _orderLogic; + + public WorkModeling(ILogger 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)); + } + } + + /// + /// Иммитация работы исполнителя + /// + /// + /// + private async Task WorkerWorkAsync(ImplementerViewModel implementer, List 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)); + } + }); + } + + /// + /// Ищем заказ, которые уже в работе (вдруг исполнителя прервали) + /// + /// + /// + 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; + } + } } } diff --git a/JewelryStoreContracts/BusinessLogicsContracts/IWorkProcess.cs b/JewelryStoreContracts/BusinessLogicsContracts/IWorkProcess.cs index 0583744..60b4065 100644 --- a/JewelryStoreContracts/BusinessLogicsContracts/IWorkProcess.cs +++ b/JewelryStoreContracts/BusinessLogicsContracts/IWorkProcess.cs @@ -6,7 +6,12 @@ using System.Threading.Tasks; namespace JewelryStoreContracts.BusinessLogicsContracts { - internal interface IWorkProcess + public interface IWorkProcess { + /// + /// Запуск работ + /// + void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic); + } } diff --git a/JewelryStoreDataModels/Models/IImplementerModel.cs b/JewelryStoreDataModels/Models/IImplementerModel.cs index d2ad852..5a48419 100644 --- a/JewelryStoreDataModels/Models/IImplementerModel.cs +++ b/JewelryStoreDataModels/Models/IImplementerModel.cs @@ -6,7 +6,12 @@ using System.Threading.Tasks; namespace JewelryStoreDataModels.Models { - internal interface IImplementerModel + public interface IImplementerModel : IId { + string ImplementerFIO { get; } + string Password { get; } + int WorkExperience { get; } + int Qualification { get; } + } } diff --git a/JewelryStoreRestApi/Controllers/ImplementerController.cs b/JewelryStoreRestApi/Controllers/ImplementerController.cs index e6367c0..9a318f4 100644 --- a/JewelryStoreRestApi/Controllers/ImplementerController.cs +++ b/JewelryStoreRestApi/Controllers/ImplementerController.cs @@ -1,12 +1,106 @@ -using Microsoft.AspNetCore.Mvc; +using JewelryStoreContracts.BindingModels; +using JewelryStoreContracts.BusinessLogicsContracts; +using JewelryStoreContracts.SearchModels; +using JewelryStoreContracts.ViewModels; +using Microsoft.AspNetCore.Mvc; namespace JewelryStoreRestApi.Controllers { + [Route("api/[controller]/[action]")] + [ApiController] public class ImplementerController : Controller { - public IActionResult Index() + private readonly ILogger _logger; + + private readonly IOrderLogic _order; + + private readonly IImplementerLogic _logic; + + public ImplementerController(IOrderLogic order, IImplementerLogic logic, ILogger logger) { - return View(); + _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? 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; + } } } }