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 : 마이페이지 유저가 참여한 그룹 기록 조회 구현 #59

Merged
merged 6 commits into from
Jan 21, 2025
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
@@ -0,0 +1,38 @@
package com.bookmile.backend.domain.userGroup.controller;

import com.bookmile.backend.domain.group.entity.GroupStatus;
import com.bookmile.backend.domain.userGroup.dto.res.UserGroupSearchResponseDto;
import com.bookmile.backend.domain.userGroup.service.UserGroupService;
import com.bookmile.backend.global.common.CommonResponse;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

import static com.bookmile.backend.global.common.StatusCode.GROUP_LIST_FOUND;

@RestController
@RequestMapping("/api/v1/user-groups")
@RequiredArgsConstructor
public class UserGroupController {
private final UserGroupService userGroupService;

@Operation(summary = "사용자 별 참여 그룹 기록을 조회합니다", description = "그룹 상태별로 구분하여 조회합니다.")
@GetMapping("/my-groups")
public ResponseEntity<CommonResponse<List<UserGroupSearchResponseDto>>> getUserGroups (
@RequestParam GroupStatus status,
@AuthenticationPrincipal UserDetails userDetails
) {
String userEmail = userDetails.getUsername();
List<UserGroupSearchResponseDto> groups = userGroupService.getUserGroupsByStatus(userEmail, status);
return ResponseEntity.status(GROUP_LIST_FOUND.getStatus())
.body(CommonResponse.from(GROUP_LIST_FOUND.getMessage(), groups));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.bookmile.backend.domain.userGroup.dto.req;


import com.bookmile.backend.domain.group.entity.GroupStatus;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class UserGroupSearchRequestDto {

@NotNull(message = "조회하려는 그룹 상태를 입력해주세요")
@Schema(description = "그룹 상태 (RECRUITING, IN_PROGRESS, COMPLETED)", example = "IN_PROGRESS")
private GroupStatus status;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.bookmile.backend.domain.userGroup.dto.res;

import com.bookmile.backend.domain.book.dto.res.BookResponseDto;
import com.bookmile.backend.domain.group.entity.Group;
import com.bookmile.backend.domain.group.entity.GroupStatus;
import com.bookmile.backend.domain.user.entity.User;
import lombok.Builder;
import lombok.Getter;

@Getter
public class UserGroupSearchResponseDto {
private final Long groupId;
private final String groupName;
private final String groupDescription;
private final int maxMembers;
private final int currentMembers;
private final GroupStatus status;
private final BookResponseDto book;
private final String goalType;
private final String goalContent;
private final String masterNickname;
private final String masterImage;

@Builder
private UserGroupSearchResponseDto(Long groupId, String groupName, String groupDescription, int maxMembers, int currentMembers,
GroupStatus status, BookResponseDto book, String goalType,
String goalContent, String masterNickname, String masterImage) {
this.groupId = groupId;
this.groupName = groupName;
this.groupDescription = groupDescription;
this.maxMembers = maxMembers;
this.currentMembers = currentMembers;
this.status = status;
this.book = book;
this.goalType = goalType;
this.goalContent = goalContent;
this.masterNickname = masterNickname;
this.masterImage = masterImage;
}

public static UserGroupSearchResponseDto toDto(Group group, int currentMembers, User masterUser) {
return UserGroupSearchResponseDto.builder()
.groupId(group.getId())
.groupName(group.getGroupName())
.groupDescription(group.getGroupDescription())
.maxMembers(group.getMaxMembers())
.currentMembers(currentMembers)
.status(GroupStatus.valueOf(group.getStatus().toString()))
.book(new BookResponseDto(group.getBook()))
.goalType(group.getGoalType())
.goalContent(group.getGoalContent())
.masterNickname(masterUser.getNickname())
.masterImage(masterUser.getImage())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.bookmile.backend.domain.userGroup.repository;

import com.bookmile.backend.domain.group.entity.GroupStatus;
import com.bookmile.backend.domain.userGroup.entity.UserGroup;
import java.util.List;
import java.util.Optional;
Expand All @@ -23,4 +24,8 @@ public interface UserGroupRepository extends JpaRepository<UserGroup, Long> {

@Query(value = "SELECT user_id FROM user_group WHERE group_id = :groupId ORDER BY RAND()", nativeQuery = true)
List<Long> findUserRandomSortByGroupId(Long groupId);

@Query("SELECT ug FROM UserGroup ug JOIN ug.group g WHERE ug.user.email = :userEmail AND g.status = :status")
List<UserGroup> findGroupsByUserEmailAndStatus(@Param("userEmail") String userEmail, @Param("status") GroupStatus status);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.bookmile.backend.domain.userGroup.service.Impl;

import com.bookmile.backend.domain.group.entity.Group;
import com.bookmile.backend.domain.group.entity.GroupStatus;
import com.bookmile.backend.domain.user.entity.User;
import com.bookmile.backend.domain.user.repository.UserRepository;
import com.bookmile.backend.domain.userGroup.dto.res.UserGroupSearchResponseDto;
import com.bookmile.backend.domain.userGroup.entity.UserGroup;
import com.bookmile.backend.domain.userGroup.repository.UserGroupRepository;
import com.bookmile.backend.domain.userGroup.service.UserGroupService;
import com.bookmile.backend.global.common.StatusCode;
import com.bookmile.backend.global.exception.CustomException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

import static com.bookmile.backend.global.common.StatusCode.INVALID_GROUP;

@Service
@RequiredArgsConstructor
public class UserGroupServiceImpl implements UserGroupService {
private final UserGroupRepository userGroupRepository;
private final UserRepository userRepository;

@Override
public List<UserGroupSearchResponseDto> getUserGroupsByStatus(String userEmail, GroupStatus status) {
User user = validateUserByEmail(userEmail);

List<UserGroup> userGroups = userGroupRepository.findGroupsByUserEmailAndStatus(userEmail, status);

List<Group> groups = userGroups.stream()
.map(UserGroup::getGroup)
.toList();

return groups.stream()
.map(group -> {
int currentMembers = countGroupMembers(group.getId());
UserGroup masterUserGroup = findMasterUserGroup(group.getId());
User masterUser = masterUserGroup.getUser();

return UserGroupSearchResponseDto.toDto(group, currentMembers, masterUser);
})
.collect(Collectors.toList());
}

private User validateUserByEmail(String email) {
return userRepository.findByEmail(email)
.orElseThrow(() -> new CustomException(StatusCode.USER_NOT_FOUND));
}

private UserGroup findMasterUserGroup(Long groupId) {
return userGroupRepository.findMasterByGroupId(groupId)
.orElseThrow(() -> new CustomException(INVALID_GROUP));
}

private int countGroupMembers(Long groupId) {
return userGroupRepository.countByGroupId(groupId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.bookmile.backend.domain.userGroup.service;

import com.bookmile.backend.domain.group.entity.GroupStatus;
import com.bookmile.backend.domain.userGroup.dto.res.UserGroupSearchResponseDto;

import java.util.List;

public interface UserGroupService {
List<UserGroupSearchResponseDto> getUserGroupsByStatus(String userEmail, GroupStatus status);
}