переделала всё нафиг

This commit is contained in:
revengel66 2024-05-22 01:01:59 +03:00
parent 11d78175cd
commit 648a139ca7
36 changed files with 682 additions and 576 deletions

View File

@ -17,12 +17,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PizzeriaFileImplement", "Pi
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PizzeriaDatabaseImplement", "PizzeriaDatabaseImplement\PizzeriaDatabaseImplement.csproj", "{31FC8CAC-BED8-4DF0-8B57-20917DC66A5C}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PizzeriaDatabaseImplement", "PizzeriaDatabaseImplement\PizzeriaDatabaseImplement.csproj", "{31FC8CAC-BED8-4DF0-8B57-20917DC66A5C}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PizzeriaClientApp", "PizzeriaClientApp\PizzeriaClientApp.csproj", "{431FCB4B-6315-4FC3-A88A-9ECFBF1D3763}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PizzeriaRestApi", "PizzeriaRestApi\PizzeriaRestApi.csproj", "{82A572AA-ADBB-4D09-ACD0-5DFFC796A7E0}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PizzeriaRestApi", "PizzeriaRestApi2\PizzeriaRestApi.csproj", "{DB5EBCD0-2BBF-4EDB-A59F-CA2F0496C56F}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PizzeriaClientApp", "PizzeriaClientApp\PizzeriaClientApp.csproj", "{355A354A-BF2C-4478-A889-1FDA57F12FBC}"
ProjectSection(ProjectDependencies) = postProject
{31FC8CAC-BED8-4DF0-8B57-20917DC66A5C} = {31FC8CAC-BED8-4DF0-8B57-20917DC66A5C}
EndProjectSection
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -58,14 +55,14 @@ Global
{31FC8CAC-BED8-4DF0-8B57-20917DC66A5C}.Debug|Any CPU.Build.0 = Debug|Any CPU {31FC8CAC-BED8-4DF0-8B57-20917DC66A5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31FC8CAC-BED8-4DF0-8B57-20917DC66A5C}.Release|Any CPU.ActiveCfg = Release|Any CPU {31FC8CAC-BED8-4DF0-8B57-20917DC66A5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31FC8CAC-BED8-4DF0-8B57-20917DC66A5C}.Release|Any CPU.Build.0 = Release|Any CPU {31FC8CAC-BED8-4DF0-8B57-20917DC66A5C}.Release|Any CPU.Build.0 = Release|Any CPU
{431FCB4B-6315-4FC3-A88A-9ECFBF1D3763}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {82A572AA-ADBB-4D09-ACD0-5DFFC796A7E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{431FCB4B-6315-4FC3-A88A-9ECFBF1D3763}.Debug|Any CPU.Build.0 = Debug|Any CPU {82A572AA-ADBB-4D09-ACD0-5DFFC796A7E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{431FCB4B-6315-4FC3-A88A-9ECFBF1D3763}.Release|Any CPU.ActiveCfg = Release|Any CPU {82A572AA-ADBB-4D09-ACD0-5DFFC796A7E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{431FCB4B-6315-4FC3-A88A-9ECFBF1D3763}.Release|Any CPU.Build.0 = Release|Any CPU {82A572AA-ADBB-4D09-ACD0-5DFFC796A7E0}.Release|Any CPU.Build.0 = Release|Any CPU
{DB5EBCD0-2BBF-4EDB-A59F-CA2F0496C56F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {355A354A-BF2C-4478-A889-1FDA57F12FBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DB5EBCD0-2BBF-4EDB-A59F-CA2F0496C56F}.Debug|Any CPU.Build.0 = Debug|Any CPU {355A354A-BF2C-4478-A889-1FDA57F12FBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB5EBCD0-2BBF-4EDB-A59F-CA2F0496C56F}.Release|Any CPU.ActiveCfg = Release|Any CPU {355A354A-BF2C-4478-A889-1FDA57F12FBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB5EBCD0-2BBF-4EDB-A59F-CA2F0496C56F}.Release|Any CPU.Build.0 = Release|Any CPU {355A354A-BF2C-4478-A889-1FDA57F12FBC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -28,6 +28,7 @@ namespace Pizzeria
{ {
dataGridView.DataSource = list; dataGridView.DataSource = list;
dataGridView.Columns["PizzaId"].Visible = false; dataGridView.Columns["PizzaId"].Visible = false;
dataGridView.Columns["ClientId"].Visible = false;
dataGridView.Columns["PizzaName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; dataGridView.Columns["PizzaName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
} }
_logger.LogInformation("Загрузка заказов"); _logger.LogInformation("Загрузка заказов");

View File

@ -7,113 +7,113 @@ using PizzeriaContracts.ViewModels;
namespace PizzeriaBusinessLogic.BusinessLogic namespace PizzeriaBusinessLogic.BusinessLogic
{ {
public class ClientLogic : IClientLogic public class ClientLogic : IClientLogic
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IClientStorage _clientStorage;
private readonly IClientStorage _clientStorage; public ClientLogic(ILogger<ClientLogic> logger, IClientStorage clientStorage)
{
_logger = logger;
_clientStorage = clientStorage;
}
public ClientLogic(ILogger<ClientLogic> logger, IClientStorage clientStorage) public List<ClientViewModel>? ReadList(ClientSearchModel? model)
{ {
_logger = logger; _logger.LogInformation("ReadList. ClientId:{Id}", model?.Id);
_clientStorage = clientStorage; 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 List<ClientViewModel>? ReadList(ClientSearchModel? model) public ClientViewModel? ReadElement(ClientSearchModel model)
{ {
_logger.LogInformation("ReadList. Email: {Email}. Id: {Id} ", model?.Email, model?.Id); if (model == null)
var list = (model == null) ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model); {
if (list == null) throw new ArgumentNullException(nameof(model));
{ }
_logger.LogWarning("ReadList return null list"); _logger.LogInformation("ReadElement. ClientFio:{ClientFio}.Id:{ Id}", model.ClientFIO, model.Id);
return null; var element = _clientStorage.GetElement(model);
} if (element == null)
_logger.LogInformation("ReadList. Count: {Count}", list.Count); {
return list; _logger.LogWarning("ReadElement element not found");
} return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public ClientViewModel? ReadElement(ClientSearchModel model) public bool Create(ClientBindingModel model)
{ {
if (model == null) CheckModel(model);
{ if (_clientStorage.Insert(model) == null)
throw new ArgumentNullException(nameof(model)); {
} _logger.LogWarning("Insert operation failed");
_logger.LogInformation("ReadElement. Client email: {Email}. Client id: {Id}", model.Email, model.Id); return false;
var element = _clientStorage.GetElement(model); }
if (element == null) return true;
{ }
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id: {Id}", element.Id);
return element;
}
public bool Create(ClientBindingModel model) public bool Update(ClientBindingModel model)
{ {
CheckModel(model); CheckModel(model);
if (_clientStorage.Insert(model) == null) if (_clientStorage.Update(model) == null)
{ {
_logger.LogWarning("Insert operation failed"); _logger.LogWarning("Update operation failed");
return false; return false;
} }
return true; return true;
} }
public bool Update(ClientBindingModel model) public bool Delete(ClientBindingModel model)
{ {
CheckModel(model); CheckModel(model, false);
if (_clientStorage.Update(model) == null) _logger.LogInformation("Delete. Id:{Id}", model.Id);
{ if (_clientStorage.Delete(model) == null)
_logger.LogWarning("Update operation failed"); {
return false; _logger.LogWarning("Delete operation failed");
} return false;
return true; }
} return true;
}
public bool Delete(ClientBindingModel model) private void CheckModel(ClientBindingModel model, bool withParams = true)
{ {
CheckModel(model, false); if (model == null)
_logger.LogInformation("Delete. Id: {Id}", model.Id); {
if (_clientStorage.Delete(model) == null) throw new ArgumentNullException(nameof(model));
{ }
_logger.LogWarning("Delete operation failed"); if (!withParams)
return false; {
} return;
return true; }
} if (string.IsNullOrEmpty(model.ClientFIO))
{
private void CheckModel(ClientBindingModel model, bool withParams = true) throw new ArgumentNullException("Нет ФИО пользователя", nameof(model.ClientFIO));
{ }
if (model == null) if (string.IsNullOrEmpty(model.Email))
{ {
throw new ArgumentNullException(nameof(model)); throw new ArgumentNullException("Нет почты пользователя", nameof(model.Email));
} }
if (!withParams) if (string.IsNullOrEmpty(model.Password))
{ {
return; throw new ArgumentNullException("Нет пароля пользователя", nameof(model.Password));
} }
if (string.IsNullOrEmpty(model.ClientFIO)) _logger.LogInformation("Client. ClientFIO:{ClientFIO}.Email:{Email}.Password:{Password}.Id:{Id}",
{ model.ClientFIO, model.Email, model.Password, model.Id);
throw new ArgumentNullException("Нет ФИО клиента", nameof(model.ClientFIO)); var element = _clientStorage.GetElement(new ClientSearchModel
} {
if (string.IsNullOrEmpty(model.Email)) ClientFIO = model.ClientFIO
{ });
throw new ArgumentNullException("Нет логина(почты) клиента", nameof(model.Email)); if (element != null && element.Id != model.Id)
} {
if (string.IsNullOrEmpty(model.Password)) throw new InvalidOperationException("Клиент с таким именем уже есть");
{ }
throw new ArgumentNullException("Нет пароля клиента", nameof(model.Password)); }
} }
_logger.LogInformation("Client. Id: {id}, FIO: {fio}, email: {email}, password: {password}", model.Id, model.ClientFIO, model.Email, model.Password);
var element = _clientStorage.GetElement(new ClientSearchModel
{
Email = model.Email
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Клиент с таким логином(почтой) уже есть");
}
}
}
} }

View File

@ -1,47 +1,49 @@
using System.Net.Http.Headers; using Newtonsoft.Json;
using System.Text;
using Newtonsoft.Json;
using PizzeriaContracts.ViewModels; using PizzeriaContracts.ViewModels;
using System.Net.Http.Headers;
using System.Text;
namespace PizzeriaClientApp namespace PizzeriaClientApp
{ {
public static class APIClient public class APIClient
{ {
private static readonly HttpClient _client = new(); private static readonly HttpClient _client = new();
public static ClientViewModel? Client { get; set; } = null;
public static void Connect(IConfiguration configuration)
{
_client.BaseAddress = new Uri(configuration["IPAddress"]);
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
}
public static T? GetRequest<T>(string requestUrl)
{
var response = _client.GetAsync(requestUrl);
var result = response.Result.Content.ReadAsStringAsync().Result;
if (response.Result.IsSuccessStatusCode)
{
return JsonConvert.DeserializeObject<T>(result);
}
else
{
throw new Exception(result);
}
}
public static void PostRequest<T>(string requestUrl, T model)
{
var json = JsonConvert.SerializeObject(model);
var data = new StringContent(json, Encoding.UTF8, "application/json");
var response = _client.PostAsync(requestUrl, data);
var result = response.Result.Content.ReadAsStringAsync().Result;
if (!response.Result.IsSuccessStatusCode)
{
throw new Exception(result);
}
}
}
public static ClientViewModel? Client { get; set; } = null;
public static void Connect(IConfiguration configuration)
{
_client.BaseAddress = new Uri(configuration["IPAddress"]);
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public static T? GetRequest<T>(string requestUrl)
{
var response = _client.GetAsync(requestUrl);
var result = response.Result.Content.ReadAsStringAsync().Result;
if (response.Result.IsSuccessStatusCode)
{
return JsonConvert.DeserializeObject<T>(result);
}
else
{
throw new Exception(result);
}
}
public static void PostRequest<T>(string requestUrl, T model)
{
var json = JsonConvert.SerializeObject(model);
var data = new StringContent(json, Encoding.UTF8, "application/json");
var response = _client.PostAsync(requestUrl, data);
var result = response.Result.Content.ReadAsStringAsync().Result;
if (!response.Result.IsSuccessStatusCode)
{
throw new Exception(result);
}
}
}
} }

View File

@ -1,150 +1,147 @@
using System.Diagnostics; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc;
using PizzeriaClientApp.Models; using PizzeriaClientApp.Models;
using PizzeriaContracts.BindingModels; using PizzeriaContracts.BindingModels;
using PizzeriaContracts.ViewModels; using PizzeriaContracts.ViewModels;
using System.Diagnostics;
namespace PizzeriaClientApp.Controllers namespace PizzeriaClientApp.Controllers
{ {
public class HomeController : Controller public class HomeController : Controller
{ {
private readonly ILogger<HomeController> _logger; private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return
View(APIClient.GetRequest<List<OrderViewModel>>($"api/main/getorders?clientId={APIClient.Client.Id}"));
}
[HttpGet]
public IActionResult Privacy()
{
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.Client);
}
[HttpPost]
public void Privacy(string login, string password, string fio)
{
if (APIClient.Client == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
if (string.IsNullOrEmpty(login) ||
string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Введите логин, пароль и ФИО");
}
APIClient.PostRequest("api/client/updatedata", new
ClientBindingModel
{
Id = APIClient.Client.Id,
ClientFIO = fio,
Email = login,
Password = password
});
APIClient.Client.ClientFIO = fio;
APIClient.Client.Email = login;
APIClient.Client.Password = password;
Response.Redirect("Index");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None,
NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel
{
RequestId =
Activity.Current?.Id ?? HttpContext.TraceIdentifier
});
}
[HttpGet]
public IActionResult Enter()
{
return View();
}
[HttpPost]
public void Enter(string login, string password)
{
if (string.IsNullOrEmpty(login) ||
string.IsNullOrEmpty(password))
{
throw new Exception("Введите логин и пароль");
}
APIClient.Client =
APIClient.GetRequest<ClientViewModel>($"api/client/login?login={login}&password={password}");
if (APIClient.Client == null)
{
throw new Exception("Неверный логин/пароль");
}
Response.Redirect("Index");
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public void Register(string login, string password, string fio)
{
if (string.IsNullOrEmpty(login) ||
string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Введите логин, пароль и ФИО");
}
APIClient.PostRequest("api/client/register", new ClientBindingModel
{
ClientFIO = fio,
Email = login,
Password = password
});
Response.Redirect("Enter");
return;
}
[HttpGet]
public IActionResult Create()
{
ViewBag.Pizzas =
APIClient.GetRequest<List<PizzaViewModel>>("api/main/getproductlist");
return View();
}
[HttpPost]
public void Create(int product, int count)
{
if (APIClient.Client == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
if (count <= 0)
{
throw new Exception("Количество и сумма должны быть больше 0");
}
APIClient.PostRequest("api/main/createorder", new
OrderBindingModel
{
ClientId = APIClient.Client.Id,
PizzaId = product,
Count = count,
Sum = Calc(count, product)
});
Response.Redirect("Index");
}
[HttpPost]
public double Calc(int count, int product)
{
var prod =
APIClient.GetRequest<PizzaViewModel>($"api/main/getproduct?productId={product}"
);
return count * (prod?.Price ?? 1);
}
}
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.GetRequest<List<OrderViewModel>>($"api/main/getorders?clientId={APIClient.Client.Id}"));
}
[HttpGet]
public IActionResult Privacy()
{
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.Client);
}
[HttpPost]
public void Privacy(string login, string password, string fio)
{
if (APIClient.Client == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Введите логин, пароль и ФИО");
}
APIClient.PostRequest("api/client/updatedata", new ClientBindingModel
{
Id = APIClient.Client.Id,
ClientFIO = fio,
Email = login,
Password = password
});
APIClient.Client.ClientFIO = fio;
APIClient.Client.Email = login;
APIClient.Client.Password = password;
Response.Redirect("Index");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
[HttpGet]
public IActionResult Enter()
{
return View();
}
[HttpPost]
public void Enter(string login, string password)
{
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password))
{
throw new Exception("Введите логин и пароль");
}
APIClient.Client = APIClient.GetRequest<ClientViewModel>($"api/client/login?login={login}&password={password}");
if (APIClient.Client == null)
{
throw new Exception("Неверный логин/пароль");
}
Response.Redirect("Index");
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public void Register(string login, string password, string fio)
{
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
{
throw new Exception("Введите логин, пароль и ФИО");
}
APIClient.PostRequest("api/client/register", new ClientBindingModel
{
ClientFIO = fio,
Email = login,
Password = password
});
Response.Redirect("Enter");
return;
}
[HttpGet]
public IActionResult Create()
{
ViewBag.Pizzas = APIClient.GetRequest<List<PizzaViewModel>>("api/main/getpizzalist");
return View();
}
[HttpPost]
public void Create(int pizza, int count)
{
if (APIClient.Client == null)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
if (count <= 0)
{
throw new Exception("Количество и сумма должны быть больше 0");
}
APIClient.PostRequest("api/main/createorder", new OrderBindingModel
{
ClientId = APIClient.Client.Id,
PizzaId = pizza,
Count = count,
Sum = Calc(count, pizza)
});
Response.Redirect("Index");
}
[HttpPost]
public double Calc(int count, int pizza)
{
var piz = APIClient.GetRequest<PizzaViewModel>($"api/main/getpizza?pizzaId={pizza}");
return count * (piz?.Price ?? 1);
}
}
} }

View File

@ -1,9 +1,9 @@
namespace PizzeriaClientApp.Models namespace PizzeriaClientApp.Models
{ {
public class ErrorViewModel public class ErrorViewModel
{ {
public string? RequestId { get; set; } public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
} }
} }

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,3 +1,5 @@
using PizzeriaClientApp;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
// Add services to the container. // Add services to the container.
@ -5,6 +7,8 @@ builder.Services.AddControllersWithViews();
var app = builder.Build(); var app = builder.Build();
APIClient.Connect(builder.Configuration);
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment()) if (!app.Environment.IsDevelopment())
{ {
@ -14,6 +18,7 @@ if (!app.Environment.IsDevelopment())
} }
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.UseStaticFiles(); app.UseStaticFiles();
app.UseRouting(); app.UseRouting();
@ -24,4 +29,4 @@ app.MapControllerRoute(
name: "default", name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}"); pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run(); app.Run();

View File

@ -3,8 +3,8 @@
"windowsAuthentication": false, "windowsAuthentication": false,
"anonymousAuthentication": true, "anonymousAuthentication": true,
"iisExpress": { "iisExpress": {
"applicationUrl": "http://localhost:24003", "applicationUrl": "http://localhost:36182",
"sslPort": 44310 "sslPort": 44316
} }
}, },
"profiles": { "profiles": {
@ -12,7 +12,7 @@
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true, "dotnetRunMessages": true,
"launchBrowser": true, "launchBrowser": true,
"applicationUrl": "https://localhost:7112;http://localhost:5283", "applicationUrl": "https://localhost:7098;http://localhost:5179",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }

View File

@ -8,43 +8,39 @@
<div class="row"> <div class="row">
<div class="col-4">Изделие:</div> <div class="col-4">Изделие:</div>
<div class="col-8"> <div class="col-8">
<select id="product" name="product" class="form-control" aspitems="@(new SelectList(@ViewBag.Pizzas,"Id", "PizzaName"))"></select> <select id="pizza" name="pizza" class="form-control" asp-items="@(new SelectList(@ViewBag.Pizzas,"Id", "PizzaName"))"></select>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-4">Количество:</div> <div class="col-4">Количество:</div>
<div class="col-8"> <div class="col-8"><input type="text" name="count" id="count" /></div>
<input type="text" name="count" id="count" />
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-4">Сумма:</div> <div class="col-4">Сумма:</div>
<div class="col-8"> <div class="col-8"><input type="text" id="sum" name="sum" readonly /></div>
<input type="text" id="sum" name="sum" readonly />
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-8"></div> <div class="col-8"></div>
<div class="col-4"> <div class="col-4"><input type="submit" value="Создать" class="btn btn-primary" /></div>
<input type="submit" value="Создать" class="btn btn-primary" />
</div>
</div> </div>
</form> </form>
<script> <script>
$('#product').on('change', function () { $('#pizza').on('change', function () {
check(); check();
}); });
$('#count').on('change', function () { $('#count').on('change', function () {
check(); check();
}); });
function check() { function check() {
var count = $('#count').val(); var count = $('#count').val();
var product = $('#product').val(); var pizza = $('#pizza').val();
if (count && product) { if (count && pizza) {
$.ajax({ $.ajax({
method: "POST", method: "POST",
url: "/Home/Calc", url: "/Home/Calc",
data: { count: count, product: product }, data: { count: count, pizza: pizza },
success: function (result) { success: function (result) {
$("#sum").val(result); $("#sum").val(result);
} }

View File

@ -1,6 +1,7 @@
@{ @{
ViewData["Title"] = "Enter"; ViewData["Title"] = "Enter";
} }
<div class="text-center"> <div class="text-center">
<h2 class="display-4">Вход в приложение</h2> <h2 class="display-4">Вход в приложение</h2>
</div> </div>
@ -15,6 +16,6 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-8"></div> <div class="col-8"></div>
<div class="col-4"><input type="submit" value="Вход" class="btn btnprimary" /></div> <div class="col-4"><input type="submit" value="Вход" class="btn btn-primary" /></div>
</div> </div>
</form> </form>

View File

@ -1,11 +1,16 @@
@using PizzeriaContracts.ViewModels @using PizzeriaContracts.ViewModels
@model List<OrderViewModel> @model List<OrderViewModel>
@{ @{
ViewData["Title"] = "Home Page"; ViewData["Title"] = "Home Page";
} }
<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) if (Model == null)
@ -13,6 +18,7 @@
<h3 class="display-4">Авторизируйтесь</h3> <h3 class="display-4">Авторизируйтесь</h3>
return; return;
} }
<p> <p>
<a asp-action="Create">Создать заказ</a> <a asp-action="Create">Создать заказ</a>
</p> </p>
@ -23,7 +29,7 @@
Номер Номер
</th> </th>
<th> <th>
Изделие Пицца
</th> </th>
<th> <th>
Дата создания Дата создания

View File

@ -1,5 +1,7 @@
@using PizzeriaContracts.ViewModels @using PizzeriaContracts.ViewModels
@model ClientViewModel @model ClientViewModel
@{ @{
ViewData["Title"] = "Privacy Policy"; ViewData["Title"] = "Privacy Policy";
} }
@ -9,26 +11,18 @@
<form method="post"> <form method="post">
<div class="row"> <div class="row">
<div class="col-4">Логин:</div> <div class="col-4">Логин:</div>
<div class="col-8"> <div class="col-8"><input type="text" name="login" value="@Model.Email" /></div>
<input type="text" name="login" value="@Model.Email" />
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-4">Пароль:</div> <div class="col-4">Пароль:</div>
<div class="col-8"> <div class="col-8"><input type="password" name="password" value="@Model.Password" /></div>
<input type="password" name="password" value="@Model.Password" />
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-4">ФИО:</div> <div class="col-4">ФИО:</div>
<div class="col-8"> <div class="col-8"><input type="text" name="fio" value="@Model.ClientFIO" /></div>
<input type="text" name="fio" value="@Model.ClientFIO" />
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-8"></div> <div class="col-8"></div>
<div class="col-4"> <div class="col-4"><input type="submit" value="Сохранить" class="btn btn-primary" /></div>
<input type="submit" value="Сохранить" class="btn btn-primary" />
</div>
</div> </div>
</form> </form>

View File

@ -1,6 +1,7 @@
@{ @{
ViewData["Title"] = "Register"; ViewData["Title"] = "Register";
} }
<div class="text-center"> <div class="text-center">
<h2 class="display-4">Регистрация</h2> <h2 class="display-4">Регистрация</h2>
</div> </div>
@ -19,8 +20,6 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-8"></div> <div class="col-8"></div>
<div class="col-4"> <div class="col-4"><input type="submit" value="Регистрация" class="btn btn-primary" /></div>
<input type="submit" value="Регистрация" class="btn btn-primary" />
</div>
</div> </div>
</form> </form>

View File

@ -12,24 +12,24 @@
<header> <header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3"> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid"> <div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" aspaction="Index">Пиццерия</a> <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Пиццерия</a>
<button class="navbar-toggler" type="button" datatoggle="collapse" data-target=".navbar-collapse" ariacontrols="navbarSupportedContent" <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation"> aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-smrow-reverse"> <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1"> <ul class="navbar-nav flex-grow-1">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Index">Заказы</a> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Заказы</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Enter">Вход</a> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Enter">Вход</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link text-dark" asparea="" asp-controller="Home" asp-action="Register">Регистрация</a> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Register">Регистрация</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -44,7 +44,7 @@
<footer class="border-top footer text-muted"> <footer class="border-top footer text-muted">
<div class="container"> <div class="container">
&copy; 2024 - PizzeriaClientApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a> &copy; 2023 - PizzeriaClientApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div> </div>
</footer> </footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/jquery/dist/jquery.min.js"></script>

View File

@ -2,47 +2,48 @@
for details on configuring this project to bundle and minify static web assets. */ for details on configuring this project to bundle and minify static web assets. */
a.navbar-brand { a.navbar-brand {
white-space: normal; white-space: normal;
text-align: center; text-align: center;
word-break: break-all; word-break: break-all;
} }
a { a {
color: #0077cc; color: #0077cc;
} }
.btn-primary { .btn-primary {
color: #fff; color: #fff;
background-color: #1b6ec2; background-color: #1b6ec2;
border-color: #1861ac; border-color: #1861ac;
} }
.nav-pills .nav-link.active, .nav-pills .show > .nav-link { .nav-pills .nav-link.active, .nav-pills .show > .nav-link {
color: #fff; color: #fff;
background-color: #1b6ec2; background-color: #1b6ec2;
border-color: #1861ac; border-color: #1861ac;
} }
.border-top { .border-top {
border-top: 1px solid #e5e5e5; border-top: 1px solid #e5e5e5;
} }
.border-bottom { .border-bottom {
border-bottom: 1px solid #e5e5e5; border-bottom: 1px solid #e5e5e5;
} }
.box-shadow { .box-shadow {
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
} }
button.accept-policy { button.accept-policy {
font-size: 1rem; font-size: 1rem;
line-height: inherit; line-height: inherit;
} }
.footer { .footer {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
white-space: nowrap; white-space: nowrap;
line-height: 60px; line-height: 60px;
} }

View File

@ -1,10 +1,10 @@
{ {
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Information",
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"IPAddress": "http://localhost:5283/" "IPAddress": "http://localhost:5175/"
} }

View File

@ -9,4 +9,5 @@ namespace PizzeriaContracts.BindingModels
public string Email { get; set; } = string.Empty; public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty; public string Password { get; set; } = string.Empty;
} }
}
}

View File

@ -1,6 +1,7 @@
using PizzeriaContracts.BindingModels; using PizzeriaContracts.BindingModels;
using PizzeriaContracts.SearchModels;
using PizzeriaContracts.ViewModels; using PizzeriaContracts.ViewModels;
using PizzeriaContracts.SearchModels;
namespace PizzeriaContracts.BusinessLogicsContracts namespace PizzeriaContracts.BusinessLogicsContracts
{ {
public interface IClientLogic public interface IClientLogic
@ -11,4 +12,4 @@ namespace PizzeriaContracts.BusinessLogicsContracts
bool Update(ClientBindingModel model); bool Update(ClientBindingModel model);
bool Delete(ClientBindingModel model); bool Delete(ClientBindingModel model);
} }
} }

View File

@ -3,8 +3,11 @@
public class ClientSearchModel public class ClientSearchModel
{ {
public int? Id { get; set; } public int? Id { get; set; }
public string? ClientFIO { get; set; } public string? ClientFIO { get; set; }
public string? Email { get; set; } public string? Email { get; set; }
public string? Password { get; set; } public string? Password { get; set; }
} }
} }

View File

@ -12,6 +12,7 @@ namespace PizzeriaContracts.ViewModels
[DisplayName("Пицца")] [DisplayName("Пицца")]
public string PizzaName { get; set; } = string.Empty; public string PizzaName { get; set; } = string.Empty;
public int ClientId { get; set; } public int ClientId { get; set; }
[DisplayName("ФИО клиента")] [DisplayName("ФИО клиента")]

View File

@ -3,7 +3,9 @@
public interface IClientModel : IId public interface IClientModel : IId
{ {
string ClientFIO { get; } string ClientFIO { get; }
string Email { get; } string Email { get; }
string Password { get; } string Password { get; }
} }

View File

@ -1,10 +1,11 @@
using PizzeriaContracts.BindingModels; using System.Collections.Generic;
using System.Linq;
using PizzeriaContracts.BindingModels;
using PizzeriaContracts.SearchModels; using PizzeriaContracts.SearchModels;
using PizzeriaContracts.StorageContracts; using PizzeriaContracts.StorageContracts;
using PizzeriaContracts.ViewModels; using PizzeriaContracts.ViewModels;
using PizzeriaDatabaseImplement.Models; using PizzeriaDatabaseImplement.Models;
namespace PizzeriaDatabaseImplement.Implements namespace PizzeriaDatabaseImplement.Implements
{ {
public class ClientStorage : IClientStorage public class ClientStorage : IClientStorage
@ -17,12 +18,12 @@ namespace PizzeriaDatabaseImplement.Implements
public List<ClientViewModel> GetFilteredList(ClientSearchModel model) public List<ClientViewModel> GetFilteredList(ClientSearchModel model)
{ {
if (string.IsNullOrEmpty(model.Email)) if (string.IsNullOrEmpty(model.ClientFIO))
{ {
return new(); return new();
} }
using var context = new PizzeriaDatabase(); using var context = new PizzeriaDatabase();
return context.Clients.Where(x => x.Email.Contains(model.Email)).Select(x => x.GetViewModel).ToList(); return context.Clients.Where(x => x.ClientFIO.Contains(model.ClientFIO)).Select(x => x.GetViewModel).ToList();
} }
public ClientViewModel? GetElement(ClientSearchModel model) public ClientViewModel? GetElement(ClientSearchModel model)
@ -33,40 +34,41 @@ namespace PizzeriaDatabaseImplement.Implements
} }
using var context = new PizzeriaDatabase(); using var context = new PizzeriaDatabase();
return context.Clients.FirstOrDefault(x => return context.Clients.FirstOrDefault(x =>
(!string.IsNullOrEmpty(model.Email) && x.Email == model.Email && !string.IsNullOrEmpty(model.Password) && x.Password == model.Password) (!string.IsNullOrEmpty(model.Email) && x.Email == model.Email && !string.IsNullOrEmpty(model.Password) && x.Password == model.Password) ||
|| (model.Id.HasValue && x.Id == model.Id))?.GetViewModel; (model.Id.HasValue && x.Id == model.Id))
?.GetViewModel;
} }
public ClientViewModel? Insert(ClientBindingModel model) public ClientViewModel? Insert(ClientBindingModel model)
{ {
var newClient = Client.Create(model); var newComponent = Client.Create(model);
if (newClient == null) if (newComponent == null)
{ {
return null; return null;
} }
using var context = new PizzeriaDatabase(); using var context = new PizzeriaDatabase();
context.Clients.Add(newClient); context.Clients.Add(newComponent);
context.SaveChanges(); context.SaveChanges();
return newClient.GetViewModel; return newComponent.GetViewModel;
} }
public ClientViewModel? Update(ClientBindingModel model) public ClientViewModel? Update(ClientBindingModel model)
{ {
using var context = new PizzeriaDatabase(); using var context = new PizzeriaDatabase();
var client = context.Clients.FirstOrDefault(x => x.Id == model.Id); var component = context.Clients.FirstOrDefault(x => x.Id == model.Id);
if (client == null) if (component == null)
{ {
return null; return null;
} }
client.Update(model); component.Update(model);
context.SaveChanges(); context.SaveChanges();
return client.GetViewModel; return component.GetViewModel;
} }
public ClientViewModel? Delete(ClientBindingModel model) public ClientViewModel? Delete(ClientBindingModel model)
{ {
using var context = new PizzeriaDatabase(); using var context = new PizzeriaDatabase();
var element = context.Clients.FirstOrDefault(x => x.Id == model.Id); var element = context.Clients.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null) if (element != null)
{ {
context.Clients.Remove(element); context.Clients.Remove(element);
@ -76,4 +78,4 @@ namespace PizzeriaDatabaseImplement.Implements
return null; return null;
} }
} }
} }

