From a44da2942b033c87d19f3a1e7db60e7f87298644 Mon Sep 17 00:00:00 2001 From: wochae Date: Mon, 12 Feb 2024 20:38:24 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[Fix]=20:=20=EC=A4=80=EB=B9=84=EB=90=90?= =?UTF-8?q?=EC=A7=80=20=EC=9E=84=EC=A0=84=EC=9C=A4=EC=B1=84=20#848?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 물론이지 호주정우 --- .../controller/board/RecruitController.java | 7 ++- .../service/board/recruit/RecruitService.java | 46 ++++++++++++------- .../backend/service/team/TeamService.java | 11 +++++ 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/main/java/peer/backend/controller/board/RecruitController.java b/src/main/java/peer/backend/controller/board/RecruitController.java index b404cabf..6ecc2a8d 100644 --- a/src/main/java/peer/backend/controller/board/RecruitController.java +++ b/src/main/java/peer/backend/controller/board/RecruitController.java @@ -13,8 +13,6 @@ import peer.backend.entity.board.recruit.Recruit; import peer.backend.entity.board.recruit.enums.RecruitFavoriteEnum; import peer.backend.entity.user.User; -import peer.backend.exception.NotFoundException; -import peer.backend.repository.board.recruit.RecruitRepository; import peer.backend.service.board.recruit.RecruitService; import javax.validation.Valid; @@ -66,8 +64,9 @@ public Long updateRecruit(@PathVariable Long recruit_id, @ApiOperation(value = "", notes = "모집글을 삭제한다.") @DeleteMapping("/{recruit_id}") - public void deleteRecruit(@PathVariable Long recruit_id) { - recruitService.deleteRecruit(recruit_id); + public void deleteRecruit(@PathVariable Long recruit_id, Authentication auth) { + User user = User.authenticationToUser(auth); + recruitService.deleteRecruit(recruit_id, user); } @ApiOperation(value = "", notes = "모집에 지원한다.") diff --git a/src/main/java/peer/backend/service/board/recruit/RecruitService.java b/src/main/java/peer/backend/service/board/recruit/RecruitService.java index b3b21585..b38b232c 100644 --- a/src/main/java/peer/backend/service/board/recruit/RecruitService.java +++ b/src/main/java/peer/backend/service/board/recruit/RecruitService.java @@ -1,6 +1,21 @@ package peer.backend.service.board.recruit; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Join; +import javax.persistence.criteria.Order; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; +import javax.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -9,7 +24,15 @@ import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; import peer.backend.annotation.tracking.RecruitWritingTracking; -import peer.backend.dto.board.recruit.*; +import peer.backend.dto.board.recruit.ApplyRecruitRequest; +import peer.backend.dto.board.recruit.RecruitCreateRequest; +import peer.backend.dto.board.recruit.RecruitFavoriteResponse; +import peer.backend.dto.board.recruit.RecruitInterviewDto; +import peer.backend.dto.board.recruit.RecruitListRequest; +import peer.backend.dto.board.recruit.RecruitListResponse; +import peer.backend.dto.board.recruit.RecruitResponce; +import peer.backend.dto.board.recruit.RecruitUpdateRequestDTO; +import peer.backend.dto.board.recruit.RecruitUpdateResponse; import peer.backend.dto.noti.enums.NotificationPriority; import peer.backend.dto.noti.enums.NotificationType; import peer.backend.dto.team.TeamApplyDataDTO; @@ -32,9 +55,11 @@ import peer.backend.entity.team.enums.TeamUserRoleType; import peer.backend.entity.team.enums.TeamUserStatus; import peer.backend.entity.user.User; +import peer.backend.exception.BadRequestException; +import peer.backend.exception.ConflictException; import peer.backend.exception.IllegalArgumentException; import peer.backend.exception.IndexOutOfBoundsException; -import peer.backend.exception.*; +import peer.backend.exception.NotFoundException; import peer.backend.repository.board.recruit.RecruitFavoriteRepository; import peer.backend.repository.board.recruit.RecruitRepository; import peer.backend.repository.team.TeamJobRepository; @@ -46,19 +71,6 @@ import peer.backend.service.profile.UserPortfolioService; import peer.backend.service.team.TeamService; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.*; -import javax.transaction.Transactional; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - @Service @RequiredArgsConstructor @Slf4j @@ -441,7 +453,7 @@ public void applyRecruit(Long recruit_id, ApplyRecruitRequest request, Authentic } @Transactional - public void deleteRecruit(Long recruit_id) { + public void deleteRecruit(Long recruit_id, User user) { Recruit recruit = recruitRepository.findById(recruit_id).orElseThrow( () -> new NotFoundException("존재하지 않는 모집게시글입니다.")); if (recruit.getStatus().equals(RecruitStatus.DONE)) { @@ -450,10 +462,10 @@ public void deleteRecruit(Long recruit_id) { if (teamUserRepository.existsApprovedByTeamId(recruit.getTeam().getId())) { throw new BadRequestException("승인된 팀원이 있는 경우 삭제할 수 없습니다."); } - objectService.deleteObject(recruit.getThumbnailUrl()); if (recruit.getFiles() != null && !recruit.getFiles().isEmpty()) recruit.getFiles().forEach(file -> objectService.deleteObject(file.getUrl())); + teamService.deleteTeam(recruit.getTeam().getId()); recruitRepository.delete(recruit); } diff --git a/src/main/java/peer/backend/service/team/TeamService.java b/src/main/java/peer/backend/service/team/TeamService.java index 21742ec6..134a912e 100644 --- a/src/main/java/peer/backend/service/team/TeamService.java +++ b/src/main/java/peer/backend/service/team/TeamService.java @@ -255,6 +255,17 @@ public void grantRole(Long teamId, Long grantingUserId, User user, ); } + @Transactional + public void deleteTeam(Long teamId) { + Team team = teamRepository.findById(teamId).orElseThrow(() -> new NotFoundException("팀을 찾을 수 없습니다.")); + // TeamUser 엔티티 삭제 + team.getTeamUsers().forEach(teamUser -> { + teamUserRepository.delete(teamUser); + }); + // Team 엔티티 삭제 + teamRepository.delete(team); + } + @Transactional public void exitTeam(Long teamId, User user) { Team team = teamRepository.findById(teamId) From 2a37a6972d653db2a9facf7d734a15e43a30af04 Mon Sep 17 00:00:00 2001 From: wochae Date: Mon, 12 Feb 2024 21:13:12 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[Refactor]=20:=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80=20#848?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 유저, 삭제 메서드 호출 관련 예외 처리 --- .../controller/board/RecruitController.java | 12 +- .../service/board/recruit/RecruitService.java | 282 +++++++++--------- 2 files changed, 153 insertions(+), 141 deletions(-) diff --git a/src/main/java/peer/backend/controller/board/RecruitController.java b/src/main/java/peer/backend/controller/board/RecruitController.java index 6ecc2a8d..d55b03d9 100644 --- a/src/main/java/peer/backend/controller/board/RecruitController.java +++ b/src/main/java/peer/backend/controller/board/RecruitController.java @@ -6,6 +6,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; import peer.backend.annotation.AuthorCheck; @@ -13,6 +14,7 @@ import peer.backend.entity.board.recruit.Recruit; import peer.backend.entity.board.recruit.enums.RecruitFavoriteEnum; import peer.backend.entity.user.User; +import peer.backend.exception.BadRequestException; import peer.backend.service.board.recruit.RecruitService; import javax.validation.Valid; @@ -64,9 +66,13 @@ public Long updateRecruit(@PathVariable Long recruit_id, @ApiOperation(value = "", notes = "모집글을 삭제한다.") @DeleteMapping("/{recruit_id}") - public void deleteRecruit(@PathVariable Long recruit_id, Authentication auth) { - User user = User.authenticationToUser(auth); - recruitService.deleteRecruit(recruit_id, user); + public ResponseEntity deleteRecruit(@PathVariable Long recruit_id, Authentication auth) { + try { + recruitService.deleteRecruit(recruit_id, User.authenticationToUser(auth)); + } catch (BadRequestException e) { + return ResponseEntity.badRequest().body(e); + } + return ResponseEntity.ok().build(); } @ApiOperation(value = "", notes = "모집에 지원한다.") diff --git a/src/main/java/peer/backend/service/board/recruit/RecruitService.java b/src/main/java/peer/backend/service/board/recruit/RecruitService.java index b38b232c..f7035975 100644 --- a/src/main/java/peer/backend/service/board/recruit/RecruitService.java +++ b/src/main/java/peer/backend/service/board/recruit/RecruitService.java @@ -98,7 +98,7 @@ public class RecruitService { public void changeRecruitFavorite(Authentication auth, Long recruitId, - RecruitFavoriteEnum type) { + RecruitFavoriteEnum type) { User user = User.authenticationToUser(auth); Optional rawTarget = recruitRepository.findById(recruitId); @@ -107,22 +107,22 @@ public void changeRecruitFavorite(Authentication auth, Long recruitId, } recruitFavoriteRepository.findById(new RecruitFavoritePK(user.getId(), recruitId)) - .ifPresentOrElse( - favorite -> { - if (favorite.getType().equals(type)) { - recruitFavoriteRepository.delete(favorite); - } else { - favorite.setType(type); - recruitFavoriteRepository.save(favorite); - } - }, - () -> { - RecruitFavorite newFavorite = new RecruitFavorite(); - newFavorite.setUserId(user.getId()); - newFavorite.setRecruitId(recruitId); - newFavorite.setType(type); - recruitFavoriteRepository.save(newFavorite); - }); + .ifPresentOrElse( + favorite -> { + if (favorite.getType().equals(type)) { + recruitFavoriteRepository.delete(favorite); + } else { + favorite.setType(type); + recruitFavoriteRepository.save(favorite); + } + }, + () -> { + RecruitFavorite newFavorite = new RecruitFavorite(); + newFavorite.setUserId(user.getId()); + newFavorite.setRecruitId(recruitId); + newFavorite.setType(type); + recruitFavoriteRepository.save(newFavorite); + }); this.notificationCreationService.makeNotificationForUser( null, @@ -138,14 +138,14 @@ public void changeRecruitFavorite(Authentication auth, Long recruitId, public List getInterviewList(Long recruit_id) { Recruit recruit = recruitRepository.findById(recruit_id) - .orElseThrow(() -> new NotFoundException("존재하지 않는 모집글입니다.")); + .orElseThrow(() -> new NotFoundException("존재하지 않는 모집글입니다.")); List result = new ArrayList<>(); for (RecruitInterview question : recruit.getInterviews()) { RecruitInterviewDto recruitInterviewDto = RecruitInterviewDto.builder() - .question(question.getQuestion()) - .type(question.getType().toString()) - .optionList(question.getOptions()) - .build(); + .question(question.getQuestion()) + .type(question.getType().toString()) + .optionList(question.getOptions()) + .build(); result.add(recruitInterviewDto); } @@ -224,112 +224,113 @@ public List getRecruitListByCriteria(RecruitListRequest request) { } public Page getRecruitSearchList(Pageable pageable, - RecruitListRequest request, User user) { + RecruitListRequest request, User user) { List recruits = getRecruitListByCriteria(request); List results = recruits.stream() - .map(recruit2 -> new RecruitListResponse( - recruit2.getTitle(), - recruit2.getThumbnailUrl(), - recruit2.getWriterId(), - recruit2.getWriter() == null ? null : recruit2.getWriter().getNickname(), - recruit2.getWriter() == null ? null : recruit2.getWriter().getImageUrl(), - recruit2.getStatus().toString(), - // TODO: 맞나 성능 개선이 필요한거 같기도 - this.tagService.recruitTagListToTagResponseList(recruit2.getRecruitTags()), - recruit2.getId(), - user != null && recruitFavoriteRepository - .existsByUserIdAndRecruitIdAndType(user.getId(), recruit2.getId(), RecruitFavoriteEnum.LIKE), - recruit2.getUpdatedAt().toString()) - ).collect(Collectors.toList()); + .map(recruit2 -> new RecruitListResponse( + recruit2.getTitle(), + recruit2.getThumbnailUrl(), + recruit2.getWriterId(), + recruit2.getWriter() == null ? null : recruit2.getWriter().getNickname(), + recruit2.getWriter() == null ? null : recruit2.getWriter().getImageUrl(), + recruit2.getStatus().toString(), + // TODO: 맞나 성능 개선이 필요한거 같기도 + this.tagService.recruitTagListToTagResponseList(recruit2.getRecruitTags()), + recruit2.getId(), + user != null && recruitFavoriteRepository + .existsByUserIdAndRecruitIdAndType(user.getId(), recruit2.getId(), + RecruitFavoriteEnum.LIKE), + recruit2.getUpdatedAt().toString()) + ).collect(Collectors.toList()); int fromIndex = pageable.getPageNumber() * pageable.getPageSize(); if (fromIndex > results.size()) { throw new IndexOutOfBoundsException("존재하지 않는 페이지입니다"); } return new PageImpl<>(results.subList(fromIndex, - Math.min(fromIndex + pageable.getPageSize(), results.size())), pageable, - results.size()); + Math.min(fromIndex + pageable.getPageSize(), results.size())), pageable, + results.size()); } @Transactional public RecruitResponce getRecruit(Long recruit_id, Authentication auth) { Recruit recruit = recruitRepository.findById(recruit_id) - .orElseThrow(() -> new NotFoundException("존재하지 않는 모집글입니다.")); + .orElseThrow(() -> new NotFoundException("존재하지 않는 모집글입니다.")); List teamJobs = recruit.getTeam().getJobs(); recruit.setHit(recruit.getHit() + 1); List jobDtoList = new ArrayList<>(); teamJobs.forEach( - role -> jobDtoList.add( - new TeamJobDto( - role.getName(), - role.getMax(), - role.getCurrent()))); + role -> jobDtoList.add( + new TeamJobDto( + role.getName(), + role.getMax(), + role.getCurrent()))); Team team = recruit.getTeam(); return RecruitResponce.builder() - .title(recruit.getTitle()) - .content(recruit.getContent()) - .region((Objects.isNull(team.getRecruit()) || Objects.isNull(team.getRegion2()) ? null - : new ArrayList<>(List.of(team.getRegion1(), team.getRegion2())))) - .status(recruit.getStatus()) - .totalNumber(team.getJobs().stream().mapToInt(TeamJob::getMax).sum()) - .current(teamUserJobRepository.findByTeamUserTeamIdAndStatus(team.getId(), - TeamUserStatus.APPROVED).size()) - .due(team.getDueTo().getLabel()) - .link(recruit.getLink()) - .leader_id(recruit.getWriterId()) - .leader_nickname(recruit.getWriter() == null ? null : recruit.getWriter().getNickname()) - .leader_image(recruit.getWriter() == null ? null : recruit.getWriter().getImageUrl()) - .tagList(this.tagService.recruitTagListToTagResponseList(recruit.getRecruitTags())) - .roleList(jobDtoList) - .place(team.getOperationFormat()) - .image(recruit.getThumbnailUrl()) - .teamName(recruit.getTeam().getName()) - .isFavorite((auth != null) && - recruitFavoriteRepository.existsByUserIdAndRecruitIdAndType( - User.authenticationToUser(auth).getId(), - recruit_id, - RecruitFavoriteEnum.LIKE) - ) - .updatedAt(recruit.getUpdatedAt().toString()) - .build(); + .title(recruit.getTitle()) + .content(recruit.getContent()) + .region((Objects.isNull(team.getRecruit()) || Objects.isNull(team.getRegion2()) ? null + : new ArrayList<>(List.of(team.getRegion1(), team.getRegion2())))) + .status(recruit.getStatus()) + .totalNumber(team.getJobs().stream().mapToInt(TeamJob::getMax).sum()) + .current(teamUserJobRepository.findByTeamUserTeamIdAndStatus(team.getId(), + TeamUserStatus.APPROVED).size()) + .due(team.getDueTo().getLabel()) + .link(recruit.getLink()) + .leader_id(recruit.getWriterId()) + .leader_nickname(recruit.getWriter() == null ? null : recruit.getWriter().getNickname()) + .leader_image(recruit.getWriter() == null ? null : recruit.getWriter().getImageUrl()) + .tagList(this.tagService.recruitTagListToTagResponseList(recruit.getRecruitTags())) + .roleList(jobDtoList) + .place(team.getOperationFormat()) + .image(recruit.getThumbnailUrl()) + .teamName(recruit.getTeam().getName()) + .isFavorite((auth != null) && + recruitFavoriteRepository.existsByUserIdAndRecruitIdAndType( + User.authenticationToUser(auth).getId(), + recruit_id, + RecruitFavoriteEnum.LIKE) + ) + .updatedAt(recruit.getUpdatedAt().toString()) + .build(); } public RecruitUpdateResponse getRecruitwithInterviewList(Long recruit_id) { Recruit recruit = recruitRepository.findById(recruit_id) - .orElseThrow(() -> new NotFoundException("존재하지 않는 모집글입니다.")); + .orElseThrow(() -> new NotFoundException("존재하지 않는 모집글입니다.")); List teamJobs = recruit.getTeam().getJobs(); List roleDtoList = new ArrayList<>(); teamJobs.forEach( - role -> roleDtoList.add( - new TeamJobDto(role.getName(), role.getMax(), role.getCurrent()))); + role -> roleDtoList.add( + new TeamJobDto(role.getName(), role.getMax(), role.getCurrent()))); Team team = recruit.getTeam(); //TODO:DTO 항목 추가 필요 return RecruitUpdateResponse.builder() - .title(recruit.getTitle()) - .content(recruit.getContent()) - .region1(team.getRegion1()) - .region2(team.getRegion2()) - .status(recruit.getStatus()) - .totalNumber(teamJobs.stream().mapToInt(TeamJob::getMax).sum()) - .current(team.getTeamUsers().size()) - .due(team.getDueTo().getLabel()) - .link(recruit.getLink()) - .leader_id(recruit.getWriterId()) - .leader_nickname( - Objects.isNull(recruit.getWriter()) ? null : recruit.getWriter().getNickname()) - .leader_image( - Objects.isNull(recruit.getWriter()) ? null : recruit.getWriter().getImageUrl()) - .tagList(this.tagService.recruitTagListToTagResponseList(recruit.getRecruitTags())) - .roleList(roleDtoList) - .interviewList(getInterviewList(recruit_id)) - .isAnswered(recruit.getTeam().getTeamUsers().size() > 1) - .place(team.getOperationFormat().getValue()) - .type(team.getType().getValue()) - .name(recruit.getTeam().getName()) - .image(recruit.getThumbnailUrl()) - .build(); + .title(recruit.getTitle()) + .content(recruit.getContent()) + .region1(team.getRegion1()) + .region2(team.getRegion2()) + .status(recruit.getStatus()) + .totalNumber(teamJobs.stream().mapToInt(TeamJob::getMax).sum()) + .current(team.getTeamUsers().size()) + .due(team.getDueTo().getLabel()) + .link(recruit.getLink()) + .leader_id(recruit.getWriterId()) + .leader_nickname( + Objects.isNull(recruit.getWriter()) ? null : recruit.getWriter().getNickname()) + .leader_image( + Objects.isNull(recruit.getWriter()) ? null : recruit.getWriter().getImageUrl()) + .tagList(this.tagService.recruitTagListToTagResponseList(recruit.getRecruitTags())) + .roleList(roleDtoList) + .interviewList(getInterviewList(recruit_id)) + .isAnswered(recruit.getTeam().getTeamUsers().size() > 1) + .place(team.getOperationFormat().getValue()) + .type(team.getType().getValue()) + .name(recruit.getTeam().getName()) + .image(recruit.getThumbnailUrl()) + .build(); } private void addInterviewsToRecruit(Recruit recruit, List interviewList) { @@ -342,18 +343,18 @@ private void addInterviewsToRecruit(Recruit recruit, List i private Recruit createRecruitFromDto(RecruitCreateRequest request, Team team, User user) { Recruit recruit = Recruit.builder() - .team(team) - .title(request.getTitle()) - .link(request.getLink()) - .content(request.getContent()) - .status(RecruitStatus.ONGOING) - .thumbnailUrl( - objectService.uploadObject("recruit/" + team.getId().toString(), request.getImage(), - "image")) - .writerId(user.getId()) - .writer(user) - .hit(0L) - .build(); + .team(team) + .title(request.getTitle()) + .link(request.getLink()) + .content(request.getContent()) + .status(RecruitStatus.ONGOING) + .thumbnailUrl( + objectService.uploadObject("recruit/" + team.getId().toString(), request.getImage(), + "image")) + .writerId(user.getId()) + .writer(user) + .hit(0L) + .build(); addInterviewsToRecruit(recruit, request.getInterviewList()); return recruit; } @@ -369,8 +370,8 @@ public Recruit createRecruit(RecruitCreateRequest request, Authentication auth) Recruit recruit = recruitRepository.save(createRecruitFromDto(request, team, user)); if (request.getTagList() != null) { recruit.setRecruitTags(request.getTagList().stream() - .map(e -> (new RecruitTag(recruit.getId(), e))).collect( - Collectors.toList())); + .map(e -> (new RecruitTag(recruit.getId(), e))).collect( + Collectors.toList())); } recruit.addFiles(objectService.extractContentImage(request.getContent())); @@ -393,8 +394,7 @@ public Recruit createRecruit(RecruitCreateRequest request, Authentication auth) public void applyRecruit(Long recruit_id, ApplyRecruitRequest request, Authentication auth) { // 모집글 찾기 Recruit recruit = recruitRepository.findById(recruit_id) - .orElseThrow(() -> new NotFoundException("존재하지 않는 모집글입니다.")); - + .orElseThrow(() -> new NotFoundException("존재하지 않는 모집글입니다.")); // 모집글 작성자 여부 검증 User user = User.authenticationToUser(auth); @@ -410,7 +410,7 @@ public void applyRecruit(Long recruit_id, ApplyRecruitRequest request, Authentic // 지원 역할 검증 TeamJob teamJob = teamJobRepository.findByTeamIdAndName(recruit_id, request.getRole()) - .orElseThrow(() -> new NotFoundException("존재하지 않는 역할입니다.")); + .orElseThrow(() -> new NotFoundException("존재하지 않는 역할입니다.")); String query = "SELECT new peer.backend.dto.team.TeamApplyDataDTO(" + "tj.id, tj.name, tj.max, tj.team.id, " + @@ -419,52 +419,58 @@ public void applyRecruit(Long recruit_id, ApplyRecruitRequest request, Authentic " FROM TeamJob tj " + " WHERE tj.team.id = :teamId AND tj.name != 'Leader'"; - List teamData = this.entityManager.createQuery(query, TeamApplyDataDTO.class).setParameter("teamId", team.getId()).getResultList(); + List teamData = this.entityManager.createQuery(query, TeamApplyDataDTO.class) + .setParameter("teamId", team.getId()).getResultList(); teamData.forEach(m -> { if (m.getName().equals(request.getRole()) && m.getMax() - m.getApplyNumber() == 0) { - throw new BadRequestException("지원이 불가능합니다!"); + throw new BadRequestException("지원이 불가능합니다!"); } }); // 팀 지원자 리스트 확인 TeamUser teamUser = this.teamUserRepository.findByUserIdAndTeamId(user.getId(), - team.getId()).orElse(null); + team.getId()).orElse(null); if (Objects.isNull(teamUser)) { teamUser = TeamUser.builder() - .teamId(team.getId()) - .userId(user.getId()) - .role(TeamUserRoleType.MEMBER) - .status(TeamUserStatus.PENDING) - .build(); + .teamId(team.getId()) + .userId(user.getId()) + .role(TeamUserRoleType.MEMBER) + .status(TeamUserStatus.PENDING) + .build(); teamUserRepository.save(teamUser); } else if (teamUserJobRepository.existsById( - new TeamUserJobPK(teamUser.getId(), teamJob.getId()))) { + new TeamUserJobPK(teamUser.getId(), teamJob.getId()))) { // 이미 지원한 경우 throw new ConflictException("이미 지원하였습니다."); } // 팀 유저에 추가 teamUser.addTeamUserJob(TeamUserJob.builder() - .teamJobId(teamJob.getId()) - .teamUserId(teamUser.getId()) - .status(TeamUserStatus.PENDING) - .answers(request.getAnswerList()) - .build()); + .teamJobId(teamJob.getId()) + .teamUserId(teamUser.getId()) + .status(TeamUserStatus.PENDING) + .answers(request.getAnswerList()) + .build()); } @Transactional public void deleteRecruit(Long recruit_id, User user) { Recruit recruit = recruitRepository.findById(recruit_id).orElseThrow( - () -> new NotFoundException("존재하지 않는 모집게시글입니다.")); + () -> new NotFoundException("존재하지 않는 모집게시글입니다.")); if (recruit.getStatus().equals(RecruitStatus.DONE)) { throw new BadRequestException("모집이 완료된 경우 삭제할 수 없습니다."); } if (teamUserRepository.existsApprovedByTeamId(recruit.getTeam().getId())) { throw new BadRequestException("승인된 팀원이 있는 경우 삭제할 수 없습니다."); } + if (!teamUserRepository.existsAndLeaderByUserIdAndTeamId(user.getId(), + recruit.getTeam().getId())) { + throw new BadRequestException("팀장만 삭제할 수 있습니다."); + } objectService.deleteObject(recruit.getThumbnailUrl()); - if (recruit.getFiles() != null && !recruit.getFiles().isEmpty()) + if (recruit.getFiles() != null && !recruit.getFiles().isEmpty()) { recruit.getFiles().forEach(file -> objectService.deleteObject(file.getUrl())); + } teamService.deleteTeam(recruit.getTeam().getId()); recruitRepository.delete(recruit); } @@ -472,13 +478,13 @@ public void deleteRecruit(Long recruit_id, User user) { @Transactional public Long updateRecruit(Long recruit_id, RecruitUpdateRequestDTO recruitUpdateRequestDTO) { Recruit recruit = recruitRepository.findById(recruit_id).orElseThrow( - () -> new NotFoundException("존재하지 않는 모집게시글입니다.")); + () -> new NotFoundException("존재하지 않는 모집게시글입니다.")); List contentImages = objectService.extractContentImage(recruitUpdateRequestDTO.getContent()); if (recruitUpdateRequestDTO.getImage() != null) { recruit.update(recruitUpdateRequestDTO, contentImages); objectService.deleteObject(recruit.getThumbnailUrl()); recruit.setThumbnailUrl(objectService.uploadObject(recruitUpdateRequestDTO.getImage(), - "recruit/" + recruit_id, "image")); + "recruit/" + recruit_id, "image")); this.userPortfolioService.setRecruitImagePath(recruit.getId(), recruit.getThumbnailUrl()); } else { recruit.update(recruitUpdateRequestDTO, contentImages); @@ -487,25 +493,25 @@ public Long updateRecruit(Long recruit_id, RecruitUpdateRequestDTO recruitUpdate } @Transactional - public List getFavoriteList(RecruitListRequest request, User user) - { + public List getFavoriteList(RecruitListRequest request, User user) { List recruitList = getRecruitListByCriteria(request); return recruitList.stream() .map(recruit -> RecruitFavoriteResponse.builder() .recruit_id(recruit.getId()) .favorite(user != null && (recruitFavoriteRepository.existsByUserIdAndRecruitIdAndType( - user.getId(), - recruit.getId(), - RecruitFavoriteEnum.LIKE))) + user.getId(), + recruit.getId(), + RecruitFavoriteEnum.LIKE))) .build() ).collect(Collectors.toList()); } @Transactional public boolean getFavorite(Long recruit_id, User user) { - if (!recruitRepository.existsById(recruit_id)) + if (!recruitRepository.existsById(recruit_id)) { throw new NotFoundException("존재하지 않는 게시글입니다."); + } return (user != null && recruitFavoriteRepository .existsByUserIdAndRecruitIdAndType( From 4f63d9f99003dca11a3197aa61cbb894c4409fc3 Mon Sep 17 00:00:00 2001 From: wochae Date: Tue, 13 Feb 2024 20:32:52 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[Refactor]=20:=20=EC=9E=91=EC=84=B1?= =?UTF-8?q?=EC=9E=90=20=EA=B6=8C=ED=95=9C=20#848?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 편집처럼 삭제도 작성자 확인로직 추가. --- .../java/peer/backend/controller/board/RecruitController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/peer/backend/controller/board/RecruitController.java b/src/main/java/peer/backend/controller/board/RecruitController.java index d55b03d9..92ae343a 100644 --- a/src/main/java/peer/backend/controller/board/RecruitController.java +++ b/src/main/java/peer/backend/controller/board/RecruitController.java @@ -66,6 +66,7 @@ public Long updateRecruit(@PathVariable Long recruit_id, @ApiOperation(value = "", notes = "모집글을 삭제한다.") @DeleteMapping("/{recruit_id}") + @AuthorCheck public ResponseEntity deleteRecruit(@PathVariable Long recruit_id, Authentication auth) { try { recruitService.deleteRecruit(recruit_id, User.authenticationToUser(auth));