瀏覽代碼

Optimize Ticket Notification Logic

BrettonYe 9 月之前
父節點
當前提交
2cdbc31df7

+ 1 - 1
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));
                 }
             });
         });

+ 2 - 17
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')])]);
         }
 

+ 4 - 17
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')])]);
         }
 

+ 3 - 0
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';

+ 1 - 1
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);
     }
 

+ 11 - 1
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

+ 49 - 0
app/Observers/TicketReplyObserver.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace App\Observers;
+
+use App\Models\TicketReply;
+use App\Models\User;
+use App\Notifications\TicketReplied;
+use Illuminate\Database\Eloquent\Collection;
+use Notification;
+
+class TicketReplyObserver
+{
+    public function created(TicketReply $reply): void
+    {
+        $ticket = $reply->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();
+    }
+}