From 32b27fe590cd15669b613df9906aec2be0f30c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=AF=D0=BA=D0=BE?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=B2?= Date: Sat, 4 May 2024 17:57:25 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20=D1=81?= =?UTF-8?q?=D1=83=D1=89=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D1=84=D0=B8=D0=B3=D0=BE=D0=B2,=20=D1=80=D0=B5=D0=B0=D0=BB?= =?UTF-8?q?=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D0=BB=20=D0=B0=D0=B1=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D1=8B=D0=B9=20=D0=BA=D0=BB=D0=B0?= =?UTF-8?q?=D1=81=D1=81=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=B8=D1=81=D0=B5=D0=BC=20=D0=B8=20=D0=BF=D0=BE=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D1=8F=D0=BB=20orderLogic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...essageLogicInfo.cs => MessageInfoLogic.cs} | 4 +- .../BusinessLogics/OrderLogic.cs | 50 ++++++++++- .../CarRepairShopBusinessLogic.csproj | 1 + .../MailWorker/AbstractMailWorker.cs | 87 +++++++++++++++++++ .../MailWorker/MailKitWorker.cs | 82 +++++++++++++++++ .../BindingModels/MailConfigBindingModel.cs | 18 ++++ .../BindingModels/MailSendInfoBindingModel.cs | 16 ++++ .../Implements/ClientStorage.cs | 2 +- .../Implements/ClientStorage.cs | 2 +- .../Implements/ClientStorage.cs | 2 +- CarRepairShop/CarRepairShopRestApi/Program.cs | 7 ++ .../CarRepairShopRestApi/appsettings.json | 4 +- CarRepairShop/CarRepairShopView/App.config | 4 +- .../CarRepairShopView.csproj | 6 ++ CarRepairShop/CarRepairShopView/Program.cs | 5 ++ 15 files changed, 278 insertions(+), 12 deletions(-) rename CarRepairShop/CarRepairShopBusinessLogic/BusinessLogics/{MessageLogicInfo.cs => MessageInfoLogic.cs} (92%) create mode 100644 CarRepairShop/CarRepairShopBusinessLogic/MailWorker/AbstractMailWorker.cs create mode 100644 CarRepairShop/CarRepairShopBusinessLogic/MailWorker/MailKitWorker.cs create mode 100644 CarRepairShop/CarRepairShopContracts/BindingModels/MailConfigBindingModel.cs create mode 100644 CarRepairShop/CarRepairShopContracts/BindingModels/MailSendInfoBindingModel.cs diff --git a/CarRepairShop/CarRepairShopBusinessLogic/BusinessLogics/MessageLogicInfo.cs b/CarRepairShop/CarRepairShopBusinessLogic/BusinessLogics/MessageInfoLogic.cs similarity index 92% rename from CarRepairShop/CarRepairShopBusinessLogic/BusinessLogics/MessageLogicInfo.cs rename to CarRepairShop/CarRepairShopBusinessLogic/BusinessLogics/MessageInfoLogic.cs index 626ec49..0effa07 100644 --- a/CarRepairShop/CarRepairShopBusinessLogic/BusinessLogics/MessageLogicInfo.cs +++ b/CarRepairShop/CarRepairShopBusinessLogic/BusinessLogics/MessageInfoLogic.cs @@ -13,12 +13,12 @@ using System.Threading.Tasks; namespace CarRepairShopBusinessLogic.BusinessLogics { - public class MessageLogicInfo : IMessageInfoLogic + public class MessageInfoLogic : IMessageInfoLogic { private readonly ILogger _logger; private readonly IMessageInfoStorage _storage; - public MessageLogicInfo(ILogger logger, IMessageInfoStorage storage) + public MessageInfoLogic(ILogger logger, IMessageInfoStorage storage) { _logger = logger; _storage = storage; diff --git a/CarRepairShop/CarRepairShopBusinessLogic/BusinessLogics/OrderLogic.cs b/CarRepairShop/CarRepairShopBusinessLogic/BusinessLogics/OrderLogic.cs index ec5f850..7281221 100644 --- a/CarRepairShop/CarRepairShopBusinessLogic/BusinessLogics/OrderLogic.cs +++ b/CarRepairShop/CarRepairShopBusinessLogic/BusinessLogics/OrderLogic.cs @@ -1,4 +1,5 @@ -using CarRepairShopContracts.BindingModels; +using CarRepairShopBusinessLogic.MailWorker; +using CarRepairShopContracts.BindingModels; using CarRepairShopContracts.BusinessLogicsContracts; using CarRepairShopContracts.SearchModels; using CarRepairShopContracts.StoragesContracts; @@ -10,6 +11,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Xml.Linq; namespace CarRepairShopBusinessLogic.BusinessLogics { @@ -17,12 +19,16 @@ namespace CarRepairShopBusinessLogic.BusinessLogics { private readonly ILogger _logger; private readonly IOrderStorage _orderStorage; + private readonly IClientStorage _clientStorage; + private readonly AbstractMailWorker _mailLogic; static readonly object locker = new object(); - public OrderLogic(ILogger logger, IOrderStorage orderStorage) + public OrderLogic(ILogger logger, IOrderStorage orderStorage, IClientStorage clientStorage, AbstractMailWorker worker) { _logger = logger; _orderStorage = orderStorage; + _clientStorage = clientStorage; + _mailLogic = worker; } public List? ReadList(OrderSearchModel? model) @@ -58,12 +64,16 @@ namespace CarRepairShopBusinessLogic.BusinessLogics { CheckModel(model); model.Status = OrderStatus.Принят; - if (_orderStorage.Insert(model) == null) + var order = _orderStorage.Insert(model); + if (order == null) { _logger.LogInformation("Create operation failed"); return false; } + var clientView = _clientStorage.GetElement(new() { Id = order.ClientId }); + SendMail(clientView, order); + return true; } @@ -109,6 +119,10 @@ namespace CarRepairShopBusinessLogic.BusinessLogics _logger.LogWarning("Update operation failed"); return false; } + + var clientView = _clientStorage.GetElement(new() { Id = element.ClientId }); + SendMail(clientView, element); + return true; } @@ -132,5 +146,35 @@ namespace CarRepairShopBusinessLogic.BusinessLogics } _logger.LogInformation("Order. Id:{Id}. Sum:{Sum}. Count:{Count}", model.Id, model.Sum, model.Count); } + + private void SendMail(ClientViewModel clientModel, OrderViewModel orderModel) + { + if(clientModel == null || orderModel == null) + { + return; + } + + MailSendInfoBindingModel mailModel; + + if(orderModel.Status == OrderStatus.Принят) + { + mailModel = new MailSendInfoBindingModel + { + MailAddress = clientModel.Email, + Subject = $"Заказ №{orderModel.Id}", + Text = $"Ваш заказ №{orderModel.Id} на сумму {orderModel.Sum} был принят" + }; + } + else + { + mailModel = new MailSendInfoBindingModel + { + MailAddress = clientModel.Email, + Subject = $"Заказ №{orderModel.Id}", + Text = $"Статус заказа №{orderModel.Id} был изменен на {orderModel.Status}" + }; + } + _mailLogic.MailSendAsync(mailModel); + } } } diff --git a/CarRepairShop/CarRepairShopBusinessLogic/CarRepairShopBusinessLogic.csproj b/CarRepairShop/CarRepairShopBusinessLogic/CarRepairShopBusinessLogic.csproj index d097b76..ec82c12 100644 --- a/CarRepairShop/CarRepairShopBusinessLogic/CarRepairShopBusinessLogic.csproj +++ b/CarRepairShop/CarRepairShopBusinessLogic/CarRepairShopBusinessLogic.csproj @@ -8,6 +8,7 @@ + diff --git a/CarRepairShop/CarRepairShopBusinessLogic/MailWorker/AbstractMailWorker.cs b/CarRepairShop/CarRepairShopBusinessLogic/MailWorker/AbstractMailWorker.cs new file mode 100644 index 0000000..abdd111 --- /dev/null +++ b/CarRepairShop/CarRepairShopBusinessLogic/MailWorker/AbstractMailWorker.cs @@ -0,0 +1,87 @@ +using CarRepairShopContracts.BindingModels; +using CarRepairShopContracts.BusinessLogicsContracts; +using Microsoft.Extensions.Logging; +using SixLabors.ImageSharp.Advanced; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CarRepairShopBusinessLogic.MailWorker +{ + public abstract class AbstractMailWorker + { + protected string _mailLogin = string.Empty; + protected string _mailPassword = string.Empty; + protected string _smtpClientHost = string.Empty; + protected int _smtpClientPort; + protected string _popHost = string.Empty; + protected int _popPort; + private readonly IMessageInfoLogic _messageInfoLogic; + private readonly ILogger _logger; + public AbstractMailWorker(IMessageInfoLogic messageInfoLogic, ILogger logger) + { + _messageInfoLogic = messageInfoLogic; + _logger = logger; + } + + public void MailConfig(MailConfigBindingModel config) + { + _mailLogin = config.MailLogin; + _mailPassword = config.MailPassword; + _smtpClientHost = config.SmtpClientHost; + _smtpClientPort = config.SmtpClientPort; + _popHost = config.PopHost; + _popPort = config.PopPort; + _logger.LogDebug("Config: {login}, {password}, {clientHost}, {clientPOrt}, { popHost}, { popPort} ", + _mailLogin, _mailPassword, _smtpClientHost, _smtpClientPort, _popHost, _popPort); + } + + public async void MailSendAsync(MailSendInfoBindingModel info) + { + if(string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword)) + { + return; + } + if(string.IsNullOrEmpty(_smtpClientHost) || _smtpClientPort == 0) + { + return; + } + if(string.IsNullOrEmpty(info.MailAddress) || string.IsNullOrEmpty(info.Subject) || string.IsNullOrEmpty(info.Text)) + { + return; + } + + _logger.LogDebug("Send Mail: {To}, {Subject}", info.MailAddress, info.Subject); + await SendMailAsync(info); + } + + public async void MailCheck() + { + if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword)) + { + return; + } + if(string.IsNullOrEmpty(_popHost) || _popPort == 0) + { + return; + } + if(_messageInfoLogic == null) + { + return; + } + + var list = await ReceiveMailAsync(); + _logger.LogDebug("Check Mail: {Count} new mails", list.Count); + foreach(var mail in list) + { + _messageInfoLogic.Create(mail); + } + } + + protected abstract Task SendMailAsync(MailSendInfoBindingModel info); + + protected abstract Task> ReceiveMailAsync(); + } +} diff --git a/CarRepairShop/CarRepairShopBusinessLogic/MailWorker/MailKitWorker.cs b/CarRepairShop/CarRepairShopBusinessLogic/MailWorker/MailKitWorker.cs new file mode 100644 index 0000000..0d3b5a3 --- /dev/null +++ b/CarRepairShop/CarRepairShopBusinessLogic/MailWorker/MailKitWorker.cs @@ -0,0 +1,82 @@ +using CarRepairShopContracts.BindingModels; +using CarRepairShopContracts.BusinessLogicsContracts; +using MailKit.Net.Pop3; +using MailKit.Security; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Mail; +using System.Text; +using System.Threading.Tasks; + +namespace CarRepairShopBusinessLogic.MailWorker +{ + public class MailKitWorker : AbstractMailWorker + { + public MailKitWorker(ILogger logger, IMessageInfoLogic messageInfoLogic) : base(messageInfoLogic, logger) { } + + protected override async Task SendMailAsync(MailSendInfoBindingModel info) + { + using var objMailMessage = new MailMessage(); + using var objSmtpClient = new SmtpClient(_smtpClientHost, _smtpClientPort); + try + { + objMailMessage.From = new MailAddress(_mailLogin); + objMailMessage.To.Add(new MailAddress(info.MailAddress)); + objMailMessage.Subject = info.Subject; + objMailMessage.Body = info.Text; + objMailMessage.SubjectEncoding = Encoding.UTF8; + objMailMessage.BodyEncoding = Encoding.UTF8; + + objSmtpClient.UseDefaultCredentials = false; + objSmtpClient.EnableSsl = true; + objSmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network; + objSmtpClient.Credentials = new NetworkCredential(_mailLogin, _mailPassword); + + await Task.Run(() => objSmtpClient.Send(objMailMessage)); + } + catch (Exception) + { + throw; + } + } + + protected override async Task> ReceiveMailAsync() + { + var list = new List(); + using var client = new Pop3Client(); + await Task.Run(() => + { + try + { + client.Connect(_popHost, _popPort, SecureSocketOptions.SslOnConnect); + client.Authenticate(_mailLogin, _mailPassword); + for (int i = 0; i < client.Count; i++) + { + var message = client.GetMessage(i); + foreach (var mail in message.From.Mailboxes) + { + list.Add(new MessageInfoBindingModel + { + DateDelivery = message.Date.DateTime, + MessageId = message.MessageId, + SenderName = mail.Address, + Subject = message.Subject, + Body = message.TextBody + }); + } + } + } + catch (AuthenticationException) + { } + finally + { + client.Disconnect(true); + } + }); + return list; + } + } +} diff --git a/CarRepairShop/CarRepairShopContracts/BindingModels/MailConfigBindingModel.cs b/CarRepairShop/CarRepairShopContracts/BindingModels/MailConfigBindingModel.cs new file mode 100644 index 0000000..8a1ad4b --- /dev/null +++ b/CarRepairShop/CarRepairShopContracts/BindingModels/MailConfigBindingModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CarRepairShopContracts.BindingModels +{ + public class MailConfigBindingModel + { + public string MailLogin { get; set; } = string.Empty; + public string MailPassword { get; set; } = string.Empty; + public string SmtpClientHost { get; set; } = string.Empty; + public int SmtpClientPort { get; set; } + public string PopHost { get; set; } = string.Empty; + public int PopPort { get; set; } + } +} diff --git a/CarRepairShop/CarRepairShopContracts/BindingModels/MailSendInfoBindingModel.cs b/CarRepairShop/CarRepairShopContracts/BindingModels/MailSendInfoBindingModel.cs new file mode 100644 index 0000000..f631001 --- /dev/null +++ b/CarRepairShop/CarRepairShopContracts/BindingModels/MailSendInfoBindingModel.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CarRepairShopContracts.BindingModels +{ + public class MailSendInfoBindingModel + { + public string MailAddress { get; set; } = string.Empty; + public string Subject { get; set; } = string.Empty; + public string Text { get; set; } = string.Empty; + + } +} diff --git a/CarRepairShop/CarRepairShopDatabaseImplement/Implements/ClientStorage.cs b/CarRepairShop/CarRepairShopDatabaseImplement/Implements/ClientStorage.cs index 614e428..7f56f1f 100644 --- a/CarRepairShop/CarRepairShopDatabaseImplement/Implements/ClientStorage.cs +++ b/CarRepairShop/CarRepairShopDatabaseImplement/Implements/ClientStorage.cs @@ -36,7 +36,7 @@ namespace CarRepairShopDatabaseImplement.Implements return null; } using var context = new CarRepairShopDatabase(); - return context.Clients.FirstOrDefault(x => (!string.IsNullOrEmpty(model.Email)) && x.Email == model.Email || model.Id.HasValue && x.Id == model.Id)?.GetViewModel; + return context.Clients.FirstOrDefault(x => (!string.IsNullOrEmpty(model.Email)) && x.Email.Contains(model.Email) || model.Id.HasValue && x.Id == model.Id)?.GetViewModel; } public ClientViewModel? Insert(ClientBindingModel model) { diff --git a/CarRepairShop/CarRepairShopFileImplement/Implements/ClientStorage.cs b/CarRepairShop/CarRepairShopFileImplement/Implements/ClientStorage.cs index 134f7ac..e311822 100644 --- a/CarRepairShop/CarRepairShopFileImplement/Implements/ClientStorage.cs +++ b/CarRepairShop/CarRepairShopFileImplement/Implements/ClientStorage.cs @@ -35,7 +35,7 @@ namespace CarRepairShopFileImplement.Implements public ClientViewModel? GetElement(ClientSearchModel model) { if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue) return null; - return source.Clients.FirstOrDefault(x => (!string.IsNullOrEmpty(model.Email) && x.Email == model.Email) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; + return source.Clients.FirstOrDefault(x => (!string.IsNullOrEmpty(model.Email) && x.Email.Contains(model.Email)) || (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; } public ClientViewModel? Insert(ClientBindingModel model) diff --git a/CarRepairShop/CarRepairShopListImplement/Implements/ClientStorage.cs b/CarRepairShop/CarRepairShopListImplement/Implements/ClientStorage.cs index abdc349..ceaa59a 100644 --- a/CarRepairShop/CarRepairShopListImplement/Implements/ClientStorage.cs +++ b/CarRepairShop/CarRepairShopListImplement/Implements/ClientStorage.cs @@ -45,7 +45,7 @@ namespace CarRepairShopListImplement.Implements if(string.IsNullOrEmpty(model.Email) && !model.Id.HasValue) return null; foreach (var client in _source.Clients) { - if((!string.IsNullOrEmpty(model.Email) && client.Email == model.Email) || (model.Id.HasValue && client.Id == model.Id)) + if((!string.IsNullOrEmpty(model.Email) && client.Email.Contains(model.Email)) || (model.Id.HasValue && client.Id == model.Id)) { return client.GetViewModel; } diff --git a/CarRepairShop/CarRepairShopRestApi/Program.cs b/CarRepairShop/CarRepairShopRestApi/Program.cs index ce3d820..1d1cd72 100644 --- a/CarRepairShop/CarRepairShopRestApi/Program.cs +++ b/CarRepairShop/CarRepairShopRestApi/Program.cs @@ -1,4 +1,5 @@ using CarRepairShopBusinessLogic.BusinessLogics; +using CarRepairShopBusinessLogic.MailWorker; using CarRepairShopContracts.BusinessLogicsContracts; using CarRepairShopContracts.StoragesContracts; using CarRepairShopDatabaseImplement.Implements; @@ -14,9 +15,15 @@ builder.Logging.AddLog4Net("log4net.config"); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); +builder.Services.AddTransient(); + builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); +builder.Services.AddTransient(); + +builder.Services.AddSingleton(); + builder.Services.AddControllers(); diff --git a/CarRepairShop/CarRepairShopRestApi/appsettings.json b/CarRepairShop/CarRepairShopRestApi/appsettings.json index 0578777..097d094 100644 --- a/CarRepairShop/CarRepairShopRestApi/appsettings.json +++ b/CarRepairShop/CarRepairShopRestApi/appsettings.json @@ -11,7 +11,7 @@ "SmtpClientPort": "587", "PopHost": "pop.gmail.com", "PopPort": "995", - "MailLogin": "labwork7@mail.com", - "MailPassword": "#eoxSyN1aJS1" + "MailLogin": "shotboll16@gmail.com", + "MailPassword": "iexy xqps iwrj ihle" } diff --git a/CarRepairShop/CarRepairShopView/App.config b/CarRepairShop/CarRepairShopView/App.config index e2d0651..87968ee 100644 --- a/CarRepairShop/CarRepairShopView/App.config +++ b/CarRepairShop/CarRepairShopView/App.config @@ -5,7 +5,7 @@ - - + + \ No newline at end of file diff --git a/CarRepairShop/CarRepairShopView/CarRepairShopView.csproj b/CarRepairShop/CarRepairShopView/CarRepairShopView.csproj index 456bc44..677fe26 100644 --- a/CarRepairShop/CarRepairShopView/CarRepairShopView.csproj +++ b/CarRepairShop/CarRepairShopView/CarRepairShopView.csproj @@ -42,4 +42,10 @@ + + + Always + + + \ No newline at end of file diff --git a/CarRepairShop/CarRepairShopView/Program.cs b/CarRepairShop/CarRepairShopView/Program.cs index f8daeb9..df547fe 100644 --- a/CarRepairShop/CarRepairShopView/Program.cs +++ b/CarRepairShop/CarRepairShopView/Program.cs @@ -1,4 +1,5 @@ using CarRepairShopBusinessLogic.BusinessLogics; +using CarRepairShopBusinessLogic.MailWorker; using CarRepairShopBusinessLogic.OfficePackage; using CarRepairShopBusinessLogic.OfficePackage.Implements; using CarRepairShopContracts.BusinessLogicsContracts; @@ -44,6 +45,7 @@ namespace CarRepairShopView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -51,7 +53,10 @@ namespace CarRepairShopView services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddSingleton(); services.AddTransient(); services.AddTransient();