LabWork07_Basic

This commit is contained in:
parent a1de87096f
commit 6354412e33
42 changed files with 2698 additions and 449 deletions

View File

@ -0,0 +1,65 @@
2024-04-22 01:54:32,867 INFO Microsoft.Hosting.Lifetime.? [?] - MESSAGE: Now listening on: https://localhost:7122
2024-04-22 01:54:32,897 INFO Microsoft.Hosting.Lifetime.? [?] - MESSAGE: Now listening on: http://localhost:5092
2024-04-22 01:54:32,904 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Application started. Press Ctrl+C to shut down.
2024-04-22 01:54:32,906 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Hosting environment: Development
2024-04-22 01:54:32,907 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Content root path: D:\ULSTU\Семестр 4\РПП\AircraftPlant\AircraftPlantRestApi\
2024-04-22 01:54:46,181 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [49] - MESSAGE: ReadList. ShopName:(null).Id:(null)
2024-04-22 01:54:48,412 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [58] - MESSAGE: ReadList. Count:2
2024-04-22 01:55:30,608 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [49] - MESSAGE: ReadList. ShopName:(null).Id:(null)
2024-04-22 01:55:30,634 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [58] - MESSAGE: ReadList. Count:2
2024-04-22 01:56:13,348 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.CheckModel [247] - MESSAGE: Shop. ShopName:Магазин 3.Address:Улица 3. Id:0
2024-04-22 01:56:13,576 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [49] - MESSAGE: ReadList. ShopName:(null).Id:(null)
2024-04-22 01:56:13,581 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [58] - MESSAGE: ReadList. Count:3
2024-04-22 01:56:21,121 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [49] - MESSAGE: ReadList. ShopName:(null).Id:(null)
2024-04-22 01:56:21,124 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [58] - MESSAGE: ReadList. Count:3
2024-04-22 01:56:21,142 INFO AircraftPlantBusinessLogic.BusinessLogics.PlaneLogic.ReadList [48] - MESSAGE: ReadList. PlaneName:(null).Id:(null)
2024-04-22 01:56:21,160 INFO AircraftPlantBusinessLogic.BusinessLogics.PlaneLogic.ReadList [57] - MESSAGE: ReadList. Count:2
2024-04-22 01:56:34,923 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.AddPlaneInShop [159] - MESSAGE: AddPlaneInShop. ShopName:(null).Id:6
2024-04-22 01:56:34,931 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.AddPlaneInShop [166] - MESSAGE: AddPlaneInShop find. Id:6
2024-04-22 01:56:34,935 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.AddPlaneInShop [183] - MESSAGE: AddPlaneInShop. Added 5 new plane to 'Магазин 3' shop
2024-04-22 01:56:34,989 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [49] - MESSAGE: ReadList. ShopName:(null).Id:(null)
2024-04-22 01:56:34,991 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [58] - MESSAGE: ReadList. Count:3
2024-04-22 01:56:45,267 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [49] - MESSAGE: ReadList. ShopName:(null).Id:(null)
2024-04-22 01:56:45,269 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [58] - MESSAGE: ReadList. Count:3
2024-04-22 01:56:45,301 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadElement [75] - MESSAGE: ReadElement. ShopName:(null).Id:4
2024-04-22 01:56:45,303 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadElement [84] - MESSAGE: ReadElement find. Id:4
2024-04-22 01:56:49,512 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadElement [75] - MESSAGE: ReadElement. ShopName:(null).Id:6
2024-04-22 01:56:49,515 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadElement [84] - MESSAGE: ReadElement find. Id:6
2024-04-22 10:34:20,669 INFO Microsoft.Hosting.Lifetime.? [?] - MESSAGE: Now listening on: https://localhost:7122
2024-04-22 10:34:20,716 INFO Microsoft.Hosting.Lifetime.? [?] - MESSAGE: Now listening on: http://localhost:5092
2024-04-22 10:34:20,721 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Application started. Press Ctrl+C to shut down.
2024-04-22 10:34:20,724 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Hosting environment: Development
2024-04-22 10:34:20,725 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Content root path: D:\ULSTU\Семестр 4\РПП\AircraftPlant\AircraftPlantRestApi\
2024-04-22 10:42:07,542 INFO Microsoft.Hosting.Lifetime.? [?] - MESSAGE: Now listening on: https://localhost:7122
2024-04-22 10:42:07,564 INFO Microsoft.Hosting.Lifetime.? [?] - MESSAGE: Now listening on: http://localhost:5092
2024-04-22 10:42:07,570 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Application started. Press Ctrl+C to shut down.
2024-04-22 10:42:07,572 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Hosting environment: Development
2024-04-22 10:42:07,573 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Content root path: D:\ULSTU\Семестр 4\РПП\AircraftPlant\AircraftPlantRestApi\
2024-04-22 10:42:26,255 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [49] - MESSAGE: ReadList. ShopName:(null).Id:(null)
2024-04-22 10:42:28,411 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [58] - MESSAGE: ReadList. Count:3
2024-04-22 10:43:50,297 INFO Microsoft.Hosting.Lifetime.? [?] - MESSAGE: Now listening on: https://localhost:7122
2024-04-22 10:43:50,324 INFO Microsoft.Hosting.Lifetime.? [?] - MESSAGE: Now listening on: http://localhost:5092
2024-04-22 10:43:50,329 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Application started. Press Ctrl+C to shut down.
2024-04-22 10:43:50,331 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Hosting environment: Development
2024-04-22 10:43:50,333 INFO Microsoft.Hosting.Lifetime.OnApplicationStarted [0] - MESSAGE: Content root path: D:\ULSTU\Семестр 4\РПП\AircraftPlant\AircraftPlantRestApi\
2024-04-22 10:48:54,048 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [49] - MESSAGE: ReadList. ShopName:(null).Id:(null)
2024-04-22 10:48:56,110 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [58] - MESSAGE: ReadList. Count:3
2024-04-22 10:49:15,718 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.CheckModel [247] - MESSAGE: Shop. ShopName:shop.Address:street. Id:0
2024-04-22 10:49:16,089 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [49] - MESSAGE: ReadList. ShopName:(null).Id:(null)
2024-04-22 10:49:16,094 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [58] - MESSAGE: ReadList. Count:4
2024-04-22 10:49:20,397 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [49] - MESSAGE: ReadList. ShopName:(null).Id:(null)
2024-04-22 10:49:20,400 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [58] - MESSAGE: ReadList. Count:4
2024-04-22 10:49:20,417 INFO AircraftPlantBusinessLogic.BusinessLogics.PlaneLogic.ReadList [48] - MESSAGE: ReadList. PlaneName:(null).Id:(null)
2024-04-22 10:49:20,446 INFO AircraftPlantBusinessLogic.BusinessLogics.PlaneLogic.ReadList [57] - MESSAGE: ReadList. Count:2
2024-04-22 10:49:26,177 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.AddPlaneInShop [159] - MESSAGE: AddPlaneInShop. ShopName:(null).Id:7
2024-04-22 10:49:26,189 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.AddPlaneInShop [166] - MESSAGE: AddPlaneInShop find. Id:7
2024-04-22 10:49:26,204 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.AddPlaneInShop [183] - MESSAGE: AddPlaneInShop. Added 3 new plane to 'shop' shop
2024-04-22 10:49:26,300 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [49] - MESSAGE: ReadList. ShopName:(null).Id:(null)
2024-04-22 10:49:26,303 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [58] - MESSAGE: ReadList. Count:4
2024-04-22 10:49:29,404 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [49] - MESSAGE: ReadList. ShopName:(null).Id:(null)
2024-04-22 10:49:29,407 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadList [58] - MESSAGE: ReadList. Count:4
2024-04-22 10:49:29,437 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadElement [75] - MESSAGE: ReadElement. ShopName:(null).Id:4
2024-04-22 10:49:29,440 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadElement [84] - MESSAGE: ReadElement find. Id:4
2024-04-22 10:49:31,043 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadElement [75] - MESSAGE: ReadElement. ShopName:(null).Id:7
2024-04-22 10:49:31,046 INFO AircraftPlantBusinessLogic.BusinessLogics.ShopLogic.ReadElement [84] - MESSAGE: ReadElement find. Id:7

