changes
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Dashboard\Actions\Faculties;
|
||||
|
||||
use App\Containers\InstituteStructure\Models\Faculty;
|
||||
use App\Containers\User\Models\User;
|
||||
use App\Services\App\Cache\FacultyCacheService;
|
||||
|
||||
class AttachFacultyWorkerAction
|
||||
{
|
||||
public function __construct(
|
||||
private readonly FacultyCacheService $cacheService,
|
||||
) {}
|
||||
|
||||
public function run(Faculty $faculty, User $user, array $data): void
|
||||
{
|
||||
$faculty->workers()->attach($user->id, [
|
||||
'position' => $data['position'],
|
||||
'service_email' => $data['service_email'] ?? null,
|
||||
'service_phone' => $data['service_phone'] ?? null,
|
||||
'cabinet' => $data['cabinet'] ?? null,
|
||||
'sort' => $data['sort'] ?? $faculty->workers()->count(),
|
||||
]);
|
||||
|
||||
$this->cacheService->clearAllCacheByModel();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Dashboard\Actions\Faculties;
|
||||
|
||||
use App\Containers\Dashboard\Tasks\Content\GenerateSearchDataTask;
|
||||
use App\Containers\InstituteStructure\Models\Faculty;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CreateFacultyAction
|
||||
{
|
||||
public function __construct(
|
||||
private readonly GenerateSearchDataTask $generateSearchDataTask,
|
||||
) {}
|
||||
|
||||
public function run(array $data): Faculty
|
||||
{
|
||||
// Генерируем slug если не передан
|
||||
if (empty($data['slug'])) {
|
||||
$data['slug'] = Str::slug($data['title']);
|
||||
}
|
||||
|
||||
// Генерируем search_data из контента
|
||||
if (!empty($data['content'])) {
|
||||
$data['search_data'] = $this->generateSearchDataTask->run($data['content']);
|
||||
}
|
||||
|
||||
$faculty = Faculty::create($data);
|
||||
|
||||
// Создаем SEO
|
||||
$this->generateSeo($faculty, $data);
|
||||
|
||||
return $faculty;
|
||||
}
|
||||
|
||||
private function generateSeo(Faculty $faculty, array $data): void
|
||||
{
|
||||
$title = $data['title'] ?? '';
|
||||
$description = null;
|
||||
|
||||
// Извлекаем description из первого paragraph блока
|
||||
if (!empty($data['content'])) {
|
||||
foreach ($data['content'] as $block) {
|
||||
if ($block['type'] === 'paragraph') {
|
||||
$description = strip_tags($block['data']['content']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$faculty->seo()->create([
|
||||
'title' => $title,
|
||||
'description' => Str::limit(htmlspecialchars($description ?? '', ENT_QUOTES, 'UTF-8'), 160),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Dashboard\Actions\Faculties;
|
||||
|
||||
use App\Containers\InstituteStructure\Models\Faculty;
|
||||
|
||||
class DeleteFacultyAction
|
||||
{
|
||||
public function run(Faculty $faculty): void
|
||||
{
|
||||
$faculty->delete();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Dashboard\Actions\Faculties;
|
||||
|
||||
use App\Containers\InstituteStructure\Models\Faculty;
|
||||
use App\Containers\User\Models\User;
|
||||
use App\Services\App\Cache\FacultyCacheService;
|
||||
|
||||
class DetachFacultyWorkerAction
|
||||
{
|
||||
public function __construct(
|
||||
private readonly FacultyCacheService $cacheService,
|
||||
) {}
|
||||
|
||||
public function run(Faculty $faculty, User $worker): void
|
||||
{
|
||||
$faculty->workers()->detach($worker->id);
|
||||
$this->cacheService->clearAllCacheByModel();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Dashboard\Actions\Faculties;
|
||||
|
||||
use App\Containers\InstituteStructure\Models\Faculty;
|
||||
|
||||
class ListFacultiesAction
|
||||
{
|
||||
public function run(array $filters = []): array
|
||||
{
|
||||
$query = Faculty::query();
|
||||
|
||||
// Фильтр по статусу
|
||||
if (isset($filters['is_active']) && $filters['is_active'] !== '') {
|
||||
$query->where('is_active', (bool) $filters['is_active']);
|
||||
}
|
||||
|
||||
// Поиск по названию
|
||||
if (!empty($filters['search'])) {
|
||||
$query->where('title', 'like', '%' . $filters['search'] . '%');
|
||||
}
|
||||
|
||||
$faculties = $query->orderBy('title')->paginate(20)->withQueryString();
|
||||
|
||||
return [
|
||||
'faculties' => $faculties,
|
||||
'filters' => $filters,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Dashboard\Actions\Faculties;
|
||||
|
||||
use App\Containers\InstituteStructure\Models\Faculty;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ListFacultyWorkersAction
|
||||
{
|
||||
public function run(Faculty $faculty, array $filters = []): array
|
||||
{
|
||||
$query = $faculty->workers()
|
||||
->withPivot(['position', 'sort', 'service_email', 'service_phone', 'cabinet'])
|
||||
->whereHas('userDetail');
|
||||
|
||||
// Поиск по ФИО
|
||||
if (!empty($filters['search'])) {
|
||||
$query->where('name', 'like', '%' . $filters['search'] . '%');
|
||||
}
|
||||
|
||||
// Фильтр по должности
|
||||
if (!empty($filters['position'])) {
|
||||
$query->where('workers_faculties.position', 'like', '%' . $filters['position'] . '%');
|
||||
}
|
||||
|
||||
$workers = $query->orderBy('workers_faculties.sort')->paginate(20)->withQueryString();
|
||||
|
||||
return [
|
||||
'workers' => $workers,
|
||||
'filters' => $filters,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Dashboard\Actions\Faculties;
|
||||
|
||||
use App\Containers\Dashboard\Tasks\Content\GenerateSearchDataTask;
|
||||
use App\Containers\InstituteStructure\Models\Faculty;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UpdateFacultyAction
|
||||
{
|
||||
public function __construct(
|
||||
private readonly GenerateSearchDataTask $generateSearchDataTask,
|
||||
) {}
|
||||
|
||||
public function run(Faculty $faculty, array $data): Faculty
|
||||
{
|
||||
// Генерируем search_data из контента только если контент передан и не пуст
|
||||
if (isset($data['content']) && !empty($data['content'])) {
|
||||
$data['search_data'] = $this->generateSearchDataTask->run($data['content']);
|
||||
}
|
||||
|
||||
$faculty->update($data);
|
||||
|
||||
// Обновляем SEO
|
||||
$this->updateSeo($faculty, $data);
|
||||
|
||||
return $faculty;
|
||||
}
|
||||
|
||||
private function updateSeo(Faculty $faculty, array $data): void
|
||||
{
|
||||
$title = $data['title'] ?? $faculty->title;
|
||||
$description = null;
|
||||
|
||||
// Извлекаем description из первого paragraph блока
|
||||
if (!empty($data['content'])) {
|
||||
foreach ($data['content'] as $block) {
|
||||
if ($block['type'] === 'paragraph') {
|
||||
$description = strip_tags($block['data']['content']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$seoData = [
|
||||
'title' => $title,
|
||||
'description' => Str::limit(htmlspecialchars($description ?? '', ENT_QUOTES, 'UTF-8'), 160),
|
||||
];
|
||||
|
||||
if ($faculty->seo) {
|
||||
$faculty->seo->update($seoData);
|
||||
} else {
|
||||
$faculty->seo()->create($seoData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Dashboard\Actions\Faculties;
|
||||
|
||||
use App\Containers\InstituteStructure\Models\Faculty;
|
||||
use App\Containers\User\Models\User;
|
||||
use App\Services\App\Cache\FacultyCacheService;
|
||||
|
||||
class UpdateFacultyWorkerAction
|
||||
{
|
||||
public function __construct(
|
||||
private readonly FacultyCacheService $cacheService,
|
||||
) {}
|
||||
|
||||
public function run(Faculty $faculty, User $worker, array $data): void
|
||||
{
|
||||
$faculty->workers()->updateExistingPivot($worker->id, [
|
||||
'position' => $data['position'],
|
||||
'service_email' => $data['service_email'] ?? null,
|
||||
'service_phone' => $data['service_phone'] ?? null,
|
||||
'cabinet' => $data['cabinet'] ?? null,
|
||||
]);
|
||||
|
||||
$this->cacheService->clearAllCacheByModel();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user