ПИбд-21 Кувшинов Тимур сложная лаба 7 #26

Closed
TImourka wants to merge 9 commits from laba7complicated into laba6complicated
25 changed files with 1223 additions and 126 deletions
Showing only changes of commit b4c17e17cd - Show all commits

View File

@ -29,7 +29,7 @@ namespace AutomobilePlantBusinessLogic.BusinessLogics
public List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? model)
{
_logger.LogInformation("ReadList. MessageId:{MessageId}.ClientId:{ClientId} ", model?.MessageId, model?.ClientId);
_logger.LogInformation("ReadList. MessageId:{MessageId}.ClientId:{ClientId}.Page:{Page}.PageSize:{PageSize}", model?.MessageId, model?.ClientId, model?.Page, model?.PageSize);
var list = (model == null) ? _messageInfoStorage.GetFullList() : _messageInfoStorage.GetFilteredList(model);
if (list == null)
{
@ -39,5 +39,26 @@ namespace AutomobilePlantBusinessLogic.BusinessLogics
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public MessageInfoViewModel? ReadElement(MessageInfoSearchModel model)
{
var message = _messageInfoStorage.GetElement(model);
if (message == null)
{
_logger.LogWarning("Read message operation failed");
return null;
}
return message;
}
public bool Update(MessageInfoBindingModel model)
{
if (_messageInfoStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
}
}

View File

@ -141,7 +141,12 @@ namespace AutomobilePlantClientApp.Controllers
{
return Redirect("~/Home/Enter");
}
return View(APIClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientId={APIClient.Client.Id}"));
return View();
}
[HttpPost]
public List<MessageInfoViewModel> LoadMails(int pageNum, int pageSize)
{
return APIClient.GetRequest<List<MessageInfoViewModel>>($"api/client/getmessages?clientId={APIClient.Client.Id}&pageNum={pageNum}&pageSize={pageSize}");
}
}

View File

@ -1,54 +1,73 @@
@using AutomobilePlantContracts.ViewModels
@model List<MessageInfoViewModel>
@{
@{
ViewData["Title"] = "Mails";
}
<div class="text-center">
<h1 class="display-4">Mails</h1>
</div>
<div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Login bobr!</h3>
return;
<table id="mailsTable" class="table">
<thead>
<tr>
<th>
Mail's date'
</th>
<th>
Title
</th>
<th>
Text
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div class="text-center">
<div>
Page: <input type="number" id="pageNum" value="1" min="1" /> Page Size: <input type="number" id="pageSize" value="2" min="1" />
</div>
</div>
</div>
<script>
$(document).ready(function () {
// Инициализируем значения NumericUpDown с текущими значениями
var pageNum = $('#pageNum').val();
var pageSize = $('#pageSize').val();
// Функция для загрузки данных с сервера
function loadMails(pageNum, pageSize) {
$.ajax({
url: '/Home/LoadMails',
type: 'POST',
data: { pageNum: pageNum, pageSize: pageSize },
success: function (data) {
// Очищаем текущие данные
$('#mailsTable tbody').empty();
// Заполняем таблицу новыми данными
$.each(data, function (index, item) {
var row = $('<tr>');
row.append($('<td>').text(item.dateDelivery));
row.append($('<td>').text(item.subject));
row.append($('<td>').text(item.body));
$('#mailsTable tbody').append(row);
});
},
error: function () {
alert('Error loading mails');
}
});
}
<table class="table">
<thead>
<tr>
<th>
Mail's date'
</th>
<th>
Title
</th>
<th>
Text
</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>
// Загружаем данные при инициализации страницы
loadMails(pageNum, pageSize);
// Обработчик изменений для NumericUpDown
$('#pageNum, #pageSize').change(function () {
pageNum = $('#pageNum').val();
pageSize = $('#pageSize').val();
loadMails(pageNum, pageSize);
});
});
</script>

View File

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

View File

@ -8,5 +8,7 @@ namespace AutomobilePlantContracts.BusinessLogicsContracts
{
List<MessageInfoViewModel>? ReadList(MessageInfoSearchModel? 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 string? MessageId { get; set; }
public int? Page { get; set; }
public int? PageSize { get; set; }
}
}

View File

@ -10,5 +10,6 @@ namespace AutomobilePlantContracts.StoragesContracts
List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model);
MessageInfoViewModel? GetElement(MessageInfoSearchModel model);
MessageInfoViewModel? Insert(MessageInfoBindingModel model);
MessageInfoViewModel? Update(MessageInfoBindingModel model);
}
}

