Сделал сущности конфигов, реализовал абстрактный класс отправки писем и поменял orderLogic

This commit is contained in:
Максим Яковлев 2024-05-04 17:57:25 +04:00
parent 021cb7f8f2
commit 32b27fe590
15 changed files with 278 additions and 12 deletions

View File

@ -13,12 +13,12 @@ using System.Threading.Tasks;
namespace CarRepairShopBusinessLogic.BusinessLogics namespace CarRepairShopBusinessLogic.BusinessLogics
{ {
public class MessageLogicInfo : IMessageInfoLogic public class MessageInfoLogic : IMessageInfoLogic
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IMessageInfoStorage _storage; private readonly IMessageInfoStorage _storage;
public MessageLogicInfo(ILogger logger, IMessageInfoStorage storage) public MessageInfoLogic(ILogger logger, IMessageInfoStorage storage)
{ {
_logger = logger; _logger = logger;
_storage = storage; _storage = storage;

View File

@ -1,4 +1,5 @@
using CarRepairShopContracts.BindingModels; using CarRepairShopBusinessLogic.MailWorker;
using CarRepairShopContracts.BindingModels;
using CarRepairShopContracts.BusinessLogicsContracts; using CarRepairShopContracts.BusinessLogicsContracts;
using CarRepairShopContracts.SearchModels; using CarRepairShopContracts.SearchModels;
using CarRepairShopContracts.StoragesContracts; using CarRepairShopContracts.StoragesContracts;
@ -10,6 +11,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Xml.Linq;
namespace CarRepairShopBusinessLogic.BusinessLogics namespace CarRepairShopBusinessLogic.BusinessLogics
{ {
@ -17,12 +19,16 @@ namespace CarRepairShopBusinessLogic.BusinessLogics
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage; private readonly IOrderStorage _orderStorage;
private readonly IClientStorage _clientStorage;
private readonly AbstractMailWorker _mailLogic;
static readonly object locker = new object(); static readonly object locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage) public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, IClientStorage clientStorage, AbstractMailWorker worker)
{ {
_logger = logger; _logger = logger;
_orderStorage = orderStorage; _orderStorage = orderStorage;
_clientStorage = clientStorage;
_mailLogic = worker;
} }
public List<OrderViewModel>? ReadList(OrderSearchModel? model) public List<OrderViewModel>? ReadList(OrderSearchModel? model)
@ -58,12 +64,16 @@ namespace CarRepairShopBusinessLogic.BusinessLogics
{ {
CheckModel(model); CheckModel(model);
model.Status = OrderStatus.Принят; model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null) var order = _orderStorage.Insert(model);
if (order == null)
{ {
_logger.LogInformation("Create operation failed"); _logger.LogInformation("Create operation failed");
return false; return false;
} }
var clientView = _clientStorage.GetElement(new() { Id = order.ClientId });
SendMail(clientView, order);
return true; return true;
} }
@ -109,6 +119,10 @@ namespace CarRepairShopBusinessLogic.BusinessLogics
_logger.LogWarning("Update operation failed"); _logger.LogWarning("Update operation failed");
return false; return false;
} }
var clientView = _clientStorage.GetElement(new() { Id = element.ClientId });
SendMail(clientView, element);
return true; return true;
} }
@ -132,5 +146,35 @@ namespace CarRepairShopBusinessLogic.BusinessLogics
} }
_logger.LogInformation("Order. Id:{Id}. Sum:{Sum}. Count:{Count}", model.Id, model.Sum, model.Count); _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);
}
} }
} }

View File

@ -8,6 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.0.2" /> <PackageReference Include="DocumentFormat.OpenXml" Version="3.0.2" />
<PackageReference Include="MailKit" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="MigraDocCore.DocumentObjectModel" Version="1.3.63" /> <PackageReference Include="MigraDocCore.DocumentObjectModel" Version="1.3.63" />
<PackageReference Include="MigraDocCore.Rendering" Version="1.3.63" /> <PackageReference Include="MigraDocCore.Rendering" Version="1.3.63" />

View File

@ -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<AbstractMailWorker> 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<List<MessageInfoBindingModel>> ReceiveMailAsync();
}
}

View File

@ -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<MailKitWorker> 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<List<MessageInfoBindingModel>> ReceiveMailAsync()
{
var list = new List<MessageInfoBindingModel>();
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;
}
}
}

View File

@ -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; }
}
}

View File

@ -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;
}
}

View File

