From 10d45bf84798cbb1a7a45a762460a7788780d064 Mon Sep 17 00:00:00 2001 From: Programmist73 Date: Tue, 4 Apr 2023 13:44:54 +0400 Subject: [PATCH] =?UTF-8?q?LabWork06=20=D0=BF=D0=BE=20=D0=A2=D0=97.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ImplementerController.cs | 111 ++++++++++++ .../BlacksmithWorkshop/FormMain.Designer.cs | 41 ++--- .../BlacksmithWorkshop/FormMain.cs | 70 ++------ .../BlacksmithWorkshop/Program.cs | 3 +- .../BusinessLogic/WorkModeling.cs | 159 ++++++++++++++++++ .../BusinessLogicsContracts/IWorkProcess.cs | 14 ++ .../Models/IImplementerModel.cs | 22 +++ 7 files changed, 331 insertions(+), 89 deletions(-) create mode 100644 BlacksmithWorkshop/BlackmithWorkshopRestApi/Controllers/ImplementerController.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogic/WorkModeling.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopContracts/BusinessLogicsContracts/IWorkProcess.cs create mode 100644 BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/IImplementerModel.cs diff --git a/BlacksmithWorkshop/BlackmithWorkshopRestApi/Controllers/ImplementerController.cs b/BlacksmithWorkshop/BlackmithWorkshopRestApi/Controllers/ImplementerController.cs new file mode 100644 index 0000000..6dc96c7 --- /dev/null +++ b/BlacksmithWorkshop/BlackmithWorkshopRestApi/Controllers/ImplementerController.cs @@ -0,0 +1,111 @@ +using BlacksmithWorkshopContracts.BindingModels; +using BlacksmithWorkshopContracts.BusinessLogicsContracts; +using BlacksmithWorkshopContracts.SearchModels; +using BlacksmithWorkshopContracts.ViewModels; +using Microsoft.AspNetCore.Mvc; + +namespace BlacksmithWorkshopRestApi.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 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? 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; + } + } + } +} diff --git a/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.Designer.cs b/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.Designer.cs index 6783697..08cb98e 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.Designer.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.Designer.cs @@ -30,8 +30,6 @@ { dataGridView = new DataGridView(); buttonCreateOrder = new Button(); - buttonTakeOrderInWork = new Button(); - buttonOrderReady = new Button(); buttonIssuedOrder = new Button(); buttonRef = new Button(); menuStrip = new MenuStrip(); @@ -44,6 +42,7 @@ ordersToolStripMenuItem = new ToolStripMenuItem(); workWithClientsToolStripMenuItem = new ToolStripMenuItem(); clientsToolStripMenuItem = new ToolStripMenuItem(); + startingWorkToolStripMenuItem = new ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); menuStrip.SuspendLayout(); SuspendLayout(); @@ -68,29 +67,9 @@ buttonCreateOrder.UseVisualStyleBackColor = true; buttonCreateOrder.Click += ButtonCreateOrder_Click; // - // buttonTakeOrderInWork - // - buttonTakeOrderInWork.Location = new Point(1247, 147); - buttonTakeOrderInWork.Name = "buttonTakeOrderInWork"; - buttonTakeOrderInWork.Size = new Size(235, 29); - buttonTakeOrderInWork.TabIndex = 2; - buttonTakeOrderInWork.Text = "Отдать на выполнение"; - buttonTakeOrderInWork.UseVisualStyleBackColor = true; - buttonTakeOrderInWork.Click += ButtonTakeOrderInWork_Click; - // - // buttonOrderReady - // - buttonOrderReady.Location = new Point(1247, 224); - buttonOrderReady.Name = "buttonOrderReady"; - buttonOrderReady.Size = new Size(235, 29); - buttonOrderReady.TabIndex = 3; - buttonOrderReady.Text = "Заказ готов"; - buttonOrderReady.UseVisualStyleBackColor = true; - buttonOrderReady.Click += ButtonOrderReady_Click; - // // buttonIssuedOrder // - buttonIssuedOrder.Location = new Point(1247, 300); + buttonIssuedOrder.Location = new Point(1247, 144); buttonIssuedOrder.Name = "buttonIssuedOrder"; buttonIssuedOrder.Size = new Size(235, 29); buttonIssuedOrder.TabIndex = 4; @@ -100,7 +79,7 @@ // // buttonRef // - buttonRef.Location = new Point(1247, 373); + buttonRef.Location = new Point(1247, 221); buttonRef.Name = "buttonRef"; buttonRef.Size = new Size(235, 29); buttonRef.TabIndex = 5; @@ -111,7 +90,7 @@ // menuStrip // menuStrip.ImageScalingSize = new Size(20, 20); - menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem, reportsToolStripMenuItem, workWithClientsToolStripMenuItem }); + menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem, reportsToolStripMenuItem, workWithClientsToolStripMenuItem, startingWorkToolStripMenuItem }); menuStrip.Location = new Point(0, 0); menuStrip.Name = "menuStrip"; menuStrip.Size = new Size(1506, 28); @@ -181,6 +160,13 @@ clientsToolStripMenuItem.Text = "Клиенты"; clientsToolStripMenuItem.Click += ClientsToolStripMenuItem_Click; // + // startingWorkToolStripMenuItem + // + startingWorkToolStripMenuItem.Name = "startingWorkToolStripMenuItem"; + startingWorkToolStripMenuItem.Size = new Size(114, 24); + startingWorkToolStripMenuItem.Text = "Запуск работ"; + startingWorkToolStripMenuItem.Click += StartingWorkToolStripMenuItem_Click; + // // FormMain // AutoScaleDimensions = new SizeF(8F, 20F); @@ -188,8 +174,6 @@ ClientSize = new Size(1506, 450); Controls.Add(buttonRef); Controls.Add(buttonIssuedOrder); - Controls.Add(buttonOrderReady); - Controls.Add(buttonTakeOrderInWork); Controls.Add(buttonCreateOrder); Controls.Add(dataGridView); Controls.Add(menuStrip); @@ -208,8 +192,6 @@ private DataGridView dataGridView; private Button buttonCreateOrder; - private Button buttonTakeOrderInWork; - private Button buttonOrderReady; private Button buttonIssuedOrder; private Button buttonRef; private MenuStrip menuStrip; @@ -222,5 +204,6 @@ private ToolStripMenuItem ordersToolStripMenuItem; private ToolStripMenuItem workWithClientsToolStripMenuItem; private ToolStripMenuItem clientsToolStripMenuItem; + private ToolStripMenuItem startingWorkToolStripMenuItem; } } \ No newline at end of file diff --git a/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.cs b/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.cs index e8058df..28bebf4 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshop/FormMain.cs @@ -23,13 +23,16 @@ namespace BlacksmithWorkshop private readonly IReportLogic _reportLogic; - public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic) + private readonly IWorkProcess _workProcess; + + public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess) { InitializeComponent(); _logger = logger; _orderLogic = orderLogic; _reportLogic = reportLogic; + _workProcess = workProcess; } private void FormMain_Load(object sender, EventArgs e) @@ -95,64 +98,6 @@ namespace BlacksmithWorkshop } - private void ButtonTakeOrderInWork_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - _logger.LogInformation("Заказ №{id}. Меняется статус на 'В работе'", id); - - try - { - var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel - { - Id = id - }); - - if (!operationResult) - { - throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); - } - - LoadData(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка передачи заказа в работу"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } - - private void ButtonOrderReady_Click(object sender, EventArgs e) - { - if (dataGridView.SelectedRows.Count == 1) - { - int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); - _logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id); - - try - { - var operationResult = _orderLogic.FinishOrder(new OrderBindingModel - { - Id = id - }); - - if (!operationResult) - { - throw new Exception("Ошибка при сохранении. Дополнительная информация в логах."); - } - - LoadData(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Ошибка отметки о готовности заказа"); - MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } - private void ButtonIssuedOrder_Click(object sender, EventArgs e) { if (dataGridView.SelectedRows.Count == 1) @@ -233,5 +178,12 @@ namespace BlacksmithWorkshop form.ShowDialog(); } } + + private void StartingWorkToolStripMenuItem_Click(object sender, EventArgs e) + { + _workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic); + + MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); + } } } \ No newline at end of file diff --git a/BlacksmithWorkshop/BlacksmithWorkshop/Program.cs b/BlacksmithWorkshop/BlacksmithWorkshop/Program.cs index 64d9fdf..78b8790 100644 --- a/BlacksmithWorkshop/BlacksmithWorkshop/Program.cs +++ b/BlacksmithWorkshop/BlacksmithWorkshop/Program.cs @@ -49,8 +49,9 @@ namespace BlacksmithWorkshop services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); - services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogic/WorkModeling.cs b/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogic/WorkModeling.cs new file mode 100644 index 0000000..624637f --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopBusinessLogic/BusinessLogic/WorkModeling.cs @@ -0,0 +1,159 @@ +using BlacksmithWorkshopContracts.BindingModels; +using BlacksmithWorkshopContracts.BusinessLogicsContracts; +using BlacksmithWorkshopContracts.SearchModels; +using BlacksmithWorkshopContracts.ViewModels; +using BlacksmithWorkshopDataModels.Enums; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopBusinessLogic.BusinessLogic +{ + 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/BlacksmithWorkshop/BlacksmithWorkshopContracts/BusinessLogicsContracts/IWorkProcess.cs b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BusinessLogicsContracts/IWorkProcess.cs new file mode 100644 index 0000000..b03728b --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopContracts/BusinessLogicsContracts/IWorkProcess.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopContracts.BusinessLogicsContracts +{ + public interface IWorkProcess + { + // Запуск работ + void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic); + } +} diff --git a/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/IImplementerModel.cs b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/IImplementerModel.cs new file mode 100644 index 0000000..f00bc19 --- /dev/null +++ b/BlacksmithWorkshop/BlacksmithWorkshopDatabaseImplement/Models/IImplementerModel.cs @@ -0,0 +1,22 @@ +using BlacksmithWorkshopDataModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BlacksmithWorkshopDatabaseImplement.Models +{ + //модель исполнителя + public interface IImplementerModel : IId + { + string ImplementerFIO { get; } + + string Password { get; } + + int WorkExperience { get; } + + int Qualification { get; } + } + +}