| @@ -38,4 +38,12 @@ | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| html::-webkit-scrollbar, body::-webkit-scrollbar { | ||||
|   overflow-y: hidden; | ||||
| } | ||||
|  | ||||
| html, body { | ||||
|   overflow-y: hidden; | ||||
| } | ||||
| </style> | ||||
|   | ||||
| @@ -55,6 +55,13 @@ async function removeContentInTheSeries(seriesId, contentId) { | ||||
|     ) | ||||
| } | ||||
|  | ||||
| async function updateSeriesOrders(ids) { | ||||
|     return Vue.axios.put( | ||||
|         "/creator-admin/audio-content/series/orders", | ||||
|         {ids: ids} | ||||
|     ) | ||||
| } | ||||
|  | ||||
| export { | ||||
|     getGenreList, | ||||
|     getSeriesList, | ||||
| @@ -62,6 +69,7 @@ export { | ||||
|     modifySeries, | ||||
|     getSeriesDetail, | ||||
|     getSeriesContent, | ||||
|     updateSeriesOrders, | ||||
|     addingContentToTheSeries, | ||||
|     removeContentInTheSeries, | ||||
|     searchContentNotInSeries | ||||
|   | ||||
| @@ -22,44 +22,54 @@ | ||||
|           </v-btn> | ||||
|         </v-col> | ||||
|       </v-row> | ||||
|       <v-row> | ||||
|         <v-col | ||||
|           v-for="(item, i) in series_list" | ||||
|           :key="i" | ||||
|           cols="3" | ||||
|       <div | ||||
|         ref="scroll_container" | ||||
|         class="scroll_container" | ||||
|         @scroll="onScroll" | ||||
|       > | ||||
|         <draggable | ||||
|           v-model="series_list" | ||||
|           class="row" | ||||
|           @end="onDropCallback(series_list)" | ||||
|         > | ||||
|           <v-card> | ||||
|             <v-card-title> | ||||
|               <v-spacer /> | ||||
|               <v-img | ||||
|                 :src="item.coverImageUrl" | ||||
|                 class="cover-image" | ||||
|                 @click="selectSeries(item)" | ||||
|               /> | ||||
|               <v-spacer /> | ||||
|             </v-card-title> | ||||
|             <v-card-text class="series-title-container"> | ||||
|               {{ item.title }} | ||||
|             </v-card-text> | ||||
|             <v-card-actions> | ||||
|               <v-spacer /> | ||||
|               <v-btn | ||||
|                 text | ||||
|                 @click="showModifyDialog(item)" | ||||
|               > | ||||
|                 수정 | ||||
|               </v-btn> | ||||
|               <v-btn | ||||
|                 text | ||||
|                 @click="deleteConfirm(item)" | ||||
|               > | ||||
|                 삭제 | ||||
|               </v-btn> | ||||
|               <v-spacer /> | ||||
|             </v-card-actions> | ||||
|           </v-card> | ||||
|         </v-col> | ||||
|       </v-row> | ||||
|           <v-col | ||||
|             v-for="(item, i) in series_list" | ||||
|             :key="i" | ||||
|             cols="3" | ||||
|           > | ||||
|             <v-card> | ||||
|               <v-card-title> | ||||
|                 <v-spacer /> | ||||
|                 <v-img | ||||
|                   :src="item.coverImageUrl" | ||||
|                   class="cover-image" | ||||
|                   @click="selectSeries(item)" | ||||
|                 /> | ||||
|                 <v-spacer /> | ||||
|               </v-card-title> | ||||
|               <v-card-text class="series-title-container"> | ||||
|                 {{ item.title }} | ||||
|               </v-card-text> | ||||
|               <v-card-actions> | ||||
|                 <v-spacer /> | ||||
|                 <v-btn | ||||
|                   text | ||||
|                   @click="showModifyDialog(item)" | ||||
|                 > | ||||
|                   수정 | ||||
|                 </v-btn> | ||||
|                 <v-btn | ||||
|                   text | ||||
|                   @click="deleteConfirm(item)" | ||||
|                 > | ||||
|                   삭제 | ||||
|                 </v-btn> | ||||
|                 <v-spacer /> | ||||
|               </v-card-actions> | ||||
|             </v-card> | ||||
|           </v-col> | ||||
|         </draggable> | ||||
|       </div> | ||||
|     </v-container> | ||||
|  | ||||
|     <v-dialog | ||||
| @@ -345,10 +355,11 @@ | ||||
|  | ||||
| <script> | ||||
| import * as api from '@/api/audio_content_series'; | ||||
| import Draggable from "vuedraggable"; | ||||
|  | ||||
| export default { | ||||
|   name: "ContentSeriesList", | ||||
|  | ||||
|   components: {Draggable}, | ||||
|   data() { | ||||
|     return { | ||||
|       is_loading: false, | ||||
| @@ -378,6 +389,14 @@ export default { | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     async onScroll() { | ||||
|       const scrollContainer = this.$refs.scroll_container; | ||||
|       const threshold = scrollContainer.scrollHeight - scrollContainer.clientHeight; | ||||
|       if (scrollContainer.scrollTop >= threshold - 10 && this.total_page >= this.page) { | ||||
|         await this.getSeriesList(); | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     imageAdd(payload) { | ||||
|       const file = payload; | ||||
|       if (file) { | ||||
| @@ -485,8 +504,18 @@ export default { | ||||
|       this.$router.push({name: 'ContentSeriesDetail', params: {seriesId: series.seriesId}}) | ||||
|     }, | ||||
|  | ||||
|     async onDropCallback(items) { | ||||
|       const ids = items.map((item) => { | ||||
|         return item.seriesId | ||||
|       }) | ||||
|  | ||||
|       const res = await api.updateSeriesOrders(ids) | ||||
|       if (res.status === 200 && res.data.success === true) { | ||||
|         this.notifySuccess(res.data.message) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async getSeriesGenreList() { | ||||
|       this.is_loading = true | ||||
|       try { | ||||
|         const res = await api.getGenreList() | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
| @@ -496,23 +525,24 @@ export default { | ||||
|         } else { | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|  | ||||
|         this.is_loading = false | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async getSeriesList() { | ||||
|       if (this.is_loading) return; | ||||
|  | ||||
|       this.is_loading = true | ||||
|       try { | ||||
|         const res = await api.getSeriesList(this.page) | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
|           const data = res.data.data | ||||
|           const total_page = Math.ceil(data.totalCount / 10) | ||||
|  | ||||
|           const total_page = Math.ceil(data.totalCount / 20) | ||||
|           this.series_list = data.items | ||||
|           if (this.page === 1) this.series_list.length = 0; | ||||
|           this.page += 1; | ||||
|           this.series_list.push(...data.items); | ||||
|  | ||||
|           if (total_page <= 0) | ||||
|             this.total_page = 1 | ||||
| @@ -665,6 +695,11 @@ export default { | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .scroll_container { | ||||
|   height: 100vh; | ||||
|   overflow-y: auto; | ||||
| } | ||||
|  | ||||
| .image-select label { | ||||
|   display: inline-block; | ||||
|   padding: 10px 20px; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user