@ -36,7 +36,7 @@ namespace CarRepairShopDatabaseImplement.Implements
return null; return null;
} }
using var context = new CarRepairShopDatabase(); 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) public ClientViewModel? Insert(ClientBindingModel model)
{ {

View File

@ -35,7 +35,7 @@ namespace CarRepairShopFileImplement.Implements
public ClientViewModel? GetElement(ClientSearchModel model) public ClientViewModel? GetElement(ClientSearchModel model)
{ {
if (string.IsNullOrEmpty(model.Email) && !model.Id.HasValue) return null; 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) public ClientViewModel? Insert(ClientBindingModel model)

View File

@ -45,7 +45,7 @@ namespace CarRepairShopListImplement.Implements
if(string.IsNullOrEmpty(model.Email) && !model.Id.HasValue) return null; if(string.IsNullOrEmpty(model.Email) && !model.Id.HasValue) return null;
foreach (var client in _source.Clients) 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; return client.GetViewModel;
} }

View File

@ -1,4 +1,5 @@
using CarRepairShopBusinessLogic.BusinessLogics; using CarRepairShopBusinessLogic.BusinessLogics;
using CarRepairShopBusinessLogic.MailWorker;
using CarRepairShopContracts.BusinessLogicsContracts; using CarRepairShopContracts.BusinessLogicsContracts;
using CarRepairShopContracts.StoragesContracts; using CarRepairShopContracts.StoragesContracts;
using CarRepairShopDatabaseImplement.Implements; using CarRepairShopDatabaseImplement.Implements;
@ -14,9 +15,15 @@ builder.Logging.AddLog4Net("log4net.config");
builder.Services.AddTransient<IClientStorage, ClientStorage>(); builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>(); builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IRepairStorage, RepairStorage>(); builder.Services.AddTransient<IRepairStorage, RepairStorage>();
builder.Services.AddTransient<IComponentStorage, ComponentStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>(); builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>(); builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IRepairLogic, RepairLogic>(); builder.Services.AddTransient<IRepairLogic, RepairLogic>();
builder.Services.AddTransient<IComponentLogic, ComponentLogic>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
builder.Services.AddControllers(); builder.Services.AddControllers();

View File

@ -11,7 +11,7 @@
"SmtpClientPort": "587", "SmtpClientPort": "587",
"PopHost": "pop.gmail.com", "PopHost": "pop.gmail.com",
"PopPort": "995", "PopPort": "995",
"MailLogin": "labwork7@mail.com", "MailLogin": "shotboll16@gmail.com",
"MailPassword": "#eoxSyN1aJS1" "MailPassword": "iexy xqps iwrj ihle"
} }

View File

@ -5,7 +5,7 @@
<add key="SmtpClientPort" value="587" /> <add key="SmtpClientPort" value="587" />
<add key="PopHost" value="pop.gmail.com" /> <add key="PopHost" value="pop.gmail.com" />
<add key="PopPort" value="995" /> <add key="PopPort" value="995" />
<add key="MailLogin" value="labwork7@mail.com" /> <add key="MailLogin" value="shotboll16@gmail.com" />
<add key="MailPassword" value="#eoxSyN1aJS1" /> <add key="MailPassword" value="iexy xqps iwrj ihle" />
</appSettings> </appSettings>
</configuration> </configuration>

View File

@ -42,4 +42,10 @@
<ProjectReference Include="..\CarRepairShopListImplement\CarRepairShopListImplement.csproj" /> <ProjectReference Include="..\CarRepairShopListImplement\CarRepairShopListImplement.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Update="App.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project> </Project>

View File

@ -1,4 +1,5 @@
using CarRepairShopBusinessLogic.BusinessLogics; using CarRepairShopBusinessLogic.BusinessLogics;
using CarRepairShopBusinessLogic.MailWorker;
using CarRepairShopBusinessLogic.OfficePackage; using CarRepairShopBusinessLogic.OfficePackage;
using CarRepairShopBusinessLogic.OfficePackage.Implements; using CarRepairShopBusinessLogic.OfficePackage.Implements;
using CarRepairShopContracts.BusinessLogicsContracts; using CarRepairShopContracts.BusinessLogicsContracts;
@ -44,6 +45,7 @@ namespace CarRepairShopView
services.AddTransient<IRepairStorage, RepairStorage>(); services.AddTransient<IRepairStorage, RepairStorage>();
services.AddTransient<IClientStorage, ClientStorage>(); services.AddTransient<IClientStorage, ClientStorage>();
services.AddTransient<IImplementerStorage, ImplementerStorage>(); services.AddTransient<IImplementerStorage, ImplementerStorage>();
services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
services.AddTransient<IComponentLogic, ComponentLogic>(); services.AddTransient<IComponentLogic, ComponentLogic>();
services.AddTransient<IOrderLogic, OrderLogic>(); services.AddTransient<IOrderLogic, OrderLogic>();
@ -51,7 +53,10 @@ namespace CarRepairShopView
services.AddTransient<IReportLogic, ReportLogic>(); services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<IClientLogic, ClientLogic>(); services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<IImplementerLogic, ImplementerLogic>(); services.AddTransient<IImplementerLogic, ImplementerLogic>();
services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
services.AddTransient<IWorkProcess, WorkModeling>(); services.AddTransient<IWorkProcess, WorkModeling>();
services.AddSingleton<AbstractMailWorker, MailKitWorker>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>(); services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
services.AddTransient<AbstractSaveToWord, SaveToWord>(); services.AddTransient<AbstractSaveToWord, SaveToWord>();