feat(admin): 관리자 페이지 캐릭터 상세 API 구현
This commit is contained in:
parent
6340ed27cf
commit
2335050834
|
@ -21,6 +21,7 @@ import org.springframework.retry.annotation.Backoff
|
|||
import org.springframework.retry.annotation.Retryable
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.PutMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
|
@ -68,6 +69,21 @@ class AdminChatCharacterController(
|
|||
ApiResponse.ok(response)
|
||||
}
|
||||
|
||||
/**
|
||||
* 캐릭터 상세 정보 조회 API
|
||||
*
|
||||
* @param characterId 캐릭터 ID
|
||||
* @return 캐릭터 상세 정보
|
||||
*/
|
||||
@GetMapping("/{characterId}")
|
||||
fun getCharacterDetail(
|
||||
@PathVariable characterId: Long
|
||||
) = run {
|
||||
val response = adminService.getChatCharacterDetail(characterId, imageHost)
|
||||
|
||||
ApiResponse.ok(response)
|
||||
}
|
||||
|
||||
@PostMapping("/register")
|
||||
@Retryable(
|
||||
value = [Exception::class],
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package kr.co.vividnext.sodalive.admin.chat.character.dto
|
||||
|
||||
import kr.co.vividnext.sodalive.chat.character.ChatCharacter
|
||||
|
||||
data class ChatCharacterDetailResponse(
|
||||
val id: Long,
|
||||
val characterUUID: String,
|
||||
val name: String,
|
||||
val imageUrl: String?,
|
||||
val description: String,
|
||||
val systemPrompt: String,
|
||||
val age: Int?,
|
||||
val gender: String?,
|
||||
val mbti: String?,
|
||||
val speechPattern: String?,
|
||||
val speechStyle: String?,
|
||||
val appearance: String?,
|
||||
val isActive: Boolean,
|
||||
val tags: List<String>,
|
||||
val hobbies: List<String>,
|
||||
val values: List<String>,
|
||||
val goals: List<String>,
|
||||
val relationships: List<String>,
|
||||
val personalities: List<PersonalityResponse>,
|
||||
val backgrounds: List<BackgroundResponse>,
|
||||
val memories: List<MemoryResponse>
|
||||
) {
|
||||
companion object {
|
||||
fun from(chatCharacter: ChatCharacter, imageHost: String = ""): ChatCharacterDetailResponse {
|
||||
val fullImagePath = if (chatCharacter.imagePath != null && imageHost.isNotEmpty()) {
|
||||
"$imageHost/${chatCharacter.imagePath}"
|
||||
} else {
|
||||
chatCharacter.imagePath
|
||||
}
|
||||
|
||||
return ChatCharacterDetailResponse(
|
||||
id = chatCharacter.id!!,
|
||||
characterUUID = chatCharacter.characterUUID,
|
||||
name = chatCharacter.name,
|
||||
imageUrl = fullImagePath,
|
||||
description = chatCharacter.description,
|
||||
systemPrompt = chatCharacter.systemPrompt,
|
||||
age = chatCharacter.age,
|
||||
gender = chatCharacter.gender,
|
||||
mbti = chatCharacter.mbti,
|
||||
speechPattern = chatCharacter.speechPattern,
|
||||
speechStyle = chatCharacter.speechStyle,
|
||||
appearance = chatCharacter.appearance,
|
||||
isActive = chatCharacter.isActive,
|
||||
tags = chatCharacter.tagMappings.map { it.tag.tag },
|
||||
hobbies = chatCharacter.hobbyMappings.map { it.hobby.hobby },
|
||||
values = chatCharacter.valueMappings.map { it.value.value },
|
||||
goals = chatCharacter.goalMappings.map { it.goal.goal },
|
||||
relationships = chatCharacter.relationships.map { it.relationShip },
|
||||
personalities = chatCharacter.personalities.map {
|
||||
PersonalityResponse(it.trait, it.description)
|
||||
},
|
||||
backgrounds = chatCharacter.backgrounds.map {
|
||||
BackgroundResponse(it.topic, it.description)
|
||||
},
|
||||
memories = chatCharacter.memories.map {
|
||||
MemoryResponse(it.title, it.content, it.emotion)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class PersonalityResponse(
|
||||
val trait: String,
|
||||
val description: String
|
||||
)
|
||||
|
||||
data class BackgroundResponse(
|
||||
val topic: String,
|
||||
val description: String
|
||||
)
|
||||
|
||||
data class MemoryResponse(
|
||||
val title: String,
|
||||
val content: String,
|
||||
val emotion: String
|
||||
)
|
|
@ -1,8 +1,10 @@
|
|||
package kr.co.vividnext.sodalive.admin.chat.character.service
|
||||
|
||||
import kr.co.vividnext.sodalive.admin.chat.character.dto.ChatCharacterDetailResponse
|
||||
import kr.co.vividnext.sodalive.admin.chat.character.dto.ChatCharacterListPageResponse
|
||||
import kr.co.vividnext.sodalive.admin.chat.character.dto.ChatCharacterListResponse
|
||||
import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterRepository
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.domain.Sort
|
||||
|
@ -43,4 +45,20 @@ class AdminChatCharacterService(
|
|||
fun createDefaultPageRequest(page: Int = 0, size: Int = 20): PageRequest {
|
||||
return PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"))
|
||||
}
|
||||
|
||||
/**
|
||||
* 캐릭터 상세 정보 조회
|
||||
*
|
||||
* @param characterId 캐릭터 ID
|
||||
* @param imageHost 이미지 호스트 URL
|
||||
* @return 캐릭터 상세 정보
|
||||
* @throws SodaException 캐릭터를 찾을 수 없는 경우
|
||||
*/
|
||||
@Transactional(readOnly = true)
|
||||
fun getChatCharacterDetail(characterId: Long, imageHost: String = ""): ChatCharacterDetailResponse {
|
||||
val chatCharacter = chatCharacterRepository.findById(characterId)
|
||||
.orElseThrow { SodaException("해당 ID의 캐릭터를 찾을 수 없습니다: $characterId") }
|
||||
|
||||
return ChatCharacterDetailResponse.from(chatCharacter, imageHost)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue