diff --git a/CandidateReviewBusinessLogic/BusinessLogic/CompanyLogic.cs b/CandidateReviewBusinessLogic/BusinessLogic/CompanyLogic.cs index 335ae50..ba782e5 100644 --- a/CandidateReviewBusinessLogic/BusinessLogic/CompanyLogic.cs +++ b/CandidateReviewBusinessLogic/BusinessLogic/CompanyLogic.cs @@ -12,10 +12,12 @@ namespace CandidateReviewBusinessLogic.BusinessLogic { private readonly ILogger _logger; private readonly ICompanyStorage _сompanyStorage; - public CompanyLogic(ILogger logger, ICompanyStorage сompanyStorage) + private readonly IVacancyStorage _vacancyStorage; + public CompanyLogic(ILogger logger, ICompanyStorage сompanyStorage, IVacancyStorage vacancyStorage) { _logger = logger; _сompanyStorage = сompanyStorage; + _vacancyStorage = vacancyStorage; } public int Create(CompanyBindingModel model) { @@ -40,7 +42,7 @@ namespace CandidateReviewBusinessLogic.BusinessLogic return true; } - public CompanyViewModel? ReadElement(CompanySearchModel model) + /*public CompanyViewModel? ReadElement(CompanySearchModel model) { if (model == null) { @@ -54,8 +56,55 @@ namespace CandidateReviewBusinessLogic.BusinessLogic } _logger.LogInformation("ReadElement find. Id: {Id}", element.Id); return element; + }*/ + + public CompanyViewModel? ReadElement(CompanySearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + var company = _сompanyStorage.GetElement(model); + if (company == null) + { + _logger.LogWarning("ReadElement: Company not found for Id: {Id}", model.Id); + return null; + } + var vacancies = _vacancyStorage.GetFilteredList(new VacancySearchModel { CompanyId = company.Id}); + + var vacancyViewModels = vacancies?.Select(v => new VacancyViewModel + { + Id = v.Id, + CompanyId = v.CompanyId, + JobTitle = v.JobTitle, + Requirements = v.Requirements, + Responsibilities = v.Responsibilities, + JobType = v.JobType, + Salary = v.Salary, + Description = v.Description, + Status = v.Status, + CreatedAt = v.CreatedAt, + Tags = v.Tags + }).ToList() ?? new List(); + + var companyViewModel = new CompanyViewModel + { + Id = company.Id, + Name = company.Name, + Description = company.Description, + Contacts = company.Contacts, + Address = company.Address, + Website = company.Website, + LogoFilePath = company.LogoFilePath, + Vacancies = vacancyViewModels + }; + + _logger.LogInformation("ReadElement: Company found. Id: {Id}", company.Id); + return companyViewModel; } + + public List? ReadList(CompanySearchModel? model) { var list = model == null ? _сompanyStorage.GetFullList() : _сompanyStorage.GetFilteredList(model); diff --git a/CandidateReviewBusinessLogic/BusinessLogic/UserLogic.cs b/CandidateReviewBusinessLogic/BusinessLogic/UserLogic.cs index 6e0c09f..b515749 100644 --- a/CandidateReviewBusinessLogic/BusinessLogic/UserLogic.cs +++ b/CandidateReviewBusinessLogic/BusinessLogic/UserLogic.cs @@ -41,7 +41,6 @@ namespace CandidateReviewBusinessLogic.BusinessLogic public bool Delete(UserBindingModel model) { CheckModel(model, false); - CheckPassword(model); _logger.LogInformation("Delete. Id: {Id}", model.Id); if (_userStorage.Delete(model) == null) { diff --git a/CandidateReviewClientApp/APIClient.cs b/CandidateReviewClientApp/APIClient.cs index 43edc7f..5ecd33c 100644 --- a/CandidateReviewClientApp/APIClient.cs +++ b/CandidateReviewClientApp/APIClient.cs @@ -10,6 +10,7 @@ namespace CandidateReviewClientApp private static readonly HttpClient _user = new(); public static UserViewModel? User { get; set; } = null; public static CompanyViewModel? Company { get; set; } = null; + public static VacancyViewModel? Vacancy { get; set; } = null; public static void Connect(IConfiguration configuration) { _user.BaseAddress = new Uri(configuration["IPAddress"]); diff --git a/CandidateReviewClientApp/Controllers/CompanyController.cs b/CandidateReviewClientApp/Controllers/CompanyController.cs index 19e8a4d..ea28f6a 100644 --- a/CandidateReviewClientApp/Controllers/CompanyController.cs +++ b/CandidateReviewClientApp/Controllers/CompanyController.cs @@ -41,7 +41,19 @@ namespace CandidateReviewClientApp.Controllers var model = APIClient.GetRequest($"api/company/profile?id={id}"); if (model != null) { - APIClient.PostRequest($"api/user/update", new UserBindingModel { Id = APIClient.User.Id, CompanyId = model.Id }); + APIClient.PostRequest($"api/user/update", new UserBindingModel { + Id = APIClient.User.Id, + CompanyId = model.Id, + Surname = APIClient.User.Surname, + Name = APIClient.User.Name, + LastName = APIClient.User.LastName, + Email = APIClient.User.Email, + Password = APIClient.User.Password, + EmailConfirmed = APIClient.User.EmailConfirmed, + Role = APIClient.User.Role, + AvatarFilePath = APIClient.User.AvatarFilePath, + PhoneNumber = APIClient.User.PhoneNumber + }); } return View(model); } @@ -61,7 +73,7 @@ namespace CandidateReviewClientApp.Controllers { APIClient.PostRequest("api/company/create", model); } - Response.Redirect("/Home/Index"); + Response.Redirect($"/Company/CompanyProfile/{model.Id}"); } [HttpPost] diff --git a/CandidateReviewClientApp/Controllers/HomeController.cs b/CandidateReviewClientApp/Controllers/HomeController.cs index bcdabe1..cd43eb1 100644 --- a/CandidateReviewClientApp/Controllers/HomeController.cs +++ b/CandidateReviewClientApp/Controllers/HomeController.cs @@ -41,6 +41,10 @@ namespace CandidateReviewUserApp.Controllers throw new Exception(" "); } APIClient.User = APIClient.GetRequest($"api/user/login?login={login}&password={password}"); + if (APIClient.User.CompanyId != null) + { + APIClient.Company = APIClient.GetRequest($"api/company/profile?id={APIClient.User?.CompanyId}"); + } if (APIClient.User == null) { throw new Exception(" /"); diff --git a/CandidateReviewClientApp/Controllers/UserController.cs b/CandidateReviewClientApp/Controllers/UserController.cs index 1cbaf14..37bde7e 100644 --- a/CandidateReviewClientApp/Controllers/UserController.cs +++ b/CandidateReviewClientApp/Controllers/UserController.cs @@ -24,7 +24,7 @@ namespace CandidateReviewClientApp.Controllers if (model == null) { - return RedirectToAction("Index"); + return RedirectToAction("/Home/Index"); } return View(model); @@ -37,7 +37,12 @@ namespace CandidateReviewClientApp.Controllers { return Redirect("/Home/Enter"); } - return View(APIClient.User); + var model = APIClient.GetRequest($"api/user/profile?id={APIClient.User.Id}"); + if (model == null) + { + return RedirectToAction("/Home/Index"); + } + return View(model); } [HttpPost] @@ -48,17 +53,17 @@ namespace CandidateReviewClientApp.Controllers Id = model.Id, Surname = model.Surname, Name = model.Name, - LastName = model.LastName ?? null, - CompanyId = model.CompanyId ?? null, + LastName = model.LastName, + CompanyId = model.CompanyId, Email = model.Email, Password = model.Password, EmailConfirmed = model.EmailConfirmed, Role = model.Role, - AvatarFilePath = model.AvatarFilePath ?? null, - PhoneNumber = model.PhoneNumber ?? null + AvatarFilePath = model.AvatarFilePath, + PhoneNumber = model.PhoneNumber }); - Response.Redirect("/User/UserProfile"); + Response.Redirect($"/User/UserProfile/{model.Id}"); } [HttpGet] @@ -68,6 +73,31 @@ namespace CandidateReviewClientApp.Controllers Response.Redirect("/Home/Enter"); } + [HttpPost] + public void Delete(UserBindingModel model) + { + if (APIClient.User == null) + { + throw new Exception("Доступно только авторизованным пользователям"); + } + + APIClient.PostRequest($"api/user/delete", new UserBindingModel { + Id = model.Id, + Surname = model.Surname, + Name = model.Name, + LastName = model.LastName, + CompanyId = model.CompanyId, + Email = model.Email, + Password = model.Password, + EmailConfirmed = model.EmailConfirmed, + Role = model.Role, + AvatarFilePath = model.AvatarFilePath, + PhoneNumber = model.PhoneNumber + }); + + Response.Redirect("/Home/Enter"); + } + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { diff --git a/CandidateReviewClientApp/Controllers/VacancyController.cs b/CandidateReviewClientApp/Controllers/VacancyController.cs new file mode 100644 index 0000000..3f566eb --- /dev/null +++ b/CandidateReviewClientApp/Controllers/VacancyController.cs @@ -0,0 +1,92 @@ +using CandidateReviewContracts.BindingModels; +using CandidateReviewContracts.ViewModels; +using Microsoft.AspNetCore.Mvc; + +namespace CandidateReviewClientApp.Controllers +{ + public class VacancyController : Controller + { + private readonly ILogger _logger; + + public VacancyController(ILogger logger) + { + _logger = logger; + } + [HttpGet] + public IActionResult Vacancy(int? id) + { + if (APIClient.User == null) + { + return Redirect("~/Home/Enter"); + } + if (id.HasValue) + { + APIClient.Vacancy = APIClient.GetRequest($"api/vacancy/details?id={id}"); + } + var model = APIClient.Vacancy; + return View(model); + } + + [HttpGet] + public IActionResult EditVacancy(int? id) + { + if (APIClient.User == null) + { + return Redirect("~/Home/Enter"); + } + if (!id.HasValue) + { + return View(new VacancyViewModel()); + } + var model = APIClient.GetRequest($"api/vacancy/details?id={id}"); + return View(model); + } + + [HttpPost] + public void EditVacancy(VacancyBindingModel model) + { + if (APIClient.User == null) + { + throw new Exception("Доступно только авторизованным пользователям"); + } + if (model.Id != 0) + { + APIClient.PostRequest("api/vacancy/update", model); + } + else + { + APIClient.PostRequest("api/vacancy/create", model); + if (APIClient.Company != null) + { + APIClient.Company?.Vacancies.Add(new VacancyViewModel + { + Id = model.Id, + CompanyId = model.CompanyId, + CreatedAt = model.CreatedAt, + Description = model.Description, + JobTitle = model.JobTitle, + JobType = model.JobType, + Requirements = model.Requirements, + Responsibilities = model.Responsibilities, + Salary = model.Salary, + Status = model.Status, + Tags = model.Tags + }); + } + } + Response.Redirect($"/Company/CompanyProfile/{model.CompanyId}"); + } + + [HttpPost] + public void Delete(int id) + { + if (APIClient.User == null) + { + throw new Exception("Доступно только авторизованным пользователям"); + } + + APIClient.PostRequest($"api/vacancy/delete", new VacancyBindingModel { Id = id }); + Response.Redirect("/Home/Index"); + } + } +} diff --git a/CandidateReviewClientApp/Views/Company/CompanyProfile.cshtml b/CandidateReviewClientApp/Views/Company/CompanyProfile.cshtml index 63f898f..5c07672 100644 --- a/CandidateReviewClientApp/Views/Company/CompanyProfile.cshtml +++ b/CandidateReviewClientApp/Views/Company/CompanyProfile.cshtml @@ -3,54 +3,86 @@ @{ ViewData["Title"] = "Профиль компании"; + var userRole = APIClient.User?.Role == CandidateReviewDataModels.Enums.RoleEnum.Сотрудник ? true : false; }
- @if (!string.IsNullOrEmpty(Model.LogoFilePath)) - { - Логотип компании - } + Логотип компании
@Model.Name
-

@Model.Description

- @Model.Website +

@(Model.Description == null ? "Описание отсутствует" : Model.Description)

+ @(Model.Website ?? "Веб-сайт отсутствует")
-
-
+
+

Информация о компании

- Редактировать + @if (userRole) + { + Редактировать + }
- - - - - - - - - - - - - - - - - - - - - - - -
Название@Model.Name
Описание@Model.Description
Официальный сайт@Model.Website
Адрес@Model.Address
Контакты@Model.Contacts
+
+
Адрес:
+
@(Model.Address?.ToString() ?? "Адрес не указан")
+ +
Контакты:
+
@(Model.Contacts?.ToString() ?? "Контакты не указаны")
+
+
+
+ +
+
+

Вакансии компании

+ @if (userRole) + { + Добавить вакансию + } +
+
+ @if (@Model.Vacancies != null && @Model.Vacancies.Any()) + { + + + + + + + + + + + @foreach (var vacancy in @Model.Vacancies) + { + + + + + + + } + +
НазваниеТип занятостиЗарплатаДействия
@vacancy.JobTitle@vacancy.JobType@vacancy.Salary + Просмотр + @if (userRole) + { + Редактировать + Удалить + } +
+ } + else + { +

Вакансий нет.

+ }
diff --git a/CandidateReviewClientApp/Views/Home/Privacy.cshtml b/CandidateReviewClientApp/Views/Home/Privacy.cshtml deleted file mode 100644 index af4fb19..0000000 --- a/CandidateReviewClientApp/Views/Home/Privacy.cshtml +++ /dev/null @@ -1,6 +0,0 @@ -@{ - ViewData["Title"] = "Privacy Policy"; -} -

@ViewData["Title"]

- -

Use this page to detail your site's privacy policy.

diff --git a/CandidateReviewClientApp/Views/Shared/_Layout.cshtml b/CandidateReviewClientApp/Views/Shared/_Layout.cshtml index 0357106..2d39dc1 100644 --- a/CandidateReviewClientApp/Views/Shared/_Layout.cshtml +++ b/CandidateReviewClientApp/Views/Shared/_Layout.cshtml @@ -8,7 +8,6 @@ - @@ -17,7 +16,7 @@
@await RenderSectionAsync("Scripts", required: false) + - + \ No newline at end of file diff --git a/CandidateReviewClientApp/Views/User/UserProfile.cshtml b/CandidateReviewClientApp/Views/User/UserProfile.cshtml index a69cdec..f4f3117 100644 --- a/CandidateReviewClientApp/Views/User/UserProfile.cshtml +++ b/CandidateReviewClientApp/Views/User/UserProfile.cshtml @@ -9,41 +9,43 @@
- @if (!string.IsNullOrEmpty(@Model.AvatarFilePath)) + @if (!string.IsNullOrEmpty(@Model?.AvatarFilePath)) { - Аватар пользователя + Аватар пользователя }
- @Model.Name @(string.IsNullOrEmpty(@Model.Surname) ? "" : @Model.Surname) @(string.IsNullOrEmpty(@Model.LastName) ? "" : @Model.LastName) + @Model?.Name @(string.IsNullOrEmpty(@Model?.Surname) ? "" : @Model?.Surname) @(string.IsNullOrEmpty(@Model?.LastName) ? "" : @Model?.LastName)
-
-
-
-
-
-
-

Контактная информация

-
- Редактировать - Удалить +
+
Email:
+
@Model?.Email
+ @if (!string.IsNullOrEmpty(@Model?.PhoneNumber)) + { +
Телефон:
+
@Model?.PhoneNumber
+ } +
Роль:
+
@Model?.Role
+
+
+ Редактировать профиль +
+ + +
Выйти
+
+
+ +
+
+
+

Мои резюме

+
-
-
Email
-
@Model.Email
- - @if (!string.IsNullOrEmpty(@Model.PhoneNumber)) - { -
Телефон
-
@Model.PhoneNumber
- } - -
Роль
-
@Model.Role
-
diff --git a/CandidateReviewClientApp/Views/Vacancy/EditVacancy.cshtml b/CandidateReviewClientApp/Views/Vacancy/EditVacancy.cshtml new file mode 100644 index 0000000..e7f7872 --- /dev/null +++ b/CandidateReviewClientApp/Views/Vacancy/EditVacancy.cshtml @@ -0,0 +1,90 @@ +@using CandidateReviewContracts.ViewModels +@using CandidateReviewDataModels.Enums +@model VacancyViewModel + +@{ + var title = @Model.Id <= 0 ? "Создать вакансию" : "Редактировать вакансию"; +} + +
+

@title

+
+ + + +
+ + +
Пожалуйста, введите название должности.
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + + + @{ + var tagsString = @Model?.Tags; + var displayedTags = string.IsNullOrEmpty(tagsString) ? "" : string.Join(", ", tagsString.Split(',').Select(t => t.Trim())); + } + +
+ + +
+ +@* + *@ +
+ +
+
+
+ + + diff --git a/CandidateReviewClientApp/Views/Vacancy/SearchVacancies.cshtml b/CandidateReviewClientApp/Views/Vacancy/SearchVacancies.cshtml new file mode 100644 index 0000000..9c4a045 --- /dev/null +++ b/CandidateReviewClientApp/Views/Vacancy/SearchVacancies.cshtml @@ -0,0 +1,40 @@ +@* @using CandidateReviewContracts.ViewModels +@model VacancyViewModel + +@{ + ViewData["Title"] = "Поиск вакансий"; +} + +
+
+
+

Поиск вакансий

+
+
+ + +
+
+ + @if (@Model != null && @Model.Vacancies != null) + { +

Результаты поиска:

+ @if (Model.Vacancies.Count > 0) + { +
    + @foreach (var vacancy in Model.Vacancies) + { +
  • @vacancy.JobTitle
  • + } +
+ } + else + { +

Вакансий не найдено.

+ } + } +
+
+
+ + *@ \ No newline at end of file diff --git a/CandidateReviewClientApp/Views/Vacancy/VacancyDetails.cshtml b/CandidateReviewClientApp/Views/Vacancy/VacancyDetails.cshtml new file mode 100644 index 0000000..9c1243d --- /dev/null +++ b/CandidateReviewClientApp/Views/Vacancy/VacancyDetails.cshtml @@ -0,0 +1,54 @@ +@using Microsoft.AspNetCore.Mvc.TagHelpers +@using CandidateReviewContracts.ViewModels +@model VacancyViewModel + +@{ + ViewData["Title"] = "Информация о вакансии"; +} + +
+
+
+

@Model.JobTitle

+ +
+
+
+
+
+
Компания:
+
@Model.CompanyId
+ +
Тип занятости:
+
@Model.JobType
+ +
Зарплата:
+
@Model.Salary
+ +
Дата публикации:
+
@Model.CreatedAt.ToShortDateString()
+ +
Статус:
+
@Model.Status
+ +
Теги:
+
@Model.Tags
+
+
+
+
+
Требования:
+
@Html.Raw(Model.Requirements)
+ +
Обязанности:
+
@Html.Raw(Model.Responsibilities)
+ +
Описание:
+
@Html.Raw(Model.Description)
+
+
+
+
+
+
+ diff --git a/CandidateReviewClientApp/images/default-company-logo.png b/CandidateReviewClientApp/images/default-company-logo.png new file mode 100644 index 0000000..1f71f25 Binary files /dev/null and b/CandidateReviewClientApp/images/default-company-logo.png differ diff --git a/CandidateReviewContracts/BindingModels/CompanyBindingModel.cs b/CandidateReviewContracts/BindingModels/CompanyBindingModel.cs index 7d8164b..9487fcd 100644 --- a/CandidateReviewContracts/BindingModels/CompanyBindingModel.cs +++ b/CandidateReviewContracts/BindingModels/CompanyBindingModel.cs @@ -1,4 +1,5 @@ -using CandidateReviewDataModels.Models; +using CandidateReviewContracts.ViewModels; +using CandidateReviewDataModels.Models; namespace CandidateReviewContracts.BindingModels { @@ -16,5 +17,7 @@ namespace CandidateReviewContracts.BindingModels public string? Contacts { get; set; } public int Id { get; set; } + + public List Vacancies { get; set; } = new(); } } diff --git a/CandidateReviewContracts/ViewModels/CompanyViewModel.cs b/CandidateReviewContracts/ViewModels/CompanyViewModel.cs index c44dfb9..a93f31e 100644 --- a/CandidateReviewContracts/ViewModels/CompanyViewModel.cs +++ b/CandidateReviewContracts/ViewModels/CompanyViewModel.cs @@ -16,5 +16,7 @@ namespace CandidateReviewContracts.ViewModels public string? Contacts { get; set; } public int Id { get; set; } + + public List Vacancies { get; set; } = new(); } } diff --git a/CandidateReviewDatabaseImplement/Models/Vacancy.cs b/CandidateReviewDatabaseImplement/Models/Vacancy.cs index 6796d1c..5e4c913 100644 --- a/CandidateReviewDatabaseImplement/Models/Vacancy.cs +++ b/CandidateReviewDatabaseImplement/Models/Vacancy.cs @@ -53,7 +53,7 @@ namespace CandidateReviewDatabaseImplement.Models Salary = model.Salary, Description = model.Description, Status = model.Status, - CreatedAt = model.CreatedAt, + CreatedAt = DateTime.Now.ToUniversalTime(), Tags = model.Tags }; } diff --git a/CandidateReviewRestApi/Controllers/CompanyController.cs b/CandidateReviewRestApi/Controllers/CompanyController.cs index e6fed6c..6ce23d5 100644 --- a/CandidateReviewRestApi/Controllers/CompanyController.cs +++ b/CandidateReviewRestApi/Controllers/CompanyController.cs @@ -2,7 +2,9 @@ using CandidateReviewContracts.BusinessLogicsContracts; using CandidateReviewContracts.SearchModels; using CandidateReviewContracts.ViewModels; +using CandidateReviewDataModels.Models; using Microsoft.AspNetCore.Mvc; +using System.Linq; namespace CandidateReviewRestApi.Controllers { @@ -12,10 +14,12 @@ namespace CandidateReviewRestApi.Controllers { private readonly ILogger _logger; private readonly ICompanyLogic _logic; - public CompanyController(ICompanyLogic logic, ILogger logger) + private readonly IVacancyLogic _vacancyLogic; + public CompanyController(ICompanyLogic logic, IVacancyLogic vacancyLogic, ILogger logger) { _logger = logger; _logic = logic; + _vacancyLogic = vacancyLogic; } [HttpGet] @@ -77,5 +81,17 @@ namespace CandidateReviewRestApi.Controllers throw; } } + + /*private CompanyBindingModel GetCompanyWithVacancies(CompanyBindingModel model) + { + var vacancies = _vacancyLogic.ReadList(new VacancySearchModel { CompanyId = model.Id }); + if (vacancies != null) + { + model.Vacancies = vacancies.Where(v => v.CompanyId == model.Id) + .Select(v => (IVacancyModel)v) + .ToList(); + } + return model; + }*/ } } diff --git a/CandidateReviewRestApi/Controllers/UserController.cs b/CandidateReviewRestApi/Controllers/UserController.cs index 29f0ae5..5a9b28d 100644 --- a/CandidateReviewRestApi/Controllers/UserController.cs +++ b/CandidateReviewRestApi/Controllers/UserController.cs @@ -80,5 +80,19 @@ namespace CandidateReviewRestApi.Controllers throw; } } + + [HttpPost] + public void Delete(UserBindingModel model) + { + try + { + _logic.Delete(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка удаления профиля пользователя"); + throw; + } + } } } diff --git a/CandidateReviewRestApi/Controllers/VacancyController.cs b/CandidateReviewRestApi/Controllers/VacancyController.cs new file mode 100644 index 0000000..17deeff --- /dev/null +++ b/CandidateReviewRestApi/Controllers/VacancyController.cs @@ -0,0 +1,80 @@ +using CandidateReviewContracts.BindingModels; +using CandidateReviewContracts.BusinessLogicsContracts; +using CandidateReviewContracts.SearchModels; +using CandidateReviewContracts.ViewModels; +using Microsoft.AspNetCore.Mvc; + +namespace CandidateReviewRestApi.Controllers +{ + [Route("api/[controller]/[action]")] + [ApiController] + public class VacancyController : Controller + { + private readonly ILogger _logger; + private readonly IVacancyLogic _logic; + public VacancyController(IVacancyLogic logic, ILogger logger) + { + _logger = logger; + _logic = logic; + } + + [HttpGet] + public VacancyViewModel? Details(int id) + { + try + { + return _logic.ReadElement(new VacancySearchModel + { + Id = id + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения вакансии"); + throw; + } + } + + [HttpPost] + public void Create(VacancyBindingModel model) + { + try + { + _logic.Create(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка создания вакансии"); + throw; + } + } + + [HttpPost] + public void Update(VacancyBindingModel model) + { + try + { + _logic.Update(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка обновления вакансии"); + throw; + } + } + + [HttpDelete] + public void Delete(VacancyBindingModel model) + { + try + { + _logic.Delete(model); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка удаления вакансии"); + throw; + } + } + } +}