1 创建表
php artisan make:model Vote -m
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public function up() { Schema::create('votes', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedInteger('user_id')->index(); $table->unsignedInteger('answer_id')->index(); $table->timestamps(); }); }
php artisan migrate
2 代码
2.1 appUser.php
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public function votes() { return $this->belongsToMany(Answer::class,'votes') ->withTimestamps(); } public function voteFor($answer) { return $this->votes()->toggle($answer); } public function hasVotedFor($answer) { return !! $this->votes()->where('answer_id',$answer)->count(); }
2.2 esourcesjscomponentsUserVoteButton.vue
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<template> <button class="btn btn-default" v-text="text" v-on:click.prevent="vote" v-bind:class="{'btn-success':voted}"> </button> </template> <script> export default { name: "UserVoteButton", props:['answer','count'], // mounted是vue中的一个钩子函数,一般在初始化页面完成后,再对dom节点进行相关操作 mounted(){ axios.post('/api/answer/' + this.answer+'/votes/users').then(res => { this.voted = res.data.voted console.log(res.data); },error => { console.log(error); //console.log(error.response.status) if(error.response.status==401){ this.auth = false } }) }, data(){ return { voted:false , auth:true , count2:this.count } }, computed:{ text(){ return this.count2 } }, methods:{ vote(){ axios.post('/api/answer/vote',{'answer':this.answer}).then(res => { this.voted = res.data.voted res.data.voted ? this.count2++ : this.count2-- console.log(res.data) }) } } } </script> <style scoped> </style>
2.3 appRepositoriesAnswerRepository.php
public function GetAnswerById($id) { return Answer::find($id); }
2.4 appHttpControllersApiVotesController.php
php artisan make:controller Api/VotesController
<?php namespace AppHttpControllersApi; use IlluminateHttpRequest; use IlluminateSupportFacadesAuth; use AppHttpControllersController; use AppRepositoriesAnswerRepository; class VotesController extends Controller { /** * 答案仓库 */ protected $answer; /** * 初始化 */ public function __construct(AnswerRepository $answer) { $this->answer = $answer; } // public function users($id) { $user = Auth::guard('api')->user(); if($user->hasVotedFor($id)){ return response()->json(['voted'=>true]); } return response()->json(['voted'=>false]); } public function vote(Request $request) { $answer = $this->answer->GetAnswerById($request->get('answer')); $voted = Auth::guard('api')->user()->voteFor($request->get('answer')); if(count($voted['attached']) > 0){ $answer->increment('votes_count'); // 作者被关注 return response()->json(['voted'=>true]); } $answer->decrement('votes_count'); // 取消作者被关注 return response()->json(['voted'=>false]); } }
2.5 esourcesjsapp.js
Vue.component('user-vote-button', require('./components/UserVoteButton'));
2.6 outesapi.php
// 点赞答案接口 Route::post('/answer/{id}/votes/users','ApiVotesController@users'); Route::post('/answer/vote','ApiVotesController@vote');
2.7 esourcesviewsquestionsshow.blade.php
<user-vote-button answer="{{$answer->id}}" count="{{$answer->votes_count}}"></user-vote-button>