From 945fd5d5a380184cc798afc25aa4edf8a4f75c88 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 5 Mar 2024 15:40:24 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A9=94=EB=89=B4=ED=8C=90=20=ED=94=84?= =?UTF-8?q?=EB=A6=AC=EC=85=8B=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../live/room/menu/CreateLiveMenuRequest.kt | 3 + .../live/room/menu/GetMenuResponse.kt | 6 ++ .../sodalive/live/room/menu/LiveRoomMenu.kt | 15 +++ .../live/room/menu/LiveRoomMenuController.kt | 66 ++++++++++++ .../live/room/menu/LiveRoomMenuRepository.kt | 7 ++ .../live/room/menu/LiveRoomMenuService.kt | 102 ++++++++++++++++++ .../live/room/menu/UpdateLiveMenuRequest.kt | 3 + 7 files changed, 202 insertions(+) create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/CreateLiveMenuRequest.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/GetMenuResponse.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenu.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenuController.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenuRepository.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenuService.kt create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/UpdateLiveMenuRequest.kt diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/CreateLiveMenuRequest.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/CreateLiveMenuRequest.kt new file mode 100644 index 0000000..8ec8188 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/CreateLiveMenuRequest.kt @@ -0,0 +1,3 @@ +package kr.co.vividnext.sodalive.live.room.menu + +data class CreateLiveMenuRequest(val menu: String, val isActive: Boolean) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/GetMenuResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/GetMenuResponse.kt new file mode 100644 index 0000000..c1187e9 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/GetMenuResponse.kt @@ -0,0 +1,6 @@ +package kr.co.vividnext.sodalive.live.room.menu + +data class GetMenuResponse( + val id: Long, + val menu: String +) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenu.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenu.kt new file mode 100644 index 0000000..947ccf4 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenu.kt @@ -0,0 +1,15 @@ +package kr.co.vividnext.sodalive.live.room.menu + +import org.springframework.data.redis.core.RedisHash +import org.springframework.data.redis.core.index.Indexed +import javax.persistence.Id + +@RedisHash("LiveRoomMenu") +data class LiveRoomMenu( + @Id + val id: Long, + @Indexed + val creatorId: Long, + var isActive: Boolean, + var menu: String +) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenuController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenuController.kt new file mode 100644 index 0000000..0531e8f --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenuController.kt @@ -0,0 +1,66 @@ +package kr.co.vividnext.sodalive.live.room.menu + +import kr.co.vividnext.sodalive.common.ApiResponse +import kr.co.vividnext.sodalive.common.SodaException +import kr.co.vividnext.sodalive.member.Member +import kr.co.vividnext.sodalive.member.MemberRole +import org.springframework.security.access.prepost.PreAuthorize +import org.springframework.security.core.annotation.AuthenticationPrincipal +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.PutMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/live/room/menu") +class LiveRoomMenuController(private val service: LiveRoomMenuService) { + @GetMapping("/creator") + @PreAuthorize("hasRole('CREATOR')") + fun getAllLiveMenu( + @RequestParam creatorId: Long, + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + + ApiResponse.ok(service.getAllLiveMenu(creatorId = creatorId, memberId = member.id!!)) + } + + @PostMapping + @PreAuthorize("hasRole('CREATOR')") + fun createLiveMenu( + @RequestBody request: CreateLiveMenuRequest, + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + ) = run { + if (member == null || member.role != MemberRole.CREATOR) { + throw SodaException("로그인 정보를 확인해주세요.") + } + + ApiResponse.ok(service.createLiveMenu(memberId = member.id!!, request = request)) + } + + @PutMapping + @PreAuthorize("hasRole('CREATOR')") + fun updateLiveMenu( + @RequestBody request: UpdateLiveMenuRequest, + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + ) = run { + if (member == null || member.role != MemberRole.CREATOR) { + throw SodaException("로그인 정보를 확인해주세요.") + } + + ApiResponse.ok(service.updateLiveMenu(memberId = member.id!!, request = request)) + } + + @GetMapping + fun getMenu( + @RequestParam creatorId: Long, + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + + ApiResponse.ok(service.getLiveMenu(creatorId = creatorId)) + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenuRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenuRepository.kt new file mode 100644 index 0000000..62c553f --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenuRepository.kt @@ -0,0 +1,7 @@ +package kr.co.vividnext.sodalive.live.room.menu + +import org.springframework.data.repository.CrudRepository + +interface LiveRoomMenuRepository : CrudRepository { + fun findByCreatorId(creatorId: Long): List +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenuService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenuService.kt new file mode 100644 index 0000000..4673943 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/LiveRoomMenuService.kt @@ -0,0 +1,102 @@ +package kr.co.vividnext.sodalive.live.room.menu + +import kr.co.vividnext.sodalive.common.SodaException +import kr.co.vividnext.sodalive.live.roulette.RedisIdGenerator +import org.springframework.stereotype.Service + +@Service +class LiveRoomMenuService( + private val idGenerator: RedisIdGenerator, + private val repository: LiveRoomMenuRepository +) { + fun getAllLiveMenu(creatorId: Long, memberId: Long): List { + if (creatorId != memberId) throw SodaException("잘못된 요청입니다.") + + return repository.findByCreatorId(creatorId) + .sortedBy { it.id } + .asSequence() + .map { GetMenuResponse(id = it.id, menu = it.menu) } + .toList() + } + + fun createLiveMenu(memberId: Long, request: CreateLiveMenuRequest): Boolean { + liveMenuValidate(menu = request.menu) + + if (request.isActive) { + val menuList = repository.findByCreatorId(creatorId = memberId) + menuList.forEach { + it.isActive = false + repository.save(it) + } + } + + val menu = LiveRoomMenu( + id = idGenerator.generateId(SEQUENCE_NAME), + creatorId = memberId, + isActive = request.isActive, + menu = request.menu + ) + + repository.save(menu) + return request.isActive + } + + fun updateLiveMenu(memberId: Long, request: UpdateLiveMenuRequest): Boolean { + liveMenuValidate(menu = request.menu) + + val menuList = repository.findByCreatorId(creatorId = memberId) + if (menuList.isEmpty()) { + throw SodaException("잘못된 요청입니다.") + } + + var isActive = false + menuList.forEach { + if (request.isActive || it.isActive) { + isActive = true + } + + if (it.id == request.id) { + it.menu = request.menu + it.isActive = request.isActive + repository.save(it) + } else if (request.isActive) { + it.isActive = false + repository.save(it) + } + } + + return isActive + } + + fun getLiveMenu(creatorId: Long): GetMenuResponse { + val menuList = repository.findByCreatorId(creatorId = creatorId) + + if (menuList.isEmpty()) { + throw SodaException("설정된 메뉴판이 없습니다.") + } + + var activeMenu: LiveRoomMenu? = null + for (menu in menuList) { + if (menu.isActive) { + activeMenu = menu + break + } + } + + if (activeMenu == null || activeMenu.menu.isEmpty()) { + throw SodaException("설정된 메뉴판이 없습니다.") + } + + return GetMenuResponse(id = activeMenu.id, menu = activeMenu.menu) + } + + private fun liveMenuValidate(menu: String) { + if (menu.isBlank()) { + throw SodaException("메뉴판은 빈칸일 수 없습니다.") + } + } + + companion object { + const val SEQUENCE_NAME = "LiveRoomMenu:sequence" + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/UpdateLiveMenuRequest.kt b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/UpdateLiveMenuRequest.kt new file mode 100644 index 0000000..2b91b8a --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/live/room/menu/UpdateLiveMenuRequest.kt @@ -0,0 +1,3 @@ +package kr.co.vividnext.sodalive.live.room.menu + +data class UpdateLiveMenuRequest(val id: Long, val menu: String, val isActive: Boolean)