фиксики + интерфейс(сайт) для продуктов и блюд

This commit is contained in:
Алексей Тихоненков 2024-08-27 04:03:48 +04:00
parent 075d1bc284
commit 083b08ae7c
120 changed files with 1881 additions and 880 deletions

View File

@ -13,6 +13,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiningRoomDatabaseImplement
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiningRoomBusinessLogic", "DiningRoomBusinessLogic\DiningRoomBusinessLogic.csproj", "{89A8AB71-ADD4-405D-AE0B-03ACB1A1BF24}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiningRoomRestApi", "DiningRoomRestApi\DiningRoomRestApi.csproj", "{B81DDA1C-49FC-480F-AEED-37049C57993E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiningRoomUserApp", "DiningRoomUserApp\DiningRoomUserApp.csproj", "{B33F6026-6F6D-4337-887F-4D326D8FA511}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -39,6 +43,14 @@ Global
{89A8AB71-ADD4-405D-AE0B-03ACB1A1BF24}.Debug|Any CPU.Build.0 = Debug|Any CPU
{89A8AB71-ADD4-405D-AE0B-03ACB1A1BF24}.Release|Any CPU.ActiveCfg = Release|Any CPU
{89A8AB71-ADD4-405D-AE0B-03ACB1A1BF24}.Release|Any CPU.Build.0 = Release|Any CPU
{B81DDA1C-49FC-480F-AEED-37049C57993E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B81DDA1C-49FC-480F-AEED-37049C57993E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B81DDA1C-49FC-480F-AEED-37049C57993E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B81DDA1C-49FC-480F-AEED-37049C57993E}.Release|Any CPU.Build.0 = Release|Any CPU
{B33F6026-6F6D-4337-887F-4D326D8FA511}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B33F6026-6F6D-4337-887F-4D326D8FA511}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B33F6026-6F6D-4337-887F-4D326D8FA511}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B33F6026-6F6D-4337-887F-4D326D8FA511}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,62 @@
using DiningRoomContracts.BindingModels;
using DiningRoomContracts.BusinessLogicContracts;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DiningRoomBusinessLogic.MailWorker
{
public abstract class AbstractMailWorker
{
protected string _mailLogin = string.Empty;
protected string _mailPassword = string.Empty;
protected string _smtpClientHost = string.Empty;
protected int _smtpClientPort;
protected string _popHost = string.Empty;
protected int _popPort;
private readonly ILogger _logger;
public AbstractMailWorker()
{
}
public void MailConfig(MailConfigBindingModel config)
{
_mailLogin = config.MailLogin;
_mailPassword = config.MailPassword;
_smtpClientHost = config.SmtpClientHost;
_smtpClientPort = config.SmtpClientPort;
_popHost = config.PopHost;
_popPort = config.PopPort;
}
public async void MailSendAsync(MailSendInfoBindingModel info)
{
if (string.IsNullOrEmpty(_mailLogin) || string.IsNullOrEmpty(_mailPassword))
{
return;
}
if (string.IsNullOrEmpty(_smtpClientHost) || _smtpClientPort == 0)
{
return;
}
if (string.IsNullOrEmpty(info.MailAddress) || string.IsNullOrEmpty(info.Subject) || string.IsNullOrEmpty(info.Text))
{
return;
}
_logger.LogDebug("Send Mail: {To}, {Subject}", info.MailAddress, info.Subject);
await SendMailAsync(info);
}
protected abstract Task SendMailAsync(MailSendInfoBindingModel info);
}
}

View File

@ -0,0 +1,48 @@
using DiningRoomContracts.BindingModels;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Net.Mime;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using DiningRoomContracts.BusinessLogicContracts;
namespace DiningRoomBusinessLogic.MailWorker
{
public class MailKitWorker : AbstractMailWorker
{
public MailKitWorker() : base() { }
protected override async Task SendMailAsync(MailSendInfoBindingModel info)
{
using var objMailMessage = new MailMessage();
using var objSmtpClient = new SmtpClient(_smtpClientHost, _smtpClientPort);
try
{
objMailMessage.From = new MailAddress(_mailLogin);
objMailMessage.To.Add(new MailAddress(info.MailAddress));
objMailMessage.Subject = info.Subject;
objMailMessage.Body = info.Text;
objMailMessage.SubjectEncoding = Encoding.UTF8;
objMailMessage.BodyEncoding = Encoding.UTF8;
Attachment attachment = new Attachment("C:\\Users\\sshan\\OneDrive\\Desktop\\reports\\reportpdf.pdf", new ContentType(MediaTypeNames.Application.Pdf));
objMailMessage.Attachments.Add(attachment);
objSmtpClient.UseDefaultCredentials = false;
objSmtpClient.EnableSsl = true;
objSmtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
objSmtpClient.Credentials = new NetworkCredential(_mailLogin, _mailPassword);
await Task.Run(() => objSmtpClient.Send(objMailMessage));
}
catch (Exception)
{
throw;
}
}
}
}

View File

@ -1,114 +0,0 @@
using DiningRoomClientApp.Models;
using DiningRoomContracts.BindingModels;
using DiningRoomContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using DiningRoomClientApp;
namespace DiningRoomClientApp.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
if (APIUser.User == null)
{
return Redirect("~/Home/Enter");
}
return View(/*APIUser.GetRequest<List<OrderViewModel>>($"api/main/getorders?userId={APIUser.User.Id}")*/);
}
[HttpGet]
public IActionResult Privacy()
{
if (APIUser.User == null)
{
return Redirect("~/Home/Enter");
}
return View(APIUser.User);
}
[HttpPost]
public void Privacy(string login, string password, string email)
{
if (APIUser.User == null)
{
throw new Exception("Вход только авторизованным");
}
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(email))
{
throw new Exception("Введите логин, пароль и почту");
}
APIUser.PostRequest("api/user/updatedata", new UserBindingModel
{
Id = APIUser.User.Id,
Login = login,
Password = password,
Email = email
});
APIUser.User.Login = login;
APIUser.User.Password = password;
APIUser.User.Email = email;
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("Введите логин и пароль");
}
APIUser.User = APIUser.GetRequest<UserViewModel>($"api/user/login?login={login}&password={password}");
if (APIUser.User == null)
{
throw new Exception("Неверный логин/пароль");
}
Response.Redirect("Index");
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public void Register(string login, string password, string email)
{
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(email))
{
throw new Exception("Введите логин, пароль и почту");
}
APIUser.PostRequest("api/user/register", new UserBindingModel
{
Login = login,
Password = password,
Email = email
});
Response.Redirect("Enter");
return;
}
}
}

View File

@ -1,31 +0,0 @@
using DiningRoomClientApp;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
APIUser.Connect(builder.Configuration);
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

View File

@ -1,50 +0,0 @@
@{
ViewData["Title"] = "Create";
}
<div class="text-center">
<h2 class="display-4">Создание заказа</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Изделие:</div>
<div class="col-8">
<select id="product" name="product" class="form-control" asp-items="@(new SelectList(@ViewBag.Products,"Id", "WoodName"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Количество:</div>
<div class="col-8"><input type="text" name="count" id="count" /></div>
</div>
<div class="row">
<div class="col-4">Сумма:</div>
<div class="col-8"><input type="text" id="sum" name="sum" readonly /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Создать" class="btn btn-primary" /></div>
</div>
</form>
<script>
$('#product').on('change', function () {
check();
});
$('#count').on('change', function () {
check();
});
function check() {
var count = $('#count').val();
var product = $('#product').val();
if (count && product) {
$.ajax({
method: "POST",
url: "/Home/Calc",
data: { count: count, product: product },
success: function (result) {
$("#sum").val(result);
}
});
};
}
</script>

