diff --git a/src/main/java/org/harang/server/controller/PostController.java b/src/main/java/org/harang/server/controller/PostController.java new file mode 100644 index 0000000..bf68463 --- /dev/null +++ b/src/main/java/org/harang/server/controller/PostController.java @@ -0,0 +1,32 @@ +package org.harang.server.controller; + +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.harang.server.annotation.MemberId; +import org.harang.server.domain.Post; +import org.harang.server.dto.common.ApiResponse; +import org.harang.server.dto.request.PostRequest; +import org.harang.server.dto.type.SuccessMessage; +import org.harang.server.service.PostService; +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; + +@Slf4j +@RestController +@RequestMapping("/v1/posts") +@RequiredArgsConstructor +public class PostController { + + private final PostService postService; + + @PostMapping + public ApiResponse createPost(@MemberId Long memberId, @Valid @RequestBody PostRequest request) { + + Post post = postService.createPost(memberId, request); + + return ApiResponse.success(SuccessMessage.CREATED); + } +} diff --git a/src/main/java/org/harang/server/controller/TestController.java b/src/main/java/org/harang/server/controller/TestController.java new file mode 100644 index 0000000..69afa9f --- /dev/null +++ b/src/main/java/org/harang/server/controller/TestController.java @@ -0,0 +1,25 @@ +package org.harang.server.controller; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.harang.server.domain.enums.Type; +import org.harang.server.dto.response.JwtTokenResponse; +import org.harang.server.util.JwtUtil; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequestMapping("/test") +@RequiredArgsConstructor +public class TestController { + private final JwtUtil jwtUtil; + + @GetMapping("/token/{memberId}") + public ResponseEntity getToken(@PathVariable("memberId") Long memberId) { + return ResponseEntity.ok(jwtUtil.generateTokens(memberId, Type.WATERING)); + } +} diff --git a/src/main/java/org/harang/server/domain/Category.java b/src/main/java/org/harang/server/domain/Category.java index 5e4f7b5..f3f79d3 100644 --- a/src/main/java/org/harang/server/domain/Category.java +++ b/src/main/java/org/harang/server/domain/Category.java @@ -6,6 +6,9 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.ArrayList; +import java.util.List; + @Entity @Getter @Table(name = "category") @@ -15,16 +18,14 @@ public class Category { @Column(name = "id", nullable = false) private Long id; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "post_id") - private Post post; - @Column(name = "name", nullable = false) private String name; + @OneToMany(mappedBy = "category") + private List postCategoryList = new ArrayList<>(); + @Builder - public Category(Post post, String name) { - this.post = post; + public Category(String name) { this.name = name; } } diff --git a/src/main/java/org/harang/server/domain/Post.java b/src/main/java/org/harang/server/domain/Post.java index 5723146..6d749b9 100644 --- a/src/main/java/org/harang/server/domain/Post.java +++ b/src/main/java/org/harang/server/domain/Post.java @@ -8,6 +8,7 @@ import org.harang.server.domain.enums.Gender; import org.harang.server.domain.enums.Status; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -36,32 +37,32 @@ public class Post { @Column(name = "chat_link", nullable = false) private String chatLink; - @Column(name = "preferred_gender", nullable = false) + @Column(name = "preferred_gender") @Enumerated(EnumType.STRING) private Gender preferredGender; - @Column(name = "preferred_age", nullable = false) - private Long preferredAge; + @Column(name = "preferred_age") + private int preferredAge; - @Column(name = "preferred_start_at", nullable = false) - private LocalDateTime preferredStartAt; + @Column(name = "preferred_start_at") + private LocalDate preferredStartAt; - @Column(name = "preferred_end_at", nullable = false) - private LocalDateTime preferredEndAt; + @Column(name = "preferred_end_at") + private LocalDate preferredEndAt; - @Column(name = "status", nullable = false) + @Column(name = "status") @Enumerated(EnumType.STRING) private Status status = Status.WAITING; /* Relation Parent Mapping */ @OneToMany(mappedBy = "post") - private List categoryList = new ArrayList<>(); + private List matchingList = new ArrayList<>(); @OneToMany(mappedBy = "post") - private List matchingList = new ArrayList<>(); + private List postCategoryList = new ArrayList<>(); @Builder - public Post(Member member, LocalDateTime createdAt, String title, String content, String chatLink, Gender preferredGender, Long preferredAge, LocalDateTime preferredStartAt, LocalDateTime preferredEndAt, Status status) { + public Post(Member member, LocalDateTime createdAt, String title, String content, String chatLink, Gender preferredGender, int preferredAge, LocalDate preferredStartAt, LocalDate preferredEndAt, Status status) { this.member = member; this.createdAt = createdAt; this.title = title; diff --git a/src/main/java/org/harang/server/domain/PostCategory.java b/src/main/java/org/harang/server/domain/PostCategory.java new file mode 100644 index 0000000..b208a15 --- /dev/null +++ b/src/main/java/org/harang/server/domain/PostCategory.java @@ -0,0 +1,34 @@ +package org.harang.server.domain; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@Table(name = "post_category") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class PostCategory { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", nullable = false) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id") + private Post post; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "category_id") + private Category category; + + @Builder + public PostCategory(Post post, Category category) { + this.post = post; + this.category = category; + } +} diff --git a/src/main/java/org/harang/server/domain/enums/Gender.java b/src/main/java/org/harang/server/domain/enums/Gender.java index 0a1cbbb..ee29730 100644 --- a/src/main/java/org/harang/server/domain/enums/Gender.java +++ b/src/main/java/org/harang/server/domain/enums/Gender.java @@ -8,7 +8,8 @@ @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public enum Gender { MALE("male"), - FEMALE("female"); + FEMALE("female"), + NONE("none"); private final String value; } diff --git a/src/main/java/org/harang/server/dto/request/PostRequest.java b/src/main/java/org/harang/server/dto/request/PostRequest.java new file mode 100644 index 0000000..b647098 --- /dev/null +++ b/src/main/java/org/harang/server/dto/request/PostRequest.java @@ -0,0 +1,29 @@ +package org.harang.server.dto.request; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import org.harang.server.domain.Category; +import org.harang.server.domain.enums.Gender; +import org.harang.server.domain.enums.Status; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +public record PostRequest( + @JsonProperty("title") @NotNull @Size(min = 5, max = 24 ) String title, + @JsonProperty("content") @NotNull(message = "내용을 입력해주세요.") String content, + @JsonProperty("chatLink") @NotNull(message = "오픈채팅방 링크를 첨부해주세요.") String chatLink, + @JsonProperty("preferredGender") Gender preferredGender, + @JsonProperty("preferredAge") int preferredAge, + @JsonProperty("preferredStartAt") @JsonFormat(pattern = "yyyy-MM-dd") LocalDate preferredStartAt, + @JsonProperty("preferredEndAt") @JsonFormat(pattern = "yyyy-MM-dd") LocalDate preferredEndAt, + @JsonProperty("category") List categoryList, + @JsonProperty("preferredLocation") String preferredLocation, + @JsonProperty("x") Double x, + @JsonProperty("y") Double y +) { + +} diff --git a/src/main/java/org/harang/server/dto/type/ErrorMessage.java b/src/main/java/org/harang/server/dto/type/ErrorMessage.java index 56f0986..a3b2f7a 100644 --- a/src/main/java/org/harang/server/dto/type/ErrorMessage.java +++ b/src/main/java/org/harang/server/dto/type/ErrorMessage.java @@ -37,6 +37,7 @@ public enum ErrorMessage { POST_NOT_FOUND("40403", HttpStatus.NOT_FOUND, "게시글이 존재하지 않습니다."), MATCHING_NOT_FOUND("40404", HttpStatus.NOT_FOUND, "매칭이 존재하지 않습니다."), + // method not allowed - 409 METHOD_NOT_ALLOWED("40901", HttpStatus.METHOD_NOT_ALLOWED, "지원하지 않는 메소드입니다."), diff --git a/src/main/java/org/harang/server/repository/CategoryRepository.java b/src/main/java/org/harang/server/repository/CategoryRepository.java new file mode 100644 index 0000000..202bc04 --- /dev/null +++ b/src/main/java/org/harang/server/repository/CategoryRepository.java @@ -0,0 +1,8 @@ +package org.harang.server.repository; + +import org.harang.server.domain.Category; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CategoryRepository extends JpaRepository { + Category findByName(String name); +} diff --git a/src/main/java/org/harang/server/repository/LocationRepository.java b/src/main/java/org/harang/server/repository/LocationRepository.java new file mode 100644 index 0000000..05ce167 --- /dev/null +++ b/src/main/java/org/harang/server/repository/LocationRepository.java @@ -0,0 +1,7 @@ +package org.harang.server.repository; + +import org.harang.server.domain.Location; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface LocationRepository extends JpaRepository { +} diff --git a/src/main/java/org/harang/server/repository/MemberRepository.java b/src/main/java/org/harang/server/repository/MemberRepository.java index 2680559..53feb24 100644 --- a/src/main/java/org/harang/server/repository/MemberRepository.java +++ b/src/main/java/org/harang/server/repository/MemberRepository.java @@ -9,4 +9,5 @@ public interface MemberRepository extends JpaRepository { default Member findByIdOrThrow(Long id) { return findById(id).orElseThrow(() -> new CustomException(ErrorMessage.MEMBER_NOT_FOUND)); } -} \ No newline at end of file +} + diff --git a/src/main/java/org/harang/server/repository/PostCategoryRepository.java b/src/main/java/org/harang/server/repository/PostCategoryRepository.java new file mode 100644 index 0000000..11e1e19 --- /dev/null +++ b/src/main/java/org/harang/server/repository/PostCategoryRepository.java @@ -0,0 +1,7 @@ +package org.harang.server.repository; + +import org.harang.server.domain.PostCategory; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostCategoryRepository extends JpaRepository { +} diff --git a/src/main/java/org/harang/server/repository/PostRepository.java b/src/main/java/org/harang/server/repository/PostRepository.java index a066016..bd4919c 100644 --- a/src/main/java/org/harang/server/repository/PostRepository.java +++ b/src/main/java/org/harang/server/repository/PostRepository.java @@ -1,12 +1,12 @@ package org.harang.server.repository; import org.harang.server.domain.Post; +import org.springframework.data.jpa.repository.JpaRepository; import org.harang.server.dto.type.ErrorMessage; import org.harang.server.exception.CustomException; -import org.springframework.data.jpa.repository.JpaRepository; public interface PostRepository extends JpaRepository { default Post findByIdOrThrow(Long id) { return findById(id).orElseThrow(() -> new CustomException(ErrorMessage.POST_NOT_FOUND)); } -} \ No newline at end of file +} diff --git a/src/main/java/org/harang/server/service/PostService.java b/src/main/java/org/harang/server/service/PostService.java new file mode 100644 index 0000000..54cbeb4 --- /dev/null +++ b/src/main/java/org/harang/server/service/PostService.java @@ -0,0 +1,69 @@ +package org.harang.server.service; + +import lombok.RequiredArgsConstructor; +import org.harang.server.domain.*; +import org.harang.server.domain.enums.Status; +import org.harang.server.dto.request.PostRequest; +import org.harang.server.repository.*; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Service +@RequiredArgsConstructor +public class PostService { + + private final PostRepository postRepository; + private final MemberRepository memberRepository; + private final CategoryRepository categoryRepository; + private final LocationRepository locationRepository; + private final PostCategoryRepository postCategoryRepository; + + @Transactional + public Post createPost(Long memberId, PostRequest request) { + LocalDateTime createdAt = LocalDateTime.now(); + Status status = Status.WAITING; + + Member member = memberRepository.findByIdOrThrow(memberId); + + Post savedPost = postRepository.save( + Post.builder() + .member(member) + .createdAt(createdAt) + .title(request.title()) + .content(request.content()) + .chatLink(request.chatLink()) + .preferredGender(request.preferredGender()) + .preferredAge(request.preferredAge()) + .preferredStartAt(request.preferredStartAt()) + .preferredEndAt(request.preferredEndAt()) + .status(status) + .build() + ); + + Location savedLocation = locationRepository.save( + Location.builder() + .post(savedPost) + .name(request.preferredLocation()) + .xValue(request.x()) + .yValue(request.y()) + .build() + ); + + for (String categoryName: request.categoryList()) { + Category category = categoryRepository.findByName(categoryName); + if(category != null) { + PostCategory savedPostCategory = + PostCategory.builder() + .post(savedPost) + .category(category) + .build(); + postCategoryRepository.save(savedPostCategory); + } + } + return savedPost; + } + +}