From 0d8e7d569616ad240d234cdae70b35a5cb32c436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=ED=95=B4=EC=B0=AC=5BVertical=20Service=20Dev1=5D?= Date: Tue, 14 May 2024 21:49:06 +0900 Subject: [PATCH 01/10] =?UTF-8?q?refactor=20:=20generation=20package=20?= =?UTF-8?q?=EC=BD=94=ED=8B=80=EB=A6=B0=20=EC=8A=A4=EB=9F=BD=EA=B2=8C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AdminGenerationController.kt | 18 +++++------ .../controller/GenerationController.kt | 15 ---------- .../convertor/GenerationConvertor.kt | 18 ----------- .../cmc_be/generation/dto/GenerationReq.kt | 30 +++++++++++++------ .../cmc_be/generation/dto/GenerationRes.kt | 5 ---- .../generation/service/GenerationService.kt | 20 +++++-------- 6 files changed, 36 insertions(+), 70 deletions(-) delete mode 100644 src/main/kotlin/com/example/cmc_be/generation/controller/GenerationController.kt delete mode 100644 src/main/kotlin/com/example/cmc_be/generation/convertor/GenerationConvertor.kt delete mode 100644 src/main/kotlin/com/example/cmc_be/generation/dto/GenerationRes.kt diff --git a/src/main/kotlin/com/example/cmc_be/generation/controller/AdminGenerationController.kt b/src/main/kotlin/com/example/cmc_be/generation/controller/AdminGenerationController.kt index 4e6bd40..c2684a3 100644 --- a/src/main/kotlin/com/example/cmc_be/generation/controller/AdminGenerationController.kt +++ b/src/main/kotlin/com/example/cmc_be/generation/controller/AdminGenerationController.kt @@ -1,12 +1,11 @@ package com.example.cmc_be.generation.controller import com.example.cmc_be.common.response.CommonResponse -import com.example.cmc_be.domain.user.entity.User -import com.example.cmc_be.generation.dto.GenerationReq +import com.example.cmc_be.domain.generation.entity.GenerationWeeksInfo +import com.example.cmc_be.generation.dto.PostGenerationInfoReq import com.example.cmc_be.generation.service.GenerationService import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.tags.Tag -import org.springframework.security.core.annotation.AuthenticationPrincipal import org.springframework.web.bind.annotation.* @RestController @@ -18,17 +17,16 @@ class AdminGenerationController( @Operation(summary = "04-01 주차별 정보 POST API") @PostMapping fun postGenerationWeeksInfo( - @AuthenticationPrincipal user: User, - @RequestBody generationInfo: GenerationReq.GenerationInfo - ): CommonResponse { - return CommonResponse.onSuccess(generationService.postGenerationWeeksInfo(generationInfo)) + @RequestBody postGenerationInfoReq: PostGenerationInfoReq + ): CommonResponse { + return CommonResponse.onSuccess(generationService.postGenerationWeeksInfo(postGenerationInfoReq)) } @Operation(summary = "04-02 주차별 모든 날짜 GET API") @GetMapping("/date") fun getGenerationWeeksInfoDate( - @AuthenticationPrincipal user: User, - ): CommonResponse> { - return CommonResponse.onSuccess(generationService.getGenerationWeeksInfoDate(user)) + @RequestParam generation: Int, + ): CommonResponse> { + return CommonResponse.onSuccess(generationService.getGenerationWeeksInfoDate(generation)) } } \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/generation/controller/GenerationController.kt b/src/main/kotlin/com/example/cmc_be/generation/controller/GenerationController.kt deleted file mode 100644 index e7d2af4..0000000 --- a/src/main/kotlin/com/example/cmc_be/generation/controller/GenerationController.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.example.cmc_be.generation.controller - -import com.example.cmc_be.generation.service.GenerationService -import io.swagger.v3.oas.annotations.tags.Tag -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController - -@RestController -@RequestMapping("/generations") -@Tag(name = "04 Generation 기수 주차 정보 API") -class GenerationController( - private val generationService: GenerationService -) { - -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/generation/convertor/GenerationConvertor.kt b/src/main/kotlin/com/example/cmc_be/generation/convertor/GenerationConvertor.kt deleted file mode 100644 index f5369da..0000000 --- a/src/main/kotlin/com/example/cmc_be/generation/convertor/GenerationConvertor.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.example.cmc_be.generation.convertor - -import com.example.cmc_be.common.annotation.Convertor -import com.example.cmc_be.domain.generation.entity.GenerationWeeksInfo -import com.example.cmc_be.generation.dto.GenerationReq - -@Convertor -class GenerationConvertor { - - fun postGenerationWeeksInfo(generationInfo: GenerationReq.GenerationInfo): GenerationWeeksInfo { - return GenerationWeeksInfo( - generation = generationInfo.generation, - week = generationInfo.week, - date = generationInfo.date, - isOffline = generationInfo.isOffline - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/generation/dto/GenerationReq.kt b/src/main/kotlin/com/example/cmc_be/generation/dto/GenerationReq.kt index d6c4c4b..328d128 100644 --- a/src/main/kotlin/com/example/cmc_be/generation/dto/GenerationReq.kt +++ b/src/main/kotlin/com/example/cmc_be/generation/dto/GenerationReq.kt @@ -1,14 +1,26 @@ package com.example.cmc_be.generation.dto +import com.example.cmc_be.domain.generation.entity.GenerationWeeksInfo import com.fasterxml.jackson.annotation.JsonFormat +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate -class GenerationReq { - data class GenerationInfo( - val generation: Int, - val week: Int, - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") - val date: LocalDate, - val isOffline: Boolean - ) -} \ No newline at end of file +data class PostGenerationInfoReq( + @Schema(example = "15") + val generation: Int, + @Schema(example = "1") + val week: Int, + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") + val date: LocalDate, + val isOffline: Boolean +) { + + fun toEntity(): GenerationWeeksInfo { + return GenerationWeeksInfo( + generation = this.generation, + week = this.week, + date = this.date, + isOffline = this.isOffline + ) + } +} diff --git a/src/main/kotlin/com/example/cmc_be/generation/dto/GenerationRes.kt b/src/main/kotlin/com/example/cmc_be/generation/dto/GenerationRes.kt deleted file mode 100644 index d122d7c..0000000 --- a/src/main/kotlin/com/example/cmc_be/generation/dto/GenerationRes.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.example.cmc_be.generation.dto - -class GenerationRes { - -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/generation/service/GenerationService.kt b/src/main/kotlin/com/example/cmc_be/generation/service/GenerationService.kt index c531f34..6623c12 100644 --- a/src/main/kotlin/com/example/cmc_be/generation/service/GenerationService.kt +++ b/src/main/kotlin/com/example/cmc_be/generation/service/GenerationService.kt @@ -1,27 +1,21 @@ package com.example.cmc_be.generation.service +import com.example.cmc_be.domain.generation.entity.GenerationWeeksInfo import com.example.cmc_be.domain.generation.repository.GenerationWeeksInfoRepository -import com.example.cmc_be.domain.user.entity.User -import com.example.cmc_be.generation.convertor.GenerationConvertor -import com.example.cmc_be.generation.dto.GenerationReq +import com.example.cmc_be.generation.dto.PostGenerationInfoReq import org.springframework.stereotype.Service @Service class GenerationService( private val generationWeeksInfoRepository: GenerationWeeksInfoRepository, - private val generationConvertor: GenerationConvertor ) { - fun getGenerationWeeksInfoDate(user: User): List { - return generationWeeksInfoRepository.findAllByGeneration(user.nowGeneration) - .map { "${it.generation}th ${it.week}week, date : ${it.date}" } + fun getGenerationWeeksInfoDate(generation: Int): List { + return generationWeeksInfoRepository.findAllByGeneration(generation) } fun postGenerationWeeksInfo( - generationInfo: GenerationReq.GenerationInfo - ): String { - return generationConvertor.postGenerationWeeksInfo(generationInfo).let { - generationWeeksInfoRepository.save(it) - "${it.generation}기수 ${it.week}주차 정보 저장 완료" - } + postGenerationInfoReq: PostGenerationInfoReq + ) { + generationWeeksInfoRepository.save(postGenerationInfoReq.toEntity()) } } \ No newline at end of file From 46f029b361d8ea9fc932273df711dbfb49333eec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=ED=95=B4=EC=B0=AC=5BVertical=20Service=20Dev1=5D?= Date: Thu, 16 May 2024 11:25:29 +0900 Subject: [PATCH 02/10] =?UTF-8?q?feat=20:=20PageResponse=20=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cmc_be/common/response/PageResponse.kt | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/example/cmc_be/common/response/PageResponse.kt b/src/main/kotlin/com/example/cmc_be/common/response/PageResponse.kt index dc7f14c..4343066 100644 --- a/src/main/kotlin/com/example/cmc_be/common/response/PageResponse.kt +++ b/src/main/kotlin/com/example/cmc_be/common/response/PageResponse.kt @@ -1,6 +1,7 @@ package com.example.cmc_be.common.response import io.swagger.v3.oas.annotations.media.Schema +import org.springframework.data.domain.Page @Schema(description = "페이징 처리 응답") @@ -9,8 +10,21 @@ data class PageResponse( val isLast: Boolean = true, @Schema(description = "총 요소 갯수", required = true, example = "10") - val totalCnt: Long = 0, + val totalCnt: Int = 0, @Schema(description = "요소", required = true) val contents: List = emptyList() -) +) { + + companion object { + + fun from(page: Page, contentMapper: (T) -> R): PageResponse { + return PageResponse( + isLast = page.isLast, + totalCnt = page.count(), + contents = page.toList().map { contentMapper(it) } + ) + } + + } +} From 76f94e82398aa63c2d2fe2c8cd3a423fe3bfeb1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=ED=95=B4=EC=B0=AC=5BVertical=20Service=20Dev1=5D?= Date: Thu, 16 May 2024 11:25:54 +0900 Subject: [PATCH 03/10] refactor : notification module --- .../controller/AdminNotificationController.kt | 24 +++++----- .../controller/NotificationController.kt | 15 +++---- .../convertor/NotificationConvertor.kt | 18 -------- .../notification/dto/NotificationReq.kt | 15 +++---- .../notification/dto/NotificationRes.kt | 28 ++++++++---- .../service/NotificationService.kt | 44 ++++++++----------- 6 files changed, 63 insertions(+), 81 deletions(-) delete mode 100644 src/main/kotlin/com/example/cmc_be/notification/convertor/NotificationConvertor.kt diff --git a/src/main/kotlin/com/example/cmc_be/notification/controller/AdminNotificationController.kt b/src/main/kotlin/com/example/cmc_be/notification/controller/AdminNotificationController.kt index 19a4305..236a101 100644 --- a/src/main/kotlin/com/example/cmc_be/notification/controller/AdminNotificationController.kt +++ b/src/main/kotlin/com/example/cmc_be/notification/controller/AdminNotificationController.kt @@ -1,6 +1,7 @@ package com.example.cmc_be.notification.controller import com.example.cmc_be.common.response.CommonResponse +import com.example.cmc_be.domain.notification.entity.Notification import com.example.cmc_be.domain.user.entity.User import com.example.cmc_be.notification.dto.NotificationReq import com.example.cmc_be.notification.dto.NotificationRes @@ -19,8 +20,8 @@ class AdminNotificationController( @PostMapping("") @Operation(summary = "02-01 공지 업로드") - fun postNotification(@RequestBody notificationInfo: NotificationReq.NotificationInfo): CommonResponse { - return CommonResponse.onSuccess(notificationService.upsertNotification(notificationInfo)) + fun postNotification(@RequestBody notificationReq: NotificationReq): CommonResponse { + return CommonResponse.onSuccess(notificationService.upsertNotification(notificationReq)) } @GetMapping("/all/{generation}") @@ -28,22 +29,22 @@ class AdminNotificationController( fun getAllNotification( @AuthenticationPrincipal user: User, @PathVariable("generation") generation: Int, - ): CommonResponse> { - return CommonResponse.onSuccess(notificationService.getAllNotification(generation)) + ): CommonResponse> { + return CommonResponse.onSuccess(notificationService.getAllNotifications(generation)) } - @PostMapping("/all/{notificationId}") + @PostMapping("/{notificationId}") @Operation(summary = "02-03 공지 편집") fun upsertNotification( @AuthenticationPrincipal user: User, @PathVariable("notificationId") notificationId: Long, - @RequestBody notificationInfo: NotificationReq.NotificationInfo - ): CommonResponse { + @RequestBody notificationReq: NotificationReq + ): CommonResponse { return CommonResponse.onSuccess( notificationService.upsertNotification( notificationId = notificationId, - notificationInfo = notificationInfo + notificationReq = notificationReq ) ) } @@ -53,10 +54,7 @@ class AdminNotificationController( fun deleteNotification( @AuthenticationPrincipal user: User, @PathVariable("notificationId") notificationId: Long, - ): CommonResponse { - return CommonResponse.onSuccess( - notificationService.deleteNotification(notificationId = notificationId) - ) + ): CommonResponse { + return CommonResponse.onSuccess(notificationService.deleteNotification(notificationId = notificationId)) } - } \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/notification/controller/NotificationController.kt b/src/main/kotlin/com/example/cmc_be/notification/controller/NotificationController.kt index 7f0f9eb..64e1ab6 100644 --- a/src/main/kotlin/com/example/cmc_be/notification/controller/NotificationController.kt +++ b/src/main/kotlin/com/example/cmc_be/notification/controller/NotificationController.kt @@ -21,24 +21,23 @@ class NotificationController( ) { @GetMapping("/latest") @Operation(summary = "02-01 본인 기수 최신 공지 조회") - fun getThisWeekNotification(@AuthenticationPrincipal user: User): CommonResponse> { - return CommonResponse.onSuccess(notificationService.getThisWeekNotification(user)) + fun getLatestNotifications(@AuthenticationPrincipal user: User): CommonResponse> { + return CommonResponse.onSuccess(notificationService.getLatestNotifications(user)) } @GetMapping("/all") @Operation(summary = "02-02 본인 기수 전체 공지 조회") - fun getAllNotification(@AuthenticationPrincipal user: User): CommonResponse> { - return CommonResponse.onSuccess(notificationService.getAllNotification(user.nowGeneration)) + fun getAllNotifications(@AuthenticationPrincipal user: User): CommonResponse> { + return CommonResponse.onSuccess(notificationService.getAllNotifications(user.nowGeneration)) } @GetMapping @Operation(summary = "02-03 본인 기수 공지 페이징 조회") - fun getAllNotificationPaging( + fun getAllNotificationsPaging( @AuthenticationPrincipal user: User, @RequestParam("page") page: Int, @RequestParam("size") size: Int, - ): CommonResponse> { - return CommonResponse.onSuccess(notificationService.getNotificationPaging(user, page, size)) + ): CommonResponse> { + return CommonResponse.onSuccess(notificationService.getNotificationsPaging(user, page, size)) } - } \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/notification/convertor/NotificationConvertor.kt b/src/main/kotlin/com/example/cmc_be/notification/convertor/NotificationConvertor.kt deleted file mode 100644 index 4eb612b..0000000 --- a/src/main/kotlin/com/example/cmc_be/notification/convertor/NotificationConvertor.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.example.cmc_be.notification.convertor - -import com.example.cmc_be.common.annotation.Convertor -import com.example.cmc_be.domain.notification.entity.Notification -import com.example.cmc_be.notification.dto.NotificationRes - -@Convertor -class NotificationConvertor { - - fun getNotification(notification: Notification): NotificationRes.NotificationDto { - return NotificationRes.NotificationDto( - id = notification.id, - title = notification.title, - notionUrl = notification.notionUrl, - week = notification.generationWeeksInfo.week - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/notification/dto/NotificationReq.kt b/src/main/kotlin/com/example/cmc_be/notification/dto/NotificationReq.kt index 8c322e2..13af0d3 100644 --- a/src/main/kotlin/com/example/cmc_be/notification/dto/NotificationReq.kt +++ b/src/main/kotlin/com/example/cmc_be/notification/dto/NotificationReq.kt @@ -1,11 +1,8 @@ package com.example.cmc_be.notification.dto -class NotificationReq { - - data class NotificationInfo( - val generation: Int, - val week: Int, - val notionUrl: String, - val title: String - ) -} \ No newline at end of file +data class NotificationReq( + val generation: Int, + val week: Int, + val notionUrl: String, + val title: String +) diff --git a/src/main/kotlin/com/example/cmc_be/notification/dto/NotificationRes.kt b/src/main/kotlin/com/example/cmc_be/notification/dto/NotificationRes.kt index 1dd468c..f09193a 100644 --- a/src/main/kotlin/com/example/cmc_be/notification/dto/NotificationRes.kt +++ b/src/main/kotlin/com/example/cmc_be/notification/dto/NotificationRes.kt @@ -1,11 +1,23 @@ package com.example.cmc_be.notification.dto -class NotificationRes { - data class NotificationDto( - val id: Long, - val week: Int, - val title: String, - val notionUrl: String, - ) +import com.example.cmc_be.domain.notification.entity.Notification + +data class NotificationRes( + val id: Long, + val week: Int, + val title: String, + val notionUrl: String, +) { + + companion object { + fun from(notification: Notification): NotificationRes { + return NotificationRes( + id = notification.id, + title = notification.title, + notionUrl = notification.notionUrl, + week = notification.generationWeeksInfo.week + ) + } + } +} -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/notification/service/NotificationService.kt b/src/main/kotlin/com/example/cmc_be/notification/service/NotificationService.kt index 31c8f2e..f636fd5 100644 --- a/src/main/kotlin/com/example/cmc_be/notification/service/NotificationService.kt +++ b/src/main/kotlin/com/example/cmc_be/notification/service/NotificationService.kt @@ -7,71 +7,65 @@ import com.example.cmc_be.domain.notification.entity.Notification import com.example.cmc_be.domain.notification.exception.NotificationExceptionErrorCode import com.example.cmc_be.domain.notification.repository.NotificationRepository import com.example.cmc_be.domain.user.entity.User -import com.example.cmc_be.notification.convertor.NotificationConvertor import com.example.cmc_be.notification.dto.NotificationReq import com.example.cmc_be.notification.dto.NotificationRes import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Sort -import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service @Service class NotificationService( private val notificationRepository: NotificationRepository, private val generationWeekRepository: GenerationWeeksInfoRepository, - private val notificationConvertor: NotificationConvertor ) { - fun getThisWeekNotification(user: User): List { + fun getLatestNotifications(user: User): List { val notification = notificationRepository.findAllByGenerationWeeksInfoGeneration( user.nowGeneration, PageRequest.of(0, 5, Sort.by("createdAt").descending()), ) return if (notification.isEmpty) { throw NotFoundException(NotificationExceptionErrorCode.NOT_FOUND_LATEST_NOTIFICATION) } else { - notification.take(5).map(notificationConvertor::getNotification) + notification.take(5).map { notification -> NotificationRes.from(notification) } } } - fun getAllNotification(generation: Int): List { + fun getAllNotifications(generation: Int): List { return notificationRepository.findAllByGenerationWeeksInfoGeneration( generation = generation, sort = Sort.by("createdAt").descending() - ).map(notificationConvertor::getNotification) + ).map { notification -> NotificationRes.from(notification) } } - fun getNotificationPaging(user: User, page: Int, size: Int): PageResponse { + fun getNotificationsPaging(user: User, page: Int, size: Int): PageResponse { val notificationPaging = notificationRepository.findAllByGenerationWeeksInfoGeneration( - user.nowGeneration, PageRequest.of(page, size, Sort.by("createdAt").descending()), - ) - return PageResponse( - isLast = notificationPaging.isLast, - totalCnt = notificationRepository.count(), - contents = notificationPaging.toList().map(notificationConvertor::getNotification) + generation = user.nowGeneration, + pageable = PageRequest.of(page, size, Sort.by("createdAt").descending()), ) + return PageResponse.from( + page = notificationPaging, + contentMapper = { + NotificationRes.from(it) + }) } - fun upsertNotification(notificationInfo: NotificationReq.NotificationInfo, notificationId: Long? = null): String { + fun upsertNotification(notificationReq: NotificationReq, notificationId: Long? = null): Notification { val generationWeeksInfo = - generationWeekRepository.findByGenerationAndWeek(notificationInfo.generation, notificationInfo.week) + generationWeekRepository.findByGenerationAndWeek(notificationReq.generation, notificationReq.week) ?: throw NotFoundException(NotificationExceptionErrorCode.NOT_FOUND_GENERATION) return notificationRepository.save( Notification( generationWeeksInfo = generationWeeksInfo, - title = notificationInfo.title, - notionUrl = notificationInfo.notionUrl + title = notificationReq.title, + notionUrl = notificationReq.notionUrl ).apply { if (notificationId != null) { this.id = notificationId } } - ).let { "${notificationInfo.generation}기수 ${notificationInfo.week}주차 공지가 업데이트 되었습니다." } + ) } - fun deleteNotification(notificationId: Long): String { - if (notificationRepository.findByIdOrNull(notificationId) == null) { - throw NotFoundException(NotificationExceptionErrorCode.NOT_FOUND_LATEST_NOTIFICATION) - } - notificationRepository.deleteById(notificationId) - return "공지 삭제 완료" + fun deleteNotification(notificationId: Long) { + return notificationRepository.deleteById(notificationId) } } \ No newline at end of file From 24d30cde0404f32bd73c5031672d6fb0ab683d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=ED=95=B4=EC=B0=AC=5BVertical=20Service=20Dev1=5D?= Date: Thu, 16 May 2024 12:25:23 +0900 Subject: [PATCH 04/10] =?UTF-8?q?style=20:=20=ED=8F=B4=EB=8D=94=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cmc_be/common/utils/RandomNumber.kt | 17 ---------------- .../cmc_be/common/utils/RandomNumberUtil.kt | 17 ++++++++++++++++ .../{common/utils => external}/MailService.kt | 6 +++--- .../controller}/HealthController.kt | 2 +- .../controller}/TestController.kt | 3 +-- .../cmc_be/user/service/AuthService.kt | 20 ++++++++++++------- 6 files changed, 35 insertions(+), 30 deletions(-) delete mode 100644 src/main/kotlin/com/example/cmc_be/common/utils/RandomNumber.kt create mode 100644 src/main/kotlin/com/example/cmc_be/common/utils/RandomNumberUtil.kt rename src/main/kotlin/com/example/cmc_be/{common/utils => external}/MailService.kt (98%) rename src/main/kotlin/com/example/cmc_be/{common/contorller => health/controller}/HealthController.kt (94%) rename src/main/kotlin/com/example/cmc_be/{common/contorller => health/controller}/TestController.kt (93%) diff --git a/src/main/kotlin/com/example/cmc_be/common/utils/RandomNumber.kt b/src/main/kotlin/com/example/cmc_be/common/utils/RandomNumber.kt deleted file mode 100644 index 57b1691..0000000 --- a/src/main/kotlin/com/example/cmc_be/common/utils/RandomNumber.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.cmc_be.common.utils - -import java.util.* - -class RandomNumber { - companion object { - fun createRandomNumber(): String { - val rand = Random() - var numStr: String = "" - for (i in 0..5) { - val ran = rand.nextInt(10).toString() - numStr += ran - } - return numStr - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/common/utils/RandomNumberUtil.kt b/src/main/kotlin/com/example/cmc_be/common/utils/RandomNumberUtil.kt new file mode 100644 index 0000000..58f4ff2 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/common/utils/RandomNumberUtil.kt @@ -0,0 +1,17 @@ +package com.example.cmc_be.common.utils + +import java.util.* + +object RandomNumberUtil { + fun createNumbers( + length: Int = 6 + ): String { + val rand = Random() + var numStr: String = "" + for (i in 1..length) { + val ran = rand.nextInt(10).toString() + numStr += ran + } + return numStr + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/common/utils/MailService.kt b/src/main/kotlin/com/example/cmc_be/external/MailService.kt similarity index 98% rename from src/main/kotlin/com/example/cmc_be/common/utils/MailService.kt rename to src/main/kotlin/com/example/cmc_be/external/MailService.kt index 3d8a176..3ff2985 100644 --- a/src/main/kotlin/com/example/cmc_be/common/utils/MailService.kt +++ b/src/main/kotlin/com/example/cmc_be/external/MailService.kt @@ -1,4 +1,4 @@ -package com.example.cmc_be.common.utils +package com.example.cmc_be.external import com.example.cmc_be.common.constants.CmcStatic.CODE import com.example.cmc_be.common.constants.CmcStatic.HTML @@ -9,6 +9,8 @@ import com.example.cmc_be.common.constants.CmcStatic.UTF import com.example.cmc_be.common.exeption.InternalServerException import com.example.cmc_be.domain.user.exeption.SendEmailErrorCode import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import org.springframework.mail.javamail.JavaMailSender import org.springframework.mail.javamail.MimeMessageHelper import org.springframework.stereotype.Component @@ -16,8 +18,6 @@ import org.thymeleaf.context.Context import org.thymeleaf.spring6.SpringTemplateEngine import org.thymeleaf.templatemode.TemplateMode import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch @Component diff --git a/src/main/kotlin/com/example/cmc_be/common/contorller/HealthController.kt b/src/main/kotlin/com/example/cmc_be/health/controller/HealthController.kt similarity index 94% rename from src/main/kotlin/com/example/cmc_be/common/contorller/HealthController.kt rename to src/main/kotlin/com/example/cmc_be/health/controller/HealthController.kt index 67222b3..bf468af 100644 --- a/src/main/kotlin/com/example/cmc_be/common/contorller/HealthController.kt +++ b/src/main/kotlin/com/example/cmc_be/health/controller/HealthController.kt @@ -1,4 +1,4 @@ -package com.example.cmc_be.common.contorller +package com.example.cmc_be.health.controller import ApiErrorCodeExample import com.example.cmc_be.common.response.CommonResponse diff --git a/src/main/kotlin/com/example/cmc_be/common/contorller/TestController.kt b/src/main/kotlin/com/example/cmc_be/health/controller/TestController.kt similarity index 93% rename from src/main/kotlin/com/example/cmc_be/common/contorller/TestController.kt rename to src/main/kotlin/com/example/cmc_be/health/controller/TestController.kt index 5863713..5589158 100644 --- a/src/main/kotlin/com/example/cmc_be/common/contorller/TestController.kt +++ b/src/main/kotlin/com/example/cmc_be/health/controller/TestController.kt @@ -1,4 +1,4 @@ -package com.example.cmc_be.common.contorller +package com.example.cmc_be.health.controller import ApiErrorCodeExample import com.example.cmc_be.common.exeption.BadRequestException @@ -9,7 +9,6 @@ import com.example.cmc_be.domain.user.entity.User import com.example.cmc_be.domain.user.exeption.UserAuthErrorCode import io.swagger.v3.oas.annotations.tags.Tag import mu.KotlinLogging -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.PathVariable diff --git a/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt b/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt index 361fc95..7bb1102 100644 --- a/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt +++ b/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt @@ -4,8 +4,7 @@ import com.example.cmc_be.common.dto.Status import com.example.cmc_be.common.exeption.BadRequestException import com.example.cmc_be.common.exeption.NotFoundException import com.example.cmc_be.common.security.JwtService -import com.example.cmc_be.common.utils.MailService -import com.example.cmc_be.common.utils.RandomNumber +import com.example.cmc_be.common.utils.RandomNumberUtil import com.example.cmc_be.domain.redis.entity.CodeAuth import com.example.cmc_be.domain.redis.entity.RefreshToken import com.example.cmc_be.domain.redis.repository.CodeAuthRepository @@ -15,6 +14,7 @@ import com.example.cmc_be.domain.user.entity.User import com.example.cmc_be.domain.user.exeption.* import com.example.cmc_be.domain.user.repository.UserPartRepository import com.example.cmc_be.domain.user.repository.UserRepository +import com.example.cmc_be.external.MailService import com.example.cmc_be.user.convertor.UserConvertor import com.example.cmc_be.user.dto.AuthReq import com.example.cmc_be.user.dto.AuthRes @@ -71,22 +71,28 @@ class AuthService( } fun checkEmail(email: String) { - if(userRepository.existsByUsernameAndStatus(email, Status.ACTIVE)) throw BadRequestException(SignUpUserErrorCode.EXISTS_USER_EMAIL); + if (userRepository.existsByUsernameAndStatus(email, Status.ACTIVE)) throw BadRequestException( + SignUpUserErrorCode.EXISTS_USER_EMAIL + ); } fun sendEmail(email: String) { - if(!userRepository.existsByUsernameAndStatus(email, Status.ACTIVE)) throw BadRequestException(UserAuthErrorCode.NOT_EXIST_USER); - val code : String = RandomNumber.createRandomNumber() + if (!userRepository.existsByUsernameAndStatus( + email, + Status.ACTIVE + ) + ) throw BadRequestException(UserAuthErrorCode.NOT_EXIST_USER); + val code: String = RandomNumberUtil.createNumbers() codeAuthRepository.save(userConvertor.convertToCodeAuth(email, code)) mailService.sendEmailAsync(email, code) } fun checkEmailAuth(checkEmailDto: AuthReq.CheckEmailDto) { - val codeAuth : CodeAuth = codeAuthRepository.findById(checkEmailDto.email).orElseThrow { + val codeAuth: CodeAuth = codeAuthRepository.findById(checkEmailDto.email).orElseThrow { NotFoundException(CheckAuthErrorCode.NOT_EXISTS_AUTH) } - if(codeAuth.code != checkEmailDto.code) throw BadRequestException(CheckAuthErrorCode.NOT_CORRECT_CODE) + if (codeAuth.code != checkEmailDto.code) throw BadRequestException(CheckAuthErrorCode.NOT_CORRECT_CODE) } fun modifyPassword(modifyPasswordDto: AuthReq.ModifyPasswordDto) { From d156b840c4662c7785d39cf304ddbc66d4a74c6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=ED=95=B4=EC=B0=AC=5BVertical=20Service=20Dev1=5D?= Date: Thu, 16 May 2024 13:01:35 +0900 Subject: [PATCH 05/10] refactor : user module --- .../cmc_be/domain/redis/entity/CodeAuth.kt | 5 +- .../user/exeption/SignUpUserErrorCode.kt | 2 +- .../domain/user/exeption/UserPartErrorCode.kt | 33 ++++++++ .../user/repository/UserPartRepository.kt | 3 +- .../cmc_be/user/controller/AuthController.kt | 25 +++--- .../cmc_be/user/controller/UserController.kt | 8 +- .../cmc_be/user/convertor/UserConvertor.kt | 77 ------------------ .../com/example/cmc_be/user/dto/AuthReq.kt | 37 --------- .../com/example/cmc_be/user/dto/AuthRes.kt | 23 ------ .../com/example/cmc_be/user/dto/UserRes.kt | 29 ------- .../cmc_be/user/dto/auth/CheckEmailDto.kt | 9 +++ .../cmc_be/user/dto/auth/LoginUserDto.kt | 9 +++ .../cmc_be/user/dto/auth/ModifyPasswordDto.kt | 9 +++ .../cmc_be/user/dto/auth/RefreshTokenDto.kt | 10 +++ .../cmc_be/user/dto/auth/SignUpUserDto.kt | 15 ++++ .../cmc_be/user/dto/auth/UserTokenDto.kt | 12 +++ .../cmc_be/user/dto/user/MyPageUserInfoDto.kt | 8 ++ .../cmc_be/user/dto/user/PartInfoDto.kt | 8 ++ .../cmc_be/user/dto/user/UserInfoDto.kt | 12 +++ .../cmc_be/user/service/AuthService.kt | 80 ++++++++++--------- .../cmc_be/user/service/UserService.kt | 42 +++++++--- 21 files changed, 221 insertions(+), 235 deletions(-) create mode 100644 src/main/kotlin/com/example/cmc_be/domain/user/exeption/UserPartErrorCode.kt delete mode 100644 src/main/kotlin/com/example/cmc_be/user/convertor/UserConvertor.kt delete mode 100644 src/main/kotlin/com/example/cmc_be/user/dto/AuthReq.kt delete mode 100644 src/main/kotlin/com/example/cmc_be/user/dto/AuthRes.kt delete mode 100644 src/main/kotlin/com/example/cmc_be/user/dto/UserRes.kt create mode 100644 src/main/kotlin/com/example/cmc_be/user/dto/auth/CheckEmailDto.kt create mode 100644 src/main/kotlin/com/example/cmc_be/user/dto/auth/LoginUserDto.kt create mode 100644 src/main/kotlin/com/example/cmc_be/user/dto/auth/ModifyPasswordDto.kt create mode 100644 src/main/kotlin/com/example/cmc_be/user/dto/auth/RefreshTokenDto.kt create mode 100644 src/main/kotlin/com/example/cmc_be/user/dto/auth/SignUpUserDto.kt create mode 100644 src/main/kotlin/com/example/cmc_be/user/dto/auth/UserTokenDto.kt create mode 100644 src/main/kotlin/com/example/cmc_be/user/dto/user/MyPageUserInfoDto.kt create mode 100644 src/main/kotlin/com/example/cmc_be/user/dto/user/PartInfoDto.kt create mode 100644 src/main/kotlin/com/example/cmc_be/user/dto/user/UserInfoDto.kt diff --git a/src/main/kotlin/com/example/cmc_be/domain/redis/entity/CodeAuth.kt b/src/main/kotlin/com/example/cmc_be/domain/redis/entity/CodeAuth.kt index 2d4097a..3e22c86 100644 --- a/src/main/kotlin/com/example/cmc_be/domain/redis/entity/CodeAuth.kt +++ b/src/main/kotlin/com/example/cmc_be/domain/redis/entity/CodeAuth.kt @@ -8,11 +8,10 @@ import org.springframework.data.redis.core.TimeToLive @Builder @RedisHash(value = "code_auth") -data class CodeAuth ( +data class CodeAuth( @Id var auth: String, var code: String, @TimeToLive var ttl: Long -){ -} \ No newline at end of file +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/domain/user/exeption/SignUpUserErrorCode.kt b/src/main/kotlin/com/example/cmc_be/domain/user/exeption/SignUpUserErrorCode.kt index 50c14d3..5366f15 100644 --- a/src/main/kotlin/com/example/cmc_be/domain/user/exeption/SignUpUserErrorCode.kt +++ b/src/main/kotlin/com/example/cmc_be/domain/user/exeption/SignUpUserErrorCode.kt @@ -16,7 +16,7 @@ enum class SignUpUserErrorCode( 인증 관련 에러코드 */ EXISTS_USER_EMAIL(HttpStatus.BAD_REQUEST, "USER001", "이메일이 중복되었습니다."); - + override val errorReason: ErrorReason get() = ErrorReason( message = message, diff --git a/src/main/kotlin/com/example/cmc_be/domain/user/exeption/UserPartErrorCode.kt b/src/main/kotlin/com/example/cmc_be/domain/user/exeption/UserPartErrorCode.kt new file mode 100644 index 0000000..4f641ba --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/domain/user/exeption/UserPartErrorCode.kt @@ -0,0 +1,33 @@ +package com.example.cmc_be.domain.user.exeption + +import com.example.cmc_be.common.annotation.ExplainError +import com.example.cmc_be.common.exeption.errorcode.BaseErrorCode +import com.example.cmc_be.config.swagger.ErrorReason +import org.springframework.http.HttpStatus +import java.util.* + +enum class UserPartErrorCode( + val httpStatus: HttpStatus, + val code: String, + val message: String +) : BaseErrorCode { + + NOT_EXISTS_USER_PART(HttpStatus.BAD_REQUEST, "USER_PART_001", "유저파트가 존재하지 않습니다."); + + override val errorReason: ErrorReason + get() = ErrorReason( + message = message, + code = code, + httpStatus = httpStatus, + isSuccess = false + ) + + @get:Throws(NoSuchFieldException::class) + override val explainError: String + get() { + val field = this.javaClass.getField(this.name) + val annotation = field.getAnnotation(ExplainError::class.java) + return annotation?.value ?: message + } + +} diff --git a/src/main/kotlin/com/example/cmc_be/domain/user/repository/UserPartRepository.kt b/src/main/kotlin/com/example/cmc_be/domain/user/repository/UserPartRepository.kt index 349bcb6..f9eb7d3 100644 --- a/src/main/kotlin/com/example/cmc_be/domain/user/repository/UserPartRepository.kt +++ b/src/main/kotlin/com/example/cmc_be/domain/user/repository/UserPartRepository.kt @@ -3,9 +3,8 @@ package com.example.cmc_be.domain.user.repository import com.example.cmc_be.domain.user.entity.User import com.example.cmc_be.domain.user.entity.UserPart import org.springframework.data.jpa.repository.JpaRepository -import java.util.* interface UserPartRepository : JpaRepository { - fun findByUserAndGeneration(user: User, nowGeneration: Int): Optional + fun findByUserAndGeneration(user: User, nowGeneration: Int): UserPart? fun findByUser(user: User): List } \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/controller/AuthController.kt b/src/main/kotlin/com/example/cmc_be/user/controller/AuthController.kt index 277a87d..b5347b5 100644 --- a/src/main/kotlin/com/example/cmc_be/user/controller/AuthController.kt +++ b/src/main/kotlin/com/example/cmc_be/user/controller/AuthController.kt @@ -6,8 +6,7 @@ import com.example.cmc_be.domain.user.exeption.CheckAuthErrorCode import com.example.cmc_be.domain.user.exeption.LoginUserErrorCode import com.example.cmc_be.domain.user.exeption.RefreshTokenErrorCode import com.example.cmc_be.domain.user.exeption.SendEmailErrorCode -import com.example.cmc_be.user.dto.AuthReq -import com.example.cmc_be.user.dto.AuthRes +import com.example.cmc_be.user.dto.auth.* import com.example.cmc_be.user.service.AuthService import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.Parameter @@ -18,7 +17,7 @@ import jakarta.validation.Valid import org.springframework.web.bind.annotation.* @RestController -@Tag(name ="00 Auth 유저 인증 관련 API") +@Tag(name = "00 Auth 유저 인증 관련 API") @RequestMapping("/auth") class AuthController( val authService: AuthService @@ -26,33 +25,32 @@ class AuthController( @PostMapping("/sign-up") @Operation(summary = "00-01 회원가입") @ApiErrorCodeExample(SendEmailErrorCode::class) - fun signUpUser(@Valid @RequestBody signUpUserDto: AuthReq.SignUpUserDto) : CommonResponse { + fun signUpUser(@Valid @RequestBody signUpUserDto: SignUpUserDto): CommonResponse { return CommonResponse.onSuccess(authService.signUpUser(signUpUserDto)) } @PostMapping("/log-in") @Operation(summary = "00-01 로그인") @ApiErrorCodeExample(LoginUserErrorCode::class) - fun logInUser(@Valid @RequestBody loginUserDto : AuthReq.LoginUserDto) : CommonResponse{ + fun logInUser(@Valid @RequestBody loginUserDto: LoginUserDto): CommonResponse { return CommonResponse.onSuccess(authService.logInUser(loginUserDto)) } @GetMapping("/email") @Operation(summary = "00-03 이메일 중복체크") @ApiErrorCodeExample(SendEmailErrorCode::class) - fun checkEmail(@Parameter(description = "이메일") @RequestParam email : String) : CommonResponse{ - authService.checkEmail(email); - return CommonResponse.onSuccess("사용 가능"); + fun checkEmail(@Parameter(description = "이메일") @RequestParam email: String): CommonResponse { + authService.checkEmail(email) + return CommonResponse.onSuccess("사용 가능") } /* 이메일 인증 번호 보내기 for 비밀번호 찾기 */ - @GetMapping("/password") @Operation(summary = "00-04 비밀번호 찾기용 이메일 인증번호 전송") @ApiErrorCodeExample(SendEmailErrorCode::class) - fun sendEmail(@RequestParam email : String) : CommonResponse{ + fun sendEmail(@RequestParam email: String): CommonResponse { authService.sendEmail(email) return CommonResponse.onSuccess("이메일 전송 성공") } @@ -60,7 +58,7 @@ class AuthController( @PostMapping("/password") @Operation(summary = "00-05 이메일 인증번호 확인") @ApiErrorCodeExample(CheckAuthErrorCode::class) - fun checkEmail(@RequestBody checkEmailDto: AuthReq.CheckEmailDto) : CommonResponse{ + fun checkEmail(@RequestBody checkEmailDto: CheckEmailDto): CommonResponse { authService.checkEmailAuth(checkEmailDto) return CommonResponse.onSuccess("이메일 인증 성공") } @@ -68,7 +66,7 @@ class AuthController( @PatchMapping("/password") @Operation(summary = "00-06 비밀번호 변경") @ApiErrorCodeExample() - fun modifyPassword(@Valid @RequestBody modifyPasswordDto : AuthReq.ModifyPasswordDto) : CommonResponse{ + fun modifyPassword(@Valid @RequestBody modifyPasswordDto: ModifyPasswordDto): CommonResponse { authService.modifyPassword(modifyPasswordDto) return CommonResponse.onSuccess("비밀번호 변경 성공") } @@ -83,7 +81,8 @@ class AuthController( `in` = ParameterIn.HEADER, name = "X-REFRESH-TOKEN", schema = Schema(type = "string") - )@RequestHeader("X-REFRESH-TOKEN") refreshToken : String) : CommonResponse{ + ) @RequestHeader("X-REFRESH-TOKEN") refreshToken: String + ): CommonResponse { return CommonResponse.onSuccess(authService.refreshToken(refreshToken)) } } \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/controller/UserController.kt b/src/main/kotlin/com/example/cmc_be/user/controller/UserController.kt index 430e043..6c77eee 100644 --- a/src/main/kotlin/com/example/cmc_be/user/controller/UserController.kt +++ b/src/main/kotlin/com/example/cmc_be/user/controller/UserController.kt @@ -4,7 +4,7 @@ import ApiErrorCodeExample import com.example.cmc_be.common.response.CommonResponse import com.example.cmc_be.domain.user.entity.User import com.example.cmc_be.domain.user.exeption.UserAuthErrorCode -import com.example.cmc_be.user.dto.UserRes +import com.example.cmc_be.user.dto.user.UserInfoDto import com.example.cmc_be.user.service.UserService import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.tags.Tag @@ -16,21 +16,21 @@ import org.springframework.web.bind.annotation.RestController @RestController @RequestMapping("/users") -@Tag(name ="01 User 유저 관련 API") +@Tag(name = "01 User 유저 관련 API") class UserController( private val userService: UserService ) { @GetMapping("") @ApiErrorCodeExample(UserAuthErrorCode::class) @Operation(summary = "01-01 내 정보 조회 홈화면과 마이페이지 용") - fun getUserInfo(@AuthenticationPrincipal user: User) : CommonResponse{ + fun getUserInfo(@AuthenticationPrincipal user: User): CommonResponse { return CommonResponse.onSuccess(userService.getUserInfo(user)) } @DeleteMapping("") @ApiErrorCodeExample(UserAuthErrorCode::class) @Operation(summary = "01-02 유저 탈퇴") - fun deleteUser(@AuthenticationPrincipal user: User) : CommonResponse{ + fun deleteUser(@AuthenticationPrincipal user: User): CommonResponse { userService.deleteUser(user) return CommonResponse.onSuccess("탈퇴 성공") } diff --git a/src/main/kotlin/com/example/cmc_be/user/convertor/UserConvertor.kt b/src/main/kotlin/com/example/cmc_be/user/convertor/UserConvertor.kt deleted file mode 100644 index 682d4ba..0000000 --- a/src/main/kotlin/com/example/cmc_be/user/convertor/UserConvertor.kt +++ /dev/null @@ -1,77 +0,0 @@ -package com.example.cmc_be.user.convertor - -import com.example.cmc_be.common.annotation.Convertor -import com.example.cmc_be.domain.redis.entity.CodeAuth -import com.example.cmc_be.domain.user.entity.User -import com.example.cmc_be.domain.user.entity.UserPart -import com.example.cmc_be.domain.user.enums.Part -import com.example.cmc_be.user.dto.AuthReq -import com.example.cmc_be.user.dto.AuthRes -import com.example.cmc_be.user.dto.UserRes -import java.util.* - -@Convertor -class UserConvertor { - fun signUpUser(signUpUserDto: AuthReq.SignUpUserDto, password: String): User { - return User( - username = signUpUserDto.email, - password = password, - name = signUpUserDto.name, - nickname = signUpUserDto.nickname, - nowGeneration = signUpUserDto.generation - ) - } - - - fun setUserPart(user: User, part: Part, generation: Int): UserPart { - return UserPart( - user = user, - part = part, - generation = generation - ) - } - - fun tokenResponse(userId: Long, accessToken: String, refreshToken: String): AuthRes.UserTokenDto { - return AuthRes.UserTokenDto( - userId = userId, - accessToken = accessToken, - refreshToken = refreshToken - ) - } - - fun convertToCodeAuth(email: String, code: String): CodeAuth { - return CodeAuth( - auth = email, - code = code, - ttl = 300L - ) - } - - fun convertToUserInfo(user: User, userPart: Optional): UserRes.UserInfoDto { - return UserRes.UserInfoDto( - nickname = user.nickname, - generation = userPart.get().generation, - name = user.name, - email = user.username, - part = userPart.get().part - ) - } - - fun convertToMyPageUserInfo(user: User, userParts: List): UserRes.MyPageUserInfoDto { - return UserRes.MyPageUserInfoDto( - name = user.name, - nickname = user.nickname, - email = user.username, - partLists = convertToPartInfo(userParts) - ) - } - - private fun convertToPartInfo(userParts: List): List { - return userParts.map { userPart -> - UserRes.PartInfoDto( - generation = userPart.generation, - part = userPart.part - ) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/dto/AuthReq.kt b/src/main/kotlin/com/example/cmc_be/user/dto/AuthReq.kt deleted file mode 100644 index c5afbc2..0000000 --- a/src/main/kotlin/com/example/cmc_be/user/dto/AuthReq.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.example.cmc_be.user.dto - -import com.example.cmc_be.domain.user.enums.Part -import jakarta.validation.constraints.Email - -class AuthReq { - data class SignUpUserDto( - @Email - val email: String, - val password: String, - val nickname: String, - val name: String, - val generation: Int, - val part: Part - ) - - data class LoginUserDto( - @Email - val email: String, - val password: String - ) { - } - - data class CheckEmailDto( - @Email - val email : String, - val code : String - ){ - } - - data class ModifyPasswordDto( - @Email - val email : String, - val password: String - ) { - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/dto/AuthRes.kt b/src/main/kotlin/com/example/cmc_be/user/dto/AuthRes.kt deleted file mode 100644 index da73769..0000000 --- a/src/main/kotlin/com/example/cmc_be/user/dto/AuthRes.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.example.cmc_be.user.dto - -import io.swagger.v3.oas.annotations.media.Schema - -class AuthRes { - - data class UserTokenDto( - @Schema(description = "userId 값", required = true, example = "1") - val userId: Long, - @Schema(description = "액세스 토큰", required = true, example = "asdkjanwjkldnjk----") - val accessToken: String, - @Schema(description = "리프레쉬 토큰", required = true, example = "asdkjanwjkldnjk----") - val refreshToken: String - ) { - } - - data class RefreshTokenDto( - @Schema(description = "액세스 토큰", required = true, example = "asdkjanwjkldnjk----") - val accessToken: String - ) { - } - -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/dto/UserRes.kt b/src/main/kotlin/com/example/cmc_be/user/dto/UserRes.kt deleted file mode 100644 index 0814a6a..0000000 --- a/src/main/kotlin/com/example/cmc_be/user/dto/UserRes.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.example.cmc_be.user.dto - -import com.example.cmc_be.domain.user.enums.Part - -class UserRes { - data class UserInfoDto( - val name : String, - val email : String, - val nickname : String, - val generation : Int, - val part : Part - ) { - } - - data class MyPageUserInfoDto( - val name : String, - val nickname : String, - val email : String, - val partLists : List - ) { - - } - - data class PartInfoDto( - val generation : Int, - val part : Part - ){ - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/dto/auth/CheckEmailDto.kt b/src/main/kotlin/com/example/cmc_be/user/dto/auth/CheckEmailDto.kt new file mode 100644 index 0000000..9d37ae6 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/user/dto/auth/CheckEmailDto.kt @@ -0,0 +1,9 @@ +package com.example.cmc_be.user.dto.auth + +import jakarta.validation.constraints.Email + +data class CheckEmailDto( + @Email + val email: String, + val code: String +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/dto/auth/LoginUserDto.kt b/src/main/kotlin/com/example/cmc_be/user/dto/auth/LoginUserDto.kt new file mode 100644 index 0000000..4710efb --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/user/dto/auth/LoginUserDto.kt @@ -0,0 +1,9 @@ +package com.example.cmc_be.user.dto.auth + +import jakarta.validation.constraints.Email + +data class LoginUserDto( + @Email + val email: String, + val password: String +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/dto/auth/ModifyPasswordDto.kt b/src/main/kotlin/com/example/cmc_be/user/dto/auth/ModifyPasswordDto.kt new file mode 100644 index 0000000..74e7592 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/user/dto/auth/ModifyPasswordDto.kt @@ -0,0 +1,9 @@ +package com.example.cmc_be.user.dto.auth + +import jakarta.validation.constraints.Email + +data class ModifyPasswordDto( + @Email + val email: String, + val password: String +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/dto/auth/RefreshTokenDto.kt b/src/main/kotlin/com/example/cmc_be/user/dto/auth/RefreshTokenDto.kt new file mode 100644 index 0000000..97eea1f --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/user/dto/auth/RefreshTokenDto.kt @@ -0,0 +1,10 @@ +package com.example.cmc_be.user.dto.auth + +import io.swagger.v3.oas.annotations.media.Schema + + +data class RefreshTokenDto( + @Schema(description = "액세스 토큰", required = true, example = "asdkjanwjkldnjk----") + val accessToken: String +) + diff --git a/src/main/kotlin/com/example/cmc_be/user/dto/auth/SignUpUserDto.kt b/src/main/kotlin/com/example/cmc_be/user/dto/auth/SignUpUserDto.kt new file mode 100644 index 0000000..95bfcf3 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/user/dto/auth/SignUpUserDto.kt @@ -0,0 +1,15 @@ +package com.example.cmc_be.user.dto.auth + +import com.example.cmc_be.domain.user.enums.Part +import jakarta.validation.constraints.Email + +data class SignUpUserDto( + @Email + val email: String, + val password: String, + val nickname: String, + val name: String, + val generation: Int, + val part: Part +) + diff --git a/src/main/kotlin/com/example/cmc_be/user/dto/auth/UserTokenDto.kt b/src/main/kotlin/com/example/cmc_be/user/dto/auth/UserTokenDto.kt new file mode 100644 index 0000000..b1debb1 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/user/dto/auth/UserTokenDto.kt @@ -0,0 +1,12 @@ +package com.example.cmc_be.user.dto.auth + +import io.swagger.v3.oas.annotations.media.Schema + +data class UserTokenDto( + @Schema(description = "userId 값", required = true, example = "1") + val userId: Long, + @Schema(description = "액세스 토큰", required = true, example = "asdkjanwjkldnjk----") + val accessToken: String, + @Schema(description = "리프레쉬 토큰", required = true, example = "asdkjanwjkldnjk----") + val refreshToken: String +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/dto/user/MyPageUserInfoDto.kt b/src/main/kotlin/com/example/cmc_be/user/dto/user/MyPageUserInfoDto.kt new file mode 100644 index 0000000..fdd3162 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/user/dto/user/MyPageUserInfoDto.kt @@ -0,0 +1,8 @@ +package com.example.cmc_be.user.dto.user + +data class MyPageUserInfoDto( + val name: String, + val nickname: String, + val email: String, + val partLists: List +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/dto/user/PartInfoDto.kt b/src/main/kotlin/com/example/cmc_be/user/dto/user/PartInfoDto.kt new file mode 100644 index 0000000..5031d3e --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/user/dto/user/PartInfoDto.kt @@ -0,0 +1,8 @@ +package com.example.cmc_be.user.dto.user + +import com.example.cmc_be.domain.user.enums.Part + +data class PartInfoDto( + val generation: Int, + val part: Part +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/dto/user/UserInfoDto.kt b/src/main/kotlin/com/example/cmc_be/user/dto/user/UserInfoDto.kt new file mode 100644 index 0000000..2247c55 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/user/dto/user/UserInfoDto.kt @@ -0,0 +1,12 @@ +package com.example.cmc_be.user.dto.user + +import com.example.cmc_be.domain.user.enums.Part + +data class UserInfoDto( + val name: String, + val email: String, + val nickname: String, + val generation: Int, + val part: Part +) + diff --git a/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt b/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt index 7bb1102..4c60721 100644 --- a/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt +++ b/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt @@ -11,13 +11,12 @@ import com.example.cmc_be.domain.redis.repository.CodeAuthRepository import com.example.cmc_be.domain.redis.repository.RefreshTokenRepository import com.example.cmc_be.domain.user.adaptor.UserAdapter import com.example.cmc_be.domain.user.entity.User +import com.example.cmc_be.domain.user.entity.UserPart import com.example.cmc_be.domain.user.exeption.* import com.example.cmc_be.domain.user.repository.UserPartRepository import com.example.cmc_be.domain.user.repository.UserRepository import com.example.cmc_be.external.MailService -import com.example.cmc_be.user.convertor.UserConvertor -import com.example.cmc_be.user.dto.AuthReq -import com.example.cmc_be.user.dto.AuthRes +import com.example.cmc_be.user.dto.auth.* import jakarta.transaction.Transactional import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.stereotype.Service @@ -25,7 +24,6 @@ import org.springframework.stereotype.Service @Service class AuthService( private val jwtService: JwtService, - private val userConvertor: UserConvertor, private val userAdapter: UserAdapter, private val userRepository: UserRepository, private val userPartRepository: UserPartRepository, @@ -35,25 +33,35 @@ class AuthService( private val refreshTokenRepository: RefreshTokenRepository ) { @Transactional - fun signUpUser(signUpUserDto: AuthReq.SignUpUserDto): AuthRes.UserTokenDto { + fun signUpUser(signUpUserDto: SignUpUserDto): UserTokenDto { userAdapter.checkEmailExists(signUpUserDto.email) - val user: User = - userRepository.save(userConvertor.signUpUser(signUpUserDto, passwordEncoder.encode(signUpUserDto.password))) - - userPartRepository.save(userConvertor.setUserPart(user, signUpUserDto.part, signUpUserDto.generation)) - - val userId: Long = user.id + val user = userRepository.save( + User( + username = signUpUserDto.email, + password = passwordEncoder.encode(signUpUserDto.password), + name = signUpUserDto.name, + nickname = signUpUserDto.nickname, + nowGeneration = signUpUserDto.generation + ) + ) + userPartRepository.save( + UserPart( + user = user, + part = signUpUserDto.part, + generation = signUpUserDto.generation + ) + ) - return userConvertor.tokenResponse( - userId, - jwtService.createToken(userId), - jwtService.createRefreshToken(userId) + return UserTokenDto( + userId = user.id, + accessToken = jwtService.createToken(user.id), + refreshToken = jwtService.createRefreshToken(user.id) ) } - fun logInUser(loginUserDto: AuthReq.LoginUserDto): AuthRes.UserTokenDto { - val user: User = userAdapter.findByUsername(loginUserDto.email) + fun logInUser(loginUserDto: LoginUserDto): UserTokenDto { + val user = userAdapter.findByUsername(loginUserDto.email) if (!passwordEncoder.matches( loginUserDto.password, @@ -61,19 +69,16 @@ class AuthService( ) ) throw BadRequestException(LoginUserErrorCode.NOT_CORRECT_PASSWORD) - val userId: Long = user.id - - return userConvertor.tokenResponse( - userId, - jwtService.createToken(userId), - jwtService.createRefreshToken(userId) + return UserTokenDto( + userId = user.id, + accessToken = jwtService.createToken(user.id), + refreshToken = jwtService.createRefreshToken(user.id) ) } fun checkEmail(email: String) { - if (userRepository.existsByUsernameAndStatus(email, Status.ACTIVE)) throw BadRequestException( - SignUpUserErrorCode.EXISTS_USER_EMAIL - ); + if (userRepository.existsByUsernameAndStatus(email, Status.ACTIVE)) + throw BadRequestException(SignUpUserErrorCode.EXISTS_USER_EMAIL) } fun sendEmail(email: String) { @@ -82,26 +87,32 @@ class AuthService( Status.ACTIVE ) ) throw BadRequestException(UserAuthErrorCode.NOT_EXIST_USER); - val code: String = RandomNumberUtil.createNumbers() - codeAuthRepository.save(userConvertor.convertToCodeAuth(email, code)) + val code = RandomNumberUtil.createNumbers() + codeAuthRepository.save( + CodeAuth( + auth = email, + code = code, + ttl = 300L + ) + ) mailService.sendEmailAsync(email, code) } - fun checkEmailAuth(checkEmailDto: AuthReq.CheckEmailDto) { - val codeAuth: CodeAuth = codeAuthRepository.findById(checkEmailDto.email).orElseThrow { + fun checkEmailAuth(checkEmailDto: CheckEmailDto) { + val codeAuth = codeAuthRepository.findById(checkEmailDto.email).orElseThrow { NotFoundException(CheckAuthErrorCode.NOT_EXISTS_AUTH) } if (codeAuth.code != checkEmailDto.code) throw BadRequestException(CheckAuthErrorCode.NOT_CORRECT_CODE) } - fun modifyPassword(modifyPasswordDto: AuthReq.ModifyPasswordDto) { + fun modifyPassword(modifyPasswordDto: ModifyPasswordDto) { val user: User = userAdapter.findByUsername(modifyPasswordDto.email) user.modifyPassword(passwordEncoder.encode(modifyPasswordDto.password)) userRepository.save(user) } - fun refreshToken(refreshToken: String): AuthRes.RefreshTokenDto? { + fun refreshToken(refreshToken: String): RefreshTokenDto? { val userId = jwtService.getUserIdByRefreshToken(refreshToken) val redisRefreshToken: RefreshToken = refreshTokenRepository.findById(userId.toString()).orElseThrow { BadRequestException( @@ -110,9 +121,6 @@ class AuthService( } if (redisRefreshToken.refreshToken != refreshToken) throw BadRequestException(RefreshTokenErrorCode.INVALID_REFRESH_TOKEN) - - return AuthRes.RefreshTokenDto(jwtService.createToken(userId)); + return RefreshTokenDto(jwtService.createToken(userId)); } - - } \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/service/UserService.kt b/src/main/kotlin/com/example/cmc_be/user/service/UserService.kt index 5839d89..344ffe2 100644 --- a/src/main/kotlin/com/example/cmc_be/user/service/UserService.kt +++ b/src/main/kotlin/com/example/cmc_be/user/service/UserService.kt @@ -1,24 +1,33 @@ package com.example.cmc_be.user.service import com.example.cmc_be.common.dto.Status +import com.example.cmc_be.common.exeption.BadRequestException import com.example.cmc_be.domain.user.entity.User import com.example.cmc_be.domain.user.entity.UserPart +import com.example.cmc_be.domain.user.exeption.UserPartErrorCode import com.example.cmc_be.domain.user.repository.UserPartRepository import com.example.cmc_be.domain.user.repository.UserRepository -import com.example.cmc_be.user.convertor.UserConvertor -import com.example.cmc_be.user.dto.UserRes +import com.example.cmc_be.user.dto.user.MyPageUserInfoDto +import com.example.cmc_be.user.dto.user.PartInfoDto +import com.example.cmc_be.user.dto.user.UserInfoDto import org.springframework.stereotype.Service -import java.util.* @Service class UserService( - private val userConvertor: UserConvertor, private val userPartRepository: UserPartRepository, private val userRepository: UserRepository ) { - fun getUserInfo(user: User): UserRes.UserInfoDto { - val userPart : Optional = userPartRepository.findByUserAndGeneration(user, user.nowGeneration) - return userConvertor.convertToUserInfo(user, userPart) + fun getUserInfo(user: User): UserInfoDto { + val userPart = + userPartRepository.findByUserAndGeneration(user, user.nowGeneration) + ?: throw BadRequestException(UserPartErrorCode.NOT_EXISTS_USER_PART) + return UserInfoDto( + nickname = user.nickname, + generation = userPart.generation, + name = user.name, + email = user.username, + part = userPart.part + ) } fun deleteUser(user: User) { @@ -26,9 +35,22 @@ class UserService( userRepository.save(user) } + fun getMyPage(user: User): MyPageUserInfoDto { + val userParts = userPartRepository.findByUser(user) + return MyPageUserInfoDto( + name = user.name, + nickname = user.nickname, + email = user.username, + partLists = convertToPartInfo(userParts) + ) + } - fun getMyPage(user: User): UserRes.MyPageUserInfoDto? { - val userParts : List = userPartRepository.findByUser(user) - return userConvertor.convertToMyPageUserInfo(user, userParts) + private fun convertToPartInfo(userParts: List): List { + return userParts.map { userPart -> + PartInfoDto( + generation = userPart.generation, + part = userPart.part + ) + } } } \ No newline at end of file From 7981de4ad3951336e90ea0ff4f2794fa2ec7a5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=ED=95=B4=EC=B0=AC=5BVertical=20Service=20Dev1=5D?= Date: Thu, 16 May 2024 14:11:57 +0900 Subject: [PATCH 06/10] =?UTF-8?q?refactor=20:=20attendance=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AdminAttendanceController.kt | 25 +++-- .../controller/AttendanceController.kt | 8 +- .../convertor/AttendanceConvertor.kt | 98 ------------------- .../cmc_be/attendance/dto/AttendanceReq.kt | 31 ------ .../cmc_be/attendance/dto/AttendanceRes.kt | 45 --------- .../attendance/dto/req/AttendanceCodeReq.kt | 5 + .../cmc_be/attendance/dto/req/GenerateCode.kt | 16 +++ .../attendance/dto/req/HourAndMinute.kt | 10 ++ .../attendance/dto/res/AllAttendanceInfos.kt | 9 ++ .../attendance/dto/res/AttendanceCodeRes.kt | 13 +++ .../dto/res/AttendanceDashboardInfo.kt | 20 ++++ .../attendance/dto/res/AttendanceInfo.kt | 15 +++ .../dto/res/AttendancesDashboard.kt | 17 ++++ .../service/AttendanceCodeValidator.kt | 30 ------ .../attendance/service/AttendanceService.kt | 73 +++++++++++--- .../attendance/service/QrCodeService.kt | 68 +++++++------ .../cmc_be/common/utils/RandomNumberUtil.kt | 14 ++- .../cmc_be/user/service/AuthService.kt | 5 +- 18 files changed, 236 insertions(+), 266 deletions(-) delete mode 100644 src/main/kotlin/com/example/cmc_be/attendance/convertor/AttendanceConvertor.kt delete mode 100644 src/main/kotlin/com/example/cmc_be/attendance/dto/AttendanceReq.kt delete mode 100644 src/main/kotlin/com/example/cmc_be/attendance/dto/AttendanceRes.kt create mode 100644 src/main/kotlin/com/example/cmc_be/attendance/dto/req/AttendanceCodeReq.kt create mode 100644 src/main/kotlin/com/example/cmc_be/attendance/dto/req/GenerateCode.kt create mode 100644 src/main/kotlin/com/example/cmc_be/attendance/dto/req/HourAndMinute.kt create mode 100644 src/main/kotlin/com/example/cmc_be/attendance/dto/res/AllAttendanceInfos.kt create mode 100644 src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendanceCodeRes.kt create mode 100644 src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendanceDashboardInfo.kt create mode 100644 src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendanceInfo.kt create mode 100644 src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendancesDashboard.kt delete mode 100644 src/main/kotlin/com/example/cmc_be/attendance/service/AttendanceCodeValidator.kt diff --git a/src/main/kotlin/com/example/cmc_be/attendance/controller/AdminAttendanceController.kt b/src/main/kotlin/com/example/cmc_be/attendance/controller/AdminAttendanceController.kt index dec44c9..bdae59c 100644 --- a/src/main/kotlin/com/example/cmc_be/attendance/controller/AdminAttendanceController.kt +++ b/src/main/kotlin/com/example/cmc_be/attendance/controller/AdminAttendanceController.kt @@ -1,11 +1,13 @@ package com.example.cmc_be.attendance.controller -import com.example.cmc_be.attendance.dto.AttendanceReq -import com.example.cmc_be.attendance.dto.AttendanceRes +import com.example.cmc_be.attendance.dto.req.GenerateCode +import com.example.cmc_be.attendance.dto.res.AllAttendanceInfos +import com.example.cmc_be.attendance.dto.res.AttendanceCodeRes import com.example.cmc_be.attendance.service.AttendanceService import com.example.cmc_be.attendance.service.QrCodeService import com.example.cmc_be.common.exeption.BadRequestException import com.example.cmc_be.common.response.CommonResponse +import com.example.cmc_be.domain.attendance.entity.AttendanceCode import com.example.cmc_be.domain.attendance.exception.AttendanceErrorCode import com.example.cmc_be.domain.generation.repository.GenerationWeeksInfoRepository import com.example.cmc_be.domain.user.entity.User @@ -27,12 +29,12 @@ class AdminAttendanceController( @Operation(summary = "03-01 출석용 코드 생성(중복 생성 가능)") fun generateCode( @AuthenticationPrincipal user: User, - @RequestBody gernerateCode: AttendanceReq.GenerateCode + @RequestBody gernerateCode: GenerateCode ): CommonResponse { val generationWeeksInfo = generationWeeksInfoRepository.findFirstByGenerationAndWeek( generation = gernerateCode.generation, week = gernerateCode.week ) ?: throw BadRequestException(AttendanceErrorCode.CANNOT_ACCESS_ATEENDANCE) - + return CommonResponse.onSuccess( qrCodeService.generateCode( generationReq = gernerateCode, @@ -42,22 +44,29 @@ class AdminAttendanceController( } @GetMapping("/code") - @Operation(summary = "03-02 코드 정보 조회") + @Operation(summary = "03-02 특정 코드 정보 조회") fun getCodeInfo( @AuthenticationPrincipal user: User, @Parameter(description = "코드", example = "8dFsb") @RequestParam code: String, - ): CommonResponse { + ): CommonResponse { return CommonResponse.onSuccess(qrCodeService.getCodeInfo(code)) } + @GetMapping("/code/all") + @Operation(summary = "03-03 모든 코드 정보 조회") + fun getCodeInfo( + @AuthenticationPrincipal user: User, + ): CommonResponse> { + return CommonResponse.onSuccess(qrCodeService.getAllCodes()) + } @GetMapping("/all") - @Operation(summary = "03-03 기수별 모든 출석 현황 체크") + @Operation(summary = "03-04 기수별 모든 출석 현황 체크") fun getParticipantsAttendance( @AuthenticationPrincipal user: User, @Parameter(description = "기수", example = "13") @RequestParam generation: Int, - ): CommonResponse> { + ): CommonResponse> { return CommonResponse.onSuccess(attendanceService.getParticipantsAttendance(generation)) } diff --git a/src/main/kotlin/com/example/cmc_be/attendance/controller/AttendanceController.kt b/src/main/kotlin/com/example/cmc_be/attendance/controller/AttendanceController.kt index c0e9ec8..01fec69 100644 --- a/src/main/kotlin/com/example/cmc_be/attendance/controller/AttendanceController.kt +++ b/src/main/kotlin/com/example/cmc_be/attendance/controller/AttendanceController.kt @@ -1,7 +1,7 @@ package com.example.cmc_be.attendance.controller -import com.example.cmc_be.attendance.dto.AttendanceReq -import com.example.cmc_be.attendance.dto.AttendanceRes +import com.example.cmc_be.attendance.dto.req.AttendanceCodeReq +import com.example.cmc_be.attendance.dto.res.AttendancesDashboard import com.example.cmc_be.attendance.service.AttendanceService import com.example.cmc_be.common.response.CommonResponse import com.example.cmc_be.domain.user.entity.User @@ -18,7 +18,7 @@ class AttendanceController( ) { @GetMapping("") @Operation(summary = "03-01 출석 현황 조회") - fun getAttendanceList(@AuthenticationPrincipal user: User): CommonResponse { + fun getAttendanceList(@AuthenticationPrincipal user: User): CommonResponse { return CommonResponse.onSuccess(attendanceService.getAttendanceList(user)) } @@ -26,7 +26,7 @@ class AttendanceController( @Operation(summary = "03-02 출석 체크 진행") fun setAttendance( @AuthenticationPrincipal user: User, - @RequestBody attendanceCode: AttendanceReq.AttendanceCode + @RequestBody attendanceCode: AttendanceCodeReq ): CommonResponse { return CommonResponse.onSuccess(attendanceService.setAttendance(user, attendanceCode)) } diff --git a/src/main/kotlin/com/example/cmc_be/attendance/convertor/AttendanceConvertor.kt b/src/main/kotlin/com/example/cmc_be/attendance/convertor/AttendanceConvertor.kt deleted file mode 100644 index 31fbbb8..0000000 --- a/src/main/kotlin/com/example/cmc_be/attendance/convertor/AttendanceConvertor.kt +++ /dev/null @@ -1,98 +0,0 @@ -package com.example.cmc_be.attendance.convertor - -import com.example.cmc_be.attendance.dto.AttendanceRes -import com.example.cmc_be.common.annotation.Convertor -import com.example.cmc_be.domain.attendance.entity.Attendance -import com.example.cmc_be.domain.attendance.entity.AttendanceCode -import com.example.cmc_be.domain.attendance.enums.AttendanceCategory -import com.example.cmc_be.domain.attendance.enums.AttendanceHour -import com.example.cmc_be.domain.generation.entity.GenerationWeeksInfo -import com.example.cmc_be.domain.user.entity.User -import java.time.ZoneId -import java.time.ZonedDateTime - -@Convertor -class AttendanceConverter { - - fun getAttendanceList( - allGenerationWeeksInfo: List, - userAllAttendanceData: Map> - ): AttendanceRes.GetAttendances { - val attendances = allGenerationWeeksInfo.map { generationWeekInfo -> - val week = generationWeekInfo.week - val firstHour = - (userAllAttendanceData[week]?.find { it.attendanceHour == AttendanceHour.FIRST_HOUR })?.attendanceCategory - ?: AttendanceCategory.ABSENT - val secondHour = - (userAllAttendanceData[week]?.find { it.attendanceHour == AttendanceHour.SECOND_HOUR })?.attendanceCategory - ?: AttendanceCategory.ABSENT - val currentDateTime = ZonedDateTime.now(ZoneId.systemDefault()) - val currentDate = currentDateTime.toLocalDate() - - AttendanceRes.AttendanceInfoDto( - week = week, - firstHour = firstHour, - secondHour = secondHour, - isOffline = generationWeekInfo.isOffline, - date = generationWeekInfo.date, - enable = currentDate.isAfter(generationWeekInfo.date.minusDays(1L)) - ) - } - val enableAttendances = attendances.filter { it.enable } - return AttendanceRes.GetAttendances( - attendanceStatus = AttendanceRes.AttendanceStatus( - attendanceCount = enableAttendances.count { it.firstHour == AttendanceCategory.ATTENDANCE } + enableAttendances.count { it.secondHour == AttendanceCategory.ATTENDANCE }, - lateCount = enableAttendances.count { it.firstHour == AttendanceCategory.LATE } + enableAttendances.count { it.secondHour == AttendanceCategory.LATE }, - absentCount = enableAttendances.count { it.firstHour == AttendanceCategory.ABSENT } + enableAttendances.count { it.secondHour == AttendanceCategory.ABSENT }, - ), - attandances = attendances - ) - } - - fun getParticipantsAttendance( - allUsers: List, - allAttendances: List, - allGeneration: List - ) = allUsers.map { user -> - val userAttandances = allAttendances.filter { it.user.id == user.id } - val attendances = allGeneration.map { generationWeekInfo -> - val userAllAttendanceData = - userAttandances.filter { it.generationWeeksInfo.week == generationWeekInfo.week } - val firstHour = - (userAllAttendanceData.find { it.attendanceHour == AttendanceHour.FIRST_HOUR })?.attendanceCategory - ?: AttendanceCategory.ABSENT - val secondHour = - (userAllAttendanceData.find { it.attendanceHour == AttendanceHour.SECOND_HOUR })?.attendanceCategory - ?: AttendanceCategory.ABSENT - AttendanceRes.AttendanceInfoDto( - week = generationWeekInfo.week, - firstHour = firstHour, - secondHour = secondHour, - isOffline = generationWeekInfo.isOffline, - date = generationWeekInfo.date, - enable = true, - ) - } - AttendanceRes.AllAttendanceInfoDto( - name = user.name, - role = user.role, - nickname = user.nickname, - attendanceStatus = AttendanceRes.AttendanceStatus( - attendanceCount = attendances.count { it.firstHour == AttendanceCategory.ATTENDANCE } + attendances.count { it.secondHour == AttendanceCategory.ATTENDANCE }, - lateCount = attendances.count { it.firstHour == AttendanceCategory.LATE } + attendances.count { it.secondHour == AttendanceCategory.LATE }, - absentCount = attendances.count { it.firstHour == AttendanceCategory.ABSENT } + attendances.count { it.secondHour == AttendanceCategory.ABSENT }, - ), - attandances = attendances - ) - } - - fun getCodeInfo(codeInfo: AttendanceCode): AttendanceRes.AttendanceCodeDto { - return AttendanceRes.AttendanceCodeDto( - availableDate = codeInfo.generationWeeksInfo.date, - startTime = codeInfo.startTime, - endTime = codeInfo.endTime, - lateMinute = codeInfo.lateMinute - ) - } - -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/attendance/dto/AttendanceReq.kt b/src/main/kotlin/com/example/cmc_be/attendance/dto/AttendanceReq.kt deleted file mode 100644 index a5db33e..0000000 --- a/src/main/kotlin/com/example/cmc_be/attendance/dto/AttendanceReq.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.example.cmc_be.attendance.dto - -import io.swagger.v3.oas.annotations.media.Schema -import java.time.LocalTime - -class AttendanceReq { - - data class AttendanceCode( - val code: String - ) - - data class GenerateCode( - @Schema(example = "14") - val generation: Int, - @Schema(example = "1") - val week: Int, - @Schema(example = "1") - val hour: Int, - val startTime: HourAndMinute, - val endTime: HourAndMinute, - @Schema(example = "15") - val lateMinute: Long, - ) - - data class HourAndMinute( - val hour: Int, - val minute: Int - ) { - fun toLocalTime(): LocalTime = LocalTime.of(hour, minute) - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/attendance/dto/AttendanceRes.kt b/src/main/kotlin/com/example/cmc_be/attendance/dto/AttendanceRes.kt deleted file mode 100644 index 02e883b..0000000 --- a/src/main/kotlin/com/example/cmc_be/attendance/dto/AttendanceRes.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.example.cmc_be.attendance.dto - -import com.example.cmc_be.domain.attendance.enums.AttendanceCategory -import com.fasterxml.jackson.annotation.JsonFormat -import java.time.LocalDate -import java.time.LocalTime - -class AttendanceRes { - data class AttendanceInfoDto( - val week: Int, - val firstHour: AttendanceCategory, - val secondHour: AttendanceCategory, - val isOffline: Boolean, - val enable: Boolean, - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") - val date: LocalDate - ) - - data class AttendanceCodeDto( - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") - val availableDate: LocalDate, - val startTime: LocalTime, - val endTime: LocalTime, - val lateMinute: Long - ) - - data class AllAttendanceInfoDto( - val name: String, - val role: String, - val nickname: String, - val attendanceStatus: AttendanceStatus, - val attandances: List - ) - - data class GetAttendances( - val attendanceStatus: AttendanceStatus, - val attandances: List - ) - - data class AttendanceStatus( - val attendanceCount: Int, - val lateCount: Int, - val absentCount: Int - ) -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/attendance/dto/req/AttendanceCodeReq.kt b/src/main/kotlin/com/example/cmc_be/attendance/dto/req/AttendanceCodeReq.kt new file mode 100644 index 0000000..eec1414 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/attendance/dto/req/AttendanceCodeReq.kt @@ -0,0 +1,5 @@ +package com.example.cmc_be.attendance.dto.req + +data class AttendanceCodeReq( + val code: String +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/attendance/dto/req/GenerateCode.kt b/src/main/kotlin/com/example/cmc_be/attendance/dto/req/GenerateCode.kt new file mode 100644 index 0000000..3513bd2 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/attendance/dto/req/GenerateCode.kt @@ -0,0 +1,16 @@ +package com.example.cmc_be.attendance.dto.req + +import io.swagger.v3.oas.annotations.media.Schema + +data class GenerateCode( + @Schema(example = "14") + val generation: Int, + @Schema(example = "1") + val week: Int, + @Schema(example = "1") + val hour: Int, + val startTime: HourAndMinute, + val endTime: HourAndMinute, + @Schema(example = "15") + val lateMinute: Long, +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/attendance/dto/req/HourAndMinute.kt b/src/main/kotlin/com/example/cmc_be/attendance/dto/req/HourAndMinute.kt new file mode 100644 index 0000000..1de09d7 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/attendance/dto/req/HourAndMinute.kt @@ -0,0 +1,10 @@ +package com.example.cmc_be.attendance.dto.req + +import java.time.LocalTime + +data class HourAndMinute( + val hour: Int, + val minute: Int +) { + fun toLocalTime(): LocalTime = LocalTime.of(hour, minute) +} diff --git a/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AllAttendanceInfos.kt b/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AllAttendanceInfos.kt new file mode 100644 index 0000000..303516c --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AllAttendanceInfos.kt @@ -0,0 +1,9 @@ +package com.example.cmc_be.attendance.dto.res + +data class AllAttendanceInfos( + val name: String, + val role: String, + val nickname: String, + val attendanceStatus: AttendanceDashboardInfo, + val attandances: List +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendanceCodeRes.kt b/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendanceCodeRes.kt new file mode 100644 index 0000000..4d7e832 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendanceCodeRes.kt @@ -0,0 +1,13 @@ +package com.example.cmc_be.attendance.dto.res + +import com.fasterxml.jackson.annotation.JsonFormat +import java.time.LocalDate +import java.time.LocalTime + +data class AttendanceCodeRes( + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") + val availableDate: LocalDate, + val startTime: LocalTime, + val endTime: LocalTime, + val lateMinute: Long +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendanceDashboardInfo.kt b/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendanceDashboardInfo.kt new file mode 100644 index 0000000..276d762 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendanceDashboardInfo.kt @@ -0,0 +1,20 @@ +package com.example.cmc_be.attendance.dto.res + +import com.example.cmc_be.domain.attendance.enums.AttendanceCategory + +data class AttendanceDashboardInfo( + val attendanceCount: Int, + val lateCount: Int, + val absentCount: Int +) { + + companion object { + fun from(attendanceInfos: List): AttendanceDashboardInfo { + return AttendanceDashboardInfo( + attendanceCount = attendanceInfos.count { it.firstHour == AttendanceCategory.ATTENDANCE } + attendanceInfos.count { it.secondHour == AttendanceCategory.ATTENDANCE }, + lateCount = attendanceInfos.count { it.firstHour == AttendanceCategory.LATE } + attendanceInfos.count { it.secondHour == AttendanceCategory.LATE }, + absentCount = attendanceInfos.count { it.firstHour == AttendanceCategory.ABSENT } + attendanceInfos.count { it.secondHour == AttendanceCategory.ABSENT }, + ) + } + } +} diff --git a/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendanceInfo.kt b/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendanceInfo.kt new file mode 100644 index 0000000..b067471 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendanceInfo.kt @@ -0,0 +1,15 @@ +package com.example.cmc_be.attendance.dto.res + +import com.example.cmc_be.domain.attendance.enums.AttendanceCategory +import com.fasterxml.jackson.annotation.JsonFormat +import java.time.LocalDate + +data class AttendanceInfo( + val week: Int, + val firstHour: AttendanceCategory, + val secondHour: AttendanceCategory, + val isOffline: Boolean, + val enable: Boolean, + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") + val date: LocalDate +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendancesDashboard.kt b/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendancesDashboard.kt new file mode 100644 index 0000000..5ee9d65 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/attendance/dto/res/AttendancesDashboard.kt @@ -0,0 +1,17 @@ +package com.example.cmc_be.attendance.dto.res + +data class AttendancesDashboard( + val attendanceStatus: AttendanceDashboardInfo, + val attandances: List +) { + + companion object { + fun from(attendanceInfos: List): AttendancesDashboard { + val enableAttendances = attendanceInfos.filter { it.enable } + return AttendancesDashboard( + attendanceStatus = AttendanceDashboardInfo.from(enableAttendances), + attandances = attendanceInfos + ) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/attendance/service/AttendanceCodeValidator.kt b/src/main/kotlin/com/example/cmc_be/attendance/service/AttendanceCodeValidator.kt deleted file mode 100644 index 8785830..0000000 --- a/src/main/kotlin/com/example/cmc_be/attendance/service/AttendanceCodeValidator.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.example.cmc_be.attendance.service - -import com.example.cmc_be.common.exeption.BadRequestException -import com.example.cmc_be.domain.attendance.entity.AttendanceCode -import com.example.cmc_be.domain.attendance.exception.AttendanceErrorCode -import com.example.cmc_be.domain.attendance.repository.AttendanceRepository -import com.example.cmc_be.domain.user.entity.User -import org.springframework.stereotype.Component - -@Component -class AttendanceCodeValidator( - private val attendanceRepository: AttendanceRepository -) { - - fun validateAlreadyAttendance( - userId: Long, attendanceCode: AttendanceCode - ) { - if (attendanceRepository.findAllByUserId(userId) - .any { it.generationWeeksInfo.week == attendanceCode.week && it.attendanceHour == attendanceCode.hour } - ) { - throw BadRequestException(AttendanceErrorCode.ALREADY_ATEENDANCE) - } - } - - fun validateGeneration(user: User, generation: Int) { - if (user.nowGeneration != generation) { - throw BadRequestException(AttendanceErrorCode.CANNOT_ACCESS_ATEENDANCE) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/attendance/service/AttendanceService.kt b/src/main/kotlin/com/example/cmc_be/attendance/service/AttendanceService.kt index e6357ff..56ca5e8 100644 --- a/src/main/kotlin/com/example/cmc_be/attendance/service/AttendanceService.kt +++ b/src/main/kotlin/com/example/cmc_be/attendance/service/AttendanceService.kt @@ -1,39 +1,60 @@ package com.example.cmc_be.attendance.service -import com.example.cmc_be.attendance.convertor.AttendanceConverter -import com.example.cmc_be.attendance.dto.AttendanceReq -import com.example.cmc_be.attendance.dto.AttendanceRes +import com.example.cmc_be.attendance.dto.req.AttendanceCodeReq +import com.example.cmc_be.attendance.dto.res.AllAttendanceInfos +import com.example.cmc_be.attendance.dto.res.AttendanceDashboardInfo +import com.example.cmc_be.attendance.dto.res.AttendanceInfo +import com.example.cmc_be.attendance.dto.res.AttendancesDashboard import com.example.cmc_be.common.exeption.NotFoundException import com.example.cmc_be.domain.attendance.entity.Attendance import com.example.cmc_be.domain.attendance.enums.AttendanceCategory +import com.example.cmc_be.domain.attendance.enums.AttendanceHour import com.example.cmc_be.domain.attendance.repository.AttendanceRepository import com.example.cmc_be.domain.generation.repository.GenerationWeeksInfoRepository import com.example.cmc_be.domain.notification.exception.NotificationExceptionErrorCode import com.example.cmc_be.domain.user.entity.User import com.example.cmc_be.domain.user.repository.UserRepository import org.springframework.stereotype.Service +import java.time.ZoneId +import java.time.ZonedDateTime @Service class AttendanceService( private val attendanceRepository: AttendanceRepository, private val generationWeeksInfoRepository: GenerationWeeksInfoRepository, private val userRepository: UserRepository, - private val attendanceConverter: AttendanceConverter, private val qrCodeService: QrCodeService ) { - fun getAttendanceList(user: User): AttendanceRes.GetAttendances { + fun getAttendanceList(user: User): AttendancesDashboard { val allGenerationWeeksInfo = generationWeeksInfoRepository.findAllByGeneration(user.nowGeneration).sortedBy { it.week } val userAllAttendanceData = attendanceRepository.findAllByUserId(user.id).groupBy { it.generationWeeksInfo.week } - return attendanceConverter.getAttendanceList( - allGenerationWeeksInfo = allGenerationWeeksInfo, - userAllAttendanceData = userAllAttendanceData - ) + val attendanceInfos = allGenerationWeeksInfo.map { generationWeekInfo -> + val week = generationWeekInfo.week + val firstHour = + (userAllAttendanceData[week]?.find { it.attendanceHour == AttendanceHour.FIRST_HOUR })?.attendanceCategory + ?: AttendanceCategory.ABSENT + val secondHour = + (userAllAttendanceData[week]?.find { it.attendanceHour == AttendanceHour.SECOND_HOUR })?.attendanceCategory + ?: AttendanceCategory.ABSENT + val currentDateTime = ZonedDateTime.now(ZoneId.systemDefault()) + val currentDate = currentDateTime.toLocalDate() + + AttendanceInfo( + week = week, + firstHour = firstHour, + secondHour = secondHour, + isOffline = generationWeekInfo.isOffline, + date = generationWeekInfo.date, + enable = currentDate.isAfter(generationWeekInfo.date.minusDays(1L)) + ) + } + return AttendancesDashboard.from(attendanceInfos) } - fun setAttendance(user: User, code: AttendanceReq.AttendanceCode): String { + fun setAttendance(user: User, code: AttendanceCodeReq): String { val attendanceCode = qrCodeService.getCode(code.code) qrCodeService.validateCode(user, attendanceCode) val attendanceCategory = if (attendanceCode.isLate()) AttendanceCategory.LATE else AttendanceCategory.ATTENDANCE @@ -52,11 +73,37 @@ class AttendanceService( return "${attendanceCategory.status}하였습니다." } - fun getParticipantsAttendance(generation: Int): List { + fun getParticipantsAttendance(generation: Int): List { val allGeneration = generationWeeksInfoRepository.findAllByGeneration(generation).sortedBy { it.week } val allUsers = userRepository.findAllByNowGeneration(generation) val allAttendances = attendanceRepository.findAllByGenerationWeeksInfoGeneration(generation) - return attendanceConverter.getParticipantsAttendance(allUsers, allAttendances, allGeneration) + return allUsers.map { user -> + val userAttandances = allAttendances.filter { it.user.id == user.id } + val attendanceInfos = allGeneration.map { generationWeekInfo -> + val userAllAttendanceData = + userAttandances.filter { it.generationWeeksInfo.week == generationWeekInfo.week } + val firstHour = + (userAllAttendanceData.find { it.attendanceHour == AttendanceHour.FIRST_HOUR })?.attendanceCategory + ?: AttendanceCategory.ABSENT + val secondHour = + (userAllAttendanceData.find { it.attendanceHour == AttendanceHour.SECOND_HOUR })?.attendanceCategory + ?: AttendanceCategory.ABSENT + AttendanceInfo( + week = generationWeekInfo.week, + firstHour = firstHour, + secondHour = secondHour, + isOffline = generationWeekInfo.isOffline, + date = generationWeekInfo.date, + enable = true, + ) + } + AllAttendanceInfos( + name = user.name, + role = user.role, + nickname = user.nickname, + attendanceStatus = AttendanceDashboardInfo.from(attendanceInfos), + attandances = attendanceInfos + ) + } } - } \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt b/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt index 7b73d0a..589b56a 100644 --- a/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt +++ b/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt @@ -1,30 +1,30 @@ package com.example.cmc_be.attendance.service -import com.example.cmc_be.attendance.convertor.AttendanceConverter -import com.example.cmc_be.attendance.dto.AttendanceReq -import com.example.cmc_be.attendance.dto.AttendanceRes +import com.example.cmc_be.attendance.dto.req.GenerateCode +import com.example.cmc_be.attendance.dto.res.AttendanceCodeRes import com.example.cmc_be.common.exeption.BadRequestException import com.example.cmc_be.common.exeption.NotFoundException +import com.example.cmc_be.common.utils.RandomNumberUtil import com.example.cmc_be.domain.attendance.entity.AttendanceCode import com.example.cmc_be.domain.attendance.enums.AttendanceHour import com.example.cmc_be.domain.attendance.exception.AttendanceErrorCode import com.example.cmc_be.domain.attendance.repository.AttendanceCodeRepository +import com.example.cmc_be.domain.attendance.repository.AttendanceRepository import com.example.cmc_be.domain.generation.entity.GenerationWeeksInfo import com.example.cmc_be.domain.user.entity.User import org.springframework.data.repository.findByIdOrNull import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service -import kotlin.random.Random @Service class QrCodeService( private val attendanceCodeRepository: AttendanceCodeRepository, - private val attendanceCodeValidator: AttendanceCodeValidator, - private val attendanceCodeConverter: AttendanceConverter + private val attendanceRepository: AttendanceRepository, + private val randomNumberUtil: RandomNumberUtil ) { fun generateCode( - generationReq: AttendanceReq.GenerateCode, + generationReq: GenerateCode, generationWeeksInfo: GenerationWeeksInfo ): String { return generateUniqueRandomCode().also { randomCode -> @@ -46,49 +46,57 @@ class QrCodeService( private fun generateUniqueRandomCode(): String { var randomCode: String do { - randomCode = generateRandomCode() + randomCode = randomNumberUtil.createNumbers(6) } while (attendanceCodeRepository.findByIdOrNull(randomCode) != null) return randomCode } - private fun generateRandomCode(): String { - return (1..CODE_LENGTH) - .map { CODE_CHARACTERS[RANDOM_INSTANT.nextInt(0, CODE_CHARACTERS.length)] } - .joinToString("") - } - fun getCode(code: String): AttendanceCode { return attendanceCodeRepository.findByIdOrNull(code) ?: throw NotFoundException(AttendanceErrorCode.NOT_EXIST_ATTENDANCE_CODE) } @Scheduled(cron = "0 0 2 * * *") - fun deleteObjectsOutsideTimeRange() { + fun deleteAttemdanceCodesOutOfTime() { val attendanceCodes = attendanceCodeRepository.findAll() val invalideAttendanceCodes = attendanceCodes.filter { attendanceCode -> attendanceCode.validate() != null } attendanceCodeRepository.deleteAll(invalideAttendanceCodes) } - fun getCodeInfo(code: String): AttendanceRes.AttendanceCodeDto = - attendanceCodeConverter.getCodeInfo( - attendanceCodeRepository.findByIdOrNull(code) ?: throw BadRequestException( - AttendanceErrorCode.INVALID_CODE - ) + fun getAllCodes(): List { + return attendanceCodeRepository.findAll() + } + + fun getCodeInfo(code: String): AttendanceCodeRes { + val codeInfo = attendanceCodeRepository.findByIdOrNull(code) ?: throw BadRequestException( + AttendanceErrorCode.INVALID_CODE + ) + return AttendanceCodeRes( + availableDate = codeInfo.generationWeeksInfo.date, + startTime = codeInfo.startTime, + endTime = codeInfo.endTime, + lateMinute = codeInfo.lateMinute ) + } + fun validateCode(user: User, attendanceCode: AttendanceCode) { - with(attendanceCodeValidator) { - validateGeneration(user, attendanceCode.generation) - validateAlreadyAttendance(user.id, attendanceCode) - } - val validateCodeException = attendanceCode.validate() - if (validateCodeException != null) throw validateCodeException + validateGeneration(user, attendanceCode.generation) + validateAlreadyAttendance(user.id, attendanceCode) + attendanceCode.validate()?.let { throw it } } + private fun validateAlreadyAttendance(userId: Long, attendanceCode: AttendanceCode) { + if (attendanceRepository.findAllByUserId(userId) + .any { it.generationWeeksInfo.week == attendanceCode.week && it.attendanceHour == attendanceCode.hour } + ) { + throw BadRequestException(AttendanceErrorCode.ALREADY_ATEENDANCE) + } + } - companion object { - private const val CODE_CHARACTERS = "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - private const val CODE_LENGTH = 7 - private val RANDOM_INSTANT = Random.Default + private fun validateGeneration(user: User, generation: Int) { + if (user.nowGeneration != generation) { + throw BadRequestException(AttendanceErrorCode.CANNOT_ACCESS_ATEENDANCE) + } } } \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/common/utils/RandomNumberUtil.kt b/src/main/kotlin/com/example/cmc_be/common/utils/RandomNumberUtil.kt index 58f4ff2..b2d71bc 100644 --- a/src/main/kotlin/com/example/cmc_be/common/utils/RandomNumberUtil.kt +++ b/src/main/kotlin/com/example/cmc_be/common/utils/RandomNumberUtil.kt @@ -1,17 +1,21 @@ package com.example.cmc_be.common.utils +import org.springframework.stereotype.Service import java.util.* -object RandomNumberUtil { +@Service +class RandomNumberUtil { + + private val rand = Random() + fun createNumbers( length: Int = 6 ): String { - val rand = Random() - var numStr: String = "" + val numStr = StringBuilder() for (i in 1..length) { val ran = rand.nextInt(10).toString() - numStr += ran + numStr.append(ran) } - return numStr + return numStr.toString() } } \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt b/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt index 4c60721..0a2a0cd 100644 --- a/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt +++ b/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt @@ -30,7 +30,8 @@ class AuthService( private val passwordEncoder: PasswordEncoder, private val mailService: MailService, private val codeAuthRepository: CodeAuthRepository, - private val refreshTokenRepository: RefreshTokenRepository + private val refreshTokenRepository: RefreshTokenRepository, + private val randomNumberUtil: RandomNumberUtil ) { @Transactional fun signUpUser(signUpUserDto: SignUpUserDto): UserTokenDto { @@ -87,7 +88,7 @@ class AuthService( Status.ACTIVE ) ) throw BadRequestException(UserAuthErrorCode.NOT_EXIST_USER); - val code = RandomNumberUtil.createNumbers() + val code = randomNumberUtil.createNumbers(length = 6) codeAuthRepository.save( CodeAuth( auth = email, From ddb4dbcf183807f36ea999d0e0cdcdd4e488de1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=ED=95=B4=EC=B0=AC=5BVertical=20Service=20Dev1=5D?= Date: Thu, 16 May 2024 14:18:21 +0900 Subject: [PATCH 07/10] =?UTF-8?q?style=20:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AdminAttendanceController.kt | 2 +- .../attendance/controller/AttendanceController.kt | 2 +- .../cmc_be/attendance/service/QrCodeService.kt | 2 +- .../common/{ => dto}/response/CommonResponse.kt | 2 +- .../common/{ => dto}/response/PageResponse.kt | 2 +- .../cmc_be/common/exeption/ExceptionAdvice.kt | 2 +- .../cmc_be/config/ConfigurationPropertiesConfig.kt | 2 +- .../com/example/cmc_be/config/SecurityConfig.kt | 10 +++++----- .../cmc_be/{common => config}/aop/LogAspect.kt | 7 +++---- .../{common => config}/properties/JwtProperties.kt | 2 +- .../security/JwtAccessDeniedHandler.kt | 2 +- .../security/JwtAuthenticationEntryPoint.kt | 2 +- .../cmc_be/{common => config}/security/JwtFilter.kt | 2 +- .../security/JwtSecurityConfig.kt | 2 +- .../{common => config}/security/JwtService.kt | 13 +++++++------ .../controller/AdminGenerationController.kt | 2 +- .../cmc_be/health/controller/HealthController.kt | 2 +- .../cmc_be/health/controller/TestController.kt | 4 ++-- .../controller/AdminNotificationController.kt | 2 +- .../controller/NotificationController.kt | 4 ++-- .../notification/service/NotificationService.kt | 2 +- .../cmc_be/user/controller/AuthController.kt | 2 +- .../cmc_be/user/controller/UserController.kt | 2 +- .../com/example/cmc_be/user/service/AuthService.kt | 4 ++-- .../cmc_be/{common => }/utils/RandomNumberUtil.kt | 2 +- 25 files changed, 40 insertions(+), 40 deletions(-) rename src/main/kotlin/com/example/cmc_be/common/{ => dto}/response/CommonResponse.kt (97%) rename src/main/kotlin/com/example/cmc_be/common/{ => dto}/response/PageResponse.kt (94%) rename src/main/kotlin/com/example/cmc_be/{common => config}/aop/LogAspect.kt (97%) rename src/main/kotlin/com/example/cmc_be/{common => config}/properties/JwtProperties.kt (89%) rename src/main/kotlin/com/example/cmc_be/{common => config}/security/JwtAccessDeniedHandler.kt (96%) rename src/main/kotlin/com/example/cmc_be/{common => config}/security/JwtAuthenticationEntryPoint.kt (98%) rename src/main/kotlin/com/example/cmc_be/{common => config}/security/JwtFilter.kt (97%) rename src/main/kotlin/com/example/cmc_be/{common => config}/security/JwtSecurityConfig.kt (93%) rename src/main/kotlin/com/example/cmc_be/{common => config}/security/JwtService.kt (94%) rename src/main/kotlin/com/example/cmc_be/{common => }/utils/RandomNumberUtil.kt (90%) diff --git a/src/main/kotlin/com/example/cmc_be/attendance/controller/AdminAttendanceController.kt b/src/main/kotlin/com/example/cmc_be/attendance/controller/AdminAttendanceController.kt index bdae59c..732fca5 100644 --- a/src/main/kotlin/com/example/cmc_be/attendance/controller/AdminAttendanceController.kt +++ b/src/main/kotlin/com/example/cmc_be/attendance/controller/AdminAttendanceController.kt @@ -5,8 +5,8 @@ import com.example.cmc_be.attendance.dto.res.AllAttendanceInfos import com.example.cmc_be.attendance.dto.res.AttendanceCodeRes import com.example.cmc_be.attendance.service.AttendanceService import com.example.cmc_be.attendance.service.QrCodeService +import com.example.cmc_be.common.dto.response.CommonResponse import com.example.cmc_be.common.exeption.BadRequestException -import com.example.cmc_be.common.response.CommonResponse import com.example.cmc_be.domain.attendance.entity.AttendanceCode import com.example.cmc_be.domain.attendance.exception.AttendanceErrorCode import com.example.cmc_be.domain.generation.repository.GenerationWeeksInfoRepository diff --git a/src/main/kotlin/com/example/cmc_be/attendance/controller/AttendanceController.kt b/src/main/kotlin/com/example/cmc_be/attendance/controller/AttendanceController.kt index 01fec69..91f2076 100644 --- a/src/main/kotlin/com/example/cmc_be/attendance/controller/AttendanceController.kt +++ b/src/main/kotlin/com/example/cmc_be/attendance/controller/AttendanceController.kt @@ -3,7 +3,7 @@ package com.example.cmc_be.attendance.controller import com.example.cmc_be.attendance.dto.req.AttendanceCodeReq import com.example.cmc_be.attendance.dto.res.AttendancesDashboard import com.example.cmc_be.attendance.service.AttendanceService -import com.example.cmc_be.common.response.CommonResponse +import com.example.cmc_be.common.dto.response.CommonResponse import com.example.cmc_be.domain.user.entity.User import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.tags.Tag diff --git a/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt b/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt index 589b56a..6c2e96e 100644 --- a/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt +++ b/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt @@ -4,7 +4,6 @@ import com.example.cmc_be.attendance.dto.req.GenerateCode import com.example.cmc_be.attendance.dto.res.AttendanceCodeRes import com.example.cmc_be.common.exeption.BadRequestException import com.example.cmc_be.common.exeption.NotFoundException -import com.example.cmc_be.common.utils.RandomNumberUtil import com.example.cmc_be.domain.attendance.entity.AttendanceCode import com.example.cmc_be.domain.attendance.enums.AttendanceHour import com.example.cmc_be.domain.attendance.exception.AttendanceErrorCode @@ -12,6 +11,7 @@ import com.example.cmc_be.domain.attendance.repository.AttendanceCodeRepository import com.example.cmc_be.domain.attendance.repository.AttendanceRepository import com.example.cmc_be.domain.generation.entity.GenerationWeeksInfo import com.example.cmc_be.domain.user.entity.User +import com.example.cmc_be.utils.RandomNumberUtil import org.springframework.data.repository.findByIdOrNull import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Service diff --git a/src/main/kotlin/com/example/cmc_be/common/response/CommonResponse.kt b/src/main/kotlin/com/example/cmc_be/common/dto/response/CommonResponse.kt similarity index 97% rename from src/main/kotlin/com/example/cmc_be/common/response/CommonResponse.kt rename to src/main/kotlin/com/example/cmc_be/common/dto/response/CommonResponse.kt index 04121ec..84b5ce0 100644 --- a/src/main/kotlin/com/example/cmc_be/common/response/CommonResponse.kt +++ b/src/main/kotlin/com/example/cmc_be/common/dto/response/CommonResponse.kt @@ -1,4 +1,4 @@ -package com.example.cmc_be.common.response +package com.example.cmc_be.common.dto.response import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty diff --git a/src/main/kotlin/com/example/cmc_be/common/response/PageResponse.kt b/src/main/kotlin/com/example/cmc_be/common/dto/response/PageResponse.kt similarity index 94% rename from src/main/kotlin/com/example/cmc_be/common/response/PageResponse.kt rename to src/main/kotlin/com/example/cmc_be/common/dto/response/PageResponse.kt index 4343066..4071e7c 100644 --- a/src/main/kotlin/com/example/cmc_be/common/response/PageResponse.kt +++ b/src/main/kotlin/com/example/cmc_be/common/dto/response/PageResponse.kt @@ -1,4 +1,4 @@ -package com.example.cmc_be.common.response +package com.example.cmc_be.common.dto.response import io.swagger.v3.oas.annotations.media.Schema import org.springframework.data.domain.Page diff --git a/src/main/kotlin/com/example/cmc_be/common/exeption/ExceptionAdvice.kt b/src/main/kotlin/com/example/cmc_be/common/exeption/ExceptionAdvice.kt index a0ca92b..25376f5 100644 --- a/src/main/kotlin/com/example/cmc_be/common/exeption/ExceptionAdvice.kt +++ b/src/main/kotlin/com/example/cmc_be/common/exeption/ExceptionAdvice.kt @@ -1,6 +1,6 @@ package com.example.cmc_be.common.exeption -import com.example.cmc_be.common.response.CommonResponse +import com.example.cmc_be.common.dto.response.CommonResponse import jakarta.servlet.http.HttpServletRequest import jakarta.validation.ConstraintViolation import jakarta.validation.ConstraintViolationException diff --git a/src/main/kotlin/com/example/cmc_be/config/ConfigurationPropertiesConfig.kt b/src/main/kotlin/com/example/cmc_be/config/ConfigurationPropertiesConfig.kt index 545cba1..5841853 100644 --- a/src/main/kotlin/com/example/cmc_be/config/ConfigurationPropertiesConfig.kt +++ b/src/main/kotlin/com/example/cmc_be/config/ConfigurationPropertiesConfig.kt @@ -1,6 +1,6 @@ package com.example.cmc_be.config; -import com.example.cmc_be.common.properties.JwtProperties +import com.example.cmc_be.config.properties.JwtProperties import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; diff --git a/src/main/kotlin/com/example/cmc_be/config/SecurityConfig.kt b/src/main/kotlin/com/example/cmc_be/config/SecurityConfig.kt index dbca3c9..7ed8af5 100644 --- a/src/main/kotlin/com/example/cmc_be/config/SecurityConfig.kt +++ b/src/main/kotlin/com/example/cmc_be/config/SecurityConfig.kt @@ -1,9 +1,9 @@ package com.example.cmc_be.config -import com.example.cmc_be.common.security.JwtAccessDeniedHandler -import com.example.cmc_be.common.security.JwtAuthenticationEntryPoint -import com.example.cmc_be.common.security.JwtSecurityConfig -import com.example.cmc_be.common.security.JwtService +import com.example.cmc_be.config.security.JwtAccessDeniedHandler +import com.example.cmc_be.config.security.JwtAuthenticationEntryPoint +import com.example.cmc_be.config.security.JwtSecurityConfig +import com.example.cmc_be.config.security.JwtService import org.slf4j.LoggerFactory import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @@ -15,7 +15,6 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.security.web.SecurityFilterChain import org.springframework.security.web.access.AccessDeniedHandler -import org.springframework.security.web.authentication.AuthenticationFailureHandler import org.springframework.security.web.util.matcher.RequestMatcher import org.springframework.web.cors.CorsUtils @@ -37,6 +36,7 @@ class SecurityConfig( fun customAuthenticationFailureHandler(): AccessDeniedHandler { return JwtAccessDeniedHandler() } + @Bean fun webSecurityCustomizer(): WebSecurityCustomizer { return WebSecurityCustomizer { web -> diff --git a/src/main/kotlin/com/example/cmc_be/common/aop/LogAspect.kt b/src/main/kotlin/com/example/cmc_be/config/aop/LogAspect.kt similarity index 97% rename from src/main/kotlin/com/example/cmc_be/common/aop/LogAspect.kt rename to src/main/kotlin/com/example/cmc_be/config/aop/LogAspect.kt index daa9c5f..9ff7503 100644 --- a/src/main/kotlin/com/example/cmc_be/common/aop/LogAspect.kt +++ b/src/main/kotlin/com/example/cmc_be/config/aop/LogAspect.kt @@ -1,4 +1,4 @@ -package com.example.cmc_be.common.aop +package com.example.cmc_be.config.aop import org.aspectj.lang.JoinPoint import org.aspectj.lang.annotation.* @@ -9,7 +9,7 @@ import java.lang.reflect.Method @Component @Aspect -class LogAspect{ +class LogAspect { @Pointcut("execution(* com.example.cmc_be..*Controller.*(..))") fun controller() { } @@ -53,7 +53,7 @@ class LogAspect{ val methodName = getMethodName(method) log.info("logging finish method = {}", methodName) log.info("==========================LOG_FINISH==========================") - } + } @AfterReturning(value = "controller()", returning = "returnObj") fun afterReturnLog(joinPoint: JoinPoint, returnObj: Any?) { @@ -79,5 +79,4 @@ class LogAspect{ } - } \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/common/properties/JwtProperties.kt b/src/main/kotlin/com/example/cmc_be/config/properties/JwtProperties.kt similarity index 89% rename from src/main/kotlin/com/example/cmc_be/common/properties/JwtProperties.kt rename to src/main/kotlin/com/example/cmc_be/config/properties/JwtProperties.kt index c0e9091..93b03e6 100644 --- a/src/main/kotlin/com/example/cmc_be/common/properties/JwtProperties.kt +++ b/src/main/kotlin/com/example/cmc_be/config/properties/JwtProperties.kt @@ -1,4 +1,4 @@ -package com.example.cmc_be.common.properties +package com.example.cmc_be.config.properties import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.stereotype.Component diff --git a/src/main/kotlin/com/example/cmc_be/common/security/JwtAccessDeniedHandler.kt b/src/main/kotlin/com/example/cmc_be/config/security/JwtAccessDeniedHandler.kt similarity index 96% rename from src/main/kotlin/com/example/cmc_be/common/security/JwtAccessDeniedHandler.kt rename to src/main/kotlin/com/example/cmc_be/config/security/JwtAccessDeniedHandler.kt index f6677c4..adc04ae 100644 --- a/src/main/kotlin/com/example/cmc_be/common/security/JwtAccessDeniedHandler.kt +++ b/src/main/kotlin/com/example/cmc_be/config/security/JwtAccessDeniedHandler.kt @@ -1,4 +1,4 @@ -package com.example.cmc_be.common.security +package com.example.cmc_be.config.security import com.example.cmc_be.domain.user.exeption.UserAuthErrorCode import jakarta.servlet.http.HttpServletRequest diff --git a/src/main/kotlin/com/example/cmc_be/common/security/JwtAuthenticationEntryPoint.kt b/src/main/kotlin/com/example/cmc_be/config/security/JwtAuthenticationEntryPoint.kt similarity index 98% rename from src/main/kotlin/com/example/cmc_be/common/security/JwtAuthenticationEntryPoint.kt rename to src/main/kotlin/com/example/cmc_be/config/security/JwtAuthenticationEntryPoint.kt index 9599d9c..2826d83 100644 --- a/src/main/kotlin/com/example/cmc_be/common/security/JwtAuthenticationEntryPoint.kt +++ b/src/main/kotlin/com/example/cmc_be/config/security/JwtAuthenticationEntryPoint.kt @@ -1,4 +1,4 @@ -package com.example.cmc_be.common.security +package com.example.cmc_be.config.security import com.example.cmc_be.domain.user.exeption.UserAuthErrorCode import jakarta.servlet.http.HttpServletRequest diff --git a/src/main/kotlin/com/example/cmc_be/common/security/JwtFilter.kt b/src/main/kotlin/com/example/cmc_be/config/security/JwtFilter.kt similarity index 97% rename from src/main/kotlin/com/example/cmc_be/common/security/JwtFilter.kt rename to src/main/kotlin/com/example/cmc_be/config/security/JwtFilter.kt index f8cf3b4..e9d0db4 100644 --- a/src/main/kotlin/com/example/cmc_be/common/security/JwtFilter.kt +++ b/src/main/kotlin/com/example/cmc_be/config/security/JwtFilter.kt @@ -1,4 +1,4 @@ -package com.example.cmc_be.common.security +package com.example.cmc_be.config.security import jakarta.servlet.FilterChain import jakarta.servlet.ServletRequest diff --git a/src/main/kotlin/com/example/cmc_be/common/security/JwtSecurityConfig.kt b/src/main/kotlin/com/example/cmc_be/config/security/JwtSecurityConfig.kt similarity index 93% rename from src/main/kotlin/com/example/cmc_be/common/security/JwtSecurityConfig.kt rename to src/main/kotlin/com/example/cmc_be/config/security/JwtSecurityConfig.kt index 7bbe79d..5ae934c 100644 --- a/src/main/kotlin/com/example/cmc_be/common/security/JwtSecurityConfig.kt +++ b/src/main/kotlin/com/example/cmc_be/config/security/JwtSecurityConfig.kt @@ -1,4 +1,4 @@ -package com.example.cmc_be.common.security +package com.example.cmc_be.config.security import org.springframework.security.config.annotation.SecurityConfigurerAdapter import org.springframework.security.config.annotation.web.builders.HttpSecurity diff --git a/src/main/kotlin/com/example/cmc_be/common/security/JwtService.kt b/src/main/kotlin/com/example/cmc_be/config/security/JwtService.kt similarity index 94% rename from src/main/kotlin/com/example/cmc_be/common/security/JwtService.kt rename to src/main/kotlin/com/example/cmc_be/config/security/JwtService.kt index f99df7e..a07829d 100644 --- a/src/main/kotlin/com/example/cmc_be/common/security/JwtService.kt +++ b/src/main/kotlin/com/example/cmc_be/config/security/JwtService.kt @@ -1,8 +1,8 @@ -package com.example.cmc_be.common.security +package com.example.cmc_be.config.security import com.example.cmc_be.common.exeption.NotApproveUserException import com.example.cmc_be.common.exeption.UnauthorizedException -import com.example.cmc_be.common.properties.JwtProperties +import com.example.cmc_be.config.properties.JwtProperties import com.example.cmc_be.domain.redis.entity.RefreshToken import com.example.cmc_be.domain.redis.repository.RefreshTokenRepository import com.example.cmc_be.domain.user.enums.SignUpApprove @@ -58,7 +58,7 @@ class JwtService( } catch (e: NoSuchElementException) { log.info("유저가 존재하지 않습니다.") servletRequest.setAttribute("exception", "NoSuchElementException") - } catch (e: NotApproveUserException) { + } catch (e: NotApproveUserException) { // NotApproveUserException을 잡아서 처리 log.info("Not approved user: ${e.message}") servletRequest.setAttribute("exception", "NotApproveUserException") @@ -102,16 +102,16 @@ class JwtService( .setSigningKey(getRefreshKey()) .parseClaimsJws(refreshToken) return claims.body.get("userId", Integer::class.java).toLong() - }catch (e: MalformedJwtException) { + } catch (e: MalformedJwtException) { throw UnauthorizedException(UserAuthErrorCode.INVALID_TOKEN_EXCEPTION) } } fun createRefreshToken(userId: Long): String { - val ttl : Duration = Duration.ofDays(jwtProperties.refreshTokenSeconds) + val ttl: Duration = Duration.ofDays(jwtProperties.refreshTokenSeconds) - val refreshToken : String = createJwtToken( + val refreshToken: String = createJwtToken( userId, Duration.ofDays(jwtProperties.refreshTokenSeconds), getRefreshKey(), @@ -122,6 +122,7 @@ class JwtService( return refreshToken } + fun createJwtToken(userId: Long?, duration: Duration, key: Key, typeHeader: String): String { val issuedAt = Instant.now() val expiration = issuedAt.plus(duration) diff --git a/src/main/kotlin/com/example/cmc_be/generation/controller/AdminGenerationController.kt b/src/main/kotlin/com/example/cmc_be/generation/controller/AdminGenerationController.kt index c2684a3..a695832 100644 --- a/src/main/kotlin/com/example/cmc_be/generation/controller/AdminGenerationController.kt +++ b/src/main/kotlin/com/example/cmc_be/generation/controller/AdminGenerationController.kt @@ -1,6 +1,6 @@ package com.example.cmc_be.generation.controller -import com.example.cmc_be.common.response.CommonResponse +import com.example.cmc_be.common.dto.response.CommonResponse import com.example.cmc_be.domain.generation.entity.GenerationWeeksInfo import com.example.cmc_be.generation.dto.PostGenerationInfoReq import com.example.cmc_be.generation.service.GenerationService diff --git a/src/main/kotlin/com/example/cmc_be/health/controller/HealthController.kt b/src/main/kotlin/com/example/cmc_be/health/controller/HealthController.kt index bf468af..7774bcb 100644 --- a/src/main/kotlin/com/example/cmc_be/health/controller/HealthController.kt +++ b/src/main/kotlin/com/example/cmc_be/health/controller/HealthController.kt @@ -1,7 +1,7 @@ package com.example.cmc_be.health.controller import ApiErrorCodeExample -import com.example.cmc_be.common.response.CommonResponse +import com.example.cmc_be.common.dto.response.CommonResponse import com.example.cmc_be.domain.user.exeption.UserAuthErrorCode import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.tags.Tag diff --git a/src/main/kotlin/com/example/cmc_be/health/controller/TestController.kt b/src/main/kotlin/com/example/cmc_be/health/controller/TestController.kt index 5589158..837dcd9 100644 --- a/src/main/kotlin/com/example/cmc_be/health/controller/TestController.kt +++ b/src/main/kotlin/com/example/cmc_be/health/controller/TestController.kt @@ -1,10 +1,10 @@ package com.example.cmc_be.health.controller import ApiErrorCodeExample +import com.example.cmc_be.common.dto.response.CommonResponse import com.example.cmc_be.common.exeption.BadRequestException import com.example.cmc_be.common.exeption.errorcode.TestErrorCode -import com.example.cmc_be.common.response.CommonResponse -import com.example.cmc_be.common.security.JwtService +import com.example.cmc_be.config.security.JwtService import com.example.cmc_be.domain.user.entity.User import com.example.cmc_be.domain.user.exeption.UserAuthErrorCode import io.swagger.v3.oas.annotations.tags.Tag diff --git a/src/main/kotlin/com/example/cmc_be/notification/controller/AdminNotificationController.kt b/src/main/kotlin/com/example/cmc_be/notification/controller/AdminNotificationController.kt index 236a101..5bce702 100644 --- a/src/main/kotlin/com/example/cmc_be/notification/controller/AdminNotificationController.kt +++ b/src/main/kotlin/com/example/cmc_be/notification/controller/AdminNotificationController.kt @@ -1,6 +1,6 @@ package com.example.cmc_be.notification.controller -import com.example.cmc_be.common.response.CommonResponse +import com.example.cmc_be.common.dto.response.CommonResponse import com.example.cmc_be.domain.notification.entity.Notification import com.example.cmc_be.domain.user.entity.User import com.example.cmc_be.notification.dto.NotificationReq diff --git a/src/main/kotlin/com/example/cmc_be/notification/controller/NotificationController.kt b/src/main/kotlin/com/example/cmc_be/notification/controller/NotificationController.kt index 64e1ab6..8689352 100644 --- a/src/main/kotlin/com/example/cmc_be/notification/controller/NotificationController.kt +++ b/src/main/kotlin/com/example/cmc_be/notification/controller/NotificationController.kt @@ -1,7 +1,7 @@ package com.example.cmc_be.notification.controller -import com.example.cmc_be.common.response.CommonResponse -import com.example.cmc_be.common.response.PageResponse +import com.example.cmc_be.common.dto.response.CommonResponse +import com.example.cmc_be.common.dto.response.PageResponse import com.example.cmc_be.domain.user.entity.User import com.example.cmc_be.notification.dto.NotificationRes import com.example.cmc_be.notification.service.NotificationService diff --git a/src/main/kotlin/com/example/cmc_be/notification/service/NotificationService.kt b/src/main/kotlin/com/example/cmc_be/notification/service/NotificationService.kt index f636fd5..dadf526 100644 --- a/src/main/kotlin/com/example/cmc_be/notification/service/NotificationService.kt +++ b/src/main/kotlin/com/example/cmc_be/notification/service/NotificationService.kt @@ -1,7 +1,7 @@ package com.example.cmc_be.notification.service +import com.example.cmc_be.common.dto.response.PageResponse import com.example.cmc_be.common.exeption.NotFoundException -import com.example.cmc_be.common.response.PageResponse import com.example.cmc_be.domain.generation.repository.GenerationWeeksInfoRepository import com.example.cmc_be.domain.notification.entity.Notification import com.example.cmc_be.domain.notification.exception.NotificationExceptionErrorCode diff --git a/src/main/kotlin/com/example/cmc_be/user/controller/AuthController.kt b/src/main/kotlin/com/example/cmc_be/user/controller/AuthController.kt index b5347b5..2254fd4 100644 --- a/src/main/kotlin/com/example/cmc_be/user/controller/AuthController.kt +++ b/src/main/kotlin/com/example/cmc_be/user/controller/AuthController.kt @@ -1,7 +1,7 @@ package com.example.cmc_be.user.controller import ApiErrorCodeExample -import com.example.cmc_be.common.response.CommonResponse +import com.example.cmc_be.common.dto.response.CommonResponse import com.example.cmc_be.domain.user.exeption.CheckAuthErrorCode import com.example.cmc_be.domain.user.exeption.LoginUserErrorCode import com.example.cmc_be.domain.user.exeption.RefreshTokenErrorCode diff --git a/src/main/kotlin/com/example/cmc_be/user/controller/UserController.kt b/src/main/kotlin/com/example/cmc_be/user/controller/UserController.kt index 6c77eee..adf60d8 100644 --- a/src/main/kotlin/com/example/cmc_be/user/controller/UserController.kt +++ b/src/main/kotlin/com/example/cmc_be/user/controller/UserController.kt @@ -1,7 +1,7 @@ package com.example.cmc_be.user.controller import ApiErrorCodeExample -import com.example.cmc_be.common.response.CommonResponse +import com.example.cmc_be.common.dto.response.CommonResponse import com.example.cmc_be.domain.user.entity.User import com.example.cmc_be.domain.user.exeption.UserAuthErrorCode import com.example.cmc_be.user.dto.user.UserInfoDto diff --git a/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt b/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt index 0a2a0cd..2800564 100644 --- a/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt +++ b/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt @@ -3,8 +3,7 @@ package com.example.cmc_be.user.service import com.example.cmc_be.common.dto.Status import com.example.cmc_be.common.exeption.BadRequestException import com.example.cmc_be.common.exeption.NotFoundException -import com.example.cmc_be.common.security.JwtService -import com.example.cmc_be.common.utils.RandomNumberUtil +import com.example.cmc_be.config.security.JwtService import com.example.cmc_be.domain.redis.entity.CodeAuth import com.example.cmc_be.domain.redis.entity.RefreshToken import com.example.cmc_be.domain.redis.repository.CodeAuthRepository @@ -17,6 +16,7 @@ import com.example.cmc_be.domain.user.repository.UserPartRepository import com.example.cmc_be.domain.user.repository.UserRepository import com.example.cmc_be.external.MailService import com.example.cmc_be.user.dto.auth.* +import com.example.cmc_be.utils.RandomNumberUtil import jakarta.transaction.Transactional import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.stereotype.Service diff --git a/src/main/kotlin/com/example/cmc_be/common/utils/RandomNumberUtil.kt b/src/main/kotlin/com/example/cmc_be/utils/RandomNumberUtil.kt similarity index 90% rename from src/main/kotlin/com/example/cmc_be/common/utils/RandomNumberUtil.kt rename to src/main/kotlin/com/example/cmc_be/utils/RandomNumberUtil.kt index b2d71bc..743b7ee 100644 --- a/src/main/kotlin/com/example/cmc_be/common/utils/RandomNumberUtil.kt +++ b/src/main/kotlin/com/example/cmc_be/utils/RandomNumberUtil.kt @@ -1,4 +1,4 @@ -package com.example.cmc_be.common.utils +package com.example.cmc_be.utils import org.springframework.stereotype.Service import java.util.* From dfb7bee97edadb268355c6c3db4c5e36e32ca7f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=ED=95=B4=EC=B0=AC=5BVertical=20Service=20Dev1=5D?= Date: Thu, 16 May 2024 14:22:25 +0900 Subject: [PATCH 08/10] =?UTF-8?q?fix=20:=20QRCode=206=EC=9E=90=EB=A6=AC=20?= =?UTF-8?q?=EC=88=AB=EC=9E=90=EB=A1=9C=EB=A7=8C=20=EC=9D=B4=EB=A3=A8?= =?UTF-8?q?=EC=96=B4=EC=A7=80=EB=8F=84=EB=A1=9D=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/cmc_be/attendance/service/QrCodeService.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt b/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt index 6c2e96e..9f118b8 100644 --- a/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt +++ b/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt @@ -27,7 +27,7 @@ class QrCodeService( generationReq: GenerateCode, generationWeeksInfo: GenerationWeeksInfo ): String { - return generateUniqueRandomCode().also { randomCode -> + return generateUniqueRandomCode().let { randomCode -> attendanceCodeRepository.save( AttendanceCode( id = randomCode, @@ -40,6 +40,7 @@ class QrCodeService( lateMinute = generationReq.lateMinute ) ) + randomCode } } @@ -57,10 +58,10 @@ class QrCodeService( } @Scheduled(cron = "0 0 2 * * *") - fun deleteAttemdanceCodesOutOfTime() { + fun deleteAttendanceCodesOutOfTime() { val attendanceCodes = attendanceCodeRepository.findAll() - val invalideAttendanceCodes = attendanceCodes.filter { attendanceCode -> attendanceCode.validate() != null } - attendanceCodeRepository.deleteAll(invalideAttendanceCodes) + val invalidAttendanceCodes = attendanceCodes.filter { attendanceCode -> attendanceCode.validate() != null } + attendanceCodeRepository.deleteAll(invalidAttendanceCodes) } fun getAllCodes(): List { @@ -79,7 +80,6 @@ class QrCodeService( ) } - fun validateCode(user: User, attendanceCode: AttendanceCode) { validateGeneration(user, attendanceCode.generation) validateAlreadyAttendance(user.id, attendanceCode) From f67f7c718111fa728b7ff50cdefe4435d5359260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=ED=95=B4=EC=B0=AC=5BVertical=20Service=20Dev1=5D?= Date: Thu, 16 May 2024 14:31:08 +0900 Subject: [PATCH 09/10] =?UTF-8?q?feat=20:=20QRCode=20=EC=8A=A4=ED=82=A4?= =?UTF-8?q?=EB=A7=88=20=EC=83=9D=EC=84=B1=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AdminAttendanceController.kt | 3 ++- .../cmc_be/attendance/dto/res/QrSchemata.kt | 9 +++++++++ .../attendance/service/QrCodeService.kt | 20 ++++++++++++++++--- 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 src/main/kotlin/com/example/cmc_be/attendance/dto/res/QrSchemata.kt diff --git a/src/main/kotlin/com/example/cmc_be/attendance/controller/AdminAttendanceController.kt b/src/main/kotlin/com/example/cmc_be/attendance/controller/AdminAttendanceController.kt index 732fca5..9b262fd 100644 --- a/src/main/kotlin/com/example/cmc_be/attendance/controller/AdminAttendanceController.kt +++ b/src/main/kotlin/com/example/cmc_be/attendance/controller/AdminAttendanceController.kt @@ -3,6 +3,7 @@ package com.example.cmc_be.attendance.controller import com.example.cmc_be.attendance.dto.req.GenerateCode import com.example.cmc_be.attendance.dto.res.AllAttendanceInfos import com.example.cmc_be.attendance.dto.res.AttendanceCodeRes +import com.example.cmc_be.attendance.dto.res.QrSchemata import com.example.cmc_be.attendance.service.AttendanceService import com.example.cmc_be.attendance.service.QrCodeService import com.example.cmc_be.common.dto.response.CommonResponse @@ -30,7 +31,7 @@ class AdminAttendanceController( fun generateCode( @AuthenticationPrincipal user: User, @RequestBody gernerateCode: GenerateCode - ): CommonResponse { + ): CommonResponse { val generationWeeksInfo = generationWeeksInfoRepository.findFirstByGenerationAndWeek( generation = gernerateCode.generation, week = gernerateCode.week ) ?: throw BadRequestException(AttendanceErrorCode.CANNOT_ACCESS_ATEENDANCE) diff --git a/src/main/kotlin/com/example/cmc_be/attendance/dto/res/QrSchemata.kt b/src/main/kotlin/com/example/cmc_be/attendance/dto/res/QrSchemata.kt new file mode 100644 index 0000000..e2da2c9 --- /dev/null +++ b/src/main/kotlin/com/example/cmc_be/attendance/dto/res/QrSchemata.kt @@ -0,0 +1,9 @@ +package com.example.cmc_be.attendance.dto.res + +import com.example.cmc_be.domain.attendance.entity.AttendanceCode + +data class QrSchemata( + val androidSchema: String, + val iosSchema: String, + val attendanceCode: AttendanceCode, +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt b/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt index 9f118b8..1035bb6 100644 --- a/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt +++ b/src/main/kotlin/com/example/cmc_be/attendance/service/QrCodeService.kt @@ -2,6 +2,7 @@ package com.example.cmc_be.attendance.service import com.example.cmc_be.attendance.dto.req.GenerateCode import com.example.cmc_be.attendance.dto.res.AttendanceCodeRes +import com.example.cmc_be.attendance.dto.res.QrSchemata import com.example.cmc_be.common.exeption.BadRequestException import com.example.cmc_be.common.exeption.NotFoundException import com.example.cmc_be.domain.attendance.entity.AttendanceCode @@ -26,9 +27,9 @@ class QrCodeService( fun generateCode( generationReq: GenerateCode, generationWeeksInfo: GenerationWeeksInfo - ): String { + ): QrSchemata { return generateUniqueRandomCode().let { randomCode -> - attendanceCodeRepository.save( + val attendanceCode = attendanceCodeRepository.save( AttendanceCode( id = randomCode, generation = generationReq.generation, @@ -40,7 +41,11 @@ class QrCodeService( lateMinute = generationReq.lateMinute ) ) - randomCode + QrSchemata( + androidSchema = generateAndroidSchmea(randomCode), + iosSchema = generateIOSSchmea(randomCode), + attendanceCode = attendanceCode + ) } } @@ -99,4 +104,13 @@ class QrCodeService( throw BadRequestException(AttendanceErrorCode.CANNOT_ACCESS_ATEENDANCE) } } + + private fun generateIOSSchmea(code: String): String { + return "cmcqrcodechecker://path?code=$code" + } + + private fun generateAndroidSchmea(code: String): String { + return "com.cmc.android://attendance&code=$code" + } + } \ No newline at end of file From e8b9c015df03920642385f2cf6b71a27cf056847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=ED=95=B4=EC=B0=AC=5BVertical=20Service=20Dev1=5D?= Date: Thu, 16 May 2024 15:51:00 +0900 Subject: [PATCH 10/10] =?UTF-8?q?fix=20:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EB=AF=B8=ED=97=88=EA=B0=80=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=B0=A8=EB=8B=A8=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/cmc_be/common/dto/BaseEntity.kt | 6 ++---- .../cmc_be/common/exeption/NotApproveUserException.kt | 9 ++++++++- .../com/example/cmc_be/config/security/JwtService.kt | 11 +++++++---- .../cmc_be/domain/user/exeption/LoginUserErrorCode.kt | 3 ++- .../com/example/cmc_be/user/service/AuthService.kt | 6 +++++- 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/com/example/cmc_be/common/dto/BaseEntity.kt b/src/main/kotlin/com/example/cmc_be/common/dto/BaseEntity.kt index e6d70fa..0b4e9d4 100644 --- a/src/main/kotlin/com/example/cmc_be/common/dto/BaseEntity.kt +++ b/src/main/kotlin/com/example/cmc_be/common/dto/BaseEntity.kt @@ -1,7 +1,6 @@ package com.example.cmc_be.common.dto import jakarta.persistence.* -import org.hibernate.annotations.ColumnDefault import org.springframework.data.annotation.CreatedDate import org.springframework.data.annotation.LastModifiedDate import org.springframework.data.jpa.domain.support.AuditingEntityListener @@ -20,10 +19,9 @@ abstract class BaseEntity( var updatedAt: LocalDateTime? = null, @Enumerated(EnumType.STRING) - @ColumnDefault(value = "ACTIVE") - var status : Status = Status.ACTIVE + var status: Status = Status.ACTIVE ) { - fun updateStatus(status : Status) { + fun updateStatus(status: Status) { this.status = status } } \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/common/exeption/NotApproveUserException.kt b/src/main/kotlin/com/example/cmc_be/common/exeption/NotApproveUserException.kt index a1eb3ef..6602c78 100644 --- a/src/main/kotlin/com/example/cmc_be/common/exeption/NotApproveUserException.kt +++ b/src/main/kotlin/com/example/cmc_be/common/exeption/NotApproveUserException.kt @@ -1,3 +1,10 @@ package com.example.cmc_be.common.exeption -class NotApproveUserException(message: String) : RuntimeException(message) +import com.example.cmc_be.common.exeption.errorcode.BaseErrorCode + +class NotApproveUserException(errorCode: BaseErrorCode) : BaseException( + errorCode.errorReason.httpStatus, + false, + errorCode.errorReason.code, + errorCode.errorReason.message +) \ No newline at end of file diff --git a/src/main/kotlin/com/example/cmc_be/config/security/JwtService.kt b/src/main/kotlin/com/example/cmc_be/config/security/JwtService.kt index a07829d..7e53a73 100644 --- a/src/main/kotlin/com/example/cmc_be/config/security/JwtService.kt +++ b/src/main/kotlin/com/example/cmc_be/config/security/JwtService.kt @@ -6,6 +6,7 @@ import com.example.cmc_be.config.properties.JwtProperties import com.example.cmc_be.domain.redis.entity.RefreshToken import com.example.cmc_be.domain.redis.repository.RefreshTokenRepository import com.example.cmc_be.domain.user.enums.SignUpApprove +import com.example.cmc_be.domain.user.exeption.LoginUserErrorCode import com.example.cmc_be.domain.user.exeption.UserAuthErrorCode import com.example.cmc_be.domain.user.repository.UserRepository import io.jsonwebtoken.ExpiredJwtException @@ -17,6 +18,7 @@ import io.jsonwebtoken.security.SecurityException import jakarta.servlet.ServletRequest import org.slf4j.LoggerFactory import org.springframework.context.annotation.Bean +import org.springframework.data.repository.findByIdOrNull import org.springframework.security.authentication.UsernamePasswordAuthenticationToken import org.springframework.security.core.Authentication import org.springframework.stereotype.Service @@ -50,11 +52,12 @@ class JwtService( try { val claims = Jwts.parserBuilder().setSigningKey(getSecretKey()).build().parseClaimsJws(token) val userId = claims.body.get("userId", Integer::class.java).toLong() - val users = userRepository.findById(userId) - if (users.get().signUpApprove.equals(SignUpApprove.NOT)) { - throw NotApproveUserException("Not approved user.") + val users = + userRepository.findByIdOrNull(userId) ?: throw UnauthorizedException(UserAuthErrorCode.NOT_EXIST_USER) + if (users.signUpApprove == SignUpApprove.NOT) { + throw NotApproveUserException(LoginUserErrorCode.NOT_APPROVE_USER) } - return UsernamePasswordAuthenticationToken(users.get(), "", users.get().authorities) + return UsernamePasswordAuthenticationToken(users, "", users.authorities) } catch (e: NoSuchElementException) { log.info("유저가 존재하지 않습니다.") servletRequest.setAttribute("exception", "NoSuchElementException") diff --git a/src/main/kotlin/com/example/cmc_be/domain/user/exeption/LoginUserErrorCode.kt b/src/main/kotlin/com/example/cmc_be/domain/user/exeption/LoginUserErrorCode.kt index 76bd843..00673e2 100644 --- a/src/main/kotlin/com/example/cmc_be/domain/user/exeption/LoginUserErrorCode.kt +++ b/src/main/kotlin/com/example/cmc_be/domain/user/exeption/LoginUserErrorCode.kt @@ -12,7 +12,8 @@ enum class LoginUserErrorCode( val message: String ) : BaseErrorCode { - NOT_CORRECT_PASSWORD(HttpStatus.BAD_REQUEST, "USER003", "비밀번호가 일치하지 않습니다."); + NOT_CORRECT_PASSWORD(HttpStatus.BAD_REQUEST, "USER003", "비밀번호가 일치하지 않습니다."), + NOT_APPROVE_USER(HttpStatus.BAD_REQUEST, "USER004", "회원가입 승인되지 않은 유저입니다."); override val errorReason: ErrorReason get() = ErrorReason( diff --git a/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt b/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt index 2800564..1ef367b 100644 --- a/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt +++ b/src/main/kotlin/com/example/cmc_be/user/service/AuthService.kt @@ -2,6 +2,7 @@ package com.example.cmc_be.user.service import com.example.cmc_be.common.dto.Status import com.example.cmc_be.common.exeption.BadRequestException +import com.example.cmc_be.common.exeption.NotApproveUserException import com.example.cmc_be.common.exeption.NotFoundException import com.example.cmc_be.config.security.JwtService import com.example.cmc_be.domain.redis.entity.CodeAuth @@ -11,6 +12,7 @@ import com.example.cmc_be.domain.redis.repository.RefreshTokenRepository import com.example.cmc_be.domain.user.adaptor.UserAdapter import com.example.cmc_be.domain.user.entity.User import com.example.cmc_be.domain.user.entity.UserPart +import com.example.cmc_be.domain.user.enums.SignUpApprove import com.example.cmc_be.domain.user.exeption.* import com.example.cmc_be.domain.user.repository.UserPartRepository import com.example.cmc_be.domain.user.repository.UserRepository @@ -63,7 +65,9 @@ class AuthService( fun logInUser(loginUserDto: LoginUserDto): UserTokenDto { val user = userAdapter.findByUsername(loginUserDto.email) - + if (user.signUpApprove.equals(SignUpApprove.NOT)) { + throw NotApproveUserException(LoginUserErrorCode.NOT_APPROVE_USER) + } if (!passwordEncoder.matches( loginUserDto.password, user.password