![](/assets/images/project_default_logo.png)
![](/assets/images/default-avatar-128.png)
240812 권민수 단어장 조회 칼럼 개선 및 책 별, 단원 별 조회 기능 추가
@ebe9d176d2385f77fd474b211798b672174eaf35
--- client/resources/css/common.css
+++ client/resources/css/common.css
... | ... | @@ -934,6 +934,10 @@ |
934 | 934 |
color: #999999; |
935 | 935 |
} |
936 | 936 |
|
937 |
+.black { |
|
938 |
+ color: #000000; |
|
939 |
+} |
|
940 |
+ |
|
937 | 941 |
.cursor { |
938 | 942 |
cursor: pointer; |
939 | 943 |
} |
--- client/views/pages/AppRouter.js
+++ client/views/pages/AppRouter.js
... | ... | @@ -85,11 +85,7 @@ |
85 | 85 |
import TextDetail from "./teacher/TextDetail.vue"; |
86 | 86 |
import QuestionList from "./teacher/QuestionList.vue"; |
87 | 87 |
import QuestionInsert from "./teacher/QuestionInsert.vue"; |
88 |
-<<<<<<< HEAD |
|
89 |
-import QuestionDetail from "./teacher/QuestionDetail.vue"; |
|
90 |
-======= |
|
91 | 88 |
import QuestionDetail from "./teacher/QuestionDetail.vue"; |
92 |
->>>>>>> e47769b90c7ad4f0b34f38bb2a56a8a69a894941 |
|
93 | 89 |
import VocaList from "./teacher/VocaList.vue"; |
94 | 90 |
import VocaInsert from "./teacher/VocaInsert.vue"; |
95 | 91 |
import VocaDetail from "./teacher/VocaDetail.vue"; |
... | ... | @@ -198,11 +194,7 @@ |
198 | 194 |
{ path: '/TextDetail.page', name: 'TextDetail', component: TextDetail }, |
199 | 195 |
{ path: '/QuestionList.page', name: 'QuestionList', component: QuestionList }, |
200 | 196 |
{ path: '/QuestionInsert.page', name: 'QuestionInsert', component: QuestionInsert }, |
201 |
-<<<<<<< HEAD |
|
202 |
- { path: '/QuestionDetail.page', name: 'QuestionDetail', component: QuestionDetail }, |
|
203 |
-======= |
|
204 | 197 |
{ path: '/QuestionDetail.page', name: 'QuestionDetail', component: QuestionDetail }, |
205 |
->>>>>>> e47769b90c7ad4f0b34f38bb2a56a8a69a894941 |
|
206 | 198 |
{ path: '/VocaList.page', name: 'VocaList', component: VocaList }, |
207 | 199 |
{ path: '/VocaInsert.page', name: 'VocaInsert', component: VocaInsert }, |
208 | 200 |
{ path: '/VocaDetail.page', name: 'VocaDetail', component: VocaDetail }, |
--- client/views/pages/teacher/VocaList.vue
+++ client/views/pages/teacher/VocaList.vue
... | ... | @@ -1,18 +1,20 @@ |
1 | 1 |
<template> |
2 | 2 |
<div class="title-box flex justify-between mb40"> |
3 | 3 |
<p class="title">단어장</p> |
4 |
- <select name="" id=""> |
|
5 |
- <option value="UNIT_000000000000001">A교재</option> |
|
4 |
+ <select v-model="selectedBookId" @change="fetchUnits"> |
|
5 |
+ <option v-for="book in books" :key="book.book_id" :value="book.book_id"> |
|
6 |
+ {{ book.book_nm }} |
|
7 |
+ </option> |
|
6 | 8 |
</select> |
7 | 9 |
</div> |
8 | 10 |
<label for="" class="title2">단원</label> |
9 |
- <div class="unit-pagination flex mt10 mb20" style="gap: 10px;"> |
|
10 |
- <button class="selected-btn">1</button> |
|
11 |
- <button>2</button> |
|
12 |
- <button>3</button> |
|
13 |
- </div> |
|
11 |
+ <div class="unit-pagination flex mt10 mb20" style="gap: 10px;"> |
|
12 |
+ <button v-for="unit in units" :key="unit.unitId" @click="selectUnit(unit.unitId)" :class="{ 'selected-btn': selectedUnitId === unit.unitId }"> |
|
13 |
+ {{ unit.unitName }} |
|
14 |
+ </button> |
|
15 |
+ </div> |
|
14 | 16 |
<div class="search-wrap flex justify-between mb20 align-center"> |
15 |
- <div class="title2 gray">?단원 전체 목록</div> |
|
17 |
+ <div class="title2 gray flex"><div class="black">[{{ selectedUnitName }}]</div>단원 전체 목록</div> |
|
16 | 18 |
<div> |
17 | 19 |
<select name="" id="" class="mr10 data-wrap"> |
18 | 20 |
<option value="">지문</option> |
... | ... | @@ -31,15 +33,13 @@ |
31 | 33 |
<td>지문</td> |
32 | 34 |
<td>단어 목록</td> |
33 | 35 |
<td>작성자</td> |
34 |
- <td>등록일</td> |
|
35 | 36 |
</thead> |
36 | 37 |
<tbody> |
37 | 38 |
<tr v-for="(wordBook, index) in dataList" :key="wordBook.wdBookId" @click="goToViewPage('VocaDetail')"> |
38 | 39 |
<td>{{ createNo(index) }}</td> |
39 | 40 |
<td>{{ wordBook.textTtl }}</td> |
40 | 41 |
<td>{{ wordBook.wordsPreview }}</td> |
41 |
- <td>{{ wordBook.userId }}</td> |
|
42 |
- <td>{{ '' }}</td> |
|
42 |
+ <td>{{ wordBook.userNm }}</td> |
|
43 | 43 |
</tr> |
44 | 44 |
</tbody> |
45 | 45 |
</table> |
... | ... | @@ -55,7 +55,7 @@ |
55 | 55 |
</button> |
56 | 56 |
</article> |
57 | 57 |
<div class="flex justify-end "> |
58 |
- <button type="button" title="등록" class="new-btn" @click="goToPage('VocaInsert')"> |
|
58 |
+ <button type="button" title="등록" class="new-btn" @click="goToViewPage('VocaInsert')"> |
|
59 | 59 |
등록 |
60 | 60 |
</button> |
61 | 61 |
</div> |
... | ... | @@ -72,15 +72,57 @@ |
72 | 72 |
data () { |
73 | 73 |
return { |
74 | 74 |
mdiMagnify: mdiMagnify, |
75 |
+ books: [], |
|
76 |
+ units: [], |
|
77 |
+ selectedBookId: null, // 선택된 책 ID 저장 변수 |
|
78 |
+ selectedUnitId: null, // 선택된 단원 ID 저장 변수 |
|
79 |
+ selectedUnitName: '', // 선택된 단원의 이름 저장 변수 |
|
75 | 80 |
dataList: [], |
76 | 81 |
currentPage: 0, |
77 | 82 |
itemsPerPage: 2, |
78 |
- totalPosts: 0, |
|
79 |
- unitId: "UNIT_000000000000001" |
|
83 |
+ totalPosts: 0 |
|
80 | 84 |
} |
81 | 85 |
}, |
82 | 86 |
methods: { |
83 | 87 |
|
88 |
+ // 모든 책 목록을 가져오는 메서드 |
|
89 |
+ fetchBooks() { |
|
90 |
+ axios.post('/book/findAll.json') |
|
91 |
+ .then(response => { |
|
92 |
+ this.books = response.data; |
|
93 |
+ if (this.books.length > 0) { |
|
94 |
+ this.selectedBookId = this.books[1].book_id; // 두 번째 책을 선택하도록 기본 설정 |
|
95 |
+ this.fetchUnits(); // 책 선택 후 단원 목록 가져오기 |
|
96 |
+ } |
|
97 |
+ }) |
|
98 |
+ .catch(error => { |
|
99 |
+ console.error("책 목록 가져오기 실패: ", error); |
|
100 |
+ }); |
|
101 |
+ }, |
|
102 |
+ |
|
103 |
+ // 선택된 책의 단원 목록을 가져오는 메서드 |
|
104 |
+ fetchUnits() { |
|
105 |
+ axios.post('/unit/unitList.json', { bookId: this.selectedBookId }) |
|
106 |
+ .then(response => { |
|
107 |
+ this.units = response.data; |
|
108 |
+ if (this.units.length > 0) { |
|
109 |
+ this.selectUnit(this.units[4].unitId); // 다섯 번째 단원을 선택하도록 기본 설정 |
|
110 |
+ } |
|
111 |
+ }) |
|
112 |
+ .catch(error => { |
|
113 |
+ console.error("단원 목록 가져오기 실패: ", error); |
|
114 |
+ }); |
|
115 |
+ }, |
|
116 |
+ |
|
117 |
+ // 단원을 선택했을 때 호출되는 메서드 |
|
118 |
+ selectUnit(unitId) { |
|
119 |
+ this.selectedUnitId = unitId; |
|
120 |
+ const selectedUnit = this.units.find(unit => unit.unitId === unitId); |
|
121 |
+ this.selectedUnitName = selectedUnit ? selectedUnit.unitName : ''; |
|
122 |
+ this.dataSelectList(); // 단어장 목록 조회 |
|
123 |
+ }, |
|
124 |
+ |
|
125 |
+ // 단어장 목록 조회 메서드 |
|
84 | 126 |
dataSelectList() { |
85 | 127 |
const vm = this; |
86 | 128 |
axios({ |
... | ... | @@ -90,7 +132,7 @@ |
90 | 132 |
"Content-Type": "application/json; charset=UTF-8", |
91 | 133 |
}, |
92 | 134 |
data: { |
93 |
- unitId: vm.unitId, |
|
135 |
+ unitId: vm.selectedUnitId, |
|
94 | 136 |
page: vm.currentPage + 1, |
95 | 137 |
pageSize: vm.itemsPerPage |
96 | 138 |
}, |
... | ... | @@ -134,6 +176,8 @@ |
134 | 176 |
alert("단어장 목록 조회에 오류가 발생했습니다."); |
135 | 177 |
}); |
136 | 178 |
}, |
179 |
+ |
|
180 |
+ // 단어 목록 생략 String 생성 메서드 |
|
137 | 181 |
generateWordsPreview(words) { |
138 | 182 |
const maxLength = 20; // 최대 표시 길이 설정 |
139 | 183 |
const wordString = words.join(', '); |
... | ... | @@ -144,9 +188,13 @@ |
144 | 188 |
return wordString; |
145 | 189 |
} |
146 | 190 |
}, |
191 |
+ |
|
192 |
+ // 단어장 NO 생성 메서드 |
|
147 | 193 |
createNo(index) { |
148 | 194 |
return this.totalPosts - (this.currentPage * this.itemsPerPage + index); |
149 | 195 |
}, |
196 |
+ |
|
197 |
+ // 페이지네이션 이동 메서드 |
|
150 | 198 |
goToPage(page) { |
151 | 199 |
if (page < 0 || page >= this.totalPages) { |
152 | 200 |
return; |
... | ... | @@ -154,6 +202,8 @@ |
154 | 202 |
this.currentPage = page; |
155 | 203 |
this.dataSelectList(); |
156 | 204 |
}, |
205 |
+ |
|
206 |
+ // 페이지 이동 메서드 |
|
157 | 207 |
goToViewPage(page) { |
158 | 208 |
this.$router.push({ name: page }); |
159 | 209 |
}, |
... | ... | @@ -184,7 +234,7 @@ |
184 | 234 |
}, |
185 | 235 |
mounted() { |
186 | 236 |
console.log('Voca Book List Component mounted'); |
187 |
- this.dataSelectList(); |
|
237 |
+ this.fetchBooks(); |
|
188 | 238 |
} |
189 | 239 |
} |
190 | 240 |
</script>(No newline at end of file) |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?