diff --git a/src/main/java/com/gongjakso/server/domain/apply/dto/ApplyReq.java b/src/main/java/com/gongjakso/server/domain/apply/dto/ApplyReq.java index bb13b372..74de45eb 100644 --- a/src/main/java/com/gongjakso/server/domain/apply/dto/ApplyReq.java +++ b/src/main/java/com/gongjakso/server/domain/apply/dto/ApplyReq.java @@ -4,6 +4,7 @@ import com.gongjakso.server.domain.apply.enumerate.PostType; import com.gongjakso.server.domain.member.entity.Member; import com.gongjakso.server.domain.post.entity.Post; +import java.util.Optional; public record ApplyReq( String application, diff --git a/src/main/java/com/gongjakso/server/domain/post/controller/PostController.java b/src/main/java/com/gongjakso/server/domain/post/controller/PostController.java index b5d8509a..164a440a 100644 --- a/src/main/java/com/gongjakso/server/domain/post/controller/PostController.java +++ b/src/main/java/com/gongjakso/server/domain/post/controller/PostController.java @@ -1,40 +1,45 @@ package com.gongjakso.server.domain.post.controller; +import com.gongjakso.server.domain.member.entity.Member; +import com.gongjakso.server.domain.post.dto.PostDeleteRes; +import com.gongjakso.server.domain.post.dto.PostReq; +import com.gongjakso.server.domain.post.dto.PostRes; +import com.gongjakso.server.domain.post.entity.Post; import com.gongjakso.server.domain.post.service.PostService; +import com.gongjakso.server.global.common.ApplicationResponse; +import com.gongjakso.server.global.security.PrincipalDetails; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.boot.autoconfigure.pulsar.PulsarProperties.Authentication; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.*; @RestController -@RequiredArgsConstructor @RequestMapping("/api/v1/post") +@RequiredArgsConstructor @Tag(name = "Post", description = "공고 관련 API") public class PostController { + private final PostService postService; -// @PostMapping -// public ResponseEntity<> createPost() { -// -// } + @PostMapping("") + public ApplicationResponse create(@AuthenticationPrincipal PrincipalDetails principalDetails, @RequestBody PostReq req) { + return ApplicationResponse.ok(postService.create(principalDetails.getMember(), req)); + } + + @GetMapping("/{id}") + public ResponseEntity read(@AuthenticationPrincipal PrincipalDetails principalDetails, @PathVariable("id") Long id) { + return ResponseEntity.ok(postService.read(principalDetails.getMember(), id)); + } + + @PutMapping("/{id}") + public ApplicationResponse modify(@AuthenticationPrincipal PrincipalDetails principalDetails, @PathVariable("id") Long id, @RequestBody PostReq req) { + return ApplicationResponse.ok(postService.modify(principalDetails.getMember(), id, req)); + } - /** 모집글 게시(CREATE) */ -// @PostMapping("/posts") -// public ResponseEntity createPost( -// @RequestBody @Validated PostCreationRequest request, -// @AuthenticationPrincipal OAuth2User user) { -// -// String email = user.getName(); -// Post post = postService.createPost(request, email); -// keywordService.addKeywords(post, request); -// -// return ResponseEntity.ok( -// PostCreationResponse.builder() -// .id(post.getId()) -// .title(post.getThumbnail().getTitle()) -// .createdDate(post.getCreatedDate()) -// .build()); -// } -} + @PatchMapping("/{id}") + public ApplicationResponse delete(@AuthenticationPrincipal PrincipalDetails principalDetails, @PathVariable("id") Long id){ + return ApplicationResponse.ok(postService.delete(principalDetails.getMember(), id)); + } +} \ No newline at end of file diff --git a/src/main/java/com/gongjakso/server/domain/post/dto/GetProjectRes.java b/src/main/java/com/gongjakso/server/domain/post/dto/GetProjectRes.java new file mode 100644 index 00000000..65cb44e3 --- /dev/null +++ b/src/main/java/com/gongjakso/server/domain/post/dto/GetProjectRes.java @@ -0,0 +1,2 @@ +package com.gongjakso.server.domain.post.dto;public class GetProjectRes { +} diff --git a/src/main/java/com/gongjakso/server/domain/post/dto/PostDeleteRes.java b/src/main/java/com/gongjakso/server/domain/post/dto/PostDeleteRes.java new file mode 100644 index 00000000..d9b2e6cb --- /dev/null +++ b/src/main/java/com/gongjakso/server/domain/post/dto/PostDeleteRes.java @@ -0,0 +1,16 @@ +package com.gongjakso.server.domain.post.dto; + +import lombok.Builder; +import lombok.Getter; + +@Getter +public class PostDeleteRes { + private Long postId; + private Long memberId; + + @Builder + public PostDeleteRes(Long postId, Long memberId){ + this.postId = postId; + this.memberId = memberId; + } +} diff --git a/src/main/java/com/gongjakso/server/domain/post/dto/PostReq.java b/src/main/java/com/gongjakso/server/domain/post/dto/PostReq.java index 3d8b48cb..38dd6ff6 100644 --- a/src/main/java/com/gongjakso/server/domain/post/dto/PostReq.java +++ b/src/main/java/com/gongjakso/server/domain/post/dto/PostReq.java @@ -1,13 +1,12 @@ package com.gongjakso.server.domain.post.dto; -import com.gongjakso.server.domain.post.enumerate.PostType; -import lombok.Builder; +import com.gongjakso.server.domain.post.enumerate.MeetingMethod; +import com.gongjakso.server.domain.post.enumerate.PostStatus; import lombok.Data; import lombok.Getter; import lombok.NoArgsConstructor; import java.time.LocalDateTime; -import org.springframework.cglib.core.Local; @Data @Getter @@ -15,13 +14,34 @@ public class PostReq { private String title; private String contents; - private PostType status; + private PostStatus status; private LocalDateTime startDate; private LocalDateTime endDate; + private LocalDateTime finishDate; private Long maxPerson; - private PostType meetingMethod; + private MeetingMethod meetingMethod; private String meetingArea; private boolean questionMethod; private String questionLink; - private boolean isProject; + private boolean postType; + + /* + * @Builder + * public PostReq(String title, String contents, PostStatus status, LocalDateTime + * startDate, LocalDateTime endDate, + * Long maxPerson, PostType meetingMethod, String meetingArea, boolean + * questionMethod, String questionLink, boolean isProject){ + * this.title = title; + * this.contents = contents; + * this.status = status; + * this.startDate = startDate; + * this.endDate = endDate; + * this.maxPerson = maxPerson; + * this.meetingArea = meetingArea; + * this.meetingMethod = meetingMethod; + * this.questionMethod = questionMethod; + * this.questionLink = questionLink; + * this.isProject = isProject; + * } + */ } \ No newline at end of file diff --git a/src/main/java/com/gongjakso/server/domain/post/dto/PostRes.java b/src/main/java/com/gongjakso/server/domain/post/dto/PostRes.java index 53f55c96..799ec6c6 100644 --- a/src/main/java/com/gongjakso/server/domain/post/dto/PostRes.java +++ b/src/main/java/com/gongjakso/server/domain/post/dto/PostRes.java @@ -1,4 +1,52 @@ package com.gongjakso.server.domain.post.dto; +import com.gongjakso.server.domain.post.enumerate.MeetingMethod; +import com.gongjakso.server.domain.post.enumerate.PostStatus; +import lombok.Builder; +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter public class PostRes { -} + private Long postId; + private Long memberId; + private String title; + private String contents; + private PostStatus status; + private LocalDateTime startDate; + private LocalDateTime endDate; + private LocalDateTime finishDate; + private Long maxPerson; + private MeetingMethod meetingMethod; + private String meetingArea; + private boolean questionMethod; + private String questionLink; + private boolean postType; + private LocalDateTime createdAt; + private LocalDateTime modifiedAt; + private LocalDateTime deletedAt; + + @Builder + public PostRes(Long postId, Long memberId, String title, String contents, PostStatus status, LocalDateTime startDate, LocalDateTime endDate, + LocalDateTime finishDate, Long maxPerson, MeetingMethod meetingMethod, String meetingArea, boolean questionMethod, String questionLink, + boolean postType, LocalDateTime createdAt, LocalDateTime modifiedAt, LocalDateTime deletedAt) { + this.postId = postId; + this.memberId = memberId; + this.title = title; + this.contents = contents; + this.status = status; + this.startDate = startDate; + this.endDate = endDate; + this.finishDate = finishDate; + this.maxPerson = maxPerson; + this.meetingArea = meetingArea; + this.meetingMethod = meetingMethod; + this.questionMethod = questionMethod; + this.questionLink = questionLink; + this.postType = postType; + this.createdAt = createdAt; + this.modifiedAt = modifiedAt; + this.deletedAt = deletedAt; + } +} \ No newline at end of file diff --git a/src/main/java/com/gongjakso/server/domain/post/entity/Post.java b/src/main/java/com/gongjakso/server/domain/post/entity/Post.java index 4cb5c8c3..2932369e 100644 --- a/src/main/java/com/gongjakso/server/domain/post/entity/Post.java +++ b/src/main/java/com/gongjakso/server/domain/post/entity/Post.java @@ -1,23 +1,20 @@ package com.gongjakso.server.domain.post.entity; -import com.gongjakso.server.domain.post.enumerate.PostType; +import com.gongjakso.server.domain.member.entity.Member; +import com.gongjakso.server.domain.post.dto.PostReq; +import com.gongjakso.server.domain.post.enumerate.MeetingMethod; +import com.gongjakso.server.domain.post.enumerate.PostStatus; import com.gongjakso.server.global.common.BaseTimeEntity; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.Table; +import jakarta.persistence.*; +import org.hibernate.annotations.SQLDelete; import java.time.LocalDateTime; - import lombok.*; @Getter @Setter @Entity @Table(name = "post") +@SQLDelete(sql="UPDATE post SET deleted_at = NOW() where post_id=?") @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Post extends BaseTimeEntity { @@ -26,7 +23,11 @@ public class Post extends BaseTimeEntity { @Column(name = "post_id", nullable = false, columnDefinition = "bigint") private Long postId; - @Column(name = "title", nullable = false, columnDefinition = "varchar(20)") + @ManyToOne(targetEntity = Member.class, fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @Column(name = "title", nullable = false, columnDefinition = "varchar(40)") private String title; @Column(name = "contents", nullable = false, columnDefinition = "varchar(500)") @@ -34,7 +35,7 @@ public class Post extends BaseTimeEntity { @Column(name = "status", columnDefinition = "varchar(255)") @Enumerated(EnumType.STRING) - private PostType status; + private PostStatus status; @Column(name = "start_date", nullable = false, columnDefinition = "timestamp") private LocalDateTime startDate; @@ -42,12 +43,15 @@ public class Post extends BaseTimeEntity { @Column(name = "end_date", nullable = false, columnDefinition = "timestamp") private LocalDateTime endDate; + @Column(name = "finish_date", nullable = false, columnDefinition = "timestamp") + private LocalDateTime finishDate; + @Column(name = "max_person", nullable = false, columnDefinition = "bigint") private Long maxPerson; @Column(name = "meeting_method", columnDefinition = "varchar(10)") @Enumerated(EnumType.STRING) - private PostType meetingMethod; + private MeetingMethod meetingMethod; @Column(name = "meeting_area", columnDefinition = "varchar(100)") private String meetingArea; @@ -58,22 +62,39 @@ public class Post extends BaseTimeEntity { @Column(name = "question_link", nullable = false, columnDefinition = "text") private String questionLink; - @Column(name = "is_project", nullable = false, columnDefinition = "tinyint") - private boolean isProject; + @Column(name = "post_type", nullable = false, columnDefinition = "tinyint") + private boolean postType; @Builder - public Post(Long postId, String title, String contents, PostType status, LocalDateTime startDate, LocalDateTime endDate, Long maxPerson, PostType meetingMethod, String meetingArea, boolean questionMethod, String questionLink, boolean isProject) { - this.postId = postId; - this.title = title; - this.contents = contents; - this.status = status; - this.startDate = startDate; - this.endDate = endDate; - this.maxPerson = maxPerson; - this.meetingMethod = meetingMethod; - this.meetingArea = meetingArea; - this.questionMethod = questionMethod; - this.questionLink = questionLink; - this.isProject = isProject; + public Post(Member member, PostReq req) { + this.title = req.getTitle(); + this.member = member; + this.contents = req.getContents(); + this.status = req.getStatus(); + this.startDate = req.getStartDate(); + this.finishDate = req.getFinishDate(); + this.endDate = req.getEndDate(); + this.maxPerson = req.getMaxPerson(); + this.meetingMethod = req.getMeetingMethod(); + this.meetingArea = req.getMeetingArea(); + this.questionMethod = req.isQuestionMethod(); + this.questionLink = req.getQuestionLink(); + this.postType = req.isPostType(); } + + public void modify(PostReq req) { + this.title = req.getTitle(); + this.contents = req.getContents(); + this.status = req.getStatus(); + this.startDate = req.getStartDate(); + this.endDate = req.getEndDate(); + this.finishDate = req.getFinishDate(); + this.maxPerson = req.getMaxPerson(); + this.meetingMethod = req.getMeetingMethod(); + this.meetingArea = req.getMeetingArea(); + this.questionMethod = req.isQuestionMethod(); + this.questionLink = req.getQuestionLink(); + this.postType = req.isPostType(); + } + } \ No newline at end of file diff --git a/src/main/java/com/gongjakso/server/domain/post/enumerate/MeetingMethod.java b/src/main/java/com/gongjakso/server/domain/post/enumerate/MeetingMethod.java new file mode 100644 index 00000000..2a5b4f5c --- /dev/null +++ b/src/main/java/com/gongjakso/server/domain/post/enumerate/MeetingMethod.java @@ -0,0 +1,5 @@ +package com.gongjakso.server.domain.post.enumerate; + +public enum MeetingMethod { + NULL, OFFLINE, ONLINE, BOTH +} \ No newline at end of file diff --git a/src/main/java/com/gongjakso/server/domain/post/enumerate/PostStatus.java b/src/main/java/com/gongjakso/server/domain/post/enumerate/PostStatus.java new file mode 100644 index 00000000..ae474248 --- /dev/null +++ b/src/main/java/com/gongjakso/server/domain/post/enumerate/PostStatus.java @@ -0,0 +1,9 @@ +package com.gongjakso.server.domain.post.enumerate; + +public enum PostStatus { + RECRUITING, + CANCEL, + CLOSE, + ACTIVE, + COMPLETE +} diff --git a/src/main/java/com/gongjakso/server/domain/post/repository/PostRepository.java b/src/main/java/com/gongjakso/server/domain/post/repository/PostRepository.java index c98a1a0a..9fcbbfc8 100644 --- a/src/main/java/com/gongjakso/server/domain/post/repository/PostRepository.java +++ b/src/main/java/com/gongjakso/server/domain/post/repository/PostRepository.java @@ -3,6 +3,11 @@ import com.gongjakso.server.domain.post.entity.Post; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface PostRepository extends JpaRepository { + //Page findAll(Pageable pageable); //전체 조회(페이징) + //Page findByCategory(StackName stackname, Pageable pageable); Post findByPostId(Long post_id); + Optional findByPostIdAndDeletedAtIsNull(Long postId); } diff --git a/src/main/java/com/gongjakso/server/domain/post/service/PostService.java b/src/main/java/com/gongjakso/server/domain/post/service/PostService.java index 16aa6f0d..c3c3920e 100644 --- a/src/main/java/com/gongjakso/server/domain/post/service/PostService.java +++ b/src/main/java/com/gongjakso/server/domain/post/service/PostService.java @@ -1,13 +1,137 @@ package com.gongjakso.server.domain.post.service; +import com.gongjakso.server.domain.member.entity.Member; +import com.gongjakso.server.domain.member.repository.MemberRepository; +import com.gongjakso.server.domain.post.dto.PostDeleteRes; +import com.gongjakso.server.domain.post.dto.PostReq; +import com.gongjakso.server.domain.post.dto.PostRes; +import com.gongjakso.server.domain.post.entity.Post; import com.gongjakso.server.domain.post.repository.PostRepository; +import com.gongjakso.server.global.exception.ApplicationException; +import io.github.classgraph.PackageInfo; +import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import static com.gongjakso.server.global.exception.ErrorCode.NOT_FOUND_EXCEPTION; +import static com.gongjakso.server.global.exception.ErrorCode.UNAUTHORIZED_EXCEPTION; + @Service @Transactional(readOnly = true) @RequiredArgsConstructor public class PostService { + private final PostRepository postRepository; -} + + @Transactional + public PostRes create(Member member, PostReq req) { + Post post = new Post(member, req); + postRepository.save(post); + + return PostRes.builder() + .postId(post.getPostId()) + .memberId(post.getMember().getMemberId()) + .title(post.getTitle()) + .contents(post.getContents()) + .status(post.getStatus()) + .startDate(post.getStartDate()) + .endDate(post.getEndDate()) + .finishDate(post.getFinishDate()) + .maxPerson(post.getMaxPerson()) + .meetingMethod(post.getMeetingMethod()) + .meetingArea(post.getMeetingArea()) + .questionMethod(post.isQuestionMethod()) + .questionLink(post.getQuestionLink()) + .postType(post.isPostType()) + .createdAt(post.getCreatedAt()) + .modifiedAt(post.getModifiedAt()) + .deletedAt(post.getDeletedAt()) + .build(); + } + + @Transactional + public PostRes read(Member member, Long id) { + Post post = postRepository.findById(id) + .orElseThrow(() -> new ApplicationException(NOT_FOUND_EXCEPTION)); + + if(!member.getMemberId().equals(post.getMember().getMemberId())) { + throw new ApplicationException(UNAUTHORIZED_EXCEPTION); + } + + return PostRes.builder() + .postId(post.getPostId()) + .memberId(post.getMember().getMemberId()) + .title(post.getTitle()) + .contents(post.getContents()) + .status(post.getStatus()) + .startDate(post.getStartDate()) + .endDate(post.getEndDate()) + .maxPerson(post.getMaxPerson()) + .meetingMethod(post.getMeetingMethod()) + .meetingArea(post.getMeetingArea()) + .questionMethod(post.isQuestionMethod()) + .questionLink(post.getQuestionLink()) + .postType(post.isPostType()) + .createdAt(post.getCreatedAt()) + .modifiedAt(post.getModifiedAt()) + .deletedAt(post.getDeletedAt()) + .build(); + } + + @Transactional + public PostRes modify(Member member, Long id, PostReq req) { + Post entity = postRepository.findByPostIdAndDeletedAtIsNull(id) + .orElseThrow(() -> new ApplicationException(NOT_FOUND_EXCEPTION)); + if(!member.getMemberId().equals(entity.getMember().getMemberId())){ + throw new ApplicationException(UNAUTHORIZED_EXCEPTION); + } + + entity.modify(req); + + return PostRes.builder() + .postId(entity.getPostId()) + .memberId(entity.getMember().getMemberId()) + .title(entity.getTitle()) + .contents(entity.getContents()) + .status(entity.getStatus()) + .startDate(entity.getStartDate()) + .endDate(entity.getEndDate()) + .finishDate(entity.getFinishDate()) + .maxPerson(entity.getMaxPerson()) + .meetingMethod(entity.getMeetingMethod()) + .meetingArea(entity.getMeetingArea()) + .questionMethod(entity.isQuestionMethod()) + .questionLink(entity.getQuestionLink()) + .postType(entity.isPostType()) + .createdAt(entity.getCreatedAt()) + .modifiedAt(entity.getModifiedAt()) + .deletedAt(entity.getDeletedAt()) + .build(); + } + + @Transactional + public PostDeleteRes delete(Member member, Long id) { + Post entity = postRepository.findByPostIdAndDeletedAtIsNull(id) + .orElseThrow(() -> new ApplicationException(NOT_FOUND_EXCEPTION)); + + postRepository.delete(entity); + return PostDeleteRes.builder() + .postId(entity.getPostId()) + .memberId(entity.getMember().getMemberId()) + .build(); + } + + /* + public Page getProjects(Pageable page) throws ApplicationException { + try { + return postRepository.findAll(page).map(projects -> new GetProjectRes( + projects.getPostId(), + projects.getTitle(), + projects.getMeetingArea()); + } catch (Exception e) { + throw new ApplicationException(INVALID_VALUE_EXCEPTION); + } + } + */ +} \ No newline at end of file diff --git a/src/main/java/com/gongjakso/server/global/common/BaseTimeEntity.java b/src/main/java/com/gongjakso/server/global/common/BaseTimeEntity.java index 2b409a86..a22f9c5c 100644 --- a/src/main/java/com/gongjakso/server/global/common/BaseTimeEntity.java +++ b/src/main/java/com/gongjakso/server/global/common/BaseTimeEntity.java @@ -4,6 +4,7 @@ import jakarta.persistence.EntityListeners; import jakarta.persistence.MappedSuperclass; import lombok.Getter; +import lombok.Setter; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -25,4 +26,4 @@ public abstract class BaseTimeEntity { @Column(name = "deleted_at", columnDefinition = "TIMESTAMP") private LocalDateTime deletedAt; -} +} \ No newline at end of file