From f7e1f7b92fad775a104d58ebf6882b196910bfdb Mon Sep 17 00:00:00 2001 From: ParkYunHo Date: Tue, 18 Jul 2023 23:14:40 +0900 Subject: [PATCH] =?UTF-8?q?:sparkles:feature=20:=20=EB=A1=9C=EB=98=90?= =?UTF-8?q?=ED=8C=90=EB=A7=A4=EC=A0=90=20=EC=A1=B0=ED=9A=8C=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../store/adapter/in/web/StoreHandler.kt | 50 ++++++++++ .../lotto/store/adapter/in/web/StoreRouter.kt | 98 +++++++++++++++++++ .../lotto/store/application/StoreService.kt | 76 ++++++++++++++ .../application/dto/LottoStoreTotalInfo.kt | 38 +++++++ .../port/in/FindLocationUseCase.kt | 20 ++++ .../application/port/in/FindStoreUseCase.kt | 22 +++++ .../common/tasklet/NoticeResultTasklet.kt | 2 + .../lotto/common/utils/NoticeMessageUtils.kt | 12 ++- .../tasklet/LottoDrwtStoreTasklet.kt | 24 +++-- .../lotto/job/number/LottoNumberBatchJob.kt | 3 + .../job/number/tasklet/LottoNumberTasklet.kt | 27 +++-- .../job/store/tasklet/LottoStoreTasklet.kt | 6 +- .../lotto/drwtstore/DrwtStoreRepository.kt | 39 ++++++++ .../com/john/lotto/number/NumberRepository.kt | 2 +- .../john/lotto/store/StoreRepositoryImpl.kt | 62 ++++++++++++ .../com/john/lotto/store/dto/LocationDto.kt | 15 +++ 16 files changed, 471 insertions(+), 25 deletions(-) create mode 100644 api/src/main/kotlin/com/john/lotto/store/adapter/in/web/StoreHandler.kt create mode 100644 api/src/main/kotlin/com/john/lotto/store/adapter/in/web/StoreRouter.kt create mode 100644 api/src/main/kotlin/com/john/lotto/store/application/StoreService.kt create mode 100644 api/src/main/kotlin/com/john/lotto/store/application/dto/LottoStoreTotalInfo.kt create mode 100644 api/src/main/kotlin/com/john/lotto/store/application/port/in/FindLocationUseCase.kt create mode 100644 api/src/main/kotlin/com/john/lotto/store/application/port/in/FindStoreUseCase.kt create mode 100644 core/src/main/kotlin/com/john/lotto/store/dto/LocationDto.kt diff --git a/api/src/main/kotlin/com/john/lotto/store/adapter/in/web/StoreHandler.kt b/api/src/main/kotlin/com/john/lotto/store/adapter/in/web/StoreHandler.kt new file mode 100644 index 0000000..f79c557 --- /dev/null +++ b/api/src/main/kotlin/com/john/lotto/store/adapter/in/web/StoreHandler.kt @@ -0,0 +1,50 @@ +package com.john.lotto.store.adapter.`in`.web + +import com.john.lotto.common.dto.BaseResponse +import com.john.lotto.common.exception.BadRequestException +import com.john.lotto.store.application.port.`in`.FindLocationUseCase +import com.john.lotto.store.application.port.`in`.FindStoreUseCase +import org.springframework.stereotype.Component +import org.springframework.web.reactive.function.server.ServerRequest +import org.springframework.web.reactive.function.server.ServerResponse +import reactor.core.publisher.Mono + +/** + * @author yoonho + * @since 2023.07.18 + */ +@Component +class StoreHandler( + private val findStoreUseCase: FindStoreUseCase, + private val findLocationUseCase: FindLocationUseCase +) { + + /** + * 로또 판매점 조회 + * + * @param request [ServerRequest] + * @return [Mono]<[ServerResponse]> + * @author yoonho + * @since 2023.07.18 + */ + fun findStore(request: ServerRequest): Mono = + findStoreUseCase.findStore( + location = request.queryParam("location").orElseThrow { BadRequestException("필수 입력값 누락") }.toString(), + subLocation = request.queryParam("subLocation").orElseThrow { BadRequestException("필수 입력값 누락") }.toString() + ) + .collectList() + .flatMap { BaseResponse().success(it) } + + /** + * 판매점 위치정보 조회 + * + * @param request [ServerRequest] + * @return [Mono]<[ServerResponse]> + * @author yoonho + * @since 2023.07.18 + */ + fun findLocation(request: ServerRequest): Mono = + findLocationUseCase.findLocation() + .collectList() + .flatMap { BaseResponse().success(it) } +} diff --git a/api/src/main/kotlin/com/john/lotto/store/adapter/in/web/StoreRouter.kt b/api/src/main/kotlin/com/john/lotto/store/adapter/in/web/StoreRouter.kt new file mode 100644 index 0000000..e6db30d --- /dev/null +++ b/api/src/main/kotlin/com/john/lotto/store/adapter/in/web/StoreRouter.kt @@ -0,0 +1,98 @@ +package com.john.lotto.store.adapter.`in`.web + +import com.john.lotto.store.application.dto.LottoStoreTotalInfo +import com.john.lotto.store.dto.LocationDto +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.ExampleObject +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.security.SecurityRequirement +import org.springdoc.core.annotations.RouterOperation +import org.springdoc.core.annotations.RouterOperations +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.http.MediaType +import org.springframework.web.bind.annotation.RequestMethod +import org.springframework.web.reactive.function.server.RouterFunction +import org.springframework.web.reactive.function.server.ServerResponse +import org.springframework.web.reactive.function.server.router + +/** + * @author yoonho + * @since 2023.07.18 + */ +@Configuration +class StoreRouter( + private val storeHandler: StoreHandler +) { + + @Bean + @RouterOperations( + value = [ + RouterOperation( + path = "/api/location", + method = [RequestMethod.GET], + beanClass = StoreHandler::class, + beanMethod = "findLocation", + operation = Operation( + tags = ["로또판매점 조회"], + summary = "판매점 위치정보 조회", + operationId = "findLocation", + responses = [ + ApiResponse( + description = "위치정", + responseCode = "200", + content = [Content(schema = Schema(implementation = LocationDto::class))] + ) + ], + security = [SecurityRequirement(name = "OpenID Connection Authentication")] + ) + ), + RouterOperation( + path = "/api/store", + method = [RequestMethod.GET], + beanClass = StoreHandler::class, + beanMethod = "findStore", + operation = Operation( + tags = ["로또판매점 조회"], + summary = "로또판매점 리스트 조회", + operationId = "findStore", + parameters = [ + Parameter( + name = "location", + description = "조회할 판매점 위치(시)", + required = true, + examples = [ + ExampleObject(name = "서울", value = "서울", description = "조회할 판매점 위치(시)") + ] + ), + Parameter( + name = "subLocation", + description = "조회할 판매점 위치(구)", + required = true, + examples = [ + ExampleObject(name = "서초구", value = "서초구", description = "조회할 판매점 위치(구)") + ] + ) + ], + responses = [ + ApiResponse( + description = "로또판매점 리스트", + responseCode = "200", + content = [Content(schema = Schema(implementation = LottoStoreTotalInfo::class))] + ) + ], + security = [SecurityRequirement(name = "OpenID Connection Authentication")] + ) + ), + ] + ) + fun mapRouterFunction(): RouterFunction = router { + accept(MediaType.APPLICATION_JSON).nest { + GET("/api/location", storeHandler::findLocation) + GET("/api/store", storeHandler::findStore) + } + } +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/john/lotto/store/application/StoreService.kt b/api/src/main/kotlin/com/john/lotto/store/application/StoreService.kt new file mode 100644 index 0000000..b9f3aac --- /dev/null +++ b/api/src/main/kotlin/com/john/lotto/store/application/StoreService.kt @@ -0,0 +1,76 @@ +package com.john.lotto.store.application + +import com.john.lotto.drwtstore.DrwtStoreRepository +import com.john.lotto.store.StoreRepositoryImpl +import com.john.lotto.store.application.dto.LottoStoreTotalInfo +import com.john.lotto.store.application.port.`in`.FindLocationUseCase +import com.john.lotto.store.application.port.`in`.FindStoreUseCase +import com.john.lotto.store.dto.LocationDto +import com.john.lotto.store.dto.LottoStoreDto +import org.springframework.stereotype.Service +import reactor.core.publisher.Flux + +/** + * @author yoonho + * @since 2023.07.18 + */ +@Service +class StoreService( + private val storeRepositoryImpl: StoreRepositoryImpl, + private val drwtStoreRepository: DrwtStoreRepository +): FindStoreUseCase, FindLocationUseCase { + + /** + * 로또 판매점 조회 + * + * @param location [String] + * @param subLocation [String] + * @return [Flux]<[LottoStoreTotalInfo]> + * @author yoonho + * @since 2023.07.18 + */ + override fun findStore(location: String, subLocation: String): Flux { + val result = mutableListOf() + + val stores = storeRepositoryImpl.findLottoStore(location = location, subLocation = subLocation) + val drwtStores = drwtStoreRepository.findLottoDrwtStore(ids = stores.map { it.rtlrid!! }) + + for(store: LottoStoreDto in stores) { + result.add( + LottoStoreTotalInfo( + rtlrid = store.rtlrid, + + latitude = store.latitude, + longitude = store.longitude, + + bplclocplc1 = store.bplclocplc1, + bplclocplc2 = store.bplclocplc2, + bplclocplc3 = store.bplclocplc3, + bplclocplc4 = store.bplclocplc4, + + bplcdorodtladres = store.bplcdorodtladres, + bplclocplcdtladres = store.bplclocplcdtladres, + rtlrstrtelno = store.rtlrstrtelno, + firmnm = store.firmnm, + + drwtNos = drwtStores.filter { it.rtlrid == store.rtlrid }.map { it.drwtNo!! }, + ) + ) + } + + return Flux.fromIterable(result) + } + + /** + * 판매점 위치정보 조회 + * + * @return [Flux]<[Flux]> + * @author yoonho + * @since 2023.07.18 + */ + override fun findLocation(): Flux { + val result = storeRepositoryImpl.findLocation() + .filter { it.bplclocplc1 != "" && it.bplclocplc2 != "" } + return Flux.fromIterable(result) + } +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/john/lotto/store/application/dto/LottoStoreTotalInfo.kt b/api/src/main/kotlin/com/john/lotto/store/application/dto/LottoStoreTotalInfo.kt new file mode 100644 index 0000000..9b90afe --- /dev/null +++ b/api/src/main/kotlin/com/john/lotto/store/application/dto/LottoStoreTotalInfo.kt @@ -0,0 +1,38 @@ +package com.john.lotto.store.application.dto + +import com.fasterxml.jackson.annotation.JsonProperty + +/** + * @author yoonho + * @since 2023.07.18 + */ +data class LottoStoreTotalInfo( + @JsonProperty("RTLRID") + val rtlrid: String? = "", + + @JsonProperty("LATITUDE") + val latitude: Float? = -1F, + @JsonProperty("LONGITUDE") + val longitude: Float? = -1F, + + @JsonProperty("BPLCLOCPLC1") + val bplclocplc1: String? = "", + @JsonProperty("BPLCLOCPLC2") + val bplclocplc2: String? = "", + @JsonProperty("BPLCLOCPLC3") + val bplclocplc3: String? = "", + @JsonProperty("BPLCLOCPLC4") + val bplclocplc4: String? = "", + + @JsonProperty("BPLCDORODTLADRES") + var bplcdorodtladres: String? = "", + @JsonProperty("BPLCLOCPLCDTLADRES") + var bplclocplcdtladres: String? = "", + @JsonProperty("RTLRSTRTELNO") + val rtlrstrtelno: String? = "", + @JsonProperty("FIRMNM") + var firmnm: String? = "", + + // 1등 당첨회차 + var drwtNos: List = mutableListOf() +) diff --git a/api/src/main/kotlin/com/john/lotto/store/application/port/in/FindLocationUseCase.kt b/api/src/main/kotlin/com/john/lotto/store/application/port/in/FindLocationUseCase.kt new file mode 100644 index 0000000..4de97d5 --- /dev/null +++ b/api/src/main/kotlin/com/john/lotto/store/application/port/in/FindLocationUseCase.kt @@ -0,0 +1,20 @@ +package com.john.lotto.store.application.port.`in` + +import com.john.lotto.store.dto.LocationDto +import reactor.core.publisher.Flux + +/** + * @author yoonho + * @since 2023.07.18 + */ +interface FindLocationUseCase { + + /** + * 판매점 위치정보 조회 + * + * @return [Flux]<[Flux]> + * @author yoonho + * @since 2023.07.18 + */ + fun findLocation(): Flux +} \ No newline at end of file diff --git a/api/src/main/kotlin/com/john/lotto/store/application/port/in/FindStoreUseCase.kt b/api/src/main/kotlin/com/john/lotto/store/application/port/in/FindStoreUseCase.kt new file mode 100644 index 0000000..ad6ddb1 --- /dev/null +++ b/api/src/main/kotlin/com/john/lotto/store/application/port/in/FindStoreUseCase.kt @@ -0,0 +1,22 @@ +package com.john.lotto.store.application.port.`in` + +import com.john.lotto.store.application.dto.LottoStoreTotalInfo +import reactor.core.publisher.Flux + +/** + * @author yoonho + * @since 2023.07.18 + */ +interface FindStoreUseCase { + + /** + * 로또 판매점 조회 + * + * @param location [String] + * @param subLocation [String] + * @return [Flux]<[LottoStoreTotalInfo]> + * @author yoonho + * @since 2023.07.18 + */ + fun findStore(location: String, subLocation: String): Flux +} \ No newline at end of file diff --git a/batch/src/main/kotlin/com/john/lotto/common/tasklet/NoticeResultTasklet.kt b/batch/src/main/kotlin/com/john/lotto/common/tasklet/NoticeResultTasklet.kt index d0a4d16..f197935 100644 --- a/batch/src/main/kotlin/com/john/lotto/common/tasklet/NoticeResultTasklet.kt +++ b/batch/src/main/kotlin/com/john/lotto/common/tasklet/NoticeResultTasklet.kt @@ -31,12 +31,14 @@ class NoticeResultTasklet( val jobExecutionContext = jobExecution.executionContext val status = jobExecutionContext.get("status")?.toString() ?: "" + val job = jobExecutionContext.get("job")?.toString() ?: "" val step = jobExecutionContext.get("step")?.toString() ?: "" val message = jobExecutionContext.get("message")?.toString() ?: "" noticeMessage = NoticeMessageUtils.MESSAGE_TEMPLATE .replace("{status}", status) .replace("{step}", step) + .replace("{job}", job) .replace("{message}", message) } diff --git a/batch/src/main/kotlin/com/john/lotto/common/utils/NoticeMessageUtils.kt b/batch/src/main/kotlin/com/john/lotto/common/utils/NoticeMessageUtils.kt index 1efd419..8f3bf13 100644 --- a/batch/src/main/kotlin/com/john/lotto/common/utils/NoticeMessageUtils.kt +++ b/batch/src/main/kotlin/com/john/lotto/common/utils/NoticeMessageUtils.kt @@ -11,18 +11,20 @@ class NoticeMessageUtils { companion object { val NOTICE_USER_NAME = "Lotto Batch Notification" var MESSAGE_TEMPLATE = "\uFE0F\uD83C\uDF1F로또배치 실행 {status}!\uD83C\uDF1F\n\n" + - "- Step : {step}\n" + - "- 메세지 : {message}\n" + - "- url: {url}" + " > Job : {job}\n" + + " > Step : {step}\n" + + " > Message : {message}" - fun setSuccessMessage(jobExecutionContext: ExecutionContext, step: String) { + fun setSuccessMessage(jobExecutionContext: ExecutionContext, job: String, step: String) { jobExecutionContext.put("message", "SUCCESS") + jobExecutionContext.put("job", job) jobExecutionContext.put("step", step) jobExecutionContext.put("status", "성공") } - fun setFailMessage(jobExecutionContext: ExecutionContext, step: String, message: String) { + fun setFailMessage(jobExecutionContext: ExecutionContext, job: String, step: String, message: String) { jobExecutionContext.put("message", message) + jobExecutionContext.put("job", job) jobExecutionContext.put("step", step) jobExecutionContext.put("status", "실패") } diff --git a/batch/src/main/kotlin/com/john/lotto/job/drwtstore/tasklet/LottoDrwtStoreTasklet.kt b/batch/src/main/kotlin/com/john/lotto/job/drwtstore/tasklet/LottoDrwtStoreTasklet.kt index da6ad1f..de24683 100644 --- a/batch/src/main/kotlin/com/john/lotto/job/drwtstore/tasklet/LottoDrwtStoreTasklet.kt +++ b/batch/src/main/kotlin/com/john/lotto/job/drwtstore/tasklet/LottoDrwtStoreTasklet.kt @@ -53,7 +53,8 @@ class LottoDrwtStoreTasklet( log.error(" >>> [drwtStore] Fail Crawling DrwtStore") NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoDrwtStoreStep", + job = stepContext.jobName, + step = stepContext.stepName, message = "[drwtStore] Fail Crawling DrwtStore" ) contribution.exitStatus = ExitStatus.FAILED @@ -68,7 +69,8 @@ class LottoDrwtStoreTasklet( log.error(" >>> [drwtStore] Exception occurs - message: ${e.message}") NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoDrwtStoreStep", + job = stepContext.jobName, + step = stepContext.stepName, message = e.message ?: "[drwtStore] Exception occurs" ) contribution.exitStatus = ExitStatus.FAILED @@ -83,7 +85,8 @@ class LottoDrwtStoreTasklet( log.warn(" >>> [drwtStore][manual] invalid parameter - startDrwtNo: $startDrwtNoParam, endDrwtNo: $endDrwtNoParam") NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoDrwtStoreStep", + job = stepContext.jobName, + step = stepContext.stepName, message = "[drwtStore][manual] invalid parameter - startDrwtNo: $startDrwtNoParam, endDrwtNo: $endDrwtNoParam" ) contribution.exitStatus = ExitStatus.FAILED @@ -98,7 +101,8 @@ class LottoDrwtStoreTasklet( log.warn(" >>> [drwtStore][manual] invalid parameter - startDrwtNo: $startDrwtNo, endDrwtNo: $endDrwtNo") NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoDrwtStoreStep", + job = stepContext.jobName, + step = stepContext.stepName, message = "[drwtStore][manual] invalid parameter - startDrwtNo: $startDrwtNo, endDrwtNo: $endDrwtNo" ) contribution.exitStatus = ExitStatus.FAILED @@ -111,7 +115,8 @@ class LottoDrwtStoreTasklet( log.error(" >>> [drwtStore][manual] Fail Crawling DrwtStore") NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoDrwtStoreStep", + job = stepContext.jobName, + step = stepContext.stepName, message = "[drwtStore][manual] Fail Crawling DrwtStore - currentDrwtNo: $endDrwtNo" ) contribution.exitStatus = ExitStatus.FAILED @@ -131,7 +136,8 @@ class LottoDrwtStoreTasklet( log.error(" >>> [drwtStore][manual] Fail Crawling DrwtStore") NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoDrwtStoreStep", + job = stepContext.jobName, + step = stepContext.stepName, message = "[drwtStore][manual] Fail Crawling DrwtStore - currentDrwtNo: $endDrwtNo, startDrwtNo: $startDrwtNo, endDrwtNo: $endDrwtNo" ) contribution.exitStatus = ExitStatus.FAILED @@ -148,7 +154,8 @@ class LottoDrwtStoreTasklet( log.error(" >>> [drwtStore][manual] Exception occurs - message: ${e.message}") NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoDrwtStoreStep", + job = stepContext.jobName, + step = stepContext.stepName, message = e.message ?: "[drwtStore][manual] Exception occurs" ) contribution.exitStatus = ExitStatus.FAILED @@ -160,7 +167,8 @@ class LottoDrwtStoreTasklet( log.info(" >>> [drwtStore] BATCH END ########") NoticeMessageUtils.setSuccessMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoDrwtStoreStep" + job = stepContext.jobName, + step = stepContext.stepName ) return RepeatStatus.FINISHED } diff --git a/batch/src/main/kotlin/com/john/lotto/job/number/LottoNumberBatchJob.kt b/batch/src/main/kotlin/com/john/lotto/job/number/LottoNumberBatchJob.kt index 3f0d3d0..6ed6321 100644 --- a/batch/src/main/kotlin/com/john/lotto/job/number/LottoNumberBatchJob.kt +++ b/batch/src/main/kotlin/com/john/lotto/job/number/LottoNumberBatchJob.kt @@ -25,6 +25,9 @@ class LottoNumberBatchJob ( ) { private val log = LoggerFactory.getLogger(this::class.java) + // TODO: + // - 실패시에도 알림가도록 설정 + @Bean fun lottoNumberJob(jobRepository: JobRepository, transactionManager: JpaTransactionManager): Job = JobBuilder("lottoNumberJob", jobRepository) diff --git a/batch/src/main/kotlin/com/john/lotto/job/number/tasklet/LottoNumberTasklet.kt b/batch/src/main/kotlin/com/john/lotto/job/number/tasklet/LottoNumberTasklet.kt index fdb9719..79c3834 100644 --- a/batch/src/main/kotlin/com/john/lotto/job/number/tasklet/LottoNumberTasklet.kt +++ b/batch/src/main/kotlin/com/john/lotto/job/number/tasklet/LottoNumberTasklet.kt @@ -20,6 +20,7 @@ import org.springframework.batch.core.step.tasklet.Tasklet import org.springframework.batch.item.ExecutionContext import org.springframework.batch.repeat.RepeatStatus import org.springframework.stereotype.Component +import org.springframework.transaction.annotation.Isolation import org.springframework.transaction.annotation.Transactional import java.time.LocalDate import java.time.format.DateTimeFormatter @@ -44,6 +45,7 @@ class LottoNumberTasklet( this.jobExecutionContext = jobExecution.executionContext } + @Transactional override fun execute(contribution: StepContribution, chunkContext: ChunkContext): RepeatStatus? { log.info(" >>> [number] BATCH START ########") val stepContext = chunkContext.stepContext @@ -62,7 +64,8 @@ class LottoNumberTasklet( if(!isSuccess) { NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoNumberStep", + job = stepContext.jobName, + step = stepContext.stepName, message = "[number] fail insert LottoInfo - drwtNo: $lastDrwtNo" ) contribution.exitStatus = ExitStatus.FAILED @@ -72,7 +75,8 @@ class LottoNumberTasklet( log.error(" >>> [number] Exception occurs - message: ${e.message}") NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoNumberStep", + job = stepContext.jobName, + step = stepContext.stepName, message = e.message ?: "[number] Exception occurs" ) contribution.exitStatus = ExitStatus.FAILED @@ -87,7 +91,8 @@ class LottoNumberTasklet( log.warn(" >>> [number][manual] invalid parameter - startDrwtNo: $startDrwtNoParam, endDrwtNo: $endDrwtNoParam") NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoNumberStep", + job = stepContext.jobName, + step = stepContext.stepName, message = "[number][manual] invalid parameter - startDrwtNo: $startDrwtNoParam, endDrwtNo: $endDrwtNoParam" ) contribution.exitStatus = ExitStatus.FAILED @@ -102,7 +107,8 @@ class LottoNumberTasklet( log.warn(" >>> [number][manual] invalid parameter - startDrwtNo: $startDrwtNo, endDrwtNo: $endDrwtNo") NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoNumberStep", + job = stepContext.jobName, + step = stepContext.stepName, message = "[number][manual] invalid parameter - startDrwtNo: $startDrwtNo, endDrwtNo: $endDrwtNo" ) contribution.exitStatus = ExitStatus.FAILED @@ -113,7 +119,8 @@ class LottoNumberTasklet( if(!isSuccess) { NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoNumberStep", + job = stepContext.jobName, + step = stepContext.stepName, message = "[number][manual] fail insert LottoInfo - currentDrwtNo: $endDrwtNo" ) contribution.exitStatus = ExitStatus.FAILED @@ -126,7 +133,8 @@ class LottoNumberTasklet( if(!isSuccess) { NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoNumberStep", + job = stepContext.jobName, + step = stepContext.stepName, message = "[number][manual] fail insert LottoInfo - currentDrwtNo: $drwtNo, startDrwtNo: $startDrwtNo, endDrwtNo: $endDrwtNo" ) contribution.exitStatus = ExitStatus.FAILED @@ -138,7 +146,8 @@ class LottoNumberTasklet( log.error(" >>> [number][manual] Exception occurs - message: ${e.message}") NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoNumberStep", + job = stepContext.jobName, + step = stepContext.stepName, message = e.message ?: "[number][manual] Exception occurs" ) contribution.exitStatus = ExitStatus.FAILED @@ -150,7 +159,8 @@ class LottoNumberTasklet( log.info(" >>> [number] BATCH END ########") NoticeMessageUtils.setSuccessMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoNumberStep" + job = stepContext.jobName, + step = stepContext.stepName ) return RepeatStatus.FINISHED } @@ -163,7 +173,6 @@ class LottoNumberTasklet( * @author yoonho * @since 2023.06.29 */ - @Transactional fun insertLottoInfo(drwtNo: String): Boolean { try { // 로또 당첨정보 조회 (by, 로또API) diff --git a/batch/src/main/kotlin/com/john/lotto/job/store/tasklet/LottoStoreTasklet.kt b/batch/src/main/kotlin/com/john/lotto/job/store/tasklet/LottoStoreTasklet.kt index c99e134..eb7410c 100644 --- a/batch/src/main/kotlin/com/john/lotto/job/store/tasklet/LottoStoreTasklet.kt +++ b/batch/src/main/kotlin/com/john/lotto/job/store/tasklet/LottoStoreTasklet.kt @@ -109,7 +109,8 @@ class LottoStoreTasklet( log.error(" >>> [store] Exception occurs - message: ${e.message}") NoticeMessageUtils.setFailMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoStoreStep", + job = stepContext.jobName, + step = stepContext.stepName, message = e.message ?: "[store] Exception occurs" ) contribution.exitStatus = ExitStatus.FAILED @@ -119,7 +120,8 @@ class LottoStoreTasklet( log.info(" >>> [store] BATCH END ########") NoticeMessageUtils.setSuccessMessage( jobExecutionContext = jobExecutionContext!!, - step = "lottoStoreStep" + job = stepContext.jobName, + step = stepContext.stepName ) return RepeatStatus.FINISHED } diff --git a/core/src/main/kotlin/com/john/lotto/drwtstore/DrwtStoreRepository.kt b/core/src/main/kotlin/com/john/lotto/drwtstore/DrwtStoreRepository.kt index 67642bc..3605b6e 100644 --- a/core/src/main/kotlin/com/john/lotto/drwtstore/DrwtStoreRepository.kt +++ b/core/src/main/kotlin/com/john/lotto/drwtstore/DrwtStoreRepository.kt @@ -1,6 +1,7 @@ package com.john.lotto.drwtstore import com.john.lotto.drwtstore.dto.DrwtStoreDto +import com.john.lotto.drwtstore.dto.QDrwtStoreDto import com.john.lotto.entity.QLottoDrwtStore import com.querydsl.jpa.impl.JPAQueryFactory import org.slf4j.LoggerFactory @@ -21,6 +22,14 @@ class DrwtStoreRepository( private val lottoDrwtStore = QLottoDrwtStore.lottoDrwtStore!! + /** + * 당첨판매점 저장 + * + * @param input [DrwtStoreDto] + * @return [Long] + * @author yoonho + * @since 2023.07.18 + */ @Transactional fun insertLottoDrwtStore(input: DrwtStoreDto): Long = queryFactory @@ -48,4 +57,34 @@ class DrwtStoreRepository( input.createdAt ) .execute() + + /** + * 당첨판매점 조회 + * + * @param ids [List]<[String]> + * @return [List]<[DrwtStoreDto]> + * @author yoonho + * @since 2023.07.18 + */ + @Transactional(readOnly = true) + fun findLottoDrwtStore(ids: List): List = + queryFactory + .select( + QDrwtStoreDto( + lottoDrwtStore.drwtNo, + lottoDrwtStore.drwtOrder, + lottoDrwtStore.drwtRank, + lottoDrwtStore.rtlrid, + lottoDrwtStore.firmnm, + lottoDrwtStore.bplcdorodtladres, + lottoDrwtStore.drwtType, + lottoDrwtStore.updatedAt, + lottoDrwtStore.createdAt + ) + ) + .from(lottoDrwtStore) + .where( + lottoDrwtStore.rtlrid.`in`(ids) + ) + .fetch() } \ No newline at end of file diff --git a/core/src/main/kotlin/com/john/lotto/number/NumberRepository.kt b/core/src/main/kotlin/com/john/lotto/number/NumberRepository.kt index 8ba3291..6c01ea8 100644 --- a/core/src/main/kotlin/com/john/lotto/number/NumberRepository.kt +++ b/core/src/main/kotlin/com/john/lotto/number/NumberRepository.kt @@ -104,7 +104,7 @@ class NumberRepository( * @author yoonho * @since 2023.06.28 */ - @Transactional +// @Transactional fun insertLottoNumber(input: LottoNumberDto): Long = queryFactory .insert(lottoNumber) diff --git a/core/src/main/kotlin/com/john/lotto/store/StoreRepositoryImpl.kt b/core/src/main/kotlin/com/john/lotto/store/StoreRepositoryImpl.kt index 1e2de1a..d490c2b 100644 --- a/core/src/main/kotlin/com/john/lotto/store/StoreRepositoryImpl.kt +++ b/core/src/main/kotlin/com/john/lotto/store/StoreRepositoryImpl.kt @@ -1,7 +1,10 @@ package com.john.lotto.store import com.john.lotto.entity.QLottoStore +import com.john.lotto.store.dto.LocationDto import com.john.lotto.store.dto.LottoStoreDto +import com.john.lotto.store.dto.QLocationDto +import com.john.lotto.store.dto.QLottoStoreDto import com.querydsl.jpa.impl.JPAQueryFactory import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Qualifier @@ -78,4 +81,63 @@ class StoreRepositoryImpl( queryFactory .delete(lottoStore) .execute() + + /** + * 로또 판매점 조회 + * + * @param location [String] + * @param subLocation [String] + * @return [List]<[LottoStoreDto]> + * @author yoonho + * @since 2023.07.18 + */ + @Transactional(readOnly = true) + fun findLottoStore(location: String, subLocation: String): List = + queryFactory + .select( + QLottoStoreDto( + lottoStore.rtlrid, + lottoStore.latitude, + lottoStore.longitude, + lottoStore.bplclocplc1, + lottoStore.bplclocplc2, + lottoStore.bplclocplc3, + lottoStore.bplclocplc4, + lottoStore.bplcdorodtladres, + lottoStore.bplclocplcdtladres, + lottoStore.rtlrstrtelno, + lottoStore.firmnm, + lottoStore.updatedAt, + lottoStore.createdAt + ) + ) + .from(lottoStore) + .where( + lottoStore.bplclocplc1.like(location), + lottoStore.bplclocplc2.like(subLocation) + ) + .fetch() + + /** + * 판매점 위치정보 조회 + * + * @return [List]<[LocationDto]> + * @author yoonho + * @since 2023.07.18 + */ + @Transactional(readOnly = true) + fun findLocation(): List = + queryFactory + .select( + QLocationDto( + lottoStore.bplclocplc1, + lottoStore.bplclocplc2, + ) + ) + .from(lottoStore) + .groupBy( + lottoStore.bplclocplc1, + lottoStore.bplclocplc2 + ) + .fetch() } \ No newline at end of file diff --git a/core/src/main/kotlin/com/john/lotto/store/dto/LocationDto.kt b/core/src/main/kotlin/com/john/lotto/store/dto/LocationDto.kt new file mode 100644 index 0000000..aed1c64 --- /dev/null +++ b/core/src/main/kotlin/com/john/lotto/store/dto/LocationDto.kt @@ -0,0 +1,15 @@ +package com.john.lotto.store.dto + +import com.fasterxml.jackson.annotation.JsonProperty +import com.querydsl.core.annotations.QueryProjection + +/** + * @author yoonho + * @since 2023.07.18 + */ +data class LocationDto @QueryProjection constructor( + @JsonProperty("BPLCLOCPLC1") + val bplclocplc1: String? = "", + @JsonProperty("BPLCLOCPLC2") + val bplclocplc2: String? = "", +)