I hope it's done...

This commit is contained in:
Никита Волков 2024-04-18 14:56:31 +04:00
parent 3f16a1bd0e
commit b06e5065f6
14 changed files with 286 additions and 82 deletions

View File

@ -16,11 +16,13 @@ namespace ComputersShopBusinessLogic.BusinessLogics
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IMessageInfoStorage _messageInfoStorage; private readonly IMessageInfoStorage _messageInfoStorage;
private readonly IClientStorage _clientStorage;
public MessageInfoLogic(ILogger<OrderLogic> logger, IMessageInfoStorage messageInfoStorage) public MessageInfoLogic(ILogger<OrderLogic> logger, IMessageInfoStorage messageInfoStorage, IClientStorage clientStorage)
{ {
_logger = logger; _logger = logger;
_messageInfoStorage = messageInfoStorage; _messageInfoStorage = messageInfoStorage;
_clientStorage = clientStorage;
} }
public bool Create(MessageInfoBindingModel model) public bool Create(MessageInfoBindingModel model)
@ -45,5 +47,47 @@ namespace ComputersShopBusinessLogic.BusinessLogics
_logger.LogInformation("ReadList. Count:{Count}", list.Count); _logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list; return list;
} }
private void CheckModel(MessageInfoBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.MessageId))
{
throw new ArgumentNullException("Не указан id сообщения", nameof(model.MessageId));
}
if (string.IsNullOrEmpty(model.SenderName))
{
throw new ArgumentNullException("Не указао почта", nameof(model.SenderName));
}
if (string.IsNullOrEmpty(model.Subject))
{
throw new ArgumentNullException("Не указана тема", nameof(model.Subject));
}
if (string.IsNullOrEmpty(model.Body))
{
throw new ArgumentNullException("Не указан текст сообщения", nameof(model.Subject));
}
_logger.LogInformation("MessageInfo. MessageId:{MessageId}.SenderName:{SenderName}.Subject:{Subject}.Body:{Body}", model.MessageId, model.SenderName, model.Subject, model.Body);
var element = _clientStorage.GetElement(new ClientSearchModel
{
Email = model.SenderName
});
if (element == null)
{
_logger.LogWarning("Не удалоссь найти клиента, отправившего письмо с адреса Email:{Email}", model.SenderName);
}
else
{
model.ClientId = element.Id;
}
}
} }
} }

View File

@ -17,6 +17,7 @@ namespace ComputersShopContracts.ViewModels
public int ClientId { get; set; } public int ClientId { get; set; }
[DisplayName("Фамилия клиента")] [DisplayName("Фамилия клиента")]
public string ClientFIO { get; set; } = string.Empty; public string ClientFIO { get; set; } = string.Empty;
public string ClientEmail { get; set; } = string.Empty;
public int? ImplementerId { get; set; } public int? ImplementerId { get; set; }
[DisplayName("Исполнитель")] [DisplayName("Исполнитель")]
public string ImplementerFIO { get; set; } = string.Empty; public string ImplementerFIO { get; set; } = string.Empty;

View File

@ -27,17 +27,21 @@ namespace ComputersShopDataBaseImplement.Implements
public ClientViewModel? GetElement(ClientSearchModel model) public ClientViewModel? GetElement(ClientSearchModel model)
{ {
if (string.IsNullOrEmpty(model.ClientFIO) &&
string.IsNullOrEmpty(model.Email) &&
string.IsNullOrEmpty(model.Password) &&
!model.Id.HasValue)
{
return null;
}
using var context = new ComputersShopDataBase(); using var context = new ComputersShopDataBase();
if (model.Id.HasValue) var temp = context.Clients
return context.Clients.FirstOrDefault(x => x.Id == model.Id)?.GetViewModel; .FirstOrDefault(x => (string.IsNullOrEmpty(model.ClientFIO) || x.ClientFIO == model.ClientFIO) &&
if (model.Email != null && model.Password != null) (string.IsNullOrEmpty(model.Email) || x.Email == model.Email) &&
return context.Clients (string.IsNullOrEmpty(model.Password) || x.Password == model.Password) &&
.FirstOrDefault(x => x.Email.Equals(model.Email) (!model.Id.HasValue || x.Id == model.Id))
&& x.Password.Equals(model.Password)) ?.GetViewModel;
?.GetViewModel; return temp;
if (model.Email != null)
return context.Clients.FirstOrDefault(x => x.Email.Equals(model.Email))?.GetViewModel;
return null;
} }
public List<ClientViewModel> GetFilteredList(ClientSearchModel model) public List<ClientViewModel> GetFilteredList(ClientSearchModel model)

