diff --git a/documentation/general/architecture.md b/documentation/general/architecture.md index fdceb7a..e703f36 100644 --- a/documentation/general/architecture.md +++ b/documentation/general/architecture.md @@ -1,3 +1,6 @@ # Архитектура платформы teh ## диаграмма компонентов ![диаграмма компонентов](architecture.png) +## диаграмма состояний (teh.face) +![диаграмма компонентов](states.png) + diff --git a/documentation/general/states.png b/documentation/general/states.png new file mode 100644 index 0000000..32b2cb6 Binary files /dev/null and b/documentation/general/states.png differ diff --git a/documentation/general/states.puml b/documentation/general/states.puml index 8641f82..c9496bf 100644 --- a/documentation/general/states.puml +++ b/documentation/general/states.puml @@ -1,4 +1,5 @@ @startuml +title "teh.face : диаграмма состояний (state)\n {структура графического интерфейса платформы}" left to right direction ' МЕЙНФРЕЙМ @@ -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 buildingsLink { - buildingsLink : Переход к работе с данными объектов строительства + state teachersLink { + teachersLink : Переход к работе с данными преподавателей } + } + + 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 storageLink --> storage viewLink --> view -' mainframe : пользователь видит: -' mainframe : - статистика базы данных -' mainframe : - статистика файлообменника -' mainframe : - панель для переходов - - - @enduml \ No newline at end of file diff --git a/face/logs/teh.log b/face/logs/teh.log index 9d8571d..19614eb 100644 --- a/face/logs/teh.log +++ b/face/logs/teh.log @@ -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"} diff --git a/face/logs/teh.log.2024-10-07.0.gz b/face/logs/teh.log.2024-10-07.0.gz deleted file mode 100644 index 3d0d08d..0000000 Binary files a/face/logs/teh.log.2024-10-07.0.gz and /dev/null differ diff --git a/face/logs/teh.log.2024-10-14.0.gz b/face/logs/teh.log.2024-10-14.0.gz new file mode 100644 index 0000000..0d11b5e Binary files /dev/null and b/face/logs/teh.log.2024-10-14.0.gz differ diff --git a/face/src/main/java/gsp/technologies/face/config/WebConfig.java b/face/src/main/java/gsp/technologies/face/config/WebConfig.java new file mode 100644 index 0000000..c3faea9 --- /dev/null +++ b/face/src/main/java/gsp/technologies/face/config/WebConfig.java @@ -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; + } +} diff --git a/face/src/main/java/gsp/technologies/face/controllers/face/v1/mainframe/MainframeController.java b/face/src/main/java/gsp/technologies/face/controllers/face/v1/mainframe/MainframeController.java index 6eb2863..ea4305d 100644 --- a/face/src/main/java/gsp/technologies/face/controllers/face/v1/mainframe/MainframeController.java +++ b/face/src/main/java/gsp/technologies/face/controllers/face/v1/mainframe/MainframeController.java @@ -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 (){}) + .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 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 (){}) + // .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 (){}) + // .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 (){}) + // .block(); + + + // System.out.println("Файл добавлен в хранилище: " + ok); + // System.out.println("ID: " + doc.getId()); + // System.out.println(doc.toString()); + + //переход на страницу импорта данных из документа + return "redirect:/face/v1/mainframe"; + } } diff --git a/face/src/main/java/gsp/technologies/face/models/FileMetadata.java b/face/src/main/java/gsp/technologies/face/models/FileMetadata.java new file mode 100644 index 0000000..3ce0b7f --- /dev/null +++ b/face/src/main/java/gsp/technologies/face/models/FileMetadata.java @@ -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"); + } +} \ No newline at end of file diff --git a/face/src/main/java/gsp/technologies/face/models/Post.java b/face/src/main/java/gsp/technologies/face/models/Post.java new file mode 100644 index 0000000..d2f8181 --- /dev/null +++ b/face/src/main/java/gsp/technologies/face/models/Post.java @@ -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; + } +} diff --git a/face/src/main/java/gsp/technologies/face/services/StorageService.java b/face/src/main/java/gsp/technologies/face/services/StorageService.java new file mode 100644 index 0000000..b572bb7 --- /dev/null +++ b/face/src/main/java/gsp/technologies/face/services/StorageService.java @@ -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 getDocumentList() { + // System.out.println("Получение списка документов, размещенных в файловом хранилище ..."); + // return client.method(HttpMethod.GET) + // .uri(storageListLink) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // } + + // public Document getDocumentById(String id) { + // // TODO: добавить линк в storage-rs, для получения документа по id + // List documents = client.method(HttpMethod.GET) + // .uri(storageListLink) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // Document result = new Document(); + // for (Document document : documents) { + // if (document.getId() == Integer.parseInt(id)) { + // result = document; + // } + // } + // return result; + // } + + /** + * Получение списка постов, размещенных в ресурсном сервисе + * @param id + * @return + */ + public List getPostList() { + System.out.println("Получение списка постов, размещенных в ресурсном сервисе ..."); + return client.method(HttpMethod.GET) + .uri(postListLink) + .retrieve() + .bodyToMono(new ParameterizedTypeReference >(){}) + .block(); + } + + /** + * Получение поста по id + * @param postID + * @return + */ + public Post getPostById(String postID) { + // TODO: добавить линк в storage-rs, для получения поста по id + List posts = client.method(HttpMethod.GET) + .uri(postListLink) + .retrieve() + .bodyToMono(new ParameterizedTypeReference >(){}) + .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 posts = client.method(HttpMethod.GET) + .uri(postListLink) + .retrieve() + .bodyToMono(new ParameterizedTypeReference >(){}) + .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> + * @param docId + * @return + */ + // public Map> getDocumentContentAsMap(String docId) { + // System.out.println("Получение данных xlsx-файла в виде Map> ..."); + // String url = storageDocumentContentLink + "?filename=" + docId + ".xlsx"; + // Map> cells = client.method(HttpMethod.GET) + // .uri(url) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >>(){}) + // .block(); + // return cells; + // } + + /** + * Получение строки из xlsx-файла + * @param docId + * @param line + * @return + */ + // public List getDocumentContentByLines(String docId, String line) { + // System.out.println("Получение данных xlsx-файла в виде List по строке ..."); + // String url = storageDocumentContentLink + "/line" + "?filename=" + docId + ".xlsx&line=" + line; + // List cells = client.method(HttpMethod.GET) + // .uri(url) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // return cells; + // } + + /** + * Получение частей из xlsx-файла + * @param docId + * @param from + * @param count + * @return + */ + // public Map> getDocumentContentByParts(String docId, int from, int count) { + // System.out.println("Получение данных xlsx-файла в виде Map> по частям ..."); + // String url = storageDocumentContentLink + "/part" + "?filename=" + docId + ".xlsx&from=" + from + "&count=" + count; + // Map> cells = client.method(HttpMethod.GET) + // .uri(url) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >>(){}) + // .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 getDocumentContentByColumn(Integer docId, Integer column) { + // System.out.println("Получение данных xlsx-файла в виде List по столбцу ..."); + // String url = storageDocumentContentLink + "/column" + "?filename=" + docId + ".xlsx&column=" + column; + // List cells = client.method(HttpMethod.GET) + // .uri(url) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // return cells; + // } + + // public List getUniqueDocumentContentByColumn(int docId, int column) { + // System.out.println("Получение уникальных данных xlsx-файла в виде List по столбцу #" + column + " ..."); + // String url = storageDocumentContentLink + "/column/unique" + "?filename=" + docId + ".xlsx&column=" + column; + // List cells = client.method(HttpMethod.GET) + // .uri(url) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // return cells; + // } + + + /*********************************************************************** */ + /* + * Извлечение данных (списков моделей) из xlsx - перебор xlsx по кускам + */ + // public List getProgramCretareasFromFile(Post post) { + // List 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> cells = this.getDocumentContentByParts(post.getDocument().getId().toString(), from, portion); + // for (Map.Entry> 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 (){}) + // .block(); + // } + + /** + * Получение перечня программ обучения из базы + * @param id + * @return + */ + // public List getBasePrograms() { + // System.out.println("Получение перечня программ обучения из базы ..."); + // List list = client.method(HttpMethod.GET) + // .uri(programsLink) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // return list; + // } + + // public List getAbsentPrograms(List xlsxList) { + // List baseList = getBasePrograms(); + + // if (xlsxList == null || xlsxList.isEmpty()) { + // return new ArrayList(); + // } + + // List 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 xlsxList) { + // return getAbsentPrograms(xlsxList).size(); + // } + + /** + * Получение перечня объектов строительства из базы + * @param id + * @return + */ + // public List getBaseBuildings() { + // System.out.println("Получение перечня объектов строительства из базы ..."); + // List list = client.method(HttpMethod.GET) + // .uri(buildingsLink) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // return list; + // } + + // public List getAbsentBuildings(List xlsxList) { + // List baseList = getBaseBuildings(); + + // if (xlsxList == null || xlsxList.isEmpty()) { + // return new ArrayList(); + // } + // List 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 xlsxList) { + // return getAbsentBuildings(xlsxList).size(); + // } + + // public int getBuildingsCount() { + // return getBaseBuildings().size(); + // } + + /** + * Получение списка курсов из базы данных + */ + // public List getBaseCourses() { + // System.out.println("Получение списка курсов из базы данных ..."); + // List list = client.method(HttpMethod.GET) + // .uri(coursesLink) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // return list; + // } + + // public List getAbsentCourses(List xlsxList) { + // List baseList = getBaseCourses(); + + // if (xlsxList == null || xlsxList.isEmpty()) { + // return new ArrayList(); + // } + // List 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 xlsxList) { + // return getAbsentCourses(xlsxList).size(); + // } + + /** + * Получение перечня преподавателей из базы данных + */ + // public List getBaseTeachers() { + // System.out.println("Получение перечня преподавателей из базы данных ..."); + // List list = client.method(HttpMethod.GET) + // .uri(teachersLink) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // return list; + // } + + /** + * Получение перечня преподавателей из xlsx-файла + * + * @return > Перечень преподавателей, полученных из xlsx-файла + * В объектах перечня незаполнены поля id + * Объекты сформированы на основании ФИО преподавателя, указанного в xlsx-файле + * + */ + // public List getXlsxTeachers(XlsxDocument xlsx) { + // System.out.println("Получение перечня преподавателей из xlsx-файла ..."); + // List list = new ArrayList<>(); + // // получаем данные в виде мапы строк + // Map> map = xlsx.getData(); + + // // удаляем строку заголовков + // map.remove(0); + + // for (Map.Entry> entry : map.entrySet()) { + // String fio = Stringer.clear(entry + // .getValue() + // .get(18) + // .getContent()); + // list.add(new Teacher(fio)); + // } + + // // удаляем дубликаты + // Set set = new HashSet<>(list); + // list = new ArrayList<>(set); + // return list; + // } + + + + /** + * Получение списка преподавателей, отсутствующих в базе данных (новых преподавателей) + * + * @param xlsxList список уникальных преподаватетей из файла + * @param baseList список преподавателей из базы + * @return List + */ + // public List getAbsentTeachers(List xlsxList, List baseList) { + // System.out.println("Получение списка преподавателей, отсутствующих в базе данных ..."); + // if (xlsxList == null || xlsxList.isEmpty()) { + // return new ArrayList(); + // } + // List 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 getAbsentTeachers(List xlsxList) { + // return getAbsentTeachers(xlsxList, getBaseTeachers()); + // } + + // public List sortTeachers(List list) { + // System.out.println("Сортировка списка преподавателей ..."); + // Comparator 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 uniqueTeachers) { + // return getAbsentTeachers(uniqueTeachers).size(); + // } + + + /** + * Получение списка критериев из баз данных + */ + // public List getBaseCretareas() { + // System.out.println("Получение списка критериев из баз данных ..."); + // List list = client.method(HttpMethod.GET) + // .uri(cretareasLink) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // return list; + // } + + // public List getAbsentCretareas(List xlsxList) { + // List baseList = getBaseCretareas(); + + // if (xlsxList == null || xlsxList.isEmpty()) { + // return new ArrayList(); + // } + + // List 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 xlsxList) { + // return getAbsentCretareas(xlsxList).size(); + // } + + /** + * Получение списка организаций из базы данных + */ + // public List getBaseOrganizations() { + // System.out.println("Получение списка организаций из базы данных ..."); + // List list = client.method(HttpMethod.GET) + // .uri(organizationsLink) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // return list; + // } + + // public List getAbsentOrganizations(List xlsxList) { + // List baseList = getBaseOrganizations(); + // if (xlsxList == null || xlsxList.isEmpty()) { + // return new ArrayList(); + // } + + // List 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 xlsxList) { + // return getAbsentOrganizations(xlsxList).size(); + // } + + // /** + // * Получение списка студентов из базы данных + // */ + // public List getBaseStudents() { + // System.out.println("Получение списка студентов из базы данных ..."); + // List list = client.method(HttpMethod.GET) + // .uri(studentsLink) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // return list; + // } + + // public List getAbsentStudents(List xlsxList) { + // List baseList = getBaseStudents(); + // if (xlsxList == null || xlsxList.isEmpty()) { + // return new ArrayList(); + // } + + // List 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 xlsxList) { + // return getAbsentStudents(xlsxList).size(); + // } + + // public List getBaseEducationEntries() { + // System.out.println("Получение списка записей об обучениях из базы данных ..."); + // List list = client.method(HttpMethod.GET) + // .uri(educationEntriesLink) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // return list; + // } + + // public List getAbsentEducationEntries(List xlsxList) { + // List baseList = getBaseEducationEntries(); + // if (xlsxList == null || xlsxList.isEmpty()) { + // return new ArrayList(); + // } + + // List 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 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 getProgramCretareasFromBase() { + // System.out.println("Получение списка критериев из баз данных ..."); + // List list = client.method(HttpMethod.GET) + // .uri(cretareasLink) + // .retrieve() + // .bodyToMono(new ParameterizedTypeReference >(){}) + // .block(); + // return list; + // } + + // public Integer getProgramCretareaCountFromBase(){ + // int count = client.method(HttpMethod.GET) + // .uri(programCretareaCountFromBaseLink) + // .retrieve() + // .bodyToMono(Integer.class) + // .block(); + // return count; + // } +} diff --git a/face/src/main/java/gsp/technologies/face/teh/fs/MpFile.java b/face/src/main/java/gsp/technologies/face/teh/fs/MpFile.java new file mode 100644 index 0000000..19ff7b2 --- /dev/null +++ b/face/src/main/java/gsp/technologies/face/teh/fs/MpFile.java @@ -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 + } + +} diff --git a/face/src/main/resources/static/content/md/mainframe.md b/face/src/main/resources/static/content/md/mainframe.md index c7e4897..f86ea7d 100644 --- a/face/src/main/resources/static/content/md/mainframe.md +++ b/face/src/main/resources/static/content/md/mainframe.md @@ -1,5 +1,10 @@ -# mainframe.md +# Инструкция по работе с платформой (mainframe.md) Форма предоставляет пользователю доступ ко всему функционалу платформы - ссылка на страницу работы с файлами (загрузка, проверка файлов) - ссылка на страницу работы с данными базы (редактирование данных, формирование отчетов) -- \ No newline at end of file + +## Загрузка файлов на платформу +### Общее +- xlsx файл не должен содержать более 5 тыс. строк +- все ячейки должны содержать значения (формулы платформа не пересчитает) +### Реестры обученных diff --git a/face/src/main/resources/templates/fragments/common/footer.html b/face/src/main/resources/templates/fragments/common/footer.html new file mode 100644 index 0000000..51062d3 --- /dev/null +++ b/face/src/main/resources/templates/fragments/common/footer.html @@ -0,0 +1,13 @@ + + + +
+
+ © 2024 ООО "ГСП-Технологии" +
+
+
+ +
+ + \ No newline at end of file diff --git a/face/src/main/resources/templates/fragments/storage.html b/face/src/main/resources/templates/fragments/storage.html new file mode 100644 index 0000000..66cbe4a --- /dev/null +++ b/face/src/main/resources/templates/fragments/storage.html @@ -0,0 +1,27 @@ + + + + +
+
+