View File

@ -8,6 +8,7 @@
<ItemGroup>
<PackageReference Include="DocumentFormat.OpenXml" Version="3.0.2" />
<PackageReference Include="MailKit" Version="4.5.0" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup>

View File

@ -8,6 +8,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace AircraftPlantBusinessLogic.BusinessLogics
@ -155,13 +156,13 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
{
throw new ArgumentNullException("Нет ФИО клиента", nameof(model.ClientFIO));
}
if (string.IsNullOrEmpty(model.Email))
if (string.IsNullOrEmpty(model.Email) || !Regex.IsMatch(model.Email, @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$", RegexOptions.IgnoreCase))
{
throw new ArgumentNullException("Нет почты клиента", nameof(model.Email));
throw new ArgumentNullException("Невалидная электронная почта клиента", nameof(model.Email));
}
if (string.IsNullOrEmpty(model.Password))
if (string.IsNullOrEmpty(model.Password) || !Regex.IsMatch(model.Password, @"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$"))
{
throw new ArgumentNullException("Нет пароля клиента", nameof(model.Password));
throw new ArgumentNullException("Слабый пароль", nameof(model.Password));
}
_logger.LogInformation("Client. ClientFIO: {ClientFIO}. Email: {Email}. Id: {Id}", model.ClientFIO, model.Email, model.Id);

View File

@ -0,0 +1,81 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.BusinessLogicsContracts;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.StoragesContracts;
using AircraftPlantContracts.ViewModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantBusinessLogic.BusinessLogics
{
/// <summary>
/// Реализация интерфейса бизнес-логики для писем
/// </summary>
public class MessageInfoLogic : IMessageInfoLogic
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Взаимодействие с хранилищем писем
/// </summary>
private readonly IMessageInfoStorage _messageStorage;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="messageStorage"></param>
public MessageInfoLogic(ILogger<MessageInfoLogic> logger, IMessageInfoStorage messageStorage)
{
_logger = logger;
_messageStorage = messageStorage;
}
/// <summary>
/// Получение списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model)
{
_logger.LogInformation("ReadList. MessageId: {MessageId}. ClientId: {ClientId}", model?.MessageId, model?.ClientId);
var list = model == null ? _messageStorage.GetFullList() : _messageStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count: {Count}", list.Count);
return list;
}
/// <summary>
/// Создание записи
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public bool Create(MessageInfoBindingModel model)
{
if (model == null)
{
return false;
}
if (_messageStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
}
}

View File

@ -1,9 +1,11 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantBusinessLogic.MailWorker;
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.BusinessLogicsContracts;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.StoragesContracts;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDataModels.Enums;
using AircraftPlantDataModels.Models;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
@ -28,16 +30,29 @@ namespace AircraftPlantBusinessLogic.BusinessLogics
/// </summary>
private readonly IOrderStorage _orderStorage;
/// <summary>
/// Взаимодействие с хранилищем клиентов
/// </summary>
private readonly IClientStorage _clientStorage;
/// <summary>
/// Конструктор
/// Бизнес-логика для отправки писем
/// </summary>
/// <param name="logger"></param>
/// <param name="orderStorage"></param>
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage
orderStorage)
private readonly AbstractMailWorker _mailLogic;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="orderStorage"></param>
/// <param name="clientStorage"></param>
/// <param name="mailLogic"></param>
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, IClientStorage clientStorage, AbstractMailWorker mailLogic)
{
_logger = logger;
_orderStorage = orderStorage;
_clientStorage = clientStorage;
_mailLogic = mailLogic;
}
/// <summary>
@ -101,11 +116,14 @@ orderStorage)
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null)
var order = _orderStorage.Insert(model);
if (order == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
SendEmail(order);
return true;
}
@ -203,12 +221,55 @@ orderStorage)
}
CheckModel(model, false);
if (_orderStorage.Update(model) == null)
var order = _orderStorage.Update(model);
if (order == null)
{
_logger.LogWarning("Change status operation failed");
return false;
}
SendEmail(order);
return true;
}
/// <summary>
/// Отправить письмо
/// </summary>
/// <param name="model"></param>
public void SendEmail(OrderViewModel order)
{
if (order == null)
{
return;
}
var client = _clientStorage.GetElement(new ClientSearchModel { Id = order.ClientId });
if (client == null)
{
return;
}
MailSendInfoBindingModel mailModel;
if (order.Status == OrderStatus.Принят)
{
mailModel = new MailSendInfoBindingModel
{
MailAddress = client.Email,
Subject = $"Order №{order.Id}",
Text = $"Your order №{order.Id} by {order.DateCreate} on {order.Sum} was accepted!"
};
}
else
{
mailModel = new MailSendInfoBindingModel
{
MailAddress = client.Email,
Subject = $"Order №{order.Id}",
Text = $"Order №{order.Id} status was changed to {order.Status}"
};
}
_mailLogic.MailSendAsync(mailModel);
}
}
}

View File

@ -0,0 +1,150 @@
using AircraftPlantBusinessLogic.BusinessLogics;
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantBusinessLogic.MailWorker
{
/// <summary>
/// Абстрактный класс для работы с письмами
/// </summary>
public abstract class AbstractMailWorker
{
private readonly ILogger _logger;
/// <summary>
/// Логин для доступа к почтовому сервису
/// </summary>
protected string _mailLogin = string.Empty;
/// <summary>
/// Пароль для доступа к почтовому сервису
/// </summary>
protected string _mailPassword = string.Empty;
/// <summary>
/// Хост SMTP-клиента
/// </summary>
protected string _smtpClientHost = string.Empty;
/// <summary>
/// Порт SMTP-клиента
/// </summary>
protected int _smtpClientPort;
/// <summary>
/// Хост протокола POP3
/// </summary>
protected string _popHost = string.Empty;
/// <summary>
/// Порт протокола POP3
/// </summary>
protected int _popPort;
private object _clientLogic;
/// <summary>
/// Бизнес-логика для писем
/// </summary>
private readonly IMessageInfoLogic _messageInfoLogic;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="messageInfoLogic"></param>
public AbstractMailWorker(ILogger<AbstractMailWorker> logger, IMessageInfoLogic messageInfoLogic)
{
_logger = logger;
_messageInfoLogic = messageInfoLogic;
}
/// <summary>
/// Настроить почтовый сервис
/// </summary>
/// <param name="config"></param>
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);
}
/// <summary>
/// Проверить и отправить письмо
/// </summary>
/// <param name="info"></param>
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);
}
/// <summary>
/// Проверить новые письма
/// </summary>
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);
}
}
/// <summary>
/// Отправить письмо
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
protected abstract Task SendMailAsync(MailSendInfoBindingModel info);
/// <summary>
/// Получить все письма
/// </summary>
/// <returns></returns>
protected abstract Task<List<MessageInfoBindingModel>> ReceiveMailAsync();
}
}

View File

@ -0,0 +1,103 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.BusinessLogicsContracts;
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;
using MailKit.Net.Pop3;
using MailKit.Security;
namespace AircraftPlantBusinessLogic.MailWorker
{
/// <summary>
/// Реализация абстрактного класса для работы с письмами
/// </summary>
public class MailKitWorker : AbstractMailWorker
{
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="messageInfoLogic"></param>
public MailKitWorker(ILogger<MailKitWorker> logger, IMessageInfoLogic messageInfoLogic) : base(logger, messageInfoLogic) { }
/// <summary>
/// Отправить письмо
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// Получить все письма
/// </summary>
/// <returns></returns>
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

@ -209,5 +209,20 @@ namespace AircraftPlantClientApp.Controllers
var prod = APIClient.GetRequest<PlaneViewModel>($"api/main/getplane?planeId={plane}");
return count * (prod?.Price ?? 1);
}
}
/// <summary>
/// Получение списка писем клиента
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult Mails()
{
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientId={APIClient.Client.Id}"));
}
}
}

View File