View File

@ -12,8 +12,8 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace ComputersShopDataBaseImplement.Migrations namespace ComputersShopDataBaseImplement.Migrations
{ {
[DbContext(typeof(ComputersShopDataBase))] [DbContext(typeof(ComputersShopDataBase))]
[Migration("20240414115616_InitialCreate")] [Migration("20240418105123_Init-Create")]
partial class InitialCreate partial class InitCreate
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -143,6 +143,36 @@ namespace ComputersShopDataBaseImplement.Migrations
b.ToTable("Implementers"); b.ToTable("Implementers");
}); });
modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Message", b =>
{
b.Property<string>("MessageId")
.HasColumnType("text");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("ClientId")
.HasColumnType("integer");
b.Property<DateTime>("DateDelivery")
.HasColumnType("timestamp with time zone");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("text");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.ToTable("Messages");
});
modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Order", b => modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Order", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -205,6 +235,13 @@ namespace ComputersShopDataBaseImplement.Migrations
b.Navigation("Computer"); b.Navigation("Computer");
}); });
modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Message", b =>
{
b.HasOne("ComputersShopDataBaseImplement.Models.Client", null)
.WithMany("Messages")
.HasForeignKey("ClientId");
});
modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Order", b => modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Order", b =>
{ {
b.HasOne("ComputersShopDataBaseImplement.Models.Client", "Client") b.HasOne("ComputersShopDataBaseImplement.Models.Client", "Client")
@ -232,6 +269,8 @@ namespace ComputersShopDataBaseImplement.Migrations
modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Client", b => modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Client", b =>
{ {
b.Navigation("Messages");
b.Navigation("Orders"); b.Navigation("Orders");
}); });

View File

