Laravel Vuejs 实战:开发知乎 (28-29)私信功能

1.数据库迁移:

  1 php artisan make:model Message –m

****_create_messages_table:

  1 <?php
  2 
  3 use IlluminateDatabaseMigrationsMigration;
  4 use IlluminateDatabaseSchemaBlueprint;
  5 use IlluminateSupportFacadesSchema;
  6 
  7 class CreateMessagesTable extends Migration
  8 {
  9     /**
 10      * Run the migrations.
 11      *
 12      * @return void
 13      */
 14     public function up()
 15     {
 16         Schema::create('messages', function (Blueprint $table) {
 17             $table->bigIncrements('id');
 18             $table->unsignedBigInteger('from_user_id')->comment("发送私信的用户的id");
 19             $table->unsignedBigInteger('to_user_id')->comment("接受私信的用户的id");
 20             $table->text('content')->comment("私信的内容");
 21             $table->timestamp('read_at')->nullable()->comment("接收方阅读的时间");
 22             $table->timestamps();
 23         });
 24     }
 25 
 26     /**
 27      * Reverse the migrations.
 28      *
 29      * @return void
 30      */
 31     public function down()
 32     {
 33         Schema::dropIfExists('messages');
 34     }
 35 }
 36 
 37 
CreateMessagesTable

2.模型关联:

Message.php

  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 
 26 
Message.php

User.php

  1 <?php
  2 
  3 namespace App;
  4 
  5 use AppModelsQuestion;
  6 use IlluminateContractsAuthMustVerifyEmail;
  7 use IlluminateDatabaseEloquentSoftDeletes;
  8 use IlluminateFoundationAuthUser as Authenticatable;
  9 use IlluminateNotificationsNotifiable;
 10 
 11 class User extends Authenticatable implements MustVerifyEmail
 12 {
 13     use Notifiable;
 14     #region 支持软删除
 15     use SoftDeletes;
 16     protected $dates = ['deleted_at'];
 17     #endregion
 18     /**
 19      * The attributes that are mass assignable.
 20      *
 21      * @var array
 22      */
 23     protected $fillable = [
 24         'name', 'email', 'password', 'avatar', 'activation_token', 'api_token'
 25     ];
 26 
 27     /**
 28      * The attributes that should be hidden for arrays.
 29      *
 30      * @var array
 31      */
 32     protected $hidden = [
 33         'password', 'remember_token',
 34     ];
 35 
 36     /**
 37      * The attributes that should be cast to native types.
 38      *
 39      * @var array
 40      */
 41     protected $casts = [
 42         'email_verified_at' => 'datetime',
 43     ];
 44 
 45 
 46     /**添加用户模型和问题模型的模型关联
 47      * @return IlluminateDatabaseEloquentRelationsHasMany
 48      */
 49     public function questions()
 50     {
 51         return $this->hasMany(Question::class);
 52     }
 53 
 54 
 55     /** 添加用户模型和回答模型的模型关联 一个用户可以有多个回答
 56      * @return IlluminateDatabaseEloquentRelationsHasMany
 57      */
 58     public function answers()
 59     {
 60         return $this->hasMany(Answer::class);
 61     }
 62 
 63 
 64     public function followQuestions()
 65     {
 66         //默认表名 可以不设置后面三个参数,自定义表名需要设置
 67         return $this->belongsToMany(Question::class, 'users_questions', 'question_id', 'user_id')->withTimestamps();
 68     }
 69 
 70 
 71     /** 用户的粉丝
 72      * @return IlluminateDatabaseEloquentRelationsBelongsToMany
 73      */
 74     public function followers()
 75     {
 76 
 77         return $this->belongsToMany
 78         (
 79             self::class,
 80             'followers',
 81             'user_id', //foreignPivotKey:当前模型在中间表的字段(当前模型类的外键) //【当前模型是leader】的外键id
 82             'follower_id'//relatedPivotKey:另一模型在中间表的字段(另一模型类的外键)
 83         )->withTimestamps();
 84     }
 85 
 86 
 87     /** 用户关注的作者
 88      * @return IlluminateDatabaseEloquentRelationsBelongsToMany
 89      */
 90     public function followings()
 91     {
 92         return $this->belongsToMany
 93         (
 94             self::class,
 95             'followers',
 96             'follower_id',//foreignPivotKey:当前模型在中间表的字段(当前模型类的外键) //【当前模型是粉丝】的外键id
 97             'user_id'//relatedPivotKey:另一模型在中间表的字段(另一模型类的外键)
 98         )
 99             ->withTimestamps();
100     }
101 
102 
103     /**
104      * @return IlluminateDatabaseEloquentRelationsBelongsToMany
105      */
106     public function votes()
107     {
108         return $this->belongsToMany(Answer::class, 'votes')->withTimestamps();
109     }
110 
111 
112     /**
113      * @param $answer_id
114      * @return array
115      */
116     public function voteAnswer($answer_id)
117     {
118         return $this->votes()->toggle($answer_id);
119     }
120 
121 
122     public function messages()
123     {
124         return $this->hasMany(Message::class, 'to_user_id');
125     }
126 
127 
128 }
129 
130 
User.php

3.执行迁移

  1 php artisan migrate

4.view层 vue

参考: PersonalAccessTokens.vue

