콘텐츠 카테고리 관리 UI 추가
This commit is contained in:
		
							
								
								
									
										28
									
								
								src/api/category.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/api/category.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| import Vue from 'vue'; | ||||
|  | ||||
| async function saveCategory(title) { | ||||
|     return Vue.axios.post('/category', {title: title, contentIdList: []}); | ||||
| } | ||||
|  | ||||
| async function modifyCategory(title, categoryId) { | ||||
|     return Vue.axios.put('/category', { | ||||
|         categoryId: categoryId, | ||||
|         title: title, | ||||
|         addContentIdList: [], | ||||
|         removeContentIdList: [] | ||||
|     }); | ||||
| } | ||||
|  | ||||
| async function deleteCategory(categoryId) { | ||||
|     return Vue.axios.delete('/category/' + categoryId) | ||||
| } | ||||
|  | ||||
| async function getCategoryList(creatorId) { | ||||
|     return Vue.axios.get('/category?creatorId=' + creatorId) | ||||
| } | ||||
|  | ||||
| async function updateCategoryOrders(ids) { | ||||
|     return Vue.axios.put('/category/orders', {ids: ids}) | ||||
| } | ||||
|  | ||||
| export {saveCategory, modifyCategory, deleteCategory, getCategoryList, updateCategoryOrders} | ||||
| @@ -20,6 +20,11 @@ const routes = [ | ||||
|                 name: 'ContentList', | ||||
|                 component: () => import(/* webpackChunkName: "content" */ '../views/Content/ContentList.vue') | ||||
|             }, | ||||
|             { | ||||
|                 path: '/content/category/list', | ||||
|                 name: 'ContentCategoryList', | ||||
|                 component: () => import(/* webpackChunkName: "content" */ '../views/Content/ContentCategoryList.vue') | ||||
|             }, | ||||
|             { | ||||
|                 path: '/calculate/live', | ||||
|                 name: 'CalculateLive', | ||||
|   | ||||
							
								
								
									
										390
									
								
								src/views/Content/ContentCategoryList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										390
									
								
								src/views/Content/ContentCategoryList.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,390 @@ | ||||
| <template> | ||||
|   <div> | ||||
|     <v-container> | ||||
|       <v-row> | ||||
|         <v-col cols="3"> | ||||
|           <v-btn | ||||
|             block | ||||
|             color="#3bb9f1" | ||||
|             dark | ||||
|             depressed | ||||
|             @click="showCreateCategoryDialog" | ||||
|           > | ||||
|             카테고리 추가 | ||||
|           </v-btn> | ||||
|           <br><br> | ||||
|           <draggable | ||||
|             :list="category_list" | ||||
|             class="list-group" | ||||
|             @end="onDropCategoryCallback()" | ||||
|           > | ||||
|             <v-list | ||||
|               v-for="category in category_list" | ||||
|               :key="category.category" | ||||
|               class="py-0" | ||||
|               rounded | ||||
|             > | ||||
|               <v-list-item :class="{ 'category-selected-item': category === selected_category }"> | ||||
|                 <v-list-item-title @click="clickCategory(category)"> | ||||
|                   {{ category.category }} | ||||
|                 </v-list-item-title> | ||||
|                 <v-list-item-icon @click="clickModifyCategory(category)"> | ||||
|                   <v-icon>mdi-pencil</v-icon> | ||||
|                 </v-list-item-icon> | ||||
|               </v-list-item> | ||||
|             </v-list> | ||||
|           </draggable> | ||||
|         </v-col> | ||||
|         <v-col cols="1" /> | ||||
|         <v-col cols="8"> | ||||
|           <v-row> | ||||
|             <v-col cols="9" /> | ||||
|             <v-col cols="3"> | ||||
|               <v-btn | ||||
|                 block | ||||
|                 color="#3bb9f1" | ||||
|                 dark | ||||
|                 depressed | ||||
|                 @click="showAddContent" | ||||
|               > | ||||
|                 콘텐츠 추가 | ||||
|               </v-btn> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|           <br><br> | ||||
|           <p v-if="selected_category !== null && selected_category !== undefined"> | ||||
|             선택된 카테고리 : {{ selected_category.category }} | ||||
|           </p> | ||||
|           <p v-else> | ||||
|             카테고리를 선택해 주세요 | ||||
|           </p> | ||||
|           <v-data-table | ||||
|             :headers="headers" | ||||
|             :items="content_list" | ||||
|             :loading="is_loading" | ||||
|             :items-per-page="-1" | ||||
|             item-key="id" | ||||
|             class="elevation-1" | ||||
|             hide-default-footer | ||||
|           > | ||||
|             <template v-slot:body="props"> | ||||
|               <draggable | ||||
|                 v-model="props.items" | ||||
|                 tag="tbody" | ||||
|               > | ||||
|                 <tr | ||||
|                   v-for="(item, index) in props.items" | ||||
|                   :key="index" | ||||
|                 > | ||||
|                   <td> | ||||
|                     <img | ||||
|                       :src="item.image" | ||||
|                       alt="" | ||||
|                       height="100" | ||||
|                       width="100" | ||||
|                     > | ||||
|                   </td> | ||||
|                   <td><h3>{{ item.title }}</h3></td> | ||||
|                   <td> | ||||
|                     <h3 v-if="item.isAdult"> | ||||
|                       O | ||||
|                     </h3> | ||||
|                     <h3 v-else> | ||||
|                       X | ||||
|                     </h3> | ||||
|                   </td> | ||||
|                   <td> | ||||
|                     <v-btn | ||||
|                       :disabled="is_loading" | ||||
|                     > | ||||
|                       삭제 | ||||
|                     </v-btn> | ||||
|                   </td> | ||||
|                 </tr> | ||||
|               </draggable> | ||||
|             </template> | ||||
|           </v-data-table> | ||||
|         </v-col> | ||||
|       </v-row> | ||||
|     </v-container> | ||||
|  | ||||
|     <v-container> | ||||
|       <v-row> | ||||
|         <v-dialog | ||||
|           v-model="show_create_category_dialog" | ||||
|           max-width="1000px" | ||||
|           persistent | ||||
|         > | ||||
|           <v-card> | ||||
|             <v-card-title v-if="modify_category"> | ||||
|               카테고리 수정 | ||||
|             </v-card-title> | ||||
|             <v-card-title v-else> | ||||
|               카테고리 추가 | ||||
|             </v-card-title> | ||||
|             <v-card-text> | ||||
|               <v-text-field | ||||
|                 v-model="title" | ||||
|                 label="카테고리 제목" | ||||
|                 required | ||||
|               /> | ||||
|             </v-card-text> | ||||
|             <v-card-actions v-show="!is_loading"> | ||||
|               <v-spacer /> | ||||
|               <v-btn | ||||
|                 color="blue darken-1" | ||||
|                 text | ||||
|                 @click="cancelCreateCategory" | ||||
|               > | ||||
|                 취소 | ||||
|               </v-btn> | ||||
|               <v-btn | ||||
|                 v-if="modify_category" | ||||
|                 color="blue darken-1" | ||||
|                 text | ||||
|                 @click="deleteCategory" | ||||
|               > | ||||
|                 삭제 | ||||
|               </v-btn> | ||||
|               <v-btn | ||||
|                 v-if="modify_category" | ||||
|                 color="blue darken-1" | ||||
|                 text | ||||
|                 @click="modifyCategory" | ||||
|               > | ||||
|                 수정 | ||||
|               </v-btn> | ||||
|               <v-btn | ||||
|                 v-else | ||||
|                 color="blue darken-1" | ||||
|                 text | ||||
|                 @click="saveCategory" | ||||
|               > | ||||
|                 등록 | ||||
|               </v-btn> | ||||
|             </v-card-actions> | ||||
|           </v-card> | ||||
|         </v-dialog> | ||||
|       </v-row> | ||||
|     </v-container> | ||||
|  | ||||
|     <v-container> | ||||
|       <v-row /> | ||||
|     </v-container> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import Draggable from 'vuedraggable'; | ||||
|  | ||||
| import * as api from "@/api/category"; | ||||
|  | ||||
| export default { | ||||
|   name: "ContentCategoryList", | ||||
|   components: {Draggable}, | ||||
|   data() { | ||||
|     return { | ||||
|       is_loading: false, | ||||
|       show_add_content_dialog: false, | ||||
|       show_create_category_dialog: false, | ||||
|       modify_category: false, | ||||
|  | ||||
|       title: '', | ||||
|       selected_category: null, | ||||
|       modify_selected_category: null, | ||||
|  | ||||
|       category_list: [], | ||||
|       content_list: [], | ||||
|  | ||||
|       headers: [ | ||||
|         { | ||||
|           text: '커버이미지', | ||||
|           align: 'center', | ||||
|           sortable: false, | ||||
|           value: 'image', | ||||
|         }, | ||||
|         { | ||||
|           text: '제목', | ||||
|           align: 'center', | ||||
|           sortable: false, | ||||
|           value: 'title', | ||||
|         }, | ||||
|         { | ||||
|           text: '19금', | ||||
|           align: 'center', | ||||
|           sortable: false, | ||||
|           value: 'isAdult', | ||||
|         }, | ||||
|         { | ||||
|           text: '관리', | ||||
|           align: 'center', | ||||
|           sortable: false, | ||||
|           value: 'management' | ||||
|         }, | ||||
|       ] | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   async created() { | ||||
|     await this.getCategoryList() | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     notifyError(message) { | ||||
|       this.$dialog.notify.error(message) | ||||
|     }, | ||||
|  | ||||
|     notifySuccess(message) { | ||||
|       this.$dialog.notify.success(message) | ||||
|     }, | ||||
|  | ||||
|     showCreateCategoryDialog() { | ||||
|       if (this.category_list.length >= 10) { | ||||
|         this.notifyError('카테고리는 최대 10개 까지 등록 가능합니다.') | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       this.show_create_category_dialog = true | ||||
|     }, | ||||
|  | ||||
|     showAddContent() { | ||||
|       if (this.selected_category === null || this.selected_category === undefined) { | ||||
|         this.notifyError('카테고리를 선택하세요') | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       this.show_add_content_dialog = true | ||||
|     }, | ||||
|  | ||||
|     cancelCreateCategory() { | ||||
|       this.title = '' | ||||
|       this.modify_category = false | ||||
|       this.modify_selected_category = null | ||||
|       this.show_create_category_dialog = false | ||||
|     }, | ||||
|  | ||||
|     clickCategory(category) { | ||||
|       this.selected_category = category | ||||
|     }, | ||||
|  | ||||
|     clickModifyCategory(category) { | ||||
|       this.modify_category = true | ||||
|       this.modify_selected_category = category | ||||
|  | ||||
|       this.title = category.category | ||||
|       this.show_create_category_dialog = true | ||||
|     }, | ||||
|  | ||||
|     async getCategoryList() { | ||||
|       this.is_loading = true | ||||
|  | ||||
|       try { | ||||
|         let res = await api.getCategoryList(this.$store.state.accountStore.userId) | ||||
|         if (res.data.success === true) { | ||||
|           this.category_list = res.data.data | ||||
|         } else { | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async saveCategory() { | ||||
|       if (this.title.trim().length <= 0) { | ||||
|         this.notifyError("제목을 입력하세요") | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       if (this.is_loading) return; | ||||
|  | ||||
|       try { | ||||
|         this.is_loading = true | ||||
|         let res = await api.saveCategory(this.title) | ||||
|         if (res.data.success === true) { | ||||
|           this.title = '' | ||||
|           this.category_list = [] | ||||
|           this.selected_category = null | ||||
|           this.cancelCreateCategory() | ||||
|           await this.getCategoryList() | ||||
|         } else { | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async deleteCategory() { | ||||
|       try { | ||||
|         this.is_loading = true | ||||
|         let res = await api.deleteCategory(this.modify_selected_category.categoryId) | ||||
|         if (res.data.success === true) { | ||||
|           this.title = '' | ||||
|           this.category_list = [] | ||||
|           this.selected_category = null | ||||
|           this.cancelCreateCategory() | ||||
|           await this.getCategoryList() | ||||
|         } else { | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async modifyCategory() { | ||||
|       if (this.title.trim().length <= 0) { | ||||
|         this.notifyError("제목을 입력하세요") | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       if (this.is_loading) return; | ||||
|  | ||||
|       try { | ||||
|         this.is_loading = true | ||||
|         let res = await api.modifyCategory(this.title, this.modify_selected_category.categoryId) | ||||
|         if (res.data.success === true) { | ||||
|           this.title = '' | ||||
|           this.category_list = [] | ||||
|           this.selected_category = null | ||||
|           this.cancelCreateCategory() | ||||
|           await this.getCategoryList() | ||||
|         } else { | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async onDropCategoryCallback() { | ||||
|       const ids = this.category_list.map((category) => { | ||||
|         return category.categoryId | ||||
|       }) | ||||
|  | ||||
|       const res = await api.updateCategoryOrders(ids) | ||||
|       if (res.status === 200 && res.data.success === true) { | ||||
|         this.notifySuccess('수정되었습니다.') | ||||
|       } else { | ||||
|         this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } | ||||
|     }, | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .category-selected-item { | ||||
|   background-color: #3bb9f1; | ||||
|   color: white !important; | ||||
| } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung