промежуточный коммит

This commit is contained in:
AnnZhimol 2023-05-03 20:50:36 +04:00
parent bcde0abd61
commit 4194be7346
26 changed files with 729 additions and 410 deletions

View File

@ -15,5 +15,7 @@ namespace SofrwareInstallationContracts.BindingModels
public string Subject { get; set; } = string.Empty; public string Subject { get; set; } = string.Empty;
public string Body { get; set; } = string.Empty; public string Body { get; set; } = string.Empty;
public DateTime DateDelivery { get; set; } public DateTime DateDelivery { get; set; }
public bool HasRead { get; set; }
public string? Reply { get; set; }
} }
} }

View File

@ -9,5 +9,9 @@ namespace SofrwareInstallationContracts.BusinessLogicsContracts
List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model); List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model);
bool Create(MessageInfoBindingModel model); bool Create(MessageInfoBindingModel model);
bool Update(MessageInfoBindingModel model);
MessageInfoViewModel? ReadElement(MessageInfoSearchModel model);
} }
} }

View File

@ -4,5 +4,7 @@
{ {
public int? ClientId { get; set; } public int? ClientId { get; set; }
public string? MessageId { get; set; } public string? MessageId { get; set; }
public int? Page { get; set; }
public int? PageSize { get; set; }
} }
} }

View File

@ -13,5 +13,7 @@ namespace SofrwareInstallationContracts.StoragesContracts
MessageInfoViewModel? GetElement(MessageInfoSearchModel model); MessageInfoViewModel? GetElement(MessageInfoSearchModel model);
MessageInfoViewModel? Insert(MessageInfoBindingModel model); MessageInfoViewModel? Insert(MessageInfoBindingModel model);
MessageInfoViewModel? Update(MessageInfoBindingModel model);
} }
} }

View File

@ -20,5 +20,11 @@ namespace SofrwareInstallationContracts.ViewModels
[DisplayName("Содержание")] [DisplayName("Содержание")]
public string Body { get; set; } = string.Empty; public string Body { get; set; } = string.Empty;
[DisplayName("Прочитано")]
public bool HasRead { get; set; }
[DisplayName("Ответ")]
public string? Reply { get; set; }
} }
} }

View File

@ -29,34 +29,74 @@
private void InitializeComponent() private void InitializeComponent()
{ {
this.DataGridView = new System.Windows.Forms.DataGridView(); this.DataGridView = new System.Windows.Forms.DataGridView();
this.PrevPageButton = new System.Windows.Forms.Button();
this.NextPageButton = new System.Windows.Forms.Button();
this.labelInfoPages = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.DataGridView)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.DataGridView)).BeginInit();
this.SuspendLayout(); this.SuspendLayout();
// //
// DataGridView // DataGridView
// //
this.DataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.DataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.DataGridView.Location = new System.Drawing.Point(3, 3); this.DataGridView.Location = new System.Drawing.Point(57, 3);
this.DataGridView.Name = "DataGridView"; this.DataGridView.Name = "DataGridView";
this.DataGridView.RowTemplate.Height = 25; this.DataGridView.RowTemplate.Height = 25;
this.DataGridView.Size = new System.Drawing.Size(794, 445); this.DataGridView.Size = new System.Drawing.Size(687, 411);
this.DataGridView.TabIndex = 0; this.DataGridView.TabIndex = 0;
this.DataGridView.RowHeaderMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.DataGridView_RowHeaderMouseClick);
//
// PrevPageButton
//
this.PrevPageButton.Location = new System.Drawing.Point(12, 158);
this.PrevPageButton.Name = "PrevPageButton";
this.PrevPageButton.Size = new System.Drawing.Size(38, 69);
this.PrevPageButton.TabIndex = 1;
this.PrevPageButton.Text = "<=";
this.PrevPageButton.UseVisualStyleBackColor = true;
this.PrevPageButton.Click += new System.EventHandler(this.PrevPageButton_Click);
//
// NextPageButton
//
this.NextPageButton.Location = new System.Drawing.Point(750, 159);
this.NextPageButton.Name = "NextPageButton";
this.NextPageButton.Size = new System.Drawing.Size(38, 68);
this.NextPageButton.TabIndex = 2;
this.NextPageButton.Text = "=>";
this.NextPageButton.UseVisualStyleBackColor = true;
this.NextPageButton.Click += new System.EventHandler(this.NextPageButton_Click);
//
// labelInfoPages
//
this.labelInfoPages.AutoSize = true;
this.labelInfoPages.Location = new System.Drawing.Point(387, 426);
this.labelInfoPages.Name = "labelInfoPages";
this.labelInfoPages.Size = new System.Drawing.Size(75, 15);
this.labelInfoPages.TabIndex = 3;
this.labelInfoPages.Text = "{0} страница";
// //
// FormMails // FormMails
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450); this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.labelInfoPages);
this.Controls.Add(this.NextPageButton);
this.Controls.Add(this.PrevPageButton);
this.Controls.Add(this.DataGridView); this.Controls.Add(this.DataGridView);
this.Name = "FormMails"; this.Name = "FormMails";
this.Text = "Эл. письма"; this.Text = "Эл. письма";
this.Load += new System.EventHandler(this.FormMails_Load); this.Load += new System.EventHandler(this.FormMails_Load);
((System.ComponentModel.ISupportInitialize)(this.DataGridView)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.DataGridView)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout();
} }
#endregion #endregion
private DataGridView DataGridView; private DataGridView DataGridView;
private Button PrevPageButton;
private Button NextPageButton;
private Label labelInfoPages;
} }
} }

