-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #46 from DDD-Community/feature/POLABO-130
feat: 6차 mvp
- Loading branch information
Showing
6 changed files
with
128 additions
and
190 deletions.
There are no files selected for viewing
45 changes: 45 additions & 0 deletions
45
src/main/kotlin/com/ddd/sonnypolabobe/domain/sticker/controller/StickerController.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package com.ddd.sonnypolabobe.domain.sticker.controller | ||
|
||
import com.ddd.sonnypolabobe.domain.sticker.dto.StickerUseRequest | ||
import com.ddd.sonnypolabobe.domain.sticker.service.StickerService | ||
import com.ddd.sonnypolabobe.domain.user.dto.UserDto | ||
import com.ddd.sonnypolabobe.global.response.ApplicationResponse | ||
import io.swagger.v3.oas.annotations.Operation | ||
import io.swagger.v3.oas.annotations.tags.Tag | ||
import jakarta.validation.Valid | ||
import org.springframework.security.core.context.SecurityContextHolder | ||
import org.springframework.web.bind.annotation.GetMapping | ||
import org.springframework.web.bind.annotation.PostMapping | ||
import org.springframework.web.bind.annotation.RequestBody | ||
import org.springframework.web.bind.annotation.RequestMapping | ||
import org.springframework.web.bind.annotation.RestController | ||
|
||
@RestController | ||
@RequestMapping("/api/v1/stickers") | ||
class StickerController( | ||
private val stickerService: StickerService | ||
) { | ||
|
||
@Tag(name = "1.5.0") | ||
@Operation( | ||
summary = "스티커 사용 이력 저장", description = "보드에 사용한 스티커 ID를 배열에 담아 모두 보내주세요." | ||
) | ||
@PostMapping("/use") | ||
fun useSticker( | ||
@RequestBody @Valid request: StickerUseRequest | ||
) : ApplicationResponse<Nothing> { | ||
val user = SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res | ||
stickerService.use(request, user) | ||
return ApplicationResponse.ok() | ||
} | ||
|
||
@Tag(name = "1.5.0") | ||
@Operation( | ||
summary = "최근 사용한 스티커 조회", description = "최근 30일 이내에 사용한 스티커를 조회합니다." | ||
) | ||
@GetMapping("/recent-use") | ||
fun getRecentUseSticker() : ApplicationResponse<Set<String>> { | ||
val user = SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res | ||
return ApplicationResponse.ok(stickerService.getRecentUse(user)) | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
src/main/kotlin/com/ddd/sonnypolabobe/domain/sticker/dto/StickerUseRequest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.ddd.sonnypolabobe.domain.sticker.dto | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema | ||
import jakarta.validation.constraints.NotBlank | ||
|
||
@Schema(description = "스티커 사용 이력 저장") | ||
data class StickerUseRequest( | ||
@field:Schema(description = "스티커 ID 리스트", example = "[\"STK_0001\",\"STK_0001\"]") | ||
val stickerIds: List<String>, | ||
@field:Schema(description = "게시글 ID", example = "adksjfldskjglaijg") | ||
@field:NotBlank(message = "게시글 ID는 필수입니다.") | ||
val boardId: String, | ||
) |
9 changes: 9 additions & 0 deletions
9
src/main/kotlin/com/ddd/sonnypolabobe/domain/sticker/repository/StickerJooqRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.ddd.sonnypolabobe.domain.sticker.repository | ||
|
||
import com.ddd.sonnypolabobe.domain.sticker.dto.StickerUseRequest | ||
import com.ddd.sonnypolabobe.domain.user.dto.UserDto | ||
|
||
interface StickerJooqRepository { | ||
fun insertAll(request: StickerUseRequest, user: UserDto.Companion.Res) | ||
fun readAllByUserId(userId: Long): Set<String> | ||
} |
39 changes: 39 additions & 0 deletions
39
src/main/kotlin/com/ddd/sonnypolabobe/domain/sticker/repository/StickerJooqRepositoryImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.ddd.sonnypolabobe.domain.sticker.repository | ||
|
||
import com.ddd.sonnypolabobe.domain.sticker.dto.StickerUseRequest | ||
import com.ddd.sonnypolabobe.domain.user.dto.UserDto | ||
import com.ddd.sonnypolabobe.global.util.DateConverter | ||
import com.ddd.sonnypolabobe.global.util.UuidConverter | ||
import com.ddd.sonnypolabobe.jooq.polabo.tables.references.STICKER_USE_HISTORY | ||
import org.jooq.DSLContext | ||
import org.springframework.stereotype.Repository | ||
import java.time.LocalDateTime | ||
|
||
@Repository | ||
class StickerJooqRepositoryImpl(private val dslContext: DSLContext) : StickerJooqRepository{ | ||
override fun insertAll(request: StickerUseRequest, user: UserDto.Companion.Res) { | ||
dslContext.batchInsert( | ||
request.stickerIds.map { | ||
STICKER_USE_HISTORY.newRecord().apply { | ||
this.userId = user.id | ||
this.stickerId = it | ||
this.boardId = UuidConverter.uuidToByteArray(UuidConverter.stringToUUID(request.boardId)) | ||
this.createdAt = DateConverter.convertToKst(LocalDateTime.now()) | ||
} | ||
} | ||
).execute() | ||
|
||
} | ||
|
||
override fun readAllByUserId(userId: Long): Set<String> { | ||
return dslContext.select(STICKER_USE_HISTORY.STICKER_ID) | ||
.from(STICKER_USE_HISTORY) | ||
.where(STICKER_USE_HISTORY.USER_ID.eq(userId).and( | ||
STICKER_USE_HISTORY.CREATED_AT.gt( | ||
DateConverter.convertToKst(LocalDateTime.now().minusDays(30)) | ||
) | ||
)) | ||
.fetchInto(String::class.java) | ||
.toSet() | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/main/kotlin/com/ddd/sonnypolabobe/domain/sticker/service/StickerService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.ddd.sonnypolabobe.domain.sticker.service | ||
|
||
import com.ddd.sonnypolabobe.domain.sticker.dto.StickerUseRequest | ||
import com.ddd.sonnypolabobe.domain.sticker.repository.StickerJooqRepository | ||
import com.ddd.sonnypolabobe.domain.user.dto.UserDto | ||
import org.springframework.stereotype.Service | ||
import org.springframework.transaction.annotation.Transactional | ||
|
||
@Service | ||
class StickerService( | ||
private val stickerJooqRepository: StickerJooqRepository | ||
) { | ||
@Transactional | ||
fun use(request: StickerUseRequest, user: UserDto.Companion.Res) { | ||
stickerJooqRepository.insertAll(request, user) | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
fun getRecentUse(user: UserDto.Companion.Res): Set<String> { | ||
return stickerJooqRepository.readAllByUserId(user.id) | ||
} | ||
} |
190 changes: 0 additions & 190 deletions
190
src/test/kotlin/com/ddd/sonnypolabobe/SonnyPolaboBeApplicationTests.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,196 +1,6 @@ | ||
package com.ddd.sonnypolabobe | ||
|
||
import org.junit.jupiter.api.Test | ||
import org.springframework.boot.test.context.SpringBootTest | ||
import java.util.* | ||
|
||
//@SpringBootTest | ||
class SonnyPolaboBeApplicationTests { | ||
|
||
@Test | ||
fun contextLoads() { | ||
println(solution(2, 10, intArrayOf(7,4,5,6))) // 8 | ||
// println(solution(arrayOf( | ||
// intArrayOf(1,2,1), | ||
// intArrayOf(8,2,0), | ||
// intArrayOf(1,7,2) | ||
// ), intArrayOf(0, 0))) // true | ||
// println(solution(arrayOf( | ||
// intArrayOf(1,2,3,2,1), | ||
// intArrayOf(4,2,0,7,2), | ||
// intArrayOf(1,3,3,8,1), | ||
// intArrayOf(2,0,1,1,1), | ||
// intArrayOf(8,2,8,1,1) | ||
// ), intArrayOf(0, 0))) // false | ||
|
||
// println(solution(arrayOf( | ||
// intArrayOf(1,2,3,2,1), | ||
// intArrayOf(4,2,0,7,1), | ||
// intArrayOf(1,3,2,8,1), | ||
// intArrayOf(2,0,1,1,1), | ||
// intArrayOf(8,2,1,2,1) | ||
// ), intArrayOf(4,3) | ||
// )) // true | ||
// println(solution( | ||
// intArrayOf(23), // 고객 수 | ||
// intArrayOf(12, 3, 19), // 모델 처리량 | ||
// intArrayOf(28, 10, 35) // 모델 비용 | ||
// )) | ||
|
||
} | ||
|
||
fun solution(bridge_length: Int, weight: Int, truck_weights: IntArray): Int { | ||
var answer = 0 | ||
|
||
val queue: Queue<Int> = LinkedList() | ||
var totalWeight = 0 | ||
|
||
for(truck in truck_weights) { | ||
queue.add(truck) | ||
} | ||
|
||
val bridge = LinkedList(List(bridge_length) { 0 }) | ||
|
||
while(bridge.isNotEmpty()) { | ||
answer++ | ||
|
||
totalWeight -= bridge.poll() // 다리를 건넌 트럭의 무게를 빼준다. | ||
|
||
if(queue.isNotEmpty()) { | ||
val nextWeight = queue.peek() | ||
if(nextWeight + totalWeight <= weight ) { | ||
totalWeight += nextWeight | ||
bridge.add(queue.poll()) | ||
} else { | ||
bridge.add(0) | ||
} | ||
} | ||
|
||
|
||
} | ||
|
||
|
||
// while (bridge.isNotEmpty()) { | ||
// answer++ | ||
// totalWeight -= bridge.poll() | ||
// | ||
// if (waiting.isNotEmpty()) { | ||
// val nextWeight = waiting.peek() | ||
// | ||
// if (totalWeight + nextWeight <= weight) { | ||
// totalWeight += nextWeight | ||
// bridge.add(waiting.poll()) | ||
// } else { | ||
// bridge.add(0) | ||
// } | ||
// } | ||
// } | ||
return answer | ||
} | ||
|
||
|
||
// fun solution(map : Array<IntArray>, entrancePoint: IntArray) : Boolean { | ||
// // 출발점에서 닭가슴살을 찾을 수 있는지 여부가 answer | ||
// // 닭가슴살은 7 | ||
// // 액상 과당은 0, 초콜릿은 8 이라고 할 때 | ||
// // map에서 출발점을 기준으로는 좌우로만 갈 수 있다. | ||
// // 이후에는 위 아래로 갈 수 있다. | ||
// // 그 다음에는 좌우로만 갈 수 있다. 이 구성을 반복한다고 할 때 이동 방향으로는 현재 위치의 숫자만큼 간다. | ||
// // 이동의 도착점에 액상 과당이나 초콜릿이 있다면 false를 반환한다. | ||
// // 영역을 벗어나도 false를 반환한다. | ||
// | ||
// var answer = false | ||
// var x = entrancePoint[0] | ||
// var y = entrancePoint[1] | ||
// var direction = if (x % 2 == 0) 0 else 2 | ||
// var nextX = 0 | ||
// var nextY = 0 | ||
// | ||
// while (true) { | ||
// if (map[x][y] == 7) { | ||
// answer = true | ||
// break | ||
// } | ||
// if (map[x][y] == 0 || map[x][y] == 8) { | ||
// break | ||
// } | ||
// when (direction) { | ||
// 0 -> { | ||
// nextX = x | ||
// nextY = y + map[x][y] | ||
// } | ||
// 1 -> { | ||
// nextX = x + map[x][y] | ||
// nextY = y | ||
// } | ||
// 2 -> { | ||
// nextX = x | ||
// nextY = y - map[x][y] | ||
// } | ||
// 3 -> { | ||
// nextX = x - map[x][y] | ||
// nextY = y | ||
// } | ||
// } | ||
// if (nextX < 0 || nextX >= map.size || nextY < 0 || nextY >= map[0].size) { | ||
// break | ||
// } | ||
// x = nextX | ||
// y = nextY | ||
// direction = (direction + 1) % 4 // 방향을 바꾼다. | ||
// } | ||
// return answer | ||
// | ||
// } | ||
|
||
// fun solution(customers : IntArray, modelCapacities: IntArray, modelCosts: IntArray) : Int { | ||
// var answer = 0 | ||
// | ||
// // 매 시간 고객의 접수 건을 담고 있는 배열 customers | ||
// // 각 모델의 처리량을 담고 있는 배열 modelCapacities 예를 들면, A-12, B-3, C-19 | ||
// // 각 모델의 비용을 담고 있는 배열 modelCosts 예를 들면, A-28, B-10, C-35 | ||
// // 각 모델은 1시간에 위 처리량만큼 처리할 수 있다. | ||
// | ||
// // 최소 비용으로 처리하고자 할 때, 그 비용을 반환한다. | ||
// | ||
// // 모델의 처리량과 비용을 (처리량, 비용) 쌍으로 묶고, 처리량이 큰 순으로 정렬 | ||
// val pair = modelCapacities.zip(modelCosts).sortedByDescending { it.first } | ||
// | ||
// for (customer in customers) { | ||
// var minCost = Int.MAX_VALUE | ||
// | ||
// for (i in pair.indices) { | ||
// val (capacity, cost) = pair[i] | ||
// val fullModelsNeeded = customer / capacity | ||
// val remainder = customer % capacity | ||
// | ||
// // 총 비용 계산 | ||
// var totalCost = cost * fullModelsNeeded | ||
// | ||
// // 잔여 고객 처리 비용 추가 | ||
// if (remainder > 0) { | ||
// // 잔여 고객을 처리하기 위한 최소 비용을 계산 | ||
// var extraCost = Int.MAX_VALUE | ||
// for (j in pair.indices) { | ||
// val (extraCapacity, extraCostValue) = pair[j] | ||
// if (extraCapacity >= remainder) { | ||
// extraCost = minOf(extraCost, extraCostValue) | ||
// } | ||
// } | ||
// totalCost += extraCost | ||
// } | ||
// | ||
// // 최소 비용 업데이트 | ||
// minCost = minOf(minCost, totalCost) | ||
// } | ||
// answer += minCost | ||
// } | ||
// | ||
// return answer | ||
// } | ||
|
||
|
||
|
||
|
||
|
||
} |