jichoi / lms_front star
권지수 2024-08-12
240812 권지수 문제 화면
@0e35d907031627a63b35d9216bd66ca23ecd1004
client/views/pages/AppRouter.js
--- client/views/pages/AppRouter.js
+++ client/views/pages/AppRouter.js
@@ -83,6 +83,7 @@
 import TextInsert from "./teacher/TextInsert.vue";
 import QuestionList from "./teacher/QuestionList.vue";
 import QuestionInsert from "./teacher/QuestionInsert.vue";
+import QuestionDetail from "./teacher/QuestionDetail.vue"; 
 import VocaList from "./teacher/VocaList.vue";
 import ExamList from "./teacher/ExamList.vue";
 import ExamDetail from "./teacher/ExamDetail.vue";
@@ -186,6 +187,7 @@
             { path: '/TextInsert.page', name: 'TextInsert', component: TextInsert },
             { path: '/QuestionList.page', name: 'QuestionList', component: QuestionList },
             { path: '/QuestionInsert.page', name: 'QuestionInsert', component: QuestionInsert },
+            { path: '/QuestionDetail.page', name: 'QuestionDetail', component: QuestionDetail }, 
             { path: '/VocaList.page', name: 'VocaList', component: VocaList },
             { path: '/ExamList.page', name: 'ExamList', component: ExamList },
             { path: '/ExamDetail.page', name: 'ExamDetail', component: ExamDetail },
 
