test #340
| @@ -69,10 +69,10 @@ class ChatCharacterController( | |||||||
|         val popularCharacters = service.getPopularCharacters() |         val popularCharacters = service.getPopularCharacters() | ||||||
|  |  | ||||||
|         // 최근 등록된 캐릭터 리스트 조회 |         // 최근 등록된 캐릭터 리스트 조회 | ||||||
|         val newCharacters = service.getRecentCharacters( |         val newCharacters = service.getRecentCharactersPage( | ||||||
|             page = 0, |             page = 0, | ||||||
|             size = 50 |             size = 50 | ||||||
|         ) |         ).content | ||||||
|  |  | ||||||
|         // 큐레이션 섹션 (활성화된 큐레이션 + 캐릭터) |         // 큐레이션 섹션 (활성화된 큐레이션 + 캐릭터) | ||||||
|         val curationSections = curationQueryService.getActiveCurationsWithCharacters() |         val curationSections = curationQueryService.getActiveCurationsWithCharacters() | ||||||
| @@ -187,7 +187,7 @@ class ChatCharacterController( | |||||||
|     @GetMapping("/recent") |     @GetMapping("/recent") | ||||||
|     fun getRecentCharacters(@RequestParam("page", required = false) page: Int?) = run { |     fun getRecentCharacters(@RequestParam("page", required = false) page: Int?) = run { | ||||||
|         ApiResponse.ok( |         ApiResponse.ok( | ||||||
|             service.getRecentCharacters( |             service.getRecentCharactersPage( | ||||||
|                 page = page ?: 0, |                 page = page ?: 0, | ||||||
|                 size = 20 |                 size = 20 | ||||||
|             ) |             ) | ||||||
|   | |||||||
| @@ -0,0 +1,9 @@ | |||||||
|  | package kr.co.vividnext.sodalive.chat.character.dto | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 최근 등록된 캐릭터 전체보기 페이지 응답 DTO | ||||||
|  |  */ | ||||||
|  | data class RecentCharactersResponse( | ||||||
|  |     val totalCount: Long, | ||||||
|  |     val content: List<Character> | ||||||
|  | ) | ||||||
| @@ -12,6 +12,7 @@ import kr.co.vividnext.sodalive.chat.character.ChatCharacterHobby | |||||||
| import kr.co.vividnext.sodalive.chat.character.ChatCharacterTag | import kr.co.vividnext.sodalive.chat.character.ChatCharacterTag | ||||||
| import kr.co.vividnext.sodalive.chat.character.ChatCharacterValue | import kr.co.vividnext.sodalive.chat.character.ChatCharacterValue | ||||||
| import kr.co.vividnext.sodalive.chat.character.dto.Character | import kr.co.vividnext.sodalive.chat.character.dto.Character | ||||||
|  | import kr.co.vividnext.sodalive.chat.character.dto.RecentCharactersResponse | ||||||
| import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterGoalRepository | import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterGoalRepository | ||||||
| import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterHobbyRepository | import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterHobbyRepository | ||||||
| import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterRepository | import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterRepository | ||||||
| @@ -68,12 +69,12 @@ class ChatCharacterService( | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 최근 등록된 캐릭터 전체보기 (페이징) |      * 최근 등록된 캐릭터 전체보기 (페이징) - 전체 개수 포함 | ||||||
|      * - 기준: 현재 시각 기준 2주 이내 생성된 활성 캐릭터 |      * - 기준: 현재 시각 기준 2주 이내 생성된 활성 캐릭터 | ||||||
|      * - 2주 이내 캐릭터가 0개라면: 최근 등록한 캐릭터 20개 반환(페이지 무시) |      * - 2주 이내 캐릭터가 0개라면: totalCount=20, 첫 페이지는 최근 등록 활성 캐릭터 20개, 그 외 페이지는 빈 리스트 | ||||||
|      */ |      */ | ||||||
|     @Transactional(readOnly = true) |     @Transactional(readOnly = true) | ||||||
|     fun getRecentCharacters(page: Int = 0, size: Int = 20): List<Character> { |     fun getRecentCharactersPage(page: Int = 0, size: Int = 20): RecentCharactersResponse { | ||||||
|         val safePage = if (page < 0) 0 else page |         val safePage = if (page < 0) 0 else page | ||||||
|         val safeSize = when { |         val safeSize = when { | ||||||
|             size <= 0 -> 20 |             size <= 0 -> 20 | ||||||
| @@ -85,13 +86,15 @@ class ChatCharacterService( | |||||||
|         val totalRecent = chatCharacterRepository.countByIsActiveTrueAndCreatedAtGreaterThanEqual(since) |         val totalRecent = chatCharacterRepository.countByIsActiveTrueAndCreatedAtGreaterThanEqual(since) | ||||||
|         if (totalRecent == 0L) { |         if (totalRecent == 0L) { | ||||||
|             if (safePage > 0) { |             if (safePage > 0) { | ||||||
|                 return emptyList() |                 return RecentCharactersResponse( | ||||||
|  |                     totalCount = 20, | ||||||
|  |                     content = emptyList() | ||||||
|  |                 ) | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             val fallback = chatCharacterRepository.findByIsActiveTrue( |             val fallback = chatCharacterRepository.findByIsActiveTrue( | ||||||
|                 PageRequest.of(0, 20, Sort.by("createdAt").descending()) |                 PageRequest.of(0, 20, Sort.by("createdAt").descending()) | ||||||
|             ) |             ) | ||||||
|             return fallback.content.map { |             val content = fallback.content.map { | ||||||
|                 Character( |                 Character( | ||||||
|                     characterId = it.id!!, |                     characterId = it.id!!, | ||||||
|                     name = it.name, |                     name = it.name, | ||||||
| @@ -99,13 +102,17 @@ class ChatCharacterService( | |||||||
|                     imageUrl = "$imageHost/${it.imagePath ?: "profile/default-profile.png"}" |                     imageUrl = "$imageHost/${it.imagePath ?: "profile/default-profile.png"}" | ||||||
|                 ) |                 ) | ||||||
|             } |             } | ||||||
|  |             return RecentCharactersResponse( | ||||||
|  |                 totalCount = 20, | ||||||
|  |                 content = content | ||||||
|  |             ) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         val pageResult = chatCharacterRepository.findRecentSince( |         val pageResult = chatCharacterRepository.findRecentSince( | ||||||
|             since, |             since, | ||||||
|             PageRequest.of(safePage, safeSize) |             PageRequest.of(safePage, safeSize) | ||||||
|         ) |         ) | ||||||
|         return pageResult.content.map { |         val content = pageResult.content.map { | ||||||
|             Character( |             Character( | ||||||
|                 characterId = it.id!!, |                 characterId = it.id!!, | ||||||
|                 name = it.name, |                 name = it.name, | ||||||
| @@ -113,6 +120,11 @@ class ChatCharacterService( | |||||||
|                 imageUrl = "$imageHost/${it.imagePath ?: "profile/default-profile.png"}" |                 imageUrl = "$imageHost/${it.imagePath ?: "profile/default-profile.png"}" | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         return RecentCharactersResponse( | ||||||
|  |             totalCount = totalRecent, | ||||||
|  |             content = content | ||||||
|  |         ) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user