187 lines
5.7 KiB
Vue
187 lines
5.7 KiB
Vue
<template>
|
|
<div class="container-xxl flex-grow-1 container-p-y">
|
|
<!-- 상단 바: 검색창, 정렬 셀렉트 박스, 새 글쓰기 버튼 -->
|
|
<div class="row mb-4">
|
|
<!-- 검색창 -->
|
|
<div class="col">
|
|
<search-bar @update:data="search" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<!-- 정렬 셀렉트 박스 -->
|
|
<div class="col-md-3 mb-4">
|
|
<select class="form-select" v-model="selectedOrder" @change="handleSortChange">
|
|
<option value="date">최신날짜</option>
|
|
<option value="views">조회수</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- 새 글쓰기 버튼 -->
|
|
<div class="col-auto ms-auto mb-4">
|
|
<router-link to="/board/write">
|
|
<WriteButton />
|
|
</router-link>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 공지사항 게시물 리스트 -->
|
|
<div class="row g-3 mt-8">
|
|
<h3>공지사항</h3>
|
|
<board-card :posts="noticeList" @click="goDetail" />
|
|
</div>
|
|
<!-- 일반 게시물 리스트 -->
|
|
<div class="row g-3 mt-8">
|
|
<h3>일반게시판</h3>
|
|
<board-card :posts="generalList" @click="goDetail" />
|
|
</div>
|
|
|
|
<!-- 페이지네이션 -->
|
|
<div class="row g-3">
|
|
<div class="mt-8">
|
|
<Pagination
|
|
:currentPage="pagination.currentPage"
|
|
:pages="pagination.pages"
|
|
:prePage="pagination.prePage"
|
|
:nextPage="pagination.nextPage"
|
|
:isFirstPage="pagination.isFirstPage"
|
|
:isLastPage="pagination.isLastPage"
|
|
:hasPreviousPage="pagination.hasPreviousPage"
|
|
:hasNextPage="pagination.hasNextPage"
|
|
:navigatePages="pagination.navigatePages"
|
|
:navigatepageNums="pagination.navigatepageNums"
|
|
:navigateFirstPage="pagination.navigateFirstPage"
|
|
:navigateLastPage="pagination.navigateLastPage"
|
|
@update:currentPage="handlePageChange"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, onMounted } from 'vue';
|
|
import BoardCard from '@/components/list/BoardCardList.vue';
|
|
import Pagination from '@c/pagination/Pagination.vue';
|
|
import SearchBar from '@c/search/SearchBar.vue';
|
|
import router from '@/router';
|
|
import WriteButton from '@c/button/WriteBtn.vue';
|
|
import axios from '@api';
|
|
|
|
// 데이터 초기화
|
|
const generalList = ref([]);
|
|
const noticeList = ref([]);
|
|
const searchText = ref('');
|
|
const selectedOrder = ref('date');
|
|
const sortDirection = ref('desc');
|
|
const pagination = ref({
|
|
currentPage: 1,
|
|
pages: 1,
|
|
prePage: 0,
|
|
nextPage: 1,
|
|
isFirstPage: true,
|
|
isLastPage: false,
|
|
hasPreviousPage: false,
|
|
hasNextPage: false,
|
|
navigatePages: 10,
|
|
navigatepageNums: [1],
|
|
navigateFirstPage: 1,
|
|
navigateLastPage: 1
|
|
});
|
|
|
|
// 상세 페이지 이동
|
|
const goDetail = (id) => {
|
|
router.push({ name: 'BoardDetail', params: { id } });
|
|
};
|
|
|
|
// 검색 처리
|
|
const search = (e) => {
|
|
searchText.value = e.trim();
|
|
fetchGeneralPosts(1);
|
|
fetchNoticePosts(searchText.value);
|
|
};
|
|
|
|
// 정렬 변경 핸들러
|
|
const handleSortChange = (event) => {
|
|
fetchGeneralPosts(1);
|
|
};
|
|
|
|
// 게시물 데이터 로드(일반)
|
|
const fetchGeneralPosts = async (page = 1) => {
|
|
const response = await axios.get("board/general", {
|
|
params: {
|
|
page: page,
|
|
orderBy: selectedOrder.value,
|
|
sortDirection: sortDirection.value,
|
|
searchKeyword: searchText.value
|
|
}
|
|
});
|
|
|
|
if (response.data && response.data.data) {
|
|
const data = response.data.data;
|
|
// 게시물 리스트 업데이트
|
|
generalList.value = data.list.map((post, index) => ({
|
|
...post,
|
|
id: post.id || index,
|
|
img: post.img || null,
|
|
views: post.cnt || 0,
|
|
likes: post.likeCount || 0,
|
|
comments: post.commentCount || 0,
|
|
}));
|
|
|
|
// 페이지네이션 정보 업데이트
|
|
pagination.value = {
|
|
currentPage: data.pageNum,
|
|
pages: data.pages,
|
|
prePage: data.prePage,
|
|
nextPage: data.nextPage,
|
|
isFirstPage: data.isFirstPage,
|
|
isLastPage: data.isLastPage,
|
|
hasPreviousPage: data.hasPreviousPage,
|
|
hasNextPage: data.hasNextPage,
|
|
navigatePages: data.navigatePages,
|
|
navigatepageNums: data.navigatepageNums,
|
|
navigateFirstPage: data.navigateFirstPage,
|
|
navigateLastPage: data.navigateLastPage
|
|
};
|
|
} else {
|
|
console.error("데이터 오류:", response.data);
|
|
}
|
|
};
|
|
|
|
// 게시물 데이터 로드(공지사항)
|
|
const fetchNoticePosts = async () => {
|
|
const response = await axios.get("board/notices", {
|
|
params: {
|
|
searchKeyword: searchText.value
|
|
}
|
|
});
|
|
|
|
if (response.data && response.data.data && Array.isArray(response.data.data)) {
|
|
noticeList.value = response.data.data.map((post, index) => ({
|
|
...post,
|
|
id: post.id || index,
|
|
img: post.img || null,
|
|
views: post.cnt || 0,
|
|
likes: post.likeCount || 0,
|
|
comments: post.commentCount || 0,
|
|
}));
|
|
} else {
|
|
console.error("데이터 오류:", response.data);
|
|
}
|
|
};
|
|
|
|
// 페이지 변경
|
|
const handlePageChange = (page) => {
|
|
if (page !== pagination.value.currentPage) {
|
|
fetchGeneralPosts(page);
|
|
}
|
|
};
|
|
|
|
// 데이터 로드
|
|
onMounted(() => {
|
|
fetchGeneralPosts();
|
|
fetchNoticePosts();
|
|
});
|
|
</script>
|