View File

@ -1,21 +0,0 @@
@{
ViewData["Title"] = "Enter";
}
<div class="text-center">
<h2 class="display-4">Вход в приложение</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8"><input type="text" name="login" /></div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8"><input type="password" name="password" /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Вход" class="btn btn-primary" /></div>
</div>
</form>

View File

@ -1,8 +0,0 @@
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

View File

@ -1,54 +0,0 @@
@using CarpentryWorkshopContracts.ViewModels
@model List<MessageInfoViewModel>
@{
ViewData["Title"] = "Mails";
}
<div class="text-center">
<h1 class="display-4">Заказы</h1>
</div>
<div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<table class="table">
<thead>
<tr>
<th>
Дата письма
</th>
<th>
Заголовок
</th>
<th>
Текст
</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>

View File

@ -1,6 +0,0 @@
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>

View File

@ -1,25 +0,0 @@
@{
ViewData["Title"] = "Register";
}
<div class="text-center">
<h2 class="display-4">Регистрация</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8"><input type="text" name="login" /></div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8"><input type="password" name="password" /></div>
</div>
<div class="row">
<div class="col-4">Почта:</div>
<div class="col-8"><input type="text" name="email" /></div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Регистрация" class="btn btn-primary" /></div>
</div>
</form>

View File

@ -1,55 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - DiningRoomClientApp</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/DiningRoomClientApp.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">DiningRoomClientApp</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Заказы</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Register">Регистрация</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2024 - DiningRoomClientApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View File

