• Laravel Vuejs 实战:开发知乎 (37-41)私信标为已读


    1.自定义MessageCollection类:

      1 <?php
      2 
      3 namespace App;
      4 
      5 use IlluminateDatabaseEloquentCollection;
      6 
      7 class MessageCollection extends Collection
      8 {
      9     public function markAsRead()
     10     {
     11         $this->each(function ($message) {
     12             $message->markAsRead();
     13         });
     14     }
     15 }
     16 
     17 
    MessageCollection.php

    2.向Message中添加一个newCollection方法:

      1 public function newCollection(array $models = [])
      2 {
      3     return new MessageCollection($models);
      4 }
      5 

    及markAsRead方法:

      1 public function markAsRead()
      2 {
      3     if (is_null($this->read_at)) {
      4         $this->forceFill(
      5             [
      6                 'read_at' => $this->freshTimestamp(),
      7             ])->save();
      8     }
      9 }
     10 
      1 <?php
      2 
      3 namespace App;
      4 
      5 use IlluminateDatabaseEloquentModel;
      6 
      7 class Message extends Model
      8 {
      9     //
     10 
     11     protected $table = 'messages';
     12 
     13     protected $fillable = ['from_user_id', 'to_user_id', 'content'];
     14 
     15     public function fromUser()
     16     {
     17         return $this->belongsTo(User::class, 'from_user_id');
     18     }
     19 
     20     public function toUser()
     21     {
     22         return $this->belongsTo(User::class, 'to_user_id');
     23     }
     24 
     25     public function markAsRead()
     26     {
     27         if (is_null($this->read_at)) {
     28             $this->forceFill(
     29                 [
     30                     'read_at' => $this->freshTimestamp(),
     31                 ])->save();
     32         }
     33     }
     34 
     35     public function newCollection(array $models = [])
     36     {
     37         return new MessageCollection($models);
     38     }
     39 }
     40 
     41 
    Message.php


    3.这样在InboxCollection.php中调用的时候:

      1 //设置信息已读
      2 $messages->markAsRead();
      3 

    即:

      1 public function show($userId)
      2 {
      3     if (auth()->user()->id == $userId) {
      4         return redirect()->back()->with('不能回复自己');
      5     }
      6     $messages = auth()->user()->messages->where('from_user_id', $userId);
      7 
      8     //设置信息已读
      9     $messages->markAsRead();
     10 
     11     //获取回复信息
     12     $replies = Message::query()->where('to_user_id', $userId)
     13         ->where('from_user_id', auth()->user()->id)
     14         ->get();
     15     if ($replies) {
     16         //整合
     17         foreach ($replies as $reply) {
     18             $messages->push($reply);
     19         }
     20     }
     21     //排序
     22     $messages = $messages->sortBy('created_at');
     23     return view('inbox.show', compact('messages'));
     24 }
     25 


    4.显示视图:

      1 @extends('layouts.app')
      2 @section('content')
      3     <div class="container">
      4         <div class="row">
      5             <div class="card">
      6                 @if($messages->first())
      7                     <div class="card-header">
      8                         <a href="#">
      9 
     10                             <img src="{{ $messages->first()->fromUser->avatar }}"
     11                                  alt="{{ $messages->first()->fromUser->name }}"
     12                                  class="img-thumbnail img-fluid card-img" style="height: 30px; 30px">
     13                             {{ $messages->first()->fromUser->name }}
     14 
     15                         </a>
     16                     </div>
     17                     <div class="card-body">
     18                         <div class="messaging">
     19                             <div class="inbox_msg">
     20 
     21                                 <div class="mesgs">
     22                                     <div class="msg_history">
     23                                         @forelse($messages as $message)
     24                                             @if($message->fromUser->id===auth()->user()->id)
     25                                                 <div class="outgoing_msg">
     26                                                     <div class="sent_msg">
     27                                                         @if($message->read_at)
     28                                                             <span class="text-black-50">已读</span>
     29                                                         @endif
     30                                                         <p> {{$message->content}}</p>
     31                                                         <span
     32                                                             class="time_date"> {{$message->created_at->diffForHumans()}}</span>
     33                                                     </div>
     34                                                 </div>
     35                                             @else
     36                                                 <div class="incoming_msg">
     37                                                     <div class="incoming_msg_img"><img
     38                                                             src="{{ $messages->first()->fromUser->avatar }}"
     39                                                             alt="{{ $messages->first()->fromUser->name }}">
     40                                                     </div>
     41                                                     <div class="received_msg">
     42                                                         <div class="received_withd_msg">
     43                                                             <p> {{$message->content}}</p>
     44                                                             <span
     45                                                                 class="time_date">  {{$message->created_at->diffForHumans()}}</span>
     46                                                         </div>
     47                                                     </div>
     48                                                 </div>
     49                                             @endif
     50                                         @empty
     51                                         @endforelse
     52                                     </div>
     53                                 </div>
     54                             </div>
     55                         </div>
     56                         <div class="type_msg mt-2">
     57                             <div class="input_msg_write">
     58                                 <form
     59                                     action="{{ route('inbox.store',($message->fromUser->id===auth()->user()->id)?$message->toUser->id:$message->fromUser->id) }}"
     60                                     method="post">
     61                                     @csrf
     62                                     <input type="text" class="write_msg" name="content" placeholder="输入信息回复"/>
     63                                     <button class="msg_send_btn" type="submit">
     64                                         <i class="fa fa-paper-plane-o"
     65                                            aria-hidden="true"></i>
     66                                     </button>
     67                                 </form>
     68                             </div>
     69                         </div>
     70                     </div>
     71                 @else
     72                     <div class="card-header">不好意思!找不到你要的数据!</div>
     73                 @endif
     74             </div>
     75         </div>
     76     </div>
     77 @endsection
     78 <style>
     79     .container {
     80         margin: auto;
     81     }
     82 
     83     img {
     84         max- 100%;
     85     }
     86 
     87     .inbox_people {
     88         background: #f8f8f8 none repeat scroll 0 0;
     89         float: left;
     90         overflow: hidden;
     91          40%;
     92         border-right: 1px solid #c4c4c4;
     93     }
     94 
     95     .inbox_msg {
     96         border: 1px solid #c4c4c4;
     97         clear: both;
     98         overflow: hidden;
     99     }
    100 
    101     .top_spac {
    102         margin: 20px 0 0;
    103     }
    104 
    105     .recent_heading {
    106         float: left;
    107          40%;
    108     }
    109 
    110     .srch_bar {
    111         display: inline-block;
    112         text-align: right;
    113          60%;
    114     }
    115 
    116     .recent_heading h4 {
    117         color: #05728f;
    118         font-size: 21px;
    119         margin: auto;
    120     }
    121 
    122     .srch_bar input {
    123         border: 1px solid #cdcdcd;
    124         border- 0 0 1px 0;
    125          80%;
    126         padding: 2px 0 4px 6px;
    127         background: none;
    128     }
    129 
    130     .srch_bar .input-group-addon button {
    131         background: rgba(0, 0, 0, 0) none repeat scroll 0 0;
    132         border: medium none;
    133         padding: 0;
    134         color: #707070;
    135         font-size: 18px;
    136     }
    137 
    138     .srch_bar .input-group-addon {
    139         margin: 0 0 0 -27px;
    140     }
    141 
    142     .chat_ib h5 {
    143         font-size: 15px;
    144         color: #464646;
    145         margin: 0 0 8px 0;
    146     }
    147 
    148     .chat_ib h5 span {
    149         font-size: 13px;
    150         float: right;
    151     }
    152 
    153     .chat_ib p {
    154         font-size: 14px;
    155         color: #989898;
    156         margin: auto
    157     }
    158 
    159     .chat_img {
    160         float: left;
    161          11%;
    162     }
    163 
    164     .chat_ib {
    165         float: left;
    166         padding: 0 0 0 15px;
    167          88%;
    168     }
    169 
    170     .chat_people {
    171         overflow: hidden;
    172         clear: both;
    173     }
    174 
    175     .chat_list {
    176         border-bottom: 1px solid #c4c4c4;
    177         margin: 0;
    178         padding: 18px 16px 10px;
    179     }
    180 
    181     .inbox_chat {
    182         height: 550px;
    183         overflow-y: scroll;
    184     }
    185 
    186     .active_chat {
    187         background: #ebebeb;
    188     }
    189 
    190     .incoming_msg_img {
    191         display: inline-block;
    192          6%;
    193     }
    194 
    195     .received_msg {
    196         display: inline-block;
    197         padding: 0 0 0 10px;
    198         vertical-align: top;
    199          92%;
    200     }
    201 
    202     .received_withd_msg p {
    203         background: #ebebeb none repeat scroll 0 0;
    204         border-radius: 3px;
    205         color: #646464;
    206         font-size: 14px;
    207         margin: 0;
    208         padding: 5px 10px 5px 12px;
    209          100%;
    210     }
    211 
    212     .time_date {
    213         color: #747474;
    214         display: block;
    215         font-size: 12px;
    216         margin: 8px 0 0;
    217     }
    218 
    219     .received_withd_msg {
    220          57%;
    221     }
    222 
    223     .mesgs {
    224         float: left;
    225         padding: 30px 15px 0 25px;
    226          60%;
    227     }
    228 
    229     .sent_msg p {
    230         background: #05728f none repeat scroll 0 0;
    231         border-radius: 3px;
    232         font-size: 14px;
    233         margin: 0;
    234         color: #fff;
    235         padding: 5px 10px 5px 12px;
    236          100%;
    237     }
    238 
    239     .outgoing_msg {
    240         overflow: hidden;
    241         margin: 26px 0 26px;
    242     }
    243 
    244     .sent_msg {
    245         float: right;
    246          46%;
    247     }
    248 
    249     .input_msg_write input {
    250         background: rgba(0, 0, 0, 0) none repeat scroll 0 0;
    251         border: medium none;
    252         color: #4c4c4c;
    253         font-size: 15px;
    254         min-height: 48px;
    255          100%;
    256     }
    257 
    258     .type_msg {
    259         border-top: 1px solid #c4c4c4;
    260         position: relative;
    261     }
    262 
    263     .msg_send_btn {
    264         background: #05728f none repeat scroll 0 0;
    265         border: medium none;
    266         border-radius: 50%;
    267         color: #fff;
    268         cursor: pointer;
    269         font-size: 17px;
    270         height: 33px;
    271         position: absolute;
    272         right: 0;
    273         top: 11px;
    274          33px;
    275     }
    276 
    277     .msg_history {
    278         height: 516px;
    279         overflow-y: auto;
    280     }
    281 </style>
    282 
    283 
    show.blade.php

    效果:

    批注 2020-03-04 134815

    5.添加新的未读消息加特效:

    当前状态:

    批注 2020-03-04 135048

    代码:

      1 @extends('layouts.app')
      2 @section('content')
      3     <div class="container">
      4         <div class="row">
      5             <div class="card">
      6                 <div class="card-header">
      7                     @if($messages->filter(function ($value, $key){
      8                         return $value->where('read_at',null)->count()>0;})->count()>0)
      9                         <div class="alert alert-danger">
     10                             你有新的消息!
     11                         </div>
     12                     @endif
     13                 </div>
     14                 <div class="card-body">
     15 
     16                     @forelse($messages as $messageGroup)
     17                         <div class="card">
     18                             <div class="card-header">
     19                                 <a href="#">
     20                                     <img src="{{ $messageGroup->first()->fromUser->avatar }}"
     21                                          alt="{{ $messageGroup->first()->fromUser->name }}"
     22                                          class="img-thumbnail img-fluid card-img" style="height: 30px; 30px">
     23                                     {{ $messageGroup->first()->fromUser->name }}
     24                                 </a>
     25                             </div>
     26                             <div class="card-body">
     27                                 <p class="text-success "> 查看详细对话请点击:</p>
     28                                 @if($messageGroup->where('read_at',null)->count()>0)
     29                                     <p class="alert alert-warning">{{$messageGroup->where('read_at',null)->count()}}
     30                                         条未读消息</p>
     31                                 @endif
     32                                 <a href=" {{ route('inbox.show', $messageGroup->first()->fromUser->id) }}"
     33                                    class="btn btn-block bg-light"> {{ $messageGroup->first()->content }}</a>
     34                             </div>
     35                         </div>
     36                     @empty
     37                     @endforelse
     38                 </div>
     39             </div>
     40         </div>
     41     </div>
     42 @endsection
     43 
     44 
    index.blade.php


    修改后:

    批注 2020-03-04 140701批注 2020-03-04 140758批注 2020-03-04 140919

    修复 bug 和实现 Repository 模式:

    我的代码没有那个bug。其次我这不实现Repository 模式


    6.实现私信通知:

    当用户收到新的私信的时候,发送一个通知告知用户。

    执行:

      1 php artisan make:notification NewMessageNotification

    代码:

    暂时只实现站内通知,

      1 <?php
      2 
      3 namespace AppNotifications;
      4 
      5 use AppMessage;
      6 use IlluminateBusQueueable;
      7 use IlluminateContractsQueueShouldQueue;
      8 use IlluminateNotificationsMessagesMailMessage;
      9 use IlluminateNotificationsNotification;
     10 
     11 class NewMessageNotification extends Notification
     12 {
     13     use Queueable;
     14     /**
     15      * @var Message
     16      */
     17     private $message;
     18 
     19     /**
     20      * Create a new notification instance.
     21      *
     22      * @return void
     23      */
     24     public function __construct(Message $message)//使用依赖注入
     25     {
     26         //
     27         $this->message = $message;
     28     }
     29 
     30     /**
     31      * Get the notification's delivery channels.
     32      *
     33      * @param mixed $notifiable
     34      * @return array
     35      */
     36     public function via($notifiable)
     37     {
     38         return ['database'];
     39     }
     40 
     41     /**
     42      * Get the mail representation of the notification.
     43      *
     44      * @param mixed $notifiable
     45      * @return IlluminateNotificationsMessagesMailMessage
     46      */
     47     public function toMail($notifiable)
     48     {
     49         return (new MailMessage)
     50             ->line('The introduction to the notification.')
     51             ->action('Notification Action', url('/'))
     52             ->line('Thank you for using our application!');
     53     }
     54 
     55     /**
     56      * Get the array representation of the notification.
     57      *
     58      * @param mixed $notifiable
     59      * @return array
     60      */
     61     public function toArray($notifiable)
     62     {
     63         return [
     64             //
     65         ];
     66     }
     67 
     68 
     69     /**
     70      * @param $notifiable
     71      * @return array
     72      */
     73     public function toDatabase($notifiable)
     74     {
     75         //要记录的数据
     76         return [
     77             'fromUser' => $this->message->fromUser->name,
     78             'id' => $this->message->fromUser->id,
     79             'content' => $this->message->content,
     80         ];
     81     }
     82 }
     83 
     84 
    NewMessageNotification.php

    添加:

      1 //发送通知
      2 $message
      3     ->toUser //通知接受方,所以是toUser
      4     ->notify(new NewMessageNotification($message));//用户类使用了Notifiable这个 trait
      5 
    到:
      1 <?php
      2 
      3 namespace AppHttpControllers;
      4 
      5 use AppMessage;
      6 
      7 use AppNotificationsNewMessageNotification;
      8 use IlluminateHttpRequest;
      9 use IlluminateSupportFacadesNotification;
     10 
     11 
     12 class InboxController extends Controller
     13 {
     14     public function __construct()
     15     {
     16         $this->middleware('auth');
     17     }
     18 
     19     //
     20     public function index()
     21     {
     22         $messages = auth()->user()->messages->groupBy('from_user_id');
     23 //        $messages->map(function ($message) {
     24 //            return $message->map(function ($item) {
     25 ////                return $item->with('user');
     26 //                return $item->fromUser;
     27 //            });
     28 //        });
     29         return view('inbox.index', compact('messages'));
     30     }
     31 
     32     public function show($userId)
     33     {
     34         if (auth()->user()->id == $userId) {
     35             return redirect()->back()->with('不能回复自己');
     36         }
     37         $messages = auth()->user()->messages->where('from_user_id', $userId);
     38 
     39         //设置信息已读
     40         $messages->markAsRead();
     41 
     42         //获取回复信息
     43         $replies = Message::query()->where('to_user_id', $userId)
     44             ->where('from_user_id', auth()->user()->id)
     45             ->get();
     46         if ($replies) {
     47             //整合
     48             foreach ($replies as $reply) {
     49                 $messages->push($reply);
     50             }
     51         }
     52         //排序
     53         $messages = $messages->sortBy('created_at');
     54         return view('inbox.show', compact('messages'));
     55     }
     56 
     57     public function store(Request $request, $userId)
     58     {
     59 
     60         if (auth()->user()->id == $userId) {
     61             return redirect()->back()->with('不能回复自己');
     62         }
     63         $message = Message::create(
     64             [
     65                 'from_user_id' => auth()->user()->id,
     66                 'to_user_id' => $userId,
     67                 'content' => $request->get('content')
     68             ]
     69         );
     70 
     71         //发送通知
     72         $message
     73             ->toUser //通知接受方,所以是toUser
     74             ->notify(new NewMessageNotification($message));//用户类使用了Notifiable这个 trait
     75 
     76         return redirect()->route('inbox.show', $userId)->with('success', '发送成功');
     77     }
     78 }
     79 
     80 
    InboxController

    view添加:

    new_message_notification.blade.php:

      1 <li class="badge badge-light text-primary">
      2     <p> "你好!"
      3         <a href="{{ route('inbox.show',$notification->data['id']) }}">
      4             {{ $notification->data['fromUser']."给你发来了新私信:" }}
      5         </a>
      6     </p>
      7     <p>  {{ $notification->data['content'] }} </p>
      8 </li>
      9 
     10 

    7.设置通知已读:

      1 <?php
      2 
      3 namespace AppHttpControllers;
      4 
      5 use AppUser;
      6 use IlluminateHttpRequest;
      7 
      8 class NotificationController extends Controller
      9 {
     10     //
     11     public function index()
     12     {
     13         $user = auth()->user();
     14 
     15         //设置已读字段数据
     16         $user->notifications->map(function ($notification) {
     17             $notification->forceFill([
     18                 'read_at' => now(),
     19             ])->save();
     20         });
     21         return view('notifications.index', compact('user'));
     22     }
     23 }
     24 
     25 
    NotificationController.php


    视图:略

  • 相关阅读:
    这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)2
    这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)2
    这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)2
    这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)1
    这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)1
    这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)1
    python-函数和函数式编程
    Python错误与异常
    IO系统-文件与目录操作
    IO系统-标准C的I/O和文件I/O
  • 原文地址:https://www.cnblogs.com/dzkjz/p/12409051.html
Copyright © 2020-2023  润新知