17 Commits

Author SHA1 Message Date
fb558a7ff2 fix 2023-05-08 18:39:29 +04:00
1dab9faa62 fix 2023-04-25 17:31:19 +04:00
3dd0029329 забыл самое главное 2023-04-25 04:19:49 +04:00
1a09e4f8ee запустилось и точка 2023-04-25 04:16:15 +04:00
fb842980e3 fix 2023-04-23 18:23:38 +04:00
789e0f79c1 очередной fix 2023-04-10 22:23:52 +04:00
126ace800a это база 2023-04-10 21:29:40 +04:00
ae68aacce0 fix 2023-04-10 21:03:44 +04:00
c4c81ca954 Lab4_Hard 2023-04-10 20:58:46 +04:00
81b9544baf 3 усложнёнка 2023-04-04 00:23:02 +04:00
fffe836607 я гей 2023-04-03 18:03:56 +04:00
dd52116f62 z utq 2023-04-03 18:01:26 +04:00
f38d94afa8 fix 2023-03-19 02:27:22 +04:00
aba6593945 Lab2_Hard 2023-03-18 01:08:33 +04:00
35856195e8 fix 2023-03-18 00:29:38 +04:00
47eb037c61 fix 2023-03-06 20:44:20 +04:00
9c846fdaed Lab1_Hard 2023-03-06 00:18:18 +04:00
288 changed files with 80433 additions and 1231 deletions

View File

@@ -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"
} }

View File

@@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -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>

View File

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

View File

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -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]

View File

@@ -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));
}
}
}

View File

@@ -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();

View File

@@ -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"
} }

View File

@@ -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>

View File

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

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<log4net> <log4net>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender"> <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="c:/temp/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" />

View 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);
}
}
}
}

View File

@@ -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");
}
}
}

View File

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

View 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();

View File

@@ -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"
}
}
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

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,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>

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

@@ -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