esoe 1 month ago
parent
commit
3d98b06a16
  1. 3
      documentation/general/architecture.md
  2. BIN
      documentation/general/states.png
  3. 49
      documentation/general/states.puml
  4. 75
      face/logs/teh.log
  5. BIN
      face/logs/teh.log.2024-10-07.0.gz
  6. BIN
      face/logs/teh.log.2024-10-14.0.gz
  7. 21
      face/src/main/java/gsp/technologies/face/config/WebConfig.java
  8. 128
      face/src/main/java/gsp/technologies/face/controllers/face/v1/mainframe/MainframeController.java
  9. 56
      face/src/main/java/gsp/technologies/face/models/FileMetadata.java
  10. 21
      face/src/main/java/gsp/technologies/face/models/Post.java
  11. 698
      face/src/main/java/gsp/technologies/face/services/StorageService.java
  12. 72
      face/src/main/java/gsp/technologies/face/teh/fs/MpFile.java
  13. 9
      face/src/main/resources/static/content/md/mainframe.md
  14. 13
      face/src/main/resources/templates/fragments/common/footer.html
  15. 27
      face/src/main/resources/templates/fragments/storage.html
  16. 132
      face/src/main/resources/templates/mainframe.html
  17. 25
      source/docker-compose.yaml
  18. 8
      source/dockerfile
  19. 12
      source/pom.xml
  20. 86
      source/src/main/java/gsp/technologies/source/controllers/api/v1/StorageController.java
  21. 36
      source/src/main/java/gsp/technologies/source/models/Building.java
  22. 47
      source/src/main/java/gsp/technologies/source/models/Course.java
  23. 36
      source/src/main/java/gsp/technologies/source/models/EducationEntry.java
  24. 56
      source/src/main/java/gsp/technologies/source/models/FileMetadata.java
  25. 44
      source/src/main/java/gsp/technologies/source/models/Organization.java
  26. 21
      source/src/main/java/gsp/technologies/source/models/Post.java
  27. 32
      source/src/main/java/gsp/technologies/source/models/Program.java
  28. 42
      source/src/main/java/gsp/technologies/source/models/ProgramCretarea.java
  29. 44
      source/src/main/java/gsp/technologies/source/models/Student.java
  30. 72
      source/src/main/java/gsp/technologies/source/models/Teacher.java
  31. 14
      source/src/main/java/gsp/technologies/source/repositories/FileMetadataRepository.java
  32. 10
      source/src/main/java/gsp/technologies/source/repositories/PostRepository.java
  33. 15
      source/src/main/java/gsp/technologies/source/services/FileMetadataService.java
  34. 15
      source/src/main/java/gsp/technologies/source/services/PostService.java
  35. 51
      source/src/main/java/gsp/technologies/source/teh/strings/Arrayer.java
  36. 16
      source/src/main/java/gsp/technologies/source/teh/strings/Dater.java
  37. 237
      source/src/main/java/gsp/technologies/source/teh/strings/Naimer.java
  38. 54
      source/src/main/java/gsp/technologies/source/teh/strings/Stringer.java
  39. 1
      source/src/main/resources/application.properties
  40. 18
      source/src/main/resources/application.yaml

3
documentation/general/architecture.md

@ -1,3 +1,6 @@ @@ -1,3 +1,6 @@
# Архитектура платформы teh
## диаграмма компонентов
![диаграмма компонентов](architecture.png)
## диаграмма состояний (teh.face)
![диаграмма компонентов](states.png)

BIN
documentation/general/states.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

