Rework admin panel and other

This commit is contained in:
F4ilji
2025-04-02 18:37:20 +05:00
parent 49072e50c7
commit 5cd6ff11b5
198 changed files with 9715 additions and 6664 deletions
@@ -2,37 +2,76 @@
namespace App\Http\Controllers;
use App\Enums\CacheKeys;
use App\Http\Resources\ClientAcademicJournalListResource;
use App\Http\Resources\ClientVirtualExhibitionListResource;
use App\Models\AcademicJournal;
use App\Models\JournalIssue;
use App\Models\VirtualExhibition;
use Illuminate\Http\Request;
use App\Services\App\Breadcrumb\BreadcrumbService;
use App\Services\App\Seo\SeoPageProvider;
use Illuminate\Support\Facades\Cache;
use Inertia\Inertia;
class ClientAcademicJournalController extends Controller
{
public function __construct(readonly SeoPageProvider $seoPageProvider){}
public function index()
{
$journals = ClientAcademicJournalListResource::collection(AcademicJournal::query()->get());
$journals = Cache::remember(
CacheKeys::ACADEMIC_JOURNALS_PREFIX->value . 'list',
now()->addWeek(), // Кешируем на неделю, так как журналы меняются редко
function () {
return ClientAcademicJournalListResource::collection(
AcademicJournal::query()->get()
);
}
);
return Inertia::render('Client/AcademicJournals/Index', compact('journals'));
$seo = $this->seoPageProvider->getSeoForCurrentPage();
return Inertia::render('Client/AcademicJournals/Index', compact('journals', 'seo'));
}
public function show(string $slug)
{
$journal = new ClientAcademicJournalListResource(AcademicJournal::query()->where('slug', '=', $slug)->firstOrFail());
$journalIssues = JournalIssue::where('academic_journal_id', $journal->id)
->groupBy('year_publication')->get();
// Кешируем основной журнал
[$journal, $seo] = Cache::remember(
CacheKeys::ACADEMIC_JOURNAL_PREFIX->value . $slug,
now()->addWeek(),
function () use ($slug) {
$journal = AcademicJournal::query()
->where('slug', $slug)
->firstOrFail();
$seo = $this->seoPageProvider->getSeoForModel($journal);
return [
new ClientAcademicJournalListResource($journal),
$seo
];
}
);
$journals = [];
// Кешируем выпуски журнала, сгруппированные по годам
$journals = Cache::remember(
CacheKeys::ACADEMIC_JOURNAL_PREFIX->value . 'issues_' . $slug,
now()->addWeek(),
function () use ($journal) {
$journalIssues = JournalIssue::where('academic_journal_id', $journal->id)
->get()
->groupBy('year_publication');
foreach ($journalIssues as $year => $journalGroup) {
$journals[] = [
'year_publication' => $year,
'journalIssues' => $journalGroup
];
}
return Inertia::render('Client/AcademicJournals/Show', compact('journal', 'journals'));
$groupedIssues = [];
foreach ($journalIssues as $year => $journalGroup) {
$groupedIssues[] = [
'year_publication' => $year,
'journalIssues' => $journalGroup
];
}
return $groupedIssues;
}
);
return Inertia::render('Client/AcademicJournals/Show', compact('journal', 'journals', 'seo'));
}
}
@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Enums\CacheKeys;
use App\Enums\FormEducation;
use App\Http\Resources\AdditionalEducationCategoryPreviewResource;
use App\Http\Resources\AdditionalEducationCategoryResource;
@@ -14,128 +15,148 @@ use App\Models\AdditionalEducation;
use App\Models\AdditionalEducationCategory;
use App\Models\DirectionAdditionalEducation;
use App\Models\Page;
use App\Services\App\Breadcrumb\BreadcrumbService;
use App\Services\App\Seo\SeoPageProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Inertia\Inertia;
class ClientAdditionalEducationController extends Controller
{
public function __construct(readonly SeoPageProvider $seoPageProvider){}
public function index(Request $request)
{
$cacheKey = md5(serialize([
'direction' => $request->input('direction'),
'form' => $request->input('form'),
'category' => $request->input('category'),
]));
$directionAdditionalEducations = DirectionAdditionalEducationResource::collection(
DirectionAdditionalEducation::query()
->where('is_active', true)
->whereHas('additionalEducationCategories', function ($q) {
$q->whereHas('additionalEducations');
})->get());
$additionalEducations = AdditionalEducationCategoryResource::collection(AdditionalEducationCategory::query()
->WithActivePrograms()
->where('is_active', '=', true)
->when($request->input('direction'), function ($q, $direction) {
$q->whereHas('direction', function ($query) use ($direction) {
$query->where('slug', $direction);
});
})
->when(request()->input('form'), function ($query, $form) {
$query->whereHas('additionalEducations', function ($q) use ($form) {
$q->where('form_education', FormEducation::fromName($form));
});
$query->with(['additionalEducations' => function ($q) use ($form) {
$q->where('form_education', FormEducation::fromName($form));
}]);
})
->when(request()->input('category'), function ($query) {
$slugs = request()->input('category');
if (is_array($slugs)) {
$query->whereIn('slug', $slugs);
}
})
->has('additionalEducations')
->get());
$categories = AdditionalEducationCategoryPreviewResource::collection(
AdditionalEducationCategory::query()
->where('is_active', true)
->has('additionalEducations')
->get()
// Основные данные (кешируются)
$directionAdditionalEducations = Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . 'directions_' . $cacheKey,
now()->addDay(),
function () {
return DirectionAdditionalEducationResource::collection(
DirectionAdditionalEducation::query()
->where('is_active', true)
->whereHas('additionalEducationCategories', fn ($q) => $q->whereHas('additionalEducations'))
->get()
);
}
);
$additionalEducations = Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . $cacheKey,
now()->addDay(),
function () use ($request) {
return AdditionalEducationCategoryResource::collection(
AdditionalEducationCategory::query()
->WithActivePrograms()
->where('is_active', true)
->when($request->direction, fn ($q, $direction) =>
$q->whereHas('direction', fn ($query) => $query->where('slug', $direction))
)
->when($request->form, fn ($query, $form) =>
$query->whereHas('additionalEducations', fn ($q) =>
$q->where('form_education', FormEducation::fromName($form))
)
->when($request->category, fn ($query) =>
is_array($request->category)
? $query->whereIn('slug', $request->category)
: $query
)
->has('additionalEducations')
->get()
));
}
);
$categories = Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . 'categories',
now()->addWeek(),
function () {
return AdditionalEducationCategoryPreviewResource::collection(
AdditionalEducationCategory::query()
->where('is_active', true)
->has('additionalEducations')
->get()
);
}
);
// Динамические данные (не кешируются)
$categoriesContent = [];
if (request()->input('category')) {
foreach (request()->input('category') as $item) {
$categoriesContent[$item] = new AdditionalEducationCategoryResource(AdditionalEducationCategory::where('slug', $item)->first());
if ($request->category) {
foreach ((array)$request->category as $item) {
$categoriesContent[$item] = new AdditionalEducationCategoryResource(
AdditionalEducationCategory::where('slug', $item)->first()
);
}
}
$forms_education = [];
foreach (FormEducation::cases() as $case) {
$forms_education[$case->name] = $case->getLabel();
}
$forms_education = array_reduce(
FormEducation::cases(),
fn ($acc, $case) => $acc + [$case->name => $case->getLabel()],
[]
);
$filters = [
'direction_filter' => [
'type' => 'direction',
'value' => request()->input('direction'),
'value' => $request->input('direction'),
'param' => 'direction'
],
'form_education_filter' => [
'type' => 'form',
'value' => request()->input('form'),
'value' => $request->input('form'),
'param' => 'form'
],
'category_filter' => [
'type' => 'category',
'value' => request()->input('category'),
'value' => $request->input('category'),
'param' => 'category',
'content' => $categoriesContent,
],
];
$routeUrl = route('client.additionalEducation.index');
$path = ltrim(parse_url($routeUrl, PHP_URL_PATH), '/');
$seo = $this->seoPageProvider->getSeoForCurrentPage();
$page = Page::where('path', '=', $path)->with('section.pages.section', 'section.mainSection')->first();
if (isset($page->section)) {
$breadcrumbs = [
'mainSection' => new ClientBreadcrumbSection($page->section->mainSection),
'subSection' => new ClientBreadcrumbSubSection($page->section),
'page' => new ClientBreadcrumbPage($page),
];
} else {
$breadcrumbs = null;
}
return Inertia::render('Client/Additional-educations/Index',
compact(
'directionAdditionalEducations',
'additionalEducations',
'filters',
'forms_education',
'categories',
'breadcrumbs'
));
return Inertia::render('Client/Additional-educations/Index', compact(
'directionAdditionalEducations',
'additionalEducations',
'filters',
'forms_education',
'categories',
'seo'
));
}
public function show(string $slug)
{
$additionalEducation = new AdditionalEducationResource(AdditionalEducation::query()->with('category.direction')->where('slug', $slug)->first());
$routeUrl = route('client.additionalEducation.index');
$path = ltrim(parse_url($routeUrl, PHP_URL_PATH), '/');
// Кешируем основную программу дополнительного образования
[$additionalEducation, $seo] = Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAM_PREFIX->value . $slug,
now()->addDay(),
function () use ($slug) {
$additionalEducation = AdditionalEducation::query()
->with('category.direction')
->where('slug', $slug)
->first();
$seo = $this->seoPageProvider->getSeoForModel($additionalEducation);
return [
new AdditionalEducationResource($additionalEducation),
$seo
];
}
);
$page = Page::where('path', '=', $path)->with('section.pages.section', 'section.mainSection')->first();
// SEO-данные берём из кешированного ресурса
if (isset($page->section)) {
$breadcrumbs = [
'mainSection' => new ClientBreadcrumbSection($page->section->mainSection),
'subSection' => new ClientBreadcrumbSubSection($page->section),
'page' => new ClientBreadcrumbPage($page),
];
} else {
$breadcrumbs = null;
}
$seo = $additionalEducation->seo ?? null;
return Inertia::render('Client/Additional-educations/Show', compact('additionalEducation', 'breadcrumbs', 'seo'));
}
}
return Inertia::render('Client/Additional-educations/Show', compact(
'additionalEducation',
'seo'
));
}}
@@ -2,34 +2,93 @@
namespace App\Http\Controllers;
use App\Enums\CacheKeys;
use App\Http\Resources\ClientDepartmentPreviewResource;
use App\Http\Resources\DepartmentResource;
use App\Models\Department;
use App\Models\Faculty;
use App\Services\App\Breadcrumb\BreadcrumbService;
use App\Services\App\Seo\SeoPageProvider;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Inertia\Inertia;
class ClientDepartmentController extends Controller
{
public function __construct(readonly SeoPageProvider $seoPageProvider){}
public function show(string $facultySlug, string $departmentSlug)
{
$faculty = Faculty::query()->where('slug', $facultySlug)->first();
$departments = ClientDepartmentPreviewResource::collection(
Department::query()
->where('is_active', true)
->where('faculty_id', $faculty->id)
->get()
);
$department = new DepartmentResource(Department::query()
->where('slug', $departmentSlug)
->where('is_active', true)
->with(['faculty', 'workers.userDetail', 'teachers.userDetail', 'programs.directionStudy'])
->first());
$directions = $this->groupProgramsByDirection($department->programs);
// Ключ для кеширования
$cacheKey = "{$facultySlug}_{$departmentSlug}";
$seo = $department->seo ?? null;
return Inertia::render('Client/Departments/Show', compact('department', 'departments', 'directions', 'seo'));
// Кешируем факультет
$faculty = Cache::remember(
CacheKeys::FACULTY_PREFIX->value . $facultySlug,
now()->addDay(),
function () use ($facultySlug) {
return Faculty::query()
->where('slug', $facultySlug)
->first();
}
);
// Кешируем список активных кафедр факультета
$departments = Cache::remember(
CacheKeys::DEPARTMENTS_PREFIX->value . 'active_' . $faculty->id,
now()->addDay(),
function () use ($faculty) {
return ClientDepartmentPreviewResource::collection(
Department::query()
->where('is_active', true)
->where('faculty_id', $faculty->id)
->get()
);
}
);
// Кешируем полные данные кафедры с отношениями
[$department, $seo] = Cache::remember(
CacheKeys::DEPARTMENT_PREFIX->value . $cacheKey,
now()->addDay(),
function () use ($departmentSlug) {
$department = Department::query()
->where('slug', $departmentSlug)
->where('is_active', true)
->with([
'faculty',
'workers.userDetail',
'teachers.userDetail',
'programs.directionStudy',
'seo'
])
->first();
$seo = $this->seoPageProvider->getSeoForModel($department);
return [
new DepartmentResource($department),
$seo
];
}
);
// Кешируем сгруппированные направления
$directions = Cache::remember(
CacheKeys::DEPARTMENT_PREFIX->value . 'directions_' . $cacheKey,
now()->addDay(),
function () use ($department) {
return $this->groupProgramsByDirection($department->programs);
}
);
return Inertia::render('Client/Departments/Show', compact(
'department',
'departments',
'directions',
'seo',
));
}
@@ -4,22 +4,31 @@ namespace App\Http\Controllers;
use App\Http\Resources\DivisionResource;
use App\Models\Division;
use App\Services\App\Breadcrumb\BreadcrumbService;
use App\Services\App\Seo\SeoPageProvider;
use Illuminate\Http\Request;
use Inertia\Inertia;
class ClientDivisionController extends Controller
{
public function __construct(readonly SeoPageProvider $seoPageProvider){}
public function index()
{
$divisions = DivisionResource::collection(Division::query()->where('is_active', true)->get());
return Inertia::render('Client/Divisions/Index', compact('divisions'));
$seo = $this->seoPageProvider->getSeoForCurrentPage();
return Inertia::render('Client/Divisions/Index', compact('divisions', 'seo'));
}
public function show(string $slug)
{
$divisions = DivisionResource::collection(Division::query()->where('is_active', true)->get());
$division = new DivisionResource(Division::with('workers.userDetail')->where('is_active', true)->where('slug', $slug)->firstOrFail());
$seo = $division->seo ?? null;
$division = new DivisionResource($divisionModel = Division::with(['workers.userDetail', 'seo'])->where('is_active', true)->where('slug', $slug)->firstOrFail());
$seo = $this->seoPageProvider->getSeoForModel($divisionModel);
return Inertia::render('Client/Divisions/Show', compact('divisions', 'division', 'seo'));
}
}
+77 -27
View File
@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Enums\CacheKeys;
use App\Http\Resources\ClientBreadcrumbPage;
use App\Http\Resources\ClientBreadcrumbSection;
use App\Http\Resources\ClientBreadcrumbSubSection;
@@ -13,53 +14,102 @@ use App\Models\Event;
use App\Models\EventCategory;
use App\Models\Page;
use App\Services\App\Breadcrumb\BreadcrumbService;
use App\Services\App\Seo\SeoPageProvider;
use Carbon\Carbon;
use DateTime;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Inertia\Inertia;
class ClientEventController extends Controller
{
public function __construct(private readonly BreadcrumbService $breadcrumbService){}
public function __construct(readonly SeoPageProvider $seoPageProvider){}
public function index(Request $request): \Inertia\Response
{
$currentDate = $this->getCurrentDate($request);
$cacheKey = md5(serialize([$currentDate, $request->all()]));
$events = Cache::remember(
CacheKeys::EVENTS_PREFIX->value . $cacheKey,
now()->addHours(12),
fn() => $this->getEvents($currentDate)
);
$eventDates = Cache::remember(
CacheKeys::EVENTS_PREFIX->value . 'dates_' . $cacheKey,
now()->addHours(12),
fn() => $this->getEventDates($this->getFilters())
);
$categories = Cache::remember(
CacheKeys::EVENTS_PREFIX->value . 'categories',
now()->addDay(),
fn() => ClientEventCategoryResource::collection(EventCategory::has('events')->get())
);
$filters = $this->getFilters();
$eventDates = $this->getEventDates($filters);
$events = $this->getEvents($currentDate);
$categories = ClientEventCategoryResource::collection(EventCategory::has('events')->get());
$seo = $this->seoPageProvider->getSeoForCurrentPage();
$breadcrumbs = $this->breadcrumbService->generateBreadcrumbs('client.event.index');
return Inertia::render('Client/Events/Index', compact('eventDates', 'events', 'currentDate', 'filters', 'categories', 'breadcrumbs'));
return Inertia::render('Client/Events/Index', compact(
'eventDates',
'events',
'currentDate',
'filters',
'categories',
'seo'
));
}
public function show(string $slug): \Inertia\Response
{
$event = new ClientEventFullResource(Event::where('slug', '=', $slug)->with('category')->first());
[$event, $seo] = Cache::remember(
CacheKeys::EVENT_PREFIX->value . $slug,
now()->addDay(),
function ($slug) {
$event = Event::where('slug', $slug)->with(['category', 'seo'])->first();
$seo = $this->seoPageProvider->getSeoForModel($event);
return [
new ClientEventFullResource($event),
$seo
];
}
);
$breadcrumbs = $this->breadcrumbService->generateBreadcrumbs('client.event.index');
$seo = $event->seo ?? null;
return Inertia::render('Client/Events/Show', compact('event', 'breadcrumbs', 'seo'));
return Inertia::render('Client/Events/Show', compact(
'event',
'seo'
));
}
public function archive(Request $request): \Inertia\Response
{
$cacheKey = md5(serialize($request->all()));
$events = Cache::remember(
CacheKeys::EVENTS_PREFIX->value . 'archive_' . $cacheKey,
now()->addDay(),
fn() => $this->getEventsArchive()
);
$categories = Cache::remember(
CacheKeys::EVENTS_PREFIX->value . 'categories',
now()->addDay(),
fn() => ClientEventCategoryResource::collection(EventCategory::has('events')->get())
);
$filters = $this->getFilters();
$events = $this->getEventsArchive();
$categories = ClientEventCategoryResource::collection(EventCategory::has('events')->get());
$seo = $this->seoPageProvider->getSeoForCurrentPage();
$breadcrumbs = $this->breadcrumbService->generateBreadcrumbs('client.event.archive');
return Inertia::render('Client/Events/Archive', compact('events', 'filters', 'categories', 'breadcrumbs'));
return Inertia::render('Client/Events/Archive', compact(
'events',
'filters',
'categories',
'seo'
));
}
private function getCurrentDate(Request $request): array
@@ -164,7 +214,12 @@ class ClientEventController extends Controller
->orderBy('event_date_start')
->get();
$mappingDates = $events->map(function ($event) {
// Получаем массив без ключей
// Извлекаем уникальные даты из событий
return $events->map(function ($event) {
$date = new DateTime($event->event_date_start);
return [
'day' => $date->format('j'),
@@ -182,12 +237,7 @@ class ClientEventController extends Controller
];
})
->sortKeys() // Сортируем ключи по возрастанию
->values(); // Получаем массив без ключей
// Извлекаем уникальные даты из событий
return $mappingDates;
->values();
}
private function getFilters(): array
@@ -2,26 +2,75 @@
namespace App\Http\Controllers;
use App\Enums\CacheKeys;
use App\Http\Resources\FacultyResource;
use App\Http\Resources\FullFacultyResource;
use App\Models\Faculty;
use App\Services\App\Breadcrumb\BreadcrumbService;
use App\Services\App\Seo\SeoPageProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Inertia\Inertia;
class ClientFacultyController extends Controller
{
public function index()
public function __construct(readonly SeoPageProvider $seoPageProvider){}
public function index(Request $request)
{
$faculties = FacultyResource::collection(Faculty::query()->where('is_active', true)->get());
return Inertia::render('Client/Faculties/Index', compact('faculties'));
$faculties = Cache::remember(
CacheKeys::FACULTIES_PREFIX->value . 'active_list',
now()->addDay(), // Кешируем на 1 день
function () {
return FacultyResource::collection(
Faculty::query()
->where('is_active', true)
->get()
);
}
);
$seo = $this->seoPageProvider->getSeoForCurrentPage();
return Inertia::render('Client/Faculties/Index', compact('faculties', 'seo'));
}
public function show(string $slug)
{
$faculties = FacultyResource::collection(Faculty::query()->where('is_active', true)->get());
$faculty = new FullFacultyResource(Faculty::where('slug', $slug)->where('is_active', true)->with(['departments.faculty', 'workers.userDetail'])->firstOrFail());
$seo = $faculty->seo ?? null;
// Кешируем список факультетов
$faculties = Cache::remember(
CacheKeys::FACULTIES_PREFIX->value . 'active_list',
now()->addDay(),
function () {
return FacultyResource::collection(
Faculty::query()
->where('is_active', true)
->get()
);
}
);
// Кешируем данные конкретного факультета
[$faculty, $seo] = Cache::remember(
CacheKeys::FACULTY_PREFIX->value . $slug,
now()->addDay(),
function () use ($slug) {
$faculty = Faculty::where('slug', $slug)
->where('is_active', true)
->with(['departments.faculty', 'workers.userDetail', 'seo'])
->firstOrFail();
$seo = $this->seoPageProvider->getSeoForModel($faculty);
return [
new FullFacultyResource($faculty),
$seo
];
}
);
return Inertia::render('Client/Faculties/Show', compact('faculty', 'faculties', 'seo'));
}
}
+8 -17
View File
@@ -3,14 +3,9 @@
namespace App\Http\Controllers;
use App\Http\Resources\CategoryResource;
use App\Http\Resources\ClientBreadcrumbPage;
use App\Http\Resources\ClientBreadcrumbSection;
use App\Http\Resources\ClientBreadcrumbSubSection;
use App\Http\Resources\ClientNavigationResource;
use App\Http\Resources\ClientPostListResource;
use App\Http\Resources\ClientTagResource;
use App\Http\Resources\MainSectionResource;
use App\Http\Resources\PageResource;
use App\Http\Resources\PostResource;
use App\Models\Category;
use App\Models\MainSection;
@@ -18,8 +13,8 @@ use App\Models\Page;
use App\Models\Post;
use App\Models\Tag;
use App\Services\App\Breadcrumb\BreadcrumbService;
use App\Services\App\Seo\SeoPageProvider;
use Carbon\Carbon;
use Doctrine\DBAL\Schema\Column;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
@@ -27,12 +22,12 @@ use Inertia\Inertia;
class ClientPostController extends Controller
{
public function __construct(private readonly BreadcrumbService $breadcrumbService){}
public function __construct(readonly SeoPageProvider $seoPageProvider){}
public function index(Request $request)
{
// Кешируем список тегов
$tagIds = Cache::remember('tag_ids', now()->addHours(1), function () {
$tagIds = Cache::remember('tag_ids', now()->addHours(), function () {
return DB::table('taggables')
->distinct()
->select('tag_id')
@@ -132,11 +127,9 @@ class ClientPostController extends Controller
],
];
$breadcrumbs = $this->breadcrumbService->generateBreadcrumbs('client.post.index');
$seo = $this->seoPageProvider->getSeoForCurrentPage();
return Inertia::render('Client/Posts/Index', compact('filters', 'posts', 'categories', 'tags', 'breadcrumbs'));
return Inertia::render('Client/Posts/Index', compact('filters', 'posts', 'categories', 'tags', 'seo'));
}
public function show(Request $request, $slug)
@@ -154,19 +147,17 @@ class ClientPostController extends Controller
// Преобразуем пост в ресурс
$postResource = new PostResource($post);
$breadcrumbs = $this->breadcrumbService->generateBreadcrumbs('client.post.index');
// SEO-данные
$seo = $post->seo ?? null;
$seo = $this->seoPageProvider->getSeoForModel($post);
// Возвращаем данные для кеширования
return [
'post' => $postResource,
'breadcrumbs' => $breadcrumbs,
'seo' => $seo,
];
});
// Возвращаем ответ с использованием кешированных данных
return Inertia::render('Client/Posts/Show', $data);
}
+114 -86
View File
@@ -3,6 +3,7 @@
namespace App\Http\Controllers;
use App\Enums\BudgetEducation;
use App\Enums\CacheKeys;
use App\Enums\FormEducation;
use App\Enums\LevelEducational;
use App\Http\Resources\CampaignDegreeResource;
@@ -16,121 +17,150 @@ use App\Models\CampaignDegree;
use App\Models\DirectionStudy;
use App\Models\EducationalProgram;
use App\Models\MainSection;
use App\Services\App\Seo\SeoPageProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Inertia\Inertia;
class ClientProgramController extends Controller
{
public function __construct(readonly SeoPageProvider $seoPageProvider){}
public function index(Request $request)
{
$activeCampaign = AdmissionCampaign::query()->where('status', 1)->first();
$cacheKey = CacheKeys::EDUCATION_PROGRAMS_PREFIX->value . md5(serialize($request->all()));
$uniqueValues = EducationalProgram::distinct()->pluck('lvl_edu');
$levelsEducational = $uniqueValues->mapWithKeys(function ($level) {
return [$level->name => $level->getLabel()];
});
$data = Cache::remember($cacheKey, now()->addHours(1), function () use ($request) {
$activeCampaign = AdmissionCampaign::query()->where('status', 1)->first();
$direction_studies = DirectionStudy::query()
->withAdmissionCampaignByYear($activeCampaign->academic_year)
->withActivePrograms()
->get();
$uniqueValues = EducationalProgram::distinct()->pluck('lvl_edu');
$levelsEducational = $uniqueValues->mapWithKeys(function ($level) {
return [$level->name => $level->getLabel()];
});
$level = request()->input('level');
$form = request()->input('form');
$budget = request()->input('budget');
$naprs = DirectionStudyResource::collection(
DirectionStudy::query()
$direction_studies = DirectionStudy::query()
->withAdmissionCampaignByYear($activeCampaign->academic_year)
->withActivePrograms()
->with('programs.admission_plans')
->when($level, function ($query) use ($level) {
$query->where('lvl_edu', LevelEducational::fromName($level)->value);
})
->when($form, function ($query) use ($form) {
$this->applyFormFilter($query, $form);
})
->when($budget, function ($query) use ($budget) {
$this->applyBudgetFilter($query, $budget);
})
->when(request()->input('direction'), function ($query) {
$slugs = request()->input('direction');
if (is_array($slugs)) {
$query->whereIn('slug', $slugs);
}
})
->get()
);
->get();
$level = request()->input('level');
$form = request()->input('form');
$budget = request()->input('budget');
$naprs = DirectionStudyResource::collection(
DirectionStudy::query()
->withAdmissionCampaignByYear($activeCampaign->academic_year)
->withActivePrograms()
->with('programs.admission_plans')
->when($level, function ($query) use ($level) {
$query->where('lvl_edu', LevelEducational::fromName($level)->value);
})
->when($form, function ($query) use ($form) {
$this->applyFormFilter($query, $form);
})
->when($budget, function ($query) use ($budget) {
$this->applyBudgetFilter($query, $budget);
})
->when(request()->input('direction'), function ($query) {
$slugs = request()->input('direction');
if (is_array($slugs)) {
$query->whereIn('slug', $slugs);
}
})
->get()
);
$campaignName = $this->getAdmissionCampaignName();
$formsEducational = FormEducation::cases();
$formsEducational = collect($formsEducational);
$formsEdu = $formsEducational->mapWithKeys(function ($formEducational) {
return [$formEducational->name => $formEducational->getLabel()];
});
$typesBudget = BudgetEducation::cases();
$typesBudget = collect($typesBudget);
$budgetEdu = $typesBudget->mapWithKeys(function ($typeBudget) {
return [$typeBudget->name => $typeBudget->getLabel()];
});
$filters = [
'level_filter' => [
'type' => 'level',
'value' => request()->input('level'),
'param' => 'level'
],
'budget_filter' => [
'type' => 'budget',
'value' => request()->input('budget'),
'param' => 'budget'
],
'formEdu_filter' => [
'type' => 'form',
'value' => request()->input('form'),
'param' => 'form'
],
'direction_filter' => [
'type' => 'direction',
'value' => request()->input('direction'),
'param' => 'direction'
],
];
$seo = $this->seoPageProvider->getSeoForCurrentPage();
$campaignName = $this->getAdmissionCampaignName();
$formsEducational = FormEducation::cases();
$formsEducational = collect($formsEducational);
$formsEdu = $formsEducational->mapWithKeys(function ($formEducational) {
return [$formEducational->name => $formEducational->getLabel()];
});
$typesBudget = BudgetEducation::cases();
$typesBudget = collect($typesBudget);
$budgetEdu = $typesBudget->mapWithKeys(function ($typeBudget) {
return [$typeBudget->name => $typeBudget->getLabel()];
});
$filters = [
'level_filter' => [
'type' => 'level',
'value' => request()->input('level'),
'param' => 'level'
],
'budget_filter' => [
'type' => 'budget',
'value' => request()->input('budget'),
'param' => 'budget'
],
'formEdu_filter' => [
'type' => 'form',
'value' => request()->input('form'),
'param' => 'form'
],
'direction_filter' => [
'type' => 'direction',
'value' => request()->input('direction'),
'param' => 'direction'
],
];
return Inertia::render('Client/Programs/Index',
compact(
return compact(
'naprs',
'campaignName',
'levelsEducational',
'filters',
'formsEdu',
'budgetEdu',
'direction_studies'
));
'direction_studies',
'seo'
);
});
return Inertia::render('Client/Programs/Index', $data);
}
public function show(string $slug)
{
$program = new EducationalProgramFullResource(EducationalProgram::query()->where('slug', $slug)->with(['admission_plans', 'directionStudy'])->firstOrFail());
$formsEducational = BudgetEducation::cases();
$formsEducational = collect($formsEducational);
$formsEdu = $formsEducational->mapWithKeys(function ($formEducational) {
return [$formEducational->value => $formEducational->getLabel()];
$cacheKey = CacheKeys::EDUCATION_PROGRAM_PREFIX->value . md5($slug);
$data = Cache::remember($cacheKey, now()->addHours(1), function () use ($slug) {
$program = new EducationalProgramFullResource(
$programModel = EducationalProgram::query()
->where('slug', $slug)
->with(['admission_plans', 'directionStudy', 'seo'])
->firstOrFail()
);
$formsEducational = BudgetEducation::cases();
$formsEducational = collect($formsEducational);
$formsEdu = $formsEducational->mapWithKeys(function ($formEducational) {
return [$formEducational->value => $formEducational->getLabel()];
});
$seo = $this->seoPageProvider->getSeoForModel($programModel);
return compact('program', 'formsEdu', 'seo');
});
$seo = $program->seo ?? null;
return Inertia::render('Client/Programs/Show', compact('program', 'formsEdu', 'seo'));
return Inertia::render('Client/Programs/Show', $data);
}
private function getAdmissionCampaignName() : string
private function getAdmissionCampaignName(): string
{
$campaign = AdmissionCampaign::query()->where('status', 1)->first();
return $campaign->name;
}
$cacheKey = CacheKeys::EDUCATION_PROGRAM_PREFIX->value . 'active_campaign_name';
return Cache::remember($cacheKey, now()->addHours(1), function () {
$campaign = AdmissionCampaign::query()->where('status', 1)->first();
return $campaign->name;
});
}
private function applyFormFilter($query, $form)
{
@@ -150,7 +180,6 @@ class ClientProgramController extends Controller
{
$budgetValue = Str::of(BudgetEducation::fromName($budget)->value)->toString();
$query->whereHas('programs.admission_plans', function ($query) use ($budgetValue) {
$query->whereJsonContains('contests', ['financing_source' => $budgetValue]);
})
@@ -160,5 +189,4 @@ class ClientProgramController extends Controller
});
}]);
}
}
}
@@ -8,11 +8,14 @@ use App\Http\Resources\ScheduleResource;
use App\Models\EducationalGroup;
use App\Models\Faculty;
use App\Models\Schedule;
use App\Services\App\Seo\SeoPageProvider;
use Illuminate\Http\Request;
use Inertia\Inertia;
class ClientScheduleController extends Controller
{
public function __construct(readonly SeoPageProvider $seoPageProvider){}
public function index(Request $request)
{
$educationalGroups = ClientEducationalGroupResource::collection(EducationalGroup::query()
@@ -46,10 +49,6 @@ class ClientScheduleController extends Controller
}
$forms_education = [];
foreach (FormEducation::cases() as $case) {
$forms_education[$case->name] = $case->getLabel();
@@ -78,8 +77,10 @@ class ClientScheduleController extends Controller
]
];
$seo = $this->seoPageProvider->getSeoForCurrentPage();
// Возвращаем данные в представление
return Inertia::render('Client/Schedules/Index', compact('educationalGroups', 'filters', 'forms_education', 'schedulesByFaculty'));
return Inertia::render('Client/Schedules/Index', compact('educationalGroups', 'filters', 'forms_education', 'schedulesByFaculty', 'seo'));
}
public function show($id)
@@ -2,22 +2,31 @@
namespace App\Http\Controllers;
use App\Enums\CacheKeys;
use App\Enums\PostStatus;
use App\Http\Resources\AdditionalEducationSearchResource;
use App\Http\Resources\PostThumbnailResource;
use App\Models\AdditionalEducation;
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
class ClientWidgetAdditionalEducationalProgramController extends Controller
{
public function index()
{
return AdditionalEducationSearchResource::collection(
AdditionalEducation::query()
->where('is_active', true)
->orderBy('title', 'desc')
->get());
return Cache::remember(
CacheKeys::ADDITIONAL_EDUCATIONAL_PROGRAMS_PREFIX->value . 'search_list',
now()->addDay(), // Кешируем на 1 день
function () {
return AdditionalEducationSearchResource::collection(
AdditionalEducation::query()
->where('is_active', true)
->orderBy('title', 'desc')
->get()
);
}
);
}
}
@@ -2,14 +2,26 @@
namespace App\Http\Controllers;
use App\Enums\CacheKeys;
use App\Http\Resources\ClientContactWidgetResource;
use App\Http\Resources\ClientPageReferenceListResource;
use App\Models\ContactWidget;
use Illuminate\Support\Facades\Cache;
class ClientWidgetContactController extends Controller
{
public function show(string $slug)
{
return new ClientContactWidgetResource(ContactWidget::query()->where('slug', $slug)->first());
return Cache::remember(
CacheKeys::CONTACT_WIDGET_PREFIX->value . $slug,
now()->addHours(12), // Кешируем на 12 часов
function () use ($slug) {
return new ClientContactWidgetResource(
ContactWidget::query()
->where('slug', $slug)
->first()
);
}
);
}
}
@@ -2,19 +2,28 @@
namespace App\Http\Controllers;
use App\Enums\CacheKeys;
use App\Enums\EducationalProgramStatus;
use App\Http\Resources\EducationalProgramSearchResource;
use App\Models\EducationalProgram;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
class ClientWidgetEducationalProgramController extends Controller
{
public function index()
{
return EducationalProgramSearchResource::collection(
EducationalProgram::query()
->where('status', EducationalProgramStatus::PUBLISHED)
->orderBy('name', 'desc')
->get());
return Cache::remember(
CacheKeys::EDUCATION_PROGRAMS_PREFIX->value . 'search_list',
now()->addDay(), // Кешируем на 1 день
function () {
return EducationalProgramSearchResource::collection(
EducationalProgram::query()
->where('status', EducationalProgramStatus::PUBLISHED)
->orderBy('name', 'desc')
->get()
);
}
);
}
}
@@ -2,14 +2,26 @@
namespace App\Http\Controllers;
use App\Enums\CacheKeys;
use App\Http\Resources\ClientPageReferenceListResource;
use App\Models\PageReferenceList;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
class ClientWidgetPageReferenceListController extends Controller
{
public function show(string $slug)
{
return new ClientPageReferenceListResource(PageReferenceList::query()->where('slug', $slug)->first());
return Cache::remember(
CacheKeys::PAGE_REFERENCE_LIST_PREFIX->value . $slug,
now()->addWeek(), // Кешируем на неделю, так как справочники меняются редко
function () use ($slug) {
return new ClientPageReferenceListResource(
PageReferenceList::query()
->where('slug', $slug)
->first()
);
}
);
}
}
@@ -15,7 +15,9 @@ class ClientWidgetSliderController extends Controller
$slider = Slider::query()
->where('slug', $slug)
->where('is_active', true)
->with('slides')
->with(['slides' => function($query) {
$query->where('is_active', true);
}])
->first();
return $slider ?: null;
+8 -33
View File
@@ -14,6 +14,7 @@ use App\Http\Resources\RegisteredPageResource;
use App\Models\MainSection;
use App\Models\Page;
use App\Models\Post;
use App\Services\App\Seo\SeoPageProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
@@ -22,7 +23,9 @@ use Inertia\Inertia;
class PageController extends Controller
{
public function render(Request $request, $path)
public function __construct(readonly SeoPageProvider $seoPageProvider){}
public function render(string $path): \Inertia\Response
{
// Генерируем уникальный ключ для кеширования
$cacheKey = 'page_' . md5($path);
@@ -37,45 +40,17 @@ class PageController extends Controller
if ($page === null) {
abort(404);
}
$subSectionPages = $page->section ? PageResource::collection($page->section->pages) : null;
if (isset($page->section)) {
$subSectionPages = PageResource::collection($page->section->pages);
$breadcrumbs = [
'mainSection' => new ClientBreadcrumbSection($page->section->mainSection),
'subSection' => new ClientBreadcrumbSubSection($page->section),
'page' => new ClientBreadcrumbPage($page),
];
} else {
$subSectionPages = null;
$breadcrumbs = null;
}
$seo = $page->seo ?? null;
$seo = $this->seoPageProvider->getSeoForModel($page);
$page = new PageResource($page);
$error = $page->code;
if ($page->code != 200) {
abort($error);
abort($page->code);
}
return Inertia::render('Page', compact('page', 'subSectionPages', 'breadcrumbs', 'seo'));
}
public function getRegisteredPages()
{
$pages = PageResource::collection(Page::query()
->when(request()->input('search'), function ($query, $search) {
$query->where('title', 'like', "%{$search}%");
})
->where('is_registered', true)
->where('is_visible', true)
->orderBy('id', 'desc')
->paginate(request()->input('perPage', 9))
->withQueryString());
$filters = [
'search' => request()->input('search'),
];
return Inertia::render('AdminPanel/Pages/Registered', compact('pages', 'filters'));
return Inertia::render('Page', compact('page', 'subSectionPages', 'seo'));
}
}
+18 -10
View File
@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Enums\CacheKeys;
use App\Http\Resources\ClientFullInfoPersonResource;
use App\Http\Resources\ClientNavigationResource;
use App\Http\Resources\MainSectionResource;
@@ -10,23 +11,30 @@ use App\Http\Resources\UserResource;
use App\Models\MainSection;
use App\Models\User;
use App\Models\UserDetail;
use App\Services\App\Seo\SeoPageProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Inertia\Inertia;
class PersonController extends Controller
{
public function index()
{
$persons = UserDetailResource::collection(UserDetail::all());
$filters = [
'search' => request()->input('search'),
];
return Inertia::render('Client/Persons/Index', compact('persons', 'filters'));
}
public function __construct(readonly SeoPageProvider $seoPageProvider){}
public function show(string $slug)
{
$person = new ClientFullInfoPersonResource(User::query()->with(['userDetail', 'departments_work.faculty', 'departments_teach.faculty', 'divisions', 'faculties'])->where('slug', $slug)->firstOrFail());
return Inertia::render('Client/Persons/Show', compact('person'));
$cacheKey = CacheKeys::USER_PREFIX->value . md5($slug);
[$person, $seo] = Cache::remember($cacheKey, now()->addHours(24), function () use ($slug) {
$person = User::query()->with(['userDetail', 'departments_work.faculty', 'departments_teach.faculty', 'divisions', 'faculties', 'seo'])
->where('slug', $slug)
->firstOrFail();
$seo = $this->seoPageProvider->getSeoForModel($person);
return [
new ClientFullInfoPersonResource($person),
$seo
];
});
return Inertia::render('Client/Persons/Show', compact('person', 'seo'));
}
}
@@ -9,6 +9,7 @@ use App\Http\Resources\EventSearchResource;
use App\Http\Resources\FacultySearchResource;
use App\Http\Resources\PageSearchResource;
use App\Http\Resources\PostSearchResource;
use App\Http\Resources\StaticPageSearchResource;
use App\Http\Resources\UserSearchResource;
use App\Models\AdditionalEducation;
use App\Models\EducationalGroup;
@@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers;
use App\Services\Filament\Services\CategoryFinderService;
use App\Services\Filament\Services\StaticFileSearch;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
class StaticSearchController extends Controller
{
public function search(Request $request)
{
return app(StaticFileSearch::class)
->search(
$request->input('search'),
$request->input('page', 1)
);
}
public function getCategories()
{
return Cache::remember('page_static_categories', now()->addWeek(), function () {
return app(CategoryFinderService::class)->getCategories();
});
}
}