Laravel 消息通知
创建通知
php artisan make:notification InvoicePaid
这个命令会在 app/Notifications
目录下生成一个新的通知类。每个通知类都包含一个 via 方法以及一个或多个消息构建的方法比如 toMail 或 toDatabase,它们会针对特定的渠道把通知转换为对应的消息。
发送通知
使用 Notifiable Trait
该方法默认包含在应用程序的 App\Models\User
模型中:
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
}
use App\Notifications\InvoicePaid;
$user->notify(new InvoicePaid($invoice));
你可以在任何模型中使用 Notifiable trait。而不仅仅是在 User 模型中。
使用 Notification Facade
主要用在当你需要给多个可接收通知的实体发送的时候,比如给用户集合发送通知。
$users = User::query()->get();
Notification::send($users, new InvoicePaid());
您也可以使用 sendNow
方法立即发送通知。即使通知实现了 ShouldQueue 接口,该方法也会立即发送通知:
Notification::sendNow($developers, new DeploymentCompleted($deployment));
发送指定频道
每个通知类都有一个 via 方法,用于确定将在哪些通道上传递通知。通知可以在 mail、database、broadcast、vonage 和 slack 频道上发送。
/**
* 获取通知发送频道
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return $notifiable->prefers_sms ? ['vonage'] : ['mail', 'database'];
}
数据库通知
开始之前,您需要创建一个数据库表来保存您的通知
php artisan notifications:table
php artisan migrate
格式化数据库通知
如果通知支持存储在数据库表中,则应在通知类上定义 toDatabase
或 toArray
方法。这个方法将接收一个 $notifiable
实体并且应该返回一个普通的 PHP
数组。 返回的数组将被编码为 JSON
并存储在 notifications
表的 data
列中。让我们看一个示例 toArray
方法:
public function toArray($notifiable)
{
return [
'invoice_id' => $this->invoice->id,
'amount' => $this->invoice->amount,
];
}
toDatabase
对比 toArray
broadcast
通道也使用 toArray
方法来确定将哪些数据广播到 JavaScript
驱动的前端。如果您想为 database
和 broadcast
通道提供两种不同的数组表示,您应该定义一个 toDatabase
方法而不是 toArray
方法。
访问通知
默认情况下,通知将按 created_at
时间戳排序,最近的通知位于集合的开头:
$user = App\Models\User::find(1);
foreach ($user->notifications as $notification) {
echo $notification->type;
}
如果您只想检索「未读」通知,可以使用 unreadNotifications
$user = App\Models\User::find(1);
foreach ($user->unreadNotifications as $notification) {
echo $notification->type;
}
将通知标记为已读
//直接在通知集合上使用 markAsRead 方法,而不是循环遍历每个通知:
$user->unreadNotifications->markAsRead();
//您还可以使用批量更新查询将所有通知标记为已读,而无需从数据库中检索它们:
$user = App\Models\User::find(1);
$user->unreadNotifications()->update(['read_at' => now()]);
//删除所有通知
$user->notifications()->delete();
自定义通知模板
默认的模板通常已经够用了,下面我们简单修改一下
一些必要操作
php artisan notifications:table
php artisan migrate
//创建通知
php artisan make:notification PasswordChangeMsg
php artisan vendor:publish --tag=laravel-mail
php artisan vendor:publish --tag=laravel-notifications
主要代码
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->level('info')
->subject('您的密码已被重置')
->greeting('您好!')
->salutation("祝\n\n万事如意")
->line('您的密码已被重置')
->lines(["登录名:$this->username", "密码:$this->password"])
->action('访问这里登录', url($this->url))
->line('此邮件由系统自动发出,请勿回复!');
}
通知模板修改
resources/views/vendor/notifications/email.blade.php
@lang(
"如果你在点击 \":actionText\" 按钮遇到麻烦,复制并粘贴下面的URL\n".
'进入你的网页浏览器:',
[
'actionText' => $actionText,
]
)
顶部修改
/resources/views/vendor/mail/html/header.blade.php
默认的只有APP_NAME
等于Laravel
时才显示图片,我们改一下
<a href="{{ $url }}" style="display: inline-block;">
@if (trim($slot) === '写代码的崔哥')
<img src="https://www.cuiwei.net/images/logo.jpg" class="logo" alt="写代码的崔哥 Logo">
@else
{{ $slot }}
@endif
</a>
底部修改
/resources/views/vendor/mail/html/message.blade.php
<x-mail::footer>
© {{ date('Y') }} {{ config('app.name') }}. @lang('版权所有')
</x-mail::footer>
最后,发送通知(邮件)
User::query()->find(1)->notify(new PasswordChangeMsg('cw', '1234', 'http://blog.cw.net/admin'));