esoe
5 months ago
102 changed files with 3862 additions and 502 deletions
@ -1,3 +1,4 @@ |
|||||||
{ |
{ |
||||||
"java.compile.nullAnalysis.mode": "automatic" |
"java.compile.nullAnalysis.mode": "automatic", |
||||||
|
"java.configuration.updateBuildConfiguration": "interactive" |
||||||
} |
} |
@ -1,16 +1,20 @@ |
|||||||
version: "3.7" |
version: "3.7" |
||||||
services: |
services: |
||||||
client-service-teachers: |
client-service-teachers: |
||||||
|
container_name: client-service-teachers |
||||||
|
hostname: client-service-teachers |
||||||
build: |
build: |
||||||
context: ../client-service-teachers |
context: ../client-service-teachers |
||||||
dockerfile: dockerfile |
dockerfile: dockerfile |
||||||
image: "client-service-teachers" |
image: "client-service-teachers" |
||||||
command: ["java","-jar","/app/client-service-teachers-0.1.jar"] |
command: ["java","-jar","/app/client-service-teachers-0.1.jar"] |
||||||
ports: |
ports: |
||||||
- 80:8181 |
- 84:8181 |
||||||
restart: unless-stopped |
restart: unless-stopped |
||||||
|
networks: |
||||||
|
- tech_network |
||||||
networks: |
networks: |
||||||
default: |
tech_network: |
||||||
external: |
|
||||||
name: tech_network |
name: tech_network |
||||||
|
external: true |
||||||
driver: bridge |
driver: bridge |
@ -0,0 +1,13 @@ |
|||||||
|
package ru.molokoin.clientserviceteachers.controllers; |
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
|
||||||
|
@Controller |
||||||
|
public class Hello { |
||||||
|
@GetMapping("/hello") |
||||||
|
public String hello(){ |
||||||
|
return "hello"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
# client-service-teacher |
@ -1 +0,0 @@ |
|||||||
# teachers.md |
|
@ -0,0 +1,14 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||||
|
<title>gates-hello</title> |
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script> |
||||||
|
<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<zero-md th:src="@{/content/md/hello.md}"></zero-md> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,2 @@ |
|||||||
|
# GATES |
||||||
|
Микросервис, предоставляющий пользовательский интерфейс для добавления документов из хранилища в базу данных |
@ -0,0 +1,20 @@ |
|||||||
|
version: "3.7" |
||||||
|
services: |
||||||
|
gates: |
||||||
|
container_name: "gates" |
||||||
|
hostname: "gates" |
||||||
|
build: |
||||||
|
context: ../gates |
||||||
|
dockerfile: dockerfile |
||||||
|
image: "gates" |
||||||
|
command: ["java","-jar","/app/gates/gates-0.0.1.jar"] |
||||||
|
ports: |
||||||
|
- 83:8383 |
||||||
|
restart: unless-stopped |
||||||
|
networks: |
||||||
|
- tech_network |
||||||
|
networks: |
||||||
|
tech_network: |
||||||
|
name: tech_network |
||||||
|
external: true |
||||||
|
driver: bridge |
@ -0,0 +1,5 @@ |
|||||||
|
FROM openjdk:17-jdk-alpine |
||||||
|
RUN apk update |
||||||
|
RUN apk upgrade |
||||||
|
COPY target/gates-0.0.1.jar /app/gates/gates-0.0.1.jar |
||||||
|
WORKDIR /app/gates |
@ -0,0 +1,70 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<parent> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-parent</artifactId> |
||||||
|
<version>3.3.0</version> |
||||||
|
<relativePath/> <!-- lookup parent from repository --> |
||||||
|
</parent> |
||||||
|
<groupId>ru.mlokoin</groupId> |
||||||
|
<artifactId>gates</artifactId> |
||||||
|
<version>0.0.1</version> |
||||||
|
<name>gates</name> |
||||||
|
<description>Demo project for Spring Boot</description> |
||||||
|
<properties> |
||||||
|
<java.version>17</java.version> |
||||||
|
</properties> |
||||||
|
<dependencies> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-webflux</artifactId> |
||||||
|
</dependency> |
||||||
|
<!-- <dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId> |
||||||
|
</dependency> --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-thymeleaf</artifactId> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-web</artifactId> |
||||||
|
</dependency> |
||||||
|
<!-- <dependency> |
||||||
|
<groupId>org.postgresql</groupId> |
||||||
|
<artifactId>postgresql</artifactId> |
||||||
|
<scope>runtime</scope> |
||||||
|
</dependency> --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<optional>true</optional> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-test</artifactId> |
||||||
|
<scope>test</scope> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
|
||||||
|
<build> |
||||||
|
<plugins> |
||||||
|
<plugin> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId> |
||||||
|
<configuration> |
||||||
|
<excludes> |
||||||
|
<exclude> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
</exclude> |
||||||
|
</excludes> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
</build> |
||||||
|
|
||||||
|
</project> |
@ -0,0 +1,13 @@ |
|||||||
|
package ru.mlokoin.gates; |
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication; |
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||||
|
|
||||||
|
@SpringBootApplication |
||||||
|
public class GatesApplication { |
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
SpringApplication.run(GatesApplication.class, args); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package ru.mlokoin.gates.config; |
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean; |
||||||
|
import org.springframework.context.annotation.Configuration; |
||||||
|
import org.springframework.web.reactive.function.client.ExchangeStrategies; |
||||||
|
import org.springframework.web.reactive.function.client.WebClient; |
||||||
|
|
||||||
|
@Configuration |
||||||
|
public class WebConfig { |
||||||
|
@Bean |
||||||
|
WebClient webClient() { |
||||||
|
final int maxInMemorySize = 50 * 1024 * 1024; // 50MB
|
||||||
|
final ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() |
||||||
|
.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(maxInMemorySize)) |
||||||
|
.build(); |
||||||
|
WebClient webClient = WebClient.builder() |
||||||
|
.exchangeStrategies(exchangeStrategies) |
||||||
|
// .baseUrl("http://resource-service-api:8181")
|
||||||
|
.build(); |
||||||
|
return webClient; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package ru.mlokoin.gates.controller; |
||||||
|
|
||||||
|
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 ru.mlokoin.gates.model.BuildingWraper; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@RequestMapping(path = "/buildings") |
||||||
|
public class BuildingController { |
||||||
|
@Autowired |
||||||
|
private WebClient client; |
||||||
|
|
||||||
|
@GetMapping("/check/{id}") |
||||||
|
public String checkBuildings(Model model, @PathVariable String id){ |
||||||
|
return "buildings-check"; |
||||||
|
// return "redirect:/document/view-as-educations/" + id;
|
||||||
|
} |
||||||
|
|
||||||
|
@PostMapping( |
||||||
|
path="/save/{id}", |
||||||
|
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE, |
||||||
|
produces = { |
||||||
|
MediaType.APPLICATION_JSON_VALUE |
||||||
|
}) |
||||||
|
public String saveBuildings(@ModelAttribute("wrapBuildngs") BuildingWraper wraper, @PathVariable String id){ |
||||||
|
return "redirect:/buildings/check/" + id; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,170 @@ |
|||||||
|
package ru.mlokoin.gates.controller; |
||||||
|
|
||||||
|
import java.time.Duration; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.List; |
||||||
|
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; |
||||||
|
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.ProgramCretarea; |
||||||
|
import ru.mlokoin.gates.model.ProgramCretareaWraper; |
||||||
|
import ru.mlokoin.gates.model.XlsxCell; |
||||||
|
import ru.mlokoin.gates.model.XlsxDocument; |
||||||
|
|
||||||
|
/** |
||||||
|
* Контроллер, для работы с критериями |
||||||
|
* - проверка соответствия критериев xlsx и базы данных |
||||||
|
* - получение списка критериев, отсутствующих в базе |
||||||
|
* - публикация новых критериев в базе |
||||||
|
* |
||||||
|
* Добавить возможности: |
||||||
|
* - просмотра и редактирования критериев в базе |
||||||
|
* - просмотра полного списка критериев в файле |
||||||
|
* - настройка алиасов притериев |
||||||
|
*/ |
||||||
|
@Controller |
||||||
|
@RequestMapping(path = "/program-cretareas") |
||||||
|
public class CretareaController { |
||||||
|
@Autowired |
||||||
|
private WebClient client; |
||||||
|
|
||||||
|
/** |
||||||
|
* Проверка критериев xlsx-файла: |
||||||
|
* - получание списка уникальных критериев из файла |
||||||
|
* - получение списка внесенных в базу критериев |
||||||
|
* - вывод пользователю критериев, не найденых в базе |
||||||
|
* - редактирование пользователем не найденых критериев |
||||||
|
* - отправка в базу новых критериев |
||||||
|
* |
||||||
|
* @param model |
||||||
|
* @param id |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@GetMapping("/check/{id}") |
||||||
|
public String checkCretareas(Model model, @PathVariable String id) { |
||||||
|
System.out.println("Проверка критериев, для внесения в базу ..."); |
||||||
|
System.out.println("Получение перечня критериев из xlsx-файла ..."); |
||||||
|
XlsxDocument xlsx = client.method(HttpMethod.GET) |
||||||
|
.uri("http://storage-rs:8282/api/document/content/" |
||||||
|
+ id + ".xlsx") |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <XlsxDocument>(){}) |
||||||
|
.block(); |
||||||
|
//список критериев из файла
|
||||||
|
ArrayList<ProgramCretarea> xlsx_cretareas = new ArrayList<>();//13 столбец
|
||||||
|
Map<Integer, List<XlsxCell>> map = xlsx.getData(); |
||||||
|
for (Map.Entry<Integer, List<XlsxCell>> entry : map.entrySet()) { |
||||||
|
ProgramCretarea pc = new ProgramCretarea(); |
||||||
|
pc.setName_short(entry |
||||||
|
.getValue() |
||||||
|
.get(12) |
||||||
|
.getContent()); |
||||||
|
xlsx_cretareas.add(pc); |
||||||
|
} |
||||||
|
xlsx_cretareas.remove(0);//Удалили из списка заголовок "Критериий"
|
||||||
|
Set<ProgramCretarea> xlsx_cretareaSet = Set.copyOf(xlsx_cretareas); |
||||||
|
|
||||||
|
//список уникальных сокращенных наименований из файла
|
||||||
|
System.out.println("Список уникальных сокращенных наименований критериев из файла:"); |
||||||
|
Set<String> xlsx_ccs = new HashSet<>(); |
||||||
|
for (ProgramCretarea pc : xlsx_cretareaSet) { |
||||||
|
System.out.println(pc.getName_short()); |
||||||
|
xlsx_ccs.add(pc.getName_short()); |
||||||
|
} |
||||||
|
|
||||||
|
//Получение перечня критериев из базы
|
||||||
|
System.out.println("Получение списка критериев из базы ..."); |
||||||
|
List<ProgramCretarea> base_cretareas = client.method(HttpMethod.GET) |
||||||
|
.uri("http://resource-service-api:8181/cretarea/list") |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <List<ProgramCretarea>>(){}) |
||||||
|
.block(); |
||||||
|
Set<ProgramCretarea> base_cretareaSet = Set.copyOf(base_cretareas); |
||||||
|
|
||||||
|
//Список сокращенных наименований критериев из базы
|
||||||
|
System.out.println("Список уникальных сокращенных наименований критериев из базы:"); |
||||||
|
Set<String> base_ccs = new HashSet<>(); |
||||||
|
for (ProgramCretarea pc : base_cretareaSet) { |
||||||
|
System.out.println(pc.getName_short()); |
||||||
|
base_ccs.add(pc.getName_short()); |
||||||
|
} |
||||||
|
|
||||||
|
//Удаление критериев присутствующих в базе
|
||||||
|
xlsx_ccs.removeAll(base_ccs); |
||||||
|
/** |
||||||
|
* Если какието критерии файла отсутствуют в базе, вернуть страницу проверки критериев |
||||||
|
*/ |
||||||
|
if (xlsx_ccs.size() != 0) { |
||||||
|
//Подготовка списка, для передачи в представление
|
||||||
|
ArrayList<ProgramCretarea> list = new ArrayList<>(); |
||||||
|
for (String string : xlsx_ccs) { |
||||||
|
ProgramCretarea pc = new ProgramCretarea(); |
||||||
|
pc.setName_short(string); |
||||||
|
list.add(pc); |
||||||
|
} |
||||||
|
|
||||||
|
ProgramCretareaWraper pcwraper = new ProgramCretareaWraper(list); |
||||||
|
|
||||||
|
model.addAttribute("wrapCretareas", pcwraper); |
||||||
|
// model.addAttribute("cretareas", list);
|
||||||
|
model.addAttribute("id", id); |
||||||
|
|
||||||
|
return "cretareas-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 saveCretareas(@ModelAttribute("wrapCretareas") ProgramCretareaWraper wraper, @PathVariable String id){ |
||||||
|
/** |
||||||
|
* Отправляем запросы на добавление новых критериев в базу |
||||||
|
*/ |
||||||
|
System.out.println("Критерии для добавления в базу: " |
||||||
|
+ wraper.getList().toString()); |
||||||
|
|
||||||
|
for (ProgramCretarea cretarea : wraper.getList()) { |
||||||
|
//Проверка наличия полного наименования критерия
|
||||||
|
if (!cretarea.getName().equals("")) { |
||||||
|
client.post() |
||||||
|
.uri("http://resource-service-api:8181/cretarea/create") |
||||||
|
.body(Mono.just(cretarea), ProgramCretarea.class) |
||||||
|
.retrieve() |
||||||
|
.toBodilessEntity() |
||||||
|
.timeout(Duration.ofSeconds(1)) |
||||||
|
.block(); |
||||||
|
} |
||||||
|
} |
||||||
|
/** |
||||||
|
* Возвращаем пользователя на страницу перечня новых критериев |
||||||
|
* - если он не пустой |
||||||
|
*/ |
||||||
|
return "redirect:/cretareas/check/" + id; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
package ru.mlokoin.gates.controller; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.core.ParameterizedTypeReference; |
||||||
|
import org.springframework.http.HttpMethod; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.ui.Model; |
||||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||||
|
import org.springframework.web.bind.annotation.PathVariable; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.reactive.function.client.WebClient; |
||||||
|
|
||||||
|
import ru.mlokoin.gates.model.XlsxDocument; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@RequestMapping(path = "/") |
||||||
|
public class EducationsController { |
||||||
|
@Autowired |
||||||
|
private WebClient client; |
||||||
|
|
||||||
|
/** |
||||||
|
* Предоставление пользователю формы "view-as-educations" |
||||||
|
* - просмотр xlsx-файла |
||||||
|
* - проверки соответствия форме "Реестра обученных" |
||||||
|
* - кнопки запуска механизмов проверок полей формы (критерии, программы, итд ...) |
||||||
|
* @param model |
||||||
|
* @param id |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@GetMapping("/document/view-as-educations/{id}") |
||||||
|
public String viewAsEducations(Model model, @PathVariable String id) { |
||||||
|
System.out.println("Просмотр содержимого файла ..."); |
||||||
|
XlsxDocument xlsx = client.method(HttpMethod.GET) |
||||||
|
.uri("http://storage-rs:8282/api/document/content/" |
||||||
|
+ id + ".xlsx") |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <XlsxDocument>(){}) |
||||||
|
.block(); |
||||||
|
|
||||||
|
model.addAttribute("filename", xlsx.getDocument().getName()); |
||||||
|
model.addAttribute("id", id); |
||||||
|
model.addAttribute("xlsx", xlsx.getData()); |
||||||
|
model.addAttribute("headers", xlsx.getHeaders()); |
||||||
|
return "view-as-educations"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,279 @@ |
|||||||
|
package ru.mlokoin.gates.controller; |
||||||
|
|
||||||
|
import java.net.URI; |
||||||
|
import java.net.URISyntaxException; |
||||||
|
import java.time.Duration; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Optional; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.core.ParameterizedTypeReference; |
||||||
|
import org.springframework.http.HttpMethod; |
||||||
|
import org.springframework.http.client.MultipartBodyBuilder; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.ui.Model; |
||||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||||
|
import org.springframework.web.bind.annotation.PathVariable; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.reactive.function.BodyInserters; |
||||||
|
import org.springframework.web.reactive.function.client.WebClient; |
||||||
|
|
||||||
|
import reactor.core.publisher.Mono; |
||||||
|
import ru.mlokoin.gates.model.Document; |
||||||
|
import ru.mlokoin.gates.model.XlsxDocument; |
||||||
|
import ru.mlokoin.gates.util.CustomMultipartFile; |
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
import org.springframework.web.bind.annotation.PostMapping; |
||||||
|
|
||||||
|
/** |
||||||
|
* Контроллер предоставления графического интерфейса |
||||||
|
*/ |
||||||
|
@Controller |
||||||
|
@RequestMapping(path = "/") |
||||||
|
public class GatesController { |
||||||
|
@Autowired |
||||||
|
private WebClient client; |
||||||
|
|
||||||
|
/** |
||||||
|
* Получение списка файлов с сервера и доступа к инструментам извлечения данных |
||||||
|
* - template : storage.html |
||||||
|
* @param model |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@GetMapping("/storage") |
||||||
|
public String getStorage(Model model){ |
||||||
|
List<Document> docs = client.method(HttpMethod.GET) |
||||||
|
.uri("http://storage-rs:8282/api/list-uploads") |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <List<Document>>(){}) |
||||||
|
.block(); |
||||||
|
model.addAttribute("documents", docs); |
||||||
|
return "storage"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Отправка файла в хранилище и сведений о нем в базу |
||||||
|
* Возвращение ползователю обновленной страницы списка файлов |
||||||
|
* - добавление метаданных файла в базу |
||||||
|
* - получение id файла |
||||||
|
* - отправка файла с новым именем в хранилище |
||||||
|
* |
||||||
|
* @param file |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@PostMapping("/storage/upload") |
||||||
|
public String postMethodName(@RequestParam("file") MultipartFile file) { |
||||||
|
|
||||||
|
Document doc = new Document(); |
||||||
|
doc.setName(file.getOriginalFilename()); |
||||||
|
doc.setSize(file.getSize()); |
||||||
|
/** |
||||||
|
* Hfcibhtybt |
||||||
|
*/ |
||||||
|
Optional<String> ext = Optional.ofNullable(file.getOriginalFilename()) |
||||||
|
.filter(f -> f.contains(".")) |
||||||
|
.map(f -> f.substring(file.getOriginalFilename().lastIndexOf(".") + 1)); |
||||||
|
doc.setExtension(ext.get()); |
||||||
|
doc.setExtension( ext.get()); |
||||||
|
// doc.setPath();
|
||||||
|
|
||||||
|
doc = client.post() |
||||||
|
.uri("http://resource-service-api:8181/storage-entry/create") |
||||||
|
.body(Mono.just(doc), Document.class) |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <Document>(){}) |
||||||
|
.timeout(Duration.ofSeconds(1)) |
||||||
|
.block(); |
||||||
|
|
||||||
|
MultipartBodyBuilder builder = new MultipartBodyBuilder(); |
||||||
|
Boolean ok; |
||||||
|
MultipartFile out = new CustomMultipartFile(file, doc.getId()+"." + doc.getExtension()); |
||||||
|
builder.part("file", out.getResource()); |
||||||
|
|
||||||
|
ok = client.method(HttpMethod.POST) |
||||||
|
.uri("http://storage-rs:8282/api/document/store") |
||||||
|
.body(BodyInserters |
||||||
|
.fromMultipartData(builder.build())) |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <Boolean>(){}) |
||||||
|
.block(); |
||||||
|
|
||||||
|
System.out.println("Файл добавлен в хранилище: " + ok); |
||||||
|
System.out.println("ID: " + doc.getId()); |
||||||
|
System.out.println(doc.toString()); |
||||||
|
return "redirect:/storage"; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Удаление файла из хранилища |
||||||
|
* и возврат пользователю страницы работы с файлами |
||||||
|
* !!! Добавить удаление записи из базы |
||||||
|
* !!! Обернуть в транзакцию |
||||||
|
* |
||||||
|
* @param name |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@GetMapping("/storage/delete/{name}") |
||||||
|
public String deleteFromStorage(@PathVariable String name) { |
||||||
|
String filename = name; |
||||||
|
String prefix = "http://storage-rs:8282/api/document/"; |
||||||
|
String postfix = "/delete"; |
||||||
|
URI uri; |
||||||
|
|
||||||
|
try { |
||||||
|
uri = new URI(prefix + filename + postfix); |
||||||
|
client.method(HttpMethod.DELETE) |
||||||
|
.uri(uri) |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <>(){}) |
||||||
|
.block(); |
||||||
|
} catch (URISyntaxException e) { |
||||||
|
System.out.println("Не верный URI: " + e.getMessage()); |
||||||
|
} |
||||||
|
return "redirect:/storage"; |
||||||
|
} |
||||||
|
|
||||||
|
@GetMapping("/document/list") |
||||||
|
public String getMethodName(Model model) { |
||||||
|
List<Document> docs = client.method(HttpMethod.GET) |
||||||
|
.uri("http://resource-service-api:8181/storage-entry/list") |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <List<Document>>(){}) |
||||||
|
.block(); |
||||||
|
model.addAttribute("documents", docs); |
||||||
|
return "documents"; |
||||||
|
} |
||||||
|
|
||||||
|
@GetMapping("/document/delete/{id}") |
||||||
|
public String deleteFromDatabase(@PathVariable String id) { |
||||||
|
System.out.println("gates# получение сведений о файле ... " + id); |
||||||
|
/** |
||||||
|
* Получеие сведений о файле из базы |
||||||
|
*/ |
||||||
|
Document doc = client.method(HttpMethod.GET) |
||||||
|
.uri("http://resource-service-api:8181/storage-entry/" + id) |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <Document>(){}) |
||||||
|
.block(); |
||||||
|
|
||||||
|
System.out.println("Документ для удаления: " + doc.toString()); |
||||||
|
System.out.println("Удаление из хранилища ..."); |
||||||
|
|
||||||
|
/** |
||||||
|
* Удаление файла из хранилища |
||||||
|
*/ |
||||||
|
client.delete() |
||||||
|
.uri("http://storage-rs:8282/api/document/delete/" |
||||||
|
+ id |
||||||
|
+ "." |
||||||
|
+ doc.getExtension()) |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(String.class) |
||||||
|
.timeout(Duration.ofSeconds(1)) |
||||||
|
.block(); |
||||||
|
|
||||||
|
|
||||||
|
System.out.println("Удаление из базы ..."); |
||||||
|
/** |
||||||
|
* Удаление записи о файле из базы |
||||||
|
*/ |
||||||
|
client.delete() |
||||||
|
.uri("http://resource-service-api:8181/storage-entry/delete/" + id) |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(String.class) |
||||||
|
.timeout(Duration.ofSeconds(1)) |
||||||
|
.block(); |
||||||
|
|
||||||
|
System.out.println("Файл успешно удален!"); |
||||||
|
|
||||||
|
return "redirect:/document/list"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Загрузка файла на сервер, |
||||||
|
* - создание записи с метаданными файла в resource-service |
||||||
|
* - передача его сервису storage-rs |
||||||
|
* @param file |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@PostMapping("/document/upload") |
||||||
|
public String upload(@RequestParam("file") MultipartFile file) { |
||||||
|
|
||||||
|
Document doc = new Document(); |
||||||
|
doc.setName(file.getOriginalFilename()); |
||||||
|
doc.setSize(file.getSize()); |
||||||
|
/** |
||||||
|
* Hfcibhtybt |
||||||
|
*/ |
||||||
|
Optional<String> ext = Optional.ofNullable(file.getOriginalFilename()) |
||||||
|
.filter(f -> f.contains(".")) |
||||||
|
.map(f -> f.substring(file.getOriginalFilename().lastIndexOf(".") + 1)); |
||||||
|
doc.setExtension(ext.get()); |
||||||
|
doc.setExtension( ext.get()); |
||||||
|
// doc.setPath();
|
||||||
|
|
||||||
|
/** |
||||||
|
* Добавление записи о файле в базу данных |
||||||
|
*/ |
||||||
|
doc = client.post() |
||||||
|
.uri("http://resource-service-api:8181/storage-entry/create") |
||||||
|
.body(Mono.just(doc), Document.class) |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <Document>(){}) |
||||||
|
.timeout(Duration.ofSeconds(1)) |
||||||
|
.block(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Добавление файла в файловое хранилище |
||||||
|
*/ |
||||||
|
MultipartBodyBuilder builder = new MultipartBodyBuilder(); |
||||||
|
Boolean ok; |
||||||
|
MultipartFile out = new CustomMultipartFile(file, doc.getId()+"." + doc.getExtension()); |
||||||
|
builder.part("file", out.getResource()); |
||||||
|
|
||||||
|
ok = client.method(HttpMethod.POST) |
||||||
|
.uri("http://storage-rs:8282/api/document/store") |
||||||
|
.body(BodyInserters |
||||||
|
.fromMultipartData(builder.build())) |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <Boolean>(){}) |
||||||
|
.block(); |
||||||
|
|
||||||
|
System.out.println("Файл добавлен в хранилище: " + ok); |
||||||
|
System.out.println("ID: " + doc.getId()); |
||||||
|
System.out.println(doc.toString()); |
||||||
|
return "redirect:/document/list"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Просмотр содержимого файла: |
||||||
|
* - предусмотреть возможность фильтрации |
||||||
|
*/ |
||||||
|
@GetMapping("/document/view-xlsx/{id}") |
||||||
|
public String view(Model model, @PathVariable String id) { |
||||||
|
System.out.println("Просмотр содержимого файла ..."); |
||||||
|
XlsxDocument xlsx = client.method(HttpMethod.GET) |
||||||
|
.uri("http://storage-rs:8282/api/document/content/" |
||||||
|
+ id + ".xlsx") |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <XlsxDocument>(){}) |
||||||
|
.block(); |
||||||
|
|
||||||
|
model.addAttribute("filename", xlsx.getDocument().getName()); |
||||||
|
model.addAttribute("id", id); |
||||||
|
model.addAttribute("xlsx", xlsx.getData()); |
||||||
|
model.addAttribute("headers", xlsx.getHeaders()); |
||||||
|
return "view-xlsx"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Публикация "Реестра обученных" |
||||||
|
* - просмотр |
||||||
|
* - фильтры |
||||||
|
* - запись в базу типа документа |
||||||
|
* - настройка всех промежуточных состояний импорта |
||||||
|
*/ |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
package ru.mlokoin.gates.controller; |
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||||
|
|
||||||
|
@Controller |
||||||
|
public class Hello { |
||||||
|
@GetMapping("/hello") |
||||||
|
public String hello(){ |
||||||
|
return "hello"; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,173 @@ |
|||||||
|
package ru.mlokoin.gates.controller; |
||||||
|
|
||||||
|
import java.time.Duration; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.List; |
||||||
|
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; |
||||||
|
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.Program; |
||||||
|
import ru.mlokoin.gates.model.ProgramCretarea; |
||||||
|
import ru.mlokoin.gates.model.ProgramWraper; |
||||||
|
import ru.mlokoin.gates.model.XlsxCell; |
||||||
|
import ru.mlokoin.gates.model.XlsxDocument; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@RequestMapping(path = "/programs") |
||||||
|
public class ProgramController { |
||||||
|
@Autowired |
||||||
|
private WebClient client; |
||||||
|
|
||||||
|
/** |
||||||
|
* Проверка соответствия программ обучения из файла - содержащимся в базе |
||||||
|
* @param model |
||||||
|
* @param id |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@GetMapping("/check/{id}") |
||||||
|
public String checkPrograms(Model model, @PathVariable String id) { |
||||||
|
System.out.println("Проверка программ обучения, для внесения в базу ..."); |
||||||
|
System.out.println("Получение перечня программ из xlsx-файла ..."); |
||||||
|
//получение данных файла в переменную xlsx
|
||||||
|
XlsxDocument xlsx = client.method(HttpMethod.GET) |
||||||
|
.uri("http://storage-rs:8282/api/document/content/" |
||||||
|
+ id + ".xlsx") |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <XlsxDocument>(){}) |
||||||
|
.block(); |
||||||
|
//список программ из файла
|
||||||
|
ArrayList<Program> xlsx_programs = new ArrayList<>();//7 столбец
|
||||||
|
Map<Integer, List<XlsxCell>> map = xlsx.getData(); |
||||||
|
for (Map.Entry<Integer, List<XlsxCell>> entry : map.entrySet()) { |
||||||
|
Program programm = new Program(); |
||||||
|
programm.setName(entry |
||||||
|
.getValue() |
||||||
|
.get(6) |
||||||
|
.getContent()); |
||||||
|
xlsx_programs.add(programm); |
||||||
|
} |
||||||
|
xlsx_programs.remove(0);//Удалили из списка заголовок
|
||||||
|
Set<Program> xlsx_programSet = Set.copyOf(xlsx_programs); |
||||||
|
|
||||||
|
//список уникальных наименований из файла
|
||||||
|
System.out.println("Список уникальных сокращенных наименований критериев из файла:"); |
||||||
|
Set<String> xlsx_stringSet = new HashSet<>(); |
||||||
|
for (Program pc : xlsx_programSet) { |
||||||
|
System.out.println(pc.getName()); |
||||||
|
xlsx_stringSet.add(pc.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
//Получение перечня программ из базы
|
||||||
|
System.out.println("Получение списка программ из базы ..."); |
||||||
|
List<Program> base_programs = client.method(HttpMethod.GET) |
||||||
|
.uri("http://resource-service-api:8181/program/list") |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <List<Program>>(){}) |
||||||
|
.block(); |
||||||
|
Set<Program> base_programSet = Set.copyOf(base_programs); |
||||||
|
|
||||||
|
//Список наименований программ из базы
|
||||||
|
System.out.println("Список уникальных наименований программ из базы:"); |
||||||
|
Set<String> base_stringSet = new HashSet<>(); |
||||||
|
for (Program pc : base_programSet) { |
||||||
|
System.out.println(pc.getName()); |
||||||
|
base_stringSet.add(pc.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
//Удаление программ присутствующих в базе
|
||||||
|
xlsx_stringSet.removeAll(base_stringSet); |
||||||
|
|
||||||
|
if (xlsx_stringSet.size() != 0) { |
||||||
|
//Подготовка списка, для передачи в представление
|
||||||
|
ArrayList<Program> list = new ArrayList<>(); |
||||||
|
for (String string : xlsx_stringSet) { |
||||||
|
Program pc = new Program(); |
||||||
|
pc.setName(string); |
||||||
|
list.add(pc); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Подготавлеваем обертку формы |
||||||
|
*/ |
||||||
|
// передаем список новых программ
|
||||||
|
ProgramWraper pwraper = new ProgramWraper(list); |
||||||
|
|
||||||
|
//подготавливаем список критериев
|
||||||
|
List<ProgramCretarea> base_cretareas = client.method(HttpMethod.GET) |
||||||
|
.uri("http://resource-service-api:8181/cretarea/list") |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <List<ProgramCretarea>>(){}) |
||||||
|
.block(); |
||||||
|
//передаем список критериев в обертку формы, для селекта
|
||||||
|
pwraper.setCretareas(base_cretareas); |
||||||
|
|
||||||
|
//передаем обертку в модель
|
||||||
|
model.addAttribute("wrapPrograms", pwraper); |
||||||
|
model.addAttribute("id", id); |
||||||
|
|
||||||
|
return "programs-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 savePrograms(@ModelAttribute("wrapPrograms") ProgramWraper wraper, @PathVariable String id){ |
||||||
|
/** |
||||||
|
* Отправляем запросы на добавление новых программ в базу |
||||||
|
*/ |
||||||
|
System.out.println("Программы для добавления в базу: " |
||||||
|
+ wraper.getPrograms().toString()); |
||||||
|
for (Program program : wraper.getPrograms()) { |
||||||
|
//Проверка наличия полного наименования имени программы
|
||||||
|
if (!program.getName().equals("")) { |
||||||
|
//проверка наличия длительности программы
|
||||||
|
if (program.getLenght() != null) { |
||||||
|
//проверка наличия направления обучения
|
||||||
|
if (!program.getStudy_direction().equals("")){ |
||||||
|
//проверка наличия критерия
|
||||||
|
if (program.getCretarea() != null){ |
||||||
|
client.post() |
||||||
|
.uri("http://resource-service-api:8181/program/create") |
||||||
|
.body(Mono.just(program), Program.class) |
||||||
|
.retrieve() |
||||||
|
.toBodilessEntity() |
||||||
|
.timeout(Duration.ofSeconds(1)) |
||||||
|
.block(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
/** |
||||||
|
* Возвращаем пользователя на страницу перечня новых критериев |
||||||
|
* - если он не пустой |
||||||
|
*/ |
||||||
|
return "redirect:/programs/check/" + id; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,268 @@ |
|||||||
|
package ru.mlokoin.gates.controller; |
||||||
|
|
||||||
|
import java.time.Duration; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
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; |
||||||
|
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.ProgramCretarea; |
||||||
|
import ru.mlokoin.gates.model.ProgramCretareaWraper; |
||||||
|
import ru.mlokoin.gates.model.Teacher; |
||||||
|
import ru.mlokoin.gates.model.TeacherWraper; |
||||||
|
import ru.mlokoin.gates.model.XlsxCell; |
||||||
|
import ru.mlokoin.gates.model.XlsxDocument; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@RequestMapping(path = "/teachers") |
||||||
|
public class TeacherController { |
||||||
|
@Autowired |
||||||
|
private WebClient client; |
||||||
|
|
||||||
|
@GetMapping("/check/{id}") |
||||||
|
public String checkTeachers(Model model, @PathVariable String id) { |
||||||
|
List<String> errors = new ArrayList<>();//список ошибок
|
||||||
|
System.out.println("Проверка преподавателей, для внесения в базу ..."); |
||||||
|
System.out.println("Получение перечня преподавателей из xlsx-файла ..."); |
||||||
|
XlsxDocument xlsx = client.method(HttpMethod.GET) |
||||||
|
.uri("http://storage-rs:8282/api/document/content/" |
||||||
|
+ id + ".xlsx") |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <XlsxDocument>(){}) |
||||||
|
.block(); |
||||||
|
//список преподавателей из файла
|
||||||
|
// ArrayList<Teacher> xlsx_teachers = new ArrayList<>();//18 столбец
|
||||||
|
Map<Integer, List<XlsxCell>> map = xlsx.getData(); |
||||||
|
|
||||||
|
/** |
||||||
|
* удалили строку заголовков |
||||||
|
*/ |
||||||
|
map.remove(0); |
||||||
|
System.out.println("Количество записей: " + map.size()); |
||||||
|
|
||||||
|
/** |
||||||
|
* что делать с пустыми строками??? |
||||||
|
* - "- - -" |
||||||
|
* - Указано два преподавателя (оставляем только первого) |
||||||
|
* - Указан формат обучения "дистанционно" (удаляем) |
||||||
|
* - Теоретически могут быть окончания "-угли, -оглы и т.д. ..." (писать через пробел чтобы отсутствовал сохранить исходное состояние) |
||||||
|
*/ |
||||||
|
Set<String> xlsx_strings = new HashSet<>();//строки для браузера
|
||||||
|
Set<Teacher> xlsx_teachers = new HashSet<>();//объекты для обработки
|
||||||
|
for (Map.Entry<Integer, List<XlsxCell>> entry : map.entrySet()) { |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* получаем значение поля "Преподаватель" |
||||||
|
* заменяем пустые поля на "- - -" |
||||||
|
* добавляем запись в список уникальных значений |
||||||
|
*/ |
||||||
|
String string = ""; |
||||||
|
try { |
||||||
|
string = entry |
||||||
|
.getValue() |
||||||
|
.get(18) |
||||||
|
.getContent(); |
||||||
|
} catch (Exception e) { |
||||||
|
System.out.println("Не указан преподаватель: " + entry.getKey() + " :: " + e.getMessage()); |
||||||
|
string = "- - -"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Преобразование строки в объект Преподавателя |
||||||
|
* - обработка возможных ошибок в файле |
||||||
|
* - разбор строк происходит в основном переборе, чтобы можно было извлечь номер строки с ошибками для пользователя |
||||||
|
*/ |
||||||
|
Teacher t = new Teacher(); |
||||||
|
String[] arr = string.split(" "); |
||||||
|
for (int i = 0; i < arr.length; i++){ |
||||||
|
switch (i) { |
||||||
|
case 0: { |
||||||
|
if (arr.length > 1){ |
||||||
|
t.setSecond_name(arr[i]);//Фамилия
|
||||||
|
break; |
||||||
|
} |
||||||
|
t.setSecond_name("-");//Фамилия
|
||||||
|
t.setFirst_name("-");//Имя
|
||||||
|
t.setLast_name("-");//Отчество
|
||||||
|
errors.add("Возможна ошибка в строке документа: " + entry.getKey() + " :: В поле *Преподаватель* указано одно слово ... " + string); |
||||||
|
break; |
||||||
|
} |
||||||
|
case 1: { |
||||||
|
t.setFirst_name(arr[i]);//Имя
|
||||||
|
break; |
||||||
|
} |
||||||
|
case 2: { |
||||||
|
t.setLast_name(arr[i]);//Отчество
|
||||||
|
break; |
||||||
|
} |
||||||
|
/** |
||||||
|
* Обработка четвертого слова в строке |
||||||
|
* Преподавателей, имеющих окончания в фамилии у нас нет. |
||||||
|
* можно все что после 3-го слова откинуть .. |
||||||
|
* |
||||||
|
*/ |
||||||
|
case 3: { |
||||||
|
// t.setLast_name(arr[(i-1)] + " " + arr[i]);//Окончание отчества - оглы, угли итд.
|
||||||
|
errors.add("Возможна ошибка в строке документа: " + entry.getKey() + " :: В поле *Преподаватель* указано больше трех слов ... " + string); |
||||||
|
break; |
||||||
|
} |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
xlsx_strings.add(string); |
||||||
|
xlsx_teachers.add(t); |
||||||
|
} |
||||||
|
/** |
||||||
|
* Промежуточные результаты в консоль |
||||||
|
*/ |
||||||
|
System.out.println("Всего преподавателей(obj): " + xlsx_teachers.size()); |
||||||
|
System.out.println("Всего преподавателей(str): " + xlsx_strings.size()); |
||||||
|
for (Teacher teacher : xlsx_teachers) { |
||||||
|
System.out.println("Преподаватель (obj): " + teacher.toString()); |
||||||
|
} |
||||||
|
System.out.println(">> errors: " + errors.size()); |
||||||
|
for (String msg : errors) { |
||||||
|
System.out.println("msg: " + msg); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Получение перечня преподавателей из базы |
||||||
|
*/ |
||||||
|
System.out.println("Получение списка преподавателей из базы ..."); |
||||||
|
Set<Teacher> base_teachers = client.method(HttpMethod.GET) |
||||||
|
.uri("http://resource-service-api:8181/teacher/list") |
||||||
|
.retrieve() |
||||||
|
.bodyToMono(new ParameterizedTypeReference <Set<Teacher>>(){}) |
||||||
|
.block(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Удаление преподавателей присутствующих в базе |
||||||
|
* сравнение по объектам не проходит: |
||||||
|
* - в объектах xlsx отсутствуют id, которые приходят с объектами из базы |
||||||
|
* - менять Teacher.equals не хочется, он на lombok завязан |
||||||
|
* - перевожу ФИО в строку и сравниваю строки!!! |
||||||
|
*/ |
||||||
|
// xlsx_teachers.removeAll(base_teachers);
|
||||||
|
Set<String> xlsx_teachers_str = new HashSet<>(); |
||||||
|
Set<String> base_teachers_str = new HashSet<>(); |
||||||
|
for (Teacher t : xlsx_teachers) { |
||||||
|
String s = t.getSecond_name() + " " |
||||||
|
+ t.getFirst_name() + " " |
||||||
|
+ t.getLast_name(); |
||||||
|
xlsx_teachers_str.add(s); |
||||||
|
} |
||||||
|
|
||||||
|
for (Teacher t : base_teachers) { |
||||||
|
String s = t.getSecond_name() + " " |
||||||
|
+ t.getFirst_name() + " " |
||||||
|
+ t.getLast_name(); |
||||||
|
base_teachers_str.add(s); |
||||||
|
} |
||||||
|
|
||||||
|
xlsx_teachers_str.removeAll(base_teachers_str); |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Если какието преподаватели отсутствуют в базе, |
||||||
|
* вернуть страницу проверки преподавателей |
||||||
|
*/ |
||||||
|
if (xlsx_teachers_str.size() != 0) { |
||||||
|
/** |
||||||
|
* Подготовка списка, для передачи в представление |
||||||
|
* - опять преобразуем список из строкового в объектный |
||||||
|
*/ |
||||||
|
ArrayList<Teacher> list = new ArrayList<>(); |
||||||
|
for (String string : xlsx_teachers_str) { |
||||||
|
Teacher t = new Teacher(); |
||||||
|
String[] arr = string.split(" "); |
||||||
|
for (int i = 0; i < arr.length; i++){ |
||||||
|
switch (i) { |
||||||
|
case 0: { |
||||||
|
t.setSecond_name(arr[i]);//Фамилия
|
||||||
|
break; |
||||||
|
} |
||||||
|
case 1: { |
||||||
|
t.setFirst_name(arr[i]);//Имя
|
||||||
|
break; |
||||||
|
} |
||||||
|
case 2: { |
||||||
|
t.setLast_name(arr[i]);//Отчество
|
||||||
|
break; |
||||||
|
} |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
list.add(t); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
//кладем список в обертку для формы
|
||||||
|
TeacherWraper teacherWraper = new TeacherWraper(list); |
||||||
|
|
||||||
|
model.addAttribute("wrapTeachers", teacherWraper); |
||||||
|
model.addAttribute("errors", errors); |
||||||
|
model.addAttribute("id", id); |
||||||
|
|
||||||
|
return "teachers-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 saveTeachers(@ModelAttribute("wrapTeachers") TeacherWraper wraper, @PathVariable String id){ |
||||||
|
/** |
||||||
|
* Отправляем запросы на добавление новых критериев в базу |
||||||
|
*/ |
||||||
|
System.out.println("Преподаватели для добавления в базу: " |
||||||
|
+ wraper.getList().toString()); |
||||||
|
|
||||||
|
for (Teacher teacher : wraper.getList()) { |
||||||
|
//Проверка наличия флага для добавления в базу
|
||||||
|
//по полю табельного номера
|
||||||
|
if (teacher.getEmployee_id() != ""){ |
||||||
|
client.post() |
||||||
|
.uri("http://resource-service-api:8181/teacher/create") |
||||||
|
.body(Mono.just(teacher), Teacher.class) |
||||||
|
.retrieve() |
||||||
|
.toBodilessEntity() |
||||||
|
.timeout(Duration.ofSeconds(1)) |
||||||
|
.block(); |
||||||
|
} |
||||||
|
} |
||||||
|
/** |
||||||
|
* Возвращаем пользователя на страницу перечня новых критериев |
||||||
|
* - если он не пустой |
||||||
|
*/ |
||||||
|
return "redirect:/teachers/check/" + id; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
/** |
||||||
|
* Сущность объекта строительства |
||||||
|
*/ |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Data |
||||||
|
public class Building implements Serializable{ |
||||||
|
private long id; |
||||||
|
private String name_short;//Сокращенное наименование
|
||||||
|
private String name_full;//Полное наименование
|
||||||
|
private String code_short;//Краткий код
|
||||||
|
private String code_full;//Полный код
|
||||||
|
|
||||||
|
// подготовить конструкторы на все варианты внесения информации о преподавателях
|
||||||
|
public Building(String name_short, String name_full, String code_short, String code_full){ |
||||||
|
this.name_short = name_short; |
||||||
|
this.name_full = name_full; |
||||||
|
this.code_short = code_short; |
||||||
|
this.code_full = code_full; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* Обертка для списка объектов строительства, обеспечивающая работоспособность thymeleaf |
||||||
|
* при отправке из формы перечня объектов строительства |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class BuildingWraper { |
||||||
|
List<Building> list; |
||||||
|
|
||||||
|
public BuildingWraper(){ |
||||||
|
init(); |
||||||
|
} |
||||||
|
|
||||||
|
public BuildingWraper(List<Building> list){ |
||||||
|
this.list = list; |
||||||
|
} |
||||||
|
|
||||||
|
public void init(){ |
||||||
|
this.list = new ArrayList<>(); |
||||||
|
} |
||||||
|
|
||||||
|
public void add(Building building){ |
||||||
|
this.list.add(building); |
||||||
|
} |
||||||
|
public String toString(){ |
||||||
|
return this.list.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Data |
||||||
|
public class Course { |
||||||
|
private long id;//уникальный идентификатор курса
|
||||||
|
private String place;//место проведения занятий
|
||||||
|
private Date start_date;//дата начала курса
|
||||||
|
private Date protocol_date;//дата протокола
|
||||||
|
private String protocol_number;//номер протоколаssss
|
||||||
|
private String report_period;//отчетный период (наименование месяца)
|
||||||
|
private Teacher teacher;//сведения о преподаватле
|
||||||
|
private Program program;//сведения о программе обучения
|
||||||
|
private Building building;//сведения об объекте строительства
|
||||||
|
|
||||||
|
/** |
||||||
|
* Конструктор без id |
||||||
|
* @param place |
||||||
|
* @param start_date |
||||||
|
* @param protocol_date |
||||||
|
* @param protocol_number |
||||||
|
* @param report_period |
||||||
|
* @param teacher |
||||||
|
* @param program |
||||||
|
* @param building |
||||||
|
*/ |
||||||
|
public Course(String place, Date start_date, Date protocol_date, String protocol_number, String report_period, |
||||||
|
Teacher teacher, Program program, Building building) { |
||||||
|
this.place = place; |
||||||
|
this.start_date = start_date; |
||||||
|
this.protocol_date = protocol_date; |
||||||
|
this.protocol_number = protocol_number; |
||||||
|
this.report_period = report_period; |
||||||
|
this.teacher = teacher; |
||||||
|
this.program = program; |
||||||
|
this.building = building; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Data |
||||||
|
public class Document implements Serializable{ |
||||||
|
private Long id; |
||||||
|
private String name;//наименование файла в файловой системе ({id}.{extension})
|
||||||
|
private String path;//путь в файловой системе (root/{id}.{extension})
|
||||||
|
private String extension;//расширение файла
|
||||||
|
private Long size;//размер файла
|
||||||
|
|
||||||
|
/** |
||||||
|
* без id |
||||||
|
* @param name |
||||||
|
* @param path |
||||||
|
* @param extension |
||||||
|
* @param size |
||||||
|
*/ |
||||||
|
public Document(String name, String path, String extension, long size) { |
||||||
|
this.name = name; |
||||||
|
this.path = path; |
||||||
|
this.extension = extension; |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Data |
||||||
|
public class EducatonEntry { |
||||||
|
private long id; |
||||||
|
private String sertificate_number;//номер удостоверения
|
||||||
|
private String frdo_number;//ФРДО номер по реестру
|
||||||
|
private String eisot_number;//ЕИСОТ номер по реестру
|
||||||
|
private String ones;//единички (вспомогатльный столбец)
|
||||||
|
private Course course;//сведения о курсе
|
||||||
|
private Student student;//сведения о студенте
|
||||||
|
|
||||||
|
/** |
||||||
|
* Конструктор без id |
||||||
|
* @param sertificate_number |
||||||
|
* @param frdo_number |
||||||
|
* @param eisot_number |
||||||
|
* @param ones |
||||||
|
* @param course |
||||||
|
* @param student |
||||||
|
*/ |
||||||
|
public EducatonEntry(String sertificate_number, String frdo_number, String eisot_number, String ones, |
||||||
|
Course course, Student student) { |
||||||
|
this.sertificate_number = sertificate_number; |
||||||
|
this.frdo_number = frdo_number; |
||||||
|
this.eisot_number = eisot_number; |
||||||
|
this.ones = ones; |
||||||
|
this.course = course; |
||||||
|
this.student = student; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
/** |
||||||
|
* Сущность организации |
||||||
|
*/ |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Data |
||||||
|
public class Organization implements Serializable{ |
||||||
|
private long id; |
||||||
|
private String ownership;//Форма собственности ПСК
|
||||||
|
private String name_short;//Сокращенное наименование
|
||||||
|
private String name_full;//Полное наименование
|
||||||
|
private String type;//вид ПСК - производственная/сервисная
|
||||||
|
private String inn;//ИНН организации
|
||||||
|
|
||||||
|
/** |
||||||
|
* Конструктор без id |
||||||
|
* @param ownership |
||||||
|
* @param name_short |
||||||
|
* @param name_full |
||||||
|
* @param type |
||||||
|
* @param inn |
||||||
|
*/ |
||||||
|
public Organization(String ownership, String name_short, String name_full, String type, String inn) { |
||||||
|
this.ownership = ownership; |
||||||
|
this.name_short = name_short; |
||||||
|
this.name_full = name_full; |
||||||
|
this.type = type; |
||||||
|
this.inn = inn; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Data |
||||||
|
public class Program { |
||||||
|
private long id; |
||||||
|
private String name;//Наименование
|
||||||
|
private Integer lenght;//длительность программы в часах
|
||||||
|
|
||||||
|
/** |
||||||
|
* Направление обучения: |
||||||
|
* - Обязательное обучение |
||||||
|
* - Производственное обучение |
||||||
|
* - Обучение вновь внедряемым процедурам |
||||||
|
* - Обучение водителей |
||||||
|
*/ |
||||||
|
private String study_direction; |
||||||
|
private Integer price;//рублей
|
||||||
|
private ProgramCretarea cretarea; |
||||||
|
|
||||||
|
/** |
||||||
|
* конструктор со всеми полями сущности, за исключением id |
||||||
|
* Подготовить все варианты конструкторов |
||||||
|
* @param name |
||||||
|
* @param lenght |
||||||
|
* @param study_direction |
||||||
|
* @param price |
||||||
|
* @param cretarea |
||||||
|
*/ |
||||||
|
public Program(String name, Integer lenght, String study_direction, Integer price, ProgramCretarea cretarea) { |
||||||
|
this.name = name; |
||||||
|
this.lenght = lenght; |
||||||
|
this.study_direction = study_direction; |
||||||
|
this.price = price; |
||||||
|
this.cretarea = cretarea; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Data |
||||||
|
public class ProgramCretarea implements Serializable{ |
||||||
|
private long id; |
||||||
|
private String name;//Наименование
|
||||||
|
private String name_short;//Наименование : сокращенно
|
||||||
|
|
||||||
|
/** |
||||||
|
* подготовить конструкторы на все варианты внесения информации о преподавателях |
||||||
|
* |
||||||
|
* @param name |
||||||
|
* @param name_short |
||||||
|
*/ |
||||||
|
public ProgramCretarea(String name, String name_short) { |
||||||
|
this.name = name; |
||||||
|
this.name_short = name_short; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* Обертка для списка критериев, обеспечивающая работоспособность thymeleaf |
||||||
|
* при отправке из формы списка критериев |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class ProgramCretareaWraper { |
||||||
|
List<ProgramCretarea> list; |
||||||
|
|
||||||
|
public ProgramCretareaWraper(){ |
||||||
|
init(); |
||||||
|
} |
||||||
|
|
||||||
|
public ProgramCretareaWraper(List<ProgramCretarea> list){ |
||||||
|
this.list = list; |
||||||
|
} |
||||||
|
|
||||||
|
public void init(){ |
||||||
|
this.list = new ArrayList<>(); |
||||||
|
} |
||||||
|
|
||||||
|
public void add(ProgramCretarea cretarea){ |
||||||
|
this.list.add(cretarea); |
||||||
|
} |
||||||
|
public String toString(){ |
||||||
|
return this.list.toString(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* Обертка для списка программ обучения - для thymeleaf |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class ProgramWraper { |
||||||
|
List<Program> programs; |
||||||
|
List<ProgramCretarea> cretareas; |
||||||
|
|
||||||
|
public ProgramWraper(){ |
||||||
|
init(); |
||||||
|
} |
||||||
|
|
||||||
|
public ProgramWraper(ArrayList<Program> list) { |
||||||
|
this.programs = list; |
||||||
|
} |
||||||
|
|
||||||
|
public void init(){ |
||||||
|
this.programs = new ArrayList<>(); |
||||||
|
} |
||||||
|
|
||||||
|
public void addProgram(Program program){ |
||||||
|
this.programs.add(program); |
||||||
|
} |
||||||
|
|
||||||
|
public void addCretarea(ProgramCretarea cretarea){ |
||||||
|
this.cretareas.add(cretarea); |
||||||
|
} |
||||||
|
|
||||||
|
public String toString(){ |
||||||
|
return this.programs.toString(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Data |
||||||
|
public class Student implements Serializable{ |
||||||
|
private long id; |
||||||
|
private String first_name;//Имя
|
||||||
|
private String second_name;//Отчество
|
||||||
|
private String last_name;//Фамилия
|
||||||
|
private String profession;//Профессия
|
||||||
|
private String category;//Категория (ИТР или рабочий)
|
||||||
|
private String direction;//Структурное подразделение
|
||||||
|
private String snils;//СНИЛС
|
||||||
|
private Date berth;//Дата рождения
|
||||||
|
private String sitizenship;//Гражданство
|
||||||
|
private String sex;//Пол (Муж/Жен)
|
||||||
|
private Organization organization;//Организация - работодатель
|
||||||
|
|
||||||
|
/** |
||||||
|
* Конструктор со всеми полями сущности кроме id |
||||||
|
* @param first_name |
||||||
|
* @param second_name |
||||||
|
* @param last_name |
||||||
|
* @param profession |
||||||
|
* @param category |
||||||
|
* @param direction |
||||||
|
* @param snils |
||||||
|
* @param berth |
||||||
|
* @param sitizenship |
||||||
|
* @param sex |
||||||
|
* @param organization |
||||||
|
*/ |
||||||
|
public Student(String first_name, String second_name, String last_name, String profession, String category, |
||||||
|
String direction, String snils, Date berth, String sitizenship, String sex, Organization organization) { |
||||||
|
this.first_name = first_name; |
||||||
|
this.second_name = second_name; |
||||||
|
this.last_name = last_name; |
||||||
|
this.profession = profession; |
||||||
|
this.category = category; |
||||||
|
this.direction = direction; |
||||||
|
this.snils = snils; |
||||||
|
this.berth = berth; |
||||||
|
this.sitizenship = sitizenship; |
||||||
|
this.sex = sex; |
||||||
|
this.organization = organization; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
/** |
||||||
|
* Сущьность преподавателя |
||||||
|
* добавить данные: |
||||||
|
* - телефоны (список) |
||||||
|
* - эл почты (список) |
||||||
|
* - программы которые преподает |
||||||
|
* - график работы |
||||||
|
* - основное место работы (офис, наимеование ОП) |
||||||
|
*/ |
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Data |
||||||
|
public class Teacher implements Serializable{ |
||||||
|
private long id; |
||||||
|
private String first_name;//Имя
|
||||||
|
private String second_name;//Фамилия
|
||||||
|
private String last_name;//Отчество
|
||||||
|
private String employee_id; |
||||||
|
private String snils; |
||||||
|
|
||||||
|
// подготовить конструкторы на все варианты внесения информации о преподавателях
|
||||||
|
public Teacher(String first_name, String second_name, String last_name){ |
||||||
|
this.first_name = first_name; |
||||||
|
this.second_name = second_name; |
||||||
|
this.last_name = last_name; |
||||||
|
} |
||||||
|
|
||||||
|
//конструктор - все аргуметы кроме id
|
||||||
|
public Teacher(String first_name, String second_name, String last_name, String employee_id, String snils){ |
||||||
|
this.first_name = first_name; |
||||||
|
this.second_name = second_name; |
||||||
|
this.last_name = last_name; |
||||||
|
this.employee_id = employee_id; |
||||||
|
this.snils = snils; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
@Data |
||||||
|
public class TeacherWraper { |
||||||
|
List<Teacher> list; |
||||||
|
|
||||||
|
public TeacherWraper(){ |
||||||
|
init(); |
||||||
|
} |
||||||
|
|
||||||
|
public TeacherWraper(List<Teacher> list){ |
||||||
|
this.list = list; |
||||||
|
} |
||||||
|
|
||||||
|
public void init(){ |
||||||
|
this.list = new ArrayList<>(); |
||||||
|
} |
||||||
|
|
||||||
|
public void add(Teacher teacher){ |
||||||
|
this.list.add(teacher); |
||||||
|
} |
||||||
|
public String toString(){ |
||||||
|
return this.list.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
@Data |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
public class XlsxCell { |
||||||
|
private String content; //содержимое ячейки
|
||||||
|
private String textColor; //цвет шрифта
|
||||||
|
private String bgColor; // цвет заливки ячейки
|
||||||
|
private String textSize; //8-12-14-24 размеры шрифта
|
||||||
|
private int textWeight; //жирность: bold (900), normal(500),
|
||||||
|
private String type;// STRING, NUMERIC, BOOLEAN, FORMULA
|
||||||
|
|
||||||
|
public XlsxCell(String content){ |
||||||
|
this.content = content; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
package ru.mlokoin.gates.model; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
@Data |
||||||
|
@AllArgsConstructor |
||||||
|
@NoArgsConstructor |
||||||
|
public class XlsxDocument implements Serializable{ |
||||||
|
private Map<Integer, List<XlsxCell>> data; |
||||||
|
private Document document; |
||||||
|
private List<XlsxCell> headers; |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
package ru.mlokoin.gates.util; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
|
||||||
|
import org.springframework.lang.NonNull; |
||||||
|
import org.springframework.lang.Nullable; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
public class CustomMultipartFile implements MultipartFile{ |
||||||
|
private MultipartFile file; |
||||||
|
private String name; |
||||||
|
|
||||||
|
/** |
||||||
|
* @param file |
||||||
|
* @param name |
||||||
|
*/ |
||||||
|
public CustomMultipartFile(MultipartFile file, String name) { |
||||||
|
this.file = file; |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public byte[] getBytes() throws IOException { |
||||||
|
return file.getBytes(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
@Nullable |
||||||
|
public String getContentType() { |
||||||
|
return file.getContentType(); |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public InputStream getInputStream() throws IOException { |
||||||
|
return file.getInputStream(); |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
@Override |
||||||
|
public String getName() { |
||||||
|
return file.getName(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
@Nullable |
||||||
|
public String getOriginalFilename() { |
||||||
|
return this.name; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public long getSize() { |
||||||
|
return file.getSize(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isEmpty() { |
||||||
|
return file.isEmpty(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void transferTo(File dest) throws IOException, IllegalStateException { |
||||||
|
//NO REALIZATION
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
spring: |
||||||
|
application: |
||||||
|
name: gates |
||||||
|
jpa: |
||||||
|
hibernate: |
||||||
|
ddl-auto: update |
||||||
|
database-platform: org.hibernate.dialect.PostgreSQLDialect |
||||||
|
datasource: |
||||||
|
url: "jdbc:postgresql://postgres-service:5432/tech-services" |
||||||
|
username: tech-services |
||||||
|
password: password |
||||||
|
servlet: |
||||||
|
multipart: |
||||||
|
max-file-size: 50MB |
||||||
|
max-request-size: 50MB |
||||||
|
mvc: |
||||||
|
hiddenmethod: |
||||||
|
filter: |
||||||
|
enabled: true |
||||||
|
format: |
||||||
|
date: yyyy-MM-dd |
||||||
|
date-time: yyyy-MM-dd HH:mm:ss |
||||||
|
time: HH:mm:ss |
||||||
|
server: |
||||||
|
port: 8383 |
||||||
|
|
||||||
|
|
@ -0,0 +1,2 @@ |
|||||||
|
# gates |
||||||
|
сервис для экспорта данных из файлов в базу |
@ -0,0 +1,53 @@ |
|||||||
|
<!DOCTYPE HTML> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>check-buildings</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-buildings</h2> |
||||||
|
<ul> |
||||||
|
<li></li> |
||||||
|
<li></li> |
||||||
|
<li></li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
</header> |
||||||
|
<main> |
||||||
|
<div class="main-wraper"> |
||||||
|
<h2>Объекты строительства, отсутствующие в базе:</h2> |
||||||
|
<!-- <form th:action="@{/program-cretareas/save/{id}(id=${id})}" |
||||||
|
th:method="post" |
||||||
|
th:object="${wrapCretareas}"> |
||||||
|
<table rules="all"> |
||||||
|
<thead> |
||||||
|
<th> |
||||||
|
<span>КРАТКО</span> |
||||||
|
</th> |
||||||
|
<th> |
||||||
|
<span>ПОЛНО</span> |
||||||
|
</th> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr th:each="dc, dcStat : *{getList()}" > |
||||||
|
<td> |
||||||
|
<input type="text" th:field="*{list[__${dcStat.index}__].name_short}"/> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" th:field="*{list[__${dcStat.index}__].name}"/> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
<input type="submit" value="POST-ALL"/> |
||||||
|
</form> --> |
||||||
|
</div> |
||||||
|
</main> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,61 @@ |
|||||||
|
<!DOCTYPE HTML> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>check-cretareas</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-cretareas</h2> |
||||||
|
<ul> |
||||||
|
<li>POST NEW CRETAREAS привязать к пути на контроллере</li> |
||||||
|
<li>Отправка формы, для передачи сервису ресурсов данных о новых критериях ...</li> |
||||||
|
<li>Для новых критериев сделать пустой объект списка критериев, который будет отправляться после заполнения ...</li> |
||||||
|
<li>Критерии добавлять в базу по одному, вдруг какие-то критерии окажутся опечатками и нужно будет редактировать исходный файл ...</li> |
||||||
|
<li>Кнопка возврата к странице экспорта документа</li> |
||||||
|
<li></li> |
||||||
|
<li></li> |
||||||
|
<li></li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
</header> |
||||||
|
<main> |
||||||
|
<div class="main-wraper"> |
||||||
|
<h2>Критерии, отсутствующие в базе:</h2> |
||||||
|
<form th:action="@{/program-cretareas/save/{id}(id=${id})}" |
||||||
|
th:method="post" |
||||||
|
th:object="${wrapCretareas}"> |
||||||
|
<table rules="all"> |
||||||
|
<thead> |
||||||
|
<th> |
||||||
|
<span>КРАТКО</span> |
||||||
|
</th> |
||||||
|
<th> |
||||||
|
<span>ПОЛНО</span> |
||||||
|
</th> |
||||||
|
<!-- <th> |
||||||
|
<span>ОТПРАВИТЬ</span> |
||||||
|
</th> --> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr th:each="dc, dcStat : *{getList()}" > |
||||||
|
<td> |
||||||
|
<input type="text" th:field="*{list[__${dcStat.index}__].name_short}"/> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" th:field="*{list[__${dcStat.index}__].name}"/> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
<input type="submit" value="POST-ALL"/> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</main> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,92 @@ |
|||||||
|
<!-- Шаблон для представления данных из базы данных |
||||||
|
- список файлов на сервере и сведения о них |
||||||
|
- инструменты управления файлами на сервере |
||||||
|
--> |
||||||
|
|
||||||
|
<!DOCTYPE HTML> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>documents</title> |
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script> |
||||||
|
<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script> |
||||||
|
</head> |
||||||
|
|
||||||
|
<body> |
||||||
|
<header> |
||||||
|
<h1>documents</h1> |
||||||
|
menu : auth : documents |
||||||
|
<br> |
||||||
|
</header> |
||||||
|
<main> |
||||||
|
<div class="main-wraper"> |
||||||
|
|
||||||
|
<!-- |
||||||
|
|
||||||
|
--> |
||||||
|
<h2>Добавление пакетов:</h2> |
||||||
|
<form method="post" th:action="@{/document/upload}" enctype="multipart/form-data"> |
||||||
|
<div> |
||||||
|
<input type="file" name="file"> |
||||||
|
</div> |
||||||
|
<button type="submit">Upload File</button> |
||||||
|
</form> |
||||||
|
<h2>Перечень файлов:</h2> |
||||||
|
<form th:action="@{/documents}" method="get"></form> |
||||||
|
<table> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>id</th> |
||||||
|
<th>name</th> |
||||||
|
<!-- <th>path</th> --> |
||||||
|
<th>extension</th> |
||||||
|
<th>size(bytes)</th> |
||||||
|
<th> |
||||||
|
|
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr th:each="doc: ${documents}"> |
||||||
|
<td> |
||||||
|
<input type="text" id="id" name="id" th:value="${doc.id}" readonly /> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" id="name" name="name" th:value="${doc.name}" readonly /> |
||||||
|
</td> |
||||||
|
<!-- <td> |
||||||
|
<input type="text" id="path" name="path" th:value="${doc.path}" readonly /> |
||||||
|
</td> --> |
||||||
|
<td> |
||||||
|
<input type="text" id="extension" name="extension" th:value="${doc.extension}" readonly /> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" id="size" name="size" th:value="${doc.size}" readonly /> |
||||||
|
</td> |
||||||
|
|
||||||
|
<td> |
||||||
|
<form th:action="@{/document/delete/{id}(id=${doc.id})}" th:method="get"> |
||||||
|
<!-- <input type="headen" th:field="${doc.name}" name="docName"> --> |
||||||
|
<input type="submit" value="X"/> |
||||||
|
</form> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<form th:action="@{/document/view-xlsx/{id}(id=${doc.id})}" th:method="get"> |
||||||
|
<input type="submit" value="VIEW"/> |
||||||
|
</form> |
||||||
|
</td> |
||||||
|
<!-- <td> |
||||||
|
<form th:action="@{/export-as-educations/{name}(name=${doc.name})}" th:method="get"> |
||||||
|
<input type="submit" value="EXPORT-AS-EDUCATIONS"/> |
||||||
|
</form> |
||||||
|
</td> --> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</main> |
||||||
|
|
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,14 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||||
|
<title>gates-hello</title> |
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script> |
||||||
|
<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<zero-md th:src="@{/content/md/hello.md}"></zero-md> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,69 @@ |
|||||||
|
<!DOCTYPE HTML> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>check-programs</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-programs</h2> |
||||||
|
<ul> |
||||||
|
<li>Наименование программы не должно содержать знаков переноса строки. |
||||||
|
При внесении в базу они заменяются пробелами и не проходят проверку при сравнении с наименованием в xlsx</li> |
||||||
|
<li></li> |
||||||
|
<li></li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
</header> |
||||||
|
<main> |
||||||
|
<form th:action="@{/programs/save/{id}(id=${id})}" |
||||||
|
th:method="post" |
||||||
|
th:object="${wrapPrograms}"> |
||||||
|
<table rules="all"> |
||||||
|
<thead> |
||||||
|
<th><span>Наименование программы (name)</span></th> |
||||||
|
<th><span>Продолжительность, часов (lenght)</span></th> |
||||||
|
<th><span>Направление обучения (study_direction)</span></th> |
||||||
|
<th><span>Стоимость (price)</span></th> |
||||||
|
<th><span>Критерий (cretarea_id)</span></th> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr th:each="p, pStat : *{getPrograms()}" > |
||||||
|
<td> |
||||||
|
<input type="text" th:field="*{programs[__${pStat.index}__].name}"> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" th:field="*{programs[__${pStat.index}__].lenght}"/> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<select th:field="*{programs[__${pStat.index}__].study_direction}"> |
||||||
|
<option value="0" disabled >выберите нарпавление обучения</option> |
||||||
|
<option value="1" >Обучение вновь внедряемым процедурам</option> |
||||||
|
<option value="2" >Обучение водителей</option> |
||||||
|
<option value="3" >Обязательное обучение</option> |
||||||
|
<option value="4" >Производственное обучение</option> |
||||||
|
<option value="4" >Профессиональная переподготовка</option> |
||||||
|
</select> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" th:field="*{programs[__${pStat.index}__].price}"/> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<select th:field="*{programs[__${pStat.index}__].cretarea.id}"> |
||||||
|
<option value="0" disabled >выберите критерий</option> |
||||||
|
<option th:each="option : *{cretareas}" th:value="${option.id}" th:text="${option.name_short}"></option> |
||||||
|
</select> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
<input type="submit" value="POST-ALL"/> |
||||||
|
</form> |
||||||
|
</main> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,28 @@ |
|||||||
|
<!DOCTYPE HTML> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>gates-uploads</title> |
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script> |
||||||
|
<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script> |
||||||
|
</head> |
||||||
|
|
||||||
|
<body> |
||||||
|
<header> |
||||||
|
<h1>gates-uploads</h1> |
||||||
|
<br> |
||||||
|
</header> |
||||||
|
<main> |
||||||
|
<div class="main-wraper"> |
||||||
|
<h2>Загрузка файла на сервер</h2> |
||||||
|
<form method="post" th:action="@{/upload}" enctype="multipart/form-data"> |
||||||
|
<div> |
||||||
|
<input type="file" name="file"> |
||||||
|
</div> |
||||||
|
<button type="submit">Upload File</button> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</main> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,91 @@ |
|||||||
|
<!-- Шаблон для представления данных из файлового хранилища |
||||||
|
- Список файлов на сервере |
||||||
|
- |
||||||
|
|
||||||
|
--> |
||||||
|
|
||||||
|
<!DOCTYPE HTML> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>Uploads</title> |
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script> |
||||||
|
<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script> |
||||||
|
</head> |
||||||
|
|
||||||
|
<body> |
||||||
|
<header> |
||||||
|
<h1>Gates</h1> |
||||||
|
menu : auth : Storage |
||||||
|
<br> |
||||||
|
</header> |
||||||
|
<main> |
||||||
|
<div class="main-wraper"> |
||||||
|
|
||||||
|
<!-- |
||||||
|
|
||||||
|
--> |
||||||
|
<h2>Добавление пакетов:</h2>\ |
||||||
|
|
||||||
|
<h2>Перечень файлов:</h2> |
||||||
|
<form th:action="@{/storage}" method="get"></form> |
||||||
|
<form method="post" th:action="@{/storage/upload}" enctype="multipart/form-data"> |
||||||
|
<div> |
||||||
|
<input type="file" name="file"> |
||||||
|
</div> |
||||||
|
<button type="submit">Upload File</button> |
||||||
|
</form> |
||||||
|
<table> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>name</th> |
||||||
|
<th>path</th> |
||||||
|
<th>extension</th> |
||||||
|
<th>size(bytes)</th> |
||||||
|
<th> |
||||||
|
|
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr th:each="doc: ${documents}"> |
||||||
|
<td> |
||||||
|
<input type="text" id="name" name="name" th:value="${doc.name}" readonly /> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" id="path" name="path" th:value="${doc.path}" readonly /> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" id="extension" name="extension" th:value="${doc.extension}" readonly /> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" id="size" name="size" th:value="${doc.size}" readonly /> |
||||||
|
</td> |
||||||
|
|
||||||
|
<td> |
||||||
|
<form th:action="@{/storage/delete/{name}(name=${doc.name})}" th:method="get"> |
||||||
|
<!-- <input type="headen" th:field="${doc.name}" name="docName"> --> |
||||||
|
<input type="submit" value="X"/> |
||||||
|
</form> |
||||||
|
</td> |
||||||
|
<!-- <td> |
||||||
|
<form th:action="@{/view/{name}(name=${doc.name})}" th:method="get"> |
||||||
|
<input type="submit" value="VIEW"/> |
||||||
|
</form> |
||||||
|
</td> --> |
||||||
|
<!-- <td> |
||||||
|
<form th:action="@{/export-as-educations/{name}(name=${doc.name})}" th:method="get"> |
||||||
|
<input type="submit" value="EXPORT-AS-EDUCATIONS"/> |
||||||
|
</form> |
||||||
|
</td> --> |
||||||
|
|
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</main> |
||||||
|
|
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,67 @@ |
|||||||
|
<!DOCTYPE HTML> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>check-teachers</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-teachers</h2> |
||||||
|
<ul> |
||||||
|
<li>Преподаватели добавляются в базу если указан табельный номер.</li> |
||||||
|
<li></li> |
||||||
|
<li></li> |
||||||
|
<li></li> |
||||||
|
<li></li> |
||||||
|
</ul> |
||||||
|
</header> |
||||||
|
<main> |
||||||
|
<form th:action="@{/teachers/save/{id}(id=${id})}" |
||||||
|
th:method="post" |
||||||
|
th:object="${wrapTeachers}"> |
||||||
|
<table rules="all"> |
||||||
|
<thead> |
||||||
|
<th>Имя (first_name)</th> |
||||||
|
<th>Фамилия (second_name)</th> |
||||||
|
<th>Отчество (last_name)</th> |
||||||
|
<th>Табельный номер (employee_id)</th> |
||||||
|
<th>СНИЛС (snils)</th> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr th:each="t, tStat : *{getList()}"> |
||||||
|
<td> |
||||||
|
<input type="text" th:field="*{list[__${tStat.index}__].first_name}"> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" th:field="*{list[__${tStat.index}__].second_name}"> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" th:field="*{list[__${tStat.index}__].last_name}"> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" th:field="*{list[__${tStat.index}__].employee_id}"> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<input type="text" th:field="*{list[__${tStat.index}__].snils}"> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
<input type="submit" value="POST-ALL"/> |
||||||
|
</form> |
||||||
|
<div> |
||||||
|
<h2>errors (потенциальные ошибки в исходном документе): |
||||||
|
<span th:text="${#lists.size(errors)}"></span> |
||||||
|
</h2> |
||||||
|
<ul th:each="e: ${errors}"> |
||||||
|
<li th:text="${e}"></li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</main> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,73 @@ |
|||||||
|
<!DOCTYPE HTML> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>view-as-educations</title> |
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script> |
||||||
|
<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script> |
||||||
|
</head> |
||||||
|
|
||||||
|
<body> |
||||||
|
<header> |
||||||
|
<h2>view-as-educations (предусмотреть): </h2> |
||||||
|
<ul> |
||||||
|
<li>Добавиь на страницу обработки ошибок и результатов отработки проверок</li> |
||||||
|
<li>Удалить перед загрузкой xlsx-файла все знаки переноса строки (при отправке в базу автоматически меняются на пробелы)</li> |
||||||
|
<li>Предусмотреть автоматический погон проверок</li> |
||||||
|
<li>Разделить контроллеры по характеру взаимодействия с базой</li> |
||||||
|
<li></li> |
||||||
|
<li></li> |
||||||
|
<li></li> |
||||||
|
</ul> |
||||||
|
<br><br> |
||||||
|
|
||||||
|
<h2>CONTROLS:</h2> |
||||||
|
<form th:action="@{/program-cretareas/check/{id}(id=${id})}" th:method="get"> |
||||||
|
<input type="submit" value="CHECK-CRETAREAS"/> |
||||||
|
</form> |
||||||
|
<form th:action="@{/programs/check/{id}(id=${id})}" th:method="get"> |
||||||
|
<input type="submit" value="CHECK-PROGRAMS"/> |
||||||
|
</form> |
||||||
|
<form th:action="@{/teachers/check/{id}(id=${id})}" th:method="get"> |
||||||
|
<input type="submit" value="CHECK-TEACHERS"/> |
||||||
|
</form> |
||||||
|
<form th:action="@{#}" th:method="get"> |
||||||
|
<input type="submit" value="CHECK-BUILDINGS"/> |
||||||
|
</form> |
||||||
|
<form th:action="@{#}" th:method="get"> |
||||||
|
<input type="submit" value="CHECK-PSK"/> |
||||||
|
</form> |
||||||
|
<form th:action="@{#}" th:method="get"> |
||||||
|
<input type="submit" value="CHECK-COURSES"/> |
||||||
|
</form> |
||||||
|
<form th:action="@{#}" th:method="get"> |
||||||
|
<input type="submit" value="CHECK-STUDENTS"/> |
||||||
|
</form> |
||||||
|
<form th:action="@{#}" th:method="get"> |
||||||
|
<input type="submit" value="POST-AS-EDUCATIONS"/> |
||||||
|
</form> |
||||||
|
</header> |
||||||
|
<main> |
||||||
|
<div class="main-wraper"> |
||||||
|
<table rules="all"> |
||||||
|
<caption th:text="${filename}"></caption> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th th:each="header : ${headers}"> |
||||||
|
<span th:text="${header.content}"></span> |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr th:each="row: ${xlsx.values()}"> |
||||||
|
<td th:if="${rowStat.count} > 1" th:each="cell : ${row}"> |
||||||
|
<span th:text="${cell.content}"></span> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</main> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,59 @@ |
|||||||
|
<!DOCTYPE HTML> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>View-xlsx</title> |
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script> |
||||||
|
<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script> |
||||||
|
</head> |
||||||
|
|
||||||
|
<body> |
||||||
|
<header> |
||||||
|
<h2>View-xlsx (предусмотреть): </h2> |
||||||
|
<ul> |
||||||
|
<li></li> |
||||||
|
</ul> |
||||||
|
<br><br> |
||||||
|
<h2>ЭКСПОРТИРОВАТЬ ФАЙЛ КАК:</h2> |
||||||
|
<ul> |
||||||
|
<li> |
||||||
|
<form th:action="@{/document/view-as-educations/{id}(id=${id})}" th:method="get"> |
||||||
|
<input type="submit" value="РЕЕСТР ОБУЧЕННЫХ (educations)"/> |
||||||
|
</form> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<form th:action="@{#}" th:method="get"> |
||||||
|
<input type="submit" value="ЗАЯВКА НА ОБУЧЕНИЕ"/> |
||||||
|
</form> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<form th:action="@{#}" th:method="get"> |
||||||
|
<input type="submit" value="СПИСОЧНЫЙ СОСТАВ"/> |
||||||
|
</form> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
</header> |
||||||
|
<main> |
||||||
|
<div class="main-wraper"> |
||||||
|
<table rules="all"> |
||||||
|
<caption th:text="${filename}"></caption> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th th:each="header : ${headers}"> |
||||||
|
<span th:text="${header.content}"></span> |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr th:each="row: ${xlsx.values()}"> |
||||||
|
<td th:if="${rowStat.count} > 1" th:each="cell : ${row}"> |
||||||
|
<span th:text="${cell.content}"></span> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</main> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,13 @@ |
|||||||
|
package ru.mlokoin.gates; |
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.springframework.boot.test.context.SpringBootTest; |
||||||
|
|
||||||
|
@SpringBootTest |
||||||
|
class GatesApplicationTests { |
||||||
|
|
||||||
|
@Test |
||||||
|
void contextLoads() { |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,68 @@ |
|||||||
|
package ru.molokoin.resourceserviceapi.controllers; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.http.HttpStatus; |
||||||
|
import org.springframework.http.MediaType; |
||||||
|
import org.springframework.http.ResponseEntity; |
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping; |
||||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||||
|
import org.springframework.web.bind.annotation.PathVariable; |
||||||
|
import org.springframework.web.bind.annotation.PostMapping; |
||||||
|
import org.springframework.web.bind.annotation.PutMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.RestController; |
||||||
|
|
||||||
|
import ru.molokoin.resourceserviceapi.entities.StorageEntry; |
||||||
|
import ru.molokoin.resourceserviceapi.repositories.StorageEntryFace; |
||||||
|
|
||||||
|
/** |
||||||
|
* Контроллер для работы с таблицей, хранящей сведения о файлах в файловом хранилище |
||||||
|
*/ |
||||||
|
@RestController |
||||||
|
@RequestMapping(path = "/", consumes = {"*/*"}) |
||||||
|
public class StorageController { |
||||||
|
@Autowired |
||||||
|
private StorageEntryFace repo; |
||||||
|
|
||||||
|
@GetMapping("/storage-entry/list") |
||||||
|
public ResponseEntity<List<StorageEntry>> getStorageEntries(){ |
||||||
|
return new ResponseEntity<>(repo.findAll(), HttpStatus.OK); |
||||||
|
} |
||||||
|
|
||||||
|
@GetMapping("/storage-entry/{id}") |
||||||
|
public ResponseEntity<?> getStorageEntryByID(@PathVariable Integer id){ |
||||||
|
return new ResponseEntity<>(repo.findStorageEntryById(id), HttpStatus.OK); |
||||||
|
} |
||||||
|
|
||||||
|
@PostMapping(path = "/storage-entry/create", |
||||||
|
consumes = MediaType.APPLICATION_JSON_VALUE, |
||||||
|
produces = MediaType.APPLICATION_JSON_VALUE) |
||||||
|
public ResponseEntity<?> saveStorageEntry(@RequestBody StorageEntry storageEntry) { |
||||||
|
repo.save(storageEntry); |
||||||
|
return new ResponseEntity<>(storageEntry, HttpStatus.CREATED); |
||||||
|
} |
||||||
|
|
||||||
|
@PutMapping(path = "/storage-entry/update/{id}", |
||||||
|
consumes = MediaType.APPLICATION_JSON_VALUE, |
||||||
|
produces = MediaType.APPLICATION_JSON_VALUE) |
||||||
|
public ResponseEntity<?> updateStorageEntry(@PathVariable Integer id, @RequestBody StorageEntry storageEntry) { |
||||||
|
StorageEntry se = repo.findStorageEntryById(id); |
||||||
|
|
||||||
|
se.setName(storageEntry.getName()); |
||||||
|
se.setPath(storageEntry.getPath()); |
||||||
|
se.setExtension(storageEntry.getExtension()); |
||||||
|
se.setSize(storageEntry.getSize()); |
||||||
|
repo.save(se); |
||||||
|
return new ResponseEntity<>(repo.findStorageEntryById(id), HttpStatus.CREATED); |
||||||
|
} |
||||||
|
|
||||||
|
@DeleteMapping("/storage-entry/delete/{id}") |
||||||
|
public ResponseEntity<String> deleteStorageEntry(@PathVariable Long id){ |
||||||
|
StorageEntry se = repo.findStorageEntryById(id); |
||||||
|
repo.delete(se); |
||||||
|
return new ResponseEntity<>("Запись id#" + id + " удалена ... ", HttpStatus.OK); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package ru.molokoin.resourceserviceapi.entities; |
||||||
|
|
||||||
|
import jakarta.persistence.Entity; |
||||||
|
import jakarta.persistence.GeneratedValue; |
||||||
|
import jakarta.persistence.GenerationType; |
||||||
|
import jakarta.persistence.Id; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.NoArgsConstructor; |
||||||
|
|
||||||
|
@NoArgsConstructor |
||||||
|
@AllArgsConstructor |
||||||
|
@Entity |
||||||
|
@Data |
||||||
|
public class StorageEntry { |
||||||
|
@Id |
||||||
|
@GeneratedValue(strategy=GenerationType.AUTO) |
||||||
|
private long id; |
||||||
|
private String name;//наименование файла в файловой системе ({id}.{extension})
|
||||||
|
private String path;//путь в файловой системе (root/{id}.{extension})
|
||||||
|
private String extension;//расширение файла
|
||||||
|
private Long size;//размер файла
|
||||||
|
|
||||||
|
/** |
||||||
|
* Конструктор без id |
||||||
|
* @param name |
||||||
|
* @param path |
||||||
|
* @param extension |
||||||
|
* @param size |
||||||
|
*/ |
||||||
|
public StorageEntry(String name, String path, String extension, Long size) { |
||||||
|
this.name = name; |
||||||
|
this.path = path; |
||||||
|
this.extension = extension; |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
package ru.molokoin.resourceserviceapi.repositories; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.springframework.data.repository.ListCrudRepository; |
||||||
|
|
||||||
|
import ru.molokoin.resourceserviceapi.entities.StorageEntry; |
||||||
|
|
||||||
|
public interface StorageEntryFace extends ListCrudRepository<StorageEntry, Long>{ |
||||||
|
List<StorageEntry> findAll(); |
||||||
|
StorageEntry findStorageEntryById(long id); |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
HELP.md |
||||||
|
target/ |
||||||
|
!.mvn/wrapper/maven-wrapper.jar |
||||||
|
!**/src/main/**/target/ |
||||||
|
!**/src/test/**/target/ |
||||||
|
|
||||||
|
### STS ### |
||||||
|
.apt_generated |
||||||
|
.classpath |
||||||
|
.factorypath |
||||||
|
.project |
||||||
|
.settings |
||||||
|
.springBeans |
||||||
|
.sts4-cache |
||||||
|
|
||||||
|
### IntelliJ IDEA ### |
||||||
|
.idea |
||||||
|
*.iws |
||||||
|
*.iml |
||||||
|
*.ipr |
||||||
|
|
||||||
|
### NetBeans ### |
||||||
|
/nbproject/private/ |
||||||
|
/nbbuild/ |
||||||
|
/dist/ |
||||||
|
/nbdist/ |
||||||
|
/.nb-gradle/ |
||||||
|
build/ |
||||||
|
!**/src/main/**/build/ |
||||||
|
!**/src/test/**/build/ |
||||||
|
|
||||||
|
### VS Code ### |
||||||
|
.vscode/ |
@ -0,0 +1,18 @@ |
|||||||
|
# Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
# or more contributor license agreements. See the NOTICE file |
||||||
|
# distributed with this work for additional information |
||||||
|
# regarding copyright ownership. The ASF licenses this file |
||||||
|
# to you under the Apache License, Version 2.0 (the |
||||||
|
# "License"); you may not use this file except in compliance |
||||||
|
# with the License. You may obtain a copy of the License at |
||||||
|
# |
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
# |
||||||
|
# Unless required by applicable law or agreed to in writing, |
||||||
|
# software distributed under the License is distributed on an |
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
# KIND, either express or implied. See the License for the |
||||||
|
# specific language governing permissions and limitations |
||||||
|
# under the License. |
||||||
|
wrapperVersion=3.3.1 |
||||||
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip |
@ -0,0 +1,25 @@ |
|||||||
|
version: "3.7" |
||||||
|
services: |
||||||
|
storage-rs: |
||||||
|
container_name: storage-rs |
||||||
|
hostname: storage-rs |
||||||
|
build: |
||||||
|
context: ../storage-rs |
||||||
|
dockerfile: dockerfile |
||||||
|
image: "storage-rs" |
||||||
|
command: ["java","-jar","/app/storage-rs/storage-rs-0.0.1.jar"] |
||||||
|
ports: |
||||||
|
- 82:8282 |
||||||
|
restart: unless-stopped |
||||||
|
volumes: |
||||||
|
- tech_storage_rs:${DATA} |
||||||
|
networks: |
||||||
|
- tech_network |
||||||
|
volumes: |
||||||
|
tech_storage_rs: |
||||||
|
external: true |
||||||
|
networks: |
||||||
|
tech_network: |
||||||
|
name: tech_network |
||||||
|
external: true |
||||||
|
driver: bridge |
@ -0,0 +1,5 @@ |
|||||||
|
FROM openjdk:17-jdk-alpine |
||||||
|
RUN apk update |
||||||
|
RUN apk upgrade |
||||||
|
COPY target/storage-rs-0.0.1.jar /app/storage-rs/storage-rs-0.0.1.jar |
||||||
|
WORKDIR /app/storage-rs |
@ -0,0 +1,250 @@ |
|||||||
|
#!/bin/sh |
||||||
|
# ---------------------------------------------------------------------------- |
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
# or more contributor license agreements. See the NOTICE file |
||||||
|
# distributed with this work for additional information |
||||||
|
# regarding copyright ownership. The ASF licenses this file |
||||||
|
# to you under the Apache License, Version 2.0 (the |
||||||
|
# "License"); you may not use this file except in compliance |
||||||
|
# with the License. You may obtain a copy of the License at |
||||||
|
# |
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
# |
||||||
|
# Unless required by applicable law or agreed to in writing, |
||||||
|
# software distributed under the License is distributed on an |
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
# KIND, either express or implied. See the License for the |
||||||
|
# specific language governing permissions and limitations |
||||||
|
# under the License. |
||||||
|
# ---------------------------------------------------------------------------- |
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------- |
||||||
|
# Apache Maven Wrapper startup batch script, version 3.3.1 |
||||||
|
# |
||||||
|
# Optional ENV vars |
||||||
|
# ----------------- |
||||||
|
# JAVA_HOME - location of a JDK home dir, required when download maven via java source |
||||||
|
# MVNW_REPOURL - repo url base for downloading maven distribution |
||||||
|
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven |
||||||
|
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output |
||||||
|
# ---------------------------------------------------------------------------- |
||||||
|
|
||||||
|
set -euf |
||||||
|
[ "${MVNW_VERBOSE-}" != debug ] || set -x |
||||||
|
|
||||||
|
# OS specific support. |
||||||
|
native_path() { printf %s\\n "$1"; } |
||||||
|
case "$(uname)" in |
||||||
|
CYGWIN* | MINGW*) |
||||||
|
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" |
||||||
|
native_path() { cygpath --path --windows "$1"; } |
||||||
|
;; |
||||||
|
esac |
||||||
|
|
||||||
|
# set JAVACMD and JAVACCMD |
||||||
|
set_java_home() { |
||||||
|
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched |
||||||
|
if [ -n "${JAVA_HOME-}" ]; then |
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ]; then |
||||||
|
# IBM's JDK on AIX uses strange locations for the executables |
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java" |
||||||
|
JAVACCMD="$JAVA_HOME/jre/sh/javac" |
||||||
|
else |
||||||
|
JAVACMD="$JAVA_HOME/bin/java" |
||||||
|
JAVACCMD="$JAVA_HOME/bin/javac" |
||||||
|
|
||||||
|
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then |
||||||
|
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 |
||||||
|
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
fi |
||||||
|
else |
||||||
|
JAVACMD="$( |
||||||
|
'set' +e |
||||||
|
'unset' -f command 2>/dev/null |
||||||
|
'command' -v java |
||||||
|
)" || : |
||||||
|
JAVACCMD="$( |
||||||
|
'set' +e |
||||||
|
'unset' -f command 2>/dev/null |
||||||
|
'command' -v javac |
||||||
|
)" || : |
||||||
|
|
||||||
|
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then |
||||||
|
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
# hash string like Java String::hashCode |
||||||
|
hash_string() { |
||||||
|
str="${1:-}" h=0 |
||||||
|
while [ -n "$str" ]; do |
||||||
|
char="${str%"${str#?}"}" |
||||||
|
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) |
||||||
|
str="${str#?}" |
||||||
|
done |
||||||
|
printf %x\\n $h |
||||||
|
} |
||||||
|
|
||||||
|
verbose() { :; } |
||||||
|
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } |
||||||
|
|
||||||
|
die() { |
||||||
|
printf %s\\n "$1" >&2 |
||||||
|
exit 1 |
||||||
|
} |
||||||
|
|
||||||
|
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties |
||||||
|
while IFS="=" read -r key value; do |
||||||
|
case "${key-}" in |
||||||
|
distributionUrl) distributionUrl="${value-}" ;; |
||||||
|
distributionSha256Sum) distributionSha256Sum="${value-}" ;; |
||||||
|
esac |
||||||
|
done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" |
||||||
|
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" |
||||||
|
|
||||||
|
case "${distributionUrl##*/}" in |
||||||
|
maven-mvnd-*bin.*) |
||||||
|
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ |
||||||
|
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in |
||||||
|
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; |
||||||
|
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;; |
||||||
|
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;; |
||||||
|
:Linux*x86_64*) distributionPlatform=linux-amd64 ;; |
||||||
|
*) |
||||||
|
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 |
||||||
|
distributionPlatform=linux-amd64 |
||||||
|
;; |
||||||
|
esac |
||||||
|
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" |
||||||
|
;; |
||||||
|
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; |
||||||
|
*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; |
||||||
|
esac |
||||||
|
|
||||||
|
# apply MVNW_REPOURL and calculate MAVEN_HOME |
||||||
|
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash> |
||||||
|
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" |
||||||
|
distributionUrlName="${distributionUrl##*/}" |
||||||
|
distributionUrlNameMain="${distributionUrlName%.*}" |
||||||
|
distributionUrlNameMain="${distributionUrlNameMain%-bin}" |
||||||
|
MAVEN_HOME="$HOME/.m2/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" |
||||||
|
|
||||||
|
exec_maven() { |
||||||
|
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : |
||||||
|
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" |
||||||
|
} |
||||||
|
|
||||||
|
if [ -d "$MAVEN_HOME" ]; then |
||||||
|
verbose "found existing MAVEN_HOME at $MAVEN_HOME" |
||||||
|
exec_maven "$@" |
||||||
|
fi |
||||||
|
|
||||||
|
case "${distributionUrl-}" in |
||||||
|
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; |
||||||
|
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; |
||||||
|
esac |
||||||
|
|
||||||
|
# prepare tmp dir |
||||||
|
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then |
||||||
|
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } |
||||||
|
trap clean HUP INT TERM EXIT |
||||||
|
else |
||||||
|
die "cannot create temp dir" |
||||||
|
fi |
||||||
|
|
||||||
|
mkdir -p -- "${MAVEN_HOME%/*}" |
||||||
|
|
||||||
|
# Download and Install Apache Maven |
||||||
|
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." |
||||||
|
verbose "Downloading from: $distributionUrl" |
||||||
|
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" |
||||||
|
|
||||||
|
# select .zip or .tar.gz |
||||||
|
if ! command -v unzip >/dev/null; then |
||||||
|
distributionUrl="${distributionUrl%.zip}.tar.gz" |
||||||
|
distributionUrlName="${distributionUrl##*/}" |
||||||
|
fi |
||||||
|
|
||||||
|
# verbose opt |
||||||
|
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' |
||||||
|
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v |
||||||
|
|
||||||
|
# normalize http auth |
||||||
|
case "${MVNW_PASSWORD:+has-password}" in |
||||||
|
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; |
||||||
|
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; |
||||||
|
esac |
||||||
|
|
||||||
|
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then |
||||||
|
verbose "Found wget ... using wget" |
||||||
|
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" |
||||||
|
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then |
||||||
|
verbose "Found curl ... using curl" |
||||||
|
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" |
||||||
|
elif set_java_home; then |
||||||
|
verbose "Falling back to use Java to download" |
||||||
|
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" |
||||||
|
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" |
||||||
|
cat >"$javaSource" <<-END |
||||||
|
public class Downloader extends java.net.Authenticator |
||||||
|
{ |
||||||
|
protected java.net.PasswordAuthentication getPasswordAuthentication() |
||||||
|
{ |
||||||
|
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); |
||||||
|
} |
||||||
|
public static void main( String[] args ) throws Exception |
||||||
|
{ |
||||||
|
setDefault( new Downloader() ); |
||||||
|
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); |
||||||
|
} |
||||||
|
} |
||||||
|
END |
||||||
|
# For Cygwin/MinGW, switch paths to Windows format before running javac and java |
||||||
|
verbose " - Compiling Downloader.java ..." |
||||||
|
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" |
||||||
|
verbose " - Running Downloader.java ..." |
||||||
|
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" |
||||||
|
fi |
||||||
|
|
||||||
|
# If specified, validate the SHA-256 sum of the Maven distribution zip file |
||||||
|
if [ -n "${distributionSha256Sum-}" ]; then |
||||||
|
distributionSha256Result=false |
||||||
|
if [ "$MVN_CMD" = mvnd.sh ]; then |
||||||
|
echo "Checksum validation is not supported for maven-mvnd." >&2 |
||||||
|
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 |
||||||
|
exit 1 |
||||||
|
elif command -v sha256sum >/dev/null; then |
||||||
|
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then |
||||||
|
distributionSha256Result=true |
||||||
|
fi |
||||||
|
elif command -v shasum >/dev/null; then |
||||||
|
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then |
||||||
|
distributionSha256Result=true |
||||||
|
fi |
||||||
|
else |
||||||
|
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 |
||||||
|
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
if [ $distributionSha256Result = false ]; then |
||||||
|
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 |
||||||
|
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
fi |
||||||
|
|
||||||
|
# unzip and move |
||||||
|
if command -v unzip >/dev/null; then |
||||||
|
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" |
||||||
|
else |
||||||
|
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" |
||||||
|
fi |
||||||
|
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" |
||||||
|
mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" |
||||||
|
|
||||||
|
clean || : |
||||||
|
exec_maven "$@" |
@ -0,0 +1,146 @@ |
|||||||
|
<# : batch portion |
||||||
|
@REM ---------------------------------------------------------------------------- |
||||||
|
@REM Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
@REM or more contributor license agreements. See the NOTICE file |
||||||
|
@REM distributed with this work for additional information |
||||||
|
@REM regarding copyright ownership. The ASF licenses this file |
||||||
|
@REM to you under the Apache License, Version 2.0 (the |
||||||
|
@REM "License"); you may not use this file except in compliance |
||||||
|
@REM with the License. You may obtain a copy of the License at |
||||||
|
@REM |
||||||
|
@REM https://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
@REM |
||||||
|
@REM Unless required by applicable law or agreed to in writing, |
||||||
|
@REM software distributed under the License is distributed on an |
||||||
|
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
@REM KIND, either express or implied. See the License for the |
||||||
|
@REM specific language governing permissions and limitations |
||||||
|
@REM under the License. |
||||||
|
@REM ---------------------------------------------------------------------------- |
||||||
|
|
||||||
|
@REM ---------------------------------------------------------------------------- |
||||||
|
@REM Apache Maven Wrapper startup batch script, version 3.3.1 |
||||||
|
@REM |
||||||
|
@REM Optional ENV vars |
||||||
|
@REM MVNW_REPOURL - repo url base for downloading maven distribution |
||||||
|
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven |
||||||
|
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output |
||||||
|
@REM ---------------------------------------------------------------------------- |
||||||
|
|
||||||
|
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) |
||||||
|
@SET __MVNW_CMD__= |
||||||
|
@SET __MVNW_ERROR__= |
||||||
|
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% |
||||||
|
@SET PSModulePath= |
||||||
|
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( |
||||||
|
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) |
||||||
|
) |
||||||
|
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% |
||||||
|
@SET __MVNW_PSMODULEP_SAVE= |
||||||
|
@SET __MVNW_ARG0_NAME__= |
||||||
|
@SET MVNW_USERNAME= |
||||||
|
@SET MVNW_PASSWORD= |
||||||
|
@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) |
||||||
|
@echo Cannot start maven from wrapper >&2 && exit /b 1 |
||||||
|
@GOTO :EOF |
||||||
|
: end batch / begin powershell #> |
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop" |
||||||
|
if ($env:MVNW_VERBOSE -eq "true") { |
||||||
|
$VerbosePreference = "Continue" |
||||||
|
} |
||||||
|
|
||||||
|
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties |
||||||
|
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl |
||||||
|
if (!$distributionUrl) { |
||||||
|
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" |
||||||
|
} |
||||||
|
|
||||||
|
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { |
||||||
|
"maven-mvnd-*" { |
||||||
|
$USE_MVND = $true |
||||||
|
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" |
||||||
|
$MVN_CMD = "mvnd.cmd" |
||||||
|
break |
||||||
|
} |
||||||
|
default { |
||||||
|
$USE_MVND = $false |
||||||
|
$MVN_CMD = $script -replace '^mvnw','mvn' |
||||||
|
break |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
# apply MVNW_REPOURL and calculate MAVEN_HOME |
||||||
|
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash> |
||||||
|
if ($env:MVNW_REPOURL) { |
||||||
|
$MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } |
||||||
|
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" |
||||||
|
} |
||||||
|
$distributionUrlName = $distributionUrl -replace '^.*/','' |
||||||
|
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' |
||||||
|
$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" |
||||||
|
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' |
||||||
|
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" |
||||||
|
|
||||||
|
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { |
||||||
|
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" |
||||||
|
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" |
||||||
|
exit $? |
||||||
|
} |
||||||
|
|
||||||
|
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { |
||||||
|
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" |
||||||
|
} |
||||||
|
|
||||||
|
# prepare tmp dir |
||||||
|
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile |
||||||
|
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" |
||||||
|
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null |
||||||
|
trap { |
||||||
|
if ($TMP_DOWNLOAD_DIR.Exists) { |
||||||
|
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } |
||||||
|
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null |
||||||
|
|
||||||
|
# Download and Install Apache Maven |
||||||
|
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." |
||||||
|
Write-Verbose "Downloading from: $distributionUrl" |
||||||
|
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" |
||||||
|
|
||||||
|
$webclient = New-Object System.Net.WebClient |
||||||
|
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { |
||||||
|
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) |
||||||
|
} |
||||||
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 |
||||||
|
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null |
||||||
|
|
||||||
|
# If specified, validate the SHA-256 sum of the Maven distribution zip file |
||||||
|
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum |
||||||
|
if ($distributionSha256Sum) { |
||||||
|
if ($USE_MVND) { |
||||||
|
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." |
||||||
|
} |
||||||
|
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash |
||||||
|
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { |
||||||
|
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
# unzip and move |
||||||
|
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null |
||||||
|
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null |
||||||
|
try { |
||||||
|
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null |
||||||
|
} catch { |
||||||
|
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { |
||||||
|
Write-Error "fail to move MAVEN_HOME" |
||||||
|
} |
||||||
|
} finally { |
||||||
|
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } |
||||||
|
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } |
||||||
|
} |
||||||
|
|
||||||
|
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" |
@ -1,4 +1,4 @@ |
|||||||
package ru.molokoin.storage_rs.config; |
package ru.molokoin.storagers.config; |
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties; |
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||||
|
|
@ -0,0 +1,198 @@ |
|||||||
|
package ru.molokoin.storagers.controller; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus; |
||||||
|
import org.springframework.http.ResponseEntity; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.ui.Model; |
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping; |
||||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||||
|
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.bind.annotation.RequestParam; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
import ru.molokoin.storagers.model.DocumentModel; |
||||||
|
import ru.molokoin.storagers.model.XlsxDocument; |
||||||
|
import ru.molokoin.storagers.service.StorageServiceFace; |
||||||
|
|
||||||
|
/** |
||||||
|
* Контроллер для работы с файловой системой контейнера |
||||||
|
* - получение |
||||||
|
* - хранение |
||||||
|
* - передача |
||||||
|
* файлов пользователя/сторонего сервиса |
||||||
|
*/ |
||||||
|
@Controller |
||||||
|
@RequestMapping(path = "/", consumes = {"*/*"}) |
||||||
|
public class StorageController { |
||||||
|
/** |
||||||
|
* Подключаем сервис доступа к базе даных |
||||||
|
*/ |
||||||
|
// private DocumentFace database;
|
||||||
|
|
||||||
|
/** |
||||||
|
* получаем в переменную root |
||||||
|
* значение свойства storage.location |
||||||
|
* из файла application.yaml |
||||||
|
*/ |
||||||
|
private StorageServiceFace storage; |
||||||
|
|
||||||
|
/** |
||||||
|
* Конструктор контроллера, дня инициализации объекта хранилища |
||||||
|
* - передается интерфейс |
||||||
|
* @param storage |
||||||
|
*/ |
||||||
|
public StorageController(StorageServiceFace storage){ |
||||||
|
this.storage = storage; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Загружаем файл пользователя и возвращаем список файлов на сервере |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@PostMapping("/upload") |
||||||
|
public String upload(@RequestParam("file") MultipartFile file){ |
||||||
|
if (file.isEmpty() != true){ |
||||||
|
//добавляем перед именем файла идентификатор
|
||||||
|
String filename = storage.list().size() + "." + file.getOriginalFilename() + ""; |
||||||
|
storage.store(file, filename); |
||||||
|
}else { |
||||||
|
System.out.println("Попытка загрузить пустой файл!!!"); |
||||||
|
} |
||||||
|
return "redirect:/uploads"; |
||||||
|
} |
||||||
|
|
||||||
|
public String prefix(String input){ |
||||||
|
String[] tokens = input.split("\\."); |
||||||
|
List<String> list = Arrays.asList(tokens); |
||||||
|
return list.get(0); |
||||||
|
} |
||||||
|
|
||||||
|
public String ext(String filename){ |
||||||
|
String[] tokens = filename.split("\\."); |
||||||
|
List<String> list = Arrays.asList(tokens); |
||||||
|
int i = list.size(); |
||||||
|
return list.get(i - 1); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Возвращаем пользователю список файлов с сервера |
||||||
|
* @param model |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@GetMapping("/uploads") |
||||||
|
public String list(Model model){ |
||||||
|
model.addAttribute("documents", storage.list()); |
||||||
|
return "documents"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Удаление файла по имени из хранилища |
||||||
|
* @param name |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@GetMapping("/delete/{name}") |
||||||
|
public String deleteByName(@PathVariable String name) { |
||||||
|
storage.delete(name); |
||||||
|
return "redirect:/uploads"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* id содержится в имени файла |
||||||
|
* - по id найти имя файла и вызвать метод удаления по имени |
||||||
|
* @param id |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
// @GetMapping("/delete/by-id/{id}")
|
||||||
|
// public String deleteById(@PathVariable Long id) {
|
||||||
|
// storage.delete(id);
|
||||||
|
// return "redirect:/uploads";
|
||||||
|
// }
|
||||||
|
|
||||||
|
/** |
||||||
|
* Просмотр содержимого xlsx-файла |
||||||
|
* @param name |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@GetMapping("/view/{name}") |
||||||
|
public String view(Model model, @PathVariable String name) { |
||||||
|
DocumentModel doc = storage.find(name); |
||||||
|
XlsxDocument xlsx = new XlsxDocument(doc); |
||||||
|
model.addAttribute("filename", xlsx.getDocument().getName()); |
||||||
|
model.addAttribute("xlsx", xlsx.getData()); |
||||||
|
model.addAttribute("headers", xlsx.getHeaders()); |
||||||
|
return "view"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Экспорт данных из xlsx файла в базу данных |
||||||
|
* - получение данных из xlsx |
||||||
|
* - формирование запросов к сервису ресурсов, для публикации данных в базе |
||||||
|
* |
||||||
|
* @param name |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@GetMapping("/export-as-educations/{name}") |
||||||
|
public String exportAsEducations(@PathVariable String name){ |
||||||
|
|
||||||
|
return "redirect:/uploads"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* API |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* Получение списка загруженных на сервер файлов в json формате |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@GetMapping("/api/list-uploads") |
||||||
|
public ResponseEntity<List<DocumentModel>> getUploads(){ |
||||||
|
return new ResponseEntity<>(storage.list(), HttpStatus.OK); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Получение метаданных о файле |
||||||
|
* @param filename |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@GetMapping("/api/document/{filename}") |
||||||
|
public ResponseEntity<?> getDocumentByName(@PathVariable String filename){ |
||||||
|
return new ResponseEntity<>(storage.find(filename), HttpStatus.OK); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Получение содержимого файла в json формате |
||||||
|
* @param filename |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@GetMapping("/api/document/content/{filename}") |
||||||
|
public ResponseEntity<?> getDocumentContentByName(@PathVariable String filename){ |
||||||
|
DocumentModel doc = storage.find(filename); |
||||||
|
XlsxDocument xlsx = new XlsxDocument(doc); |
||||||
|
return new ResponseEntity<>(xlsx, HttpStatus.OK); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Удаление файла по имени |
||||||
|
*/ |
||||||
|
@DeleteMapping("/api/document/delete/{filename}") |
||||||
|
public ResponseEntity<Boolean> deleteProgram(@PathVariable String filename){ |
||||||
|
return new ResponseEntity<>(storage.delete(filename), HttpStatus.OK); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Загрузка файла на сервер |
||||||
|
* @param file |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@PostMapping("/api/document/store") |
||||||
|
public ResponseEntity<Boolean> store(@RequestParam("file") MultipartFile file){ |
||||||
|
return new ResponseEntity<>(storage.store(file, file.getOriginalFilename()), HttpStatus.OK); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,157 @@ |
|||||||
|
package ru.molokoin.storagers.model; |
||||||
|
|
||||||
|
// import lombok.AllArgsConstructor;
|
||||||
|
// import lombok.Data;
|
||||||
|
// import lombok.Getter;
|
||||||
|
// import lombok.NoArgsConstructor;
|
||||||
|
// import lombok.Setter;
|
||||||
|
|
||||||
|
// @Getter
|
||||||
|
// @Setter
|
||||||
|
// @AllArgsConstructor
|
||||||
|
// @NoArgsConstructor
|
||||||
|
public class DocumentModel { |
||||||
|
private Long id; |
||||||
|
private String name;//наименование файла в файловой системе ({id}.{extension})
|
||||||
|
private String path;//путь в файловой системе (root/{id}.{extension})
|
||||||
|
private String extension;//расширение файла
|
||||||
|
private Long size;//размер файла
|
||||||
|
/** |
||||||
|
* @return the name |
||||||
|
*/ |
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
/** |
||||||
|
* @param name the name to set |
||||||
|
*/ |
||||||
|
public void setName(String name) { |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
/** |
||||||
|
* @return the path |
||||||
|
*/ |
||||||
|
public String getPath() { |
||||||
|
return path; |
||||||
|
} |
||||||
|
/** |
||||||
|
* @param path the path to set |
||||||
|
*/ |
||||||
|
public void setPath(String path) { |
||||||
|
this.path = path; |
||||||
|
} |
||||||
|
/** |
||||||
|
* @return the extension |
||||||
|
*/ |
||||||
|
public String getExtension() { |
||||||
|
return extension; |
||||||
|
} |
||||||
|
/** |
||||||
|
* @param extension the extension to set |
||||||
|
*/ |
||||||
|
public void setExtension(String extension) { |
||||||
|
this.extension = extension; |
||||||
|
} |
||||||
|
/** |
||||||
|
* @return the size |
||||||
|
*/ |
||||||
|
public Long getSize() { |
||||||
|
return size; |
||||||
|
} |
||||||
|
/** |
||||||
|
* @param size the size to set |
||||||
|
*/ |
||||||
|
public void setSize(Long size) { |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
/** |
||||||
|
* |
||||||
|
*/ |
||||||
|
public DocumentModel() { |
||||||
|
} |
||||||
|
/** |
||||||
|
* @param name |
||||||
|
* @param path |
||||||
|
* @param extension |
||||||
|
* @param size |
||||||
|
*/ |
||||||
|
public DocumentModel(String name, String path, String extension, Long size) { |
||||||
|
this.name = name; |
||||||
|
this.path = path; |
||||||
|
this.extension = extension; |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
@Override |
||||||
|
public int hashCode() { |
||||||
|
final int prime = 31; |
||||||
|
int result = 1; |
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode()); |
||||||
|
result = prime * result + ((path == null) ? 0 : path.hashCode()); |
||||||
|
result = prime * result + ((extension == null) ? 0 : extension.hashCode()); |
||||||
|
result = prime * result + ((size == null) ? 0 : size.hashCode()); |
||||||
|
return result; |
||||||
|
} |
||||||
|
@Override |
||||||
|
public boolean equals(Object obj) { |
||||||
|
if (this == obj) |
||||||
|
return true; |
||||||
|
if (obj == null) |
||||||
|
return false; |
||||||
|
if (getClass() != obj.getClass()) |
||||||
|
return false; |
||||||
|
DocumentModel other = (DocumentModel) obj; |
||||||
|
if (name == null) { |
||||||
|
if (other.name != null) |
||||||
|
return false; |
||||||
|
} else if (!name.equals(other.name)) |
||||||
|
return false; |
||||||
|
if (path == null) { |
||||||
|
if (other.path != null) |
||||||
|
return false; |
||||||
|
} else if (!path.equals(other.path)) |
||||||
|
return false; |
||||||
|
if (extension == null) { |
||||||
|
if (other.extension != null) |
||||||
|
return false; |
||||||
|
} else if (!extension.equals(other.extension)) |
||||||
|
return false; |
||||||
|
if (size == null) { |
||||||
|
if (other.size != null) |
||||||
|
return false; |
||||||
|
} else if (!size.equals(other.size)) |
||||||
|
return false; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the id |
||||||
|
*/ |
||||||
|
public Long getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
/** |
||||||
|
* @param id the id to set |
||||||
|
*/ |
||||||
|
public void setId(Long id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
/** |
||||||
|
* @param id |
||||||
|
* @param name |
||||||
|
* @param path |
||||||
|
* @param extension |
||||||
|
* @param size |
||||||
|
*/ |
||||||
|
public DocumentModel(Long id, String name, String path, String extension, Long size) { |
||||||
|
this.id = id; |
||||||
|
this.name = name; |
||||||
|
this.path = path; |
||||||
|
this.extension = extension; |
||||||
|
this.size = size; |
||||||
|
} |
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "DocumentModel [id=" + id + ", name=" + name + ", path=" + path + ", extension=" + extension + ", size=" |
||||||
|
+ size + "]"; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,186 @@ |
|||||||
|
package ru.molokoin.storagers.model; |
||||||
|
|
||||||
|
// import lombok.AllArgsConstructor;
|
||||||
|
// import lombok.Data;
|
||||||
|
// import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
// @Data
|
||||||
|
// @AllArgsConstructor
|
||||||
|
// @NoArgsConstructor
|
||||||
|
public class XlsxCell { |
||||||
|
private String content; //содержимое ячейки
|
||||||
|
private String textColor; //цвет шрифта
|
||||||
|
private String bgColor; // цвет заливки ячейки
|
||||||
|
private String textSize; //8-12-14-24 размеры шрифта
|
||||||
|
private int textWeight; //жирность: bold (900), normal(500),
|
||||||
|
private String type;// STRING, NUMERIC, BOOLEAN, FORMULA
|
||||||
|
|
||||||
|
public XlsxCell(String content){ |
||||||
|
this.content = content; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the content |
||||||
|
*/ |
||||||
|
public String getContent() { |
||||||
|
return content; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param content the content to set |
||||||
|
*/ |
||||||
|
public void setContent(String content) { |
||||||
|
this.content = content; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the textColor |
||||||
|
*/ |
||||||
|
public String getTextColor() { |
||||||
|
return textColor; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param textColor the textColor to set |
||||||
|
*/ |
||||||
|
public void setTextColor(String textColor) { |
||||||
|
this.textColor = textColor; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the bgColor |
||||||
|
*/ |
||||||
|
public String getBgColor() { |
||||||
|
return bgColor; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param bgColor the bgColor to set |
||||||
|
*/ |
||||||
|
public void setBgColor(String bgColor) { |
||||||
|
this.bgColor = bgColor; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the textSize |
||||||
|
*/ |
||||||
|
public String getTextSize() { |
||||||
|
return textSize; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param textSize the textSize to set |
||||||
|
*/ |
||||||
|
public void setTextSize(String textSize) { |
||||||
|
this.textSize = textSize; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the textWeight |
||||||
|
*/ |
||||||
|
public int getTextWeight() { |
||||||
|
return textWeight; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param textWeight the textWeight to set |
||||||
|
*/ |
||||||
|
public void setTextWeight(int textWeight) { |
||||||
|
this.textWeight = textWeight; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the type |
||||||
|
*/ |
||||||
|
public String getType() { |
||||||
|
return type; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param type the type to set |
||||||
|
*/ |
||||||
|
public void setType(String type) { |
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int hashCode() { |
||||||
|
final int prime = 31; |
||||||
|
int result = 1; |
||||||
|
result = prime * result + ((content == null) ? 0 : content.hashCode()); |
||||||
|
result = prime * result + ((textColor == null) ? 0 : textColor.hashCode()); |
||||||
|
result = prime * result + ((bgColor == null) ? 0 : bgColor.hashCode()); |
||||||
|
result = prime * result + ((textSize == null) ? 0 : textSize.hashCode()); |
||||||
|
result = prime * result + textWeight; |
||||||
|
result = prime * result + ((type == null) ? 0 : type.hashCode()); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean equals(Object obj) { |
||||||
|
if (this == obj) |
||||||
|
return true; |
||||||
|
if (obj == null) |
||||||
|
return false; |
||||||
|
if (getClass() != obj.getClass()) |
||||||
|
return false; |
||||||
|
XlsxCell other = (XlsxCell) obj; |
||||||
|
if (content == null) { |
||||||
|
if (other.content != null) |
||||||
|
return false; |
||||||
|
} else if (!content.equals(other.content)) |
||||||
|
return false; |
||||||
|
if (textColor == null) { |
||||||
|
if (other.textColor != null) |
||||||
|
return false; |
||||||
|
} else if (!textColor.equals(other.textColor)) |
||||||
|
return false; |
||||||
|
if (bgColor == null) { |
||||||
|
if (other.bgColor != null) |
||||||
|
return false; |
||||||
|
} else if (!bgColor.equals(other.bgColor)) |
||||||
|
return false; |
||||||
|
if (textSize == null) { |
||||||
|
if (other.textSize != null) |
||||||
|
return false; |
||||||
|
} else if (!textSize.equals(other.textSize)) |
||||||
|
return false; |
||||||
|
if (textWeight != other.textWeight) |
||||||
|
return false; |
||||||
|
if (type == null) { |
||||||
|
if (other.type != null) |
||||||
|
return false; |
||||||
|
} else if (!type.equals(other.type)) |
||||||
|
return false; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "XlsxCell [content=" + content + ", textColor=" + textColor + ", bgColor=" + bgColor + ", textSize=" |
||||||
|
+ textSize + ", textWeight=" + textWeight + ", type=" + type + "]"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
*/ |
||||||
|
public XlsxCell() { |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param content |
||||||
|
* @param textColor |
||||||
|
* @param bgColor |
||||||
|
* @param textSize |
||||||
|
* @param textWeight |
||||||
|
* @param type |
||||||
|
*/ |
||||||
|
public XlsxCell(String content, String textColor, String bgColor, String textSize, int textWeight, String type) { |
||||||
|
this.content = content; |
||||||
|
this.textColor = textColor; |
||||||
|
this.bgColor = bgColor; |
||||||
|
this.textSize = textSize; |
||||||
|
this.textWeight = textWeight; |
||||||
|
this.type = type; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,209 @@ |
|||||||
|
package ru.molokoin.storagers.model; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.FileInputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.Cell; |
||||||
|
import org.apache.poi.ss.usermodel.Row; |
||||||
|
import org.apache.poi.ss.usermodel.Sheet; |
||||||
|
import org.apache.poi.ss.usermodel.Workbook; |
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
||||||
|
|
||||||
|
// import lombok.AllArgsConstructor;
|
||||||
|
// import lombok.Data;
|
||||||
|
// import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
// @Data
|
||||||
|
// @AllArgsConstructor
|
||||||
|
// @NoArgsConstructor
|
||||||
|
public class XlsxDocument implements Serializable{ |
||||||
|
private Map<Integer, List<XlsxCell>> data; |
||||||
|
private DocumentModel document; |
||||||
|
private List<XlsxCell> headers;//верхняя строка формы
|
||||||
|
|
||||||
|
public XlsxDocument(DocumentModel document){ |
||||||
|
this.document = document; |
||||||
|
this.data = init(document); |
||||||
|
this.headers = data.get(0); |
||||||
|
} |
||||||
|
|
||||||
|
private Map<Integer, List<XlsxCell>> init(DocumentModel document) { |
||||||
|
FileInputStream file; |
||||||
|
Workbook workbook; |
||||||
|
try { |
||||||
|
file = new FileInputStream(new File(document.getPath())); |
||||||
|
workbook = new XSSFWorkbook(file); |
||||||
|
|
||||||
|
Sheet sheet = workbook.getSheetAt(0); |
||||||
|
data = new HashMap<>(); |
||||||
|
Integer i = 0; |
||||||
|
|
||||||
|
//перебор строк
|
||||||
|
int rowStart = sheet.getFirstRowNum(); |
||||||
|
int rowEnd = sheet.getLastRowNum(); |
||||||
|
for (int rowNum = rowStart; rowNum < rowEnd; rowNum++){ |
||||||
|
Row r = sheet.getRow(rowNum); |
||||||
|
if (r != null) { |
||||||
|
//перебор ячеек в строке
|
||||||
|
List<XlsxCell> xlsxCells = new ArrayList<>(); |
||||||
|
XlsxCell xlsxCell = null; |
||||||
|
int lastColumn = r.getLastCellNum(); |
||||||
|
for (int cn = 0; cn < lastColumn; cn++){ |
||||||
|
Cell cell = r.getCell(cn); |
||||||
|
if (cell == null) { |
||||||
|
//обработка нулевой ячейки
|
||||||
|
xlsxCell = new XlsxCell(""); |
||||||
|
xlsxCell.setType("NULL"); |
||||||
|
} else { |
||||||
|
//обработка ячейки
|
||||||
|
switch (cell.getCellType()) { |
||||||
|
case STRING: { |
||||||
|
xlsxCell = new XlsxCell(cell.getStringCellValue() + ""); |
||||||
|
xlsxCell.setType("STRING"); |
||||||
|
} break; |
||||||
|
case NUMERIC: { |
||||||
|
xlsxCell = new XlsxCell(cell.getNumericCellValue() + ""); |
||||||
|
xlsxCell.setType("NUMERIC"); |
||||||
|
} break; |
||||||
|
case BOOLEAN: { |
||||||
|
xlsxCell = new XlsxCell(cell.getBooleanCellValue() + ""); |
||||||
|
xlsxCell.setType("BOOLEAN"); |
||||||
|
} break; |
||||||
|
case FORMULA: { |
||||||
|
xlsxCell = new XlsxCell(cell.getCellFormula() + ""); |
||||||
|
xlsxCell = new XlsxCell("FORMULA"); |
||||||
|
xlsxCell.setType("FORMULA"); |
||||||
|
} break; |
||||||
|
case BLANK: { |
||||||
|
xlsxCell = new XlsxCell(""); |
||||||
|
xlsxCell.setType("BLANK"); |
||||||
|
} break; |
||||||
|
case ERROR: { |
||||||
|
xlsxCell = new XlsxCell(""); |
||||||
|
xlsxCell.setType("ERROR"); |
||||||
|
} break; |
||||||
|
case _NONE: { |
||||||
|
xlsxCell = new XlsxCell(""); |
||||||
|
xlsxCell.setType("_NONE"); |
||||||
|
} break; |
||||||
|
} |
||||||
|
} |
||||||
|
xlsxCells.add(xlsxCell); |
||||||
|
} |
||||||
|
data.put(rowNum, xlsxCells); |
||||||
|
} |
||||||
|
} |
||||||
|
}catch (IOException e) { |
||||||
|
System.out.println("Не читается файл: " + e.getMessage()); |
||||||
|
} |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the data |
||||||
|
*/ |
||||||
|
public Map<Integer, List<XlsxCell>> getData() { |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param data the data to set |
||||||
|
*/ |
||||||
|
public void setData(Map<Integer, List<XlsxCell>> data) { |
||||||
|
this.data = data; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the document |
||||||
|
*/ |
||||||
|
public DocumentModel getDocument() { |
||||||
|
return document; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param document the document to set |
||||||
|
*/ |
||||||
|
public void setDocument(DocumentModel document) { |
||||||
|
this.document = document; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return the headers |
||||||
|
*/ |
||||||
|
public List<XlsxCell> getHeaders() { |
||||||
|
return headers; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param headers the headers to set |
||||||
|
*/ |
||||||
|
public void setHeaders(List<XlsxCell> headers) { |
||||||
|
this.headers = headers; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int hashCode() { |
||||||
|
final int prime = 31; |
||||||
|
int result = 1; |
||||||
|
result = prime * result + ((data == null) ? 0 : data.hashCode()); |
||||||
|
result = prime * result + ((document == null) ? 0 : document.hashCode()); |
||||||
|
result = prime * result + ((headers == null) ? 0 : headers.hashCode()); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean equals(Object obj) { |
||||||
|
if (this == obj) |
||||||
|
return true; |
||||||
|
if (obj == null) |
||||||
|
return false; |
||||||
|
if (getClass() != obj.getClass()) |
||||||
|
return false; |
||||||
|
XlsxDocument other = (XlsxDocument) obj; |
||||||
|
if (data == null) { |
||||||
|
if (other.data != null) |
||||||
|
return false; |
||||||
|
} else if (!data.equals(other.data)) |
||||||
|
return false; |
||||||
|
if (document == null) { |
||||||
|
if (other.document != null) |
||||||
|
return false; |
||||||
|
} else if (!document.equals(other.document)) |
||||||
|
return false; |
||||||
|
if (headers == null) { |
||||||
|
if (other.headers != null) |
||||||
|
return false; |
||||||
|
} else if (!headers.equals(other.headers)) |
||||||
|
return false; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "XlsxDocument [data=" + data + ", document=" + document + ", headers=" + headers + "]"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param data |
||||||
|
* @param document |
||||||
|
* @param headers |
||||||
|
*/ |
||||||
|
public XlsxDocument(Map<Integer, List<XlsxCell>> data, DocumentModel document, List<XlsxCell> headers) { |
||||||
|
this.data = data; |
||||||
|
this.document = document; |
||||||
|
this.headers = headers; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
*/ |
||||||
|
public XlsxDocument() { |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,6 +1,6 @@ |
|||||||
spring: |
spring: |
||||||
application: |
application: |
||||||
name: storage_rs |
name: storage-rs |
||||||
jpa: |
jpa: |
||||||
hibernate: |
hibernate: |
||||||
ddl-auto: update |
ddl-auto: update |
@ -1,4 +1,4 @@ |
|||||||
# storage_rs |
# storageRS |
||||||
Сервис работы с файлами: |
Сервис работы с файлами: |
||||||
- загрузка файлов на сервер |
- загрузка файлов на сервер |
||||||
- скачивание файлов с сервера |
- скачивание файлов с сервера |
@ -0,0 +1,44 @@ |
|||||||
|
<!DOCTYPE HTML> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>Uploads</title> |
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script> |
||||||
|
<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script> |
||||||
|
</head> |
||||||
|
|
||||||
|
<body> |
||||||
|
<header> |
||||||
|
<h1>View</h1> |
||||||
|
menu : auth : View |
||||||
|
<br> |
||||||
|
</header> |
||||||
|
<main> |
||||||
|
<div class="main-wraper"> |
||||||
|
<table> |
||||||
|
<caption th:text="${filename}"></caption> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th th:each="header : ${headers}"> |
||||||
|
<span th:text="${header.content}"></span> |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr th:each="row: ${xlsx.values()}"> |
||||||
|
<td> |
||||||
|
<span th:text="${rowStat.count}"></span> |
||||||
|
</td> |
||||||
|
<td th:if="${rowStat.count} > 1" th:each="cell : ${row}"> |
||||||
|
<!-- <span th:text="${cellStat.count}"></span> |
||||||
|
<br><br> --> |
||||||
|
<span th:text="${cell.content}"></span> |
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</main> |
||||||
|
</body> |
||||||
|
</html> |
@ -1,4 +1,4 @@ |
|||||||
package ru.molokoin.storage_rs; |
package ru.molokoin.storagers; |
||||||
|
|
||||||
import org.junit.jupiter.api.Test; |
import org.junit.jupiter.api.Test; |
||||||
import org.springframework.boot.test.context.SpringBootTest; |
import org.springframework.boot.test.context.SpringBootTest; |
@ -1,21 +0,0 @@ |
|||||||
version: "3.7" |
|
||||||
services: |
|
||||||
storage_rs: |
|
||||||
build: |
|
||||||
context: ../storage_rs |
|
||||||
dockerfile: dockerfile |
|
||||||
image: "storage_rs" |
|
||||||
command: ["java","-jar","/app/storage_rs/storage_rs-0.0.1.jar"] |
|
||||||
ports: |
|
||||||
- 82:8282 |
|
||||||
restart: unless-stopped |
|
||||||
volumes: |
|
||||||
- tech_storage_rs:${DATA} |
|
||||||
volumes: |
|
||||||
tech_storage_rs: |
|
||||||
external: true |
|
||||||
networks: |
|
||||||
default: |
|
||||||
external: |
|
||||||
name: tech_network |
|
||||||
driver: bridge |
|
@ -1,5 +0,0 @@ |
|||||||
FROM openjdk:17-jdk-alpine |
|
||||||
RUN apk update |
|
||||||
RUN apk upgrade |
|
||||||
COPY target/storage_rs-0.0.1.jar /app/storage_rs/storage_rs-0.0.1.jar |
|
||||||
WORKDIR /app/storage_rs |
|
@ -1,5 +0,0 @@ |
|||||||
package ru.molokoin.storage_rs.controller; |
|
||||||
|
|
||||||
public class ChohortController { |
|
||||||
|
|
||||||
} |
|
@ -1,95 +0,0 @@ |
|||||||
package ru.molokoin.storage_rs.controller; |
|
||||||
|
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller; |
|
||||||
import org.springframework.ui.Model; |
|
||||||
import org.springframework.web.bind.annotation.GetMapping; |
|
||||||
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.bind.annotation.RequestParam; |
|
||||||
import org.springframework.web.multipart.MultipartFile; |
|
||||||
|
|
||||||
import ru.molokoin.storage_rs.model.Document; |
|
||||||
import ru.molokoin.storage_rs.model.XlsxCell; |
|
||||||
import ru.molokoin.storage_rs.model.XlsxDocument; |
|
||||||
import ru.molokoin.storage_rs.service.StorageServiceFace; |
|
||||||
|
|
||||||
/** |
|
||||||
* Контроллер для работы с файловой системой контейнера |
|
||||||
* - получение |
|
||||||
* - хранение |
|
||||||
* - передача |
|
||||||
* файлов пользователя/сторонего сервиса |
|
||||||
*/ |
|
||||||
@Controller |
|
||||||
@RequestMapping(path = "/", consumes = {"*/*"}) |
|
||||||
public class StorageController { |
|
||||||
/** |
|
||||||
* получаем в переменную root |
|
||||||
* значение свойства storage.location |
|
||||||
* из файла application.yaml |
|
||||||
*/ |
|
||||||
private StorageServiceFace storage; |
|
||||||
|
|
||||||
/** |
|
||||||
* Конструктор контроллера, дня инициализации объекта хранилища |
|
||||||
* - передается интерфейс |
|
||||||
* @param storage |
|
||||||
*/ |
|
||||||
public StorageController(StorageServiceFace storage){ |
|
||||||
this.storage = storage; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Загружаем файл пользователя и возвращаем список файлов на сервере |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
@PostMapping("/upload") |
|
||||||
public String upload(@RequestParam("file") MultipartFile file){ |
|
||||||
storage.store(file); |
|
||||||
return "redirect:/uploads"; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Возвращаем пользователю список файлов с сервера |
|
||||||
* @param model |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
@GetMapping("/uploads") |
|
||||||
public String list(Model model){ |
|
||||||
model.addAttribute("documents", storage.list()); |
|
||||||
return "documents"; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Удаление файла из хранилища |
|
||||||
* @param name |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
@GetMapping("/delete/{name}") |
|
||||||
public String delete(@PathVariable String name) { |
|
||||||
storage.delete(name); |
|
||||||
return "redirect:/uploads"; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Удаление файла из хранилища |
|
||||||
* @param name |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
@GetMapping("/view/{name}") |
|
||||||
public String view(@PathVariable String name) { |
|
||||||
Document doc = storage.find(name); |
|
||||||
XlsxDocument xlsx = new XlsxDocument(doc); |
|
||||||
for (List<XlsxCell> row : xlsx.getData().values()) { |
|
||||||
for (XlsxCell xlsxCell : row) { |
|
||||||
System.out.println(xlsxCell.getContent()); |
|
||||||
} |
|
||||||
} |
|
||||||
return "redirect:/uploads"; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
@ -1,79 +0,0 @@ |
|||||||
package ru.molokoin.storage_rs.model; |
|
||||||
|
|
||||||
public class Document { |
|
||||||
private String name;//наименование файла в файловой системе ({id}.{extension})
|
|
||||||
private String path;//путь в файловой системе (root/{id}.{extension})
|
|
||||||
private String extension;//расширение файла
|
|
||||||
private Long size;//размер файла
|
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* |
|
||||||
*/ |
|
||||||
public Document() { |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* @param name |
|
||||||
* @param path |
|
||||||
* @param extension |
|
||||||
* @param size |
|
||||||
*/ |
|
||||||
public Document(String name, String path, String extension, long size) { |
|
||||||
this.name = name; |
|
||||||
this.path = path; |
|
||||||
this.extension = extension; |
|
||||||
this.size = size; |
|
||||||
} |
|
||||||
/** |
|
||||||
* @return the name |
|
||||||
*/ |
|
||||||
public String getName() { |
|
||||||
return name; |
|
||||||
} |
|
||||||
/** |
|
||||||
* @param name the name to set |
|
||||||
*/ |
|
||||||
public void setName(String name) { |
|
||||||
this.name = name; |
|
||||||
} |
|
||||||
/** |
|
||||||
* @return the path |
|
||||||
*/ |
|
||||||
public String getPath() { |
|
||||||
return path; |
|
||||||
} |
|
||||||
/** |
|
||||||
* @param path the path to set |
|
||||||
*/ |
|
||||||
public void setPath(String path) { |
|
||||||
this.path = path; |
|
||||||
} |
|
||||||
/** |
|
||||||
* @return the extension |
|
||||||
*/ |
|
||||||
public String getExtension() { |
|
||||||
return extension; |
|
||||||
} |
|
||||||
/** |
|
||||||
* @param extension the extension to set |
|
||||||
*/ |
|
||||||
public void setExtension(String extension) { |
|
||||||
this.extension = extension; |
|
||||||
} |
|
||||||
/** |
|
||||||
* @return the size |
|
||||||
*/ |
|
||||||
public long getSize() { |
|
||||||
return size; |
|
||||||
} |
|
||||||
/** |
|
||||||
* @param size the size to set |
|
||||||
*/ |
|
||||||
public void setSize(Long size) { |
|
||||||
this.size = size; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue