Skip to content

Commit

Permalink
Merge pull request #43 from Na-o-man/feature/#35/get-shareGroup-api
Browse files Browse the repository at this point in the history
[FEAT] ShareGroup 조회 API 구현
  • Loading branch information
bflykky authored Aug 1, 2024
2 parents 12a9ced + c9cdce9 commit 8dc8343
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.umc.naoman.domain.member.entity.Member;
import com.umc.naoman.domain.shareGroup.converter.ShareGroupConverter;
import com.umc.naoman.domain.shareGroup.dto.ShareGroupRequest;
import com.umc.naoman.domain.shareGroup.dto.ShareGroupRequest.createShareGroupRequest;
import com.umc.naoman.domain.shareGroup.dto.ShareGroupResponse;
import com.umc.naoman.domain.shareGroup.entity.Profile;
import com.umc.naoman.domain.shareGroup.entity.ShareGroup;
Expand All @@ -15,11 +16,16 @@
import io.swagger.v3.oas.annotations.Parameters;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
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;
Expand All @@ -28,40 +34,65 @@
@RequiredArgsConstructor
@RequestMapping("/shareGroups")
public class ShareGroupController {

private final ShareGroupService shareGroupService;
private final ShareGroupConverter shareGroupConverter;

@PostMapping
@Operation(summary = "공유그룹 생성 API", description = "새로운 공유그룹을 생성하는 API입니다.")
public ResultResponse<ShareGroupResponse
.ShareGroupInfo> createShareGroup(@Valid @RequestBody ShareGroupRequest.createShareGroupRequest request,
.ShareGroupInfo> createShareGroup(@Valid @RequestBody createShareGroupRequest request,
@LoginMember Member member) {

ShareGroup shareGroup = shareGroupService.createShareGroup(request, member);
return ResultResponse.of(ShareGroupResultCode.CREATE_SHARE_GROUP, ShareGroupConverter.toShareGroupInfoDTO(shareGroup));
return ResultResponse.of(ShareGroupResultCode.CREATE_SHARE_GROUP, shareGroupConverter.toShareGroupInfo(shareGroup));
}

@GetMapping("/{shareGroupId}")
@Operation(summary = "공유그룹 조회 API", description = "shareGroupId로 특정 공유그룹을 조회하는 API입니다.")
@Parameters(value = {
@Parameter(name = "shareGroupId", description = "특정 공유그룹 id를 입력해 주세요.")
})
public ResultResponse<ShareGroupResponse.ShareGroupInfo> getShareGroupInfo(@PathVariable(name = "shareGroupId") Long shareGroupId) {

public ResultResponse<ShareGroupResponse.ShareGroupDetailInfo> getShareGroupDetailInfo(@PathVariable(name = "shareGroupId") Long shareGroupId) {
ShareGroup shareGroup = shareGroupService.findShareGroup(shareGroupId);
List<Profile> profileList = shareGroupService.findProfileList(shareGroupId);

return ResultResponse.of(ShareGroupResultCode.SHARE_GROUP_INFO,
ShareGroupConverter.toShareGroupDetailInfoDTO(shareGroup, profileList));
shareGroupConverter.toShareGroupDetailInfo(shareGroup, profileList));
}

@GetMapping
@Operation(summary = "초대 코드로 공유그룹 조회 API", description = "inviteCode로 특정 공유그룹을 조회하는 API입니다.")
@Parameters(value = {
@Parameter(name = "inviteCode", description = "참여하려는 공유그룹의 초대 코드")
})
public ResultResponse<ShareGroupResponse.ShareGroupDetailInfo> getShareGroupByInviteCode(@RequestParam String inviteCode) {
ShareGroup shareGroup = shareGroupService.findShareGroup(inviteCode);
List<Profile> profileList = shareGroupService.findProfileList(shareGroup.getId());

return ResultResponse.of(ShareGroupResultCode.SHARE_GROUP_INFO,
shareGroupConverter.toShareGroupDetailInfo(shareGroup, profileList));
}

@GetMapping("/my")
@Operation(summary = "내가 참여한 공유그룹 목록 조회 API", description = "내가 참여한 공유그룹 목록을 페이징 처리하여 조회하는 API입니다.")
@Parameters(value = {
@Parameter(name = "page", description = "조회할 페이지를 입력해 주세요.(0번부터 시작)"),
@Parameter(name = "size", description = "한 페이지에 나타낼 공유그룹 개수를 입력해주세요.")
})
public ResultResponse<ShareGroupResponse.PagedShareGroupInfo> getMyShareGroupList(@LoginMember Member member,
@PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC)
@Parameter(hidden = true) Pageable pageable) {
Page<ShareGroup> shareGroupList = shareGroupService.getMyShareGroupList(member, pageable);
return ResultResponse.of(ShareGroupResultCode.SHARE_GROUP_INFO_LIST,
shareGroupConverter.toPagedShareGroupInfo(shareGroupList));
}

@PostMapping("/join")
@Operation(summary = "공유그룹 참여 API", description = "특정 공유그룹에 참여하는 API입니다.")
public ResultResponse<ShareGroupResponse.ShareGroupId> joinShareGroup(@Valid @RequestBody ShareGroupRequest.JoinShareGroupRequest request,
@LoginMember Member member) {
@LoginMember Member member) {
ShareGroup shareGroup = shareGroupService.joinShareGroup(request.getShareGroupId(), request.getProfileId(), member);
return ResultResponse.of(ShareGroupResultCode.JOIN_SHARE_GROUP,
ShareGroupConverter.toJoinShareGroupInfoDTO(shareGroup));
shareGroupConverter.toJoinShareGroupInfo(shareGroup));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,66 @@

import com.umc.naoman.domain.shareGroup.dto.ShareGroupRequest;
import com.umc.naoman.domain.shareGroup.dto.ShareGroupResponse;
import com.umc.naoman.domain.shareGroup.dto.ShareGroupResponse.PagedShareGroupInfo;
import com.umc.naoman.domain.shareGroup.dto.ShareGroupResponse.ShareGroupDetailInfo;
import com.umc.naoman.domain.shareGroup.dto.ShareGroupResponse.ShareGroupInfo;
import com.umc.naoman.domain.shareGroup.entity.Profile;
import com.umc.naoman.domain.shareGroup.entity.ShareGroup;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Component;

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

@Component
public class ShareGroupConverter {
private static final String BASE_URL = "https://na0man/invite/"; //baseUrl 상수

public static ShareGroup toEntity(ShareGroupRequest.createShareGroupRequest request) {
public ShareGroup toEntity(ShareGroupRequest.createShareGroupRequest request) {
return ShareGroup.builder()
.memberCount(request.getMemberNameList().size()) // 변경 가능성 있음. memberCount 대신 nameList의 size 사용
.name("임시 공유 그룹 이름") //임시 공유 그룹 이름
.build();
}

private static final String baseUrl = "https://na0man/invite/"; //baseUrl 상수

// 그룹 생성 시 반환하는 정보 DTO
public static ShareGroupResponse.ShareGroupInfo toShareGroupInfoDTO(ShareGroup shareGroup) {
return ShareGroupResponse.ShareGroupInfo.builder()
public ShareGroupInfo toShareGroupInfo(ShareGroup shareGroup) {
return ShareGroupInfo.builder()
.shareGroupId(shareGroup.getId())
.name("임시 공유 그룹 이름") //임시 공유 그룹 이름 (고유 코드 출력)
.inviteUrl(baseUrl + shareGroup.getInviteCode())
.name(shareGroup.getName())
.image(shareGroup.getImage())
.memberCount(shareGroup.getMemberCount())
.inviteUrl(BASE_URL + shareGroup.getInviteCode())
.createdAt(shareGroup.getCreatedAt())
.build();
}

// 그룹 참여 시 반환하는 DTO
public static ShareGroupResponse.ShareGroupId toJoinShareGroupInfoDTO(ShareGroup shareGroup) {
public ShareGroupResponse.ShareGroupId toJoinShareGroupInfo(ShareGroup shareGroup) {
return ShareGroupResponse.ShareGroupId.builder()
.shareGroupId(shareGroup.getId())
.build();
}

// 조회 시, 디테일한 그룹 정보를 반환하는 DTO
public static ShareGroupResponse.ShareGroupInfo toShareGroupDetailInfoDTO(ShareGroup shareGroup, List<Profile> profiles) {
public ShareGroupDetailInfo toShareGroupDetailInfo(ShareGroup shareGroup, List<Profile> profiles) {
List<ShareGroupResponse.ProfileInfo> profileInfoList = profiles.stream()
.map(ShareGroupConverter::toProfileInfo)
.map(this::toProfileInfo)
.toList();

return ShareGroupResponse.ShareGroupInfo.builder()
return ShareGroupDetailInfo.builder()
.shareGroupId(shareGroup.getId())
.name("임시 공유 그룹 이름") //임시 공유 그룹 이름 (고유 코드 출력)
.name(shareGroup.getName()) //임시 공유 그룹 이름 (고유 코드 출력)
.image(shareGroup.getImage())
.memberCount(shareGroup.getMemberCount())
.inviteUrl(BASE_URL + shareGroup.getInviteCode())
.profileInfoList(profileInfoList) //프로필 리스트 출력
.createdAt(shareGroup.getCreatedAt())
.build();
}

// profile 정보 반환 DTO
public static ShareGroupResponse.ProfileInfo toProfileInfo(Profile profile) {
public ShareGroupResponse.ProfileInfo toProfileInfo(Profile profile) {
return ShareGroupResponse.ProfileInfo.builder()
.profileId(profile.getId())
.name(profile.getName())
Expand All @@ -62,4 +70,21 @@ public static ShareGroupResponse.ProfileInfo toProfileInfo(Profile profile) {
.build();
}

public PagedShareGroupInfo toPagedShareGroupInfo(Page<ShareGroup> shareGroupList) {
// 각 공유 그룹에 대한 상세 정보를 가져오기 (DetailInfo response 재사용)
List<ShareGroupInfo> shareGroupInfoList = shareGroupList
.stream()
.map(this::toShareGroupInfo)
.toList();

return PagedShareGroupInfo.builder()
.shareGroupInfoList(shareGroupInfoList) // 만든 info 리스트
.page(shareGroupList.getNumber())
.totalElements(shareGroupList.getTotalElements())
.isFirst(shareGroupList.isFirst())
.isLast(shareGroupList.isLast())
.build();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ public abstract class ShareGroupRequest {
@NoArgsConstructor
@AllArgsConstructor
public static class createShareGroupRequest {
@NotNull(message = "멤버 수를 입력해야 합니다.")
private Integer memberCount;
@NotEmpty(message = "멤버 이름 리스트는 비어 있을 수 없습니다.")
private List<String> memberNameList;
@NotEmpty(message = "모임의 성격을 하나 이상 선택해야 합니다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,48 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

import java.time.LocalDateTime;
import java.util.List;

public abstract class ShareGroupResponse {

@Getter
@Builder
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public static class ShareGroupInfo {
private Long shareGroupId;
private String name; //공유그룹 이름 반환
private String image; //공유그룹 대표 이미지 반환. 처음 공유 그룹 생성 시에는 null
private int memberCount; //공유 그룹의 프로필 개수
private String inviteUrl; //공유그룹 초대 코드 반환
private String image; //공유그룹 대표 이미지 반환
private int memberCount;
private List<ProfileInfo> profileInfoList;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDateTime createdAt;
}

@Getter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public static class ShareGroupDetailInfo extends ShareGroupInfo {
private List<ProfileInfo> profileInfoList;
}

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class PagedShareGroupInfo {
private List<ShareGroupInfo> shareGroupInfoList; //공유그룹 상세 정보 리스트
private int page; // 페이지 번호
private long totalElements; // 해당 조건에 부합하는 요소의 총 개수
private boolean isFirst; // 첫 페이지 여부
private boolean isLast; // 마지막 페이지 여부
}

@Getter
@Builder
@NoArgsConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@
@Repository
public interface ProfileRepository extends JpaRepository<Profile, Long> {
List<Profile> findByShareGroupId(Long shareGroupId);
List<Profile> findByMemberId(Long memberId);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package com.umc.naoman.domain.shareGroup.repository;

import com.umc.naoman.domain.shareGroup.entity.ShareGroup;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface ShareGroupRepository extends JpaRepository<ShareGroup, Long> {
Optional<ShareGroup> findByInviteCode(String inviteCode);
Page<ShareGroup> findByIdIn(List<Long> shareGroupIds, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
import com.umc.naoman.domain.shareGroup.dto.ShareGroupRequest;
import com.umc.naoman.domain.shareGroup.entity.Profile;
import com.umc.naoman.domain.shareGroup.entity.ShareGroup;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;

public interface ShareGroupService {
ShareGroup createShareGroup(ShareGroupRequest.createShareGroupRequest request, Member member);
ShareGroup findShareGroup(Long shareGroupId);
ShareGroup findShareGroup(String inviteCode);
List<Profile> findProfileList(Long shareGroupId);
ShareGroup joinShareGroup(Long shareGroupId, Long profileId, Member member);
Profile findProfile(Long profileId);
Page<ShareGroup> getMyShareGroupList(Member member, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@
import com.umc.naoman.domain.member.repository.MemberRepository;
import com.umc.naoman.domain.shareGroup.converter.ShareGroupConverter;
import com.umc.naoman.domain.shareGroup.dto.ShareGroupRequest;
import com.umc.naoman.domain.shareGroup.dto.ShareGroupResponse;
import com.umc.naoman.domain.shareGroup.dto.ShareGroupResponse.PagedShareGroupInfo;
import com.umc.naoman.domain.shareGroup.entity.Profile;
import com.umc.naoman.domain.shareGroup.entity.Role;
import com.umc.naoman.domain.shareGroup.entity.ShareGroup;
import com.umc.naoman.domain.shareGroup.repository.ProfileRepository;
import com.umc.naoman.domain.shareGroup.repository.ShareGroupRepository;
import com.umc.naoman.global.error.BusinessException;
import com.umc.naoman.global.error.code.MemberErrorCode;
import com.umc.naoman.global.error.code.ShareGroupErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@Transactional(readOnly = true)
Expand All @@ -28,16 +32,16 @@ public class ShareGroupServiceImpl implements ShareGroupService {
private final ShareGroupRepository shareGroupRepository;
private final ProfileRepository profileRepository;
private final MemberRepository memberRepository;
private final ShareGroupConverter shareGroupConverter;

@Transactional
@Override
public ShareGroup createShareGroup(ShareGroupRequest.createShareGroupRequest request, Member member) {

// 초대링크를 위한 고유번호 생성 (UUID)
String inviteCode = UUID.randomUUID().toString().replace("-", "").toUpperCase();

// 변환 로직
ShareGroup newShareGroup = ShareGroupConverter.toEntity(request);
ShareGroup newShareGroup = shareGroupConverter.toEntity(request);
newShareGroup.setInviteCode(inviteCode);

// 생성된 공유 그룹 저장
Expand Down Expand Up @@ -83,12 +87,30 @@ public ShareGroup joinShareGroup(Long shareGroupId, Long profileId, Member membe
return shareGroup;
}

@Override
public Page<ShareGroup> getMyShareGroupList(Member member, Pageable pageable) {
// 멤버를 통해 profile을 가져와서, 해당 profile의 shareGroupId를 추출
List<Long> shareGroupIdList = profileRepository.findByMemberId(member.getId())
.stream()
.map(profile -> profile.getShareGroup().getId())
.collect(Collectors.toList()); // 리스트로 수집

// 추출한 공유 그룹 ID 리스트를 통해 해당 공유 그룹들을 페이징 처리하여 가져오기
return shareGroupRepository.findByIdIn(shareGroupIdList, pageable);
}

@Override
public ShareGroup findShareGroup(Long shareGroupId) {
return shareGroupRepository.findById(shareGroupId)
.orElseThrow(() -> new BusinessException(ShareGroupErrorCode.SHARE_GROUP_NOT_FOUND));
}

@Override
public ShareGroup findShareGroup(String inviteCode) {
return shareGroupRepository.findByInviteCode(inviteCode)
.orElseThrow(() -> new BusinessException(ShareGroupErrorCode.SHARE_GROUP_NOT_FOUND));
}

@Override
public List<Profile> findProfileList(Long shareGroupId) {
return profileRepository.findByShareGroupId(shareGroupId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
public enum ShareGroupResultCode implements ResultCode {
CREATE_SHARE_GROUP(200, "SG001", "성공적으로 공유 그룹을 생성하였습니다."),
SHARE_GROUP_INFO(200, "SG002", "공유 그룹을 성공적으로 조회했습니다."),
JOIN_SHARE_GROUP(200, "SG003", "성공적으로 공유 그룹에 참여했습니다." )

JOIN_SHARE_GROUP(200, "SG003", "성공적으로 공유 그룹에 참여했습니다." ),
SHARE_GROUP_INFO_LIST(200, "SG004", "내가 참여한 공유 그룹 목록을 성공적으로 조회하였습니다.")
;
private final int status;
private final String code;
Expand Down

0 comments on commit 8dc8343

Please sign in to comment.