19
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										19
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -11,6 +11,7 @@ | ||||
|         "core-js": "^3.6.5", | ||||
|         "vue": "^2.6.11", | ||||
|         "vue-router": "^3.2.0", | ||||
|         "vue-show-more-text": "^2.0.2", | ||||
|         "vue2-datepicker": "^3.11.1", | ||||
|         "vue2-editor": "^2.10.3", | ||||
|         "vue2-timepicker": "^1.1.6", | ||||
| @@ -14488,6 +14489,15 @@ | ||||
|       "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.3.tgz", | ||||
|       "integrity": "sha512-FUlILrW3DGitS2h+Xaw8aRNvGTwtuaxrRkNSHWTizOfLUie7wuYwezeZ50iflRn8YPV5kxmU2LQuu3nM/b3Zsg==" | ||||
|     }, | ||||
|     "node_modules/vue-show-more-text": { | ||||
|       "version": "2.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/vue-show-more-text/-/vue-show-more-text-2.0.2.tgz", | ||||
|       "integrity": "sha512-x/WuikWAx8Hm4gpZx6KHtJYiXDordGdSoXrd34lTiJeAnlT8Y7Yc0FfGBNdUv6mXncuET3LiRwwNz+X5gI+oiw==", | ||||
|       "dependencies": { | ||||
|         "core-js": "^3.6.5", | ||||
|         "vue": "^2.6.11" | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/vue-style-loader": { | ||||
|       "version": "4.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", | ||||
| @@ -27252,6 +27262,15 @@ | ||||
|       "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.3.tgz", | ||||
|       "integrity": "sha512-FUlILrW3DGitS2h+Xaw8aRNvGTwtuaxrRkNSHWTizOfLUie7wuYwezeZ50iflRn8YPV5kxmU2LQuu3nM/b3Zsg==" | ||||
|     }, | ||||
|     "vue-show-more-text": { | ||||
|       "version": "2.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/vue-show-more-text/-/vue-show-more-text-2.0.2.tgz", | ||||
|       "integrity": "sha512-x/WuikWAx8Hm4gpZx6KHtJYiXDordGdSoXrd34lTiJeAnlT8Y7Yc0FfGBNdUv6mXncuET3LiRwwNz+X5gI+oiw==", | ||||
|       "requires": { | ||||
|         "core-js": "^3.6.5", | ||||
|         "vue": "^2.6.11" | ||||
|       } | ||||
|     }, | ||||
|     "vue-style-loader": { | ||||
|       "version": "4.1.3", | ||||
|       "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", | ||||
|   | ||||
| @@ -13,6 +13,7 @@ | ||||
|     "core-js": "^3.6.5", | ||||
|     "vue": "^2.6.11", | ||||
|     "vue-router": "^3.2.0", | ||||
|     "vue-show-more-text": "^2.0.2", | ||||
|     "vue2-datepicker": "^3.11.1", | ||||
|     "vue2-editor": "^2.10.3", | ||||
|     "vue2-timepicker": "^1.1.6", | ||||
|   | ||||
							
								
								
									
										68
									
								
								src/api/audio_content_series.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/api/audio_content_series.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| import Vue from 'vue'; | ||||
|  | ||||
| async function getGenreList() { | ||||
|     return Vue.axios.get("/creator-admin/audio-content/series/genre"); | ||||
| } | ||||
|  | ||||
| async function getSeriesList(page) { | ||||
|     return Vue.axios.get("/creator-admin/audio-content/series?page=" + (page - 1) + "&size=10"); | ||||
| } | ||||
|  | ||||
| async function createSeries(formData) { | ||||
|     return Vue.axios.post("/creator-admin/audio-content/series", formData, { | ||||
|         headers: { | ||||
|             "Content-Type": "multipart/form-data", | ||||
|         }, | ||||
|     }); | ||||
| } | ||||
|  | ||||
| async function modifySeries(formData) { | ||||
|     return Vue.axios.put("/creator-admin/audio-content/series", formData, { | ||||
|         headers: { | ||||
|             "Content-Type": "multipart/form-data", | ||||
|         }, | ||||
|     }); | ||||
| } | ||||
|  | ||||
| async function getSeriesDetail(seriesId) { | ||||
|     return Vue.axios.get("/creator-admin/audio-content/series/" + seriesId); | ||||
| } | ||||
|  | ||||
| async function getSeriesContent(seriesId, page) { | ||||
|     return Vue.axios.get( | ||||
|         "/creator-admin/audio-content/series/" + seriesId + "/content?page=" + (page - 1) + "&size=10" | ||||
|     ); | ||||
| } | ||||
|  | ||||
| async function searchContentNotInSeries(seriesId, searchWord) { | ||||
|     return Vue.axios.get( | ||||
|         "/creator-admin/audio-content/series/content/search?series_id=" + seriesId + | ||||
|         "&search_word=" + searchWord | ||||
|     ) | ||||
| } | ||||
|  | ||||
| async function addingContentToTheSeries(seriesId, contentIdList) { | ||||
|     return Vue.axios.post( | ||||
|         "/creator-admin/audio-content/series/add/content", | ||||
|         {seriesId: seriesId, contentIdList: contentIdList} | ||||
|     ) | ||||
| } | ||||
|  | ||||
| async function removeContentInTheSeries(seriesId, contentId) { | ||||
|     return Vue.axios.put( | ||||
|         "/creator-admin/audio-content/series/remove/content", | ||||
|         {seriesId: seriesId, contentId: contentId} | ||||
|     ) | ||||
| } | ||||
|  | ||||
| export { | ||||
|     getGenreList, | ||||
|     getSeriesList, | ||||
|     createSeries, | ||||
|     modifySeries, | ||||
|     getSeriesDetail, | ||||
|     getSeriesContent, | ||||
|     addingContentToTheSeries, | ||||
|     removeContentInTheSeries, | ||||
|     searchContentNotInSeries | ||||
| } | ||||
| @@ -25,6 +25,16 @@ const routes = [ | ||||
|                 name: 'ContentCategoryList', | ||||
|                 component: () => import(/* webpackChunkName: "content" */ '../views/Content/ContentCategoryList.vue') | ||||
|             }, | ||||
|             { | ||||
|                 path: '/content/series/list', | ||||
|                 name: 'ContentSeriesList', | ||||
|                 component: () => import(/* webpackChunkName: "content" */ '../views/Content/ContentSeriesList.vue') | ||||
|             }, | ||||
|             { | ||||
|                 path: '/content/series/detail', | ||||
|                 name: 'ContentSeriesDetail', | ||||
|                 component: () => import(/* webpackChunkName: "content" */ '../views/Content/ContentSeriesDetail.vue') | ||||
|             }, | ||||
|             { | ||||
|                 path: '/calculate/live', | ||||
|                 name: 'CalculateLive', | ||||
|   | ||||
| @@ -339,33 +339,6 @@ export default { | ||||
|  | ||||
|       page: 1, | ||||
|       total_page: 0, | ||||
|  | ||||
|       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' | ||||
|         }, | ||||
|       ] | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   | ||||
| @@ -617,20 +617,6 @@ | ||||
|         </v-card-actions> | ||||
|       </v-card> | ||||
|     </v-dialog> | ||||
|  | ||||
|     <v-dialog | ||||
|       v-model="is_loading" | ||||
|       max-width="400px" | ||||
|       persistent | ||||
|     > | ||||
|       <v-card> | ||||
|         <v-card-text> | ||||
|           <v-progress-circular | ||||
|             indeterminate | ||||
|           /> | ||||
|         </v-card-text> | ||||
|       </v-card> | ||||
|     </v-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
|   | ||||
							
								
								
									
										517
									
								
								src/views/Content/ContentSeriesDetail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										517
									
								
								src/views/Content/ContentSeriesDetail.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,517 @@ | ||||
| <template> | ||||
|   <div> | ||||
|     <v-container> | ||||
|       <v-row> | ||||
|         <v-col cols="4"> | ||||
|           <v-card> | ||||
|             <v-img | ||||
|               :src="series_detail.coverImageUrl" | ||||
|               class="cover-image" | ||||
|             /> | ||||
|             <v-card-text> | ||||
|               제목 : {{ series_detail.title }} | ||||
|             </v-card-text> | ||||
|             <v-card-text> | ||||
|               소개 : | ||||
|               <vue-show-more-text | ||||
|                 :text="series_detail.introduction" | ||||
|                 :lines="2" | ||||
|               /> | ||||
|             </v-card-text> | ||||
|             <v-card-text> | ||||
|               연재요일 : {{ series_detail.publishedDaysOfWeek }} | ||||
|             </v-card-text> | ||||
|             <v-card-text> | ||||
|               장르 : {{ series_detail.genre }} | ||||
|             </v-card-text> | ||||
|             <v-card-text> | ||||
|               키워드 : {{ series_detail.keywords }} | ||||
|             </v-card-text> | ||||
|             <v-card-text> | ||||
|               연령제한 : <span v-if="series_detail.isAdult">19세이상</span><span v-else>전체이용가</span> | ||||
|             </v-card-text> | ||||
|             <v-card-text> | ||||
|               완결여부 : {{ series_detail.state }} | ||||
|             </v-card-text> | ||||
|             <v-card-text v-show="series_detail.writer !== undefined && series_detail.writer !== null"> | ||||
|               작가 : {{ series_detail.writer }} | ||||
|             </v-card-text> | ||||
|             <v-card-text v-show="series_detail.studio !== undefined && series_detail.studio !== null"> | ||||
|               제작사 : {{ series_detail.studio }} | ||||
|             </v-card-text> | ||||
|           </v-card> | ||||
|         </v-col> | ||||
|         <v-col cols="8"> | ||||
|           <v-row> | ||||
|             <v-col cols="8" /> | ||||
|             <v-col cols="4"> | ||||
|               <v-btn | ||||
|                 block | ||||
|                 color="#3bb9f1" | ||||
|                 dark | ||||
|                 depressed | ||||
|                 @click="showAddContent" | ||||
|               > | ||||
|                 콘텐츠 추가 | ||||
|               </v-btn> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|           <v-row> | ||||
|             <v-col v-if="series_content_list.length > 0"> | ||||
|               <v-simple-table> | ||||
|                 <template> | ||||
|                   <thead> | ||||
|                     <tr> | ||||
|                       <th class="text-center"> | ||||
|                         썸네일 | ||||
|                       </th> | ||||
|                       <th class="text-center"> | ||||
|                         제목 | ||||
|                       </th> | ||||
|                       <th class="text-center"> | ||||
|                         19금 | ||||
|                       </th> | ||||
|                       <th class="text-center"> | ||||
|                         관리 | ||||
|                       </th> | ||||
|                     </tr> | ||||
|                   </thead> | ||||
|                   <tbody> | ||||
|                     <tr | ||||
|                       v-for="content in series_content_list" | ||||
|                       :key="content.contentId" | ||||
|                     > | ||||
|                       <td align="center"> | ||||
|                         <v-img | ||||
|                           :src="content.coverImage" | ||||
|                           max-width="100" | ||||
|                           class="content-cover-image" | ||||
|                         /> | ||||
|                       </td> | ||||
|                       <td align="center"> | ||||
|                         {{ content.title }} | ||||
|                       </td> | ||||
|                       <td align="center"> | ||||
|                         <div v-if="content.isAdult"> | ||||
|                           O | ||||
|                         </div> | ||||
|                         <div v-else> | ||||
|                           X | ||||
|                         </div> | ||||
|                       </td> | ||||
|                       <td align="center"> | ||||
|                         <v-btn | ||||
|                           color="#3bb9f1" | ||||
|                           @click="deleteConfirm(content)" | ||||
|                         > | ||||
|                           삭제 | ||||
|                         </v-btn> | ||||
|                       </td> | ||||
|                     </tr> | ||||
|                   </tbody> | ||||
|                 </template> | ||||
|               </v-simple-table> | ||||
|               <br><br> | ||||
|               <v-row | ||||
|                 v-if="total_page > 0" | ||||
|                 class="text-center" | ||||
|               > | ||||
|                 <v-col> | ||||
|                   <v-pagination | ||||
|                     v-model="page" | ||||
|                     :length="total_page" | ||||
|                     circle | ||||
|                     @input="next" | ||||
|                   /> | ||||
|                 </v-col> | ||||
|               </v-row> | ||||
|             </v-col> | ||||
|             <v-col | ||||
|               v-else | ||||
|               class="no-series-content" | ||||
|             > | ||||
|               등록된 콘텐츠가 없습니다. | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-col> | ||||
|       </v-row> | ||||
|     </v-container> | ||||
|  | ||||
|     <v-dialog | ||||
|       v-model="show_add_series_content" | ||||
|       max-width="1000px" | ||||
|       persistent | ||||
|     > | ||||
|       <v-card> | ||||
|         <v-card-title> | ||||
|           콘텐츠 추가 | ||||
|         </v-card-title> | ||||
|         <v-card-text> | ||||
|           <v-text-field | ||||
|             v-model="search_word" | ||||
|             label="콘텐츠 제목" | ||||
|             @keyup.enter="searchContentNotInSeries" | ||||
|           > | ||||
|             <v-btn | ||||
|               slot="append" | ||||
|               color="#3bb9f1" | ||||
|               dark | ||||
|               @click="searchContentNotInSeries" | ||||
|             > | ||||
|               검색 | ||||
|             </v-btn> | ||||
|           </v-text-field> | ||||
|         </v-card-text> | ||||
|         <v-card-text v-if="search_content_list.length > 0 || add_content_list.length > 0"> | ||||
|           <v-row> | ||||
|             <v-col> | ||||
|               검색결과 | ||||
|               <v-simple-table> | ||||
|                 <template v-slot:default> | ||||
|                   <thead> | ||||
|                     <tr> | ||||
|                       <th class="text-center"> | ||||
|                         제목 | ||||
|                       </th> | ||||
|                       <th /> | ||||
|                     </tr> | ||||
|                   </thead> | ||||
|                   <tbody> | ||||
|                     <tr | ||||
|                       v-for="content in search_content_list" | ||||
|                       :key="content.contentId" | ||||
|                     > | ||||
|                       <td>{{ content.title }}</td> | ||||
|                       <td> | ||||
|                         <v-btn | ||||
|                           color="#3bb9f1" | ||||
|                           @click="addContent(content)" | ||||
|                         > | ||||
|                           추가 | ||||
|                         </v-btn> | ||||
|                       </td> | ||||
|                     </tr> | ||||
|                   </tbody> | ||||
|                 </template> | ||||
|               </v-simple-table> | ||||
|             </v-col> | ||||
|             <v-col v-if="add_content_list.length > 0"> | ||||
|               추가할 콘텐츠 | ||||
|               <v-simple-table> | ||||
|                 <template> | ||||
|                   <thead> | ||||
|                     <tr> | ||||
|                       <th class="text-center"> | ||||
|                         제목 | ||||
|                       </th> | ||||
|                       <th /> | ||||
|                     </tr> | ||||
|                   </thead> | ||||
|                   <tbody> | ||||
|                     <tr | ||||
|                       v-for="content in add_content_list" | ||||
|                       :key="content.contentId" | ||||
|                     > | ||||
|                       <td>{{ content.title }}</td> | ||||
|                       <td> | ||||
|                         <v-btn | ||||
|                           color="#3bb9f1" | ||||
|                           @click="removeContent(content)" | ||||
|                         > | ||||
|                           제거 | ||||
|                         </v-btn> | ||||
|                       </td> | ||||
|                     </tr> | ||||
|                   </tbody> | ||||
|                 </template> | ||||
|               </v-simple-table> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-card-text> | ||||
|         <v-card-actions v-show="!is_loading"> | ||||
|           <v-spacer /> | ||||
|           <v-btn | ||||
|             color="blue darken-1" | ||||
|             text | ||||
|             @click="cancel" | ||||
|           > | ||||
|             취소 | ||||
|           </v-btn> | ||||
|           <v-btn | ||||
|             color="blue darken-1" | ||||
|             text | ||||
|             @click="addContentInSeries" | ||||
|           > | ||||
|             추가 | ||||
|           </v-btn> | ||||
|         </v-card-actions> | ||||
|       </v-card> | ||||
|     </v-dialog> | ||||
|  | ||||
|     <v-dialog | ||||
|       v-model="show_delete_confirm_dialog" | ||||
|       max-width="400px" | ||||
|       persistent | ||||
|     > | ||||
|       <v-card> | ||||
|         <v-card-text /> | ||||
|         <v-card-text v-if="selected_series_content !== null"> | ||||
|           {{ selected_series_content.title }} 삭제하시겠습니까? | ||||
|         </v-card-text> | ||||
|         <v-card-text v-else> | ||||
|           삭제하시겠습니까? | ||||
|         </v-card-text> | ||||
|         <v-card-actions v-show="!is_loading"> | ||||
|           <v-spacer /> | ||||
|           <v-btn | ||||
|             color="blue darken-1" | ||||
|             text | ||||
|             @click="deleteCancel" | ||||
|           > | ||||
|             취소 | ||||
|           </v-btn> | ||||
|           <v-btn | ||||
|             color="blue darken-1" | ||||
|             text | ||||
|             @click="removeContentInSeries" | ||||
|           > | ||||
|             확인 | ||||
|           </v-btn> | ||||
|         </v-card-actions> | ||||
|       </v-card> | ||||
|     </v-dialog> | ||||
|  | ||||
|     <v-dialog | ||||
|       v-model="is_loading" | ||||
|       max-width="400px" | ||||
|       persistent | ||||
|     > | ||||
|       <v-card> | ||||
|         <v-card-text> | ||||
|           <v-progress-circular | ||||
|             indeterminate | ||||
|           /> | ||||
|         </v-card-text> | ||||
|       </v-card> | ||||
|     </v-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import * as api from '@/api/audio_content_series'; | ||||
|  | ||||
| import VueShowMoreText from 'vue-show-more-text' | ||||
|  | ||||
| export default { | ||||
|   name: "ContentSeriesDetail", | ||||
|  | ||||
|   components: {VueShowMoreText}, | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       is_loading: false, | ||||
|       series_id: 0, | ||||
|       series_detail: {}, | ||||
|       series_content_list: [], | ||||
|       selected_series_content: null, | ||||
|       page: 1, | ||||
|       total_page: 0, | ||||
|  | ||||
|       search_word: '', | ||||
|       add_content_list: [], | ||||
|       search_content_list: [], | ||||
|       show_add_series_content: false, | ||||
|  | ||||
|       show_delete_confirm_dialog: false, | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   async created() { | ||||
|     this.series_id = this.$route.params.seriesId | ||||
|     if (this.series_id !== undefined && this.series_id > 0) { | ||||
|       await this.getSeriesDetail() | ||||
|       await this.getSeriesContentList() | ||||
|     } else { | ||||
|       this.$router.go(-1); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     notifyError(message) { | ||||
|       this.$dialog.notify.error(message) | ||||
|     }, | ||||
|  | ||||
|     notifySuccess(message) { | ||||
|       this.$dialog.notify.success(message) | ||||
|     }, | ||||
|  | ||||
|     cancel() { | ||||
|       this.search_word = '' | ||||
|       this.add_content_list = [] | ||||
|       this.search_content_list = [] | ||||
|       this.selected_series_content = null | ||||
|       this.show_add_series_content = false | ||||
|       this.show_delete_confirm_dialog = false | ||||
|     }, | ||||
|  | ||||
|     deleteConfirm(series_content) { | ||||
|       this.selected_series_content = series_content | ||||
|       this.show_delete_confirm_dialog = true | ||||
|     }, | ||||
|  | ||||
|     deleteCancel() { | ||||
|       this.cancel(); | ||||
|     }, | ||||
|  | ||||
|     showAddContent() { | ||||
|       this.show_add_series_content = true | ||||
|     }, | ||||
|  | ||||
|     addContent(content) { | ||||
|       this.search_content_list = this.search_content_list.filter((item) => { | ||||
|         return item.contentId !== content.contentId | ||||
|       }); | ||||
|       this.add_content_list.push(content) | ||||
|     }, | ||||
|  | ||||
|     removeContent(content) { | ||||
|       this.add_content_list = this.add_content_list.filter((item) => { | ||||
|         return item.contentId !== content.contentId | ||||
|       }); | ||||
|       this.search_content_list.push(content) | ||||
|     }, | ||||
|  | ||||
|     async searchContentNotInSeries() { | ||||
|       if (this.search_word.length < 2) { | ||||
|         this.notifyError('검색어를 2글자 이상 입력하세요.') | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       this.is_loading = true | ||||
|  | ||||
|       try { | ||||
|         const res = await api.searchContentNotInSeries(this.series_id, this.search_word) | ||||
|  | ||||
|         if (res.data.success === true) { | ||||
|           this.search_content_list = res.data.data | ||||
|           if (res.data.data.length <= 0) { | ||||
|             this.notifyError('검색결과가 없습니다.') | ||||
|           } | ||||
|         } else { | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async addContentInSeries() { | ||||
|       this.is_loading = true | ||||
|       const contentIdList = this.add_content_list.map((item) => { | ||||
|         return item.contentId | ||||
|       }) | ||||
|  | ||||
|       try { | ||||
|         const res = await api.addingContentToTheSeries(this.series_id, contentIdList) | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
|           this.cancel() | ||||
|           this.page = 1 | ||||
|           this.total_page = 0 | ||||
|           await this.getSeriesContentList() | ||||
|         } else { | ||||
|           this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async getSeriesDetail() { | ||||
|       this.is_loading = true | ||||
|  | ||||
|       try { | ||||
|         const res = await api.getSeriesDetail(this.series_id) | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
|           this.series_detail = res.data.data | ||||
|         } else { | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async next() { | ||||
|       await this.getSeriesContentList() | ||||
|     }, | ||||
|  | ||||
|     async getSeriesContentList() { | ||||
|       try { | ||||
|         const res = await api.getSeriesContent(this.series_id, this.page) | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
|           const data = res.data.data | ||||
|           this.series_content_list = data.items | ||||
|  | ||||
|           const total_page = Math.ceil(data.totalCount / 20) | ||||
|           if (total_page <= 0) | ||||
|             this.total_page = 1 | ||||
|           else | ||||
|             this.total_page = total_page | ||||
|         } else { | ||||
|           this.notifyError(res.data.message || '콘텐츠를 불러오지 못했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async removeContentInSeries() { | ||||
|       this.is_loading = true | ||||
|  | ||||
|       try { | ||||
|         const res = await api.removeContentInTheSeries(this.series_id, this.selected_series_content.contentId) | ||||
|  | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
|           this.page = 1 | ||||
|           this.total_page = 0 | ||||
|           this.series_content_list = [] | ||||
|           this.cancel() | ||||
|           this.notifySuccess('삭제되었습니다.') | ||||
|           await this.getSeriesContentList() | ||||
|         } else { | ||||
|           this.notifyError('콘텐츠를 삭제하지 못했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('콘텐츠를 삭제하지 못했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .v-card__text { | ||||
|   text-align: left; | ||||
| } | ||||
|  | ||||
| .cover-image { | ||||
|   aspect-ratio: 1/1.4; | ||||
| } | ||||
|  | ||||
| .content-cover-image { | ||||
|   aspect-ratio: 1; | ||||
| } | ||||
|  | ||||
| .no-series-content { | ||||
|   height: 50vh; | ||||
|   margin-top: 100px; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										707
									
								
								src/views/Content/ContentSeriesList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										707
									
								
								src/views/Content/ContentSeriesList.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,707 @@ | ||||
| <template> | ||||
|   <div> | ||||
|     <v-toolbar dark> | ||||
|       <v-spacer /> | ||||
|       <v-toolbar-title>시리즈 관리</v-toolbar-title> | ||||
|       <v-spacer /> | ||||
|     </v-toolbar> | ||||
|  | ||||
|     <br> | ||||
|     <v-container> | ||||
|       <v-row> | ||||
|         <v-col cols="10" /> | ||||
|         <v-col> | ||||
|           <v-btn | ||||
|             block | ||||
|             color="#3bb9f1" | ||||
|             dark | ||||
|             depressed | ||||
|             @click="showWriteDialog" | ||||
|           > | ||||
|             시리즈 등록 | ||||
|           </v-btn> | ||||
|         </v-col> | ||||
|       </v-row> | ||||
|       <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> | ||||
|       </v-row> | ||||
|     </v-container> | ||||
|  | ||||
|     <v-dialog | ||||
|       v-model="show_write_dialog" | ||||
|       max-width="1000px" | ||||
|       persistent | ||||
|     > | ||||
|       <v-card> | ||||
|         <v-card-title> | ||||
|           시리즈 등록 | ||||
|         </v-card-title> | ||||
|  | ||||
|         <div class="image-select"> | ||||
|           <label for="image"> | ||||
|             커버 이미지 등록 | ||||
|           </label> | ||||
|           <v-file-input | ||||
|             id="image" | ||||
|             v-model="series.cover_image" | ||||
|             accept="image/*" | ||||
|             @change="imageAdd" | ||||
|           /> | ||||
|         </div> | ||||
|         <img | ||||
|           v-if="series.cover_image_url" | ||||
|           :src="series.cover_image_url" | ||||
|           alt="" | ||||
|           class="image-preview" | ||||
|         > | ||||
|         <v-card-text> | ||||
|           <v-row align="center"> | ||||
|             <v-col cols="4"> | ||||
|               제목* | ||||
|             </v-col> | ||||
|             <v-col cols="8"> | ||||
|               <v-text-field | ||||
|                 v-model="series.title" | ||||
|                 label="제목" | ||||
|                 required | ||||
|               /> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-card-text> | ||||
|         <v-card-text> | ||||
|           <v-row align="center"> | ||||
|             <v-col cols="4"> | ||||
|               소개* | ||||
|             </v-col> | ||||
|             <v-col cols="8"> | ||||
|               <v-textarea | ||||
|                 v-model="series.introduction" | ||||
|                 label="소개" | ||||
|                 required | ||||
|               /> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-card-text> | ||||
|         <v-card-text> | ||||
|           <v-row> | ||||
|             <v-col cols="4"> | ||||
|               연재요일* | ||||
|             </v-col> | ||||
|             <v-col | ||||
|               cols="8" | ||||
|               align="left" | ||||
|             > | ||||
|               <v-row> | ||||
|                 <v-col | ||||
|                   v-for="(day, index) in days_of_week" | ||||
|                   :key="index" | ||||
|                 > | ||||
|                   <input | ||||
|                     :id="'checkbox_' + day.value" | ||||
|                     v-model="series.published_days_of_week" | ||||
|                     type="checkbox" | ||||
|                     :value="day.value" | ||||
|                     @change="handleCheckboxChange(day.value, $event)" | ||||
|                   > | ||||
|                   <label :for="'checkbox_' + day.value"> {{ day.str }}</label><br> | ||||
|                 </v-col> | ||||
|               </v-row> | ||||
|  | ||||
|               <input | ||||
|                 id="checkbox_random" | ||||
|                 v-model="series.published_days_of_week" | ||||
|                 type="checkbox" | ||||
|                 value="RANDOM" | ||||
|                 @change="handleCheckboxChange('RANDOM', $event)" | ||||
|               > | ||||
|               <label for="checkbox_random"> 랜덤</label> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-card-text> | ||||
|         <v-card-text> | ||||
|           <v-row align="center"> | ||||
|             <v-col cols="4"> | ||||
|               크리에이터 | ||||
|             </v-col> | ||||
|             <v-col cols="8"> | ||||
|               <v-select | ||||
|                 v-model="series.genre_id" | ||||
|                 :items="series_genre_list" | ||||
|                 item-text="name" | ||||
|                 item-value="value" | ||||
|                 label="장르 선택" | ||||
|               /> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-card-text> | ||||
|         <v-card-text v-show="selected_series === undefined || selected_series === null"> | ||||
|           <v-row align="center"> | ||||
|             <v-col cols="4"> | ||||
|               키워드* | ||||
|             </v-col> | ||||
|             <v-col cols="8"> | ||||
|               <v-text-field | ||||
|                 v-model="series.keyword" | ||||
|                 label="키워드 예 : #달달 #장기연애 #첫사랑" | ||||
|                 required | ||||
|               /> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-card-text> | ||||
|         <v-card-text> | ||||
|           <v-row> | ||||
|             <v-col cols="4"> | ||||
|               연령제한 | ||||
|             </v-col> | ||||
|             <v-col | ||||
|               cols="8" | ||||
|               align="left" | ||||
|             > | ||||
|               <input | ||||
|                 v-model="series.is_adult" | ||||
|                 type="checkbox" | ||||
|               > | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-card-text> | ||||
|         <v-card-text v-show="selected_series !== undefined && selected_series !== null"> | ||||
|           <v-row> | ||||
|             <v-col cols="4"> | ||||
|               완결여부* | ||||
|             </v-col> | ||||
|             <v-col | ||||
|               cols="8" | ||||
|               align="left" | ||||
|             > | ||||
|               <v-row> | ||||
|                 <v-col> | ||||
|                   <input | ||||
|                     id="radio_proceeding" | ||||
|                     v-model="series.state" | ||||
|                     type="radio" | ||||
|                     value="PROCEEDING" | ||||
|                   > | ||||
|                   <label for="radio_proceeding"> 연재중</label> | ||||
|                 </v-col> | ||||
|                 <v-col> | ||||
|                   <input | ||||
|                     id="radio_suspend" | ||||
|                     v-model="series.state" | ||||
|                     type="radio" | ||||
|                     value="SUSPEND" | ||||
|                   > | ||||
|                   <label for="radio_suspend"> 휴재중</label> | ||||
|                 </v-col> | ||||
|                 <v-col> | ||||
|                   <input | ||||
|                     id="radio_complete" | ||||
|                     v-model="series.state" | ||||
|                     type="radio" | ||||
|                     value="COMPLETE" | ||||
|                   > | ||||
|                   <label for="radio_complete"> 완결</label> | ||||
|                 </v-col> | ||||
|               </v-row> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-card-text> | ||||
|         <v-card-text> | ||||
|           <v-row align="center"> | ||||
|             <v-col cols="4"> | ||||
|               작가 | ||||
|             </v-col> | ||||
|             <v-col cols="8"> | ||||
|               <v-text-field | ||||
|                 v-model="series.writer" | ||||
|                 label="작가" | ||||
|                 required | ||||
|               /> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-card-text> | ||||
|         <v-card-text> | ||||
|           <v-row align="center"> | ||||
|             <v-col cols="4"> | ||||
|               제작사 | ||||
|             </v-col> | ||||
|             <v-col cols="8"> | ||||
|               <v-text-field | ||||
|                 v-model="series.studio" | ||||
|                 label="제작사" | ||||
|                 required | ||||
|               /> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-card-text> | ||||
|         <v-card-actions v-show="!is_loading"> | ||||
|           <v-spacer /> | ||||
|           <v-btn | ||||
|             color="blue darken-1" | ||||
|             text | ||||
|             @click="cancel" | ||||
|           > | ||||
|             취소 | ||||
|           </v-btn> | ||||
|           <v-btn | ||||
|             v-if="selected_series !== undefined && selected_series !== null" | ||||
|             color="blue darken-1" | ||||
|             text | ||||
|             @click="modify" | ||||
|           > | ||||
|             수정 | ||||
|           </v-btn> | ||||
|           <v-btn | ||||
|             v-else | ||||
|             color="blue darken-1" | ||||
|             text | ||||
|             @click="validate" | ||||
|           > | ||||
|             등록 | ||||
|           </v-btn> | ||||
|         </v-card-actions> | ||||
|       </v-card> | ||||
|     </v-dialog> | ||||
|  | ||||
|     <v-dialog | ||||
|       v-model="show_delete_confirm_dialog" | ||||
|       max-width="400px" | ||||
|       persistent | ||||
|     > | ||||
|       <v-card> | ||||
|         <v-card-text /> | ||||
|         <v-card-text> | ||||
|           삭제하시겠습니까? | ||||
|         </v-card-text> | ||||
|         <v-card-actions v-show="!is_loading"> | ||||
|           <v-spacer /> | ||||
|           <v-btn | ||||
|             color="blue darken-1" | ||||
|             text | ||||
|             @click="deleteCancel" | ||||
|           > | ||||
|             취소 | ||||
|           </v-btn> | ||||
|           <v-btn | ||||
|             color="blue darken-1" | ||||
|             text | ||||
|             @click="deleteSeries" | ||||
|           > | ||||
|             확인 | ||||
|           </v-btn> | ||||
|         </v-card-actions> | ||||
|       </v-card> | ||||
|     </v-dialog> | ||||
|  | ||||
|     <v-dialog | ||||
|       v-model="is_loading" | ||||
|       max-width="400px" | ||||
|       persistent | ||||
|     > | ||||
|       <v-card> | ||||
|         <v-card-text> | ||||
|           <v-progress-circular | ||||
|             indeterminate | ||||
|           /> | ||||
|         </v-card-text> | ||||
|       </v-card> | ||||
|     </v-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import * as api from '@/api/audio_content_series'; | ||||
|  | ||||
| export default { | ||||
|   name: "ContentSeriesList", | ||||
|  | ||||
|   data() { | ||||
|     return { | ||||
|       is_loading: false, | ||||
|       show_write_dialog: false, | ||||
|       show_delete_confirm_dialog: false, | ||||
|       series: {is_adult: false, published_days_of_week: []}, | ||||
|       series_list: [], | ||||
|       selected_series: null, | ||||
|       series_genre_list: [], | ||||
|       page: 1, | ||||
|       total_page: 0, | ||||
|       days_of_week: [ | ||||
|         {value: 'SUN', str: '일'}, | ||||
|         {value: 'MON', str: '월'}, | ||||
|         {value: 'TUE', str: '화'}, | ||||
|         {value: 'WED', str: '수'}, | ||||
|         {value: 'THU', str: '목'}, | ||||
|         {value: 'FRI', str: '금'}, | ||||
|         {value: 'SAT', str: '토'}, | ||||
|       ], | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   async created() { | ||||
|     await this.getSeriesGenreList(); | ||||
|     await this.getSeriesList(); | ||||
|   }, | ||||
|  | ||||
|   methods: { | ||||
|     imageAdd(payload) { | ||||
|       const file = payload; | ||||
|       if (file) { | ||||
|         this.series.cover_image_url = URL.createObjectURL(file) | ||||
|         URL.revokeObjectURL(file) | ||||
|       } else { | ||||
|         this.series.cover_image_url = null | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     notifyError(message) { | ||||
|       this.$dialog.notify.error(message) | ||||
|     }, | ||||
|  | ||||
|     notifySuccess(message) { | ||||
|       this.$dialog.notify.success(message) | ||||
|     }, | ||||
|  | ||||
|     showWriteDialog() { | ||||
|       this.show_write_dialog = true | ||||
|     }, | ||||
|  | ||||
|     showModifyDialog(series) { | ||||
|       this.series = { | ||||
|         title: series.title, | ||||
|         introduction: series.introduction, | ||||
|         published_days_of_week: series.publishedDaysOfWeek, | ||||
|         genre_id: series.genreId, | ||||
|         is_adult: series.isAdult, | ||||
|         state: series.state, | ||||
|         cover_image_url: series.coverImageUrl | ||||
|       } | ||||
|  | ||||
|       if (series.writer !== undefined && series.writer !== null) { | ||||
|         this.series.writer = series.writer | ||||
|       } | ||||
|  | ||||
|       if (series.studio !== undefined && series.studio !== null) { | ||||
|         this.series.studio = series.studio | ||||
|       } | ||||
|  | ||||
|       this.selected_series = series | ||||
|       this.show_write_dialog = true | ||||
|     }, | ||||
|  | ||||
|     cancel() { | ||||
|       this.series = {is_adult: false, published_days_of_week: []} | ||||
|       this.selected_series = null | ||||
|       this.show_write_dialog = false | ||||
|       this.show_delete_confirm_dialog = false | ||||
|     }, | ||||
|  | ||||
|     deleteConfirm(series) { | ||||
|       this.selected_series = series | ||||
|       this.show_delete_confirm_dialog = true | ||||
|     }, | ||||
|  | ||||
|     deleteCancel() { | ||||
|       this.cancel(); | ||||
|     }, | ||||
|  | ||||
|     handleCheckboxChange(checked_days_of_week, event) { | ||||
|       if (checked_days_of_week === 'RANDOM' && event.target.checked) { | ||||
|         this.series.published_days_of_week = ['RANDOM']; | ||||
|       } else { | ||||
|         this.series.published_days_of_week = this.series.published_days_of_week.filter(item => item !== 'RANDOM'); | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     validate() { | ||||
|       if (this.series.cover_image === undefined || this.series.cover_image === null) { | ||||
|         this.notifyError('커버 이미지를 선택하세요') | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       if (this.series.title === undefined || this.series.title === null || this.series.title.trim().length <= 0) { | ||||
|         this.notifyError('시리즈 제목을 입력하세요') | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       if (this.series.introduction === undefined || this.series.introduction === null || this.series.introduction.trim().length <= 0) { | ||||
|         this.notifyError('시리즈 소개를 입력하세요') | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       if (this.series.published_days_of_week === undefined || this.series.published_days_of_week === null || this.series.published_days_of_week.length <= 0) { | ||||
|         this.notifyError('시리즈 연재요일을 선택하세요') | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       if (this.series.keyword === undefined || this.series.keyword === null || this.series.keyword.replaceAll('#', '').trim().length <= 0) { | ||||
|         this.notifyError('시리즈를 설명할 수 있는 키워드를 입력하세요') | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       if (this.series.genre_id === undefined || this.series.genre_id === null || this.series.genre_id <= 0) { | ||||
|         this.notifyError('올바른 장르를 선택하세요') | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       this.submit(); | ||||
|     }, | ||||
|  | ||||
|     selectSeries(series) { | ||||
|       this.$router.push({name: 'ContentSeriesDetail', params: {seriesId: series.seriesId}}) | ||||
|     }, | ||||
|  | ||||
|     async getSeriesGenreList() { | ||||
|       this.is_loading = true | ||||
|       try { | ||||
|         const res = await api.getGenreList() | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
|           this.series_genre_list = res.data.data.map((item) => { | ||||
|             return {name: item.genre, value: item.id} | ||||
|           }) | ||||
|         } else { | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|  | ||||
|         this.is_loading = false | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async getSeriesList() { | ||||
|       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 / 20) | ||||
|           this.series_list = data.items | ||||
|  | ||||
|           if (total_page <= 0) | ||||
|             this.total_page = 1 | ||||
|           else | ||||
|             this.total_page = total_page | ||||
|         } else { | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|  | ||||
|         this.is_loading = false | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async submit() { | ||||
|       if (this.is_loading) return; | ||||
|       this.is_loading = true | ||||
|  | ||||
|       try { | ||||
|         const request = { | ||||
|           title: this.series.title, | ||||
|           introduction: this.series.introduction, | ||||
|           publishedDaysOfWeek: this.series.published_days_of_week, | ||||
|           keyword: this.series.keyword, | ||||
|           genreId: this.series.genre_id, | ||||
|           isAdult: this.series.is_adult, | ||||
|           writer: this.series.writer || null, | ||||
|           studio: this.series.studio || null | ||||
|         } | ||||
|  | ||||
|         const formData = new FormData() | ||||
|         formData.append("image", this.series.cover_image); | ||||
|         formData.append("request", JSON.stringify(request)) | ||||
|  | ||||
|         const res = await api.createSeries(formData); | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
|           this.cancel(); | ||||
|           this.notifySuccess(res.data.message || '등록되었습니다.') | ||||
|           this.page = 1 | ||||
|           await this.getSeriesList() | ||||
|         } else { | ||||
|           this.is_loading = false | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|           this.is_loading = false | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async modify() { | ||||
|       if (this.is_loading) return; | ||||
|       this.is_loading = true | ||||
|  | ||||
|       try { | ||||
|         const request = {seriesId: this.selected_series.seriesId} | ||||
|         if (this.selected_series.title !== this.series.title) { | ||||
|           request.title = this.series.title | ||||
|         } | ||||
|  | ||||
|         if (this.selected_series.introduction !== this.series.introduction) { | ||||
|           request.introduction = this.series.introduction | ||||
|         } | ||||
|  | ||||
|         if (this.selected_series.publishedDaysOfWeek !== this.series.published_days_of_week) { | ||||
|           request.publishedDaysOfWeek = this.series.published_days_of_week | ||||
|         } | ||||
|  | ||||
|         if (this.selected_series.genreId !== this.series.genre_id) { | ||||
|           request.genreId = this.series.genre_id | ||||
|         } | ||||
|  | ||||
|         if (this.selected_series.isAdult !== this.series.is_adult) { | ||||
|           request.isAdult = this.series.is_adult | ||||
|         } | ||||
|  | ||||
|         if (this.selected_series.state !== this.series.state) { | ||||
|           request.state = this.series.state | ||||
|         } | ||||
|  | ||||
|         if (this.selected_series.state !== this.series.state) { | ||||
|           request.state = this.series.state | ||||
|         } | ||||
|  | ||||
|         if (this.selected_series.writer !== this.series.writer) { | ||||
|           request.writer = this.series.writer | ||||
|         } | ||||
|  | ||||
|         if (this.selected_series.studio !== this.series.studio) { | ||||
|           request.studio = this.series.studio | ||||
|         } | ||||
|  | ||||
|         const formData = new FormData() | ||||
|         formData.append("request", JSON.stringify(request)) | ||||
|  | ||||
|         if (this.series.cover_image !== undefined && this.series.cover_image !== null) { | ||||
|           formData.append("image", this.series.cover_image); | ||||
|         } | ||||
|  | ||||
|         const res = await api.modifySeries(formData); | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
|           this.cancel(); | ||||
|           this.notifySuccess(res.data.message || '등록되었습니다.') | ||||
|           this.page = 1 | ||||
|           await this.getSeriesList() | ||||
|         } else { | ||||
|           this.is_loading = false | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|           this.is_loading = false | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async deleteSeries() { | ||||
|       if (this.is_loading) return; | ||||
|       this.is_loading = true | ||||
|  | ||||
|       try { | ||||
|         const request = {seriesId: this.selected_series.seriesId, isActive: false} | ||||
|         const formData = new FormData() | ||||
|         formData.append("request", JSON.stringify(request)) | ||||
|  | ||||
|         const res = await api.modifySeries(formData) | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
|           this.cancel(); | ||||
|           this.notifySuccess('시리즈가 삭제되었습니다.') | ||||
|           this.page = 1 | ||||
|           await this.getSeriesList() | ||||
|         } else { | ||||
|           this.is_loading = false | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|           this.is_loading = false | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .image-select label { | ||||
|   display: inline-block; | ||||
|   padding: 10px 20px; | ||||
|   background-color: #232d4a; | ||||
|   color: #fff; | ||||
|   vertical-align: middle; | ||||
|   font-size: 15px; | ||||
|   cursor: pointer; | ||||
|   border-radius: 5px; | ||||
| } | ||||
|  | ||||
| .v-file-input { | ||||
|   position: absolute; | ||||
|   width: 0; | ||||
|   height: 0; | ||||
|   padding: 0; | ||||
|   overflow: hidden; | ||||
|   border: 0; | ||||
| } | ||||
|  | ||||
| .image-preview { | ||||
|   max-width: 100%; | ||||
|   width: 250px; | ||||
|   object-fit: cover; | ||||
|   margin-top: 10px; | ||||
| } | ||||
|  | ||||
| .series-title-container { | ||||
|   display: -webkit-box; | ||||
|   -webkit-box-orient: vertical; | ||||
|   overflow: hidden; | ||||
|   text-overflow: ellipsis; | ||||
|   -webkit-line-clamp: 2; | ||||
|   max-height: 2em; | ||||
| } | ||||
|  | ||||
| .cover-image { | ||||
|   aspect-ratio: 1/1.4; | ||||
| } | ||||
| </style> | ||||
		Reference in New Issue
	
	Block a user