View File

@ -16,5 +16,9 @@ namespace AutomobilePlantContracts.ViewModels
public string Subject { get; set; } = string.Empty;
[DisplayName("Body")]
public string Body { get; set; } = string.Empty;
[DisplayName("Readed")]
public bool IsReaded { get; set; }
[DisplayName("Reply")]
public string? Reply { get; set; }
}
}

View File

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

View File

@ -22,10 +22,15 @@ namespace AutomobilePlantDatabaseImplement.Implements
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
using var context = new AutomobilePlantDatabase();
return context.Messages
var messages = context.Messages
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
if (!model.Page.HasValue || !model.PageSize.HasValue)
{
return messages.ToList();
}
return messages.Skip((model.Page.Value - 1) * model.PageSize.Value).Take(model.PageSize.Value).ToList();
}
public List<MessageInfoViewModel> GetFullList()
@ -48,5 +53,17 @@ namespace AutomobilePlantDatabaseImplement.Implements
context.SaveChanges();
return newMessage.GetViewModel;
}
public MessageInfoViewModel? Update(MessageInfoBindingModel model)
{
using var context = new AutomobilePlantDatabase();
var message = context.Messages.FirstOrDefault(x => x.MessageId.Equals(model.MessageId));
if (message != null)
{
message.Update(model);
context.SaveChanges();
}
return message?.GetViewModel;
}
}
}

View File