@ -1,3 +0,0 @@
@using DiningRoomClientApp
@using DiningRoomClientApp.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DiningRoomContracts.BindingModels
{
public class MailConfigBindingModel
{
public string MailLogin { get; set; } = string.Empty;
public string MailPassword { get; set; } = string.Empty;
public string SmtpClientHost { get; set; } = string.Empty;
public int SmtpClientPort { get; set; }
public string PopHost { get; set; } = string.Empty;
public int PopPort { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DiningRoomContracts.BindingModels
{
public class MailSendInfoBindingModel
{
public string MailAddress { get; set; } = string.Empty;
public string Subject { get; set; } = string.Empty;
public string Text { get; set; } = string.Empty;
}
}

View File

@ -76,15 +76,20 @@ namespace DiningRoomDatabaseImplement.Implements
using var transaction = context.Database.BeginTransaction();
try
{
var Product = context.Products.FirstOrDefault(rec => rec.Id == model.Id);
var Product = context.Products
.Include(x => x.Components)
.ThenInclude(x => x.Component)
.FirstOrDefault(rec => rec.Id == model.Id);
if (Product == null)
{
return null;
}
Product.Update(model);
context.SaveChanges();
Product.UpdateComponents(context, model);
transaction.Commit();
Product.UpdateComponents(context, model);
context.SaveChanges();
Product.Update(model);
context.SaveChanges();
transaction.Commit();
return Product.GetViewModel;
}
catch

View File

@ -12,7 +12,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace DiningRoomDatabaseImplement.Migrations
{
[DbContext(typeof(DiningRoomDatabase))]
[Migration("20240527031110_InitialCreate")]
[Migration("20240827000029_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />

View File

@ -69,20 +69,20 @@ namespace DiningRoomDatabaseImplement.Models
};
public void UpdateComponents(DiningRoomDatabase context, ProductBindingModel model)
{
// Получаем список текущих записей ProductComponents для продукта
var productComponents = context.ProductComponents.Where(rec => rec.ProductId == model.Id).ToList();
// Удаляем все текущие записи
if (productComponents != null && productComponents.Count > 0)
{ // удалили те, которых нет в модели
context.ProductComponents.RemoveRange(productComponents.Where(rec => !model.ProductComponents.ContainsKey(rec.ComponentId)));
context.SaveChanges();
// обновили количество у существующих записей
foreach (var updateComponent in productComponents)
{
updateComponent.Count = model.ProductComponents[updateComponent.ComponentId].Item2;
model.ProductComponents.Remove(updateComponent.ComponentId);
}
{
context.ProductComponents.RemoveRange(productComponents);
context.SaveChanges();
}
var product = context.Products.First(x => x.Id == Id);
// Получаем продукт по его Id
var product = context.Products.First(x => x.Id == model.Id);
// Добавляем новые записи ProductComponents из модели
foreach (var pc in model.ProductComponents)
{
context.ProductComponents.Add(new ProductComponent
@ -91,9 +91,14 @@ namespace DiningRoomDatabaseImplement.Models
Component = context.Components.First(x => x.Id == pc.Key),
Count = pc.Value.Item2
});
context.SaveChanges();
}
// Сохраняем изменения
context.SaveChanges();
// Сбрасываем кэш связанных компонентов, если требуется
_productComponents = null;
}
}
}

View File

@ -1,105 +0,0 @@
using DiningRoomContracts.BindingModels;
using DiningRoomContracts.BusinessLogicContracts;
using DiningRoomContracts.SearchModels;
using DiningRoomContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace DiningRoomRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class CardController : Controller
{
private readonly ILogger _logger;
private readonly ICardLogic _logic;
public CardController(ICardLogic logic, ILogger<CardController> logger)
{
_logger = logger;
_logic = logic;
}
[HttpGet]
public CardViewModel? GetCard(int id)
{
try
{
return _logic.ReadElement(new CardSearchModel
{
Id = id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения заказа");
throw;
}
}
/// <summary>
/// Получение карт по id(полный список, кот. будет выводиться)
/// </summary>
[HttpGet]
public List<CardViewModel>? GetCards(int Id)
{
try
{
return _logic.ReadList(new CardSearchModel { Id = Id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка заказов клиента id={Id}", Id);
throw;
}
}
[HttpPost]
public void CreateCard(CardBindingModel model)
{
try
{
_logic.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания заказа");
throw;
}
}
[HttpPost]
public void UpdateCard(CardBindingModel model)
{
try
{
_logic.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления заказа");
throw;
}
}
[HttpDelete]
public void DeleteCard(CardBindingModel model)
{
try
{
_logic.Delete(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления заказа");
throw;
}
}
}
}

View File

@ -1,82 +0,0 @@
using DiningRoomContracts.BindingModels;
using DiningRoomContracts.BusinessLogicContracts;
using DiningRoomContracts.SearchModels;
using DiningRoomContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace DiningRoomRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ComponentController : Controller
{
private readonly ILogger _logger;
private readonly IComponentLogic _componentLogic;
public ComponentController(IComponentLogic Logic, ILogger<ComponentController> Logger)
{
_logger = Logger;
_componentLogic = Logic;
}
[HttpGet]
public ComponentViewModel? GetComponent(int Id)
{
try
{
return _componentLogic.ReadElement(new ComponentSearchModel
{
Id = Id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения продукта");
throw;
}
}
[HttpPost]
public void CreateComponent(ComponentBindingModel Model)
{
try
{
_componentLogic.Create(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания продукта");
throw;
}
}
[HttpPost]
public void UpdateComponent(ComponentBindingModel Model)
{
try
{
_componentLogic.Update(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления продукта");
throw;
}
}
[HttpDelete]
public void DeleteComponent(ComponentBindingModel Model)
{
try
{
_componentLogic.Delete(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления продукта");
throw;
}
}
}
}

View File

@ -1,82 +0,0 @@
using DiningRoomContracts.BindingModels;
using DiningRoomContracts.BusinessLogicContracts;
using DiningRoomContracts.SearchModels;
using DiningRoomContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace DiningRoomRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class DrinkController : Controller
{
private readonly ILogger _logger;
private readonly IDrinkLogic _DrinkLogic;
public DrinkController(IDrinkLogic Logic, ILogger<DrinkController> Logger)
{
_logger = Logger;
_DrinkLogic = Logic;
}
[HttpGet]
public DrinkViewModel? GetDrink(int Id)
{
try
{
return _DrinkLogic.ReadElement(new DrinkSearchModel
{
Id = Id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения напитка");
throw;
}
}
[HttpPost]
public void CreateDrink(DrinkBindingModel Model)
{
try
{
_DrinkLogic.Create(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания напитка");
throw;
}
}
[HttpPost]
public void UpdateDrink(DrinkBindingModel Model)
{
try
{
_DrinkLogic.Update(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления напитка");
throw;
}
}
[HttpDelete]
public void DeleteDrink(DrinkBindingModel Model)
{
try
{
_DrinkLogic.Delete(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления напитка");
throw;
}
}
}
}

View File

@ -0,0 +1,401 @@
using DiningRoomContracts.BindingModels;
using DiningRoomContracts.BusinessLogicContracts;
using DiningRoomContracts.SearchModels;
using DiningRoomContracts.ViewModels;
using DiningRoomDatabaseImplement;
using DiningRoomDatabaseImplement.Models;
using DocumentFormat.OpenXml.Wordprocessing;
using Microsoft.AspNetCore.Mvc;
namespace DiningRoomRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class MainController : Controller
{
private readonly ILogger _logger;
private readonly ICardLogic _card;
private readonly IOrderLogic _order;
private readonly IProductLogic _product;
private readonly IComponentLogic _component;
private readonly IDrinkLogic _drink;
public MainController(ILogger<MainController> logger, ICardLogic card, IOrderLogic order, IProductLogic product, IComponentLogic component, IDrinkLogic drink)
{
_logger = logger;
_card = card;
_order = order;
_product = product;
_component = component;
_drink = drink;
}
[HttpGet]
public List<CardViewModel>? GetCardList(int Id)
{
try
{
return _card.ReadList(new CardSearchModel
{
Id = Id,
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error get list Card");
throw;
}
}
[HttpGet]
public List<OrderViewModel>? GetOrderList(int Id)
{
try
{
return _order.ReadList(new OrderSearchModel
{
Id = Id,
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error get list Order");
throw;
}
}
[HttpGet]
public List<ProductViewModel>? GetProductList(int UserId)
{
try
{
return _product.ReadList(new ProductSearchModel
{
UserId = UserId,
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error get list Product");
throw;
}
}
[HttpPost]
public void CreateProduct(ProductBindingModel model)
{
try
{
_product.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error create Product");
throw;
}
}
[HttpPost]
public void UpdateProduct(ProductBindingModel model)
{
try
{
_product.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error update Product");
throw;
}
}
[HttpPost]
public void DeleteProduct(ProductBindingModel model)
{
try
{
_product.Delete(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error delete Product");
throw;
}
}
[HttpGet]
public List<ComponentViewModel>? GetComponentList(int UserId)
{
try
{
return _component.ReadList(new ComponentSearchModel
{
UserId = UserId,
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error get list Component");
throw;
}
}
[HttpPost]
public void CreateComponent(ComponentBindingModel model)
{
try
{
_component.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error create Component");
throw;
}
}
[HttpGet]
public List<DrinkViewModel>? GetDrinkList(int userId)
{
try
{
return _drink.ReadList(new DrinkSearchModel
{
UserId = userId,
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error get list Drink");
throw;
}
}
[HttpPost]
public void UpdateOrder(OrderBindingModel model)
{
try
{
_order.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error update Order");
throw;
}
}
[HttpGet]
public OrderViewModel? GetOrder(int orderId)
{
try
{
return _order.ReadElement(new OrderSearchModel
{
Id = orderId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error get order by id={Id}", orderId);
throw;
}
}
[HttpPost]
public void CreateOrder(OrderBindingModel model)
{
try
{
_order.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error create Order");
throw;
}
}
[HttpPost]
public void DeleteOrder(OrderBindingModel model)
{
try
{
_order.Delete(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error delete Order");
throw;
}
}
[HttpPost]
public void UpdateComponent(ComponentBindingModel model)
{
try
{
_component.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error update Component");
throw;
}
}
[HttpGet]
public ComponentViewModel? GetComponent(int componentId)
{
try
{
return _component.ReadElement(new ComponentSearchModel
{
Id = componentId
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Error get Component by id={Id}", componentId);
throw;
}
}
[HttpPost]
public void DeleteComponent(ComponentBindingModel model)
{
try
{
_component.Delete(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error delete Component");
throw;
}
}
[HttpPost]
public void CreateCard(CardBindingModel model)
{
try
{
_card.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error create Card");
throw;
}
}
[HttpPost]
public void UpdateCard(CardBindingModel model)
{
try
{
_card.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error update Card");
throw;
}
}
[HttpPost]
public void DeleteCard(CardBindingModel model)
{
try
{
_card.Delete(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error delete card");
throw;
}
}
[HttpPost]
public void CreateDrink(DrinkBindingModel model)
{
try
{
_drink.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error create Drink");
throw;
}
}
[HttpPost]
public void UpdateDrink(DrinkBindingModel model)
{
try
{
_drink.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error update Drink");
throw;
}
}
[HttpPost]
public void DeleteDrink(DrinkBindingModel model)
{
try
{
_drink.Delete(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error delete Drink");
throw;
}
}
[HttpGet]
public List<ProductViewModel>? GetProducts()
{
try
{
return _product.ReadList(null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка конференций");
throw;
}
}
[HttpGet]
public List<DrinkViewModel>? GetDrinks()
{
try
{
return _drink.ReadList(null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения списка конференций");
throw;
}
}
[HttpGet]
public DrinkViewModel GetDrinkById(int drinkId)
{
try
{
var elem = _drink.ReadElement(new DrinkSearchModel { Id = drinkId });
if (elem == null)
return null;
return elem;
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения по id={Id}", drinkId);
throw;
}
}
}
}

View File

@ -1,84 +0,0 @@
using DiningRoomContracts.BindingModels;
using DiningRoomContracts.BusinessLogicContracts;
using DiningRoomContracts.SearchModels;
using DiningRoomContracts.ViewModels;
using DiningRoomDatabaseImplement.Models;
using Microsoft.AspNetCore.Mvc;
namespace DiningRoomRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class OrderController : Controller
{
private readonly ILogger _logger;
private readonly IOrderLogic _logic;
public OrderController(IOrderLogic logic, ILogger<OrderController> logger)
{
_logger = logger;
_logic = logic;
}
[HttpGet]
public OrderViewModel? GetOrder(int id)
{
try
{
return _logic.ReadElement(new OrderSearchModel
{
Id = id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения заказа");
throw;
}
}
[HttpPost]
public void CreateOrder(OrderBindingModel model)
{
try
{
_logic.Create(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания заказа");
throw;
}
}
[HttpPost]
public void UpdateOrder(OrderBindingModel model)
{
try
{
_logic.Update(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления заказа");
throw;
}
}
[HttpDelete]
public void DeleteOrder(OrderBindingModel model)
{
try
{
_logic.Delete(model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления заказа");
throw;
}
}
}
}

View File

@ -1,82 +0,0 @@
using DiningRoomContracts.BindingModels;
using DiningRoomContracts.BusinessLogicContracts;
using DiningRoomContracts.SearchModels;
using DiningRoomContracts.ViewModels;
using Microsoft.AspNetCore.Mvc;
namespace DiningRoomRestApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ProductController : Controller
{
private readonly ILogger _logger;
private readonly IProductLogic _productLogic;
public ProductController(IProductLogic Logic, ILogger<ProductController> Logger)
{
_logger = Logger;
_productLogic = Logic;
}
[HttpGet]
public ProductViewModel? GetProduct(int Id)
{
try
{
return _productLogic.ReadElement(new ProductSearchModel
{
Id = Id
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения блюда");
throw;
}
}
[HttpPost]
public void CreateProduct(ProductBindingModel Model)
{
try
{
_productLogic.Create(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания блюда");
throw;
}
}
[HttpPost]
public void UpdateProduct(ProductBindingModel Model)
{
try
{
_productLogic.Update(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления блюда");
throw;
}
}
[HttpDelete]
public void DeleteProduct(ProductBindingModel Model)
{
try
{
_productLogic.Delete(Model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления блюда");
throw;
}
}
}
}

View File

@ -2,7 +2,6 @@
using DiningRoomContracts.BusinessLogicContracts;
using DiningRoomContracts.SearchModels;
using DiningRoomContracts.ViewModels;
using DiningRoomDataModels.Enums;
using Microsoft.AspNetCore.Mvc;
namespace DiningRoomRestApi.Controllers
@ -13,31 +12,37 @@ namespace DiningRoomRestApi.Controllers
{
private readonly ILogger _logger;
private readonly IUserLogic _logic;
public UserController(IUserLogic logic, ILogger<UserController> logger)
{
_logic = logic;
_logger = logger;
_logic = logic;
}
[HttpGet]
public UserViewModel? Login(string login, string password)
{
try
{
return _logic.ReadElement(new UserSearchModel
if (login.Contains("@"))
{
return _logic.ReadElement(new UserSearchModel
{
Email = login,
Password = password
});
}
return _logic.ReadElement(new UserSearchModel
{
Login = login,
Password = password,
Login = login,
Password = password
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка входа в систему");
_logger.LogError(ex, "Login error");
throw;
}
}
[HttpPost]
public void Register(UserBindingModel model)
{
@ -47,7 +52,7 @@ namespace DiningRoomRestApi.Controllers
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка регистрации");
_logger.LogError(ex, "Registration error");
throw;
}
}
@ -61,7 +66,7 @@ namespace DiningRoomRestApi.Controllers
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка обновления данных");
_logger.LogError(ex, "Update data error");
throw;
}
}

View File

@ -7,18 +7,17 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.18">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.11">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging.Log4Net.AspNetCore" Version="6.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DiningRoomBusinessLogic\DiningRoomBusinessLogic.csproj" />
<ProjectReference Include="..\DiningRoomContracts\DiningRoomContracts.csproj" />
<ProjectReference Include="..\DiningRoomDatabaseImplement\DiningRoomDatabaseImplement.csproj" />
<ProjectReference Include="..\DiningRoomDataModels\DiningRoomDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -1,32 +1,45 @@
using DiningRoomBusinessLogic.BusinessLogic;
using DiningRoomBusinessLogic.MailWorker;
//using DiningRoomBusinessLogic.MailWorker;
using DiningRoomBusinessLogic.OfficePackage;
using DiningRoomBusinessLogic.OfficePackage.Implements;
using DiningRoomContracts.BindingModels;
using DiningRoomContracts.BusinessLogicContracts;
using DiningRoomContracts.StorageContracts;
using DiningRoomDatabaseImplement.Implements;
using Microsoft.OpenApi.Models;
var Builder = WebApplication.CreateBuilder(args);
var builder = WebApplication.CreateBuilder(args);
builder.Logging.SetMinimumLevel(LogLevel.Trace);
// Add services to the container.
builder.Services.AddTransient<IComponentStorage, ComponentStorage>();
builder.Services.AddTransient<IProductStorage, ProductStorage>();
builder.Services.AddTransient<IDrinkStorage, DrinkStorage>();
builder.Services.AddTransient<ICardStorage, CardStorage>();
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
builder.Services.AddTransient<IUserStorage, UserStorage>();
builder.Services.AddTransient<IComponentLogic, ComponentLogic>();
builder.Services.AddTransient<IProductLogic, ProductLogic>();
builder.Services.AddTransient<IDrinkLogic, DrinkLogic>();
builder.Services.AddTransient<ICardLogic, CardLogic>();
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
builder.Services.AddTransient<IUserLogic, UserLogic>();
builder.Services.AddSingleton<AbstractMailWorker, MailKitWorker>();
builder.Services.AddTransient<AbstractSaveToPdf, SaveToPdf>();
builder.Services.AddTransient<IReportLogic, ReportLogic>();
builder.Services.AddTransient<AbstractSaveToExcel, SaveToExcel>();
builder.Services.AddTransient<AbstractSaveToWord, SaveToWord>();
Builder.Services.AddTransient<IUserStorage, UserStorage>();
Builder.Services.AddTransient<ICardStorage, CardStorage>();
Builder.Services.AddTransient<IDrinkStorage, DrinkStorage>();
Builder.Services.AddTransient<IOrderStorage, OrderStorage>();
Builder.Services.AddTransient<IComponentStorage, ComponentStorage>();
Builder.Services.AddTransient<IProductStorage, ProductStorage>();
Builder.Services.AddTransient<IUserLogic, UserLogic>();
Builder.Services.AddTransient<ICardLogic, CardLogic>();
Builder.Services.AddTransient<IDrinkLogic, DrinkLogic>();
Builder.Services.AddTransient<IOrderLogic, OrderLogic>();
Builder.Services.AddTransient<IComponentLogic, ComponentLogic>();
Builder.Services.AddTransient<IProductLogic, ProductLogic>();
Builder.Services.AddTransient<IReportLogic, ReportLogic>();
Builder.Services.AddControllers();
Builder.Services.AddEndpointsApiExplorer();
Builder.Services.AddSwaggerGen(c =>
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
{
@ -35,16 +48,33 @@ Builder.Services.AddSwaggerGen(c =>
});
});
var App = Builder.Build();
if (App.Environment.IsDevelopment())
var app = builder.Build();
var mailSender = app.Services.GetService<AbstractMailWorker>();
mailSender?.MailConfig(new MailConfigBindingModel
{
App.UseSwagger();
App.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "DiningRoomRestApi v1"));
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.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "DiningRoomRestApi v1"));
}
App.UseHttpsRedirection();
App.UseAuthorization();
App.MapControllers();
App.Run();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@ -4,8 +4,8 @@
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:38485",
"sslPort": 44318
"applicationUrl": "http://localhost:16420",
"sslPort": 44394
}
},
"profiles": {
@ -14,7 +14,7 @@
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7080;http://localhost:5150",
"applicationUrl": "https://localhost:7253;http://localhost:5121",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}

View File

@ -5,5 +5,11 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"SmtpClientHost": "smtp.gmail.com",
"SmtpClientPort": "587",
"PopHost": "pop.gmail.com",
"PopPort": "995",
"MailLogin": "mailworker2024@gmail.com",
"MailPassword": "bixb rbag kumt lefa"
}

View File

@ -1,17 +1,17 @@
using DiningRoomContracts.ViewModels;
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
namespace DiningRoomClientApp
namespace DiningRoomUserApp
{
public class APIUser
public class APIClient
{
private static readonly HttpClient _user = new();
public static UserViewModel? User { get; set; } = null;
public static void Connect(IConfiguration configuration)
public static void Connect(IConfiguration configuration)
{
_user.BaseAddress = new Uri(configuration["IPAddress"]);
_user.DefaultRequestHeaders.Accept.Clear();

View File

@ -0,0 +1,312 @@
using DiningRoomUserApp.Models;
using DocumentFormat.OpenXml.Wordprocessing;
using DiningRoomUserApp.Models;
using DiningRoomContracts.BindingModels;
using DiningRoomContracts.BusinessLogicContracts;
using DiningRoomContracts.SearchModels;
using DiningRoomContracts.ViewModels;
using DiningRoomDatabaseImplement;
using DiningRoomDatabaseImplement.Models;
using DiningRoomDataModels.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
using DiningRoomDataModels.Enums;
using System.Reflection;
namespace DiningRoomUserApp.Controllers
{
public class HomeController : Controller
{
private readonly IComponentLogic _component;
public HomeController(IComponentLogic component)
{
_component = component;
}
public IActionResult Index()
{
return View();
}
public IActionResult Components()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.GetRequest<List<ComponentViewModel>>($"api/main/getcomponentlist?userId={APIClient.User.Id}"));
}
public IActionResult CreateComponent()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
var componentUnits = Enum.GetValues(typeof(DiningRoomDataModels.Enums.ComponentUnit))
.Cast<DiningRoomDataModels.Enums.ComponentUnit>()
.Select(e => new SelectListItem
{
Value = ((int)e).ToString(),
Text = e.ToString()
}).ToList();
ViewBag.ComponentUnits = new SelectList(componentUnits, "Value", "Text");
return View();
}
[HttpPost]
public void CreateComponent(string componentName, double componentPrice, ComponentUnit unit)
{
if (APIClient.User == null)
{
throw new Exception("Необходима авторизация");
}
if (componentName.Length <=0 || componentPrice<=0 || unit == ComponentUnit.Неизвестна)
{
throw new Exception("Введите данные");
}
APIClient.PostRequest("api/main/createcomponent", new ComponentBindingModel
{
ComponentName = componentName,
Cost = componentPrice,
Unit = unit,
UserId = APIClient.User.Id,
});
Response.Redirect("Components");
}
public IActionResult UpdateComponent()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
var componentUnits = Enum.GetValues(typeof(DiningRoomDataModels.Enums.ComponentUnit))
.Cast<DiningRoomDataModels.Enums.ComponentUnit>()
.Select(e => new SelectListItem
{
Value = ((int)e).ToString(),
Text = e.ToString()
}).ToList();
ViewBag.ComponentUnits = new SelectList(componentUnits, "Value", "Text");
ViewBag.Components = APIClient.GetRequest<List<ComponentViewModel>>($"api/main/getcomponentlist?userid={APIClient.User.Id}");
return View();
}
[HttpPost]
public void UpdateComponent(int component, string componentName, double componentPrice, ComponentUnit unit)
{
if (APIClient.User == null)
{
throw new Exception("Необходима авторизация");
}
if (componentName.Length <=0 || componentPrice<=0 || unit == ComponentUnit.Неизвестна)
{
throw new Exception("Введите данные");
}
APIClient.PostRequest("api/main/updatecomponent", new ComponentBindingModel
{
Id = component,
ComponentName = componentName,
Cost = componentPrice,
Unit = unit,
UserId = APIClient.User.Id,
});
Response.Redirect("Components");
}
public IActionResult DeleteComponent()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
ViewBag.Components = APIClient.GetRequest<List<ComponentViewModel>>($"api/main/getcomponentlist?userId={APIClient.User.Id}");
return View();
}
[HttpPost]
public void DeleteComponent(int component)
{
if (APIClient.User == null)
{
throw new Exception("Необходима авторизация");
}
APIClient.PostRequest("api/main/deletecomponent", new ComponentBindingModel
{
Id = component
});
Response.Redirect("Components");
}
public IActionResult Products()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.GetRequest<List<ProductViewModel>>($"api/main/getproductlist?userId={APIClient.User.Id}"));
}
public IActionResult CreateProduct()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
var list = _component.ReadList(new ComponentSearchModel { UserId = APIClient.User.Id });
var simpComponent = list.Select(x => new { ComponentId = x.Id, ComponentName = x.ComponentName });
ViewBag.components = new MultiSelectList(simpComponent, "ComponentId", "ComponentName");
return View();
}
[HttpPost]
public void CreateProduct(string productName, double productPrice, int[] components)
{
if (APIClient.User == null)
{
throw new Exception("Необходима авторизация");
}
if (productName.Length <=0 || productPrice<=0 || components.Length == 0)
{
throw new Exception("Введите данные");
}
Dictionary<int, (IComponentModel, int)> _productComponents = new Dictionary<int, (IComponentModel, int)>();
foreach (int id in components)
{
_productComponents.Add(id, (_component.ReadElement(new ComponentSearchModel { Id = id }),1));
}
APIClient.PostRequest("api/main/createproduct", new ProductBindingModel
{
ProductName = productName,
Cost = productPrice,
UserId = APIClient.User.Id,
ProductComponents = _productComponents,
});
Response.Redirect("Products");
}
public IActionResult UpdateProduct()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
ViewBag.Products = APIClient.GetRequest<List<ProductViewModel>>($"api/main/getproductlist?userid={APIClient.User.Id}");
ViewBag.Components = APIClient.GetRequest<List<ComponentViewModel>>($"api/main/getcomponentlist?userid={APIClient.User.Id}");
return View();
}
[HttpPost]
public void UpdateProduct(int product, string productName, double productPrice, List<int> components)
{
if (APIClient.User == null)
{
throw new Exception("Необходима авторизация");
}
if (productName.Length <= 0 || productPrice <= 0)
{
throw new Exception("Введите данные");
}
Dictionary<int, (IComponentModel, int)> _productComponents = new Dictionary<int, (IComponentModel, int)>();
foreach (int id in components)
{
_productComponents.Add(id, (new ComponentSearchModel { Id = id } as IComponentModel, 1));
}
APIClient.PostRequest("api/main/updateproduct", new ProductBindingModel
{
Id = product,
ProductName = productName,
Cost = productPrice,
UserId = APIClient.User.Id,
ProductComponents = _productComponents,
});
Response.Redirect("Products");
}
[HttpGet]
public IActionResult Privacy()
{
if (APIClient.User == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.User);
}
[HttpPost]
public void Privacy(string login, string email, string password, string fio, string phone)
{
if (APIClient.User == null)
{
throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
}
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio) || string.IsNullOrEmpty(email) || string.IsNullOrEmpty(phone))
{
throw new Exception("Введите логин, пароль и ФИО");
}
APIClient.PostRequest("api/user/updatedata", new UserBindingModel
{
Id = APIClient.User.Id,
Login = login,
Password = password,
Email = email,
});
APIClient.User.Login = login;
APIClient.User.Password = password;
APIClient.User.Email = email;
Response.Redirect("Index");
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public void Register(string login, string email, string password)
{
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(email))
{
throw new Exception("Введите все данные");
}
APIClient.PostRequest("api/user/register", new UserBindingModel
{
Login = login,
Password = password,
Email = email,
});
Response.Redirect("Enter");
return;
}
[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.User = APIClient.GetRequest<UserViewModel>($"api/user/login?login={login}&password={password}");
if (APIClient.User == null)
{
throw new Exception("Неверный логин/пароль");
}
Response.Redirect("Index");
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}

View File

@ -7,11 +7,14 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DiningRoomBusinessLogic\DiningRoomBusinessLogic.csproj" />
<ProjectReference Include="..\DiningRoomContracts\DiningRoomContracts.csproj" />
<ProjectReference Include="..\DiningRoomDatabaseImplement\DiningRoomDatabaseImplement.csproj" />
<ProjectReference Include="..\DiningRoomDataModels\DiningRoomDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,20 @@
using System.Collections.Generic;
using DiningRoomDataModels.Enums;
namespace DiningRoomUserApp.Models
{
public class ComponentUnitViewModel
{
public List<string> Units { get; set; }
public ComponentUnitViewModel()
{
Units = new List<string>();
foreach (ComponentUnit unit in Enum.GetValues(typeof(ComponentUnit)))
{
Units.Add(unit.ToString());
}
}
}
}

View File

@ -1,4 +1,4 @@
namespace DiningRoomClientApp.Models
namespace DiningRoomUserApp.Models
{
public class ErrorViewModel
{

View File

@ -0,0 +1,38 @@
using DiningRoomUserApp;
using DiningRoomBusinessLogic.BusinessLogic;
using DiningRoomBusinessLogic.OfficePackage;
using DiningRoomBusinessLogic.OfficePackage.Implements;
using DiningRoomContracts.BusinessLogicContracts;
using DiningRoomContracts.StorageContracts;
using DiningRoomDatabaseImplement.Implements;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddTransient<IProductStorage, ProductStorage>();
builder.Services.AddTransient<IProductLogic, ProductLogic>();
builder.Services.AddTransient<IComponentStorage, ComponentStorage>();
builder.Services.AddTransient<IComponentLogic, ComponentLogic>();
//builder.Services.AddTransient<AbstractSaveToPdfUser, SaveToPdfUser>();
var app = builder.Build();
APIClient.Connect(builder.Configuration);
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

View File

@ -3,16 +3,16 @@
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:51304",
"sslPort": 44359
"applicationUrl": "http://localhost:63952",
"sslPort": 44327
}
},
"profiles": {
"DiningRoomClientApp": {
"DiningRoomUserApp": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7143;http://localhost:5230",
"applicationUrl": "https://localhost:7001;http://localhost:5154",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}

View File

@ -0,0 +1,65 @@
@using DiningRoomContracts.ViewModels
@model List<ComponentViewModel>
@{
ViewData["Title"] = "Components";
}
<head>
<link rel="stylesheet" href="~/css/style.css" asp-append-version="true" />
</head>
<div class="text-center">
<h2 class="u-text u-text-custom-color-1 u-text-default u-text-1"> Список продуктов</h2>
</div>
<form method="post">
<div class="main">
<table class="table">
<thead>
<tr>
<th>
Номер
</th>
<th>
Название
</th>
<th>
Цена
</th>
<th>
Ед.изм.
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr style="height: 75px">
<td>
@Html.DisplayFor(modelItem => item.Id)
</td>
<td>
@Html.DisplayFor(modelItem => item.ComponentName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Cost)
</td>
<td>
@Html.DisplayFor(modelItem => item.Unit)
</td>
</tr>
}
</tbody>
</table>
<div class="buttons-action-with-component">
<div class="button">
<a asp-area="" asp-controller="Home" asp-action="CreateComponent" class="button-action" style="width: 130px">Добавить</a>
</div>
<div class="button">
<a asp-area="" asp-controller="Home" asp-action="UpdateComponent" class="button-action" style="width: 130px">Изменить</a>
</div>
<div class="button">
<a asp-area="" asp-controller="Home" asp-action="DeleteComponent" class="button-action" style="width: 130px">Удалить</a>
</div>
</div>
</div>
</form>

View File

@ -0,0 +1,29 @@
@using DiningRoomContracts.ViewModels
@model DiningRoomUserApp.Models.ComponentUnitViewModel
@{
ViewData["Title"] = "CreateComponent";
}
<head>
<link rel="stylesheet" href="~/css/style.css" asp-append-version="true" />
</head>
<div class="text-center">
<h2 class="u-text u-text-custom-color-1 u-text-default u-text-1"> Добавить продукт</h2>
</div>
<form method="post">
<input name="componentName" style="margin-bottom: 20px" type="text" placeholder="Введите название продукта" class="form-control" />
<input name="componentPrice" style="margin-bottom: 20px" type="number" placeholder="Введите стоимость продукта" class="form-control" step="1" />
<div class="spisok">
<label class="u-label u-text-custom-color-1 u-label-1">Единицы измерения: </label>
<div>
@Html.DropDownList("unit", (SelectList)ViewBag.ComponentUnits, new { @class = "form-control" })
</div>
</div>
<div class="button">
<button class="button-action" type="submit">Сохранить</button>
</div>
<div class="button">
<a asp-area="" asp-controller="Home" asp-action="Components" class="button-action">Назад</a>
</div>
</form>

View File

@ -0,0 +1,28 @@
@using DiningRoomContracts.ViewModels
@model ComponentViewModel
@{
ViewData["Title"] = "CreateProduct";
}
<head>
<link rel="stylesheet" href="~/css/style.css" asp-append-version="true" />
</head>
<div class="text-center">
<h2 class="u-text u-text-custom-color-1 u-text-default u-text-1"> Добавить блюдо</h2>
</div>
<form method="post">
<input name="productName" style="margin-bottom: 20px" type="text" placeholder="Введите название блюда" class="form-control" />
<input name="productPrice" style="margin-bottom: 20px" type="number" placeholder="Введите стоимость блюда" class="form-control" step="1" />
<div class="spisok">
<label class="u-label u-text-custom-color-1 u-label-1">Продукты: </label>
<div>
@Html.ListBox("components", (MultiSelectList)ViewBag.Components, new { @class = "form-control", size = "10" })
</div>
</div>
<div class="button">
<button class="button-action" type="submit">Сохранить</button>
</div>
<div class="button">
<a asp-area="" asp-controller="Home" asp-action="Products" class="button-action">Назад</a>
</div>
</form>

View File

@ -0,0 +1,22 @@
@{
ViewData["Title"] = "DeleteComponent";
}
<head>
<link rel="stylesheet" href="~/css/style.css" asp-append-version="true" />
</head>
<div class="text-center">
<h2 class="u-text u-text-custom-color-1 u-text-default u-text-1"> Удалить продукт</h2>
</div>
<form method="post">
<div class="spisok">
<label class="u-label u-text-custom-color-1 u-label-1">Продукт: </label>
<select id="component" name="component" class="form-control" asp-items="@(new SelectList(@ViewBag.Components, "Id", "ComponentName"))"></select>
</div>
<div class="button">
<button type="submit" class="button-action">Удалить</button>
</div>
<div class="button">
<a asp-area="" asp-controller="Home" asp-action="Components" class="button-action">Назад</a>
</div>
</form>

View File

@ -0,0 +1,22 @@
@{
ViewData["Title"] = "DeleteRoom";
}
<head>
<link rel="stylesheet" href="~/css/style.css" asp-append-version="true" />
</head>
<div class="text-center">
<h2 class="u-text u-text-custom-color-1 u-text-default u-text-1"> Удалить комнату</h2>
</div>
<form method="post">
<div class="spisok">
<label class="u-label u-text-custom-color-1 u-label-1">Комната: </label>
<select id="room" name="room" class="form-control" asp-items="@(new SelectList(@ViewBag.Rooms, "Id", "RoomNumber"))"></select>
</div>
<div class="button">
<button type="submit" class="button-action">Удалить</button>
</div>
<div class="button">
<a asp-area="" asp-controller="Home" asp-action="Rooms" class="button-action">Назад</a>
</div>
</form>

View File

@ -0,0 +1,37 @@
@{
ViewData["Title"] = "Enter";
}
<head>
<link rel="stylesheet" href="~/css/enter.css" asp-append-version="true" />
</head>
<div class="text-center">
<h2 class="u-text u-text-custom-color-1 u-text-default u-text-1"> Вход в приложение</h2>
</div>
<form method="post">
<div class="main">
<div class="main_wrapper">
<div class="main_block">
<div class="main_fields">
<div class="main_field_one">
<input type="text" placeholder="логин/почта" name="login">
</div>
<div class="main_field_two">
<input type="password" placeholder="пароль" name="password">
</div>
</div>
<div class="class_login">
<button class="button_login" type="submit">
Вход
</button>
</div>
<div class="down_word">
Если у вас нет аккаунта то
<a href="Register" class="word_registr">
заригестрируйтесь
</a>
</div>
</div>
</div>
</div>
</form>

View File

@ -0,0 +1,50 @@
@{
ViewData["Title"] = "Home Page";
}
<head>
<link rel="stylesheet" href="~/css/style.css" asp-append-version="true" />
</head>
<style>
.main {
background-repeat: no-repeat;
background-size: cover;
width: 100%;
display: flex;
align-items: center;
margin-top: 124px;
}
.intro_wrapper{
display: flex;
justify-content: right;
min-height: 240px;
}
.intro_block {
width: 553px;
}
.intro_title {
font-size: 60px;
font-weight: 700;
margin: 0 0 29px 0;
}
.intro_text {
font-size: 20px;
margin: 0;
}
</style>
<form method="post">
<div class="main">
<div class="container-fluid">
<div class="intro_wrapper">
<div class="intro_block">
<h1 class="intro_title">
Столовая "Рога и Копыта"
</h1>
<p class="intro_text">
Здесь ты сможешь добавлять продукты, блюда и напитки по картам
</p>
</div>
</div>
</div>
</div>
</form>

View File

@ -0,0 +1,43 @@
@using DiningRoomContracts.ViewModels
@model UserViewModel
@{
ViewData["Title"] = "Privacy";
}
<head>
<link rel="stylesheet" href="~/css/style.css" asp-append-version="true" />
</head>
<style>
input {
margin-bottom: 20px;
max-width: 400px;
}
.pole{
display:flex;
justify-content:center;
}
</style>
<div class="text-center">
<h2 class="display-4">Личные данные</h2>
</div>
<form method="post">
<label class="u-label u-text-custom-color-1 u-label-1" style="display:flex;justify-content:center">Логин </label>
<div class="pole">
<input type="text" name="login" class="form-control" value="@Model.Login" />
</div>
<label class="u-label u-text-custom-color-1 u-label-1" style="display:flex;justify-content:center">Почта </label>
<div class="pole">
<input type="email" name="email" class="form-control" value="@Model.Email" />
</div>
<label class="u-label u-text-custom-color-1 u-label-1" style="display:flex;justify-content:center">Пароль </label>
<div class="pole">
<input type="password" name="password" class="form-control" value="@Model.Password" />
</div>
<div class="button" style="display:flex;justify-content:center">
<button class="button-action" type="submit">Сохранить</button>
</div>
</form>

View File

@ -0,0 +1,59 @@
@using DiningRoomContracts.ViewModels
@model List<ProductViewModel>
@{
ViewData["Title"] = "Products";
}
<head>
<link rel="stylesheet" href="~/css/style.css" asp-append-version="true" />
</head>
<div class="text-center">
<h2 class="u-text u-text-custom-color-1 u-text-default u-text-1"> Список блюд</h2>
</div>
<form method="post">
<div class="main">
<table class="table">
<thead>
<tr>
<th>
Номер
</th>
<th>
Название блюда
</th>
<th>
Цена
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr style="height: 75px">
<td>
@Html.DisplayFor(modelItem => item.Id)
</td>
<td>
@Html.DisplayFor(modelItem => item.ProductName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Cost)
</td>
</tr>
}
</tbody>
</table>
<div class="buttons-action-with-product">
<div class="button">
<a asp-area="" asp-controller="Home" asp-action="CreateProduct" class="button-action" style="width: 130px">Добавить</a>
</div>
<div class="button">
<a asp-area="" asp-controller="Home" asp-action="UpdateProduct" class="button-action" style="width: 130px">Изменить</a>
</div>
<div class="button">
<a asp-area="" asp-controller="Home" asp-action="DeleteProduct" class="button-action" style="width: 130px">Удалить</a>
</div>
</div>
</div>
</form>

View File

@ -0,0 +1,40 @@
@{
ViewData["Title"] = "Register";
}
<head>
<link rel="stylesheet" href="~/css/register.css" asp-append-version="true" />
</head>
<div class="text-center">
<h2 class="u-text u-text-custom-color-1 u-text-default u-text-1">Регистрация в приложении</h2>
</div>
<form method="post">
<div class="main">
<div class="main_wrapper">
<div class="main_block">
<div class="main_fields">
<div class="up_word">
<p class="main_text">
Введите все данные указанные ниже<br>
для регистрации
</p>
</div>
<div class="main_field">
<input type="text" placeholder="Логин" name="login">
</div>
<div class="main_field">
<input type="email" placeholder="Эл. почта" name="email">
</div>
<div class="main_field">
<input type="password" placeholder="Пароль" name="password">
</div>
</div>
<div class="class_login">
<button class="button_login" type="submit">
Регистрация
</button>
</div>
</div>
</div>
</div>
</form>

View File

@ -0,0 +1,37 @@
@using DiningRoomContracts.ViewModels;
@{
ViewData["Title"] = "UpdateComponent";
}
<head>
<link rel="stylesheet" href="~/css/style.css" asp-append-version="true" />
</head>
<div class="text-center">
<h2 class="u-text u-text-custom-color-1 u-text-default u-text-1"> Обновить продукт</h2>
</div>
<form method="post">
<div class="spisok">
<label class="u-label u-text-custom-color-1 u-label-1">Продукты: </label>
<select id="component" name="component" class="form-control" asp-items="@(new SelectList(@ViewBag.Components, "Id", "ComponentName"))"></select>
</div>
<div class="form-group">
<input name="componentName" style="margin-bottom: 20px" type="text" placeholder="Введите новое название продукта" class="form-control" />
</div>
<div class="form-group">
<input name="componentPrice" style="margin-bottom: 20px" type="number" placeholder="Введите новую стоимость продукта" class="form-control" step="1" />
</div>
<br>
<div class="spisok">
<label class="u-label u-text-custom-color-1 u-label-1">Единицы измерения: </label>
<div>
@Html.DropDownList("unit", (SelectList)ViewBag.ComponentUnits, new { @class = "form-control" })
</div>
</div>
<br>
<div class="button">
<button class="button-action">Сохранить</button>
</div>
<div class="button">
<a asp-area="" asp-controller="Home" asp-action="Components" class="button-action">Назад</a>
</div>
</form>

View File

@ -0,0 +1,70 @@
@using DiningRoomContracts.ViewModels;
@{
ViewData["Title"] = "UpdateProduct";
}
<head>
<link rel="stylesheet" href="~/css/style.css" asp-append-version="true" />
</head>
<div class="text-center">
<h2 class="u-text u-text-custom-color-1 u-text-default u-text-1"> Обновить блюдо</h2>
</div>
<form method="post">
<div class="spisok">
<label class="u-label u-text-custom-color-1 u-label-1">Блюда: </label>
<select id="product" name="product" class="form-control" asp-items="@(new SelectList(@ViewBag.Products, "Id", "ProductName"))"></select>
</div>
<div class="form-group">
<input name="productName" style="margin-bottom: 20px" type="text" placeholder="Введите новое название блюда" class="form-control" />
</div>
<div class="form-group">
<input name="productPrice" style="margin-bottom: 20px" type="number" placeholder="Введите новую стоимость блюда" class="form-control" step="1" />
</div>
<br>
<div class="row">
<div class="col-4">Продукты:</div>
<div class="col-8">
<select name="components" class="form-control" multiple size="5" id="components">
@foreach (var component in ViewBag.Components)
{
<option value="@component.Id" data-name="@component.Id">@component.ComponentName</option>
}
</select>
</div>
</div>
<br>
<div class="button">
<button class="button-action">Сохранить</button>
</div>
<div class="button">
<a asp-area="" asp-controller="Home" asp-action="Rooms" class="button-action">Назад</a>
</div>
</form>
@section Scripts
{
<script>
function check() {
var room = $('#room').val();
$("#dinners option:selected").removeAttr("selected");
if (room) {
$.ajax({
method: "GET",
url: "/Home/GetRoom",
data: { roomId: room },
success: function (result) {
$('#roomNumber').val(result.roomNumber);
$('#roomPrice').val(result.RoomPrice);
$('#dateCreate').val(result.DateCreate);
$.map(result.item2, function (n) {
$(`option[data-name=${n.item2}]`).attr("selected", "selected")
});
}
});
};
}
check();
$('#room').on('change', function () {
check();
});
</script>
}

View File

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["DiningRoomAdmin"] - Столовая "Рога и Копыта"</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/DiningRoomUserApp.styles.css" asp-append-version="true" />
<style>
body{
background-image: url('https://avatanplus.com/files/resources/original/5b65647d4d98f16504108986.jpg');
background-repeat: no-repeat;
background-size: cover;
}
.href-footer{
text-decoration:none;
}
</style>
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">
<img src="https://thumbs.dreamstime.com/b/%D0%BC%D0%B8%D0%BD%D0%B8%D0%BC%D0%B0%D0%BB%D0%B8%D1%81%D1%82%D0%B8%D1%87%D0%BD%D1%8B%D0%B9-%D1%87%D0%B5%D1%80%D0%BD%D0%BE-%D0%B1%D0%B5%D0%BB%D1%8B%D0%B9-%D1%80%D0%B8%D1%81%D1%83%D0%BD%D0%BE%D0%BA-%D0%BE%D1%82%D0%B5%D0%BB%D1%8F-%D1%81%D0%B8%D0%BB%D1%83%D1%8D%D1%82-%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D1%8F-%D0%B3%D0%BE%D1%81%D1%82%D0%B8%D0%BD%D0%B8%D1%86%D1%8B-%D0%B2-292394123.jpg"
alt="Описание изображения" width="60">
Столовая "Рога и Копыта"
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-smrow-reverse justify-content-end" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" asparea="" asp-controller="Home" asp-action="Index">Главное меню</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Справочники
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<li class="nav-item">
<a class="nav-link" asparea="" asp-controller="Home" asp-action="Components">Продукты</a>
</li>
<li class="nav-item">
<a class="nav-link" asparea="" asp-controller="Home" asp-action="Products">Блюда</a>
</li>
<li class="nav-item">
<a class="nav-link" asparea="" asp-controller="Home" asp-action="Drinks">Напитки</a>
</li>
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Отчеты
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<li class="nav-item">
<a class="nav-link" asparea="" asp-controller="Home" asp-action="MealPlanDinnerReport">Отчет (word/excel)</a>
</li>
<li class="nav-item">
<a class="nav-link" asparea="" asp-controller="Home" asp-action="AddDinnerToFile">Отчет (pdf) </a>
</li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link" asparea="" asp-controller="Home" asp-action="AddRoomToMealPlan">Привязка</a>
</li>
<li class="nav-item">
<a class="nav-link" asparea="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link" asparea="" asp-controller="Home" asp-action="Register">Регистрация</a>
</li>
<li class="nav-item">
<a class="nav-link" asparea="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="bg-light border-top footer text-muted fixed-bottom">
<div class="container">
&copy; 2024 - DiningRoom - <a asp-area="" aspcontroller="Home" asp-action="Privacy" class="href-footer">Личные данные</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View File

@ -0,0 +1,3 @@
@using DiningRoomUserApp
@using DiningRoomUserApp.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -5,6 +5,5 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"IPAddress": "http://localhost:5150/"
"IPAddress": "http://localhost:5121/"
}

View File

@ -0,0 +1,78 @@
.main {
margin-top: 50px;
display: flex;
align-items: center;
justify-content: center;
}
.main_wrapper {
width: 430px;
display: flex;
justify-content: center;
text-align: center;
}
.main_block {
margin-top: 35px;
}
.main_fields {
margin-top: 18px;
}
input {
height: 53px;
width: 100%;
font-size: 20px;
line-height: 16px;
border: 1px solid #000000;
border-radius: 30px;
padding-left: 31px;
}
.main_field_one {
margin-bottom: 17px;
width: 100%;
}
.class_login {
width: 100%;
display: flex;
justify-content: center;
margin-top: 84px;
}
.button_login {
background-color: #FFFFFF;
display: flex;
justify-content: center;
align-items: center;
width: 216px;
height: 39px;
border-radius: 30px;
border: 1px solid #000000;
font-size: 20px;
line-height: 39px;
transition: 0.2s ease;
cursor: pointer;
}
.button_login:hover {
background: #E3E3E3;
}
.down_word {
width: 100%;
margin-top: 23px;
font-size: 15px;
}
.word_registr {
text-decoration: none;
color: #18BDF1;
transition: color 0.2s ease;
}
.word_registr:hover {
color: #91F0FD;
}

View File

@ -0,0 +1,73 @@
.up_word {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 10px;
}
.main_text {
font-size: 17px;
}
.main {
display: flex;
align-items: center;
justify-content: center;
}
.main_wrapper {
width: 430px;
display: flex;
justify-content: center;
text-align: center;
}
.main_block {
margin-top: 20px;
}
.main_fields {
margin-top: 15px;
}
input {
height: 53px;
width: 100%;
font-size: 20px;
line-height: 16px;
border: 1px solid #000000;
border-radius: 30px;
padding-left: 31px;
}
.main_field {
margin-bottom: 10px;
width: 100%;
}
.class_login {
width: 100%;
display: flex;
justify-content: center;
margin-top: 55px;
}
.button_login {
background-color: #FFFFFF;
display: flex;
justify-content: center;
align-items: center;
width: 216px;
height: 39px;
border-radius: 30px;
border: 1px solid #000000;
font-size: 20px;
line-height: 39px;
transition: 0.2s ease;
cursor: pointer;
}
.button_login:hover {
background: #E3E3E3;
}

View File

@ -0,0 +1,66 @@
.text-center {
margin-bottom: 30px;
}
.list-words-add {
display: flex;
justify-content: center;
font-size: 20px;
margin-top: 20px;
margin-bottom: 20px;
font-weight: bold;
}
.table {
text-align: center;
}
.spisok {
margin-bottom: 20px;
}
.word-dinner {
font-size: 25px;
display: flex;
justify-content: center;
}
.button-action {
display: flex;
width: 300px;
height: 40px;
border-radius: 10px;
border: 1px solid #000000;
align-items: center;
justify-content: center;
background-color: #BDBDBD;
text-decoration: none;
color: #000000;
transition: 0.2s ease;
margin-bottom: 10px;
}
.button-action:hover {
background-color: #D2D3D3;
color: #393939;
}
.buttons-create-file {
display: flex;
justify-content: center;
}
.buttons-action-with-drink {
display: flex;
justify-content: space-between;
}
.buttons-action-with-product {
display: flex;
justify-content: space-between;
}
.buttons-action-with-component {
display: flex;
justify-content: space-between;
}

View File

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Some files were not shown because too many files have changed in this diff Show More