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: Group Detail view with id #57

Merged
merged 2 commits into from
Aug 4, 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
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.mashup.pic.group.applicationservice

import com.mashup.pic.common.exception.PicException
import com.mashup.pic.common.exception.PicExceptionType
import com.mashup.pic.domain.event.EventDto
import com.mashup.pic.domain.event.EventService
import com.mashup.pic.domain.event.EventStatus
import com.mashup.pic.domain.event.UploadService
Expand All @@ -13,8 +16,10 @@ import com.mashup.pic.group.applicationservice.dto.CreateGroupServiceRequest
import com.mashup.pic.group.applicationservice.dto.JoinGroupServiceRequest
import com.mashup.pic.group.controller.dto.FramedImage
import com.mashup.pic.group.controller.dto.GroupViewStatus
import com.mashup.pic.group.controller.dto.HistoryItem
import com.mashup.pic.group.controller.dto.JoinGroupResponse
import com.mashup.pic.group.controller.dto.RecentEvent
import com.mashup.pic.group.controller.dto.RecentEventDetail
import com.mashup.pic.group.controller.dto.ViewGroupDetailResponse
import com.mashup.pic.group.controller.dto.ViewGroupItem
import com.mashup.pic.group.controller.dto.ViewGroupResponse
Expand All @@ -23,6 +28,7 @@ import com.mashup.pic.group.util.GroupViewStatusUtil
import com.mashup.pic.util.InviteCodeUtil
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDateTime

@Service
@Transactional(readOnly = true)
Expand Down Expand Up @@ -58,12 +64,69 @@ class GroupApplicationService(
return ViewGroupResponse(groupItems)
}

fun getGroup(
fun getGroupDetail(
userId: Long,
groupId: Long
): ViewGroupDetailResponse? {
// TODO: add detail view logic
return null
): ViewGroupDetailResponse {
val group = groupService.getGroupById(groupId)
val lastEvent = eventService.getLastEvent(group.id)

val status: GroupViewStatus
val statusDescription = GroupViewStatusUtil.generateDescription(lastEvent)
var recentEventDetail = RecentEventDetail()
val cardFrontImageUrl: String
var cardBackImages: ResultDto? = null

if (lastEvent == null) { // ํ˜„ ์ด๋ฒคํŠธ X, ์—ญ๋Œ€ ์ด๋ฒคํŠธ X
status = GroupViewStatus.NO_PAST_AND_CURRENT_EVENT
cardFrontImageUrl = group.imageUrl
} else if (lastEvent.eventStatus == EventStatus.COMPLETE) { // ํ˜„ ์ด๋ฒคํŠธ X, ์—ญ๋Œ€ ์ด๋ฒคํŠธ O
status =
if (eventService.hasVisitedEvent(userId, lastEvent.id)) { // ๋ฐฉ๋ฌธํ–ˆ๋‹ค๋ฉด
GroupViewStatus.NO_CURRENT_EVENT
} else {
GroupViewStatus.EVENT_COMPLETED
}
recentEventDetail = RecentEventDetail(lastEvent.id, lastEvent.description, lastEvent.date, getDeadline(lastEvent))
cardBackImages = resultService.getResultOfEvent(lastEvent.id)
cardFrontImageUrl = cardBackImages.resultImages[0].imageUrl
} else { // ํ˜„ ์ด๋ฒคํŠธ O
recentEventDetail = RecentEventDetail(lastEvent.id, lastEvent.description, lastEvent.date, getDeadline(lastEvent))
cardFrontImageUrl = eventService.getRandomImageOptionFromEvent(lastEvent.id)

status =
when (lastEvent.eventStatus) {
EventStatus.UPLOADING ->
if (uploadService.hasUserUploaded(userId, lastEvent.id)) {
GroupViewStatus.AFTER_MY_UPLOAD
} else {
GroupViewStatus.BEFORE_MY_UPLOAD
}

EventStatus.VOTING ->
if (voteService.hasUserVoted(userId, lastEvent.id)) {
GroupViewStatus.AFTER_MY_VOTE
} else {
GroupViewStatus.BEFORE_MY_VOTE
}

else -> {
GroupViewStatus.NO_CURRENT_EVENT
}
}
}

return ViewGroupDetailResponse(
id = groupId,
name = group.name,
keyword = group.keyword,
status = status,
statusDescription = statusDescription,
recentEvent = recentEventDetail,
cardFrontImageUrl = cardFrontImageUrl,
cardBackImages = convertResultDtoToFramedImages(cardBackImages),
history = getHistoryItems(groupId)
)
}

private fun getViewGroupItem(
Expand All @@ -82,12 +145,12 @@ class GroupApplicationService(
status = GroupViewStatus.NO_PAST_AND_CURRENT_EVENT
cardFrontImageUrl = group.imageUrl
} else if (lastEvent.eventStatus == EventStatus.COMPLETE) { // ํ˜„ ์ด๋ฒคํŠธ X, ์—ญ๋Œ€ ์ด๋ฒคํŠธ O
status = GroupViewStatus.EVENT_COMPLETED
recentEvent = RecentEvent(lastEvent.description, lastEvent.date)
status = GroupViewStatus.NO_CURRENT_EVENT
recentEvent = RecentEvent(lastEvent.id, lastEvent.description, lastEvent.date)
cardBackImages = resultService.getResultOfEvent(lastEvent.id)
cardFrontImageUrl = cardBackImages.resultImages[0].imageUrl
} else { // ํ˜„ ์ด๋ฒคํŠธ O
recentEvent = RecentEvent(lastEvent.description, lastEvent.date)
recentEvent = RecentEvent(lastEvent.id, lastEvent.description, lastEvent.date)
cardFrontImageUrl = eventService.getRandomImageOptionFromEvent(lastEvent.id)

status =
Expand All @@ -107,7 +170,7 @@ class GroupApplicationService(
}

else -> {
GroupViewStatus.EVENT_COMPLETED
GroupViewStatus.NO_CURRENT_EVENT
}
}
}
Expand All @@ -121,6 +184,26 @@ class GroupApplicationService(
)
}

