This commit is contained in:
song2remaster 2024-05-01 21:20:46 +04:00
parent 90728871ce
commit 6a3247660b
34 changed files with 915 additions and 90 deletions

View File

@ -19,6 +19,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MotorPlantDatabaseImplement
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MotorPlantRestApi", "MotorPlantRestApi\MotorPlantRestApi.csproj", "{29E5B36D-7602-4EE5-96BB-A43FF9A49780}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MotorPlantRestApi", "MotorPlantRestApi\MotorPlantRestApi.csproj", "{29E5B36D-7602-4EE5-96BB-A43FF9A49780}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MotorPlantClientApi", "MotorPlantClientApi\MotorPlantClientApi.csproj", "{6F7A6389-1E4D-4F35-AE10-143EAA601F62}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -57,6 +59,10 @@ Global
{29E5B36D-7602-4EE5-96BB-A43FF9A49780}.Debug|Any CPU.Build.0 = Debug|Any CPU {29E5B36D-7602-4EE5-96BB-A43FF9A49780}.Debug|Any CPU.Build.0 = Debug|Any CPU
{29E5B36D-7602-4EE5-96BB-A43FF9A49780}.Release|Any CPU.ActiveCfg = Release|Any CPU {29E5B36D-7602-4EE5-96BB-A43FF9A49780}.Release|Any CPU.ActiveCfg = Release|Any CPU
{29E5B36D-7602-4EE5-96BB-A43FF9A49780}.Release|Any CPU.Build.0 = Release|Any CPU {29E5B36D-7602-4EE5-96BB-A43FF9A49780}.Release|Any CPU.Build.0 = Release|Any CPU
{6F7A6389-1E4D-4F35-AE10-143EAA601F62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6F7A6389-1E4D-4F35-AE10-143EAA601F62}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6F7A6389-1E4D-4F35-AE10-143EAA601F62}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F7A6389-1E4D-4F35-AE10-143EAA601F62}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,6 @@
@ClientRestApi_HostAddress = http://localhost:5227
GET {{ClientRestApi_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

@ -0,0 +1,33 @@
using Microsoft.AspNetCore.Mvc;
namespace ClientRestApi.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}

View File

@ -0,0 +1,25 @@
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@ -0,0 +1,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:25213",
"sslPort": 44395
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5227",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7097;http://localhost:5227",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,13 @@
namespace ClientRestApi
{
public class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}
}

View File

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

View File

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

View File

@ -0,0 +1,47 @@
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
using MotorPlantContracts.ViewModels;
namespace MotorPlantClientApp
{
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,151 @@
using Microsoft.AspNetCore.Mvc;
using MotorPlantClientApp.Models;
using System.Diagnostics;
using MotorPlantContracts.BindingModels;
using MotorPlantContracts.ViewModels;
using MotorPlantContracts.VeiwModels;
namespace MotorPlantClientApp.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.Engines =
APIClient.GetRequest<List<EngineViewModel>>("api/main/getEnginelist");
return View();
}
[HttpPost]
public void Create(int Engine, 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,
EngineId = Engine,
Count = count,
Sum = Calc(count, Engine)
});
Response.Redirect("Index");
}
[HttpPost]
public double Calc(int count, int Engine)
{
var _Engine =
APIClient.GetRequest<EngineViewModel>($"api/main/getEngine?Engineid={Engine}"
);
return Math.Round(count * (_Engine?.Price ?? 1), 2);
}
}
}

View File

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

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\MotorPlantContracts\MotorPlantContracts.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,6 @@
@MotorPlantClientApi_HostAddress = http://localhost:5126
GET {{MotorPlantClientApi_HostAddress}}/weatherforecast/
Accept: application/json
###

View File

