<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="#9970ff" dark depressed @click="showWriteDialog" > 시그니처 등록 </v-btn> </v-col> </v-row> <v-row> <v-col> <v-data-table :headers="headers" :items="signature_list" :loading="is_loading" :items-per-page="-1" item-key="id" class="elevation-1" hide-default-footer > <template v-slot:item.id="{ item }"> {{ item.id }} </template> <template v-slot:item.nickname="{ item }"> {{ item.nickname }} </template> <template v-slot:item.can="{ item }"> {{ item.can }} </template> <template v-slot:item.isAdult="{ item }"> <h3 v-if="item.isAdult"> O </h3> <h3 v-else> X </h3> </template> <template v-slot:item.image="{ item }"> <v-img :src="item.image" max-width="200" max-height="200" align="center" class="center-image" /> </template> <template v-slot:item.management="{ item }"> <v-row> <v-col /> <v-col> <v-btn :disabled="is_loading" @click="showModifyDialog(item)" > 수정 </v-btn> </v-col> <v-col> <v-btn :disabled="is_loading" @click="showDeleteConfirm(item)" > 삭제 </v-btn> </v-col> <v-col /> </v-row> </template> </v-data-table> </v-col> </v-row> <v-row class="text-center"> <v-col> <v-pagination v-model="page" :length="total_page" circle @input="next" /> </v-col> </v-row> </v-container> <v-row> <v-dialog v-model="show_write_dialog" max-width="1000px" persistent > <v-card> <v-card-title> 시그니처 캔 등록 </v-card-title> <v-card-text> <v-row align="center"> <v-col cols="4"> 크리에이터 번호 </v-col> <v-col cols="8"> <v-text-field v-model="creator_id" 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-text-field v-model="can" label="캔" /> </v-col> </v-row> </v-card-text> <v-card-text> <v-row> <v-col cols="4"> 19금 </v-col> <v-col cols="8"> <input v-model="is_adult" type="checkbox" > </v-col> </v-row> </v-card-text> <v-card-text> <v-row align="center"> <v-col cols="4"> 이미지 </v-col> <v-col cols="8"> <div class="image-select"> <label for="image"> 이미지 불러오기 </label> <v-file-input id="image" v-model="image" accept="image/*" @change="imageAdd" /> </div> <img v-if="image_url" :src="image_url" alt="" class="image-preview" > </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="validate" > 등록 </v-btn> </v-card-actions> </v-card> </v-dialog> </v-row> <v-row> <v-dialog v-model="show_modify_dialog" max-width="1000px" persistent > <v-card> <v-card-title> 시그니처 캔 수정 </v-card-title> <v-card-text> <v-row align="center"> <v-col cols="4"> 캔 </v-col> <v-col cols="8"> <v-text-field v-model="can" label="캔" /> </v-col> </v-row> </v-card-text> <v-card-text> <v-row> <v-col cols="4"> 19금 </v-col> <v-col cols="8"> <input v-model="is_adult" type="checkbox" > </v-col> </v-row> </v-card-text> <v-card-text> <v-row align="center"> <v-col cols="4"> 이미지 </v-col> <v-col cols="8"> <div class="image-select"> <label for="image"> 이미지 불러오기 </label> <v-file-input id="image" v-model="image" accept="image/*" @change="imageAdd" /> </div> <img v-if="image_url" :src="image_url" alt="" class="image-preview" > </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="modifySignatureCan" > 수정 </v-btn> </v-card-actions> </v-card> </v-dialog> </v-row> <v-row> <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="deleteSignature" > 확인 </v-btn> </v-card-actions> </v-card> </v-dialog> </v-row> </div> </template> <script> import * as api from "@/api/signature"; export default { name: "CanSignature", data() { return { is_loading: false, show_write_dialog: false, show_modify_dialog: false, show_delete_confirm_dialog: false, signature_list: [], page: 1, total_page: 0, can: 0, image: null, is_adult: false, image_url: null, creator_id: null, is_active: null, selected_signature_can: {}, headers: [ { text: '순번', align: 'center', sortable: false, value: 'id', }, { text: '닉네임', align: 'center', sortable: false, value: 'nickname', }, { text: '캔', align: 'center', sortable: false, value: 'can', }, { text: '19금', align: 'center', sortable: false, value: 'isAdult', }, { text: '이미지', align: 'center', sortable: false, value: 'image', }, { text: '관리', align: 'center', sortable: false, value: 'management', }, ], } }, async created() { await this.getSignatureList(); }, methods: { notifyError(message) { this.$dialog.notify.error(message) }, notifySuccess(message) { this.$dialog.notify.success(message) }, imageAdd(payload) { const file = payload; if (file) { this.image_url = URL.createObjectURL(file) URL.revokeObjectURL(file) } else { this.image_url = null } }, showWriteDialog() { this.show_write_dialog = true }, showModifyDialog(item) { this.can = item.can; this.is_adult = item.isAdult this.image_url = item.image; this.selected_signature_can = item this.show_modify_dialog = true }, showDeleteConfirm(item) { this.selected_signature_can = item this.show_delete_confirm_dialog = true }, validate() { if ( this.can === 0 || this.image === null || this.creator_id === null ) { this.notifyError('내용을 입력하세요') } else { this.submit() } }, cancel() { this.show_write_dialog = false this.show_modify_dialog = false this.show_delete_confirm_dialog = false this.image = null this.image_url = null this.can = 0 this.is_active = null this.is_adult = false this.selected_signature_can = {} }, async getSignatureList() { this.isLoading = true try { let res = await api.getSignatureList(this.page); if (res.status === 200 && res.data.success === true) { const data = res.data.data const total_page = Math.ceil(data.totalCount / 20) this.signature_list = data.items if (total_page <= 0) this.total_page = 1 else this.total_page = total_page } } catch (e) { this.notifyError("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.") } finally { this.isLoading = false } }, async submit() { if (this.is_loading) return; this.is_loading = true try { const formData = new FormData() formData.append("can", this.can) formData.append("image", this.image) formData.append("isAdult", this.is_adult) formData.append("creator_id", this.creator_id) const res = await api.createSignature(formData) if (res.status === 200 && res.data.success === true) { this.cancel() this.notifySuccess(res.data.message || '등록되었습니다.') this.page = 1 await this.getSignatureList() } else { this.is_loading = false this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') } } catch (e) { this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') this.is_loading = false } finally { this.is_loading = false } }, async modifySignatureCan() { if ( this.image === null && this.is_adult === this.selected_signature_can.isAdult && this.can === this.selected_signature_can.can ) { this.notifyError('수정사항이 없습니다.') return; } if (this.is_loading) return; this.is_loading = true try { const formData = new FormData() formData.append("id", this.selected_signature_can.id) if (this.image !== null) { formData.append("image", this.image) } if (this.is_adult !== this.selected_signature_can.isAdult) { formData.append("isAdult", this.is_adult) } if (this.can !== this.selected_signature_can.can) { formData.append("can", this.can) } const res = await api.modifySignature(formData) if (res.status === 200 && res.data.success === true) { this.cancel() this.notifySuccess(res.data.message || '수정되었습니다.') this.page = 1 await this.getSignatureList() } else { this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') this.is_loading = false } } catch (e) { this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') this.is_loading = false } finally { this.is_loading = false } }, async deleteSignature() { if (this.is_loading) return; this.is_loading = true try { const formData = new FormData() formData.append("id", this.selected_signature_can.id) formData.append("isActive", false) const res = await api.modifySignature(formData) if (res.status === 200 && res.data.success === true) { this.cancel() this.notifySuccess(res.data.message || '등록되었습니다.') this.page = 1 await this.getSignatureList() } else { this.is_loading = false this.notifyError(res.data.message || '알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') } } catch (e) { this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.') this.is_loading = false } finally { this.is_loading = false } }, async next() { await this.getSignatureList(); } } } </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; } .v-card__text { margin-top: 20px; } .v-card__actions { margin-top: 100px; } .v-card__actions > .v-btn { font-size: 20px; } .center-image { display: block; margin: 0 auto; } </style>