@ -7,7 +7,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace ComputersShopDataBaseImplement.Migrations namespace ComputersShopDataBaseImplement.Migrations
{ {
/// <inheritdoc /> /// <inheritdoc />
public partial class InitialCreate : Migration public partial class InitCreate : Migration
{ {
/// <inheritdoc /> /// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
@ -71,6 +71,27 @@ namespace ComputersShopDataBaseImplement.Migrations
table.PrimaryKey("PK_Implementers", x => x.Id); table.PrimaryKey("PK_Implementers", x => x.Id);
}); });
migrationBuilder.CreateTable(
name: "Messages",
columns: table => new
{
MessageId = table.Column<string>(type: "text", nullable: false),
ClientId = table.Column<int>(type: "integer", nullable: true),
SenderName = table.Column<string>(type: "text", nullable: false),
DateDelivery = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
Subject = table.Column<string>(type: "text", nullable: false),
Body = table.Column<string>(type: "text", 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.CreateTable( migrationBuilder.CreateTable(
name: "ComputerComponents", name: "ComputerComponents",
columns: table => new columns: table => new
@ -145,6 +166,11 @@ namespace ComputersShopDataBaseImplement.Migrations
table: "ComputerComponents", table: "ComputerComponents",
column: "ComputerId"); column: "ComputerId");
migrationBuilder.CreateIndex(
name: "IX_Messages_ClientId",
table: "Messages",
column: "ClientId");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_Orders_ClientId", name: "IX_Orders_ClientId",
table: "Orders", table: "Orders",
@ -167,6 +193,9 @@ namespace ComputersShopDataBaseImplement.Migrations
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "ComputerComponents"); name: "ComputerComponents");
migrationBuilder.DropTable(
name: "Messages");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Orders"); name: "Orders");

View File

@ -140,6 +140,36 @@ namespace ComputersShopDataBaseImplement.Migrations
b.ToTable("Implementers"); b.ToTable("Implementers");
}); });
modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Message", b =>
{
b.Property<string>("MessageId")
.HasColumnType("text");
b.Property<string>("Body")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("ClientId")
.HasColumnType("integer");
b.Property<DateTime>("DateDelivery")
.HasColumnType("timestamp with time zone");
b.Property<string>("SenderName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Subject")
.IsRequired()
.HasColumnType("text");
b.HasKey("MessageId");
b.HasIndex("ClientId");
b.ToTable("Messages");
});
modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Order", b => modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Order", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")
@ -202,6 +232,13 @@ namespace ComputersShopDataBaseImplement.Migrations
b.Navigation("Computer"); b.Navigation("Computer");
}); });
modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Message", b =>
{
b.HasOne("ComputersShopDataBaseImplement.Models.Client", null)
.WithMany("Messages")
.HasForeignKey("ClientId");
});
modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Order", b => modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Order", b =>
{ {
b.HasOne("ComputersShopDataBaseImplement.Models.Client", "Client") b.HasOne("ComputersShopDataBaseImplement.Models.Client", "Client")
@ -229,6 +266,8 @@ namespace ComputersShopDataBaseImplement.Migrations
modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Client", b => modelBuilder.Entity("ComputersShopDataBaseImplement.Models.Client", b =>
{ {
b.Navigation("Messages");
b.Navigation("Orders"); b.Navigation("Orders");
}); });

View File

