Skip to content

Commit

Permalink
✨feature : 로또판매점 조회기능 작업
Browse files Browse the repository at this point in the history
  • Loading branch information
ParkYunHo committed Jul 18, 2023
1 parent 5e75bc4 commit f7e1f7b
Show file tree
Hide file tree
Showing 16 changed files with 471 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -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<ServerResponse> =
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<ServerResponse> =
findLocationUseCase.findLocation()
.collectList()
.flatMap { BaseResponse().success(it) }
}
Original file line number Diff line number Diff line change
@@ -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<ServerResponse> = router {
accept(MediaType.APPLICATION_JSON).nest {
GET("/api/location", storeHandler::findLocation)
GET("/api/store", storeHandler::findStore)
}
}
}
Original file line number Diff line number Diff line change
@@ -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<LottoStoreTotalInfo> {
val result = mutableListOf<LottoStoreTotalInfo>()

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<LocationDto> {
val result = storeRepositoryImpl.findLocation()
.filter { it.bplclocplc1 != "" && it.bplclocplc2 != "" }
return Flux.fromIterable(result)
}
}
Original file line number Diff line number Diff line change
@@ -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<Long> = mutableListOf()
)
Original file line number Diff line number Diff line change
@@ -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<LocationDto>
}
Original file line number Diff line number Diff line change
@@ -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<LottoStoreTotalInfo>
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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", "실패")
}
Expand Down
Loading

0 comments on commit f7e1f7b

Please sign in to comment.