Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

후기 댓글 작성 + 삭제 기능 추가 #72

Merged
merged 3 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/main/java/likelion/MZConnent/api/member/LoginController.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public ResponseEntity register(@Valid @RequestBody CreateMemberRequest request,
Long memberId = loginService.createUser(request);
log.info("회원가입 성공: {}", memberId);

return ResponseEntity.ok("회원가입 성공");
return ResponseEntity.ok(Map.of("message", "회원가입 성공"));
}

@PostMapping("/api/auth/login")
Expand All @@ -50,7 +50,7 @@ public ResponseEntity login(@Valid @RequestBody LoginMemberRequest request, Bind
}

@PostMapping("/api/auth/logout")
public ResponseEntity logout(@AuthenticationPrincipal UserPrinciple userPrinciple, @RequestHeader("Authorization") String authHeader) {
public ResponseEntity<Map<String, String>> logout(@AuthenticationPrincipal UserPrinciple userPrinciple, @RequestHeader("Authorization") String authHeader) {
String email = userPrinciple.getEmail();

log.info("로그아웃 이메일: {}", email);
Expand All @@ -60,4 +60,16 @@ public ResponseEntity logout(@AuthenticationPrincipal UserPrinciple userPrincipl

return ResponseEntity.ok(Map.of("message", "로그아웃 성공"));
}

@GetMapping("/api/auth/email")
public ResponseEntity<Map<String, String>> checkDuplicateEmail(@RequestParam("email") String email) {
loginService.checkDuplicateEmail(email);
return ResponseEntity.ok(Map.of("message", "이메일 중복 점검 성공"));
}

@GetMapping("/api/auth/username")
public ResponseEntity<Map<String, String>> checkDuplicateUsername(@RequestParam("username") String username) {
loginService.checkDuplicateUsername(username);
return ResponseEntity.ok(Map.of("message", "닉네임 중복 점검 성공"));
}
}
36 changes: 36 additions & 0 deletions src/main/java/likelion/MZConnent/api/review/CommentController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package likelion.MZConnent.api.review;

import likelion.MZConnent.dto.review.request.SaveCommentRequest;
import likelion.MZConnent.dto.review.response.SaveCommentResponse;
import likelion.MZConnent.jwt.principle.UserPrinciple;
import likelion.MZConnent.service.review.CommentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequiredArgsConstructor
@Slf4j
public class CommentController {
private final CommentService commentService;

@PostMapping("/api/reviews/{reviewId}/comments")
public ResponseEntity<SaveCommentResponse> saveComment(@RequestBody Map<String, String> request, @PathVariable("reviewId") Long reviewId, @AuthenticationPrincipal UserPrinciple userPrinciple) {
SaveCommentResponse comment = commentService.saveComment(userPrinciple.getEmail(), reviewId, request.get("content"));

log.info("댓글 작성: {}", comment);

return ResponseEntity.ok(comment);
}

@DeleteMapping("/api/reviews/{reviewId}/comments/{commentId}")
public ResponseEntity<Map<String, String>> deleteComment(@PathVariable("commentId") Long commentId, @AuthenticationPrincipal UserPrinciple userPrinciple) {
commentService.deleteComment(userPrinciple.getEmail(), commentId);
return ResponseEntity.ok(Map.of("message", "댓글 삭제 성공"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class SecurityConfig {

// 아무나 접근 가능한 URI
private final String[] permitAllUrl = {"/error",
"/api/auth/login", // 회원
"/api/auth/login", "/api/auth/email", "/api/auth/username", // 회원
"/api/categories/culture", "/api/cultures", "/api/cultures/**", // 문화
"/api/reviews", // 후기
"/api/categories/region", "/api/clubs/list",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import likelion.MZConnent.domain.member.Member;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

Expand All @@ -12,6 +13,7 @@ public class MemberProfileDto {
private String username;
private String profileImageUrl = ""; // TODO: 기본 이미지로 초기화

@Builder
public MemberProfileDto(Member member) {
this.userId = member.getId();
this.username = member.getUsername();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package likelion.MZConnent.dto.review.request;

import likelion.MZConnent.domain.member.Member;
import likelion.MZConnent.domain.review.ReviewComment;
import likelion.MZConnent.dto.review.response.SaveCommentResponse;
import lombok.*;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class SaveCommentRequest {
private Long reviewId;
private String content;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package likelion.MZConnent.dto.review.response;

import likelion.MZConnent.domain.review.ReviewComment;
import likelion.MZConnent.dto.member.MemberProfileDto;
import lombok.*;

@Getter
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class SaveCommentResponse {
private Long commentId;
private Long reviewId;
private MemberProfileDto commenter;
private String content;


@Builder
public SaveCommentResponse(ReviewComment comment) {
this.commentId = comment.getCommentId();
this.reviewId = comment.getReview().getReviewId();
this.commenter = MemberProfileDto.builder()
.member(comment.getMember()).build();
this.content = comment.getContent();
}
}
29 changes: 17 additions & 12 deletions src/main/java/likelion/MZConnent/service/member/LoginService.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,6 @@ public Long createUser(CreateMemberRequest request) {
// 비밀번호 정책에 맞는지 점검
checkPasswordPolicy(request.getPassword());

// 이미 등록된 이메일인지 점검
if (memberRepository.existsByEmail(request.getEmail())) {
log.info("이미 등록된 이메일={}", request.getEmail());
throw new IllegalArgumentException("이미 등록된 이메일입니다.");
}

// 중복되는 닉네임인지 점검
if (memberRepository.existsByUsername(request.getUsername())) {
log.info("중복되는 닉네임={}", request.getEmail());
throw new IllegalArgumentException("중복되는 닉네임입니다.");
}

Member member = Member.builder()
.email(request.getEmail())
.password(passwordEncoder.encode(request.getPassword())) // 비밀번호 암호화
Expand Down Expand Up @@ -121,6 +109,22 @@ public void logoout(String accessToken, String email) {
accessTokenBlackList.setBlackList(accessToken, email);
}

// 이메일 중복 점검
public void checkDuplicateEmail(String email) {
if (memberRepository.existsByEmail(email)) {
log.info("이미 등록된 이메일={}", email);
throw new IllegalArgumentException("이미 등록된 이메일입니다.");
}
}

// 닉네임 중복 점검
public void checkDuplicateUsername(String username) {
if (memberRepository.existsByUsername(username)) {
log.info("중복되는 닉네임={}", username);
throw new IllegalArgumentException("중복되는 닉네임입니다.");
}
}


// 비밀번호 정책에 맞는지 점검하는 함수
private void checkPasswordPolicy(String password) {
Expand All @@ -146,4 +150,5 @@ private void checkPassword(String password, Member member) {
}
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package likelion.MZConnent.service.review;

import likelion.MZConnent.domain.member.Member;
import likelion.MZConnent.domain.review.Review;
import likelion.MZConnent.domain.review.ReviewComment;
import likelion.MZConnent.dto.culture.request.CreateCultureRequest;
import likelion.MZConnent.dto.review.request.SaveCommentRequest;
import likelion.MZConnent.dto.review.response.SaveCommentResponse;
import likelion.MZConnent.repository.member.MemberRepository;
import likelion.MZConnent.repository.review.ReviewCommentRepository;
import likelion.MZConnent.repository.review.ReviewRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Optional;

@Service
@Slf4j
@RequiredArgsConstructor
public class CommentService {
private final MemberRepository memberRepository;
private final ReviewCommentRepository reviewCommentRepository;
private final ReviewRepository reviewRepository;


// 후기 댓글 작성
@Transactional
public SaveCommentResponse saveComment(String email, Long reviewId, String content) {
Member member = findMemberByEmail(email);
Review review = findReviewById(reviewId);

ReviewComment comment = ReviewComment.builder()
.content(content)
.createdDate(LocalDateTime.now())
.member(member)
.review(review)
.build();

reviewCommentRepository.save(comment);

return SaveCommentResponse.builder().comment(comment).build();
}

// 후기 댓글 삭제
@Transactional
public void deleteComment(String email, Long commentId) {
ReviewComment comment = findCommentById(commentId);
Member member = findMemberByEmail(email);
Review review = findReviewById(comment.getReview().getReviewId());

member.getReviewComments().remove(comment);
review.getReviewComments().remove(comment);
reviewCommentRepository.delete(comment);
}

private ReviewComment findCommentById(Long commentId) {
return reviewCommentRepository.findById(commentId).orElseThrow(() -> {
log.info("해당 후기 댓글이 존재하지 않음.");
return new IllegalArgumentException("해당 후기 댓글이 존재하지 않습니다.");
});
}

private Review findReviewById(Long reviewId ) {
return reviewRepository.findById(reviewId).orElseThrow(() -> {
log.info("후기가 존재하지 않음.");
return new IllegalArgumentException("후기가 존재하지 않습니다.");
});
}


private Member findMemberByEmail(String email) {
return memberRepository.findByEmail(email).orElseThrow(() -> {
log.info("회원이 존재하지 않음.");
return new IllegalArgumentException("회원이 존재하지 않습니다.");
});
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import static org.junit.jupiter.api.Assertions.*;
class CommentServiceTest {

}
Loading