Compare commits

...

103 Commits

Author SHA1 Message Date
bde0db3668 Добавил миграцию для удаления заказов 2024-04-22 12:46:01 +04:00
ce6b839975 Фикс хранилища, метод получения одного элемента заказа 2024-04-22 12:29:42 +04:00
5b500f9835 Отображение пароля клиента 2024-04-22 12:26:10 +04:00
ac5c359c5f Фикс хранилища заказов для отображения исполнителя 2024-04-22 12:25:56 +04:00
5786cfdc95 Фикс формы 2024-04-22 12:14:57 +04:00
23b67a747f Реализовал логику выполнения работ 2024-04-22 12:10:06 +04:00
23b9b538c9 Добавлен контроллер исполнителя в API 2024-04-22 12:01:55 +04:00
f6e470911d Добавлен метод ReadElement для логики заказа 2024-04-22 12:01:43 +04:00
4b1cc73321 Работа с формами 2024-04-22 11:52:50 +04:00
5e5eeffe7b Реализовал форму списка исполнителей 2024-04-22 11:39:58 +04:00
b33e1094da Реализовал форму добавления работника 2024-04-22 11:35:23 +04:00
86e83dac7b Это условие все таки нужно оказалось 2024-04-22 11:29:01 +04:00
9e79e50027 Фикс кода отдачи заказа на выполнение 2024-04-22 11:02:50 +04:00
86fa2bf375 Добавил вохможность поиска заказа по статусу и исполнителю 2024-04-22 10:58:35 +04:00
0ef5453070 Визуальные фиксы таблицы на главной форме 2024-04-22 10:52:30 +04:00
eaa6f1c3ca Создал миграции для добавления исполнителя 2024-04-22 10:52:09 +04:00
78fbcb7e13 Фикс пустого значения исполнителя в модели бд у заказа 2024-04-22 10:34:51 +04:00
bfbc7e59ee Реализовал связь моделей исполнителя и заказа в бд 2024-04-22 10:32:38 +04:00
fdb3444f21 Фиксы кода, реализация изменений по заказам для файлов и листа 2024-04-22 10:25:46 +04:00
6a118d4622 Добавил поле фио работника во view модель заказа, порписал поле id в модели бд 2024-04-22 10:18:23 +04:00
452f66187c Обновил поле ImplementerId в моделях заказа, теперь оно может быть null 2024-04-22 10:12:59 +04:00
653f011380 Добавил поле ImplementerId во все модели заказа 2024-04-22 10:04:47 +04:00
e0ccb4f889 Перевод метода взятия заказа в работу в однопоточный режим 2024-04-20 17:08:39 +04:00
92cab84005 Реализовано хранение исполнителя в бд 2024-04-20 16:34:56 +04:00
ff28061afa Реализовал модель хранения данных для исполнителя в бд 2024-04-20 16:15:24 +04:00
91e37358dc Реализовал хранилище исполнителей в файле 2024-04-20 14:51:30 +04:00
b752932b60 Реализовал хранилище для исполнителей на списке 2024-04-20 14:31:38 +04:00
ac043889c2 Реализовал модель хранения исполнителя для списка 2024-04-20 14:25:29 +04:00
2bb5209f9f Реализован класс логики исполнителя 2024-04-20 14:15:19 +04:00
01c7928e2a Добавлен интерфейс хранилища для исполнителя 2024-04-20 14:00:10 +04:00
3fef0274b2 Добавлен интерфейс логики для исполнителя 2024-04-20 13:58:24 +04:00
f7a7ed6ed6 Добавлена view модель исполнителя 2024-04-20 13:55:58 +04:00
fb7a2a4065 Добавил search модель исполнителя 2024-04-20 13:50:34 +04:00
cd0176b2d8 Добавил биндинг модель 2024-04-20 13:48:22 +04:00
198259830e Фикс модели исполнителя 2024-04-20 13:45:48 +04:00
72f55c5027 Добавлена модель-интерфейс исполнителя 2024-04-20 13:35:47 +04:00
73d3264d20 Правки в макете web 2024-04-08 11:07:12 +04:00
02be1b2c65 Готовая лаба 5 2024-04-07 13:45:41 +04:00
e972cea604 Изменен шаблон страниц 2024-04-07 13:03:06 +04:00
c2aecee976 Добавлена натсройка адреса 2024-04-07 12:52:22 +04:00
582d6f4946 Добавлен проект веб приложения 2024-04-07 12:48:31 +04:00
d82184c6a0 Добавлен MainController 2024-04-07 09:57:17 +04:00
8d912acd98 Добавлен контроллер для клиента 2024-04-07 01:56:52 +04:00
44af2044b6 Добавлен поиск по паролю (кто так вообще делает) 2024-04-07 01:56:01 +04:00
10082f1517 Добавил конфигурационный файл log4net 2024-04-07 01:25:50 +04:00
3c2a383103 Добавлен RESTAPI проект 2024-04-07 01:22:23 +04:00
59b2514874 Правка Grid на форме с клиентами 2024-04-07 00:55:26 +04:00
165d7df93f Реализована логика отображения клиента на главной форме 2024-04-07 00:51:23 +04:00
7fbe743e1a Реализовано добавление клиента в заказ 2024-04-07 00:41:06 +04:00
fbfb6f133b Реализована логика формы списка клиентов 2024-04-07 00:28:00 +04:00
305ce116c7 Настройка внешнего вида сорфмы списков клиентов 2024-04-07 00:14:29 +04:00
bf00322af8 Добавлена форма для списка клиентов без логики 2024-04-07 00:09:48 +04:00
6f5e4ad315 Создал миграцию для добавления клиента 2024-04-07 00:01:05 +04:00
645cdb306f Добавил реализацию информации о клиенте в заказе в списочное хранилизе и файловое хранилище 2024-04-06 23:54:12 +04:00
2bff37f117 Реализовано взаимодействие с сущностью клиента в сущности заказа 2024-04-06 23:41:33 +04:00
d67e4acbb8 Информация о клиенте добавлена в модель заказа 2024-04-06 23:04:10 +04:00
0e1780a96a Реализовано хранение клиентов в БД 2024-04-06 22:55:12 +04:00
b4b11629ed Реализована модель для хранения клиента в БД 2024-04-06 21:29:17 +04:00
936fb6f1d5 Реализована логика хранения клиента в файле 2024-04-06 20:17:19 +04:00
fda5b29e56 Добавлена модель клиента для логики хранеиния в файле 2024-04-06 20:13:16 +04:00
4b78a089b3 Изменено поле Id в поисковой модели для клиента 2024-04-06 20:04:29 +04:00
4b18777fc3 Реализована логика хранения клиента в списке 2024-04-06 20:04:05 +04:00
7b6853bc9f Реализована логику хранения клиента в списке 2024-04-06 17:58:46 +04:00
8655c06386 Добавлена проверка на наличие фио клиента в логику 2024-04-06 17:56:47 +04:00
0a39b0e81d Реализована логика клиента 2024-04-06 17:46:45 +04:00
d1f76526ac Добавлен класс интерфейс storage для клиента 2024-04-06 14:26:41 +04:00
c186900d17 Добавлен класс интерфейса бизнес логики для клиента 2024-04-06 14:25:25 +04:00
3d9db83280 Добавлен класс search модели клиента 2024-04-06 14:25:04 +04:00
a297252595 Добавлен класс view модели клиента 2024-04-06 14:20:25 +04:00
08fbeb87c1 Добавлен класс биндинг модели клиента 2024-04-06 14:19:30 +04:00
b8aba7688e Добавлен класс модели клиента 2024-04-06 14:18:40 +04:00
464cebeb0f Реализовано сохранение статуса заказов в PDF и в отчете 2024-03-24 22:50:41 +04:00
9f481f8879 Реализовано сохранение компонентов и изделий в excel по требованиям 2024-03-24 22:28:06 +04:00
e37e94a14f Реализовал сохранение списка изделий в word 2024-03-24 22:07:47 +04:00
f47e53df7d Реализована фильтрация заказов по дате для всех реализаций хранения 2024-03-24 21:50:48 +04:00
1c849d9f5a Работают все отчеты по дефолту, нужно подогнать под требования 2024-03-24 21:26:56 +04:00
28292950ad Добавлен отчет 2024-03-24 19:53:21 +04:00
0247ccc68b Установлен пакет ReportViewerCore 2024-03-24 17:03:22 +04:00
3588b7263a Добавлена форма отчета по компонентам и реализована ее логика 2024-03-24 16:59:41 +04:00
97aac1ac05 Исправлен порядок tab на формах 2024-03-24 16:45:53 +04:00
111637973c Реструктурирован проект с формами 2024-03-24 16:37:33 +04:00
adf0fa582c Реализована логика сохранения отчетов 2024-03-24 16:20:22 +04:00
2d0bd7ff56 Реализованы классы для отчета PDF 2024-03-24 16:14:34 +04:00
d0f0cf29c6 Добавлены дополнительные классы для отчета PDF 2024-03-24 16:08:26 +04:00
0118686e2b Реализованы классы для сохранения отчета в Excel 2024-03-24 15:35:37 +04:00
4d58b86778 Добавлены дополнительные классы для отчета Excel 2024-03-24 15:31:40 +04:00
3f98c6b58a Реализованы классы для отчета Word 2024-03-24 15:28:01 +04:00
4fd502a9dc Добавлены классы HelperModels и HelperEnums для отчетов Word 2024-03-24 15:01:54 +04:00
3e3def55a6 Созданы Bindong и View классы для отчетов 2024-03-24 14:54:52 +04:00
4ffda04240 Готовая лаба 3 2024-03-11 09:28:13 +04:00
4915cfcc0f Готовая лаб. работа 2 2024-02-26 10:08:58 +04:00
0036d7a05a Реализованы интерфейсы для логики хранения данных в файле 2024-02-26 09:57:24 +04:00
c1bc36a049 Реализован класс DataFileSingleton 2024-02-26 09:48:14 +04:00
4e317f4971 Реализованы модели хранения данных в файлах 2024-02-26 09:40:53 +04:00
267df68fda Поправлены формы 2024-02-26 09:02:50 +04:00
eeffc761e0 Готовая лаб. работа 1 2024-02-26 01:20:07 +04:00
3e34afb54b Баг с отображением устранен 2024-02-26 00:47:21 +04:00
a204cc5e69 Все реализовано, но есть баг: не сохраняются изделия и компоненты 2024-02-26 00:26:47 +04:00
ea0854e950 Почти все готово, осталось реализовать форму для списка изделий 2024-02-26 00:11:41 +04:00
53192ffd12 Реализованы все библиотеки классов для лаб. работы 1 2024-02-25 22:08:12 +04:00
385252ecd2 Реализована бизнес логика 2024-02-25 21:33:22 +04:00
fb38ed9959 Реализован проект Contracts 2024-02-25 18:57:38 +04:00
fc59da0008 Созданы проекты DataModels и Contracts 2024-02-25 18:41:53 +04:00
247 changed files with 87237 additions and 77 deletions

