jichoi / lms_front star
구자현 구자현 08-12
240812 반 교재 CRUD(이후 수정 필요)
@9c517509f14c38f3790dbf6a17c53509a8878909
client/views/pages/teacher/C_TextBookDetail.vue
--- client/views/pages/teacher/C_TextBookDetail.vue
+++ client/views/pages/teacher/C_TextBookDetail.vue
@@ -1,6 +1,6 @@
 <template>
     <div class="title-box flex justify-between mb40">
-        <p class="title">A교재</p>
+        <p class="title">{{ bookDetails ? bookDetails.book_nm : 'Loading...' }}</p>
         <select name="" id="">
             <option value="">A 반</option>
         </select>
@@ -66,7 +66,7 @@
 import SvgIcon from '@jamescoyle/vue-icon';
 import { mdiMagnify, mdilArrowRight } from '@mdi/js';
 import ProgressBar from '../../component/ProgressBar.vue';
-
+import axios from 'axios';
 
 export default {
     data() {
@@ -74,7 +74,9 @@
             mdiMagnify: mdiMagnify,
             mdilArrowRight: mdilArrowRight,
             timer: "00:00",
-            progress: 20
+            progress: 20,
+            selectedBookId: this.$route.query.book_Id,
+            bookDetails: null,
         }
     },
     methods: {
@@ -100,6 +102,25 @@
                 this.goBack();
             }
         },
+        fetchBookDetails() {
+            axios({
+                url: "/book/find.json",
+                method: "post",
+                headers: {
+                    "Content-Type": "application/json; charset=UTF-8",
+                },
+                data: {
+                    book_id: this.$route.query.book_id
+                }
+            })
+            .then(response => {
+                console.log('Book details:', response.data);
+                this.bookDetails = response.data;
+            })
+            .catch(error => {
+                console.error('Error fetching book details:', error);
+            });
+        }  
     },
     watch: {
 
@@ -112,7 +133,8 @@
         ProgressBar
     },
     mounted() {
-        console.log('Main2 mounted');
+        console.log('Mounted with book_id:', this.$route.query.book_id);
+        this.fetchBookDetails();
     }
 }
 </script>
client/views/pages/teacher/C_Textbook.vue
--- client/views/pages/teacher/C_Textbook.vue
+++ client/views/pages/teacher/C_Textbook.vue
@@ -1,62 +1,67 @@
 <template>
     <div class="title-box flex justify-between mb40">
         <p class="title">교재</p>
-        <select name="" id="">
-            <option value="">A반</option>
+        <select v-model="selectedClassId">
+            <option v-for="classItem in classList" :key="classItem.sclsId" :value="classItem.sclsId">
+                {{ classItem.sclsNm }}
+            </option>
         </select>
-        </div>
-        <div class="content-t">
-            <div  class=" flex " style="gap: 50px;">
-                <div class="textbook">
-                    <div class="box " style="gap: 10px;" @click="goToPage('C_TextBookDetail')">
-                    </div>
-                    <div class="text ">
-                        <p class="title1" style="color: #fff;">A 교재</p>
-                        <div class="btnGroup mt15 flex align-center justify-end" style="gap: 10px;">
-                            <button>수정</button><p>&#124;</p>
-                            <button @click="showConfirm('delete')">삭제</button>
-                        </div>
-                    </div>
+    </div>
+    <div class="content-t">
+        <div class="flex" style="gap: 2.5%;" :style="{flexWrap: 'wrap'}">
+            <div class="textbook" v-for="textbookItem in textbookList" :key="textbookItem.book_id" style="width: 22.5%; margin-bottom: 30px;">
+                <div class="box" style="gap: 10px;" @click="goToPage('C_TextBookDetail', textbookItem.book_id)">
                 </div>
-                
-                <div class="textbook-add">
-                        <button  @click="buttonSearch"><img src="../../../resources/img/btn32_98t_normal.png" alt=""></button>
-        
+                <div class="text">
+                    <p class="title1" style="color: #fff;">{{ textbookItem.book_nm }}</p>
+                    <div class="btnGroup mt15 flex align-center justify-end" style="gap: 10px;">
+                        <button @click="deleteBook(textbookItem.book_id)">삭제</button>
+                    </div>
                 </div>
             </div>
