Skip to content

Commit deb0510

Browse files
committed
feat: 4차 MVP 개발
1 parent c90397b commit deb0510

22 files changed

+238
-178
lines changed

src/main/kotlin/com/ddd/sonnypolabobe/domain/board/controller/BoardController.kt

+3-4
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,18 @@ class BoardController(
2828
"""
2929
)
3030
@PostMapping
31-
fun create(@RequestBody request: BoardCreateRequest)
32-
: ApplicationResponse<UUID> {
31+
fun create(@RequestBody request: BoardCreateRequest) : ApplicationResponse<UUID> {
3332
val user =
3433
SecurityContextHolder.getContext().authentication.principal as UserDto.Companion.Res
3534
request.userId = user.id
3635
return ApplicationResponse.ok(this.boardService.create(request))
3736
}
3837

39-
@Tag(name = "1.2.0")
38+
@Tag(name = "1.3.0")
4039
@Operation(
4140
summary = "보드 조회", description = """
4241
보드를 조회합니다.
43-
DTO 필드 수정했습니다. 폴라로이드에 닉네임 필드 추가
42+
DTO 필드 수정했습니다. 스티커 리스트 추가했습니다.
4443
4544
"""
4645
)
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package com.ddd.sonnypolabobe.domain.board.controller.dto
22

3+
import com.ddd.sonnypolabobe.domain.board.sticker.dto.StickerGetResponse
34
import com.ddd.sonnypolabobe.domain.polaroid.controller.dto.PolaroidGetResponse
45
import io.swagger.v3.oas.annotations.media.Schema
56

67
data class BoardGetResponse(
78
@Schema(description = "제목", example = "쏘니의 보드")
89
val title: String,
9-
@Schema(description = "작성자", example = "작성자입니다.")
10-
val items: List<PolaroidGetResponse>
10+
@Schema(description = "폴라로이드")
11+
val items: List<PolaroidGetResponse>,
12+
@Schema(description = "스티커 리스트")
13+
val stickers : List<StickerGetResponse>?
1114
)

src/main/kotlin/com/ddd/sonnypolabobe/domain/board/entity/BoardEntity.kt

-15
This file was deleted.

src/main/kotlin/com/ddd/sonnypolabobe/domain/board/repository/BoardJooqRepository.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.ddd.sonnypolabobe.domain.board.repository
22

33
import com.ddd.sonnypolabobe.domain.board.controller.dto.BoardCreateRequest
44
import com.ddd.sonnypolabobe.domain.board.my.dto.MyBoardDto
5+
import com.ddd.sonnypolabobe.domain.board.repository.vo.BoardGetOneVo
56
import com.ddd.sonnypolabobe.domain.user.dto.GenderType
67
import com.ddd.sonnypolabobe.jooq.polabo.tables.Board
78
import org.jooq.Record6
@@ -12,7 +13,7 @@ import java.util.*
1213

1314
interface BoardJooqRepository {
1415
fun insertOne(request: BoardCreateRequest): ByteArray?
15-
fun selectOneById(id: UUID) : Array<out Record7<String?, Long?, String?, String?, LocalDateTime?, Long?, String?>>
16+
fun selectOneById(id: UUID) : List<BoardGetOneVo>
1617
fun selectTotalCount(): Long
1718
fun selectTodayTotalCount(): Long
1819
fun findById(id: UUID): MyBoardDto.Companion.GetOneRes?

src/main/kotlin/com/ddd/sonnypolabobe/domain/board/repository/BoardJooqRepositoryImpl.kt

+9-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ package com.ddd.sonnypolabobe.domain.board.repository
33
import com.ddd.sonnypolabobe.domain.board.controller.dto.BoardCreateRequest
44
import com.ddd.sonnypolabobe.domain.board.controller.dto.BoardGetResponse
55
import com.ddd.sonnypolabobe.domain.board.my.dto.MyBoardDto
6+
import com.ddd.sonnypolabobe.domain.board.repository.vo.BoardGetOneVo
67
import com.ddd.sonnypolabobe.domain.user.dto.GenderType
78
import com.ddd.sonnypolabobe.global.util.DateConverter
89
import com.ddd.sonnypolabobe.global.util.UuidConverter
910
import com.ddd.sonnypolabobe.global.util.UuidGenerator
1011
import com.ddd.sonnypolabobe.jooq.polabo.enums.UserGender
1112
import com.ddd.sonnypolabobe.jooq.polabo.tables.Board
13+
import com.ddd.sonnypolabobe.jooq.polabo.tables.BoardSticker
1214
import com.ddd.sonnypolabobe.jooq.polabo.tables.Polaroid
1315
import com.ddd.sonnypolabobe.jooq.polabo.tables.User
1416
import org.jooq.*
@@ -43,18 +45,21 @@ class BoardJooqRepositoryImpl(
4345
return if (result == 1) id else null
4446
}
4547

46-
override fun selectOneById(id: UUID): Array<out Record7<String?, Long?, String?, String?, LocalDateTime?, Long?, String?>> {
48+
override fun selectOneById(id: UUID): List<BoardGetOneVo> {
4749
val jBoard = Board.BOARD
4850
val jPolaroid = Polaroid.POLAROID
51+
4952
return this.dslContext
5053
.select(
54+
jBoard.ID.convertFrom { it?.let{UuidConverter.byteArrayToUUID(it) } },
5155
jBoard.TITLE,
52-
jPolaroid.ID,
56+
jPolaroid.ID.`as`(BoardGetOneVo::polaroidId.name),
5357
jPolaroid.IMAGE_KEY,
5458
jPolaroid.ONE_LINE_MESSAGE,
5559
jPolaroid.CREATED_AT,
5660
jPolaroid.USER_ID,
57-
jPolaroid.NICKNAME
61+
jPolaroid.NICKNAME,
62+
jPolaroid.OPTIONS
5863
)
5964
.from(jBoard)
6065
.leftJoin(jPolaroid).on(
@@ -66,7 +71,7 @@ class BoardJooqRepositoryImpl(
6671
.and(jBoard.ACTIVEYN.eq(1))
6772
)
6873
.orderBy(jPolaroid.CREATED_AT.desc())
69-
.fetchArray()
74+
.fetchInto(BoardGetOneVo::class.java)
7075

7176
}
7277

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.ddd.sonnypolabobe.domain.board.repository.vo
2+
3+
import java.time.LocalDateTime
4+
import java.util.UUID
5+
6+
data class BoardGetOneVo(
7+
val id: UUID?,
8+
val title: String?,
9+
val polaroidId : Long?,
10+
val imageKey : String?,
11+
val oneLineMessage: String?,
12+
val createdAt: LocalDateTime?,
13+
val userId : Long?,
14+
val nickName: String?,
15+
val options: String?
16+
)

src/main/kotlin/com/ddd/sonnypolabobe/domain/board/service/BoardService.kt

+19-10
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,27 @@ package com.ddd.sonnypolabobe.domain.board.service
33
import com.ddd.sonnypolabobe.domain.board.controller.dto.BoardCreateRequest
44
import com.ddd.sonnypolabobe.domain.board.controller.dto.BoardGetResponse
55
import com.ddd.sonnypolabobe.domain.board.repository.BoardJooqRepository
6+
import com.ddd.sonnypolabobe.domain.board.sticker.dto.StickerGetResponse
7+
import com.ddd.sonnypolabobe.domain.board.sticker.repository.BoardStickerRepository
68
import com.ddd.sonnypolabobe.domain.polaroid.controller.dto.PolaroidGetResponse
9+
import com.ddd.sonnypolabobe.domain.polaroid.enumerate.PolaroidOption
710
import com.ddd.sonnypolabobe.domain.user.dto.UserDto
811
import com.ddd.sonnypolabobe.global.exception.ApplicationException
912
import com.ddd.sonnypolabobe.global.exception.CustomErrorCode
1013
import com.ddd.sonnypolabobe.global.security.AuthenticatedMember
1114
import com.ddd.sonnypolabobe.global.util.S3Util
1215
import com.ddd.sonnypolabobe.global.util.UuidConverter
16+
import com.fasterxml.jackson.core.type.TypeReference
17+
import com.fasterxml.jackson.databind.ObjectMapper
1318
import org.springframework.beans.factory.annotation.Value
1419
import org.springframework.stereotype.Service
1520
import java.util.*
21+
import javax.swing.text.html.HTML.Tag.U
1622

1723
@Service
1824
class BoardService(
1925
private val boardJooqRepository: BoardJooqRepository,
26+
private val boardStickerRepository: BoardStickerRepository,
2027
private val s3Util: S3Util,
2128
@Value("\${limit.count}")
2229
private val limit: Int
@@ -29,22 +36,24 @@ class BoardService(
2936
return id.run {
3037
val queryResult =
3138
boardJooqRepository.selectOneById(UuidConverter.stringToUUID(this@run))
32-
val groupByTitle = queryResult.groupBy { it.value1() }
39+
val stickers = boardStickerRepository.findByBoardId(UuidConverter.stringToUUID(id))
40+
val groupByTitle = queryResult.groupBy { it.title }
3341
groupByTitle.map { entry ->
3442
val title = entry.key
3543
val polaroids = entry.value.map {
3644
PolaroidGetResponse(
37-
id = it.value2() ?: 0L,
38-
imageUrl = it.value3()?.let { it1 -> s3Util.getImgUrl(it1) } ?: "",
39-
oneLineMessage = it.value4() ?: "폴라보와의 추억 한 줄",
40-
userId = it.value6() ?: 0L,
41-
nickname = it.value7() ?: "",
42-
isMine = it.value6() == user?.id?.toLong(),
43-
createdAt = it.value5()
45+
id = it.polaroidId ?: 0L,
46+
imageUrl = it.imageKey?.let { it1 -> s3Util.getImgUrl(it1) } ?: "",
47+
oneLineMessage = it.oneLineMessage ?: "폴라보와의 추억 한 줄",
48+
userId = it.userId ?: 0L,
49+
nickname = it.nickName ?: "",
50+
isMine = it.userId == user?.id?.toLong(),
51+
createdAt = it.createdAt,
52+
options = it.options?.let{ ObjectMapper().readValue(it, object : TypeReference<Map<PolaroidOption, String>>() {})}
4453

4554
)
46-
}.filter { it.id != 0L }
47-
BoardGetResponse(title = title ?: "", items = polaroids)
55+
}.filter { it.id != 0L }.distinctBy { it.id }
56+
BoardGetResponse(title = title ?: "", items = polaroids, stickers = stickers)
4857
}
4958
}
5059
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.ddd.sonnypolabobe.domain.board.sticker.controller
2+
3+
import com.ddd.sonnypolabobe.domain.board.sticker.dto.StickerCreateRequest
4+
import com.ddd.sonnypolabobe.domain.board.sticker.service.StickerService
5+
import com.ddd.sonnypolabobe.global.response.ApplicationResponse
6+
import com.ddd.sonnypolabobe.global.security.JwtUtil
7+
import io.swagger.v3.oas.annotations.tags.Tag
8+
import org.springframework.web.bind.annotation.GetMapping
9+
import org.springframework.web.bind.annotation.PostMapping
10+
import org.springframework.web.bind.annotation.RequestBody
11+
import org.springframework.web.bind.annotation.RequestHeader
12+
import org.springframework.web.bind.annotation.RequestMapping
13+
import org.springframework.web.bind.annotation.RestController
14+
15+
@RestController
16+
@RequestMapping("/api/v1/boards/sticker")
17+
class BoardStickerController(
18+
private val jwtUtil: JwtUtil,
19+
private val stickerService: StickerService
20+
) {
21+
22+
@Tag(name = "1.3.0")
23+
@GetMapping("/recent")
24+
fun getRecentList( @RequestHeader("Authorization") token: String?)
25+
: ApplicationResponse<List<String>> {
26+
val user = token?.let { this.jwtUtil.getAuthenticatedMemberFromToken(it) }
27+
return ApplicationResponse.ok(this.stickerService.getByUserId(user?.id?.toLong()))
28+
}
29+
30+
@Tag(name = "1.3.0")
31+
@PostMapping
32+
fun createStickerToBoard(
33+
@RequestHeader("Authorization") token: String?,
34+
@RequestBody req : StickerCreateRequest
35+
) : ApplicationResponse<Nothing> {
36+
val user = token?.let { this.jwtUtil.getAuthenticatedMemberFromToken(it) }
37+
this.stickerService.create(req, user?.id?.toLong())
38+
return ApplicationResponse.ok()
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.ddd.sonnypolabobe.domain.board.sticker.dto
2+
3+
data class StickerCreateRequest(
4+
val boardId : String,
5+
val stickerId: String,
6+
val x : String,
7+
val y : String,
8+
val scale: String,
9+
val rotate: String
10+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.ddd.sonnypolabobe.domain.board.sticker.dto
2+
3+
data class StickerGetResponse(
4+
val id : String,
5+
val x : String,
6+
val y : String,
7+
val scale: String,
8+
val rotate : String
9+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.ddd.sonnypolabobe.domain.board.sticker.repository
2+
3+
import com.ddd.sonnypolabobe.domain.board.sticker.dto.StickerCreateRequest
4+
import com.ddd.sonnypolabobe.domain.board.sticker.dto.StickerGetResponse
5+
import java.util.*
6+
7+
interface BoardStickerRepository {
8+
fun findByUserId(id: Long) : List<String>
9+
fun insertOne(req: StickerCreateRequest, userId: Long?)
10+
fun findByBoardId(stringToUUID: UUID): List<StickerGetResponse>?
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.ddd.sonnypolabobe.domain.board.sticker.repository
2+
3+
import com.ddd.sonnypolabobe.domain.board.sticker.dto.StickerCreateRequest
4+
import com.ddd.sonnypolabobe.domain.board.sticker.dto.StickerGetResponse
5+
import com.ddd.sonnypolabobe.global.util.DateConverter
6+
import com.ddd.sonnypolabobe.global.util.UuidConverter
7+
import com.ddd.sonnypolabobe.jooq.polabo.tables.BoardSticker
8+
import org.jooq.DSLContext
9+
import org.springframework.stereotype.Repository
10+
import java.time.LocalDateTime
11+
import java.util.*
12+
13+
@Repository
14+
class BoardStickerRepositoryImpl(
15+
private val dslContext: DSLContext
16+
) : BoardStickerRepository {
17+
override fun findByUserId(userId: Long): List<String> {
18+
val jSticker = BoardSticker.BOARD_STICKER
19+
return this.dslContext.selectDistinct(jSticker.STICKER_ID)
20+
.from(jSticker)
21+
.where(jSticker.USER_ID.eq(userId))
22+
.orderBy(jSticker.CREATED_AT.desc())
23+
.fetchInto(String::class.java)
24+
}
25+
26+
override fun insertOne(req: StickerCreateRequest, userId: Long?) {
27+
val jSticker = BoardSticker.BOARD_STICKER
28+
this.dslContext.insertInto(jSticker)
29+
.columns(
30+
jSticker.STICKER_ID,
31+
jSticker.BOARD_ID,
32+
jSticker.USER_ID,
33+
jSticker.X,
34+
jSticker.Y,
35+
jSticker.SCALE,
36+
jSticker.ROTATE,
37+
jSticker.CREATED_AT
38+
).values(
39+
req.stickerId,
40+
UuidConverter.uuidToByteArray(UuidConverter.stringToUUID(req.boardId)),
41+
userId,
42+
req.x,
43+
req.y,
44+
req.scale,
45+
req.rotate,
46+
DateConverter.convertToKst(LocalDateTime.now())
47+
).execute()
48+
}
49+
50+
override fun findByBoardId(stringToUUID: UUID): List<StickerGetResponse>? {
51+
val jSticker = BoardSticker.BOARD_STICKER
52+
return this.dslContext.select(
53+
jSticker.ID,
54+
jSticker.X,
55+
jSticker.Y,
56+
jSticker.SCALE,
57+
jSticker.ROTATE
58+
)
59+
.from(jSticker)
60+
.where(jSticker.BOARD_ID.eq(UuidConverter.uuidToByteArray(stringToUUID)))
61+
.fetchInto(StickerGetResponse::class.java)
62+
}
63+
64+
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.ddd.sonnypolabobe.domain.board.sticker.service
2+
3+
import com.ddd.sonnypolabobe.domain.board.sticker.dto.StickerCreateRequest
4+
import com.ddd.sonnypolabobe.domain.board.sticker.repository.BoardStickerRepository
5+
import org.springframework.stereotype.Service
6+
import org.springframework.transaction.annotation.Transactional
7+
8+
@Service
9+
class StickerService(
10+
private val boardStickerRepository: BoardStickerRepository
11+
) {
12+
@Transactional(readOnly = true)
13+
fun getByUserId(id: Long?): List<String>
14+
= id?.let { this.boardStickerRepository.findByUserId(id) } ?: emptyList()
15+
16+
@Transactional
17+
fun create(req: StickerCreateRequest, userId: Long?) {
18+
this.boardStickerRepository.insertOne(req, userId)
19+
}
20+
}

src/main/kotlin/com/ddd/sonnypolabobe/domain/polaroid/controller/BoardPolaroidV2Controller.kt

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.ddd.sonnypolabobe.domain.polaroid.controller
22

33
import com.ddd.sonnypolabobe.domain.polaroid.controller.dto.PolaroidCreateRequest
4+
import com.ddd.sonnypolabobe.domain.polaroid.enumerate.PolaroidOption
45
import com.ddd.sonnypolabobe.domain.polaroid.service.PolaroidService
56
import com.ddd.sonnypolabobe.global.response.ApplicationResponse
67
import com.ddd.sonnypolabobe.global.security.JwtUtil
@@ -9,7 +10,7 @@ import io.swagger.v3.oas.annotations.tags.Tag
910
import jakarta.validation.Valid
1011
import org.springframework.web.bind.annotation.*
1112

12-
@Tag(name = "1.1.0")
13+
@Tag(name = "1.3.0")
1314
@RestController
1415
@RequestMapping("/api/v2/boards/{boardId}/polaroids")
1516
class BoardPolaroidV2Controller(
@@ -21,7 +22,9 @@ class BoardPolaroidV2Controller(
2122
summary = "폴라로이드 생성", description = """
2223
폴라로이드를 생성합니다.
2324
24-
작성자 닉네임이 추가되었습니다.
25+
옵션을 추가했습니다.
26+
27+
enum에 따라 옵션을 선택해주세요.
2528
"""
2629
)
2730
@PostMapping

0 commit comments

Comments
 (0)