esoe 3 months ago
parent
commit
c024a0a789
  1. 105
      gates/src/main/java/ru/mlokoin/gates/controller/v1/CourseController.java
  2. 4
      gates/src/main/java/ru/mlokoin/gates/controller/v1/OrganizationController.java
  3. 158
      gates/src/main/java/ru/mlokoin/gates/controller/v1/StudentController.java
  4. 5
      gates/src/main/java/ru/mlokoin/gates/model/education/EducationEntryWraper.java
  5. 36
      gates/src/main/java/ru/mlokoin/gates/model/student/Student.java
  6. 38
      gates/src/main/java/ru/mlokoin/gates/model/student/StudentWraper.java
  7. 15
      gates/src/main/java/ru/mlokoin/gates/repository/Storage.java
  8. 82
      gates/src/main/resources/templates/students-check.html
  9. 2
      gates/src/main/resources/templates/view-as-educations.html

105
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.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; 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.http.MediaType;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@ -102,56 +97,72 @@ public class CourseController {
//Получение перечня курсов из базы //Получение перечня курсов из базы
System.out.println("Получение списка курсов из базы ..."); System.out.println("Получение списка курсов из базы ...");
List<Course> base_courses = storage.getBaseCourse(); List<Course> base_courses = storage.getBaseCourse();
System.out.println("Количество курсов в базе: " + base_courses.size());
/***************************************************************************************** */
/*****************************************************************************************
//Удаляем повторяющиеся курсы *
// List<Course> set = new ArrayList<>(xlsx_courses); * Удаление повторяющихся курсов
// Set<Course> set = new HashSet<>(xlsx_courses); * - удаляем повторяющиеся курсы в xlsx-файле
// List<Course> courses = new ArrayList<>(set); * - удаляем курсы, присутствующие в базе
System.out.println("Удаляем повторяющиеся курсы ..."); * *
System.out.println("Количество курсов в xlsx_courses (list): " + xlsx_courses.size()); ******************************************************************************************/
for (Course courseA : new ArrayList<>(xlsx_courses)) { System.out.println("Удаляем повторяющиеся в xlsx-файле курсы ...");
Boolean isExists = false; System.out.println("Количество курсов в xlsx_courses: " + xlsx_courses.size());
for (Course courseB : new ArrayList<>(xlsx_courses)) { List<Course> filtered = new ArrayList<Course>();
if (Course.isSimilar(courseA, courseB) && !isExists) { for (Course course : xlsx_courses) {
isExists = true; if (course != null) {
} else { if (course.getStart_date() != null && course.getBuilding() != null && course.getTeacher() != null) {
if (Course.isSimilar(courseA, courseB) && isExists) { if (!filtered.contains(course)) {
xlsx_courses.remove(courseA); 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("Количество уникальных курсов filtered: " + filtered.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("Количество курсов для добавления в базу (xlsx_courses): " + xlsx_courses.size()); if (filtered.size() > 0) {
}
if (xlsx_courses.size() > 0) {
//Ограничиваем количество курсов, подлежащих передаче в wraper //Ограничиваем количество курсов, подлежащих передаче в wraper
System.out.println("Общее количество курсов для добавления в базу: " + xlsx_courses.size()); // System.out.println("Общее количество курсов для добавления в базу: " + filtered.size());
if (xlsx_courses.size() > 10) { if (filtered.size() > 200) {
xlsx_courses = xlsx_courses.subList(0, 10); filtered = filtered.subList(0, 200);
} }
//Создаем wraper для передачи в шаблон //Создаем wraper для передачи в шаблон
CourseWraper wraper = new CourseWraper(xlsx_courses); CourseWraper wraper = new CourseWraper(filtered);
wraper.addPrograms(programs); wraper.addPrograms(programs);
wraper.addBuildings(buildings); wraper.addBuildings(buildings);
wraper.addTeachers(teachers); wraper.addTeachers(teachers);
@ -165,7 +176,7 @@ public class CourseController {
} }
/** /**
* Добавление новых программ обучения в базу * Добавление новых курсов в базу
* @param wraper * @param wraper
* @param id * @param id
* @return * @return

4
gates/src/main/java/ru/mlokoin/gates/controller/v1/OrganizationController.java

@ -8,8 +8,6 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; 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.http.MediaType;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; 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 org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono; 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.XlsxCell;
import ru.mlokoin.gates.model.fs.xlsx.XlsxDocument; import ru.mlokoin.gates.model.fs.xlsx.XlsxDocument;
import ru.mlokoin.gates.model.organization.Organization; import ru.mlokoin.gates.model.organization.Organization;

158
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<String> errors = new ArrayList<>();//список ошибок
//Получение списка организаций, для передачи в врапер
List<Organization> 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<Student> xlsx_students = new ArrayList<>();
Map<Integer, List<XlsxCell>> map = xlsx.getData();
for (Map.Entry<Integer, List<XlsxCell>> entry : map.entrySet()) {
xlsx_students.add(new Student(entry, base_organizations));
}
System.out.println("Всего студентов в xlsx: " + xlsx_students.size());
//получение перечня студентов из базы
List<Student> base_students = storage.getBaseStudents();
System.out.println("Всего студентов в базе: " + base_students.size());
/**
* Удаляем повторяющихся студентов из списка
* Исключаем из списка студентов, данные о которых уже присутствуют в базе
*/
List<Student> 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<String> errors = new ArrayList<>();
System.out.println("Отправляем запросы на добавление новых студентов в базу ...");
List<Student> 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;
}
}

5
gates/src/main/java/ru/mlokoin/gates/model/education/EducationEntryWraper.java

@ -0,0 +1,5 @@
package ru.mlokoin.gates.model.education;
public class EducationEntryWraper {
}

36
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.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import ru.mlokoin.gates.model.fs.xlsx.XlsxCell;
import ru.mlokoin.gates.model.organization.Organization; import ru.mlokoin.gates.model.organization.Organization;
import ru.mlokoin.gates.teh.strings.Naimer;
import ru.mlokoin.gates.teh.strings.Stringer;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@ -53,4 +58,35 @@ public class Student implements Serializable{
this.sex = sex; this.sex = sex;
this.organization = organization; this.organization = organization;
} }
public Student(Map.Entry<Integer, List<XlsxCell>> entry, List<Organization> base_organizations) {
if (entry.getKey() != 0) {
List<XlsxCell> 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);
}
}
} }

38
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<Student> students;
List<Organization> organizations;
public StudentWraper(){
init();
}
public StudentWraper(List<Student> 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();
}
}

15
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.fs.xlsx.XlsxDocument;
import ru.mlokoin.gates.model.organization.Organization; import ru.mlokoin.gates.model.organization.Organization;
import ru.mlokoin.gates.model.program.Program; 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.model.teacher.Teacher;
import ru.mlokoin.gates.teh.strings.Stringer; 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 teachersLink = "http://resource-service-api:8181/teacher/list";
private String cretareasLink = "http://resource-service-api:8181/cretarea/list"; private String cretareasLink = "http://resource-service-api:8181/cretarea/list";
private String organizationsLink = "http://resource-service-api:8181/organization/list"; private String organizationsLink = "http://resource-service-api:8181/organization/list";
private String studentsLink = "http://resource-service-api:8181/student/list";
@Autowired @Autowired
private WebClient client; private WebClient client;
@ -229,6 +231,19 @@ public class Storage {
return list; return list;
} }
/**
* Получение списка студентов из базы данных
*/
public List<Student> getBaseStudents() {
System.out.println("Получение списка студентов из базы данных ...");
List<Student> list = client.method(HttpMethod.GET)
.uri(studentsLink)
.retrieve()
.bodyToMono(new ParameterizedTypeReference <List<Student>>(){})
.block();
return list;
}

82
gates/src/main/resources/templates/students-check.html

@ -0,0 +1,82 @@
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>check-students</title>
<!-- Скрипт обработки thymeleaf компонентов -->
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script>
<!-- скрипт просмотра *.MD документов -->
<!-- <script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script> -->
</head>
<body>
<header>
<h2>check-students</h2>
</header>
<main>
<div>
<h2>Стоит обратить внимание (errors):
<span th:text="${#lists.size(errors)}"></span>
</h2>
<ul th:each="e: ${errors}">
<li th:text="${e}"></li>
</ul>
</div>
<form th:action="@{/students/save/{id}(id=${id})}"
th:method="post"
th:object="${studentWraper}">
<input type="submit" value="POST-ALL"/>
<table rules="all">
<thead>
<th><span>Фамилия (last_name)</span></th>
<th><span>Имя (first_name)</span></th>
<th><span>Отчество (second_name)</span></th>
<th><span>Профессия (profession)</span></th>
<th><span>Категория ИТР/рабочий (category)</span></th>
<th><span>Структурное подразделение (direction)</span></th>
<th><span>Организация (organization)</span></th>
<th><span>СНИЛС (snils)</span></th>
<th><span>Дата рождения (berth)</span></th>
<th><span>Гражданство (sitizenship)</span></th>
<th><span>Пол Муж/Жен (sex)</span></th>
</thead>
<tbody>
<tr th:each="student, studentStat : *{students}" >
<td>
<input type="text" th:field="*{students[__${studentStat.index}__].second_name}">
</td>
<td>
<input type="text" th:field="*{students[__${studentStat.index}__].first_name}">
</td>
<td>
<input type="text" th:field="*{students[__${studentStat.index}__].last_name}">
</td>
<td>
<input type="text" th:field="*{students[__${studentStat.index}__].profession}">
</td>
<td>
<input type="text" th:field="*{students[__${studentStat.index}__].category}">
</td>
<td>
<input type="text" th:field="*{students[__${studentStat.index}__].direction}">
</td>
<td>
<input type="text" th:field="*{students[__${studentStat.index}__].organization.id}">
</td>
<td>
<input type="text" th:field="*{students[__${studentStat.index}__].berth}">
</td>
<td>
<input type="text" th:field="*{students[__${studentStat.index}__].sitizenship}">
</td>
<td>
<input type="text" th:field="*{students[__${studentStat.index}__].sex}">
</td>
</tr>
</tbody>
</table>
<input type="submit" value="POST-ALL"/>
</form>
</main>
</body>
</html>

2
gates/src/main/resources/templates/view-as-educations.html

@ -53,7 +53,7 @@ xmlns:th="http://www.thymeleaf.org">
<form th:action="@{/courses/check/{id}(id=${id})}" th:method="get"> <form th:action="@{/courses/check/{id}(id=${id})}" th:method="get">
<input type="submit" value="CHECK-COURSES"/> <input type="submit" value="CHECK-COURSES"/>
</form> </form>
<form th:action="@{#}" th:method="get"> <form th:action="@{/students/check/{id}(id=${id})}" th:method="get">
<input type="submit" value="CHECK-STUDENTS"/> <input type="submit" value="CHECK-STUDENTS"/>
</form> </form>
<form th:action="@{#}" th:method="get"> <form th:action="@{#}" th:method="get">

Loading…
Cancel
Save