View File

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

View File

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

View File

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

View File

@ -0,0 +1,21 @@
using SecurirySystemClientApp;
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:51155",
"sslPort": 44375
}
},
"profiles": {
"SecurirySystemClientApp": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7141;http://localhost:5102",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,17 @@
<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.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SecuritySystemContracts\SecuritySystemContracts.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,54 @@
@{
ViewData["Title"] = "Создание заказа";
}
<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="secure" name="secure" class="form-control" asp-items="@(new SelectList(@ViewBag.Secures,"Id", "SecureName"))"></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>
$('#secure').on('change', function () {
check();
});
$('#count').on('change', function () {
check();
});
function check() {
var count = $('#count').val();
var secure = $('#secure').val();
if (count && secure) {
$.ajax({
method: "POST",
url: "/Home/Calc",
data: { count: count, secure: secure },
success: function (result) {
$("#sum").val(result);
}
});
};
}
</script>

View File

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace SecurirySystemClientApp.Views.Home
{
public class CreateModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@ -0,0 +1,20 @@
@{
ViewData["Title"] = "Вход";
}
<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

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace SecurirySystemClientApp.Views.Home
{
public class EnterModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@ -0,0 +1,75 @@
@using SecuritySystemContracts.ViewModels
@model List<OrderViewModel>
@{
ViewData["Title"] = "Главная";
}
<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>
</p>
<table class="table">
<thead>
<tr>
<th>
Номер
</th>
<th>
Продукт
</th>
<th>
Дата создания
</th>
<th>
Количество
</th>
<th>
Сумма
</th>
<th>
Статус
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem =>
item.Id)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.SecureName)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.DateCreate)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.Count)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.Sum)
</td>
<td>
@Html.DisplayFor(modelItem =>
item.Status)
</td>
</tr>
}
</tbody>
</table>
}
</div>

View File