-        </div>
-        <div v-show="searchOpen" class="popup-wrap">
-                <div class="popup-box ">
-                    <div class="flex justify-between mb30">
-                        <p class="popup-title">교재 이름</p>
-                        <button type="button" class="popup-close-btn" @click="closeBtn">
-                            <svg-icon type="mdi" :path="mdiWindowClose" class="close-btn"></svg-icon>
 
-                        </button>
-                    </div>
-                    <div class="search-wrap mb30">
-                        <select v-model="selectedSearchOption" class="mr10 data-wrap">
-      <option value="bbsTtl">제목</option>
-      <option value="bbsCnt">내용</option>
-      <option value="userNm">작성자</option>
-      <option value="bbsCls">카테고리</option>
-    </select>
-                    </div>
-                    <div class="flex justify-center ">
-                        <button type="button" title="글쓰기" class="new-btn mr10">
-                            취소
-                        </button>
-                        <button type="button" title="글쓰기" class="new-btn">
-                            등록
-                        </button>
-                    </div>
-                </div>
+            <div class="textbook-add" style="width: 22.5%; margin-bottom: 30px;">
+                <button @click="buttonSearch">
+                    <img src="../../../resources/img/btn32_98t_normal.png" alt="">
+                </button>
             </div>
+        </div>
+    </div>
+    <div v-show="searchOpen" class="popup-wrap">
+    <div class="popup-box">
+        <div class="flex justify-between mb30">
+            <p class="popup-title">교재 이름</p>
+            <button type="button" class="popup-close-btn" @click="closeBtn">
+                <svg-icon type="mdi" :path="mdiWindowClose" class="close-btn"></svg-icon>
+            </button>
+        </div>
+        <div class="search-wrap mb30">
+            <input v-model="searchKeyword" type="text" placeholder="검색하세요." @keyup.enter="bookDataSearch"/>
+            <button type="button" @click="bookDataSearch()" title="교재 검색">
+                <img src="../../../resources/img/look_t.png" alt="" />
+            </button>
+        </div>
+        <div class="table-wrap">
+        <div v-if="searchResults.length">
+            <tbody>
+                <tr v-for="book in searchResults" :key="book.book_id">
+                    <td>{{ book.book_nm }}<button type="button" title="등록" class="new-btn" @click="insertBook(book.book_id)" style="margin-left: 10px;">추가</button></td>
+                </tr>
+        </tbody>
+        </div>
+    <div v-else>
+        <p>검색 결과가 없습니다.</p>
+    </div>
+</div>
+
+    </div>
+</div>
 </template>
 
 <script>
 import SvgIcon from '@jamescoyle/vue-icon';
 import { mdiMagnify, mdiWindowClose } from '@mdi/js';
