Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fb558a7ff2 | |||
| 1dab9faa62 | |||
| 3dd0029329 | |||
| 1a09e4f8ee | |||
| fb842980e3 | |||
| 789e0f79c1 | |||
| 126ace800a | |||
| ae68aacce0 | |||
| c4c81ca954 | |||
| 81b9544baf | |||
| fffe836607 | |||
| dd52116f62 | |||
| f38d94afa8 | |||
| aba6593945 | |||
| 35856195e8 | |||
| 47eb037c61 | |||
| 9c846fdaed |
@@ -3,8 +3,8 @@
|
|||||||
"windowsAuthentication": false,
|
"windowsAuthentication": false,
|
||||||
"anonymousAuthentication": true,
|
"anonymousAuthentication": true,
|
||||||
"iisExpress": {
|
"iisExpress": {
|
||||||
"applicationUrl": "http://localhost:20662",
|
"applicationUrl": "http://localhost:37980",
|
||||||
"sslPort": 44346
|
"sslPort": 44326
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"profiles": {
|
"profiles": {
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"dotnetRunMessages": true,
|
"dotnetRunMessages": true,
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"applicationUrl": "https://localhost:7085;http://localhost:5011",
|
"applicationUrl": "https://localhost:7000;http://localhost:5137",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
}
|
||||||
@@ -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>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<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" asp-action="Index">Программное обеспечение</a>
|
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Установка ПО</a>
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="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>
|
||||||
10
SoftwareInstallation/ConfectioneryClientApp/appsettings.json
Normal file
10
SoftwareInstallation/ConfectioneryClientApp/appsettings.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"IPAddress": "http://localhost:5010/"
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
@@ -16,11 +16,11 @@ namespace SoftwareInstallationRestApi.Controllers
|
|||||||
|
|
||||||
private readonly IPackageLogic _Package;
|
private readonly IPackageLogic _Package;
|
||||||
|
|
||||||
public MainController(ILogger<MainController> logger, IOrderLogic order, IPackageLogic package)
|
public MainController(ILogger<MainController> logger, IOrderLogic order, IPackageLogic Package)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_order = order;
|
_order = order;
|
||||||
_Package = package;
|
_Package = Package;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
using SoftwareInstallationContracts.BindingModels;
|
||||||
|
using SoftwareInstallationContracts.BusinessLogicsContracts;
|
||||||
|
using SoftwareInstallationContracts.SearchModels;
|
||||||
|
using SoftwareInstallationContracts.ViewModels;
|
||||||
|
using SoftwareInstallationDatabaseImplement.Models;
|
||||||
|
using SoftwareInstallationDataModels.Models;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SoftwareInstallationRestApi.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
public class ShopController : Controller
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
|
private readonly IShopLogic _logic;
|
||||||
|
|
||||||
|
public ShopController(IShopLogic logic, ILogger<ShopController> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_logic = logic;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public List<ShopViewModel>? GetShops()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _logic.ReadList(null);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Ошибка получения списка магазинов");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Получает на вход айди магазина и по нему возвращает магазин
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The identifier.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// Кортеж из магазина, итератора с изделиями которые находятся в магазине и итератора с количеством этих изделий.
|
||||||
|
/// </returns>
|
||||||
|
/// Почему изделия и их количество не находятся в одном кортеже? потому что тогда он их не сериализует
|
||||||
|
/// и я не знаю почему.
|
||||||
|
/// Также, к сожалению, приходится явно присваивать каждое поле из IPastyModel в PastyViewModel, поскольку
|
||||||
|
/// нельзя сериализовать интерфейс, и при это нельзя его неявно кастануть к PackageViewModel, даже если в
|
||||||
|
/// истинном типе SoftwareInstallationDatabaseImplement.Package такой каст есть.
|
||||||
|
/// Сделать же каст в PackageViewModel из IPackageModel нельзя, потому что запрещен каст с интерфейсами.
|
||||||
|
/// Единственный нормальный вариант создать отдельную сущность, где объединить изделия и их количество,
|
||||||
|
/// и уже ее хранить в магазине и соответственно ее передавать. Но поскольку для этого нужно перелопатить пол-проекта
|
||||||
|
/// и получить минус баллы на pr я откажусь от подобной идеи.
|
||||||
|
[HttpGet]
|
||||||
|
public Tuple<ShopViewModel, IEnumerable<PackageViewModel>, IEnumerable<int>>? GetShopWithPackages(int id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
var shop = _logic.ReadElement(new() { Id = id });
|
||||||
|
if (shop == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Tuple.Create(shop,
|
||||||
|
shop.Packages.Select(x => new PackageViewModel ()
|
||||||
|
{
|
||||||
|
Id = x.Value.Item1.Id,
|
||||||
|
Price = x.Value.Item1.Price,
|
||||||
|
PackageName = x.Value.Item1.PackageName,
|
||||||
|
}),
|
||||||
|
shop.Packages.Select(x => x.Value.Item2));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Ошибка получения магазина");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public void CRUDShop(Action action)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
action.Invoke();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Ошибка операции CRUD - {operation} с магазином", action.Method.Name);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public void UpdateShop(ShopBindingModel model) => CRUDShop(() => _logic.Update(model));
|
||||||
|
[HttpPost]
|
||||||
|
public void CreateShop(ShopBindingModel model) => CRUDShop(() => _logic.Create(model));
|
||||||
|
[HttpPost]
|
||||||
|
public void DeleteShop(ShopBindingModel model) => CRUDShop(() => _logic.Delete(model));
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public void AddPackageInShop(Tuple<ShopSearchModel, PackageViewModel, int> countPackageForShop)
|
||||||
|
{
|
||||||
|
CRUDShop(() => _logic.AddPackage(countPackageForShop.Item1, countPackageForShop.Item2, countPackageForShop.Item3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
using SoftwareInstallationBusinessLogic;
|
using SoftwareInstallationBusinessLogic;
|
||||||
using SoftwareInstallationBusinessLogic.BusinessLogics;
|
using SoftwareInstallationBusinessLogic.BusinessLogics;
|
||||||
using SoftwareInstallationContracts.BusinessLogicsContracts;
|
using SoftwareInstallationContracts.BusinessLogicsContracts;
|
||||||
using SoftwareInstallationContracts.StoragesContracts;
|
using SoftwareInstallationDatabaseImplement;
|
||||||
using SoftwareInstallationDatabaseImplement.Implements;
|
using SoftwareInstallationDatabaseImplement.Implements;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
|
using SoftwareInstallationContracts.StoragesContracts;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
@@ -13,12 +14,14 @@ builder.Logging.AddLog4Net("log4net.config");
|
|||||||
builder.Services.AddTransient<IClientStorage, ClientStorage>();
|
builder.Services.AddTransient<IClientStorage, ClientStorage>();
|
||||||
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
|
builder.Services.AddTransient<IOrderStorage, OrderStorage>();
|
||||||
builder.Services.AddTransient<IPackageStorage, PackageStorage>();
|
builder.Services.AddTransient<IPackageStorage, PackageStorage>();
|
||||||
|
builder.Services.AddTransient<IShopStorage, ShopStorage>();
|
||||||
|
|
||||||
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
|
builder.Services.AddTransient<IOrderLogic, OrderLogic>();
|
||||||
builder.Services.AddTransient<IClientLogic, ClientLogic>();
|
builder.Services.AddTransient<IClientLogic, ClientLogic>();
|
||||||
builder.Services.AddTransient<IPackageLogic, PackageLogic>();
|
builder.Services.AddTransient<IPackageLogic, PackageLogic>();
|
||||||
|
builder.Services.AddTransient<IShopLogic, ShopLogic>();
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
// Learn more about configuring Swagger/OpenAPI at
|
// Learn more about configuring Swagger/OpenAPI at
|
||||||
https://aka.ms/aspnetcore/swashbuckle
|
https://aka.ms/aspnetcore/swashbuckle
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
@@ -26,9 +29,8 @@ builder.Services.AddSwaggerGen(c =>
|
|||||||
{
|
{
|
||||||
c.SwaggerDoc("v1", new OpenApiInfo
|
c.SwaggerDoc("v1", new OpenApiInfo
|
||||||
{
|
{
|
||||||
Title = "SoftwareInstallationRestApi",
|
Title = "ConfectoneryRestApi",
|
||||||
Version
|
Version = "v1"
|
||||||
= "v1"
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
@@ -37,7 +39,7 @@ if (app.Environment.IsDevelopment())
|
|||||||
{
|
{
|
||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json",
|
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json",
|
||||||
"SoftwareInstallationRestApi v1"));
|
"ConfectoneryRestApi v1"));
|
||||||
}
|
}
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
"windowsAuthentication": false,
|
"windowsAuthentication": false,
|
||||||
"anonymousAuthentication": true,
|
"anonymousAuthentication": true,
|
||||||
"iisExpress": {
|
"iisExpress": {
|
||||||
"applicationUrl": "http://localhost:7121",
|
"applicationUrl": "http://localhost:29422",
|
||||||
"sslPort": 44331
|
"sslPort": 44350
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"profiles": {
|
"profiles": {
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
"dotnetRunMessages": true,
|
"dotnetRunMessages": true,
|
||||||
"launchBrowser": true,
|
"launchBrowser": true,
|
||||||
"launchUrl": "swagger",
|
"launchUrl": "swagger",
|
||||||
"applicationUrl": "https://localhost:7123;http://localhost:5044",
|
"applicationUrl": "https://localhost:7146;http://localhost:5010",
|
||||||
"environmentVariables": {
|
"environmentVariables": {
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
}
|
}
|
||||||
@@ -17,4 +17,10 @@
|
|||||||
<ProjectReference Include="..\SoftwareInstallationDatabaseImplement\SoftwareInstallationDatabaseImplement.csproj" />
|
<ProjectReference Include="..\SoftwareInstallationDatabaseImplement\SoftwareInstallationDatabaseImplement.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Update="log4net.config">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -6,5 +6,5 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"IPAddress": "http://localhost:5044"
|
"PasswordToAccessShop": "12345"
|
||||||
}
|
}
|
||||||
@@ -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/SoftwareInstallationRestApi.log" />
|
<file value="c:/temp/AbstractShopRestApi.log" />
|
||||||
<appendToFile value="true" />
|
<appendToFile value="true" />
|
||||||
<maximumFileSize value="100KB" />
|
<maximumFileSize value="100KB" />
|
||||||
<maxSizeRollBackups value="2" />
|
<maxSizeRollBackups value="2" />
|
||||||
55
SoftwareInstallation/ConfectioneryShopApp/APIClient.cs
Normal file
55
SoftwareInstallation/ConfectioneryShopApp/APIClient.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SoftwareInstallationShopApp
|
||||||
|
{
|
||||||
|
public class APIClient
|
||||||
|
{
|
||||||
|
private static readonly HttpClient _client = new();
|
||||||
|
|
||||||
|
public static bool IsAccessAllowed { get; private 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 void Login(string password)
|
||||||
|
{
|
||||||
|
IsAccessAllowed = password == AccessPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
using SoftwareInstallationShopApp;
|
||||||
|
using SoftwareInstallationContracts.BindingModels;
|
||||||
|
using SoftwareInstallationContracts.ViewModels;
|
||||||
|
using SoftwareInstallationShopApp.Models;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using SoftwareInstallationContracts.SearchModels;
|
||||||
|
|
||||||
|
namespace SoftwareInstallationShopApp.Controllers
|
||||||
|
{
|
||||||
|
public class HomeController : Controller
|
||||||
|
{
|
||||||
|
private readonly ILogger<HomeController> _logger;
|
||||||
|
|
||||||
|
public HomeController(ILogger<HomeController> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
[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 password)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(password))
|
||||||
|
{
|
||||||
|
throw new Exception("введите пароль");
|
||||||
|
}
|
||||||
|
APIClient.Login(password);
|
||||||
|
if (!APIClient.IsAccessAllowed)
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
MaxCountPackages = maxCount,
|
||||||
|
});
|
||||||
|
Response.Redirect("Index");
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public Tuple<string, ShopViewModel>? GetTablePackagesFromShop(int shop)
|
||||||
|
{
|
||||||
|
var result = APIClient.GetRequest<Tuple<ShopViewModel, IEnumerable<PackageViewModel>, IEnumerable<int>>?>($"api/shop/getshopwithpackages?id={shop}");
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var shopModel = result.Item1;
|
||||||
|
var resultHtml = "";
|
||||||
|
foreach (var (item, count) in result.Item2.Zip(result.Item3))
|
||||||
|
{
|
||||||
|
resultHtml += "<tr>";
|
||||||
|
resultHtml += $"<td>{item?.PackageName ?? string.Empty}</td>";
|
||||||
|
resultHtml += $"<td>{item?.Price ?? 0}</td>";
|
||||||
|
resultHtml += $"<td>{count}</td>";
|
||||||
|
resultHtml += "</tr>";
|
||||||
|
}
|
||||||
|
return Tuple.Create(resultHtml, shopModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
[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 AddPackage()
|
||||||
|
{
|
||||||
|
ViewBag.Shops = APIClient.GetRequest<List<ShopViewModel>>("api/shop/getshops");
|
||||||
|
ViewBag.Packages = APIClient.GetRequest<List<PackageViewModel>>("api/main/getpackagelist");
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public void AddPackage(int shop, int package, int count)
|
||||||
|
{
|
||||||
|
if (APIClient.IsAccessAllowed is false)
|
||||||
|
{
|
||||||
|
throw new Exception("Вы как суда попали? Суда вход только авторизованным");
|
||||||
|
}
|
||||||
|
if (count <= 0)
|
||||||
|
{
|
||||||
|
throw new Exception("Количество должно быть больше 0");
|
||||||
|
}
|
||||||
|
APIClient.PostRequest("api/shop/addpackageinshop", Tuple.Create(
|
||||||
|
new ShopSearchModel() { Id = shop },
|
||||||
|
new PackageViewModel() { Id = package },
|
||||||
|
count
|
||||||
|
));
|
||||||
|
Response.Redirect("Index");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace SoftwareInstallationShopApp.Models
|
||||||
|
{
|
||||||
|
public class ErrorViewModel
|
||||||
|
{
|
||||||
|
public string? RequestId { get; set; }
|
||||||
|
|
||||||
|
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||||
|
}
|
||||||
|
}
|
||||||
31
SoftwareInstallation/ConfectioneryShopApp/Program.cs
Normal file
31
SoftwareInstallation/ConfectioneryShopApp/Program.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using SoftwareInstallationShopApp;
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Add services to the container.
|
||||||
|
builder.Services.AddControllersWithViews();
|
||||||
|
|
||||||
|
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();
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:40086",
|
||||||
|
"sslPort": 44313
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"SoftwareInstallationShopApp": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"applicationUrl": "https://localhost:7114;http://localhost:5129",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\SoftwareInstallationContracts\SoftwareInstallationContracts.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Update="Views\Shared\_Layout.cshtml">
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
@using SoftwareInstallationContracts.ViewModels;
|
||||||
|
@using SoftwareInstallationDataModels.Models;
|
||||||
|
|
||||||
|
@model Dictionary<int, (IPackageModel, int)>
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "AddPackage";
|
||||||
|
}
|
||||||
|
<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="package" name="package" class="form-control" asp-items="@(new SelectList(@ViewBag.Packages, "Id", "PackageName"))"></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>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
@using SoftwareInstallationContracts.ViewModels;
|
||||||
|
@using SoftwareInstallationDataModels.Models;
|
||||||
|
|
||||||
|
@model Dictionary<int, (IPackageModel, int)>
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "AddPackage";
|
||||||
|
}
|
||||||
|
<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="package" name="package" class="form-control" asp-items="@(new SelectList(@ViewBag.Packages, "Id", "PackageName"))"></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>
|
||||||
@@ -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>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
@{
|
||||||
|
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>
|
||||||
|
</form>
|
||||||
@@ -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>
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
@using SoftwareInstallationContracts.ViewModels
|
||||||
|
|
||||||
|
@model List<ShopViewModel>
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Home Page";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<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="AddPackage">Добавить изделие в магазин</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.MaxCountPackages)
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user