View File

@ -1,87 +1,59 @@
using Microsoft.EntityFrameworkCore; using PizzeriaContracts.BindingModels;
using PizzeriaContracts.BindingModels;
using PizzeriaContracts.SearchModels; using PizzeriaContracts.SearchModels;
using PizzeriaContracts.StorageContracts;
using PizzeriaContracts.ViewModels; using PizzeriaContracts.ViewModels;
using PizzeriaDatabaseImplement.Models; using PizzeriaDatabaseImplement.Models;
using Microsoft.EntityFrameworkCore;
using PizzeriaContracts.StorageContracts;
using System.Collections.Generic;
using System.Linq;
namespace PizzeriaDatabaseImplement.Implements namespace PizzeriaDatabaseImplement.Implements
{ {
public class OrderStorage : IOrderStorage public class OrderStorage : IOrderStorage
{ {
public List<OrderViewModel> GetFullList()
public OrderViewModel? GetElement(OrderSearchModel model)
{ {
if (!model.Id.HasValue)
{
return null;
}
using var context = new PizzeriaDatabase(); using var context = new PizzeriaDatabase();
return context.Orders return context.Orders.Include(x => x.Pizza).Include(x => x.Client).Select(x => x.GetViewModel).ToList();
.Include(x => x.Pizza)
.Include(x => x.Client)
.FirstOrDefault(x => x.Id == model.Id)
?.GetViewModel;
} }
public List<OrderViewModel> GetFilteredList(OrderSearchModel model) public List<OrderViewModel> GetFilteredList(OrderSearchModel model)
{ {
using var context = new PizzeriaDatabase(); using var context = new PizzeriaDatabase();
if (model.Id.HasValue) if (model.DateFrom.HasValue)
{ {
return context.Orders return context.Orders.Include(x => x.Pizza).Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo).Select(x => x.GetViewModel).ToList();
.Include(x => x.Pizza)
.Include(x => x.Client)
.Where(x => x.Id == model.Id)
.Select(x => x.GetViewModel)
.ToList();
} }
else if (model.DateFrom != null && model.DateTo != null) if (model.ClientId.HasValue)
{ {
return context.Orders return context.Orders.Include(x => x.Pizza).Where(x => x.ClientId == model.ClientId).Select(x => x.GetViewModel).ToList();
.Include(x => x.Pizza)
.Include(x => x.Client)
.Where(x => x.DateCreate >= model.DateFrom && x.DateCreate <= model.DateTo)
.Select(x => x.GetViewModel)
.ToList();
} }
else if (model.ClientId.HasValue) return context.Orders.Include(x => x.Pizza).Where(x => x.Id == model.Id).Select(x => x.GetViewModel).ToList();
{
return context.Orders
.Include(x => x.Pizza)
.Include(x => x.Client)
.Where(x => x.ClientId == model.ClientId)
.Select(x => x.GetViewModel)
.ToList();
}
return new();
} }
public List<OrderViewModel> GetFullList() public OrderViewModel? GetElement(OrderSearchModel model)
{ {
if (!model.Id.HasValue)
{
return new();
}
using var context = new PizzeriaDatabase(); using var context = new PizzeriaDatabase();
return context.Orders return context.Orders.Include(x => x.Pizza).FirstOrDefault(x => x.Id == model.Id)?.GetViewModel;
.Include(x => x.Pizza)
.Include(x => x.Client)
.Select(x => x.GetViewModel)
.ToList();
} }
public OrderViewModel? Insert(OrderBindingModel model) public OrderViewModel? Insert(OrderBindingModel model)
{ {
var newOrder = Order.Create(model); using var context = new PizzeriaDatabase();
if (model == null)
return null;
var newOrder = Order.Create(context, model);
if (newOrder == null) if (newOrder == null)
{ {
return null; return null;
} }
using var context = new PizzeriaDatabase();
context.Orders.Add(newOrder); context.Orders.Add(newOrder);
context.SaveChanges(); context.SaveChanges();
return context.Orders return newOrder.GetViewModel;
.Include(x => x.Pizza)
.Include(x => x.Client)
.FirstOrDefault(x => x.Id == newOrder.Id)
?.GetViewModel;
} }
public OrderViewModel? Update(OrderBindingModel model) public OrderViewModel? Update(OrderBindingModel model)
@ -94,28 +66,20 @@ namespace PizzeriaDatabaseImplement.Implements
} }
order.Update(model); order.Update(model);
context.SaveChanges(); context.SaveChanges();
return context.Orders return order.GetViewModel;
.Include(x => x.Pizza)
.Include(x => x.Client)
.FirstOrDefault(x => x.Id == model.Id)
?.GetViewModel;
} }
public OrderViewModel? Delete(OrderBindingModel model) public OrderViewModel? Delete(OrderBindingModel model)
{ {
using var context = new PizzeriaDatabase(); using var context = new PizzeriaDatabase();
var element = context.Orders.FirstOrDefault(rec => rec.Id == model.Id); var order = context.Orders.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null) if (order != null)
{ {
var deletedElement = context.Orders context.Orders.Remove(order);
.Include(x => x.Pizza)
.Include(x => x.Client)
.FirstOrDefault(x => x.Id == model.Id)
?.GetViewModel;
context.Orders.Remove(element);
context.SaveChanges(); context.SaveChanges();
return deletedElement; return order.GetViewModel;
} }
return null; return null;
} }
} }
} }

