Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Client.Wasm/Components/StudentCard.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
</CardHeader>
<CardBody>
<UnorderedList Unstyled>
<UnorderedListItem>Номер <Strong>№X "Название лабораторной"</Strong></UnorderedListItem>
<UnorderedListItem>Вариант <Strong>№Х "Название варианта"</Strong></UnorderedListItem>
<UnorderedListItem>Выполнена <Strong>Фамилией Именем 65ХХ</Strong> </UnorderedListItem>
<UnorderedListItem><Link To="https://puginarug.com/">Ссылка на форк</Link></UnorderedListItem>
<UnorderedListItem>Номер <Strong>№1 "Кэширование"</Strong></UnorderedListItem>
<UnorderedListItem>Вариант <Strong>№2 "Сотрудник компании"</Strong></UnorderedListItem>
<UnorderedListItem>Выполнена <Strong>Беляковой Вероникой 6511</Strong> </UnorderedListItem>
<UnorderedListItem><Link To="https://github.com/Cat-sandwich/cloud-development">Ссылка на форк</Link></UnorderedListItem>
</UnorderedList>
</CardBody>
</Card>
2 changes: 1 addition & 1 deletion Client.Wasm/wwwroot/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
}
},
"AllowedHosts": "*",
"BaseAddress": ""
"BaseAddress": "https://localhost:7491/api/employee"
}
18 changes: 18 additions & 0 deletions CloudDevelopment.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ VisualStudioVersion = 17.14.36811.4
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client.Wasm", "Client.Wasm\Client.Wasm.csproj", "{AE7EEA74-2FE0-136F-D797-854FD87E022A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Employee.AppHost", "Employee\Employee.AppHost\Employee.AppHost.csproj", "{8575D1CE-B605-4372-A759-BA1598A8C6F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Employee.ServiceDefaults", "Employee\Employee.ServiceDefaults\Employee.ServiceDefaults.csproj", "{6194C225-7198-D470-1A5E-025DA0008A3E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Employee.ApiService", "Employee\Employee.ApiService\Employee.ApiService.csproj", "{EBEFA5C3-3225-5108-6105-B7C3D2FA6DC2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -15,6 +21,18 @@ Global
{AE7EEA74-2FE0-136F-D797-854FD87E022A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE7EEA74-2FE0-136F-D797-854FD87E022A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE7EEA74-2FE0-136F-D797-854FD87E022A}.Release|Any CPU.Build.0 = Release|Any CPU
{8575D1CE-B605-4372-A759-BA1598A8C6F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8575D1CE-B605-4372-A759-BA1598A8C6F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8575D1CE-B605-4372-A759-BA1598A8C6F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8575D1CE-B605-4372-A759-BA1598A8C6F9}.Release|Any CPU.Build.0 = Release|Any CPU
{6194C225-7198-D470-1A5E-025DA0008A3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6194C225-7198-D470-1A5E-025DA0008A3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6194C225-7198-D470-1A5E-025DA0008A3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6194C225-7198-D470-1A5E-025DA0008A3E}.Release|Any CPU.Build.0 = Release|Any CPU
{EBEFA5C3-3225-5108-6105-B7C3D2FA6DC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EBEFA5C3-3225-5108-6105-B7C3D2FA6DC2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EBEFA5C3-3225-5108-6105-B7C3D2FA6DC2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EBEFA5C3-3225-5108-6105-B7C3D2FA6DC2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
20 changes: 20 additions & 0 deletions Employee/Employee.ApiService/Employee.ApiService.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Employee.ServiceDefaults\Employee.ServiceDefaults.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Aspire.StackExchange.Redis.DistributedCaching" Version="13.1.2" />
<PackageReference Include="Bogus" Version="35.6.5" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="10.1.5" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="10.1.5" />
</ItemGroup>

</Project>
6 changes: 6 additions & 0 deletions Employee/Employee.ApiService/Employee.ApiService.http
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Этот файл можно удалить

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@ApiService_HostAddress = http://localhost:5547

GET {{ApiService_HostAddress}}/weatherforecast/
Accept: application/json

###
58 changes: 58 additions & 0 deletions Employee/Employee.ApiService/Models/EmployeeModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
namespace Employee.ApiService.Models;

/// <summary>
/// Класс сотрудник компании
/// </summary>
public class EmployeeModel
{

/// <summary>
/// Идентификатор сотрудника в системе
/// </summary>
public required int Id { get; set; }

/// <summary>
/// ФИО
/// </summary>
public required string Name { get; set; }

/// <summary>
/// Должность
/// </summary>
public required string Position { get; set; }

/// <summary>
/// Отдел
/// </summary>
public required string Department { get; set; }

/// <summary>
/// Дата приема
/// </summary>
public required DateOnly DateAdmission { get; set; }

/// <summary>
/// Оклад
/// </summary>
public required decimal Salary { get; set; }

/// <summary>
/// Электронная почта
/// </summary>
public required string Email { get; set; }

/// <summary>
/// Номер телефона
/// </summary>
public required string Phone { get; set; }

/// <summary>
/// Индикатор увольнения
/// </summary>
public bool DismissalIndicator { get; set; } = false;

/// <summary>
/// Дата увольнения
/// </summary>
public DateOnly? DateDismissal { get; set; }
}
43 changes: 43 additions & 0 deletions Employee/Employee.ApiService/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Employee.ApiService.Services;
using Employee.ServiceDefaults;

var builder = WebApplication.CreateBuilder(args);

builder.AddServiceDefaults();
builder.AddRedisDistributedCache("redis");

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddCors(options =>
{
options.AddPolicy("wasm", policy =>
{
policy.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});

builder.Services.AddSingleton<EmployeeGenerator>();
builder.Services.AddScoped<EmployeeService>();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
Comment on lines +27 to +31
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если добавлять swagger, то нужно и добавить xml комментарии


app.MapDefaultEndpoints();
app.UseHttpsRedirection();
app.UseCors("wasm");

app.MapGet("/api/employee", async (int id, EmployeeService service) =>
{
var employee = await service.GetEmployeeAsync(id);
return Results.Ok(employee);
});

app.Run();
23 changes: 23 additions & 0 deletions Employee/Employee.ApiService/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5547",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7491;http://localhost:5547",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
139 changes: 139 additions & 0 deletions Employee/Employee.ApiService/Services/EmployeeGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
using Bogus;
using Employee.ApiService.Models;

namespace Employee.ApiService.Services;

/// <summary>
/// Генератор тестовых сотрудников
/// </summary>
public class EmployeeGenerator
{
/// <summary>
/// Справочник профессий
/// </summary>
private static readonly string[] _professions =
[
"Developer",
"Manager",
"Analyst",
"QA",
"DevOps",
"Designer"
];

/// <summary>
/// Справочник суффиксов должностей и коэффициентов зарплаты
/// </summary>
private static readonly Dictionary<string, decimal> _positionLevels = new()
{
{ "Junior", 0.7m },
{ "Middle", 1.0m },
{ "Senior", 1.5m },
{ "Lead", 2.0m }
};

/// <summary>
/// Константа базовой зарплаты
/// </summary>
private const decimal BaseSalary = 100000m;

/// <summary>
/// Генерация должности
/// </summary>
private static string GeneratePosition(Faker f)
{
var level = f.PickRandom(_positionLevels.Keys.ToArray());
var profession = f.PickRandom(_professions);

return $"{level} {profession}";
}
Comment on lines +43 to +49
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Этот метод возможно тоже не стоит выделять и написать все в RuleFor

Выделять стоит только большие участки кода


/// <summary>
/// Генерация даты приема
/// </summary>
private static DateOnly GenerateAdmissionDate(Faker f)
{
return DateOnly.FromDateTime(f.Date.Past(10));
}
Comment on lines +54 to +57
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Как будто нет смысла выделять это в метод, можно в лямбде RuleFor написать этот код

А еще есть Date.PastDateOnly(10), который сразу вернут только дату


/// <summary>
/// Генерация зарплаты с учетом коэффициента уровня
/// </summary>
private static decimal GenerateSalary(Faker f, string position)
{
var level = _positionLevels.Keys.FirstOrDefault(position.Contains);

decimal coefficient = 1;

if (level != null)
{
coefficient = _positionLevels[level];
}

var randomFactor = f.Random.Decimal(0.9m, 1.1m);

var salary = BaseSalary * coefficient * randomFactor;

return Math.Round(salary, 2);
}

/// <summary>
/// Генерация даты увольнения
/// </summary>
private static DateOnly? GenerateDismissalDate(Faker f, EmployeeModel employee)
{
if (!employee.DismissalIndicator)
return null;

var start = employee.DateAdmission.ToDateTime(TimeOnly.MinValue);

var dismissal = f.Date.Between(start, DateTime.Now);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Есть Date.BetweenDateOnly


return DateOnly.FromDateTime(dismissal);
}
/// <summary>
/// Генерация ФИО
/// </summary>
private static string GenerateFullName(Faker f)
{
var gender = f.PickRandom<Bogus.DataSets.Name.Gender>();

var firstName = f.Name.FirstName(gender);
var lastName = f.Name.LastName(gender);

// имя отца
var fatherName = f.Name.FirstName(Bogus.DataSets.Name.Gender.Male);

var patronymic = gender == Bogus.DataSets.Name.Gender.Male
? fatherName + "ович"
: fatherName + "овна";

return $"{lastName} {firstName} {patronymic}";
}

/// <summary>
/// Преднастроенный генератор
/// </summary>
private static readonly Faker<EmployeeModel> _faker = new Faker<EmployeeModel>("ru")
.RuleFor(e => e.Name, f => GenerateFullName(f))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут можно попроще:

.RuleFor(e => e.Name, GenerateFullName)

Ниже аналогично

.RuleFor(e => e.Position, f => GeneratePosition(f))
.RuleFor(e => e.Department, f => f.Commerce.Department())
.RuleFor(e => e.DateAdmission, f => GenerateAdmissionDate(f))
.RuleFor(e => e.Salary, (f, e) => GenerateSalary(f, e.Position))
.RuleFor(e => e.Email, (f, e) => f.Internet.Email())
.RuleFor(e => e.Phone, f => f.Phone.PhoneNumber("+7(###)###-##-##"))
.RuleFor(e => e.DismissalIndicator, f => f.Random.Bool(0.2f))
.RuleFor(e => e.DateDismissal, (f, e) => GenerateDismissalDate(f, e));

/// <summary>
/// Генерация сотрудника
/// </summary>
public EmployeeModel Generate(int id)
{
var employee = _faker.Generate();
employee.Id = id;

return employee;
}

}
Loading