Добавление пакетов:

+
+ + + + + +
+
+ + \ No newline at end of file diff --git a/face/src/main/resources/templates/mainframe.html b/face/src/main/resources/templates/mainframe.html index 79cde0d..f900ad1 100644 --- a/face/src/main/resources/templates/mainframe.html +++ b/face/src/main/resources/templates/mainframe.html @@ -7,29 +7,139 @@ th-шаблон, для предоставления доступа к функ xmlns:th="http://www.thymeleaf.org"> + teh-mainframe -

teh-mainframe

-
+
- + +

Хранилище данных

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Критерии0
Программы0
Преподаватели0
Объекты строительства0
Организации0
Курсы0
Студенты0
Обучения0
+
+ +

Извлечение данных

+ + + + + + + + + + + + + + + + + + + + + + +
Формы ФРДО
Формы ЕИСОТ
Протокол
Приказ о зачислении
Приказ об отчислении
Документы об обучении
+
+ +

Импорт данных в базу

+ + +
+ + +

Последние загруженные документы: COUNT

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Вид документаНаименованиеВремя загрузкиСтатус
Реестр обученныхНаименование.xlsxдатаобработан/не обработан
Реестр обученныхНаименование.xlsxдатаобработан/не обработан
Реестр обученныхНаименование.xlsxдатаобработан/не обработан
Реестр обученныхНаименование.xlsxдатаобработан/не обработан
Реестр обученныхНаименование.xlsxдатаобработан/не обработан
+
- +
+
diff --git a/source/docker-compose.yaml b/source/docker-compose.yaml new file mode 100644 index 0000000..0ae8816 --- /dev/null +++ b/source/docker-compose.yaml @@ -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 \ No newline at end of file diff --git a/source/dockerfile b/source/dockerfile new file mode 100644 index 0000000..9c53e24 --- /dev/null +++ b/source/dockerfile @@ -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 \ No newline at end of file diff --git a/source/pom.xml b/source/pom.xml index b9fb17d..9468f07 100644 --- a/source/pom.xml +++ b/source/pom.xml @@ -34,20 +34,23 @@ org.springframework.boot spring-boot-starter-thymeleaf + + org.projectlombok + lombok + true + org.springframework.boot spring-boot-starter-web - org.postgresql postgresql runtime - org.projectlombok - lombok - true + org.springframework.boot + spring-boot-starter-data-jpa org.springframework.boot @@ -72,5 +75,4 @@ - diff --git a/source/src/main/java/gsp/technologies/source/controllers/api/v1/StorageController.java b/source/src/main/java/gsp/technologies/source/controllers/api/v1/StorageController.java new file mode 100644 index 0000000..cd8f19d --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/controllers/api/v1/StorageController.java @@ -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> getStorageEntries(){ + return new ResponseEntity<>(metaRepo.findAll(), HttpStatus.OK); + } + + @GetMapping("/post/list") + public ResponseEntity> 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 deleteStorageEntry(@PathVariable Integer id){ + FileMetadata meta= metaRepo.findById(id); + metaRepo.delete(meta); + return new ResponseEntity<>("Запись id#" + id + " удалена ... ", HttpStatus.OK); + } +} \ No newline at end of file diff --git a/source/src/main/java/gsp/technologies/source/models/Building.java b/source/src/main/java/gsp/technologies/source/models/Building.java new file mode 100644 index 0000000..f15b7db --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/models/Building.java @@ -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; + } +} diff --git a/source/src/main/java/gsp/technologies/source/models/Course.java b/source/src/main/java/gsp/technologies/source/models/Course.java new file mode 100644 index 0000000..e325310 --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/models/Course.java @@ -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;//сведения об объекте строительства +} diff --git a/source/src/main/java/gsp/technologies/source/models/EducationEntry.java b/source/src/main/java/gsp/technologies/source/models/EducationEntry.java new file mode 100644 index 0000000..901fad1 --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/models/EducationEntry.java @@ -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;//Сведения о студенте +} diff --git a/source/src/main/java/gsp/technologies/source/models/FileMetadata.java b/source/src/main/java/gsp/technologies/source/models/FileMetadata.java new file mode 100644 index 0000000..c7e05e4 --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/models/FileMetadata.java @@ -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"); + } +} diff --git a/source/src/main/java/gsp/technologies/source/models/Organization.java b/source/src/main/java/gsp/technologies/source/models/Organization.java new file mode 100644 index 0000000..bd41ddb --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/models/Organization.java @@ -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; + } +} diff --git a/source/src/main/java/gsp/technologies/source/models/Post.java b/source/src/main/java/gsp/technologies/source/models/Post.java new file mode 100644 index 0000000..b92cf30 --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/models/Post.java @@ -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; + } +} diff --git a/source/src/main/java/gsp/technologies/source/models/Program.java b/source/src/main/java/gsp/technologies/source/models/Program.java new file mode 100644 index 0000000..cc809fa --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/models/Program.java @@ -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; +} diff --git a/source/src/main/java/gsp/technologies/source/models/ProgramCretarea.java b/source/src/main/java/gsp/technologies/source/models/ProgramCretarea.java new file mode 100644 index 0000000..5be864a --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/models/ProgramCretarea.java @@ -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; + } +} diff --git a/source/src/main/java/gsp/technologies/source/models/Student.java b/source/src/main/java/gsp/technologies/source/models/Student.java new file mode 100644 index 0000000..76c0224 --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/models/Student.java @@ -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;//Организация - работодатель + +} diff --git a/source/src/main/java/gsp/technologies/source/models/Teacher.java b/source/src/main/java/gsp/technologies/source/models/Teacher.java new file mode 100644 index 0000000..ffc9f1c --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/models/Teacher.java @@ -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()); + } +} diff --git a/source/src/main/java/gsp/technologies/source/repositories/FileMetadataRepository.java b/source/src/main/java/gsp/technologies/source/repositories/FileMetadataRepository.java new file mode 100644 index 0000000..46bf1f1 --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/repositories/FileMetadataRepository.java @@ -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 findById(long id); + Page findById(PageRequest of, Long id); +} diff --git a/source/src/main/java/gsp/technologies/source/repositories/PostRepository.java b/source/src/main/java/gsp/technologies/source/repositories/PostRepository.java new file mode 100644 index 0000000..ac38c68 --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/repositories/PostRepository.java @@ -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 { +} \ No newline at end of file diff --git a/source/src/main/java/gsp/technologies/source/services/FileMetadataService.java b/source/src/main/java/gsp/technologies/source/services/FileMetadataService.java new file mode 100644 index 0000000..33b9f31 --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/services/FileMetadataService.java @@ -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; + } + +} diff --git a/source/src/main/java/gsp/technologies/source/services/PostService.java b/source/src/main/java/gsp/technologies/source/services/PostService.java new file mode 100644 index 0000000..531cb87 --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/services/PostService.java @@ -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; + } + +} diff --git a/source/src/main/java/gsp/technologies/source/teh/strings/Arrayer.java b/source/src/main/java/gsp/technologies/source/teh/strings/Arrayer.java new file mode 100644 index 0000000..e2a9e6e --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/teh/strings/Arrayer.java @@ -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 uniqueList(List list) { + // Удаление повторяющихся элементов списка + List result = list.stream().distinct().toList(); + return result; + } + + +} diff --git a/source/src/main/java/gsp/technologies/source/teh/strings/Dater.java b/source/src/main/java/gsp/technologies/source/teh/strings/Dater.java new file mode 100644 index 0000000..9d81108 --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/teh/strings/Dater.java @@ -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; +} diff --git a/source/src/main/java/gsp/technologies/source/teh/strings/Naimer.java b/source/src/main/java/gsp/technologies/source/teh/strings/Naimer.java new file mode 100644 index 0000000..df90e56 --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/teh/strings/Naimer.java @@ -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(); + } +} diff --git a/source/src/main/java/gsp/technologies/source/teh/strings/Stringer.java b/source/src/main/java/gsp/technologies/source/teh/strings/Stringer.java new file mode 100644 index 0000000..071b6e2 --- /dev/null +++ b/source/src/main/java/gsp/technologies/source/teh/strings/Stringer.java @@ -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(); + } +} diff --git a/source/src/main/resources/application.properties b/source/src/main/resources/application.properties deleted file mode 100644 index 97f565a..0000000 --- a/source/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name=source diff --git a/source/src/main/resources/application.yaml b/source/src/main/resources/application.yaml new file mode 100644 index 0000000..4ca9b9a --- /dev/null +++ b/source/src/main/resources/application.yaml @@ -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 \ No newline at end of file