first&last

This commit is contained in:
sbb45
2026-03-20 15:47:17 +05:00
commit d6441abdd2
230 changed files with 20367 additions and 0 deletions
+159
View File
@@ -0,0 +1,159 @@
<?php
namespace App\Livewire\Requests;
use App\Exports\CsvExport;
use App\Models\Priority;
use App\Models\RequestType;
use App\Models\ServiceRequest;
use App\Models\Status;
use App\Models\User;
use App\Services\ActivityLogService;
use Illuminate\Database\Eloquent\Builder;
use Livewire\Attributes\Layout;
use Livewire\Component;
use Livewire\WithPagination;
#[Layout('layouts.app')]
class RequestIndexPage extends Component
{
use WithPagination;
public string $search = '';
public string $statusId = '';
public string $priorityId = '';
public string $typeId = '';
public string $technicianId = '';
public string $dateFrom = '';
public string $dateTo = '';
public string $sortField = 'created_at';
public string $sortDirection = 'desc';
public int $perPage = 15;
public array $selected = [];
public string $bulkAssignee = '';
public string $bulkStatus = '';
public function mount(): void
{
abort_unless(auth()->user()->isAdmin() || auth()->user()->isManager(), 403);
}
public function updatingSearch(): void
{
$this->resetPage();
}
public function sortBy(string $field): void
{
if ($this->sortField === $field) {
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
return;
}
$this->sortField = $field;
$this->sortDirection = 'asc';
}
public function clearFilters(): void
{
$this->reset(['search', 'statusId', 'priorityId', 'typeId', 'technicianId', 'dateFrom', 'dateTo']);
$this->resetPage();
}
public function bulkAssign(ActivityLogService $activityLogService): void
{
if (!$this->bulkAssignee || empty($this->selected)) {
return;
}
ServiceRequest::query()
->whereIn('id', $this->selected)
->update(['assigned_to' => $this->bulkAssignee]);
$activityLogService->log(auth()->user(), ServiceRequest::class, 0, 'bulk_assign', 'Массовое назначение заявок', request()->ip());
$this->selected = [];
session()->flash('success', 'Исполнитель назначен выбранным заявкам.');
}
public function bulkChangeStatus(ActivityLogService $activityLogService): void
{
if (!$this->bulkStatus || empty($this->selected)) {
return;
}
ServiceRequest::query()
->whereIn('id', $this->selected)
->update(['status_id' => $this->bulkStatus]);
$activityLogService->log(auth()->user(), ServiceRequest::class, 0, 'bulk_status_change', 'Массовая смена статуса заявок', request()->ip());
$this->selected = [];
session()->flash('success', 'Статус обновлен для выбранных заявок.');
}
public function exportCsv()
{
$rows = $this->query()->get()->map(function (ServiceRequest $request) {
return [
$request->ticket_number,
$request->title,
$request->client?->name,
$request->assignee?->name,
$request->priority?->name,
$request->status?->name,
$request->deadline_at?->format('d.m.Y H:i'),
$request->created_at?->format('d.m.Y H:i'),
];
})->toArray();
return CsvExport::download(
'requests.csv',
['Ticket', 'Заголовок', 'Клиент', 'Исполнитель', 'Приоритет', 'Статус', 'Дедлайн', 'Создана'],
$rows
);
}
private function query(): Builder
{
return ServiceRequest::query()
->with(['client', 'assignee', 'priority', 'status', 'type'])
->when($this->search !== '', function (Builder $query): void {
$query->where(function (Builder $q): void {
$q->where('title', 'like', "%{$this->search}%")
->orWhere('ticket_number', 'like', "%{$this->search}%");
});
})
->when($this->statusId !== '', fn (Builder $q) => $q->where('status_id', $this->statusId))
->when($this->priorityId !== '', fn (Builder $q) => $q->where('priority_id', $this->priorityId))
->when($this->typeId !== '', fn (Builder $q) => $q->where('type_id', $this->typeId))
->when($this->technicianId !== '', fn (Builder $q) => $q->where('assigned_to', $this->technicianId))
->when($this->dateFrom !== '', fn (Builder $q) => $q->whereDate('created_at', '>=', $this->dateFrom))
->when($this->dateTo !== '', fn (Builder $q) => $q->whereDate('created_at', '<=', $this->dateTo))
->orderBy($this->sortField, $this->sortDirection);
}
public function render()
{
return view('livewire.requests.request-index-page', [
'requests' => $this->query()->paginate($this->perPage),
'statuses' => Status::query()->orderBy('sort_order')->get(),
'priorities' => Priority::query()->orderBy('level')->get(),
'types' => RequestType::query()->orderBy('name')->get(),
'technicians' => User::query()->where('role', 'technician')->orderBy('name')->get(),
])->title('Заявки');
}
}