为你的论坛系统添加一个『提及』功能 
                                                    
                        
                    
                    
  
                    
                    背景
在论坛系统中,提及用户 是一个很常见的功能,也就是我们常说的@
例如:在learnku的回帖功能中我们可以看到,键入@会自动输出你已关注的用户列表,回帖成功后,被提及用户将受到一条通知

回帖完成后,被@用户将会收到一条消息通知。今天,我们将为larabbs来添加这一功能
修改数据模型
我们可以使用正则表达式,来匹配用户回复内容中提及的一个或多个用户。我们需要修改下 Reply 模型。
修改文件为以下:
app/Models/Reply.php
<?php
namespace App\Models;
class Reply extends Model
{
    .
    .
    .
    public function mentionedUsers()
    {
        preg_match_all('/@([\w\-]+)/', $this->content, $matches);
        return $matches[1];
    }
}生成通知类
$ php artisan make:notification UserMentioned修改文件为以下:
app/Notifications/UserMentioned.php
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use App\Models\Reply;
class UserMentioned extends Notification
{
    use Queueable;
    public $reply;
    public function __construct(Reply $reply)
    {
        // 注入回复实体,方便 toDatabase 方法中的使用
        $this->reply = $reply;
    }
    public function via($notifiable)
    {
        // 开启通知的频道
        return ['database'];
    }
    public function toDatabase($notifiable)
    {
        $topic = $this->reply->topic;
        $link =  $topic->link(['#reply' . $this->reply->id]);
        // 存入数据库里的数据
        return [
            'reply_id' => $this->reply->id,
            'reply_content' => $this->reply->content,
            'user_id' => $this->reply->user->id,
            'user_name' => $this->reply->user->name,
            'user_avatar' => $this->reply->user->avatar,
            'topic_link' => $link,
            'topic_id' => $topic->id,
            'topic_title' => $topic->title,
        ];
    }
}触发通知
我们希望当用户回复主题后,通知到被提及用户。故触发通知的时机是:『回复发布成功后』,在模型监控器里,我们可以在 created 方法里实现此部分代码,修改 created() 方法为以下:
app/Observers/ReplyObserver.php
<?php
.
.
.
use App\Models\User;
use App\Notifications\UserMentioned;
class ReplyObserver
{
    public function created(Reply $reply)
    {
        .
        .
        .
        // 通知被提及用户
        User::whereIn('name', $reply->mentionedUsers())
            ->get()
            ->each(function ($user) use ($reply) {
                $user->notify(new UserMentioned($reply));
            });
    }
    .
    .
    .
}创建通知模板
创建此文件:
resources/views/notifications/types/_user_mentioned.blade.php
<li class="media @if ( ! $loop->last) border-bottom @endif">
  <div class="media-left">
    <a href="{{ route('users.show', $notification->data['user_id']) }}">
      <img class="media-object img-thumbnail mr-3" alt="{{ $notification->data['user_name'] }}" src="{{ $notification->data['user_avatar'] }}" style="width:48px;height:48px;" />
    </a>
  </div>
  <div class="media-body">
    <div class="media-heading mt-0 mb-1 text-secondary">
      <a href="{{ route('users.show', $notification->data['user_id']) }}">{{ $notification->data['user_name'] }}</a>
      在
      <a href="{{ $notification->data['topic_link'] }}">{{ $notification->data['topic_title'] }}</a>
      的评论中提及了你
      <span class="meta float-right" title="{{ $notification->created_at }}">
        <i class="far fa-clock"></i>
        {{ $notification->created_at->diffForHumans() }}
      </span>
    </div>
    <div class="reply-content">
      {!! $notification->data['reply_content'] !!}
    </div>
  </div>
</li>至此,提及用户 功能开发完毕
本作品采用《CC 协议》,转载必须注明作者和本文链接
 
           pigzzz 的个人博客
 pigzzz 的个人博客
         
             
             
             
                     
                     
             
           
           关于 LearnKu
                关于 LearnKu
               
                     
                     
                     粤公网安备 44030502004330号
 粤公网安备 44030502004330号 
 
推荐文章: