diff --git a/University/UniversityBusinessLogic/MailWorker/AbstractMailWorker.cs b/University/UniversityBusinessLogic/MailWorker/AbstractMailWorker.cs new file mode 100644 index 0000000..97ce1f4 --- /dev/null +++ b/University/UniversityBusinessLogic/MailWorker/AbstractMailWorker.cs @@ -0,0 +1,62 @@ +using Microsoft.Extensions.Logging; +using UniversityContracts.BindingModels; +using UniversityContracts.BusinessLogicsContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace UniversityBusinessLogic.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 ILogger _logger; + + 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.Text)) + { + return; + } + + _logger.LogDebug("Send Mail: {To}, {Subject}", info.MailAddress, info.Subject); + + await SendMailAsync(info); + } + + protected abstract Task SendMailAsync(MailSendInfoBindingModel info); + } +} diff --git a/University/UniversityBusinessLogic/MailWorker/MailKitWorker.cs b/University/UniversityBusinessLogic/MailWorker/MailKitWorker.cs new file mode 100644 index 0000000..ac46a95 --- /dev/null +++ b/University/UniversityBusinessLogic/MailWorker/MailKitWorker.cs @@ -0,0 +1,52 @@ +using Microsoft.Extensions.Logging; +using UniversityContracts.BindingModels; +using UniversityContracts.BusinessLogicsContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Mail; +using System.Net; +using System.Security.Authentication; +using System.Text; +using System.Threading.Tasks; +using MailKit.Net.Pop3; +using MailKit.Security; +using System.Net.Mime; + +namespace UniversityBusinessLogic.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.SubjectEncoding = Encoding.UTF8; + objMailMessage.BodyEncoding = Encoding.UTF8; + Attachment attachment = new Attachment($"C:\\Users\\{Environment.UserName}\\Desktop\\Сведения по планам обучения.pdf", new ContentType(MediaTypeNames.Application.Pdf)); + objMailMessage.Attachments.Add(attachment); + + 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/University/UniversityBusinessLogic/OfficePackage/AbstractSaveToPdfWorker.cs b/University/UniversityBusinessLogic/OfficePackage/AbstractSaveToPdfWorker.cs index d01ffee..1ad7b83 100644 --- a/University/UniversityBusinessLogic/OfficePackage/AbstractSaveToPdfWorker.cs +++ b/University/UniversityBusinessLogic/OfficePackage/AbstractSaveToPdfWorker.cs @@ -5,7 +5,7 @@ namespace UniversityBusinessLogic.OfficePackage { public abstract class AbstractSaveToPdfWorker { - /*public void CreateDoc(PdfInfoWorker info) + public void CreateDoc(PdfInfoWorker info) { CreatePdf(info); CreateParagraph(new PdfParagraph { Text = info.Title, Style = "NormalTitle", ParagraphAlignment = PdfParagraphAlignmentType.Center }); @@ -15,24 +15,22 @@ namespace UniversityBusinessLogic.OfficePackage CreateRow(new PdfRowParameters { - Texts = new List { "Номер", "Дата заказа", "Работа", "Статус", "Сумма" }, + Texts = new List { "Номер", "План обучения", "Студент - дисциплина" }, Style = "NormalTitle", ParagraphAlignment = PdfParagraphAlignmentType.Center }); - foreach (var order in info.Orders) + foreach (var item in info.PlanOfStudyAndStudent) { CreateRow(new PdfRowParameters { - Texts = new List { order.Id.ToString(), order.DateCreate.ToShortDateString(), order.WorkName, order.OrderStatus.ToString(), order.Sum.ToString() }, + Texts = new List { item.Id.ToString(), item.PlanOfStudyName, string.Join(", ", item.StudentsAndDisciplines.Select(sd => $"{sd.Student} - {sd.Discipline}")) }, Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Left }); } - CreateParagraph(new PdfParagraph { Text = $"Итого: {info.Orders.Sum(x => x.Sum)}\t", Style = "Normal", ParagraphAlignment = PdfParagraphAlignmentType.Right }); - SavePdf(info); - }*/ + } /// /// Создание doc-файла diff --git a/University/UniversityBusinessLogic/OfficePackage/HelperModels/PdfInfoWorker.cs b/University/UniversityBusinessLogic/OfficePackage/HelperModels/PdfInfoWorker.cs index dba7672..393dd1b 100644 --- a/University/UniversityBusinessLogic/OfficePackage/HelperModels/PdfInfoWorker.cs +++ b/University/UniversityBusinessLogic/OfficePackage/HelperModels/PdfInfoWorker.cs @@ -1,4 +1,6 @@ -namespace UniversityBusinessLogic.OfficePackage.HelperModels +using UniversityContracts.ViewModels; + +namespace UniversityBusinessLogic.OfficePackage.HelperModels { public class PdfInfoWorker { @@ -9,5 +11,6 @@ public DateOnly DateFrom { get; set; } public DateOnly DateTo { get; set; } public List ReportObjects { get; set; } = new(); + public List PlanOfStudyAndStudent { get; set; } = new(); } } diff --git a/University/UniversityBusinessLogic/OfficePackage/Implements/SaveToPdfWorker.cs b/University/UniversityBusinessLogic/OfficePackage/Implements/SaveToPdfWorker.cs index 2f574e1..94bf731 100644 --- a/University/UniversityBusinessLogic/OfficePackage/Implements/SaveToPdfWorker.cs +++ b/University/UniversityBusinessLogic/OfficePackage/Implements/SaveToPdfWorker.cs @@ -43,7 +43,7 @@ namespace UniversityBusinessLogic.OfficePackage.Implements { _document = new Document(); DefineStyles(_document); - + _document.DefaultPageSetup.Orientation = Orientation.Landscape; _section = _document.AddSection(); } @@ -107,6 +107,7 @@ namespace UniversityBusinessLogic.OfficePackage.Implements { Document = _document }; + System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); renderer.RenderDocument(); renderer.PdfDocument.Save(info.FileName); } diff --git a/University/UniversityBusinessLogic/UniversityBusinessLogic.csproj b/University/UniversityBusinessLogic/UniversityBusinessLogic.csproj index 65aaa64..81bc281 100644 --- a/University/UniversityBusinessLogic/UniversityBusinessLogic.csproj +++ b/University/UniversityBusinessLogic/UniversityBusinessLogic.csproj @@ -8,6 +8,7 @@ + diff --git a/University/UniversityContracts/BindingModels/MailConfigBindingModel.cs b/University/UniversityContracts/BindingModels/MailConfigBindingModel.cs new file mode 100644 index 0000000..ffbbbb1 --- /dev/null +++ b/University/UniversityContracts/BindingModels/MailConfigBindingModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace UniversityContracts.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/University/UniversityContracts/BindingModels/MailSendInfoBindingModel.cs b/University/UniversityContracts/BindingModels/MailSendInfoBindingModel.cs new file mode 100644 index 0000000..6b04516 --- /dev/null +++ b/University/UniversityContracts/BindingModels/MailSendInfoBindingModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace UniversityContracts.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/University/UniversityContracts/ViewModels/ReportPlanOfStudyAndStudentViewModel.cs b/University/UniversityContracts/ViewModels/ReportPlanOfStudyAndStudentViewModel.cs index c33ba9b..efe29ca 100644 --- a/University/UniversityContracts/ViewModels/ReportPlanOfStudyAndStudentViewModel.cs +++ b/University/UniversityContracts/ViewModels/ReportPlanOfStudyAndStudentViewModel.cs @@ -8,6 +8,7 @@ namespace UniversityContracts.ViewModels { public class ReportPlanOfStudyAndStudentViewModel { + public int Id { get; set; } public string PlanOfStudyName { get; set; } = string.Empty; public List<(string Student, string Discipline)> StudentsAndDisciplines { get; set; } = new(); } diff --git a/University/UniversityDatabaseImplement/UniversityDatabase.cs b/University/UniversityDatabaseImplement/UniversityDatabase.cs index 07213d0..2b73bad 100644 --- a/University/UniversityDatabaseImplement/UniversityDatabase.cs +++ b/University/UniversityDatabaseImplement/UniversityDatabase.cs @@ -11,7 +11,7 @@ namespace UniversityDatabaseImplement if (optionsBuilder.IsConfigured == false) { //Возможно понадобится писать вместо (localdb) название пк, вот пк Егора: DESKTOP-N8BRIPR; other-name: LAPTOP-DYCTATOR; other-name: DyCTaTOR - optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-N8BRIPR\SQLEXPRESS;Initial Catalog=UniversityDatabaseFull;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); + optionsBuilder.UseSqlServer(@"Data Source=DyCTaTOR\SQLEXPRESS;Initial Catalog=UniversityDatabaseFull;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); } base.OnConfiguring(optionsBuilder); } diff --git a/University/UniversityRestApi/Controllers/PlanOfStudysController.cs b/University/UniversityRestApi/Controllers/PlanOfStudysController.cs index a5e36ce..6acb154 100644 --- a/University/UniversityRestApi/Controllers/PlanOfStudysController.cs +++ b/University/UniversityRestApi/Controllers/PlanOfStudysController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using UniversityBusinessLogic.MailWorker; using UniversityContracts.BindingModels; using UniversityContracts.BusinessLogicContracts; using UniversityContracts.BusinessLogicsContracts; @@ -15,11 +16,13 @@ namespace UniversityRestApi.Controllers private readonly ILogger _logger; private readonly IPlanOfStudyLogic _logic; private readonly IReportLogic _reportLogic; - public PlanOfStudysController(IPlanOfStudyLogic logic, ILogger logger, IReportLogic reportLogic) + private readonly AbstractMailWorker _mailWorker; + public PlanOfStudysController(IPlanOfStudyLogic logic, ILogger logger, IReportLogic reportLogic, AbstractMailWorker mailWorker) { _logic = logic; _logger = logger; _reportLogic = reportLogic; + _mailWorker = mailWorker; } [HttpGet] public List? GetPlanOfStudys(int userId) @@ -87,6 +90,19 @@ namespace UniversityRestApi.Controllers } } [HttpPost] + public void SendPDFToMail(MailSendInfoBindingModel model) + { + try + { + _mailWorker.MailSendAsync(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка отправки письма"); + throw; + } + } + [HttpPost] public void CreatePlanOfStudy(PlanOfStudyBindingModel model) { try diff --git a/University/UniversityRestApi/Program.cs b/University/UniversityRestApi/Program.cs index 7e4ee7c..ea95d50 100644 --- a/University/UniversityRestApi/Program.cs +++ b/University/UniversityRestApi/Program.cs @@ -1,9 +1,11 @@ using Microsoft.OpenApi.Models; using UniversityBusinessLogic.BusinessLogics; +using UniversityBusinessLogic.MailWorker; using UniversityBusinessLogic.OfficePackage; using UniversityBusinessLogic.OfficePackage.Implements; using UniversityBusinessLogics.BusinessLogics; +using UniversityContracts.BindingModels; using UniversityContracts.BusinessLogicContracts; using UniversityContracts.BusinessLogicsContracts; using UniversityContracts.StorageContracts; @@ -52,6 +54,18 @@ builder.Services.AddSwaggerGen(c => var app = builder.Build(); +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/University/UniversityRestApi/appsettings.json b/University/UniversityRestApi/appsettings.json index 4d56694..9ae31dd 100644 --- a/University/UniversityRestApi/appsettings.json +++ b/University/UniversityRestApi/appsettings.json @@ -5,5 +5,12 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + + "SmtpClientHost": "smtp.gmail.com", + "SmtpClientPort": "587", + "PopHost": "pop.gmail.com", + "PopPort": "995", + "MailLogin": "labwork7Stroev@gmail.com", + "MailPassword": "ilvf bkyd gali fhus" }