Skip to content

Commit fb8ee59

Browse files
authored
Merge pull request #97 from everymeals/feature/withdraw
[feature/withdraw] 신고하기 플로우 구현 및 리뷰조회 api 연결
2 parents e37c8ce + 8046695 commit fb8ee59

File tree

27 files changed

+665
-207
lines changed

27 files changed

+665
-207
lines changed

data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSource.kt

+19-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,28 @@
11
package com.everymeal.data.datasource.review
22

3+
import androidx.paging.PagingData
34
import com.everymeal.data.model.review.ReviewListResponse
5+
import com.everymeal.data.model.review.ReviewResponse
46
import com.everymeal.data.model.review.StoreReviewRequest
7+
import com.everymeal.domain.model.review.GetStoreReviewEntity
8+
import kotlinx.coroutines.flow.Flow
59

610
interface ReviewDataSource {
7-
suspend fun getReviewList(
8-
cursorIdx: Int,
9-
mealIdx: Int,
10-
pageSize: Int,
11+
12+
suspend fun getPagingStoreReviews(
13+
order: String?,
14+
group: String?,
15+
grade: Int?,
16+
campusIdx: Int,
17+
): Flow<PagingData<ReviewResponse>>
18+
19+
suspend fun getStoreReviews(
20+
offset: Int,
21+
limit: Int,
22+
order: String?,
23+
group: String?,
24+
grade: Int?,
25+
campusIdx: Int,
1126
): Result<ReviewListResponse>
1227

1328
suspend fun postReview(storeReviewRequest: StoreReviewRequest): Result<Boolean>

data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSourceImpl.kt

+39-12
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,54 @@
11
package com.everymeal.data.datasource.review
22

3+
import androidx.paging.Pager
4+
import androidx.paging.PagingConfig
5+
import androidx.paging.PagingData
6+
import com.everymeal.data.datasource.restaurant.PAGING_SIZE
37
import com.everymeal.data.model.review.ReviewListResponse
8+
import com.everymeal.data.model.review.ReviewResponse
49
import com.everymeal.data.model.review.StoreReviewRequest
510
import com.everymeal.data.model.unwrapRunCatching
611
import com.everymeal.data.service.review.StoreReviewApi
12+
import kotlinx.coroutines.flow.Flow
713
import javax.inject.Inject
814

915
class ReviewDataSourceImpl @Inject constructor(
1016
private val storeReviewApi: StoreReviewApi,
1117
) : ReviewDataSource {
18+
override suspend fun getPagingStoreReviews(
19+
order: String?,
20+
group: String?,
21+
grade: Int?,
22+
campusIdx: Int
23+
): Flow<PagingData<ReviewResponse>> {
24+
val pagingSourceFactory = { ReviewPagingSource(storeReviewApi, order, group, grade, campusIdx) }
25+
return Pager(
26+
config = PagingConfig(
27+
initialLoadSize = PAGING_SIZE,
28+
pageSize = PAGING_SIZE,
29+
enablePlaceholders = false,
30+
),
31+
pagingSourceFactory = pagingSourceFactory
32+
).flow
33+
}
1234

13-
override suspend fun getReviewList(
14-
cursorIdx: Int,
15-
mealIdx: Int,
16-
pageSize: Int,
17-
): Result<ReviewListResponse> =
18-
unwrapRunCatching {
19-
storeReviewApi.getStoreReviewsWithId(
20-
cursorIdx,
21-
mealIdx,
22-
pageSize,
23-
)
24-
}
35+
override suspend fun getStoreReviews(
36+
offset: Int,
37+
limit: Int,
38+
order: String?,
39+
group: String?,
40+
grade: Int?,
41+
campusIdx: Int
42+
): Result<ReviewListResponse> {
43+
return unwrapRunCatching { storeReviewApi.getStoresReviews(
44+
offset = 0,
45+
limit = 3,
46+
order = order,
47+
group = group,
48+
grade = grade,
49+
campusIdx = campusIdx
50+
) }
51+
}
2552

2653
override suspend fun postReview(
2754
storeReviewRequest: StoreReviewRequest,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.everymeal.data.datasource.review
2+
3+
import androidx.paging.PagingSource
4+
import androidx.paging.PagingState
5+
import com.everymeal.data.datasource.restaurant.PAGING_SIZE
6+
import com.everymeal.data.datasource.restaurant.STARTING_PAGE_INDEX
7+
import com.everymeal.data.model.restaruant.RestaurantResponse
8+
import com.everymeal.data.model.review.ReviewResponse
9+
import com.everymeal.data.service.restaurant.RestaurantApi
10+
import com.everymeal.data.service.review.StoreReviewApi
11+
import retrofit2.HttpException
12+
import java.io.IOException
13+
14+
class ReviewPagingSource (
15+
private val storeReviewApi: StoreReviewApi,
16+
private val order: String?,
17+
private val group: String?,
18+
private val grade: Int?,
19+
private val campusIdx: Int
20+
) : PagingSource<Int, ReviewResponse>() {
21+
override fun getRefreshKey(state: PagingState<Int, ReviewResponse>): Int? {
22+
return state.anchorPosition?.let { anchorPosition ->
23+
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
24+
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
25+
}
26+
}
27+
28+
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, ReviewResponse> {
29+
val position = params.key ?: STARTING_PAGE_INDEX
30+
31+
return try {
32+
val response = storeReviewApi.getStoresReviews(
33+
campusIdx = campusIdx,
34+
order = order,
35+
group = group,
36+
grade = grade,
37+
offset = position,
38+
limit = PAGING_SIZE
39+
)
40+
val restaurants = response.data.content
41+
LoadResult.Page(
42+
data = restaurants,
43+
prevKey = if (position == STARTING_PAGE_INDEX) null else position - 1,
44+
nextKey = if (restaurants.isEmpty()) null else position + 1
45+
)
46+
} catch (exception: IOException) {
47+
LoadResult.Error(exception)
48+
} catch (exception: HttpException) {
49+
LoadResult.Error(exception)
50+
}
51+
}
52+
53+
}
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,75 @@
11
package com.everymeal.data.model.review
22

33

4-
import com.everymeal.domain.model.review.Review
5-
import kotlinx.serialization.SerialName
4+
import com.everymeal.domain.model.review.GetStoreReviewEntity
5+
import com.everymeal.domain.model.review.StoreReviewEntity
66
import kotlinx.serialization.Serializable
77

88
@Serializable
99
data class ReviewListResponse(
10-
@SerialName("reviewPagingList")
11-
val reviewPagingList: List<ReviewPaging>? = null,
12-
@SerialName("reviewTotalCnt")
13-
val reviewTotalCnt: Int? = null
14-
) {
15-
@Serializable
16-
data class ReviewPaging(
17-
@SerialName("content")
18-
val content: String? = null,
19-
@SerialName("grade")
20-
val grade: Int? = null,
21-
@SerialName("imageList")
22-
val imageList: List<String>? = null,
23-
@SerialName("mealCategory")
24-
val mealCategory: String? = null,
25-
@SerialName("mealType")
26-
val mealType: String? = null,
27-
@SerialName("restaurantName")
28-
val restaurantName: String? = null,
29-
@SerialName("reviewIdx")
30-
val reviewIdx: Int? = null,
31-
@SerialName("reviewMarksCnt")
32-
val reviewMarksCnt: Int? = null
33-
) {
34-
fun toReviewDetail(): Review.ReviewDetail {
35-
return Review.ReviewDetail(
36-
content = content ?: "",
37-
grade = grade ?: 0,
38-
imageList = imageList ?: listOf(),
39-
mealCategory = mealCategory ?: "",
40-
mealType = mealType ?: "",
41-
restaurantName = restaurantName ?: "",
42-
reviewIdx = reviewIdx ?: 0,
43-
reviewMarksCnt = reviewMarksCnt ?: 0
44-
)
45-
}
46-
}
47-
48-
fun toReview(): Review {
49-
return Review(
50-
reviewPagingList = reviewPagingList?.map { it.toReviewDetail() } ?: listOf(),
51-
reviewTotalCnt = reviewTotalCnt ?: 0
52-
)
53-
}
10+
val content: List<ReviewResponse>,
11+
val pageable: Pageable,
12+
val totalPages: Int,
13+
val totalElements: Int,
14+
val last: Boolean,
15+
val size: Int,
16+
val number: Int,
17+
val sort: Sort,
18+
val numberOfElements: Int,
19+
val first: Boolean,
20+
val empty: Boolean,
21+
)
22+
23+
@Serializable
24+
data class ReviewResponse(
25+
val reviewIdx: Int,
26+
val content: String,
27+
val grade: Int,
28+
val createdAt: String,
29+
val formattedCreatedAt: String,
30+
val nickName: String,
31+
val profileImageUrl: String,
32+
val reviewMarksCnt: Int,
33+
val images: List<String>?,
34+
val storeIdx: Int,
35+
val storeName: String,
36+
)
37+
38+
@Serializable
39+
data class Pageable(
40+
val sort: Sort,
41+
val offset: Int,
42+
val pageNumber: Int,
43+
val pageSize: Int,
44+
val paged: Boolean,
45+
val unpaged: Boolean,
46+
)
47+
48+
@Serializable
49+
data class Sort(
50+
val empty: Boolean,
51+
val sorted: Boolean,
52+
val unsorted: Boolean,
53+
)
54+
55+
fun ReviewResponse.toStoreReviewEntity(): StoreReviewEntity {
56+
return StoreReviewEntity(
57+
reviewIdx = this.reviewIdx,
58+
content = this.content,
59+
grade = this.grade,
60+
createdAt = this.createdAt,
61+
formattedCreatedAt = this.formattedCreatedAt,
62+
nickName = this.nickName,
63+
profileImageUrl = this.profileImageUrl,
64+
reviewMarksCnt = this.reviewMarksCnt,
65+
images = this.images,
66+
storeIdx = this.storeIdx,
67+
storeName = this.storeName,
68+
)
69+
}
70+
71+
fun ReviewListResponse.toStoreReviewEntityList(): GetStoreReviewEntity {
72+
return GetStoreReviewEntity(
73+
data = this.content.map { it.toStoreReviewEntity() }
74+
)
5475
}

data/src/main/java/com/everymeal/data/repository/review/DefaultReviewRepository.kt

+41-7
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,57 @@
11
package com.everymeal.data.repository.review
22

3+
import androidx.paging.PagingData
4+
import androidx.paging.map
35
import com.everymeal.data.datasource.review.ReviewDataSource
6+
import com.everymeal.data.model.restaruant.toRestaurant
47
import com.everymeal.data.model.review.toReviewRequest
8+
import com.everymeal.data.model.review.toStoreReviewEntity
9+
import com.everymeal.data.model.review.toStoreReviewEntityList
10+
import com.everymeal.domain.model.review.GetStoreReviewEntity
511
import com.everymeal.domain.model.review.Review
12+
import com.everymeal.domain.model.review.StoreReviewEntity
613
import com.everymeal.domain.model.review.UserReview
714
import com.everymeal.domain.repository.review.ReviewRepository
15+
import kotlinx.coroutines.flow.Flow
16+
import kotlinx.coroutines.flow.map
817
import javax.inject.Inject
918

1019
class DefaultReviewRepository @Inject constructor(
1120
private val reviewDataSource: ReviewDataSource,
1221
) : ReviewRepository {
13-
override suspend fun getReviewList(
14-
cursorIdx: Int,
15-
mealIdx: Int,
16-
pageSize: Int,
17-
): Result<Review> =
18-
reviewDataSource.getReviewList(cursorIdx, mealIdx, pageSize).map {
19-
it.toReview()
22+
override suspend fun getPagingStoreReviews(
23+
order: String?,
24+
group: String?,
25+
grade: Int?,
26+
campusIdx: Int
27+
): Flow<PagingData<StoreReviewEntity>> {
28+
return reviewDataSource.getPagingStoreReviews(
29+
order,
30+
group,
31+
grade,
32+
campusIdx
33+
).map { pagingData ->
34+
pagingData.map { it.toStoreReviewEntity() }
2035
}
36+
}
37+
38+
override suspend fun getStoreReviews(
39+
offset: Int,
40+
limit: Int,
41+
order: String?,
42+
group: String?,
43+
grade: Int?,
44+
campusIdx: Int,
45+
): Result<GetStoreReviewEntity> {
46+
return reviewDataSource.getStoreReviews(
47+
offset,
48+
limit,
49+
order,
50+
group,
51+
grade,
52+
campusIdx
53+
).map { it.toStoreReviewEntityList() }
54+
}
2155

2256
override suspend fun postReview(
2357
userReview: UserReview,

data/src/main/java/com/everymeal/data/service/review/StoreReviewApi.kt

+10-9
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,21 @@ import retrofit2.http.POST
99
import retrofit2.http.Query
1010

1111
interface StoreReviewApi {
12-
@GET("/api/v1/stores/{index}/reviews")
13-
suspend fun getStoreReviewsWithId(
14-
@Query("index") index: Int,
15-
@Query("offset") offset: Int,
16-
@Query("limit") limit: Int,
17-
): BaseResponse<ReviewListResponse>
12+
// @GET("/api/v1/stores/{index}/reviews")
13+
// suspend fun getStoreReviewsWithId(
14+
// @Query("index") index: Int,
15+
// @Query("offset") offset: Int,
16+
// @Query("limit") limit: Int,
17+
// ): BaseResponse<ReviewListResponse>
1818

1919
@GET("/api/v1/stores/reviews")
2020
suspend fun getStoresReviews(
2121
@Query("offset") offset: Int,
2222
@Query("limit") limit: Int,
23-
@Query("order") order: String,
24-
@Query("group") group: String,
25-
@Query("grade") grade: Int,
23+
@Query("order") order: String?,
24+
@Query("group") group: String?,
25+
@Query("grade") grade: Int?,
26+
@Query("campusIdx") campusIdx: Int,
2627
): BaseResponse<ReviewListResponse>
2728

2829
@POST("/api/v1/reviews/store")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.everymeal.domain.model.review
2+
3+
data class GetStoreReviewEntity(
4+
val data: List<StoreReviewEntity>
5+
)
6+
7+
data class StoreReviewEntity(
8+
val reviewIdx: Int,
9+
val content: String,
10+
val grade: Int,
11+
val createdAt: String,
12+
val formattedCreatedAt: String,
13+
val nickName: String,
14+
val profileImageUrl: String,
15+
val reviewMarksCnt: Int,
16+
val images: List<String>?,
17+
val storeIdx: Int,
18+
val storeName: String,
19+
)

0 commit comments

Comments
 (0)