如何在Laravel Livewire评分系统中限制仅购买过商品的买家可评价
实现仅购买过商品的用户可评价的修改方案
步骤1:修改Livewire组件类 ProductRatings.php
改动点说明:
- 新增权限判断属性
$canReview - 登录时自动校验用户是否有当前商品的已完成订单
- 提交评价接口新增权限校验,防止绕过前端直接请求
完整修改后代码:
class ProductRatings extends Component { public $rating; public $comment; public $currentId; public $product; public $hideForm; // 新增:是否有权限评价的标识 public $canReview = false; protected $rules = [ 'rating' => ['required', 'in:1,2,3,4,5'], 'comment' => 'required', ]; public function render() { $comments = Rating::where('product_id', $this->product->id)->where('status', 1)->with('user')->get(); return view('livewire.product-ratings', compact('comments')); } public function mount() { if (auth()->user()) { // 原有已评价逻辑保留 $rating = Rating::where('user_id', auth()->user()->id)->where('product_id', $this->product->id)->first(); if (!empty($rating)) { $this->rating = $rating->rating; $this->comment = $rating->comment; $this->currentId = $rating->id; } // 新增:判断是否有当前商品的已完成订单 // 请将下面的status条件值替换为你业务中「订单完成」对应的状态值 // 若你没有单独的订单项表,product_id直接存在eorders表,可删除whereHas部分,直接加where('product_id', $this->product->id) $this->canReview = Eorder::where('user_id', auth()->user()->id) ->where('status', 'completed') ->whereHas('orderItems', function ($query) { $query->where('product_id', $this->product->id); }) ->exists(); } return view('livewire.product-ratings'); } public function delete($id) { $rating = Rating::where('id', $id)->first(); if ($rating && ($rating->user_id == auth()->user()->id)) { $rating->delete(); } if ($this->currentId) { $this->currentId = ''; $this->rating = ''; $this->comment = ''; } } public function rate() { // 新增:后端权限校验,防止绕过前端直接提交 if (!$this->canReview) { abort(403, '您无权评价该商品'); } $rating = Rating::where('user_id', auth()->user()->id)->where('product_id', $this->product->id)->first(); $this->validate(); if (!empty($rating)) { $rating->user_id = auth()->user()->id; $rating->product_id = $this->product->id; $rating->rating = $this->rating; $rating->comment = $this->comment; $rating->status = 1; try { $rating->update(); } catch (\Throwable $th) { throw $th; } session()->flash('message', 'Success!'); } else { $rating = new Rating; $rating->user_id = auth()->user()->id; $rating->product_id = $this->product->id; $rating->rating = $this->rating; $rating->comment = $this->comment; $rating->status = 1; try { $rating->save(); } catch (\Throwable $th) { throw $th; } $this->hideForm = true; } } }
补充关联配置
如果还没有配置订单和订单项的关联,需要先在Eorder模型中添加关联方法:
// app/Models/Eorder.php public function orderItems() { return $this->hasMany(OrderItem::class); }
步骤2:修改Blade模板 product-ratings.blade.php
改动点说明:
- 新增权限判断,无权限的登录用户不展示评价表单,展示对应提示
- 原有未登录、已隐藏表单逻辑保留
完整修改后代码:
@auth @if($canReview) @if($hideForm != true) <form wire:submit.prevent="rate()" class="form-horizontal" id="form-review"> <div id="review"></div> <div class="col-sm-12 form-group required"> <div class="flex space-x-1 rating"> <label class="control-label">Rating: </label> <label for="star1"> <input hidden wire:model="rating" type="radio" id="star1" name="rating" value="1" /> <svg class="cursor-pointer block w-8 h-8 @if($rating>= 1 ) text-orange-400 @else text-grey @endif " fill=" currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"> <path d="M10 15l-5.878 3.09 1.123-6.545L.489 6.91l6.572-.955L10 0l2.939 5.955 6.572.955-4.756 4.635 1.123 6.545z" /> </svg> </label> <!-- 其余星星渲染逻辑和原有代码保持一致即可 --> </div> <div class="my-5 "> @error('comment') <p class="mt-1 text-red-500">{{ $message }}</p> @enderror <label class="control-label" for="input-review">Your Review</label> <textarea wire:model.lazy="comment" name="description" class="form-control" rows="5" placeholder="Comment.."></textarea> </div> </div> <div class="block"> <button type="submit" class="btn btn-primary">Rate</button> @if($currentId) <button type="submit" class="btn btn-danger" wire:click.prevent="delete({{ $currentId }})" class="text-sm cursor-pointer">Delete</button> @endif </div> </form> @endif @else <div class="mb-8 text-center text-gray-600"> 您需要成功购买该商品后才可进行评价 </div> @endif @else <div class="review-button"> <div class="mb-8 text-center text-gray-600"> 您需要登录后才可以评价商品 </div> <a href="/register" class="px-5 py-2 mx-auto font-medium text-center text-gray-600 bg-white border rounded-lg shadow-sm focus:outline-none hover:bg-gray-100" style="width:45%;padding:10px;display:block;float:left;margin-left:20px;">Register</a> <a href="/login" class="px-5 py-2 mx-auto font-medium text-center text-gray-600 bg-white border rounded-lg shadow-sm focus:outline-none hover:bg-gray-100" style="width:45%;padding:10px;display:block;float:left;margin-left:20px;">Login</a> </div> @endauth
注意事项
请根据你实际的数据库字段调整订单完成状态的判断条件,以及订单项关联的字段名即可。
内容的提问来源于stack exchange,提问作者Muhammad Shahzaib
相关产品推荐
相关产品推荐

