............…………………….…………...„--~*'¯…….'\
............………….…………………… („-~~--„¸_….,/ì
...........…….…………………….¸„-^"¯ : : : : :¸-¯"¯/'
............……………………¸„„-^"¯ : : : : : : : '\¸„„,-"
**¯¯¯'^^~-„„„----~^*'"¯ : : : : : : : : : :¸-"
.:.:.:.:.„-^" : : : : : : : : : : : : : : : : :„-"
:.:.:.:.:.:.:.:.:.:.: : : : : : : : : : ¸„-^¯
.::.:.:.:.:.:.:.:. : : : : : : : ¸„„-^¯
:.' : : '\ : : : : : : : ;¸„„-~"¯
:.:.:: :"-„""***/*'ì¸'¯
:.': : : : :"-„ : : :"\
.:.:.: : : : :" : : : : \,
:.: : : : : : : : : : : : 'Ì
: : : : : : :, : : : : : :/
"-„_::::_„-*__„„
This commit is contained in:
Данияр Аглиуллов 2023-03-06 02:22:10 +04:00
parent b79c79886d
commit ed9206d516
13 changed files with 478 additions and 23 deletions

View File

@ -4,6 +4,7 @@ using ConfectioneryContracts.SearchModels;
using ConfectioneryContracts.ViewModels;
using ConfectioneryDataModels.Models;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
namespace ConfectioneryRestApi.Controllers
{
@ -35,6 +36,21 @@ namespace ConfectioneryRestApi.Controllers
}
}
[HttpGet]
public ShopViewModel? GetJsonShop(int id)
{
try
{
return _logic.ReadElement(new() { Id = id });
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения магазина");
throw;
}
}
[HttpPost]
public void CRUDShop(Action action)
{

View File

@ -0,0 +1,51 @@
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Text;
namespace ConfectioneryShopApp
{
public class APIClient
{
private static readonly HttpClient _client = new();
public static bool IsAccessAllowed { get; set; } = false;
public static string AccessPassword { get; private set; } = string.Empty;
public static void Connect(IConfiguration configuration)
{
AccessPassword = configuration["PasswordToAccessShop"];
_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

@ -6,6 +6,14 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ConfectioneryContracts\ConfectioneryContracts.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="Views\Shared\_Layout.cshtml">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>

View File

@ -1,6 +1,10 @@
using ConfectioneryShopApp.Models;
using ConfectioneryShopApp;
using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.ViewModels;
using ConfectioneryShopApp.Models;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using ConfectioneryContracts.SearchModels;
namespace ConfectioneryShopApp.Controllers
{
@ -15,11 +19,20 @@ namespace ConfectioneryShopApp.Controllers
public IActionResult Index()
{
return View();
if (APIClient.IsAccessAllowed is false)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.GetRequest<List<ShopViewModel>>($"api/shop/getshops"));
}
[HttpGet]
public IActionResult Privacy()
{
if (APIClient.IsAccessAllowed is false)
{
return Redirect("~/Home/Enter");
}
return View();
}
@ -28,5 +41,158 @@ namespace ConfectioneryShopApp.Controllers
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
[HttpGet]
public IActionResult Enter()
{
return View();
}
[HttpPost]
public void Enter(string password)
{
if (string.IsNullOrEmpty(password))
{
throw new Exception("Введите пароль");
}
APIClient.IsAccessAllowed = password.Equals(APIClient.AccessPassword);
if (APIClient.IsAccessAllowed is false)
{
throw new Exception("Неверный пароль");
}
Response.Redirect("Index");
}
[HttpGet]
public IActionResult Create()
{
return View();
}
[HttpPost]
public void Create(string name, string address, int maxCount)
{
if (APIClient.IsAccessAllowed is false)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
if (maxCount <= 0)
{
throw new Exception("Количество и сумма должны быть больше 0");
}
if (string.IsNullOrEmpty(name))
{
throw new Exception($"Имя магазина не должно быть пустым");
}
if (string.IsNullOrEmpty(address))
{
throw new Exception($"Адрес магазина не должен быть пустым");
}
APIClient.PostRequest("api/shop/createshop", new ShopBindingModel
{
Name = name,
Address = address,
MaxCountPastries = maxCount,
});
Response.Redirect("Index");
}
[HttpGet]
public Tuple<string, ShopViewModel?> GetTablePastriesFromShop(int shop)
{
var sh = APIClient.GetRequest<ShopViewModel>($"api/shop/getjsonshop?id={shop}");
var resultHtml = "";
if (sh != null)
{
foreach (var (item, count) in sh.Pastries.Values)
{
resultHtml += "<tr>";
resultHtml += $"<td>{item?.PastryName ?? string.Empty}</td>";
resultHtml += $"<td>{item?.Price ?? 0}</td>";
resultHtml += $"<td>{count}</td>";
resultHtml += "</tr>";
}
}
return Tuple.Create(resultHtml, sh);
}
[HttpGet]
public IActionResult Update()
{
ViewBag.Shops = APIClient.GetRequest<List<ShopViewModel>>("api/shop/getshops");
return View();
}
[HttpPost]
public void Update(int shop, string name, string address)
{
if (APIClient.IsAccessAllowed is false)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
if (string.IsNullOrEmpty(name))
{
throw new Exception($"Имя магазина не должно быть пустым");
}
if (string.IsNullOrEmpty(address))
{
throw new Exception($"Адрес магазина не должен быть пустым");
}
APIClient.PostRequest("api/shop/updateshop", new ShopBindingModel
{
Id = shop,
Name = name,
Address = address,
});
Response.Redirect("Index");
}
[HttpGet]
public IActionResult Delete()
{
ViewBag.Shops = APIClient.GetRequest<List<ShopViewModel>>("api/shop/getshops");
return View();
}
[HttpPost]
public void Delete(int shop)
{
if (APIClient.IsAccessAllowed is false)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
APIClient.PostRequest("api/shop/deleteshop", new ShopBindingModel
{
Id = shop,
});
Response.Redirect("Index");
}
[HttpGet]
public IActionResult AddPastry()
{
ViewBag.Shops = APIClient.GetRequest<List<ShopViewModel>>("api/shop/getshops");
ViewBag.Pastries = APIClient.GetRequest<List<PastryViewModel>>("api/main/getpastrylist");
return View();
}
[HttpPost]
public void AddPastry(int shop, int pastry, int count)
{
if (APIClient.IsAccessAllowed is false)
{
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
}
if (count <= 0)
{
throw new Exception("Количество должно быть больше 0");
}
APIClient.PostRequest("api/shop/addpastryinshop", Tuple.Create(
new ShopSearchModel() { Id = shop },
new PastryBindingModel() { Id = pastry },
count
));
Response.Redirect("Index");
}
}
}

View File

@ -1,3 +1,5 @@
using ConfectioneryShopApp;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
@ -5,6 +7,8 @@ builder.Services.AddControllersWithViews();
var app = builder.Build();
APIClient.Connect(builder.Configuration);
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{

View File

@ -0,0 +1,33 @@
@using ConfectioneryContracts.ViewModels;
@using ConfectioneryDataModels.Models;
@model Dictionary<int, (IPastryModel, int)>
@{
ViewData["Title"] = "AddPastry";
}
<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="shop" name="shop" class="form-control" asp-items="@(new SelectList(@ViewBag.Shops, "Id", "Name"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Выбранное изделие:</div>
<div class="col-8">
<select id="pastry" name="pastry" class="form-control" asp-items="@(new SelectList(@ViewBag.Pastries, "Id", "PastryName"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Количество:</div>
<div class="col-8"><input type="text" id="count" name="count"/></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

@ -0,0 +1,24 @@
@{
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"><input type="text" name="name" id="name" /></div>
</div>
<div class="row">
<div class="col-4">Адрес магазина:</div>
<div class="col-8"><input type="text" id="address" name="address"/></div>
</div>
<div class="row">
<div class="col-4">Максимальное кол-во изделий:</div>
<div class="col-8"><input type="text" id="maxCount" name="maxCount"/></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

@ -0,0 +1,19 @@
@{
ViewData["Title"] = "Update";
}
<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="shop" name="shop" class="form-control" asp-items="@(new SelectList(@ViewBag.Shops, "Id", "Name"))"></select>
</div>
</div>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Удалить" class="btn btn-primary" /></div>
</div>
</div>
</form>

View File

@ -0,0 +1,15 @@
@{
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="password" name="password" /></div>
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Вход" class="btn btn-primary" /></div>
</div>
</form>

View File

@ -1,8 +1,66 @@
@{
ViewData["Title"] = "Home Page";
@using ConfectioneryContracts.ViewModels
@model List<ShopViewModel>
@{
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>
<h1 class="display-4">Заказы</h1>
</div>
<div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Введите пароль</h3>
return;
}
<p>
<a asp-action="Create">Создать магазин</a>
<a asp-action="Update">Редактировать магазин</a>
<a asp-action="Delete">Удалить магазин</a>
<a asp-action="AddPastry">Добавить изделие в магазин</a>
</p>
<table class="table">
<thead>
<tr>
<th>
Название магазина
</th>
<th>
Адрес
</th>
<th>
Дата открытия
</th>
<th>
Максимальное количество изделий
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Address)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateOpening)
</td>
<td>
@Html.DisplayFor(modelItem => item.MaxCountPastries)
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -0,0 +1,70 @@
@using ConfectioneryContracts.ViewModels;
@using ConfectioneryDataModels.Models;
@model Dictionary<int, (IPastryModel, int)>
@{
ViewData["Title"] = "Update";
}
<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="shop" name="shop" class="form-control" asp-items="@(new SelectList(@ViewBag.Shops, "Id", "Name"))"></select>
</div>
</div>
<div class="row">
<div class="col-4">Новое название магазина:</div>
<div class="col-8"><input type="text" name="name" id="name" /></div>
</div>
<div class="row">
<div class="col-4">Адрес магазина:</div>
<div class="col-8"><input type="text" id="address" name="address"/></div>
</div>
<table class="table">
<thead>
<tr>
<th>
Название изделия
</th>
<th>
Цена
</th>
<th>
Количество
</th>
</tr>
</thead>
<tbody id="table-pastries">
</tbody>
</table>
<div class="row">
<div class="col-8"></div>
<div class="col-4"><input type="submit" value="Изменить" class="btn btn-primary" /></div>
</div>
</form>
<script>
function check() {
var shop = $('#shop').val();
if (shop) {
$.ajax({
method: "GET",
url: "/Home/GetTablePastriesFromShop",
data: { shop: shop },
success: function (result) {
$('#name').val(result.item2.name);
$('#address').val(result.item2.address);
$('#table-pastries').html(result.item1);
}
});
};
}
check();
$('#shop').on('change', (e) => check());
</script>

View File

@ -3,10 +3,13 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - ConfectioneryClientApp</title>
<title>@ViewData["Title"] - ConfectioneryShopApp</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="~/ConfectioneryClientApp.styles.css" asp-append-version="true" />
<link rel="stylesheet" href="~/ConfectioneryShopApp.styles.css" asp-append-version="true" />
<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>
</head>
<body>
<header>
@ -22,15 +25,6 @@
<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>
@ -44,12 +38,9 @@
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2023 - ConfectioneryClientApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
&copy; 2023 - ConfectioneryShopApp - <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

@ -7,6 +7,6 @@
},
"AllowedHosts": "*",
"IPAddress": "http://localhost:5010/"
"IPAddress": "http://localhost:5010/",
"PasswordToAccessShop": "12345"
}