View File

@ -1,8 +1,9 @@
using PizzeriaContracts.BindingModels; using PizzeriaContracts.BindingModels;
using PizzeriaContracts.ViewModels; using PizzeriaContracts.ViewModels;
using PizzeriaDataModels.Models; using PizzeriaDataModels.Models;
using System.ComponentModel.DataAnnotations.Schema; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace PizzeriaDatabaseImplement.Models namespace PizzeriaDatabaseImplement.Models
{ {
@ -11,13 +12,11 @@ namespace PizzeriaDatabaseImplement.Models
public int Id { get; private set; } public int Id { get; private set; }
[Required] [Required]
public string ClientFIO { get; private set; } = string.Empty; public string ClientFIO { get; set; } = string.Empty;
[Required] [Required]
public string Email { get; private set; } = string.Empty; public string Email { get; set; } = string.Empty;
[Required] [Required]
public string Password { get; private set; } = string.Empty; public string Password { get; set; } = string.Empty;
[ForeignKey("ClientId")] [ForeignKey("ClientId")]
public virtual List<Order> Orders { get; set; } = new(); public virtual List<Order> Orders { get; set; } = new();
@ -28,7 +27,18 @@ namespace PizzeriaDatabaseImplement.Models
{ {
return null; return null;
} }
return new() return new Client()
{
Id = model.Id,
ClientFIO = model.ClientFIO,
Email = model.Email,
Password = model.Password
};
}
public static Client Create(ClientViewModel model)
{
return new Client
{ {
Id = model.Id, Id = model.Id,
ClientFIO = model.ClientFIO, ClientFIO = model.ClientFIO,
@ -56,4 +66,4 @@ namespace PizzeriaDatabaseImplement.Models
Password = Password Password = Password
}; };
} }
} }

