From 2cdbc31df73742f3960668a4e644fe57f9d0dd2f Mon Sep 17 00:00:00 2001 From: BrettonYe Date: Wed, 1 Jan 2025 16:26:36 +0800 Subject: [PATCH] Optimize Ticket Notification Logic --- app/Console/Commands/TaskDaily.php | 2 +- .../Controllers/Admin/TicketController.php | 19 +------ .../Controllers/User/TicketController.php | 21 ++------ app/Models/TicketReply.php | 3 ++ app/Notifications/TicketCreated.php | 2 +- app/Observers/TicketObserver.php | 12 ++++- app/Observers/TicketReplyObserver.php | 49 +++++++++++++++++++ 7 files changed, 71 insertions(+), 37 deletions(-) create mode 100644 app/Observers/TicketReplyObserver.php diff --git a/app/Console/Commands/TaskDaily.php b/app/Console/Commands/TaskDaily.php index c5868bb8..8dd72e86 100644 --- a/app/Console/Commands/TaskDaily.php +++ b/app/Console/Commands/TaskDaily.php @@ -79,7 +79,7 @@ class TaskDaily extends Command $tickets->each(function ($ticket) use ($closeTicketsHours) { if ($ticket->close()) { $ticket->user->notify(new TicketClosed($ticket->id, $ticket->title, route('ticket.edit', $ticket), - __('You have not responded this ticket in :num hours, System has closed your ticket.', ['num' => $closeTicketsHours]))); + __('You have not responded this ticket in :num hours, System has closed your ticket.', ['num' => $closeTicketsHours]), true)); } }); }); diff --git a/app/Http/Controllers/Admin/TicketController.php b/app/Http/Controllers/Admin/TicketController.php index b565cc30..0a9fb613 100644 --- a/app/Http/Controllers/Admin/TicketController.php +++ b/app/Http/Controllers/Admin/TicketController.php @@ -7,8 +7,6 @@ use App\Http\Requests\Admin\TicketRequest; use App\Models\Ticket; use App\Models\User; use App\Notifications\TicketClosed; -use App\Notifications\TicketCreated; -use App\Notifications\TicketReplied; use Illuminate\Contracts\View\View; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -39,9 +37,7 @@ class TicketController extends Controller return response()->json(['status' => 'fail', 'message' => trans('admin.ticket.self_send')]); } - if ($ticket = Ticket::create(['user_id' => $user->id, 'admin_id' => auth()->id(), 'title' => $data['title'], 'content' => clean($data['content'])])) { - $user->notify(new TicketCreated($ticket, route('ticket.edit', $ticket))); - + if (Ticket::create(['user_id' => $user->id, 'admin_id' => auth()->id(), 'title' => $data['title'], 'content' => clean($data['content']), 'status' => 1])) { return response()->json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.create')])]); } @@ -61,18 +57,7 @@ class TicketController extends Controller { // 回复工单 $content = substr(str_replace(['atob', 'eval'], '', clean($request->input('content'))), 0, 300); - $reply = $ticket->reply()->create(['admin_id' => Auth::id(), 'content' => $content]); - if ($reply) { - // 将工单置为已回复 - if ($ticket->status !== 1) { - $ticket->update(['status' => 1]); - } - - // 通知用户 - if (sysConfig('ticket_replied_notification')) { - $ticket->user->notify(new TicketReplied($reply, route('ticket.edit', $ticket), true)); - } - + if ($ticket->reply()->create(['admin_id' => auth()->id(), 'content' => $content])) { return response()->json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('user.ticket.reply')])]); } diff --git a/app/Http/Controllers/User/TicketController.php b/app/Http/Controllers/User/TicketController.php index 774c2f7b..83744ee3 100644 --- a/app/Http/Controllers/User/TicketController.php +++ b/app/Http/Controllers/User/TicketController.php @@ -4,13 +4,9 @@ namespace App\Http\Controllers\User; use App\Http\Controllers\Controller; use App\Models\Ticket; -use App\Models\User; -use App\Notifications\TicketCreated; -use App\Notifications\TicketReplied; use Illuminate\Contracts\View\View; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; -use Notification; class TicketController extends Controller { @@ -32,12 +28,12 @@ class TicketController extends Controller ]); } - if ($ticket = auth()->user()->tickets()->create(compact('title', 'content'))) { + if (auth()->user()->tickets()->create(compact('title', 'content'))) { // 通知相关管理员 - Notification::send(User::find(1), new TicketCreated($ticket, route('admin.ticket.edit', $ticket))); + return response()->json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.submit')])]); } - return response()->json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('common.submit')])]); + return response()->json(['status' => 'fail', 'message' => trans('common.failed_item', ['attribute' => trans('common.create')])]); } public function edit(Ticket $ticket): View @@ -58,16 +54,7 @@ class TicketController extends Controller ]); } - $reply = $ticket->reply()->create(['user_id' => auth()->id(), 'content' => $content]); - if ($reply) { - // 重新打开工单 - if (in_array($ticket->status, [1, 2], true)) { - $ticket->update(['status' => 0]); - } - - // 通知相关管理员 - Notification::send(User::find(1), new TicketReplied($reply, route('admin.ticket.edit', $ticket))); - + if ($ticket->reply()->create(['user_id' => auth()->id(), 'content' => $content])) { return response()->json(['status' => 'success', 'message' => trans('common.success_item', ['attribute' => trans('user.ticket.reply')])]); } diff --git a/app/Models/TicketReply.php b/app/Models/TicketReply.php index 7a877d65..4aca7642 100644 --- a/app/Models/TicketReply.php +++ b/app/Models/TicketReply.php @@ -2,12 +2,15 @@ namespace App\Models; +use App\Observers\TicketReplyObserver; +use Illuminate\Database\Eloquent\Attributes\ObservedBy; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; /** * 工单回复. */ +#[ObservedBy([TicketReplyObserver::class])] class TicketReply extends Model { protected $table = 'ticket_reply'; diff --git a/app/Notifications/TicketCreated.php b/app/Notifications/TicketCreated.php index a6a71667..11883473 100644 --- a/app/Notifications/TicketCreated.php +++ b/app/Notifications/TicketCreated.php @@ -36,7 +36,7 @@ class TicketCreated extends Notification implements ShouldQueue return (new MailMessage) ->subject(trans('notification.new_ticket', ['title' => $this->ticket->title])) ->line(trans('notification.ticket_content')) - ->line($this->ticket->content) + ->line(strip_tags($this->ticket->content)) ->action(trans('notification.view_ticket'), $this->url); } diff --git a/app/Observers/TicketObserver.php b/app/Observers/TicketObserver.php index 62b9acdc..a290a75b 100644 --- a/app/Observers/TicketObserver.php +++ b/app/Observers/TicketObserver.php @@ -2,13 +2,23 @@ namespace App\Observers; +use App\Models\Ticket; +use App\Models\User; +use App\Notifications\TicketCreated; use Cache; +use Notification; class TicketObserver { - public function created(): void + public function created(Ticket $ticket): void { Cache::forget('open_ticket_count'); + + if (! $ticket->admin_id) { + Notification::send(User::find(1), new TicketCreated($ticket, route('admin.ticket.edit', $ticket))); // 通知相关管理员 + } else { + $ticket->user->notify(new TicketCreated($ticket, route('ticket.edit', $ticket), true)); + } } public function updated(): void diff --git a/app/Observers/TicketReplyObserver.php b/app/Observers/TicketReplyObserver.php new file mode 100644 index 00000000..f5f92cb6 --- /dev/null +++ b/app/Observers/TicketReplyObserver.php @@ -0,0 +1,49 @@ +ticket; + if ($reply->user_id) { + if ($ticket->status !== 0) { + $ticket->update(['status' => 0]); + } + + Notification::send($this->findAdmin($reply), new TicketReplied($reply, route('admin.ticket.edit', $ticket))); // 通知相关管理员 + } + + if ($reply->admin_id) { + if ($ticket->status !== 1) { + $ticket->update(['status' => 1]); + } + + if (sysConfig('ticket_replied_notification')) { // 通知用户 + $ticket->user->notify(new TicketReplied($reply, route('ticket.edit', $ticket), true)); + } + } + } + + private function findAdmin(TicketReply $reply): Collection + { + $ticket = $reply->ticket; + if ($ticket->admin_id) { + return $ticket->admin()->get(); + } + + $admins = $ticket->reply()->whereNotNull('admin_id')->distinct()->pluck('admin_id'); + if ($admins) { + return User::findMany($admins); + } + + return User::role('Super Admin')->get(); + } +}