From c167875567f3d45d0b32502298dc9ebe05eb2d94 Mon Sep 17 00:00:00 2001 From: ByungCheol Date: Sun, 28 Jun 2026 13:34:40 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20=ED=83=9C?= =?UTF-8?q?=EA=B7=B8=20=ED=99=94=EB=A9=B4=20-=20=EA=B7=B8=EB=A3=B9?= =?UTF-8?q?=EB=B3=84=20=EA=B2=8C=EC=8B=9C=ED=8C=90=20=EB=A7=A4=ED=95=91=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=EB=B0=95=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 전역 단일 카테고리 선택 제거 → 각 태그 그룹에 사용 게시판 체크박스(커뮤니티/짠테크/재테크 팁) - 저장 시 boards 함께 전송, 선택 없으면 전체 게시판 - 글쓰기 화면은 현재 게시판에 매핑된 그룹 태그만 노출(boardApi.tagGroups(category)) Co-Authored-By: Claude Opus 4.8 --- src/api/boardApi.js | 4 +- src/views/admin/TagAdminView.vue | 94 ++++++++++++++++-------------- src/views/board/BoardWriteView.vue | 2 +- 3 files changed, 54 insertions(+), 46 deletions(-) diff --git a/src/api/boardApi.js b/src/api/boardApi.js index 45646d6..107ccf4 100644 --- a/src/api/boardApi.js +++ b/src/api/boardApi.js @@ -38,8 +38,8 @@ export const boardApi = { tags() { return http.get('/board/tags') }, - tagGroups() { - return http.get('/board/tag-groups') + tagGroups(category) { + return http.get('/board/tag-groups', { params: { category: category || undefined } }) }, addComment(id, content) { return http.post(`/board/posts/${id}/comments`, { content }) diff --git a/src/views/admin/TagAdminView.vue b/src/views/admin/TagAdminView.vue index b523961..273b8e3 100644 --- a/src/views/admin/TagAdminView.vue +++ b/src/views/admin/TagAdminView.vue @@ -2,6 +2,7 @@ import { onMounted, reactive, ref } from 'vue' import { adminApi } from '@/api/adminApi' import { useDialog } from '@/composables/dialog' +import { BOARDS } from '@/constants/boards' import IconBtn from '@/components/ui/IconBtn.vue' const dialog = useDialog() @@ -11,18 +12,17 @@ const error = ref(null) const newCategoryName = ref('') const newTag = reactive({}) // { [categoryId]: '입력값' } -const boardCategoryId = ref('') // 게시판에서 사용할 카테고리 ('' = 제한 없음) async function load() { loading.value = true error.value = null try { - categories.value = await adminApi.categories() - categories.value.forEach((c) => { + const list = await adminApi.categories() + list.forEach((c) => { + if (!Array.isArray(c.boards)) c.boards = [] if (newTag[c.id] === undefined) newTag[c.id] = '' }) - const setting = await adminApi.getBoardSetting() - boardCategoryId.value = setting.tagCategoryId ?? '' + categories.value = list } catch (e) { error.value = e.response?.data?.message || '불러오지 못했습니다.' } finally { @@ -30,21 +30,18 @@ async function load() { } } -async function saveBoardSetting() { - try { - const id = boardCategoryId.value === '' ? null : Number(boardCategoryId.value) - await adminApi.setBoardSetting(id) - alert('게시판 사용 카테고리를 저장했습니다.') - } catch (e) { - alert(e.response?.data?.message || '저장 실패') - } +// 카테고리의 게시판 매핑 토글 +function toggleBoard(cat, key) { + const i = cat.boards.indexOf(key) + if (i >= 0) cat.boards.splice(i, 1) + else cat.boards.push(key) } async function addCategory() { const name = newCategoryName.value.trim() if (!name) return try { - await adminApi.createCategory({ name, sortOrder: categories.value.length }) + await adminApi.createCategory({ name, sortOrder: categories.value.length, boards: [] }) newCategoryName.value = '' await load() } catch (e) { @@ -56,7 +53,8 @@ async function saveCategory(cat) { const name = (cat.name || '').trim() if (!name) return try { - await adminApi.updateCategory(cat.id, { name, sortOrder: cat.sortOrder }) + await adminApi.updateCategory(cat.id, { name, sortOrder: cat.sortOrder, boards: cat.boards }) + alert('저장했습니다.') await load() } catch (e) { alert(e.response?.data?.message || '카테고리 수정 실패') @@ -100,15 +98,7 @@ onMounted(load)