feat(chat-character): 원작/원작 링크/캐릭터 유형 추가 및 외부 API 호출 분리
- ChatCharacter 엔티티에 originalTitle, originalLink(Nullable), characterType(Enum) 필드 추가 - characterType: CLONE | CHARACTER (기본값 CHARACTER) - 원작/원작 링크는 빈 문자열 대신 null 허용으로 저장 - Admin DTO(Register/Update)에 originalTitle, originalLink, characterType 필드 추가 - 등록 API에서 외부 API 요청 바디에 3개 필드(originalTitle, originalLink, characterType) 제외 처리 - 수정 API에서 3개 필드만 변경된 경우 외부 API 호출 생략하고 DB만 업데이트 - hasChanges: 외부 API 대상 필드 변경 여부 판단(3개 필드 제외) - hasDbOnlyChanges: 3개 필드만 변경된 경우 처리 분기 - Service 계층에 필드 매핑 및 Enum 파싱 추가 - createChatCharacter / createChatCharacterWithDetails에 originalTitle/originalLink/characterType 반영 - 이름 중복 검증 로직 유지, isActive=false 비활성화 이름 처리 로직 유지
This commit is contained in:
@@ -4,6 +4,8 @@ import kr.co.vividnext.sodalive.common.BaseEntity
|
||||
import javax.persistence.CascadeType
|
||||
import javax.persistence.Column
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.EnumType
|
||||
import javax.persistence.Enumerated
|
||||
import javax.persistence.FetchType
|
||||
import javax.persistence.OneToMany
|
||||
|
||||
@@ -41,6 +43,19 @@ class ChatCharacter(
|
||||
@Column(columnDefinition = "TEXT")
|
||||
var appearance: String? = null,
|
||||
|
||||
// 원작 (optional)
|
||||
@Column(nullable = true)
|
||||
var originalTitle: String? = null,
|
||||
|
||||
// 원작 링크 (optional)
|
||||
@Column(nullable = true)
|
||||
var originalLink: String? = null,
|
||||
|
||||
// 캐릭터 유형
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(nullable = false)
|
||||
var characterType: CharacterType = CharacterType.CHARACTER,
|
||||
|
||||
var isActive: Boolean = true
|
||||
) : BaseEntity() {
|
||||
var imagePath: String? = null
|
||||
@@ -117,3 +132,8 @@ class ChatCharacter(
|
||||
relationships.add(relationship)
|
||||
}
|
||||
}
|
||||
|
||||
enum class CharacterType {
|
||||
CLONE,
|
||||
CHARACTER
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package kr.co.vividnext.sodalive.chat.character.service
|
||||
|
||||
import kr.co.vividnext.sodalive.admin.chat.character.dto.ChatCharacterUpdateRequest
|
||||
import kr.co.vividnext.sodalive.chat.character.CharacterType
|
||||
import kr.co.vividnext.sodalive.chat.character.ChatCharacter
|
||||
import kr.co.vividnext.sodalive.chat.character.ChatCharacterGoal
|
||||
import kr.co.vividnext.sodalive.chat.character.ChatCharacterHobby
|
||||
@@ -208,6 +209,9 @@ class ChatCharacterService(
|
||||
speechPattern: String? = null,
|
||||
speechStyle: String? = null,
|
||||
appearance: String? = null,
|
||||
originalTitle: String? = null,
|
||||
originalLink: String? = null,
|
||||
characterType: CharacterType = CharacterType.CHARACTER,
|
||||
tags: List<String> = emptyList(),
|
||||
values: List<String> = emptyList(),
|
||||
hobbies: List<String> = emptyList(),
|
||||
@@ -223,7 +227,10 @@ class ChatCharacterService(
|
||||
mbti = mbti,
|
||||
speechPattern = speechPattern,
|
||||
speechStyle = speechStyle,
|
||||
appearance = appearance
|
||||
appearance = appearance,
|
||||
originalTitle = originalTitle,
|
||||
originalLink = originalLink,
|
||||
characterType = characterType
|
||||
)
|
||||
|
||||
// 관련 엔티티 연결
|
||||
@@ -286,6 +293,9 @@ class ChatCharacterService(
|
||||
speechPattern: String? = null,
|
||||
speechStyle: String? = null,
|
||||
appearance: String? = null,
|
||||
originalTitle: String? = null,
|
||||
originalLink: String? = null,
|
||||
characterType: CharacterType = CharacterType.CHARACTER,
|
||||
tags: List<String> = emptyList(),
|
||||
values: List<String> = emptyList(),
|
||||
hobbies: List<String> = emptyList(),
|
||||
@@ -296,8 +306,23 @@ class ChatCharacterService(
|
||||
relationships: List<Pair<String, String>> = emptyList()
|
||||
): ChatCharacter {
|
||||
val chatCharacter = createChatCharacter(
|
||||
characterUUID, name, description, systemPrompt, age, gender, mbti,
|
||||
speechPattern, speechStyle, appearance, tags, values, hobbies, goals
|
||||
characterUUID = characterUUID,
|
||||
name = name,
|
||||
description = description,
|
||||
systemPrompt = systemPrompt,
|
||||
age = age,
|
||||
gender = gender,
|
||||
mbti = mbti,
|
||||
speechPattern = speechPattern,
|
||||
speechStyle = speechStyle,
|
||||
appearance = appearance,
|
||||
originalTitle = originalTitle,
|
||||
originalLink = originalLink,
|
||||
characterType = characterType,
|
||||
tags = tags,
|
||||
values = values,
|
||||
hobbies = hobbies,
|
||||
goals = goals
|
||||
)
|
||||
|
||||
// 추가 정보 설정
|
||||
@@ -365,6 +390,11 @@ class ChatCharacterService(
|
||||
request.speechPattern?.let { chatCharacter.speechPattern = it }
|
||||
request.speechStyle?.let { chatCharacter.speechStyle = it }
|
||||
request.appearance?.let { chatCharacter.appearance = it }
|
||||
request.originalTitle?.let { chatCharacter.originalTitle = it }
|
||||
request.originalLink?.let { chatCharacter.originalLink = it }
|
||||
request.characterType?.let {
|
||||
runCatching { CharacterType.valueOf(it) }.getOrNull()?.let { ct -> chatCharacter.characterType = ct }
|
||||
}
|
||||
|
||||
// request에서 변경된 데이터만 업데이트
|
||||
if (request.tags != null) {
|
||||
|
Reference in New Issue
Block a user