캐릭터 챗봇 #74
|
@ -280,82 +280,6 @@
|
|||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- 인물 관계 -->
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-divider class="my-4" />
|
||||
<h3 class="mb-2">
|
||||
인물 관계
|
||||
</h3>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-row>
|
||||
<v-col cols="11">
|
||||
<v-text-field
|
||||
v-model="newRelationship"
|
||||
label="새 인물 관계 추가 (최대 200자)"
|
||||
outlined
|
||||
dense
|
||||
counter="200"
|
||||
:rules="[v => v.length <= 200 || '최대 200자까지 입력 가능합니다']"
|
||||
@keyup.enter="addRelationship"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="1">
|
||||
<v-btn
|
||||
color="primary"
|
||||
class="mt-1"
|
||||
block
|
||||
:disabled="!newRelationship.trim() || relationships.length >= 10"
|
||||
@click="addRelationship"
|
||||
>
|
||||
추가
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-card
|
||||
outlined
|
||||
class="memory-container"
|
||||
>
|
||||
<v-list
|
||||
v-if="relationships.length > 0"
|
||||
class="memory-list"
|
||||
>
|
||||
<v-list-item
|
||||
v-for="(relationship, index) in relationships"
|
||||
:key="index"
|
||||
class="memory-item"
|
||||
>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title class="memory-text">
|
||||
{{ relationship }}
|
||||
</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-btn
|
||||
small
|
||||
color="error"
|
||||
class="delete-btn"
|
||||
@click="removeRelationship(index)"
|
||||
>
|
||||
삭제
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<v-card-text
|
||||
v-else
|
||||
class="text-center grey--text"
|
||||
>
|
||||
인물 관계가 없습니다. 위 입력창에서 인물 관계를 추가해주세요. (최대 10개)
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- 취미 목록 -->
|
||||
<v-row>
|
||||
|
@ -881,6 +805,154 @@
|
|||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- 인물 관계 -->
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-divider class="my-4" />
|
||||
<h3 class="mb-2">
|
||||
인물 관계
|
||||
</h3>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<!-- 1행: 상대방 이름, 관계명 -->
|
||||
<v-row>
|
||||
<v-col cols="4">
|
||||
<v-text-field
|
||||
v-model="newRelationship.personName"
|
||||
label="상대방 이름 (최대 10자)"
|
||||
outlined
|
||||
dense
|
||||
counter="10"
|
||||
:rules="personNameRules"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="8">
|
||||
<v-text-field
|
||||
v-model="newRelationship.relationshipName"
|
||||
label="관계명 (어머니, 아버지, 친구 등) (최대 20자)"
|
||||
outlined
|
||||
dense
|
||||
counter="20"
|
||||
:rules="relationshipNameRules"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- 2행: 관계 타입, 현재 상태, 중요도 -->
|
||||
<v-row>
|
||||
<v-col cols="5">
|
||||
<v-text-field
|
||||
v-model="newRelationship.relationshipType"
|
||||
label="관계 타입 (최대 10자)"
|
||||
outlined
|
||||
dense
|
||||
counter="10"
|
||||
:rules="relationshipTypeRules"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="5">
|
||||
<v-text-field
|
||||
v-model="newRelationship.currentStatus"
|
||||
label="현재 상태 (최대 10자)"
|
||||
outlined
|
||||
dense
|
||||
counter="10"
|
||||
:rules="relationshipStatusRules"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="2">
|
||||
<v-text-field
|
||||
v-model.number="newRelationship.importance"
|
||||
label="중요도 (1~10)"
|
||||
outlined
|
||||
dense
|
||||
type="number"
|
||||
min="1"
|
||||
max="10"
|
||||
:rules="relationshipImportanceRules"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="11">
|
||||
<v-textarea
|
||||
v-model="newRelationship.description"
|
||||
label="관계 설명 (최대 500자)"
|
||||
outlined
|
||||
dense
|
||||
auto-grow
|
||||
rows="2"
|
||||
counter="500"
|
||||
:rules="relationshipDescriptionRules"
|
||||
@keyup.enter="addRelationship"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="1">
|
||||
<v-btn
|
||||
color="primary"
|
||||
class="mt-1"
|
||||
block
|
||||
:disabled="!newRelationship.personName || !newRelationship.relationshipName || !newRelationship.relationshipType || !newRelationship.currentStatus || !newRelationship.importance || relationships.length >= 10"
|
||||
@click="addRelationship"
|
||||
>
|
||||
추가
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-card
|
||||
outlined
|
||||
class="memory-container"
|
||||
>
|
||||
<v-list
|
||||
v-if="relationships.length > 0"
|
||||
class="memory-list"
|
||||
>
|
||||
<v-list-item
|
||||
v-for="(relationship, index) in relationships"
|
||||
:key="index"
|
||||
class="memory-item"
|
||||
>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title class="memory-text font-weight-bold">
|
||||
{{ relationship.personName }} - {{ relationship.relationshipName }}
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle class="memory-text mt-1">
|
||||
타입: {{ relationship.relationshipType }} | 상태: {{ relationship.currentStatus }} | 중요도: {{ relationship.importance }}
|
||||
</v-list-item-subtitle>
|
||||
<v-list-item-subtitle
|
||||
v-if="relationship.description"
|
||||
class="memory-text mt-1"
|
||||
>
|
||||
{{ relationship.description }}
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-btn
|
||||
small
|
||||
color="error"
|
||||
class="delete-btn"
|
||||
@click="removeRelationship(index)"
|
||||
>
|
||||
삭제
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<v-card-text
|
||||
v-else
|
||||
class="text-center grey--text"
|
||||
>
|
||||
인물 관계가 없습니다. 위 입력창에서 인물 관계를 추가해주세요. (최대 10개)
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- 활성화 상태 -->
|
||||
<v-row v-show="isEdit">
|
||||
<v-col cols="12">
|
||||
|
@ -936,7 +1008,14 @@ export default {
|
|||
newMemoryTitle: '',
|
||||
newMemoryContent: '',
|
||||
newMemoryEmotion: '',
|
||||
newRelationship: '',
|
||||
newRelationship: {
|
||||
personName: '',
|
||||
relationshipName: '',
|
||||
description: '',
|
||||
importance: null,
|
||||
relationshipType: '',
|
||||
currentStatus: ''
|
||||
},
|
||||
newHobby: '',
|
||||
newValue: '',
|
||||
newGoal: '',
|
||||
|
@ -1007,6 +1086,33 @@ export default {
|
|||
typeOptions: ['Clone', 'Character'],
|
||||
systemPromptRules: [
|
||||
v => (this.isEdit ? true : (!!v && v.trim().length > 0) || '시스템 프롬프트를 입력하세요')
|
||||
],
|
||||
// 인물 관계 옵션 및 검증 규칙
|
||||
relationshipTypeOptions: ['가족', '친구', '동료', '연인', '기타'],
|
||||
relationshipStatusOptions: ['생존', '사망', '불명'],
|
||||
personNameRules: [
|
||||
v => (v === '' || v != null) || '상대방 이름을 입력하세요',
|
||||
v => (!v || (typeof v === 'string' && v.length <= 10)) || '최대 10자까지 입력 가능합니다',
|
||||
v => (!!v && v.trim().length > 0) || '상대방 이름을 입력하세요'
|
||||
],
|
||||
relationshipNameRules: [
|
||||
v => (!!v && v.trim().length > 0) || '관계명을 입력하세요',
|
||||
v => (typeof v === 'string' && v.length <= 20) || '최대 20자까지 입력 가능합니다'
|
||||
],
|
||||
relationshipDescriptionRules: [
|
||||
v => (!v || (typeof v === 'string' && v.length <= 500)) || '최대 500자까지 입력 가능합니다'
|
||||
],
|
||||
relationshipImportanceRules: [
|
||||
v => (v !== null && v !== '' && !isNaN(v)) || '중요도를 입력하세요',
|
||||
v => (parseInt(v) >= 1 && parseInt(v) <= 10) || '1~10 사이 숫자만 입력 가능합니다'
|
||||
],
|
||||
relationshipTypeRules: [
|
||||
v => (!!v && v.trim().length > 0) || '관계 타입을 입력하세요',
|
||||
v => (typeof v === 'string' && v.length <= 10) || '최대 10자까지 입력 가능합니다'
|
||||
],
|
||||
relationshipStatusRules: [
|
||||
v => (!!v && v.trim().length > 0) || '현재 상태를 입력하세요',
|
||||
v => (typeof v === 'string' && v.length <= 10) || '최대 10자까지 입력 가능합니다'
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -1145,19 +1251,52 @@ export default {
|
|||
},
|
||||
|
||||
addRelationship() {
|
||||
if (this.newRelationship.trim()) {
|
||||
if (this.relationships.length >= 10) {
|
||||
this.notifyError('인물 관계는 최대 10개까지 등록 가능합니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.newRelationship.length > 200) {
|
||||
this.newRelationship = this.newRelationship.substring(0, 200);
|
||||
}
|
||||
|
||||
this.relationships.unshift(this.newRelationship.trim());
|
||||
this.newRelationship = '';
|
||||
const r = this.newRelationship;
|
||||
// 필수값 검사
|
||||
if (!r.personName || !r.relationshipName || !r.relationshipType || !r.currentStatus || r.importance === null || r.importance === '') {
|
||||
this.notifyError('상대방 이름, 관계명, 관계 타입, 현재 상태, 중요도를 모두 입력하세요.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.relationships.length >= 10) {
|
||||
this.notifyError('인물 관계는 최대 10개까지 등록 가능합니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
// 길이 제한 적용
|
||||
let personName = r.personName.trim().substring(0, 10);
|
||||
let relationshipName = r.relationshipName.trim().substring(0, 20);
|
||||
let description = (r.description || '').trim().substring(0, 500);
|
||||
|
||||
// 중요도 범위 보정
|
||||
let importance = parseInt(r.importance);
|
||||
if (isNaN(importance)) importance = 1;
|
||||
importance = Math.max(1, Math.min(10, importance));
|
||||
|
||||
// 타입/상태 길이 제한 적용
|
||||
let relationshipType = (r.relationshipType || '').trim().substring(0, 10);
|
||||
let currentStatus = (r.currentStatus || '').trim().substring(0, 10);
|
||||
|
||||
const relationshipObj = {
|
||||
personName,
|
||||
relationshipName,
|
||||
description,
|
||||
importance,
|
||||
relationshipType,
|
||||
currentStatus
|
||||
};
|
||||
|
||||
this.relationships.unshift(relationshipObj);
|
||||
|
||||
// 입력 필드 초기화
|
||||
this.newRelationship = {
|
||||
personName: '',
|
||||
relationshipName: '',
|
||||
description: '',
|
||||
importance: null,
|
||||
relationshipType: '',
|
||||
currentStatus: ''
|
||||
};
|
||||
},
|
||||
|
||||
removeRelationship(index) {
|
||||
|
@ -1371,7 +1510,7 @@ export default {
|
|||
|
||||
// 배열 필드 비교 (깊은 비교)
|
||||
const arrayFields = [
|
||||
'tags', 'hobbies', 'values', 'goals', 'relationships'
|
||||
'tags', 'hobbies', 'values', 'goals'
|
||||
];
|
||||
|
||||
arrayFields.forEach(field => {
|
||||
|
@ -1387,7 +1526,7 @@ export default {
|
|||
|
||||
// 복잡한 객체 배열 비교
|
||||
const objectArrayFields = [
|
||||
'personalities', 'backgrounds', 'memories'
|
||||
'personalities', 'backgrounds', 'memories', 'relationships'
|
||||
];
|
||||
|
||||
objectArrayFields.forEach(field => {
|
||||
|
|
Loading…
Reference in New Issue