+import axios from 'axios';
 
 export default {
     data () {
@@ -64,21 +69,38 @@
             mdiWindowClose: mdiWindowClose,
             showModal: false,
             searchOpen: false,
+            classList: [],
+            textbookList: [],
+            newBookName: '',
+            editMode: false,
+            editBookId: null,
+            selectedClassId: '',
+            searchOpen: false,
+            searchKeyword: '',
+            searchResults: [],
         }
     },
     methods: {
-        goToPage(page) {
-            this.$router.push({ name: page });
-        },
-        closeModal() {
-            this.showModal = false;
+        goToPage(page, book_id) {
+            this.$router.push({ name: page, query: { book_id: book_id } });
         },
         buttonSearch() {
             this.searchOpen = true;
         },
         closeBtn() {
             this.searchOpen = false;
-
+            this.editMode = false;
+            this.editBookId = null;
+            this.newBookName = '';
+        },
+        editBook(book) {
+            this.newBookName = book.book_nm;
+            this.editMode = true;
+            this.editBookId = book.book_id;
+            this.searchOpen = true;
+        },
+        closeModal() {
+            this.showModal = false;
         },
         showConfirm(type) {
             let message = '';
@@ -94,22 +116,131 @@
                 this.goBack();
             }
         },
+        bookDataSearch() {
+            const vm = this;
+            const searchPayload = {
+                keyword: vm.searchKeyword,
+            };
+            axios.post("/book/search.json", searchPayload)
+                .then(function (res) {
+                    console.log("bookDataSearch - response : ", res.data);
+                    vm.searchResults = res.data.result; // 검색 결과 저장
+                })
+                .catch(function (error) {
+                    console.log("bookSearch - error : ", error);
+                    alert("책이 존재하지 않습니다.");
+                });
+        },
+        stdClassesSelectList() {
+            const vm = this;
+            axios({
+                url: "/classes/selectClass.json",
+                method: "post",
+                headers:{
+                    "Content-Type": "application/json; charset=UTF-8",
+                },
+                data: {
+                    userId:"USID_000000000000001"
+                }
+            })
+            .then(function (response) {
+                console.log("classList - response : ", response.data);
+                vm.classList = response.data.data;
+            })
+            .catch(function (error) {
+                console.log("classList - error : ", error);
+                alert("학생 반 조회에 오류가 발생했습니다.");
+            });
+        },
+        bookList() {
+            console.log('Fetching books for class ID:', this.selectedClassId);
+            if (!this.selectedClassId) return;
 
+            const vm = this;
+            axios({
+                url: "/classBook/findAll.json",
+                method: "post",
+                headers: {
+                    "Content-Type": "application/json; charset=UTF-8",
+                },
+                data: {
+                    sclsId: this.selectedClassId
+                }
+            })
+            .then(response => {
+                console.log("bookList - response : ", response.data);
+                vm.textbookList = response.data.result;
+            })
+            .catch(error => {
+                console.error('Error fetching books:', error);
+            });
+        },
+        insertBook(bookId) {
+            const bookToAdd = [{
+                bookId: bookId,
+                sclsId: this.selectedClassId
+            }];
+
+            axios.post('/classBook/register.json', bookToAdd)
+                .then(response => {
+                    console.log('Book added successfully:', response.data);
+                    this.bookList();
+                })
+                .catch(error => {
+                    console.error('Error adding book:', error);
+                });
+        },
+        deleteBook(bookId) {
+            if (confirm('삭제하시겠습니까?')) {
+                axios({
+                    url: "/classBook/delete.json",
+                    method: "post",
+                    headers: {
+                        "Content-Type": "application/json; charset=UTF-8",
+                    },
+                    data: {
+                        bookId: bookId,
+                        sclsId: this.selectedClassId
+                    },
+                })
+                .then(response => {
+                    this.bookList();
+                })
+                .catch(error => {
+                    console.error('Error deleting book:', error);
+                });
+            }
+        },
     },
     watch: {
-
-    },
-    computed: {
-
+        selectedClassId(newVal) {
+            if (newVal) {
+                this.bookList();
+            }
+        }
     },
     components: {
         SvgIcon
     },
     mounted() {
         console.log('Main2 mounted');
+        this.stdClassesSelectList();
     }
 }
+
 </script>
+
 <style scoped>
-.textbook{width: 300px;}
+.content-t {
+    flex-wrap: wrap; 
+    height: 90%;
+    overflow-y: scroll;
+}
+.flex {
+    display: flex;
+    flex-wrap: wrap;
+}
+.textbook, .textbook-add {
+    margin-bottom: 30px;
+}
 </style>
(파일 끝에 줄바꿈 문자 없음)
client/views/pages/teacher/TextBookDetail.vue
--- client/views/pages/teacher/TextBookDetail.vue
+++ client/views/pages/teacher/TextBookDetail.vue
@@ -1,18 +1,13 @@
 <template>
     <div class="title-box flex justify-between mb40">
-        <p class="title">A교재</p>
-        <!-- <select name="" id="">
-            <option value="">1단원</option>
-        </select> -->
-    </div>
+    <p class="title">{{ bookDetails ? bookDetails.book_nm : 'Loading...' }}</p>
+  </div>
     <label for="" class="title1">단원</label>
         <div class="unit-pagination flex mt10" style="gap: 10px;">
             <button class="selected-btn">1</button>
             <button>2</button>
             <button>3</button>