View File

@ -1,6 +1,7 @@
using SofrwareInstallationContracts.BusinessLogicsContracts; using SofrwareInstallationContracts.BusinessLogicsContracts;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Windows.Forms; using System.Windows.Forms;
using SofrwareInstallationContracts.ViewModels;
namespace SoftwareInstallationView namespace SoftwareInstallationView
{ {
@ -8,20 +9,27 @@ namespace SoftwareInstallationView
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IMessageInfoLogic _logic; private readonly IMessageInfoLogic _logic;
private int currentPage = 1;
public int pageSize = 5;
public FormMails(ILogger<FormMails> logger, IMessageInfoLogic logic) public FormMails(ILogger<FormMails> logger, IMessageInfoLogic logic)
{ {
InitializeComponent(); InitializeComponent();
_logger = logger; _logger = logger;
_logic = logic; _logic = logic;
PrevPageButton.Enabled = false;
LoadData(); LoadData();
} }
private void LoadData() private bool LoadData()
{ {
try try
{ {
var list = _logic.ReadList(null); var list = _logic.ReadList(new()
{
Page = currentPage,
PageSize = pageSize,
});
if (list != null) if (list != null)
{ {
DataGridView.DataSource = list; DataGridView.DataSource = list;
@ -30,12 +38,15 @@ namespace SoftwareInstallationView
DataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; DataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
} }
_logger.LogInformation("Загрузка писем"); _logger.LogInformation("Загрузка писем");
labelInfoPages.Text = $"{currentPage} страница";
return true;
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка загрузки писем"); _logger.LogError(ex, "Ошибка загрузки писем");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error); MessageBoxIcon.Error);
return false;
} }
} }
@ -43,5 +54,50 @@ namespace SoftwareInstallationView
{ {
LoadData(); LoadData();
} }
private void PrevPageButton_Click(object sender, EventArgs e)
{
if (currentPage == 1)
{
_logger.LogWarning("Неккоректный номер страницы {page}", currentPage - 1);
return;
}
currentPage--;
if (LoadData())
{
NextPageButton.Enabled = true;
if (currentPage == 1)
{
PrevPageButton.Enabled = false;
}
}
}
private void NextPageButton_Click(object sender, EventArgs e)
{
currentPage++;
if (!LoadData() || ((List<MessageInfoViewModel>)DataGridView.DataSource).Count == 0)
{
_logger.LogWarning("Out of range messages");
currentPage--;
LoadData();
NextPageButton.Enabled = false;
}
else
{
PrevPageButton.Enabled = true;
}
}
private void DataGridView_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormReplyMail));
if (service is FormReplyMail form)
{
form.MessageId = (string)DataGridView.Rows[e.RowIndex].Cells["MessageId"].Value;
form.ShowDialog();
LoadData();
}
}
} }
} }

View File