@ -0,0 +1,54 @@
@using AircraftPlantContracts.ViewModels
@model List<MessageInfoViewModel>
@{
ViewData["Title"] = "Mails";
}
<div class="text-center">
<h1 class="display-4">Письма</h1>
</div>
<div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<table class="table">
<thead>
<tr>
<th>
Дата письма
</th>
<th>
Заголовок
</th>
<th>
Текст
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.DateDelivery)
</td>
<td>
@Html.DisplayFor(modelItem => item.Subject)
</td>
<td>
@Html.DisplayFor(modelItem => item.Body)
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -27,6 +27,9 @@
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Mails">Письма</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.BindingModels
{
/// <summary>
/// Модель привязки для настройки почтового сервиса
/// </summary>
public class MailConfigBindingModel
{
/// <summary>
/// Логин для доступа к почтовому сервису
/// </summary>
public string MailLogin { get; set; } = string.Empty;
/// <summary>
/// Пароль для доступа к почтовому сервису
/// </summary>
public string MailPassword { get; set; } = string.Empty;
/// <summary>
/// Хост SMTP-клиента
/// </summary>
public string SmtpClientHost { get; set; } = string.Empty;
/// <summary>
/// Порт SMTP-клиента
/// </summary>
public int SmtpClientPort { get; set; }
/// <summary>
/// Хост протокола POP3
/// </summary>
public string PopHost { get; set; } = string.Empty;
/// <summary>
/// Порт протокола POP3
/// </summary>
public int PopPort { get; set; }
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.BindingModels
{
/// <summary>
/// Модель привязки для информации о письме для отправки
/// </summary>
public class MailSendInfoBindingModel
{
/// <summary>
/// Адрес электронной почты
/// </summary>
public string MailAddress { get; set; } = string.Empty;
/// <summary>
/// Заголовок письма
/// </summary>
public string Subject { get; set; } = string.Empty;
/// <summary>
/// Текст письма
/// </summary>
public string Text { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,46 @@
using AircraftPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.BindingModels
{
/// <summary>
/// Модель для передачи данных пользователя
/// в методы для сохранения данных для писем
/// </summary>
public class MessageInfoBindingModel : IMessageInfoModel
{
/// <summary>
/// Идентификатор
/// </summary>
public string MessageId { get; set; } = string.Empty;
/// <summary>
/// Идентификатор клиента
/// </summary>
public int? ClientId { get; set; }
/// <summary>
/// Адрес электронной почты отправителя
/// </summary>
public string SenderName { get; set; } = string.Empty;
/// <summary>
/// Дата получения письма
/// </summary>
public DateTime DateDelivery { get; set; }
/// <summary>
/// Заголовок письма
/// </summary>
public string Subject { get; set; } = string.Empty;
/// <summary>
/// Тело письма
/// </summary>
public string Body { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,31 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.BusinessLogicsContracts
{
/// <summary>
/// Интерфейс для описания работы бизнес-логики для писем
/// </summary>
public interface IMessageInfoLogic
{
/// <summary>
/// Получение списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model);
/// <summary>
/// Создание записи
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
bool Create(MessageInfoBindingModel model);
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.SearchModels
{
/// <summary>
/// Модель для передачи данных пользователя
/// в методы для поиска данных для писем
/// </summary>
public class MessageInfoSearchModel
{
/// <summary>
/// Идентификатор
/// </summary>
public string? MessageId { get; set; }
/// <summary>
/// Идентификатор клиента
/// </summary>
public int? ClientId { get; set; }
}
}

View File

@ -0,0 +1,44 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.StoragesContracts
{
/// <summary>
/// Интерфейс для описания работы с хранилищем для писем
/// </summary>
public interface IMessageInfoStorage
{
/// <summary>
/// Получение полного списка
/// </summary>
/// <returns></returns>
List<MessageInfoViewModel> GetFullList();
/// <summary>
/// Получение фильтрованного списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model);
/// <summary>
/// Получение элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
MessageInfoViewModel? GetElement(MessageInfoSearchModel model);
/// <summary>
/// Добавление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
MessageInfoViewModel? Insert(MessageInfoBindingModel model);
}
}

View File

@ -0,0 +1,51 @@
using AircraftPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantContracts.ViewModels
{
/// <summary>
/// Модель для передачи данных пользователю
/// для отображения для писем
/// </summary>
public class MessageInfoViewModel : IMessageInfoModel
{
/// <summary>
/// Идентификатор
/// </summary>
public string MessageId { get; set; } = string.Empty;
/// <summary>
/// Идентификатор клиента
/// </summary>
public int? ClientId { get; set; }
/// <summary>
/// Адрес электронной почты отправителя
/// </summary>
[DisplayName("Отправитель")]
public string SenderName { get; set; } = string.Empty;
/// <summary>
/// Дата получения письма
/// </summary>
[DisplayName("Дата письма")]
public DateTime DateDelivery { get; set; }
/// <summary>
/// Заголовок письма
/// </summary>
[DisplayName("Заголовок")]
public string Subject { get; set; } = string.Empty;
/// <summary>
/// Тело письма
/// </summary>
[DisplayName("Текст")]
public string Body { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantDataModels.Models
{
/// <summary>
/// Интерфейс для модели письма
/// </summary>
public interface IMessageInfoModel
{
/// <summary>
/// Идентификатор
/// </summary>
string MessageId { get; }
/// <summary>
/// Идентификатор клиента
/// </summary>
int? ClientId { get; }
/// <summary>
/// Адрес электронной почты отправителя
/// </summary>
string SenderName { get; }
/// <summary>
/// Дата получения письма
/// </summary>
DateTime DateDelivery { get; }
/// <summary>
/// Заголовок письма
/// </summary>
string Subject { get; }
/// <summary>
/// Тело письма
/// </summary>
string Body { get; }
}
}

View File

@ -55,5 +55,10 @@ namespace AircraftPlantDatabaseImplement
/// Таблица исполнителей
/// </summary>
public virtual DbSet<Implementer> Implementers { set; get; }
}
/// <summary>
/// Таблица писем
/// </summary>
public virtual DbSet<Message> Messages { set; get; }
}
}

View File

@ -0,0 +1,87 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.StoragesContracts;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDatabaseImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantDatabaseImplement.Implements
{
/// <summary>
/// Реализация интерфейса хранилища для писем
/// </summary>
public class MessageInfoStorage : IMessageInfoStorage
{
/// <summary>
/// Получение полного списка
/// </summary>
/// <returns></returns>
public List<MessageInfoViewModel> GetFullList()
{
using var context = new AircraftPlantDatabase();
return context.Messages
.Select(x => x.GetViewModel)
.ToList();
}
/// <summary>
/// Получение фильтрованного списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
if (!model.ClientId.HasValue)
{
return new();
}
using var context = new AircraftPlantDatabase();
return context.Messages
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
/// <summary>
/// Получение элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId))
{
return null;
}
using var context = new AircraftPlantDatabase();
return context.Messages
.FirstOrDefault(x => x.MessageId == model.MessageId)
?.GetViewModel;
}
/// <summary>
/// Добавление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessage = Message.Create(model);
if (newMessage == null)
{
return null;
}
using var context = new AircraftPlantDatabase();
context.Messages.Add(newMessage);
context.SaveChanges();
return newMessage.GetViewModel;
}
}
}

View File

@ -0,0 +1,298 @@
// <auto-generated />
using System;
using AircraftPlantDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace AircraftPlantDatabaseImplement.Migrations
{
[DbContext(typeof(AircraftPlantDatabase))]
[Migration("20240504174710_MessageInfoCreate")]
partial class MessageInfoCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Client", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClientFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Clients");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Component", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ComponentName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Cost")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Components");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Implementer", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ImplementerFIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Qualification")
.HasColumnType("int");
b.Property<int>("WorkExperience")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("Implementers");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Message", b =>
{
b.Property<string>("MessageId")
.HasColumnType("nvarchar(450)");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("ClientId")
.HasColumnType("int");
b.Property<DateTime>("DateDelivery")
.HasColumnType("datetime2");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.ToTable("Messages");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ClientId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<DateTime>("DateCreate")
.HasColumnType("datetime2");
b.Property<DateTime?>("DateImplement")
.HasColumnType("datetime2");
b.Property<int?>("ImplementerId")
.HasColumnType("int");
b.Property<int>("PlaneId")
.HasColumnType("int");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.HasIndex("PlaneId");
b.ToTable("Orders");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Plane", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("PlaneName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Planes");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.PlaneComponent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ComponentId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("PlaneId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("PlaneId");
b.ToTable("PlaneComponents");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Message", b =>
{
b.HasOne("AircraftPlantDatabaseImplement.Models.Client", "Client")
.WithMany("Messages")
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Order", b =>
{
b.HasOne("AircraftPlantDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AircraftPlantDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.HasOne("AircraftPlantDatabaseImplement.Models.Plane", "Plane")
.WithMany("Orders")
.HasForeignKey("PlaneId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Plane");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.PlaneComponent", b =>
{
b.HasOne("AircraftPlantDatabaseImplement.Models.Component", "Component")
.WithMany("PlaneComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AircraftPlantDatabaseImplement.Models.Plane", "Plane")
.WithMany("Components")
.HasForeignKey("PlaneId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Plane");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Client", b =>
{
b.Navigation("Messages");
b.Navigation("Orders");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Component", b =>
{
b.Navigation("PlaneComponents");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Plane", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,48 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AircraftPlantDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class MessageInfoCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Messages",
columns: table => new
{
MessageId = table.Column<string>(type: "nvarchar(450)", nullable: false),
ClientId = table.Column<int>(type: "int", nullable: true),
SenderName = table.Column<string>(type: "nvarchar(max)", nullable: false),
DateDelivery = table.Column<DateTime>(type: "datetime2", nullable: false),
Subject = table.Column<string>(type: "nvarchar(max)", nullable: false),
Body = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Messages", x => x.MessageId);
table.ForeignKey(
name: "FK_Messages_Clients_ClientId",
column: x => x.ClientId,
principalTable: "Clients",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_Messages_ClientId",
table: "Messages",
column: "ClientId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Messages");
}
}
}

View File

@ -94,6 +94,36 @@ namespace AircraftPlantDatabaseImplement.Migrations
b.ToTable("Implementers");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Message", b =>
{
b.Property<string>("MessageId")
.HasColumnType("nvarchar(450)");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int?>("ClientId")
.HasColumnType("int");
b.Property<DateTime>("DateDelivery")
.HasColumnType("datetime2");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.ToTable("Messages");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
@ -183,6 +213,15 @@ namespace AircraftPlantDatabaseImplement.Migrations
b.ToTable("PlaneComponents");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Message", b =>
{
b.HasOne("AircraftPlantDatabaseImplement.Models.Client", "Client")
.WithMany("Messages")
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Order", b =>
{
b.HasOne("AircraftPlantDatabaseImplement.Models.Client", "Client")
@ -229,6 +268,8 @@ namespace AircraftPlantDatabaseImplement.Migrations
modelBuilder.Entity("AircraftPlantDatabaseImplement.Models.Client", b =>
{
b.Navigation("Messages");
b.Navigation("Orders");
});

View File

@ -45,12 +45,18 @@ namespace AircraftPlantDatabaseImplement.Models
[ForeignKey("ClientId")]
public virtual List<Order> Orders { get; set; } = new();
/// <summary>
/// Создание модели клиента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public static Client? Create(ClientBindingModel model)
/// <summary>
/// Связь с письмами
/// </summary>
[ForeignKey("ClientId")]
public virtual List<Message> Messages { get; set; } = new();
/// <summary>
/// Создание модели клиента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public static Client? Create(ClientBindingModel model)
{
if (model == null)
{

View File

@ -0,0 +1,94 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantDatabaseImplement.Models
{
/// <summary>
/// Сущность "Письмо"
/// </summary>
public class Message : IMessageInfoModel
{
/// <summary>
/// Идентификатор
/// </summary>
[Key]
public string MessageId { get; set; } = string.Empty;
/// <summary>
/// Идентификатор клиента
/// </summary>
public int? ClientId { get; set; }
/// <summary>
/// Сущность "Клиент"
/// </summary>
public virtual Client? Client { get; set; }
/// <summary>
/// Адрес электронной почты отправителя
/// </summary>
[Required]
public string SenderName { get; set; } = string.Empty;
/// <summary>
/// Дата получения письма
/// </summary>
[Required]
public DateTime DateDelivery { get; set; }
/// <summary>
/// Заголовок письма
/// </summary>
[Required]
public string Subject { get; set; } = string.Empty;
/// <summary>
/// Тело письма
/// </summary>
[Required]
public string Body { get; set; } = string.Empty;
/// <summary>
/// Создание модели письма
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public static Message? Create(MessageInfoBindingModel model)
{
if (model == null)
{
return null;
}
return new()
{
MessageId = model.MessageId,
ClientId = model.ClientId,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
Subject = model.Subject,
Body = model.Body,
};
}
/// <summary>
/// Получение модели письма
/// </summary>
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
DateDelivery = DateDelivery,
Subject = Subject,
Body = Body
};
}
}

View File

@ -43,10 +43,15 @@ namespace AircraftPlantFileImplement
/// </summary>
private readonly string ImplementerFileName = "Implementer.xml";
/// <summary>
/// Список классов-моделей компонентов
/// </summary>
public List<Component> Components { get; set; }
/// <summary>
/// Название файла для хранения информации о письмах
/// </summary>
private readonly string MessageFileName = "Message.xml";
/// <summary>
/// Список классов-моделей компонентов
/// </summary>
public List<Component> Components { get; set; }
/// <summary>
/// Список классов-моделей заказов
@ -68,16 +73,22 @@ namespace AircraftPlantFileImplement
/// </summary>
public List<Implementer> Implementers { get; set; }
/// <summary>
/// Конструктор
/// </summary>
private DataFileSingleton()
/// <summary>
/// Список классов-моделей писем
/// </summary>
public List<Message> Messages { get; set; }
/// <summary>
/// Конструктор
/// </summary>
private DataFileSingleton()
{
Components = LoadData(ComponentFileName, "Component", x => Component.Create(x)!)!;
Planes = LoadData(PlaneFileName, "Plane", x => Plane.Create(x)!)!;
Orders = LoadData(OrderFileName, "Order", x => Order.Create(x)!)!;
Clients = LoadData(ClientFileName, "Client", x => Client.Create(x)!)!;
Implementers = LoadData(ImplementerFileName, "Implementer", x => Implementer.Create(x)!)!;
Messages = LoadData(MessageFileName, "Message", x => Message.Create(x)!)!;
}
/// <summary>
@ -118,15 +129,20 @@ namespace AircraftPlantFileImplement
/// </summary>
public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement);
/// <summary>
/// Метод для загрузки данных из xml-файла
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="filename"></param>
/// <param name="xmlNodeName"></param>
/// <param name="selectFunction"></param>
/// <returns></returns>
private static List<T>? LoadData<T>(string filename, string xmlNodeName, Func<XElement, T> selectFunction)
/// <summary>
/// Сохранение писем
/// </summary>
public void SaveMessages() => SaveData(Messages, MessageFileName, "Messages", x => x.GetXElement);
/// <summary>
/// Метод для загрузки данных из xml-файла
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="filename"></param>
/// <param name="xmlNodeName"></param>
/// <param name="selectFunction"></param>
/// <returns></returns>
private static List<T>? LoadData<T>(string filename, string xmlNodeName, Func<XElement, T> selectFunction)
{
if (File.Exists(filename))
{

View File

@ -0,0 +1,95 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.ViewModels;
using AircraftPlantFileImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantFileImplement.Implements
{
/// <summary>
/// Реализация интерфейса хранилища для писем
/// </summary>
public class MessageInfoStorage
{
/// <summary>
/// Хранилище
/// </summary>
private readonly DataFileSingleton _source;
/// <summary>
/// Конструктор
/// </summary>
public MessageInfoStorage()
{
_source = DataFileSingleton.GetInstance();
}
/// <summary>
/// Получение полного списка
/// </summary>
/// <returns></returns>
public List<MessageInfoViewModel> GetFullList()
{
return _source.Messages
.Select(x => x.GetViewModel)
.ToList();
}
/// <summary>
/// Получение фильтрованного списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
if (!model.ClientId.HasValue)
{
return new();
}
return _source.Messages
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
/// <summary>
/// Получение элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId))
{
return null;
}
return _source.Messages
.FirstOrDefault(x => x.MessageId == model.MessageId)
?.GetViewModel;
}
/// <summary>
/// Добавление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessage = Message.Create(model);
if (newMessage == null)
{
return null;
}
_source.Messages.Add(newMessage);
_source.SaveMessages();
return newMessage.GetViewModel;
}
}
}

View File

@ -0,0 +1,118 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace AircraftPlantFileImplement.Models
{
/// <summary>
/// Сущность "Письмо"
/// </summary>
public class Message : IMessageInfoModel
{
/// <summary>
/// Идентификатор
/// </summary>
public string MessageId { get; set; } = string.Empty;
/// <summary>
/// Идентификатор клиента
/// </summary>
public int? ClientId { get; set; }
/// <summary>
/// Адрес электронной почты отправителя
/// </summary>
public string SenderName { get; set; } = string.Empty;
/// <summary>
/// Дата получения письма
/// </summary>
public DateTime DateDelivery { get; set; }
/// <summary>
/// Заголовок письма
/// </summary>
public string Subject { get; set; } = string.Empty;
/// <summary>
/// Тело письма
/// </summary>
public string Body { get; set; } = string.Empty;
/// <summary>
/// Создание модели письма
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public static Message? Create(MessageInfoBindingModel model)
{
if (model == null)
{
return null;
}
return new()
{
MessageId = model.MessageId,
ClientId = model.ClientId,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
Subject = model.Subject,
Body = model.Body,
};
}
/// <summary>
/// Создание модели письма из данных файла
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
public static Message? Create(XElement element)
{
if (element == null)
{
return null;
}
return new()
{
MessageId = element.Attribute("MessageId")!.Value,
ClientId = Convert.ToInt32(element.Attribute("ClientId")!.Value),
SenderName = element.Attribute("SenderName")!.Value,
DateDelivery = Convert.ToDateTime(element.Attribute("DateDelivery")!.Value),
Subject = element.Attribute("Subject")!.Value,
Body = element.Attribute("Body")!.Value
};
}
/// <summary>
/// Получение модели письма
/// </summary>
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
DateDelivery = DateDelivery,
Subject = Subject,
Body = Body
};
/// <summary>
/// Запись данных о модели письма в файл
/// </summary>
public XElement GetXElement => new("MessageInfo",
new XAttribute("MessageId", MessageId),
new XAttribute("ClientId", ClientId),
new XAttribute("SenderName", SenderName),
new XAttribute("DateDelivery", DateDelivery),
new XAttribute("Subject", Subject),
new XAttribute("Body", Body));
}
}

View File

@ -42,16 +42,22 @@ namespace AircraftPlantListImplement
/// </summary>
public List<Implementer> Implementers { get; set; }
/// <summary>
/// Конструктор
/// </summary>
private DataListSingleton()
/// <summary>
/// Список классов-моделей писем
/// </summary>
public List<Message> Messages { get; set; }
/// <summary>
/// Конструктор
/// </summary>
private DataListSingleton()
{
Components = new List<Component>();
Orders = new List<Order>();
Planes = new List<Plane>();
Clients = new List<Client>();
Implementers = new List<Implementer>();
Messages = new List<Message>();
}
/// <summary>

View File

@ -0,0 +1,107 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.SearchModels;
using AircraftPlantContracts.StoragesContracts;
using AircraftPlantContracts.ViewModels;
using AircraftPlantListImplement.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantListImplement.Implements
{
/// <summary>
/// Реализация интерфейса хранилища для писем
/// </summary>
public class MessageInfoStorage : IMessageInfoStorage
{
/// <summary>
/// Хранилище
/// </summary>
private readonly DataListSingleton _source;
/// <summary>
/// Конструктор
/// </summary>
public MessageInfoStorage()
{
_source = DataListSingleton.GetInstance();
}
/// <summary>
/// Получение полного списка
/// </summary>
/// <returns></returns>
public List<MessageInfoViewModel> GetFullList()
{
var result = new List<MessageInfoViewModel>();
foreach (var message in _source.Messages)
{
result.Add(message.GetViewModel);
}
return result;
}
/// <summary>
/// Получение фильтрованного списка
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
var result = new List<MessageInfoViewModel>();
if (!model.ClientId.HasValue)
{
return new();
}
foreach (var message in _source.Messages)
{
if (message.ClientId == model.ClientId)
{
result.Add(message.GetViewModel);
}
}
return result;
}
/// <summary>
/// Получение элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public MessageInfoViewModel? GetElement(MessageInfoSearchModel model)
{
if (string.IsNullOrEmpty(model.MessageId))
{
return null;
}
foreach (var message in _source.Messages)
{
if (model.MessageId.Equals(message.MessageId))
return message.GetViewModel;
}
return null;
}
/// <summary>
/// Добавление элемента
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{
var newMessage = Message.Create(model);
if (newMessage == null)
{
return null;
}
_source.Messages.Add(newMessage);
return newMessage.GetViewModel;
}
}
}

View File

@ -0,0 +1,83 @@
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.ViewModels;
using AircraftPlantDataModels.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AircraftPlantListImplement.Models
{
/// <summary>
/// Сущность "Письмо"
/// </summary>
public class Message : IMessageInfoModel
{
/// <summary>
/// Идентификатор
/// </summary>
public string MessageId { get; set; } = string.Empty;
/// <summary>
/// Идентификатор клиента
/// </summary>
public int? ClientId { get; set; }
/// <summary>
/// Адрес электронной почты отправителя
/// </summary>
public string SenderName { get; set; } = string.Empty;
/// <summary>
/// Дата получения письма
/// </summary>
public DateTime DateDelivery { get; set; }
/// <summary>
/// Заголовок письма
/// </summary>
public string Subject { get; set; } = string.Empty;
/// <summary>
/// Тело письма
/// </summary>
public string Body { get; set; } = string.Empty;
/// <summary>
/// Создание модели письма
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public static Message? Create(MessageInfoBindingModel model)
{
if (model == null)
{
return null;
}
return new()
{
MessageId = model.MessageId,
ClientId = model.ClientId,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
Subject = model.Subject,
Body = model.Body,
};
}
/// <summary>
/// Получение модели письма
/// </summary>
public MessageInfoViewModel GetViewModel => new()
{
MessageId = MessageId,
ClientId = ClientId,
SenderName = SenderName,
DateDelivery = DateDelivery,
Subject = Subject,
Body = Body
};
}
}

View File

@ -23,15 +23,22 @@ namespace AircraftPlantRestApi.Controllers
/// </summary>
private readonly IClientLogic _logic;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logic"></param>
/// <param name="logger"></param>
public ClientController(IClientLogic logic, ILogger<ClientController> logger)
/// <summary>
/// Бизнес-логика для писем
/// </summary>
private readonly IMessageInfoLogic _mailLogic;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logic"></param>
/// <param name="logger"></param>
/// <param name="mailLogic"></param>
public ClientController(IClientLogic logic, ILogger<ClientController> logger, IMessageInfoLogic mailLogic)
{
_logger = logger;
_logic = logic;
_mailLogic = mailLogic;
}
/// <summary>
@ -93,5 +100,27 @@ namespace AircraftPlantRestApi.Controllers
throw;
}
}
}
/// <summary>
/// Получение списка писем клиента
/// </summary>
/// <param name="clientId"></param>
/// <returns></returns>
[HttpGet]
public List<MessageInfoViewModel>? GetMessages(int clientId)
{
try
{
return _mailLogic.ReadList(new MessageInfoSearchModel
{
ClientId = clientId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения писем клиента");
throw;
}
}
}
}

View File

@ -1,4 +1,6 @@
using AircraftPlantBusinessLogic.BusinessLogics;
using AircraftPlantBusinessLogic.MailWorker;
using AircraftPlantContracts.BindingModels;
using AircraftPlantContracts.BusinessLogicsContracts;
using AircraftPlantContracts.StoragesContracts;
using AircraftPlantDatabaseImplement.Implements;
@ -14,11 +16,15 @@ builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IPlaneStorage, PlaneStorage>();
builder.Services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IPlaneLogic, PlaneLogic>();
builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
@ -30,6 +36,18 @@ builder.Services.AddSwaggerGen(c =>
var app = builder.Build();
// Íàñòðîéêà äëÿ îòïðàâêè ïèñåì
var mailSender = app.Services.GetService<AbstractMailWorker>();
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())
{

View File

@ -5,5 +5,12 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"SmtpClientHost": "smtp.gmail.com",
"SmtpClientPort": "587",
"PopHost": "pop.gmail.com",
"PopPort": "995",
"MailLogin": "aircraftplant73@gmail.com",
"MailPassword": "vcus klnn auqe axlq"
}

View File

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

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="SmtpClientHost" value="smtp.gmail.com" />
<add key="SmtpClientPort" value="587" />
<add key="PopHost" value="pop.gmail.com" />
<add key="PopPort" value="995" />
<add key="MailLogin" value="aircraftplant73@gmail.com" />
<add key="MailPassword" value="vcus klnn auqe axlq" />
</appSettings>
</configuration>

View File

@ -0,0 +1,70 @@
namespace AircraftPlantView
{
partial class FormMail
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
dataGridView = new DataGridView();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Fill;
dataGridView.GridColor = Color.Black;
dataGridView.Location = new Point(0, 0);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowTemplate.Height = 25;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(584, 361);
dataGridView.TabIndex = 2;
//
// FormMail
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(584, 361);
Controls.Add(dataGridView);
Name = "FormMail";
Text = "Письма";
Load += FormMail_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
}
}

View File

@ -0,0 +1,77 @@
using AircraftPlantContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AircraftPlantView
{
/// <summary>
/// Форма для вывода писем
/// </summary>
public partial class FormMail : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика для писем
/// </summary>
private readonly IMessageInfoLogic _logic;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="logic"></param>
public FormMail(ILogger<FormMail> logger, IMessageInfoLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
/// <summary>
/// Загрузка писем
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormMail_Load(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Метод загрузки писем
/// </summary>
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["MessageId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка писем");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки писем");
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -20,184 +20,192 @@
base.Dispose(disposing);
}
#region Windows Form Designer generated code
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
dataGridView = new DataGridView();
buttonCreateOrder = new Button();
buttonIssuedOrder = new Button();
buttonRefresh = new Button();
menuStrip = new MenuStrip();
справочникиToolStripMenuItem = new ToolStripMenuItem();
компонентыToolStripMenuItem = new ToolStripMenuItem();
изделияToolStripMenuItem = new ToolStripMenuItem();
клиентыToolStripMenuItem = new ToolStripMenuItem();
отчетыToolStripMenuItem = new ToolStripMenuItem();
изделияToolStripMenuItem1 = new ToolStripMenuItem();
изделияСКомпонентамиToolStripMenuItem = new ToolStripMenuItem();
списокЗаказовToolStripMenuItem = new ToolStripMenuItem();
запускРаботToolStripMenuItem = new ToolStripMenuItem();
исполнителиToolStripMenuItem = new ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
menuStrip.SuspendLayout();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.GridColor = Color.White;
dataGridView.Location = new Point(0, 24);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowTemplate.Height = 25;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(800, 337);
dataGridView.TabIndex = 0;
//
// buttonCreateOrder
//
buttonCreateOrder.Location = new Point(822, 36);
buttonCreateOrder.Name = "buttonCreateOrder";
buttonCreateOrder.Size = new Size(150, 23);
buttonCreateOrder.TabIndex = 1;
buttonCreateOrder.Text = "Создать заказ";
buttonCreateOrder.UseVisualStyleBackColor = true;
buttonCreateOrder.Click += buttonCreateOrder_Click;
//
// buttonIssuedOrder
//
buttonIssuedOrder.Location = new Point(822, 65);
buttonIssuedOrder.Name = "buttonIssuedOrder";
buttonIssuedOrder.Size = new Size(150, 23);
buttonIssuedOrder.TabIndex = 4;
buttonIssuedOrder.Text = "Заказ выдан";
buttonIssuedOrder.UseVisualStyleBackColor = true;
buttonIssuedOrder.Click += buttonIssuedOrder_Click;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(822, 94);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(150, 23);
buttonRefresh.TabIndex = 5;
buttonRefresh.Text = "Обновить список";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += buttonRefresh_Click;
//
// menuStrip
//
menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчетыToolStripMenuItem, запускРаботToolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(984, 24);
menuStrip.TabIndex = 6;
menuStrip.Text = "menuStrip1";
//
// справочникиToolStripMenuItem
//
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, изделияToolStripMenuItem, клиентыToolStripMenuItem, исполнителиToolStripMenuItem });
справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem";
справочникиToolStripMenuItem.Size = new Size(94, 20);
справочникиToolStripMenuItem.Text = "Справочники";
//
// компонентыToolStripMenuItem
//
компонентыToolStripMenuItem.Name = омпонентыToolStripMenuItem";
компонентыToolStripMenuItem.Size = new Size(180, 22);
компонентыToolStripMenuItem.Text = "Компоненты";
компонентыToolStripMenuItem.Click += компонентыToolStripMenuItem_Click;
//
// изделияToolStripMenuItem
//
изделияToolStripMenuItem.Name = "изделияToolStripMenuItem";
изделияToolStripMenuItem.Size = new Size(180, 22);
изделияToolStripMenuItem.Text = "Изделия";
изделияToolStripMenuItem.Click += изделияToolStripMenuItem_Click;
//
// клиентыToolStripMenuItem
//
клиентыToolStripMenuItem.Name = "клиентыToolStripMenuItem";
клиентыToolStripMenuItem.Size = new Size(180, 22);
клиентыToolStripMenuItem.Text = "Клиенты";
клиентыToolStripMenuItem.Click += клиентыToolStripMenuItem_Click;
//
// отчетыToolStripMenuItem
//
отчетыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { изделияToolStripMenuItem1, изделияСКомпонентамиToolStripMenuItem, списокЗаказовToolStripMenuItem });
отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem";
отчетыToolStripMenuItem.Size = new Size(60, 20);
отчетыToolStripMenuItem.Text = "Отчеты";
//
// изделияToolStripMenuItem1
//
изделияToolStripMenuItem1.Name = "изделияToolStripMenuItem1";
изделияToolStripMenuItem1.Size = new Size(215, 22);
изделияToolStripMenuItem1.Text = "Изделия";
изделияToolStripMenuItem1.Click += изделияToolStripMenuItem1_Click;
//
// изделияСКомпонентамиToolStripMenuItem
//
изделияСКомпонентамиToolStripMenuItem.Name = "изделияСКомпонентамиToolStripMenuItem";
изделияСКомпонентамиToolStripMenuItem.Size = new Size(215, 22);
изделияСКомпонентамиToolStripMenuItem.Text = "Изделия с компонентами";
изделияСКомпонентамиToolStripMenuItem.Click += изделияСКомпонентамиToolStripMenuItem_Click;
//
// списокЗаказовToolStripMenuItem
//
списокЗаказовToolStripMenuItem.Name = "списокЗаказовToolStripMenuItem";
списокЗаказовToolStripMenuItem.Size = new Size(215, 22);
списокЗаказовToolStripMenuItem.Text = "Список заказов";
списокЗаказовToolStripMenuItem.Click += списокЗаказовToolStripMenuItem_Click;
//
// запускРаботToolStripMenuItem
//
запускРаботToolStripMenuItem.Name = апускРаботToolStripMenuItem";
запускРаботToolStripMenuItem.Size = new Size(92, 20);
запускРаботToolStripMenuItem.Text = "Запуск работ";
запускРаботToolStripMenuItem.Click += запускРаботToolStripMenuItem_Click;
//
// исполнителиToolStripMenuItem
//
исполнителиToolStripMenuItem.Name = сполнителиToolStripMenuItem";
исполнителиToolStripMenuItem.Size = new Size(180, 22);
исполнителиToolStripMenuItem.Text = "Исполнители";
исполнителиToolStripMenuItem.Click += исполнителиToolStripMenuItem_Click;
//
// FormMain
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(984, 361);
Controls.Add(buttonRefresh);
Controls.Add(buttonIssuedOrder);
Controls.Add(buttonCreateOrder);
Controls.Add(dataGridView);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;
Name = "FormMain";
Text = "Авиационный завод";
Load += FormMain_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
dataGridView = new DataGridView();
buttonCreateOrder = new Button();
buttonIssuedOrder = new Button();
buttonRefresh = new Button();
menuStrip = new MenuStrip();
справочникиToolStripMenuItem = new ToolStripMenuItem();
компонентыToolStripMenuItem = new ToolStripMenuItem();
изделияToolStripMenuItem = new ToolStripMenuItem();
клиентыToolStripMenuItem = new ToolStripMenuItem();
исполнителиToolStripMenuItem = new ToolStripMenuItem();
отчетыToolStripMenuItem = new ToolStripMenuItem();
изделияToolStripMenuItem1 = new ToolStripMenuItem();
изделияСКомпонентамиToolStripMenuItem = new ToolStripMenuItem();
списокЗаказовToolStripMenuItem = new ToolStripMenuItem();
запускРаботToolStripMenuItem = new ToolStripMenuItem();
почтаToolStripMenuItem = new ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
menuStrip.SuspendLayout();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Left;
dataGridView.GridColor = Color.White;
dataGridView.Location = new Point(0, 24);
dataGridView.MultiSelect = false;
dataGridView.Name = "dataGridView";
dataGridView.ReadOnly = true;
dataGridView.RowHeadersVisible = false;
dataGridView.RowTemplate.Height = 25;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(800, 337);
dataGridView.TabIndex = 0;
//
// buttonCreateOrder
//
buttonCreateOrder.Location = new Point(822, 36);
buttonCreateOrder.Name = "buttonCreateOrder";
buttonCreateOrder.Size = new Size(150, 23);
buttonCreateOrder.TabIndex = 1;
buttonCreateOrder.Text = "Создать заказ";
buttonCreateOrder.UseVisualStyleBackColor = true;
buttonCreateOrder.Click += buttonCreateOrder_Click;
//
// buttonIssuedOrder
//
buttonIssuedOrder.Location = new Point(822, 65);
buttonIssuedOrder.Name = "buttonIssuedOrder";
buttonIssuedOrder.Size = new Size(150, 23);
buttonIssuedOrder.TabIndex = 4;
buttonIssuedOrder.Text = "Заказ выдан";
buttonIssuedOrder.UseVisualStyleBackColor = true;
buttonIssuedOrder.Click += buttonIssuedOrder_Click;
//
// buttonRefresh
//
buttonRefresh.Location = new Point(822, 94);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(150, 23);
buttonRefresh.TabIndex = 5;
buttonRefresh.Text = "Обновить список";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += buttonRefresh_Click;
//
// menuStrip
//
menuStrip.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem, отчетыToolStripMenuItem, запускРаботToolStripMenuItem, почтаToolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(984, 24);
menuStrip.TabIndex = 6;
menuStrip.Text = "menuStrip1";
//
// справочникиToolStripMenuItem
//
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { компонентыToolStripMenuItem, изделияToolStripMenuItem, клиентыToolStripMenuItem, исполнителиToolStripMenuItem });
справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem";
справочникиToolStripMenuItem.Size = new Size(94, 20);
справочникиToolStripMenuItem.Text = "Справочники";
//
// компонентыToolStripMenuItem
//
компонентыToolStripMenuItem.Name = омпонентыToolStripMenuItem";
компонентыToolStripMenuItem.Size = new Size(149, 22);
компонентыToolStripMenuItem.Text = "Компоненты";
компонентыToolStripMenuItem.Click += компонентыToolStripMenuItem_Click;
//
// изделияToolStripMenuItem
//
изделияToolStripMenuItem.Name = "изделияToolStripMenuItem";
изделияToolStripMenuItem.Size = new Size(149, 22);
изделияToolStripMenuItem.Text = "Изделия";
изделияToolStripMenuItem.Click += изделияToolStripMenuItem_Click;
//
// клиентыToolStripMenuItem
//
клиентыToolStripMenuItem.Name = "клиентыToolStripMenuItem";
клиентыToolStripMenuItem.Size = new Size(149, 22);
клиентыToolStripMenuItem.Text = "Клиенты";
клиентыToolStripMenuItem.Click += клиентыToolStripMenuItem_Click;
//
// исполнителиToolStripMenuItem
//
исполнителиToolStripMenuItem.Name = сполнителиToolStripMenuItem";
исполнителиToolStripMenuItem.Size = new Size(149, 22);
исполнителиToolStripMenuItem.Text = "Исполнители";
исполнителиToolStripMenuItem.Click += исполнителиToolStripMenuItem_Click;
//
// отчетыToolStripMenuItem
//
отчетыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { изделияToolStripMenuItem1, изделияСКомпонентамиToolStripMenuItem, списокЗаказовToolStripMenuItem });
отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem";
отчетыToolStripMenuItem.Size = new Size(60, 20);
отчетыToolStripMenuItem.Text = "Отчеты";
//
// изделияToolStripMenuItem1
//
изделияToolStripMenuItem1.Name = "изделияToolStripMenuItem1";
изделияToolStripMenuItem1.Size = new Size(215, 22);
изделияToolStripMenuItem1.Text = "Изделия";
изделияToolStripMenuItem1.Click += изделияToolStripMenuItem1_Click;
//
// изделияСКомпонентамиToolStripMenuItem
//
изделияСКомпонентамиToolStripMenuItem.Name = "изделияСКомпонентамиToolStripMenuItem";
изделияСКомпонентамиToolStripMenuItem.Size = new Size(215, 22);
изделияСКомпонентамиToolStripMenuItem.Text = "Изделия с компонентами";
изделияСКомпонентамиToolStripMenuItem.Click += изделияСКомпонентамиToolStripMenuItem_Click;
//
// списокЗаказовToolStripMenuItem
//
списокЗаказовToolStripMenuItem.Name = "списокЗаказовToolStripMenuItem";
списокЗаказовToolStripMenuItem.Size = new Size(215, 22);
списокЗаказовToolStripMenuItem.Text = "Список заказов";
списокЗаказовToolStripMenuItem.Click += списокЗаказовToolStripMenuItem_Click;
//
// запускРаботToolStripMenuItem
//
запускРаботToolStripMenuItem.Name = апускРаботToolStripMenuItem";
запускРаботToolStripMenuItem.Size = new Size(92, 20);
запускРаботToolStripMenuItem.Text = "Запуск работ";
запускРаботToolStripMenuItem.Click += запускРаботToolStripMenuItem_Click;
//
// почтаToolStripMenuItem
//
почтаToolStripMenuItem.Name = "почтаToolStripMenuItem";
почтаToolStripMenuItem.Size = new Size(53, 20);
почтаToolStripMenuItem.Text = "Почта";
почтаToolStripMenuItem.Click += почтаToolStripMenuItem_Click;
//
// FormMain
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(984, 361);
Controls.Add(buttonRefresh);
Controls.Add(buttonIssuedOrder);
Controls.Add(buttonCreateOrder);
Controls.Add(dataGridView);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;
Name = "FormMain";
Text = "Авиационный завод";
Load += FormMain_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
#endregion
private DataGridView dataGridView;
private DataGridView dataGridView;
private Button buttonCreateOrder;
private Button buttonIssuedOrder;
private Button buttonRefresh;
@ -212,5 +220,6 @@
private ToolStripMenuItem клиентыToolStripMenuItem;
private ToolStripMenuItem запускРаботToolStripMenuItem;
private ToolStripMenuItem исполнителиToolStripMenuItem;
}
private ToolStripMenuItem почтаToolStripMenuItem;
}
}

View File

@ -14,244 +14,258 @@ using System.Windows.Forms;
namespace AircraftPlantView
{
/// <summary>
/// Главная форма
/// </summary>
public partial class FormMain : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Главная форма
/// </summary>
public partial class FormMain : Form
{
/// <summary>
/// Логгер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Бизнес-логика для заказов
/// </summary>
private readonly IOrderLogic _orderLogic;
/// <summary>
/// Бизнес-логика для заказов
/// </summary>
private readonly IOrderLogic _orderLogic;
/// <summary>
/// Взаимодействие с отчетами
/// </summary>
private readonly IReportLogic _reportLogic;
/// <summary>
/// Взаимодействие с отчетами
/// </summary>
private readonly IReportLogic _reportLogic;
/// <summary>
/// Имитация деятельности исполнителей
/// </summary>
private readonly IWorkProcess _workProcess;
/// <summary>
/// Имитация деятельности исполнителей
/// </summary>
private readonly IWorkProcess _workProcess;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="logic"></param>
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
_workProcess = workProcess;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="logger"></param>
/// <param name="logic"></param>
public FormMain(ILogger<FormMain> logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess)
{
InitializeComponent();
_logger = logger;
_orderLogic = orderLogic;
_reportLogic = reportLogic;
_workProcess = workProcess;
}
/// <summary>
/// Загрузка списка заказов
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Загрузка списка заказов
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormMain_Load(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Показать список всех компонентов
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void компонентыToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormComponents));
if (service is FormComponents form)
{
form.ShowDialog();
}
}
/// <summary>
/// Показать список всех компонентов
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void компонентыToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormComponents));
if (service is FormComponents form)
{
form.ShowDialog();
}
}
/// <summary>
/// Показать список всех изделий
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void изделияToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormPlanes));
if (service is FormPlanes form)
{
form.ShowDialog();
}
}
/// <summary>
/// Показать список всех изделий
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void изделияToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormPlanes));
if (service is FormPlanes form)
{
form.ShowDialog();
}
}
/// <summary>
/// Вывести список всех клиентов
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void клиентыToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormClients));
if (service is FormClients form)
{
form.ShowDialog();
}
}
/// <summary>
/// Вывести список всех клиентов
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void клиентыToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormClients));
if (service is FormClients form)
{
form.ShowDialog();
}
}
/// <summary>
/// Вывести список всех исполнителей
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void исполнителиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementers));
if (service is FormImplementers form)
{
form.ShowDialog();
}
}
/// <summary>
/// Вывести список всех исполнителей
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void исполнителиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormImplementers));
if (service is FormImplementers form)
{
form.ShowDialog();
}
}
/// <summary>
/// Вывести отчет по изделиям
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void изделияToolStripMenuItem1_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK)
{
_reportLogic.SavePlanesToWordFile(new ReportBindingModel { FileName = dialog.FileName });
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
/// <summary>
/// Вывести отчет по изделиям
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void изделияToolStripMenuItem1_Click(object sender, EventArgs e)
{
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK)
{
_reportLogic.SavePlanesToWordFile(new ReportBindingModel { FileName = dialog.FileName });
MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
/// <summary>
/// Получить отчет по изделиям с расшифровкой по компонентам
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void изделияСКомпонентамиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportPlaneComponents));
if (service is FormReportPlaneComponents form)
{
form.ShowDialog();
}
}
/// <summary>
/// Получить отчет по изделиям с расшифровкой по компонентам
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void изделияСКомпонентамиToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportPlaneComponents));
if (service is FormReportPlaneComponents form)
{
form.ShowDialog();
}
}
/// <summary>
/// Получить отчет по заказам
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void списокЗаказовToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form)
{
form.ShowDialog();
}
}
/// <summary>
/// Получить отчет по заказам
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void списокЗаказовToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form)
{
form.ShowDialog();
}
}
/// <summary>
/// Запуск имитации работы исполнителей
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void запускРаботToolStripMenuItem_Click(object sender, EventArgs e)
{
_workProcess.DoWork((
Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!,
_orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
/// <summary>
/// Запуск имитации работы исполнителей
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void запускРаботToolStripMenuItem_Click(object sender, EventArgs e)
{
_workProcess.DoWork((
Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!,
_orderLogic);
MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
/// <summary>
/// Кнопка "Создать заказ"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCreateOrder_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
if (service is FormCreateOrder form)
{
form.ShowDialog();
LoadData();
}
}
/// <summary>
/// Посмотреть письма
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void почтаToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormMail));
if (service is FormMail form)
{
form.ShowDialog();
}
}
/// <summary>
/// Кнопка "Заказ выдан"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonIssuedOrder_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("Ошибка при сохранении. Дополнительная информация в логах.");
}
_logger.LogInformation("Заказ №{id} выдан", id);
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о выдаче заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
/// <summary>
/// Кнопка "Создать заказ"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonCreateOrder_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder));
if (service is FormCreateOrder form)
{
form.ShowDialog();
LoadData();
}
}
/// <summary>
/// Кнопка "Обновить список"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonRefresh_Click(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Кнопка "Заказ выдан"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonIssuedOrder_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("Ошибка при сохранении. Дополнительная информация в логах.");
}
_logger.LogInformation("Заказ №{id} выдан", id);
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка отметки о выдаче заказа");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
/// <summary>
/// Метод загрузки списка заказов
/// </summary>
private void LoadData()
{
_logger.LogInformation("Загрузка заказов");
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["PlaneId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["ImplementerId"].Visible = false;
}
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
/// <summary>
/// Кнопка "Обновить список"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonRefresh_Click(object sender, EventArgs e)
{
LoadData();
}
/// <summary>
/// Метод загрузки списка заказов
/// </summary>
private void LoadData()
{
_logger.LogInformation("Загрузка заказов");
try
{
var list = _orderLogic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["PlaneId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["ImplementerId"].Visible = false;
}
_logger.LogInformation("Загрузка заказов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки заказов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -8,6 +8,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using System;
using AircraftPlantBusinessLogic.MailWorker;
using AircraftPlantContracts.BindingModels;
namespace AircraftPlantView
{
@ -33,7 +35,30 @@ namespace AircraftPlantView
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
// Íàñòðîéêà äëÿ îòïðàâêè ïèñåì
try
{
var mailSender = _serviceProvider.GetService<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel
{
MailLogin = System.Configuration.ConfigurationManager.AppSettings["MailLogin"] ?? string.Empty,
MailPassword = System.Configuration.ConfigurationManager.AppSettings["MailPassword"] ?? string.Empty,
SmtpClientHost = System.Configuration.ConfigurationManager.AppSettings["SmtpClientHost"] ?? string.Empty,
SmtpClientPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["SmtpClientPort"]),
PopHost = System.Configuration.ConfigurationManager.AppSettings["PopHost"] ?? string.Empty,
PopPort = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["PopPort"])
});
// ñîçäàåì òàéìåð
var timer = new System.Threading.Timer(new TimerCallback(MailCheck!), null, 0, 60000);
}
catch (Exception ex)
{
var logger = _serviceProvider.GetService<ILogger>();
logger?.LogError(ex, "Îøèáêà ðàáîòû ñ ïî÷òîé");
}
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
}
/// <summary>
@ -53,6 +78,7 @@ namespace AircraftPlantView
services.AddTransient<IComponentStorage, ComponentStorage>();
services.AddTransient<IOrderStorage, OrderStorage>();
services.AddTransient<IPlaneStorage, PlaneStorage>();
services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
services.AddTransient<IClientLogic, ClientLogic>();
services.AddTransient<IImplementerLogic, ImplementerLogic>();
@ -60,7 +86,10 @@ namespace AircraftPlantView
services.AddTransient<IOrderLogic, OrderLogic>();
services.AddTransient<IPlaneLogic, PlaneLogic>();
services.AddTransient<IReportLogic, ReportLogic>();
services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
services.AddTransient<IWorkProcess, WorkModeling>();
services.AddSingleton<AbstractMailWorker, MailKitWorker>();
services.AddTransient<AbstractSaveToWord, SaveToWord>();
services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
@ -78,6 +107,13 @@ namespace AircraftPlantView
services.AddTransient<FormPlanes>();
services.AddTransient<FormReportPlaneComponents>();
services.AddTransient<FormReportOrders>();
services.AddTransient<FormMail>();
}
/// <summary>
/// Ïðîâåðêà ïî÷òû
/// </summary>
/// <param name="obj"></param>
private static void MailCheck(object obj) => ServiceProvider?.GetService<AbstractMailWorker>()?.MailCheck();
}
}