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

[feat] 스크랩 상품 등록 API 연결 #34

Merged
merged 5 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from 52 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
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package org.sopt.kream.data.datasource

import org.sopt.kream.data.model.response.ResponseProductDetailDto
import org.sopt.kream.data.model.response.ResponseRecommendProductDto
import org.sopt.kream.data.model.response.ResponseSearchProductDto
import org.sopt.kream.util.base.BaseResponse

interface ProductRemoteDataSource {
suspend fun getSearchProduct(findName: String): BaseResponse<ResponseSearchProductDto>

suspend fun getProductDetail(productId: Int): BaseResponse<ResponseProductDetailDto>

suspend fun getRecommendProduct(memberId: Int): BaseResponse<ResponseRecommendProductDto>

suspend fun postScrap(
memberId: Int,
productId: Int,
): BaseResponse<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package org.sopt.kream.data.datasourceimpl

import org.sopt.kream.data.ServicePool
import org.sopt.kream.data.datasource.ProductRemoteDataSource
import org.sopt.kream.data.model.request.RequestPostScrapDto
import org.sopt.kream.data.model.response.ResponseProductDetailDto
import org.sopt.kream.data.model.response.ResponseRecommendProductDto
import org.sopt.kream.data.model.response.ResponseSearchProductDto
import org.sopt.kream.util.base.BaseResponse

Expand All @@ -12,4 +14,11 @@ class ProductRemoteDataSourceImpl : ProductRemoteDataSource {
override suspend fun getSearchProduct(findName: String): BaseResponse<ResponseSearchProductDto> = productService.getSearchProduct(findName = findName)

override suspend fun getProductDetail(productId: Int): BaseResponse<ResponseProductDetailDto> = productService.getProductDetail(productId = productId)

override suspend fun getRecommendProduct(memberId: Int): BaseResponse<ResponseRecommendProductDto> = productService.getRecommendProduct(memberId = memberId)

override suspend fun postScrap(
memberId: Int,
productId: Int,
): BaseResponse<Unit> = productService.postScrap(memberId = memberId, request = RequestPostScrapDto(productId))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.sopt.kream.data.mapper

import org.sopt.kream.data.model.response.ResponseRecommendProductDto.ResponseForYouProductDto
import org.sopt.kream.domain.model.RecommendForYouProductModel

fun ResponseForYouProductDto.toRecommendForYouProductModel() =
RecommendForYouProductModel(
thumbnailUrl = this.thumbnailUrl,
brandTitle = this.brandTitle,
engTitle = this.engTitle,
price = this.price,
transactionCount = this.transactionCount,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sopt.kream.data.mapper

import org.sopt.kream.data.model.response.ResponseRecommendProductDto.ResponseJustDroppedProductDto
import org.sopt.kream.domain.model.RecommendJustDroppedProductModel

fun ResponseJustDroppedProductDto.toRecommendJustDroppedProductModel() =
RecommendJustDroppedProductModel(
thumbnailUrl = this.thumbnailUrl,
brandTitle = this.brandTitle,
engTitle = this.engTitle,
price = this.price,
transactionCount = this.transactionCount,
isScrap = this.isScrap,
isFast = this.isFast,
isFreeDeliver = this.isFreeDeliver,
isSave = this.isSave,
isCoupon = this.isCoupon,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.sopt.kream.data.mapper

import org.sopt.kream.data.model.response.ResponseRecommendProductDto
import org.sopt.kream.domain.model.RecommendProductModel

fun ResponseRecommendProductDto.toRecommendProductModel() =
RecommendProductModel(
recommendForYouProducts = this.forYouList.map { it.toRecommendForYouProductModel() },
recommendJustDroppedProducts = this.justDropList.map { it.toRecommendJustDroppedProductModel() },
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.sopt.kream.data.model.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class RequestPostScrapDto(
@SerialName("productId")
val productId: Int,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.sopt.kream.data.model.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseRecommendProductDto(
@SerialName("forYouList")
val forYouList: List<ResponseForYouProductDto>,
@SerialName("justDropList")
val justDropList: List<ResponseJustDroppedProductDto>,
) {
@Serializable
data class ResponseForYouProductDto(
@SerialName("thumbnailUrl")
val thumbnailUrl: String,
@SerialName("brandTitle")
val brandTitle: String,
@SerialName("engTitle")
val engTitle: String,
@SerialName("price")
val price: String,
@SerialName("transactionCount")
val transactionCount: String,
)

@Serializable
data class ResponseJustDroppedProductDto(
@SerialName("thumbnailUrl")
val thumbnailUrl: String,
@SerialName("brandTitle")
val brandTitle: String,
@SerialName("engTitle")
val engTitle: String,
@SerialName("price")
val price: String,
@SerialName("transactionCount")
val transactionCount: String,
@SerialName("isScrap")
val isScrap: Boolean,
@SerialName("isFast")
val isFast: Boolean,
@SerialName("isFreeDeliver")
val isFreeDeliver: Boolean,
@SerialName("isSave")
val isSave: Boolean,
@SerialName("isCoupon")
val isCoupon: Boolean,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package org.sopt.kream.data.repository

import org.sopt.kream.data.datasource.ProductRemoteDataSource
import org.sopt.kream.data.mapper.toProductDetailModel
import org.sopt.kream.data.mapper.toRecommendProductModel
import org.sopt.kream.data.mapper.toSearchProductModel
import org.sopt.kream.domain.model.ProductDetailModel
import org.sopt.kream.domain.model.RecommendProductModel
import org.sopt.kream.domain.model.SearchProductModel
import org.sopt.kream.domain.repository.ProductRepository

Expand All @@ -19,4 +21,17 @@ class ProductRepositoryImpl(
runCatching {
productRemoteDataSource.getProductDetail(productId = productId).data.toProductDetailModel()
}

override suspend fun getRecommendProduct(memberId: Int): Result<RecommendProductModel> =
runCatching {
productRemoteDataSource.getRecommendProduct(memberId = memberId).data.toRecommendProductModel()
}

override suspend fun postScrap(
memberId: Int,
productId: Int,
): Result<Unit> =
runCatching {
productRemoteDataSource.postScrap(memberId = memberId, productId = productId)
}
}
15 changes: 15 additions & 0 deletions app/src/main/java/org/sopt/kream/data/service/ProductService.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package org.sopt.kream.data.service

import org.sopt.kream.data.model.request.RequestPostScrapDto
import org.sopt.kream.data.model.response.ResponseProductDetailDto
import org.sopt.kream.data.model.response.ResponseRecommendProductDto
import org.sopt.kream.data.model.response.ResponseReleaseProductDto
import org.sopt.kream.data.model.response.ResponseSearchProductDto
import org.sopt.kream.util.base.BaseResponse
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query

Expand All @@ -32,6 +36,17 @@ interface ProductService {
@Header("memberId") userid: Int,
): BaseResponse<ResponseReleaseProductDto>

@GET("product/recommend")
suspend fun getRecommendProduct(
@Header("memberId") memberId: Int,
): BaseResponse<ResponseRecommendProductDto>

@POST("scrap")
suspend fun postScrap(
@Header("memberId") memberId: Int,
@Body request: RequestPostScrapDto,
): BaseResponse<Unit>

companion object {
const val MEMBER_ID = 1
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.kream.domain.model

data class RecommendForYouProductModel(
val thumbnailUrl: String,
val brandTitle: String,
val engTitle: String,
val price: String,
val transactionCount: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.sopt.kream.domain.model

data class RecommendJustDroppedProductModel(
val thumbnailUrl: String,
val brandTitle: String,
val engTitle: String,
val price: String,
val transactionCount: String,
val isScrap: Boolean,
val isFast: Boolean,
val isFreeDeliver: Boolean,
val isSave: Boolean,
val isCoupon: Boolean,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.sopt.kream.domain.model

data class RecommendProductModel(
val recommendForYouProducts: List<RecommendForYouProductModel>,
val recommendJustDroppedProducts: List<RecommendJustDroppedProductModel>,
)
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
package org.sopt.kream.domain.repository

import org.sopt.kream.domain.model.ProductDetailModel
import org.sopt.kream.domain.model.RecommendProductModel
import org.sopt.kream.domain.model.SearchProductModel

interface ProductRepository {
suspend fun getSearchProduct(findName: String): Result<SearchProductModel>

suspend fun getProductDetail(productId: Int): Result<ProductDetailModel>

suspend fun getRecommendProduct(memberId: Int): Result<RecommendProductModel>

suspend fun postScrap(
memberId: Int,
productId: Int,
): Result<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.sopt.kream.data.datasourceimpl.ProductRemoteDataSourceImpl
import org.sopt.kream.data.repository.DummyRepositoryImpl
import org.sopt.kream.data.repository.ProductRepositoryImpl
import org.sopt.kream.presentation.ui.dummy.DummyViewModel
import org.sopt.kream.presentation.ui.main.home.recommend.RecommendViewModel
import org.sopt.kream.presentation.ui.productdetail.ProductDetailViewModel
import org.sopt.kream.presentation.ui.search.SearchViewModel

Expand All @@ -18,6 +19,8 @@ class ViewModelFactory : ViewModelProvider.Factory {
return SearchViewModel(ProductRepositoryImpl(ProductRemoteDataSourceImpl())) as T
} else if (modelClass.isAssignableFrom(ProductDetailViewModel::class.java)) {
return ProductDetailViewModel(ProductRepositoryImpl(ProductRemoteDataSourceImpl())) as T
} else if (modelClass.isAssignableFrom(RecommendViewModel::class.java)) {
return RecommendViewModel(ProductRepositoryImpl(ProductRemoteDataSourceImpl())) as T
}
throw IllegalArgumentException("Unknown ViewModel Class")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.sopt.kream.presentation.model

import androidx.annotation.DrawableRes

data class InstagramModel(
@DrawableRes val image: Int,
val id: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.sopt.kream.presentation.ui.main.home.recommend

import androidx.recyclerview.widget.RecyclerView
import org.sopt.kream.databinding.ItemRecommendAdvertisementBinding

class RecommendAdvertisementViewHolder(
private val binding: ItemRecommendAdvertisementBinding,
) : RecyclerView.ViewHolder(binding.root) {
fun onBind(
item: Int,
) {
with(binding) {
ivRecommendAdvertisement.setImageResource(item)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.sopt.kream.presentation.ui.main.home.recommend

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import org.sopt.kream.databinding.ItemRecommendAdvertisementBinding

class RecommendAdvertisementViewPagerAdapter(private val data: List<Int>) : RecyclerView.Adapter<RecommendAdvertisementViewHolder>() {
private val item = data

override fun getItemCount(): Int = item.size

override fun onBindViewHolder(
holder: RecommendAdvertisementViewHolder,
position: Int,
) {
holder.onBind(item[position])
}

override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
): RecommendAdvertisementViewHolder {
val binding = ItemRecommendAdvertisementBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return RecommendAdvertisementViewHolder(binding)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.sopt.kream.presentation.ui.main.home.recommend

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import org.sopt.kream.databinding.ItemRecommendCircleMenuBinding
import org.sopt.kream.presentation.ui.type.RecommendCircleMenuType
import kotlin.enums.EnumEntries

class RecommendCircleMenuAdapter(private val list: EnumEntries<RecommendCircleMenuType>) : RecyclerView.Adapter<RecommendCircleMenuViewHolder>() {
private val item = list

override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
): RecommendCircleMenuViewHolder {
val binding = ItemRecommendCircleMenuBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return RecommendCircleMenuViewHolder(binding)
}

override fun onBindViewHolder(
holder: RecommendCircleMenuViewHolder,
position: Int,
) {
holder.onBind(item.get(position).menu)
}

override fun getItemCount(): Int = list.size
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.sopt.kream.presentation.ui.main.home.recommend

import androidx.recyclerview.widget.RecyclerView
import org.sopt.kream.databinding.ItemRecommendCircleMenuBinding

class RecommendCircleMenuViewHolder(
private val binding: ItemRecommendCircleMenuBinding,
) : RecyclerView.ViewHolder(binding.root) {
fun onBind(
item: Int,
) {
with(binding) {
tvCircleMenuTitle.setText(item)
}
}
}
Loading
Loading