client/views/pages/teacher/QuestionDetail.vue (added)
+++ client/views/pages/teacher/QuestionDetail.vue
@@ -0,0 +1,232 @@
+<template>
+    <div class="title-box flex justify-between mb40">
+        <p class="title">문제 조회</p>
+    </div>
+    <div class="board-wrap">
+        <div class="flex align-center">
+            <label for="" class="title2">문제</label>
+            <p class="data-wrap">{{ questionExpln }}</p>
+        </div>
+        <hr>
+        <div class="flex align-center">
+            <label for="" class="title2">유형</label>
+            <p class="data-wrap">{{ questionTypeId }}</p>
+        </div>
+        <div class="flex align-center">
+            <label for="" class="title2">카테고리</label>
+            <p class="data-wrap">{{ questionCategoryId }}</p>
+        </div>
+        <div class="flex align-center">
+            <label for="" class="title2">사용자 아이디</label>
+            <p class="data-wrap">{{ userId }}</p>
+        </div>
+        <div class="flex align-center">
+            <label for="" class="title2">책 아이디</label>
+            <p class="data-wrap">{{ bookId }}</p>
+        </div>
+        <div class="flex align-center">
+            <label for="" class="title2">단원 아이디</label>
+            <p class="data-wrap">{{ unitId }}</p>
+        </div>
+        <hr>
+        <div class="flex align-center">
+            <label for="" class="title2">문제 점수</label>
+            <p class="data-wrap">{{ questionScore }}</p>
+        </div>
+        <div class="flex align-center">
+            <label for="" class="title2">문제 힌트</label>
+            <p class="data-wrap">{{ questionHint }}</p>
+        </div>
+        <div class="flex align-center">
+            <label for="" class="title2">문제 해설</label>
+            <p class="data-wrap">{{ questionExplanation }}</p>
+        </div>
+        <hr>
+        <div class="flex align-center">
+            <label for="" class="title2">첨부파일</label>
+            <p class="data-wrap">{{ questionFile }}</p>
+        </div>
+        <div class="flex align-center mb20">
+            <label for="" class="title2">답</label>
+            <p class="data-wrap">{{ questionAnswer }}</p>
+        </div>
+        <div>
+            <label for="" class="title2">오답 학생</label>
+            <div class="table-wrap mt20">
+                <table>
+                    <thead>
+                        <tr>
+                            <td>No.</td>
+                            <td>이름</td>
+                            <td>학년</td>
+                            <td>반</td>
+                            <td>오답</td>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        <tr v-for="(student, index) in wrongStudents" :key="index" @click="goToPage('noticeDetail')">
+                            <td>{{ index + 1 }}</td>
+                            <td>{{ student.name }}</td>
+                            <td>{{ student.grade }}</td>
+                            <td>{{ student.class }}</td>
+                            <td>{{ student.wrongAnswer }}</td>
+                        </tr>
+                    </tbody>
+                </table>
+            </div>
+        </div>
+    </div>
+    <div class="flex justify-between mt50">
+        <button type="button" title="글쓰기" class="new-btn" @click="goToPage('QuestionList')">
+            목록
+        </button>
+        <div class="flex">
+            <button type="button" title="글쓰기" class="new-btn mr10" @click="editQuestion">
+                수정
+            </button>
+            <button type="button" title="글쓰기" class="new-btn" @click="confirmDelete">
+                삭제
+            </button>
+        </div>
+    </div>
+
+    <!-- 모달 창 -->
+    <div v-if="showModal" class="modal-overlay">
+        <div class="modal-content">
+            <p>삭제하시겠습니까?</p>
+            <button @click="deleteQuestion">예, 삭제</button>
+            <button @click="cancelDelete">취소</button>
+        </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,
+            questionTitle: '샘플 제목',
+            questionExpln: '샘플 내용',
+            questionFile: null, // 파일 URL을 여기에 저장
+            questionAnswer: '샘플 답',
+            wrongStudents: [],
+            showModal: false,
+            parsedData: null, // parsedData 추가
+            questionTypeId: '',
+            questionCategoryId: '',
+            userId: '',
+            bookId: '',
+            unitId: '',
+            questionScore: '',
+            questionHint: '',
+            questionExplanation: ''
+        }
+    },
+    methods: {
+        goToPage(page) {
+            this.$router.push({ name: page });
+        },
+        editQuestion() {
+            // 수정 로직 추가
+            console.log('수정 버튼 클릭');
+        },
+        confirmDelete() {
+            this.showModal = true;
+        },
+        async deleteQuestion() {
+            try {
+                const prblmId = this.parsedData.prblmId; // this.parsedData 사용
+                const response = await axios.post('/problem/deleteProblem.json', { prblmId : prblmId });
+                console.log('삭제 완료:', response.data);
+                this.showModal = false;
+                this.goToPage('QuestionList');
+            } catch (error) {
+                console.error('삭제 실패:', error);
+            }
+        },
+        cancelDelete() {
+            this.showModal = false;
+        },
+        loadFromLocalStorage() {
+            const data = sessionStorage.getItem('selectQuestionList');
+            if (data) {
+                this.parsedData = JSON.parse(data); // this.parsedData 설정
+                console.log('Loaded data from local storage:', this.parsedData);
+                
+                this.questionExpln = this.parsedData.prblmExpln || '내용 없음';
+                this.questionFile = this.parsedData.fileMngId || '첨부파일 없음'; // 파일 경로는 실제 경로에 맞게 수정
+                this.questionAnswer = this.parsedData.prblmCmmt || '답 없음';
+                this.wrongStudents = this.parsedData.wrongStudents || [];
+                this.questionTypeId = this.parsedData.prblmTypeId || '유형 아이디 없음';
+                this.questionCategoryId = this.parsedData.prblmCtgryId || '카테고리 아이디 없음';
+                this.userId = this.parsedData.userId || '사용자 아이디 없음';
+                this.bookId = this.parsedData.bookId || '책 아이디 없음';
+                this.unitId = this.parsedData.unitId || '단원 아이디 없음';
+                this.questionScore = this.parsedData.prblmScr || '점수 없음',
+                this.questionHint = this.parsedData.prblmHint || '힌트 없음',
+                this.questionExplanation = this.parsedData.prblmExpln || '해설 없음'
+            } else {
+                console.log('No data found in local storage');
+            }
+        },
+        downloadFile() {
+            window.open(this.questionFile, '_blank');
+        },
+        getProblemId() {
+            // 문제 ID를 얻는 로직을 추가하세요
+            return 'sampleProblemId';
+        }
+    },
+    components: {
+        SvgIcon
+    },
+    mounted() {
+        this.loadFromLocalStorage();
+    }
+}
+</script>
+
+<style>
+    .data-wrap {
+        width: -webkit-fill-available;
+        padding: 1.2rem;
+    }
+    .download-btn {
+        background-color: #007bff;
+        color: white;
+        border: none;
+        padding: 10px 20px;
+        cursor: pointer;
+        text-decoration: none;
+        font-size: 1rem;
+    }
+    .download-btn:hover {
+        background-color: #0056b3;
+    }
+    .modal-overlay {
+        position: fixed;
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
+        background-color: rgba(0, 0, 0, 0.5);
+        display: flex;
+        justify-content: center;
+        align-items: center;
+    }
+    .modal-content {
+        background-color: white;
+        padding: 20px;
+        border-radius: 5px;
+        text-align: center;
+    }
+    .modal-content button {
+        margin: 10px;
+        padding: 10px 20px;
+        cursor: pointer;
+    }
+</style>
client/views/pages/teacher/QuestionList.vue
--- client/views/pages/teacher/QuestionList.vue
+++ client/views/pages/teacher/QuestionList.vue
@@ -6,66 +6,84 @@
         </select>
     </div>
     <div class="search-wrap flex justify-end mb20">
