query('q', '')); $notices = GcBoard::query() ->visibleNotice() ->when($q !== '', function ($query) use ($q) { $query->where(function ($w) use ($q) { $w->where('subject', 'like', "%{$q}%") ->orWhere('content', 'like', "%{$q}%"); }); }) ->noticeOrder() ->paginate(15) ->withQueryString(); return view('web.cs.notice.index', [ 'notices' => $notices, 'q' => $q, ]); } public function show(Request $request, int $seq) { $notice = GcBoard::query() ->visibleNotice() ->where('seq', $seq) ->firstOrFail(); // 조회수 (세션 기준 중복 방지) $hitKey = "cs_notice_hit_{$seq}"; if (!$request->session()->has($hitKey)) { GcBoard::where('seq', $seq)->increment('hit'); $request->session()->put($hitKey, 1); $notice->hit = (int)$notice->hit + 1; } // base $base = GcBoard::query()->visibleNotice(); /** * 전제: noticeOrder()가 "최신/우선 노출이 위" 정렬이라고 가정 * 예) first_sign DESC, seq DESC (또는 regdate DESC 포함) * * - prev: 리스트에서 '아래' 글(더 오래된/더 낮은 우선순위) => 정렬상 "뒤" * - next: 리스트에서 '위' 글(더 최신/더 높은 우선순위) => 정렬상 "앞" */ // ✅ prev (뒤쪽: first_sign 더 낮거나, 같으면 seq 더 낮은 것) $prev = (clone $base) ->where(function ($w) use ($notice) { $w->where('first_sign', '<', $notice->first_sign) ->orWhere(function ($w2) use ($notice) { $w2->where('first_sign', '=', $notice->first_sign) ->where('seq', '<', $notice->seq); }); }) ->noticeOrder() // DESC 정렬 그대로 (뒤쪽 중에서 가장 가까운 1개) ->first(); // ✅ next (앞쪽: first_sign 더 높거나, 같으면 seq 더 높은 것) // "가장 가까운 앞"을 얻기 위해 정렬을 ASC로 뒤집어서 first()로 뽑는다. $next = (clone $base) ->where(function ($w) use ($notice) { $w->where('first_sign', '>', $notice->first_sign) ->orWhere(function ($w2) use ($notice) { $w2->where('first_sign', '=', $notice->first_sign) ->where('seq', '>', $notice->seq); }); }) ->orderBy('first_sign', 'asc') ->orderBy('seq', 'asc') ->first(); return view('web.cs.notice.show', [ 'notice' => $notice, 'prev' => $prev, 'next' => $next, ]); } }