Skip to content

Commit

Permalink
Merge pull request #219 from LearnsMate/feature/member
Browse files Browse the repository at this point in the history
멤버 페이지네이션 추가
  • Loading branch information
Hellin22 authored Nov 21, 2024
2 parents 987760f + a450c3b commit b95c50a
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package intbyte4.learnsmate.member.controller;

import intbyte4.learnsmate.member.domain.dto.FindSingleStudentDTO;
import intbyte4.learnsmate.member.domain.dto.FindSingleTutorDTO;
import intbyte4.learnsmate.member.domain.dto.MemberFilterRequestDTO;
import intbyte4.learnsmate.member.domain.dto.*;
import intbyte4.learnsmate.member.domain.vo.request.RequestEditMemberVO;
import intbyte4.learnsmate.member.domain.vo.request.RequestFilterMembertVO;
import intbyte4.learnsmate.member.domain.vo.response.ResponseFindStudentDetailVO;
import intbyte4.learnsmate.member.domain.vo.response.ResponseFindTutorDetailVO;
import intbyte4.learnsmate.member.mapper.MemberMapper;
import intbyte4.learnsmate.member.domain.MemberType;
import intbyte4.learnsmate.member.domain.dto.MemberDTO;
import intbyte4.learnsmate.member.domain.vo.request.RequestSaveMemberVO;
import intbyte4.learnsmate.member.domain.vo.response.ResponseFindMemberVO;
import intbyte4.learnsmate.member.service.MemberFacade;
import intbyte4.learnsmate.member.service.MemberService;
import intbyte4.learnsmate.voc.domain.dto.VOCPageResponse;
import intbyte4.learnsmate.voc.domain.vo.response.ResponseFindVOCVO;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -36,30 +35,23 @@ public class MemberController {

// 1. 모든 학생 조회(member_flag가 true인 사람 + member_type이 STUDENT)
@GetMapping("/students")
public ResponseEntity<List<ResponseFindMemberVO>> findAllStudent() {
public ResponseEntity<MemberPageResponse<ResponseFindMemberVO>> findAllStudent(
@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "15") int size) {

List<MemberDTO> memberDTOList = memberService.findAllMemberByMemberType(MemberType.STUDENT);

// DTO 리스트를 VO 리스트로 변환
List<ResponseFindMemberVO> responseVOList = memberDTOList.stream()
.map(memberMapper::fromMemberDTOtoResponseFindMemberVO)
.collect(Collectors.toList());

return ResponseEntity.status(HttpStatus.OK).body(responseVOList);
MemberPageResponse<ResponseFindMemberVO> response
= memberService.findAllMemberByMemberType(page, size, MemberType.STUDENT);
return ResponseEntity.ok(response);
}

// 1-2. 모든 강사 조회(member_flag가 true + member_type이 TUTOR)
@GetMapping("/tutors")
public ResponseEntity<List<ResponseFindMemberVO>> findAllTutor() {

List<MemberDTO> memberDTOList = memberService.findAllMemberByMemberType(MemberType.TUTOR);
public ResponseEntity<MemberPageResponse<ResponseFindMemberVO>> findAllTutor(
@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "15") int size) {

// DTO 리스트를 VO 리스트로 변환
List<ResponseFindMemberVO> responseVOList = memberDTOList.stream()
.map(memberMapper::fromMemberDTOtoResponseFindMemberVO)
.collect(Collectors.toList());
MemberPageResponse<ResponseFindMemberVO> response
= memberService.findAllMemberByMemberType(page, size, MemberType.TUTOR);

return ResponseEntity.status(HttpStatus.OK).body(responseVOList);
return ResponseEntity.ok(response);
}

// 2-1. 학생 단건 조회(member flag가 true + member_type이 STUDENT)
Expand Down Expand Up @@ -122,31 +114,35 @@ public ResponseEntity<String> deleteMember(@PathVariable("membercode") Long memb

@Operation(summary = "직원 - 학생 필터링 검색")
@PostMapping("/filter/student")
public ResponseEntity<List<ResponseFindMemberVO>> findStudentByFilter(@RequestBody RequestFilterMembertVO request) {
public ResponseEntity<MemberPageResponse<ResponseFindMemberVO>> findStudentByFilter(
@RequestBody RequestFilterMembertVO request,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "15") int size) {

MemberFilterRequestDTO dto =
memberMapper.fromRequestFilterVOtoMemberFilterRequestDTO(request);

List<MemberDTO> memberDTOList = memberService.filterStudent(dto);
dto.setMemberType(MemberType.STUDENT);

return ResponseEntity.status(HttpStatus.OK)
.body(memberDTOList.stream()
.map(memberMapper::fromMemberDTOtoResponseFindMemberVO)
.collect(Collectors.toList()));
MemberPageResponse<ResponseFindMemberVO> response = memberService.filterStudent(dto, page, size);

return ResponseEntity.ok(response);
}

@Operation(summary = "직원 - 강사 필터링 검색")
@PostMapping("/filter/tutor")
public ResponseEntity<?> findTutorByFilter(@RequestBody RequestFilterMembertVO request) {
public ResponseEntity<?> findTutorByFilter(
@RequestBody RequestFilterMembertVO request,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "15") int size) {

MemberFilterRequestDTO dto =
memberMapper.fromRequestFilterVOtoMemberFilterRequestDTO(request);

List<MemberDTO> memberDTOList = memberService.filterTutor(dto);
dto.setMemberType(MemberType.TUTOR);

MemberPageResponse<ResponseFindMemberVO> response = memberService.filterTutor(dto, page, size);

return ResponseEntity.status(HttpStatus.OK)
.body(memberDTOList.stream()
.map(memberMapper::fromMemberDTOtoResponseFindMemberVO)
.collect(Collectors.toList()));
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package intbyte4.learnsmate.member.domain.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.List;

@Getter
@AllArgsConstructor
public class MemberPageResponse<T> {

private List<T> content;
private long totalElements;
private int totalPages;
private int currentPage;
private int size;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import intbyte4.learnsmate.campaign.domain.vo.request.RequestEditCampaignStudentVO;
import intbyte4.learnsmate.campaign.domain.vo.request.RequestFindCampaignStudentVO;
import intbyte4.learnsmate.member.domain.MemberType;
import intbyte4.learnsmate.member.domain.dto.FindSingleStudentDTO;
import intbyte4.learnsmate.member.domain.dto.FindSingleTutorDTO;
import intbyte4.learnsmate.member.domain.dto.MemberDTO;
Expand All @@ -17,6 +18,7 @@
import org.springframework.stereotype.Component;

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

@Component
public class MemberMapper{
Expand Down Expand Up @@ -202,4 +204,22 @@ public MemberFilterRequestDTO fromRequestFilterVOtoMemberFilterRequestDTO(Reques
.createdEndDate(request.getCreatedEndDate())
.build();
}

public ResponseFindMemberVO fromMemberToResponseFindMemberVO(Member member) {
return ResponseFindMemberVO.builder()
.memberCode(member.getMemberCode())
.memberType(member.getMemberType())
.memberEmail(member.getMemberEmail())
.memberPassword(member.getMemberPassword())
.memberName(member.getMemberName())
.memberAge(member.getMemberAge())
.memberPhone(member.getMemberPhone())
.memberAddress(member.getMemberAddress())
.memberBirth(member.getMemberBirth())
.memberFlag(member.getMemberFlag())
.memberDormantStatus(member.getMemberDormantStatus())
.createdAt(member.getCreatedAt())
.updatedAt(member.getUpdatedAt())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
import intbyte4.learnsmate.member.domain.MemberType;
import intbyte4.learnsmate.member.domain.entity.Member;
import org.springframework.context.annotation.Primary;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
@Primary
public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom {

List<Member> findByMemberFlagTrueAndMemberType(MemberType memberType);
Page<Member> findByMemberFlagTrueAndMemberType(MemberType memberType, PageRequest pageable);

Member findByMemberFlagTrueAndMemberCodeAndMemberType(Long memberCode, MemberType memberType);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import intbyte4.learnsmate.member.domain.entity.Member;
import intbyte4.learnsmate.member.domain.dto.MemberFilterRequestDTO;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;

public interface MemberRepositoryCustom {
List<Member> searchBy(MemberFilterRequestDTO request);
Page<Member> searchBy(MemberFilterRequestDTO request, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import intbyte4.learnsmate.member.domain.MemberType;
import intbyte4.learnsmate.member.domain.entity.Member;
import intbyte4.learnsmate.member.domain.entity.QMember;
import intbyte4.learnsmate.member.domain.dto.MemberFilterRequestDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

import java.time.LocalDateTime;
import java.util.List;
Expand All @@ -18,26 +22,39 @@ public class MemberRepositoryImpl implements MemberRepositoryCustom {
private final JPAQueryFactory queryFactory;

@Override
public List<Member> searchBy(MemberFilterRequestDTO request) {
public Page<Member> searchBy(MemberFilterRequestDTO request, Pageable pageable) {
QMember member = QMember.member;

// BooleanBuilder를 사용해 필터 조건 생성
BooleanBuilder builder = new BooleanBuilder()
.and(eqMemberCode(request.getMemberCode()))
.and(eqMemberType(request.getMemberType()))
.and(likeEmail(request.getMemberEmail()))
.and(likeName(request.getMemberName()))
.and(betweenAge(request.getMemberStartAge(), request.getMemberEndAge())) // 나이 범위
.and(betweenAge(request.getMemberStartAge(), request.getMemberEndAge()))
.and(likePhone(request.getMemberPhone()))
.and(likeAddress(request.getMemberAddress()))
.and(eqMemberFlag(request.getMemberFlag())) // 멤버 플래그
.and(eqMemberDormantFlag(request.getMemberDormantFlag())) // 휴면 멤버 플래그
.and(betweenBirth(request.getBirthStartDate(), request.getBirthEndDate())) // 생년월일 범위
.and(betweenCreatedAt(request.getCreatedStartDate(), request.getCreatedEndDate())); // 생성일 범위
.and(eqMemberFlag(request.getMemberFlag()))
.and(eqMemberDormantFlag(request.getMemberDormantFlag()))
.and(betweenBirth(request.getBirthStartDate(), request.getBirthEndDate()))
.and(betweenCreatedAt(request.getCreatedStartDate(), request.getCreatedEndDate()));

return queryFactory
// Query 생성
JPAQuery<Member> query = queryFactory
.selectFrom(member)
.where(builder)
.where(builder);

// 전체 데이터 수 조회
long total = query.fetchCount();

// 페이징 적용
List<Member> members = query
.offset(pageable.getOffset()) // 시작 위치
.limit(pageable.getPageSize()) // 페이지 크기
.fetch();

// PageImpl 객체 생성
return new PageImpl<>(members, pageable, total);
}

// memberCode 검색 조건
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import intbyte4.learnsmate.common.exception.CommonException;
import intbyte4.learnsmate.common.exception.StatusEnum;
import intbyte4.learnsmate.member.domain.dto.MemberFilterRequestDTO;
import intbyte4.learnsmate.member.domain.dto.MemberPageResponse;
import intbyte4.learnsmate.member.domain.vo.response.ResponseFindMemberVO;
import intbyte4.learnsmate.member.mapper.MemberMapper;
import intbyte4.learnsmate.member.domain.MemberType;
import intbyte4.learnsmate.member.domain.dto.MemberDTO;
Expand All @@ -11,6 +13,9 @@
import intbyte4.learnsmate.member.repository.MemberRepositoryCustom;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
Expand All @@ -25,7 +30,6 @@ public class MemberService {

private final MemberRepository memberRepository;
private final MemberMapper memberMapper;
private final MemberRepositoryCustom memberRepositoryCustom;

public void saveMember(MemberDTO memberDTO) {
LocalDateTime now = LocalDateTime.now();
Expand All @@ -34,16 +38,26 @@ public void saveMember(MemberDTO memberDTO) {
memberRepository.save(member);
}

public List<MemberDTO> findAllMemberByMemberType(MemberType memberType) {
public MemberPageResponse<ResponseFindMemberVO> findAllMemberByMemberType(int page, int size, MemberType memberType) {

List<Member> allMember = memberRepository.findByMemberFlagTrueAndMemberType(memberType);
// Pageable 객체 생성
PageRequest pageable = PageRequest.of(page, size);
// 페이징 처리된 데이터 조회
Page<Member> memberPage = memberRepository.findByMemberFlagTrueAndMemberType(memberType, pageable);

List<MemberDTO> memberDTOList = new ArrayList<>();
for (Member member : allMember) {
memberDTOList.add(memberMapper.fromMembertoMemberDTO(member));
}
// Member -> ResponseFindMemberVO 변환
List<ResponseFindMemberVO> responseVOList = memberPage.getContent().stream()
.map(memberMapper::fromMemberToResponseFindMemberVO)
.collect(Collectors.toList());

return memberDTOList;
// MemberPageResponse 반환
return new MemberPageResponse<>(
responseVOList,
memberPage.getTotalElements(),
memberPage.getTotalPages(),
memberPage.getNumber(),
memberPage.getSize()
);
}

public MemberDTO findByStudentCode(Long memberCode) {
Expand Down Expand Up @@ -93,20 +107,48 @@ public MemberDTO findById(Long memberCode){
}

// 학생 필터링하는 서비스 코드
public List<MemberDTO> filterStudent(MemberFilterRequestDTO dto){
List<Member> memberList = memberRepositoryCustom.searchBy(dto);
public MemberPageResponse<ResponseFindMemberVO> filterStudent(MemberFilterRequestDTO dto, int page, int size){
// Pageable 객체 생성
Pageable pageable = PageRequest.of(page, size);

// 필터 조건과 페이징 처리된 데이터 조회
Page<Member> memberPage = memberRepository.searchBy(dto, pageable);

return memberList.stream()
.map(memberMapper::fromMembertoMemberDTO)
// DTO 리스트로 변환
List<ResponseFindMemberVO> memberVOList = memberPage.getContent().stream()
.map(memberMapper::fromMemberToResponseFindMemberVO)
.collect(Collectors.toList());

// MemberPageResponse 생성 후 반환
return new MemberPageResponse<>(
memberVOList, // 데이터 리스트
memberPage.getTotalElements(), // 전체 데이터 수
memberPage.getTotalPages(), // 전체 페이지 수
memberPage.getNumber() + 1, // 현재 페이지 (0-based → 1-based)
memberPage.getSize() // 페이지 크기
);
}

// 강사 필터링하는 코드 -> 강사 필터링은 조건이 더 적음(멤버에 다 포함됨)
public List<MemberDTO> filterTutor(MemberFilterRequestDTO dto) {
List<Member> memberList = memberRepositoryCustom.searchBy(dto);
public MemberPageResponse<ResponseFindMemberVO> filterTutor(MemberFilterRequestDTO dto, int page, int size){
// Pageable 객체 생성
Pageable pageable = PageRequest.of(page, size);

// 필터 조건과 페이징 처리된 데이터 조회
Page<Member> memberPage = memberRepository.searchBy(dto, pageable);

return memberList.stream()
.map(memberMapper::fromMembertoMemberDTO)
// DTO 리스트로 변환
List<ResponseFindMemberVO> memberVOList = memberPage.getContent().stream()
.map(memberMapper::fromMemberToResponseFindMemberVO)
.collect(Collectors.toList());

// MemberPageResponse 생성 후 반환
return new MemberPageResponse<>(
memberVOList, // 데이터 리스트
memberPage.getTotalElements(), // 전체 데이터 수
memberPage.getTotalPages(), // 전체 페이지 수
memberPage.getNumber() + 1, // 현재 페이지 (0-based → 1-based)
memberPage.getSize() // 페이지 크기
);
}
}

0 comments on commit b95c50a

Please sign in to comment.