Skip to content

Commit

Permalink
Merge pull request #97 from everymeals/feature/withdraw
Browse files Browse the repository at this point in the history
[feature/withdraw] 신고하기 플로우 구현 및 리뷰조회 api 연결
  • Loading branch information
SsongSik authored Feb 8, 2024
2 parents e37c8ce + 8046695 commit fb8ee59
Show file tree
Hide file tree
Showing 27 changed files with 665 additions and 207 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
package com.everymeal.data.datasource.review

import androidx.paging.PagingData
import com.everymeal.data.model.review.ReviewListResponse
import com.everymeal.data.model.review.ReviewResponse
import com.everymeal.data.model.review.StoreReviewRequest
import com.everymeal.domain.model.review.GetStoreReviewEntity
import kotlinx.coroutines.flow.Flow

interface ReviewDataSource {
suspend fun getReviewList(
cursorIdx: Int,
mealIdx: Int,
pageSize: Int,

suspend fun getPagingStoreReviews(
order: String?,
group: String?,
grade: Int?,
campusIdx: Int,
): Flow<PagingData<ReviewResponse>>

suspend fun getStoreReviews(
offset: Int,
limit: Int,
order: String?,
group: String?,
grade: Int?,
campusIdx: Int,
): Result<ReviewListResponse>

suspend fun postReview(storeReviewRequest: StoreReviewRequest): Result<Boolean>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,54 @@
package com.everymeal.data.datasource.review

import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.everymeal.data.datasource.restaurant.PAGING_SIZE
import com.everymeal.data.model.review.ReviewListResponse
import com.everymeal.data.model.review.ReviewResponse
import com.everymeal.data.model.review.StoreReviewRequest
import com.everymeal.data.model.unwrapRunCatching
import com.everymeal.data.service.review.StoreReviewApi
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject

class ReviewDataSourceImpl @Inject constructor(
private val storeReviewApi: StoreReviewApi,
) : ReviewDataSource {
override suspend fun getPagingStoreReviews(
order: String?,
group: String?,
grade: Int?,
campusIdx: Int
): Flow<PagingData<ReviewResponse>> {
val pagingSourceFactory = { ReviewPagingSource(storeReviewApi, order, group, grade, campusIdx) }
return Pager(
config = PagingConfig(
initialLoadSize = PAGING_SIZE,
pageSize = PAGING_SIZE,
enablePlaceholders = false,
),
pagingSourceFactory = pagingSourceFactory
).flow
}

override suspend fun getReviewList(
cursorIdx: Int,
mealIdx: Int,
pageSize: Int,
): Result<ReviewListResponse> =
unwrapRunCatching {
storeReviewApi.getStoreReviewsWithId(
cursorIdx,
mealIdx,
pageSize,
)
}
override suspend fun getStoreReviews(
offset: Int,
limit: Int,
order: String?,
group: String?,
grade: Int?,
campusIdx: Int
): Result<ReviewListResponse> {
return unwrapRunCatching { storeReviewApi.getStoresReviews(
offset = 0,
limit = 3,
order = order,
group = group,
grade = grade,
campusIdx = campusIdx
) }
}

override suspend fun postReview(
storeReviewRequest: StoreReviewRequest,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.everymeal.data.datasource.review

import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.everymeal.data.datasource.restaurant.PAGING_SIZE
import com.everymeal.data.datasource.restaurant.STARTING_PAGE_INDEX
import com.everymeal.data.model.restaruant.RestaurantResponse
import com.everymeal.data.model.review.ReviewResponse
import com.everymeal.data.service.restaurant.RestaurantApi
import com.everymeal.data.service.review.StoreReviewApi
import retrofit2.HttpException
import java.io.IOException

class ReviewPagingSource (
private val storeReviewApi: StoreReviewApi,
private val order: String?,
private val group: String?,
private val grade: Int?,
private val campusIdx: Int
) : PagingSource<Int, ReviewResponse>() {
override fun getRefreshKey(state: PagingState<Int, ReviewResponse>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ReviewResponse> {
val position = params.key ?: STARTING_PAGE_INDEX

return try {
val response = storeReviewApi.getStoresReviews(
campusIdx = campusIdx,
order = order,
group = group,
grade = grade,
offset = position,
limit = PAGING_SIZE
)
val restaurants = response.data.content
LoadResult.Page(
data = restaurants,
prevKey = if (position == STARTING_PAGE_INDEX) null else position - 1,
nextKey = if (restaurants.isEmpty()) null else position + 1
)
} catch (exception: IOException) {
LoadResult.Error(exception)
} catch (exception: HttpException) {
LoadResult.Error(exception)
}
}

}
Original file line number Diff line number Diff line change
@@ -1,54 +1,75 @@
package com.everymeal.data.model.review


import com.everymeal.domain.model.review.Review
import kotlinx.serialization.SerialName
import com.everymeal.domain.model.review.GetStoreReviewEntity
import com.everymeal.domain.model.review.StoreReviewEntity
import kotlinx.serialization.Serializable

@Serializable
data class ReviewListResponse(
@SerialName("reviewPagingList")
val reviewPagingList: List<ReviewPaging>? = null,
@SerialName("reviewTotalCnt")
val reviewTotalCnt: Int? = null
) {
@Serializable
data class ReviewPaging(
@SerialName("content")
val content: String? = null,
@SerialName("grade")
val grade: Int? = null,
@SerialName("imageList")
val imageList: List<String>? = null,
@SerialName("mealCategory")
val mealCategory: String? = null,
@SerialName("mealType")
val mealType: String? = null,
@SerialName("restaurantName")
val restaurantName: String? = null,
@SerialName("reviewIdx")
val reviewIdx: Int? = null,
@SerialName("reviewMarksCnt")
val reviewMarksCnt: Int? = null
) {
fun toReviewDetail(): Review.ReviewDetail {
return Review.ReviewDetail(
content = content ?: "",
grade = grade ?: 0,
imageList = imageList ?: listOf(),
mealCategory = mealCategory ?: "",
mealType = mealType ?: "",
restaurantName = restaurantName ?: "",
reviewIdx = reviewIdx ?: 0,
reviewMarksCnt = reviewMarksCnt ?: 0
)
}
}

fun toReview(): Review {
return Review(
reviewPagingList = reviewPagingList?.map { it.toReviewDetail() } ?: listOf(),
reviewTotalCnt = reviewTotalCnt ?: 0
)
}
val content: List<ReviewResponse>,
val pageable: Pageable,
val totalPages: Int,
val totalElements: Int,
val last: Boolean,
val size: Int,
val number: Int,
val sort: Sort,
val numberOfElements: Int,
val first: Boolean,
val empty: Boolean,
)

@Serializable
data class ReviewResponse(
val reviewIdx: Int,
val content: String,
val grade: Int,
val createdAt: String,
val formattedCreatedAt: String,
val nickName: String,
val profileImageUrl: String,
val reviewMarksCnt: Int,
val images: List<String>?,
val storeIdx: Int,
val storeName: String,
)

@Serializable
data class Pageable(
val sort: Sort,
val offset: Int,
val pageNumber: Int,
val pageSize: Int,
val paged: Boolean,
val unpaged: Boolean,
)

@Serializable
data class Sort(
val empty: Boolean,
val sorted: Boolean,
val unsorted: Boolean,
)

fun ReviewResponse.toStoreReviewEntity(): StoreReviewEntity {
return StoreReviewEntity(
reviewIdx = this.reviewIdx,
content = this.content,
grade = this.grade,
createdAt = this.createdAt,
formattedCreatedAt = this.formattedCreatedAt,
nickName = this.nickName,
profileImageUrl = this.profileImageUrl,
reviewMarksCnt = this.reviewMarksCnt,
images = this.images,
storeIdx = this.storeIdx,
storeName = this.storeName,
)
}

fun ReviewListResponse.toStoreReviewEntityList(): GetStoreReviewEntity {
return GetStoreReviewEntity(
data = this.content.map { it.toStoreReviewEntity() }
)
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,57 @@
package com.everymeal.data.repository.review

import androidx.paging.PagingData
import androidx.paging.map
import com.everymeal.data.datasource.review.ReviewDataSource
import com.everymeal.data.model.restaruant.toRestaurant
import com.everymeal.data.model.review.toReviewRequest
import com.everymeal.data.model.review.toStoreReviewEntity
import com.everymeal.data.model.review.toStoreReviewEntityList
import com.everymeal.domain.model.review.GetStoreReviewEntity
import com.everymeal.domain.model.review.Review
import com.everymeal.domain.model.review.StoreReviewEntity
import com.everymeal.domain.model.review.UserReview
import com.everymeal.domain.repository.review.ReviewRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject

class DefaultReviewRepository @Inject constructor(
private val reviewDataSource: ReviewDataSource,
) : ReviewRepository {
override suspend fun getReviewList(
cursorIdx: Int,
mealIdx: Int,
pageSize: Int,
): Result<Review> =
reviewDataSource.getReviewList(cursorIdx, mealIdx, pageSize).map {
it.toReview()
override suspend fun getPagingStoreReviews(
order: String?,
group: String?,
grade: Int?,
campusIdx: Int
): Flow<PagingData<StoreReviewEntity>> {
return reviewDataSource.getPagingStoreReviews(
order,
group,
grade,
campusIdx
).map { pagingData ->
pagingData.map { it.toStoreReviewEntity() }
}
}

override suspend fun getStoreReviews(
offset: Int,
limit: Int,
order: String?,
group: String?,
grade: Int?,
campusIdx: Int,
): Result<GetStoreReviewEntity> {
return reviewDataSource.getStoreReviews(
offset,
limit,
order,
group,
grade,
campusIdx
).map { it.toStoreReviewEntityList() }
}

override suspend fun postReview(
userReview: UserReview,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@ import retrofit2.http.POST
import retrofit2.http.Query

interface StoreReviewApi {
@GET("/api/v1/stores/{index}/reviews")
suspend fun getStoreReviewsWithId(
@Query("index") index: Int,
@Query("offset") offset: Int,
@Query("limit") limit: Int,
): BaseResponse<ReviewListResponse>
// @GET("/api/v1/stores/{index}/reviews")
// suspend fun getStoreReviewsWithId(
// @Query("index") index: Int,
// @Query("offset") offset: Int,
// @Query("limit") limit: Int,
// ): BaseResponse<ReviewListResponse>

@GET("/api/v1/stores/reviews")
suspend fun getStoresReviews(
@Query("offset") offset: Int,
@Query("limit") limit: Int,
@Query("order") order: String,
@Query("group") group: String,
@Query("grade") grade: Int,
@Query("order") order: String?,
@Query("group") group: String?,
@Query("grade") grade: Int?,
@Query("campusIdx") campusIdx: Int,
): BaseResponse<ReviewListResponse>

@POST("/api/v1/reviews/store")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.everymeal.domain.model.review

data class GetStoreReviewEntity(
val data: List<StoreReviewEntity>
)

data class StoreReviewEntity(
val reviewIdx: Int,
val content: String,
val grade: Int,
val createdAt: String,
val formattedCreatedAt: String,
val nickName: String,
val profileImageUrl: String,
val reviewMarksCnt: Int,
val images: List<String>?,
val storeIdx: Int,
val storeName: String,
)
Loading

0 comments on commit fb8ee59

Please sign in to comment.