View File

@ -2,67 +2,79 @@
using PizzeriaContracts.ViewModels; using PizzeriaContracts.ViewModels;
using PizzeriaDataModels.Enums; using PizzeriaDataModels.Enums;
using PizzeriaDataModels.Models; using PizzeriaDataModels.Models;
using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace PizzeriaDatabaseImplement.Models namespace PizzeriaDatabaseImplement.Models
{ {
public class Order : IOrderModel public class Order : IOrderModel
{ {
public int Id { get; private set; } public int Id { get; private set; }
[Required]
public int ClientId { get; private set; }
public virtual Client Client { get; private set; } = new();
[Required] [Required]
public int PizzaId { get; private set; } public int PizzaId { get; private set; }
[Required]
public int ClientId { get; set; } public virtual Pizza Pizza { get; set; } = new();
[Required] [Required]
public int Count { get; private set; } public int Count { get; private set; }
[Required] [Required]
public double Sum { get; private set; } public double Sum { get; private set; }
[Required] [Required]
public OrderStatus Status { get; private set; } public OrderStatus Status { get; private set; } = OrderStatus.Неизвестен;
[Required] [Required]
public DateTime DateCreate { get; private set; } public DateTime DateCreate { get; private set; } = DateTime.Now;
public DateTime? DateImplement { get; private set; } public DateTime? DateImplement { get; private set; }
public virtual Pizza Pizza { get; set; }
public virtual Client Client { get; set; } public static Order Create(PizzeriaDatabase context, OrderBindingModel model)
public static Order? Create(OrderBindingModel? model)
{ {
if (model == null)
{
return null;
}
return new Order() return new Order()
{ {
Id = model.Id, Id = model.Id,
PizzaId = model.PizzaId,
ClientId = model.ClientId, ClientId = model.ClientId,
Client = context.Clients.First(x => x.Id == model.ClientId),
PizzaId = model.PizzaId,
Pizza = context.Pizzas.First(x => x.Id == model.PizzaId),
Count = model.Count, Count = model.Count,
Sum = model.Sum, Sum = model.Sum,
Status = model.Status, Status = model.Status,
DateCreate = model.DateCreate, DateCreate = model.DateCreate,
DateImplement = model.DateImplement DateImplement = model.DateImplement,
}; };
} }
public void Update(OrderBindingModel? model) public void Update(OrderBindingModel? model)
{ {
if (model == null) if (model == null)
{ {
return; return;
} }
Status = model.Status; Status = model.Status;
DateImplement = model.DateImplement; DateImplement = model.DateImplement;
} }
public OrderViewModel GetViewModel => new() public OrderViewModel GetViewModel => new()
{ {
Id = Id, Id = Id,
PizzaId = PizzaId,
ClientId = ClientId, ClientId = ClientId,
ClientFIO = Client.ClientFIO,
PizzaId = PizzaId,
PizzaName = Pizza.PizzaName,
Count = Count, Count = Count,
Sum = Sum, Sum = Sum,
Status = Status, Status = Status,
DateCreate = DateCreate, DateCreate = DateCreate,
DateImplement = DateImplement, DateImplement = DateImplement,
PizzaName = Pizza.PizzaName
}; };
} }
} }