@ -0,0 +1,31 @@
using MotorPlantClientApp;
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,41 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:44719",
"sslPort": 44341
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5126",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7006;http://localhost:5126",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,50 @@
@{
ViewData["Title"] = "Create";
}
<div class="text-center">
<h2 class="display-4">Создание заказа</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Изделие:</div>
<div class="col-8">
<select id="engine" name="engine" class="form-control" asp-items="@(new SelectList(@ViewBag.Engines,"Id", "EngineName"))"></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>
$('#engine').on('change', function () {
check();
});
$('#count').on('change', function () {
check();
});
function check() {
var count = $('#count').val();
var engine = $('#engine').val();
if (count && engine) {
$.ajax({
method: "POST",
url: "/Home/Calc",
data: { count: count, engine: engine },
success: function (result) {
$("#sum").val(result);
}
});
};
}
</script>

View File

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

View File

@ -0,0 +1,75 @@
@using MotorPlantContracts.ViewModels
@model List<OrderViewModel>
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Заказы</h1>
</div>
<div class="text-center">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<p>
<a asp-action="Create">Создать заказ</a>
</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.EngineName)
</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,28 @@
@using MotorPlantContracts.ViewModels
@model ClientViewModel
@{
ViewData["Title"] = "Privacy Policy";
}
<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,25 @@
@{
ViewData["Title"] = "Register";
}
<div class="text-center">
<h2 class="display-4">Регистрация</h2>
</div>
<form method="post">
<div class="row">
<div class="col-4">Логин:</div>
<div class="col-8"><input type="text" name="login" /></div>
</div>
<div class="row">
<div class="col-4">Пароль:</div>
<div class="col-8"><input type="password" name="password" /></div>
</div>
<div class="row">
<div class="col-4">ФИО:</div>
<div class="col-8"><input type="text" name="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,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,55 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MotorPlantClientApp</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/MotorPlantClientApp.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MotorPlantClientApp</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Заказы</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Личные данные</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Enter">Вход</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Register">Регистрация</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2024 - MotorPlantClientApp - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

View File

