diff --git a/gates/src/main/java/ru/mlokoin/gates/controller/v1/CourseController.java b/gates/src/main/java/ru/mlokoin/gates/controller/v1/CourseController.java index b4ef83d..4eaa874 100644 --- a/gates/src/main/java/ru/mlokoin/gates/controller/v1/CourseController.java +++ b/gates/src/main/java/ru/mlokoin/gates/controller/v1/CourseController.java @@ -2,16 +2,11 @@ package ru.mlokoin.gates.controller.v1; import java.time.Duration; import java.util.ArrayList; -import java.util.Date; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -102,56 +97,72 @@ public class CourseController { //Получение перечня курсов из базы System.out.println("Получение списка курсов из базы ..."); List base_courses = storage.getBaseCourse(); + System.out.println("Количество курсов в базе: " + base_courses.size()); - /***************************************************************************************** */ - - //Удаляем повторяющиеся курсы - // List set = new ArrayList<>(xlsx_courses); - // Set set = new HashSet<>(xlsx_courses); - // List courses = new ArrayList<>(set); - System.out.println("Удаляем повторяющиеся курсы ..."); - System.out.println("Количество курсов в xlsx_courses (list): " + xlsx_courses.size()); - for (Course courseA : new ArrayList<>(xlsx_courses)) { - Boolean isExists = false; - for (Course courseB : new ArrayList<>(xlsx_courses)) { - if (Course.isSimilar(courseA, courseB) && !isExists) { - isExists = true; - } else { - if (Course.isSimilar(courseA, courseB) && isExists) { - xlsx_courses.remove(courseA); + /***************************************************************************************** + * + * Удаление повторяющихся курсов + * - удаляем повторяющиеся курсы в xlsx-файле + * - удаляем курсы, присутствующие в базе + * * + ******************************************************************************************/ + System.out.println("Удаляем повторяющиеся в xlsx-файле курсы ..."); + System.out.println("Количество курсов в xlsx_courses: " + xlsx_courses.size()); + List filtered = new ArrayList(); + for (Course course : xlsx_courses) { + if (course != null) { + if (course.getStart_date() != null && course.getBuilding() != null && course.getTeacher() != null) { + if (!filtered.contains(course)) { + boolean exists = false; + + //Проверяем наличие курса в базе + if (base_courses.size() > 0) { + //Сравниваем курс из xlsx-файла с каждой записью в базе + for (Course base_course : base_courses) { + // номер протокола нулевой, сравниваем курсы по дате начала обучения, объекту строительства, фио преподавателя + if (course.getProtocol_number() == null || + course.getProtocol_number().isEmpty() || + course.getProtocol_number().equals("")) { + + exists = course.getTeacher().equals(base_course.getTeacher()) + && course.getProgram().equals(base_course.getProgram()) + && course.getPlace().equals(base_course.getPlace()) + && course.getStart_date().equals(base_course.getStart_date()); + if (exists) { + break; + } + } + // номер протокола не нулевой, сравниваем курсы по номеру протокола + else { + exists = course.getProtocol_number().equals(base_course.getProtocol_number()); + if (exists) { + break; + } + } + } + } + + //Если курс еще не в списке и не существует в базе, добавляем курс в список + if (!exists) { + filtered.add(course); + } } + } } } - System.out.println("Количество уникальных курсов в xlsx_courses (list): " + xlsx_courses.size()); - - System.out.println("Удаляем курсы уже учтенные в базе ..."); - // System.out.println("Количество уникальных курсов в xlsx (set): " + set.size()); - if (base_courses.size() > 0) { - System.out.println("Количество курсов в базе: " + base_courses.size()); - for (Course b : base_courses) { - for (Course x : new ArrayList<>(xlsx_courses)) { - if (Course.isSimilar(b, x)) { - // System.out.println("Курс " + b.getProtocol_number() + " от " + b.getStart_date() + " повторяется в set"); - xlsx_courses.remove(x); - } - else { - // System.out.println("Курс " + x.getProtocol_number() + " от " + x.getStart_date() + " не повторяется в базе"); - } - } + System.out.println("Количество уникальных курсов filtered: " + filtered.size()); - } - System.out.println("Количество курсов для добавления в базу (xlsx_courses): " + xlsx_courses.size()); - } - if (xlsx_courses.size() > 0) { + //Передаем курсы в шаблон + if (filtered.size() > 0) { //Ограничиваем количество курсов, подлежащих передаче в wraper - System.out.println("Общее количество курсов для добавления в базу: " + xlsx_courses.size()); - if (xlsx_courses.size() > 10) { - xlsx_courses = xlsx_courses.subList(0, 10); + // System.out.println("Общее количество курсов для добавления в базу: " + filtered.size()); + if (filtered.size() > 200) { + filtered = filtered.subList(0, 200); } //Создаем wraper для передачи в шаблон - CourseWraper wraper = new CourseWraper(xlsx_courses); + CourseWraper wraper = new CourseWraper(filtered); wraper.addPrograms(programs); wraper.addBuildings(buildings); wraper.addTeachers(teachers); @@ -165,7 +176,7 @@ public class CourseController { } /** - * Добавление новых программ обучения в базу + * Добавление новых курсов в базу * @param wraper * @param id * @return diff --git a/gates/src/main/java/ru/mlokoin/gates/controller/v1/OrganizationController.java b/gates/src/main/java/ru/mlokoin/gates/controller/v1/OrganizationController.java index 229d0a8..849dde3 100644 --- a/gates/src/main/java/ru/mlokoin/gates/controller/v1/OrganizationController.java +++ b/gates/src/main/java/ru/mlokoin/gates/controller/v1/OrganizationController.java @@ -8,8 +8,6 @@ import java.util.Map; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -21,8 +19,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; -import ru.mlokoin.gates.model.building.Building; -import ru.mlokoin.gates.model.building.BuildingWraper; import ru.mlokoin.gates.model.fs.xlsx.XlsxCell; import ru.mlokoin.gates.model.fs.xlsx.XlsxDocument; import ru.mlokoin.gates.model.organization.Organization; diff --git a/gates/src/main/java/ru/mlokoin/gates/controller/v1/StudentController.java b/gates/src/main/java/ru/mlokoin/gates/controller/v1/StudentController.java new file mode 100644 index 0000000..576fba4 --- /dev/null +++ b/gates/src/main/java/ru/mlokoin/gates/controller/v1/StudentController.java @@ -0,0 +1,158 @@ +package ru.mlokoin.gates.controller.v1; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.reactive.function.client.WebClient; + +import reactor.core.publisher.Mono; +import ru.mlokoin.gates.model.fs.xlsx.XlsxCell; +import ru.mlokoin.gates.model.fs.xlsx.XlsxDocument; +import ru.mlokoin.gates.model.organization.Organization; +import ru.mlokoin.gates.model.student.Student; +import ru.mlokoin.gates.model.student.StudentWraper; +import ru.mlokoin.gates.repository.Storage; + +@Controller +@RequestMapping(path = "/students") +public class StudentController { + @Autowired + private WebClient client; + + @Autowired + private Storage storage; + + @GetMapping("/check/{id}") + public String checkStudents(Model model, @PathVariable String id) { + System.out.println("Проверка студентов из xlsx, для внесения в базу ..."); + List errors = new ArrayList<>();//список ошибок + + //Получение списка организаций, для передачи в врапер + List base_organizations; + try { + base_organizations = storage.getBaseOrganizations(); + } catch (Exception e) { + errors.add("Ошибка при получении списка организаций из базы :: " +e.getMessage()); + System.out.println("Не удалось получить список организаций из базы: " + e.getMessage()); + base_organizations = new ArrayList<>(); + } + + //получение данных файла в переменную xlsx + XlsxDocument xlsx = storage.getXlsxDocument(id); + + //получение перечня студентов из xlsx + ArrayList xlsx_students = new ArrayList<>(); + Map> map = xlsx.getData(); + for (Map.Entry> entry : map.entrySet()) { + xlsx_students.add(new Student(entry, base_organizations)); + } + System.out.println("Всего студентов в xlsx: " + xlsx_students.size()); + + //получение перечня студентов из базы + List base_students = storage.getBaseStudents(); + System.out.println("Всего студентов в базе: " + base_students.size()); + + /** + * Удаляем повторяющихся студентов из списка + * Исключаем из списка студентов, данные о которых уже присутствуют в базе + */ + List filtered = new ArrayList<>(); + for (Student xlsx_student : xlsx_students) { + if (xlsx_student != null) { + // если имя не отсутствует, считаем, что студент существует + if (xlsx_student.getFirst_name() != null){ + if (!filtered.contains(xlsx_student)) { + boolean exists = false; + if (base_students.size() > 0) { + for (Student base_student : base_students) { + exists = xlsx_student.getFirst_name().equals(base_student.getFirst_name()) + && xlsx_student.getLast_name().equals(base_student.getLast_name()) + && xlsx_student.getSecond_name().equals(base_student.getSecond_name()) + && xlsx_student.getProfession().equals(base_student.getProfession()) + && xlsx_student.getOrganization().equals(base_student.getOrganization()) + && xlsx_student.getDirection().equals(base_student.getDirection()); + + if (exists) { + break; + } + } + } + if (!exists) { + filtered.add(xlsx_student); + } + } + } + } + } + System.out.println("Уникальных студентов в xlsx: " + filtered.size()); + + //передает список студентов в шаблон + if (filtered.size() > 0) { + if (filtered.size() > 200) { + filtered = filtered.subList(0, 200); + } + //создаем врапер для списка студентов + StudentWraper wraper = new StudentWraper(filtered); + + //передаем врапер в шаблон + model.addAttribute("studentWraper", wraper); + model.addAttribute("errors", errors); + return "students-check"; + } + return "redirect:/document/view-as-educations/" + id; + } + + /** + * Добавление новых студентов в базу + * @param wraper + * @param id + * @return + */ + @PostMapping( + path="/save/{id}", + consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE + ) + public String saveCourses(Model model, @ModelAttribute("studentWraper") StudentWraper wraper, @PathVariable String id){ + /** + * Отправляем запросы на добавление новых студентов в базу + */ + List errors = new ArrayList<>(); + System.out.println("Отправляем запросы на добавление новых студентов в базу ..."); + List students = wraper.getStudents(); + System.out.println("Количество студентов для добавления в базу: " + students.size()); + + for (Student student : students) { + try{ + client.post() + .uri("http://resource-service-api:8181/student/create") + .body(Mono.just(student), Student.class) + .retrieve() + .toBodilessEntity() + .timeout(Duration.ofSeconds(2)) + .block(); + } catch (Exception e) { + errors.add("Не удалось добавить студента: " + student.toString() + " :: " + e.getMessage()); + System.out.println("Не удалось добавить студента: " + student.toString() + " :: " + e.getMessage()); + } + } + + model.addAttribute("errors", errors); + /** + * Возвращаем пользователя на страницу перечня новых студентов + * - если он не пустой + */ + return "redirect:/students/check/" + id; + } +} diff --git a/gates/src/main/java/ru/mlokoin/gates/model/education/EducationEntryWraper.java b/gates/src/main/java/ru/mlokoin/gates/model/education/EducationEntryWraper.java new file mode 100644 index 0000000..b2551ab --- /dev/null +++ b/gates/src/main/java/ru/mlokoin/gates/model/education/EducationEntryWraper.java @@ -0,0 +1,5 @@ +package ru.mlokoin.gates.model.education; + +public class EducationEntryWraper { + +} diff --git a/gates/src/main/java/ru/mlokoin/gates/model/student/Student.java b/gates/src/main/java/ru/mlokoin/gates/model/student/Student.java index f01e7c1..1518fba 100644 --- a/gates/src/main/java/ru/mlokoin/gates/model/student/Student.java +++ b/gates/src/main/java/ru/mlokoin/gates/model/student/Student.java @@ -2,11 +2,16 @@ package ru.mlokoin.gates.model.student; import java.io.Serializable; import java.util.Date; +import java.util.List; +import java.util.Map; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import ru.mlokoin.gates.model.fs.xlsx.XlsxCell; import ru.mlokoin.gates.model.organization.Organization; +import ru.mlokoin.gates.teh.strings.Naimer; +import ru.mlokoin.gates.teh.strings.Stringer; @NoArgsConstructor @AllArgsConstructor @@ -53,4 +58,35 @@ public class Student implements Serializable{ this.sex = sex; this.organization = organization; } + + public Student(Map.Entry> entry, List base_organizations) { + if (entry.getKey() != 0) { + List cells = entry.getValue(); + + this.first_name = Naimer.getFirstNameOf(cells.get(3).getContent()); + this.second_name = Naimer.getSecondNameOf(cells.get(3).getContent()); + this.last_name = Naimer.getLastNameOf(cells.get(3).getContent()); + + this.profession = cells.get(4).getContent(); + this.direction = cells.get(2).getContent(); + /** + * Данные, отсутствующие в реестре: + * - category + * - snils + * - berth + * - sitizenship + * - sex + * + * Будут заполнены пользователем при внесении сведений об обученных + */ + + // Поиск организации + String organization = Stringer.clear(cells.get(1).getContent()); + this.organization = base_organizations + .stream() + .filter(org -> org.getName_full().equals(organization)) + .findFirst() + .orElse(null); + } + } } diff --git a/gates/src/main/java/ru/mlokoin/gates/model/student/StudentWraper.java b/gates/src/main/java/ru/mlokoin/gates/model/student/StudentWraper.java new file mode 100644 index 0000000..ba25a23 --- /dev/null +++ b/gates/src/main/java/ru/mlokoin/gates/model/student/StudentWraper.java @@ -0,0 +1,38 @@ +package ru.mlokoin.gates.model.student; + +import java.util.ArrayList; +import java.util.List; + +import lombok.Data; +import ru.mlokoin.gates.model.organization.Organization; + +@Data +public class StudentWraper { + List students; + List organizations; + + public StudentWraper(){ + init(); + } + + public StudentWraper(List list) { + this.students = list; + } + + public void init(){ + this.students = new ArrayList<>(); + } + + public void addStudent(Student student){ + this.students.add(student); + } + + public void addOrganization(Organization organization){ + this.organizations.add(organization); + } + + public String toString(){ + return this.students.toString(); + } + +} diff --git a/gates/src/main/java/ru/mlokoin/gates/repository/Storage.java b/gates/src/main/java/ru/mlokoin/gates/repository/Storage.java index 4a2be95..088d9b0 100644 --- a/gates/src/main/java/ru/mlokoin/gates/repository/Storage.java +++ b/gates/src/main/java/ru/mlokoin/gates/repository/Storage.java @@ -23,6 +23,7 @@ import ru.mlokoin.gates.model.fs.xlsx.XlsxCell; import ru.mlokoin.gates.model.fs.xlsx.XlsxDocument; import ru.mlokoin.gates.model.organization.Organization; import ru.mlokoin.gates.model.program.Program; +import ru.mlokoin.gates.model.student.Student; import ru.mlokoin.gates.model.teacher.Teacher; import ru.mlokoin.gates.teh.strings.Stringer; @@ -41,6 +42,7 @@ public class Storage { private String teachersLink = "http://resource-service-api:8181/teacher/list"; private String cretareasLink = "http://resource-service-api:8181/cretarea/list"; private String organizationsLink = "http://resource-service-api:8181/organization/list"; + private String studentsLink = "http://resource-service-api:8181/student/list"; @Autowired private WebClient client; @@ -229,6 +231,19 @@ public class Storage { return list; } + /** + * Получение списка студентов из базы данных + */ + public List getBaseStudents() { + System.out.println("Получение списка студентов из базы данных ..."); + List list = client.method(HttpMethod.GET) + .uri(studentsLink) + .retrieve() + .bodyToMono(new ParameterizedTypeReference >(){}) + .block(); + return list; + } + diff --git a/gates/src/main/resources/templates/students-check.html b/gates/src/main/resources/templates/students-check.html new file mode 100644 index 0000000..d437881 --- /dev/null +++ b/gates/src/main/resources/templates/students-check.html @@ -0,0 +1,82 @@ + + + + + check-students + + + + + + +
+

check-students

+
+
+
+

Стоит обратить внимание (errors): + +

+
    +
  • +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Фамилия (last_name)Имя (first_name)Отчество (second_name)Профессия (profession)Категория ИТР/рабочий (category)Структурное подразделение (direction)Организация (organization)СНИЛС (snils)Дата рождения (berth)Гражданство (sitizenship)Пол Муж/Жен (sex)
+ + + + + + + + + + + + + + + + + + + +
+ +
+
+ + \ No newline at end of file diff --git a/gates/src/main/resources/templates/view-as-educations.html b/gates/src/main/resources/templates/view-as-educations.html index 8d95802..a043678 100644 --- a/gates/src/main/resources/templates/view-as-educations.html +++ b/gates/src/main/resources/templates/view-as-educations.html @@ -53,7 +53,7 @@ xmlns:th="http://www.thymeleaf.org">
-
+