Laravel 通知系统实战:用 Notification 收口多渠道通知与数据库落库

test12026-10-063 次阅读

为什么用 Notification 而不是到处发邮件

一个"订单发货"事件可能要发邮件、写站内信、推短信。把通知逻辑散落在控制器里难维护。Laravel 的 Notification 把"通知什么"和"走哪些渠道"收敛到一个类,控制器只管触发。

生成一个通知类

// app/Notifications/OrderShipped.php
namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;

class OrderShipped extends Notification
{
    use Queueable;

    public function __construct(public string $orderNo) {}

    // 支持的可投递渠道
    public function via(object $notifiable): array
    {
        return ['mail', 'database'];
    }

    public function toMail(object $notifiable): MailMessage
    {
        return (new MailMessage)
            ->subject('订单已发货')
            ->line("订单 {$this->orderNo} 已发出");
    }

    // 落库内容,写入 notifications 表
    public function toArray(object $notifiable): array
    {
        return ['order_no' => $this->orderNo, 'type' => 'shipped'];
    }
}

触发通知

use App\Notifications\OrderShipped;
use App\Models\User;

$user = User::find(1);
$user->notify(new OrderShipped('NO20261006'));

// 或一次性通知多人
User::where('vip', 1)->each(
    fn ($u) => $u->notify(new OrderShipped('NO20261006'))
);

读取与标记已读

database 渠道会把通知写入 notifications 表,前端列表直接查未读。

$unread = $user->unreadNotifications;
foreach ($unread as $n) {
    echo $n->data['order_no'];
}
$user->unreadNotifications->markAsRead();

扩展渠道

  • 短信、钉钉、自定义 Webhook 都可写成 toXxx 方法并加入 via 数组,控制器无感。
  • 通知类建议实现 ShouldQueue,让发信走队列,避免阻塞主请求。
  • notifications 表用 notifications:table 迁移生成,data 字段为 JSON,便于扩展。
T

test1

文章作者

为什么用 Notification 而不是到处发邮件 一个"订单发货"事件可能要发邮件、写站内信、推短信。把通知逻辑散...

分类
技术
发布时间
2026-10-06
字数
约 1536 字
阅读
3 次