Skip to content

Commit

Permalink
Merge pull request #72 from LIKELION-TEAM4-HACKATHON/feature/review-d…
Browse files Browse the repository at this point in the history
…etail
  • Loading branch information
oosedus authored Jul 30, 2024
2 parents 270dd4f + 72ae8ed commit d240d4f
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 15 deletions.
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 {

}

0 comments on commit d240d4f

Please sign in to comment.