-            <button ><svg-icon type="mdi" :path="mdiPlus" style="    padding-top: 6px;
-    width: 30px;
-    height: 30px;"></svg-icon></button>
+            <button ><svg-icon type="mdi" :path="mdiPlus" style=" padding-top: 6px; width: 30px; height: 30px;"></svg-icon></button>
         </div>
     <div class="board-wrap mt30">
         <div class="mb20 ">
@@ -177,57 +172,52 @@
 
 <script>
 import SvgIcon from '@jamescoyle/vue-icon';
-import { mdiMagnify,mdiPlus  } from '@mdi/js';
+import { mdiMagnify, mdiPlus } from '@mdi/js';
 import { mdilArrowRight } from '@mdi/light-js';
 import ProgressBar from '../../component/ProgressBar.vue';
-
+import axios from 'axios';
 
 export default {
     data() {
         return {
-            mdiPlus :mdiPlus ,
+            mdiPlus: mdiPlus,
             mdiMagnify: mdiMagnify,
             mdilArrowRight: mdilArrowRight,
-            timer: "00:00",
-            progress: 20
-        }
+            selectedBookId: this.$route.query.book_Id,
+            bookDetails: null,
+        };
     },
     methods: {
         goToPage(page) {
             this.$router.push({ name: page });
         },
-        increaseProgress() {
-            if (this.progress < 100) {
-                this.progress += 10;
-            }
-        },
-        showConfirm(type) {
-            let message = '';
-            if (type === 'delete') {
-                message = '삭제하시겠습니까?';
-            } else if (type === 'reset') {
-                message = '초기화하시겠습니까?';
-            } else if (type === 'save') {
-                message = '등록하시겠습니까?';
-            }
-
-            if (confirm(message)) {
-                this.goBack();
-            }
-        },
+        fetchBookDetails() {
+            axios({
+                url: "/book/find.json",
+                method: "post",
+                headers: {
+                    "Content-Type": "application/json; charset=UTF-8",
+                },
+                data: {
+                    book_id: this.$route.query.book_id
+                }
+            })
+            .then(response => {
+                console.log('Book details:', response.data);
+                this.bookDetails = response.data;
+            })
+            .catch(error => {
+                console.error('Error fetching book details:', error);
+            });
+        }
     },
-    watch: {
-
-    },
-    computed: {
-
+    mounted() {
+        console.log('Mounted with book_id:', this.$route.query.book_id);
+        this.fetchBookDetails();
     },
     components: {
         SvgIcon,
         ProgressBar
-    },
-    mounted() {
-        console.log('Main2 mounted');
     }
 }
 </script>
client/views/pages/teacher/textbook.vue
--- client/views/pages/teacher/textbook.vue
+++ client/views/pages/teacher/textbook.vue
@@ -1,61 +1,56 @@
 <template>
     <div class="title-box flex justify-between mb40">
-        <p class="title">교재</p>
-        <select name="" id="">
-            <option value="">A반</option>
-        </select>
+      <p class="title">교재</p>
     </div>
     <div class="content-t">
-        <div class="flex" style="gap: 2.5%;" :style="{flexWrap: 'wrap'}">
-            <div class="textbook" v-for="textbookItem in textbookList" :key="textbookItem.book_id" style="width: 22.5%; margin-bottom: 30px;">
-                <div class="box" style="gap: 10px;" @click="goToPage('TextBookDetail', textbookItem.book_id)">
-                </div>
-                <div class="text">
-                    <p class="title1" style="color: #fff;">{{ textbookItem.book_nm }}</p>
-                    <div class="btnGroup mt15 flex align-center justify-end" style="gap: 10px;">
-                        <button @click="editBook(textbookItem)">수정</button>
-                        <p>&#124;</p>
-                        <button @click="deleteBook(textbookItem.book_id)">삭제</button>
-                    </div>
-                </div>
+      <div class="flex" style="gap: 2.5%;" :style="{flexWrap: 'wrap'}">
+        <div class="textbook" v-for="textbookItem in textbookList" :key="textbookItem.book_id" style="width: 22.5%; margin-bottom: 30px;">
+          <div class="box" style="gap: 10px;" @click="goToPage('TextBookDetail', textbookItem.book_id)">
+          </div>
+          <div class="text">
+            <p class="title1" style="color: #fff;">{{ textbookItem.book_nm }}</p>
+            <div class="btnGroup mt15 flex align-center justify-end" style="gap: 10px;">
+              <button @click="editBook(textbookItem)">수정</button>
+              <p>&#124;</p>
+              <button @click="deleteBook(textbookItem.book_id)">삭제</button>
             </div>