@ -0,0 +1,381 @@
// <auto-generated />
using System;
using AutomobilePlantDatabaseImplement;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace AutomobilePlantDatabaseImplement.Migrations
{
[DbContext(typeof(AutomobilePlantDatabase))]
[Migration("20240505173052_MbINeedItLC7")]
partial class MbINeedItLC7
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.16")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Car", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("CarName")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<double>("Price")
.HasColumnType("float");
b.HasKey("Id");
b.ToTable("Cars");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.CarComponent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("CarId")
.HasColumnType("int");
b.Property<int>("ComponentId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CarId");
b.HasIndex("ComponentId");
b.ToTable("CarComponents");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.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("AutomobilePlantDatabaseImplement.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("AutomobilePlantDatabaseImplement.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("AutomobilePlantDatabaseImplement.Models.MessageInfo", 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<bool>("IsReaded")
.HasColumnType("bit");
b.Property<string>("Reply")
.HasColumnType("nvarchar(max)");
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("AutomobilePlantDatabaseImplement.Models.Order", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("CarId")
.HasColumnType("int");
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>("Status")
.HasColumnType("int");
b.Property<double>("Sum")
.HasColumnType("float");
b.HasKey("Id");
b.HasIndex("CarId");
b.HasIndex("ClientId");
b.HasIndex("ImplementerId");
b.ToTable("Orders");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Shop", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Address")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("MaxCountCars")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("OpeningDate")
.HasColumnType("datetime2");
b.HasKey("Id");
b.ToTable("Shops");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.ShopCar", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<int>("CarId")
.HasColumnType("int");
b.Property<int>("Count")
.HasColumnType("int");
b.Property<int>("ShopId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("CarId");
b.HasIndex("ShopId");
b.ToTable("ShopCars");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.CarComponent", b =>
{
b.HasOne("AutomobilePlantDatabaseImplement.Models.Car", "Car")
.WithMany("Components")
.HasForeignKey("CarId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AutomobilePlantDatabaseImplement.Models.Component", "Component")
.WithMany("CarComponents")
.HasForeignKey("ComponentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Car");
b.Navigation("Component");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.MessageInfo", b =>
{
b.HasOne("AutomobilePlantDatabaseImplement.Models.Client", "Client")
.WithMany("Messages")
.HasForeignKey("ClientId");
b.Navigation("Client");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Order", b =>
{
b.HasOne("AutomobilePlantDatabaseImplement.Models.Car", "Car")
.WithMany("Orders")
.HasForeignKey("CarId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AutomobilePlantDatabaseImplement.Models.Client", "Client")
.WithMany("Orders")
.HasForeignKey("ClientId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AutomobilePlantDatabaseImplement.Models.Implementer", "Implementer")
.WithMany("Orders")
.HasForeignKey("ImplementerId");
b.Navigation("Car");
b.Navigation("Client");
b.Navigation("Implementer");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.ShopCar", b =>
{
b.HasOne("AutomobilePlantDatabaseImplement.Models.Car", "Car")
.WithMany()
.HasForeignKey("CarId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AutomobilePlantDatabaseImplement.Models.Shop", "Shop")
.WithMany("Cars")
.HasForeignKey("ShopId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Car");
b.Navigation("Shop");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Car", b =>
{
b.Navigation("Components");
b.Navigation("Orders");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Client", b =>
{
b.Navigation("Messages");
b.Navigation("Orders");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Component", b =>
{
b.Navigation("CarComponents");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Shop", b =>
{
b.Navigation("Cars");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,39 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AutomobilePlantDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class MbINeedItLC7 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsReaded",
table: "Messages",
type: "bit",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<string>(
name: "Reply",
table: "Messages",
type: "nvarchar(max)",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsReaded",
table: "Messages");
migrationBuilder.DropColumn(
name: "Reply",
table: "Messages");
}
}
}

View File

@ -155,6 +155,12 @@ namespace AutomobilePlantDatabaseImplement.Migrations
b.Property<DateTime>("DateDelivery")
.HasColumnType("datetime2");
b.Property<bool>("IsReaded")
.HasColumnType("bit");
b.Property<string>("Reply")
.HasColumnType("nvarchar(max)");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("nvarchar(max)");
@ -357,15 +363,15 @@ namespace AutomobilePlantDatabaseImplement.Migrations
b.Navigation("CarComponents");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Shop", b =>
{
b.Navigation("Cars");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Implementer", b =>
{
b.Navigation("Orders");
});
modelBuilder.Entity("AutomobilePlantDatabaseImplement.Models.Shop", b =>
{
b.Navigation("Cars");
});
#pragma warning restore 612, 618
}
}

View File

@ -19,6 +19,8 @@ namespace AutomobilePlantDatabaseImplement.Models
public string Subject { get; private set; } = string.Empty;
public string Body { get; private set; } = string.Empty;
public bool IsReaded { get; private set; }
public string? Reply { get; private set; }
public virtual Client? Client { get; private set; }
@ -36,9 +38,21 @@ namespace AutomobilePlantDatabaseImplement.Models
MessageId = model.MessageId,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
IsReaded = model.IsReaded,
Reply = model.Reply
};
}
public void Update(MessageInfoBindingModel model)
{
if (model == null)
{
return;
}
Reply = model.Reply;
IsReaded = model.IsReaded;
}
public MessageInfoViewModel GetViewModel => new()
{
Body = Body,
@ -47,6 +61,8 @@ namespace AutomobilePlantDatabaseImplement.Models
MessageId = MessageId,
SenderName = SenderName,
DateDelivery = DateDelivery,
Reply = Reply,
IsReaded = IsReaded,
};
}
}

View File

@ -25,10 +25,15 @@ namespace AutomobilePlantFileImplement.Implements
public List<MessageInfoViewModel> GetFilteredList(MessageInfoSearchModel model)
{
return _source.Messages
var messages = _source.Messages
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
if (!model.Page.HasValue || !model.PageSize.HasValue)
{
return messages.ToList();
}
return messages.Skip((model.Page.Value - 1) * model.PageSize.Value).Take(model.PageSize.Value).ToList();
}
public List<MessageInfoViewModel> GetFullList()
@ -49,5 +54,16 @@ namespace AutomobilePlantFileImplement.Implements
_source.SaveMessages();
return newMessage.GetViewModel;
}
public MessageInfoViewModel? Update(MessageInfoBindingModel model)
{
var message = _source.Messages.FirstOrDefault(x => x.MessageId.Equals(model.MessageId));
if (message != null)
{
message.Update(model);
_source.SaveMessages();
}
return message?.GetViewModel;
}
}
}

