캐릭터 챗봇 #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()) { | ||||
|       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; | ||||
|       } | ||||
|  | ||||
|         if (this.newRelationship.length > 200) { | ||||
|           this.newRelationship = this.newRelationship.substring(0, 200); | ||||
|         } | ||||
|       // 길이 제한 적용 | ||||
|       let personName = r.personName.trim().substring(0, 10); | ||||
|       let relationshipName = r.relationshipName.trim().substring(0, 20); | ||||
|       let description = (r.description || '').trim().substring(0, 500); | ||||
|  | ||||
|         this.relationships.unshift(this.newRelationship.trim()); | ||||
|         this.newRelationship = ''; | ||||
|       } | ||||
|       // 중요도 범위 보정 | ||||
|       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 => { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user