where('status', 'published') ->latest('created_at') ->with('post:id,title,slug') ->paginate(30); return theme_view('comments', compact('comments')); } public function store(Request $request, Post $post) { abort_unless($post->status === 'published', 404); if ($post->close_comment) { return back()->with('error', '该文章已关闭评论'); } $data = $request->validate([ 'author_name' => ['required', 'string', 'max:50'], 'author_email' => ['nullable', 'email', 'max:255'], 'author_url' => ['nullable', 'url', 'max:255'], 'content' => ['required', 'string', 'min:'.(int) blog_setting('comment_min_len', 2), 'max:'.(int) blog_setting('comment_max_len', 6000)], ]); // 蜜罐:隐藏字段被填写则直接丢弃(现代垃圾评论防护) if ($request->filled('website')) { return back()->with('error', '提交失败,请重试'); } $minInterval = (int) blog_setting('comment_post_space', 20); if ($minInterval > 0) { $last = Comment::query()->where('ip', $request->ip())->latest('created_at')->first(); if ($last && $last->created_at->diffInSeconds(now()) < $minInterval) { return back()->with('error', '评论太频繁,请稍后再试')->withInput(); } } $status = (int) blog_setting('comment_audit', 0) === 1 ? 'pending' : 'published'; $comment = DB::transaction(function () use ($post, $data, $request, $status) { $comment = $post->comments()->create([ 'user_id' => auth()->id(), 'author_name' => $data['author_name'], 'author_email' => $data['author_email'] ?? null, 'author_url' => $data['author_url'] ?? null, 'content' => $data['content'], 'ip' => $request->ip(), 'status' => $status, ]); if ($status === 'published') { $post->increment('comment_count'); } return $comment; }); if ($status === 'pending') { return back()->with('success', '评论已提交,等待审核通过后显示')->withFragment('comments'); } return back()->with('success', '评论已发布')->withFragment('comments'); } }