diff --git a/.gitignore b/.gitignore index 31e0805..e4e679f 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ dump.sql **/. .cursor hot +QWEN.md diff --git a/_docker/jenkins/Dockerfile b/_docker/jenkins/Dockerfile new file mode 100644 index 0000000..b77b9c8 --- /dev/null +++ b/_docker/jenkins/Dockerfile @@ -0,0 +1,24 @@ +# _docker/jenkins/Dockerfile + +FROM jenkins/jenkins:lts-jdk17 + +# Переключаемся на пользователя root для установки пакетов +USER root + +# Устанавливаем Docker CLI и другие утилиты +RUN apt-get update && apt-get install -y --no-install-recommends lsb-release curl && \ + curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc https://download.docker.com/linux/debian/gpg && \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.asc] https://download.docker.com/linux/debian $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list && \ + apt-get update && \ + apt-get install -y --no-install-recommends docker-ce-cli && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# Устанавливаем Docker Compose v2 (как плагин) +RUN mkdir -p /usr/local/lib/docker/cli-plugins && \ + curl -SL "https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-linux-$(uname -m)" -o /usr/local/lib/docker/cli-plugins/docker-compose && \ + chmod +x /usr/local/lib/docker/cli-plugins/docker-compose + +# Возвращаемся к пользователю jenkins +USER jenkins + diff --git a/app/Containers/Main/Actions/GetMainPageDataAction.php b/app/Containers/Main/Actions/GetMainPageDataAction.php new file mode 100644 index 0000000..bfa8931 --- /dev/null +++ b/app/Containers/Main/Actions/GetMainPageDataAction.php @@ -0,0 +1,35 @@ +getEducationsDataTask->run(); + $posts = $this->getRecentPostsTask->run(); + $events = $this->getUpcomingEventsTask->run(); + $page = $this->getPageDataTask->run(); + + $seo = $page->seo ?? null; + + return [ + 'educations' => $educations, + 'posts' => $posts, + 'events' => $events, + 'seo' => $seo + ]; + } +} \ No newline at end of file diff --git a/app/Containers/Main/Tasks/GetEducationsDataTask.php b/app/Containers/Main/Tasks/GetEducationsDataTask.php new file mode 100644 index 0000000..0f1719c --- /dev/null +++ b/app/Containers/Main/Tasks/GetEducationsDataTask.php @@ -0,0 +1,50 @@ +addHour(), function () { + return $this->getEducationsData(); + }); + } + + private function getEducationsData(): array + { + return [ + 'admission_campaign' => $this->getAdmissionCampaign(), + 'additional_education' => [ + 'educations_count' => AdditionalEducation::where('is_active', true)->count(), + 'categories_count' => AdditionalEducationCategory::where('is_active', true)->count(), + ], + ]; + } + + private function getAdmissionCampaign(): array + { + $info = AdmissionCampaign::first()->info ?? []; + + return collect($info)->reduce(function ($carry, $a) { + $lvl = LevelEducational::from((int)$a['edu_name'])->name; + $carry[$lvl] = [ + 'total_programs' => $a['total_programs'], + 'places' => [ + 'och_count' => $a['och_count'], + 'zaoch_count' => $a['zaoch_count'], + 'budget_places' => $a['budget_places'], + 'non_budget_places' => $a['non_budget_places'] + ], + ]; + return $carry; + }, []); + } +} \ No newline at end of file diff --git a/app/Containers/Main/Tasks/GetPageDataTask.php b/app/Containers/Main/Tasks/GetPageDataTask.php new file mode 100644 index 0000000..fe46ef9 --- /dev/null +++ b/app/Containers/Main/Tasks/GetPageDataTask.php @@ -0,0 +1,18 @@ +addHour(), function () use ($path) { + return Page::where('path', $path)->first(); + }); + } +} \ No newline at end of file diff --git a/app/Containers/Main/Tasks/GetRecentPostsTask.php b/app/Containers/Main/Tasks/GetRecentPostsTask.php new file mode 100644 index 0000000..7c87b77 --- /dev/null +++ b/app/Containers/Main/Tasks/GetRecentPostsTask.php @@ -0,0 +1,32 @@ +addHour(), function () { + return $this->getRecentPosts(); + }); + } + + private function getRecentPosts() + { + return PostThumbnailResource::collection( + Post::select('title', 'slug', 'authors', 'preview_text', 'category_id', 'preview', 'search_data', 'publish_at', 'created_at') + ->with('category') + ->where('publish_at', '<', Carbon::now()) + ->where('status', '=', PostStatus::PUBLISHED) + ->orderBy('publish_at', 'desc') + ->limit(3) + ->get() + ); + } +} \ No newline at end of file diff --git a/app/Containers/Main/Tasks/GetUpcomingEventsTask.php b/app/Containers/Main/Tasks/GetUpcomingEventsTask.php new file mode 100644 index 0000000..97bbd3f --- /dev/null +++ b/app/Containers/Main/Tasks/GetUpcomingEventsTask.php @@ -0,0 +1,31 @@ +addHour(), function () { + return $this->getUpcomingEvents(); + }); + } + + private function getUpcomingEvents() + { + $event_date_start = (new DateTime())->format('Y-m-d'); + + return EventThumbnailResource::collection( + Event::select('title', 'slug', 'event_date_start', 'event_time_start' , 'address', 'is_online', 'category_id') + ->where('event_date_start', '>=', $event_date_start) + ->orderBy('event_date_start', 'asc') + ->limit(3) + ->get() + ); + } +} \ No newline at end of file diff --git a/app/Containers/Main/UI/WEB/Controllers/MainController.php b/app/Containers/Main/UI/WEB/Controllers/MainController.php new file mode 100644 index 0000000..94af014 --- /dev/null +++ b/app/Containers/Main/UI/WEB/Controllers/MainController.php @@ -0,0 +1,21 @@ +getMainPageDataAction->run(); + + return Inertia::render('Main', $data); + } +} \ No newline at end of file diff --git a/app/Containers/Main/UI/WEB/Resources/MainPageResource.php b/app/Containers/Main/UI/WEB/Resources/MainPageResource.php new file mode 100644 index 0000000..9da30e8 --- /dev/null +++ b/app/Containers/Main/UI/WEB/Resources/MainPageResource.php @@ -0,0 +1,18 @@ + $this->educations, + 'posts' => $this->posts, + 'events' => $this->events, + 'seo' => $this->seo, + ]; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/MainController.php b/app/Http/Controllers/MainController.php index ebd12b0..acf05d3 100644 --- a/app/Http/Controllers/MainController.php +++ b/app/Http/Controllers/MainController.php @@ -2,110 +2,16 @@ namespace App\Http\Controllers; -use App\Containers\AdditionalEducation\Models\AdditionalEducation; -use App\Containers\AdditionalEducation\Models\AdditionalEducationCategory; -use App\Containers\AppStructure\Models\Page; -use App\Containers\Article\Enums\PostStatus; -use App\Containers\Article\Models\Post; -use App\Containers\Education\Models\AdmissionCampaign; -use App\Containers\Event\Models\Event; -use App\Containers\Event\UI\WEB\Transformers\EventThumbnailResource; -use App\Containers\Widget\UI\API\Transformers\PostThumbnailResource; -use App\Ship\Enums\Education\LevelEducational; -use Carbon\Carbon; -use DateTime; -use Illuminate\Support\Facades\Cache; -use Inertia\Inertia; - +/** + * @deprecated Use App\Containers\Main\UI\WEB\Controllers\MainController instead + * This controller is deprecated and will be removed in future versions. + * All logic has been moved to the Main container following Porto architecture. + */ class MainController extends Controller { public function index() { - // Кешируем данные на 60 минут (можно изменить время по необходимости) -// $admissionCampaign = Cache::remember('admission_campaign', now()->addHour(), function () { -// return $this->getAdmissionCampaign(); -// }); - -// $educations = Cache::remember('educations_data', now()->addHour(), function () { -// return $this->getEducationsData(); -// }); - - $educations = $this->getEducationsData(); - - $posts = Cache::remember('posts_recent', now()->addHour(), function () { - return $this->getRecentPosts(); - }); - -// $events = Cache::remember('upcoming_events', now()->addHour(), function () { -// return $this->getUpcomingEvents(); -// }); - - $events = $this->getUpcomingEvents(); - - $path = route('index', null, false); - $page = Cache::remember('page_' . $path, now()->addHour(), function () use ($path) { - return Page::where('path', $path)->first(); - }); - - $seo = $page->seo ?? null; - - return Inertia::render('Main', compact('posts', 'events', 'educations', 'seo')); - } - - private function getAdmissionCampaign() - { - $info = AdmissionCampaign::first()->info ?? []; - - return collect($info)->reduce(function ($carry, $a) { - $lvl = LevelEducational::from((int)$a['edu_name'])->name; - $carry[$lvl] = [ - 'total_programs' => $a['total_programs'], - 'places' => [ - 'och_count' => $a['och_count'], - 'zaoch_count' => $a['zaoch_count'], - 'budget_places' => $a['budget_places'], - 'non_budget_places' => $a['non_budget_places'] - ], - ]; - return $carry; - }, []); - } - - private function getEducationsData() - { - return [ - 'admission_campaign' => $this->getAdmissionCampaign(), - 'additional_education' => [ - 'educations_count' => AdditionalEducation::where('is_active', true)->count(), - 'categories_count' => AdditionalEducationCategory::where('is_active', true)->count(), - ], - ]; - } - - - private function getRecentPosts() - { - return PostThumbnailResource::collection( - Post::select('title', 'slug', 'authors', 'preview_text', 'category_id', 'preview', 'search_data', 'publish_at', 'created_at') - ->with('category') - ->where('publish_at', '<', Carbon::now()) - ->where('status', '=', PostStatus::PUBLISHED) - ->orderBy('publish_at', 'desc') - ->limit(3) - ->get() - ); - } - - private function getUpcomingEvents() - { - $event_date_start = (new DateTime())->format('Y-m-d'); - - return EventThumbnailResource::collection( - Event::select('title', 'slug', 'event_date_start', 'event_time_start' , 'address', 'is_online', 'category_id') - ->where('event_date_start', '>=', $event_date_start) - ->orderBy('event_date_start', 'asc') - ->limit(3) - ->get() - ); + // This method is deprecated. Use App\Containers\Main\UI\WEB\Controllers\MainController instead. + abort(500, 'MainController in Http namespace is deprecated. Use the containerized version.'); } } diff --git a/app/Jobs/CreateVkPostJob.php b/app/Jobs/CreateVkPostJob.php index 7a304c1..2b07e5e 100644 --- a/app/Jobs/CreateVkPostJob.php +++ b/app/Jobs/CreateVkPostJob.php @@ -41,7 +41,7 @@ class CreateVkPostJob implements ShouldQueue $this->videos = $videos; $this->documents = $documents; $this->publish_date = $publish_date; - $this->public_id = env('PUBLIC_ID'); + $this->public_id = config('services.vk.public_id'); } public function handle() @@ -382,7 +382,7 @@ class CreateVkPostJob implements ShouldQueue // Добавим проверку if(!isset($album['id'])) return []; - $uploadServer = (new VkAlbumService($vk))->getServerForUploadImages($album['id'], env('PUBLIC_ID')); + $uploadServer = (new VkAlbumService($vk))->getServerForUploadImages($album['id'], config('PUBLIC_ID')); foreach (array_chunk($images, 4) as $images_slice) { $images_data = (new VkAlbumService($vk))->uploadImagesToUploadServer($uploadServer['upload_url'], $images_slice); (new VkAlbumService($vk))->saveImagesToUploadServer( diff --git a/app/Jobs/ImportApiDataPost.php b/app/Jobs/ImportApiDataPost.php index 9784281..4d95c4c 100644 --- a/app/Jobs/ImportApiDataPost.php +++ b/app/Jobs/ImportApiDataPost.php @@ -32,13 +32,13 @@ class ImportApiDataPost implements ShouldQueue { try { // Получаем первую страницу данных - $response = Http::get(env('TRANSFER_PROXY_URL') . '/api/posts')->object(); + $response = Http::get(config('TRANSFER_PROXY_URL') . '/api/posts')->object(); $last_page = $response->last_page; Log::info('Last page: ' . $last_page); // Проходим по всем страницам for ($page = 1; $page <= $last_page; $page++) { - $response = Http::get(env('TRANSFER_PROXY_URL') . "/api/posts?page=$page")->object(); + $response = Http::get(config('TRANSFER_PROXY_URL') . "/api/posts?page=$page")->object(); $results = $response->data; // Обрабатываем каждую запись diff --git a/app/Jobs/UpdateVkPostJob.php b/app/Jobs/UpdateVkPostJob.php index d3cf64d..2c8d157 100644 --- a/app/Jobs/UpdateVkPostJob.php +++ b/app/Jobs/UpdateVkPostJob.php @@ -41,7 +41,7 @@ class UpdateVkPostJob implements ShouldQueue $this->videos = $videos; $this->documents = $documents; $this->publish_date = $publish_date; - $this->public_id = env('PUBLIC_ID'); + $this->public_id = config('services.vk.public_id'); } public function handle() @@ -324,7 +324,7 @@ class UpdateVkPostJob implements ShouldQueue $vk = new VKApiClient(); $album = (new VkAlbumService($vk))->createAlbum($title); - $uploadServer = (new VkAlbumService($vk))->getServerForUploadImages($album['id'], env('PUBLIC_ID')); + $uploadServer = (new VkAlbumService($vk))->getServerForUploadImages($album['id'], config('PUBLIC_ID')); foreach (array_chunk($images, 4) as $images_slice) { $images_data = (new VkAlbumService($vk))->uploadImagesToUploadServer($uploadServer['upload_url'], $images_slice); (new VkAlbumService($vk))->saveImagesToUploadServer( diff --git a/app/Services/App/Cache/AbstractCacheService.php b/app/Services/App/Cache/AbstractCacheService.php index f67adee..dc1ec6c 100644 --- a/app/Services/App/Cache/AbstractCacheService.php +++ b/app/Services/App/Cache/AbstractCacheService.php @@ -9,7 +9,7 @@ abstract class AbstractCacheService public function clearCacheByPrefix(string $prefix): void { // Получаем префикс из .env - $redisPrefix = env('REDIS_PREFIX', 'ntspi'); + $redisPrefix = config('database.redis.options.prefix', 'ntspi'); // Получаем ключи, соответствующие префиксу $keys = Redis::keys($prefix); diff --git a/app/Services/VK/Album/VkAlbumService.php b/app/Services/VK/Album/VkAlbumService.php index 6755994..16569b2 100644 --- a/app/Services/VK/Album/VkAlbumService.php +++ b/app/Services/VK/Album/VkAlbumService.php @@ -21,8 +21,8 @@ class VkAlbumService public function __construct(VKApiClient $vk) { $this->vk = $vk; $this->vkAuthService = new VkAuthService(); - $this->serviceToken = env('SERVICE_ACCESS_VK_KEY'); - $this->publicId = env('PUBLIC_ID'); + $this->serviceToken = config('services.vk.service_key'); + $this->publicId = config('services.vk.public_id'); } public function getServerForUploadImages($album_id, $group_id) @@ -109,7 +109,7 @@ class VkAlbumService $postFields = [ 'album_id' => $albumId, 'server' => $server, - 'group_id' => env('PUBLIC_ID'), + 'group_id' => config('services.vk.public_id'), 'photos_list' => $photosList, // Преобразуем массив в JSON-строку 'hash' => $hash, 'access_token' => $this->vkAuthService->getToken()->access_token, diff --git a/app/Services/VK/VkAuthService.php b/app/Services/VK/VkAuthService.php index 270f479..a301cf9 100644 --- a/app/Services/VK/VkAuthService.php +++ b/app/Services/VK/VkAuthService.php @@ -33,30 +33,6 @@ class VkAuthService } } -// public function redirectToProvider() -// { -// $state = bin2hex(random_bytes(16)); // Генерация случайной строки состояния -// session(['vk_state' => $state]); // -// -// $code_verifier = $this->generateCodeVerifier(); -// $code_challenge = $this->generateCodeChallenge($code_verifier); -// -// session(['vk_code_verifier' => $code_verifier]); -// -// -// $url = 'https://id.vk.ru/authorize?' . http_build_query([ -// 'response_type' => 'code', -// 'client_id' => env('VK_APP_ID'), -// 'redirect_uri' => env('VK_REDIRECT_URI'), -// 'state' => $state, -// 'scope' => 'photos wall video docs', -// 'code_challenge' => $code_challenge, -// 'code_challenge_method' => 's256', -// ]); -// -// return redirect($url); -// } - public function redirectToProvider() { $state = bin2hex(random_bytes(16)); // Генерирует случайную строку состояния (state) для защиты от CSRF-атак. @@ -69,8 +45,8 @@ class VkAuthService $url = 'https://id.vk.ru/authorize?' . http_build_query([ // Формирует URL для перенаправления на страницу авторизации VK ID с параметрами: 'response_type' => 'code', // Указывает, что нужен код авторизации. - 'client_id' => env('VK_APP_ID'), // ID приложения VK из переменных окружения. - 'redirect_uri' => env('VK_REDIRECT_URI'), // URI для перенаправления после авторизации. + 'client_id' => config('services.vk.app_id'), // ID приложения VK из переменных окружения. + 'redirect_uri' => config('services.vk.redirect_uri'), // URI для перенаправления после авторизации. 'state' => $state, // Передает строку состояния для проверки. 'scope' => 'photos wall video docs', // Запрашивает доступ к фото, стене, видео и документам. 'code_challenge' => $code_challenge, // Передает code_challenge для PKCE. @@ -115,9 +91,9 @@ class VkAuthService return Http::asForm()->post('https://id.vk.ru/oauth2/auth', [ 'grant_type' => 'authorization_code', 'code_verifier' => $codeVerifier, - 'redirect_uri' => env('VK_REDIRECT_URI_AFTER_AUTH'), + 'redirect_uri' => config('services.vk.'), 'code' => $request->code, - 'client_id' => env('VK_APP_ID'), + 'client_id' => config('services.vk.app_id'), 'device_id' => $request->device_id, 'state' => $request->state, 'scope' => 'photos wall video docs', @@ -129,7 +105,7 @@ class VkAuthService $response = Http::asForm()->post('https://id.vk.ru/oauth2/auth', [ 'grant_type' => 'refresh_token', 'refresh_token' => $refresh_token, - 'client_id' => env('VK_APP_ID'), + 'client_id' => config('services.vk.app_id'), 'device_id' => $device_id, 'state' => $state, 'scope' => 'photos wall video docs', diff --git a/app/Services/VK/VkService.php b/app/Services/VK/VkService.php index 6138c5e..654d5f1 100644 --- a/app/Services/VK/VkService.php +++ b/app/Services/VK/VkService.php @@ -19,7 +19,7 @@ class VkService $vk = new VKApiClient(); $this->wallService = new VkWallService($vk); $this->albumService = new VkAlbumService($vk); - $this->public_id = env('PUBLIC_ID'); + $this->public_id = config('services.vk.public_id'); $this->vkAuthService = new VkAuthService(); } @@ -108,7 +108,7 @@ class VkService public function createAlbum(string $title, $images) { $album = $this->albumService->createAlbum($title); - $uploadServer = $this->albumService->getServerForUploadImages($album['id'], env('PUBLIC_ID')); + $uploadServer = $this->albumService->getServerForUploadImages($album['id'], config('services.vk.public_id')); foreach (array_chunk($images, 4) as $images_slice) { $images_data = $this->albumService->uploadImagesToUploadServer($uploadServer['upload_url'], $images_slice); $this->albumService->saveImagesToUploadServer( @@ -142,7 +142,7 @@ class VkService return $baseUrl . $img; }, $images); - $photos = $this->uploadWallPhotos($imagePaths, env('PUBLIC_ID')); + $photos = $this->uploadWallPhotos($imagePaths, config('services.vk.public_id')); return implode(',', array_map(function($photo) { return "photo{$photo['owner_id']}_{$photo['id']}"; @@ -158,7 +158,7 @@ class VkService $videoPaths = array_map(function($vid) use ($baseUrl) { return $baseUrl . $vid; }, $videos); - return $this->uploadVideos($videoPaths, env('PUBLIC_ID')); // Возвращает массив, например: ['video123_456', 'video789_012'] + return $this->uploadVideos($videoPaths, config('services.vk.public_id')); // Возвращает массив, например: ['video123_456', 'video789_012'] } private function uploadVideos(array $videoPaths, ?int $groupId = null): array diff --git a/app/Services/VK/Wall/VkWallService.php b/app/Services/VK/Wall/VkWallService.php index 6623fcb..f1bc4d8 100644 --- a/app/Services/VK/Wall/VkWallService.php +++ b/app/Services/VK/Wall/VkWallService.php @@ -20,10 +20,10 @@ class VkWallService public function __construct(VKApiClient $vk) { $this->vk = $vk; - $this->wallToken = env('WALL_ACCESS_VK_TOKEN'); - $this->serviceToken = env('SERVICE_ACCESS_VK_KEY'); - $this->publicId = env('PUBLIC_ID'); - $this->publicDomain = env('PUBLIC_DOMAIN'); + $this->wallToken = config('services.vk.wall_token'); + $this->serviceToken = config('services.vk.service_key'); + $this->publicId = config('services.vk.public_id'); + $this->publicDomain = config('services.vk.public_id'); $this->vkAuthService = new VkAuthService(); } @@ -142,7 +142,7 @@ class VkWallService public function generateAttachmentsParams(string $attachmentType, int $attachmentId) { - $pubic_id = env('PUBLIC_ID'); + $pubic_id = config('services.vk.public_id'); switch ($attachmentType) { case 'album': { return "album-{$pubic_id}_{$attachmentId}"; diff --git a/app/Services/Vicon/DirectionStudy/AdmissionPlanService.php b/app/Services/Vicon/DirectionStudy/AdmissionPlanService.php index 3c00132..629073f 100644 --- a/app/Services/Vicon/DirectionStudy/AdmissionPlanService.php +++ b/app/Services/Vicon/DirectionStudy/AdmissionPlanService.php @@ -28,7 +28,7 @@ class AdmissionPlanService try { $response = $this->callAPI( "https://db-nica.ru/api/v1/campaigns", - env('VICON_TOKEN') + config('services.vicon.token') ); if (!is_array($response)) { Log::warning('Unexpected response type in getCampaigns', [ @@ -52,7 +52,7 @@ class AdmissionPlanService try { $response = $this->callAPI( "https://db-nica.ru/api/v1/planPriema/$campaign_levels_code", - env('VICON_TOKEN') + config('services.vicon.token') ); if (!is_object($response)) { diff --git a/app/Services/Vicon/DirectionStudy/DirectionStudyService.php b/app/Services/Vicon/DirectionStudy/DirectionStudyService.php index f7f6dc3..c8143ab 100644 --- a/app/Services/Vicon/DirectionStudy/DirectionStudyService.php +++ b/app/Services/Vicon/DirectionStudy/DirectionStudyService.php @@ -40,31 +40,31 @@ class DirectionStudyService public function getNaprs(int $edu_level): object { - $data = $this->callAPI("https://db-nica.ru/api/v1/naprs?perPage=200&filter_edu_level=$edu_level", env('VICON_TOKEN')); + $data = $this->callAPI("https://db-nica.ru/api/v1/naprs?perPage=200&filter_edu_level=$edu_level", config('services.vicon.token')); return $data; } public function getNapr(string $uuid): object { - $data = $this->callAPI("https://db-nica.ru/api/v1/napr/$uuid", env('VICON_TOKEN')); + $data = $this->callAPI("https://db-nica.ru/api/v1/napr/$uuid", config('services.vicon.token')); return $data; } public function getPrograms(int $edu_level): object { - $data = $this->callAPI("https://db-nica.ru/api/v1/programs?filter_edu_level=$edu_level&perPage=200", env('VICON_TOKEN')); + $data = $this->callAPI("https://db-nica.ru/api/v1/programs?filter_edu_level=$edu_level&perPage=200", config('services.vicon.token')); return $data; } public function getProgram(string $uuid): object { - $data = $this->callAPI("https://db-nica.ru/api/v1/program/$uuid", env('VICON_TOKEN')); + $data = $this->callAPI("https://db-nica.ru/api/v1/program/$uuid", config('services.vicon.token')); return $data; } public function getProgramDocs(string $uuid): object { - $data = $this->callAPI("https://db-nica.ru/api/v1/program/$uuid/edu-docs?perPage=200", env('VICON_TOKEN')); + $data = $this->callAPI("https://db-nica.ru/api/v1/program/$uuid/edu-docs?perPage=200", config('services.vicon.token')); return $data; } diff --git a/app/Services/Vicon/EducationalProgram/EducationalProgramService.php b/app/Services/Vicon/EducationalProgram/EducationalProgramService.php index 582de3f..fcb7b86 100644 --- a/app/Services/Vicon/EducationalProgram/EducationalProgramService.php +++ b/app/Services/Vicon/EducationalProgram/EducationalProgramService.php @@ -27,13 +27,13 @@ class EducationalProgramService public function getPrograms(int $edu_level) : object { - $data = $this->callAPI("https://db-nica.ru/api/v1/programs?filter_edu_level=$edu_level&perPage=200", env('VICON_TOKEN')); + $data = $this->callAPI("https://db-nica.ru/api/v1/programs?filter_edu_level=$edu_level&perPage=200", config('services.vicon.token')); return $data; } public function getProgram(string $uuid) : object { - $data = $this->callAPI("https://db-nica.ru/api/v1/program/$uuid", env('VICON_TOKEN')); + $data = $this->callAPI("https://db-nica.ru/api/v1/program/$uuid", config('services.vicon.token')); return $data; } diff --git a/config/services.php b/config/services.php index 1d56945..4064c3b 100644 --- a/config/services.php +++ b/config/services.php @@ -35,4 +35,20 @@ return [ 'id' => env('YANDEX_METRIKA_ID'), ], + 'vk' => [ + 'app_id' => env('VK_APP_ID'), + 'service_key' => env('SERVICE_ACCESS_VK_KEY'), + 'wall_token' => env('WALL_ACCESS_VK_TOKEN'), + 'public_id' => env('PUBLIC_ID'), + 'public_domain' => env('PUBLIC_DOMAIN'), + 'redirect_uri' => env('VK_REDIRECT_URI'), + 'redirect_uri_after_auth' => env('VK_REDIRECT_URI_AFTER_AUTH'), + ], + + 'vicon' => [ + 'token' => env('VICON_TOKEN'), + 'api_url' => 'https://db-nica.ru/api/v1', + ], + + ]; diff --git a/docker-compose.yml b/docker-compose.yml index 9ff1801..9ad898b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -100,10 +100,30 @@ services: networks: - app-network + jenkins: + build: + context: . + dockerfile: _docker/jenkins/Dockerfile + container_name: ntspi-jenkins + restart: always + ports: + - "8080:8080" # Порт для доступа к UI Jenkins + - "50000:50000" # Порт для агентов + volumes: + - jenkins_home:/var/jenkins_home # Сохранение данных Jenkins + - /var/run/docker.sock:/var/run/docker.sock # Доступ к Docker хоста + - ./:/var/www # Доступ к файлам проекта + networks: + - app-network + group_add: + - 999 volumes: cache: driver: local + jenkins_home: + driver: local + networks: app-network: driver: bridge diff --git a/routes/api.php b/routes/api.php index 819e481..50cce95 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,65 +1,3 @@ where('status', 1)->first(); -// return $activeCampaign->academic_year; -//})->name('academic.year'); - - - -Route::middleware('ensure.browser')->group(function () { -// Route::get('/getNavigation', [NavigateController::class, 'index'])->name('client.main.navigate'); - -// Route::get('/search', [SearchController::class, 'index'])->name('client.search.index'); -// -// Route::get('/static/search', [StaticSearchController::class, 'search'])->name('client.search.static'); -// Route::get('/static/categories', [StaticSearchController::class, 'getCategories'])->name('client.categories.static'); - - -// Route::get('/widget/get-posts', [ClientWidgetPostController::class, 'index'])->name('client.widget.post.index'); -// -// Route::get('/widget/get-posts/{id}', [ClientWidgetPostController::class, 'single'])->name('client.widget.post.single'); -// -// Route::get('/widget/get-additional-programs', [ClientWidgetAdditionalEducationalProgramController::class, 'index'])->name('client.widget.additional.program.index'); -// -// Route::get('/widget/get-educational-programs', [ClientWidgetEducationalProgramController::class, 'index'])->name('client.widget.educational.program.index'); -// -// Route::get('/widget/get-page-resource/{id}', [ClientWidgetPageReferenceListController::class, 'show'])->name('client.widget.page.resource.show'); -// -// Route::get('/widget/get-contact-widget/{id}', [ClientWidgetContactController::class, 'show'])->name('client.widget.contact.show'); -// -// Route::get('/widget/get-page/{path}', [ClientWidgetPageController::class, 'single'])->name('client.widget.page.single'); -// -// Route::get('/widget/get-form/{id}', [ClientWidgetFormController::class, 'single'])->middleware('rate.limited.check')->name('client.widget.form.single'); -// -// Route::post('/widget/get-form/{id}/submit', [ClientWidgetFormController::class, 'submit'])->middleware(['rate.limited.counter', 'rate.limited.check', 'form.time.period'])->name('client.widget.form.submit'); -// -// Route::get('/widget/get-slider/{slug}', [ClientWidgetSliderController::class, 'show'])->name('client.widget.slider.show'); -}); - - -//Route::middleware(['auth', 'superadmin'])->group(function () { -// Route::get('/get-edu-program-data', [UpdateEduDataApiController::class, 'index']); -// Route::get('/get-admission-plans-data', [UpdateAdmissionPlansDataApiController::class, 'index']); -// -// -// Route::get('/login/vk', [VkAuthService::class, 'redirectToProvider'])->name('vk.login'); -// Route::get('/login/vk/callback', [VkAuthService::class, 'handleProviderCallback'])->name('vk.callback'); -// Route::get('/vk-get-token', [VkAuthService::class, 'getToken'])->name('vk.getToken'); -// Route::get('/vk-refresh-token', [VkAuthService::class, 'refresh'])->name('vk.refreshToken'); -// Route::get('/vk-logout', [VkAuthService::class, 'logout'])->name('vk.logout'); -//}); - - - - - - - - -//Route::get('/vk-handle', [VkPostController::class, 'index']); -//Route::get('/vk-handle/get-auth-token', [VkAuthController::class, 'getToken']); -//Route::get('/vk-handle/wall', [VkPostController::class, 'wall']); diff --git a/routes/web.php b/routes/web.php index fbece99..ba5e2de 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,72 +1,14 @@ group(function () { - // Главная страница Route::get('/', [MainController::class, 'index'])->name('index'); Route::get('{path}', [PageController::class, 'render'])->where('path', '[0-9,a-z,/,-]+')->name('page.view'); - - -// // Расписание занятий -// Route::get('/schedule', [ClientScheduleController::class, 'index'])->name('client.schedule.index'); -// Route::get('/schedule/{id}', [ClientScheduleController::class, 'show'])->name('client.schedule.show'); - -// Route::get('/persons/{slug}', [PersonController::class, 'show'])->name('client.person.show'); - - // Новости -// Route::get('/news', [ClientPostController::class, 'index'])->name('client.post.index'); -// Route::get('/news/{slug}', [ClientPostController::class, 'show'])->name('client.post.show'); - - // Образовательные программы - -// Route::get('/programs/', [ClientProgramController::class, 'index'])->name('client.program.index'); -// Route::get('/program/{slug}', [ClientProgramController::class, 'show'])->name('client.program.show'); - - - // Образовательные программы -// Route::get('/additional-education/', [ClientAdditionalEducationController::class, 'index'])->name('client.additionalEducation.index'); -// Route::get('/additional-education/{slug}', [ClientAdditionalEducationController::class, 'show'])->name('client.additionalEducation.show'); - - // События -// Route::get('/events', [ClientEventController::class, 'index'])->name('client.event.index'); -// Route::get('/events/archive', [ClientEventController::class, 'archive'])->name('client.event.archive'); // Доделать builder -// Route::get('/events/{slug}', [ClientEventController::class, 'show'])->name('client.event.show'); - -// // Заметки библиотеки -// Route::get('/library/news', [ClientLibraryNewsController::class, 'index'])->name('client.library.news.index'); // Доделать builder -// Route::get('/library/news/{slug}', [ClientLibraryNewsController::class, 'show'])->name('client.library.news.show'); -// -// // Виртуальные выставки библиотеки -// Route::get('/library/exhibition', [ClientVirtualExhibitionController::class, 'index'])->name('client.library.exhibition.index'); // Доделать builder -// Route::get('/library/exhibition/{slug}', [ClientVirtualExhibitionController::class, 'show'])->name('client.library.exhibition.show'); - - // Вакансии вуза -// Route::get('/vacant/', [ClientVacantPositionController::class, 'index'])->name('client.vacant.index'); - -// // Вакансии других учереждений -// Route::get('/current-vacancies/', [ClientExternalVacancyController::class, 'index'])->name('client.external.vacant.index'); // Доделать builder -// Route::get('/current-vacancies/{id}', [ClientExternalVacancyController::class, 'show'])->name('client.external.vacant.show'); - - -// Route::get('/academic-journals/', [ClientAcademicJournalController::class, 'index'])->name('client.academicJournals.index'); -// Route::get('/academic-journals/{slug}', [ClientAcademicJournalController::class, 'show'])->name('client.academicJournals.show'); - -// // Факультеты и кафедры -// Route::get('/faculties', [ClientFacultyController::class, 'index'])->name('client.faculty.index'); -// Route::get('/faculties/{slug}', [ClientFacultyController::class, 'show'])->name('client.faculty.show'); -// Route::get('/faculties/{facultySlug}/{departmentSlug}', [ClientDepartmentController::class, 'show'])->name('client.department.show'); -// -// // Подразделения института -// Route::get('/divisions', [ClientDivisionController::class, 'index'])->name('client.division.index'); -// Route::get('/divisions/{slug}', [ClientDivisionController::class, 'show'])->name('client.division.show'); - });