feat: 캐릭터 등록 폼 추가
This commit is contained in:
@@ -139,77 +139,6 @@
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
<!-- 캐릭터 추가/수정 다이얼로그 -->
|
||||
<v-dialog
|
||||
v-model="show_dialog"
|
||||
max-width="600px"
|
||||
persistent
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
{{ is_edit ? '캐릭터 수정' : '캐릭터 추가' }}
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-container>
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-text-field
|
||||
v-model="character.name"
|
||||
label="이름"
|
||||
required
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-textarea
|
||||
v-model="character.description"
|
||||
label="설명"
|
||||
required
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-file-input
|
||||
v-model="character.image"
|
||||
label="캐릭터 이미지"
|
||||
accept="image/*"
|
||||
prepend-icon="mdi-camera"
|
||||
show-size
|
||||
truncate-length="15"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-switch
|
||||
v-model="character.isActive"
|
||||
label="활성화"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
color="blue darken-1"
|
||||
text
|
||||
@click="closeDialog"
|
||||
>
|
||||
취소
|
||||
</v-btn>
|
||||
<v-btn
|
||||
color="blue darken-1"
|
||||
text
|
||||
@click="saveCharacter"
|
||||
>
|
||||
저장
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<!-- 삭제 확인 다이얼로그 -->
|
||||
<v-dialog
|
||||
@@ -246,6 +175,7 @@
|
||||
|
||||
<script>
|
||||
import VueShowMoreText from 'vue-show-more-text'
|
||||
import { getCharacterList, searchCharacters, deleteCharacter as apiDeleteCharacter } from '@/api/character'
|
||||
|
||||
export default {
|
||||
name: "CharacterList",
|
||||
@@ -255,21 +185,10 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
is_loading: false,
|
||||
show_dialog: false,
|
||||
show_delete_confirm_dialog: false,
|
||||
is_edit: false,
|
||||
page: 1,
|
||||
total_page: 0,
|
||||
search_word: '',
|
||||
character: {
|
||||
id: null,
|
||||
name: '',
|
||||
description: '',
|
||||
image: null,
|
||||
imageUrl: '',
|
||||
isActive: true,
|
||||
createdAt: ''
|
||||
},
|
||||
characters: [],
|
||||
selected_character: {}
|
||||
}
|
||||
@@ -289,47 +208,18 @@ export default {
|
||||
},
|
||||
|
||||
showAddDialog() {
|
||||
this.is_edit = false
|
||||
this.character = {
|
||||
id: null,
|
||||
name: '',
|
||||
description: '',
|
||||
image: null,
|
||||
imageUrl: '',
|
||||
isActive: true,
|
||||
createdAt: ''
|
||||
}
|
||||
this.show_dialog = true
|
||||
// 페이지로 이동
|
||||
this.$router.push('/character/form');
|
||||
},
|
||||
|
||||
showEditDialog(item) {
|
||||
this.is_edit = true
|
||||
this.selected_character = item
|
||||
this.character = {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
description: item.description,
|
||||
image: null,
|
||||
imageUrl: item.imageUrl,
|
||||
isActive: item.isActive,
|
||||
createdAt: item.createdAt
|
||||
}
|
||||
this.show_dialog = true
|
||||
// 페이지로 이동하면서 id 전달
|
||||
this.$router.push({
|
||||
path: '/character/form',
|
||||
query: { id: item.id }
|
||||
});
|
||||
},
|
||||
|
||||
closeDialog() {
|
||||
this.show_dialog = false
|
||||
this.character = {
|
||||
id: null,
|
||||
name: '',
|
||||
description: '',
|
||||
image: null,
|
||||
imageUrl: '',
|
||||
isActive: true,
|
||||
createdAt: ''
|
||||
}
|
||||
this.selected_character = {}
|
||||
},
|
||||
|
||||
deleteConfirm(item) {
|
||||
this.selected_character = item
|
||||
@@ -341,68 +231,21 @@ export default {
|
||||
this.selected_character = {}
|
||||
},
|
||||
|
||||
async saveCharacter() {
|
||||
if (
|
||||
this.character.name === null ||
|
||||
this.character.name === undefined ||
|
||||
this.character.name.trim().length <= 0
|
||||
) {
|
||||
this.notifyError("이름을 입력하세요")
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
this.character.description === null ||
|
||||
this.character.description === undefined ||
|
||||
this.character.description.trim().length <= 0
|
||||
) {
|
||||
this.notifyError("설명을 입력하세요")
|
||||
return
|
||||
}
|
||||
|
||||
if (this.is_loading) return;
|
||||
|
||||
this.is_loading = true
|
||||
|
||||
try {
|
||||
// 여기에 API 호출 코드를 추가합니다.
|
||||
// 예시:
|
||||
// const res = this.is_edit
|
||||
// ? await api.updateCharacter(this.character)
|
||||
// : await api.createCharacter(this.character);
|
||||
|
||||
// API 호출이 없으므로 임시로 성공 처리
|
||||
setTimeout(() => {
|
||||
this.closeDialog()
|
||||
this.notifySuccess(this.is_edit ? '수정되었습니다.' : '추가되었습니다.')
|
||||
this.getCharacters()
|
||||
this.is_loading = false
|
||||
}, 1000)
|
||||
} catch (e) {
|
||||
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||
this.is_loading = false
|
||||
}
|
||||
},
|
||||
|
||||
async deleteCharacter() {
|
||||
if (this.is_loading) return;
|
||||
this.is_loading = true
|
||||
|
||||
try {
|
||||
// 여기에 API 호출 코드를 추가합니다.
|
||||
// 예시:
|
||||
// const res = await api.deleteCharacter(this.selected_character.id);
|
||||
|
||||
// API 호출이 없으므로 임시로 성공 처리
|
||||
setTimeout(() => {
|
||||
this.closeDeleteDialog()
|
||||
this.notifySuccess('삭제되었습니다.')
|
||||
this.getCharacters()
|
||||
this.is_loading = false
|
||||
}, 1000)
|
||||
await apiDeleteCharacter(this.selected_character.id);
|
||||
this.closeDeleteDialog();
|
||||
this.notifySuccess('삭제되었습니다.');
|
||||
await this.getCharacters();
|
||||
} catch (e) {
|
||||
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||
this.is_loading = false
|
||||
console.error('캐릭터 삭제 오류:', e);
|
||||
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.');
|
||||
} finally {
|
||||
this.is_loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -418,38 +261,22 @@ export default {
|
||||
async getCharacters() {
|
||||
this.is_loading = true
|
||||
try {
|
||||
// 여기에 API 호출 코드를 추가합니다.
|
||||
// 예시:
|
||||
// const res = await api.getCharacters(this.page);
|
||||
const response = await getCharacterList(this.page);
|
||||
|
||||
// API 호출이 없으므로 임시 데이터 생성
|
||||
setTimeout(() => {
|
||||
// 임시 데이터
|
||||
const mockData = {
|
||||
totalCount: 15,
|
||||
items: Array.from({ length: 10 }, (_, i) => ({
|
||||
id: i + 1 + (this.page - 1) * 10,
|
||||
name: `캐릭터 ${i + 1 + (this.page - 1) * 10}`,
|
||||
description: `이것은 캐릭터 ${i + 1 + (this.page - 1) * 10}에 대한 설명입니다. 이 캐릭터는 다양한 특성을 가지고 있습니다.`,
|
||||
imageUrl: 'https://via.placeholder.com/150',
|
||||
isActive: Math.random() > 0.3,
|
||||
createdAt: new Date().toISOString().split('T')[0]
|
||||
}))
|
||||
}
|
||||
if (response && response.data) {
|
||||
const data = response.data;
|
||||
this.characters = data.items || [];
|
||||
|
||||
const total_page = Math.ceil(mockData.totalCount / 10)
|
||||
this.characters = mockData.items
|
||||
|
||||
if (total_page <= 0)
|
||||
this.total_page = 1
|
||||
else
|
||||
this.total_page = total_page
|
||||
|
||||
this.is_loading = false
|
||||
}, 500)
|
||||
const total_page = Math.ceil((data.totalCount || 0) / 10);
|
||||
this.total_page = total_page <= 0 ? 1 : total_page;
|
||||
} else {
|
||||
throw new Error('응답 데이터가 없습니다.');
|
||||
}
|
||||
} catch (e) {
|
||||
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||
this.is_loading = false
|
||||
console.error('캐릭터 목록 조회 오류:', e);
|
||||
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.');
|
||||
} finally {
|
||||
this.is_loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -466,40 +293,22 @@ export default {
|
||||
} else {
|
||||
this.is_loading = true
|
||||
try {
|
||||
// 여기에 API 호출 코드를 추가합니다.
|
||||
// 예시:
|
||||
// const res = await api.searchCharacters(this.search_word, this.page);
|
||||
const response = await searchCharacters(this.search_word, this.page);
|
||||
|
||||
// API 호출이 없으므로 임시 데이터 생성
|
||||
setTimeout(() => {
|
||||
// 검색 결과 임시 데이터
|
||||
const filteredItems = Array.from({ length: 3 }, (_, i) => ({
|
||||
id: i + 1,
|
||||
name: `${this.search_word} 캐릭터 ${i + 1}`,
|
||||
description: `이것은 ${this.search_word} 캐릭터 ${i + 1}에 대한 설명입니다.`,
|
||||
imageUrl: 'https://via.placeholder.com/150',
|
||||
isActive: true,
|
||||
createdAt: new Date().toISOString().split('T')[0]
|
||||
}))
|
||||
if (response && response.data) {
|
||||
const data = response.data;
|
||||
this.characters = data.items || [];
|
||||
|
||||
const mockData = {
|
||||
totalCount: 3,
|
||||
items: filteredItems
|
||||
}
|
||||
|
||||
const total_page = Math.ceil(mockData.totalCount / 10)
|
||||
this.characters = mockData.items
|
||||
|
||||
if (total_page <= 0)
|
||||
this.total_page = 1
|
||||
else
|
||||
this.total_page = total_page
|
||||
|
||||
this.is_loading = false
|
||||
}, 500)
|
||||
const total_page = Math.ceil((data.totalCount || 0) / 10);
|
||||
this.total_page = total_page <= 0 ? 1 : total_page;
|
||||
} else {
|
||||
throw new Error('응답 데이터가 없습니다.');
|
||||
}
|
||||
} catch (e) {
|
||||
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.')
|
||||
this.is_loading = false
|
||||
console.error('캐릭터 검색 오류:', e);
|
||||
this.notifyError('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.');
|
||||
} finally {
|
||||
this.is_loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user