- URL 할당 및 통합
- 8개 기능 추가
1. GET/team/find모든 팀 조회 메서드
모든 팀을 조회할 수 있는 메서드가 없었기 때문에 새로 추가하였다.
- 컨트롤러
/**
*
* @param teamName (필터) 팀 이름
* @param teamIntroduce (필터) 팀 상세
* @param projectStatus (필터) 팀 상태
* @param page 최소 출력 값
* @param size 최대 출력 값
* @return PageImpl 필터링 결과값 반환
*/
@GetMapping("/find")
@Operation(summary = "모든 팀 조회 메서드", description = "모든 팀을 조회하는 메서드 입니다.")
@Parameters({
@Parameter(name = "teamName" , description = "팀 이름"),
@Parameter(name = "teamIntroduce" , description = "팀 설명"),
@Parameter(name = "projectStatus" , description = "프로젝트 상태"),
@Parameter(name = "page" , description = "페이지 번호", example = "1"),
@Parameter(name = "size" , description = "한 페이지 결과 수", example = "10")
})
public ResponseEntity<PageImpl<TeamResponseDto>> getTeams(
@RequestParam(required = false) String teamName,
@RequestParam(required = false) String teamIntroduce,
@RequestParam(required = false) ProjectStatus projectStatus,
@RequestParam int page,
@RequestParam int size){
PageImpl<TeamResponseDto> teamSearch =
teamService.allUserTeams(teamName, teamIntroduce, projectStatus, page, size);
return ResponseEntity.status(HttpStatus.OK). body(teamSearch);
}
- 서비스 상세
/**
* 모든 팀 정보 조회
* @param teamName (필터) 팀 이름
* @param teamIntroduce (필터) 팀 상세
* @param projectStatus (필터) 팀 상태
* @param page 최소 출력 값
* @param size 최대 출력 값
* @return PageImpl 필터링 결과값 반환
*/
public PageImpl<TeamResponseDto> allUserTeams(
String teamName, String teamIntroduce, ProjectStatus projectStatus, int page, int size) {
Pageable pageable = PageRequest.of(page, size);
Page<TeamResponseDto> teams = teamUserRepository.findByStatusForTeams(projectStatus, pageable);
List<TeamResponseDto> filteredTeams = teams.stream()
.filter(team -> teamName == null || team.getTeamName().contains(teamName))
.filter(team -> teamIntroduce == null || team.getTeamIntroduce().contains(teamIntroduce))
.filter(team -> projectStatus == null || team.getProjectStatus().equals(projectStatus))
.toList();
return new PageImpl<>(filteredTeams, pageable, teams.getTotalElements());
}
- 리포지토리
/**
* 모든 팀 정보 조회
* @param status (필터) 팀 상태
* @param pageable 페이징 크기
* @return TeamResponseDto
*/
@Query("SELECT new com.beyond.backend.data.dto.teamDto.TeamResponseDto" +
"(t.no, t.teamName, t.teamIntroduce, t.projectStatus, t.timePeriod) " +
"FROM Team t " +
"WHERE (:status IS NULL OR t.projectStatus = :status)")
Page<TeamResponseDto> findByStatusForTeams(@Param("status") ProjectStatus status, Pageable pageable);
- @Param("status") 의 값이 있다면 조건 검색, 없다면 모든 검색 결과 반환
2. GET/team/find/team팀원 목록 조회 메서드
해당 팀의 팀원들의 목록을 조회하는 메서드이다.
- 컨트롤러
/**
* 팀원 목록 조회 메서드
* @param teamNo 팀번호
* @return TeamMemberListDto
* @throws Exception 팀이 존재하지 않습니다.
*/
@GetMapping("/find/team")
@Operation(summary = "팀원 목록 조회 메서드", description = "팀원 목록 조회 메서드입니다.")
@Parameters({@Parameter(name = "teamNo" , description = "팀 번호", example = "1")})
public ResponseEntity<List<TeamMemberListDto>> getUserTeams( @RequestParam Long teamNo ) throws Exception {
List<TeamMemberListDto> teamMembers = teamService.getTeamMembers(teamNo);
return ResponseEntity.status(HttpStatus.OK).body(teamMembers);
}
- 서비스
/**
* 팀원 목록 조회 서비스
*
* @param teamNo 팀번호
* @return TeamMemberListDto
* @throws Exception 팀이 존재하지 않습니다.
*/
@Override
public List<TeamMemberListDto> getTeamMembers(Long teamNo) throws Exception {
teamRepository.findById(teamNo)
.orElseThrow(() -> new IllegalArgumentException("팀이 존재하지 않습니다."));
return teamUserRepository.findByTeamNoForNonLeader(teamNo);
}
- 리포지토리
/**
* 모든 팀 정보 조회
* @param status (필터) 팀 상태
* @param pageable 페이징 크기
* @return TeamResponseDto
*/
@Query("SELECT new com.beyond.backend.data.dto.teamDto.TeamResponseDto" +
"(t.no, t.teamName, t.teamIntroduce, t.projectStatus, t.timePeriod) " +
"FROM Team t " +
"WHERE (:status IS NULL OR t.projectStatus = :status)")
Page<TeamResponseDto> findByStatusForTeams(@Param("status") ProjectStatus status, Pageable pageable);
3. GET/team/find/user해당 유저의 모든 팀 조회 메서드
리포지토리의 SQL 쿼리에서 불필요한 JOIN문을 지웠다.
4
/**
* 유저가 활동한 모든 팀 조회
* @param userNo 유저번호
* @param pageable 페이징 크기
* @return TeamSearchDto
*/
@Query("SELECT new com.beyond.backend.data.dto.teamDto.TeamResponseDto" +
"(t.no, t.teamName, t.teamIntroduce, t.projectStatus, t.timePeriod) " +
"FROM Team t " +
"JOIN t.teamUsers tu " +
"WHERE tu.user.no = :userNo")
Page<TeamResponseDto> findByUserNoForUserTeams(@Param("userNo") Long userNo, Pageable pageable);
4. POST/team/joinRequest팀원 가입 신청 메서드
팀원이 가입 신청을 하면 중간 테이블에 등록 하도록 하였다.
- 컨트롤러
/**
* 팀원 가입 신청 메서드
* @param teamNo 팀번호
* @param userNo 유저번호
* @return 없음
* @throws Exception 팀이 존재하지 않습니다.
* @throws Exception 유저가 존재하지 않습니다.
* @throws Exception 모집중이 아닙니다!
* @throws Exception 이미 등록되었거나 요청한 팀 입니다!!
*/
@PostMapping("/joinRequest")
@Operation(summary = "팀원 가입 신청 메서드", description = "팀원 가입 신청 메서드입니다.")
@Parameters({
@Parameter(name = "teamNo" , description = "팀 번호", example = "1"),
@Parameter(name = "userNo" , description = "유저 번호")
})
public ResponseEntity<String> teamJoinRequest (@RequestParam Long teamNo,
@RequestParam Long userNo) throws Exception {
teamService.teamJoinRequest(teamNo, userNo);
return ResponseEntity.status(HttpStatus.OK).body("정상적으로 신청되었습니다.");
}
- 서비스
/**
* 팀원 신청
*
* @param teamNo 팀번호
* @param userNo 유저번호
* @throws Exception 팀이 존재하지 않습니다.
* @throws Exception 유저가 존재하지 않습니다.
* @throws Exception 모집중이 아닙니다!
* @throws Exception 이미 등록되었거나 요청한 팀 입니다!!
*/
@Override
public void teamJoinRequest(Long teamNo, Long userNo) throws Exception {
if (teamUserRepository.findByUserNoEquals(teamNo, userNo)) {
throw new IllegalArgumentException("이미 등록되었거나 요청한 팀 입니다!!");
}
com.beyond.backend.data.entity.Team Team = teamRepository.findById(teamNo)
.orElseThrow(() -> new IllegalArgumentException("팀이 존재하지 않습니다."));
User user = userRepository.findById(userNo)
.orElseThrow(() -> new IllegalArgumentException("유저가 존재하지 않습니다."));
if (Team.getProjectStatus() != ProjectStatus.OPEN) {
throw new IllegalArgumentException("모집중이 아닙니다!");
}
TeamUser teamUser = TeamUser.builder()
.user(user)
.team(Team)
.status(false)
.isLeader(false)
.build();
teamUserRepository.save(teamUser);
}
다양한 예외 처리를 하였는데 이를 하나로 통일해서 관리하면 좋을 것 같다.
- 리포지토리
/**
* 유저가 팀에 속해있는지 여부
* @param teamNo 팀번호
* @param userNo 유저번호
* @return Boolean
*/
@Query("SELECT COUNT(tu) > 0 " +
"FROM TeamUser tu " +
"WHERE tu.team.no = :teamNo AND tu.user.no = :userNo ")
Boolean findByUserNoEquals (@Param("teamNo") Long teamNo, @Param("userNo") Long userNo);
5. DELETE/team/joinRequestCancel팀원 가입 취소 메서드
팀원이 가입 취소 버튼을 누르면 중간 테이블에서 삭제하는 메서드이다
이를 활용하면 팀원 개인이 스스로 탈퇴할 수 있다.
- 컨트롤러
/**
* 팀원 가입 취소 메서드
* @param teamNo 팀번호
* @param userNo 유저번호
* @return 없음
* @throws Exception 신청하지 않았거나 존재하지 않는 팀입니다.
*/
@PDeleteMapping("/joinRequestCancel")
@Operation(summary = "팀원 가입 취소 메서드", description = "팀원 가입 취소 메서드입니다.")
@Parameters({
@Parameter(name = "teamNo" , description = "팀 번호", example = "1"),
@Parameter(name = "userNo" , description = "유저 번호")
})
public ResponseEntity<String> teamJoinRequestCancel (@RequestParam Long teamNo,
@RequestParam Long userNo) throws Exception {
teamService.teamJoinRequestCancel(teamNo, userNo);
return ResponseEntity.status(HttpStatus.OK).body("정상적으로 취소되었습니다.");
}
- 서비스
/**
* 팀원 취소
* @param teamNo 팀번호
* @param userNo 유저번호
* @throws Exception 신청하지 않았거나 존재하지 않는 팀입니다.
*/
@Override
public void teamJoinRequestCancel(Long teamNo, Long userNo) throws Exception {
Long teamUserNo = teamUserRepository.findByUserNoForTeamUserNo(teamNo, userNo);
if (teamUserNo == null) {
throw new IllegalArgumentException("신청하지 않았거나 존재하지 않는 팀입니다.");
} else {
teamUserRepository.deleteById(teamUserNo);
}
}
6. GET/team/member/setting[팀장] 팀원 신청 목록 조회
팀장이 승인 여부가 ‘F’인 팀원들에 대한 목록을 조회하는 기능
- 컨트롤러
/**
* [팀장] 팀원 신청 목록 조회
* @param teamNo 팀번호
* @param userNo 유저번호
* @return TeamMemberListDto
* @throws Exception 권한이 없습니다!
*/
@GetMapping("/member/setting")
@Operation(summary = "[팀장] 팀원 신청 목록 조회", description = "팀원 신청 목록 조회 메서드입니다.")
@Parameters({
@Parameter(name = "teamNo" , description = "팀 번호", example = "1"),
@Parameter(name = "userNo" , description = "팀장 번호", example = "1")
})
public ResponseEntity<List<TeamMemberListDto>> getMemberRequest(
@RequestParam Long teamNo,
@RequestParam Long userNo) throws Exception {
List<TeamMemberListDto> teamMemberRequest = teamService.getTeamMemberRequest(teamNo, userNo);
return ResponseEntity.status(HttpStatus.OK).body(teamMemberRequest);
}
- 서비스
/**
* [팀장] 팀원 신청 목록 조회
*
* @param teamNo 팀번호
* @param userNo 유저번호
* @return TeamMemberListDto
* @throws Exception 권한이 없습니다!
*/
@Override
public List<TeamMemberListDto> getTeamMemberRequest(Long teamNo, Long userNo) throws Exception {
Boolean isLeader = teamUserRepository.isLeader(teamNo, userNo);
if (isLeader != null && isLeader) {
return teamUserRepository.findByTeamNoForMemberRequest(teamNo);
} else {
throw new IllegalArgumentException("권한이 없습니다!");
}
}
7. PUT/team/member/setting/teamAccept[팀장] 팀원 가입 수락
팀장이 승인 여부가 ‘F’인 회원을 승인 여부 ‘T’로 저장 → 팀원 추가
- 컨트롤러
/**
* [팀장] 팀원 가입 수락 메서드
* @param teamNo 팀번호
* @param userNo 신청한 유저의 유저번호
* @return 정상적으로 수락되었습니다.
* @throws Exception 신청한 유저가 없습니다!
* @throws Exception 이미 가입된 유저입니다!
*/
@PutMapping("/member/setting/teamAccept")
@Operation(summary = "[팀장] 팀원 가입 수락 메서드", description = "팀원 가입 수락 메서드입니다.")
@Parameters({
@Parameter(name = "teamNo" , description = "팀 번호", example = "1"),
@Parameter(name = "userNo" , description = "유저 번호")
})
public ResponseEntity<String> teamAccept (@RequestParam Long teamNo,
@RequestParam Long userNo) throws Exception {
teamService.teamAccept(teamNo, userNo);
return ResponseEntity.status(HttpStatus.OK).body("정상적으로 수락 되었습니다.");
}
- 서비스
/**
* [팀장] 팀원 가입 수락
* @param teamNo 팀번호
* @param userNo 신청한 유저의 유저번호
* @throws Exception 신청한 유저가 없습니다!
* @throws Exception 이미 가입된 유저입니다!
*/
@Override
public void teamAccept(Long teamNo, Long userNo) throws Exception {
Long teamUserNo = teamUserRepository.findByUserNoForTeamUserNo(teamNo, userNo);
TeamUser teamUser = teamUserRepository.findById(teamUserNo)
.orElseThrow(() -> new IllegalArgumentException("신청한 유저가 없습니다!"));
boolean status = teamUser.isStatus();
if (status) {
throw new IllegalArgumentException("이미 가입된 유저입니다!");
}else {
teamUser.setStatus(true);
teamUserRepository.save(teamUser);
}
}
8. DELETE/team/member/setting/teamDelete[팀장] 팀원 가입 거부
팀장이 중간 테이블에서 팀원을 제거한다. 추방 기능으로 활용도 가능하지만 보류
- 컨트롤러
/**
* [팀장] 팀원 가입 거부 메서드
* @param teamNo 팀번호
* @param userNo 신청한 유저의 유저번호
* @return 정상적으로 처리 되었습니다.
* @throws Exception 신청한 유저가 없습니다!
*/
@DeleteMapping("/member/setting/teamDelete")
@Operation(summary = "[팀장] 팀원 가입 거부 메서드", description = "팀원 가입 거부 메서드입니다.")
@Parameters({
@Parameter(name = "teamNo" , description = "팀 번호", example = "1"),
@Parameter(name = "userNo" , description = "유저 번호")
})
public ResponseEntity<String> teamDelete(@RequestParam Long teamNo,
@RequestParam Long userNo) throws Exception {
teamService.teamDelete(teamNo, userNo);
return ResponseEntity.status(HttpStatus.OK).body("정상적으로 처리 되었습니다.");
}
- 서비스
/**
* [팀장] 팀원 신청 거부
* @param teamNo 팀번호
* @param userNo 신청한 유저의 유저번호
* @throws Exception 신청한 유저가 없습니다!
*/
@Override
public void teamDelete(Long teamNo, Long userNo) throws Exception {
Long teamUserNo = teamUserRepository.findByUserNoForTeamUserNo(teamNo, userNo);
TeamUser teamUser = teamUserRepository.findById(teamUserNo)
.orElseThrow(() -> new IllegalArgumentException("신청한 유저가 없습니다!"));
boolean status = teamUser.isStatus();
if (!status) {
teamUserRepository.deleteById(teamUserNo);
}
// 추방도 가능하지만 일방적인 추방 기능은 논의해봐야할듯
// 현재는 유저 스스로 나가는것만 가능
}
이후에 URL 수정을 해주었다.
DELETE/team/{teamNo}/join-cancel**팀원 가입 취소 메서드
POST/team/{teamNo}/join-request**팀원 가입 신청 메서드
DELETE/team/{teamNo}/setting/delete**팀 삭제 메서드
GET/team/{teamNo}/setting/members[팀장] 팀원 신청 목록 조회
PUT/team/{teamNo}/setting/members/accept/{userNo}[팀장] 팀원 가입 수락 메서드
PUT/team/{teamNo}/setting/members/delete/{userNo}[팀장] 팀원 가입 거부 메서드
GET/team/{teamNo}/setting/members/find**팀원 목록 조회 메서드
PUT/team/{teamNo}/setting/update**팀 수정 메서드
POST/team/create**팀 생성 메서드
GET/team/find**해당 유저의 모든 팀 조회 메서드
하지만 RESTFul 하지 않기 때문에 다시 수정해야한다.
'백엔드 > Spring Boot' 카테고리의 다른 글
모여봄 #4 팀 조회 페이징 추가 (0) | 2025.03.08 |
---|---|
모여봄 #3 팀 조회 기능 (1) | 2025.03.08 |
모여봄 #2 CRUD 구현 (0) | 2025.03.02 |
모여봄 #1 프로젝트 구상 (0) | 2025.02.23 |