Skip to content

Commit 199ac8c

Browse files
authored
merge #81 -> develop
[Feat/#81] 산책하기 리뷰 - 상세보기 정보, 카테고리, 데이터 post 까지 api 연동 완료
2 parents d40a8ed + a67853a commit 199ac8c

File tree

33 files changed

+730
-325
lines changed

33 files changed

+730
-325
lines changed

app/src/main/java/com/paw/key/core/util/PhotoUtils.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.paw.key.core.util
22

3+
import android.content.ContentResolver
34
import android.graphics.Bitmap
5+
import android.net.Uri
46
import android.util.Log
57
import okhttp3.MediaType.Companion.toMediaTypeOrNull
68
import okhttp3.MultipartBody
@@ -94,5 +96,17 @@ class PhotoUtils {
9496
null
9597
}
9698
}
99+
100+
fun uriListToMultipartParts(
101+
uris: List<Uri>,
102+
contentResolver: ContentResolver
103+
): List<MultipartBody.Part> {
104+
return uris.mapIndexed { index, uri ->
105+
val inputStream = contentResolver.openInputStream(uri) ?: throw IllegalArgumentException("Can't open URI: $uri")
106+
val fileName = "image_$index.jpg" // 혹은 uri에서 파일명 추출
107+
val requestBody = inputStream.readBytes().toRequestBody("image/*".toMediaTypeOrNull())
108+
MultipartBody.Part.createFormData("images", fileName, requestBody)
109+
}
110+
}
97111
}
98112
}

