You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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> &nbsp;&nbsp;&nbsp;
                        <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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 10:39:03