feat(mng): 게시판-메뉴 자동 연동 및 URL 패턴 변경
## 주요 변경사항
### 게시판-메뉴 자동 연동
- 게시판 생성 시 메뉴 자동 생성 (BoardService.createBoardFromTemplate)
- 게시판 삭제 시 연결 메뉴 함께 삭제 (Soft Delete 연동)
- 게시판 복원 시 메뉴 재생성
- 게시판 영구삭제 시 메뉴 영구삭제
### 게시판 메뉴 보호
- MenuService: 게시판 연동 메뉴 수동 수정/삭제 방지
- isBoardMenuUrl(), isBoardMenu(), validateNotBoardUrl() 헬퍼 추가
- 8개 CRUD 메서드에 검증 로직 적용
### URL 패턴 변경
- 시스템 게시판: /system-boards/{code} → /customer-center/{code}
- 테넌트 게시판: /boards/{code} (변경 없음)
### UI 개선
- 메뉴 목록에서 게시판 메뉴 "📋 게시판" 뱃지 표시
- 게시판 메뉴는 수정/삭제 버튼 숨김 (활성/숨김 토글만 허용)
- 삭제된 게시판 행 클릭 시 404 오류 수정
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,10 @@
|
||||
|
||||
class BoardService
|
||||
{
|
||||
public function __construct(
|
||||
protected MenuService $menuService
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 시스템 게시판 목록 조회 (페이지네이션)
|
||||
*/
|
||||
@@ -316,10 +320,12 @@ public function getBaseFields(): array
|
||||
|
||||
/**
|
||||
* 템플릿 기반 게시판 생성
|
||||
*
|
||||
* @param bool $createMenu 메뉴 자동 생성 여부 (기본: true)
|
||||
*/
|
||||
public function createBoardFromTemplate(array $data, ?string $templateType = null, ?string $templateKey = null): Board
|
||||
public function createBoardFromTemplate(array $data, ?string $templateType = null, ?string $templateKey = null, bool $createMenu = true): Board
|
||||
{
|
||||
return DB::transaction(function () use ($data, $templateType, $templateKey) {
|
||||
return DB::transaction(function () use ($data, $templateType, $templateKey, $createMenu) {
|
||||
// 템플릿 설정 적용
|
||||
$template = null;
|
||||
if ($templateType && $templateKey) {
|
||||
@@ -362,6 +368,16 @@ public function createBoardFromTemplate(array $data, ?string $templateType = nul
|
||||
}
|
||||
}
|
||||
|
||||
// 메뉴 자동 생성
|
||||
if ($createMenu) {
|
||||
$this->menuService->createMenuForBoard([
|
||||
'board_code' => $board->board_code,
|
||||
'name' => $board->name,
|
||||
'is_system' => $board->is_system,
|
||||
'tenant_id' => $board->tenant_id,
|
||||
]);
|
||||
}
|
||||
|
||||
return $board->load('fields');
|
||||
});
|
||||
}
|
||||
@@ -376,21 +392,15 @@ public function createBoardFromTemplate(array $data, ?string $templateType = nul
|
||||
public function getAllBoards(array $filters = [], int $perPage = 15): LengthAwarePaginator
|
||||
{
|
||||
$query = Board::query()
|
||||
->with('tenant:id,code,company_name')
|
||||
->withCount('fields')
|
||||
->withTrashed();
|
||||
|
||||
// 게시판 유형 필터 (시스템/테넌트)
|
||||
if (isset($filters['board_scope'])) {
|
||||
if ($filters['board_scope'] === 'system') {
|
||||
$query->where('is_system', true);
|
||||
} elseif ($filters['board_scope'] === 'tenant') {
|
||||
$query->where('is_system', false);
|
||||
}
|
||||
}
|
||||
|
||||
// 테넌트 필터
|
||||
// 테넌트 필터: 선택 없으면 시스템만, 선택하면 해당 테넌트만
|
||||
if (! empty($filters['tenant_id'])) {
|
||||
$query->where('tenant_id', $filters['tenant_id']);
|
||||
} else {
|
||||
$query->where('is_system', true);
|
||||
}
|
||||
|
||||
// 검색 필터
|
||||
@@ -489,6 +499,7 @@ public function updateAnyBoard(int $id, array $data): bool
|
||||
|
||||
/**
|
||||
* 게시판 삭제 (시스템/테넌트 공통, Soft Delete)
|
||||
* - 연결된 메뉴도 함께 Soft Delete
|
||||
*/
|
||||
public function deleteAnyBoard(int $id): bool
|
||||
{
|
||||
@@ -497,11 +508,19 @@ public function deleteAnyBoard(int $id): bool
|
||||
$board->deleted_by = auth()->id();
|
||||
$board->save();
|
||||
|
||||
// 연결된 메뉴도 함께 삭제 (Soft Delete)
|
||||
$this->menuService->deleteMenuForBoard(
|
||||
$board->board_code,
|
||||
$board->is_system,
|
||||
$board->tenant_id
|
||||
);
|
||||
|
||||
return $board->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 게시판 복원 (시스템/테넌트 공통)
|
||||
* - 연결된 메뉴도 함께 복원
|
||||
*/
|
||||
public function restoreAnyBoard(int $id): bool
|
||||
{
|
||||
@@ -509,11 +528,25 @@ public function restoreAnyBoard(int $id): bool
|
||||
|
||||
$board->deleted_by = null;
|
||||
|
||||
return $board->restore();
|
||||
// 게시판 복원
|
||||
$result = $board->restore();
|
||||
|
||||
// 메뉴가 없으면 다시 생성
|
||||
if ($result) {
|
||||
$this->menuService->createMenuForBoard([
|
||||
'board_code' => $board->board_code,
|
||||
'name' => $board->name,
|
||||
'is_system' => $board->is_system,
|
||||
'tenant_id' => $board->tenant_id,
|
||||
]);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 게시판 영구 삭제 (시스템/테넌트 공통)
|
||||
* - 연결된 메뉴도 함께 영구 삭제
|
||||
*/
|
||||
public function forceDeleteAnyBoard(int $id): bool
|
||||
{
|
||||
@@ -522,6 +555,14 @@ public function forceDeleteAnyBoard(int $id): bool
|
||||
// 관련 필드 삭제
|
||||
$board->fields()->delete();
|
||||
|
||||
// 연결된 메뉴도 함께 영구 삭제
|
||||
$this->menuService->deleteMenuForBoard(
|
||||
$board->board_code,
|
||||
$board->is_system,
|
||||
$board->tenant_id,
|
||||
true // forceDelete
|
||||
);
|
||||
|
||||
return $board->forceDelete();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user