【问题标题】:How to show an alert message to a user with Event Listener如何使用事件侦听器向用户显示警报消息
【发布时间】:2021-08-11 07:05:51
【问题描述】:

我创建了一个名为 UserWalletNewTransaction.php 的事件并将其添加到其中:

public $transaction;

public function __construct($transaction) {
    $this->$transaction = $transaction;
}

现在为了在控制器上触发这个事件,我编写了这样的代码:

$newTransaction = UserWalletTransaction::create(['user_id' => $user_id, 'wallet_id' => $wallet_id, 'creator_id' => $creator_id, 'amount' => $amount_add_value, 'description' => $trans_desc]);

event(new UserWalletNewTransaction($newTransaction));

然后在 Listener,UserWalletNotification.php,我尝试了:

public function handle(UserWalletNewTransaction $event) {
    $uid = $event->transaction->user_id;
    $user = User::find($uid);
    // now sends alert message to the user
}

所以场景是,当管理员为自定义用户创建新事务时,必须为他/她发送新的警报消息,让他/她知道为他/她添加了新事务。

但我真的不知道该怎么做。所以如果你知道,请告诉我,我将非常感激...

提前致谢。

【问题讨论】:

  • alert message 是什么意思?应该是电子邮件还是其他?

标签: php laravel laravel-5.8


【解决方案1】:

如果警报是指在 Web 界面上显示消息,请使用 Flash 数据。

https://laravel.com/docs/5.8/session#flash-data

$newTransaction = UserWalletTransaction::create(...);

event(new UserWalletNewTransaction($newTransaction));

$request->session()->flash('status', 'Transaction done.');

return view(...)
<span>{{ session('status') }}</span>

如果您的意思是发送电子邮件,只需在侦听器中使用 Mail 外观即可发送可邮寄邮件。

https://laravel.com/docs/5.8/mail#sending-mail

public function handle(UserWalletNewTransaction $event) {
    $uid = $event->transaction->user_id;
    $user = User::find($uid);

    Mail::to($user)->send(new TransactionDoneMail($event->transaction)); // TransactionDoneMail being your mailable class, made with "php artisan make:email TransactionDoneMail"
}

文档中有关于如何构建可邮寄类的很好的示例。

https://laravel.com/docs/5.8/mail#writing-mailables

【讨论】:

  • 警报仅针对管理员为其提交交易的网站用户。我需要在侦听器中执行此操作,而不是在控制器中。控制器用于网站的管理员,我不想将管理员重定向到用户的视图。我只需要通知用户他有一个新的交易。
  • @tejoslaeslio 这是不可能的,你需要做这个前端,因为你可以使用 pusher,laravel echo 设置起来非常简单pusher.com
【解决方案2】:

在“提醒”客户方面,您可以做很多不同的事情。

一种方法是在您的事件侦听器中发送电子邮件或短信。请参阅https://laravel.com/docs/5.8/mail 以通过电子邮件获得帮助。

另一种方法是使用浏览器推送通知。您可以为此使用OneSignal。您将设置前端向客户用户显示警报,询问他们是否要订阅推送通知。当他们订阅时,您将获得该特定用户的 ID。对您的 Laravel 应用程序进行 API 调用,并将该 ID 存储在 users 表中(您将需要迁移)。然后在您的事件监听器中,您可以调用 OneSignal 的 API 并向用户发送通知,该通知将在他们的计算机上弹出。

以下是使用 OneSignal 通过 API 向用户发送事件的示例:

您的 OneSignal 服务:

<?php

namespace App\Services;

use App\User;
use GuzzleHttp\Client;

class OneSignalService
{
    public function sendNotificationToUser(User $user, string $title, string $message, string $url, string $subtitle = null)
    {
        if (!$user->one_signal_id) {
            return;
        }
        $fields = [
            'app_id' => config('services.onesignal.app_id'),
            'include_player_ids' => [$user->one_signal_id],
            'headings' => ['en' => $title],
            'contents' => ['en' => $message],
            'url' => $url,
        ];
        if ($subtitle) {
            $fields['subtitle'] = ['en' => $subtitle];
        }
        $client = new Client([
            'base_uri' => 'https://onesignal.com/api/v1/',
            'headers' => [
                'Content-Type' => 'application/json; charset=utf-8',
                'Authorization' => 'Basic <<API_KEY>>',
            ]
        ]);
        $client->request('POST', 'notifications', [
            'json' => $fields
        ])
    }
}

用户钱包通知:

public function handle(UserWalletNewTransaction $event) {
    $uid = $event->transaction->user_id;
    $user = User::find($uid);
    // now sends alert message to the user
    $oneSignal = new OneSignalService();
    $oneSignal->sendNotificationToUser($user, 'New Transaction', 'You have a new transaction', 'yourwebsite.com');
}

我将通过broadcasting 解决此问题,它会使用 websockets 立即向客户用户发送警报到他们的浏览器,然后您可以在其中显示某种弹出窗口。您可以安装Laravel Echo Server,但为了简单起见,您可以使用Pusher。按照指南安装在您网站的前端。

然后,创建一个特定于客户用户“transaction.created.{{USER ID}}”的私人频道并在您的前端监听它。

在 Laravel 中,您将通过 composer 安装 PHP Pusher SDK

然后在您的 .env 文件集中:

BROADCAST_DRIVER=pusher

接下来,在 Laravel 的 routes 目录中打开 channels.php 并添加:

Broadcast::channel('transaction.created.{id}', function ($user, $id) {
    return (int) $user->id === (int) $id;
});

这将验证您的用户对私人频道的身份验证。

创建一个 Laravel 事件:

<?php

namespace App\Events;

use App\User;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class TransactionCreated implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $user = null;
    public $transaction = null;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(User $user, UserWalletTransaction $transaction)
    {
        $this->user = $user;
        $this->transaction = $transaction;
    }

    public function broadcastWith(): array
    {
        return $this->transaction->toArray(); //Or whatever information you want to send to the front end
    }

    public function broadcastAs(): string
    {
        return 'TransactionCreated';
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('transaction.created.' . $this->user->id);
    }
}

从 UserWalletNotification 触发事件:

public function handle(UserWalletNewTransaction $event) {
    $uid = $event->transaction->user_id;
    $user = User::find($uid);
    // now sends alert message to the user
    event(new TransactionCreated($user, $event->transaction));
}

最后,创建某种弹出窗口并在调用私人频道的回调函数时将其显示在前端。

如果您需要更多帮助,请随时发表评论。

【讨论】:

    【解决方案3】:

    我相信你想做的是异步通知

    好吧,如果你真的指的是闪存消息——那些存储在会话中的消息——就不会那么容易了。

    正常步骤是为当前登录网站的用户创建闪存消息,存储在当前用户唯一的会话中。只能针对该用户显示。

    您想要以管理员身份创建 Flash 消息(从管理员的角度来看),然后只能向管理员显示。

    我会这样做,创建新表,何时存储这些通知消息。一些带有id, user_id, message, type, created_date, shown_date 等列的表。管理员将为每个用户放置警报/通知消息。然后创建将为每个用户检查此表的类(例如可以在控制器中),如果有新的尚未显示的消息,则在该当前用户的闪存消息中正常显示它。不要忘记标记该消息,如图所示。就是这样。

    自定义解决方案就这么多。我相信必须有一些用于异步通知的例如 jQuery/其他 Jvascript 插件或 Laravel 插件,请检查这些。

    【讨论】:

      猜你喜欢
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-27
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 2019-05-23
      相关资源
      最近更新 更多