49
documentation/general/states.puml

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
@startuml
title "teh.face : диаграмма состояний (state)\n {структура графического интерфейса платформы}"
left to right direction
' МЕЙНФРЕЙМ
@ -11,25 +12,46 @@ state "mainframe" as mainframe { @@ -11,25 +12,46 @@ state "mainframe" as mainframe {
baseStat : - количество программ обучения
baseStat : - ...
state teachersLink {
teachersLink : Переход к работе с данными преподавателей
state buildingsLink {
buildingsLink : Переход к работе с данными объектов строительства
}
state coursesLink {
coursesLink : Переход к работе с данными курсов
}
state cretareasLink {
cretareasLink : Переход к работе с критериями программ обучения
}
state educationsLink {
educationsLink : Переход к работе с записями реестра обученных
}
state organizationsLink {
organizationsLink : Переход к работе с записями реестра обученных
}
state programsLink {
programsLink : Переход к работе с данными программ обучения
}
state coursesLink {
coursesLink : Переход к работе с данными курсов
state studentsLink {
studentsLink : Переход к работе с данными программ обучения
}
state teachersLink {
teachersLink : Переход к работе с данными преподавателей
}
state buildingsLink {
buildingsLink : Переход к работе с данными объектов строительства
}
state "Извлечение данных с сервера" as execute {
execute: Формы ФРДО
execute: Формы ЕИСОТ
execute: Протоколы
execute: Документы об обучении
execute: Приказы о зачислении
execute: Приказы об отчислении
}
state "Статистика по файлобменнику" as storageStat {
storageStat: Данные по загруженным документам:
storageStat: - количество загруженных документов\n по видам документов
storageStat: -
state "Загрузка данных на сервер" as storageStat {
storageStat: Последние загруженные документы
storageStat: Загрузка файлов в хранилище
state storageLink {
storageLink : Переход к работе с файлообменником
}
@ -103,11 +125,4 @@ toMainframe --> mainframe @@ -103,11 +125,4 @@ toMainframe --> mainframe
storageLink --> storage
viewLink --> view
' mainframe : пользователь видит:
' mainframe : - статистика базы данных
' mainframe : - статистика файлообменника
' mainframe : - панель для переходов
@enduml

75
face/logs/teh.log

@ -1,3 +1,72 @@ @@ -1,3 +1,72 @@
{"@timestamp":"2024-10-14T07:42:59.798197100Z","log.level":"INFO","process.pid":24236,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 24236 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-14T07:42:59.811604300Z","log.level":"INFO","process.pid":24236,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-14T07:43:01.511680800Z","log.level":"INFO","process.pid":24236,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.178 seconds (process running for 3.357)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T06:58:25.401365200Z","log.level":"INFO","process.pid":18360,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 18360 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T06:58:25.420342800Z","log.level":"INFO","process.pid":18360,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T06:58:27.149308400Z","log.level":"INFO","process.pid":18360,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.195 seconds (process running for 3.296)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T06:59:59.876416300Z","log.level":"INFO","process.pid":21256,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 21256 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T06:59:59.884775400Z","log.level":"INFO","process.pid":21256,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:00:01.898558600Z","log.level":"INFO","process.pid":21256,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.456 seconds (process running for 3.62)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:01:15.761298200Z","log.level":"INFO","process.pid":25484,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 25484 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:01:15.768132300Z","log.level":"INFO","process.pid":25484,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:01:17.384655100Z","log.level":"INFO","process.pid":25484,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.041 seconds (process running for 3.126)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:01:34.475610100Z","log.level":"INFO","process.pid":13404,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 13404 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:01:34.486051900Z","log.level":"INFO","process.pid":13404,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:01:36.009313200Z","log.level":"INFO","process.pid":13404,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 1.981 seconds (process running for 3.109)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:03:51.509645700Z","log.level":"INFO","process.pid":3924,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 3924 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:03:51.515645500Z","log.level":"INFO","process.pid":3924,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:03:53.098716800Z","log.level":"INFO","process.pid":3924,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.027 seconds (process running for 3.091)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:04:44.875344100Z","log.level":"INFO","process.pid":11632,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 11632 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:04:44.885344900Z","log.level":"INFO","process.pid":11632,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:04:46.599374900Z","log.level":"INFO","process.pid":11632,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.208 seconds (process running for 3.45)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:17:20.407868200Z","log.level":"INFO","process.pid":20068,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 20068 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:17:20.414844100Z","log.level":"INFO","process.pid":20068,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:17:22.041664800Z","log.level":"INFO","process.pid":20068,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.199 seconds (process running for 3.335)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:20:25.233141700Z","log.level":"INFO","process.pid":18632,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 18632 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:20:25.239706500Z","log.level":"INFO","process.pid":18632,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:20:26.883033200Z","log.level":"INFO","process.pid":18632,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.12 seconds (process running for 3.2)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:20:41.404344Z","log.level":"INFO","process.pid":10532,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 10532 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:20:41.410344700Z","log.level":"INFO","process.pid":10532,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:20:43.516986100Z","log.level":"INFO","process.pid":10532,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.638 seconds (process running for 3.995)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:27:16.970919600Z","log.level":"INFO","process.pid":18168,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 18168 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:27:16.980920100Z","log.level":"INFO","process.pid":18168,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:27:18.804281800Z","log.level":"INFO","process.pid":18168,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.313 seconds (process running for 3.511)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:29:00.247600900Z","log.level":"INFO","process.pid":13576,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 13576 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:29:00.258902300Z","log.level":"INFO","process.pid":13576,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T07:29:02.130547300Z","log.level":"INFO","process.pid":13576,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.438 seconds (process running for 3.687)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T08:15:33.927111800Z","log.level":"INFO","process.pid":19756,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 19756 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T08:15:33.934116500Z","log.level":"INFO","process.pid":19756,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T08:15:35.917222400Z","log.level":"INFO","process.pid":19756,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.559 seconds (process running for 3.912)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T08:17:20.248731200Z","log.level":"INFO","process.pid":18980,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 18980 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T08:17:20.256729800Z","log.level":"INFO","process.pid":18980,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T08:17:22.171203900Z","log.level":"INFO","process.pid":18980,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.491 seconds (process running for 3.731)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T08:36:01.602371300Z","log.level":"INFO","process.pid":15980,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 15980 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T08:36:01.608341Z","log.level":"INFO","process.pid":15980,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T08:36:03.146454900Z","log.level":"INFO","process.pid":15980,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.055 seconds (process running for 3.15)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T08:41:59.441333900Z","log.level":"INFO","process.pid":14156,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 14156 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T08:41:59.447360Z","log.level":"INFO","process.pid":14156,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T08:42:00.967345600Z","log.level":"INFO","process.pid":14156,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 1.995 seconds (process running for 3.092)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:04:42.999341700Z","log.level":"INFO","process.pid":18848,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 18848 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:04:43.008365200Z","log.level":"INFO","process.pid":18848,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:04:45.431310200Z","log.level":"INFO","process.pid":18848,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 3.125 seconds (process running for 4.801)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:38:53.193947900Z","log.level":"INFO","process.pid":10880,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 10880 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:38:53.200484Z","log.level":"INFO","process.pid":10880,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:38:55.226375300Z","log.level":"INFO","process.pid":10880,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.507 seconds (process running for 3.716)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:44:15.428223500Z","log.level":"INFO","process.pid":21836,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 21836 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:44:15.438215900Z","log.level":"INFO","process.pid":21836,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:44:16.927268900Z","log.level":"INFO","process.pid":21836,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 1.968 seconds (process running for 3.16)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:47:54.022919800Z","log.level":"INFO","process.pid":24984,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 24984 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:47:54.030918800Z","log.level":"INFO","process.pid":24984,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:47:55.955495200Z","log.level":"INFO","process.pid":24984,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.448 seconds (process running for 3.591)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:49:45.291168600Z","log.level":"INFO","process.pid":20836,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 20836 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:49:45.297167300Z","log.level":"INFO","process.pid":20836,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:49:46.828682100Z","log.level":"INFO","process.pid":20836,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 1.994 seconds (process running for 3.093)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:53:07.279315Z","log.level":"INFO","process.pid":25072,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 25072 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:53:07.286315500Z","log.level":"INFO","process.pid":25072,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T09:53:08.864121700Z","log.level":"INFO","process.pid":25072,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.028 seconds (process running for 3.193)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T12:10:18.164651800Z","log.level":"INFO","process.pid":28300,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 28300 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T12:10:18.172651500Z","log.level":"INFO","process.pid":28300,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T12:10:19.745267700Z","log.level":"INFO","process.pid":28300,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 2.047 seconds (process running for 3.157)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T12:14:59.582298700Z","log.level":"INFO","process.pid":27480,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 27480 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T12:14:59.589299300Z","log.level":"INFO","process.pid":27480,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T12:15:01.111189500Z","log.level":"INFO","process.pid":27480,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 1.986 seconds (process running for 3.104)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T12:17:12.827823700Z","log.level":"INFO","process.pid":25856,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Starting FaceApplicationTests using Java 17.0.7 with PID 25856 (started by devuser in C:\\Users\\devuser\\Documents\\code\\teh\\face)","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T12:17:12.833491600Z","log.level":"INFO","process.pid":25856,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"No active profile set, falling back to 1 default profile: \"default\"","ecs.version":"8.11"}
{"@timestamp":"2024-10-15T12:17:14.373969600Z","log.level":"INFO","process.pid":25856,"process.thread.name":"main","service.name":"face","service.version":"1","service.environment":"Production","service.node.name":"Primary","log.logger":"gsp.technologies.face.FaceApplicationTests","message":"Started FaceApplicationTests in 1.987 seconds (process running for 3.053)","ecs.version":"8.11"}

BIN
face/logs/teh.log.2024-10-07.0.gz

Binary file not shown.

BIN
face/logs/teh.log.2024-10-14.0.gz

Binary file not shown.

21
face/src/main/java/gsp/technologies/face/config/WebConfig.java

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
package gsp.technologies.face.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 = 1000 * 1024 * 1024; // 1000MB
final ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder()
.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(maxInMemorySize))
.build();
WebClient webClient = WebClient.builder()
.exchangeStrategies(exchangeStrategies)
.build();
return webClient;
}
}

128
face/src/main/java/gsp/technologies/face/controllers/face/v1/mainframe/MainframeController.java

@ -1,13 +1,137 @@ @@ -1,13 +1,137 @@
package gsp.technologies.face.controllers.face.v1.mainframe;
import java.time.Duration;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.ModelAttribute;
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 org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import gsp.technologies.face.models.FileMetadata;
import gsp.technologies.face.models.Post;
import gsp.technologies.face.teh.fs.MpFile;
import reactor.core.publisher.Mono;
@Controller
@RequestMapping(path = "/face/v1")
public class MainframeController {
private static final Logger log = LoggerFactory.getLogger(MainframeController.class);
@Autowired
private WebClient client;
// @Autowired
// private Storage storage;
@GetMapping("/mainframe")
public String mainframe(Model model) {
log.info("GET /face/v1/mainframe");
//добавляем объект Post для отправки сведений о новом документе в базу
Post post = new Post();
model.addAttribute("newPost", post);
@GetMapping("/face/v1/mainframe")
public String mainframe(){
return "mainframe";
}
/**
* Загрузка файла на сервер,
*
* Реализация:
* постим запись в базу ресурсов, получаем id документа
* отправляем файл в хранилище с новым именем {id}.{ext}
*
* @param file
* @return
*/
@PostMapping("/document/upload")
public String upload(@RequestParam("file") MultipartFile file, Model model, @ModelAttribute("post") Post post) {
log.info("POST /face/v1/document/upload, file: {}, type: {}", file.getOriginalFilename(), post.getType());
//подготавливаем объект метаданных
FileMetadata metadata = new FileMetadata();
metadata.setName(file.getOriginalFilename());
metadata.setSize(file.getSize());
// получаем объект метаданных с id
metadata = client.post()
.uri("http://source:8181/api/v1/metadata/create")
.body(Mono.just(metadata), FileMetadata.class)
.retrieve()
.bodyToMono(new ParameterizedTypeReference <FileMetadata>(){})
.timeout(Duration.ofSeconds(1))
.block();
// Добавление файла в файловое хранилище
MultipartBodyBuilder builder = new MultipartBodyBuilder();
Boolean ok;
MultipartFile out = new MpFile(file, metadata.getId() + "." + metadata.getExtension());
builder.part("file", out.getResource());
// Document doc = new Document();
// doc.setName(file.getOriginalFilename());
// doc.setSize(file.getSize());
// 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 = 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();
// post.setDocument(doc);
// post = client.post()
// .uri("http://resource-service-api:8181/post/create")
// .body(Mono.just(post), Post.class)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <Post>(){})
// .timeout(Duration.ofSeconds(1))
// .block();
// System.out.println("Пакет передан в ресурсный сервис ...");
// System.out.println("Пакет: " + post.toString());
// Добавление файла в файловое хранилище
// MultipartBodyBuilder builder = new MultipartBodyBuilder();
// Boolean ok;
// MultipartFile out = new MpFile(file, doc.getId() + "." + doc.getExtension());
// builder.part("file", out.getResource());
// ok = client.method(HttpMethod.POST)
// .uri("http://storage: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:/face/v1/mainframe";
}
}

56
face/src/main/java/gsp/technologies/face/models/FileMetadata.java

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
package gsp.technologies.face.models;
import java.nio.file.Path;
import java.time.LocalDateTime;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@Data
public class FileMetadata {
//идентификатор записи о фале
private Long id;
//имя файла
private String name;
//расширение
private String extension;
//путь к корневому каталогу на сервере, где размещено хранилище данныхприложения
private Path rootPath;
//путь относительно корневого каталога
private Path relativePath;
//абсолютный путь к файлу или директории на сервере
private Path absolutePath;
//размер файла в байтах
private Long size;
//дата создания файла или директории
private LocalDateTime createdDate;
//дата последнего изенения файла или директории
private LocalDateTime lastModifiedDate;
//пользователь - владелец файла или директории
private String owner;
//тип: файл или директория
private String type;
//права доступа к файлу или директории
private String permissions;
/**
* Определение типа объекта (файл или директория)
*
* @return Возвращает true, если текущий объект является директорией
*/
public boolean isDirectory() {
return type.equals("directory");
}
}

21
face/src/main/java/gsp/technologies/face/models/Post.java

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
package gsp.technologies.face.models;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Post implements Serializable {
private long id;
private String type;//тип документа (реестр/ списочный состав/ прочее)
private FileMetadata metadata;
public Post(String type, FileMetadata metadata) {
this.type = type;
this.metadata = metadata;
}
}

698
face/src/main/java/gsp/technologies/face/services/StorageService.java

@ -0,0 +1,698 @@ @@ -0,0 +1,698 @@
package gsp.technologies.face.services;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import gsp.technologies.face.models.Post;
@Service
public class StorageService {
private static final Logger log = LoggerFactory.getLogger(StorageService.class);
// private String programCretareaCountFromBaseLink = "http://resource-service-api:8181/cretarea/count";
// private String storageLink = "http://storage-rs:8282/api/document/content/";
private String storageDocumentContentLink = "http://storage-rs:8282/api/document/content/";
// private String storageListLink = "http://resource-service-api:8181/storage-entry/list";
private String postListLink = "http://resource-service-api:8181/post/list";
// private String programsLink = "http://resource-service-api:8181/program/list";
// private String buildingsLink = "http://resource-service-api:8181/building/list";
// private String coursesLink = "http://resource-service-api:8181/course/list";
// private String teachersLink = "http://resource-service-api:8181/teacher/list";
// private String cretareasLink = "http://resource-service-api:8181/cretarea/list";
// private String organizationsLink = "http://resource-service-api:8181/organization/list";
// private String studentsLink = "http://resource-service-api:8181/student/list";
// private String educationEntriesLink = "http://resource-service-api:8181/education/list";
@Autowired
private WebClient client;
/**
* Получение списка документов, размещенных в файловом хранилище
* @param id
* @return
*/
// public List<Document> getDocumentList() {
// System.out.println("Получение списка документов, размещенных в файловом хранилище ...");
// return client.method(HttpMethod.GET)
// .uri(storageListLink)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<Document>>(){})
// .block();
// }
// public Document getDocumentById(String id) {
// // TODO: добавить линк в storage-rs, для получения документа по id
// List<Document> documents = client.method(HttpMethod.GET)
// .uri(storageListLink)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<Document>>(){})
// .block();
// Document result = new Document();
// for (Document document : documents) {
// if (document.getId() == Integer.parseInt(id)) {
// result = document;
// }
// }
// return result;
// }
/**
* Получение списка постов, размещенных в ресурсном сервисе
* @param id
* @return
*/
public List<Post> getPostList() {
System.out.println("Получение списка постов, размещенных в ресурсном сервисе ...");
return client.method(HttpMethod.GET)
.uri(postListLink)
.retrieve()
.bodyToMono(new ParameterizedTypeReference <List<Post>>(){})
.block();
}
/**
* Получение поста по id
* @param postID
* @return
*/
public Post getPostById(String postID) {
// TODO: добавить линк в storage-rs, для получения поста по id
List<Post> posts = client.method(HttpMethod.GET)
.uri(postListLink)
.retrieve()
.bodyToMono(new ParameterizedTypeReference <List<Post>>(){})
.block();
Post result = new Post();
for (Post post : posts) {
if (post.getId() == Integer.parseInt(postID)) {
result = post;
}
}
return result;
}
public Post getPostById(int postID) {
// TODO: добавить линк в storage-rs, для получения поста по id
List<Post> posts = client.method(HttpMethod.GET)
.uri(postListLink)
.retrieve()
.bodyToMono(new ParameterizedTypeReference <List<Post>>(){})
.block();
Post result = new Post();
for (Post post : posts) {
if (post.getId() == postID) {
result = post;
}
}
return result;
}
public int getPostCount(){
// TODO: добавить линк в resource-service, для получения количества постов
return getPostList().size();
}
/**
* Получение содержимого xlsx-файла в виде Map<Integer, List<XlsxCell>>
* @param docId
* @return
*/
// public Map<Integer, List<XlsxCell>> getDocumentContentAsMap(String docId) {
// System.out.println("Получение данных xlsx-файла в виде Map<Integer, List<XlsxCell>> ...");
// String url = storageDocumentContentLink + "?filename=" + docId + ".xlsx";
// Map<Integer, List<XlsxCell>> cells = client.method(HttpMethod.GET)
// .uri(url)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <Map<Integer, List<XlsxCell>>>(){})
// .block();
// return cells;
// }
/**
* Получение строки из xlsx-файла
* @param docId
* @param line
* @return
*/
// public List<XlsxCell> getDocumentContentByLines(String docId, String line) {
// System.out.println("Получение данных xlsx-файла в виде List<XlsxCell> по строке ...");
// String url = storageDocumentContentLink + "/line" + "?filename=" + docId + ".xlsx&line=" + line;
// List<XlsxCell> cells = client.method(HttpMethod.GET)
// .uri(url)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<XlsxCell>>(){})
// .block();
// return cells;
// }
/**
* Получение частей из xlsx-файла
* @param docId
* @param from
* @param count
* @return
*/
// public Map<Integer, List<XlsxCell>> getDocumentContentByParts(String docId, int from, int count) {
// System.out.println("Получение данных xlsx-файла в виде Map<Integer, List<XlsxCell>> по частям ...");
// String url = storageDocumentContentLink + "/part" + "?filename=" + docId + ".xlsx&from=" + from + "&count=" + count;
// Map<Integer, List<XlsxCell>> cells = client.method(HttpMethod.GET)
// .uri(url)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <Map<Integer, List<XlsxCell>>>(){})
// .block();
// return cells;
// }
/**
* Получение количества записей в xlsx-файле
* @param docId
* @return
*/
public Integer getDocumentContentLenght(String docId) {
System.out.println("Получение количества записей в xlsx-файле ...");
String url = storageDocumentContentLink + "/lenght" + "?filename=" + docId + ".xlsx";
Integer count = client.method(HttpMethod.GET)
.uri(url)
.retrieve()
.bodyToMono(Integer.class)
.block();
return count;
}
/**
* Получение столбца из xlsx-файла
* @param docId
* @param column
* @return
*/
// public List<XlsxCell> getDocumentContentByColumn(Integer docId, Integer column) {
// System.out.println("Получение данных xlsx-файла в виде List<XlsxCell> по столбцу ...");
// String url = storageDocumentContentLink + "/column" + "?filename=" + docId + ".xlsx&column=" + column;
// List<XlsxCell> cells = client.method(HttpMethod.GET)
// .uri(url)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<XlsxCell>>(){})
// .block();
// return cells;
// }
// public List<XlsxCell> getUniqueDocumentContentByColumn(int docId, int column) {
// System.out.println("Получение уникальных данных xlsx-файла в виде List<XlsxCell> по столбцу #" + column + " ...");
// String url = storageDocumentContentLink + "/column/unique" + "?filename=" + docId + ".xlsx&column=" + column;
// List<XlsxCell> cells = client.method(HttpMethod.GET)
// .uri(url)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<XlsxCell>>(){})
// .block();
// return cells;
// }
/*********************************************************************** */
/*
* Извлечение данных (списков моделей) из xlsx - перебор xlsx по кускам
*/
// public List<ProgramCretarea> getProgramCretareasFromFile(Post post) {
// List<ProgramCretarea> programCretareas = new ArrayList<>();
// int max = this.getDocumentContentLenght(String.valueOf(post.getDocument().getId()));
// int portion = 10000;
// int from = 0;
// while (from < max) {
// portion = Math.min(max - from, portion);
// Map<Integer,List<XlsxCell>> cells = this.getDocumentContentByParts(post.getDocument().getId().toString(), from, portion);
// for (Map.Entry<Integer,List<XlsxCell>> entry : cells.entrySet()) {
// ProgramCretarea programCretarea = new ProgramCretarea(entry);
// if(!programCretareas.contains(programCretarea)
// && !programCretarea.isEmpty()){
// programCretareas.add(programCretarea);
// }
// }
// from += portion;
// }
// programCretareas.sort(Comparator.comparing(ProgramCretarea::getNameShort));
// return programCretareas;
// }
/*********************************************************************** */
/**
* Получение всего содержимого xlsx-файла из файлового хранилища
* по id документа в хранилище
*
* @param id Идентфикатор файла
* @return XlsxDocument Объект с данными xlsx файла
*/
// public XlsxDocument getXlsxDocument(String id) {
// System.out.println("Получение всего содержимого xlsx-файла ...");
// return client.method(HttpMethod.GET)
// .uri(storageLink
// + id + ".xlsx")
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <XlsxDocument>(){})
// .block();
// }
/**
* Получение перечня программ обучения из базы
* @param id
* @return
*/
// public List<Program> getBasePrograms() {
// System.out.println("Получение перечня программ обучения из базы ...");
// List<Program> list = client.method(HttpMethod.GET)
// .uri(programsLink)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<Program>>(){})
// .block();
// return list;
// }
// public List<Program> getAbsentPrograms(List<Program> xlsxList) {
// List<Program> baseList = getBasePrograms();
// if (xlsxList == null || xlsxList.isEmpty()) {
// return new ArrayList<Program>();
// }
// List<Program> result = new ArrayList<>(xlsxList);
// if (baseList == null || baseList.isEmpty()) {
// return result;
// }
// for (Program program : xlsxList) {
// for (Program baseProgram : baseList) {
// if (program.isSimilar(baseProgram)) {
// result.remove(program);
// break;
// }
// }
// }
// return result;
// }
// public int getAbsentProgramsCount(List<Program> xlsxList) {
// return getAbsentPrograms(xlsxList).size();
// }
/**
* Получение перечня объектов строительства из базы
* @param id
* @return
*/
// public List<Building> getBaseBuildings() {
// System.out.println("Получение перечня объектов строительства из базы ...");
// List<Building> list = client.method(HttpMethod.GET)
// .uri(buildingsLink)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<Building>>(){})
// .block();
// return list;
// }
// public List<Building> getAbsentBuildings(List<Building> xlsxList) {
// List<Building> baseList = getBaseBuildings();
// if (xlsxList == null || xlsxList.isEmpty()) {
// return new ArrayList<Building>();
// }
// List<Building> result = new ArrayList<>(xlsxList);
// if (baseList == null || baseList.isEmpty()) {
// return result;
// }
// for (Building building : xlsxList) {
// for (Building baseBuilding : baseList) {
// if (building.getName_short().equals(baseBuilding.getName_short())) {
// result.remove(building);
// break;
// }
// }
// }
// return result;
// }
// public int getAbsentBuildingsCount(List<Building> xlsxList) {
// return getAbsentBuildings(xlsxList).size();
// }
// public int getBuildingsCount() {
// return getBaseBuildings().size();
// }
/**
* Получение списка курсов из базы данных
*/
// public List<Course> getBaseCourses() {
// System.out.println("Получение списка курсов из базы данных ...");
// List<Course> list = client.method(HttpMethod.GET)
// .uri(coursesLink)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<Course>>(){})
// .block();
// return list;
// }
// public List<Course> getAbsentCourses(List<Course> xlsxList) {
// List<Course> baseList = getBaseCourses();
// if (xlsxList == null || xlsxList.isEmpty()) {
// return new ArrayList<Course>();
// }
// List<Course> result = new ArrayList<>(xlsxList);
// if (baseList == null || baseList.isEmpty()) {
// return result;
// }
// for (Course course : xlsxList) {
// for (Course baseCourse : baseList) {
// if(course.isSimilar(baseCourse)) {
// result.remove(course);
// break;
// }
// }
// }
// return result;
// }
// public int getAbsentCoursesCount(List<Course> xlsxList) {
// return getAbsentCourses(xlsxList).size();
// }
/**
* Получение перечня преподавателей из базы данных
*/
// public List<Teacher> getBaseTeachers() {
// System.out.println("Получение перечня преподавателей из базы данных ...");
// List<Teacher> list = client.method(HttpMethod.GET)
// .uri(teachersLink)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<Teacher>>(){})
// .block();
// return list;
// }
/**
* Получение перечня преподавателей из xlsx-файла
*
* @return <List<Teacher>> Перечень преподавателей, полученных из xlsx-файла
* В объектах перечня незаполнены поля id
* Объекты сформированы на основании ФИО преподавателя, указанного в xlsx-файле
*
*/
// public List<Teacher> getXlsxTeachers(XlsxDocument xlsx) {
// System.out.println("Получение перечня преподавателей из xlsx-файла ...");
// List<Teacher> list = new ArrayList<>();
// // получаем данные в виде мапы строк
// Map<Integer, List<XlsxCell>> map = xlsx.getData();
// // удаляем строку заголовков
// map.remove(0);
// for (Map.Entry<Integer, List<XlsxCell>> entry : map.entrySet()) {
// String fio = Stringer.clear(entry
// .getValue()
// .get(18)
// .getContent());
// list.add(new Teacher(fio));
// }
// // удаляем дубликаты
// Set <Teacher> set = new HashSet<>(list);
// list = new ArrayList<>(set);
// return list;
// }
/**
* Получение списка преподавателей, отсутствующих в базе данных (новых преподавателей)
*
* @param xlsxList список уникальных преподаватетей из файла
* @param baseList список преподавателей из базы
* @return List<Teacher>
*/
// public List<Teacher> getAbsentTeachers(List<Teacher> xlsxList, List<Teacher> baseList) {
// System.out.println("Получение списка преподавателей, отсутствующих в базе данных ...");
// if (xlsxList == null || xlsxList.isEmpty()) {
// return new ArrayList<Teacher>();
// }
// List<Teacher> result = new ArrayList<>(xlsxList);
// if (baseList == null || baseList.isEmpty()) {
// return result;
// }
// for (Teacher xlsxTeacher : xlsxList) {
// for (Teacher baseTeacher : baseList) {
// if (xlsxTeacher.getFullName().equals(baseTeacher.getFullName())) {
// result.remove(xlsxTeacher);
// break;
// }
// }
// }
// return result;
// }
// public List<Teacher> getAbsentTeachers(List<Teacher> xlsxList) {
// return getAbsentTeachers(xlsxList, getBaseTeachers());
// }
// public List<Teacher> sortTeachers(List<Teacher> list) {
// System.out.println("Сортировка списка преподавателей ...");
// Comparator<Teacher> compareBySecondName = Comparator
// .comparing(Teacher::getSecond_name)
// .thenComparing(Teacher::getFirst_name)
// .thenComparing(Teacher::getLast_name);
// return list.stream()
// .sorted(compareBySecondName)
// .collect(Collectors.toCollection(ArrayList::new));
// }
// public int getAbsentTeachersCount(List<Teacher> uniqueTeachers) {
// return getAbsentTeachers(uniqueTeachers).size();
// }
/**
* Получение списка критериев из баз данных
*/
// public List<ProgramCretarea> getBaseCretareas() {
// System.out.println("Получение списка критериев из баз данных ...");
// List<ProgramCretarea> list = client.method(HttpMethod.GET)
// .uri(cretareasLink)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<ProgramCretarea>>(){})
// .block();
// return list;
// }
// public List<ProgramCretarea> getAbsentCretareas(List<ProgramCretarea> xlsxList) {
// List<ProgramCretarea> baseList = getBaseCretareas();
// if (xlsxList == null || xlsxList.isEmpty()) {
// return new ArrayList<ProgramCretarea>();
// }
// List<ProgramCretarea> result = new ArrayList<>(xlsxList);
// if (baseList == null || baseList.isEmpty()) {
// return result;
// }
// for (ProgramCretarea xlsxCretarea : xlsxList) {
// for (ProgramCretarea baseCretarea : baseList) {
// if (xlsxCretarea.getNameShort().equals(baseCretarea.getNameShort())) {
// result.remove(xlsxCretarea);
// break;
// }
// }
// }
// return result;
// }
// public int getAbsentCretareasCount(List<ProgramCretarea> xlsxList) {
// return getAbsentCretareas(xlsxList).size();
// }
/**
* Получение списка организаций из базы данных
*/
// public List<Organization> getBaseOrganizations() {
// System.out.println("Получение списка организаций из базы данных ...");
// List<Organization> list = client.method(HttpMethod.GET)
// .uri(organizationsLink)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<Organization>>(){})
// .block();
// return list;
// }
// public List<Organization> getAbsentOrganizations(List<Organization> xlsxList) {
// List<Organization> baseList = getBaseOrganizations();
// if (xlsxList == null || xlsxList.isEmpty()) {
// return new ArrayList<Organization>();
// }
// List<Organization> result = new ArrayList<>(xlsxList);
// if (baseList == null || baseList.isEmpty()) {
// return result;
// }
// for (Organization xlsxOrganization : xlsxList) {
// for (Organization baseOrganization : baseList) {
// if (xlsxOrganization.getNameFull().equals(baseOrganization.getNameFull())) {
// result.remove(xlsxOrganization);
// break;
// }
// }
// }
// return result;
// }
// public int getAbsentOrganizationsCount(List<Organization> xlsxList) {
// return getAbsentOrganizations(xlsxList).size();
// }
// /**
// * Получение списка студентов из базы данных
// */
// public List<Student> getBaseStudents() {
// System.out.println("Получение списка студентов из базы данных ...");
// List<Student> list = client.method(HttpMethod.GET)
// .uri(studentsLink)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<Student>>(){})
// .block();
// return list;
// }
// public List<Student> getAbsentStudents(List<Student> xlsxList) {
// List<Student> baseList = getBaseStudents();
// if (xlsxList == null || xlsxList.isEmpty()) {
// return new ArrayList<Student>();
// }
// List<Student> result = new ArrayList<>(xlsxList);
// if (baseList == null || baseList.isEmpty()) {
// return result;
// }
// for (Student xlsxStudent : xlsxList) {
// for (Student baseStudent : baseList) {
// if (xlsxStudent.getSecond_name().equals(baseStudent.getSecond_name())
// && xlsxStudent.getFirst_name().equals(baseStudent.getFirst_name())
// && xlsxStudent.getLast_name().equals(baseStudent.getLast_name())
// && xlsxStudent.getProfession().equals(baseStudent.getProfession())
// && xlsxStudent.getDirection().equals(baseStudent.getDirection())
// && xlsxStudent.getProfession().equals(baseStudent.getProfession())
// && xlsxStudent.getOrganization().getNameFull().equals(baseStudent.getOrganization().getNameFull())) {
// result.remove(xlsxStudent);
// break;
// }
// }
// }
// return result;
// }
// public int getAbsentStudentsCount(List<Student> xlsxList) {
// return getAbsentStudents(xlsxList).size();
// }
// public List<EducatonEntry> getBaseEducationEntries() {
// System.out.println("Получение списка записей об обучениях из базы данных ...");
// List<EducatonEntry> list = client.method(HttpMethod.GET)
// .uri(educationEntriesLink)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<EducatonEntry>>(){})
// .block();
// return list;
// }
// public List<EducatonEntry> getAbsentEducationEntries(List<EducatonEntry> xlsxList) {
// List<EducatonEntry> baseList = getBaseEducationEntries();
// if (xlsxList == null || xlsxList.isEmpty()) {
// return new ArrayList<EducatonEntry>();
// }
// List<EducatonEntry> result = new ArrayList<>(xlsxList);
// if (baseList == null || baseList.isEmpty()) {
// return result;
// }
// for (EducatonEntry xlsxEducatonEntry : xlsxList) {
// for (EducatonEntry baseEducatonEntry : baseList) {
// if (xlsxEducatonEntry.isSimilar(baseEducatonEntry)) {
// result.remove(xlsxEducatonEntry);
// break;
// }
// }
// }
// return result;
// }
// public int getAbsentEducationsCount(List<EducatonEntry> uniqueEducations) {
// return getAbsentEducationEntries(uniqueEducations).size();
// }
// public int getCoursesCount() {
// return getBaseCourses().size();
// }
// public int getEducationsCount() {
// return getBaseEducationEntries().size();
// }
// public int getProgramsCount() {
// return getBasePrograms().size();
// }
// public int getStudentsCount() {
// return getBaseStudents().size();
// }
// public int getTeachersCount() {
// return getBaseTeachers().size();
// }
// public int getCretareasCount() {
// return getBaseCretareas().size();
// }
// public int getOrganizationsCount() {
// return getBaseOrganizations().size();
// }
// public List<ProgramCretarea> getProgramCretareasFromBase() {
// System.out.println("Получение списка критериев из баз данных ...");
// List<ProgramCretarea> list = client.method(HttpMethod.GET)
// .uri(cretareasLink)
// .retrieve()
// .bodyToMono(new ParameterizedTypeReference <List<ProgramCretarea>>(){})
// .block();
// return list;
// }
// public Integer getProgramCretareaCountFromBase(){
// int count = client.method(HttpMethod.GET)
// .uri(programCretareaCountFromBaseLink)
// .retrieve()
// .bodyToMono(Integer.class)
// .block();
// return count;
// }
}

72
face/src/main/java/gsp/technologies/face/teh/fs/MpFile.java

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
package gsp.technologies.face.teh.fs;
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;
/**
* Переопределены методы MultipartFile
*/
public class MpFile implements MultipartFile{
private MultipartFile file;
private String name;
/**
* @param file
* @param name
*/
public MpFile(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
}
}

9
face/src/main/resources/static/content/md/mainframe.md

@ -1,5 +1,10 @@ @@ -1,5 +1,10 @@
# mainframe.md
# Инструкция по работе с платформой (mainframe.md)
Форма предоставляет пользователю доступ ко всему функционалу платформы
- ссылка на страницу работы с файлами (загрузка, проверка файлов)
- ссылка на страницу работы с данными базы (редактирование данных, формирование отчетов)
-
## Загрузка файлов на платформу
### Общее
- xlsx файл не должен содержать более 5 тыс. строк
- все ячейки должны содержать значения (формулы платформа не пересчитает)
### Реестры обученных

13
face/src/main/resources/templates/fragments/common/footer.html

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="copy">
<hr>
© 2024 ООО "ГСП-Технологии"
</div>
<div th:fragment="info">
<hr>
<zero-md th:src="@{/content/md/mainframe.md}"></zero-md>
</div>
</body>
</html>

27
face/src/main/resources/templates/fragments/storage.html

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<!--
Добавление документов на сервер
отправляет данные о виде документа и файл
-->
<div th:fragment="upload (post)">
<hr>
<h2>Добавление пакетов:</h2>
<form th:method="post" th:action="@{/face/v1/document/upload}" enctype="multipart/form-data" th:object="${post}">
<!-- <p th:text="${post}"></p> -->
<!-- <input type="text" id="type" name="type" th:value="*{type}"> -->
<select id="type" name="type" th:value="*{type}">
<!-- <select th:field="${post.type}"> -->
<option value="" disabled selected>--Выберите вид загружаемого документа--</option>
<option value="Реестр обученных">Реестр обученных</option>
<option value="Списочный состав">Списочный состав</option>
<option value="Заявка на обучение">Заявка на обучение</option>
<option value="Прочее ...">Прочее ...</option>
</select>
<input type="file" name="file">
<button type="submit">Загрузить пакет</button>
</form>
</div>
</body>
</html>

132
face/src/main/resources/templates/mainframe.html

@ -7,29 +7,139 @@ th-шаблон, для предоставления доступа к функ @@ -7,29 +7,139 @@ th-шаблон, для предоставления доступа к функ
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>teh-mainframe</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>teh-mainframe</h1>
<br>
<hr>
</header>
<main>
<ul>
<li>
<a th:href="@{#}">base-controls</a>
</li>
<li>
<a th:href="@{#}">files</a>
</li>
</ul>
<!-- Хранилище данных -->
<h1>Хранилище данных</h1>
<table rules="all">
<thead></thead>
<tbody>
<tr>
<td>Критерии</td>
<td>0</td>
</tr>
<tr>
<td>Программы</td>
<td>0</td>
</tr>
<tr>
<td>Преподаватели</td>
<td>0</td>
</tr>
<tr>
<td>Объекты строительства</td>
<td>0</td>
</tr>
<tr>
<td>Организации</td>
<td>0</td>
</tr>
<tr>
<td>Курсы</td>
<td>0</td>
</tr>
<tr>
<td>Студенты</td>
<td>0</td>
</tr>
<tr>
<td>Обучения</td>
<td>0</td>
</tr>
</tbody>
</table>
<hr>
<!-- Извлечение данных -->
<h1>Извлечение данных</h1>
<table>
<thead></thead>
<tbody>
<tr>
<td>Формы ФРДО</td>
</tr>
<tr>
<td>Формы ЕИСОТ</td>
</tr>
<tr>
<td>Протокол</td>
</tr>
<tr>
<td>Приказ о зачислении</td>
</tr>
<tr>
<td>Приказ об отчислении</td>
</tr>
<tr>
<td>Документы об обучении</td>
</tr>
</tbody>
</table>
<hr>
<!-- Импорт данных в базу -->
<h1>Импорт данных в базу</h1>
<!-- Добавление пакетов -->
<div th:insert="~{fragments/storage :: upload(post=${newPost})}"></div>
<!-- Вывести по три документа каждого типа -->
<h2>Последние загруженные документы: COUNT</h2>
<table rules="all">
<thead>
<tr>
<th>Вид документа</th>
<th>Наименование</th>
<th>Время загрузки</th>
<th>Статус</th>
</tr>
</thead>
<tbody>
<tr>
<td>Реестр обученных</td>
<td>Наименование.xlsx</td>
<td>дата</td>
<td>обработан/не обработан</td>
</tr>
<tr>
<td>Реестр обученных</td>
<td>Наименование.xlsx</td>
<td>дата</td>
<td>обработан/не обработан</td>
</tr>
<tr>
<td>Реестр обученных</td>
<td>Наименование.xlsx</td>
<td>дата</td>
<td>обработан/не обработан</td>
</tr>
<tr>
<td>Реестр обученных</td>
<td>Наименование.xlsx</td>
<td>дата</td>
<td>обработан/не обработан</td>
</tr>
<tr>
<td>Реестр обученных</td>
<td>Наименование.xlsx</td>
<td>дата</td>
<td>обработан/не обработан</td>
</tr>
</tbody>
</table>
</main>
<!-- подвал -->
<footer>
<zero-md th:src="@{/content/md/mainframe.md}"></zero-md>
<div th:insert="~{fragments/common/footer :: info}"></div>
<div th:insert="~{fragments/common/footer :: copy}"></div>
</footer>
</body>

25
source/docker-compose.yaml

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
version: "3.7"
services:
source:
container_name: source
hostname: source
build:
context: ../source
dockerfile: dockerfile
image: "source"
command: ["java","-jar","/app/source/source-0.1.jar"]
volumes:
- teh-logs:${LOGGER_DATA}
ports:
- 81:8181
restart: unless-stopped
networks:
- teh-net
volumes:
teh-logs:
external: true
networks:
teh-net:
name: teh-net
external: true
driver: bridge

8
source/dockerfile

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
FROM openjdk:17-jdk-alpine
RUN apk update
RUN apk upgrade
COPY target/source-0.1.jar /app/source/source-0.1.jar
WORKDIR /app/source
# ENTRYPOINT ["java","-jar","/app/resource-service-api-0.1.jar"]
# docker image build -t resource-service-api:latest .
# docker run -p80:8181 resource-service-api:latest

12
source/pom.xml

@ -34,20 +34,23 @@ @@ -34,20 +34,23 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@ -72,5 +75,4 @@ @@ -72,5 +75,4 @@
</plugin>
</plugins>
</build>
</project>

86
source/src/main/java/gsp/technologies/source/controllers/api/v1/StorageController.java

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
package gsp.technologies.source.controllers.api.v1;
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 gsp.technologies.source.models.FileMetadata;
import gsp.technologies.source.models.Post;
import gsp.technologies.source.repositories.FileMetadataRepository;
import gsp.technologies.source.repositories.PostRepository;
/**
* Контроллер для работы с таблицей, хранящей сведения о файлах в файловом хранилище
*/
@RestController
@RequestMapping(path = "/api/v1/storage")
public class StorageController {
@Autowired
private FileMetadataRepository metaRepo;
@Autowired
private PostRepository postRepo;
@GetMapping("/metadata/list")
public ResponseEntity<List<FileMetadata>> getStorageEntries(){
return new ResponseEntity<>(metaRepo.findAll(), HttpStatus.OK);
}
@GetMapping("/post/list")
public ResponseEntity<List<Post>> getPostList(){
return new ResponseEntity<>(postRepo.findAll(), HttpStatus.OK);
}
@GetMapping("/metadata/{id}")
public ResponseEntity<?> getStorageEntryByID(@PathVariable Integer id){
return new ResponseEntity<>(metaRepo.findById(id), HttpStatus.OK);
}
@PostMapping(path = "/metadata/create",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> saveStorageEntry(@RequestBody FileMetadata metadata) {
metaRepo.save(metadata);
return new ResponseEntity<>(metadata, HttpStatus.CREATED);
}
@PostMapping(path = "/post/create",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> savePost(@RequestBody Post post) {
postRepo.save(post);
return new ResponseEntity<>(post, HttpStatus.CREATED);
}
@PutMapping(path = "/metadata/update/{id}",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> updateStorageEntry(@PathVariable Integer id, @RequestBody FileMetadata metadata) {
FileMetadata meta = metaRepo.findById(id);
meta.setName(metadata.getName());
meta.setRelativePath(metadata.getRelativePath());
meta.setExtension(metadata.getExtension());
meta.setSize(metadata.getSize());
metaRepo.save(meta);
return new ResponseEntity<>(metaRepo.findById(id), HttpStatus.CREATED);
}
@DeleteMapping("/metadata/delete/{id}")
public ResponseEntity<String> deleteStorageEntry(@PathVariable Integer id){
FileMetadata meta= metaRepo.findById(id);
metaRepo.delete(meta);
return new ResponseEntity<>("Запись id#" + id + " удалена ... ", HttpStatus.OK);
}
}

36
source/src/main/java/gsp/technologies/source/models/Building.java

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
package gsp.technologies.source.models;
import jakarta.persistence.Column;
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 Building {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@Column(length=50)
private String nameShort;//Сокращенное наименование
private String nameFull;//Полное наименование
private String codeShort;//Краткий код
private String codeFull;//Полный код
// подготовить конструкторы на все варианты внесения информации о преподавателях
public Building(String name_short, String name_full, String code_short, String code_full){
this.nameShort = name_short;
this.nameFull = name_full;
this.codeShort = code_short;
this.codeFull = code_full;
}
}

47
source/src/main/java/gsp/technologies/source/models/Course.java

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
package gsp.technologies.source.models;
import java.util.Date;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Сведения о курсе (учебном потоке)
*/
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Data
public class Course {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;//уникальный идентификатор курса
private String place;//место проведения занятий
private Date startDate;//дата начала курса
private Date protocolDate;//дата протокола
private String protocolNumber;//номер протоколаssss
private String reportPeriod;//отчетный период (наименование месяца)
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@OnDelete(action = OnDeleteAction.SET_NULL)
private Teacher teacher;//сведения о преподаватле
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@OnDelete(action = OnDeleteAction.SET_NULL)
private Program program;//сведения о программе обучения
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@OnDelete(action = OnDeleteAction.SET_NULL)
private Building building;//сведения об объекте строительства
}

36
source/src/main/java/gsp/technologies/source/models/EducationEntry.java

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
package gsp.technologies.source.models;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Data
public class EducationEntry {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String sertificateNumber;//Номер удостоверения
private String frdoNumber;//ФРДО номер по реестру
private String eisotNumber;//ЕИСОТ номер по реестру
private String ones;//Единички (вспомогатльный столбец)
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@OnDelete(action = OnDeleteAction.SET_NULL)
private Course course;//Сведения о курсе
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@OnDelete(action = OnDeleteAction.SET_NULL)
private Student student;//Сведения о студенте
}

56
source/src/main/java/gsp/technologies/source/models/FileMetadata.java

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
package gsp.technologies.source.models;
import java.nio.file.Path;
import java.time.LocalDateTime;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@Data
public class FileMetadata {
//идентификатор по базе
private Long id;
//имя файла
private String name;
//расширение
private String extension;
//путь к корневому каталогу на сервере, где размещено хранилище данныхприложения
private Path rootPath;
//путь относительно корневого каталога
private Path relativePath;
//абсолютный путь к файлу или директории на сервере
private Path absolutePath;
//размер файла в байтах
private Long size;
//дата создания файла или директории
private LocalDateTime createdDate;
//дата последнего изенения файла или директории
private LocalDateTime lastModifiedDate;
//пользователь - владелец файла или директории
private String owner;
//тип: файл или директория
private String type;
//права доступа к файлу или директории
private String permissions;
/**
* Определение типа объекта (файл или директория)
*
* @return Возвращает true, если текущий объект является директорией
*/
public boolean isDirectory() {
return type.equals("directory");
}
}

44
source/src/main/java/gsp/technologies/source/models/Organization.java

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
package gsp.technologies.source.models;
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 Organization {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String ownership;//Форма собственности ПСК
private String nameShort;//Сокращенное наименование
private String nameFull;//Полное наименование
private String type;//вид ПСК - производственная/сервисная
private String inn;//ИНН организации
/**
* подготовить конструкторы на все варианты внесения информации о преподавателях
* @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.nameShort = name_short;
this.nameFull = name_full;
this.type = type;
this.inn = inn;
}
}

21
source/src/main/java/gsp/technologies/source/models/Post.java

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
package gsp.technologies.source.models;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Post implements Serializable {
private Long id;
private String type;//тип документа (реестр/ списочный состав/ прочее)
private FileMetadata metadata;
public Post(String type, FileMetadata metadata) {
this.type = type;
this.metadata = metadata;
}
}

32
source/src/main/java/gsp/technologies/source/models/Program.java

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
package gsp.technologies.source.models;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Data
public class Program {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String name;//Наименование
private Integer lenght;//длительность программы
private String studyDirection;//направление обучения: обязательное-производственное (учесть в ограничениях)
private Integer price;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@OnDelete(action = OnDeleteAction.SET_NULL)
private ProgramCretarea cretarea;
}

42
source/src/main/java/gsp/technologies/source/models/ProgramCretarea.java

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
package gsp.technologies.source.models;
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 ProgramCretarea {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String name;//Наименование
private String nameShort;//Наименование : сокращенно
/**
* подготовить конструкторы на все варианты внесения информации о преподавателях
*
* @param name
* @param name_short
*/
public ProgramCretarea(String name, String nameShort) {
this.name = name;
this.nameShort = nameShort;
}
}

44
source/src/main/java/gsp/technologies/source/models/Student.java

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
package gsp.technologies.source.models;
import java.util.Date;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Сведения об обученных
*/
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Data
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String firstName;//Имя
private String secondName;//Отчество
private String lastName;//Фамилия
private String profession;//Профессия
private String category;//Категория (ИТР или рабочий)
private String direction;//Структурное подразделение
private String snils;//СНИЛС
private Date berth;//Дата рождения
private String sitizenship;//Гражданство
private String sex;//Пол (м/ж)
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@OnDelete(action = OnDeleteAction.SET_NULL)
private Organization organization;//Организация - работодатель
}

72
source/src/main/java/gsp/technologies/source/models/Teacher.java

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
package gsp.technologies.source.models;
import gsp.technologies.source.teh.strings.Naimer;
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 Teacher{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String secondName;//Фамилия
private String firstName;//Имя
private String lastName;//Отчество
private String employeeId;
private String snils;
// подготовить конструкторы на все варианты внесения информации о преподавателях
public Teacher(String second_name, String first_name, String last_name){
setSecondName(second_name);
setFirstName(first_name);
setLastName(last_name);
}
public Teacher(String fio){
setSecondName(Naimer.getSecondNameOf(fio));
setFirstName(Naimer.getFirstNameOf(fio));
setLastName(Naimer.getLastNameOf(fio));
}
public String fio(){
return Naimer.getFioOf(this);
}
/**
* проверка совпадения ФИО
* @param teacher
* @return
*/
public boolean like(Teacher teacher) {
return this.fio().equals(teacher.fio());
}
/**
* проверка совпадения всех полей кроме id
* @param teacher
* @return
*/
public boolean isSimilar(Teacher teacher) {
return this.fio().equals(teacher.fio())&&
this.getEmployeeId().equals(teacher.getEmployeeId())&&
this.getSnils().equals(teacher.getSnils());
}
}

14
source/src/main/java/gsp/technologies/source/repositories/FileMetadataRepository.java

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
package gsp.technologies.source.repositories;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import gsp.technologies.source.models.FileMetadata;
@Repository
public interface FileMetadataRepository extends JpaRepository<FileMetadata, Long> {
FileMetadata findById(long id);
Page<FileMetadata> findById(PageRequest of, Long id);
}

10
source/src/main/java/gsp/technologies/source/repositories/PostRepository.java

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
package gsp.technologies.source.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import gsp.technologies.source.models.Post;
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
}

15
source/src/main/java/gsp/technologies/source/services/FileMetadataService.java

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
package gsp.technologies.source.services;
import org.springframework.stereotype.Service;
import gsp.technologies.source.repositories.FileMetadataRepository;
@Service
public class FileMetadataService {
private final FileMetadataRepository repo;
public FileMetadataService(FileMetadataRepository repo) {
this.repo = repo;
}
}

15
source/src/main/java/gsp/technologies/source/services/PostService.java

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
package gsp.technologies.source.services;
import org.springframework.stereotype.Service;
import gsp.technologies.source.repositories.PostRepository;
@Service
public class PostService {
private final PostRepository repo;
public PostService(PostRepository repo){
this.repo = repo;
}
}

51
source/src/main/java/gsp/technologies/source/teh/strings/Arrayer.java

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
package gsp.technologies.source.teh.strings;
import java.util.List;
public class Arrayer {
/**
* Удаляет все пустые строки из массива строк и возвращает новый массив с оставшимися строками.
*
* @param strings Массив строк из которогу удаляются пустые строки.
* @return Новый массив с оставшимися строками.
*/
public static String[] removeEmptyStrings(String[] strings) {
// Подсчет количества непустых строк в входном массиве
int count = 0;
for (String string : strings) {
if (!string.equals("")) {
count++;
}
}
// Новый массив для хранения непустых строк
String[] result = new String[count];
// Копирование непустых строк из входного массива в новый массив
int index = 0;
for (String string : strings) {
if (!string.equals("")) {
result[index] = string;
index++;
}
}
// Возвращение нового массива с непустыми строками
return result;
}
/**
* Удаление повторяющихся элементов списка строк
* Получение списка уникальных строк
*
*/
public static List<String> uniqueList(List<String> list) {
// Удаление повторяющихся элементов списка
List<String> result = list.stream().distinct().toList();
return result;
}
}

16
source/src/main/java/gsp/technologies/source/teh/strings/Dater.java

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
package gsp.technologies.source.teh.strings;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
/**
* Обработка строк с датами
*/
public class Dater {
private Long longDate;
private String stringDate;
private Date date;
private LocalDate localDate;
private LocalDateTime localDateTime;
}

237
source/src/main/java/gsp/technologies/source/teh/strings/Naimer.java

@ -0,0 +1,237 @@ @@ -0,0 +1,237 @@
package gsp.technologies.source.teh.strings;
import gsp.technologies.source.models.Teacher;
/**
* Обработка строк, содержащих сведения о ФИО
* - Teacher
* - Student
* - Person
*/
public class Naimer {
private static String not = "Нет";
/**
* Объединяет фамилию, имя и отчество в одну строку.
* Возможые ситуации:
* - фамилия, имя или отчество могут содержать нулевые значения
* - отчество может содержать приписки
*
* @param second_name - фамилия
* @param first_name - имя
* @param last_name - отчество
* @return объединенную строку или пустую строку,
* если все входящие параметры являются нулевыми значениями
*/
public static String getFioOf(String second_name, String first_name, String last_name) {
// Инициализируем StringBuilder для хранения результата.
StringBuilder result = new StringBuilder();
// Проверяем, является ли фамилия нулевым значением.
if (!Stringer.checkForEmpty(second_name)) {
// Если фамилия не является нулевым значением, то добавляем ее в строку.
result.append(second_name);
} else {
// Если фамилия является нулевым значением, то добавляем "Нет" в строку.
result.append(not);
}
// Проверяем, является ли имя нулевым значением.
if (!Stringer.checkForEmpty(first_name)) {
// Если имя не является нулевым значением, то добавляем пробел и имя в строку.
result.append(" " + first_name);
} else {
// Если имя является нулевым значением, то добавляем "Нет" в строку.
result.append(" " + not);
}
// Проверяем, является ли отчество нулевым значением.
if (!Stringer.checkForEmpty(last_name)) {
// Если отчество не является нулевым значением, то добавляем пробел и отчество в строку.
result.append(" " + last_name);
} else {
// Если отчество является нулевым значением, то добавляем "Нет" в строку.
result.append(" " + not);
}
// Возвращаем объединенную строку или строку "Нет Нет Нет",
//если все входящие параметры являются нулевыми значениями.
return result.toString().trim();
}
/**
* Объединяет фамилию, имя и отчество из объекта преподавателя в одну строку.
* Возможные ситуации:
* - фамилия, имя или отчество могут содержать нулевые значения
* - отчество может содержать приписки
*
* @param teacher - объект преподавателя
* @return объединенная строка или строка "Нет Нет Нет",
* если все входящие параметры являются нулевыми значениями
*/
public static String getFioOf(Teacher teacher) {
// Инициализируем StringBuilder для хранения результата.
StringBuilder result = new StringBuilder();
// Проверяем, является ли фамилия нулевым значением.
if (!Stringer.checkForEmpty(teacher.getSecondName())) {
// Если фамилия не является нулевым значением, то добавляем ее в строку.
result.append(teacher.getSecondName());
} else {
// Если фамилия является нулевым значением, то добавляем "Нет" в строку.
result.append(not);
}
// Проверяем, является ли имя нулевым значением.
if (!Stringer.checkForEmpty(teacher.getFirstName())) {
// Если имя не является нулевым значением, то добавляем пробел и имя в строку.
result.append(" " + teacher.getFirstName());
} else {
// Если имя является нулевым значением, то добавляем "Нет" в строку.
result.append(" " + not);
}
// Проверяем, является ли отчество нулевым значением.
if (!Stringer.checkForEmpty(teacher.getLastName())) {
// Если отчество не является нулевым значением, то добавляем пробел и отчество в строку.
result.append(" " + teacher.getLastName());
} else {
// Если отчество является нулевым значением, то добавляем "Нет" в строку.
result.append(" " + not);
}
// Возвращаем объединенную строку или строку "Нет Нет Нет", если все входящие параметры
// являются нулевыми значениями.
return result.toString().trim();
}
/**
* Извлекает фамилию из строки, содержащей полное имя (ФИО).
* Строка ФИО может содержать:
* - пустую строку (null, empty, "")
* - одно слово (фамилия, "Нет", односложный комментарий)
* - два слова (фамилия, имя, "Нет")
* - три слова (фамилия, имя, отчество, "Нет")
* - четыре слова (фамилия, имя, отчество, постфикс отчества, комментарии)
* - и более.
*
* Все слова начиная с пятого однозначно являются бесполезным наполнением, однако
* такие слова должны включены в строку отчества, если они есть.
*
* Строка может быть извлечена из xlsx файла
* или сгенерирована из данныых содержащихся в базе данных
*
* @param fio строка, содержащая ФИО
* @return строка, содержащая первое слово из fio которое является фамилией или содержит слово "Нет"
*/
public static String getSecondNameOf(String fio) {
// Инициализируем StringBuilder для хранения результата.
StringBuilder result = new StringBuilder();
// Проверяем, является ли строка null, пустой строкой или состоит только из пробелов.
if (Stringer.checkForEmpty(fio)) {
// Если строка является нулевым значением, то добавляем "Нет" в строку.
result.append(not);
} else {
//убираем пробелы в начале и в конце строки
fio = fio.trim();
// Разделяем строку на пробелы и возвращаем первую часть, которая как ожидается является фамилией
result.append(fio.split(" ")[0]);
}
// Возвращаем первое слово в строке или строку "Нет"
return result.toString().trim();
}
/**
* Извлекает имя (фамилия, имя или отчество) из строки, предположительно содержащей только одно слово.
* - проверяет не пустая ли строка, если нет, то добавляет "Нет"
* - очищает строку от лишних пробельных символов
* - возвращает имя или "Нет"
*
* @param name
* @return name
*/
public static String getNameOf(String name) {
// Проверяем, является ли строка null, пустой строкой или состоит только из пробелов.
if (Stringer.checkForEmpty(name)) {
// Если строка является нулевым значением, то добавляем "Нет" в строку.
return not;
} else {
//очищаем строку
name = Stringer.clear(name);
// возвращаем имя
return name;
}
}
/**
* Извлекает имя из строки, содержащей полное имя (ФИО).
*
* @param fio строка, содержащая ФИО
* @return строка, содержащая второе слово из fio которое является именем или содержит слово "Нет"
*/
public static String getFirstNameOf(String fio) {
// Создаем StringBuilder для хранения результата
StringBuilder result = new StringBuilder();
// Проверяем, является ли строка null, пустой строкой или состоит только из пробелов.
if (Stringer.checkForEmpty(fio)) {
// Если строка является нулевым значением, то добавляем "Нет" в строку.
result.append(not);
} else {
//убираем излишние пробельные символы
fio = Stringer.clear(fio);
// Разбиваем строку по пробелам и пишем слова в массив
String[] strings = fio.split(" ");
// Если массив содержит два или более слов, то второе слово является именем.
if (strings.length > 1) {
// Пишем второе слово в результат
result.append(strings[1].trim());
}else {
// Если массив содержит только одно слово, то добавляем "Нет" в строку.
result.append(not);
}
}
// Возвращаем второе слово в строке или строку "Нет"
return result.toString().trim();
}
/**
* Извлекает отчество из строки, содержащей полное имя (ФИО).
* @param fio строка, содержащая ФИО
* @return строка, содержащая третье слово из fio которое является отчеством\
* или содержит слово "Нет"
* или содержит все слова, содержащиеся в ФИО, за исключением первых двух
*/
public static String getLastNameOf(String fio) {
// Создаем StringBuilder для хранения результата
StringBuilder result = new StringBuilder();
// Проверяем, является ли строка null, пустой строкой или состоит только из пробелов.
if (Stringer.checkForEmpty(fio)) {
// Если строка является нулевым значением, то добавляем "Нет" в строку.
result.append(not);
} else {
//убираем пробелы в начале и в конце строки
fio = fio.trim();
fio = Stringer.clear(fio);
String[] strings = fio.split(" ");
if (strings.length > 2) {
// Пишем третье и последующие слова в результат
for (int i = 2; i < strings.length; i++) {
result.append(strings[i]).append(" ");
}
} else {
// Если массив содержит только два или менее слов, то добавляем "Нет" в строку.
result.append(not);
}
}
// Возвращаем строку ФИО без первых двух слов с удаленными лишними пробелами
return result.toString().trim();
}
}

54
source/src/main/java/gsp/technologies/source/teh/strings/Stringer.java

@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
package gsp.technologies.source.teh.strings;
/**
* Класс для работы со строками
*/
public class Stringer {
/**
* Проверяет, является ли переданная строка null, пустой строкой или состоит только из пробелов.
*
* @param str Строка для проверки
* @return True если строка является null, пустой строкой или состоит только из пробелов
* False в противном случае
*/
public static Boolean checkForEmpty(String str) {
// Check if the string is null
if (str == null) {
return true;
}
// Check if the string is empty or consists only of whitespace characters
if (str.isEmpty() || str.trim().isEmpty()) {
return true;
}
// The string is not null, not empty and does not consist only of whitespace characters
return false;
}
/**
* Удаляет регулярным выражением лишние пробельные символы из строки.
*
* Заменяет знаки переноса строки на пробелы с помощью использования регулярного выражения
* \s+ - пробелы (и все ниже приведенные пробельные символы)
* \t - табуляция
* \v - вертикальная табуляция
* \r - перенос в начало строки
* \n - перенос строки
* \f - форматированный перенос строки
*
* Осавляет по одному пробелу между словами, если слов больше одного
* Возвращает пустую строку, если получена строка null
*
* @param string строка для обработки
* @return строку без лишних пробелов или пустую строку
*/
public static String clear(String string) {
// Проверяем, не является ли строка null. Если строка null, возвращаем пустую строку.
if (string == null) {
return "";
}
// Удаляем лишние пробелы из строки.
return string.replaceAll("\\s+", " ").trim();
}
}

1
source/src/main/resources/application.properties

@ -1 +0,0 @@ @@ -1 +0,0 @@
spring.application.name=source

18
source/src/main/resources/application.yaml

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
server:
port: 8181
spring:
application:
name: source
thymeleaf:
enabled: true
encoding: UTF-8
mode: LEGACYHTML5
# Разрешение на формирование скрытых запросов (DELETE)
mvc:
hiddenmethod:
filter:
enabled: true
format:
date: yyyy-MM-dd
date-time: yyyy-MM-dd HH:mm:ss
time: HH:mm:ss
Loading…
Cancel
Save