feat(notification): 實作通知輪詢與優化顯示名稱

- 新增通知輪詢 API 與前端自動更新機制
- 修正生產工單單號格式為 PRO-YYYYMMDD-XX
- 確保通知顯示實際建立者名稱而非系統
This commit is contained in:
2026-02-12 17:13:09 +08:00
parent 299602d3b1
commit 882091ce5f
14 changed files with 528 additions and 47 deletions

View File

@@ -62,6 +62,11 @@ class PurchaseOrder extends Model
return $this->belongsTo(Vendor::class);
}
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
{
return $this->belongsTo(\App\Modules\Core\Models\User::class);
}

View File

@@ -0,0 +1,54 @@
<?php
namespace App\Modules\Procurement\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use App\Modules\Procurement\Models\PurchaseOrder;
class NewPurchaseOrder extends Notification
{
use Queueable;
protected $purchaseOrder;
protected $creatorName;
/**
* Create a new notification instance.
*/
public function __construct(PurchaseOrder $purchaseOrder, string $creatorName)
{
$this->purchaseOrder = $purchaseOrder;
$this->creatorName = $creatorName;
}
/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(object $notifiable): array
{
return ['database'];
}
/**
* Get the array representation of the notification.
*
* @return array<string, mixed>
*/
public function toArray(object $notifiable): array
{
return [
'type' => 'purchase_order',
'action' => 'created',
'purchase_order_id' => $this->purchaseOrder->id,
'code' => $this->purchaseOrder->code,
'creator_name' => $this->creatorName,
'message' => "{$this->creatorName} 建立了新的採購單:{$this->purchaseOrder->code}",
'link' => route('purchase-orders.index', ['search' => $this->purchaseOrder->code]), // 暫時導向列表並搜尋,若有詳情頁可改
];
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Modules\Procurement\Observers;
use App\Modules\Procurement\Models\PurchaseOrder;
use App\Modules\Procurement\Notifications\NewPurchaseOrder;
use App\Modules\Core\Models\User;
use Illuminate\Support\Facades\Notification;
class PurchaseOrderObserver
{
/**
* Handle the PurchaseOrder "created" event.
*/
public function created(PurchaseOrder $purchaseOrder): void
{
// 找出有檢視採購單權限的使用者
$users = User::permission('purchase_orders.view')->get();
// 排除建立者自己(避免自己收到自己的通知)
// $users = $users->reject(function ($user) use ($purchaseOrder) {
// return $user->id === $purchaseOrder->user_id;
// });
$creatorName = $purchaseOrder->user ? $purchaseOrder->user->name : '系統';
if ($users->isNotEmpty()) {
Notification::send($users, new NewPurchaseOrder($purchaseOrder, $creatorName));
}
}
}

View File

@@ -6,6 +6,10 @@ use Illuminate\Support\ServiceProvider;
use App\Modules\Procurement\Contracts\ProcurementServiceInterface;
use App\Modules\Procurement\Services\ProcurementService;
use App\Modules\Procurement\Models\PurchaseOrder;
use App\Modules\Procurement\Observers\PurchaseOrderObserver;
class ProcurementServiceProvider extends ServiceProvider
{
public function register(): void
@@ -15,6 +19,6 @@ class ProcurementServiceProvider extends ServiceProvider
public function boot(): void
{
//
PurchaseOrder::observe(PurchaseOrderObserver::class);
}
}