diff --git a/JewelryStore/JewelryStoreBusinessLogic/BusinessLogics/ClientLogic.cs b/JewelryStore/JewelryStoreBusinessLogic/BusinessLogics/ClientLogic.cs new file mode 100644 index 0000000..67e76e7 --- /dev/null +++ b/JewelryStore/JewelryStoreBusinessLogic/BusinessLogics/ClientLogic.cs @@ -0,0 +1,121 @@ +using JewelryStoreContracts.BindingModels; +using JewelryStoreContracts.BusinessLogicsContracts; +using JewelryStoreContracts.SearchModels; +using JewelryStoreContracts.StoragesContracts; +using JewelryStoreContracts.ViewModels; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JewelryStoreBusinessLogic.BusinessLogics +{ + public class ClientLogic : IClientLogic + { + private readonly ILogger _logger; + private readonly IClientStorage _clientStorage; + public ClientLogic(ILogger logger, IClientStorage clientStorage) + { + _logger = logger; + _clientStorage = clientStorage; + } + public bool Create(ClientBindingModel model) + { + CheckModel(model); + if (_clientStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + public bool Delete(ClientBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id: {Id}", model.Id); + if (_clientStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + + public ClientViewModel? ReadElement(ClientSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. ClientFIO: {ClientFIO}. Email: {Email}. Id: {Id}.", model.ClientFIO, model.Email, model.Id); + var element = _clientStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id: {Id}", element.Id); + return element; + } + + public List? ReadList(ClientSearchModel? model) + { + _logger.LogInformation("ReadList. ClientFIO: {ClientName}. Email: {Email}. Id: {Id}.", model?.ClientFIO, model?.Email, model?.Id); + var list = model == null ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count: {Count}", list.Count); + return list; + } + + public bool Update(ClientBindingModel model) + { + CheckModel(model); + if (_clientStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + + private void CheckModel(ClientBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.ClientFIO)) + { + throw new ArgumentNullException("Нет ФИО клиента", nameof(model.ClientFIO)); + } + if (string.IsNullOrEmpty(model.Email)) + { + throw new ArgumentNullException("Нет почты клиента", nameof(model.Email)); + } + if (string.IsNullOrEmpty(model.Password)) + { + throw new ArgumentNullException("Нет пароля клиента", nameof(model.Password)); + } + _logger.LogInformation("Client. ClientFIO: {ClientFIO}. Email: {Email}. Id: {Id}", model.ClientFIO, model.Email, model.Id); + var element = _clientStorage.GetElement(new ClientSearchModel + { + Email = model.Email + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Клиент с такой почтой уже есть"); + } + } + } +} diff --git a/JewelryStore/JewelryStoreRestApi/Controllers/ClientController.cs b/JewelryStore/JewelryStoreRestApi/Controllers/ClientController.cs new file mode 100644 index 0000000..5aad241 --- /dev/null +++ b/JewelryStore/JewelryStoreRestApi/Controllers/ClientController.cs @@ -0,0 +1,68 @@ +using JewelryStoreContracts.BindingModels; +using JewelryStoreContracts.BusinessLogicsContracts; +using JewelryStoreContracts.SearchModels; +using JewelryStoreContracts.ViewModels; +using Microsoft.AspNetCore.Mvc; + +namespace JewelryStoreRestApi.Controllers +{ + [Route("api/[controller]/[action]")] + [ApiController] + public class ClientController : Controller + { + private readonly ILogger _logger; + private readonly IClientLogic _logic; + + public ClientController(IClientLogic logic, ILogger logger) + { + _logger = logger; + _logic = logic; + } + + [HttpGet] + public ClientViewModel? Login(string login, string password) + { + try + { + return _logic.ReadElement(new ClientSearchModel + { + Email = login, + Password = password + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка входа в систему"); + throw; + } + } + + [HttpPost] + public void Register(ClientBindingModel model) + { + try + { + _logic.Create(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка регистрации"); + throw; + } + } + + [HttpPost] + public void UpdateData(ClientBindingModel model) + { + try + { + _logic.Update(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка обновления данных"); + throw; + } + } + } +} diff --git a/JewelryStore/JewelryStoreRestApi/Controllers/MainController.cs b/JewelryStore/JewelryStoreRestApi/Controllers/MainController.cs new file mode 100644 index 0000000..ec8eebf --- /dev/null +++ b/JewelryStore/JewelryStoreRestApi/Controllers/MainController.cs @@ -0,0 +1,86 @@ +using JewelryStoreContracts.BindingModels; +using JewelryStoreContracts.BusinessLogicsContracts; +using JewelryStoreContracts.SearchModels; +using JewelryStoreContracts.ViewModels; +using Microsoft.AspNetCore.Mvc; + +namespace JewelryStoreRestApi.Controllers +{ + [Route("api/[controller]/[action]")] + [ApiController] + public class MainController : Controller + { + private readonly ILogger _logger; + private readonly IOrderLogic _order; + private readonly IJewelLogic _jewel; + + public MainController(ILogger logger, IOrderLogic order, IJewelLogic jewel) + { + _logger = logger; + _order = order; + _jewel = jewel; + } + + [HttpGet] + public List? GetJewelList() + { + try + { + return _jewel.ReadList(null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения списка продуктов"); + throw; + } + } + + [HttpGet] + public JewelViewModel? GetJewel(int jewelId) + { + try + { + return _jewel.ReadElement(new JewelSearchModel + { + Id = jewelId + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения продукта по id={Id}", jewelId); + throw; + } + } + + [HttpGet] + public List? GetOrders(int clientId) + { + try + { + return _order.ReadList(new OrderSearchModel + { + ClientId = clientId + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения списка заказов клиента id ={ Id}", clientId); + throw; + } + } + + [HttpPost] + public void CreateOrder(OrderBindingModel model) + { + try + { + _order.CreateOrder(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка создания заказа"); + throw; + } + } + } +} diff --git a/JewelryStore/JewelryStoreRestApi/JewelryStoreRestApi.csproj b/JewelryStore/JewelryStoreRestApi/JewelryStoreRestApi.csproj new file mode 100644 index 0000000..bc3e9ff --- /dev/null +++ b/JewelryStore/JewelryStoreRestApi/JewelryStoreRestApi.csproj @@ -0,0 +1,20 @@ + + + + net7.0 + enable + enable + + + + + + + + + + + + + + diff --git a/JewelryStore/JewelryStoreRestApi/Program.cs b/JewelryStore/JewelryStoreRestApi/Program.cs new file mode 100644 index 0000000..030810e --- /dev/null +++ b/JewelryStore/JewelryStoreRestApi/Program.cs @@ -0,0 +1,47 @@ +using JewelryStoreBusinessLogic.BusinessLogics; +using JewelryStoreContracts.BusinessLogicsContracts; +using JewelryStoreContracts.StoragesContracts; +using JewelryStoreDatabaseImplement.Implements; +using Microsoft.OpenApi.Models; + +var builder = WebApplication.CreateBuilder(args); + +builder.Logging.SetMinimumLevel(LogLevel.Trace); +builder.Logging.AddLog4Net("log4net.config"); + +// Add services to the container. + +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); + +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); + + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(c => +{ + c.SwaggerDoc("v1", new OpenApiInfo { Title = "JewelryStoreRestApi", Version = "v1" }); +}); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "JewelryStoreRestApi v1")); +} + + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/JewelryStore/JewelryStoreRestApi/Properties/launchSettings.json b/JewelryStore/JewelryStoreRestApi/Properties/launchSettings.json new file mode 100644 index 0000000..64d8134 --- /dev/null +++ b/JewelryStore/JewelryStoreRestApi/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:16817", + "sslPort": 44384 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5278", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7170;http://localhost:5278", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/JewelryStore/JewelryStoreRestApi/appsettings.Development.json b/JewelryStore/JewelryStoreRestApi/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/JewelryStore/JewelryStoreRestApi/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/JewelryStore/JewelryStoreRestApi/appsettings.json b/JewelryStore/JewelryStoreRestApi/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/JewelryStore/JewelryStoreRestApi/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/JewelryStore/JewelryStoreRestApi/log4net.config b/JewelryStore/JewelryStoreRestApi/log4net.config new file mode 100644 index 0000000..d31db1e --- /dev/null +++ b/JewelryStore/JewelryStoreRestApi/log4net.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/JewelryStore/JewerlyStoreView/JewerlyStoreView.sln b/JewelryStore/JewerlyStoreView/JewerlyStoreView.sln index 097522b..91dabb9 100644 --- a/JewelryStore/JewerlyStoreView/JewerlyStoreView.sln +++ b/JewelryStore/JewerlyStoreView/JewerlyStoreView.sln @@ -17,6 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JewerlyStoreFileImplement", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JewerlyStoreView", "JewerlyStoreView.csproj", "{2A784D25-F667-471A-A320-0EF04F57953B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JewelryStoreRestApi", "..\JewelryStoreRestApi\JewelryStoreRestApi.csproj", "{71980C93-4E25-47EC-8C0C-6763205425DD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,8 +53,15 @@ Global {2A784D25-F667-471A-A320-0EF04F57953B}.Debug|Any CPU.Build.0 = Debug|Any CPU {2A784D25-F667-471A-A320-0EF04F57953B}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A784D25-F667-471A-A320-0EF04F57953B}.Release|Any CPU.Build.0 = Release|Any CPU + {71980C93-4E25-47EC-8C0C-6763205425DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {71980C93-4E25-47EC-8C0C-6763205425DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {71980C93-4E25-47EC-8C0C-6763205425DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {71980C93-4E25-47EC-8C0C-6763205425DD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5DE84A94-D0E2-45FB-8EDF-F71BE634BD89} + EndGlobalSection EndGlobal