app/src/main/java/com/paw/key/data/di/RepositoryModule.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@ import com.paw.key.data.repositoryimpl.onboarding.OnboardingRepositoryImpl
88
import com.paw.key.data.repositoryimpl.RegionRepositoryImpl
99
import com.paw.key.data.repositoryimpl.WalkCourseRepositoryImpl
1010
import com.paw.key.data.repositoryimpl.WalkSharedResultRepositoryImpl
11-
import com.paw.key.data.repositoryimpl.filter.FilterOptionRepositoryImpl
1211
import com.paw.key.data.repositoryimpl.sharedwalk.SharedWalkRepositoryImpl
1312
import com.paw.key.data.repositoryimpl.home.HomeRegionRepositoryImpl
13+
import com.paw.key.data.repositoryimpl.walkreview.WalkReviewRepositoryImpl
1414
import com.paw.key.domain.repository.DummyRepository
1515
import com.paw.key.domain.repository.onboarding.OnboardingInfoRepository
1616
import com.paw.key.domain.repository.onboarding.OnboardingRegionRepository
1717
import com.paw.key.domain.repository.onboarding.OnboardingRepository
1818
import com.paw.key.domain.repository.RegionRepository
1919
import com.paw.key.domain.repository.WalkSharedResultRepository
20-
import com.paw.key.domain.repository.filter.FilterOptionRepository
2120
import com.paw.key.domain.repository.sharedwalk.SharedWalkRepository
2221
import com.paw.key.domain.repository.home.HomeRegionRepository
2322
import com.paw.key.domain.repository.petprofile.PetProfileRepository
2423
import com.paw.key.domain.repository.walkcourse.WalkCourseRepository
24+
import com.paw.key.domain.repository.walkreview.WalkReviewRepository
2525
import dagger.Binds
2626
import dagger.Module
2727
import dagger.hilt.InstallIn
@@ -55,7 +55,7 @@ interface RepositoryModule {
5555
fun bindsWalkCourseRepository(
5656
walkCourseRepositoryImpl: WalkCourseRepositoryImpl
5757
): WalkCourseRepository
58-
58+
5959
@Binds
6060
@Singleton
6161
fun bindOnboardingRepository(
@@ -96,7 +96,7 @@ interface RepositoryModule {
9696

9797
@Binds
9898
@Singleton
99-
fun bindFilterOptionRepository(
100-
impl: FilterOptionRepositoryImpl
101-
): FilterOptionRepository
99+
fun bindWalkReviewRepository(
100+
impl: WalkReviewRepositoryImpl
101+
) : WalkReviewRepository
102102
}

app/src/main/java/com/paw/key/data/di/ServiceModule.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import com.paw.key.data.service.onboarding.OnboardingInfoService
66
import com.paw.key.data.service.onboarding.OnboardingPetsService
77
import com.paw.key.data.service.onboarding.OnboardingRegionService
88
import com.paw.key.data.service.RegionService
9-
import com.paw.key.data.service.filter.FilterOptionService
109
import com.paw.key.data.service.sharedwalk.SharedWalkService
1110
import com.paw.key.data.service.home.HomeRegionService
1211
import com.paw.key.data.service.walkcourse.WalkCourseService
12+
import com.paw.key.data.service.walkreview.WalkReviewService
1313
import dagger.Module
1414
import dagger.Provides
1515
import dagger.hilt.InstallIn
@@ -36,7 +36,7 @@ object ServiceModule {
3636
@Singleton
3737
fun providesWalkCourseService(retrofit: Retrofit ): WalkCourseService =
3838
retrofit.create()
39-
39+
4040
@Provides
4141
@Singleton
4242
fun provideOnboardingPetsService(retrofit: Retrofit): OnboardingPetsService =
@@ -70,7 +70,8 @@ object ServiceModule {
7070

7171
@Provides
7272
@Singleton
73-
fun provideFilterOptionService(retrofit: Retrofit): FilterOptionService =
74-
retrofit.create(FilterOptionService::class.java)
73+
fun provideWalkReviewService(retrofit: Retrofit): WalkReviewService =
74+
retrofit.create()
75+
7576

7677
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.paw.key.data.dto.request.sharedwalk
2+
3+
import kotlinx.serialization.SerialName
4+
import kotlinx.serialization.Serializable
5+
6+
@Serializable
7+
data class SharedWalkReviewRequestDto(
8+
@SerialName("selectedCategories")
9+
val selectedCategories: List<SharedWalkReviewCategoryDto>
10+
)
11+
12+
@Serializable
13+
data class SharedWalkReviewCategoryDto(
14+
@SerialName("categoryId")
15+
val categoryId: Int,
16+
17+
@SerialName("selectedOptionIds")
18+
val selectedOptionIds: List<Int>
19+
)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.paw.key.data.dto.request.walkreview
2+
3+
import kotlinx.serialization.SerialName
4+
import kotlinx.serialization.Serializable
5+
6+
7+
@Serializable
8+
data class WalkCourseReviewRequestDto(
9+
@SerialName("title")
10+
val title: String,
11+
12+
@SerialName("description")
13+
val description: String,
14+
15+
@SerialName("isPublic")
16+
val isPublic: Boolean,
17+
18+
@SerialName("selectedCategories")
19+
val selectedCategories: List<SelectedCategoryDto>,
20+
21+
@SerialName("routeId")
22+
val routeId: Long
23+
)
24+
25+
@Serializable
26+
data class SelectedCategoryDto(
27+
@SerialName("categoryId")
28+
val categoryId: Int,
29+
30+
@SerialName("selectedOptionIds")
31+
val selectedOptionIds: List<Int>
32+
)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.paw.key.data.dto.response.walkreview
2+
3+
import com.paw.key.domain.model.entity.walkreview.WalkReviewCategoryEntity
4+
import com.paw.key.domain.model.entity.walkreview.WalkReviewCategoryListEntity
5+
import com.paw.key.domain.model.entity.walkreview.WalkReviewOptionOptionsResponseEntity
6+
import kotlinx.serialization.Serializable
7+
8+
@Serializable
9+
data class WalkReviewCategoryResponseDto(
10+
val categoryList : List<CategoryResponseDto>
11+
) {
12+
fun toEntity() = WalkReviewCategoryListEntity(
13+
categoryList = categoryList.map { it.toEntity() }
14+
)
15+
}
16+
17+
@Serializable
18+
data class CategoryResponseDto(
19+
val categoryId : Int,
20+
val categoryName : String,
21+
val categoryOptions : List<OptionsResponseDto>
22+
) {
23+
fun toEntity() = WalkReviewCategoryEntity(
24+
categoryId = categoryId,
25+
categoryName = categoryName,
26+
options = categoryOptions.map { it.toEntity() }
27+
)
28+
29+
}
30+
31+
@Serializable
32+
data class OptionsResponseDto(
33+
val categoryOptionId : Int,
34+
val categoryOptionText : String
35+
) {
36+
fun toEntity() = WalkReviewOptionOptionsResponseEntity(
37+
categoryOptionId = categoryOptionId,
38+
optionText = categoryOptionText
39+
)
40+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.paw.key.data.dto.response.walkreview
2+
3+
import com.paw.key.domain.model.entity.walkreview.WalkReviewInfoEntity
4+
import com.paw.key.domain.model.entity.walkreview.WalkReviewRouteInfoEntity
5+
import kotlinx.serialization.SerialName
6+
import kotlinx.serialization.Serializable
7+
8+
@Serializable
9+
data class WalkReviewInfoResponseDto(
10+
@SerialName("routeDto")
11+
val routeDto: WalkReviewRouteInfoResponseDto,
12+
@SerialName("petName")
13+
val petName: String
14+
) {
15+
fun toEntity() = WalkReviewInfoEntity(
16+
routeDto = routeDto.toEntity(),
17+
petName = petName
18+
)
19+
}
20+
21+
@Serializable
22+
data class WalkReviewRouteInfoResponseDto(
23+
val id: Int,
24+
@SerialName("locationDescription")
25+
val locationDescription: String,
26+
@SerialName("dateDescription")
27+
val dateDescription: String,
28+
@SerialName("descriptionTags")
29+
val descriptionTags: List<String>
30+
) {
31+
fun toEntity() = WalkReviewRouteInfoEntity(
32+
id = id,
33+
locationDescription = locationDescription,
34+
dateDescription = dateDescription,
35+
descriptionTags = descriptionTags
36+
)
37+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.paw.key.data.remote.datasource.walkreview
2+
3+
import com.paw.key.data.dto.request.walkcourse.WalkCourseRequestDto
4+
import com.paw.key.data.dto.request.walkreview.WalkCourseReviewRequestDto
5+
import com.paw.key.data.dto.response.BaseResponse
6+
import com.paw.key.data.service.walkreview.WalkReviewService
7+
import kotlinx.serialization.json.Json
8+
import okhttp3.MediaType.Companion.toMediaType
9+
import okhttp3.MultipartBody
10+
import okhttp3.RequestBody.Companion.toRequestBody
11+
import javax.inject.Inject
12+
13+
class WalkReviewDataSource @Inject constructor(
14+
private val service: WalkReviewService
15+
) {
16+
suspend fun postWalkReview(
17+
userId: Int,
18+
imageFiles: List<MultipartBody.Part>,
19+
walkReviewRequestDto: WalkCourseReviewRequestDto
20+
) : BaseResponse<Unit> {
21+
val jsonString = Json.encodeToString(WalkCourseReviewRequestDto.serializer(), walkReviewRequestDto)
22+
val requestBody = jsonString.toRequestBody("application/json".toMediaType())
23+
24+
return service.postWalkReview(
25+
userId = userId,
26+
imageFiles = imageFiles,
27+
data = requestBody
28+
)
29+
}
30+
31+
suspend fun getWalkReviewInfo(
32+
userId: Int,
33+
routeId: Int
34+
) = service.getWalkReviewInfo(
35+
userId = userId,
36+
routeId = routeId
37+
)
38+
39+
suspend fun getWalkReviewCategory(
40+
userId: Int
41+
) = service.getWalkReviewCategory(
42+
userId = userId
43+
)
44+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.paw.key.data.repositoryimpl.walkreview
2+
3+
import com.paw.key.data.remote.datasource.walkreview.WalkReviewDataSource
4+
import com.paw.key.domain.model.entity.walkreview.WalkReviewCategoryListEntity
5+
import com.paw.key.domain.model.entity.walkreview.WalkReviewInfoEntity
6+
import com.paw.key.domain.model.entity.walkreview.WalkReviewRecordEntity
7+
import com.paw.key.domain.repository.walkreview.WalkReviewRepository
8+
import okhttp3.MultipartBody
9+
import javax.inject.Inject
10+
11+
class WalkReviewRepositoryImpl @Inject constructor(
12+
private val dataSource: WalkReviewDataSource
13+
) : WalkReviewRepository {
14+
override suspend fun postWalkReview(
15+
userId: Int,
16+
imageFiles: List<MultipartBody.Part>,
17+
walkReviewRequest: WalkReviewRecordEntity
18+
): Result<Unit> {
19+
return runCatching {
20+
dataSource.postWalkReview(
21+
userId = userId,
22+
imageFiles = imageFiles,
23+
walkReviewRequestDto = walkReviewRequest.toDto()
24+
)
25+
}
26+
}
27+
28+
override suspend fun getWalkReviewInfo(
29+
userId: Int,
30+
routeId: Int
31+
): Result<WalkReviewInfoEntity> {
32+
return runCatching {
33+
dataSource.getWalkReviewInfo(
34+
userId = userId,
35+
routeId = routeId
36+
).data.toEntity()
37+
}
38+
}
39+
40+
override suspend fun getWalkReviewCategory(
41+
userId: Int
42+
): Result<WalkReviewCategoryListEntity> {
43+
return runCatching {
44+
dataSource.getWalkReviewCategory(
45+
userId = userId
46+
).data.toEntity()
47+
}
48+
}
49+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.paw.key.data.service.walkreview
2+
3+
import com.paw.key.data.dto.response.BaseResponse
4+
import com.paw.key.data.dto.response.walkreview.WalkReviewCategoryResponseDto
5+
import com.paw.key.data.dto.response.walkreview.WalkReviewInfoResponseDto
6+
import okhttp3.MultipartBody
7+
import okhttp3.RequestBody
8+
import retrofit2.http.GET
9+
import retrofit2.http.Header
10+
import retrofit2.http.Multipart
11+
import retrofit2.http.POST
12+
import retrofit2.http.Part
13+
import retrofit2.http.Path
14+
15+
interface WalkReviewService {
16+
@Multipart
17+
@POST("posts")
18+
suspend fun postWalkReview(
19+
@Header("X-USER-ID") userId: Int,
20+
@Part imageFiles: List<MultipartBody.Part>,
21+
@Part("data") data: RequestBody
22+
): BaseResponse<Unit>
23+
24+
@GET("posts/categories")
25+
suspend fun getWalkReviewCategory(
26+
@Header("X-USER-ID") userId: Int,
27+
): BaseResponse<WalkReviewCategoryResponseDto>
28+
29+
@GET("routes/{routeId}/info")
30+
suspend fun getWalkReviewInfo(
31+
@Header("X-USER-ID") userId: Int,
32+
@Path("routeId") routeId: Int
33+
): BaseResponse<WalkReviewInfoResponseDto>
34+
}

0 commit comments

Comments
 (0)