-            <select name="" id="" class="mr10 data-wrap">
-                <option value="">전체</option>
-            </select>
-                <input  type="text" placeholder="검색하세요.">
-                <button type="button" title="위원회 검색">
-                    <img src="../../../resources/img/look_t.png" alt="">
-                </button>
-        </div>
-        <div class="table-wrap">
-            <table>
-                <thead>
+        <select name="" id="" class="mr10 data-wrap" v-model="searchOption">
+            <option value="">전체</option>
+            <option value="">제목</option>
+            <option value="prblm_expln">문제</option>
+            <option value="user_id">작성자</option>
+            <option value="">등록일</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>
-                </thead>
-                <tbody>
-                    <tr @click="goToPage('QuestionInsert')">
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                        <td></td>
-                    </tr>
-                </tbody>
-            </table>
-            <article class="table-pagination flex justify-center align-center mb20 mt30" style="gap: 10px;">
-                    <button><img src="../../../resources/img/btn27_90t_normal.png" alt=""></button>
-                    <button class="selected-btn">1</button>
-                    <button>2</button>
-                    <button>3</button>
-                    <button><img src="../../../resources/img/btn28_90t_normal.png" alt=""></button>
-                </article>
-                <div class="flex justify-end ">
-                <button type="button" title="등록" class="new-btn" @click="goToPage('QuestionInsert')">
-                    등록
-                </button>
+                </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>제목</td>
+                    <td>{{ problem.prblmExpln }}</td>
+                    <td>{{ problem.userId }}</td>
+                    <td>오답률</td>
+                    <td>등록일</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="">
+            </button>
+            <button :class="{ 'selected-btn': currentPage === 1 }" @click="changePage(1)">1</button>
+            <button :class="{ 'selected-btn': currentPage === 2 }" @click="changePage(2)">2</button>
+            <button :class="{ 'selected-btn': currentPage === 3 }" @click="changePage(3)">3</button>
+            <button @click="changePage(currentPage + 1)" :disabled="currentPage === totalPages">
+                <img src="../../../resources/img/btn28_90t_normal.png" alt="">
+            </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 { mdiMagnify } from '@mdi/js';
+import axios from 'axios';
 
 export default {
-    data () {
+    data() {
         return {
+            problems: [],
             mdiMagnify: mdiMagnify,
+            currentPage: 1,
+            totalPages: 3,
+            searchOption: '',
+            searchKeyword: '',
         }
     },
     methods: {
         goToPage(page) {
-         this.$router.push({ name: page });
-      },
-      showConfirm(type) {
+            this.$router.push({ name: page });
+        },
+        selectQuestionList(item) {
+            sessionStorage.setItem("selectQuestionList", JSON.stringify(item));
+        },
+        showConfirm(type) {
             let message = '';
             if (type === 'cancel') {
                 message = '삭제하시겠습니까?';
@@ -79,19 +97,32 @@
                 this.goBack();
             }
         },
-
-    },
-    watch: {
-
-    },
-    computed: {
-       
-    },
-    components:{
-        SvgIcon
+        async fetchProblems(page = 1) {
+            try {
+                const response = await axios.post('/problem/problemList.json', {
+                    option: this.searchOption,
+                    keyword: this.searchKeyword,
+                    pageSize: 10,
+                    startIndex: (page - 1) * 10
+                });
+                this.problems = response.data;
+                this.currentPage = page;
+            } catch (error) {
+                console.error('문제 목록을 불러오는 중 오류가 발생했습니다.', error);
+            }
+        },
+        changePage(page) {
+            if (page < 1 || page > this.totalPages) return;
+            this.fetchProblems(page);
+            this.currentPage = page;
+        },
+        searchProblems() {
+            this.fetchProblems(1);
+        }
     },
     mounted() {
         console.log('Main2 mounted');
+        this.fetchProblems();
     }
 }
-</script>
(No newline at end of file)
+</script>
Add a comment
List