View File

@ -19,6 +19,10 @@ namespace AutomobilePlantFileImplement.Models
public string Body { get; private set; } = string.Empty;
public bool IsReaded { get; private set; }
public string? Reply { get; private set; }
public static MessageInfo? Create(MessageInfoBindingModel model)
{
if (model == null)
@ -33,6 +37,8 @@ namespace AutomobilePlantFileImplement.Models
MessageId = model.MessageId,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
Reply = model.Reply,
IsReaded = model.IsReaded,
};
}
@ -50,9 +56,21 @@ namespace AutomobilePlantFileImplement.Models
MessageId = element.Attribute("MessageId")!.Value,
SenderName = element.Attribute("SenderName")!.Value,
DateDelivery = Convert.ToDateTime(element.Attribute("DateDelivery")!.Value),
Reply = element.Attribute("Reply")!.Value,
IsReaded = Convert.ToBoolean(element.Attribute("IsReaded")!.Value),
};
}
public void Update(MessageInfoBindingModel model)
{
if (model == null)
{
return;
}
Reply = model.Reply;
IsReaded = model.IsReaded;
}
public MessageInfoViewModel GetViewModel => new()
{
Body = Body,
@ -61,6 +79,8 @@ namespace AutomobilePlantFileImplement.Models
MessageId = MessageId,
SenderName = SenderName,
DateDelivery = DateDelivery,
Reply = Reply,
IsReaded = IsReaded,
};
public XElement GetXElement => new("MessageInfo",
@ -69,7 +89,9 @@ namespace AutomobilePlantFileImplement.Models
new XAttribute("ClientId", ClientId),
new XAttribute("MessageId", MessageId),
new XAttribute("SenderName", SenderName),
new XAttribute("DateDelivery", DateDelivery)
new XAttribute("DateDelivery", DateDelivery),
new XAttribute("Reply", Reply),
new XAttribute("HasRead", IsReaded)
);
}
}

View File

@ -33,7 +33,11 @@ namespace AutomobilePlantListImplement.Implements
result.Add(item.GetViewModel);
}
}
return result;
if (!model.Page.HasValue || !model.PageSize.HasValue)
{
return result;
}
return result.Skip((model.Page.Value - 1) * model.PageSize.Value).Take(model.PageSize.Value).ToList();
}
public List<MessageInfoViewModel> GetFullList()
@ -56,5 +60,17 @@ namespace AutomobilePlantListImplement.Implements
_source.Messages.Add(newMessage);
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

@ -18,6 +18,10 @@ namespace AutomobilePlantListImplement.Models
public string Body { get; private set; } = string.Empty;
public bool IsReaded { get; private set; }
public string? Reply { get; private set; }
public static MessageInfo? Create(MessageInfoBindingModel model)
{
if (model == null)
@ -32,9 +36,21 @@ namespace AutomobilePlantListImplement.Models
MessageId = model.MessageId,
SenderName = model.SenderName,
DateDelivery = model.DateDelivery,
Reply = model.Reply,
IsReaded = model.IsReaded,
};
}
public void Update(MessageInfoBindingModel model)
{
if (model == null)
{
return;
}
Reply = model.Reply;
IsReaded = model.IsReaded;
}
public MessageInfoViewModel GetViewModel => new()
{
Body = Body,
@ -43,6 +59,8 @@ namespace AutomobilePlantListImplement.Models
MessageId = MessageId,
SenderName = SenderName,
DateDelivery = DateDelivery,
Reply = Reply,
IsReaded = IsReaded,
};
}
}

View File