vue层:【要点击按钮弹出一个对话框,点击发送按钮,发送数据】

  1 <template>
  2     <div>
  3         <button class="btn btn-sm btn-secondary ml-2"
  4                 @click="showMessageForm">私信
  5         </button>
  6 
  7         <div class="modal fade" id="model-send-message" tabindex="-1" role="dialog">
  8             <div class="modal-dialog">
  9                 <div class="modal-content">
 10                     <div class="modal-header">
 11                         <h4 class="modal-title">
 12                             编辑并发送私信
 13                         </h4>
 14                         <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
 15                     </div>
 16 
 17                     <div class="modal-body">
 18                         <textarea class="form-control" rows="10" v-model="message" v-if="!success"></textarea>
 19                         <div class="alert alert-success" v-if="success">私信发送成功!</div>
 20                     </div>
 21 
 22                     <!-- Modal Actions -->
 23                     <div class="modal-footer">
 24                         <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
 25                         <button type="button" class="btn btn-success" @click="send" v-if="!success">发送</button>
 26                     </div>
 27                 </div>
 28             </div>
 29         </div>
 30     </div>
 31 </template>
 32 
 33 <script>
 34     export default {
 35         props: ['user'],
 36         name: "SendMessage",
 37         data() {
 38             return {
 39                 voteable: true,
 40                 message: '',
 41                 success: false,
 42             }
 43         },
 44         computed: {},
 45         mounted: function () {
 46 
 47         },
 48         methods: {
 49             send() {
 50                 let currentObj = this;
 51                 axios.post('/api/messages/send', {'user': this.user, 'message': this.message})
 52                     .then(function (response) {
 53                             currentObj.message = '';
 54                             currentObj.success = response.data.success;
 55                             //两秒钟后关闭弹窗
 56                             if (currentObj.success) {
 57                                 setTimeout(function () {
 58                                     $('#model-send-message').modal('hide');
 59                                 }, 2000);
 60                             }
 61                         }
 62                     )
 63                     .catch(function (e) {
 64                         console.log(e);
 65                     });
 66             },
 67             showMessageForm() {
 68                 $('#model-send-message').modal('show');//显示发送编辑框
 69             }
 70         }
 71     }
 72 </script>
 73 
 74 <style scoped>
 75 
 76 </style>
 77 
 78 
SendMessage.vue
  1 <div>
  2     <img src="{{ $userable->user->avatar }}" class="card-img img-thumbnail imgWrap "
  3          style=" 50px" alt="{{ $userable->user->name }}">
  4     <span class="text text-info">{{ $userable->user->name }}</span>
  5 </div>
  6 <div class="float-left mt-2">
  7     <user-follow-button user="{{ $userable->user->id }}"user->id }}"></user-follow-button>
  8     @if(auth()->check())
  9         @if(auth()->user()->id!==$userable->user->id)
 10             <div class="float-right">
 11                 <send-message user="{{ $userable->user->id }}"user->id }}"></send-message>
 12             </div>
 13         @endif
 14     @endif
 15 </div>
 16 
 17 
_small_icon.blade.php

路由:

  1 <?php
  2 
  3 use IlluminateHttpRequest;
  4 
  5 /*
  6 |--------------------------------------------------------------------------
  7 | API Routes
  8 |--------------------------------------------------------------------------
  9 |
 10 | Here is where you can register API routes for your application. These
 11 | routes are loaded by the RouteServiceProvider within a group which
 12 | is assigned the "api" middleware group. Enjoy building your API!
 13 |
 14 */
 15 
 16 Route::middleware('auth:api')->get('/user', function (Request $request) {
 17     return $request->user();
 18 });
 19 
 20 Route::middleware('api')->get('/topics', function (Request $request) {
 21     $query = $request->query('q');
 22     return AppTopic::query()->where('name', 'like', '%' . $query . '%')->get();
 23 });
 24 #region 问题关注
 25 //加载页面时取关注状态
 26 Route::middleware('auth:api')->post('/questions/follow/stats', 'QuestionController@getFollowStats');
 27 //执行关注/取关操作
 28 Route::middleware('auth:api')->post('/questions/follow', 'QuestionController@followThroughApi');
 29 #endregion
 30 
 31 #region 用户关注
 32 //加载页面时取关注状态
 33 Route::middleware('auth:api')->post('/users/follow/stats', 'FollowerController@getFollowStats');
 34 //执行关注/取关操作
 35 Route::middleware('auth:api')->post('/users/follow', 'FollowerController@followThroughApi');
 36 
 37 #endregion
 38 
 39 
 40 #region
 41 //加载页面时取赞状态
 42 Route::middleware('auth:api')->post('/answers/vote/stats', 'VoteController@getVoteStats');
 43 //执行赞/取消赞操作
 44 Route::middleware('auth:api')->post('/answers/vote/up', 'VoteController@voteUpThroughApi');
 45 #endregion
 46 
 47 
 48 #region
 49 
 50 Route::middleware('auth:api')->post('/messages/send', 'MessageController@store');
 51 
 52 #endregion
 53 
 54 
api.php

控制器:

  1 php artisan make:controller MessageController

  1 <?php
  2 
  3 namespace AppHttpControllers;
  4 
  5 use AppMessage;
  6 use AppUser;
  7 use IlluminateHttpRequest;
  8 
  9 class MessageController extends Controller
 10 {
 11     //
 12 
 13     public function __construct()
 14     {
 15         $this->middleware('auth');
 16     }
 17 
 18     public function store(Request $request)
 19     {
 20         $toUser = $request->get('user');
 21 
 22         $currentUser = auth()->user()->id;
 23 
 24         $content = $request->get('message');
 25 
 26         if ($content) {
 27             $data = [
 28                 'from_user_id' => $currentUser,
 29                 'to_user_id' => $toUser,
 30                 'content' => $content,
 31             ];
 32             $message = Message::create($data);
 33             if ($message) {
 34                 return response()->json(['success' => true]);
 35             }
 36         }
 37         return response()->json(['success' => false]);
 38     }
 39 }
 40 
 41 
MessageController.php

原文地址:https://www.cnblogs.com/dzkjz/p/12402317.html