-
-            <div class="textbook-add" style="width: 22.5%; margin-bottom: 30px;">
-                <button @click="buttonSearch">
-                    <img src="../../../resources/img/btn32_98t_normal.png" alt="">
-                </button>
-            </div>
-
-            <div v-show="searchOpen" class="popup-wrap">
-                <div class="popup-box">
-                    <div class="flex justify-between mb30">
-                        <p class="popup-title">교재 이름</p>
-                        <button type="button" class="popup-close-btn" @click="closeBtn">
-                            <svg-icon type="mdi" :path="mdiWindowClose" class="close-btn"></svg-icon>
-                        </button>
-                    </div>
-                    <div class="search-wrap mb30">
-                        <input type="text" class="data-wrap" v-model="newBookName" placeholder="교재 이름을 입력하세요">
-                        <button type="button" title="교재 검색" @click="insertBook">
-                            <img src="../../../resources/img/look_t.png" alt="">
-                        </button>
-                    </div>
-                    <div class="flex justify-center">
-                        <button type="button" title="취소" class="new-btn mr10" @click="closeBtn">
-                            취소
-                        </button>
-                        <button type="button" title="생성" class="new-btn" @click="editMode ? updateBook() : insertBook()">
-                            {{ editMode ? '수정' : '생성' }}
-                        </button>
-                    </div>
-                </div>
-            </div>
+          </div>
         </div>
+  
+        <div class="textbook-add" style="width: 22.5%; margin-bottom: 30px;">
+          <button @click="buttonSearch">
+            <img src="../../../resources/img/btn32_98t_normal.png" alt="">
+          </button>
+        </div>
+  
+        <div v-show="searchOpen" class="popup-wrap">
+          <div class="popup-box">
+            <div class="flex justify-between mb30">
+              <p class="popup-title">교재 이름</p>
+              <button type="button" class="popup-close-btn" @click="closeBtn">
+                <svg-icon type="mdi" :path="mdiWindowClose" class="close-btn"></svg-icon>
+              </button>
+            </div>
+            <div class="search-wrap mb30">
+              <input type="text" class="data-wrap" v-model="newBookName" placeholder="교재 이름을 입력하세요">
+              <button type="button" title="교재 검색" @click="insertBook">
+                <img src="../../../resources/img/look_t.png" alt="">
+              </button>
+            </div>
+            <div class="flex justify-center">
+              <button type="button" title="취소" class="new-btn mr10" @click="closeBtn">
+                취소
+              </button>
+              <button type="button" title="생성" class="new-btn" @click="editMode ? updateBook() : insertBook()">
+                {{ editMode ? '수정' : '생성' }}
+              </button>
+            </div>
+          </div>
+        </div>
+      </div>
     </div>
 </template>
-
-
-
+  
 <script>
 import SvgIcon from '@jamescoyle/vue-icon';
 import { mdiWindowClose } from '@mdi/js';
@@ -75,7 +70,7 @@
     },
     methods: {
         goToPage(page, book_id) {
-            this.$router.push({ name: page, query: { book_id }});
+            this.$router.push({ name: page, query: { book_id: book_id } });
         },
         buttonSearch() {
             this.searchOpen = true;
@@ -160,10 +155,7 @@
                     console.error('Error deleting book:', error);
                 });
             }
-        }
-    },
-    computed: {
-
+        },
     },
     components: {
         SvgIcon
@@ -188,4 +180,4 @@
 .textbook, .textbook-add {
     margin-bottom: 30px;
 }
-</style>
(파일 끝에 줄바꿈 문자 없음)
+</style>
Add a comment
List