"feat(api): 캐릭터 리스트 API 수정 및 데이터 처리 로직 개선

- API 경로를 /admin/chat/character/list로 변경
- size 파라미터 기본값을 20으로 설정
- 응답 데이터 구조 변경 (items → content)
- total_page 계산 로직 수정 (전체 개수와 size로 계산)
- 태그 표시 기능 추가"
This commit is contained in:
Yu Sung 2025-08-07 17:01:13 +09:00
parent 3783714c75
commit 13c85bb2a8
2 changed files with 37 additions and 34 deletions

View File

@ -1,15 +1,15 @@
import Vue from 'vue'; import Vue from 'vue';
// 캐릭터 리스트 // 캐릭터 리스트
async function getCharacterList(page = 1, size = 10) { async function getCharacterList(page = 1, size = 20) {
return Vue.axios.get('/api/admin/characters', { return Vue.axios.get('/admin/chat/character/list', {
params: { page, size } params: { page: page - 1, size }
}) })
} }
// 캐릭터 검색 // 캐릭터 검색
async function searchCharacters(keyword, page = 1, size = 10) { async function searchCharacters(keyword, page = 1, size = 20) {
return Vue.axios.get('/api/admin/characters/search', { return Vue.axios.get('/api/admin/chat/character/search', {
params: { keyword, page, size } params: { keyword, page, size }
}) })
} }

View File

@ -70,6 +70,9 @@
<th class="text-center"> <th class="text-center">
대화 스타일 대화 스타일
</th> </th>
<th class="text-center">
태그
</th>
<th class="text-center"> <th class="text-center">
등록일 등록일
</th> </th>
@ -97,7 +100,7 @@
</td> </td>
<td>{{ item.name }}</td> <td>{{ item.name }}</td>
<td>{{ item.gender || '-' }}</td> <td>{{ item.gender || '-' }}</td>
<td>{{ calculateAge(item.birthDate) }}</td> <td>{{ item.age || '-' }}</td>
<td> <td>
<v-btn <v-btn
small small
@ -121,11 +124,26 @@
<v-btn <v-btn
small small
color="info" color="info"
@click="showDetailDialog(item, 'systemPrompt')" @click="showDetailDialog(item, 'speechStyle')"
> >
보기 보기
</v-btn> </v-btn>
</td> </td>
<td>
<div v-if="item.tags && item.tags.length > 0">
<v-chip
v-for="(tag, index) in item.tags"
:key="index"
small
class="ma-1"
color="primary"
text-color="white"
>
{{ tag }}
</v-chip>
</div>
<span v-else>-</span>
</td>
<td>{{ item.createdAt }}</td> <td>{{ item.createdAt }}</td>
<td>{{ item.updatedAt || '-' }}</td> <td>{{ item.updatedAt || '-' }}</td>
<td> <td>
@ -211,9 +229,11 @@
<v-card-title> <v-card-title>
{{ detail_title }} {{ detail_title }}
</v-card-title> </v-card-title>
<v-divider></v-divider> <v-divider />
<v-card-text class="pt-4"> <v-card-text class="pt-4">
<div style="white-space: pre-wrap;">{{ detail_content }}</div> <div style="white-space: pre-wrap;">
{{ detail_content }}
</div>
</v-card-text> </v-card-text>
<v-card-actions> <v-card-actions>
<v-spacer /> <v-spacer />
@ -265,23 +285,6 @@ export default {
this.$dialog.notify.success(message) this.$dialog.notify.success(message)
}, },
calculateAge(birthDate) {
if (!birthDate) return '-';
// birthDate YYYY-MM-DD
const today = new Date();
const birth = new Date(birthDate);
let age = today.getFullYear() - birth.getFullYear();
const monthDiff = today.getMonth() - birth.getMonth();
// 1
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
age--;
}
return age;
},
showDetailDialog(item, type) { showDetailDialog(item, type) {
this.selected_character = item; this.selected_character = item;
@ -297,9 +300,9 @@ export default {
this.detail_title = '말투'; this.detail_title = '말투';
this.detail_content = item.speechPattern || '내용이 없습니다.'; this.detail_content = item.speechPattern || '내용이 없습니다.';
break; break;
case 'systemPrompt': case 'speechStyle':
this.detail_title = '대화 스타일'; this.detail_title = '대화 스타일';
this.detail_content = item.systemPrompt || '내용이 없습니다.'; this.detail_content = item.speechStyle || '내용이 없습니다.';
break; break;
default: default:
this.detail_title = ''; this.detail_title = '';
@ -374,12 +377,12 @@ export default {
if (response && response.data) { if (response && response.data) {
const data = response.data; const data = response.data;
this.characters = data.items || []; this.characters = data.content || [];
const total_page = Math.ceil((data.totalCount || 0) / 10); const total_page = Math.ceil((data.totalCount || 0) / 20);
this.total_page = total_page <= 0 ? 1 : total_page; this.total_page = total_page <= 0 ? 1 : total_page;
} else { } else {
throw new Error('응답 데이터가 없습니다.'); this.notifyError('응답 데이터가 없습니다.');
} }
} catch (e) { } catch (e) {
console.error('캐릭터 목록 조회 오류:', e); console.error('캐릭터 목록 조회 오류:', e);
@ -406,12 +409,12 @@ export default {
if (response && response.data) { if (response && response.data) {
const data = response.data; const data = response.data;
this.characters = data.items || []; this.characters = data.content || [];
const total_page = Math.ceil((data.totalCount || 0) / 10); const total_page = Math.ceil((data.totalCount || 0) / 20);
this.total_page = total_page <= 0 ? 1 : total_page; this.total_page = total_page <= 0 ? 1 : total_page;
} else { } else {
throw new Error('응답 데이터가 없습니다.'); this.notifyError('응답 데이터가 없습니다.');
} }
} catch (e) { } catch (e) {
console.error('캐릭터 검색 오류:', e); console.error('캐릭터 검색 오류:', e);