Laravel Filament中如何仅向服务工单指派用户发送数据库通知
问题:无法通过Filament向服务工单指派用户发送数据库通知
我正在尝试使用Laravel的Filament组件开发数据库通知功能,但发现无法向服务工单的指派用户发送通知。服务工单可指派多名员工,因此已创建中间表,相关代码如下:
ServiceOrderObserver.php(观察者)
<?php namespace App\Observers; use App\Models\User; use App\Models\ServiceOrder; use Filament\Notifications\Notification; class ServiceOrderOberserver { /** * Handle the ServiceOrder "created" event. */ public function created(ServiceOrder $serviceOrder): void { // Fetch the users who are assigned to this specific service order $assignedStaff = User::whereHas('serviceOrders', function($query) use ($serviceOrder) { $query->where('service_order_id', $serviceOrder->id); })->get(); // Loop through each assigned staff member and send the notification foreach ($assignedStaff as $staff) { Notification::make() ->title('New Service Order: ' . $serviceOrder->pOrder) ->body('You have been assigned to service order ' . $serviceOrder->pOrder) ->success() // Styling for the notification (optional) ->sendToDatabase($staff); // Send notification to each staff member } } // 其他事件方法... }
ServiceOrder.php(模型)
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class ServiceOrder extends Model { use HasFactory; protected $fillable = [ 'pOrder', 'clientAddress', 'clientPhone', 'description', 'registeredDate', 'assignedDate', 'handoverDate', 'estimatedTime', 'status', 'remarks', ]; public function assignedStaff() { return $this->belongsToMany(User::class, 'service_order_staff', 'service_order_id', 'user_id') ->withTimestamps(); } public function users() { return $this->belongsToMany(User::class, 'service_order_staff', 'service_order_id', 'user_id'); } }
中间表迁移代码
public function up(): void { Schema::create('service_order_staff', function (Blueprint $table) { $table->id(); $table->foreignId('service_order_id')->constrained()->onDelete('cascade'); $table->foreignId('user_id')->constrained()->onDelete('cascade'); $table->timestamps(); }); }
解决方案
1. 核心问题分析
created事件触发时机过早:服务工单刚创建完成时,中间表service_order_staff的关联数据还未被写入,导致whereHas查询无法获取到指派用户。- 可能缺失User模型的关联定义:若User模型未定义与ServiceOrder的多对多关系,
whereHas('serviceOrders')会直接返回空结果。
2. 具体修复步骤
(1)完善User模型的关联关系
在App\Models\User.php中添加与服务工单的多对多关系:
use Illuminate\Database\Eloquent\Relations\BelongsToMany; public function serviceOrders(): BelongsToMany { return $this->belongsToMany(ServiceOrder::class, 'service_order_staff', 'user_id', 'service_order_id'); }
同时,确保User模型实现Filament的数据库通知接口:
use Filament\Models\Contracts\HasDatabaseNotifications; use Filament\Notifications\HasDatabaseNotifications as HasFilamentDatabaseNotifications; class User extends Authenticatable implements HasDatabaseNotifications { use HasFilamentDatabaseNotifications; // ... 其他原有代码 }
(2)修改观察者的事件处理逻辑
将created事件替换为saved事件(该事件在模型创建或更新后触发,此时关联数据已写入中间表),并直接通过模型关联获取指派用户:
public function saved(ServiceOrder $serviceOrder): void { // 直接通过关联关系获取已指派的员工,无需额外查询 $assignedStaff = $serviceOrder->assignedStaff; foreach ($assignedStaff as $staff) { Notification::make() ->title('新服务工单:' . $serviceOrder->pOrder) ->body('您被指派到服务工单 ' . $serviceOrder->pOrder) ->success() ->sendToDatabase($staff); } }
(3)确认观察者已注册
在App\Providers\AppServiceProvider.php的boot方法中注册观察者:
use App\Models\ServiceOrder; use App\Observers\ServiceOrderOberserver; public function boot() { ServiceOrder::observe(ServiceOrderOberserver::class); }
3. 额外检查项
- 确保Filament的通知组件已正确配置,用户能在Filament面板中看到通知中心。
- 测试时,创建工单并指派用户后,检查
filament_notifications表是否生成了对应的通知记录。
内容的提问来源于stack exchange,提问作者Mohammad Faiz Asyraf bin Azaha
相关产品推荐
相关产品推荐