@ -0,0 +1,145 @@
namespace SoftwareInstallationView
{
partial class FormReplyMail
{
/// <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()
{
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.HeadTextBox = new System.Windows.Forms.TextBox();
this.MailTextBox = new System.Windows.Forms.TextBox();
this.ReplyTextBox = new System.Windows.Forms.TextBox();
this.ReplyButton = new System.Windows.Forms.Button();
this.ButtonCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(4, 19);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(40, 15);
this.label1.TabIndex = 0;
this.label1.Text = "Тема: ";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(4, 48);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(82, 15);
this.label2.TabIndex = 1;
this.label2.Text = "Содержание: ";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(4, 178);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(44, 15);
this.label3.TabIndex = 2;
this.label3.Text = "Ответ: ";
//
// HeadTextBox
//
this.HeadTextBox.Location = new System.Drawing.Point(92, 16);
this.HeadTextBox.Name = "HeadTextBox";
this.HeadTextBox.ReadOnly = true;
this.HeadTextBox.Size = new System.Drawing.Size(469, 23);
this.HeadTextBox.TabIndex = 5;
//
// MailTextBox
//
this.MailTextBox.Location = new System.Drawing.Point(92, 45);
this.MailTextBox.Multiline = true;
this.MailTextBox.Name = "MailTextBox";
this.MailTextBox.ReadOnly = true;
this.MailTextBox.Size = new System.Drawing.Size(469, 93);
this.MailTextBox.TabIndex = 6;
//
// ReplyTextBox
//
this.ReplyTextBox.Location = new System.Drawing.Point(92, 175);
this.ReplyTextBox.Multiline = true;
this.ReplyTextBox.Name = "ReplyTextBox";
this.ReplyTextBox.Size = new System.Drawing.Size(469, 125);
this.ReplyTextBox.TabIndex = 7;
//
// ReplyButton
//
this.ReplyButton.Location = new System.Drawing.Point(351, 306);
this.ReplyButton.Name = "ReplyButton";
this.ReplyButton.Size = new System.Drawing.Size(102, 36);
this.ReplyButton.TabIndex = 6;
this.ReplyButton.Text = "Ответить";
this.ReplyButton.UseVisualStyleBackColor = true;
this.ReplyButton.Click += new System.EventHandler(this.ReplyButton_Click);
//
// ButtonCancel
//
this.ButtonCancel.Location = new System.Drawing.Point(459, 306);
this.ButtonCancel.Name = "ButtonCancel";
this.ButtonCancel.Size = new System.Drawing.Size(102, 36);
this.ButtonCancel.TabIndex = 7;
this.ButtonCancel.Text = "Отмена";
this.ButtonCancel.UseVisualStyleBackColor = true;
this.ButtonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
//
// FormReplyMail
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(573, 354);
this.Controls.Add(this.ButtonCancel);
this.Controls.Add(this.ReplyButton);
this.Controls.Add(this.ReplyTextBox);
this.Controls.Add(this.MailTextBox);
this.Controls.Add(this.HeadTextBox);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Name = "FormReplyMail";
this.Text = "Ответ";
this.Load += new System.EventHandler(this.FormReplyMail_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Label label1;
private Label label2;
private Label label3;
private TextBox HeadTextBox;
private TextBox MailTextBox;
private TextBox ReplyTextBox;
private Button ReplyButton;
private Button ButtonCancel;
}
}

View File

@ -0,0 +1,86 @@
using Microsoft.Extensions.Logging;
using SofrwareInstallationContracts.BusinessLogicsContracts;
using SofrwareInstallationContracts.ViewModels;
using SoftwareInstallationBusinessLogic.MailWorker;
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 SoftwareInstallationView
{
public partial class FormReplyMail : Form
{
private readonly ILogger _logger;
private readonly AbstractMailWorker _mailWorker;
private readonly IMessageInfoLogic _logic;
private MessageInfoViewModel _message;
public string MessageId { get; set; } = string.Empty;
public FormReplyMail(ILogger<FormReplyMail> logger, AbstractMailWorker mailWorker, IMessageInfoLogic logic)
{
InitializeComponent();
_logger = logger;
_mailWorker = mailWorker;
_logic = logic;
}
private void ReplyButton_Click(object sender, EventArgs e)
{
_mailWorker.MailSendAsync(new()
{
MailAddress = _message.SenderName,
Subject = _message.Subject,
Text = ReplyTextBox.Text,
});
_logic.Update(new()
{
MessageId = MessageId,
Reply = ReplyTextBox.Text,
HasRead = true,
});
MessageBox.Show("Успешно отправлено письмо", "Отправка письма", MessageBoxButtons.OK);
DialogResult = DialogResult.OK;
Close();
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void FormReplyMail_Load(object sender, EventArgs e)
{
try
{
_message = _logic.ReadElement(new() { MessageId = MessageId });
if (_message == null)
throw new ArgumentNullException("Письма с таким id не существует");
Text += $"для {_message.SenderName}";
HeadTextBox.Text = _message.Subject;
MailTextBox.Text = _message.Body;
if (_message.HasRead is false)
{
_logic.Update(new() { MessageId = MessageId, HasRead = true, Reply = _message.Reply });
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения собщения");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}

View File

@ -0,0 +1,60 @@
<root>
<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

@ -91,6 +91,7 @@ namespace SoftwareInstallationView
services.AddTransient<FormImplementer>(); services.AddTransient<FormImplementer>();
services.AddTransient<FormImplementers>(); services.AddTransient<FormImplementers>();
services.AddTransient<FormMails>(); services.AddTransient<FormMails>();
services.AddTransient<FormReplyMail>();
services.AddTransient<FormReportStorePackages>(); services.AddTransient<FormReportStorePackages>();
services.AddTransient<FormStores>(); services.AddTransient<FormStores>();
services.AddTransient<FormStore>(); services.AddTransient<FormStore>();

View File

@ -46,5 +46,31 @@ namespace SoftwareInstallationBusinessLogic.BusinessLogic
return list; return list;
} }
public MessageInfoViewModel? ReadElement(MessageInfoSearchModel model)
{
var res = _messageStorage.GetElement(model);
if (res == null)
{
_logger.LogWarning("Read element operation failed");
return null;
}
return res;
}
public bool Update(MessageInfoBindingModel model)
{
if (_messageStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
} }
} }

View File

@ -18,8 +18,7 @@ namespace SoftwareInstallationBusinessLogic.BusinessLogic
private readonly IStoreLogic _storeLogic; private readonly IStoreLogic _storeLogic;
private readonly IPackageStorage _packageStorage; private readonly IPackageStorage _packageStorage;
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, AbstractMailWorker mailWorker, IClientLogic clientLogic) public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, IPackageStorage packageStorage,IStoreLogic storeLogic, AbstractMailWorker mailWorker, IClientLogic clientLogic)
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage, IPackageStorage packageStorage,IStoreLogic storeLogic)
{ {
_logger = logger; _logger = logger;
_orderStorage = orderStorage; _orderStorage = orderStorage;
@ -100,6 +99,9 @@ namespace SoftwareInstallationBusinessLogic.BusinessLogic
_logger.LogWarning("Update operation failed"); _logger.LogWarning("Update operation failed");
return false; return false;
} }
SendOrderMessage(result.ClientId, $"Изменен статус заказа #{result.Id}", $"Заказ #{model.Id} изменен статус на {result.Status}");
return true; return true;
} }
@ -182,5 +184,24 @@ namespace SoftwareInstallationBusinessLogic.BusinessLogic
return element; return element;
} }
private bool SendOrderMessage(int clientId, string subject, string text)
{
var client = _clientLogic.ReadElement(new() { Id = clientId });
if (client == null)
{
return false;
}
_mailWorker.MailSendAsync(new()
{
MailAddress = client.Email,
Subject = subject,
Text = text
});
return true;
}
} }
} }