@ -28,6 +28,9 @@ namespace ComputersShopDataBaseImplement.Models
[ForeignKey("ClientId")] [ForeignKey("ClientId")]
public virtual List<Order> Orders { get; set; } = new(); public virtual List<Order> Orders { get; set; } = new();
[ForeignKey("ClientId")]
public virtual List<Message> Messages { get; set; } = new();
public static Client? Create(ClientBindingModel model) public static Client? Create(ClientBindingModel model)
{ {
if (model == null) if (model == null)

View File

@ -70,6 +70,7 @@ namespace ComputersShopDataBaseImplement.Models
ComputerId = ComputerId, ComputerId = ComputerId,
ClientId = ClientId, ClientId = ClientId,
ClientFIO = Client.ClientFIO, ClientFIO = Client.ClientFIO,
ClientEmail = Client.Email,
ImplementerId = ImplementerId, ImplementerId = ImplementerId,
ImplementerFIO = Implementer?.ImplementerFIO ?? string.Empty, ImplementerFIO = Implementer?.ImplementerFIO ?? string.Empty,
Count = Count, Count = Count,

View File

@ -18,6 +18,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="log4net.config"> <Content Update="log4net.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>

View File

@ -6,65 +6,85 @@ using Microsoft.AspNetCore.Mvc;
namespace ComputersShopRestApi.Controllers namespace ComputersShopRestApi.Controllers
{ {
[Route("api/[controller]/[action]")] [Route("api/[controller]/[action]")]
[ApiController] [ApiController]
public class ClientController : Controller public class ClientController : Controller
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IClientLogic _logic; private readonly IClientLogic _logic;
public ClientController(IClientLogic logic, ILogger<ClientController> logger) private readonly IMessageInfoLogic _mailLogic;
{
_logger = logger;
_logic = logic;
}
[HttpGet] public ClientController(IClientLogic logic, ILogger<ClientController> logger, IMessageInfoLogic mailLogic)
public ClientViewModel? Login(string login, string password) {
{ _logger = logger;
try _logic = logic;
{ _mailLogic = mailLogic;
return _logic.ReadElement(new ClientSearchModel }
{
Email = login,
Password = password
});
} [HttpGet]
catch (Exception ex) public ClientViewModel? Login(string login, string password)
{ {
_logger.LogError(ex, "Ошибка входа в систему"); try
throw; {
} return _logic.ReadElement(new ClientSearchModel
} {
Email = login,
Password = password
});
[HttpPost] }
public void Register(ClientBindingModel model) catch (Exception ex)
{ {
try _logger.LogError(ex, "Ошибка входа в систему");
{ throw;
_logic.Create(model); }
} }
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка регистрации");
throw;
}
}
[HttpPost] [HttpPost]
public void UpdateData(ClientBindingModel model) public void Register(ClientBindingModel model)
{ {
try try
{ {
_logic.Update(model); _logic.Create(model);
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка обновления данных"); _logger.LogError(ex, "Ошибка регистрации");
throw; throw;
} }
} }
}
[HttpPost]
public void UpdateData(ClientBindingModel model)
{
try
{
_logic.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления данных");
throw;
}
}
[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 ComputersShopBusinessLogic.BusinessLogics; using ComputersShopBusinessLogic.BusinessLogics;
using ComputersShopBusinessLogic.MailWorker;
using ComputersShopContracts.BindingModels;
using ComputersShopContracts.BusinessLogicContracts; using ComputersShopContracts.BusinessLogicContracts;
using ComputersShopContracts.StoragesContracts; using ComputersShopContracts.StoragesContracts;
using ComputersShopDataBaseImplement.Implements; using ComputersShopDataBaseImplement.Implements;
@ -11,34 +13,47 @@ builder.Logging.AddLog4Net("log4net.config");
// Add services to the container. // Add services to the container.
builder.Services.AddTransient<IClientStorage, ClientStorage>(); builder.Services.AddTransient<IClientStorage, ClientStorage>();
builder.Services.AddTransient<IImplementerStorage, ImplementerStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>(); builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IComputerStorage, ComputerStorage>(); builder.Services.AddTransient<IComputerStorage, ComputerStorage>();
builder.Services.AddTransient<IMessageInfoStorage, MessageInfoStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>(); builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IImplementerLogic, ImplementerLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>(); builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IComputerLogic, ComputerLogic>(); builder.Services.AddTransient<IComputerLogic, ComputerLogic>();
builder.Services.AddTransient<IMessageInfoLogic, MessageInfoLogic>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
builder.Services.AddControllers(); builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c => builder.Services.AddSwaggerGen(c =>
{ {
c.SwaggerDoc("v1", new OpenApiInfo c.SwaggerDoc("v1", new OpenApiInfo
{ {
Title = "ComputersShopRestApi", Title = "ComputersShopRestApi",
Version = "v1" Version = "v1"
}); });
}); });
var app = builder.Build(); 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. // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) if (app.Environment.IsDevelopment())
{ {
app.UseSwagger(); app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ComputersShopRestApi v1")); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ComputersShopRestApi v1"));
} }
app.UseHttpsRedirection(); app.UseHttpsRedirection();

View File

@ -11,6 +11,6 @@
"SmtpClientPort": "587", "SmtpClientPort": "587",
"PopHost": "pop.gmail.com", "PopHost": "pop.gmail.com",
"PopPort": "995", "PopPort": "995",
"MailLogin": "rpplabs24@gmail.com", "MailLogin": "rpplabs724@gmail.com",
"MailPassword": "qqwezxc2024" "MailPassword": "qqeqweeeq24zxc"
} }

View File

@ -5,7 +5,7 @@
<add key="SmtpClientPort" value="587" /> <add key="SmtpClientPort" value="587" />
<add key="PopHost" value="pop.gmail.com" /> <add key="PopHost" value="pop.gmail.com" />
<add key="PopPort" value="995" /> <add key="PopPort" value="995" />
<add key="MailLogin" value="rpplabs24@gmail.com" /> <add key="MailLogin" value="rpplabs724@gmail.com" />
<add key="MailPassword" value="qqwezxc2024" /> <add key="MailPassword" value="qqeqweeeq24zxc" />
</appSettings> </appSettings>
</configuration> </configuration>

View File

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