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
+158
View File
@@ -0,0 +1,158 @@
<?php
namespace App\Livewire\Requests;
use App\Models\RequestComment;
use App\Models\ServiceRequest;
use App\Models\Status;
use App\Services\NotificationService;
use App\Services\RequestService;
use Illuminate\Support\Facades\Gate;
use Livewire\Attributes\Layout;
use Livewire\Component;
#[Layout('layouts.app')]
class RequestShowPage extends Component
{
public ServiceRequest $request;
public string $commentBody = '';
public bool $commentInternal = false;
public string $nextStatusId = '';
public ?int $rating = null;
public string $ratingComment = '';
public function mount(ServiceRequest $request): void
{
Gate::authorize('view', $request);
$this->request = $request->load([
'type',
'priority',
'status',
'client',
'assignee',
'equipment.category',
'comments.user',
'attachments.user',
]);
}
public function addComment(NotificationService $notificationService): void
{
Gate::authorize('update', $this->request);
$data = $this->validate([
'commentBody' => ['required', 'string', 'max:5000'],
'commentInternal' => ['nullable', 'boolean'],
]);
if (($data['commentInternal'] ?? false) && !auth()->user()->isStaff()) {
abort(403);
}
$comment = $this->request->comments()->create([
'user_id' => auth()->id(),
'body' => $data['commentBody'],
'is_internal' => (bool) ($data['commentInternal'] ?? false),
]);
$this->commentBody = '';
$this->commentInternal = false;
$notificationService->notifyCommentAdded($this->request->fresh(['assignee', 'client']), auth()->user());
session()->flash('success', 'Комментарий добавлен.');
$this->request->refresh();
}
public function deleteComment(int $commentId): void
{
$comment = RequestComment::query()->findOrFail($commentId);
abort_unless($comment->user_id === auth()->id(), 403);
$comment->delete();
session()->flash('success', 'Комментарий удален.');
$this->request->refresh();
}
public function changeStatus(RequestService $requestService): void
{
Gate::authorize('update', $this->request);
if ($this->nextStatusId === '') {
return;
}
$target = Status::query()->findOrFail($this->nextStatusId);
$allowed = $requestService->allowedTransitions($this->request->fresh('status'), auth()->user());
if (!in_array($target->slug, $allowed, true)) {
abort(422, 'Переход статуса недоступен.');
}
$requestService->changeStatus($this->request, $target, auth()->user());
$this->nextStatusId = '';
session()->flash('success', 'Статус обновлен.');
$this->request->refresh();
}
public function submitRating(): void
{
Gate::authorize('rate', $this->request);
$data = $this->validate([
'rating' => ['required', 'integer', 'between:1,5'],
'ratingComment' => ['nullable', 'string', 'max:2000'],
]);
$this->request->update([
'client_rating' => $data['rating'],
'client_comment' => $data['ratingComment'] ?? null,
]);
session()->flash('success', 'Спасибо за оценку заявки.');
$this->request->refresh();
}
private function allowedStatuses()
{
$requestService = app(RequestService::class);
$slugs = $requestService->allowedTransitions($this->request->fresh('status'), auth()->user());
return Status::query()->whereIn('slug', $slugs)->orderBy('sort_order')->get();
}
public function render()
{
$isClient = auth()->user()->isClient();
$comments = $this->request->comments()
->with('user')
->when($isClient, fn ($q) => $q->where('is_internal', false))
->latest()
->get();
return view('livewire.requests.request-show-page', [
'allowedStatuses' => $this->allowedStatuses(),
'comments' => $comments,
'activity' => $this->request->id
? \App\Models\ActivityLog::query()
->where('model_type', ServiceRequest::class)
->where('model_id', $this->request->id)
->with('user')
->latest('created_at')
->limit(20)
->get()
: collect(),
])->title("Заявка {$this->request->ticket_number}");
}
}