View File

@ -8,7 +8,7 @@ namespace SoftwareInstallationClientApp
public class APIClient public class APIClient
{ {
private static readonly HttpClient _client = new(); private static readonly HttpClient _client = new();
public static int CurrentPage { get; set; } = 0;
public static ClientViewModel? Client { get; set; } = null; public static ClientViewModel? Client { get; set; } = null;
public static void Connect(IConfiguration configuration) public static void Connect(IConfiguration configuration)

View File

@ -3,6 +3,9 @@ using SoftwareInstallationClientApp.Models;
using SofrwareInstallationContracts.BindingModels; using SofrwareInstallationContracts.BindingModels;
using SofrwareInstallationContracts.ViewModels; using SofrwareInstallationContracts.ViewModels;
using System.Diagnostics; using System.Diagnostics;
using System.Text;
using SofrwareInstallationContracts.SearchModels;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace SoftwareInstallationClientApp.Controllers namespace SoftwareInstallationClientApp.Controllers
{ {
@ -151,7 +154,45 @@ namespace SoftwareInstallationClientApp.Controllers
{ {
return Redirect("~/Home/Enter"); return Redirect("~/Home/Enter");
} }
return View(APIClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientId={APIClient.Client.Id}")); return View();
}
[HttpGet]
public Tuple<string?, string?, bool, bool>? SwitchPage(bool isNext)
{
if (isNext)
{
APIClient.CurrentPage++;
}
else
{
if (APIClient.CurrentPage == 1)
{
return null;
}
APIClient.CurrentPage--;
}
var res = APIClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientId={APIClient.Client!.Id}&page={APIClient.CurrentPage}");
if (isNext && (res == null || res.Count == 0))
{
APIClient.CurrentPage--;
return Tuple.Create<string?, string?, bool, bool>(null, null, APIClient.CurrentPage != 1, false);
}
StringBuilder htmlTable = new();
foreach (var mail in res)
{
htmlTable.Append("<tr>" +
$"<td>{mail.DateDelivery}</td>" +
$"<td>{mail.Subject}</td>" +
$"<td>{mail.Body}</td>" +
"<td>" + (mail.HasRead ? "Прочитано" : "Непрочитано") + "</td>" +
$"<td>{mail.Reply}</td>" +
"</tr>");
}
return Tuple.Create<string?, string?, bool, bool>(htmlTable.ToString(), APIClient.CurrentPage.ToString(), APIClient.CurrentPage != 1, true);
} }
} }
} }

