Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

7/5 배포 작업 #119

Merged
merged 1 commit into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions src/main/kotlin/backend/itracker/crawl/common/ProductCategory.kt
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
package backend.itracker.crawl.common

import backend.itracker.crawl.macbook.domain.MacbookCategory

enum class ProductCategory {
MACBOOK_AIR,
MACBOOK_PRO,
MACBOOK,
MAC,
I_PHONE,
I_PAD,
AIRPODS,
APPLE_WATCH;

fun toMacbookCategory(): MacbookCategory {
return when (this) {
MACBOOK_AIR -> MacbookCategory.MACBOOK_AIR
MACBOOK_PRO -> MacbookCategory.MACBOOK_PRO
else -> throw IllegalArgumentException("MacbookCategory로 변환할 수 없는 ProductCategory 입니다. category: $this")
companion object {
fun from(productFilterCategory: ProductFilterCategory): ProductCategory {
return when (productFilterCategory) {
ProductFilterCategory.MACBOOK_AIR,
ProductFilterCategory.MACBOOK_PRO -> MACBOOK
ProductFilterCategory.MAC -> MAC
ProductFilterCategory.I_PHONE -> I_PHONE
ProductFilterCategory.I_PAD -> I_PAD
ProductFilterCategory.AIRPODS -> AIRPODS
ProductFilterCategory.APPLE_WATCH -> APPLE_WATCH
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package backend.itracker.crawl.common

import backend.itracker.crawl.macbook.domain.MacbookCategory

enum class ProductFilterCategory {
MACBOOK_AIR,
MACBOOK_PRO,
MAC,
I_PHONE,
I_PAD,
AIRPODS,
APPLE_WATCH;

fun toMacbookCategory(): MacbookCategory {
return when (this) {
MACBOOK_AIR -> MacbookCategory.MACBOOK_AIR
MACBOOK_PRO -> MacbookCategory.MACBOOK_PRO
else -> throw IllegalArgumentException("MacbookCategory로 변환할 수 없는 ProductCategory 입니다. category: $this")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package backend.itracker.tracker.common.converter

import backend.itracker.crawl.common.ProductFilterCategory
import org.springframework.core.convert.converter.Converter

private val productFilterCategories = ProductFilterCategory.entries

class ProductFilterCategoryConverter : Converter<String, ProductFilterCategory> {

override fun convert(source: String): ProductFilterCategory {
return productFilterCategories.firstOrNull { it.name.lowercase() == source }
?: throw IllegalArgumentException("지원하지 않는 카테고리 입니다. category: $source")
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package backend.itracker.tracker.config

import backend.itracker.tracker.common.converter.OauthServerTypeConverter
import backend.itracker.tracker.common.converter.ProductCategoryConverter
import backend.itracker.tracker.common.converter.ProductFilterCategoryConverter
import org.springframework.context.annotation.Configuration
import org.springframework.format.FormatterRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
Expand All @@ -10,7 +10,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
class WebMvcConfig : WebMvcConfigurer {

override fun addFormatters(registry: FormatterRegistry) {
registry.addConverter(ProductCategoryConverter())
registry.addConverter(ProductFilterCategoryConverter())
registry.addConverter(OauthServerTypeConverter())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package backend.itracker.tracker.coupang.controller

import backend.itracker.crawl.airpods.service.AirPodsService
import backend.itracker.crawl.common.PartnersLinkInfo
import backend.itracker.crawl.common.ProductCategory
import backend.itracker.crawl.common.ProductFilterCategory
import backend.itracker.crawl.macbook.service.MacbookService
import backend.itracker.tracker.coupang.service.CoupangPartnersService
import org.springframework.http.ResponseEntity
Expand All @@ -20,18 +20,18 @@ class CoupangPartnersController(

@PatchMapping("/api/v1/coupang/deeplink/{category}")
fun updatePartnersLink(
@PathVariable category: ProductCategory,
@PathVariable category: ProductFilterCategory,
@RequestParam start: Long,
@RequestParam end: Long,
): ResponseEntity<Unit> {
return when (category) {
ProductCategory.MACBOOK_AIR, ProductCategory.MACBOOK_PRO -> {
ProductFilterCategory.MACBOOK_AIR, ProductFilterCategory.MACBOOK_PRO -> {
val partnersLink = coupangPartnersService.updateAllMacbookPartnersLink(start, end)
macbookService.updateAllPartnersLink(partnersLink.map { PartnersLinkInfo(it.originalUrl, it.shortenUrl)})
ResponseEntity.ok().build()
}

ProductCategory.AIRPODS -> {
ProductFilterCategory.AIRPODS -> {
val partnersLink = coupangPartnersService.updateAllAirPodsPartnersLink(start, end)
airPodsService.updateAllPartnersLink(partnersLink.map { PartnersLinkInfo(it.originalUrl, it.shortenUrl)})
ResponseEntity.ok().build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ data class KakaoMemberResponse(
return Member(
oauthId = OauthId(id.toString(), OauthServerType.KAKAO),
nickname = kakaoAccount.profile.nickname,
phoneNumber = kakaoAccount.phoneNumber ?: "01000000000",
profileImage = kakaoAccount.profile.profileImageUrl,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ import backend.itracker.tracker.member.service.handler.response.CommonFavoritePr
import backend.itracker.tracker.resolver.LoginMember
import org.springframework.data.domain.PageRequest
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.ModelAttribute
import org.springframework.web.bind.annotation.PatchMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.bind.annotation.*

private const val FAVORITE_DEFAULT_SIZE = 6

Expand All @@ -32,7 +28,7 @@ class FavoriteController(
val favoriteInfo = request.toFavoriteInfo()
val favorite = Favorite(
member = member,
product = FavoriteProduct(productId = favoriteInfo.productId, productCategory = favoriteInfo.category)
product = FavoriteProduct.of(favoriteInfo.productId, favoriteInfo.category)
)
favoriteService.patchFavorite(favorite)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package backend.itracker.tracker.member.controller.request

import backend.itracker.crawl.common.ProductCategory
import backend.itracker.crawl.common.ProductFilterCategory
import backend.itracker.tracker.member.service.vo.FavoriteInfo

data class FavoritePatchRequest(
Expand All @@ -12,7 +12,7 @@ data class FavoritePatchRequest(
{
return FavoriteInfo(
productId = productId,
category = ProductCategory.valueOf(productCategory.uppercase())
category = ProductFilterCategory.valueOf(productCategory.uppercase())
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package backend.itracker.tracker.member.domain

import backend.itracker.crawl.common.ProductCategory
import backend.itracker.crawl.common.ProductFilterCategory
import jakarta.persistence.Embeddable
import jakarta.persistence.EnumType
import jakarta.persistence.Enumerated
Expand All @@ -14,6 +15,12 @@ class FavoriteProduct(
val productCategory: ProductCategory,
) {

companion object {
fun of(productId: Long, productFilterCategory: ProductFilterCategory): FavoriteProduct {
return FavoriteProduct(productId, ProductCategory.from(productFilterCategory))
}
}

override fun toString(): String {
return "FavoriteProduct(productId=$productId, productCategory=$productCategory)"
}
Expand Down
14 changes: 4 additions & 10 deletions src/main/kotlin/backend/itracker/tracker/member/domain/Member.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,7 @@ package backend.itracker.tracker.member.domain
import backend.itracker.crawl.common.BaseEntity
import backend.itracker.tracker.oauth.OauthId
import backend.itracker.tracker.oauth.OauthServerType
import jakarta.persistence.Column
import jakarta.persistence.Embedded
import jakarta.persistence.Entity
import jakarta.persistence.EnumType
import jakarta.persistence.Enumerated
import jakarta.persistence.FetchType
import jakarta.persistence.OneToMany
import jakarta.persistence.Table
import jakarta.persistence.UniqueConstraint
import jakarta.persistence.*

@Entity
@Table(
Expand All @@ -26,6 +18,7 @@ class Member(
val oauthId: OauthId,

var nickname: String,
val phoneNumber: String,

@Column(columnDefinition = "text")
var profileImage: String,
Expand All @@ -47,13 +40,14 @@ class Member(
fun isAnonymous() = this.id == 0L

override fun toString(): String {
return "Member(id='$id' oauthId=$oauthId, nickname='$nickname', profileImage='$profileImage', authType=$authType)"
return "Member(oauthId=$oauthId, nickname='$nickname', phoneNumber='$phoneNumber', profileImage='$profileImage', authType=$authType, favorites=$favorites)"
}

companion object {
fun anonymous() = Member(
oauthId = OauthId("anonymous", OauthServerType.KAKAO),
nickname = "익명",
phoneNumber = "01012345678",
profileImage = "익명",
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,13 @@ interface FavoriteRepository : JpaRepository<Favorite, Long> {
): Optional<Favorite>

fun findAllByMember(member: Member, pageable: Pageable): Page<Favorite>

@Query(
"""
select count(f)
from Favorite f
where f.product = :product
"""
)
fun findCountByProduct(@Param("product") favoriteProduct: FavoriteProduct): Long
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package backend.itracker.tracker.member.service

import backend.itracker.tracker.member.domain.Favorite
import backend.itracker.tracker.member.domain.FavoriteProduct
import backend.itracker.tracker.member.domain.Member
import backend.itracker.tracker.member.domain.repository.FavoriteRepository
import backend.itracker.tracker.member.service.handler.FavoriteComposite
import backend.itracker.tracker.member.service.handler.response.CommonFavoriteProductModel
import backend.itracker.tracker.member.service.vo.FavoriteCount
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageImpl
import org.springframework.data.domain.Pageable
Expand Down Expand Up @@ -43,4 +45,16 @@ class FavoriteService(

return PageImpl(productsContents, pageFavorites.pageable, productsContents.size.toLong())
}

@Transactional(readOnly = true)
fun findFavoritesCountByFavoriteProduct(
favoriteProduct: FavoriteProduct
): FavoriteCount {
val count = favoriteRepository.findCountByProduct(favoriteProduct)
return FavoriteCount(
productId = favoriteProduct.productId,
category = favoriteProduct.productCategory,
count = count
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,9 @@ class MemberService(
fun getByOauthId(oauthId: OauthId): Member {
return memberRepository.getByOauthId(oauthId)
}

@Transactional(readOnly = true)
fun isDuplicatedPhoneNumber(phoneNumber: String): Boolean {
return memberRepository.isDuplicatedPhoneNumber(phoneNumber)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ package backend.itracker.tracker.member.service.handler.airpods
import backend.itracker.crawl.airpods.service.AirPodsService
import backend.itracker.crawl.common.ProductCategory
import backend.itracker.tracker.member.domain.Favorite
import backend.itracker.tracker.member.domain.repository.FavoriteRepository
import backend.itracker.tracker.member.service.handler.FavoriteHandleable
import backend.itracker.tracker.member.service.handler.response.AirpodsFavoriteResponse
import backend.itracker.tracker.member.service.handler.response.CommonFavoriteProductModel
import org.springframework.stereotype.Component

@Component
class FavoriteAirpodsHandler(
private val airpodsService: AirPodsService
private val airpodsService: AirPodsService,
private val favoriteRepository: FavoriteRepository,
) : FavoriteHandleable {

override fun supports(category: ProductCategory): Boolean {
return ProductCategory.AIRPODS == category
}
Expand All @@ -24,7 +27,9 @@ class FavoriteAirpodsHandler(
val favorite = favorites.find { it.product.productId == airpod.id }
?: throw IllegalStateException("찜한 상품을 찾을 수 없습니다.")

AirpodsFavoriteResponse.of(airpod, favorite)
val notificationCount =
favoriteRepository.findCountByProduct(favorite.product)
AirpodsFavoriteResponse.of(airpod, notificationCount, favorite)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@ package backend.itracker.tracker.member.service.handler.macbook
import backend.itracker.crawl.common.ProductCategory
import backend.itracker.crawl.macbook.service.MacbookService
import backend.itracker.tracker.member.domain.Favorite
import backend.itracker.tracker.member.domain.repository.FavoriteRepository
import backend.itracker.tracker.member.service.handler.FavoriteHandleable
import backend.itracker.tracker.member.service.handler.response.CommonFavoriteProductModel
import backend.itracker.tracker.member.service.handler.response.MacbookFavoriteResponse
import org.springframework.stereotype.Component

@Component
class FavoriteMacbookHandler(
private val macbookService: MacbookService
private val macbookService: MacbookService,
private val favoriteRepository: FavoriteRepository,
) : FavoriteHandleable {

override fun supports(category: ProductCategory): Boolean {
return category == ProductCategory.MACBOOK_PRO || category == ProductCategory.MACBOOK_AIR
return category == ProductCategory.MACBOOK
}

override fun findAllByIds(favorites: List<Favorite>): List<CommonFavoriteProductModel> {
Expand All @@ -24,7 +27,10 @@ class FavoriteMacbookHandler(
val favorite = favorites.find { it.product.productId == macbook.id }
?: throw IllegalStateException("찜한 상품을 찾을 수 없습니다.")

MacbookFavoriteResponse.of(macbook, favorite)
val notificationCount =
favoriteRepository.findCountByProduct(favorite.product)

MacbookFavoriteResponse.of(macbook, notificationCount, favorite)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ class AirpodsFavoriteResponse(
val currentPrice: BigDecimal,
val isOutOfStock: Boolean,

notificationCount: Long,
createdAt: LocalDateTime
): CommonFavoriteProductModel(createdAt){
): CommonFavoriteProductModel(notificationCount, createdAt){

companion object {
fun of(airPods: AirPods, favorite: Favorite): AirpodsFavoriteResponse {
fun of(airPods: AirPods, notificationCount: Long, favorite: Favorite): AirpodsFavoriteResponse {
val name = when (airPods.category) {
AirPodsCategory.AIRPODS -> "에어팟"
AirPodsCategory.AIRPODS_PRO -> "에어팟 프로"
Expand All @@ -43,6 +44,7 @@ class AirpodsFavoriteResponse(
discountPercentage = airPods.findDiscountPercentage(),
currentPrice = airPods.findCurrentPrice(),
isOutOfStock = airPods.isOutOfStock(),
notificationCount = notificationCount,
createdAt = favorite.createdAt
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore
import java.time.LocalDateTime

abstract class CommonFavoriteProductModel(
val notificationCount: Long,

@JsonIgnore
val createdAt: LocalDateTime
)
Loading
Loading