Laravel 如何实现用户首次浏览帖子时为作者发放唯一积分?
功能实现方案
现有代码问题
你当前的代码存在三个核心逻辑偏差:
- 触发条件错误:用帖子总浏览数判断是否发积分,没有关联当前浏览用户的历史浏览记录,完全无法识别是否为单用户首次浏览
- 发放对象错误:积分发放给了当前浏览用户,需求是发放给帖子的作者
- 去重逻辑不匹配:仅设置了浏览统计的24小时冷却,没有绑定用户维度的浏览校验,无法实现单用户同帖浏览去重的要求
具体实现方案
方案1:基于现有views扩展包实现(无需额外建表)
如果你当前使用的是Laravel常用的浏览统计扩展,直接调用其用户维度的浏览查询能力即可,修正后代码如下:
public function mount(Post $post) { $this->post = $post; $shouldAwardPoint = false; $user = auth()->user(); // 仅已登录用户参与积分规则校验 if ($user) { // 查询当前用户是否已经浏览过该帖子,和你原有24小时冷却规则保持一致 $hasViewed = views($post) ->cooldown(24) ->byUser($user) ->count() > 0; if (!$hasViewed) { $shouldAwardPoint = true; } } // 统一记录浏览行为,游客也计入浏览统计 views($post)->cooldown(24)->record(); // 首次浏览触发积分发放,积分给到帖子作者 if ($shouldAwardPoint) { $point = Point::find(1); $post->user->achievePoint($point); } }
该方案适合允许24小时后重复浏览计入有效浏览的场景,如果需要永久去重,建议用方案2。
方案2:自建用户-帖子浏览关联表(可控性更高,支持永久去重)
单独新建post_views表存储浏览关系,必填字段:
- user_id(关联用户表,加联合索引:user_id + post_id)
- post_id(关联帖子表)
- created_at
对应逻辑代码如下:
public function mount(Post $post) { $this->post = $post; $user = auth()->user(); // 游客仅记录浏览统计,不处理积分 if (!$user) { views($post)->cooldown(24)->record(); return; } // 用firstOrCreate避免重复插入,返回的属性可以判断是否为首次插入 $viewRecord = \App\Models\PostView::firstOrCreate( ['user_id' => $user->id, 'post_id' => $post->id], ['created_at' => now()] ); views($post)->cooldown(24)->record(); // 首次插入记录说明是首次浏览,给作者加积分 if ($viewRecord->wasRecentlyCreated) { $point = Point::find(1); $post->user->achievePoint($point); } }
该方案可以实现永久去重,同一用户无论间隔多久浏览同一篇帖子,只会触发一次积分发放,适合对积分规则要求严格的场景。
内容的提问来源于stack exchange,提问作者caro Media
相关产品推荐
相关产品推荐

