캐릭터 챗봇 #74
| @@ -57,36 +57,15 @@ async function createCharacter(characterData) { | ||||
| } | ||||
|  | ||||
| // 캐릭터 수정 | ||||
| async function updateCharacter(characterData) { | ||||
| async function updateCharacter(characterData, image = null) { | ||||
|   const formData = new FormData() | ||||
|  | ||||
|   // 이미지만 FormData에 추가 | ||||
|   if (characterData.image) formData.append('image', characterData.image) | ||||
|   // 이미지가 있는 경우에만 FormData에 추가 | ||||
|   if (image) formData.append('image', image) | ||||
|  | ||||
|   // 나머지 데이터는 JSON 문자열로 변환하여 request 필드에 추가 | ||||
|   const requestData = { | ||||
|     id: characterData.id, | ||||
|     name: characterData.name, | ||||
|     systemPrompt: characterData.systemPrompt, | ||||
|     description: characterData.description, | ||||
|     age: characterData.age, | ||||
|     gender: characterData.gender, | ||||
|     mbti: characterData.mbti, | ||||
|     speechPattern: characterData.speechPattern, | ||||
|     speechStyle: characterData.conversationStyle, | ||||
|     appearance: characterData.appearance, | ||||
|     tags: characterData.tags || [], | ||||
|     hobbies: characterData.hobbies || [], | ||||
|     values: characterData.values || [], | ||||
|     goals: characterData.goals || [], | ||||
|     relationships: characterData.relationships || [], | ||||
|     personalities: characterData.personalities || [], | ||||
|     backgrounds: characterData.backgrounds || [], | ||||
|     memories: characterData.memories || [], | ||||
|     isActive: characterData.isActive | ||||
|   } | ||||
|  | ||||
|   formData.append('request', JSON.stringify(requestData)) | ||||
|   // 변경된 데이터만 JSON 문자열로 변환하여 request 필드에 추가 | ||||
|   // characterData는 이미 변경된 필드만 포함하고 있음 | ||||
|   formData.append('request', JSON.stringify(characterData)) | ||||
|  | ||||
|   return Vue.axios.put(`/admin/chat/character/update`, formData, { | ||||
|     headers: { | ||||
|   | ||||
| @@ -914,6 +914,7 @@ export default { | ||||
|       goals: [], | ||||
|       personalities: [], | ||||
|       backgrounds: [], | ||||
|       originalCharacter: null, // 원본 캐릭터 데이터 저장용 | ||||
|       character: { | ||||
|         id: null, | ||||
|         name: '', | ||||
| @@ -1233,6 +1234,97 @@ export default { | ||||
|       this.backgrounds.splice(index, 1); | ||||
|     }, | ||||
|  | ||||
|     // 변경된 필드만 추출하는 함수 | ||||
|     getChangedFields() { | ||||
|       if (!this.originalCharacter || !this.isEdit) { | ||||
|         // 신규 등록인 경우 또는 원본 데이터가 없는 경우 전체 데이터 반환 | ||||
|         return { | ||||
|           name: this.character.name, | ||||
|           systemPrompt: this.character.systemPrompt, | ||||
|           description: this.character.description, | ||||
|           age: this.character.age, | ||||
|           gender: this.character.gender, | ||||
|           mbti: this.character.mbti, | ||||
|           speechPattern: this.character.speechPattern, | ||||
|           speechStyle: this.character.conversationStyle, | ||||
|           appearance: this.character.appearance, | ||||
|           tags: this.character.tags || [], | ||||
|           hobbies: this.character.hobbies || [], | ||||
|           values: this.character.values || [], | ||||
|           goals: this.character.goals || [], | ||||
|           relationships: this.character.relationships || [], | ||||
|           personalities: this.character.personalities || [], | ||||
|           backgrounds: this.character.backgrounds || [], | ||||
|           memories: this.character.memories || [], | ||||
|           isActive: this.character.isActive | ||||
|         }; | ||||
|       } | ||||
|  | ||||
|       // 변경된 필드만 포함하는 객체 | ||||
|       const changedFields = { | ||||
|         id: this.character.id // ID는 항상 포함 | ||||
|       }; | ||||
|  | ||||
|       // 기본 필드 비교 | ||||
|       const simpleFields = [ | ||||
|         'name', 'description', 'age', 'gender', 'mbti', | ||||
|         'speechPattern', 'isActive' | ||||
|       ]; | ||||
|  | ||||
|       simpleFields.forEach(field => { | ||||
|         if (this.character[field] !== this.originalCharacter[field]) { | ||||
|           changedFields[field] = this.character[field]; | ||||
|         } | ||||
|       }); | ||||
|  | ||||
|       // 특수 필드 매핑 처리 (conversationStyle은 API에서 speechStyle로 사용됨) | ||||
|       if (this.character.conversationStyle !== this.originalCharacter.conversationStyle) { | ||||
|         changedFields.speechStyle = this.character.conversationStyle; | ||||
|       } | ||||
|  | ||||
|       if (this.character.systemPrompt !== this.originalCharacter.systemPrompt) { | ||||
|         changedFields.systemPrompt = this.character.systemPrompt; | ||||
|       } | ||||
|  | ||||
|       if (this.character.appearance !== this.originalCharacter.appearance) { | ||||
|         changedFields.appearance = this.character.appearance; | ||||
|       } | ||||
|  | ||||
|       // 배열 필드 비교 (깊은 비교) | ||||
|       const arrayFields = [ | ||||
|         'tags', 'hobbies', 'values', 'goals', 'relationships' | ||||
|       ]; | ||||
|  | ||||
|       arrayFields.forEach(field => { | ||||
|         const original = this.originalCharacter[field] || []; | ||||
|         const current = this.character[field] || []; | ||||
|  | ||||
|         // 길이가 다르거나 내용이 다른 경우 | ||||
|         if (original.length !== current.length || | ||||
|             JSON.stringify(original) !== JSON.stringify(current)) { | ||||
|           changedFields[field] = current; | ||||
|         } | ||||
|       }); | ||||
|  | ||||
|       // 복잡한 객체 배열 비교 | ||||
|       const objectArrayFields = [ | ||||
|         'personalities', 'backgrounds', 'memories' | ||||
|       ]; | ||||
|  | ||||
|       objectArrayFields.forEach(field => { | ||||
|         const original = this.originalCharacter[field] || []; | ||||
|         const current = this.character[field] || []; | ||||
|  | ||||
|         // 길이가 다르거나 내용이 다른 경우 | ||||
|         if (original.length !== current.length || | ||||
|             JSON.stringify(original) !== JSON.stringify(current)) { | ||||
|           changedFields[field] = current; | ||||
|         } | ||||
|       }); | ||||
|  | ||||
|       return changedFields; | ||||
|     }, | ||||
|  | ||||
|     async loadCharacter(id) { | ||||
|       this.isLoading = true; | ||||
|       try { | ||||
| @@ -1242,6 +1334,9 @@ export default { | ||||
|         if (response && response.data) { | ||||
|           const data = response.data; | ||||
|  | ||||
|           // 원본 데이터 저장 (깊은 복사) | ||||
|           this.originalCharacter = JSON.parse(JSON.stringify(data)); | ||||
|  | ||||
|           // 기본 데이터 설정 | ||||
|           this.character = { | ||||
|             ...this.character, // 기본 구조 유지 | ||||
| @@ -1293,9 +1388,15 @@ export default { | ||||
|         let response; | ||||
|  | ||||
|         if (this.isEdit) { | ||||
|           response = await updateCharacter(this.character); | ||||
|           // 수정 시 변경된 필드만 전송 | ||||
|           const changedData = this.getChangedFields(); | ||||
|           console.log('변경된 필드만 전송:', changedData); | ||||
|           response = await updateCharacter(changedData, this.character.image); | ||||
|         } else { | ||||
|           response = await createCharacter(this.character); | ||||
|           // 신규 등록 시 ID 필드를 제외한 데이터 전송 | ||||
|           const characterWithoutId = { ...this.character }; | ||||
|           delete characterWithoutId.id; | ||||
|           response = await createCharacter(characterWithoutId); | ||||
|         } | ||||
|  | ||||
|         if (response && response.data) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user