You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 20:55:54