@ -0,0 +1,34 @@
@using SecuritySystemContracts.ViewModels
@model ClientViewModel
@{
ViewData["Title"] = "Личные данные";
}
<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" value="@Model.Email" />
</div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8">
<input type="password" name="password" value="@Model.Password" />
</div>
</div>
<div class="row">
<div class="col-4">ФИО:</div>
<div class="col-8">
<input type="text" name="fio" value="@Model.ClientFIO" />
</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,26 @@
@{
ViewData["Title"] = "Регистрация";
}
<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="fio" /></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,12 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace SecurirySystemClientApp.Views.Home
{
public class RegisterModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@ -0,0 +1,25 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>

View File

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - SecuritySystemClientApp</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
</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">
<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" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm row-reverse">
<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 - SecuritySystem - <a asp-area="" asp controller="Home" asp-action="Privacy">Личные данные</a>
</div>
</footer>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>

View File

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

View File

@ -0,0 +1,2 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

View File

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

View File

@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

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

View File

@ -0,0 +1,18 @@
html {
font-size: 14px;
}
@media (min-width: 768px) {
html {
font-size: 16px;
}
}
html {
position: relative;
min-height: 100%;
}
body {
margin-bottom: 60px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,4 @@
// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
// for details on configuring this project to bundle and minify static web assets.
// Write your JavaScript code.

View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2011-2021 Twitter, Inc.
Copyright (c) 2011-2021 The Bootstrap Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,427 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
background-color: currentColor;
border: 0;
opacity: 0.25;
}
hr:not([size]) {
height: 1px;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-bs-original-title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-left: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.2em;
background-color: #fcf8e3;
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: #0d6efd;
text-decoration: underline;
}
a:hover {
color: #0a58ca;
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
direction: ltr /* rtl:ignore */;
unicode-bidi: bidi-override;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: #d63384;
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.2rem 0.4rem;
font-size: 0.875em;
color: #fff;
background-color: #212529;
border-radius: 0.2rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
font-weight: 700;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: #6c757d;
text-align: left;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]::-webkit-calendar-picker-indicator {
display: none;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: left;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: left;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
outline-offset: -2px;
-webkit-appearance: textfield;
}
/* rtl:raw:
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::file-selector-button {
font: inherit;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.min.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,424 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
@media (prefers-reduced-motion: no-preference) {
:root {
scroll-behavior: smooth;
}
}
body {
margin: 0;
font-family: var(--bs-body-font-family);
font-size: var(--bs-body-font-size);
font-weight: var(--bs-body-font-weight);
line-height: var(--bs-body-line-height);
color: var(--bs-body-color);
text-align: var(--bs-body-text-align);
background-color: var(--bs-body-bg);
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
hr {
margin: 1rem 0;
color: inherit;
background-color: currentColor;
border: 0;
opacity: 0.25;
}
hr:not([size]) {
height: 1px;
}
h6, h5, h4, h3, h2, h1 {
margin-top: 0;
margin-bottom: 0.5rem;
font-weight: 500;
line-height: 1.2;
}
h1 {
font-size: calc(1.375rem + 1.5vw);
}
@media (min-width: 1200px) {
h1 {
font-size: 2.5rem;
}
}
h2 {
font-size: calc(1.325rem + 0.9vw);
}
@media (min-width: 1200px) {
h2 {
font-size: 2rem;
}
}
h3 {
font-size: calc(1.3rem + 0.6vw);
}
@media (min-width: 1200px) {
h3 {
font-size: 1.75rem;
}
}
h4 {
font-size: calc(1.275rem + 0.3vw);
}
@media (min-width: 1200px) {
h4 {
font-size: 1.5rem;
}
}
h5 {
font-size: 1.25rem;
}
h6 {
font-size: 1rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-bs-original-title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul {
padding-right: 2rem;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: 0.5rem;
margin-right: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 0.875em;
}
mark {
padding: 0.2em;
background-color: #fcf8e3;
}
sub,
sup {
position: relative;
font-size: 0.75em;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
a {
color: #0d6efd;
text-decoration: underline;
}
a:hover {
color: #0a58ca;
}
a:not([href]):not([class]), a:not([href]):not([class]):hover {
color: inherit;
text-decoration: none;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
direction: ltr ;
unicode-bidi: bidi-override;
}
pre {
display: block;
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
font-size: 0.875em;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
code {
font-size: 0.875em;
color: #d63384;
word-wrap: break-word;
}
a > code {
color: inherit;
}
kbd {
padding: 0.2rem 0.4rem;
font-size: 0.875em;
color: #fff;
background-color: #212529;
border-radius: 0.2rem;
}
kbd kbd {
padding: 0;
font-size: 1em;
font-weight: 700;
}
figure {
margin: 0 0 1rem;
}
img,
svg {
vertical-align: middle;
}
table {
caption-side: bottom;
border-collapse: collapse;
}
caption {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
color: #6c757d;
text-align: right;
}
th {
text-align: inherit;
text-align: -webkit-match-parent;
}
thead,
tbody,
tfoot,
tr,
td,
th {
border-color: inherit;
border-style: solid;
border-width: 0;
}
label {
display: inline-block;
}
button {
border-radius: 0;
}
button:focus:not(:focus-visible) {
outline: 0;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
select {
text-transform: none;
}
[role=button] {
cursor: pointer;
}
select {
word-wrap: normal;
}
select:disabled {
opacity: 1;
}
[list]::-webkit-calendar-picker-indicator {
display: none;
}
button,
[type=button],
[type=reset],
[type=submit] {
-webkit-appearance: button;
}
button:not(:disabled),
[type=button]:not(:disabled),
[type=reset]:not(:disabled),
[type=submit]:not(:disabled) {
cursor: pointer;
}
::-moz-focus-inner {
padding: 0;
border-style: none;
}
textarea {
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
float: right;
width: 100%;
padding: 0;
margin-bottom: 0.5rem;
font-size: calc(1.275rem + 0.3vw);
line-height: inherit;
}
@media (min-width: 1200px) {
legend {
font-size: 1.5rem;
}
}
legend + * {
clear: right;
}
::-webkit-datetime-edit-fields-wrapper,
::-webkit-datetime-edit-text,
::-webkit-datetime-edit-minute,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-year-field {
padding: 0;
}
::-webkit-inner-spin-button {
height: auto;
}
[type=search] {
outline-offset: -2px;
-webkit-appearance: textfield;
}
[type="tel"],
[type="url"],
[type="email"],
[type="number"] {
direction: ltr;
}
::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-color-swatch-wrapper {
padding: 0;
}
::file-selector-button {
font: inherit;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
iframe {
border: 0;
}
summary {
display: list-item;
cursor: pointer;
}
progress {
vertical-align: baseline;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,8 @@
/*!
* Bootstrap Reboot v5.1.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){h1{font-size:2.5rem}}h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){h2{font-size:2rem}}h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){h3{font-size:1.75rem}}h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){h4{font-size:1.5rem}}h5{font-size:1.25rem}h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-right:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-right:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:.875em}mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:right}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:right;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:right}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}[type=email],[type=number],[type=tel],[type=url]{direction:ltr}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}
/*# sourceMappingURL=bootstrap-reboot.rtl.min.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,12 @@
Copyright (c) .NET Foundation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
these files except in compliance with the License. You may obtain a copy of the
License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

View File

@ -0,0 +1,432 @@
// Unobtrusive validation support library for jQuery and jQuery Validate
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// @version v3.2.11
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
/*global document: false, jQuery: false */
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define("jquery.validate.unobtrusive", ['jquery-validation'], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS-like environments that support module.exports
module.exports = factory(require('jquery-validation'));
} else {
// Browser global
jQuery.validator.unobtrusive = factory(jQuery);
}
}(function ($) {
var $jQval = $.validator,
adapters,
data_validation = "unobtrusiveValidation";
function setValidationValues(options, ruleName, value) {
options.rules[ruleName] = value;
if (options.message) {
options.messages[ruleName] = options.message;
}
}
function splitAndTrim(value) {
return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
}
function escapeAttributeValue(value) {
// As mentioned on http://api.jquery.com/category/selectors/
return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
}
function getModelPrefix(fieldName) {
return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
}
function appendModelPrefix(value, prefix) {
if (value.indexOf("*.") === 0) {
value = value.replace("*.", prefix);
}
return value;
}
function onError(error, inputElement) { // 'this' is the form element
var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
container.removeClass("field-validation-valid").addClass("field-validation-error");
error.data("unobtrusiveContainer", container);
if (replace) {
container.empty();
error.removeClass("input-validation-error").appendTo(container);
}
else {
error.hide();
}
}
function onErrors(event, validator) { // 'this' is the form element
var container = $(this).find("[data-valmsg-summary=true]"),
list = container.find("ul");
if (list && list.length && validator.errorList.length) {
list.empty();
container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
$.each(validator.errorList, function () {
$("<li />").html(this.message).appendTo(list);
});
}
}
function onSuccess(error) { // 'this' is the form element
var container = error.data("unobtrusiveContainer");
if (container) {
var replaceAttrValue = container.attr("data-valmsg-replace"),
replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
container.addClass("field-validation-valid").removeClass("field-validation-error");
error.removeData("unobtrusiveContainer");
if (replace) {
container.empty();
}
}
}
function onReset(event) { // 'this' is the form element
var $form = $(this),
key = '__jquery_unobtrusive_validation_form_reset';
if ($form.data(key)) {
return;
}
// Set a flag that indicates we're currently resetting the form.
$form.data(key, true);
try {
$form.data("validator").resetForm();
} finally {
$form.removeData(key);
}
$form.find(".validation-summary-errors")
.addClass("validation-summary-valid")
.removeClass("validation-summary-errors");
$form.find(".field-validation-error")
.addClass("field-validation-valid")
.removeClass("field-validation-error")
.removeData("unobtrusiveContainer")
.find(">*") // If we were using valmsg-replace, get the underlying error
.removeData("unobtrusiveContainer");
}
function validationInfo(form) {
var $form = $(form),
result = $form.data(data_validation),
onResetProxy = $.proxy(onReset, form),
defaultOptions = $jQval.unobtrusive.options || {},
execInContext = function (name, args) {
var func = defaultOptions[name];
func && $.isFunction(func) && func.apply(form, args);
};
if (!result) {
result = {
options: { // options structure passed to jQuery Validate's validate() method
errorClass: defaultOptions.errorClass || "input-validation-error",
errorElement: defaultOptions.errorElement || "span",
errorPlacement: function () {
onError.apply(form, arguments);
execInContext("errorPlacement", arguments);
},
invalidHandler: function () {
onErrors.apply(form, arguments);
execInContext("invalidHandler", arguments);
},
messages: {},
rules: {},
success: function () {
onSuccess.apply(form, arguments);
execInContext("success", arguments);
}
},
attachValidation: function () {
$form
.off("reset." + data_validation, onResetProxy)
.on("reset." + data_validation, onResetProxy)
.validate(this.options);
},
validate: function () { // a validation function that is called by unobtrusive Ajax
$form.validate();
return $form.valid();
}
};
$form.data(data_validation, result);
}
return result;
}
$jQval.unobtrusive = {
adapters: [],
parseElement: function (element, skipAttach) {
/// <summary>
/// Parses a single HTML element for unobtrusive validation attributes.
/// </summary>
/// <param name="element" domElement="true">The HTML element to be parsed.</param>
/// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
/// validation to the form. If parsing just this single element, you should specify true.
/// If parsing several elements, you should specify false, and manually attach the validation
/// to the form when you are finished. The default is false.</param>
var $element = $(element),
form = $element.parents("form")[0],
valInfo, rules, messages;
if (!form) { // Cannot do client-side validation without a form
return;
}
valInfo = validationInfo(form);
valInfo.options.rules[element.name] = rules = {};
valInfo.options.messages[element.name] = messages = {};
$.each(this.adapters, function () {
var prefix = "data-val-" + this.name,
message = $element.attr(prefix),
paramValues = {};
if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
prefix += "-";
$.each(this.params, function () {
paramValues[this] = $element.attr(prefix + this);
});
this.adapt({
element: element,
form: form,
message: message,
params: paramValues,
rules: rules,
messages: messages
});
}
});
$.extend(rules, { "__dummy__": true });
if (!skipAttach) {
valInfo.attachValidation();
}
},
parse: function (selector) {
/// <summary>
/// Parses all the HTML elements in the specified selector. It looks for input elements decorated
/// with the [data-val=true] attribute value and enables validation according to the data-val-*
/// attribute values.
/// </summary>
/// <param name="selector" type="String">Any valid jQuery selector.</param>
// $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
// element with data-val=true
var $selector = $(selector),
$forms = $selector.parents()
.addBack()
.filter("form")
.add($selector.find("form"))
.has("[data-val=true]");
$selector.find("[data-val=true]").each(function () {
$jQval.unobtrusive.parseElement(this, true);
});
$forms.each(function () {
var info = validationInfo(this);
if (info) {
info.attachValidation();
}
});
}
};
adapters = $jQval.unobtrusive.adapters;
adapters.add = function (adapterName, params, fn) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
/// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
/// mmmm is the parameter name).</param>
/// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
/// attributes into jQuery Validate rules and/or messages.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
if (!fn) { // Called with no params, just a function
fn = params;
params = [];
}
this.push({ name: adapterName, params: params, adapt: fn });
return this;
};
adapters.addBool = function (adapterName, ruleName) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation rule has no parameter values.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
/// of adapterName will be used instead.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, function (options) {
setValidationValues(options, ruleName || adapterName, true);
});
};
adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
/// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
/// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
/// have a minimum value.</param>
/// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
/// have a maximum value.</param>
/// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
/// have both a minimum and maximum value.</param>
/// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
/// contains the minimum value. The default is "min".</param>
/// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
/// contains the maximum value. The default is "max".</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
var min = options.params.min,
max = options.params.max;
if (min && max) {
setValidationValues(options, minMaxRuleName, [min, max]);
}
else if (min) {
setValidationValues(options, minRuleName, min);
}
else if (max) {
setValidationValues(options, maxRuleName, max);
}
});
};
adapters.addSingleVal = function (adapterName, attribute, ruleName) {
/// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
/// the jQuery Validate validation rule has a single value.</summary>
/// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
/// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
/// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
/// The default is "val".</param>
/// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
/// of adapterName will be used instead.</param>
/// <returns type="jQuery.validator.unobtrusive.adapters" />
return this.add(adapterName, [attribute || "val"], function (options) {
setValidationValues(options, ruleName || adapterName, options.params[attribute]);
});
};
$jQval.addMethod("__dummy__", function (value, element, params) {
return true;
});
$jQval.addMethod("regex", function (value, element, params) {
var match;
if (this.optional(element)) {
return true;
}
match = new RegExp(params).exec(value);
return (match && (match.index === 0) && (match[0].length === value.length));
});
$jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
var match;
if (nonalphamin) {
match = value.match(/\W/g);
match = match && match.length >= nonalphamin;
}
return match;
});
if ($jQval.methods.extension) {
adapters.addSingleVal("accept", "mimtype");
adapters.addSingleVal("extension", "extension");
} else {
// for backward compatibility, when the 'extension' validation method does not exist, such as with versions
// of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
// validating the extension, and ignore mime-type validations as they are not supported.
adapters.addSingleVal("extension", "extension", "accept");
}
adapters.addSingleVal("regex", "pattern");
adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength");
adapters.add("equalto", ["other"], function (options) {
var prefix = getModelPrefix(options.element.name),
other = options.params.other,
fullOtherName = appendModelPrefix(other, prefix),
element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
setValidationValues(options, "equalTo", element);
});
adapters.add("required", function (options) {
// jQuery Validate equates "required" with "mandatory" for checkbox elements
if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
setValidationValues(options, "required", true);
}
});
adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
var value = {
url: options.params.url,
type: options.params.type || "GET",
data: {}
},
prefix = getModelPrefix(options.element.name);
$.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
var paramName = appendModelPrefix(fieldName, prefix);
value.data[paramName] = function () {
var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']");
// For checkboxes and radio buttons, only pick up values from checked fields.
if (field.is(":checkbox")) {
return field.filter(":checked").val() || field.filter(":hidden").val() || '';
}
else if (field.is(":radio")) {
return field.filter(":checked").val() || '';
}
return field.val();
};
});
setValidationValues(options, "remote", value);
});
adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
if (options.params.min) {
setValidationValues(options, "minlength", options.params.min);
}
if (options.params.nonalphamin) {
setValidationValues(options, "nonalphamin", options.params.nonalphamin);
}
if (options.params.regex) {
setValidationValues(options, "regex", options.params.regex);
}
});
adapters.add("fileextensions", ["extensions"], function (options) {
setValidationValues(options, "extension", options.params.extensions);
});
$(function () {
$jQval.unobtrusive.parse(document);
});
return $jQval.unobtrusive;
}));

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,22 @@
The MIT License (MIT)
=====================
Copyright Jörn Zaefferer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,36 @@
Copyright JS Foundation and other contributors, https://js.foundation/
This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history
available at https://github.com/jquery/jquery
The following license applies to all parts of this software except as
documented below:
====
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
====
All files located in the node_modules and external directories are
externally maintained libraries used by this software which have their
own licenses; we recommend you read them, as their terms may differ from
the terms above.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3,18 +3,142 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.6.33815.320
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecuritySystemView", "SecuritySystemView\SecuritySystemView.csproj", "{B4D0310E-1162-4BCF-A7E0-2AC41959C963}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SecuritySystemView", "SecuritySystemView\SecuritySystemView.csproj", "{B4D0310E-1162-4BCF-A7E0-2AC41959C963}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SecuritySystemDataModels", "SecuritySystemDataModels\SecuritySystemDataModels.csproj", "{37DD658F-D5C0-4C97-A83D-A21EE0076C55}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SecuritySystemContracts", "SecuritySystemContracts\SecuritySystemContracts.csproj", "{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SecuritySystemBusinessLogic", "SecuritySystemBusinessLogic\SecuritySystemBusinessLogic.csproj", "{38C8A0AB-9363-4914-B967-02586827588D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SecuritySystemListImplement", "SecuritySystemListImplement\SecuritySystemListImplement.csproj", "{6A104362-3398-4D4E-A3D0-2F4B32858569}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SecuritySystemFileImplement", "SecuritySystemFileImplement\SecuritySystemFileImplement.csproj", "{0ACD169C-97A8-452E-A17A-19E2464F5286}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SecuritySystemDatabaseImplement", "SecuritySystemDatabaseImplement\SecuritySystemDatabaseImplement.csproj", "{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SecuritySystemRestApi", "SecuritySystemRestApi\SecuritySystemRestApi.csproj", "{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SecurirySystemClientApp", "SecurirySystemClientApp\SecurirySystemClientApp.csproj", "{4DEDBF73-8644-48A2-B9FC-604F96EE0324}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B4D0310E-1162-4BCF-A7E0-2AC41959C963}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B4D0310E-1162-4BCF-A7E0-2AC41959C963}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B4D0310E-1162-4BCF-A7E0-2AC41959C963}.Debug|x64.ActiveCfg = Debug|x64
{B4D0310E-1162-4BCF-A7E0-2AC41959C963}.Debug|x64.Build.0 = Debug|x64
{B4D0310E-1162-4BCF-A7E0-2AC41959C963}.Debug|x86.ActiveCfg = Debug|x86
{B4D0310E-1162-4BCF-A7E0-2AC41959C963}.Debug|x86.Build.0 = Debug|x86
{B4D0310E-1162-4BCF-A7E0-2AC41959C963}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B4D0310E-1162-4BCF-A7E0-2AC41959C963}.Release|Any CPU.Build.0 = Release|Any CPU
{B4D0310E-1162-4BCF-A7E0-2AC41959C963}.Release|x64.ActiveCfg = Release|x64
{B4D0310E-1162-4BCF-A7E0-2AC41959C963}.Release|x64.Build.0 = Release|x64
{B4D0310E-1162-4BCF-A7E0-2AC41959C963}.Release|x86.ActiveCfg = Release|x86
{B4D0310E-1162-4BCF-A7E0-2AC41959C963}.Release|x86.Build.0 = Release|x86
{37DD658F-D5C0-4C97-A83D-A21EE0076C55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{37DD658F-D5C0-4C97-A83D-A21EE0076C55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{37DD658F-D5C0-4C97-A83D-A21EE0076C55}.Debug|x64.ActiveCfg = Debug|x64
{37DD658F-D5C0-4C97-A83D-A21EE0076C55}.Debug|x64.Build.0 = Debug|x64
{37DD658F-D5C0-4C97-A83D-A21EE0076C55}.Debug|x86.ActiveCfg = Debug|x86
{37DD658F-D5C0-4C97-A83D-A21EE0076C55}.Debug|x86.Build.0 = Debug|x86
{37DD658F-D5C0-4C97-A83D-A21EE0076C55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{37DD658F-D5C0-4C97-A83D-A21EE0076C55}.Release|Any CPU.Build.0 = Release|Any CPU
{37DD658F-D5C0-4C97-A83D-A21EE0076C55}.Release|x64.ActiveCfg = Release|x64
{37DD658F-D5C0-4C97-A83D-A21EE0076C55}.Release|x64.Build.0 = Release|x64
{37DD658F-D5C0-4C97-A83D-A21EE0076C55}.Release|x86.ActiveCfg = Release|x86
{37DD658F-D5C0-4C97-A83D-A21EE0076C55}.Release|x86.Build.0 = Release|x86
{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}.Debug|x64.ActiveCfg = Debug|x64
{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}.Debug|x64.Build.0 = Debug|x64
{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}.Debug|x86.ActiveCfg = Debug|x86
{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}.Debug|x86.Build.0 = Debug|x86
{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}.Release|Any CPU.Build.0 = Release|Any CPU
{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}.Release|x64.ActiveCfg = Release|x64
{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}.Release|x64.Build.0 = Release|x64
{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}.Release|x86.ActiveCfg = Release|x86
{0737BCB2-EEDB-44A4-8BD2-5B5EA689A7FF}.Release|x86.Build.0 = Release|x86
{38C8A0AB-9363-4914-B967-02586827588D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38C8A0AB-9363-4914-B967-02586827588D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38C8A0AB-9363-4914-B967-02586827588D}.Debug|x64.ActiveCfg = Debug|x64
{38C8A0AB-9363-4914-B967-02586827588D}.Debug|x64.Build.0 = Debug|x64
{38C8A0AB-9363-4914-B967-02586827588D}.Debug|x86.ActiveCfg = Debug|x86
{38C8A0AB-9363-4914-B967-02586827588D}.Debug|x86.Build.0 = Debug|x86
{38C8A0AB-9363-4914-B967-02586827588D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38C8A0AB-9363-4914-B967-02586827588D}.Release|Any CPU.Build.0 = Release|Any CPU
{38C8A0AB-9363-4914-B967-02586827588D}.Release|x64.ActiveCfg = Release|x64
{38C8A0AB-9363-4914-B967-02586827588D}.Release|x64.Build.0 = Release|x64
{38C8A0AB-9363-4914-B967-02586827588D}.Release|x86.ActiveCfg = Release|x86
{38C8A0AB-9363-4914-B967-02586827588D}.Release|x86.Build.0 = Release|x86
{6A104362-3398-4D4E-A3D0-2F4B32858569}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6A104362-3398-4D4E-A3D0-2F4B32858569}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6A104362-3398-4D4E-A3D0-2F4B32858569}.Debug|x64.ActiveCfg = Debug|x64
{6A104362-3398-4D4E-A3D0-2F4B32858569}.Debug|x64.Build.0 = Debug|x64
{6A104362-3398-4D4E-A3D0-2F4B32858569}.Debug|x86.ActiveCfg = Debug|x86
{6A104362-3398-4D4E-A3D0-2F4B32858569}.Debug|x86.Build.0 = Debug|x86
{6A104362-3398-4D4E-A3D0-2F4B32858569}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6A104362-3398-4D4E-A3D0-2F4B32858569}.Release|Any CPU.Build.0 = Release|Any CPU
{6A104362-3398-4D4E-A3D0-2F4B32858569}.Release|x64.ActiveCfg = Release|x64
{6A104362-3398-4D4E-A3D0-2F4B32858569}.Release|x64.Build.0 = Release|x64
{6A104362-3398-4D4E-A3D0-2F4B32858569}.Release|x86.ActiveCfg = Release|x86
{6A104362-3398-4D4E-A3D0-2F4B32858569}.Release|x86.Build.0 = Release|x86
{0ACD169C-97A8-452E-A17A-19E2464F5286}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0ACD169C-97A8-452E-A17A-19E2464F5286}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0ACD169C-97A8-452E-A17A-19E2464F5286}.Debug|x64.ActiveCfg = Debug|x64
{0ACD169C-97A8-452E-A17A-19E2464F5286}.Debug|x64.Build.0 = Debug|x64
{0ACD169C-97A8-452E-A17A-19E2464F5286}.Debug|x86.ActiveCfg = Debug|Any CPU
{0ACD169C-97A8-452E-A17A-19E2464F5286}.Debug|x86.Build.0 = Debug|Any CPU
{0ACD169C-97A8-452E-A17A-19E2464F5286}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0ACD169C-97A8-452E-A17A-19E2464F5286}.Release|Any CPU.Build.0 = Release|Any CPU
{0ACD169C-97A8-452E-A17A-19E2464F5286}.Release|x64.ActiveCfg = Release|x64
{0ACD169C-97A8-452E-A17A-19E2464F5286}.Release|x64.Build.0 = Release|x64
{0ACD169C-97A8-452E-A17A-19E2464F5286}.Release|x86.ActiveCfg = Release|Any CPU
{0ACD169C-97A8-452E-A17A-19E2464F5286}.Release|x86.Build.0 = Release|Any CPU
{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}.Debug|x64.ActiveCfg = Debug|x64
{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}.Debug|x64.Build.0 = Debug|x64
{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}.Debug|x86.ActiveCfg = Debug|Any CPU
{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}.Debug|x86.Build.0 = Debug|Any CPU
{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}.Release|Any CPU.Build.0 = Release|Any CPU
{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}.Release|x64.ActiveCfg = Release|x64
{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}.Release|x64.Build.0 = Release|x64
{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}.Release|x86.ActiveCfg = Release|Any CPU
{4AE7461C-39CC-463B-B5A1-A47ED3B9E925}.Release|x86.Build.0 = Release|Any CPU
{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}.Debug|x64.ActiveCfg = Debug|Any CPU
{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}.Debug|x64.Build.0 = Debug|Any CPU
{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}.Debug|x86.ActiveCfg = Debug|Any CPU
{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}.Debug|x86.Build.0 = Debug|Any CPU
{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}.Release|Any CPU.Build.0 = Release|Any CPU
{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}.Release|x64.ActiveCfg = Release|Any CPU
{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}.Release|x64.Build.0 = Release|Any CPU
{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}.Release|x86.ActiveCfg = Release|Any CPU
{A45C62CE-D0FF-4347-A6FF-773A6563BDA9}.Release|x86.Build.0 = Release|Any CPU
{4DEDBF73-8644-48A2-B9FC-604F96EE0324}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4DEDBF73-8644-48A2-B9FC-604F96EE0324}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4DEDBF73-8644-48A2-B9FC-604F96EE0324}.Debug|x64.ActiveCfg = Debug|Any CPU
{4DEDBF73-8644-48A2-B9FC-604F96EE0324}.Debug|x64.Build.0 = Debug|Any CPU
{4DEDBF73-8644-48A2-B9FC-604F96EE0324}.Debug|x86.ActiveCfg = Debug|Any CPU
{4DEDBF73-8644-48A2-B9FC-604F96EE0324}.Debug|x86.Build.0 = Debug|Any CPU
{4DEDBF73-8644-48A2-B9FC-604F96EE0324}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4DEDBF73-8644-48A2-B9FC-604F96EE0324}.Release|Any CPU.Build.0 = Release|Any CPU
{4DEDBF73-8644-48A2-B9FC-604F96EE0324}.Release|x64.ActiveCfg = Release|Any CPU
{4DEDBF73-8644-48A2-B9FC-604F96EE0324}.Release|x64.Build.0 = Release|Any CPU
{4DEDBF73-8644-48A2-B9FC-604F96EE0324}.Release|x86.ActiveCfg = Release|Any CPU
{4DEDBF73-8644-48A2-B9FC-604F96EE0324}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,115 @@
using Microsoft.Extensions.Logging;
using SecuritySystemContracts.BindingModels;
using SecuritySystemContracts.BusinessLogicsContracts;
using SecuritySystemContracts.SearchModels;
using SecuritySystemContracts.StoragesContracts;
using SecuritySystemContracts.ViewModels;
namespace SecuritySystemBusinessLogic.BusinessLogics
{
public class ClientLogic : IClientLogic
{
private ILogger _logger;
private IClientStorage _clientStorage;
public ClientLogic(ILogger<ClientLogic> logger, IClientStorage clientStorage)
{
_logger = logger;
_clientStorage = clientStorage;
}
public bool Create(ClientBindingModel model)
{
CheckModel(model);
if (_clientStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Delete(ClientBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_clientStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public ClientViewModel? ReadElement(ClientSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Email:{Email}. Id:{Id}", model.Email, model.Id);
var element = _clientStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public List<ClientViewModel>? ReadList(ClientSearchModel? model)
{
_logger.LogInformation("ReadList. Email:{Email}. Id:{Id}", model?.Email, model?.Id);
var list = model == null ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool Update(ClientBindingModel model)
{
CheckModel(model);
if (_clientStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(ClientBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.Email))
{
throw new ArgumentNullException("Нет email клиента", nameof(model.Email));
}
if (string.IsNullOrEmpty(model.Password))
{
throw new ArgumentNullException("Нет пароля клиента", nameof(model.Password));
}
if (string.IsNullOrEmpty(model.ClientFIO))
{
throw new ArgumentNullException("Нет фио клиента", nameof(model.ClientFIO));
}
_logger.LogInformation("Client. Email:{Email}. Id: {Id}", model.Email, model.Id);
var element = _clientStorage.GetElement(new ClientSearchModel
{
Email = model.Email
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Клиент с таким email уже есть");
}
}
}
}

View File

@ -0,0 +1,109 @@
using Microsoft.Extensions.Logging;
using SecuritySystemContracts.BindingModels;
using SecuritySystemContracts.BusinessLogicsContracts;
using SecuritySystemContracts.SearchModels;
using SecuritySystemContracts.StoragesContracts;
using SecuritySystemContracts.ViewModels;
namespace SecuritySystemBusinessLogic.BusinessLogics
{
public class ComponentLogic : IComponentLogic
{
private readonly ILogger _logger;
private readonly IComponentStorage _componentStorage;
public ComponentLogic(ILogger<ComponentLogic> logger, IComponentStorage componentStorage)
{
_logger = logger;
_componentStorage = componentStorage;
}
public List<ComponentViewModel>? ReadList(ComponentSearchModel? model)
{
_logger.LogInformation("ReadList. ComponentName:{ComponentName}. Id:{Id}", model?.ComponentName, model?.Id);
var list = model == null ? _componentStorage.GetFullList() : _componentStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public ComponentViewModel? ReadElement(ComponentSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. ComponentName:{ComponentName}. Id:{Id}", model.ComponentName, model.Id);
var element = _componentStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool Create(ComponentBindingModel model)
{
CheckModel(model);
if (_componentStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(ComponentBindingModel model)
{
CheckModel(model);
if (_componentStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ComponentBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_componentStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ComponentBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.ComponentName))
{
throw new ArgumentNullException("Нет названия компонента",
nameof(model.ComponentName));
}
if (model.Cost <= 0)
{
throw new ArgumentNullException("Цена компонента должна быть больше 0", nameof(model.Cost));
}
_logger.LogInformation("Component. ComponentName:{ComponentName}. Cost:{Cost}. Id: {Id}", model.ComponentName, model.Cost, model.Id);
var element = _componentStorage.GetElement(new ComponentSearchModel
{
ComponentName = model.ComponentName
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Компонент с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,126 @@
using Microsoft.Extensions.Logging;
using SecuritySystemContracts.BindingModels;
using SecuritySystemContracts.BusinessLogicsContracts;
using SecuritySystemContracts.SearchModels;
using SecuritySystemContracts.StoragesContracts;
using SecuritySystemContracts.ViewModels;
namespace SecuritySystemBusinessLogic.BusinessLogics
{
public class ImplementerLogic : IImplementerLogic
{
private ILogger _logger;
private IImplementerStorage _implementerStorage;
public ImplementerLogic(ILogger<ImplementerLogic> logger, IImplementerStorage implementerStorage)
{
_logger = logger;
_implementerStorage = implementerStorage;
}
public bool Create(ImplementerBindingModel model)
{
CheckModel(model);
if (_implementerStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Delete(ImplementerBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_implementerStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public ImplementerViewModel? ReadElement(ImplementerSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. FIO:{FIO}. Id:{Id}", model.ImplementerFIO, model.Id);
var element = _implementerStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public List<ImplementerViewModel>? ReadList(ImplementerSearchModel? model)
{
_logger.LogInformation("ReadList. FIO:{FIO}. Id:{Id}", model?.ImplementerFIO, model?.Id);
var list = model == null ? _implementerStorage.GetFullList() : _implementerStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool Update(ImplementerBindingModel model)
{
CheckModel(model);
if (_implementerStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(ImplementerBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.WorkExperience < 0)
{
throw new ArgumentNullException("Опыт работы исполнителя должен быть больше или равен нулю", nameof(model.Password));
}
if (model.Qualification < 0)
{
throw new ArgumentNullException("Квалификация исполнителя должна быть больше или равна нулю", nameof(model.Password));
}
if (string.IsNullOrEmpty(model.Password))
{
throw new ArgumentNullException("Нет пароля исполнителя", nameof(model.Password));
}
if (string.IsNullOrEmpty(model.Password))
{
throw new ArgumentNullException("Нет пароля исполнителя", nameof(model.Password));
}
if (string.IsNullOrEmpty(model.ImplementerFIO))
{
throw new ArgumentNullException("Нет фио клиента", nameof(model.ImplementerFIO));
}
_logger.LogInformation("ReadElement. FIO:{FIO}. Id:{Id}", model.ImplementerFIO, model.Id);
var element = _implementerStorage.GetElement(new ImplementerSearchModel
{
ImplementerFIO = model.ImplementerFIO
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Сотрудник с таким фио уже есть");
}
}
}
}

View File

@ -0,0 +1,144 @@
using Microsoft.Extensions.Logging;
using SecuritySystemContracts.BindingModels;
using SecuritySystemContracts.BusinessLogicsContracts;
using SecuritySystemContracts.SearchModels;
using SecuritySystemContracts.StoragesContracts;
using SecuritySystemContracts.ViewModels;
using SecuritySystemDataModels.Enums;
namespace SecuritySystemBusinessLogic.BusinessLogics
{
public class OrderLogic : IOrderLogic
{
private readonly ILogger _logger;
private readonly IOrderStorage _orderStorage;
static readonly object locker = new object();
public OrderLogic(ILogger<OrderLogic> logger, IOrderStorage orderStorage)
{
_logger = logger;
_orderStorage = orderStorage;
}
public List<OrderViewModel>? ReadList(OrderSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{ Id}", model?.Id);
var list = model == null ? _orderStorage.GetFullList() : _orderStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool CreateOrder(OrderBindingModel model)
{
CheckModel(model);
if (model.Status != OrderStatus.Неизвестен) return false;
model.Status = OrderStatus.Принят;
if (_orderStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool ChangeStatus(OrderBindingModel model, OrderStatus status)
{
CheckModel(model, false);
var element = _orderStorage.GetElement(new OrderSearchModel { Id = model.Id });
if (element == null)
{
_logger.LogWarning("Read operation failed");
return false;
}
if (element.Status != status - 1)
{
_logger.LogWarning("Status change operation failed");
throw new InvalidOperationException("Текущий статус заказа не может быть переведен в выбранный");
}
if (element.ImplementerId.HasValue)
{
model.ImplementerId = element.ImplementerId;
}
OrderStatus oldStatus = model.Status;
model.Status = status;
if (model.Status == OrderStatus.Выдан)
model.DateImplement = DateTime.Now;
if (_orderStorage.Update(model) == null)
{
model.Status = oldStatus;
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool TakeOrderInWork(OrderBindingModel model)
{
lock (locker)
{
return ChangeStatus(model, OrderStatus.Выполняется);
}
}
public bool FinishOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Готов);
}
public bool DeliveryOrder(OrderBindingModel model)
{
return ChangeStatus(model, OrderStatus.Выдан);
}
private void CheckModel(OrderBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.SecureId < 0)
{
throw new ArgumentNullException("Некорректный идентификатор secure", nameof(model.SecureId));
}
if (model.Count <= 0)
{
throw new ArgumentNullException("Количество secure в заказе должно быть больше 0", nameof(model.Count));
}
if (model.Sum <= 0)
{
throw new ArgumentNullException("Цена заказа должна быть больше 0", nameof(model.Sum));
}
if (model.Count <= 0)
{
throw new ArgumentNullException("Количество элементов в заказе должно быть больше 0", nameof(model.Count));
}
_logger.LogInformation("Order. Sum:{Cost}. Id: {Id}", model.Sum, model.Id);
}
public OrderViewModel? ReadElement(OrderSearchModel? model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. Order Id:{Id}", model.Id);
var element = _orderStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
}
}

View File

@ -0,0 +1,121 @@
using SecuritySystemBusinessLogic.OfficePackage.HelperModels;
using SecuritySystemBusinessLogic.OfficePackage;
using SecuritySystemContracts.BindingModels;
using SecuritySystemContracts.BusinessLogicsContracts;
using SecuritySystemContracts.SearchModels;
using SecuritySystemContracts.StoragesContracts;
using SecuritySystemContracts.ViewModels;
namespace SecuritySystemBusinessLogic.BusinessLogics
{
public class ReportLogic : IReportLogic
{
private readonly IComponentStorage _componentStorage;
private readonly ISecureStorage _secureStorage;
private readonly IOrderStorage _orderStorage;
private readonly AbstractSaveToExcel _saveToExcel;
private readonly AbstractSaveToWord _saveToWord;
private readonly AbstractSaveToPdf _saveToPdf;
public ReportLogic(ISecureStorage secureStorage, IComponentStorage componentStorage, IOrderStorage orderStorage, AbstractSaveToExcel saveToExcel, AbstractSaveToWord saveToWord, AbstractSaveToPdf saveToPdf)
{
_secureStorage = secureStorage;
_componentStorage = componentStorage;
_orderStorage = orderStorage;
_saveToExcel = saveToExcel;
_saveToWord = saveToWord;
_saveToPdf = saveToPdf;
}
/// <summary>
/// Получение списка компонент с указанием, в каких изделиях используются
/// </summary>
/// <returns></returns>
public List<ReportSecureComponentViewModel> GetSecureComponent()
{
var components = _componentStorage.GetFullList();
var secures = _secureStorage.GetFullList();
var list = new List<ReportSecureComponentViewModel>();
foreach (var secure in secures)
{
var record = new ReportSecureComponentViewModel
{
SecureName = secure.SecureName,
Components = new List<Tuple<string, int>>(),
TotalCount = 0
};
foreach (var component in components)
{
if (secure.SecureComponents.ContainsKey(component.Id))
{
record.Components.Add(new Tuple<string, int>(component.ComponentName, secure.SecureComponents[component.Id].Item2));
record.TotalCount += secure.SecureComponents[component.Id].Item2;
}
}
list.Add(record);
}
return list;
}
/// <summary>
/// Получение списка заказов за определенный период
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public List<ReportOrdersViewModel> GetOrders(ReportBindingModel model)
{
return _orderStorage.GetFilteredList(new OrderSearchModel
{
DateFrom = model.DateFrom,
DateTo = model.DateTo
})
.Select(x => new ReportOrdersViewModel
{
Id = x.Id,
DateCreate = x.DateCreate,
SecureName = x.SecureName,
Status = x.Status.ToString(),
Sum = x.Sum
})
.ToList();
}
/// <summary>
/// Сохранение компонент в файл-Word
/// </summary>
/// <param name="model"></param>
public void SaveSecuresToWordFile(ReportBindingModel model)
{
_saveToWord.CreateDoc(new WordInfo
{
FileName = model.FileName,
Title = "Список изделий",
Secures = _secureStorage.GetFullList()
});
}
/// <summary>
/// Сохранение компонент с указаеним продуктов в файл-Excel
/// </summary>
/// <param name="model"></param>
public void SaveSecureComponentToExcelFile(ReportBindingModel model)
{
_saveToExcel.CreateReport(new ExcelInfo
{
FileName = model.FileName,
Title = "Список изделий и компонентов",
SecureComponents = GetSecureComponent()
});
}
/// <summary>
/// Сохранение заказов в файл-Pdf
/// </summary>
/// <param name="model"></param>
public void SaveOrdersToPdfFile(ReportBindingModel model)
{
_saveToPdf.CreateDoc(new PdfInfo
{
FileName = model.FileName,
Title = "Список заказов",
DateFrom = model.DateFrom!.Value,
DateTo = model.DateTo!.Value,
Orders = GetOrders(model)
});
}
}
}

View File

@ -0,0 +1,107 @@
using Microsoft.Extensions.Logging;
using SecuritySystemContracts.BindingModels;
using SecuritySystemContracts.BusinessLogicsContracts;
using SecuritySystemContracts.SearchModels;
using SecuritySystemContracts.StoragesContracts;
using SecuritySystemContracts.ViewModels;
namespace SecuritySystemBusinessLogic.BusinessLogics
{
public class SecureLogic : ISecureLogic
{
private readonly ILogger _logger;
private readonly ISecureStorage _secureStorage;
public SecureLogic(ILogger<ComponentLogic> logger, ISecureStorage secureStorage)
{
_logger = logger;
_secureStorage = secureStorage;
}
public bool Create(SecureBindingModel model)
{
CheckModel(model);
if (_secureStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Delete(SecureBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_secureStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
public SecureViewModel? ReadElement(SecureSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. SecureName:{SecureName}. Id:{Id}", model.SecureName, model.Id);
var element = _secureStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public List<SecureViewModel>? ReadList(SecureSearchModel? model)
{
_logger.LogInformation("ReadList. SecureName:{SecureName}. Id:{Id}", model?.SecureName, model?.Id);
var list = model == null ? _secureStorage.GetFullList() : _secureStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public bool Update(SecureBindingModel model)
{
CheckModel(model);
if (_secureStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
private void CheckModel(SecureBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.SecureName))
{
throw new ArgumentNullException("Нет названия secure", nameof(model.SecureName));
}
if (model.Price <= 0)
{
throw new ArgumentNullException("Цена secure должна быть больше 0", nameof(model.Price));
}
_logger.LogInformation("Secure. SecureName:{SecureName}. Price:{Price}. Id:{Id}", model.SecureName, model.Price, model.Id);
var element = _secureStorage.GetElement(new SecureSearchModel
{
SecureName = model.SecureName
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Secure с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,139 @@
using Microsoft.Extensions.Logging;
using SecuritySystemContracts.BindingModels;
using SecuritySystemContracts.BusinessLogicsContracts;
using SecuritySystemContracts.SearchModels;
using SecuritySystemContracts.ViewModels;
using SecuritySystemDataModels.Enums;
namespace SecuritySystemBusinessLogic.BusinessLogics
{
public class WorkModeling : IWorkProcess
{
private readonly ILogger _logger;
private readonly Random _rnd;
private IOrderLogic? _orderLogic;
public WorkModeling(ILogger<WorkModeling> logger)
{
_logger = logger;
_rnd = new Random(1000);
}
public void DoWork(IImplementerLogic implementerLogic, IOrderLogic orderLogic)
{
_orderLogic = orderLogic;
var implementers = implementerLogic.ReadList(null);
if (implementers == null)
{
_logger.LogWarning("DoWork. Implementers is null");
return;
}
var orders = _orderLogic.ReadList(new OrderSearchModel
{
Status = OrderStatus.Принят
});
if (orders == null || orders.Count == 0)
{
_logger.LogWarning("DoWork. Orders is null or empty");
return;
}
_logger.LogDebug("DoWork for {Count} orders", orders.Count);
foreach (var implementer in implementers)
{
Task.Run(() => WorkerWorkAsync(implementer, orders));
}
}
/// <summary>
/// Иммитация работы исполнителя
/// </summary>
/// <param name="implementer"></param>
/// <param name="orders"></param>
private async Task WorkerWorkAsync(ImplementerViewModel implementer, List<OrderViewModel> orders)
{
if (_orderLogic == null || implementer == null)
{
return;
}
await RunOrderInWork(implementer);
await Task.Run(() =>
{
foreach (var order in orders)
{
try
{
_logger.LogDebug("DoWork. Worker {Id} try get order {Order}", implementer.Id, order.Id);
// пытаемся назначить заказ на исполнителя
_orderLogic.TakeOrderInWork(new OrderBindingModel
{
Id = order.Id,
ImplementerId = implementer.Id
});
// делаем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 1000) * order.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, order.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = order.Id
});
}
// кто-то мог уже перехватить заказ, игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// заканчиваем выполнение имитации в случае иной ошибки
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
// отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
});
}
/// <summary>
/// Ищем заказ, которые уже в работе (вдруг исполнителя прервали)
/// </summary>
/// <param name="implementer"></param>
/// <returns></returns>
private async Task RunOrderInWork(ImplementerViewModel implementer)
{
if (_orderLogic == null || implementer == null)
{
return;
}
try
{
var runOrder = await Task.Run(() => _orderLogic.ReadElement(new OrderSearchModel
{
ImplementerId = implementer.Id,
Status = OrderStatus.Выполняется
}));
if (runOrder == null)
{
return;
}
_logger.LogDebug("DoWork. Worker {Id} back to order {Order}", implementer.Id, runOrder.Id);
// доделываем работу
Thread.Sleep(implementer.WorkExperience * _rnd.Next(100, 300) * runOrder.Count);
_logger.LogDebug("DoWork. Worker {Id} finish order {Order}", implementer.Id, runOrder.Id);
_orderLogic.FinishOrder(new OrderBindingModel
{
Id = runOrder.Id
});
// отдыхаем
Thread.Sleep(implementer.Qualification * _rnd.Next(10, 100));
}
// заказа может не быть, просто игнорируем ошибку
catch (InvalidOperationException ex)
{
_logger.LogWarning(ex, "Error try get work");
}
// а может возникнуть иная ошибка, тогда просто заканчиваем выполнение имитации
catch (Exception ex)
{
_logger.LogError(ex, "Error while do work");
throw;
}
}
}
}

View File

@ -0,0 +1,98 @@
using SecuritySystemBusinessLogic.OfficePackage.HelperEnums;
using SecuritySystemBusinessLogic.OfficePackage.HelperModels;
namespace SecuritySystemBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToExcel
{
/// <summary>
/// Создание отчета
/// </summary>
/// <param name="info"></param>
public void CreateReport(ExcelInfo info)
{
CreateExcel(info);
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = 1,
Text = info.Title,
StyleInfo = ExcelStyleInfoType.Title
});
MergeCells(new ExcelMergeParameters
{
CellFromName = "A1",
CellToName = "C1"
});
uint rowIndex = 2;
foreach (var pc in info.SecureComponents)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = pc.SecureName,
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
foreach (var secure in pc.Components)
{
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "B",
RowIndex = rowIndex,
Text = secure.Item1,
StyleInfo =
ExcelStyleInfoType.TextWithBroder
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = secure.Item2.ToString(),
StyleInfo =
ExcelStyleInfoType.TextWithBroder
});
rowIndex++;
}
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "A",
RowIndex = rowIndex,
Text = "Итого",
StyleInfo = ExcelStyleInfoType.Text
});
InsertCellInWorksheet(new ExcelCellParameters
{
ColumnName = "C",
RowIndex = rowIndex,
Text = pc.TotalCount.ToString(),
StyleInfo = ExcelStyleInfoType.Text
});
rowIndex++;
}
SaveExcel(info);
}
/// <summary>
/// Создание excel-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreateExcel(ExcelInfo info);
/// <summary>
/// Добавляем новую ячейку в лист
/// </summary>
/// <param name="cellParameters"></param>
protected abstract void InsertCellInWorksheet(ExcelCellParameters
excelParams);
/// <summary>
/// Объединение ячеек
/// </summary>
/// <param name="mergeParameters"></param>
protected abstract void MergeCells(ExcelMergeParameters excelParams);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SaveExcel(ExcelInfo info);
}
}

View File

@ -0,0 +1,75 @@
using SecuritySystemBusinessLogic.OfficePackage.HelperEnums;
using SecuritySystemBusinessLogic.OfficePackage.HelperModels;
namespace SecuritySystemBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToPdf
{
public void CreateDoc(PdfInfo info)
{
CreatePdf(info);
CreateParagraph(new PdfParagraph
{
Text = info.Title,
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateParagraph(new PdfParagraph
{
Text = $"с {info.DateFrom.ToShortDateString()} по {info.DateTo.ToShortDateString()}",
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
CreateTable(new List<string> { "2cm", "3cm", "6cm", "3cm", "3cm" });
CreateRow(new PdfRowParameters
{
Texts = new List<string> { "Номер", "Дата заказа", "Изделие", "Статус", "Сумма" },
Style = "NormalTitle",
ParagraphAlignment = PdfParagraphAlignmentType.Center
});
foreach (var order in info.Orders)
{
CreateRow(new PdfRowParameters
{
Texts = new List<string> { order.Id.ToString(), order.DateCreate.ToShortDateString(), order.SecureName, order.Status.ToString(), order.Sum.ToString() },
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Left
});
}
CreateParagraph(new PdfParagraph
{
Text = $"Итого: {info.Orders.Sum(x => x.Sum)}\t",
Style = "Normal",
ParagraphAlignment = PdfParagraphAlignmentType.Rigth
});
SavePdf(info);
}
/// <summary>
/// Создание doc-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreatePdf(PdfInfo info);
/// <summary>
/// Создание параграфа с текстом
/// </summary>
/// <param name="title"></param>
/// <param name="style"></param>
protected abstract void CreateParagraph(PdfParagraph paragraph);
/// <summary>
/// Создание таблицы
/// </summary>
/// <param name="title"></param>
/// <param name="style"></param>
protected abstract void CreateTable(List<string> columns);
/// <summary>
/// Создание и заполнение строки
/// </summary>
/// <param name="rowParameters"></param>
protected abstract void CreateRow(PdfRowParameters rowParameters);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SavePdf(PdfInfo info);
}
}

View File

@ -0,0 +1,54 @@
using SecuritySystemBusinessLogic.OfficePackage.HelperEnums;
using SecuritySystemBusinessLogic.OfficePackage.HelperModels;
namespace SecuritySystemBusinessLogic.OfficePackage
{
public abstract class AbstractSaveToWord
{
public void CreateDoc(WordInfo info)
{
CreateWord(info);
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> { (info.Title, new WordTextProperties { Bold = true, Size = "24", }) },
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Center
}
});
foreach (var secure in info.Secures)
{
CreateParagraph(new WordParagraph
{
Texts = new List<(string, WordTextProperties)> {
(secure.SecureName, new WordTextProperties { Bold = true, Size = "24", }),
("\t" + secure.Price.ToString() + " руб.", new WordTextProperties { Size = "24", })
},
TextProperties = new WordTextProperties
{
Size = "24",
JustificationType = WordJustificationType.Both
}
});
}
SaveWord(info);
}
/// <summary>
/// Создание doc-файла
/// </summary>
/// <param name="info"></param>
protected abstract void CreateWord(WordInfo info);
/// <summary>
/// Создание абзаца с текстом
/// </summary>
/// <param name="paragraph"></param>
/// <returns></returns>
protected abstract void CreateParagraph(WordParagraph paragraph);
/// <summary>
/// Сохранение файла
/// </summary>
/// <param name="info"></param>
protected abstract void SaveWord(WordInfo info);
}
}

View File

@ -0,0 +1,10 @@
namespace SecuritySystemBusinessLogic.OfficePackage.HelperEnums
{
public enum ExcelStyleInfoType
{
Title,
Text,
TextWithBroder
}
}

View File

@ -0,0 +1,9 @@
namespace SecuritySystemBusinessLogic.OfficePackage.HelperEnums
{
public enum PdfParagraphAlignmentType
{
Center,
Left,
Rigth
}
}

View File

@ -0,0 +1,8 @@
namespace SecuritySystemBusinessLogic.OfficePackage.HelperEnums
{
public enum WordJustificationType
{
Center,
Both
}
}

View File

@ -0,0 +1,13 @@
using SecuritySystemBusinessLogic.OfficePackage.HelperEnums;
namespace SecuritySystemBusinessLogic.OfficePackage.HelperModels
{
public class ExcelCellParameters
{
public string ColumnName { get; set; } = string.Empty;
public uint RowIndex { get; set; }
public string Text { get; set; } = string.Empty;
public string CellReference => $"{ColumnName}{RowIndex}";
public ExcelStyleInfoType StyleInfo { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using SecuritySystemContracts.ViewModels;
namespace SecuritySystemBusinessLogic.OfficePackage.HelperModels
{
public class ExcelInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public List<ReportSecureComponentViewModel> SecureComponents
{
get;
set;
} = new();
}
}

View File

@ -0,0 +1,9 @@
namespace SecuritySystemBusinessLogic.OfficePackage.HelperModels
{
public class ExcelMergeParameters
{
public string CellFromName { get; set; } = string.Empty;
public string CellToName { get; set; } = string.Empty;
public string Merge => $"{CellFromName}:{CellToName}";
}
}

View File

@ -0,0 +1,13 @@
using SecuritySystemContracts.ViewModels;
namespace SecuritySystemBusinessLogic.OfficePackage.HelperModels
{
public class PdfInfo
{
public string FileName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
public List<ReportOrdersViewModel> Orders { get; set; } = new();
}
}

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