@ -63,13 +63,15 @@ namespace AutomobilePlantRestApi.Controllers
}
}
[HttpGet]
public List<MessageInfoViewModel>? GetMessages(int clientId)
public List<MessageInfoViewModel>? GetMessages(int clientId, int pageNum, int pageSize)
{
try
{
return _mailLogic.ReadList(new MessageInfoSearchModel
{
ClientId = clientId
ClientId = clientId,
Page = pageNum,
PageSize = pageSize
});
}
catch (Exception ex)

View File

@ -0,0 +1,195 @@
namespace AutomobilePlantView
{
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()
{
textBoxHead = new TextBox();
textBoxBody = new TextBox();
labelHead = new Label();
labelBody = new Label();
labelFrom = new Label();
labelHeadReply = new Label();
labelBoryReply = new Label();
labelMessage = new Label();
labelHeadMessage = new Label();
label1 = new Label();
buttonCancel = new Button();
buttonSave = new Button();
SuspendLayout();
//
// textBoxHead
//
textBoxHead.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
textBoxHead.Location = new Point(85, 256);
textBoxHead.Name = "textBoxHead";
textBoxHead.Size = new Size(703, 23);
textBoxHead.TabIndex = 0;
//
// textBoxBody
//
textBoxBody.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
textBoxBody.Location = new Point(85, 285);
textBoxBody.Multiline = true;
textBoxBody.Name = "textBoxBody";
textBoxBody.Size = new Size(703, 153);
textBoxBody.TabIndex = 1;
//
// labelHead
//
labelHead.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
labelHead.Location = new Point(103, 32);
labelHead.Name = "labelHead";
labelHead.Size = new Size(685, 61);
labelHead.TabIndex = 2;
labelHead.Text = "Head";
//
// labelBody
//
labelBody.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
labelBody.Location = new Point(103, 93);
labelBody.Name = "labelBody";
labelBody.Size = new Size(685, 160);
labelBody.TabIndex = 3;
labelBody.Text = "Body";
//
// labelFrom
//
labelFrom.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
labelFrom.Location = new Point(103, 9);
labelFrom.Name = "labelFrom";
labelFrom.Size = new Size(685, 23);
labelFrom.TabIndex = 4;
labelFrom.Text = "From";
//
// labelHeadReply
//
labelHeadReply.AutoSize = true;
labelHeadReply.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
labelHeadReply.Location = new Point(12, 259);
labelHeadReply.Name = "labelHeadReply";
labelHeadReply.Size = new Size(67, 15);
labelHeadReply.TabIndex = 5;
labelHeadReply.Text = "Head reply:";
//
// labelBoryReply
//
labelBoryReply.AutoSize = true;
labelBoryReply.Location = new Point(12, 288);
labelBoryReply.Name = "labelBoryReply";
labelBoryReply.Size = new Size(66, 15);
labelBoryReply.TabIndex = 6;
labelBoryReply.Text = "Body reply:";
//
// labelMessage
//
labelMessage.AutoSize = true;
labelMessage.Location = new Point(12, 93);
labelMessage.Name = "labelMessage";
labelMessage.Size = new Size(86, 15);
labelMessage.TabIndex = 8;
labelMessage.Text = "Body message:";
//
// labelHeadMessage
//
labelHeadMessage.AutoSize = true;
labelHeadMessage.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
labelHeadMessage.Location = new Point(12, 32);
labelHeadMessage.Name = "labelHeadMessage";
labelHeadMessage.Size = new Size(87, 15);
labelHeadMessage.TabIndex = 7;
labelHeadMessage.Text = "Head message:";
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(12, 9);
label1.Name = "label1";
label1.Size = new Size(85, 15);
label1.TabIndex = 9;
label1.Text = "Message from:";
//
// buttonCancel
//
buttonCancel.Location = new Point(713, 449);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(75, 23);
buttonCancel.TabIndex = 10;
buttonCancel.Text = "Cancel";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(632, 449);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(75, 23);
buttonSave.TabIndex = 11;
buttonSave.Text = "Save";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// FormMail
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 484);
Controls.Add(buttonSave);
Controls.Add(buttonCancel);
Controls.Add(label1);
Controls.Add(labelMessage);
Controls.Add(labelHeadMessage);
Controls.Add(labelBoryReply);
Controls.Add(labelHeadReply);
Controls.Add(labelFrom);
Controls.Add(labelBody);
Controls.Add(labelHead);
Controls.Add(textBoxBody);
Controls.Add(textBoxHead);
Name = "FormMail";
Text = "Mail";
Load += FormMail_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private TextBox textBoxHead;
private TextBox textBoxBody;
private Label labelHead;
private Label labelBody;
private Label labelFrom;
private Label labelHeadReply;
private Label labelBoryReply;
private Label labelMessage;
private Label labelHeadMessage;
private Label label1;
private Button buttonCancel;
private Button buttonSave;
}
}