private fun getHistoryItems(groupId: Long): List<HistoryItem> {
val events = eventService.getAllEventsAsc(groupId).drop(1)
return events.map {
HistoryItem(
id = it.id,
name = it.description,
date = it.date,
images = convertResultDtoToFramedImages(resultService.getResultOfEvent(it.id))
)
}
}

private fun getDeadline(event: EventDto): LocalDateTime {
if (event.eventStatus == EventStatus.UPLOADING) {
return event.createdAt.plusHours(UPLOADING_HOURS)
}

return event.uploadingEndDate?.plusHours(VOTING_HOURS) ?: throw PicException.of(PicExceptionType.ARGUMENT_NOT_VALID, "์—…๋กœ๋“œ ์ข…๋ฃŒ ์‹œ๊ฐ„ ์˜ค๋ฅ˜")
}

private fun convertResultDtoToFramedImages(resultDto: ResultDto?): List<FramedImage>? {
return resultDto?.resultImages?.map { resultItem ->
FramedImage(
Expand All @@ -129,4 +212,9 @@ class GroupApplicationService(
)
}
}

companion object {
const val UPLOADING_HOURS = 2L
const val VOTING_HOURS = 2L
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,6 @@ class GroupController(private val groupApplicationService: GroupApplicationServi
@AuthenticationPrincipal userInfo: UserInfo,
@PathVariable groupId: Long
): ApiResponse<ViewGroupDetailResponse> {
return ApiResponse.success(groupApplicationService.getGroup(userInfo.id, groupId))
return ApiResponse.success(groupApplicationService.getGroupDetail(userInfo.id, groupId))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ data class ViewGroupDetailResponse(
)

data class RecentEventDetail(
val name: String,
val date: LocalDateTime,
val deadline: LocalDateTime
val id: Long = -1,
val name: String = "",
val date: LocalDateTime = LocalDateTime.now(),
val deadline: LocalDateTime = LocalDateTime.now()
)

data class HistoryItem(
val id: Long,
val name: String,
val date: LocalDateTime,
val images: List<FramedImage>
val images: List<FramedImage>?
)
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ data class FramedImage(
)

data class RecentEvent(
var id: Long = -1,
var name: String? = null,
var date: LocalDateTime? = null
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,48 +1,31 @@
package com.mashup.pic.group.util

import com.mashup.pic.domain.event.EventDto
import com.mashup.pic.group.controller.dto.GroupViewStatus
import java.time.LocalDateTime
import java.time.temporal.ChronoUnit

object GroupViewStatusUtil {
fun determineStatus(
hasCurrentEvent: Boolean,
hasPastEvent: Boolean,
uploaded: Boolean,
voted: Boolean
): GroupViewStatus {
return when {
!hasCurrentEvent && !hasPastEvent -> GroupViewStatus.NO_PAST_AND_CURRENT_EVENT
hasCurrentEvent && !hasPastEvent -> GroupViewStatus.NO_CURRENT_EVENT
!uploaded && !voted -> GroupViewStatus.BEFORE_MY_UPLOAD
uploaded && !voted -> GroupViewStatus.AFTER_MY_UPLOAD
uploaded && voted -> GroupViewStatus.BEFORE_MY_VOTE
else -> GroupViewStatus.AFTER_MY_VOTE
}
}

fun determineStatus(
hasCurrentEvent: Boolean,
hasPastEvent: Boolean,
uploaded: Boolean,
voted: Boolean,
visited: Boolean
): GroupViewStatus {
return when {
!hasCurrentEvent && !hasPastEvent -> GroupViewStatus.NO_PAST_AND_CURRENT_EVENT
hasCurrentEvent && !hasPastEvent -> GroupViewStatus.NO_CURRENT_EVENT
!uploaded && !voted -> GroupViewStatus.BEFORE_MY_UPLOAD
uploaded && !voted -> GroupViewStatus.AFTER_MY_UPLOAD
uploaded && voted -> GroupViewStatus.BEFORE_MY_VOTE
!visited -> GroupViewStatus.AFTER_MY_VOTE
else -> GroupViewStatus.EVENT_COMPLETED
}
}
private const val RECENT_UPDATE = "์ตœ๊ทผ ์—…๋ฐ์ดํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค."
private const val VOTING_MESSAGE = "์‰ฟ, ํˆฌํ‘œ ์ค‘"
private const val DAYS_AGO_UPDATE = "%d์ผ ์ „ ์—…๋ฐ์ดํŠธ"
private const val WEEK_AGO_UPDATE = "์ผ์ฃผ์ผ ์ „ ์—…๋ฐ์ดํŠธ"
private const val TWO_WEEKS_AGO_UPDATE = "์ด์ฃผ์ผ ์ „ ์—…๋ฐ์ดํŠธ"
private const val NO_RECENT_PIC = "์ตœ๊ทผ PIC์ด ์—†์–ด์š”"

// TODO: Update with real parameters
fun generateDescription(event: EventDto?): String {
return when {
event != null -> "์ตœ๊ทผ ์—…๋ฐ์ดํŠธ 10์ผ ์ „"
else -> "์‰ฟ, ํˆฌํ‘œ ์ค‘"
return if (event != null) {
val daysSinceUpdate = ChronoUnit.DAYS.between(event.date.toLocalDate(), LocalDateTime.now().toLocalDate())

when {
daysSinceUpdate in 1..6 -> DAYS_AGO_UPDATE.format(daysSinceUpdate)
daysSinceUpdate == 7L -> WEEK_AGO_UPDATE
daysSinceUpdate in 8..13 -> DAYS_AGO_UPDATE.format(daysSinceUpdate)
daysSinceUpdate == 14L -> TWO_WEEKS_AGO_UPDATE
daysSinceUpdate >= 15 -> NO_RECENT_PIC
else -> RECENT_UPDATE
}
} else {
VOTING_MESSAGE
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ data class EventDto(
val date: LocalDateTime,
val eventStatus: EventStatus,
val uploadingEndDate: LocalDateTime?,
val votingEndDate: LocalDateTime?
val votingEndDate: LocalDateTime?,
val createdAt: LocalDateTime
)

fun Event.toDto(): EventDto {
Expand All @@ -20,6 +21,7 @@ fun Event.toDto(): EventDto {
date = this.date,
eventStatus = this.eventStatus,
uploadingEndDate = this.uploadingEndDate,
votingEndDate = this.votingEndDate
votingEndDate = this.votingEndDate,
createdAt = this.createdAt
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ import org.springframework.data.jpa.repository.JpaRepository

interface EventRepository : JpaRepository<Event, Long> {
fun findTopByGroupIdOrderByDateDesc(groupId: Long): Event?

fun findTopByGroupIdOrderByDateAsc(groupId: Long): Event?

fun findAllByGroupIdOrderByIdDesc(groupId: Long): List<Event>
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class EventService(
}

fun getLastEvent(groupId: Long): EventDto? {
return eventRepository.findTopByGroupIdOrderByDateDesc(groupId)?.toDto()
return eventRepository.findTopByGroupIdOrderByDateAsc(groupId)?.toDto()
}

fun getRandomImageOptionFromEvent(eventId: Long): String {
Expand Down Expand Up @@ -99,6 +99,18 @@ class EventService(
}
}

fun hasVisitedEvent(
userId: Long,
eventId: Long
): Boolean {
return getEventJoinByUserIdAndEventId(userId, eventId).isVisited
}

fun getAllEventsAsc(groupId: Long): List<EventDto> {
val events = eventRepository.findAllByGroupIdOrderByIdDesc(groupId)
return events.map { it.toDto() }
}

private fun validateUserImageUpload(
event: Event,
evenJoinId: Long
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.mashup.pic.domain.group
import com.mashup.pic.common.exception.PicException
import com.mashup.pic.common.exception.PicExceptionType
import com.mashup.pic.domain.user.UserRepository
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

Expand Down Expand Up @@ -41,6 +42,10 @@ class GroupService(
return groupRepository.findAllById(myGroupIds).map { it.toDto() }
}

fun getGroupById(groupId: Long): GroupDto {
return groupRepository.findByIdOrNull(groupId)?.toDto() ?: throw PicException.of(PicExceptionType.ARGUMENT_NOT_VALID, "์—†๋Š” ๊ทธ๋ฃน ID")
}

private fun validateUser(userId: Long) {
if (!checkUserExists(userId)) {
throw PicException.of(
Expand Down
Loading