View File

@ -1,24 +1,11 @@
@using SofrwareInstallationContracts.ViewModels @{
@model List<MessageInfoViewModel>
@{
ViewData["Title"] = "Mails"; ViewData["Title"] = "Mails";
} }
<div class="text-center"> <div class="text-center">
<h1 class="display-4">Письма</h1> <h1 class="display-4">Письма</h1>
</div> </div>
<div class="text-center"> <div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
@ -31,24 +18,62 @@
<th> <th>
Содержание Содержание
</th> </th>
<th>
Статус
</th>
<th>
Ответ
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody id="mails-table-body">
@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> </tbody>
</table> </table>
} <ul class="pagination justify-content-center">
<li id="prev-page" class="page-item">
<a class="page-link" href="#" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
<span class="sr-only">Предыдущее</span>
</a>
</li>
<li class="page-item">
<a id="current-page" class="page-link"></a>
</li>
<li id="next-page" class="page-item">
<a class="page-link" href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
<span class="sr-only">Следующее</span>
</a>
</li>
</ul>
</div> </div>
<script>
function onClicked(isNext) {
$.ajax({
method: "GET",
url: "/Home/SwitchPage",
data: { isNext: isNext },
success: function (result) {
if (result != null) {
if (result.item1 != null && result.item2 != null) {
$("#mails-table-body").html(result.item1);
$("#current-page").text(result.item2);
}
if (result.item3)
$("#prev-page").removeClass("page-item disabled");
else
$("#prev-page").addClass("page-item disabled");
if (result.item4)
$("#next-page").removeClass("page-item disabled");
else
$("#next-page").addClass("page-item disabled");
}
}
});
}
onClicked(true);
$("#prev-page").on('click', () => onClicked(false));
$("#next-page").on('click', () => onClicked(true));
</script>

View File

@ -18,13 +18,18 @@ namespace SoftwareInstallationDataBaseImplement.Implements
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model) public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{ {
if (!model.ClientId.HasValue)
return new();
using var context = new SoftwareInstallationDataBase(); using var context = new SoftwareInstallationDataBase();
return context.Messages
.Where(x => x.ClientId == model.ClientId) var res = context.Messages
.Select(x => x.GetViewModel) .Where(x => !model.ClientId.HasValue || x.ClientId == model.ClientId)
.ToList(); .Select(x => x.GetViewModel);
if (!(model.Page.HasValue && model.PageSize.HasValue))
{
return res.ToList();
}
return res.Skip((model.Page.Value - 1) * model.PageSize.Value).Take(model.PageSize.Value).ToList();
} }
public List<MessageInfoViewModel> GetFullList() public List<MessageInfoViewModel> GetFullList()
@ -37,15 +42,31 @@ namespace SoftwareInstallationDataBaseImplement.Implements
public MessageInfoViewModel? Insert(MessageInfoBindingModel model) public MessageInfoViewModel? Insert(MessageInfoBindingModel model)
{ {
using var context = new SoftwareInstallationDataBase();
var newMessage = Message.Create(model); var newMessage = Message.Create(model);
if (newMessage == null)
if (newMessage == null || context.Messages.Any(x => x.MessageId.Equals(model.MessageId)))
{ {
return null; return null;
} }
using var context = new SoftwareInstallationDataBase();
context.Messages.Add(newMessage); context.Messages.Add(newMessage);
context.SaveChanges(); context.SaveChanges();
return newMessage.GetViewModel; return newMessage.GetViewModel;
} }
public MessageInfoViewModel? Update(MessageInfoBindingModel model)
{
using var context = new SoftwareInstallationDataBase();
var res = context.Messages.FirstOrDefault(x => x.MessageId.Equals(model.MessageId));
if (res != null)
{
res.Update(model);
context.SaveChanges();
}
return res?.GetViewModel;
}
} }
} }

