Skip to content

Commit

Permalink
Merge pull request #46 from DDD-Community/feature/POLABO-130
Browse files Browse the repository at this point in the history
feat: 6차 mvp
  • Loading branch information
dldmsql authored Dec 4, 2024
2 parents 33a211d + 7b85558 commit 0919cad
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 190 deletions.
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))
}
}
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,
)
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>
}
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()
}
}
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 src/test/kotlin/com/ddd/sonnypolabobe/SonnyPolaboBeApplicationTests.kt
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
// }





}

0 comments on commit 0919cad

Please sign in to comment.