<template> <div class="title-box flex justify-between mb40"> <p class="title">문제</p> <select name="" id="" v-model="selectedBook" @change="fetchUnits"> <option value="" disabled>교재를 선택하세요</option> <option v-for="book in books" :key="book.book_id" :value="book.book_id"> {{ book.book_nm }} </option> </select> </div> <div class="content-t"> <label for="" class="title2">단원</label> <div class="unit-pagination flex mt10 mb20" style="gap: 10px;"> <button v-for="(unit, index) in units" :key="index" :class="{ 'selected-btn': selectedUnitId === unit.unitId }" @click="selectUnit(unit.unitId)"> {{ unit.unitName }} </button> </div> <div class="search-wrap flex justify-end mb20"> <select name="" id="" class="mr10 data-wrap" v-model="searchOption"> <option value="">전체</option> <option value="prblm_expln">문제</option> <option value="prblm_type_id">유형</option> <option value="user_id">작성자</option> </select> <input type="text" placeholder="검색하세요." v-model="searchKeyword"> <button type="button" title="위원회 검색" @click="searchProblems"> <img src="../../../resources/img/look_t.png" alt=""> </button> </div> <div class="table-wrap"> <table> <thead> <tr> <td>No.</td> <td>문제</td> <td>유형</td> <td>점수</td> <td>작성자</td> <td>등록일</td> </tr> </thead> <tbody> <tr v-for="(problem, index) in problems" :key="problem.prblmId" @click="[goToPage('QuestionDetail', selectQuestionList(problem))]"> <td>{{ (currentPage - 1) * 10 + index + 1 }}</td> <td>{{ problem.prblmExpln }}</td> <td>{{ problem.prblmTypeNm }}</td> <td>{{ problem.prblmScr }}</td> <td>{{ problem.userId }}</td> <td>{{ problem.regDt }}</td> </tr> </tbody> </table> <article class="table-pagination flex justify-center align-center mb20 mt30" style="gap: 10px;"> <button @click="changePage(currentPage - 1)" :disabled="currentPage === 1"> <img src="../../../resources/img/btn27_90t_normal.png" alt="Previous"> </button> <button v-for="page in paginationButtons" :key="page" @click="changePage(page)" :class="{ 'selected-btn': currentPage === page }"> {{ page }} </button> <button @click="changePage(currentPage + 1)" :disabled="currentPage === totalPages"> <img src="../../../resources/img/btn28_90t_normal.png" alt="Next"> </button> </article> <div class="flex justify-end "> <button type="button" title="등록" class="new-btn" @click="goToPage('QuestionInsert')"> 등록 </button> </div> </div> </div> </template> <script> import SvgIcon from '@jamescoyle/vue-icon'; import { mdiMagnify } from '@mdi/js'; import axios from 'axios'; export default { data() { return { mdiMagnify: mdiMagnify, problems: [], units: [], books: [], currentPage: 1, pageSize: 10, totalPosts: 0, searchOption: '', searchKeyword: '', selectedUnitId: '', selectedBook: "", } }, methods: { goToPage(page) { this.$router.push({ name: page, query: { book_id: this.selectedBook, unit_id: this.selectedUnitId, } }); }, showConfirm(type) { let message = ''; if (type === 'cancel') { message = '삭제하시겠습니까?'; } else if (type === 'reset') { message = '초기화하시겠습니까?'; } else if (type === 'save') { message = '등록하시겠습니까?'; } if (confirm(message)) { this.goBack(); } }, selectQuestionList(item) { sessionStorage.setItem("selectQuestionList", JSON.stringify(item)); }, selectUnit(unitId) { this.selectedUnitId = unitId; // 선택된 단원 ID 설정 this.fetchProblems(1); // 첫 페이지로 문제 목록 새로 고침 }, async fetchProblems(page = 1) { try { const response = await axios.post('/problem/problemList.json', { option: this.searchOption, keyword: this.searchKeyword, unitId: this.selectedUnitId, pageSize: 10, startIndex: (page - 1) * 10 }); this.problems = response.data.problems; this.totalPosts = response.data.totalProblem; this.currentPage = page; } catch (error) { console.error('문제 목록을 불러오는 중 오류가 발생했습니다.', error); } }, changePage(page) { if (page < 1 || page > this.totalPages) return; this.currentPage = page; this.fetchProblems(page); }, searchProblems() { this.fetchProblems(1); }, fetchBooks() { axios({ url: "/book/findAll.json", method: "post", headers: { "Content-Type": "application/json; charset=UTF-8", }, }) .then(response => { console.log(response.data) this.books = response.data; }) .catch(error => { console.error("fetchBooks - error: ", error); alert("교재 목록을 불러오는 중 오류가 발생했습니다."); }); }, fetchUnits() { if (!this.selectedBook) return; axios({ url: "/unit/unitList.json", method: "post", headers: { "Content-Type": "application/json; charset=UTF-8", }, data: { "bookId": this.selectedBook }, }) .then(response => { console.log(response.data) this.units = response.data; }) .catch(error => { console.error("fetchUnits - error: ", error); alert("단원 목록을 불러오는 중 오류가 발생했습니다."); }); }, }, watch: { }, computed: { totalPages() { return Math.ceil(this.totalPosts / this.pageSize); }, paginationButtons() { let start = Math.max(0, this.currentPage - 2); let end = Math.min(start + 5, this.totalPages); if (end - start < 5) { start = Math.max(0, end - 5); } return Array.from({ length: end - start }, (_, i) => start + i + 1); }, startIndex() { return this.currentPage * this.itemsPerPage; } }, components: { SvgIcon }, mounted() { this.selectedUnitId = this.$route.query.unit_id || ''; this.selectedBook = this.$route.query.book_id || ''; this.fetchBooks(); this.fetchProblems(); this.fetchUnits(); } } </script>