View File

@ -1,337 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SoftwareInstallationDataBaseImplement;
#nullable disable
namespace SoftwareInstallationDataBaseImplement.Migrations
{
[DbContext(typeof(SoftwareInstallationDataBase))]
partial class SoftwareInstallationDataBaseModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.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("SoftwareInstallationDataBaseImplement.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("SoftwareInstallationDataBaseImplement.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("SoftwareInstallationDataBaseImplement.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>("PackageId")
.HasColumnType("int");
b.Property<string>("PackageName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.HasIndex("PackageId");
b.ToTable("Orders");
});
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.Models.Package", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("PackageName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Packages");
});
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.Models.PackageComponent", 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>("PackageId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("ComponentId");
b.HasIndex("PackageId");
b.ToTable("PackageComponents");
});
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.Models.Store", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<DateTime>("OpeningDate")
.HasColumnType("datetime2");
b.Property<int>("PackageMaxCount")
.HasColumnType("int");
b.Property<string>("StoreAdress")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("StoreName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Stores");
});
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.Models.StorePackage", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("PackageId")
.HasColumnType("int");
b.Property<int>("StoreId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("PackageId");
b.HasIndex("StoreId");
b.ToTable("StorePackages");
});
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.Models.Order", b =>
{
b.HasOne("SoftwareInstallationDataBaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SoftwareInstallationDataBaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.HasOne("SoftwareInstallationDataBaseImplement.Models.Package", "Package")
.WithMany("Orders")
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Client");
b.Navigation("Implementer");
b.Navigation("Package");
});
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.Models.PackageComponent", b =>
{
b.HasOne("SoftwareInstallationDataBaseImplement.Models.Component", "Component")
.WithMany("PackageComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SoftwareInstallationDataBaseImplement.Models.Package", "Package")
.WithMany("Components")
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Component");
b.Navigation("Package");
});
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.Models.StorePackage", b =>
{
b.HasOne("SoftwareInstallationDataBaseImplement.Models.Package", "Package")
.WithMany("StorePackages")
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("SoftwareInstallationDataBaseImplement.Models.Store", "Store")
.WithMany("Packages")
.HasForeignKey("StoreId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Package");
b.Navigation("Store");
});
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.Models.Client", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.Models.Component", b =>
{
b.Navigation("PackageComponents");
});
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.Models.Package", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
b.Navigation("StorePackages");
});
modelBuilder.Entity("SoftwareInstallationDataBaseImplement.Models.Store", b =>
{
b.Navigation("Packages");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -18,6 +18,10 @@ namespace SoftwareInstallationDataBaseImplement.Models
public string Subject { get; private set; } = string.Empty; public string Subject { get; private set; } = string.Empty;
[Required] [Required]
public string Body { get; private set; } = string.Empty; public string Body { get; private set; } = string.Empty;
[Required]
public bool HasRead { get; private set; }
[Required]
public string? Reply { get; private set; }
public virtual Client Client { get; set; } public virtual Client Client { get; set; }
@ -30,6 +34,8 @@ namespace SoftwareInstallationDataBaseImplement.Models
return new() return new()
{ {
Body = model.Body, Body = model.Body,
Reply = model.Reply,
HasRead = model.HasRead,
Subject = model.Subject, Subject = model.Subject,
ClientId = model.ClientId, ClientId = model.ClientId,
MessageId = model.MessageId, MessageId = model.MessageId,
@ -38,9 +44,21 @@ namespace SoftwareInstallationDataBaseImplement.Models
}; };
} }
public void Update(MessageInfoBindingModel model)
{
if (model == null)
{
return;
}
Reply = model.Reply;
HasRead = model.HasRead;
}
public MessageInfoViewModel GetViewModel => new() public MessageInfoViewModel GetViewModel => new()
{ {
Body = Body, Body = Body,
Reply = Reply,
HasRead = HasRead,
Subject = Subject, Subject = Subject,
ClientId = ClientId, ClientId = ClientId,
MessageId = MessageId, MessageId = MessageId,

View File

@ -8,5 +8,7 @@
DateTime DateDelivery { get; } DateTime DateDelivery { get; }
string Subject { get; } string Subject { get; }
string Body { get; } string Body { get; }
public bool HasRead { get; }
public string? Reply { get; }
} }
} }