@ -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 MotorPlantClientApp
@using MotorPlantClientApp.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,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@ -7,6 +7,7 @@ namespace MotorPlantContracts.BindingModels
{ {
public int Id { get; set; } public int Id { get; set; }
public int EngineId { get; set; } public int EngineId { get; set; }
public int ClientId { get; set; }
public string EngineName { get; set; } = string.Empty; public string EngineName { get; set; } = string.Empty;
public int Count { get; set; } public int Count { get; set; }
public double Sum { get; set; } public double Sum { get; set; }

View File

@ -5,29 +5,24 @@ namespace MotorPlantContracts.VeiwModels
{ {
public class OrderViewModel : IOrderModel public class OrderViewModel : IOrderModel
{ {
[DisplayName("Номер")] [DisplayName("Номер")]
public int Id { get; set; } public int Id { get; set; }
public int EngineId { get; set; }
public int EngineId { get; set; } public int ClientId { get; set; }
[DisplayName("Клиент")]
[DisplayName("Изделие")] public string ClientFIO { get; set; } = string.Empty;
public string EngineName { get; set; } = string.Empty; [DisplayName("Двигатель")]
public string EngineName { get; set; } = string.Empty;
[DisplayName("Количество")] [DisplayName("Количество")]
public int Count { get; set; } public int Count { get; set; }
[DisplayName("Сумма")]
[DisplayName("Сумма")] public double Sum { get; set; }
public double Sum { get; set; } [DisplayName("Статус")]
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен;
[DisplayName("Статус")] [DisplayName("Дата создания")]
public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; public DateTime DateCreate { get; set; } = DateTime.Now;
[DisplayName("Дата выполнения")]
[DisplayName("Дата создания")] public DateTime? DateImplement { get; set; }
public DateTime DateCreate { get; set; } = DateTime.Now; }
[DisplayName("Дата выполнения")]
public DateTime? DateImplement { get; set; }
}
}
}

View File

@ -32,6 +32,7 @@
toolStripDropDownButton1 = new ToolStripDropDownButton(); toolStripDropDownButton1 = new ToolStripDropDownButton();
КомпонентыToolStripMenuItem = new ToolStripMenuItem(); КомпонентыToolStripMenuItem = new ToolStripMenuItem();
ДвигателиToolStripMenuItem = new ToolStripMenuItem(); ДвигателиToolStripMenuItem = new ToolStripMenuItem();
клиентыToolStripMenuItem = new ToolStripMenuItem();
ReportsToolStripMenuItem = new ToolStripMenuItem(); ReportsToolStripMenuItem = new ToolStripMenuItem();
ListComponentsToolStripMenuItem = new ToolStripMenuItem(); ListComponentsToolStripMenuItem = new ToolStripMenuItem();
EngineComponentsToolStripMenuItem = new ToolStripMenuItem(); EngineComponentsToolStripMenuItem = new ToolStripMenuItem();
@ -52,14 +53,14 @@
toolStrip1.Items.AddRange(new ToolStripItem[] { toolStripDropDownButton1, ReportsToolStripMenuItem }); toolStrip1.Items.AddRange(new ToolStripItem[] { toolStripDropDownButton1, ReportsToolStripMenuItem });
toolStrip1.Location = new Point(0, 0); toolStrip1.Location = new Point(0, 0);
toolStrip1.Name = "toolStrip1"; toolStrip1.Name = "toolStrip1";
toolStrip1.Size = new Size(969, 25); toolStrip1.Size = new Size(996, 25);
toolStrip1.TabIndex = 0; toolStrip1.TabIndex = 0;
toolStrip1.Text = "toolStrip1"; toolStrip1.Text = "toolStrip1";
// //
// toolStripDropDownButton1 // toolStripDropDownButton1
// //
toolStripDropDownButton1.DisplayStyle = ToolStripItemDisplayStyle.Text; toolStripDropDownButton1.DisplayStyle = ToolStripItemDisplayStyle.Text;
toolStripDropDownButton1.DropDownItems.AddRange(new ToolStripItem[] { КомпонентыToolStripMenuItem, ДвигателиToolStripMenuItem }); toolStripDropDownButton1.DropDownItems.AddRange(new ToolStripItem[] { КомпонентыToolStripMenuItem, ДвигателиToolStripMenuItem, клиентыToolStripMenuItem });
toolStripDropDownButton1.ImageTransparentColor = Color.Magenta; toolStripDropDownButton1.ImageTransparentColor = Color.Magenta;
toolStripDropDownButton1.Name = "toolStripDropDownButton1"; toolStripDropDownButton1.Name = "toolStripDropDownButton1";
toolStripDropDownButton1.Size = new Size(90, 22); toolStripDropDownButton1.Size = new Size(90, 22);
@ -79,6 +80,13 @@
ДвигателиToolStripMenuItem.Text = "Двигатели"; ДвигателиToolStripMenuItem.Text = "Двигатели";
ДвигателиToolStripMenuItem.Click += ИзделияToolStripMenuItem_Click; ДвигателиToolStripMenuItem.Click += ИзделияToolStripMenuItem_Click;
// //
// клиентыToolStripMenuItem
//
клиентыToolStripMenuItem.Name = "клиентыToolStripMenuItem";
клиентыToolStripMenuItem.Size = new Size(148, 22);
клиентыToolStripMenuItem.Text = "Клиенты";
клиентыToolStripMenuItem.Click += клиентыToolStripMenuItem_Click;
//
// ReportsToolStripMenuItem // ReportsToolStripMenuItem
// //
ReportsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ListComponentsToolStripMenuItem, EngineComponentsToolStripMenuItem, ListOrdersToolStripMenuItem }); ReportsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { ListComponentsToolStripMenuItem, EngineComponentsToolStripMenuItem, ListOrdersToolStripMenuItem });
@ -109,9 +117,9 @@
// //
// buttonCreateOrder // buttonCreateOrder
// //
buttonCreateOrder.Location = new Point(850, 56); buttonCreateOrder.Location = new Point(879, 57);
buttonCreateOrder.Name = "buttonCreateOrder"; buttonCreateOrder.Name = "buttonCreateOrder";
buttonCreateOrder.Size = new Size(91, 38); buttonCreateOrder.Size = new Size(105, 38);
buttonCreateOrder.TabIndex = 1; buttonCreateOrder.TabIndex = 1;
buttonCreateOrder.Text = "Создать заказ"; buttonCreateOrder.Text = "Создать заказ";
buttonCreateOrder.UseVisualStyleBackColor = true; buttonCreateOrder.UseVisualStyleBackColor = true;
@ -119,9 +127,9 @@
// //
// buttonTakeOrderInWork // buttonTakeOrderInWork
// //
buttonTakeOrderInWork.Location = new Point(850, 100); buttonTakeOrderInWork.Location = new Point(879, 101);
buttonTakeOrderInWork.Name = "buttonTakeOrderInWork"; buttonTakeOrderInWork.Name = "buttonTakeOrderInWork";
buttonTakeOrderInWork.Size = new Size(91, 38); buttonTakeOrderInWork.Size = new Size(105, 46);
buttonTakeOrderInWork.TabIndex = 2; buttonTakeOrderInWork.TabIndex = 2;
buttonTakeOrderInWork.Text = "Отдать на выполнение"; buttonTakeOrderInWork.Text = "Отдать на выполнение";
buttonTakeOrderInWork.UseVisualStyleBackColor = true; buttonTakeOrderInWork.UseVisualStyleBackColor = true;
@ -129,9 +137,9 @@
// //
// buttonOrderReady // buttonOrderReady
// //
buttonOrderReady.Location = new Point(850, 153); buttonOrderReady.Location = new Point(879, 153);
buttonOrderReady.Name = "buttonOrderReady"; buttonOrderReady.Name = "buttonOrderReady";
buttonOrderReady.Size = new Size(91, 38); buttonOrderReady.Size = new Size(105, 43);
buttonOrderReady.TabIndex = 3; buttonOrderReady.TabIndex = 3;
buttonOrderReady.Text = "Заказ готов"; buttonOrderReady.Text = "Заказ готов";
buttonOrderReady.UseVisualStyleBackColor = true; buttonOrderReady.UseVisualStyleBackColor = true;
@ -139,9 +147,9 @@
// //
// buttonIssuedOrder // buttonIssuedOrder
// //
buttonIssuedOrder.Location = new Point(850, 207); buttonIssuedOrder.Location = new Point(879, 202);
buttonIssuedOrder.Name = "buttonIssuedOrder"; buttonIssuedOrder.Name = "buttonIssuedOrder";
buttonIssuedOrder.Size = new Size(91, 38); buttonIssuedOrder.Size = new Size(105, 40);
buttonIssuedOrder.TabIndex = 4; buttonIssuedOrder.TabIndex = 4;
buttonIssuedOrder.Text = "Заказ выдан"; buttonIssuedOrder.Text = "Заказ выдан";
buttonIssuedOrder.UseVisualStyleBackColor = true; buttonIssuedOrder.UseVisualStyleBackColor = true;
@ -149,9 +157,9 @@
// //
// buttonRef // buttonRef
// //
buttonRef.Location = new Point(850, 260); buttonRef.Location = new Point(879, 248);
buttonRef.Name = "buttonRef"; buttonRef.Name = "buttonRef";
buttonRef.Size = new Size(91, 38); buttonRef.Size = new Size(105, 42);
buttonRef.TabIndex = 5; buttonRef.TabIndex = 5;
buttonRef.Text = "Обновить список"; buttonRef.Text = "Обновить список";
buttonRef.UseVisualStyleBackColor = true; buttonRef.UseVisualStyleBackColor = true;
@ -167,14 +175,14 @@
dataGridView.RowHeadersWidth = 51; dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 24; dataGridView.RowTemplate.Height = 24;
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dataGridView.Size = new Size(816, 435); dataGridView.Size = new Size(873, 435);
dataGridView.TabIndex = 6; dataGridView.TabIndex = 6;
// //
// FormMain // FormMain
// //
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(969, 461); ClientSize = new Size(996, 461);
Controls.Add(dataGridView); Controls.Add(dataGridView);
Controls.Add(buttonRef); Controls.Add(buttonRef);
Controls.Add(buttonIssuedOrder); Controls.Add(buttonIssuedOrder);
@ -208,5 +216,6 @@
private ToolStripMenuItem ListComponentsToolStripMenuItem; private ToolStripMenuItem ListComponentsToolStripMenuItem;
private ToolStripMenuItem EngineComponentsToolStripMenuItem; private ToolStripMenuItem EngineComponentsToolStripMenuItem;
private ToolStripMenuItem ListOrdersToolStripMenuItem; private ToolStripMenuItem ListOrdersToolStripMenuItem;
} private ToolStripMenuItem клиентыToolStripMenuItem;
}
} }

