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

[배포] Post, Heart, Notice API 개발 완료 #7

Merged
merged 40 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
5ae0b51
feat: 건의/감사 글 request dto 생성
xyzwv Mar 15, 2024
1891db4
feat: 건의/감사 글 response dto 생성
xyzwv Mar 15, 2024
49c3222
fix: Post에 createDate 추가
xyzwv Mar 15, 2024
c1d4535
feat: PostRepository 생성
xyzwv Mar 15, 2024
0ce511c
feat: 건의/감사 글 저장을 위한 서비스 메소드 추가
xyzwv Mar 15, 2024
8f84781
feat: 건의 글 등록을 위한 컨트롤러 메소드 추가
xyzwv Mar 15, 2024
29c84ef
feat: 감사 글 등록을 위한 컨트롤러 메소드 추가
xyzwv Mar 15, 2024
df78652
fix: 건의/감사 글 등록 시 반환되는 응답 Dto 클래스명 수정
xyzwv Mar 15, 2024
72c7753
fix: 건의/감사 글 등록 시 반환되는 응답 Dto 생성자 변경
xyzwv Mar 15, 2024
5592098
feat: 건의/감사 글에서 사용자와 연관된 정보를 담는 Dto 생성
xyzwv Mar 15, 2024
a6085fd
feat: 건의/감사 글 상세 조회 응답 Dto 생성
xyzwv Mar 15, 2024
7cab20d
fix: 인증 정보 없을 경우 현재 사용자 객체 대신 null 반환
xyzwv Mar 15, 2024
76ed078
feat: 건의/감사 글 상세 조회 시 좋아요 수 계산 로직을 제외한 서비스 메소드 구현
xyzwv Mar 15, 2024
55cd53e
feat: 건의/감사 글 상세 조회 컨트롤러 메서드 추가
xyzwv Mar 15, 2024
0ef3cb3
feat: 추천하는 글의 id를 담는 dto 생성
xyzwv Mar 15, 2024
63c8a83
feat: 좋아요 등록/취소 서비스 메서드 추가
xyzwv Mar 15, 2024
91c5147
feat: 좋아요 등록/취소 컨트롤러 메서드 추가
xyzwv Mar 15, 2024
8a76008
feat: 건의/감사 글의 좋아요 수 계산 로직 추가
xyzwv Mar 15, 2024
2e7b1f7
feat: 사용자의 건의/감사 글 좋아요 여부 확인 로직 추가
xyzwv Mar 15, 2024
f00ed87
fix: 사용자가 건의/감사 글의 작성자인지 확인하는 로직 변경
xyzwv Mar 15, 2024
a6fcdbe
feat: 건의/감사 글 리스트 응답 Dto 생성
xyzwv Mar 15, 2024
053394d
feat: 건의/감사 글 리스트 조회를 위한 서비스 메서드 추가
xyzwv Mar 15, 2024
ceaf1b0
feat: 건의 글 리스트 조회를 위한 컨트롤러 메서드 추가
xyzwv Mar 15, 2024
d62760b
feat: 감사 글 리스트 조회를 위한 컨트롤러 메서드 추가
xyzwv Mar 15, 2024
d6132a2
fix: 건의/감사 글이 삭제될 때 해당 글의 좋아요도 함께 삭제될 수 있도록 연관관계 수정
xyzwv Mar 15, 2024
e8b921f
feat: 건의/감사 글 삭제를 위한 서비스 메서드 추가
xyzwv Mar 15, 2024
cbee9fc
feat: 건의/감사 글 삭제를 위한 컨트롤러 메서드 추가
xyzwv Mar 15, 2024
fd83efc
refactor: 연관관계 설정에 따른 좋아요 수 계산 로직 변경
xyzwv Mar 15, 2024
ab06a50
Merge pull request #5 from EWHA-THON-E-BUS/feat/post
xyzwv Mar 15, 2024
362d9aa
feat: 공지사항 응답 dto 추가
xyzwv Mar 15, 2024
b91e747
fix: Notice 엔티티의 작성자라는 의미를 분명하게 하기 위해 컬럼명 변경
xyzwv Mar 15, 2024
57ad546
feat: 공지사항 등록을 위한 서비스 메서드 추가
xyzwv Mar 15, 2024
c94f12d
feat: 공지사항 등록을 위한 컨트롤러 메서드 추가
xyzwv Mar 15, 2024
1c86671
feat: 공지사항 조회를 위한 서비스 메서드 추가
xyzwv Mar 15, 2024
10f0e85
feat: 공지사항 조회를 위한 컨트롤러 메서드 추가
xyzwv Mar 15, 2024
acb9432
feat: 공지사항 리스트 조회를 위한 서비스 메서드 추가
xyzwv Mar 15, 2024
9b74bb1
feat: 공지사항 리스트 조회를 위한 컨트롤러 메서드 추가
xyzwv Mar 15, 2024
e789bb8
feat: 공지사항 삭제를 위한 서비스 메서드 추가
xyzwv Mar 15, 2024
87d3406
feat: 공지사항 삭제를 위한 컨트롤러 메서드 추가
xyzwv Mar 15, 2024
d800711
Merge pull request #6 from EWHA-THON-E-BUS/feat/notice
xyzwv Mar 15, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package EBus.EBusback.domain.heart.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import EBus.EBusback.domain.heart.dto.HeartRequestDto;
import EBus.EBusback.domain.heart.service.HeartService;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/hearts")
public class HeartController {

private final HeartService heartService;

@PostMapping
public String clickHeart(@RequestBody HeartRequestDto requestDto) {
return heartService.createOrRemoveHeart(requestDto.getPostId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package EBus.EBusback.domain.heart.dto;

import lombok.Getter;

@Getter
public class HeartRequestDto {

private Long postId;
}
49 changes: 30 additions & 19 deletions src/main/java/EBus/EBusback/domain/heart/entity/Heart.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package EBus.EBusback.domain.heart.entity;

import EBus.EBusback.domain.member.entity.Member;

import EBus.EBusback.domain.post.entity.Post;
import jakarta.persistence.*;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -13,25 +19,30 @@
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Heart {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false, updatable = false)
private Long heartId;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false, updatable = false)
private Long heartId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", nullable = false)
private Member member;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", nullable = false)
private Member member;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id", nullable = false)
private Post post;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id", nullable = false)
private Post post;
@Column(nullable = false)
private Boolean isValid;

@Column(nullable = false)
private Boolean isValid;
@Builder
public Heart(Member member, Post post) {
this.member = member;
this.post = post;
this.isValid = false;
}

@Builder
public Heart(Member member, Post post){
this.member = member;
this.post = post;
}
public void updateHeart() {
this.isValid = !isValid;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package EBus.EBusback.domain.heart.repository;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;

import EBus.EBusback.domain.heart.entity.Heart;
import EBus.EBusback.domain.member.entity.Member;
import EBus.EBusback.domain.post.entity.Post;

public interface HeartRepository extends JpaRepository<Heart, Long> {

Optional<Heart> findByMemberAndPost(Member member, Post post);

Boolean existsByMemberAndPostAndIsValid(Member member, Post post, Boolean isValid);
}
44 changes: 44 additions & 0 deletions src/main/java/EBus/EBusback/domain/heart/service/HeartService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package EBus.EBusback.domain.heart.service;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import EBus.EBusback.domain.heart.entity.Heart;
import EBus.EBusback.domain.heart.repository.HeartRepository;
import EBus.EBusback.domain.member.entity.Member;
import EBus.EBusback.domain.post.entity.Post;
import EBus.EBusback.domain.post.repository.PostRepository;
import EBus.EBusback.global.SecurityUtil;
import lombok.RequiredArgsConstructor;

@Service
@Transactional
@RequiredArgsConstructor
public class HeartService {

private final HeartRepository heartRepository;
private final PostRepository postRepository;

public String createOrRemoveHeart(Long postId) {
Member member = SecurityUtil.getCurrentUser();
if (member == null)
throw new RuntimeException("사용자를 찾을 수 없습니다.");

Post post = postRepository.findById(postId)
.orElseThrow(() -> new IllegalArgumentException("글을 찾을 수 없습니다."));

Heart heart = heartRepository.findByMemberAndPost(member, post)
.orElseGet(() -> heartRepository.save(Heart.builder().member(member).post(post).build()));

heart.updateHeart();

if (heart.getIsValid())
return "좋아요가 등록되었습니다.";
else
return "좋아요가 취소되었습니다.";
}

public Boolean existsHeart(Member member, Post post) {
return heartRepository.existsByMemberAndPostAndIsValid(member, post, true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package EBus.EBusback.domain.notice.controller;

import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import EBus.EBusback.domain.notice.dto.NoticeResponseDto;
import EBus.EBusback.domain.notice.service.NoticeService;
import EBus.EBusback.domain.post.dto.PostRequestDto;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/notices")
public class NoticeController {

private final NoticeService noticeService;

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public NoticeResponseDto createNotice(@RequestBody PostRequestDto requestDto) {
return noticeService.createNotice(requestDto);
}

@GetMapping("/{noticeId}")
@ResponseStatus(HttpStatus.OK)
public NoticeResponseDto findNotice(@PathVariable Long noticeId) {
return noticeService.findNotice(noticeId);
}

@GetMapping
@ResponseStatus(HttpStatus.OK)
public List<NoticeResponseDto> findNoticeList() {
return noticeService.findNoticeList();
}

@DeleteMapping("/{noticeId}")
@ResponseStatus(HttpStatus.OK)
public String removeNotice(@PathVariable Long noticeId) {
noticeService.removeNotice(noticeId);
return "공지사항이 삭제되었습니다.";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package EBus.EBusback.domain.notice.dto;

import java.time.LocalDateTime;

import EBus.EBusback.domain.notice.entity.Notice;
import lombok.Getter;

@Getter
public class NoticeResponseDto {

private Long noticeId;
private String title;
private String content;
private LocalDateTime createdDate;

public NoticeResponseDto(Notice notice) {
this.noticeId = notice.getNoticeId();
this.title = notice.getTitle();
this.content = notice.getContent();
this.createdDate = notice.getCreatedDate();
}
}
12 changes: 10 additions & 2 deletions src/main/java/EBus/EBusback/domain/notice/entity/Notice.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

Expand All @@ -28,6 +29,13 @@ public class Notice extends BaseTimeEntity {
private String content;

@ManyToOne
@JoinColumn(name = "member_id")
private Member member;
@JoinColumn(name = "writer_id")
private Member writer;

@Builder
public Notice(String title, String content, Member writer) {
this.title = title;
this.content = content;
this.writer = writer;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package EBus.EBusback.domain.notice.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import EBus.EBusback.domain.notice.entity.Notice;

public interface NoticeRepository extends JpaRepository<Notice, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package EBus.EBusback.domain.notice.service;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import EBus.EBusback.domain.member.entity.Member;
import EBus.EBusback.domain.member.entity.Role;
import EBus.EBusback.domain.notice.dto.NoticeResponseDto;
import EBus.EBusback.domain.notice.entity.Notice;
import EBus.EBusback.domain.notice.repository.NoticeRepository;
import EBus.EBusback.domain.post.dto.PostRequestDto;
import EBus.EBusback.global.SecurityUtil;
import lombok.RequiredArgsConstructor;

@Service
@Transactional
@RequiredArgsConstructor
public class NoticeService {

private final NoticeRepository noticeRepository;

public NoticeResponseDto createNotice(PostRequestDto requestDto) {
Member member = SecurityUtil.getCurrentUser();
if (!member.getRole().equals(Role.ADMIN))
throw new RuntimeException("공지사항은 관리자만 작성 가능합니다.");
return new NoticeResponseDto(noticeRepository.save(
Notice.builder().title(requestDto.getTitle()).content(requestDto.getContent()).writer(member).build()
));
}

public NoticeResponseDto findNotice(Long noticeId) {
Notice notice = noticeRepository.findById(noticeId)
.orElseThrow(() -> new RuntimeException("공지사항을 찾을 수 없습니다."));
return new NoticeResponseDto(notice);
}

public List<NoticeResponseDto> findNoticeList() {
return noticeRepository.findAll().stream()
.map(NoticeResponseDto::new).collect(Collectors.toList());
}

public void removeNotice(Long noticeId) {
Member member = SecurityUtil.getCurrentUser();
Notice notice = noticeRepository.findById(noticeId)
.orElseThrow(() -> new RuntimeException("공지사항을 찾을 수 없습니다."));
if (!member.getRole().equals(Role.ADMIN))
throw new RuntimeException("관리자만 삭제할 수 있습니다.");
noticeRepository.delete(notice);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package EBus.EBusback.domain.post.controller;

import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import EBus.EBusback.domain.post.dto.PostCreateResponseDto;
import EBus.EBusback.domain.post.dto.PostDetailResponseDto;
import EBus.EBusback.domain.post.dto.PostOutlineResponseDto;
import EBus.EBusback.domain.post.dto.PostRequestDto;
import EBus.EBusback.domain.post.service.PostService;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/posts")
public class PostController {

private final PostService postService;

@PostMapping("/suggestion")
@ResponseStatus(HttpStatus.CREATED)
public PostCreateResponseDto createSuggestion(@RequestBody PostRequestDto requestDto) {
return postService.createPost(requestDto, true);
}

@PostMapping("/appreciation")
@ResponseStatus(HttpStatus.CREATED)
public PostCreateResponseDto createAppreciation(@RequestBody PostRequestDto requestDto) {
return postService.createPost(requestDto, false);
}

@GetMapping("/{postId}")
@ResponseStatus(HttpStatus.OK)
public PostDetailResponseDto findPost(@PathVariable Long postId) {
return postService.findPost(postId);
}

@GetMapping("/suggestion")
@ResponseStatus(HttpStatus.OK)
public List<PostOutlineResponseDto> findSuggestionList() {
return postService.findPostList(true);
}

@GetMapping("/appreciation")
@ResponseStatus(HttpStatus.OK)
public List<PostOutlineResponseDto> findAppreciationList() {
return postService.findPostList(false);
}

@DeleteMapping("/{postId}")
@ResponseStatus(HttpStatus.OK)
public String removePost(@PathVariable Long postId) {
postService.removePost(postId);
return "글이 삭제되었습니다.";
}

}
Loading
Loading