View File

@ -38,8 +38,6 @@ namespace SoftwareInstallationFileImplement
public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement); public void SaveClients() => SaveData(Clients, ClientFileName, "Clients", x => x.GetXElement);
public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement); public void SaveImplementers() => SaveData(Implementers, ImplementerFileName, "Implementers", x => x.GetXElement);
public void SaveMessages() => SaveData(Messages, MessageFileName, "Messages", x => x.GetXElement); public void SaveMessages() => SaveData(Messages, MessageFileName, "Messages", x => x.GetXElement);
public void SaveClients() => SaveData(Clients, OrderFileName, "Clients", x => x.GetXElement);
public void SaveImplementers() => SaveData(Implementers, OrderFileName, "Implementers", x => x.GetXElement);
public void SaveStores() => SaveData(Stores, StoreFileName, "Stores", x => x.GetXElement); public void SaveStores() => SaveData(Stores, StoreFileName, "Stores", x => x.GetXElement);
private DataFileSingleton() private DataFileSingleton()

View File

@ -22,12 +22,14 @@ namespace SoftwareInstallationFileImplement.Implements
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model) public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{ {
if (!model.ClientId.HasValue) var res = source.Messages
return new(); .Where(x => !model.ClientId.HasValue || x.ClientId == model.ClientId)
return source.Messages .Select(x => x.GetViewModel);
.Where(x => x.ClientId == model.ClientId) if (!(model.Page.HasValue && model.PageSize.HasValue))
.Select(x => x.GetViewModel) {
.ToList(); return res.ToList();
}
return res.Skip((model.Page.Value - 1) * model.PageSize.Value).Take(model.PageSize.Value).ToList();
} }
public List<MessageInfoViewModel> GetFullList() public List<MessageInfoViewModel> GetFullList()
@ -48,5 +50,16 @@ namespace SoftwareInstallationFileImplement.Implements
source.SaveMessages(); source.SaveMessages();
return newMessage.GetViewModel; return newMessage.GetViewModel;
} }
public MessageInfoViewModel? Update(MessageInfoBindingModel model)
{
var res = source.Messages.FirstOrDefault(x => x.MessageId.Equals(model.MessageId));
if (res != null)
{
res.Update(model);
source.SaveMessages();
}
return res?.GetViewModel;
}
} }
} }

View File

@ -19,6 +19,10 @@ namespace SoftwareInstallationFileImplement.Models
public string Body { get; private set; } = string.Empty; public string Body { get; private set; } = string.Empty;
public bool HasRead { get; private set; }
public string? Reply { get; private set; }
public static Message? Create(MessageInfoBindingModel model) public static Message? Create(MessageInfoBindingModel model)
{ {
if (model == null) if (model == null)
@ -27,6 +31,8 @@ namespace SoftwareInstallationFileImplement.Models
} }
return new() return new()
{ {
Reply = model.Reply,
HasRead = model.HasRead,
Body = model.Body, Body = model.Body,
Subject = model.Subject, Subject = model.Subject,
DateDelivery = model.DateDelivery, DateDelivery = model.DateDelivery,
@ -44,6 +50,8 @@ namespace SoftwareInstallationFileImplement.Models
} }
return new() return new()
{ {
Reply = element.Attribute("Reply")!.Value,
HasRead = Convert.ToBoolean(element.Attribute("HasRead")!.Value),
Body = element.Attribute("Body")!.Value, Body = element.Attribute("Body")!.Value,
Subject = element.Attribute("Subject")!.Value, Subject = element.Attribute("Subject")!.Value,
DateDelivery = Convert.ToDateTime(element.Attribute("DateDelivery")!.Value), DateDelivery = Convert.ToDateTime(element.Attribute("DateDelivery")!.Value),
@ -53,10 +61,22 @@ namespace SoftwareInstallationFileImplement.Models
}; };
} }
public void Update(MessageInfoBindingModel model)
{
if (model == null)
{
return;
}
Reply = model.Reply;
HasRead = model.HasRead;
}
public MessageInfoViewModel GetViewModel => new() public MessageInfoViewModel GetViewModel => new()
{ {
Body = Body, Body = Body,
Subject = Subject, Subject = Subject,
Reply = Reply,
HasRead = HasRead,
DateDelivery = DateDelivery, DateDelivery = DateDelivery,
SenderName = SenderName, SenderName = SenderName,
ClientId = ClientId, ClientId = ClientId,
@ -66,6 +86,8 @@ namespace SoftwareInstallationFileImplement.Models
public XElement GetXElement => new("MessageInfo", public XElement GetXElement => new("MessageInfo",
new XAttribute("Subject", Subject), new XAttribute("Subject", Subject),
new XAttribute("Body", Body), new XAttribute("Body", Body),
new XAttribute("Reply", Reply),
new XAttribute("HasRead", HasRead),
new XAttribute("ClientId", ClientId), new XAttribute("ClientId", ClientId),
new XAttribute("MessageId", MessageId), new XAttribute("MessageId", MessageId),
new XAttribute("SenderName", SenderName), new XAttribute("SenderName", SenderName),

View File

@ -41,8 +41,22 @@ namespace SoftwareInstallationListImplement.Implements
result.Add(item.GetViewModel); result.Add(item.GetViewModel);
} }
} }
if (!(model.Page.HasValue && model.PageSize.HasValue))
{
return result; return result;
} }
if (model.Page * model.PageSize >= result.Count)
{
return null;
}
List<MessageInfoViewModel> filteredResult = new();
for (var i = (model.Page.Value - 1) * model.PageSize.Value; i < model.Page.Value * model.PageSize.Value; i++)
{
filteredResult.Add(result[i]);
}
return filteredResult;
}
public List<MessageInfoViewModel> GetFullList() public List<MessageInfoViewModel> GetFullList()
{ {
@ -64,5 +78,18 @@ namespace SoftwareInstallationListImplement.Implements
_source.Messages.Add(newMessage); _source.Messages.Add(newMessage);
return newMessage.GetViewModel; return newMessage.GetViewModel;
} }
public MessageInfoViewModel? Update(MessageInfoBindingModel model)
{
foreach (var message in _source.Messages)
{
if (message.MessageId.Equals(model.MessageId))
{
message.Update(model);
return message.GetViewModel;
}
}
return null;
}
} }
} }