View File

@ -0,0 +1,79 @@
using AutomobilePlantBusinessLogic.MailWorker;
using AutomobilePlantContracts.BusinessLogicsContracts;
using AutomobilePlantContracts.ViewModels;
using Microsoft.Extensions.Logging;
namespace AutomobilePlantView
{
public partial class FormMail : Form
{
private readonly ILogger _logger;
private readonly AbstractMailWorker _mailWorker;
private readonly IMessageInfoLogic _logic;
private MessageInfoViewModel _message;
public string MessageId { get; set; } = string.Empty;
public FormMail(ILogger<FormMail> logger, AbstractMailWorker mailWorker, IMessageInfoLogic logic)
{
InitializeComponent();
_logger = logger;
_mailWorker = mailWorker;
_logic = logic;
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void buttonSave_Click(object sender, EventArgs e)
{
_mailWorker.MailSendAsync(new()
{
MailAddress = _message.SenderName,
Subject = textBoxHead.Text,
Text = textBoxBody.Text,
});
_logic.Update(new()
{
MessageId = MessageId,
Reply = textBoxBody.Text,
IsReaded = true,
});
MessageBox.Show("Успешно отправлен ответ", "Отправлен ответ", MessageBoxButtons.OK);
DialogResult = DialogResult.OK;
Close();
}
private void FormMail_Load(object sender, EventArgs e)
{
try
{
_message = _logic.ReadElement(new() { MessageId = MessageId });
if (_message == null) throw new ArgumentNullException("Письма с таким Id не существует");
_logic.Update(new()
{
MessageId = MessageId,
Reply = _message.Reply,
IsReaded = true,
});
labelHead.Text = _message.Subject;
labelBody.Text = _message.Body;
labelFrom.Text = $"From: {_message.SenderName}";
if (_message.IsReaded is false)
{
_logic.Update(new() { MessageId = MessageId, IsReaded = true, Reply = _message.Reply });
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения собщения");
MessageBox.Show(ex.Message, "Eror", 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,43 +20,121 @@
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();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Fill;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowTemplate.Height = 25;
dataGridView.Size = new Size(800, 450);
dataGridView.TabIndex = 0;
//
// FormMails
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(dataGridView);
Name = "FormMails";
Text = "Mails";
Load += FormMails_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
/// <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();
panel1 = new Panel();
numericUpDownPageSize = new NumericUpDown();
labelPageSize = new Label();
numericUpDownPage = new NumericUpDown();
labelPage = new Label();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)numericUpDownPageSize).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownPage).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.AllowUserToAddRows = false;
dataGridView.AllowUserToDeleteRows = false;
dataGridView.AllowUserToResizeColumns = false;
dataGridView.AllowUserToResizeRows = false;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Dock = DockStyle.Fill;
dataGridView.Location = new Point(0, 0);
dataGridView.Name = "dataGridView";
dataGridView.RowTemplate.Height = 25;
dataGridView.Size = new Size(800, 450);
dataGridView.TabIndex = 0;
dataGridView.RowHeaderMouseDoubleClick += dataGridView_RowHeaderMouseDoubleClick;
//
// panel1
//
panel1.Controls.Add(numericUpDownPageSize);
panel1.Controls.Add(labelPageSize);
panel1.Controls.Add(numericUpDownPage);
panel1.Controls.Add(labelPage);
panel1.Dock = DockStyle.Bottom;
panel1.Location = new Point(0, 395);
panel1.Name = "panel1";
panel1.Size = new Size(800, 55);
panel1.TabIndex = 1;
//
// numericUpDownPageSize
//
numericUpDownPageSize.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
numericUpDownPageSize.Location = new Point(229, 14);
numericUpDownPageSize.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
numericUpDownPageSize.Name = "numericUpDownPageSize";
numericUpDownPageSize.Size = new Size(67, 29);
numericUpDownPageSize.TabIndex = 6;
numericUpDownPageSize.Value = new decimal(new int[] { 2, 0, 0, 0 });
numericUpDownPageSize.ValueChanged += numericUpDownPageSize_ValueChanged;
//
// labelPageSize
//
labelPageSize.AutoSize = true;
labelPageSize.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
labelPageSize.Location = new Point(137, 16);
labelPageSize.Name = "labelPageSize";
labelPageSize.Padding = new Padding(10, 0, 0, 0);
labelPageSize.Size = new Size(86, 21);
labelPageSize.TabIndex = 5;
labelPageSize.Text = "Page size:";
//
// numericUpDownPage
//
numericUpDownPage.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
numericUpDownPage.Location = new Point(64, 14);
numericUpDownPage.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
numericUpDownPage.Name = "numericUpDownPage";
numericUpDownPage.Size = new Size(67, 29);
numericUpDownPage.TabIndex = 4;
numericUpDownPage.Value = new decimal(new int[] { 1, 0, 0, 0 });
numericUpDownPage.ValueChanged += numericUpDownPage_ValueChanged;
//
// labelPage
//
labelPage.AutoSize = true;
labelPage.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point);
labelPage.Location = new Point(12, 16);
labelPage.Name = "labelPage";
labelPage.Size = new Size(46, 21);
labelPage.TabIndex = 1;
labelPage.Text = "Page:";
//
// FormMails
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(panel1);
Controls.Add(dataGridView);
Name = "FormMails";
Text = "Mails";
Load += FormMails_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
panel1.ResumeLayout(false);
panel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)numericUpDownPageSize).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownPage).EndInit();
ResumeLayout(false);
}
#endregion
#endregion
private DataGridView dataGridView;
private DataGridView dataGridView;
private Panel panel1;
private Label labelPage;
private NumericUpDown numericUpDownPage;
private NumericUpDown numericUpDownPageSize;
private Label labelPageSize;
}
}

