Migrate backend to Porto architecture and fix minor bugs
- Fully transitioned the backend to the Porto architectural pattern - Improved code organization and maintainability - Fixed minor bugs and inconsistencies
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\InstituteStructure\UI\WEB\Controllers;
|
||||
|
||||
use App\Containers\InstituteStructure\Models\Department;
|
||||
use App\Containers\InstituteStructure\Models\Faculty;
|
||||
use App\Containers\InstituteStructure\UI\WEB\Transformers\DepartmentPreviewResource;
|
||||
use App\Containers\InstituteStructure\UI\WEB\Transformers\DepartmentResource;
|
||||
use App\Ship\Contracts\SeoServiceInterface;
|
||||
use App\Ship\Controllers\Controller;
|
||||
use App\Ship\Enums\CacheKeys;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ClientDepartmentController extends Controller
|
||||
{
|
||||
public function __construct(readonly SeoServiceInterface $seoPageProvider){}
|
||||
|
||||
public function show(string $facultySlug, string $departmentSlug)
|
||||
{
|
||||
// Ключ для кеширования
|
||||
$cacheKey = "{$facultySlug}_{$departmentSlug}";
|
||||
|
||||
// Кешируем факультет
|
||||
$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 DepartmentPreviewResource::collection(
|
||||
Department::query()
|
||||
->where('is_active', true)
|
||||
->where('faculty_id', $faculty->id)
|
||||
->get()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$departmentModel = Cache::remember(
|
||||
CacheKeys::DEPARTMENT_PREFIX->value . $cacheKey,
|
||||
now()->addDay(),
|
||||
function () use ($departmentSlug) {
|
||||
return Department::query()
|
||||
->where('slug', $departmentSlug)
|
||||
->where('is_active', true)
|
||||
->with([
|
||||
'faculty',
|
||||
'workers.userDetail',
|
||||
'teachers.userDetail',
|
||||
'programs.directionStudy',
|
||||
'seo'
|
||||
])
|
||||
->firstOrFail();
|
||||
}
|
||||
);
|
||||
|
||||
$seo = Cache::remember(
|
||||
CacheKeys::DEPARTMENT_PREFIX->value . 'seo_' . $cacheKey,
|
||||
now()->addDay(),
|
||||
function () use ($departmentModel) {
|
||||
return $this->seoPageProvider->getSeoForModel($departmentModel);
|
||||
}
|
||||
);
|
||||
|
||||
$department = new DepartmentResource($departmentModel);
|
||||
|
||||
$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',
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
private function groupProgramsByDirection(Collection $programs): Collection
|
||||
{
|
||||
// Группируем программы по имени направления
|
||||
return $programs->groupBy(function ($program) {
|
||||
return $program->directionStudy->code . " " . $program->directionStudy->name; // Используем имя направления как ключ
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\InstituteStructure\UI\WEB\Controllers;
|
||||
|
||||
use App\Containers\InstituteStructure\Models\Division;
|
||||
use App\Containers\InstituteStructure\UI\WEB\Transformers\DivisionResource;
|
||||
use App\Ship\Contracts\SeoServiceInterface;
|
||||
use App\Ship\Controllers\Controller;
|
||||
use App\Ship\Enums\CacheKeys;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ClientDivisionController extends Controller
|
||||
{
|
||||
public function __construct(readonly SeoServiceInterface $seoPageProvider){}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$divisions = Cache::remember(CacheKeys::DIVISIONS_PREFIX->value . 'list', now()->addDay(), function () {
|
||||
return DivisionResource::collection(
|
||||
Division::query()->where('is_active', true)->get()
|
||||
);
|
||||
});
|
||||
|
||||
$seo = Cache::remember(CacheKeys::DIVISIONS_PREFIX->value . 'seo', now()->addDay(), function () {
|
||||
return $this->seoPageProvider->getSeoForCurrentPage();
|
||||
});
|
||||
|
||||
return Inertia::render('Client/Divisions/Index', compact('divisions', 'seo'));
|
||||
}
|
||||
|
||||
public function show(string $slug): \Inertia\Response
|
||||
{
|
||||
$divisions = Cache::remember(CacheKeys::DIVISIONS_PREFIX->value . 'list', now()->addDay(), function () {
|
||||
return DivisionResource::collection(
|
||||
Division::query()->where('is_active', true)->get()
|
||||
);
|
||||
});
|
||||
|
||||
$divisionData = Cache::remember(CacheKeys::DIVISION_PREFIX->value . $slug, now()->addDay(), function () use ($slug) {
|
||||
return Division::with(['workers.userDetail', 'seo'])->where('is_active', true)->where('slug', $slug)->firstOrFail();
|
||||
});
|
||||
|
||||
$seo = $this->seoPageProvider->getSeoForModel($divisionData);
|
||||
|
||||
$division = new DivisionResource($divisionData);
|
||||
|
||||
return Inertia::render('Client/Divisions/Show', compact('divisions', 'division', 'seo'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\InstituteStructure\UI\WEB\Controllers;
|
||||
|
||||
|
||||
use App\Containers\InstituteStructure\Models\Faculty;
|
||||
use App\Containers\InstituteStructure\UI\WEB\Transformers\FacultyPreviewResource;
|
||||
use App\Containers\InstituteStructure\UI\WEB\Transformers\FacultyResource;
|
||||
use App\Ship\Contracts\SeoServiceInterface;
|
||||
use App\Ship\Controllers\Controller;
|
||||
use App\Ship\Enums\CacheKeys;
|
||||
use App\Ship\Requests\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Inertia\Inertia;
|
||||
|
||||
|
||||
class ClientFacultyController extends Controller
|
||||
{
|
||||
public function __construct(readonly SeoServiceInterface $seoPageProvider){}
|
||||
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$faculties = Cache::remember(
|
||||
CacheKeys::FACULTIES_PREFIX->value . 'active_list',
|
||||
now()->addDay(), // Кешируем на 1 день
|
||||
function () {
|
||||
return FacultyPreviewResource::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 = Cache::remember(
|
||||
CacheKeys::FACULTIES_PREFIX->value . 'active_list',
|
||||
now()->addDay(),
|
||||
function () {
|
||||
return FacultyPreviewResource::collection(
|
||||
Faculty::query()
|
||||
->where('is_active', true)
|
||||
->get()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Кешируем данные конкретного факультета
|
||||
$faculty = Cache::remember(
|
||||
CacheKeys::FACULTY_PREFIX->value . $slug,
|
||||
now()->addDay(),
|
||||
function () use ($slug) {
|
||||
return Faculty::where('slug', $slug)
|
||||
->where('is_active', true)
|
||||
->with(['departments.faculty', 'workers', 'seo'])
|
||||
->firstOrFail();
|
||||
}
|
||||
);
|
||||
|
||||
$seo = Cache::remember(
|
||||
CacheKeys::FACULTY_PREFIX->value . "SEO_" . $slug,
|
||||
now()->addDay(),
|
||||
function () use ($faculty) {
|
||||
return $this->seoPageProvider->getSeoForModel($faculty);
|
||||
}
|
||||
);
|
||||
|
||||
$faculty = new FacultyResource($faculty);
|
||||
|
||||
|
||||
|
||||
return Inertia::render('Client/Faculties/Show', compact('faculty', 'faculties', 'seo'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
use App\Containers\InstituteStructure\UI\WEB\Controllers\ClientDepartmentController;
|
||||
use App\Containers\InstituteStructure\UI\WEB\Controllers\ClientDivisionController;
|
||||
use App\Containers\InstituteStructure\UI\WEB\Controllers\ClientFacultyController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
|
||||
|
||||
Route::middleware('access-check')->group(function () {
|
||||
// Факультеты и кафедры
|
||||
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');
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\InstituteStructure\UI\WEB\Transformers;
|
||||
|
||||
use App\Ship\Resources\JsonResource;
|
||||
|
||||
|
||||
class DepartmentPreviewResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'title' => $this->title,
|
||||
'slug' => $this->slug,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\InstituteStructure\UI\WEB\Transformers;
|
||||
|
||||
|
||||
use App\Containers\User\UI\WEB\Transformers\PersonDepartmentPreviewResource;
|
||||
use App\Containers\User\UI\WEB\Transformers\PersonDepartmentTeachPreviewResource;
|
||||
use App\Ship\Resources\JsonResource;
|
||||
|
||||
class DepartmentResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'title' => $this->title,
|
||||
'content' => $this->content,
|
||||
'faculty' => $this->faculty,
|
||||
'slug' => $this->slug,
|
||||
'workers' => PersonDepartmentPreviewResource::collection($this->workers),
|
||||
'teachers' => PersonDepartmentTeachPreviewResource::collection($this->teachers),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\InstituteStructure\UI\WEB\Transformers;
|
||||
|
||||
use App\Containers\User\UI\WEB\Transformers\PersonDivisionPreviewResource;
|
||||
use App\Ship\Resources\JsonResource;
|
||||
|
||||
class DivisionResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'title' => $this->title,
|
||||
'slug' => $this->slug,
|
||||
'workers' => PersonDivisionPreviewResource::collection($this->whenLoaded('workers')),
|
||||
'description' => $this->description,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\InstituteStructure\UI\WEB\Transformers;
|
||||
|
||||
|
||||
use App\Ship\Resources\JsonResource;
|
||||
|
||||
class FacultyPreviewResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'title' => $this->title,
|
||||
'shortTitle' => $this->abbreviation,
|
||||
'slug' => $this->slug,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\InstituteStructure\UI\WEB\Transformers;
|
||||
|
||||
|
||||
use App\Containers\User\UI\WEB\Transformers\PersonFacultyPreviewResource;
|
||||
use App\Ship\Resources\JsonResource;
|
||||
|
||||
class FacultyResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'title' => $this->title,
|
||||
'content' => $this->content,
|
||||
'shortTitle' => $this->abbreviation,
|
||||
'slug' => $this->slug,
|
||||
'workers' => PersonFacultyPreviewResource::collection($this->workers),
|
||||
'departments' => DepartmentPreviewResource::collection($this->departments)
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user