View File

@ -23,6 +23,10 @@ namespace SoftwareInstallationListImplement.Models
public string Body { get; private set; } = string.Empty; public string Body { get; private set; } = string.Empty;
public bool HasRead { get; private set; }
public string? Reply { get; private set; }
public static Message? Create(MessageInfoBindingModel model) public static Message? Create(MessageInfoBindingModel model)
{ {
if (model == null) if (model == null)
@ -31,6 +35,8 @@ namespace SoftwareInstallationListImplement.Models
} }
return new() return new()
{ {
Reply = model.Reply,
HasRead = model.HasRead,
Body = model.Body, Body = model.Body,
Subject = model.Subject, Subject = model.Subject,
DateDelivery = model.DateDelivery, DateDelivery = model.DateDelivery,
@ -40,9 +46,21 @@ namespace SoftwareInstallationListImplement.Models
}; };
} }
public void Update(MessageInfoBindingModel model)
{
if (model == null)
{
return;
}
Reply = model.Reply;
HasRead = model.HasRead;
}
public MessageInfoViewModel GetViewModel => new() public MessageInfoViewModel GetViewModel => new()
{ {
Body = Body, Body = Body,
Reply = Reply,
HasRead = HasRead,
Subject = Subject, Subject = Subject,
DateDelivery = DateDelivery, DateDelivery = DateDelivery,
SenderName = SenderName, SenderName = SenderName,

View File

@ -14,6 +14,7 @@ namespace SoftwareInstallationRestApi.Controllers
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IClientLogic _logic; private readonly IClientLogic _logic;
private readonly IMessageInfoLogic _mailLogic; private readonly IMessageInfoLogic _mailLogic;
public int pageSize = 3;
public ClientController(IClientLogic logic, ILogger<ClientController> logger, IMessageInfoLogic mailLogic) public ClientController(IClientLogic logic, ILogger<ClientController> logger, IMessageInfoLogic mailLogic)
{ {
@ -22,6 +23,25 @@ namespace SoftwareInstallationRestApi.Controllers
_mailLogic = mailLogic; _mailLogic = mailLogic;
} }
[HttpGet]
public List<MessageInfoViewModel>? GetMessages(int clientId, int page)
{
try
{
return _mailLogic.ReadList(new()
{
ClientId = clientId,
Page = page,
PageSize = pageSize
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения писем клиента");
throw;
}
}
[HttpGet] [HttpGet]
public ClientViewModel? Login(string login, string password) public ClientViewModel? Login(string login, string password)
{ {