오디션 상세페이지 - 배역 리스트/등록/수정/삭제 추가
This commit is contained in:
		| @@ -24,6 +24,31 @@ async function getAuditionDetail(id) { | ||||
|     return Vue.axios.get("/admin/audition/" + id); | ||||
| } | ||||
|  | ||||
| export { | ||||
|     getAuditionList, createAudition, updateAudition, getAuditionDetail | ||||
| async function createAuditionRole(formData) { | ||||
|     return Vue.axios.post("/admin/audition/role", formData, { | ||||
|         headers: { | ||||
|             "Content-Type": "multipart/form-data", | ||||
|         }, | ||||
|     }); | ||||
| } | ||||
|  | ||||
| async function updateAuditionRole(formData) { | ||||
|     return Vue.axios.put("/admin/audition/role", formData, { | ||||
|         headers: { | ||||
|             "Content-Type": "multipart/form-data", | ||||
|         }, | ||||
|     }); | ||||
| } | ||||
|  | ||||
| async function getAuditionRoleDetail(id) { | ||||
|     return Vue.axios.get("/admin/audition/role/" + id); | ||||
| } | ||||
|  | ||||
| async function getAuditionApplicantList(id, page) { | ||||
|     return Vue.axios.get("/admin/audition/role/" + id + "/applicant?page=" + (page - 1) + "&size=20"); | ||||
| } | ||||
|  | ||||
| export { | ||||
|     getAuditionList, createAudition, updateAudition, getAuditionDetail, | ||||
|     createAuditionRole, updateAuditionRole, getAuditionRoleDetail, getAuditionApplicantList | ||||
| } | ||||
|   | ||||
| @@ -50,6 +50,7 @@ | ||||
|                 color="#3bb9f1" | ||||
|                 dark | ||||
|                 depressed | ||||
|                 @click="showWriteDialog" | ||||
|               > | ||||
|                 배역 등록 | ||||
|               </v-btn> | ||||
| @@ -60,7 +61,7 @@ | ||||
|             <v-col | ||||
|               v-for="(item, i) in audition_role_list" | ||||
|               :key="i" | ||||
|               cols="12" | ||||
|               cols="4" | ||||
|             > | ||||
|               <v-card> | ||||
|                 <v-card-title> | ||||
| @@ -68,6 +69,7 @@ | ||||
|                   <v-img | ||||
|                     :src="item.imageUrl" | ||||
|                     class="audition-image" | ||||
|                     @click="selectAuditionRole(item)" | ||||
|                   /> | ||||
|                   <v-spacer /> | ||||
|                 </v-card-title> | ||||
| @@ -81,11 +83,13 @@ | ||||
|                   <v-spacer /> | ||||
|                   <v-btn | ||||
|                     text | ||||
|                     @click="showModifyDialog(item)" | ||||
|                   > | ||||
|                     수정 | ||||
|                   </v-btn> | ||||
|                   <v-btn | ||||
|                     text | ||||
|                     @click="deleteConfirm(item)" | ||||
|                   > | ||||
|                     삭제 | ||||
|                   </v-btn> | ||||
| @@ -101,6 +105,152 @@ | ||||
|         </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="audition_role.image" | ||||
|             accept="image/*" | ||||
|             @change="imageAdd" | ||||
|           /> | ||||
|         </div> | ||||
|         <img | ||||
|           v-if="audition_role.image_url" | ||||
|           :src="audition_role.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="audition_role.name" | ||||
|                 label="배역 이름" | ||||
|                 required | ||||
|               /> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-card-text> | ||||
|         <v-card-text> | ||||
|           <v-row align="center"> | ||||
|             <v-col cols="4"> | ||||
|               오디션 대본 URL | ||||
|             </v-col> | ||||
|             <v-col cols="8"> | ||||
|               <v-textarea | ||||
|                 v-model="audition_role.audition_script_url" | ||||
|                 label="오디션 대본 URL" | ||||
|                 required | ||||
|               /> | ||||
|             </v-col> | ||||
|           </v-row> | ||||
|         </v-card-text> | ||||
|         <v-card-text v-if="selected_role !== null"> | ||||
|           <v-row> | ||||
|             <v-col cols="4"> | ||||
|               모집상태 | ||||
|             </v-col> | ||||
|             <v-col | ||||
|               cols="8" | ||||
|               align="left" | ||||
|             > | ||||
|               <v-row> | ||||
|                 <v-col> | ||||
|                   <input | ||||
|                     id="radio_in_progress" | ||||
|                     v-model="audition_role.status" | ||||
|                     type="radio" | ||||
|                     value="IN_PROGRESS" | ||||
|                   > | ||||
|                   <label for="radio_in_progress"> 모집중</label> | ||||
|                 </v-col> | ||||
|                 <v-col> | ||||
|                   <input | ||||
|                     id="radio_complete" | ||||
|                     v-model="audition_role.status" | ||||
|                     type="radio" | ||||
|                     value="COMPLETED" | ||||
|                   > | ||||
|                   <label for="radio_complete"> 모집완료</label> | ||||
|                 </v-col> | ||||
|               </v-row> | ||||
|             </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_role !== 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="cancel" | ||||
|           > | ||||
|             취소 | ||||
|           </v-btn> | ||||
|           <v-btn | ||||
|             color="blue darken-1" | ||||
|             text | ||||
|             @click="deleteAuditionRole" | ||||
|           > | ||||
|             확인 | ||||
|           </v-btn> | ||||
|         </v-card-actions> | ||||
|       </v-card> | ||||
|     </v-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| @@ -122,7 +272,11 @@ export default { | ||||
|       audition_detail: {}, | ||||
|       audition_role_list: [], | ||||
|  | ||||
|       show_write_dialog: false, | ||||
|       show_delete_confirm_dialog: false, | ||||
|  | ||||
|       audition_role: {}, | ||||
|       selected_role: null, | ||||
|     } | ||||
|   }, | ||||
|  | ||||
| @@ -190,11 +344,206 @@ export default { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     imageAdd(payload) { | ||||
|       const file = payload; | ||||
|       if (file) { | ||||
|         this.audition_role.image_url = URL.createObjectURL(file) | ||||
|         URL.revokeObjectURL(file) | ||||
|       } else { | ||||
|         this.audition_role.image_url = null | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     showWriteDialog() { | ||||
|       this.show_write_dialog = true | ||||
|     }, | ||||
|  | ||||
|     showModifyDialog(auditionRole) { | ||||
|       this.audition_role = { | ||||
|         name: auditionRole.name, | ||||
|         image_url: auditionRole.imageUrl, | ||||
|         audition_script_url: auditionRole.auditionScriptUrl, | ||||
|         status: auditionRole.status | ||||
|       } | ||||
|  | ||||
|       this.selected_role = auditionRole | ||||
|       this.show_write_dialog = true | ||||
|     }, | ||||
|  | ||||
|     cancel() { | ||||
|       this.audition_role = {} | ||||
|       this.selected_role = null | ||||
|       this.show_write_dialog = false | ||||
|       this.show_delete_confirm_dialog = false | ||||
|     }, | ||||
|  | ||||
|     deleteConfirm(auditionRole) { | ||||
|       this.selected_role = auditionRole | ||||
|       this.show_delete_confirm_dialog = true | ||||
|     }, | ||||
|  | ||||
|     validate() { | ||||
|       if (this.audition_role.image === undefined || this.audition_role.image === null) { | ||||
|         this.notifyError('배역 이미지를 선택하세요') | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       if (this.audition_role.name.trim().length <= 0) { | ||||
|         this.notifyError('배역 이름을 입력하세요') | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       if ( | ||||
|         this.audition_role.audition_script_url === undefined || | ||||
|         this.audition_role.audition_script_url === null || | ||||
|         this.audition_role.audition_script_url.trim().length <= 10 | ||||
|       ) { | ||||
|         this.notifyError('오디션 대본 URL을 입력하세요') | ||||
|         return | ||||
|       } | ||||
|  | ||||
|       this.submit() | ||||
|     }, | ||||
|  | ||||
|     async submit() { | ||||
|       if (this.is_loading) return; | ||||
|       this.is_loading = true | ||||
|  | ||||
|       try { | ||||
|         const request = { | ||||
|           auditionId: this.audition_id, | ||||
|           name: this.audition_role.name, | ||||
|           auditionScriptUrl: this.audition_role.audition_script_url | ||||
|         } | ||||
|  | ||||
|         const formData = new FormData() | ||||
|         formData.append("image", this.audition_role.image); | ||||
|         formData.append("request", JSON.stringify(request)) | ||||
|  | ||||
|         const res = await api.createAuditionRole(formData); | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
|           this.cancel(); | ||||
|           this.notifySuccess(res.data.message || '등록되었습니다.') | ||||
|           this.is_loading = false | ||||
|  | ||||
|           await this.getAuditionDetail() | ||||
|         } else { | ||||
|           this.is_loading = false | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async modify() { | ||||
|       if (this.is_loading) return; | ||||
|       this.is_loading = true | ||||
|  | ||||
|       try { | ||||
|         const request = {id: this.selected_role.id} | ||||
|         if (this.audition_role.name !== this.selected_role.name) { | ||||
|           request.name = this.audition_role.name | ||||
|         } | ||||
|  | ||||
|         if (this.audition_role.audition_script_url !== this.selected_role.audition_script_url) { | ||||
|           request.auditionScriptUrl = this.audition_role.audition_script_url | ||||
|         } | ||||
|  | ||||
|         if (this.audition_role.status !== this.selected_role.status) { | ||||
|           request.status = this.audition_role.status | ||||
|         } | ||||
|  | ||||
|         const formData = new FormData() | ||||
|         formData.append("request", JSON.stringify(request)) | ||||
|  | ||||
|         if (this.audition_role.image !== undefined && this.audition_role.image !== null) { | ||||
|           formData.append("image", this.audition_role.image) | ||||
|         } | ||||
|  | ||||
|         const res = await api.updateAuditionRole(formData); | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
|           this.cancel(); | ||||
|           this.notifySuccess(res.data.message || '등록되었습니다.') | ||||
|           this.is_loading = false | ||||
|  | ||||
|           await this.getAuditionDetail() | ||||
|         } else { | ||||
|           this.is_loading = false | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     async deleteAuditionRole() { | ||||
|       if (this.is_loading) return; | ||||
|       this.is_loading = true | ||||
|  | ||||
|       try { | ||||
|         const request = {id: this.selected_role.id, isActive: false} | ||||
|         const formData = new FormData() | ||||
|         formData.append("request", JSON.stringify(request)) | ||||
|  | ||||
|         const res = await api.updateAuditionRole(formData) | ||||
|         if (res.status === 200 && res.data.success === true) { | ||||
|           this.cancel(); | ||||
|           this.notifySuccess('오디션 배역이 삭제되었습니다.') | ||||
|           this.is_loading = false | ||||
|  | ||||
|           await this.getAuditionDetail() | ||||
|         } else { | ||||
|           this.is_loading = false | ||||
|           this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|           this.is_loading = false | ||||
|         } | ||||
|       } catch (e) { | ||||
|         this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') | ||||
|       } finally { | ||||
|         this.is_loading = false | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     selectAuditionRole(auditionRole) { | ||||
|     }, | ||||
|   }, | ||||
| } | ||||
| </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: 300px; | ||||
|   object-fit: cover; | ||||
|   margin-top: 10px; | ||||
| } | ||||
|  | ||||
| .original-work-link { | ||||
|   text-decoration: none; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Yu Sung
					Yu Sung