From fd31ade8554ad294a30a7a2f9b1a03d91e7331e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=B0=D1=82=D1=8C=D1=8F=D0=BD=D0=B0=20=D0=90=D1=80?= =?UTF-8?q?=D1=82=D0=B0=D0=BC=D0=BE=D0=BD=D0=BE=D0=B2=D0=B0?= Date: Fri, 13 Dec 2024 04:12:54 +0400 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D1=81=D1=82=D0=B8=D0=BB=D0=B8,=20=D0=BC=D0=B5?= =?UTF-8?q?=D0=BB=D0=BA=D0=B8=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BE=D1=86=D0=B5=D0=BD=D0=BA=D0=B0=20=D0=BF=D0=BE=D1=87?= =?UTF-8?q?=D1=82=D0=B8=20=D0=BD=D0=BE=20=D0=BD=D0=B8=D0=BA=D0=B0=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogic/AssessmentLogic.cs | 31 +---- .../BusinessLogic/ResumeLogic.cs | 2 + .../BusinessLogic/VacancyLogic.cs | 6 + .../Controllers/AssessmentController.cs | 62 ++++++++- .../Controllers/ResumeController.cs | 20 ++- .../Controllers/UserController.cs | 8 +- .../Controllers/VacancyController.cs | 11 ++ .../Views/Company/CompanyProfile.cshtml | 124 ++++++++++++------ .../Views/Company/EditCompanyProfile.cshtml | 16 +++ .../Views/Criterion/ManageCriterions.cshtml | 18 ++- .../Views/Home/Enter.cshtml | 86 ++++++++---- .../Views/Home/Index.cshtml | 31 +++-- .../Views/Home/Register.cshtml | 59 ++++++++- .../Views/Resume/EditResume.cshtml | 28 +++- .../Views/Resume/ResumeDetails.cshtml | 49 +++++-- .../Views/Shared/_Layout.cshtml | 30 ++++- .../Views/Shared/_VacanciesTable.cshtml | 33 ----- .../Views/User/Employees.cshtml | 101 ++++++++++++++ .../Views/User/UserProfile.cshtml | 121 +++++++++-------- .../Views/User/UserProfileEdit.cshtml | 76 +++++------ .../Views/Vacancy/EditVacancy.cshtml | 17 +++ .../Views/Vacancy/SearchVacancies.cshtml | 27 ++-- .../Views/Vacancy/Vacancies.cshtml | 107 +++++++++++++++ .../Views/Vacancy/VacancyDetails.cshtml | 17 +++ .../BindingModels/AssessmentBindingModel.cs | 2 +- .../StoragesContracts/IAssessmentStorage.cs | 1 - .../AssessmentCriterionViewModel.cs | 17 --- .../ViewModels/AssessmentViewModel.cs | 2 +- .../ViewModels/UserViewModel.cs | 1 + .../Models/CriterionModel.cs | 15 +++ .../Models/IAssessmentCriterionModel.cs | 9 -- .../Implements/AssessmentStorage.cs | 42 ++---- .../Implements/VacancyStorage.cs | 9 ++ .../Models/Assessment.cs | 43 +++--- .../Models/AssessmentCriterion.cs | 8 -- .../Controllers/VacancyController.cs | 21 +++ 36 files changed, 860 insertions(+), 390 deletions(-) delete mode 100644 CandidateReviewClientApp/Views/Shared/_VacanciesTable.cshtml create mode 100644 CandidateReviewClientApp/Views/User/Employees.cshtml create mode 100644 CandidateReviewClientApp/Views/Vacancy/Vacancies.cshtml delete mode 100644 CandidateReviewContracts/ViewModels/AssessmentCriterionViewModel.cs create mode 100644 CandidateReviewDataModels/Models/CriterionModel.cs delete mode 100644 CandidateReviewDataModels/Models/IAssessmentCriterionModel.cs diff --git a/CandidateReviewBusinessLogic/BusinessLogic/AssessmentLogic.cs b/CandidateReviewBusinessLogic/BusinessLogic/AssessmentLogic.cs index 91307f3..2d6ee60 100644 --- a/CandidateReviewBusinessLogic/BusinessLogic/AssessmentLogic.cs +++ b/CandidateReviewBusinessLogic/BusinessLogic/AssessmentLogic.cs @@ -67,40 +67,15 @@ namespace CandidateReviewBusinessLogic.BusinessLogic public List? ReadList(AssessmentSearchModel? model) { var list = model == null ? _assessmentStorage.GetFullList() : _assessmentStorage.GetFilteredList(model); - List result = new(); - foreach (var elem in list) - { - var user = _userStorage.GetElement(new UserSearchModel { Id = elem.UserId }); - var assessmentCriterions = _assessmentStorage.GetAssessmentCriterions(elem.Id); - - var assessmentViewModel = new AssessmentViewModel - { - Id = elem.Id, - ResumeId = elem.ResumeId, - UserId = elem.UserId, - UserName = user.Name + " " + user.Name, - Comment = elem.Comment, - AssessmentCriterions = assessmentCriterions.Select(ac => new AssessmentCriterionViewModel - { - AssessmentId = ac.AssessmentId, - CriterionId = ac.CriterionId, - Value = ac.Value, - CriterionName = _criterionStorage.GetElement(new CriterionSearchModel { Id = ac.CriterionId })?.Name - }).ToList() - }; - - result.Add(assessmentViewModel); - } - - if (result == null) + if (list == null) { _logger.LogWarning("ReadList return null list"); return null; } - _logger.LogInformation("ReadList. Count: {Count}", result.Count); - return result; + _logger.LogInformation("ReadList. Count: {Count}", list.Count); + return list; } public bool Update(AssessmentBindingModel model) diff --git a/CandidateReviewBusinessLogic/BusinessLogic/ResumeLogic.cs b/CandidateReviewBusinessLogic/BusinessLogic/ResumeLogic.cs index 0bdcafc..c8acf0c 100644 --- a/CandidateReviewBusinessLogic/BusinessLogic/ResumeLogic.cs +++ b/CandidateReviewBusinessLogic/BusinessLogic/ResumeLogic.cs @@ -64,6 +64,7 @@ namespace CandidateReviewBusinessLogic.BusinessLogic { Id = a.Id, ResumeId = a.ResumeId, + UserName = a.UserName, UserId = a.UserId, Comment = a.Comment, AssessmentCriterions = a.AssessmentCriterions @@ -107,6 +108,7 @@ namespace CandidateReviewBusinessLogic.BusinessLogic Id = a.Id, ResumeId = a.ResumeId, UserId = a.UserId, + UserName = a.UserName, Comment = a.Comment, AssessmentCriterions = a.AssessmentCriterions }).ToList() ?? new List(); diff --git a/CandidateReviewBusinessLogic/BusinessLogic/VacancyLogic.cs b/CandidateReviewBusinessLogic/BusinessLogic/VacancyLogic.cs index d843b3f..a34c6d3 100644 --- a/CandidateReviewBusinessLogic/BusinessLogic/VacancyLogic.cs +++ b/CandidateReviewBusinessLogic/BusinessLogic/VacancyLogic.cs @@ -104,6 +104,12 @@ namespace CandidateReviewBusinessLogic.BusinessLogic _logger.LogWarning("ReadList return null list"); return null; } + foreach (var item in list) + { + var companyName = _companyStorage.GetElement(new CompanySearchModel { Id = item.CompanyId }).Name; + item.CompanyName = companyName; + } + _logger.LogInformation("ReadList. Count: {Count}", list.Count); return list; } diff --git a/CandidateReviewClientApp/Controllers/AssessmentController.cs b/CandidateReviewClientApp/Controllers/AssessmentController.cs index 4fa8dcb..379c30b 100644 --- a/CandidateReviewClientApp/Controllers/AssessmentController.cs +++ b/CandidateReviewClientApp/Controllers/AssessmentController.cs @@ -5,6 +5,8 @@ using CandidateReviewContracts.ViewModels; using CandidateReviewDataModels.Models; using Microsoft.AspNetCore.Mvc; using System.Diagnostics; +using System.Reflection; +using System.Security.Cryptography.Xml; namespace CandidateReviewClientApp.Controllers { @@ -22,7 +24,7 @@ namespace CandidateReviewClientApp.Controllers [HttpPost] public async Task AddAssessmentCriterion(int resumeId, int[] criterion, int[] value, string comment) { - string returnUrl = HttpContext.Request.Headers["Referer"].ToString(); + string returnUrl = HttpContext.Request.Headers.Referer.ToString(); try { @@ -35,22 +37,54 @@ namespace CandidateReviewClientApp.Controllers { throw new ArgumentException("Массивы критериев и оценок должны быть не null и одинаковой длины."); } + Dictionary assCriterions = new(); + var userId = APIClient.User?.Id; - var assessmentData = new Dictionary(); - var assessmentModel = new AssessmentBindingModel { ResumeId = resumeId, UserId = userId, Comment = comment, - AssessmentCriterions = criterion.Select((t, i) => new KeyValuePair - (t, (new CriterionViewModel { Id = t }, value[i]))).ToDictionary(kv => kv.Key, kv => kv.Value) + AssessmentCriterions = assCriterions }; - int assessmentId = await APIClient.PostRequestAsync("api/assessment/create", assessmentModel); + for (int i = 0; i < criterion.Length; i++) + { + var crit = APIClient.GetRequest($"api/criterion/details?id={criterion[i]}"); + assCriterions.Add(assessmentId, (new CriterionModel { Id = crit.Id, Name = crit.Name }, value[i])); + } + + assessmentModel.AssessmentCriterions = assCriterions; + assessmentModel.Id = assessmentId; + APIClient.PostRequest("api/assessment/update", assessmentModel); + + var user = APIClient.GetRequest($"api/user/profile?id={APIClient.User?.Id}"); + + APIClient.User?.Assessments.Add(new AssessmentViewModel + { + ResumeId = assessmentModel.ResumeId, + UserId = assessmentModel.UserId, + Comment = assessmentModel.Comment, + AssessmentCriterions = assessmentModel.AssessmentCriterions + }); + var resume = APIClient.GetRequest($"api/resume/details?id={resumeId}"); + if (resume != null) + { + resume?.Assessments.Add(new AssessmentViewModel + { + ResumeId = assessmentModel.ResumeId, + UserId = assessmentModel.UserId, + Comment = assessmentModel.Comment, + AssessmentCriterions = assessmentModel.AssessmentCriterions + }); + } + else + { + throw new Exception("Пользователь не найден"); + } return Redirect($"~/Resume/ResumeDetails/{resumeId}"); } catch (Exception ex) @@ -59,6 +93,22 @@ namespace CandidateReviewClientApp.Controllers } } + public IActionResult Delete(int id, int resumeId) + { + string returnUrl = HttpContext.Request.Headers["Referer"].ToString(); + + try + { + APIClient.PostRequest($"api/assessment/delete", new AssessmentBindingModel { Id = id }); + + return Redirect($"~/Resume/ResumeDetails/{resumeId}") ; + } + catch (Exception ex) + { + return RedirectToAction("Error", new { errorMessage = $"{ex.Message}", returnUrl }); + } + } + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error(string errorMessage, string returnUrl) { diff --git a/CandidateReviewClientApp/Controllers/ResumeController.cs b/CandidateReviewClientApp/Controllers/ResumeController.cs index 1378462..d955349 100644 --- a/CandidateReviewClientApp/Controllers/ResumeController.cs +++ b/CandidateReviewClientApp/Controllers/ResumeController.cs @@ -105,7 +105,15 @@ namespace CandidateReviewClientApp.Controllers { APIClient.User?.Resumes.Add(new ResumeViewModel { - Id = model.Id + Id = model.Id, + Description = model.Description, + Education = model.Education, + Experience = model.Experience, + Skills = model.Skills, + Status = model.Status, + Title = model.Title, + UserId = model.UserId, + VacancyId = model.VacancyId }); } else @@ -116,7 +124,15 @@ namespace CandidateReviewClientApp.Controllers { vacancy.Resumes.Add(new ResumeViewModel { - Id = model.Id + Id = model.Id, + Description = model.Description, + Education = model.Education, + Experience = model.Experience, + Skills = model.Skills, + Status = model.Status, + Title = model.Title, + UserId = model.UserId, + VacancyId = model.VacancyId }); } else diff --git a/CandidateReviewClientApp/Controllers/UserController.cs b/CandidateReviewClientApp/Controllers/UserController.cs index 3c2383c..71d9d1e 100644 --- a/CandidateReviewClientApp/Controllers/UserController.cs +++ b/CandidateReviewClientApp/Controllers/UserController.cs @@ -43,7 +43,11 @@ namespace CandidateReviewClientApp.Controllers if (!id.HasValue) { - return View(new UserViewModel()); + var model = new UserViewModel + { + CompanyId = APIClient.Company.Id + }; + return View(model); } else if (id.HasValue) { @@ -68,7 +72,7 @@ namespace CandidateReviewClientApp.Controllers APIClient.PostRequest("api/user/update", model); } else - { + { APIClient.PostRequest("api/user/register", model); if (APIClient.Company != null) { diff --git a/CandidateReviewClientApp/Controllers/VacancyController.cs b/CandidateReviewClientApp/Controllers/VacancyController.cs index 922e9a9..9c2bb73 100644 --- a/CandidateReviewClientApp/Controllers/VacancyController.cs +++ b/CandidateReviewClientApp/Controllers/VacancyController.cs @@ -30,6 +30,17 @@ namespace CandidateReviewClientApp.Controllers return View(); } + [HttpGet] + public IActionResult Vacancies(int? companyId) + { + if (APIClient.User == null) + { + return Redirect("~/Home/Enter"); + } + var vacancies = APIClient.GetRequest?>($"api/vacancy/list?companyId={companyId}"); + return View(vacancies); + } + [HttpGet] public IActionResult EditVacancy(int? id) { diff --git a/CandidateReviewClientApp/Views/Company/CompanyProfile.cshtml b/CandidateReviewClientApp/Views/Company/CompanyProfile.cshtml index e623865..f8f33a8 100644 --- a/CandidateReviewClientApp/Views/Company/CompanyProfile.cshtml +++ b/CandidateReviewClientApp/Views/Company/CompanyProfile.cshtml @@ -3,6 +3,7 @@ @{ ViewData["Title"] = "Профиль компании"; + var isAdmin = APIClient.User.Role == CandidateReviewDataModels.Enums.RoleEnum.Администратор ? true : false; }
@@ -48,20 +49,54 @@

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

Добавить вакансию + class="btn btn-success"> Добавить вакансию
@if (Model.Vacancies != null && Model.Vacancies.Any()) { - @await Html.PartialAsync("_VacanciesTable", Model.Vacancies.Take(5)) +
+ + + + + + + + + + @foreach (var vacancy in Model.Vacancies.Take(5)) + { + + + + + + } + +
Название вакансииСтатусДействия
@vacancy.JobTitle@vacancy.Status + +
+
+ @if (Model.Vacancies.Count() > 5) { - + Посмотреть все } - - } else { @@ -73,44 +108,50 @@

Сотрудники компании

+ @if (@isAdmin) { Добавить сотрудника + class="btn btn-success"> Добавить сотрудника + }
@if (Model.Employees != null && Model.Employees.Any()) { - - - - - - - - - - - @foreach (var employee in Model.Employees) + +
+
ФамилияИмяЭл. почтаДействия
+ + + + + + + + + + @foreach (var employee in Model.Employees.Take(5)) { + } - -
ФамилияИмяЭл. почтаДействия
@employee.Surname @employee.Name@employee.Email - - Просмотр + + - - Редактировать + + - - Удалить + +
+ + +
} else { @@ -121,20 +162,19 @@
+ diff --git a/CandidateReviewClientApp/Views/Company/EditCompanyProfile.cshtml b/CandidateReviewClientApp/Views/Company/EditCompanyProfile.cshtml index 4823d99..631d595 100644 --- a/CandidateReviewClientApp/Views/Company/EditCompanyProfile.cshtml +++ b/CandidateReviewClientApp/Views/Company/EditCompanyProfile.cshtml @@ -78,4 +78,20 @@ }) })() + diff --git a/CandidateReviewClientApp/Views/Criterion/ManageCriterions.cshtml b/CandidateReviewClientApp/Views/Criterion/ManageCriterions.cshtml index c9027dd..650bd35 100644 --- a/CandidateReviewClientApp/Views/Criterion/ManageCriterions.cshtml +++ b/CandidateReviewClientApp/Views/Criterion/ManageCriterions.cshtml @@ -70,4 +70,20 @@ - \ No newline at end of file + + \ No newline at end of file diff --git a/CandidateReviewClientApp/Views/Home/Enter.cshtml b/CandidateReviewClientApp/Views/Home/Enter.cshtml index e2d229c..666e842 100644 --- a/CandidateReviewClientApp/Views/Home/Enter.cshtml +++ b/CandidateReviewClientApp/Views/Home/Enter.cshtml @@ -3,40 +3,28 @@ Layout = "_LoginLayout"; } -@if (!ViewData.ModelState.IsValid) -{ -
-
    - @foreach (var error in ViewData.ModelState.Values.SelectMany(v => v.Errors)) - { -
  • @error.ErrorMessage
  • - } -
-
-} -
-
-
-

Вход в приложение

+
+
+

Вход в приложение

-
+
-
- +
+
-
- +
+
-
+ diff --git a/CandidateReviewClientApp/Views/Home/Index.cshtml b/CandidateReviewClientApp/Views/Home/Index.cshtml index a220f38..21a1270 100644 --- a/CandidateReviewClientApp/Views/Home/Index.cshtml +++ b/CandidateReviewClientApp/Views/Home/Index.cshtml @@ -7,18 +7,21 @@

Здесь вы можете:

-
-

Создать профиль компании

-
-
-

Подобрать кандидатов на вакансию

-
-
-

Найти подходящую вакансию

-
-
-

Оценить кандидатов на вакансию

-
+
+ +

Создать профиль компании

+
+
+ +

Подобрать кандидатов на вакансию

+
+
+ +

Найти подходящую вакансию

+
+
+ +

Оценить кандидатов на вакансию

@@ -30,6 +33,10 @@ gap: 20px; } + .box i { + margin-bottom: 10px; + } + .box { border: 1px solid #ccc; border-radius: 8px; diff --git a/CandidateReviewClientApp/Views/Home/Register.cshtml b/CandidateReviewClientApp/Views/Home/Register.cshtml index 67a4af1..70562ea 100644 --- a/CandidateReviewClientApp/Views/Home/Register.cshtml +++ b/CandidateReviewClientApp/Views/Home/Register.cshtml @@ -6,8 +6,8 @@
-
-
+
+

Регистрация

@@ -36,11 +36,62 @@
-
\ No newline at end of file +
+ + + \ No newline at end of file diff --git a/CandidateReviewClientApp/Views/Resume/EditResume.cshtml b/CandidateReviewClientApp/Views/Resume/EditResume.cshtml index d69af52..655a242 100644 --- a/CandidateReviewClientApp/Views/Resume/EditResume.cshtml +++ b/CandidateReviewClientApp/Views/Resume/EditResume.cshtml @@ -40,12 +40,6 @@
-
- - - Предварительный просмотр фото -
Выберите файл изображения.
-
@if (Model.Status == ResumeStatusEnum.Черновик) { @@ -54,6 +48,10 @@ @if (Model.Id <= 0) { + } + else + { + }
@@ -78,4 +76,20 @@ }, false) }) })() - \ No newline at end of file + + \ No newline at end of file diff --git a/CandidateReviewClientApp/Views/Resume/ResumeDetails.cshtml b/CandidateReviewClientApp/Views/Resume/ResumeDetails.cshtml index feb204d..2d4f95a 100644 --- a/CandidateReviewClientApp/Views/Resume/ResumeDetails.cshtml +++ b/CandidateReviewClientApp/Views/Resume/ResumeDetails.cshtml @@ -7,16 +7,14 @@ @{ ViewData["Title"] = "Резюме"; bool userRole = APIClient.User?.Role == CandidateReviewDataModels.Enums.RoleEnum.Сотрудник || APIClient.User.Role == CandidateReviewDataModels.Enums.RoleEnum.Администратор; + bool isAdmin = APIClient.User.Role == CandidateReviewDataModels.Enums.RoleEnum.Администратор ? true : false; + var assessmentCriterions = new Dictionary(); }

@Model.Title

- Аватар пользователя
@@ -64,6 +62,14 @@ {

Оценка резюме

+ @if (isAdmin) + { + +

+ } +
@@ -85,11 +91,11 @@
- +
} @@ -111,15 +117,20 @@
- +
}

Комментарий: @userAssessment.Comment

+ + + Удалить оценку +
} else @@ -160,11 +171,8 @@ }
- - } +
+ + diff --git a/CandidateReviewClientApp/Views/Shared/_Layout.cshtml b/CandidateReviewClientApp/Views/Shared/_Layout.cshtml index 6e90a02..5f02239 100644 --- a/CandidateReviewClientApp/Views/Shared/_Layout.cshtml +++ b/CandidateReviewClientApp/Views/Shared/_Layout.cshtml @@ -14,25 +14,25 @@
-