From f57a08bc31c2161ad9f494bbbf44dd3733f5986c Mon Sep 17 00:00:00 2001 From: Factorino73 Date: Mon, 27 May 2024 01:52:34 +0400 Subject: [PATCH] BusinessLogics / Add Mail service --- .../MailWorker/AbstractMailWorker.cs | 108 ++++++++++++++++++ .../MailWorker/MailKitWorker.cs | 57 +++++++++ .../BindingModels/MailConfigBindingModel.cs | 44 +++++++ .../BindingModels/MailSendInfoBindingModel.cs | 34 ++++++ .../Controllers/HomeController.cs | 33 +++++- Hospital/HospitalWebApp/Program.cs | 15 +++ .../HospitalWebApp/Views/Home/Reports.cshtml | 2 +- Hospital/HospitalWebApp/appsettings.json | 9 +- 8 files changed, 296 insertions(+), 6 deletions(-) create mode 100644 Hospital/HospitalBusinessLogics/MailWorker/AbstractMailWorker.cs create mode 100644 Hospital/HospitalBusinessLogics/MailWorker/MailKitWorker.cs create mode 100644 Hospital/HospitalContracts/BindingModels/MailConfigBindingModel.cs create mode 100644 Hospital/HospitalContracts/BindingModels/MailSendInfoBindingModel.cs diff --git a/Hospital/HospitalBusinessLogics/MailWorker/AbstractMailWorker.cs b/Hospital/HospitalBusinessLogics/MailWorker/AbstractMailWorker.cs new file mode 100644 index 0000000..54972d2 --- /dev/null +++ b/Hospital/HospitalBusinessLogics/MailWorker/AbstractMailWorker.cs @@ -0,0 +1,108 @@ +using HospitalContracts.BindingModels; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalBusinessLogics.MailWorker +{ + /// + /// Абстрактный класс для работы с письмами + /// + public abstract class AbstractMailWorker + { + /// + /// Логгер + /// + private readonly ILogger _logger; + + /// + /// Логин для доступа к почтовому сервису + /// + protected string _mailLogin = string.Empty; + + /// + /// Пароль для доступа к почтовому сервису + /// + protected string _mailPassword = string.Empty; + + /// + /// Хост SMTP-клиента + /// + protected string _smtpClientHost = string.Empty; + + /// + /// Порт SMTP-клиента + /// + protected int _smtpClientPort; + + /// + /// Хост протокола POP3 + /// + protected string _popHost = string.Empty; + + /// + /// Порт протокола POP3 + /// + protected int _popPort; + + /// + /// Конструктор + /// + /// + public AbstractMailWorker(ILogger logger) + { + _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.Path)) + { + return; + } + + _logger.LogDebug("Send Mail: {To}, {Subject}", info.MailAddress, info.Subject); + await SendMailAsync(info); + } + + /// + /// Отправить письмо + /// + /// + /// + protected abstract Task SendMailAsync(MailSendInfoBindingModel info); + } +} diff --git a/Hospital/HospitalBusinessLogics/MailWorker/MailKitWorker.cs b/Hospital/HospitalBusinessLogics/MailWorker/MailKitWorker.cs new file mode 100644 index 0000000..4689a1b --- /dev/null +++ b/Hospital/HospitalBusinessLogics/MailWorker/MailKitWorker.cs @@ -0,0 +1,57 @@ +using HospitalContracts.BindingModels; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Mail; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalBusinessLogics.MailWorker +{ + /// + /// Реализация абстрактного класса для работы с письмами + /// + public class MailKitWorker : AbstractMailWorker + { + /// + /// Конструктор + /// + /// + public MailKitWorker(ILogger logger) : base(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.Attachments.Add(new Attachment(info.Path)); + // Указываем параметры + 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; + } + } + } +} diff --git a/Hospital/HospitalContracts/BindingModels/MailConfigBindingModel.cs b/Hospital/HospitalContracts/BindingModels/MailConfigBindingModel.cs new file mode 100644 index 0000000..bf03d6b --- /dev/null +++ b/Hospital/HospitalContracts/BindingModels/MailConfigBindingModel.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalContracts.BindingModels +{ + /// + /// Модель привязки для настройки почтового сервиса + /// + public class MailConfigBindingModel + { + /// + /// Логин для доступа к почтовому сервису + /// + public string MailLogin { get; set; } = string.Empty; + + /// + /// Пароль для доступа к почтовому сервису + /// + public string MailPassword { get; set; } = string.Empty; + + /// + /// Хост SMTP-клиента + /// + public string SmtpClientHost { get; set; } = string.Empty; + + /// + /// Порт SMTP-клиента + /// + public int SmtpClientPort { get; set; } + + /// + /// Хост протокола POP3 + /// + public string PopHost { get; set; } = string.Empty; + + /// + /// Порт протокола POP3 + /// + public int PopPort { get; set; } + } +} diff --git a/Hospital/HospitalContracts/BindingModels/MailSendInfoBindingModel.cs b/Hospital/HospitalContracts/BindingModels/MailSendInfoBindingModel.cs new file mode 100644 index 0000000..a221b20 --- /dev/null +++ b/Hospital/HospitalContracts/BindingModels/MailSendInfoBindingModel.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalContracts.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; + + /// + /// Путь до файла + /// + public string Path { get; set; } = string.Empty; + } +} diff --git a/Hospital/HospitalWebApp/Controllers/HomeController.cs b/Hospital/HospitalWebApp/Controllers/HomeController.cs index 5446063..ecff19f 100644 --- a/Hospital/HospitalWebApp/Controllers/HomeController.cs +++ b/Hospital/HospitalWebApp/Controllers/HomeController.cs @@ -1,4 +1,5 @@ -using HospitalContracts.BindingModels; +using HospitalBusinessLogics.MailWorker; +using HospitalContracts.BindingModels; using HospitalContracts.BusinessLogicsContracts; using HospitalContracts.SearchModels; using HospitalContracts.ViewModels; @@ -29,17 +30,24 @@ namespace HospitalWebApp.Controllers /// private readonly IReportLogic _reportLogic; + /// + /// Бизнес-логика для отправки писем + /// + private readonly AbstractMailWorker _mailLogic; + /// /// Конструктор /// /// /// /// - public HomeController(ILogger logger, IDoctorLogic doctorLogic, IReportLogic reportLogic) + /// + public HomeController(ILogger logger, IDoctorLogic doctorLogic, IReportLogic reportLogic, AbstractMailWorker mailLogic) { _logger = logger; _doctorLogic = doctorLogic; _reportLogic = reportLogic; + _mailLogic = mailLogic; } /// @@ -325,16 +333,33 @@ namespace HospitalWebApp.Controllers /// /// Отправить по почте отчёт /// + /// /// [HttpPost] - public void SendReport() + public void SendReport(IFormFile fileUpload) { if (APIClient.Doctor == null) { throw new Exception("Необходимо авторизоваться!"); } - // TODO + if (fileUpload == null || fileUpload.Length <= 0) + { + throw new Exception("Файл не выбран или пуст!"); + } + + // Путь до файла + var uploadPath = @"D:\ULSTU\Семестр 4\РПП Coursework\Reports\"; + var fileName = Path.GetFileName(fileUpload.FileName); + var fullPath = Path.Combine(uploadPath, fileName); + + _mailLogic.MailSendAsync(new MailSendInfoBindingModel + { + MailAddress = APIClient.Doctor.Email, + Subject = $"{fileName.Split('.')[0]}", + Text = $"Отчёт отправлен {DateTime.Now}", + Path = fullPath + }); Response.Redirect("/Home/Reports"); } diff --git a/Hospital/HospitalWebApp/Program.cs b/Hospital/HospitalWebApp/Program.cs index 469f5dd..a415524 100644 --- a/Hospital/HospitalWebApp/Program.cs +++ b/Hospital/HospitalWebApp/Program.cs @@ -1,6 +1,8 @@ using HospitalBusinessLogics.BusinessLogics; +using HospitalBusinessLogics.MailWorker; using HospitalBusinessLogics.OfficePackage; using HospitalBusinessLogics.OfficePackage.Implements; +using HospitalContracts.BindingModels; using HospitalContracts.BusinessLogicsContracts; using HospitalContracts.StoragesContracts; using HospitalDatabaseImplement.Implements; @@ -26,6 +28,7 @@ builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); +builder.Services.AddSingleton(); // BusinessLogic Reports services builder.Services.AddTransient(); @@ -35,6 +38,18 @@ builder.Services.AddTransient(); var app = builder.Build(); +// Configuration for MailService +var mailSender = app.Services.GetService(); +mailSender?.MailConfig(new MailConfigBindingModel +{ + MailLogin = builder.Configuration?.GetSection("MailLogin")?.Value?.ToString() ?? string.Empty, + MailPassword = builder.Configuration?.GetSection("MailPassword")?.Value?.ToString() ?? string.Empty, + SmtpClientHost = builder.Configuration?.GetSection("SmtpClientHost")?.Value?.ToString() ?? string.Empty, + SmtpClientPort = Convert.ToInt32(builder.Configuration?.GetSection("SmtpClientPort")?.Value?.ToString()), + PopHost = builder.Configuration?.GetSection("PopHost")?.Value?.ToString() ?? string.Empty, + PopPort = Convert.ToInt32(builder.Configuration?.GetSection("PopPort")?.Value?.ToString()) +}); + // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { diff --git a/Hospital/HospitalWebApp/Views/Home/Reports.cshtml b/Hospital/HospitalWebApp/Views/Home/Reports.cshtml index 642d7d4..2009a38 100644 --- a/Hospital/HospitalWebApp/Views/Home/Reports.cshtml +++ b/Hospital/HospitalWebApp/Views/Home/Reports.cshtml @@ -10,7 +10,7 @@

Отчеты

-
+
diff --git a/Hospital/HospitalWebApp/appsettings.json b/Hospital/HospitalWebApp/appsettings.json index 10f68b8..8f1c1a7 100644 --- a/Hospital/HospitalWebApp/appsettings.json +++ b/Hospital/HospitalWebApp/appsettings.json @@ -5,5 +5,12 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + + "SmtpClientHost": "smtp.gmail.com", + "SmtpClientPort": "587", + "PopHost": "pop.gmail.com", + "PopPort": "995", + "MailLogin": "besick73@gmail.com", + "MailPassword": "jmcp rbai teqa ltmc" }