

240808 박세훈 게시판 상세화면 페이지
@ba5e61fce676b8c347244844cdad82ca5b98d0bc
--- client/views/layout/Header.vue
+++ client/views/layout/Header.vue
... | ... | @@ -102,7 +102,7 @@ |
102 | 102 |
|
103 | 103 |
// 페이징 정보 |
104 | 104 |
page: 1, |
105 |
- pageSize: 3, |
|
105 |
+ pageSize: 2, |
|
106 | 106 |
totalpages: null, |
107 | 107 |
|
108 | 108 |
// 사용자 정보 |
--- client/views/pages/teacher/Board.vue
+++ client/views/pages/teacher/Board.vue
... | ... | @@ -38,7 +38,7 @@ |
38 | 38 |
:class="{ 'selected-row': selectedRow == item.dataList }" |
39 | 39 |
@click="[goToPage('noticeDetail'), selectBoardList(item)]" |
40 | 40 |
> |
41 |
- <td>{{ totalBoard - index }}</td> |
|
41 |
+ <td>{{ createNo(index) }}</td> |
|
42 | 42 |
<td>{{ item.bbsTtl }}</td> |
43 | 43 |
<td>{{ item.bbsCls }}</td> |
44 | 44 |
<td>{{ userNm }}</td> |
... | ... | @@ -50,22 +50,19 @@ |
50 | 50 |
class="table-pagination flex justify-center align-center mb20 mt30" |
51 | 51 |
style="gap: 10px" |
52 | 52 |
> |
53 |
- <button> |
|
54 |
- <img |
|
55 |
- src="../../../resources/img/btn27_90t_normal.png" |
|
56 |
- alt="" |
|
57 |
- @click="previousPage" |
|
58 |
- :disabled="page === 1" |
|
59 |
- /> |
|
53 |
+ <button @click="goToPagination(currentPage - 1)"> |
|
54 |
+ <img src="../../../resources/img/btn27_90t_normal.png" alt="" /> |
|
60 | 55 |
</button> |
61 |
- <button class="selected-btn">{{ page }}</button> |
|
62 |
- <button> |
|
63 |
- <img |
|
64 |
- src="../../../resources/img/btn28_90t_normal.png" |
|
65 |
- alt="" |
|
66 |
- @click="nextPage" |
|
67 |
- :disabled="page === totalPages" |
|
68 |
- /> |
|
56 |
+ <button |
|
57 |
+ v-for="page in paginationButtons" |
|
58 |
+ :key="page" |
|
59 |
+ @click="goToPagination(page - 1)" |
|
60 |
+ :class="{ 'selected-btn': currentPage === page - 1 }" |
|
61 |
+ > |
|
62 |
+ {{ page }} |
|
63 |
+ </button> |
|
64 |
+ <button @click="goToPagination(currentPage + 1)"> |
|
65 |
+ <img src="../../../resources/img/btn28_90t_normal.png" alt="" /> |
|
69 | 66 |
</button> |
70 | 67 |
</article> |
71 | 68 |
<div class="flex justify-end"> |
... | ... | @@ -93,13 +90,12 @@ |
93 | 90 |
|
94 | 91 |
// 게시글 정보 |
95 | 92 |
dataList: [], |
96 |
- totalBoard: null, |
|
93 |
+ totalPosts: 0, |
|
97 | 94 |
selectedRow: "", |
98 | 95 |
|
99 | 96 |
// 페이징 |
100 |
- page: 1, |
|
101 |
- pageSize: 8, |
|
102 |
- totalPages: null, |
|
97 |
+ currentPage: 0, |
|
98 |
+ itemsPerPage: 8, |
|
103 | 99 |
|
104 | 100 |
// 반 아이디 (추후 세션에서 받는걸로 수정) |
105 | 101 |
sclsId: "1", |
... | ... | @@ -137,21 +133,22 @@ |
137 | 133 |
headers: { |
138 | 134 |
"Content-Type": "application/json; charset=UTF-8", |
139 | 135 |
}, |
140 |
- data: { page: vm.page, pageSize: vm.pageSize, sclsId: vm.sclsId }, |
|
136 |
+ data: { |
|
137 |
+ page: vm.currentPage + 1, |
|
138 |
+ pageSize: vm.itemsPerPage, |
|
139 |
+ sclsId: vm.sclsId, |
|
140 |
+ }, |
|
141 | 141 |
}) |
142 | 142 |
.then(function (res) { |
143 | 143 |
console.log("dataList - response : ", res.data); |
144 |
- console.log(res.data.result[0].boardClass[0].board); |
|
145 | 144 |
|
146 | 145 |
vm.dataList = res.data.result[0].boardClass[0].board; |
147 | 146 |
vm.userNm = res.data.result[0].userNm; |
148 | 147 |
vm.userId = res.data.result[0].userId; |
149 |
- vm.totalBoard = res.data.totalBoard; |
|
150 |
- vm.totalPages = Math.ceil(vm.totalBoard / vm.pageSize); |
|
148 |
+ vm.totalPosts = res.data.totalBoard; |
|
151 | 149 |
}) |
152 | 150 |
.catch(function (error) { |
153 | 151 |
console.log("result - error : ", error); |
154 |
- alert("비상 비상!"); |
|
155 | 152 |
}); |
156 | 153 |
}, |
157 | 154 |
|
... | ... | @@ -171,8 +168,8 @@ |
171 | 168 |
let searchPayload = { |
172 | 169 |
keyword: vm.searchKeyword, |
173 | 170 |
option: vm.selectedSearchOption, |
174 |
- page: vm.page, |
|
175 |
- pageSize: vm.pageSize, |
|
171 |
+ page: vm.currentPage, |
|
172 |
+ pageSize: vm.itemsPerPage, |
|
176 | 173 |
sclsId: vm.sclsId, |
177 | 174 |
}; |
178 | 175 |
axios({ |
... | ... | @@ -188,7 +185,7 @@ |
188 | 185 |
vm.dataList = res.data.result[0].boardClass[0].board; |
189 | 186 |
vm.userNm = res.data.result[0].userNm; |
190 | 187 |
vm.userId = res.data.result[0].userId; |
191 |
- vm.totalBoard = res.data.totalBoard; |
|
188 |
+ vm.totalPosts = res.data.totalBoard; |
|
192 | 189 |
}) |
193 | 190 |
.catch(function (error) { |
194 | 191 |
console.log("dataSearch - error : ", error); |
... | ... | @@ -196,22 +193,37 @@ |
196 | 193 |
}); |
197 | 194 |
}, |
198 | 195 |
|
199 |
- previousPage() { |
|
200 |
- if (this.page > 1) { |
|
201 |
- this.page -= 1; |
|
202 |
- this.boardList(); |
|
203 |
- } |
|
196 |
+ createNo(index) { |
|
197 |
+ return this.totalPosts - (this.currentPage * this.itemsPerPage + index); |
|
204 | 198 |
}, |
205 | 199 |
|
206 |
- nextPage() { |
|
207 |
- if (this.page < this.totalPages) { |
|
208 |
- this.page += 1; |
|
209 |
- this.boardList(); |
|
200 |
+ goToPagination(page) { |
|
201 |
+ if (page < 0 || page >= this.totalPages) { |
|
202 |
+ return; |
|
210 | 203 |
} |
204 |
+ this.currentPage = page; |
|
205 |
+ this.boardList(); |
|
211 | 206 |
}, |
212 | 207 |
}, |
213 | 208 |
watch: {}, |
214 |
- computed: {}, |
|
209 |
+ computed: { |
|
210 |
+ totalPages() { |
|
211 |
+ return Math.ceil(this.totalPosts / this.itemsPerPage); |
|
212 |
+ }, |
|
213 |
+ paginationButtons() { |
|
214 |
+ let start = Math.max(0, this.currentPage - 2); |
|
215 |
+ let end = Math.min(start + 5, this.totalPages); |
|
216 |
+ |
|
217 |
+ if (end - start < 5) { |
|
218 |
+ start = Math.max(0, end - 5); |
|
219 |
+ } |
|
220 |
+ |
|
221 |
+ return Array.from({ length: end - start }, (_, i) => start + i + 1); |
|
222 |
+ }, |
|
223 |
+ startIndex() { |
|
224 |
+ return this.currentPage * this.itemsPerPage; |
|
225 |
+ }, |
|
226 |
+ }, |
|
215 | 227 |
components: { |
216 | 228 |
SvgIcon, |
217 | 229 |
}, |
--- client/views/pages/teacher/noticeDetail.vue
+++ client/views/pages/teacher/noticeDetail.vue
... | ... | @@ -1,78 +1,200 @@ |
1 | 1 |
<template> |
2 |
- <div class="title-box flex justify-between mb40"> |
|
3 |
- <p class="title">공지 등록</p> |
|
2 |
+ <div class="title-box flex justify-between mb40"> |
|
3 |
+ <p class="title">{{ dataList.bbsCls }}</p> |
|
4 |
+ </div> |
|
5 |
+ <div class="board-wrap"> |
|
6 |
+ <div class="flex align-center"> |
|
7 |
+ <label for="" class="title2">{{ dataList.bbsTtl }}</label> |
|
4 | 8 |
</div> |
5 |
- <div class="board-wrap"> |
|
6 |
- <div class="flex align-center"> |
|
7 |
- <label for="" class="title2">제목</label> |
|
8 |
- <input type="text" class="data-wrap"> |
|
9 |
- </div> |
|
10 |
- <hr> |
|
11 |
- <textarea name="" id=""></textarea> |
|
12 |
- <hr> |
|
13 |
- <div class="flex align-center"> |
|
14 |
- <label for="" class="title2">첨부파일</label> |
|
15 |
- <input type="file" ref="fileInput" @change="handleFileUpload" /> |
|
16 |
- </div> |
|
17 |
- <hr> |
|
18 |
- <div class="flex justify-between"> |
|
19 |
- <button type="button" class="flex align-center"> |
|
20 |
- <svg-icon type="mdi" :path="mdilChevronLeft" ></svg-icon> |
|
21 |
- <p> 이전글</p> |
|
22 |
- </button> |
|
23 |
- <button type="button" class="flex align-center"><p>다음글</p> |
|
24 |
- <svg-icon type="mdi" :path="mdilChevronRight" ></svg-icon> |
|
25 |
- |
|
26 |
- </button> |
|
27 |
- |
|
28 |
- |
|
29 |
- </div> |
|
30 |
- </div> |
|
31 |
- <div class="flex justify-between mt50"> |
|
32 |
- <button type="button" title="글쓰기" class="new-btn" @click="goToPage('Board')"> |
|
33 |
- 목록 |
|
34 |
- </button> |
|
35 |
- <div class="flex"> |
|
36 |
- <button type="button" title="글쓰기" class="new-btn mr10" > |
|
37 |
- 수정 |
|
38 |
- </button> |
|
39 |
- <button type="button" title="글쓰기" class="new-btn" > |
|
40 |
- 삭제 |
|
41 |
- </button> |
|
42 |
- </div> |
|
43 |
- </div> |
|
9 |
+ <hr /> |
|
10 |
+ <textarea readonly name="" id="">{{ dataList.bbsCnt }}</textarea> |
|
11 |
+ <hr /> |
|
12 |
+ <div class="flex align-center"> |
|
13 |
+ <label for="" class="title2">첨부파일</label> |
|
14 |
+ <label for="" class="title2" v-if="file">{{ file.fileNm }}</label> |
|
15 |
+ </div> |
|
16 |
+ <hr /> |
|
17 |
+ <div class="flex justify-between"> |
|
18 |
+ <button type="button" class="flex align-center" @click="prevBoard()"> |
|
19 |
+ <svg-icon type="mdi" :path="mdilChevronLeft"></svg-icon> |
|
20 |
+ <p>이전글</p> |
|
21 |
+ </button> |
|
22 |
+ <button type="button" class="flex align-center" @click="nextBoard()"> |
|
23 |
+ <p>다음글</p> |
|
24 |
+ <svg-icon type="mdi" :path="mdilChevronRight"></svg-icon> |
|
25 |
+ </button> |
|
26 |
+ </div> |
|
27 |
+ </div> |
|
28 |
+ <div class="flex justify-between mt50"> |
|
29 |
+ <button |
|
30 |
+ type="button" |
|
31 |
+ title="글쓰기" |
|
32 |
+ class="new-btn" |
|
33 |
+ @click="goToPage('Board')" |
|
34 |
+ > |
|
35 |
+ 목록 |
|
36 |
+ </button> |
|
37 |
+ <div class="flex"> |
|
38 |
+ <button type="button" title="글쓰기" class="new-btn mr10">수정</button> |
|
39 |
+ <button |
|
40 |
+ type="button" |
|
41 |
+ title="글쓰기" |
|
42 |
+ class="new-btn" |
|
43 |
+ @click="[deleteBoard(), goToPage('Board')]" |
|
44 |
+ > |
|
45 |
+ 삭제 |
|
46 |
+ </button> |
|
47 |
+ </div> |
|
48 |
+ </div> |
|
44 | 49 |
</template> |
45 | 50 |
|
46 | 51 |
<script> |
47 |
-import SvgIcon from '@jamescoyle/vue-icon'; |
|
48 |
-import { mdiMagnify } from '@mdi/js'; |
|
49 |
-import { mdilChevronRight,mdilChevronLeft } from '@mdi/light-js'; |
|
50 |
- |
|
52 |
+import SvgIcon from "@jamescoyle/vue-icon"; |
|
53 |
+import { mdiMagnify } from "@mdi/js"; |
|
54 |
+import { mdilChevronRight, mdilChevronLeft } from "@mdi/light-js"; |
|
55 |
+import axios from "axios"; |
|
51 | 56 |
|
52 | 57 |
export default { |
53 |
- data () { |
|
54 |
- return { |
|
55 |
- mdiMagnify: mdiMagnify, |
|
56 |
- mdilChevronRight: mdilChevronRight , |
|
57 |
- mdilChevronLeft:mdilChevronLeft, |
|
58 |
- } |
|
59 |
- }, |
|
60 |
- methods: { |
|
61 |
- goToPage(page) { |
|
62 |
- this.$router.push({ name: page }); |
|
63 |
- }, |
|
64 |
- }, |
|
65 |
- watch: { |
|
58 |
+ data() { |
|
59 |
+ return { |
|
60 |
+ mdiMagnify: mdiMagnify, |
|
61 |
+ mdilChevronRight: mdilChevronRight, |
|
62 |
+ mdilChevronLeft: mdilChevronLeft, |
|
66 | 63 |
|
64 |
+ dataList: null, |
|
65 |
+ sclsId: "", |
|
66 |
+ |
|
67 |
+ title: "", |
|
68 |
+ content: "", |
|
69 |
+ category: "", |
|
70 |
+ file: "", |
|
71 |
+ user: "", |
|
72 |
+ }; |
|
73 |
+ }, |
|
74 |
+ methods: { |
|
75 |
+ goToPage(page) { |
|
76 |
+ this.$router.push({ name: page }); |
|
67 | 77 |
}, |
68 |
- computed: { |
|
69 |
- |
|
78 |
+ created() { |
|
79 |
+ const vm = this; |
|
80 |
+ const seletedBoardList = JSON.parse( |
|
81 |
+ sessionStorage.getItem("selectedBoardList") |
|
82 |
+ ); |
|
83 |
+ |
|
84 |
+ if (seletedBoardList) { |
|
85 |
+ vm.dataList = seletedBoardList; |
|
86 |
+ } |
|
87 |
+ console.log(vm.dataList); |
|
70 | 88 |
}, |
71 |
- components:{ |
|
72 |
- SvgIcon |
|
89 |
+ |
|
90 |
+ findFile() { |
|
91 |
+ const vm = this; |
|
92 |
+ axios({ |
|
93 |
+ url: "/file/find.json", |
|
94 |
+ method: "post", |
|
95 |
+ headers: { |
|
96 |
+ "Content-Type": "application/json; charset=UTF-8", |
|
97 |
+ }, |
|
98 |
+ data: { |
|
99 |
+ file_mng_id: vm.dataList.fileMngId, |
|
100 |
+ }, |
|
101 |
+ }) |
|
102 |
+ .then(function (res) { |
|
103 |
+ console.log("fileInfo - response : ", res.data.list[0]); |
|
104 |
+ vm.file = res.data.list[0]; |
|
105 |
+ }) |
|
106 |
+ .catch(function (error) { |
|
107 |
+ console.log("result - error : ", error); |
|
108 |
+ }); |
|
73 | 109 |
}, |
74 |
- mounted() { |
|
75 |
- console.log('Main2 mounted'); |
|
76 |
- } |
|
77 |
-} |
|
78 |
-</script>(No newline at end of file) |
|
110 |
+ |
|
111 |
+ prevBoard() { |
|
112 |
+ const vm = this; |
|
113 |
+ axios({ |
|
114 |
+ url: "/board/prevBoard.json", |
|
115 |
+ method: "post", |
|
116 |
+ headers: { |
|
117 |
+ "Content-Type": "application/json; charset=UTF-8", |
|
118 |
+ }, |
|
119 |
+ data: { |
|
120 |
+ sclsId: vm.dataList.sclsId, |
|
121 |
+ bbsId: vm.dataList.bbsId, |
|
122 |
+ }, |
|
123 |
+ }) |
|
124 |
+ .then(function (res) { |
|
125 |
+ console.log("dataList - response : ", res.data); |
|
126 |
+ vm.dataList = res.data[0].boardClass[0].board[0]; |
|
127 |
+ sessionStorage.setItem( |
|
128 |
+ "selectedBoardList", |
|
129 |
+ JSON.stringify(vm.dataList) |
|
130 |
+ ); |
|
131 |
+ vm.findFile(); |
|
132 |
+ console.log(vm.dataList); |
|
133 |
+ }) |
|
134 |
+ .catch(function (error) { |
|
135 |
+ console.log("result - error : ", error); |
|
136 |
+ alert("첫번째 글 입니다."); |
|
137 |
+ }); |
|
138 |
+ }, |
|
139 |
+ |
|
140 |
+ nextBoard() { |
|
141 |
+ const vm = this; |
|
142 |
+ axios({ |
|
143 |
+ url: "/board/nextBoard.json", |
|
144 |
+ method: "post", |
|
145 |
+ headers: { |
|
146 |
+ "Content-Type": "application/json; charset=UTF-8", |
|
147 |
+ }, |
|
148 |
+ data: { |
|
149 |
+ sclsId: vm.dataList.sclsId, |
|
150 |
+ bbsId: vm.dataList.bbsId, |
|
151 |
+ }, |
|
152 |
+ }) |
|
153 |
+ .then(function (res) { |
|
154 |
+ console.log("dataList - response : ", res.data); |
|
155 |
+ vm.dataList = res.data[0].boardClass[0].board[0]; |
|
156 |
+ sessionStorage.setItem( |
|
157 |
+ "selectedBoardList", |
|
158 |
+ JSON.stringify(vm.dataList) |
|
159 |
+ ); |
|
160 |
+ vm.findFile(); |
|
161 |
+ console.log(vm.dataList); |
|
162 |
+ }) |
|
163 |
+ .catch(function (error) { |
|
164 |
+ console.log("result - error : ", error); |
|
165 |
+ alert("가장 최신 글 입니다."); |
|
166 |
+ }); |
|
167 |
+ }, |
|
168 |
+ deleteBoard() { |
|
169 |
+ const vm = this; |
|
170 |
+ axios({ |
|
171 |
+ url: "/board/delete.json", |
|
172 |
+ method: "post", |
|
173 |
+ headers: { |
|
174 |
+ "Content-Type": "application/json; charset=UTF-8", |
|
175 |
+ }, |
|
176 |
+ data: { |
|
177 |
+ bbsId: vm.dataList.bbsId, |
|
178 |
+ }, |
|
179 |
+ }) |
|
180 |
+ .then(function (res) { |
|
181 |
+ console.log("delete - response : ", res.data); |
|
182 |
+ alert("삭제 되었습니다."); |
|
183 |
+ }) |
|
184 |
+ .catch(function (error) { |
|
185 |
+ console.log("rssult - error : ", error); |
|
186 |
+ }); |
|
187 |
+ }, |
|
188 |
+ }, |
|
189 |
+ watch: {}, |
|
190 |
+ computed: {}, |
|
191 |
+ components: { |
|
192 |
+ SvgIcon, |
|
193 |
+ }, |
|
194 |
+ mounted() { |
|
195 |
+ console.log("Main2 mounted"); |
|
196 |
+ this.created(); |
|
197 |
+ this.findFile(); |
|
198 |
+ }, |
|
199 |
+}; |
|
200 |
+</script> |
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?