View File

@ -1,4 +1,4 @@
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using MotorPlantContracts.BindingModels; using MotorPlantContracts.BindingModels;
using MotorPlantContracts.BusinessLogicsContracts; using MotorPlantContracts.BusinessLogicsContracts;
using MotorPlantBusinessLogic; using MotorPlantBusinessLogic;
@ -23,7 +23,7 @@ namespace MotorPlantView.Forms
} }
private void LoadData() private void LoadData()
{ {
_logger.LogInformation("Çàãðóçêà çàêàçîâ"); _logger.LogInformation("Загрузка заказов");
try try
{ {
var list = _orderLogic.ReadList(null); var list = _orderLogic.ReadList(null);
@ -35,14 +35,14 @@ namespace MotorPlantView.Forms
dataGridView.Columns["EngineName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; dataGridView.Columns["EngineName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
} }
_logger.LogInformation("Çàãðóçêà çàêàçîâ"); _logger.LogInformation("Загрузка заказов");
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Îøèáêà çàãðóçêè çàêàçîâ"); _logger.LogError(ex, "Ошибка загрузки заказов");
} }
} }
private void ÊîìïîíåíòûToolStripMenuItem_Click(object sender, EventArgs e) private void КомпонентыToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormComponents)); var service = Program.ServiceProvider?.GetService(typeof(FormComponents));
if (service is FormComponents form) if (service is FormComponents form)
@ -50,7 +50,7 @@ namespace MotorPlantView.Forms
form.ShowDialog(); form.ShowDialog();
} }
} }
private void ÈçäåëèÿToolStripMenuItem_Click(object sender, EventArgs e) private void ИзделияToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormEngines)); var service = Program.ServiceProvider?.GetService(typeof(FormEngines));
@ -73,7 +73,7 @@ namespace MotorPlantView.Forms
if (dataGridView.SelectedRows.Count == 1) if (dataGridView.SelectedRows.Count == 1)
{ {
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Çàêàç ¹{id}. Ìåíÿåòñÿ ñòàòóñ íà 'Â ðàáîòå'", id); _logger.LogInformation("Заказ №{id}. Меняется статус на 'В работе'", id);
try try
{ {
var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel var operationResult = _orderLogic.TakeOrderInWork(new OrderBindingModel
@ -82,14 +82,14 @@ namespace MotorPlantView.Forms
}); });
if (!operationResult) if (!operationResult)
{ {
throw new Exception("Îøèáêà ïðè ñîõðàíåíèè. Äîïîëíèòåëüíàÿ èíôîðìàöèÿ â ëîãàõ."); throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
} }
LoadData(); LoadData();
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Îøèáêà ïåðåäà÷è çàêàçà â ðàáîòó"); _logger.LogError(ex, "Ошибка передачи заказа в работу");
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
} }
@ -99,20 +99,20 @@ namespace MotorPlantView.Forms
{ {
int id = int id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Çàêàç ¹{id}. Ìåíÿåòñÿ ñòàòóñ íà 'Ãîòîâ'", id); _logger.LogInformation("Заказ №{id}. Меняется статус на 'Готов'", id);
try try
{ {
var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { Id = id }); var operationResult = _orderLogic.FinishOrder(new OrderBindingModel { Id = id });
if (!operationResult) if (!operationResult)
{ {
throw new Exception("Îøèáêà ïðè ñîõðàíåíèè. Äîïîëíèòåëüíàÿ èíôîðìàöèÿ â ëîãàõ."); throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
} }
LoadData(); LoadData();
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Îøèáêà îòìåòêè î ãîòîâíîñòè çàêàçà"); _logger.LogError(ex, "Ошибка отметки о готовности заказа");
MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
} }
@ -121,7 +121,7 @@ namespace MotorPlantView.Forms
if (dataGridView.SelectedRows.Count == 1) if (dataGridView.SelectedRows.Count == 1)
{ {
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Çàêàç ¹{id}. Ìåíÿåòñÿ ñòàòóñ íà 'Âûäàí'", id); _logger.LogInformation("Заказ №{id}. Меняется статус на 'Выдан'", id);
try try
{ {
var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel var operationResult = _orderLogic.DeliveryOrder(new OrderBindingModel
@ -130,14 +130,14 @@ namespace MotorPlantView.Forms
}); });
if (!operationResult) if (!operationResult)
{ {
throw new Exception("Îøèáêà ïðè ñîõðàíåíèè. Äîïîëíèòåëüíàÿ èíôîðìàöèÿ â ëîãàõ."); throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
} }
_logger.LogInformation("Çàêàç ¹{id} âûäàí", id); _logger.LogInformation("Заказ №{id} выдан", id);
LoadData(); LoadData();
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Îøèáêà îòìåòêè î âûäà÷è çàêàçà"); MessageBox.Show(ex.Message, "Îøèáêà", MessageBoxButtons.OK, MessageBoxIcon.Error); _logger.LogError(ex, "Ошибка отметки о выдачи заказа"); MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
} }
} }
@ -145,7 +145,7 @@ namespace MotorPlantView.Forms
{ {
LoadData(); LoadData();
} }
private void ñïèñîêÊîìïîíåíòîâToolStripMenuItem_Click(object sender, EventArgs e) private void списокКомпонентовToolStripMenuItem_Click(object sender, EventArgs e)
{ {
using var dialog = new SaveFileDialog { Filter = "docx|*.docx" }; using var dialog = new SaveFileDialog { Filter = "docx|*.docx" };
if (dialog.ShowDialog() == DialogResult.OK) if (dialog.ShowDialog() == DialogResult.OK)
@ -154,12 +154,11 @@ namespace MotorPlantView.Forms
{ {
FileName = dialog.FileName FileName = dialog.FileName
}); });
MessageBox.Show("Âûïîëíåíî", "Óñïåõ", MessageBoxButtons.OK, MessageBox.Show("Выполнено", "Успех", MessageBoxButtons.OK,
MessageBoxIcon.Information); MessageBoxIcon.Information);
} }
} }
private void компонентыПоДвигателямToolStripMenuItem_Click(object sender, EventArgs e)
private void êîìïîíåíòûÏîÄâèãàòåëÿìToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormReportEngineComponents)); var service = Program.ServiceProvider?.GetService(typeof(FormReportEngineComponents));
if (service is FormReportEngineComponents form) if (service is FormReportEngineComponents form)
@ -167,8 +166,7 @@ namespace MotorPlantView.Forms
form.ShowDialog(); form.ShowDialog();
} }
} }
private void списокЗаказовToolStripMenuItem_Click(object sender, EventArgs e)
private void ñïèñîêÇàêàçîâToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders)); var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders));
if (service is FormReportOrders form) if (service is FormReportOrders form)
@ -176,5 +174,13 @@ namespace MotorPlantView.Forms
form.ShowDialog(); form.ShowDialog();
} }
} }
} private void клиентыToolStripMenuItem_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormClients));
if (service is FormClients form)
{
form.ShowDialog();
}
}
}
} }

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->
@ -117,4 +117,7 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root> </root>