114 lines
3.4 KiB
PHP
114 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\ForumBoard;
|
|
use App\Models\ForumReply;
|
|
use App\Models\ForumThread;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\View\View;
|
|
|
|
class ForumController extends Controller
|
|
{
|
|
public function index(): View
|
|
{
|
|
$boards = ForumBoard::orderBy('sort')->orderBy('name')
|
|
->withCount(['threads' => fn ($q) => $q->where('status', ForumThread::STATUS_APPROVED)])
|
|
->get();
|
|
|
|
return view('forum.index', compact('boards'));
|
|
}
|
|
|
|
public function board(ForumBoard $board): View
|
|
{
|
|
$threads = $board->threads()
|
|
->visible(Auth::user())
|
|
->with('user')
|
|
->orderByDesc('is_pinned')
|
|
->orderByDesc('last_reply_at')
|
|
->orderByDesc('created_at')
|
|
->paginate(15);
|
|
|
|
return view('forum.board', compact('board', 'threads'));
|
|
}
|
|
|
|
public function thread(ForumThread $thread): View
|
|
{
|
|
if ($thread->trashed()) {
|
|
abort(404);
|
|
}
|
|
|
|
$user = Auth::user();
|
|
$isMod = $user && $user->canPerm('forum.moderate');
|
|
$isOwner = $user && $thread->user_id === $user->id;
|
|
|
|
// 待审且非作者、非审核员:不可见
|
|
if ($thread->status !== ForumThread::STATUS_APPROVED && ! $isMod && ! $isOwner) {
|
|
abort(404);
|
|
}
|
|
|
|
$thread->increment('views');
|
|
|
|
$replies = $thread->replies()
|
|
->visible($user)
|
|
->with('user')
|
|
->orderBy('created_at')
|
|
->paginate(20);
|
|
|
|
return view('forum.thread', compact('thread', 'replies'));
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'board_id' => ['required', 'exists:forum_boards,id'],
|
|
'title' => ['required', 'string', 'max:120'],
|
|
'body' => ['required', 'string', 'max:8000'],
|
|
]);
|
|
|
|
$thread = ForumThread::create([
|
|
'board_id' => $data['board_id'],
|
|
'user_id' => Auth::id(),
|
|
'title' => $data['title'],
|
|
'body' => $data['body'],
|
|
'status' => ForumThread::STATUS_PENDING,
|
|
'last_reply_at' => now(),
|
|
]);
|
|
|
|
$request->user()->awardPoints(10);
|
|
|
|
return redirect()->route('forum.thread', $thread)
|
|
->with('success', '帖子已提交,管理员审核通过后将公开展示');
|
|
}
|
|
|
|
public function reply(Request $request, ForumThread $thread)
|
|
{
|
|
if ($thread->is_locked) {
|
|
return back()->withErrors(['body' => '该帖子已锁定,无法回复。']);
|
|
}
|
|
|
|
// 待审帖子的回复入口对普通用户不可见(thread() 已拦截),此处仅作兜底
|
|
if ($thread->status !== ForumThread::STATUS_APPROVED && ! Auth::user()?->canPerm('forum.moderate')) {
|
|
return back()->withErrors(['body' => '该帖子尚未通过审核,暂不可回复。']);
|
|
}
|
|
|
|
$data = $request->validate([
|
|
'body' => ['required', 'string', 'max:8000'],
|
|
]);
|
|
|
|
ForumReply::create([
|
|
'thread_id' => $thread->id,
|
|
'user_id' => Auth::id(),
|
|
'body' => $data['body'],
|
|
'status' => ForumReply::STATUS_PENDING,
|
|
]);
|
|
|
|
$thread->update(['last_reply_at' => now()]);
|
|
|
|
$request->user()->awardPoints(5);
|
|
|
|
return back()->with('success', '回复已提交,审核通过后将公开展示');
|
|
}
|
|
}
|