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

Laravel如何实现用户每日仅可分享1次不重复任务的限制

Laravel实现任务分享双重限制规则方案

1. 前置表结构确认

首先确保shares表包含以下必要字段,缺失的话可以通过新增迁移补充:

  • user_id:关联执行分享操作的用户ID,整数类型、外键关联users表id
  • task_id:关联被分享的任务ID,整数类型、外键关联tasks表id
  • created_at:分享操作创建时间,时间戳类型,Laravel默认自带该字段

2. 配置模型关联

分别在三个模型中配置关联关系,简化后续查询:

  • 在User模型中新增关联:
// app/Models/User.php
public function shares()
{
    return $this->hasMany(Share::class);
}
  • 在Task模型中新增关联:
// app/Models/Task.php
public function shares()
{
    return $this->hasMany(Share::class);
}
  • 在Share模型中新增反向关联:
// app/Models/Share.php
public function user()
{
    return $this->belongsTo(User::class);
}

public function task()
{
    return $this->belongsTo(Task::class);
}

3. 业务校验逻辑实现

在处理分享请求的控制器方法中加入两层校验,直接用Laravel内置的验证机制即可,不需要额外引入扩展包:

// app/Http/Controllers/TaskController.php
public function share(Request $request)
{
    $userId = auth()->id();
    $todayTimeRange = [now()->startOfDay(), now()->endOfDay()];

    $validated = $request->validate([
        'task_id' => [
            'required',
            'integer',
            'exists:tasks,id',
            // 校验规则1:当前用户从未分享过该任务
            function ($attr, $value, $fail) use ($userId) {
                $shared = Share::where('user_id', $userId)
                    ->where('task_id', $value)
                    ->exists();
                if ($shared) $fail('不可重复分享同一任务');
            },
            // 校验规则2:当前用户当日未执行过分享操作
            function ($attr, $value, $fail) use ($userId, $todayTimeRange) {
                $todayShared = Share::where('user_id', $userId)
                    ->whereBetween('created_at', $todayTimeRange)
                    ->exists();
                if ($todayShared) $fail('每日仅可进行1次任务分享');
            }
        ]
    ]);

    // 校验通过后创建分享记录
    Share::create([
        'user_id' => $userId,
        'task_id' => $validated['task_id']
    ]);

    return back()->with('success', '分享成功');
}

4. 数据库层兜底防并发

仅靠代码校验在高并发场景下可能出现穿透问题,需要给shares表新增联合唯一索引,从数据库层面阻止同一用户重复分享同一任务的记录写入:

// 生成新迁移文件执行索引添加
Schema::table('shares', function (Blueprint $table) {
    $table->unique(['user_id', 'task_id'], 'user_task_share_unique');
});

添加索引后可以在控制器中补充异常捕获,当并发请求触发唯一索引报错时返回友好提示即可。

可选优化

如果多处用到分享校验逻辑,可以把两个闭包校验封装成Laravel自定义验证规则类,提升代码复用性。


内容的提问来源于stack exchange,提问作者kiki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:54:22