diff --git a/dump.rdb b/dump.rdb new file mode 100644 index 00000000..9b39316a Binary files /dev/null and b/dump.rdb differ diff --git a/src/main/java/com/example/tily/alarm/AlarmRepository.java b/src/main/java/com/example/tily/alarm/AlarmRepository.java index 1ab6ad12..80c731e6 100644 --- a/src/main/java/com/example/tily/alarm/AlarmRepository.java +++ b/src/main/java/com/example/tily/alarm/AlarmRepository.java @@ -2,6 +2,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -15,5 +16,10 @@ public interface AlarmRepository extends JpaRepository { "where a.receiver.id=:receiverId and a.comment.writer.id!=:receiverId") List findAllByReceiverId(@Param("receiverId") Long receiverId, Sort sort); + @Modifying void deleteByCommentId(Long commentId); + + @Modifying + @Query("delete from Alarm a where a.comment.id in :commentIds") + void deleteByCommentIds(List commentIds); } diff --git a/src/main/java/com/example/tily/alarm/AlarmRequest.java b/src/main/java/com/example/tily/alarm/AlarmRequest.java index 0fe3ee75..a5639a21 100644 --- a/src/main/java/com/example/tily/alarm/AlarmRequest.java +++ b/src/main/java/com/example/tily/alarm/AlarmRequest.java @@ -5,7 +5,6 @@ public class AlarmRequest { public record ReadAlarmDTO(List alarms) { - public record AlarmDTO(Long id) { } } diff --git a/src/main/java/com/example/tily/alarm/AlarmResponse.java b/src/main/java/com/example/tily/alarm/AlarmResponse.java index 620fe6b2..c9550223 100644 --- a/src/main/java/com/example/tily/alarm/AlarmResponse.java +++ b/src/main/java/com/example/tily/alarm/AlarmResponse.java @@ -10,7 +10,8 @@ public class AlarmResponse { public record RoadmapDTO(Long id, String name) { public RoadmapDTO(Roadmap roadmap) { - this(roadmap.getId(), roadmap.getName()); + this(roadmap.getId(), roadmap.getName() + ); } } @@ -41,10 +42,11 @@ public AlarmDTO(Alarm alarm){ alarm.getCreatedDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")), new RoadmapDTO(alarm.getTil().getRoadmap()), new StepDTO(alarm.getTil().getStep()), - new SenderDTO(alarm.getComment().getWriter())); + new SenderDTO(alarm.getComment().getWriter()) + ); } } - public record FindAllDTO(List alarms) { + public record FindAllDTO(List alarms) { } } diff --git a/src/main/java/com/example/tily/comment/CommentRepository.java b/src/main/java/com/example/tily/comment/CommentRepository.java index 44a96fc5..785678e4 100644 --- a/src/main/java/com/example/tily/comment/CommentRepository.java +++ b/src/main/java/com/example/tily/comment/CommentRepository.java @@ -8,14 +8,23 @@ import java.util.List; public interface CommentRepository extends JpaRepository { - + @Modifying @Query("select c from Comment c join fetch c.writer where c.til.id=:tilId") List findByTilId(@Param("tilId") Long tilId); + List findByWriterId(Long writerId); + + @Query("select c from Comment c where c.til.id in :tilIds") + List findByTilIds(@Param("tilIds") List tilIds); + @Modifying @Query("update Comment c SET c.isDeleted = true WHERE c.isDeleted = false AND c.id = :commentId") void softDeleteCommentById(Long commentId); + @Modifying + @Query("update Comment c SET c.isDeleted = true WHERE c.isDeleted = false AND c.id IN :commentIds") + void softDeleteCommentsByIds(List commentIds); + @Modifying @Query("update Comment c SET c.isDeleted = true WHERE c.isDeleted = false AND c.til.id = :tilId") void softDeleteCommentsByTilId(Long tilId); diff --git a/src/main/java/com/example/tily/comment/CommentRequest.java b/src/main/java/com/example/tily/comment/CommentRequest.java index 229dbd9c..1472dd70 100644 --- a/src/main/java/com/example/tily/comment/CommentRequest.java +++ b/src/main/java/com/example/tily/comment/CommentRequest.java @@ -4,7 +4,10 @@ public class CommentRequest { - public record CreateCommentDTO(Long roadmapId, Long stepId, Long tilId, @NotBlank(message = "댓글 내용을 입력해주세요.") String content) { + public record CreateCommentDTO(Long roadmapId, + Long stepId, + Long tilId, + @NotBlank(message = "댓글 내용을 입력해주세요.") String content) { } public record UpdateCommentDTO(@NotBlank(message = "댓글 내용을 입력해주세요.") String content) { diff --git a/src/main/java/com/example/tily/comment/CommentService.java b/src/main/java/com/example/tily/comment/CommentService.java index 5763c3b1..e74e5a29 100644 --- a/src/main/java/com/example/tily/comment/CommentService.java +++ b/src/main/java/com/example/tily/comment/CommentService.java @@ -19,6 +19,7 @@ @RequiredArgsConstructor @Service public class CommentService { + private final RoadmapRepository roadmapRepository; private final StepRepository stepRepository; private final TilRepository tilRepository; @@ -43,19 +44,32 @@ public CommentResponse.CreateCommentDTO createComment(CommentRequest.CreateComme String content = requestDTO.content(); - Comment comment = Comment.builder().roadmap(roadmap).step(step).writer(user).til(til).content(content).build(); + Comment comment = Comment.builder(). + roadmap(roadmap). + step(step). + writer(user). + til(til). + content(content). + build(); commentRepository.save(comment); // 댓글 작성하면 알림 생성 - Alarm alarm = Alarm.builder().til(til).receiver(til.getWriter()).comment(comment).isRead(false).build(); + Alarm alarm = Alarm.builder(). + til(til). + receiver(til.getWriter()). + comment(comment). + isRead(false). + build(); alarmRepository.save(alarm); + // til내 댓글 갯수 증가 + til.addCommentNum(); + return new CommentResponse.CreateCommentDTO(comment); } @Transactional public void updateComment(CommentRequest.UpdateCommentDTO requestDTO, Long commentId, User user) { - Comment comment = commentRepository.findById(commentId) .orElseThrow(() -> new CustomException(ExceptionCode.COMMENT_NOT_FOUND)); diff --git a/src/main/java/com/example/tily/roadmap/Roadmap.java b/src/main/java/com/example/tily/roadmap/Roadmap.java index c402d197..0ba9f128 100644 --- a/src/main/java/com/example/tily/roadmap/Roadmap.java +++ b/src/main/java/com/example/tily/roadmap/Roadmap.java @@ -1,7 +1,6 @@ package com.example.tily.roadmap; import com.example.tily.BaseTimeEntity; -import com.example.tily.roadmap.relation.UserRoadmap; import com.example.tily.user.User; import lombok.AccessLevel; import lombok.Builder; @@ -11,8 +10,6 @@ import org.hibernate.annotations.Where; import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -21,6 +18,7 @@ @SQLDelete(sql = "UPDATE roadmap_tb SET is_deleted = true WHERE id = ?") @Where(clause = "is_deleted = false") public class Roadmap extends BaseTimeEntity { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -75,12 +73,16 @@ public Roadmap(Long id, User creator, Category category, String name, String des this.image = image; } - public void update(RoadmapRequest.UpdateGroupRoadmapDTO roadmap){ + public void update(RoadmapRequest.UpdateRoadmapDTO roadmap){ this.name = roadmap.name(); this.description = roadmap.description(); this.isPublic = roadmap.isPublic(); this.isRecruit = roadmap.isRecruit(); } + public void addStepNum() { + this.stepNum++; + } + public void updateImage (String image) {this.image = image; } } \ No newline at end of file diff --git a/src/main/java/com/example/tily/roadmap/RoadmapController.java b/src/main/java/com/example/tily/roadmap/RoadmapController.java index 9f4238f1..fdf691ed 100644 --- a/src/main/java/com/example/tily/roadmap/RoadmapController.java +++ b/src/main/java/com/example/tily/roadmap/RoadmapController.java @@ -21,7 +21,7 @@ public class RoadmapController { // 로드맵 생성하기 @PostMapping("/roadmaps") public ResponseEntity createRoadmap(@RequestBody @Valid RoadmapRequest.CreateRoadmapDTO requestDTO, Errors errors, - @AuthenticationPrincipal CustomUserDetails userDetails){ + @AuthenticationPrincipal CustomUserDetails userDetails){ RoadmapResponse.CreateRoadmapDTO responseDTO = roadmapService.createRoadmap(requestDTO, userDetails.getUser()); return ResponseEntity.ok().body(ApiUtils.success(responseDTO)); } @@ -29,25 +29,32 @@ public ResponseEntity createRoadmap(@RequestBody @Valid RoadmapRequest.Create // 틸리 로드맵 생성하기 - 임시 api @PostMapping("/roadmaps/tily") public ResponseEntity createTilyRoadmap(@RequestBody @Valid RoadmapRequest.CreateTilyRoadmapDTO requestDTO, Errors errors, - @AuthenticationPrincipal CustomUserDetails userDetails){ + @AuthenticationPrincipal CustomUserDetails userDetails){ RoadmapResponse.CreateRoadmapDTO responseDTO = roadmapService.createTilyRoadmap(requestDTO, userDetails.getUser()); return ResponseEntity.ok().body(ApiUtils.success(responseDTO)); } - // 틸리, 그룹 로드맵 정보 조회하기 + // 로드맵 정보 조회하기 (틸리, 그룹) @GetMapping("/roadmaps/{id}") - public ResponseEntity findGroupRoadmap(@PathVariable Long id, @AuthenticationPrincipal CustomUserDetails userDetails){ + public ResponseEntity findRoadmap(@PathVariable Long id, @AuthenticationPrincipal CustomUserDetails userDetails){ User user = Optional.ofNullable(userDetails).map(CustomUserDetails::getUser).orElse(null); - RoadmapResponse.FindGroupRoadmapDTO responseDTO = roadmapService.findGroupRoadmap(id, user); + RoadmapResponse.FindRoadmapDTO responseDTO = roadmapService.findRoadmap(id, user); return ResponseEntity.ok().body(ApiUtils.success(responseDTO)); } - // 그룹 로드맵 정보 수정하기 + // 로드맵 정보 수정하기 @PatchMapping("/roadmaps/{id}") - public ResponseEntity updateGroupRoadmap(@RequestBody @Valid RoadmapRequest.UpdateGroupRoadmapDTO requestDTO, Errors errors, - @PathVariable Long id, @AuthenticationPrincipal CustomUserDetails userDetails){ - roadmapService.updateGroupRoadmap(id, requestDTO, userDetails.getUser()); + public ResponseEntity updateRoadmap(@RequestBody @Valid RoadmapRequest.UpdateRoadmapDTO requestDTO, Errors errors, + @PathVariable Long id, @AuthenticationPrincipal CustomUserDetails userDetails){ + roadmapService.updateRoadmap(id, requestDTO, userDetails.getUser()); + return ResponseEntity.ok().body(ApiUtils.success(null)); + } + + // 로드맵 삭제 + @DeleteMapping("/roadmaps/{id}") + public ResponseEntity deleteRoadmap(@PathVariable Long id, @AuthenticationPrincipal CustomUserDetails userDetails){ + roadmapService.deleteRoadmap(id, userDetails.getUser()); return ResponseEntity.ok().body(ApiUtils.success(null)); } @@ -84,7 +91,7 @@ public ResponseEntity applyTilyRoadmap(@PathVariable("tilyId") Long tilyId, @ return ResponseEntity.ok().body(ApiUtils.success(null)); } - // 참가 코드로 로드맵 참여하기 + // 참가 코드로 그룹 로드맵 참여하기 @PostMapping("/roadmaps/groups/participate") public ResponseEntity participateRoadmap(@RequestBody @Valid RoadmapRequest.ParticipateRoadmapDTO requestDTO, Errors errors, @AuthenticationPrincipal CustomUserDetails userDetails){ @@ -92,14 +99,14 @@ public ResponseEntity participateRoadmap(@RequestBody @Valid RoadmapRequest.P return ResponseEntity.ok().body(ApiUtils.success(responseDTO)); } - // 로드맵의 구성원 전체 조회하기 + // 그룹 로드맵의 구성원 전체 조회하기 @GetMapping("/roadmaps/groups/{groupId}/members") public ResponseEntity findRoadmapMembers(@PathVariable Long groupId, @AuthenticationPrincipal CustomUserDetails userDetails){ RoadmapResponse.FindRoadmapMembersDTO responseDTO = roadmapService.findRoadmapMembers(groupId, userDetails.getUser()); return ResponseEntity.ok().body(ApiUtils.success(responseDTO)); } - // 로드맵의 구성원 역할 바꾸기 + // 그룹 로드맵의 구성원 역할 바꾸기 @PatchMapping("/roadmaps/groups/{groupId}/members/{memberId}") public ResponseEntity changeMemberRole(@RequestBody @Valid RoadmapRequest.ChangeMemberRoleDTO requestDTO, Errors errors, @PathVariable Long groupId, @PathVariable Long memberId, @@ -108,7 +115,7 @@ public ResponseEntity changeMemberRole(@RequestBody @Valid RoadmapRequest.Cha return ResponseEntity.ok().body(ApiUtils.success(null)); } - // 로드맵의 구성원 강퇴하기 + // 그룹 로드맵의 구성원 강퇴하기 @DeleteMapping("/roadmaps/groups/{groupId}/members/{memberId}") public ResponseEntity dismissMember(@PathVariable Long groupId, @PathVariable Long memberId, @AuthenticationPrincipal CustomUserDetails userDetails){ @@ -116,32 +123,25 @@ public ResponseEntity dismissMember(@PathVariable Long groupId, @PathVariable return ResponseEntity.ok().body(ApiUtils.success(null)); } - // 로드맵에 신청한 사람들 목록 조회하기 + // 그룹 로드맵에 신청한 사람들 목록 조회하기 @GetMapping("/roadmaps/groups/{groupId}/members/apply") public ResponseEntity findAppliedUsers(@PathVariable Long groupId, @AuthenticationPrincipal CustomUserDetails userDetails){ RoadmapResponse.FindAppliedUsersDTO responseDTO = roadmapService.findAppliedUsers(groupId, userDetails.getUser()); return ResponseEntity.ok().body(ApiUtils.success(responseDTO)); } - // 로드맵 참여 신청 승인 + // 그룹 로드맵 참여 신청 승인 @PostMapping("/roadmaps/groups/{groupId}/members/{memberId}/accept") public ResponseEntity acceptApplication(@PathVariable Long groupId, @PathVariable Long memberId, @AuthenticationPrincipal CustomUserDetails userDetails){ roadmapService.acceptApplication(groupId, memberId, userDetails.getUser()); return ResponseEntity.ok().body(ApiUtils.success(null)); } - // 로드맵 참여 신청 거절 + // 그룹 로드맵 참여 신청 거절 @DeleteMapping("/roadmaps/groups/{groupId}/members/{memberId}/reject") public ResponseEntity rejectApplication(@PathVariable Long groupId, @PathVariable Long memberId, @AuthenticationPrincipal CustomUserDetails userDetails){ roadmapService.rejectApplication(groupId, memberId, userDetails.getUser()); return ResponseEntity.ok().body(ApiUtils.success(null)); } - - // 그룹 로드맵 삭제 - @DeleteMapping("/roadmaps/{id}") - public ResponseEntity deleteRoadmap(@PathVariable Long id, @AuthenticationPrincipal CustomUserDetails userDetails){ - roadmapService.deleteRoadmap(id, userDetails.getUser()); - return ResponseEntity.ok().body(ApiUtils.success(null)); - } } \ No newline at end of file diff --git a/src/main/java/com/example/tily/roadmap/RoadmapRequest.java b/src/main/java/com/example/tily/roadmap/RoadmapRequest.java index cb344731..c60db760 100644 --- a/src/main/java/com/example/tily/roadmap/RoadmapRequest.java +++ b/src/main/java/com/example/tily/roadmap/RoadmapRequest.java @@ -1,27 +1,13 @@ package com.example.tily.roadmap; -import com.example.tily.roadmap.relation.GroupRole; - import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; import java.time.LocalDateTime; import java.util.List; public class RoadmapRequest { - public record CreateIndividualRoadmapDTO( - @NotBlank(message = "이름을 입력해주세요.") - @Size(min=2, max=20, message = "이름은 2자에서 20자 이내여야 합니다.") - String name - ) { } - public record CreateGroupRoadmapDTO( - String name, - String description, - boolean isPublic - ) { } - public record CreateRoadmapDTO ( @NotBlank(message = "카테고리를 선택해주세요.") String category, @@ -37,7 +23,7 @@ public record CreateTilyRoadmapDTO( List steps ) { } - public record UpdateGroupRoadmapDTO( + public record UpdateRoadmapDTO( String name, String description, boolean isPublic, diff --git a/src/main/java/com/example/tily/roadmap/RoadmapResponse.java b/src/main/java/com/example/tily/roadmap/RoadmapResponse.java index a144a88a..2fc6e2eb 100644 --- a/src/main/java/com/example/tily/roadmap/RoadmapResponse.java +++ b/src/main/java/com/example/tily/roadmap/RoadmapResponse.java @@ -13,23 +13,52 @@ public class RoadmapResponse { + public record CreateRoadmapDTO(Long id) { public CreateRoadmapDTO(Roadmap roadmap) { this(roadmap.getId()); } } - public record FindGroupRoadmapDTO(Creator creator, String name, String description, String myRole, Long recentTilId, Long recentStepId, boolean isPublic, boolean isRecruit, String code, String category, List steps) { - public FindGroupRoadmapDTO(Roadmap roadmap, List steps, User user, Long recentTilId, Long recentStepId, String myRole) { - this(new Creator(user.getName(), user.getImage()), roadmap.getName(), roadmap.getDescription(), myRole, recentTilId, recentStepId, roadmap.isPublic(), roadmap.isRecruit(), roadmap.getCode(), roadmap.getCategory().getValue(), steps); + public record FindRoadmapDTO(Creator creator, + String name, + String description, + String myRole, + Long recentTilId, + Long recentStepId, + boolean isPublic, + boolean isRecruit, + String code, + String category, + List steps) { + public FindRoadmapDTO(Roadmap roadmap, List steps, User user, Long recentTilId, Long recentStepId, String myRole) { + this(new Creator(user.getName(), + user.getImage()), + roadmap.getName(), + roadmap.getDescription(), + myRole, + recentTilId, + recentStepId, + roadmap.isPublic(), + roadmap.isRecruit(), + roadmap.getCode(), + roadmap.getCategory().getValue(), + steps); } public record Creator(String name, String image) {} - public record StepDTO(Long id, String title, String description, String dueDate, ReferenceDTOs references) { + public record StepDTO(Long id, + String title, + String description, + String dueDate, + ReferenceDTOs references) { public StepDTO(Step step, List youtubeList, List webList) { - this(step.getId(), step.getTitle(), step.getDescription(), step.getDueDate()!=null ? DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(step.getDueDate()) : null, new ReferenceDTOs(youtubeList, webList)); + this(step.getId(), + step.getTitle(), + step.getDescription(), + step.getDueDate()!=null ? DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(step.getDueDate()) : null, new ReferenceDTOs(youtubeList, webList)); } } } @@ -52,32 +81,64 @@ public CategoryDTO(Roadmap roadmap) { public record RoadmapDTO(List tilys, List groups) {} } - public record TilyDTO (Long id, String name, String image, int stepNum, String description) { + public record TilyDTO (Long id, + String name, + String image, + int stepNum, + String description) { public TilyDTO(Roadmap roadmap) { - this(roadmap.getId(), roadmap.getName(), roadmap.getImage(), roadmap.getStepNum(), roadmap.getDescription()); + this(roadmap.getId(), + roadmap.getName(), + roadmap.getImage(), + roadmap.getStepNum(), + roadmap.getDescription()); } } - public record GroupDTO (Long id, String name, int stepNum, Creator creator, boolean isManager, String description) { + public record GroupDTO (Long id, String name, + int stepNum, Creator creator, + boolean isManager, + String description) { public GroupDTO(Roadmap roadmap, boolean isManager) { - this(roadmap.getId(), roadmap.getName(), roadmap.getStepNum(), new Creator(roadmap.getCreator()), isManager, roadmap.getDescription()); + this(roadmap.getId(), + roadmap.getName(), + roadmap.getStepNum(), + new Creator(roadmap.getCreator()), + isManager, + roadmap.getDescription()); } - public record Creator(Long id, String name, String image) { + public record Creator(Long id, + String name, + String image) { public Creator(User user) { - this(user.getId(), user.getName(), user.getImage()); + this(user.getId(), + user.getName(), + user.getImage()); } } } - public record FindRoadmapByQueryDTO (String category, List roadmaps, boolean hasNext) { + public record FindRoadmapByQueryDTO (String category, + List roadmaps, + boolean hasNext) { public FindRoadmapByQueryDTO(Category category, List roadmaps, boolean hasNext) { - this(category.getValue(), roadmaps, hasNext); + this(category.getValue(), + roadmaps, + hasNext); } - public record RoadmapDTO (Long id, String name, String description, int stepNum, GroupDTO.Creator creator) { + public record RoadmapDTO (Long id, + String name, + String description, + int stepNum, + GroupDTO.Creator creator) { public RoadmapDTO(Roadmap roadmap) { - this(roadmap.getId(), roadmap.getName(), roadmap.getDescription(), roadmap.getStepNum(), new GroupDTO.Creator(roadmap.getCreator())); + this(roadmap.getId(), + roadmap.getName(), + roadmap.getDescription(), + roadmap.getStepNum(), + new GroupDTO.Creator(roadmap.getCreator())); } } } @@ -89,23 +150,43 @@ public ParticipateRoadmapDTO(Roadmap roadmap) { } public record FindRoadmapMembersDTO(String myRole, List users) { - public record UserDTO(Long id, String name, String image, String role) { + public record UserDTO(Long id, + String name, + String image, + String role) { public UserDTO(User user, String role) { - this(user.getId(), user.getName(), user.getImage(), role); + this(user.getId(), + user.getName(), + user.getImage(), + role); } } } public record FindAppliedUsersDTO(List users) { - public record UserDTO(Long id, String name, String image, LocalDate date, String content) { + public record UserDTO(Long id, + String name, + String image, + LocalDate date, + String content) { public UserDTO(User user, UserRoadmap userRoadmap) { - this(user.getId(), user.getName(), user.getImage(), userRoadmap.getCreatedDate().toLocalDate(), userRoadmap.getContent()); + this(user.getId(), + user.getName(), + user.getImage(), + userRoadmap.getCreatedDate().toLocalDate(), + userRoadmap.getContent()); } } } public record FindTilOfStepDTO(List members) { - public record MemberDTO(Long tilId, Long userId, String name, String image, String content, LocalDateTime submitDate, Integer commentNum) { + public record MemberDTO(Long tilId, + Long userId, + String name, + String image, + String content, + LocalDateTime submitDate, + Integer commentNum) { public MemberDTO(Til til, User user) { this( diff --git a/src/main/java/com/example/tily/roadmap/RoadmapService.java b/src/main/java/com/example/tily/roadmap/RoadmapService.java index d717b566..77b4c17b 100644 --- a/src/main/java/com/example/tily/roadmap/RoadmapService.java +++ b/src/main/java/com/example/tily/roadmap/RoadmapService.java @@ -2,6 +2,8 @@ import com.example.tily._core.errors.exception.CustomException; import com.example.tily._core.errors.exception.ExceptionCode; +import com.example.tily.alarm.AlarmRepository; +import com.example.tily.comment.Comment; import com.example.tily.comment.CommentRepository; import com.example.tily.roadmap.relation.GroupRole; import com.example.tily.roadmap.relation.UserRoadmap; @@ -20,9 +22,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; import java.util.*; import java.util.stream.Collectors; @@ -30,6 +29,7 @@ @RequiredArgsConstructor @Service public class RoadmapService { + private final RoadmapRepository roadmapRepository; private final StepRepository stepRepository; private final ReferenceRepository referenceRepository; @@ -37,11 +37,11 @@ public class RoadmapService { private final UserRoadmapRepository userRoadmapRepository; private final UserStepRepository userStepRepository; private final CommentRepository commentRepository; + private final AlarmRepository alarmRepository; - // 로드맵 생성하기 + // 로드맵 생성하기(개인, 그룹) @Transactional public RoadmapResponse.CreateRoadmapDTO createRoadmap(RoadmapRequest.CreateRoadmapDTO requestDTO, User user){ - Roadmap roadmap = Roadmap.builder() .creator(user) .category(Category.getCategory(requestDTO.category())) @@ -49,8 +49,8 @@ public RoadmapResponse.CreateRoadmapDTO createRoadmap(RoadmapRequest.CreateRoadm .description(requestDTO.description()) .isPublic(requestDTO.isPublic()) // 공개여부 .currentNum(1L) - .code(requestDTO.category().equals(Category.CATEGORY_TILY.getValue()) ? generateRandomCode() : null) - .isRecruit(requestDTO.category().equals(Category.CATEGORY_TILY.getValue())) // 모집여부 + .code(requestDTO.category().equals(Category.CATEGORY_GROUP.getValue()) ? generateRandomCode() : null) + .isRecruit(!requestDTO.category().equals(Category.CATEGORY_INDIVIDUAL.getValue())) // 모집여부 .stepNum(0) .build(); roadmapRepository.save(roadmap); @@ -70,7 +70,6 @@ public RoadmapResponse.CreateRoadmapDTO createRoadmap(RoadmapRequest.CreateRoadm // 틸리 로드맵 생성하기 - 임시 api @Transactional public RoadmapResponse.CreateRoadmapDTO createTilyRoadmap(RoadmapRequest.CreateTilyRoadmapDTO requestDTO, User user){ - Roadmap roadmap = Roadmap.builder() .creator(user) .category(Category.CATEGORY_TILY) @@ -111,14 +110,22 @@ public RoadmapResponse.CreateRoadmapDTO createTilyRoadmap(RoadmapRequest.CreateT // (1) youtube List youtubeDTOs = referenceDTOs.youtube(); for(RoadmapRequest.ReferenceDTO youtubeDTO : youtubeDTOs){ - Reference reference = Reference.builder().step(step).category("youtube").link(youtubeDTO.link()).build(); + Reference reference = Reference.builder(). + step(step). + category("youtube"). + link(youtubeDTO.link()). + build(); references.add(reference); } // (2) reference List webDTOs = referenceDTOs.web(); for(RoadmapRequest.ReferenceDTO webDTO : webDTOs){ - Reference reference = Reference.builder().step(step).category("web").link(webDTO.link()).build(); + Reference reference = Reference.builder(). + step(step). + category("web"). + link(webDTO.link()). + build(); references.add(reference); } @@ -138,7 +145,7 @@ public RoadmapResponse.CreateRoadmapDTO createTilyRoadmap(RoadmapRequest.CreateT } // 로드맵 정보 조회하기 - public RoadmapResponse.FindGroupRoadmapDTO findGroupRoadmap(Long id, User user){ + public RoadmapResponse.FindRoadmapDTO findRoadmap(Long id, User user){ Roadmap roadmap = roadmapRepository.findById(id) .orElseThrow(() -> new CustomException(ExceptionCode.ROADMAP_NOT_FOUND)); @@ -166,8 +173,8 @@ else if(reference.getCategory().equals("web")){ webMap.put(step.getId(), webList); } - List steps = stepList.stream() - .map(step -> new RoadmapResponse.FindGroupRoadmapDTO.StepDTO(step + List steps = stepList.stream() + .map(step -> new RoadmapResponse.FindRoadmapDTO.StepDTO(step , youtubeMap.get(step.getId()).stream() .map(RoadmapResponse.ReferenceDTOs.ReferenceDTO::new).collect(Collectors.toList()) , webMap.get(step.getId()).stream() @@ -189,12 +196,12 @@ else if(reference.getCategory().equals("web")){ } } - return new RoadmapResponse.FindGroupRoadmapDTO(roadmap, steps, roadmap.getCreator(), recentTilId, recentStepId, myRole); + return new RoadmapResponse.FindRoadmapDTO(roadmap, steps, roadmap.getCreator(), recentTilId, recentStepId, myRole); } // 그룹 로드맵 정보 수정하기 @Transactional - public void updateGroupRoadmap(Long id, RoadmapRequest.UpdateGroupRoadmapDTO requestDTO, User user){ + public void updateRoadmap(Long id, RoadmapRequest.UpdateRoadmapDTO requestDTO, User user){ checkMasterAndManagerPermission(id ,user); Roadmap roadmap = roadmapRepository.findById(id) @@ -206,7 +213,6 @@ public void updateGroupRoadmap(Long id, RoadmapRequest.UpdateGroupRoadmapDTO req // 내가 속한 로드맵 전체 목록 조회하기 public RoadmapResponse.FindAllMyRoadmapDTO findAllMyRoadmaps(User user) { - List roadmaps = userRoadmapRepository.findByUserIdAndIsAccept(user.getId(), true); // 내가 속한 로드맵 조회 List categories = roadmaps.stream() @@ -230,7 +236,6 @@ public RoadmapResponse.FindAllMyRoadmapDTO findAllMyRoadmaps(User user) { // 로드맵 조회하기 public RoadmapResponse.FindRoadmapByQueryDTO findAll(String category, String name, int page, int size) { - // 생성일자를 기준으로 내림차순 Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdDate")); @@ -376,7 +381,7 @@ public void dismissMember(Long groupsId, Long membersId, User user){ if (role.equals(GroupRole.ROLE_MANAGER.getValue()) & userRoadmap.getRole().equals(GroupRole.ROLE_MASTER.getValue())) throw new CustomException(ExceptionCode.ROADMAP_DISMISS_FORBIDDEN); - userRoadmap.updateRole(GroupRole.ROLE_NONE.getValue()); + userRoadmap.updateRoleAndIsAccept(GroupRole.ROLE_NONE.getValue(), false); } public RoadmapResponse.FindAppliedUsersDTO findAppliedUsers(Long groupsId, User user){ @@ -427,22 +432,28 @@ public void rejectApplication(Long groupId, Long memberId, User user){ @Transactional public void deleteRoadmap(Long roadmapId, User user){ - Roadmap roadmap = getRoadmapById(roadmapId); - checkMasterAndManagerPermission(roadmapId, user); - // 1. Til과 연관된 Comment들을 삭제한다. + // 1. Til을 삭제한다. List tils = getTilsByRoadmapId(roadmapId); List tilIds = tils.stream() .map(Til::getId) .collect(Collectors.toList()); - commentRepository.softDeleteCommentsByTilIds(tilIds); - - // 2. Til을 삭제한다. tilRepository.softDeleteTilsByTilIds(tilIds); - // 3. Reference들을 삭제한다 + // 2. Til과 연관된 Comment들을 삭제한다. + List comments = getCommentsByTilIds(tilIds); + List commentIds = comments.stream() + .map(Comment::getId) + .collect(Collectors.toList()); + + commentRepository.softDeleteCommentsByIds(commentIds); + + // 3. Comment와 관련된 알람을 삭제한다. + alarmRepository.deleteByCommentIds(commentIds); + + // 4. Reference들을 삭제한다. List steps = getStepsByRoadmapId(roadmapId); List stepIds = steps.stream() .map(Step::getId) @@ -450,16 +461,16 @@ public void deleteRoadmap(Long roadmapId, User user){ referenceRepository.softDeleteReferenceByStepIds(stepIds); - // 4. Step들을 삭제한다. + // 5. Step들을 삭제한다. stepRepository.softDeleteStepByStepIds(stepIds); - // 5. UserStep들을 삭제한다. + // 6. UserStep들을 삭제한다. userStepRepository.softDeleteUserStepByStepIds(stepIds); - // 6. UserRoadmap을 삭제한다 + // 7. UserRoadmap을 삭제한다 userRoadmapRepository.softDeleteUserRoadmapByRoadmapId(roadmapId); - // 7. Roadmap을 삭제한다 + // 8. Roadmap을 삭제한다 roadmapRepository.softDeleteRoadmapById(roadmapId); } @@ -526,6 +537,10 @@ private List getTilsByRoadmapId(Long roadmapId){ return tilRepository.findByRoadmapId(roadmapId); } + private List getCommentsByTilIds( List tilIds){ + return commentRepository.findByTilIds(tilIds); + } + // 해당 로드맵에 속하지 않은 user private UserRoadmap getUserNotBelongRoadmap(Long roadmapId, Long userId) { return userRoadmapRepository.findByRoadmapIdAndUserIdAndIsAcceptFalse(roadmapId, userId).orElseThrow(() -> new CustomException(ExceptionCode.USER_NOT_FOUND)); diff --git a/src/main/java/com/example/tily/roadmap/relation/UserRoadmap.java b/src/main/java/com/example/tily/roadmap/relation/UserRoadmap.java index baf1dc9b..1759d7a0 100644 --- a/src/main/java/com/example/tily/roadmap/relation/UserRoadmap.java +++ b/src/main/java/com/example/tily/roadmap/relation/UserRoadmap.java @@ -19,6 +19,7 @@ @SQLDelete(sql = "UPDATE user_roadmap_tb SET is_deleted = true WHERE id = ?") @Where(clause = "is_deleted = false") public class UserRoadmap extends BaseTimeEntity { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -56,7 +57,14 @@ public UserRoadmap(Roadmap roadmap, User user, String content, boolean isAccept, this.progress = progress; } - public void updateRole(String role) { this.role = role; } + public void updateRole(String role) { + this.role = role; + } + + public void updateRoleAndIsAccept(String role, boolean isAccept) { + this.role = role; + this.isAccept = isAccept; + } public void updateIsAccept(boolean isAccept) { this.isAccept = isAccept; } diff --git a/src/main/java/com/example/tily/step/StepRepository.java b/src/main/java/com/example/tily/step/StepRepository.java index dd9fce5d..fc17be9e 100644 --- a/src/main/java/com/example/tily/step/StepRepository.java +++ b/src/main/java/com/example/tily/step/StepRepository.java @@ -9,10 +9,6 @@ import java.util.Optional; public interface StepRepository extends JpaRepository { - //List findByRoadmapId(Long id); - - //@Query("select s from Step s join fetch s.roadmap where s.id=:id") - //Optional findById(Long id); @Query("select s from Step s join fetch s.roadmap where s.id=:stepId") Optional findById(@Param("stepId") Long stepId); diff --git a/src/main/java/com/example/tily/step/StepResponse.java b/src/main/java/com/example/tily/step/StepResponse.java index 051fbef0..9afdb218 100644 --- a/src/main/java/com/example/tily/step/StepResponse.java +++ b/src/main/java/com/example/tily/step/StepResponse.java @@ -6,15 +6,22 @@ public class StepResponse { + public record CreateStepDTO(Long id) { public CreateStepDTO(Step step) { this(step.getId()); } } - public record FindReferenceDTO(Long id, String description, List youtubes, List webs) { + public record FindReferenceDTO(Long id, + String description, + List youtubes, + List webs) { public FindReferenceDTO(Step step, List youtubeDTOs, List webDTOs) { - this(step.getId(), step.getDescription(), youtubeDTOs, webDTOs); + this(step.getId(), + step.getDescription(), + youtubeDTOs, + webDTOs); } public record YoutubeDTO(Long id, String link) {} @@ -22,11 +29,18 @@ public record YoutubeDTO(Long id, String link) {} public record WebDTO(Long id, String link) {} } - public record FindAllStepDTO(List steps, int progress, String myRole) { - - public record StepDTO(Long id, String title, boolean isSubmit, Long tilId) { + public record FindAllStepDTO(List steps, + int progress, + String myRole) { + public record StepDTO(Long id, + String title, + boolean isSubmit, + Long tilId) { public StepDTO(Step step, Til til) { - this(step.getId(), step.getTitle(), til==null ? false : (til.getSubmitContent()!=null), til==null ? null : til.getId()); + this(step.getId(), + step.getTitle(), + til==null ? false : (til.getSubmitContent()!=null), + til==null ? null : til.getId()); } } } diff --git a/src/main/java/com/example/tily/step/StepService.java b/src/main/java/com/example/tily/step/StepService.java index 75e216ee..c5d2cb9c 100644 --- a/src/main/java/com/example/tily/step/StepService.java +++ b/src/main/java/com/example/tily/step/StepService.java @@ -2,6 +2,8 @@ import com.example.tily._core.errors.exception.ExceptionCode; import com.example.tily._core.errors.exception.CustomException; +import com.example.tily.alarm.AlarmRepository; +import com.example.tily.comment.Comment; import com.example.tily.roadmap.Category; import com.example.tily.comment.CommentRepository; import com.example.tily.roadmap.Roadmap; @@ -9,7 +11,6 @@ import com.example.tily.roadmap.relation.GroupRole; import com.example.tily.roadmap.relation.UserRoadmap; import com.example.tily.roadmap.relation.UserRoadmapRepository; -import com.example.tily.step.reference.Reference; import com.example.tily.step.reference.ReferenceRepository; import com.example.tily.step.relation.UserStep; import com.example.tily.step.relation.UserStepRepository; @@ -34,6 +35,7 @@ public class StepService { private final UserStepRepository userStepRepository; private final CommentRepository commentRepository; private final ReferenceRepository referenceRepository; + private final AlarmRepository alarmRepository; // step 생성하기 @Transactional @@ -52,7 +54,7 @@ public StepResponse.CreateStepDTO createStep(StepRequest.CreateStepDTO requestDT .roadmap(roadmap) .title(requestDTO.title()) .description(requestDTO.description()) - .dueDate(requestDTO.dueDate()) + .dueDate(requestDTO.dueDate()!=null ? requestDTO.dueDate().plusHours(9) : null) .build(); // 개인 로드맵이므로 description, dueDate 는 null stepRepository.save(step); @@ -67,6 +69,8 @@ public StepResponse.CreateStepDTO createStep(StepRequest.CreateStepDTO requestDT userStepRepository.save(userStep); } + roadmap.addStepNum(); + return new StepResponse.CreateStepDTO(step); } @@ -87,7 +91,7 @@ public void updateStep(Long stepId, StepRequest.UpdateStepDTO requestDTO, User u if (til != null) til.updateTitle(requestDTO.title()); step.updateTitle(requestDTO.title()); } else { // 그룹 로드맵일 때 - step.update(requestDTO.title(), requestDTO.description(), requestDTO.dueDate()); + step.update(requestDTO.title(), requestDTO.description(), requestDTO.dueDate()!=null ? requestDTO.dueDate().plusHours(9) : null); } } @@ -120,24 +124,32 @@ public void deleteStep(Long stepId, User user){ checkMasterAndManagerPermission(step.getRoadmap().getId(), user); // 매니저급만 삭제 가능 - List tils = getTisByStepId(stepId); + // 1. Til을 삭제한다. + List tils = getTilsByStepId(stepId); List tilIds = tils.stream() .map(Til::getId) .collect(Collectors.toList()); - // 1. Til과 연관된 Comment들을 삭제한다. - commentRepository.softDeleteCommentsByTilIds(tilIds); - - // 2. Til들을 삭제한다 tilRepository.softDeleteTilsByTilIds(tilIds); - // 3. Reference들을 삭제한다. + // 2. Til과 연관된 Comment들을 삭제한다. + List comments = getCommentsByTilIds(tilIds); + List commentIds = comments.stream() + .map(Comment::getId) + .collect(Collectors.toList()); + + commentRepository.softDeleteCommentsByIds(commentIds); + + // 3. Comment와 관련된 알람을 삭제한다. + alarmRepository.deleteByCommentIds(commentIds); + + // 4. Reference들을 삭제한다. referenceRepository.softDeleteReferenceByStepId(stepId); - // 4. UserStep을 삭제한다 + // 5. UserStep을 삭제한다 userStepRepository.softDeleteUserStepByStepId(stepId); - // 5. Step을 삭제한다 + // 6. Step을 삭제한다 stepRepository.softDeleteStepById(stepId); } @@ -159,10 +171,14 @@ private Roadmap getRoadmapById(Long roadmapId) { return roadmapRepository.findById(roadmapId).orElseThrow(() -> new CustomException(ExceptionCode.ROADMAP_NOT_FOUND)); } - private List getTisByStepId(Long stepId){ + private List getTilsByStepId(Long stepId){ return tilRepository.findByStepId(stepId); } + private List getCommentsByTilIds( List tilIds){ + return commentRepository.findByTilIds(tilIds); + } + // 해당 로드맵에 속한 user private UserRoadmap getUserBelongRoadmap(Long roadmapId, Long userId) { return userRoadmapRepository.findByRoadmapIdAndUserIdAndIsAcceptTrue(roadmapId, userId) diff --git a/src/main/java/com/example/tily/step/reference/ReferenceController.java b/src/main/java/com/example/tily/step/reference/ReferenceController.java index 7176798a..dfb9ddb8 100644 --- a/src/main/java/com/example/tily/step/reference/ReferenceController.java +++ b/src/main/java/com/example/tily/step/reference/ReferenceController.java @@ -27,10 +27,11 @@ public ResponseEntity createReference(@RequestBody @Valid ReferenceRequest.Cr } // step의 참고자료 목록 조회 - @GetMapping("/steps/{id}/references") - public ResponseEntity findReference(@RequestBody @Valid ReferenceRequest.FindReferenceDTO requestDTO, + + @GetMapping("/steps/{stepId}/references") + public ResponseEntity findReference(@PathVariable("stepId") Long stepId, @AuthenticationPrincipal CustomUserDetails userDetails){ - StepResponse.FindReferenceDTO responseDTO = referenceService.findReference(requestDTO, userDetails.getUser()); + StepResponse.FindReferenceDTO responseDTO = referenceService.findReference(stepId, userDetails.getUser()); return ResponseEntity.ok().body(ApiUtils.success(responseDTO)); } diff --git a/src/main/java/com/example/tily/step/reference/ReferenceRepository.java b/src/main/java/com/example/tily/step/reference/ReferenceRepository.java index 54eb33ba..b3bbd438 100644 --- a/src/main/java/com/example/tily/step/reference/ReferenceRepository.java +++ b/src/main/java/com/example/tily/step/reference/ReferenceRepository.java @@ -8,6 +8,7 @@ import java.util.List; public interface ReferenceRepository extends JpaRepository { + List findByStepId(Long stepId); @Modifying diff --git a/src/main/java/com/example/tily/step/reference/ReferenceRequest.java b/src/main/java/com/example/tily/step/reference/ReferenceRequest.java index 25964bfd..867ca9f3 100644 --- a/src/main/java/com/example/tily/step/reference/ReferenceRequest.java +++ b/src/main/java/com/example/tily/step/reference/ReferenceRequest.java @@ -4,6 +4,7 @@ import java.time.LocalDateTime; public class ReferenceRequest { + public record FindReferenceDTO(Long stepId){ } diff --git a/src/main/java/com/example/tily/step/reference/ReferenceService.java b/src/main/java/com/example/tily/step/reference/ReferenceService.java index 74f68ad7..78e94e47 100644 --- a/src/main/java/com/example/tily/step/reference/ReferenceService.java +++ b/src/main/java/com/example/tily/step/reference/ReferenceService.java @@ -34,6 +34,8 @@ public void createReference(ReferenceRequest.CreateReferenceDTO requestDTO, User Long stepId = requestDTO.stepId(); Step step = getStepById(stepId); + checkMasterAndManagerPermission(step.getRoadmap().getId(), user); // 생성자 혹 매니저만 생성 가능 + Reference reference = Reference.builder() .step(step) .category(requestDTO.category()) @@ -44,8 +46,7 @@ public void createReference(ReferenceRequest.CreateReferenceDTO requestDTO, User } // step의 참고자료 목록 조회하기 - public StepResponse.FindReferenceDTO findReference(ReferenceRequest.FindReferenceDTO requestDTO, User user){ - Long stepId = requestDTO.stepId(); + public StepResponse.FindReferenceDTO findReference(Long stepId, User user){ Step step = getStepById(stepId); List references = referenceRepository.findByStepId(stepId); @@ -71,7 +72,7 @@ else if(category.equals("web")) public void deleteReference(Long referenceId, User user){ Reference reference = getReferenceById(referenceId); - checkMasterAndManagerPermission(reference.getStep().getRoadmap().getId(), user); // 매니저급만 삭제 가능 + checkMasterAndManagerPermission(reference.getStep().getRoadmap().getId(), user); // 생성자 혹 매니저만 삭제 가능 referenceRepository.softDeleteReferenceById(referenceId); } diff --git a/src/main/java/com/example/tily/til/Til.java b/src/main/java/com/example/tily/til/Til.java index 634e742f..0bfa3075 100644 --- a/src/main/java/com/example/tily/til/Til.java +++ b/src/main/java/com/example/tily/til/Til.java @@ -78,6 +78,10 @@ public void updateTitle (String title) { this.title = title; } + public void addCommentNum () { + this.commentNum++; + } + public void submitTil(String submitContent) { this.content = submitContent; this.submitContent = submitContent; diff --git a/src/main/java/com/example/tily/til/TilResponse.java b/src/main/java/com/example/tily/til/TilResponse.java index 79e41187..9428a3f5 100644 --- a/src/main/java/com/example/tily/til/TilResponse.java +++ b/src/main/java/com/example/tily/til/TilResponse.java @@ -22,9 +22,20 @@ public CreateTilDTO(Til til) { } } - public record ViewDTO(String content, String submitContent, boolean isPersonal, boolean isSubmit, String roadmapName, StepDTO step, List comments) { + public record ViewDTO(String content, + String submitContent, + boolean isPersonal, + boolean isSubmit, + String roadmapName, + StepDTO step, + List comments) { public ViewDTO(Step step, Til til, boolean isSubmit, List comments) { - this(til.getContent(), til.getSubmitContent(), til.isPersonal(), isSubmit, step.getRoadmap().getName(), new StepDTO(step), comments); + this(til.getContent(), + til.getSubmitContent(), + til.isPersonal(), + isSubmit, + step.getRoadmap().getName(), + new StepDTO(step), comments); } public record StepDTO(Long id, String title) { @@ -33,9 +44,18 @@ public StepDTO(Step step) { } } - public record CommentDTO(Long id, String content, String name, String image, boolean isOwner, String createDate) { + public record CommentDTO(Long id, + String content, + String name, + String image, + boolean isOwner, + String createDate) { public CommentDTO(Comment comment, boolean isOwner) { - this(comment.getId(), comment.getContent(), comment.getWriter().getName(), comment.getWriter().getImage(), isOwner, + this(comment.getId(), + comment.getContent(), + comment.getWriter().getName(), + comment.getWriter().getImage(), + isOwner, comment.getCreatedDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); } } @@ -43,9 +63,15 @@ public CommentDTO(Comment comment, boolean isOwner) { public record FindAllDTO(List tils, boolean hasNext) {} - public record TilDTO(Long id, String createDate, StepDTO step, RoadmapDTO roadmap) { + public record TilDTO(Long id, + String createDate, + StepDTO step, + RoadmapDTO roadmap) { public TilDTO(Til til, Step step, Roadmap roadmap) { - this(til.getId(), til.getCreatedDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")), new StepDTO(step), new RoadmapDTO(roadmap)); + this(til.getId(), + til.getCreatedDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")), + new StepDTO(step), + new RoadmapDTO(roadmap)); } public record StepDTO(Long id, String title) { @@ -54,9 +80,9 @@ public StepDTO(Step step) { } } - public record RoadmapDTO(Long id, String name) { + public record RoadmapDTO(Long id, String name, String category) { public RoadmapDTO(Roadmap roadmap) { - this(roadmap.getId(), roadmap.getName()); + this(roadmap.getId(), roadmap.getName(), roadmap.getCategory().getValue()); } } } diff --git a/src/main/java/com/example/tily/til/TilService.java b/src/main/java/com/example/tily/til/TilService.java index 620bfd87..7cf29d02 100644 --- a/src/main/java/com/example/tily/til/TilService.java +++ b/src/main/java/com/example/tily/til/TilService.java @@ -3,6 +3,7 @@ import com.example.tily._core.errors.exception.ExceptionCode; import com.example.tily._core.errors.exception.CustomException; +import com.example.tily.alarm.AlarmRepository; import com.example.tily.comment.Comment; import com.example.tily.comment.CommentRepository; import com.example.tily.roadmap.Category; @@ -44,6 +45,7 @@ public class TilService { private final CommentRepository commentRepository; private final UserStepRepository userStepRepository; private final UserRoadmapRepository userRoadmapRepository; + private final AlarmRepository alarmRepository; // til 생성하기 @Transactional @@ -149,15 +151,22 @@ public void submitTil(TilRequest.SubmitTilDTO requestDTO, Long tilId, User user) @Transactional public void deleteTil(Long tilId, User user) { - Til til = getTilById(tilId); checkTilWriterEqualUser(til, user); // 1. Til과 연관된 Comment들을 삭제한다. - commentRepository.softDeleteCommentsByTilId(tilId); + List comments = commentRepository.findByTilId(tilId); + List commentIds = comments.stream() + .map(Comment::getId) + .collect(Collectors.toList()); + + commentRepository.softDeleteCommentsByIds(commentIds); + + // 2. Comment들과 관련된 Alarm 삭제 + alarmRepository.deleteByCommentIds(commentIds); - // 2. Til을 삭제한다. + // 3. Til을 삭제한다. tilRepository.softDeleteTilById(tilId); } diff --git a/src/main/java/com/example/tily/user/UserResponse.java b/src/main/java/com/example/tily/user/UserResponse.java index 687902cd..acd40a62 100644 --- a/src/main/java/com/example/tily/user/UserResponse.java +++ b/src/main/java/com/example/tily/user/UserResponse.java @@ -14,9 +14,15 @@ public record ViewGardensDTO(List gardens) { public record GardenDTO(String day, int value) {} } - public record UserDTO(Long id, String name, String email, String image) { + public record UserDTO(Long id, + String name, + String email, + String image) { public UserDTO(User user) { - this(user.getId(), user.getName(), user.getEmail(), user.getImage()); + this(user.getId(), + user.getName(), + user.getEmail(), + user.getImage()); } } } diff --git a/src/main/java/com/example/tily/user/UserService.java b/src/main/java/com/example/tily/user/UserService.java index 25b1b44b..275fae6d 100644 --- a/src/main/java/com/example/tily/user/UserService.java +++ b/src/main/java/com/example/tily/user/UserService.java @@ -5,8 +5,9 @@ import com.auth0.jwt.interfaces.DecodedJWT; import com.example.tily._core.security.JWTProvider; import com.example.tily._core.utils.RedisUtils; +import com.example.tily.alarm.AlarmRepository; +import com.example.tily.comment.Comment; import com.example.tily.comment.CommentRepository; -import com.example.tily.roadmap.Category; import com.example.tily.roadmap.Roadmap; import com.example.tily.roadmap.RoadmapRepository; import com.example.tily.roadmap.relation.UserRoadmap; @@ -47,6 +48,7 @@ public class UserService { private final CommentRepository commentRepository; private final StepRepository stepRepository; private final ReferenceRepository referenceRepository; + private final AlarmRepository alarmRepository; private String defaultImage = "user/profile-user.jpg"; @@ -183,17 +185,25 @@ public UserResponse.ViewGardensDTO viewGardens(User user) { // 회원 탈퇴하기 public void withdrawMembership(User user){ // 1. 유저가 작성한 Comment들 삭제 + List comments = getCommentByUserId(user.getId()); + List commentIds = comments.stream() + .map(Comment::getId) + .collect(Collectors.toList()); + + commentRepository.softDeleteCommentsByIds(commentIds); + + // 2. Comment들과 관련된 Alarm 삭제 + alarmRepository.deleteByCommentIds(commentIds); + + // 3. 유저가 작성한 Til 삭제 List tils = getTilByUserId(user.getId()); List tilIds = tils.stream() .map(Til::getId) .collect(Collectors.toList()); - commentRepository.softDeleteCommentsByTilIds(tilIds); - - // 2. 유저가 작성한 Til 삭제 tilRepository.softDeleteTilsByTilIds(tilIds); - // 3. UserStep들을 삭제 + // 4. UserStep들을 삭제 List userSteps = getUserStepByUserId(user.getId()); List userStepIds = userSteps.stream() .map(UserStep::getId) @@ -201,7 +211,7 @@ public void withdrawMembership(User user){ userStepRepository.softDeleteUserStepByUserStepIds(userStepIds); - // 4. 유저가 만든 Step들을 삭제 + // 5. 유저가 만든 Step들을 삭제 List steps = userSteps.stream() .map(userStep -> userStep.getStep()) .collect(Collectors.toList()); @@ -212,10 +222,10 @@ public void withdrawMembership(User user){ stepRepository.softDeleteStepByStepIds(stepIds); - // 5. 유저가 작성한 Reference들을 삭제 + // 6. 유저가 작성한 Reference들을 삭제 referenceRepository.softDeleteReferenceByStepIds(stepIds); - // 6. UserRoadmap 삭제 + // 7. UserRoadmap 삭제 List userRoadmaps = getUserRoadmapByUserId(user.getId()); List userRoadmapIds = userRoadmaps.stream() .map(UserRoadmap::getId) @@ -223,7 +233,7 @@ public void withdrawMembership(User user){ userRoadmapRepository.softDeleteUserRoadmapByUserRoadmapIds(userRoadmapIds); - // 7. 유저가 만든 로드맵 삭제 + // 8. 유저가 만든 로드맵 삭제 List roadmaps = userRoadmaps.stream() .map(userRoadmap -> userRoadmap.getRoadmap()) .filter(roadmap -> roadmap.getCreator().getId().equals(user.getId())) @@ -235,7 +245,7 @@ public void withdrawMembership(User user){ roadmapRepository.softDeleteRoadmapByRoadmapIds(roadmapIds); - // 8. 유저 삭제 + // 9. 유저 삭제 userRepository.softDeleteUserById(user.getId()); } @@ -324,4 +334,6 @@ private List getUserStepByUserId(Long userId) { private List getTilByUserId(Long userId){ return tilRepository.findByWriterId(userId); } + + private List getCommentByUserId(Long userId){return commentRepository.findByWriterId(userId);} } diff --git a/src/test/java/com/example/tily/roadmap/RoadmapControllerTest.java b/src/test/java/com/example/tily/roadmap/RoadmapControllerTest.java index dd493658..706c70c8 100644 --- a/src/test/java/com/example/tily/roadmap/RoadmapControllerTest.java +++ b/src/test/java/com/example/tily/roadmap/RoadmapControllerTest.java @@ -12,8 +12,6 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; -import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -39,12 +37,14 @@ public void roadmap_individual_create_success_test() throws Exception { // given String name = "hong"; + String category = "individual"; String description = "알고리즘 마무리하는 로드맵입니다."; Boolean isPublic = false; RoadmapRequest.CreateRoadmapDTO requestDTO = new RoadmapRequest.CreateRoadmapDTO(category,name,description,isPublic); + String requestBody = om.writeValueAsString(requestDTO); // when @@ -65,6 +65,7 @@ public void roadmap_individual_create_success_test() throws Exception { public void roadmap_group_create_success_test() throws Exception { // given + String name = "hong"; String category = "group"; String description = "알고리즘 마무리하는 로드맵입니다."; @@ -212,7 +213,8 @@ public void roadmap_group_update_success_test() throws Exception { // 로드맵 RoadmapRequest.RoadmapDTO roadmap = new RoadmapRequest.RoadmapDTO("new JAVA - 생활 코딩", "새로운 버젼 입니다", "modifiedCode1234", false, true); - RoadmapRequest.UpdateGroupRoadmapDTO requestDTO = new RoadmapRequest.UpdateGroupRoadmapDTO(roadmap.name(), roadmap.description(),roadmap.isPublic(), roadmap.isRecruit()); + + RoadmapRequest.UpdateRoadmapDTO requestDTO = new RoadmapRequest.UpdateRoadmapDTO(null,"새로운 버젼 입니다", true, true ); String requestBody = om.writeValueAsString(requestDTO); @@ -258,7 +260,9 @@ public void roadmap_group_update_fail_test_1() throws Exception { // 로드맵 RoadmapRequest.RoadmapDTO roadmap = new RoadmapRequest.RoadmapDTO(null, "새로운 버젼 입니다", "modifiedCode1234", false, true); - RoadmapRequest.UpdateGroupRoadmapDTO requestDTO = new RoadmapRequest.UpdateGroupRoadmapDTO(roadmap.name(), roadmap.description(), roadmap.isPublic(), roadmap.isRecruit()); + + RoadmapRequest.UpdateRoadmapDTO requestDTO = new RoadmapRequest.UpdateRoadmapDTO(null,"새로운 버젼 입니다", true, true ); + String requestBody = om.writeValueAsString(requestDTO);