View File

@ -3,6 +3,8 @@ using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using PizzeriaContracts.BindingModels; using PizzeriaContracts.BindingModels;
using PizzeriaContracts.ViewModels; using PizzeriaContracts.ViewModels;
using System.Collections.Generic;
using System.Linq;
namespace PizzeriaDatabaseImplement.Models namespace PizzeriaDatabaseImplement.Models
{ {

View File

@ -6,62 +6,64 @@ using PizzeriaContracts.ViewModels;
namespace PizzeriaRestApi.Controllers namespace PizzeriaRestApi.Controllers
{ {
[Route("api/[controller]/[action]")]
[ApiController]
public class ClientController : Controller
{
private readonly ILogger _logger;
[Route("api/[controller]/[action]")] private readonly IClientLogic _logic;
[ApiController]
public class ClientController : Controller
{
private readonly ILogger _logger;
private readonly IClientLogic _logic;
public ClientController(IClientLogic logic, ILogger<ClientController>
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;
}
}
}
public ClientController(IClientLogic logic, ILogger<ClientController> 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;
}
}
}
} }

View File

@ -1,5 +1,4 @@
using DocumentFormat.OpenXml.Office2010.Excel; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc;
using PizzeriaContracts.BindingModels; using PizzeriaContracts.BindingModels;
using PizzeriaContracts.BusinessLogicsContracts; using PizzeriaContracts.BusinessLogicsContracts;
using PizzeriaContracts.SearchModels; using PizzeriaContracts.SearchModels;
@ -12,14 +11,18 @@ namespace PizzeriaRestApi.Controllers
public class MainController : Controller public class MainController : Controller
{ {
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IOrderLogic _order; private readonly IOrderLogic _order;
private readonly IPizzaLogic _pizza; private readonly IPizzaLogic _pizza;
public MainController(ILogger<MainController> logger, IOrderLogic order, IPizzaLogic pizza) public MainController(ILogger<MainController> logger, IOrderLogic order, IPizzaLogic pizza)
{ {
_logger = logger; _logger = logger;
_order = order; _order = order;
_pizza = pizza; _pizza = pizza;
} }
[HttpGet] [HttpGet]
public List<PizzaViewModel>? GetPizzaList() public List<PizzaViewModel>? GetPizzaList()
{ {
@ -33,40 +36,35 @@ namespace PizzeriaRestApi.Controllers
throw; throw;
} }
} }
[HttpGet] [HttpGet]
public PizzaViewModel? GetPizza(int pizzaId) public PizzaViewModel? GetPizza(int pizzaId)
{ {
try try
{ {
return _pizza.ReadElement(new PizzaSearchModel return _pizza.ReadElement(new PizzaSearchModel { Id = pizzaId });
{
Id =
pizzaId
});
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка получения продукта по id={Id}", _logger.LogError(ex, "Ошибка получения продукта по id={Id}", pizzaId);
pizzaId);
throw; throw;
} }
} }
[HttpGet] [HttpGet]
public List<OrderViewModel>? GetOrders(int clientId) public List<OrderViewModel>? GetOrders(int clientId)
{ {
try try
{ {
return _order.ReadList(new OrderSearchModel return _order.ReadList(new OrderSearchModel { ClientId = clientId });
{
ClientId = clientId
});
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Ошибка получения списка заказов клиента id ={ Id}", clientId); _logger.LogError(ex, "Ошибка получения списка заказов клиента id={Id}", clientId);
throw; throw;
} }
} }
[HttpPost] [HttpPost]
public void CreateOrder(OrderBindingModel model) public void CreateOrder(OrderBindingModel model)
{ {

View File

@ -7,8 +7,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="6.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,19 +1,23 @@
using PizzeriaContracts.BusinessLogicsContracts;
using PizzeriaDatabaseImplement.Implements;
using PizzeriaContracts.StorageContracts;
using PizzeriaBusinessLogic.BusinessLogic; using PizzeriaBusinessLogic.BusinessLogic;
using PizzeriaContracts.BusinessLogicsContracts;
using PizzeriaContracts.StorageContracts;
using PizzeriaDatabaseImplement.Implements;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Trace); builder.Logging.SetMinimumLevel(LogLevel.Trace);
builder.Logging.AddLog4Net("log4net.config"); 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<IOrderStorage, OrderStorage>(); builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IPizzaStorage, PizzaStorage>(); builder.Services.AddTransient<IPizzaStorage, PizzaStorage>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>(); builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IClientLogic, ClientLogic>(); builder.Services.AddTransient<IClientLogic, ClientLogic>();
builder.Services.AddTransient<IPizzaLogic, PizzaLogic>(); builder.Services.AddTransient<IPizzaLogic, PizzaLogic>();
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();
@ -21,16 +25,20 @@ builder.Services.AddSwaggerGen(c =>
{ {
c.SwaggerDoc("v1", new OpenApiInfo { Title = "PizzeriaRestApi", Version = "v1" }); c.SwaggerDoc("v1", new OpenApiInfo { Title = "PizzeriaRestApi", Version = "v1" });
}); });
var app = builder.Build(); var app = builder.Build();
// 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", "PizzeriaRestApi v1")); app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "PizzeriaRestApi v1"));
} }
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();
app.Run();
app.Run();

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
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">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</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.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:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<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" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</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>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -4,17 +4,17 @@
"windowsAuthentication": false, "windowsAuthentication": false,
"anonymousAuthentication": true, "anonymousAuthentication": true,
"iisExpress": { "iisExpress": {
"applicationUrl": "http://localhost:37303", "applicationUrl": "http://localhost:38846",
"sslPort": 44315 "sslPort": 44358
} }
}, },
"profiles": { "profiles": {
"PizzeriaRestApi2": { "PizzeriaRestApi": {
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true, "dotnetRunMessages": true,
"launchBrowser": true, "launchBrowser": true,
"launchUrl": "swagger", "launchUrl": "swagger",
"applicationUrl": "https://localhost:7291;http://localhost:5166", "applicationUrl": "https://localhost:7175;http://localhost:5175",
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }
@ -28,4 +28,4 @@
} }
} }
} }
} }

View File

@ -5,4 +5,4 @@
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
} }
} }

View File

@ -6,4 +6,4 @@
} }
}, },
"AllowedHosts": "*" "AllowedHosts": "*"
} }

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8" ?>
<log4net> <log4net>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender"> <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="c:/temp/PrecastConcretePlantRestApi.log" /> <file value="c:/temp/PizzeriaRestApi.log" />
<appendToFile value="true" /> <appendToFile value="true" />
<maximumFileSize value="100KB" /> <maximumFileSize value="100KB" />
<maxSizeRollBackups value="2" /> <maxSizeRollBackups value="2" />