data class StoreDto(
val id: Int,
val shopName: String,
val mallName: String,
val domain: String,
val email: String,
val phoneNumber: String,
val businessType: String?,
val address: String,
val totalEvaluation: Int?, // 타입을 Int?로 변경
val situation: String,
val monitoringDate: String
) {
constructor(store: Store) : this(
id = store.id,
shopName = store.shopName,
mallName = store.mallName,
domain = store.domain,
email = store.email,
phoneNumber = store.phoneNumber,
businessType = store.businessType,
address = store.address,
totalEvaluation = store.totalEvaluation,
situation = store.situation,
monitoringDate = store.monitoringDate
)
}// constructor를 넣은 이유는 안그러면 controller에서 설명이 길어짐
@Service
class StoreServiceImpl(private val storeRepository: StoreRepository) : StoreService {
override fun getStoresByTotalEvaluation(rating: Int): List<StoreDto> {
return storeRepository.findAll()
.filter { it.totalEvaluation == rating }//가져온 상점 정보 중에서 "totalEvaluation"이 입력받은 "rating"과 같은 상점만 필터링
.sortedByDescending { it.monitoringDate }//필터링된 상점들을 "monitoringDate"를 기준으로 내림차순
.map { StoreDto(it) }// 정렬된 상점 정보를 StoreDto 객체로 변환하여 리스트로
}
override fun getStoresBySituation(status: String): List<StoreDto> {
return storeRepository.findAll()
.filter { it.situation == status }
.sortedByDescending { it.monitoringDate }
.map { StoreDto(it) }
}
// .map { store -> StoreDto(
// id = store.id,
// shopName = store.shopName,
// mallName = store.mallName,
// domain = store.domain,
// email = store.email,
// phoneNumber = store.phoneNumber,
// businessType = store.businessType,
// address = store.address,
// totalEvaluation = store.totalEvaluation,
// situation = store.situation,
// monitoringDate = store.monitoringDate
// )} dto에 컨스트럭터로 긴거 안넣으며 여기에 이걸 넣어야 하기 때문
override fun getStoresByTotalEvaluationAndSituation(rating: Int, status: String): List<StoreDto> {
return storeRepository.findAll()
.filter { it.totalEvaluation == rating && it.situation == status }
.sortedByDescending { it.monitoringDate }
.map { StoreDto(it) }
}
}
@RestController
@RequestMapping("/api/stores")
class StoreController(
private val storeService: StoreService
) {
@GetMapping("/rating")
@Operation(summary = "전체 점수 조회", description = "0~3 까지의 숫자를 입력하세요.")
fun getStoresByTotalEvaluation(
@RequestParam rating: Int //이게 있어야 스웨거에서 숫자입력
): ResponseEntity<List<StoreDto>> {
val stores = storeService.getStoresByTotalEvaluation(rating)
return ResponseEntity.ok(stores)
}
@GetMapping("/status")
@Operation(summary = "점포 상태 조회", description = "사이트운영중단, 휴업중, 광고용(홍보용), 등록정보불일치, 사이트폐쇄, 영업중, 확인안됨 상태 중 1개를 선택하세요.")
fun getStoresBySituation(
@RequestParam status: String
): ResponseEntity<List<StoreDto>> {
val stores = storeService.getStoresBySituation(status)//"storeService"의 "getStoresBySituation" 메서드를 호출하여 결과를 "stores" 변수에 저장하는 부분
return ResponseEntity.ok(stores)
}
@GetMapping("/rating-status")
@Operation(summary = "전체평가, 점포 상태 조회", description = "0~3 까지의 숫자와 사이트운영중단, 휴업중, 광고용(홍보용), 등록정보불일치, 사이트폐쇄, 영업중, 확인안됨 상태 중 1개를 선택하세요.")
fun getStoresByTotalEvaluationAndSituation(
@RequestParam rating: Int,
@RequestParam status: String
): ResponseEntity<List<StoreDto>> {
val stores = storeService.getStoresByTotalEvaluationAndSituation(rating, status)
return ResponseEntity.ok(stores)
}
}
이건 그냥 조회니까 try catch로 맞으면, 아니면 할필요도 없음
그리고 팀원이 검색, 삭제를 만들었는데, 그중 검색기능은 처음 보는거라서 이렇게 저장해둔다.
컨트롤러에 추가
@GetMapping("/search")
fun searchStores(
@RequestParam(required = false) name: String?,
@RequestParam(required = false) domain: String?,
@RequestParam(required = false) email: String?
): ResponseEntity<List<StoreDto>> {
val stores = storeService.searchStores(name, domain, email)
return ResponseEntity.ok(stores)
}
@RequestParam(required = false) 어노테이션은 해당 파라미터가 필수가 아니기에 요청에서 해당 파라미터가 누락되어도 요청 처리가 가능하다는 것을 의미한다. 파라미터가 누락되면 기본값으로 null이 사용.
따라서, 이 메서드는 name, domain, email 중 하나 이상의 파라미터를 받아서 상점을 검색하며, 특정 파라미터가 누락되면 해당 조건으로는 검색하지 않는다.
예를 들어, name과 email만 요청에 포함되면, name과 email로 상점을 검색하고 domain 조건은 무시합니다. 이렇게 하면 사용자가 원하는 조건만으로 상점을 검색.
마지막으로, storeService.searchStores(name, domain, email)는 검색 조건을 받아서 상점을 검색하는 서비스 메서드를 호출하고, 그 결과를 stores에 저장 하는 역할이라고 한다.
서비스임플에 추가하는건,
override fun searchStores(name: String?, domain: String?, email: String?): List<StoreDto> {
return storeRepository.findAll()
.filter { store ->
(name == null || store.shopName.contains(name))
&&(domain == null || store.domain.contains(domain))
&&(email == null || store.email.contains(email))
}
.sortedByDescending { it.monitoringDate }
.map { StoreDto(it) }
}
서비스에 추가하는건,
fun searchStores(name: String?, domain: String?, email: String?): List<StoreDto>
이러면 검색기능이 추가된다.
서비스 임플에 입력하는 오류 메시지는 인텔리제이 화면에 뜨는것이고,
class BusinessException(message: String) : RuntimeException(message)
이렇게 전용으로 exception 만들어야 인텔리제이에 오류메시지를 띄울수 있다.
스웨거에 오류가 뜨게 하려면 GlobalExceptionHandler 를 만들고
@ControllerAdvice
class GlobalExceptionHandler {
@ExceptionHandler(BusinessException::class)
fun handleBusinessException(e: BusinessException): ResponseEntity<String> {
return ResponseEntity.badRequest().body(e.message)
}
}
그 안에 이렇게 해당하는 오류를 그안에 넣으면 스웨거 화면에서도 동일한 메시지가 나온다.
그리고 이제 내가 작성한 get 세개도 오류시의 메시지를 넣는다.
package com.teamsparta.hoop.service
import com.teamsparta.hoop.exception.BusinessException
import com.teamsparta.hoop.dto.StoreDto
import com.teamsparta.hoop.repository.StoreRepository
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
@Service
class StoreServiceImpl(
private val storeRepository: StoreRepository
) : StoreService {
override fun getStoresByTotalEvaluation(rating: Int): List<StoreDto> {
if (rating < 0 || rating > 3) {
throw BusinessException("잘못된 숫자입니다. 숫자는 0 이상 3 이하의 값이어야 합니다.")
}
return storeRepository.findAll()
.filter { it.totalEvaluation == rating }//가져온 상점 정보 중에서 "totalEvaluation"이 입력받은 "rating"과 같은 상점만 필터링
.sortedByDescending { it.monitoringDate }//필터링된 상점들을 "monitoringDate"를 기준으로 내림차순
.map { StoreDto(it) }// 정렬된 상점 정보를 StoreDto 객체로 변환하여 리스트로
}
override fun getStoresBySituation(status: String): List<StoreDto> {
val allowedStatuses = listOf("사이트운영중단", "휴업중", "광고용(홍보용)", "등록정보불일치", "사이트폐쇄", "영업중", "확인안됨")
if (status !in allowedStatuses) {
throw BusinessException("잘못 입력하셨습니다.")
}
return storeRepository.findAll()
.filter { it.situation == status }
.sortedByDescending { it.monitoringDate }
.map { StoreDto(it) }
}
override fun getStoresByTotalEvaluationAndSituation(rating: Int, status: String): List<StoreDto> {
if (rating < 0 || rating > 3) {
throw BusinessException("잘못된 숫자입니다. 숫자는 0 이상 3 이하의 값이어야 합니다.")
}
val allowedStatuses = listOf("사이트운영중단", "휴업중", "광고용(홍보용)", "등록정보불일치", "사이트폐쇄", "영업중", "확인안됨")
if (status !in allowedStatuses) {
throw BusinessException("잘못 입력하셨습니다.")
}
return storeRepository.findAll()
.filter { it.totalEvaluation == rating && it.situation == status }
.sortedByDescending { it.monitoringDate }
.map { StoreDto(it) }
}
override fun searchStores(
name: String?,
domain: String?,
email: String?
): List<StoreDto> {
return storeRepository.findAll()
.filter { store ->
(name == null || store.shopName.contains(name))
&&(domain == null || store.domain.contains(domain))
&&(email == null || store.email.contains(email))
}
.sortedByDescending { it.monitoringDate }
.map { StoreDto(it) }
}
@Transactional
override fun deleteStore(shopName: String) {
try {
val store = storeRepository.findByShopName(shopName)
if (store != null) {
storeRepository.delete(store)
}
} catch (e: NoSuchElementException) {
throw BusinessException("업체를 찾을 수 없습니다. shopName: $shopName")
}
}
}
참고로 0이상 3이하는 require(rating in 0..3)도 되는 모양이다.
어쨋든
if (rating < 0 || rating > 3) {
throw BusinessException("잘못된 숫자입니다. 숫자는 0 이상 3 이하의 값이어야 합니다.")
} 이걸 List<StoreDto>의 바로 뒤에 넣어주면 이제 틀린 숫자를 입력하면 잘못된 숫자입니다. 숫자는 0 이상 3 이하의 값이어야 합니다.가 출력 된다.
val allowedStatuses = listOf("사이트운영중단", "휴업중", "광고용(홍보용)", "등록정보불일치", "사이트폐쇄", "영업중", "확인안됨")
if (status !in allowedStatuses) {
throw BusinessException("잘못 입력하셨습니다.")
} 이건 저 리스트 안에 있는 숫자가 아니면 잘못 입력하셨습니다를 출력하도록 해준다.
package com.teamsparta.hoop.controller
import com.teamsparta.hoop.dto.StoreDto
import com.teamsparta.hoop.service.StoreService
import io.swagger.v3.oas.annotations.Operation
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/api/stores")
class StoreController(
private val storeService: StoreService
) {
@GetMapping("/rating")
@Operation(summary = "전체 점수 조회", description = "0~3 까지의 숫자를 입력하세요.")
fun getStoresByTotalEvaluation(
@RequestParam rating: Int //이게 있어야 스웨거에서 숫자입력
): ResponseEntity<List<StoreDto>> {
val stores = storeService.getStoresByTotalEvaluation(rating)
return ResponseEntity.ok(stores)
}
@GetMapping("/status")
@Operation(summary = "가게 상태 조회", description = "사이트운영중단, 휴업중, 광고용(홍보용), 등록정보불일치, 사이트폐쇄, 영업중, 확인안됨 상태 중 1개를 선택하세요.")
fun getStoresBySituation(
@RequestParam status: String
): ResponseEntity<List<StoreDto>> {
val stores = storeService.getStoresBySituation(status)//"storeService"의 "getStoresBySituation" 메서드를 호출하여 결과를 "stores" 변수에 저장하는 부분
return ResponseEntity.ok(stores)
}
@GetMapping("/rating-status")
@Operation(summary = "전체평가, 가게 상태 조회", description = "0~3 까지의 숫자와 사이트운영중단, 휴업중, 광고용(홍보용), 등록정보불일치, 사이트폐쇄, 영업중, 확인안됨 상태 중 1개를 선택하세요.")
fun getStoresByTotalEvaluationAndSituation(
@RequestParam rating: Int,
@RequestParam status: String
): ResponseEntity<List<StoreDto>> {
val stores = storeService.getStoresByTotalEvaluationAndSituation(rating, status)
return ResponseEntity.ok(stores)
}
@GetMapping("/search")
@Operation(summary = "가게 이름 검색", description = "이름, 사이트 주소, 이메일 중 하나만 입력해도 됩니다.")
fun searchStores(
@RequestParam(required = false) name: String?,
@RequestParam(required = false) domain: String?,
@RequestParam(required = false) email: String?
): ResponseEntity<List<StoreDto>> {
val stores = storeService.searchStores(name, domain, email)
return ResponseEntity.ok(stores)
}
@DeleteMapping("/delete")
@Operation(summary = "가게 삭제", description = "입력한 이름과 같은 가게를 삭제합니다.")
fun deleteStore(
@RequestParam shopName: String
): ResponseEntity<Unit> {
storeService.deleteStore(shopName)
return ResponseEntity.noContent().build()
}
}
그리고 검색과 삭제에도 설명을 넣어 주었다.
그리고 왠지 모르게 깃허브에 올라가질 않아서 시간을 엉첨나게 낭비했는데, 내가 sw에 있는데도 sw가 없다던가 하면서
git push origin SW
error: src refspec SW does not match any
error: failed to push some refs to 'origin'
이러고 안될 때, git checkout -b SW를 하고 다시 올렸더니 됬다. sw를 인식 못하니, sw를 다시 만들어서 올린것이다.
그리고 깃허브에 올린 dev도 잘 안받아지길래, 인텔리제이에서 직접 dev를 클릭해서 병합이나 리베이스를 사용하여 sw에 풀 이걸로 받아왔다.