feat(board): 슈퍼관리자 삭제 게시물 관리 및 회사명 표시 기능 추가

## 슈퍼관리자 삭제 게시물 관리
- 삭제된 게시물 목록에 표시 (빨간색 배경, 취소선)
- 게시물 복원 기능 추가 (POST /{post}/restore)
- 게시물 영구삭제 기능 추가 (DELETE /{post}/force)
- 통계 카드에 삭제됨 카운트 추가

## 페이지 타이틀 회사명 표시
- /boards: "회사명 게시판 관리" 형식으로 표시
- /boards/{code}/posts: "회사명 게시판명" 형식으로 표시
- 회사명 파란색으로 구분 표시

## 버그 수정
- 통계 카드 CSS: Tailwind 동적 클래스 문제 해결
  (grid-cols-{{ }} → 정적 클래스로 변경)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-29 09:11:21 +09:00
parent d77dc37068
commit 0db6e99a22
6 changed files with 168 additions and 28 deletions

View File

@@ -29,14 +29,16 @@ private function resolveBoard(string $boardCode, Request $request): Board
// t 파라미터가 있으면 해당 테넌트의 게시판 조회
if ($tenantId) {
return Board::where('board_code', $boardCode)
return Board::with('tenant')
->where('board_code', $boardCode)
->where('tenant_id', $tenantId)
->where('is_active', true)
->firstOrFail();
}
// t 파라미터가 없으면: 시스템 게시판 우선, 그 다음 로그인 회원의 테넌트 게시판
$board = Board::where('board_code', $boardCode)
$board = Board::with('tenant')
->where('board_code', $boardCode)
->whereNull('tenant_id') // 시스템 게시판
->where('is_active', true)
->first();
@@ -48,7 +50,8 @@ private function resolveBoard(string $boardCode, Request $request): Board
// 시스템 게시판이 없으면 로그인 회원의 테넌트 게시판
$userTenantId = auth()->user()?->tenant_id;
return Board::where('board_code', $boardCode)
return Board::with('tenant')
->where('board_code', $boardCode)
->where('tenant_id', $userTenantId)
->where('is_active', true)
->firstOrFail();
@@ -60,12 +63,17 @@ private function resolveBoard(string $boardCode, Request $request): Board
public function index(string $boardCode, Request $request): View
{
$board = $this->resolveBoard($boardCode, $request);
$filters = $request->only(['search', 'is_notice']);
$posts = $this->postService->getPosts($board->id, $filters, 15);
$notices = $this->postService->getNotices($board->id, 5);
$stats = $this->postService->getBoardPostStats($board->id);
$filters = $request->only(['search', 'is_notice', 'trashed']);
return view('posts.index', compact('board', 'posts', 'notices', 'stats', 'filters'));
// 슈퍼관리자: 삭제된 게시물 포함 조회
$isSuperAdmin = auth()->user()->hasRole('super-admin');
$includeTrashed = $isSuperAdmin;
$posts = $this->postService->getPosts($board->id, $filters, 15, $includeTrashed);
$notices = $this->postService->getNotices($board->id, 5);
$stats = $this->postService->getBoardPostStats($board->id, $includeTrashed);
return view('posts.index', compact('board', 'posts', 'notices', 'stats', 'filters', 'isSuperAdmin'));
}
/**
@@ -266,6 +274,46 @@ public function destroy(string $boardCode, Post $post, Request $request): Redire
->with('success', '게시글이 삭제되었습니다.');
}
/**
* 게시글 복원 (슈퍼관리자 전용)
*/
public function restore(string $boardCode, int $postId, Request $request): RedirectResponse
{
// 슈퍼관리자 권한 확인
if (! auth()->user()->hasRole('super-admin')) {
abort(403);
}
$board = $this->resolveBoard($boardCode, $request);
$post = Post::onlyTrashed()->where('board_id', $board->id)->findOrFail($postId);
$this->postService->restorePost($post);
return redirect()
->route('boards.posts.index', [$board->board_code, 't' => $board->tenant_id])
->with('success', '게시글이 복원되었습니다.');
}
/**
* 게시글 영구 삭제 (슈퍼관리자 전용)
*/
public function forceDestroy(string $boardCode, int $postId, Request $request): RedirectResponse
{
// 슈퍼관리자 권한 확인
if (! auth()->user()->hasRole('super-admin')) {
abort(403);
}
$board = $this->resolveBoard($boardCode, $request);
$post = Post::withTrashed()->where('board_id', $board->id)->findOrFail($postId);
$this->postService->forceDeletePost($post);
return redirect()
->route('boards.posts.index', [$board->board_code, 't' => $board->tenant_id])
->with('success', '게시글이 영구 삭제되었습니다.');
}
// =========================================================================
// File Management
// =========================================================================