View File

@ -3,38 +3,71 @@ using Microsoft.Extensions.Logging;
namespace AutomobilePlantView
{
public partial class FormMails : Form
{
private readonly ILogger _logger;
private readonly IMessageInfoLogic _logic;
public partial class FormMails : Form
{
private readonly ILogger _logger;
private readonly IMessageInfoLogic _logic;
public FormMails(ILogger<FormMails> logger, IMessageInfoLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
public FormMails(ILogger<FormMails> logger, IMessageInfoLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormMails_Load(object sender, EventArgs e)
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["MessageId"].Visible = false;
dataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка писем");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки писем");
MessageBox.Show(ex.Message, "Eror", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
void LoadData()
{
try
{
var list = _logic.ReadList(new()
{
Page = ((int)numericUpDownPage.Value),
PageSize = ((int)numericUpDownPageSize.Value),
});
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["MessageId"].Visible = false;
dataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка писем");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки писем");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private void FormMails_Load(object sender, EventArgs e)
{
LoadData();
}
private void numericUpDownPage_ValueChanged(object sender, EventArgs e)
{
LoadData();
}
private void numericUpDownPageSize_ValueChanged(object sender, EventArgs e)
{
LoadData();
}
private void dataGridView_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormMail));
if (service is FormMail form)
{
form.MessageId = (string)(dataGridView.SelectedRows[0].Cells["MessageId"].Value);
form.ShowDialog();
LoadData();
}
}
}
}
}

View File

@ -99,6 +99,7 @@ namespace AutomobilePlantView
services.AddTransient<FormImplementers>();
services.AddTransient<FormImplementer>();
services.AddTransient<FormMails>();
}
services.AddTransient<FormMail>();
}
}
}